[med-svn] [fis-gtm] 02/04: Imported Upstream version 6.1-000

Amul Shah tuskentower-guest at moszumanska.debian.org
Fri Aug 29 14:15:46 UTC 2014


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

tuskentower-guest pushed a commit to branch master
in repository fis-gtm.

commit f5cf19599dedf83f0935d415d123fc28c1e89e62
Author: Amul Shah <Amul.Shah at fisglobal.com>
Date:   Fri Aug 29 09:50:09 2014 -0400

    Imported Upstream version 6.1-000
---
 CMakeLists.txt                                 |    92 +-
 README                                         |    20 +-
 sr_avms/release_name.h                         |     4 +-
 sr_i386/emit_code.c                            |   206 +-
 sr_i386/gdeerrors_ctl.c                        |    64 +-
 sr_i386/merrors_ansi.h                         |    35 +-
 sr_i386/merrors_ctl.c                          |    82 +-
 sr_i386/ttt.c                                  |   792 +-
 sr_linux/gtm_env_sp.csh                        |     3 +-
 sr_linux/release_name.h                        |    12 +-
 sr_port/act_in_gvt.c                           |    37 +-
 sr_port/alias_funcs.c                          |     4 +-
 sr_port/anticipatory_freeze.h                  |    14 +-
 sr_port/buddy_list.h                           |     4 +-
 sr_port/cdbg_dump.c                            |    29 +-
 sr_port/cdbg_dump.h                            |     3 +-
 sr_port/collseq.h                              |    13 +-
 sr_port/compiler.h                             |    92 +-
 sr_port/compiler_ch.c                          |     4 +-
 sr_port/compiler_startup.c                     |    40 +-
 sr_port/cre_jnl_file.c                         |    58 +-
 sr_port/cre_private_code_copy.c                |     9 +-
 sr_port/create_dummy_gbldir.c                  |    85 +-
 sr_port/dbcertify_base_ch.c                    |    76 +-
 sr_port/dbcertify_scan_phase.c                 |    44 +-
 sr_port/deviceparameters.c                     |    32 +-
 sr_port/dfa_calc.c                             |    16 +-
 sr_port/dpgbldir.c                             |   117 +-
 sr_port/dpgbldir.h                             |    14 +-
 sr_port/dse.h                                  |    11 +-
 sr_port/dse.hlp                                |    44 +-
 sr_port/dse_adrec.c                            |    23 +-
 sr_port/dse_adstar.c                           |    13 +-
 sr_port/dse_all.c                              |    51 +-
 sr_port/dse_chng_bhead.c                       |     7 +-
 sr_port/dse_chng_rhead.c                       |    13 +-
 sr_port/dse_dmp.c                              |     4 +-
 sr_port/dse_f_blk.c                            |    16 +-
 sr_port/dse_f_key.c                            |   108 +-
 sr_port/dse_f_reg.c                            |    89 +-
 sr_port/dse_find_gvt.c                         |    71 +
 sr_port/dse_getki.c                            |    66 +-
 sr_port/dse_ksrch.c                            |    16 +-
 sr_port/dse_over.c                             |    16 +-
 sr_port/dse_rest.c                             |    37 +-
 sr_port/dse_rmrec.c                            |     5 +-
 sr_port/dse_shift.c                            |    13 +-
 sr_port/dump_record.c                          |    42 +-
 sr_port/eintr_wrappers.h                       |    20 +-
 sr_port/emit_code.c                            |    80 +-
 sr_port/entryref.c                             |    45 +-
 sr_port/expritem.c                             |     6 +-
 sr_port/f_text.c                               |     9 +-
 sr_port/fgncal.h                               |    15 +-
 sr_port/fgncal_unwind.c                        |    43 +-
 sr_port/find_mvstent.c                         |   105 +-
 sr_port/find_rtn_hdr.c                         |    51 +-
 sr_port/fntext_ch.c                            |     2 +-
 sr_port/format_targ_key.c                      |    39 +-
 sr_port/gbldef.mpt                             |    65 +-
 sr_port/gbldefs.c                              |    57 +-
 sr_port/gde.hlp                                |   117 +-
 sr_port/gde.m                                  |    59 +-
 sr_port/gdeadd.m                               |    20 +-
 sr_port/gdechang.m                             |    27 +-
 sr_port/gdedelet.m                             |    13 +-
 sr_port/gdeerrors.msg                          |    36 +-
 sr_port/gdeexit.m                              |    26 +-
 sr_port/gdeinit.m                              |   225 +-
 sr_port/gdemap.m                               |   591 +-
 sr_port/gdemsgin.m                             |    38 +-
 sr_port/gdeparse.m                             |   445 +-
 sr_port/gdequit.m                              |     3 +-
 sr_port/gderenam.m                             |    25 +-
 sr_port/gdescan.m                              |   136 +-
 sr_port/gdeshow.m                              |   406 +-
 sr_port/gdetempl.m                             |     3 +-
 sr_port/gdsbml.h                               |     3 +
 sr_port/gdsbt.h                                |     6 +-
 sr_port/gdsfhead.h                             |  1396 +-
 sr_port/{iotcp_read.c => get_dlr_zkey.c}       |    10 +-
 sr_port/get_dollar_stack_info.c                |     8 +-
 sr_port/get_frame_place_mcode.c                |     6 +-
 sr_port/glvn_pool.h                            |     4 +-
 sr_port/gtm_common_defs.h                      |     4 +
 sr_port/gtm_connect.c                          |    58 +
 sr_port/gtm_env_init.c                         |    13 +-
 sr_port/gtm_imagetype_init.c                   |    19 +-
 sr_port/gtm_malloc_src.h                       |    13 +-
 sr_port/gtm_maxstr.c                           |     4 +-
 sr_port/gtm_netdb.h                            |    26 +
 sr_port/gtm_repl.h                             |    74 +
 sr_unix/iotcp_select.h => sr_port/gtm_select.h |     8 +-
 sr_port/gtm_threadgbl_defs.h                   |    74 +-
 sr_port/gtm_threadgbl_deftypes.c               |     1 -
 sr_port/gtm_threadgbl_init.c                   |     1 -
 sr_port/{iotcp_dummy.c => gtm_un.h}            |    15 +-
 sr_port/gtmrecv_ch.c                           |    11 +-
 sr_port/gtmrecv_get_opt.c                      |    30 +-
 sr_port/gtmsource_ch.c                         |    12 +-
 sr_port/gv_bind_name.c                         |   114 +-
 sr_port/gv_bind_subsname.c                     |    41 +
 sr_port/gv_rundown.c                           |    46 +-
 sr_port/gv_select.c                            |   257 +-
 sr_port/gv_srch_gblname.c                      |    52 +
 sr_port/gv_srch_map.c                          |   139 +
 sr_port/gv_xform_key.c                         |     9 +-
 sr_port/gvcst_blk_build.c                      |    34 +-
 sr_port/gvcst_data.c                           |    16 +-
 sr_port/gvcst_dataget.c                        |    11 +-
 sr_port/gvcst_gblmod.c                         |    16 +-
 sr_port/gvcst_get.c                            |    19 +-
 sr_port/gvcst_init.c                           |    88 +-
 sr_port/gvcst_kill.c                           |     1 -
 sr_port/gvcst_order.c                          |    30 +-
 sr_port/gvcst_protos.h                         |    46 +-
 sr_port/gvcst_put.c                            |   240 +-
 sr_port/gvcst_query.c                          |    28 +-
 sr_port/gvcst_queryget.c                       |    17 +-
 sr_port/gvcst_root_search.c                    |    87 +-
 sr_port/gvcst_zprevious.c                      |    30 +-
 sr_port/gvinit.c                               |    14 +-
 sr_port/gvn.c                                  |    19 +-
 sr_port/gvname_env_restore.c                   |    27 +-
 sr_port/gvname_env_save.c                      |    29 +-
 sr_port/gvname_info.h                          |    24 +-
 sr_port/gvnh_spanreg.h                         |    33 +
 sr_port/gvnh_spanreg_init.c                    |   130 +
 sr_port/gvnh_spanreg_ismapped.c                |    41 +
 sr_port/gvnh_spanreg_subs_gvt_init.c           |   104 +
 sr_port/gvsub2str.c                            |    69 +-
 sr_port/gvt_hashtab.c                          |    54 +
 sr_unix/dbopen_ch.c => sr_port/gvt_hashtab.h   |    15 +-
 sr_port/gvzwr_fini.c                           |    23 +-
 sr_port/gvzwr_var.c                            |    30 +-
 sr_port/gvzwrite_ch.c                          |     4 +-
 sr_port/gvzwrite_clnup.c                       |     6 +-
 sr_port/hashtab_mname.h                        |    11 +-
 sr_port/hashtab_rehash_ch.c                    |    12 +-
 sr_port/have_crit.h                            |     8 +-
 sr_port/init_root_gv.h                         |    71 -
 sr_port/int_namelook.c                         |    52 +
 sr_port/{iotcp_dummy.c => int_namelook.h}      |    12 +-
 sr_port/io.h                                   |    27 +-
 sr_port/io_dev_dispatch.h                      |    25 +-
 sr_port/io_init_ch.c                           |     4 +-
 sr_port/iop.h                                  |     7 +-
 sr_port/iosocket_bind.c                        |   265 +-
 sr_port/iosocket_close.c                       |    95 +-
 sr_port/iosocket_connect.c                     |   215 +-
 sr_port/iosocket_create.c                      |   255 +-
 sr_port/iosocket_delimiter.c                   |     7 +-
 sr_port/iosocket_destroy.c                     |     4 +-
 sr_port/iosocket_flush.c                       |     8 +-
 sr_port/iosocket_handle.c                      |     4 +-
 sr_port/iosocket_iocontrol.c                   |   120 +-
 sr_port/iosocket_listen.c                      |    48 +-
 sr_port/iosocket_open.c                        |   103 +-
 sr_port/iosocket_poolinit.c                    |     5 +-
 sr_port/iosocket_rdone.c                       |     5 +-
 sr_port/iosocket_read.c                        |     3 +-
 sr_port/iosocket_readfl.c                      |    17 +-
 sr_port/iosocket_snr.c                         |    26 +-
 sr_port/iosocket_switch.c                      |    17 +-
 sr_port/iosocket_use.c                         |    39 +-
 sr_port/iosocket_wait.c                        |   527 +-
 sr_port/iosocket_write.c                       |    49 +-
 sr_port/iosocket_wteol.c                       |    15 +-
 sr_port/iosocket_wtff.c                        |    16 +-
 sr_port/iosocket_wtone.c                       |     5 +-
 sr_port/iosocketdef.h                          |    37 +-
 sr_port/iotcp_close.c                          |    86 -
 sr_port/iotcp_fillroutine.c                    |   130 -
 sr_port/iotcp_flush.c                          |    40 -
 sr_port/iotcp_iocontrol.c                      |    56 -
 sr_port/iotcp_list.c                           |   194 -
 sr_port/iotcp_open.c                           |   417 -
 sr_port/iotcp_rdone.c                          |    26 -
 sr_port/iotcp_readfl.c                         |   285 -
 sr_port/iotcp_use.c                            |   122 -
 sr_port/iotcp_write.c                          |    85 -
 sr_port/iotcp_wteol.c                          |    32 -
 sr_port/iotcp_wtff.c                           |    42 -
 sr_port/iotcp_wtone.c                          |    32 -
 sr_port/iotcpdef.h                             |    93 -
 sr_port/iotcpdefsp.h                           |    19 -
 sr_port/iotcproutine.h                         |    30 -
 sr_port/is_canonic_name.c                      |     8 +-
 sr_port/jnl_put_jrt_pini.c                     |     8 +-
 sr_port/jnl_write_aimg_rec.c                   |    16 +-
 sr_port/jobexam_process.c                      |     2 +-
 sr_port/lastchance3.c                          |     4 +-
 sr_port/lke.hlp                                |    37 +-
 sr_port/lvzwr_out.c                            |    33 +-
 sr_port/m_set.c                                |    73 +-
 sr_port/m_write.c                              |     4 +-
 sr_port/m_zbreak.c                             |     7 +-
 sr_port/m_zprint.c                             |     7 +-
 sr_port/make_gvsubsc.c                         |     8 +-
 sr_port/md5hash.c                              |   295 +
 sr_port/md5hash.h                              |    37 +
 sr_port/mdb_condition_handler.c                |    13 +-
 sr_port/mdef.h                                 |    80 +-
 sr_port/memcoherency.h                         |    41 +-
 sr_port/merge_desc_check.c                     |   213 +-
 sr_port/merrors.msg                            |    45 +-
 sr_port/mlk_region_lookup.c                    |    55 +-
 sr_port/mtables.c                              |     9 +-
 sr_port/mu_extr_gblout.c                       |   176 +-
 sr_port/mu_extr_getblk.c                       |    84 +-
 sr_port/mu_extr_ident.c                        |    12 +-
 sr_port/mu_freeze_ch.c                         |     4 +-
 sr_port/mu_gv_stack_init.c                     |    10 +-
 sr_port/mu_int_err.c                           |     9 +-
 sr_port/mu_int_fhead.c                         |    15 +-
 sr_port/mu_int_getkey.c                        |    21 +-
 sr_port/mu_int_maps.c                          |    24 +-
 sr_port/mu_int_read.c                          |    18 +-
 sr_port/mu_int_reg_ch.c                        |     4 +-
 sr_port/mu_reorg.c                             |   100 +-
 sr_port/mu_reorg_upgrd_dwngrd.c                |    25 +-
 sr_port/mu_swap_blk.c                          |     5 +-
 sr_port/mucregini.c                            |    46 +-
 sr_port/muextr.h                               |   178 +-
 sr_port/mumps.hlp                              | 28618 +++++++++++------------
 sr_port/mupint.h                               |     6 +-
 sr_port/mupip.hlp                              |   266 +-
 sr_port/mupip_backup.c                         |     5 +-
 sr_port/mupip_integ.c                          |    70 +-
 sr_port/mupip_io_dev_dispatch.h                |    10 +-
 sr_port/mupip_load_ch.c                        |     4 +-
 sr_port/mupip_recover.c                        |    71 +-
 sr_port/mupip_reorg.c                          |    69 +-
 sr_port/mupip_reorg.h                          |     4 +-
 sr_port/mupip_set_jnl_ch.c                     |     4 +-
 sr_port/muprec.h                               |   136 +-
 sr_port/mur_apply_pblk.c                       |     4 +-
 sr_port/mur_block_count_correct.c              |    46 +-
 sr_port/mur_close_files.c                      |    12 +-
 sr_port/mur_forward.c                          |    10 +-
 sr_port/mur_forward_play_cur_jrec.c            |    41 +-
 sr_port/mur_jnl_ext.c                          |    14 +-
 sr_port/mur_open_files.c                       |   279 +-
 sr_port/mur_output_record.c                    |    19 +-
 sr_port/mur_pini_addr_reset.c                  |     4 +-
 sr_port/mutex_deadlock_check.c                 |     8 +-
 sr_port/mval2subsc.c                           |    23 +-
 sr_port/nil_iocontrol.c                        |     8 +-
 sr_port/objlabel.h                             |     2 +-
 sr_port/one_job_param.c                        |     6 +-
 sr_port/op.h                                   |     5 +-
 sr_port/op_close.c                             |    10 +-
 sr_port/op_fnfnumber.c                         |    17 +-
 sr_port/op_fnquery.c                           |     8 +-
 sr_port/op_fntext.c                            |    20 +-
 sr_port/op_fnview.c                            |   591 +-
 sr_port/op_fnztrigger.c                        |    39 +-
 sr_port/op_gvdata.c                            |    20 +-
 sr_port/op_gvextnam.c                          |    78 +-
 sr_port/op_gvkill.c                            |    24 +-
 sr_port/op_gvnaked.c                           |   135 +-
 sr_port/op_gvname.c                            |   108 +-
 sr_port/op_gvnext.c                            |    19 +-
 sr_port/op_gvorder.c                           |   205 +-
 sr_port/op_gvquery.c                           |    14 +-
 sr_port/op_gvqueryget.c                        |    13 +-
 sr_port/op_gvrectarg.c                         |     7 +-
 sr_port/op_gvsavtarg.c                         |    17 +-
 sr_port/op_gvzwithdraw.c                       |    17 +-
 sr_port/op_indtext.c                           |    11 +-
 sr_port/op_merge.c                             |   254 +-
 sr_port/op_newintrinsic.c                      |    25 +-
 sr_port/op_nullexp.c                           |    12 +-
 sr_port/op_read.c                              |     4 +-
 sr_port/op_readfl.c                            |     8 +-
 sr_port/op_rhdaddr.c                           |    56 +-
 sr_port/op_savgvn.c                            |     5 +-
 sr_port/op_setzbrk.c                           |    23 +-
 sr_port/op_setzextract.c                       |     6 +-
 sr_port/op_setzp1.c                            |     6 +-
 sr_port/op_setzpiece.c                         |     7 +-
 sr_port/op_svget.c                             |    35 +-
 sr_port/op_svput.c                             |    38 +-
 sr_port/op_tcommit.c                           |     1 -
 sr_port/op_trollback.c                         |    11 +-
 sr_port/op_tstart.c                            |    77 +-
 sr_port/op_view.c                              |    69 +-
 sr_port/op_zgoto.c                             |    24 +-
 sr_port/op_zprevious.c                         |   131 +-
 sr_port/op_zshow.c                             |    21 +-
 sr_port/opcode_def.h                           |     2 +-
 sr_port/outofband.h                            |     4 +-
 sr_port/parm_pool.c                            |     7 +-
 sr_port/patcode.h                              |     7 +-
 sr_port/patstr.c                               |    80 +-
 sr_port/preemptive_db_clnup.c                  |     8 +-
 sr_port/print_target.c                         |     9 +-
 sr_port/probe.h                                |     6 +-
 sr_port/process_gvt_pending_list.c             |   105 +-
 sr_port/process_gvt_pending_list.h             |     4 +-
 sr_port/region_init_ch.c                       |     4 +-
 sr_port/repl_comm.c                            |   337 +-
 sr_port/repl_comm.h                            |    29 +-
 sr_port/repl_errno.h                           |     5 +-
 sr_port/repl_filter.c                          |   121 +-
 sr_port/replic_gbldefs.c                       |    36 +-
 sr_port/replication_ch.c                       |     4 +-
 sr_port/rtn_src_chksum.c                       |   174 +
 sr_port/rtn_src_chksum.h                       |    61 +
 sr_port/s2n.c                                  |    15 +-
 sr_port/s2pool_concat.c                        |    47 +
 sr_port/secshr_db_clnup.c                      |    38 +-
 sr_port/sorts_after.c                          |     4 +-
 sr_port/spec_type.h                            |    11 +-
 sr_port/stack_frame.h                          |     9 +
 sr_port/stp_gcol_ch.c                          |    12 +-
 sr_port/stp_gcol_src.h                         |     8 +-
 sr_port/str2gvkey_nogvfunc.c                   |    21 +-
 sr_port/stringpool.h                           |     4 +-
 sr_port/svnames.h                              |     4 +-
 sr_port/t_ch.c                                 |    34 +-
 sr_port/t_end.c                                |  1514 +-
 sr_port/tab_gvstats_rec.h                      |     2 +-
 sr_port/targ_alloc.c                           |    65 +-
 sr_port/tcp_open.c                             |    53 +-
 sr_port/tp.h                                   |     9 +-
 sr_port/tp_frame.h                             |    15 +-
 sr_port/tp_restart.c                           |    76 +-
 sr_port/tp_tend.c                              |    40 +-
 sr_port/trans_code.c                           |     4 +-
 sr_port/unw_mv_ent.c                           |    29 +-
 sr_port/updhelper_reader.c                     |    39 +-
 sr_port/updproc.c                              |    51 +-
 sr_port/updproc.h                              |    30 +-
 sr_port/updproc_get_gblname.c                  |    16 +-
 sr_port/updproc_get_gblname.h                  |     4 +-
 sr_port/updproc_init.c                         |    14 +-
 sr_port/updproc_open_files.c                   |    11 +-
 sr_port/util_base_ch.c                         |   108 +-
 sr_port/util_ch.c                              |    11 +-
 sr_port/view.h                                 |    14 +-
 sr_port/view_arg_convert.c                     |   192 +-
 sr_port/view_routines.c                        |   129 +-
 sr_port/viewtab.h                              |   188 +-
 sr_port/wbox_test_init.h                       |     8 +-
 sr_port/wcs_phase2_commit_wait.c               |    52 +-
 sr_port/wcs_recover.c                          |    52 +-
 sr_port/xfer.h                                 |     6 +-
 sr_port/zlput_rname.c                          |   266 +-
 sr_port/zshow.h                                |    11 +-
 sr_port/zshow_ch.c                             |     4 +-
 sr_port/zshow_output.c                         |    41 +-
 sr_port/zshow_stack.c                          |    31 +-
 sr_port/zshow_svn.c                            |    23 +-
 sr_port/zwrite.h                               |     4 +-
 sr_port_cm/gtcm_bind_name.c                    |    34 +-
 sr_port_cm/gtcmtr_order.c                      |    21 +-
 sr_port_cm/gtcmtr_query.c                      |    12 +-
 sr_port_cm/gvcmy_open.c                        |    23 +-
 sr_port_cm/gvcmy_open_ch.c                     |     6 +-
 sr_port_cm/gvcmz_netopen.c                     |    35 +-
 sr_unix/CMakeLists.txt                         |    90 +-
 sr_unix/Makefile.mk                            |   223 +
 sr_unix/bdelete.txt                            |    14 +-
 sr_unix/bin_load.c                             |   202 +-
 sr_unix/build.sh                               |   176 -
 sr_unix/buildaux.csh                           |   126 +-
 sr_unix/ch_overrun.c                           |    11 +-
 sr_unix/check_encrypt_support.sh               |     6 +-
 sr_unix/comlist.csh                            |    22 +-
 sr_unix/configure.gtc                          |    54 +-
 sr_unix/continue_proc.c                        |    16 +-
 sr_unix/daemon_ch.c                            |    17 -
 sr_unix/dbinit_ch.c                            |    16 +-
 sr_unix/dm_read.c                              |    23 +-
 sr_unix/dpgbldir_sysops.c                      |    31 +-
 sr_unix/dse.c                                  |    19 +-
 sr_unix/dse_cmd.c                              |    19 +-
 sr_unix/dsk_write_nocache.c                    |    18 +-
 sr_unix/dtgbldir.c                             |    78 +-
 sr_unix/errorsp.h                              |    18 +-
 sr_unix/f_piece.c                              |     6 +-
 sr_unix/file_input.c                           |    17 +-
 sr_unix/ftok_sems.c                            |    48 +-
 sr_unix/gbldirnam.h                            |     4 +-
 sr_unix/gdeget.m                               |   319 +-
 sr_unix/gdeoget.m                              |   436 -
 sr_unix/gdeput.m                               |   153 +-
 sr_unix/gdeverif.m                             |   103 +-
 sr_unix/gds_rundown.c                          |    31 +-
 sr_unix/gds_rundown_ch.c                       |     2 +-
 sr_unix/gdsfilext.c                            |    36 +-
 sr_unix/generic_signal_handler.c               |     4 +-
 sr_unix/get_command_line.c                     |     6 +-
 sr_unix/get_src_line.c                         |   130 +-
 sr_unix/getpass.m                              |    22 -
 sr_unix/gt_timer.h                             |     5 +-
 sr_unix/gt_timers.c                            |   182 +-
 sr_unix/gt_timers_add_safe_hndlrs.c            |     5 +-
 sr_unix/gtm_env_init_sp.c                      |    14 +-
 sr_unix/gtm_exit_handler.c                     |     4 +-
 sr_unix/gtm_fork_n_core.c                      |    23 +-
 sr_unix/gtm_icu.c                              |    30 +-
 sr_unix/gtm_ipc.h                              |     9 +-
 sr_unix/gtm_logicals.h                         |     5 +-
 sr_unix/gtm_main.c                             |   120 +-
 sr_unix/gtm_permissions.c                      |    74 +-
 sr_unix/gtm_permissions.h                      |     6 +-
 sr_unix/gtm_startup_chk.c                      |     6 +-
 sr_unix/gtm_test_install.csh                   |    32 +-
 sr_unix/gtm_test_install.txt                   |    44 +-
 sr_unix/gtm_tls.c                              |   159 +
 sr_unix/gtm_tls.h                              |    80 +
 sr_unix/gtm_tls_funclist.h                     |    30 +
 sr_unix/gtm_tls_impl.c                         |   869 +
 sr_unix/gtm_tls_impl.h                         |    55 +
 sr_unix/gtm_tls_interface.h                    |   285 +
 sr_unix/gtm_tls_loadlibrary.c                  |   124 +
 sr_unix/gtm_trigger.c                          |    69 +-
 sr_unix/gtm_unlink_all.c                       |    21 +-
 sr_unix/gtm_utf8.c                             |   162 +-
 sr_unix/gtm_utf8.h                             |    18 +-
 sr_unix/gtm_utf8_stx.c                         |    91 -
 sr_unix/gtmci.c                                |   247 +-
 sr_unix/gtmci.h                                |     9 +-
 sr_unix/gtmci_ch.c                             |     7 +-
 sr_unix/gtmcrypt.h                             |   195 +-
 sr_unix/gtmcrypt.tab                           |     1 -
 sr_unix/gtmcrypt_dbk_ref.c                     |   410 +-
 sr_unix/gtmcrypt_dbk_ref.h                     |    72 +-
 sr_unix/gtmcrypt_entry.c                       |   182 +-
 sr_unix/gtmcrypt_funclist.h                    |    23 +
 sr_unix/gtmcrypt_interface.h                   |    31 +-
 sr_unix/gtmcrypt_pk_ref.c                      |   263 +-
 sr_unix/gtmcrypt_pk_ref.h                      |    11 +-
 sr_unix/gtmcrypt_ref.c                         |   242 +-
 sr_unix/gtmcrypt_ref.h                         |   176 +-
 sr_unix/gtmcrypt_sym_ref.c                     |   140 +
 sr_unix/gtmcrypt_sym_ref.h                     |   152 +-
 sr_unix/gtmcrypt_util.c                        |   368 +
 sr_unix/gtmcrypt_util.h                        |   234 +
 sr_unix/gtmlink.c                              |    64 +
 sr_unix/gtmlink.h                              |    26 +
 sr_unix/gtmrecv_end.c                          |    19 +-
 sr_unix/gtmrecv_fetchresync.c                  |    15 +-
 sr_unix/gtmrecv_poll_actions.c                 |    20 +-
 sr_unix/gtmrecv_process.c                      |   245 +-
 sr_unix/gtmsecshr.c                            |    30 +-
 sr_unix/gtmsecshr.h                            |     3 +-
 sr_unix/gtmsecshr_sock_init.c                  |    69 +-
 sr_unix/gtmsource.c                            |    22 +-
 sr_unix/gtmsource.h                            |    20 +-
 sr_unix/gtmsource_end.c                        |    15 +-
 sr_unix/gtmsource_get_opt.c                    |    60 +-
 sr_unix/gtmsource_heartbeat.c                  |     8 +-
 sr_unix/gtmsource_process.c                    |   194 +-
 sr_unix/gtmsource_process_ops.c                |   138 +-
 sr_unix/gtmsource_shutdown.c                   |    13 +-
 sr_unix/gtmxc_types.h                          |    35 +-
 sr_unix/gv_trigger.c                           |    62 +-
 sr_unix/gv_trigger.h                           |    36 +-
 sr_unix/gvcst_init_sysops.c                    |    43 +-
 sr_unix/gvcst_spr_data.c                       |   143 +
 sr_unix/gvcst_spr_kill.c                       |   143 +
 sr_unix/gvcst_spr_order.c                      |   201 +
 sr_unix/gvcst_spr_query.c                      |   163 +
 sr_unix/gvcst_spr_queryget.c                   |   171 +
 sr_unix/gvcst_spr_zprevious.c                  |   197 +
 sr_unix/heartbeat_timer.c                      |    14 +-
 sr_unix/incr_link.c                            |    11 +-
 sr_unix/init_gtm.c                             |    30 +-
 sr_unix/install.sh                             |    89 -
 sr_unix/io_get_fgn_driver.c                    |     8 +-
 sr_unix/io_open_try.c                          |     7 +-
 sr_unix/iomt_ch.c                              |     7 +-
 sr_unix/iopi_iocontrol.c                       |     1 -
 sr_unix/iopi_open.c                            |     6 +-
 sr_unix/iorm_close.c                           |    68 +-
 sr_unix/iorm_get.c                             |   144 +-
 sr_unix/iorm_readfl.c                          |   338 +-
 sr_unix/iormdef.h                              |     9 +-
 sr_unix/iott_iocontrol.c                       |     1 -
 sr_unix/iott_rdone.c                           |    10 +-
 sr_unix/iott_readfl.c                          |    13 +-
 sr_unix/jnl_file_extend.c                      |     6 +-
 sr_unix/jnlpool_init.c                         |    18 +-
 sr_unix/jobchild_init.c                        |    21 +-
 sr_unix/joberr.h                               |     9 +
 sr_unix/jobexam_signal_handler.c               |    42 +-
 sr_unix/jobsp.h                                |    62 +-
 sr_unix/libdse.list                            |     1 +
 sr_unix/lke_ctrlc_handler.c                    |     4 +-
 sr_unix/lowerc_cp.sh                           |     4 +-
 sr_unix/map_sym.c                              |    23 +-
 sr_unix/maskpass.c                             |   250 +-
 sr_unix/mu_cre_file.c                          |    31 +-
 sr_unix/mu_extract.c                           |   132 +-
 sr_unix/mu_int_ch.c                            |     4 +-
 sr_unix/mu_op_open.c                           |    17 +-
 sr_unix/mu_rndwn_all.c                         |    88 +-
 sr_unix/mu_rndwn_all.h                         |    11 +-
 sr_unix/mu_rndwn_file.c                        |    34 +-
 sr_unix/mu_rndwn_repl_instance.c               |    66 +-
 sr_unix/mu_rndwn_replpool.c                    |     2 +-
 sr_unix/mu_size_arsample.c                     |    13 +-
 sr_unix/mu_size_impsample.c                    |    13 +-
 sr_unix/mu_size_scan.c                         |    14 +-
 sr_unix/mu_swap_root.c                         |    33 +-
 sr_unix/mu_truncate.c                          |     6 +-
 sr_unix/mubfilcpy.c                            |     6 +-
 sr_unix/mubinccpy.c                            |    40 +-
 sr_unix/mupip.c                                |    10 +-
 sr_unix/mupip_cmd.c                            |    61 +-
 sr_unix/mupip_cmd_disallow.c                   |    18 +-
 sr_unix/mupip_cvtgbl.c                         |     4 +-
 sr_unix/mupip_endiancvt.c                      |    55 +-
 sr_unix/mupip_exit_handler.c                   |     2 +-
 sr_unix/mupip_restore.c                        |    24 +-
 sr_unix/mupip_rundown.c                        |    24 +-
 sr_unix/mupip_size.c                           |    33 +-
 sr_unix/mupip_size.h                           |     8 +-
 sr_unix/mupip_trigger.c                        |     3 +-
 sr_unix/mutex.c                                |    45 +-
 sr_unix/obj_code.c                             |     5 +-
 sr_unix/obj_file.c                             |    22 +-
 sr_unix/ojchildioset.c                         |   220 +-
 sr_unix/ojchildparms.c                         |   324 +-
 sr_unix/ojparams.c                             |    61 +-
 sr_unix/ojstartchild.c                         |   440 +-
 sr_unix/op_fnfgncal.c                          |   351 +-
 sr_unix/op_fnzpeek.c                           |     6 +-
 sr_unix/op_fnzsearch.c                         |    12 +-
 sr_unix/op_job.c                               |    35 +-
 sr_unix/op_setextract.c                        |     6 +-
 sr_unix/op_setp1.c                             |     6 +-
 sr_unix/op_setpiece.c                          |     6 +-
 sr_unix/op_zhelp_xfr.c                         |    23 +-
 sr_unix/op_zlink.c                             |    99 +-
 sr_unix/pinentry.m                             |     9 +-
 sr_unix/repl_inst_dump.c                       |     9 +-
 sr_unix/repl_instance.c                        |    62 +-
 sr_unix/repl_instance.h                        |    30 +-
 sr_unix/repl_ipc_cleanup.c                     |     2 +-
 sr_unix/repl_msg.h                             |    18 +-
 sr_unix/rtnhdr.h                               |    10 +-
 sr_unix/runall.csh                             |     5 +-
 sr_unix/secshr_client.c                        |    23 +-
 sr_unix/sleep.h                                |     2 +-
 sr_unix/source_file.c                          |    13 +-
 sr_unix/ss_initiate.c                          |    61 +-
 sr_unix/trigger.h                              |   341 +-
 sr_unix/trigger_compare.c                      |    20 +-
 sr_unix/trigger_delete.c                       |    87 +-
 sr_unix/trigger_fill_xecute_buffer.c           |    50 +-
 sr_unix/trigger_gbl_fill_xecute_buffer.c       |     2 +-
 sr_unix/trigger_read_name_entry.c              |    15 +-
 sr_unix/trigger_select.c                       |    73 +-
 sr_unix/trigger_source_read_andor_verify.c     |    50 +-
 sr_unix/trigger_tpwrap_ch.c                    |     4 +-
 sr_unix/trigger_trgfile.c                      |    10 +-
 sr_unix/trigger_update.c                       |   106 +-
 sr_unix/ttt.txt                                |    16 +-
 sr_unix/util_exit_handler.c                    |     6 +-
 sr_unix/versions.csh                           |     2 +-
 sr_unix/wait_for_disk_space.c                  |     5 +-
 sr_unix/wcs_flu.c                              |    18 +-
 sr_unix/wcs_wtstart.c                          |    61 +-
 sr_unix/zshow_devices.c                        |    43 +-
 sr_unix_cm/gtcm_loop.c                         |     2 +
 sr_unix_cm/omi_dbms_ch.c                       |     9 +-
 sr_unix_cm/omi_gvextnam.c                      |    21 +-
 sr_unix_cm/omi_prc_ordr.c                      |    18 +-
 sr_unix_cm/rc_dbms_ch.c                        |     9 +-
 sr_unix_cm/rc_fnd_file.c                       |    72 +-
 sr_unix_cm/rc_gbl_ord.c                        |    20 +-
 sr_unix_cm/rc_mval2subsc.c                     |    18 +-
 sr_unix_cm/rc_prc_getr.c                       |    32 +-
 sr_unix_cm/rc_prc_kill.c                       |    48 +-
 sr_unix_cm/rc_prc_set.c                        |    34 +-
 sr_unix_cm/rc_prc_setf.c                       |    10 +-
 sr_unix_gnp/cmi_close.c                        |     3 +-
 sr_unix_gnp/cmi_init.c                         |     1 +
 sr_unix_gnp/cmi_open.c                         |     5 +-
 sr_unix_gnp/cmi_peer_info.c                    |     1 -
 sr_unix_gnp/cmj_clb_async.c                    |     3 +-
 sr_unix_gnp/cmj_err.c                          |     3 +-
 sr_unix_gnp/cmj_firstone.c                     |     3 +-
 sr_unix_gnp/cmj_incoming_call.c                |     1 +
 sr_unix_gnp/cmu_getclb.c                       |     1 -
 sr_unix_gnp/gtcm_ch.c                          |     6 +-
 sr_unix_nsb/obj_code.c                         |     7 +-
 sr_unix_nsb/opcode_def.h                       |     2 +-
 sr_unix_nsb/rtnhdr.h                           |     7 +
 sr_unix_nsb/ttt.txt                            |    16 +-
 sr_vms_cm/gtcm_server.c                        |    20 +-
 sr_vvms/bin_load.c                             |    88 +-
 sr_vvms/buildaux.com                           |    35 +-
 sr_vvms/ccp_exi_ch.c                           |     4 +-
 sr_vvms/cli.c                                  |    36 +-
 sr_vvms/dbinit_ch.c                            |     2 +-
 sr_vvms/do_zcall.c                             |    50 +-
 sr_vvms/dpgbldir_sysops.c                      |    23 +-
 sr_vvms/dse.c                                  |    35 +-
 sr_vvms/dtgbldir.c                             |    45 +-
 sr_vvms/errorsp.h                              |     2 +-
 sr_vvms/exi_ch.c                               |     2 +-
 sr_vvms/fgncal_ch.c                            |     4 +-
 sr_vvms/gbldirnam.h                            |     4 +-
 sr_vvms/gdeget.m                               |   355 +-
 sr_vvms/gdeoget.m                              |   436 -
 sr_vvms/gdeput.m                               |   115 +-
 sr_vvms/gdeverif.m                             |    85 +-
 sr_vvms/gds_rundown.c                          |    31 +-
 sr_vvms/generic_exit_handler.c                 |     4 -
 sr_vvms/get_src_line.c                         |   121 +-
 sr_vvms/goq_m11_load.c                         |    58 +-
 sr_vvms/goq_mvx_load.c                         |    90 +-
 sr_vvms/gt_timer.h                             |     7 +-
 sr_vvms/gtm_env_translate.c                    |    14 +-
 sr_vvms/gtm_logicals.h                         |     3 +
 sr_vvms/gtmrecv_fetchresync.c                  |     3 +-
 sr_vvms/gtmrecv_process.c                      |     8 +-
 sr_vvms/gtmsource_heartbeat.c                  |    13 +-
 sr_vvms/gtmsource_process.c                    |     8 +-
 sr_vvms/io_open_try.c                          |     7 +-
 sr_vvms/iotcp_select.h                         |    49 -
 sr_vvms/iotcp_string.c                         |   107 -
 sr_vvms/jnl_file_extend.c                      |    47 +-
 sr_vvms/jnlpool_init.c                         |     2 +-
 sr_vvms/map_sym.c                              |    14 +-
 sr_vvms/mu_extract.c                           |    76 +-
 sr_vvms/mubinccpy.c                            |    60 +-
 sr_vvms/mupip.c                                |     8 +-
 sr_vvms/mupip_restore.c                        |    40 +-
 sr_vvms/mupip_rundown.c                        |    36 +-
 sr_vvms/obj_code.c                             |     7 +-
 sr_vvms/op_fnzfile.c                           |    55 +-
 sr_vvms/op_setzp1.c                            |     6 +-
 sr_vvms/rtnhdr.h                               |     3 +
 sr_vvms/ttt.c                                  |  1358 +-
 sr_vvms/ttt.txt                                |    18 +-
 sr_vvms/zro_load.c                             |    96 +-
 sr_vvms/zshow_devices.c                        |     3 +-
 sr_x86_64/gdeerrors_ctl.c                      |    64 +-
 sr_x86_64/merrors_ansi.h                       |    35 +-
 sr_x86_64/merrors_ctl.c                        |    82 +-
 sr_x86_64/ttt.c                                |   774 +-
 647 files changed, 39252 insertions(+), 31430 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b200284..6512d64 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,7 +26,7 @@ foreach(lang ${languages})
 endforeach()
 
 # Defaults
-set(version V6.0-003)
+set(version V6.1-000)
 if("${version}" STREQUAL "")
         set(version V9.9-0)
 endif()
@@ -57,7 +57,8 @@ set(gtm_osarch_libs "")
 set(gt_src_list)
 set(sources_used "")
 set(extralibs "")
-set(is_encryption_supported 1)
+# Disable encryption for the time being. Need to change this to invoke the gtmcrypt Makefile AS 2013.12.18
+set(is_encryption_supported 0)
 set(libmumpsrestoreregex "")
 message("--> OS = ${CMAKE_SYSTEM_NAME} / ARCH = ${CMAKE_SYSTEM_PROCESSOR}")
 # Establish platform
@@ -220,10 +221,12 @@ set_source_list(gtcm_server      gtcm_main omi_srvc_xct)
 set_source_list(gtcm_shmclean    gtcm_shmclean)
 set_source_list(gtmsecshr        gtmsecshr_wrapper)
 set_source_list(gtmsecshr_real   gtmsecshr)
-set_source_list(libgtmcrypt      gtmcrypt_ref gtmcrypt_pk_ref gtmcrypt_dbk_ref)
+set_source_list(libgtmcrypt      gtmcrypt_ref gtmcrypt_pk_ref gtmcrypt_dbk_ref gtmcrypt_sym_ref)
+set_source_list(libgtmtls        gtm_tls_impl)
+set_source_list(libgtmcryptutil  gtmcrypt_util)
 set_source_list(libgtmshr        gtm_main)
 set_source_list(lke              lke lke_cmd)
-set_source_list(maskpass         maskpass)
+set_source_list(maskpass         maskpass gtmcrypt_util)
 set_source_list(mumps            gtm)
 set_source_list(mupip            mupip mupip_cmd)
 set_source_list(semstat2         semstat2)
@@ -472,6 +475,14 @@ if(is_encryption_supported)
     set(GPG_LIBRARIES ${GPG_LIBRARIES} ${GPGLIB_${gpglib}})
   endforeach()
 
+  # Iterate over the list of SSL related libraries
+  foreach(ssl)
+    # For each library, we need a new CMake variable, hence TLSLIB_${tlslib}
+    find_library(TLSLIB_${tlslib} NAME ${tlslib} PATHS ${CMAKE_LIBRARY_PATH})
+    # Append the found library to the list
+    set(TLS_LIBRARIES ${TLS_LIBRARIES} ${TLSLIB_${tlslib}})
+  endforeach()
+
   add_library(libgtmcrypt MODULE ${libgtmcrypt_SOURCES})
   set_target_properties(libgtmcrypt PROPERTIES
     OUTPUT_NAME gtmcrypt
@@ -481,57 +492,76 @@ if(is_encryption_supported)
   target_link_libraries(libgtmcrypt ${GPG_LIBRARIES})
   install(TARGETS libgtmcrypt DESTINATION ${GTM_INSTALL_DIR}/plugin)
 
+  add_library(libgtmtls MODULE ${libgtmtls_SOURCES})
+  set_target_properties(libgtmtls PROPERTIES
+    OUTPUT_NAME gtmtls
+    LIBRARY_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin
+    )
+  target_link_libraries(libgtmtls ${TLS_LIBRARIES})
+  install(TARGETS libgtmtls DESTINATION ${GTM_INSTALL_DIR}/plugin)
+
+  add_library(libgtmcryptutil MODULE ${libgtmcryptutil_SOURCES})
+  set_target_properties(libgtmcryptutil PROPERTIES
+    OUTPUT_NAME gtmcryptutil
+    COMPILE_DEFINITIONS "USE_GCRYPT -DUSE_AES256CFB"
+    LIBRARY_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin
+    )
+  target_link_libraries(libgtmcryptutil ${GPG_LIBRARIES})
+  install(TARGETS libgtmcryptutil DESTINATION ${GTM_INSTALL_DIR}/plugin)
+
   add_executable(maskpass ${maskpass_SOURCES})
   target_link_libraries(maskpass ${GPG_LIBRARIES})
   set_target_properties(maskpass PROPERTIES
-    COMPILE_DEFINITIONS USE_GCRYPT
+    COMPILE_DEFINITIONS "USE_GCRYPT -DUSE_SYSLIB_FUNCS"
     RUNTIME_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin/gtmcrypt
     )
   install(TARGETS maskpass DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt)
+endif()
 
-  foreach(f
+# Always copy files into the plugin directory
+foreach(f
+      Makefile.mk
       add_db_key.sh
-      build.sh
       encrypt_sign_db_key.sh
       gen_keypair.sh
       gen_sym_hash.sh
       gen_sym_key.sh
-      gtmcrypt.tab
+      gtm_tls_impl.c
+      gtm_tls_impl.h
+      gtm_tls_interface.h
       gtmcrypt_dbk_ref.c
       gtmcrypt_dbk_ref.h
       gtmcrypt_interface.h
       gtmcrypt_pk_ref.c
       gtmcrypt_pk_ref.h
-      gtmcrypt_dbk_ref.c
-      gtmcrypt_dbk_ref.h
       gtmcrypt_ref.c
       gtmcrypt_ref.h
+      gtmcrypt_sym_ref.c
       gtmcrypt_sym_ref.h
-      gtmxc_types.h
+      gtmcrypt_util.c
+      gtmcrypt_util.h
       import_and_sign_key.sh
-      install.sh
       maskpass.c
       pinentry-gtm.sh
       pinentry.m
-      pinentry.m
       show_install_config.sh
-      )
-    set(f_in "${GTM_SOURCE_DIR}/sr_unix/${f}")
-    set(f_out "${GTM_BINARY_DIR}/plugin/gtmcrypt/${f}")
-    add_custom_command(
-      OUTPUT "${f_out}"
-      DEPENDS "${f_in}"
-      COMMAND ${CMAKE_COMMAND} -E copy "${f_in}" "${f_out}"
-      )
-    if("${f}" MATCHES "\\.sh$")
-      set(permissions PERMISSIONS ${install_permissions_script})
-    else()
-      set(permissions "")
-    endif()
-    install(FILES "${f_out}" DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt ${permissions})
-    list(APPEND files_to_place "${f_out}")
-  endforeach()
-endif()
+    )
+  set(f_in "${GTM_SOURCE_DIR}/sr_unix/${f}")
+  string(REGEX REPLACE ".mk$" "" f_mod "${f}")
+  set(f_out "${GTM_BINARY_DIR}/plugin/gtmcrypt/${f_mod}")
+  add_custom_command(
+    OUTPUT "${f_out}"
+    DEPENDS "${f_in}"
+    COMMAND ${CMAKE_COMMAND} -E copy "${f_in}" "${f_out}"
+    )
+  if("${f}" MATCHES "\\.sh$")
+    set(permissions PERMISSIONS ${install_permissions_script})
+  else()
+    set(permissions "")
+  endif()
+  install(FILES "${f_out}" DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt ${permissions})
+  list(APPEND files_to_place "${f_out}")
+endforeach()
 
 install(TARGETS
   mumps
@@ -623,6 +653,7 @@ endforeach()
 
 set(files)
 foreach(f
+  gtm_common_defs.h
   gtm_descript.h
   gtm_limits.h
   gtm_sizeof.h
@@ -759,6 +790,7 @@ Halt")
     )
   list(APPEND files_to_place ${help}help.dat)
   install(FILES ${GTM_BINARY_DIR}/${help}help.dat DESTINATION ${GTM_INSTALL_DIR})
+  install(FILES ${GTM_BINARY_DIR}/${help}help.gld DESTINATION ${GTM_INSTALL_DIR})
 endforeach()
 #-----------------------------------------------------------------------------
 
diff --git a/README b/README
index c7a9d51..5fdb02d 100644
--- a/README
+++ b/README
@@ -31,11 +31,11 @@ To build GT.M for Linux, do the following steps:
    from http://sourceforge.net/projects/fis-gtm/ Unpack the tar file and run
    the configure script as root. Note: the tar file unpacks everything into
    your current working directory, not a new subdirectory. The Linux Standard
-   Base (LSB) install path for GT.M V6.0-003 is /opt/fis-gtm/V6.0-003_i686 or
-   /opt/fis-gtm/V6.0-003_x8664. These instrcutions are written using x8664, please
+   Base (LSB) install path for GT.M V6.1-000 is /opt/fis-gtm/V6.1-000_i686 or
+   /opt/fis-gtm/V6.1-000_x8664. These instrcutions are written using x8664, please
    use i686 as necessary.
 
-   $ tar xfz gtm_V60003_linux_x8664_pro.tar.gz
+   $ tar xfz gtm_V61000_linux_x8664_pro.tar.gz
 
    # Note down the installation path for use with cmake below
 
@@ -43,16 +43,16 @@ To build GT.M for Linux, do the following steps:
 
 2. Unpack the GT.M sources
    The GT.M source tarball extracts to a directory with the version number in
-   the name, fis-gtm-V6.0-003
-   $ tar xfz fis-gtm-V6.0-003.tar.gz
-   $ cd fis-gtm-V6.0-003
+   the name, fis-gtm-V6.1-000
+   $ tar xfz fis-gtm-V6.1-000.tar.gz
+   $ cd fis-gtm-V6.1-000
 
    You should find this README, LICENSE, COPYING and CMakeLists.txt file and
    sr_* source directories.
 
 3. Building GT.M -
    <fis-gtm-build> can be a sub directory of the source directory,
-   fis-gtm-V6.0-003, or any other valid path.
+   fis-gtm-V6.1-000, or any other valid path.
 
    $ mkdir <fis-gtm-build>
    $ cd <fis-gtm-build>
@@ -71,16 +71,16 @@ To build GT.M for Linux, do the following steps:
    #
    #     -D CMAKE_INSTALL_PREFIX:PATH=${PWD}/package
    #
-   $ cmake <path to>/fis-gtm-V6.0-003 -D CMAKE_INSTALL_PREFIX:PATH=${PWD}/package
+   $ cmake <path to>/fis-gtm-V6.1-000 -D CMAKE_INSTALL_PREFIX:PATH=${PWD}/package
 
    $ make
 
    $ make install
 
-   $ cd package/lib/fis-gtm/V6.0-003_x86_64
+   $ cd package/lib/fis-gtm/V6.1-000_x86_64
 
    # Now you are ready to install GT.M. Answer a few questions and install it.
-   # The recommended installation path is /opt/fis-gtm/V6.0-003_x86_64
+   # The recommended installation path is /opt/fis-gtm/V6.1-000_x86_64
 
    $ sudo ./configure
 
diff --git a/sr_avms/release_name.h b/sr_avms/release_name.h
index 32baa09..150f221 100644
--- a/sr_avms/release_name.h
+++ b/sr_avms/release_name.h
@@ -9,6 +9,6 @@
  *								*
  ****************************************************************/
 
-#define GTM_RELEASE_NAME	"GT.M V6.0-003 VMS AXP"
+#define GTM_RELEASE_NAME	"GT.M V6.1-000 VMS AXP"
 #define GTM_PRODUCT		"GT.M"
-#define GTM_VERSION		"V6.0"
+#define GTM_VERSION		"V6.1"
diff --git a/sr_i386/emit_code.c b/sr_i386/emit_code.c
index 66256ce..aade6e1 100644
--- a/sr_i386/emit_code.c
+++ b/sr_i386/emit_code.c
@@ -149,13 +149,13 @@ void trip_gen(triple *ct)
 		case OC_CALL:
 		case OC_FORLCLDO:
 		case OC_CALLSP:
-/*  Changes to emit_xfer, emit_base_offset, or emit_jmp may require changes
-	here since we try to predict how big the call into the xfer_table
-	and the following jump will be.
-	There is also an assumption that both the word and long variants
-	of the opcode will be followed by a jmp with 32 bit offset while
-	the -BYTE variants will be followed by a BRB with an 8 bit offset.
-*/
+			/* Changes to emit_xfer, emit_base_offset, or emit_jmp may require changes
+			 * here since we try to predict how big the call into the xfer_table
+			 * and the following jump will be.
+			 * There is also an assumption that both the word and long variants
+			 * of the opcode will be followed by a jmp with 32 bit offset while
+			 * the -BYTE variants will be followed by a BRB with an 8 bit offset.
+			*/
 			tsp = (short *)&ttt[ttt[tp]];
 			if (-128 <= tsp[CALL_4LCLDO_XFER] && 127 >= tsp[CALL_4LCLDO_XFER])
 				off = jmp_offset - XFER_BYTE_INST_SIZE;
@@ -190,7 +190,7 @@ void trip_gen(triple *ct)
 			tsp = (short *)&ttt[ttt[tp]];
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && ct->opcode);
 			break;
 		}
 	}
@@ -208,7 +208,7 @@ void trip_gen(triple *ct)
 			tp = ttt[tp + 4];
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && (oc_tab[ct->operand[0].oprval.tref->opcode].octype & (OCT_VALUE | OCT_BOOL)));
 			break;
 		}
 		tsp = (short *)&ttt[tp];
@@ -226,7 +226,7 @@ void trip_gen(triple *ct)
 			assert(repcnt != 1);
 			for (irep_index = repcnt, irep_opr = &ct->operand[1]; irep_index > 2; --irep_index)
 			{
-				assert (irep_opr->oprclass == TRIP_REF);
+				assert(irep_opr->oprclass == TRIP_REF);
 				irep_opr = &irep_opr->oprval.tref->operand[1];
 			}
 
@@ -285,7 +285,7 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 				break;
 			case VXI_BLBC:
 			case VXI_BLBS:
-				assert (*inst == VXT_REG);
+				assert(VXT_REG == *inst);
 				inst++;
 				inst++;
 				emit_xfer(4*xf_dt_get);
@@ -296,40 +296,39 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 					emit_jmp(VXI_BEQL, &inst);
 				else
 				{
-					assert (sav_in == VXI_BLBS);
+					assert(sav_in == VXI_BLBS);
 					emit_jmp(VXI_BNEQ, &inst);
 				}
 				break;
 			case VXI_BICB2:
 			case VXI_BISB2:
-				assert (*inst == VXT_LIT);
+				assert(VXT_LIT == *inst);
 				inst++;
-				assert (*inst == 1);
+				assert(1 == *inst);
 				inst++;
-				assert (*inst == VXT_REG);
+				assert(VXT_REG == *inst);
 				inst++;
 				inst++;
 				if (sav_in == VXI_BICB2)
 					emit_xfer(4*xf_dt_false);
 				else
 				{
-					assert (sav_in == VXI_BISB2);
+					assert(sav_in == VXI_BISB2);
 					emit_xfer(4*xf_dt_true);
 				}
 				break;
 			case VXI_CALLS:
 				oc_int = TRUE;
-				if (*inst == VXT_LIT)
+				if (VXT_LIT == *inst)
 				{
 					inst++;
 					cnt = (int4) *inst++;
-				}
-				else
+				} else
 				{
-					assert(*inst == VXT_VAL);
+					assert(VXT_VAL == *inst);
 					inst++;
 					opr = *(fst_opr + *inst);
-					assert (opr->oprclass == TRIP_REF);
+					assert(opr->oprclass == TRIP_REF);
 					ct = opr->oprval.tref;
 					if (ct->destination.oprclass)
 					{
@@ -361,7 +360,7 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						emit_trip(PUSH, opr, TRUE, 0);
 					}
 				}
-				assert (*inst == VXT_XFER);
+				assert(VXT_XFER == *inst);
 				inst++;
 				emit_xfer(*inst++);
 				if (oc_int)
@@ -381,25 +380,25 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 				}
 				break;
 			case VXI_CLRL:
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				emit_trip(CLEAR, *(fst_opr + *inst++), TRUE, 0);
 				break;
 			case VXI_CMPL:
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				emit_trip(LOAD, *(fst_opr + *inst++), TRUE, I386_REG_EDX);
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				emit_trip(COMPARE, *(fst_opr + *inst++), TRUE, I386_REG_EDX);
 				break;
 			case VXI_INCL:
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				emit_trip(INCREMENT, *(fst_opr + *inst++), TRUE, 0);
 				break;
 			case VXI_JMP:
-				if (*inst == VXT_VAL)
+				if (VXT_VAL == *inst)
 				{
 					inst++;
 					emit_trip(JUMP, *(fst_opr + *inst++), FALSE, 0);
@@ -410,47 +409,45 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 				}
 				break;
 			case VXI_JSB:
-				assert (*inst == VXT_XFER);
+				assert(VXT_XFER == *inst);
 				inst++;
 				emit_xfer(*inst++);
 				break;
 			case VXI_MOVAB:
-				if (*inst == VXT_JMP)
+				if (VXT_JMP == *inst)
 				{
 					inst += 2;
 					emit_pcrel(LOAD_ADDRESS, I386_REG_EAX);
-					assert (*inst == VXT_ADDR);
+					assert(VXT_ADDR == *inst);
 					inst++;
 					emit_trip(STORE, *(fst_opr + *inst++), FALSE, I386_REG_EAX);
-				}
-				else if (*inst == VXT_ADDR || *inst == VXT_VAL)
+				} else if ((VXT_ADDR == *inst) || (VXT_VAL == *inst))
 				{
 					bool	addr;
 					unsigned char reg;
 					short	save_inst;
 
-					addr = (*inst == VXT_VAL);
+					addr = (VXT_VAL == *inst);
 					inst++;
 					save_inst = *inst++;
-					assert (*inst == VXT_REG);
+					assert(VXT_REG == *inst);
 					inst++;
 					reg = ((*inst++ & 0x01) ? I386_REG_EDX : I386_REG_EAX); /* r0 and r1 are only ones used */
 					emit_trip(LOAD_ADDRESS, *(fst_opr + save_inst), addr, reg);
-				}
-				else
-					GTMASSERT;
+				} else
+					assertpro(FALSE && *inst);
 				break;
 			case VXI_MOVC3:
-				assert (*inst == VXT_LIT);
+				assert(VXT_LIT == *inst);
 				inst += 2;
-				assert(*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				code_buf[code_idx++] = I386_INS_PUSH_eSI;
 				code_buf[code_idx++] = I386_INS_PUSH_eDI;
 
 				emit_trip(LOAD_ADDRESS, *(fst_opr + *inst++), TRUE, I386_REG_ECX);
 
-				assert(*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst++;
 				emit_trip(LOAD_ADDRESS, *(fst_opr + *inst++), TRUE, I386_REG_EDI);
 
@@ -471,32 +468,31 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 				code_buf[code_idx++] = I386_INS_POP_eSI;
 				break;
 			case VXI_MOVL:
-				if (*inst == VXT_REG)
+				if (VXT_REG == *inst)
 				{
 					inst++;
 					if (*inst > 0x5f)	/* OC_CURRHD */  /* any mode >= 6 (deferred), any register */
 					{
 						inst++;
-						assert (*inst == VXT_ADDR);
+						assert(VXT_ADDR == *inst);
 						inst++;
 
 						emit_xfer(4*xf_get_msf);
 						emit_op_base_offset(LOAD, I386_REG_EAX, 0, I386_REG_EAX);
 						emit_trip(STORE, *(fst_opr + *inst++), FALSE, I386_REG_EAX);
-					}
-					else
+					} else
 					{
 						bool addr;
 
-						assert (*inst == 0x50);  /* register mode: R0 */
+						assert(0x50 == *inst);  /* register mode: R0 */
 						inst++;
-						if (*inst == VXT_VAL || *inst == VXT_ADDR)
+						if ((VXT_VAL == *inst) || (VXT_ADDR == *inst))
 						{
-							addr = (*inst == VXT_VAL);
+							addr = (VXT_VAL == *inst);
 							inst++;
 							emit_trip(STORE, *(fst_opr + *inst++), addr, I386_REG_EAX);
 						}
-						else if (*inst == VXT_REG)
+						else if (VXT_REG == *inst)
 						{
 							unsigned char	reg;
 
@@ -516,49 +512,44 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 								code_buf[code_idx++] = modrm_byte.byte;
 							}
 							inst++;
-						}
-						else
-							GTMASSERT;
+						} else
+							assertpro(FALSE && *inst);
 					}
-				}
-				else if (*inst == VXT_VAL)
+				} else if (VXT_VAL == *inst)
 				{
 					inst++;
 					emit_trip(LOAD, *(fst_opr + *inst++), TRUE, I386_REG_EDX);
-					assert (*inst == VXT_REG);
+					assert(VXT_REG == *inst);
 					inst++;
-					assert (*inst == 0x51);  /* register mode: R1 */
+					assert(0x51 == *inst);  /* register mode: R1 */
 					inst++;
-				}
-				else
-					GTMASSERT;
+				} else
+					assertpro(FALSE && *inst);
 				break;
 			case VXT_IREPAB:
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst += 2;
 				emit_trip(PUSH_ADDRESS, *lst_opr, TRUE, 0);
 				break;
 			case VXI_PUSHAB:
-				if (*inst == VXT_JMP)
+				if (VXT_JMP == *inst)
 				{
 					inst += 2;
 					emit_pcrel(PUSH_ADDRESS, 0);
-				}
-				else if (*inst == VXT_VAL)
+				} else if (VXT_VAL == *inst)
 				{
 					inst++;
 					emit_trip(PUSH_ADDRESS, *(fst_opr + *inst++), TRUE, 0);
-				}
-				else
-					GTMASSERT;
+				} else
+					assertpro(FALSE && *inst);
 				break;
 			case VXT_IREPL:
-				assert (*inst == VXT_VAL);
+				assert(VXT_VAL == *inst);
 				inst += 2;
 				emit_trip(PUSH, *lst_opr, TRUE, 0);
 				break;
 			case VXI_PUSHL:
-				if (*inst == VXT_LIT)
+				if (VXT_LIT == *inst)
 				{
 					int4	lit;
 
@@ -575,22 +566,19 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						*((int4 *)&code_buf[code_idx]) = lit;
 						code_idx += SIZEOF(int4);
 					}
-				}
-				else if (*inst == VXT_ADDR)
+				} else if (VXT_ADDR == *inst)
 				{
 					inst++;
 					emit_trip(PUSH, *(fst_opr + *inst++), FALSE, 0);
-				}
-				else if (*inst == VXT_VAL)
+				} else if (VXT_VAL == *inst)
 				{
 					inst++;
 					emit_trip(PUSH, *(fst_opr + *inst++), TRUE, 0);
-				}
-				else
-					GTMASSERT;
+				} else
+					assertpro(FALSE && *inst);
 				break;
 			case VXI_TSTL:
-				if (*inst == VXT_VAL)
+				if (VXT_VAL == *inst)
 				{
 				  inst++;
 				  emit_trip(TEST, *(fst_opr + *inst++), TRUE, 0);
@@ -603,19 +591,18 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 				    inst++;
 				    *((int4 *)&code_buf[code_idx]) = 0;	/* 32 bit immediate 0 */
 				    code_idx += SIZEOF(int4);
-				}
-				else
-				  GTMASSERT;
+				} else
+					assertpro(FALSE && *inst);
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && sav_in);
 		}
 		break;
 	default:
-		GTMASSERT;
+		assertpro(FALSE && cg_phase);
 		break;
 	}
-	assert (code_idx < BUFFERED_CODE_SIZE);
+	assert(code_idx < BUFFERED_CODE_SIZE);
 	if (cg_phase == CGP_MACHINE)
 	{
          	generated_code_size += code_idx;
@@ -639,18 +626,18 @@ short *emit_vax_inst(short *inst, oprtype **fst_opr, oprtype **lst_opr)
 void emit_jmp(short vax_in, short **instp)
 {
 
-	assert (jmp_offset != 0);
+	assert(jmp_offset != 0);
 	jmp_offset -= code_idx * SIZEOF(code_buf[0]);	/* size of this particular instruction */
 
-	assert (**instp == VXT_JMP);
+	assert(**instp == VXT_JMP);
 	*instp += 1;
-	assert (**instp == 1);
+	assert(**instp == 1);
 	*instp += 1;
 	if (jmp_offset == 0)
 	{
 		code_buf[code_idx++] = I386_INS_NOP__;
 	}
-	else if ((jmp_offset - 2) >= -128  &&  (jmp_offset - 2) <= 127 &&
+	else if ((jmp_offset - 2) >= -128  && (jmp_offset - 2) <= 127 &&
 			JMP_LONG_INST_SIZE != call_4lcldo_variant)
 	{
 		jmp_offset -= 2;
@@ -681,7 +668,7 @@ void emit_jmp(short vax_in, short **instp)
 			code_buf[code_idx++] = I386_INS_JMP_Jb;
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && vax_in);
 			break;
 		}
 		code_buf[code_idx++] = jmp_offset & 0xff;
@@ -719,7 +706,7 @@ void emit_jmp(short vax_in, short **instp)
 				code_buf[code_idx++] = I386_INS_JNZ_Jv;
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && vax_in);
 				break;
 			}
 		}
@@ -836,7 +823,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 				}
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && ct->opcode);
 				break;
 			}
 			break;
@@ -845,8 +832,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 			assert(val_output);
 			offset = sa_temps_offset[opr->oprclass];
 			offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass];
-			if (offset < 0  &&  offset > 65535)
-				GTMASSERT;
+			assertpro((0 <= offset) && (65535 >= offset));
 			emit_op_base_offset(op, I386_REG_EDI, offset, use_reg);
 			break;
 		case TCAD_REF:
@@ -854,9 +840,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 		case TVAR_REF:
 			offset = sa_temps_offset[opr->oprclass];
 			offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass];
-			if (offset < 0  &&  offset > 65535)
-				GTMASSERT;
-
+			assertpro((0 <= offset) && (65535 >= offset));
 			if (opr->oprclass == TVAR_REF)
 				base_reg = I386_REG_ESI;
 			else
@@ -1036,7 +1020,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 				}
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && ct->opcode);
 				break;
 			}
 			break;
@@ -1045,8 +1029,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 			assert(val_output);
 			offset = sa_temps_offset[opr->oprclass];
 			offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass];
-			if (offset < 0  &&  offset > 65535)
-				GTMASSERT;
+			assertpro((0 <= offset) && (65535 >= offset));
 			emit_op_base_offset(op, I386_REG_EDI, offset, use_reg);
 			break;
 		case TCAD_REF:
@@ -1054,8 +1037,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 		case TVAR_REF:
 			offset = sa_temps_offset[opr->oprclass];
 			offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass];
-			if (offset < 0  &&  offset > 65535)
-				GTMASSERT;
+			assertpro((0 <= offset) && (65535 >= offset));
 			if (opr->oprclass == TVAR_REF)
 				base_reg = I386_REG_ESI;
 			else
@@ -1064,7 +1046,7 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 			switch (op)
 			{
 			case JUMP:
-				assert (use_reg == 0);
+				assert(use_reg == 0);
 				if (val_output)
 				{
 					code_buf[code_idx++] = I386_INS_MOV_Gv_Ev;
@@ -1150,12 +1132,12 @@ void emit_trip(generic_op op, oprtype *opr, bool val_output, unsigned char use_r
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && opr->oprclass);
 			break;
 		}
 		break;
 	default:
-		GTMASSERT;
+		assertpro(FALSE && cg_phase);
 		break;
 	}
 }
@@ -1295,13 +1277,23 @@ unsigned char i386_reg(unsigned char vax_reg)
 
 	switch (vax_reg & 0xf)	/* mask out VAX register mode field */
 	{
-	case 0:		reg = I386_REG_EAX;	break;
-	case 1:		reg = I386_REG_EDX;	break;
-	case 8:		reg = I386_REG_ESI;	break;
-	case 9:		reg = I386_REG_EDI;	break;
-	case 11:	reg = I386_REG_EBX;	break;
+	case 0:
+		reg = I386_REG_EAX;
+		break;
+	case 1:
+		reg = I386_REG_EDX;
+		break;
+	case 8:
+		reg = I386_REG_ESI;
+		break;
+	case 9:
+		reg = I386_REG_EDI;
+		break;
+	case 11:
+		reg = I386_REG_EBX;
+		break;
 	default:
-		GTMASSERT;
+		assertpro(FALSE && (vax_reg & 0xf));
 		break;
 	}
 
diff --git a/sr_i386/gdeerrors_ctl.c b/sr_i386/gdeerrors_ctl.c
index 90dc1b3..07cc7be 100644
--- a/sr_i386/gdeerrors_ctl.c
+++ b/sr_i386/gdeerrors_ctl.c
@@ -26,14 +26,14 @@ LITDEF	err_msg gdeerrors[] = {
 	"KEYTOOBIG", "But record size !AD can only support key size !AD", 4,
 	"KEYSIZIS", "Key size is !AD", 2,
 	"KEYWRDAMB", "!AD is ambiguous for !AD", 4,
-	"KEYWRDBAD", "!AD is not a valid !AD", 4,
+	"KEYWRDBAD", "!AD is not a valid !AD in this context", 4,
 	"LOADGD", "Loading Global Directory file !/	!AD", 2,
 	"LOGOFF", "No longer logging to file !AD", 2,
 	"LOGON", "Logging to file !AD", 2,
 	"LVSTARALON", "The * name cannot be deleted or renamed", 0,
 	"MAPBAD", "!AD !AD for !AD !AD does not exist", 8,
 	"MAPDUP", "!AD !AD and !AD both map to !AD !AD", 10,
-	"NAMSTARTBAD", "!AD must start with '%' or an alphabetic character", 2,
+	"NAMENDBAD", "Subscripted name !AD must end with right parenthesis", 2,
 	"NOACTION", "Not updating Global Directory !AD", 2,
 	"RPAREN", "List must end with right parenthesis or continue with comma", 0,
 	"NOEXIT", "Cannot exit because of verification failure", 0,
@@ -45,7 +45,7 @@ LITDEF	err_msg gdeerrors[] = {
 	"OBJNOTCHG", "Not changing !AD !AD", 4,
 	"OBJNOTFND", "!AD !AD does not exist", 4,
 	"OBJREQD", "!AD required", 2,
-	"PREFIXBAD", "!AD must start with an alphabetic character to be a !AD", 4,
+	"PREFIXBAD", "!AD - !AD !AD must start with an alphabetic character", 6,
 	"QUALBAD", "!AD is not a valid qualifier", 2,
 	"QUALDUP", "!AD qualifier appears more than once in the list", 2,
 	"QUALREQD", "!AD required", 2,
@@ -70,7 +70,33 @@ LITDEF	err_msg gdeerrors[] = {
 	"NONASCII", "!AD is illegal for a !AD as it contains non-ASCII characters", 4,
 	"CRYPTNOMM", "!AD is an encrypted database. Cannot support MM access method.", 2,
 	"JNLALLOCGROW", "Increased Journal ALLOCATION from [!AD blocks] to [!AD blocks] to match AUTOSWITCHLIMIT for !AD !AD", 8,
-	"KEYFORBLK", "But block size !AD can only support key size !AD", 4,
+	"KEYFORBLK", "But block size !AD and reserved bytes !AD limit key size to !AD", 6,
+	"STRMISSQUOTE", "Missing double-quote at end of string specification !AD", 2,
+	"GBLNAMEIS", "in gblname !AD", 2,
+	"NAMSUBSEMPTY", "Subscript #!UL is empty in name specification", 3,
+	"NAMSUBSBAD", "Subscript #!UL with value !AD in name specification is an invalid number or string", 3,
+	"NAMNUMSUBSOFLOW", "Subscript #!UL with value !AD in name specification has a numeric overflow", 3,
+	"NAMNUMSUBNOTEXACT", "Subscript #!UL with value !AD in name specification is not an exact GT.M number", 3,
+	"MISSINGDELIM", "Delimiter !AD expected before !AD !AD", 6,
+	"NAMRANGELASTSUB", "Ranges in name specification !AD are allowed only in the last subscript", 2,
+	"NAMSTARSUBSMIX", "Name specification !AD cannot contain * and subscripts at the same time", 2,
+	"NAMLPARENNOTBEG", "Subscripted Name specification !AD needs to have a left parenthesis at the beginning of subscripts", 2,
+	"NAMRPARENNOTEND", "Subscripted Name specification !AD cannot have anything following the right parenthesis at the end of subscripts", 2,
+	"NAMONECOLON", "Subscripted Name specification !AD must have at most one colon (range) specification", 2,
+	"NAMRPARENMISSING", "Subscripted Name specification !AD is missing one or more right parentheses at the end of subscripts", 2,
+	"NAMGVSUBSMAX", "Subscripted Name specification !AD has more than the maximum # of subscripts (!UL)", 3,
+	"NAMNOTSTRSUBS", "Subscript #!UL with value !AD in name specification is not a properly formatted string subscript", 3,
+	"NAMSTRSUBSFUN", "Subscript #!UL with value !AD in name specification uses function other than $C/$CHAR/$ZCH/$ZCHAR", 3,
+	"NAMSTRSUBSLPAREN", "Subscript #!UL with value !AD in name specification does not have left parenthesis following $ specification", 3,
+	"NAMSTRSUBSCHINT", "Subscript #!UL with value !AD in name specification does not have a positive integer inside $C/$CHAR/$ZCH/$ZCHAR", 3,
+	"NAMSTRSUBSCHARG", "Subscript #!UL with value !AD in name specification specifies a $C/$ZCH with number !UL that is invalid in the current $zchset", 4,
+	"GBLNAMCOLLUNDEF", "Error opening shared library of collation sequence #!UL for GBLNAME !AD", 3,
+	"NAMRANGEORDER", "Range in name specification !AD specifies out-of-order subscripts using collation sequence #!UL", 3,
+	"NAMRANGEOVERLAP", "Range in name specifications !AD and !AD overlap using collation sequence #!UL", 5,
+	"NAMGVSUBOFLOW", "Subscripted name !AD...!AD is too long to represent in the database using collation value #!UL", 5,
+	"GBLNAMCOLLRANGE", "Collation sequence #!UL is out of range (0 thru 255)", 3,
+	"STDNULLCOLLREQ", "Region !AD needs Standard Null Collation enabled because global !AD spans through it", 4,
+	"GBLNAMCOLLVER", "Global directory indicates GBLNAME !AD has collation sequence #!UL with a version #!UL but shared library reports different version #!UL", 5,
 };
 
 LITDEF	int GDE_BLKSIZ512 = 150503435;
@@ -93,7 +119,7 @@ LITDEF	int GDE_LOGON = 150503563;
 LITDEF	int GDE_LVSTARALON = 150503570;
 LITDEF	int GDE_MAPBAD = 150503579;
 LITDEF	int GDE_MAPDUP = 150503587;
-LITDEF	int GDE_NAMSTARTBAD = 150503594;
+LITDEF	int GDE_NAMENDBAD = 150503594;
 LITDEF	int GDE_NOACTION = 150503603;
 LITDEF	int GDE_RPAREN = 150503610;
 LITDEF	int GDE_NOEXIT = 150503619;
@@ -131,9 +157,35 @@ LITDEF	int GDE_NONASCII = 150503866;
 LITDEF	int GDE_CRYPTNOMM = 150503874;
 LITDEF	int GDE_JNLALLOCGROW = 150503883;
 LITDEF	int GDE_KEYFORBLK = 150503891;
+LITDEF	int GDE_STRMISSQUOTE = 150503898;
+LITDEF	int GDE_GBLNAMEIS = 150503907;
+LITDEF	int GDE_NAMSUBSEMPTY = 150503914;
+LITDEF	int GDE_NAMSUBSBAD = 150503922;
+LITDEF	int GDE_NAMNUMSUBSOFLOW = 150503930;
+LITDEF	int GDE_NAMNUMSUBNOTEXACT = 150503938;
+LITDEF	int GDE_MISSINGDELIM = 150503946;
+LITDEF	int GDE_NAMRANGELASTSUB = 150503954;
+LITDEF	int GDE_NAMSTARSUBSMIX = 150503962;
+LITDEF	int GDE_NAMLPARENNOTBEG = 150503970;
+LITDEF	int GDE_NAMRPARENNOTEND = 150503978;
+LITDEF	int GDE_NAMONECOLON = 150503986;
+LITDEF	int GDE_NAMRPARENMISSING = 150503994;
+LITDEF	int GDE_NAMGVSUBSMAX = 150504002;
+LITDEF	int GDE_NAMNOTSTRSUBS = 150504010;
+LITDEF	int GDE_NAMSTRSUBSFUN = 150504018;
+LITDEF	int GDE_NAMSTRSUBSLPAREN = 150504026;
+LITDEF	int GDE_NAMSTRSUBSCHINT = 150504034;
+LITDEF	int GDE_NAMSTRSUBSCHARG = 150504042;
+LITDEF	int GDE_GBLNAMCOLLUNDEF = 150504050;
+LITDEF	int GDE_NAMRANGEORDER = 150504058;
+LITDEF	int GDE_NAMRANGEOVERLAP = 150504066;
+LITDEF	int GDE_NAMGVSUBOFLOW = 150504074;
+LITDEF	int GDE_GBLNAMCOLLRANGE = 150504082;
+LITDEF	int GDE_STDNULLCOLLREQ = 150504091;
+LITDEF	int GDE_GBLNAMCOLLVER = 150504098;
 
 GBLDEF	err_ctl gdeerrors_ctl = {
 	248,
 	"GDE",
 	&gdeerrors[0],
-	58};
+	84};
diff --git a/sr_i386/merrors_ansi.h b/sr_i386/merrors_ansi.h
index 38cc6a1..0df7c77 100644
--- a/sr_i386/merrors_ansi.h
+++ b/sr_i386/merrors_ansi.h
@@ -510,8 +510,8 @@ const static readonly int error_ansi[] = {
 	   0,	/* NOPRINCIO */
 	   0,	/* INVPORTSPEC */
 	   0,	/* INVADDRSPEC */
-	  78,	/* SOCKPARMREQ */
-	   0,	/* IPADDRREQ */
+	  78,	/* UNUSEDMSG677 */
+	   0,	/* UNUSEDMSG678 */
 	  80,	/* SOCKWAIT */
 	  81,	/* SOCKACPT */
 	  80,	/* SOCKINIT */
@@ -614,7 +614,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* NOFORKCORE */
 	   0,	/* JNLREAD */
 	   0,	/* JNLMINALIGN */
-	   0,	/* UNUSEDMSG781 */
+	   0,	/* JOBSTARTCMDFAIL */
 	   0,	/* JNLPOOLSETUP */
 	   0,	/* JNLSTATEOFF */
 	   0,	/* RECVPOOLSETUP */
@@ -677,7 +677,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* BUFFLUFAILED */
 	   0,	/* MUQUALINCOMP */
 	   0,	/* DISTPATHMAX */
-	   0,	/* UNUSEDMSG844 */
+	   0,	/* FILEOPENFAIL */
 	   0,	/* IMAGENAME */
 	   0,	/* GTMSECSHRPERM */
 	   0,	/* GTMDISTUNDEF */
@@ -805,7 +805,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* SEMWT2LONG */
 	   0,	/* REPLINSTOPEN */
 	   0,	/* REPLINSTCLOSE */
-	   0,	/* UNUSEDMSG972 */
+	   0,	/* JOBSETUP */
 	   0,	/* DBCRERR8 */
 	   0,	/* NUMPROCESSORS */
 	   0,	/* DBADDRANGE8 */
@@ -940,7 +940,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* ZDIROUTOFSYNC */
 	   0,	/* GBLNOEXIST */
 	   0,	/* MAXBTLEVEL */
-	   0,	/* UNUSEDMSG1107 */
+	  35,	/* INVMNEMCSPC */
 	   0,	/* JNLALIGNSZCHG */
 	   0,	/* UNUSEDMSG1109 */
 	   0,	/* GVFAILCORE */
@@ -1152,7 +1152,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* CRYPTKEYFETCHFAILED */
 	   0,	/* CRYPTKEYFETCHFAILEDNF */
 	   0,	/* CRYPTHASHGENFAILED */
-	   0,	/* CRYPTNOPSWDINTP */
+	   0,	/* UNUSEDMSG1319 */
 	   0,	/* BADTAG */
 	   0,	/* ICUVERLT36 */
 	   0,	/* ICUSYMNOTFOUND */
@@ -1251,7 +1251,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* SECNOTSUPPLEMENTARY */
 	   0,	/* SUPRCVRNEEDSSUPSRC */
 	   0,	/* UNUSEDMSG1417 */
-	   0,	/* UNUSEDMSG1418 */
+	   0,	/* SETITIMERFAILED */
 	   0,	/* UPDSYNC2MTINS */
 	   0,	/* UPDSYNCINSTFILE */
 	   0,	/* REUSEINSTNAME */
@@ -1361,4 +1361,23 @@ const static readonly int error_ansi[] = {
 	   0,	/* INSTFRZDEFER */
 	   0,	/* REGOPENRETRY */
 	   0,	/* REGOPENFAIL */
+	   0,	/* REPLINSTNOSHM */
+	   0,	/* DEVPARMTOOSMALL */
+	   0,	/* REMOTEDBNOSPGBL */
+	   0,	/* NCTCOLLSPGBL */
+	   0,	/* ACTCOLLMISMTCH */
+	   0,	/* GBLNOMAPTOREG */
+	   0,	/* ISSPANGBL */
+	   0,	/* TPNOSUPPORT */
+	   0,	/* GVSUBSERR */
+	   0,	/* TRIGNOSPANGBL */
+	   0,	/* FILTERTIMEDOUT */
+	   0,	/* TLSDLLNOOPEN */
+	   0,	/* TLSINIT */
+	   0,	/* TLSCONVSOCK */
+	   0,	/* TLSHANDSHAKE */
+	   0,	/* TLSCONNINFO */
+	   0,	/* TLSIOERROR */
+	   0,	/* TLSRENEGOTIATE */
+	   0,	/* REPLNOTLS */
 	};
diff --git a/sr_i386/merrors_ctl.c b/sr_i386/merrors_ctl.c
index a409df6..c8412e9 100644
--- a/sr_i386/merrors_ctl.c
+++ b/sr_i386/merrors_ctl.c
@@ -42,7 +42,7 @@ LITDEF	err_msg merrors[] = {
 	"DBRDERR", "Cannot read database file !AD after opening", 2,
 	"CCEDUMPNOW", "", 0,
 	"DEVPARINAP", "Device parameter inappropriate to this command", 0,
-	"RECORDSTAT", "!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL  max rec len: !UL", 6,
+	"RECORDSTAT", "!AD:!_  Key cnt: !UL  max subsc len: !UL  max rec len: !UL  max node len: !UL", 6,
 	"NOTGBL", "!_!AD!/!_!_!_\"^\" Expected", 2,
 	"DEVPARPROT", "The protection specification is invalid", 0,
 	"PREMATEOF", "Premature end of file detected", 0,
@@ -512,12 +512,12 @@ LITDEF	err_msg merrors[] = {
 	"NOPRINCIO", "Unable to write to principal device", 0,
 	"INVPORTSPEC", "Invalid port specification", 0,
 	"INVADDRSPEC", "Invalid IP address specification", 0,
-	"SOCKPARMREQ", "Socket device parameter is required for TCP open", 0,
-	"IPADDRREQ", "Active connection requires IP address", 0,
+	"UNUSEDMSG677", "SOCKPARMREQ last used in V6.0-002", 0,
+	"UNUSEDMSG678", "IPADDRREQ last used in V6.0-002", 0,
 	"SOCKWAIT", "Error waiting for socket connection", 0,
 	"SOCKACPT", "Error accepting socket connection", 0,
-	"SOCKINIT", "Error initializing TCP socket: (errno == !UL) !AD", 3,
-	"OPENCONN", "Error opening TCP connection", 0,
+	"SOCKINIT", "Error initializing socket: (errno == !UL) !AD", 3,
+	"OPENCONN", "Error opening socket connection", 0,
 	"DEVNOTIMP", "!AD device not implemented on in this environment", 2,
 	"JNLEXTR", "Error writing journal extract file: !AD", 2,
 	"DBREMOTE", "Database region !AD is remote; perform maintenance on the server node", 2,
@@ -543,7 +543,7 @@ LITDEF	err_msg merrors[] = {
 	"MUNOACTION", "MUPIP unable to perform requested action", 0,
 	"RMBIGSHARE", "File with BIGRECORD specified may only be shared if READONLY", 0,
 	"TPRESTART", "Database !AD; code: !AD; blk: 0x!XL in glbl: ^!AD; pvtmods: !UL, blkmods: !UL, blklvl: !UL, type: !UL, readset: !UL, writeset: !UL, local_tn: 0x!16 at XQ", 14,
-	"SOCKWRITE", "Write to a TCP/IP socket failed", 0,
+	"SOCKWRITE", "Write to a socket failed", 0,
 	"DBCNTRLERR", "Database file !AD: control error suspected but not found", 2,
 	"NOTERMENV", "Environment variable TERM not set.  Assuming \"unknown.\"", 0,
 	"NOTERMENTRY", "TERM = \"!AD\" has no \"terminfo\" entry.  Possible terminal handling problems.", 2,
@@ -616,7 +616,7 @@ LITDEF	err_msg merrors[] = {
 	"NOFORKCORE", "Unable to fork off process to create core.  Core creation postponed.", 0,
 	"JNLREAD", "Error reading from journal file !AD at offset [0x!XL]", 3,
 	"JNLMINALIGN", "Journal Record Alignment !UL is less than the minimum value of !UL", 2,
-	"UNUSEDMSG781", "JNLDSKALIGN : Last used in V4.3-000", 0,
+	"JOBSTARTCMDFAIL", "JOB command STARTUP script invocation failed", 0,
 	"JNLPOOLSETUP", "Journal Pool setup error", 0,
 	"JNLSTATEOFF", "ROLLBACK or RECOVER BACKWARD cannot proceed as database file !AD does not have journaling ENABLED and ON", 2,
 	"RECVPOOLSETUP", "Receive Pool setup error", 0,
@@ -679,7 +679,7 @@ LITDEF	err_msg merrors[] = {
 	"BUFFLUFAILED", "Error flushing buffers from !AD for database file !AD", 4,
 	"MUQUALINCOMP", "Incompatible qualifiers - FILE and REGION", 0,
 	"DISTPATHMAX", "$gtm_dist path is greater than maximum (!UL)", 1,
-	"UNUSEDMSG844", "MAXTRACEHEIGHT last used in V5.4-002", 0,
+	"FILEOPENFAIL", "Failed to open file !AD", 2,
 	"IMAGENAME", "The executing module name should be !AD instead of !AD", 4,
 	"GTMSECSHRPERM", "The gtmsecshr module in $gtm_dist does not have the correct permission and uid", 0,
 	"GTMDISTUNDEF", "Environment variable $gtm_dist is not defined", 0,
@@ -807,7 +807,7 @@ LITDEF	err_msg merrors[] = {
 	"SEMWT2LONG", "Process !UL waited !UL second(s) for the !AD lock for region !AD, lock held by pid !UL", 7,
 	"REPLINSTOPEN", "Error opening replication instance file !AD", 2,
 	"REPLINSTCLOSE", "Error closing replication instance file !AD", 2,
-	"UNUSEDMSG972", "JNLNOTFOUND : Last used in V4.4-000", 0,
+	"JOBSETUP", "Error receiving !AD from parent process", 2,
 	"DBCRERR8", "Database file !AD, cr location 0x!XJ blk = 0x!XL error: !AD was 0x!16 at XQ, expecting 0x!16 at XQ -- called from module !AD at line !UL", 11,
 	"NUMPROCESSORS", "Could not determine number of processors", 0,
 	"DBADDRANGE8", "Database file !AD, element location 0x!XJ: blk = 0x!XL: control 0x!16 at XQ was outside !AD range 0x!16 at XQ to 0x!16 at XQ", 9,
@@ -942,7 +942,7 @@ LITDEF	err_msg merrors[] = {
 	"ZDIROUTOFSYNC", "$ZDIRECTORY !AD is not the same as its cached value !AD", 4,
 	"GBLNOEXIST", "Global !AD no longer exists", 2,
 	"MAXBTLEVEL", "Global !AD reached maximum level", 2,
-	"UNUSEDMSG1107", "JNLSTRESTFL : found no evidence it ever was used in a production release", 0,
+	"INVMNEMCSPC", "Unsupported mnemonicspace !AD", 2,
 	"JNLALIGNSZCHG", "Journal ALIGNSIZE is rounded up to !UL blocks (closest next higher power of two)", 1,
 	"UNUSEDMSG1109", "MAXTRACELEVEL : last used in V5.4-002B", 0,
 	"GVFAILCORE", "A core file is being created for later analysis if necessary", 0,
@@ -1154,7 +1154,7 @@ LITDEF	err_msg merrors[] = {
 	"CRYPTKEYFETCHFAILED", "Could not retrieve encryption key corresponding to file !AD. !AD", 4,
 	"CRYPTKEYFETCHFAILEDNF", "Could not retrieve encryption key during !AD operation key. !AD", 4,
 	"CRYPTHASHGENFAILED", "Could not generate cryptographic hash for symmetric key corresponding to file !AD. !AD", 4,
-	"CRYPTNOPSWDINTP", "Cannot prompt for password inside a TP transaction.", 0,
+	"UNUSEDMSG1319", "CRYPTNOPSWDINTP : Last used in V6.0-003", 0,
 	"BADTAG", "Unable to use file !AD (CCSID !UL) with CCSID !UL", 4,
 	"ICUVERLT36", "!AD !UL.!UL. ICU version greater than or equal to 3.6 should be used", 4,
 	"ICUSYMNOTFOUND", "Symbol !AD not found in the ICU libraries. ICU needs to be built with symbol-renaming disabled or gtm_icu_version environment variable needs to be properly specified", 2,
@@ -1253,7 +1253,7 @@ LITDEF	err_msg merrors[] = {
 	"SECNOTSUPPLEMENTARY", "!AD is a Supplementary Instance and so cannot act as a source to non-Supplementary Instance !AD ", 4,
 	"SUPRCVRNEEDSSUPSRC", "Instance !AD is not configured to perform local updates so it cannot act as a receiver for non-Supplementary Instance !AD", 4,
 	"UNUSEDMSG1417", "SYNCTOSAMETYPE: Never used before so slot free for reuse", 0,
-	"UNUSEDMSG1418", "TARGINSRUNNING: Never used before so slot free for reuse", 0,
+	"SETITIMERFAILED", "A setitimer() call returned an error status of !UL", 1,
 	"UPDSYNC2MTINS", "Can only UPDATERESYNC with an empty instance file", 0,
 	"UPDSYNCINSTFILE", "Error with instance file name specified in UPDATERESYNC qualifier", 0,
 	"REUSEINSTNAME", "Error with instance name specified in REUSE qualifier", 0,
@@ -1359,10 +1359,29 @@ LITDEF	err_msg merrors[] = {
 	"HOSTCONFLICT", "Host !AD could not open database file !AD because it is marked as already open on node !AD", 6,
 	"GETADDRINFO", "Error in getting address info", 0,
 	"GETNAMEINFO", "Error in getting name info", 0,
-	"SOCKBIND", "Error in binding TCP socket", 0,
+	"SOCKBIND", "Error in binding socket", 0,
 	"INSTFRZDEFER", "Instance Freeze initiated by !AD error on region !AD deferred due to critical resource conflict", 4,
 	"REGOPENRETRY", "Attempt to open region !AD (!AD) using startup shortcut failed due to conflicting database shutdown. Retrying...", 4,
 	"REGOPENFAIL", "Failed to open region !AD (!AD) due to conflicting database shutdown activity", 4,
+	"REPLINSTNOSHM", "Database !AD has no active connection to a replication journal pool; please verify that the database is listed in your instance file", 2,
+	"DEVPARMTOOSMALL", "Deviceparameter must be greater than zero (0)", 0,
+	"REMOTEDBNOSPGBL", "Database region !AD contains portion of a spanning global and so cannot point to a remote file", 2,
+	"NCTCOLLSPGBL", "Database region !AD contains portion of spanning global ^!AD and so cannot support non-zero numeric collation type", 4,
+	"ACTCOLLMISMTCH", "Global ^!AD inherits alternative collation sequence #!UL from global directory but database file !AD contains different collation sequence #!UL for this global", 6,
+	"GBLNOMAPTOREG", "Global !AD does not map to region !AD in current global directory", 4,
+	"ISSPANGBL", "Operation cannot be performed on global ^!AD as it spans multiple regions in current global directory", 2,
+	"TPNOSUPPORT", "Operation cannot be performed while inside of a TP transaction", 0,
+	"GVSUBSERR", "Invalid subscripted global name specification in $VIEW() function", 0,
+	"TRIGNOSPANGBL", "Triggers cannot be installed/deleted for global name !AD as it spans multiple regions in current global directory", 2,
+	"FILTERTIMEDOUT", "Replication server timed out attempting to read seqno !16 at XQ from external filter", 1,
+	"TLSDLLNOOPEN", "Failed to load GT.M TLS/SSL library for secure communication", 0,
+	"TLSINIT", "Failed to initialize GT.M TLS/SSL library for secure communication", 0,
+	"TLSCONVSOCK", "Failed to convert Unix TCP/IP socket to TLS/SSL aware socket", 0,
+	"TLSHANDSHAKE", "Connection to remote side using TLS/SSL protocol failed", 0,
+	"TLSCONNINFO", "Failed to obtain information on the TLS/SSL connection", 0,
+	"TLSIOERROR", "Error during TLS/SSL !AD operation", 2,
+	"TLSRENEGOTIATE", "Failed to renegotiate TLS/SSL connection", 0,
+	"REPLNOTLS", "!AD requested TLS/SSL communication but the !AD was either not started with TLSID qualifier or does not support TLS/SSL protocol", 4,
 };
 
 LITDEF	int ERR_ACK = 150372361;
@@ -1864,8 +1883,8 @@ LITDEF	int ERR_CCPSIGDMP = 150376323;
 LITDEF	int ERR_NOPRINCIO = 150376332;
 LITDEF	int ERR_INVPORTSPEC = 150376338;
 LITDEF	int ERR_INVADDRSPEC = 150376346;
-LITDEF	int ERR_SOCKPARMREQ = 150376354;
-LITDEF	int ERR_IPADDRREQ = 150376362;
+LITDEF	int ERR_UNUSEDMSG677 = 150376354;
+LITDEF	int ERR_UNUSEDMSG678 = 150376362;
 LITDEF	int ERR_SOCKWAIT = 150376370;
 LITDEF	int ERR_SOCKACPT = 150376378;
 LITDEF	int ERR_SOCKINIT = 150376386;
@@ -1968,7 +1987,7 @@ LITDEF	int ERR_BCKUPBUFLUSH = 150377154;
 LITDEF	int ERR_NOFORKCORE = 150377160;
 LITDEF	int ERR_JNLREAD = 150377170;
 LITDEF	int ERR_JNLMINALIGN = 150377176;
-LITDEF	int ERR_UNUSEDMSG781 = 150377186;
+LITDEF	int ERR_JOBSTARTCMDFAIL = 150377186;
 LITDEF	int ERR_JNLPOOLSETUP = 150377194;
 LITDEF	int ERR_JNLSTATEOFF = 150377202;
 LITDEF	int ERR_RECVPOOLSETUP = 150377210;
@@ -2031,7 +2050,7 @@ LITDEF	int ERR_RECSIZENOTEVEN = 150377658;
 LITDEF	int ERR_BUFFLUFAILED = 150377666;
 LITDEF	int ERR_MUQUALINCOMP = 150377674;
 LITDEF	int ERR_DISTPATHMAX = 150377682;
-LITDEF	int ERR_UNUSEDMSG844 = 150377690;
+LITDEF	int ERR_FILEOPENFAIL = 150377690;
 LITDEF	int ERR_IMAGENAME = 150377698;
 LITDEF	int ERR_GTMSECSHRPERM = 150377706;
 LITDEF	int ERR_GTMDISTUNDEF = 150377714;
@@ -2159,7 +2178,7 @@ LITDEF	int ERR_MUTEXRSRCCLNUP = 150378683;
 LITDEF	int ERR_SEMWT2LONG = 150378690;
 LITDEF	int ERR_REPLINSTOPEN = 150378698;
 LITDEF	int ERR_REPLINSTCLOSE = 150378706;
-LITDEF	int ERR_UNUSEDMSG972 = 150378714;
+LITDEF	int ERR_JOBSETUP = 150378714;
 LITDEF	int ERR_DBCRERR8 = 150378723;
 LITDEF	int ERR_NUMPROCESSORS = 150378728;
 LITDEF	int ERR_DBADDRANGE8 = 150378739;
@@ -2294,7 +2313,7 @@ LITDEF	int ERR_INVZDIRFORM = 150379762;
 LITDEF	int ERR_ZDIROUTOFSYNC = 150379768;
 LITDEF	int ERR_GBLNOEXIST = 150379779;
 LITDEF	int ERR_MAXBTLEVEL = 150379786;
-LITDEF	int ERR_UNUSEDMSG1107 = 150379794;
+LITDEF	int ERR_INVMNEMCSPC = 150379794;
 LITDEF	int ERR_JNLALIGNSZCHG = 150379803;
 LITDEF	int ERR_UNUSEDMSG1109 = 150379810;
 LITDEF	int ERR_GVFAILCORE = 150379818;
@@ -2506,7 +2525,7 @@ LITDEF	int ERR_CRYPTJNLWRONGHASH = 150381458;
 LITDEF	int ERR_CRYPTKEYFETCHFAILED = 150381466;
 LITDEF	int ERR_CRYPTKEYFETCHFAILEDNF = 150381474;
 LITDEF	int ERR_CRYPTHASHGENFAILED = 150381482;
-LITDEF	int ERR_CRYPTNOPSWDINTP = 150381490;
+LITDEF	int ERR_UNUSEDMSG1319 = 150381490;
 LITDEF	int ERR_BADTAG = 150381498;
 LITDEF	int ERR_ICUVERLT36 = 150381506;
 LITDEF	int ERR_ICUSYMNOTFOUND = 150381514;
@@ -2605,7 +2624,7 @@ LITDEF	int ERR_MUUSERECOV = 150382250;
 LITDEF	int ERR_SECNOTSUPPLEMENTARY = 150382258;
 LITDEF	int ERR_SUPRCVRNEEDSSUPSRC = 150382266;
 LITDEF	int ERR_UNUSEDMSG1417 = 150382275;
-LITDEF	int ERR_UNUSEDMSG1418 = 150382283;
+LITDEF	int ERR_SETITIMERFAILED = 150382284;
 LITDEF	int ERR_UPDSYNC2MTINS = 150382290;
 LITDEF	int ERR_UPDSYNCINSTFILE = 150382298;
 LITDEF	int ERR_REUSEINSTNAME = 150382306;
@@ -2715,9 +2734,28 @@ LITDEF	int ERR_SOCKBIND = 150383130;
 LITDEF	int ERR_INSTFRZDEFER = 150383139;
 LITDEF	int ERR_REGOPENRETRY = 150383147;
 LITDEF	int ERR_REGOPENFAIL = 150383154;
+LITDEF	int ERR_REPLINSTNOSHM = 150383162;
+LITDEF	int ERR_DEVPARMTOOSMALL = 150383170;
+LITDEF	int ERR_REMOTEDBNOSPGBL = 150383178;
+LITDEF	int ERR_NCTCOLLSPGBL = 150383186;
+LITDEF	int ERR_ACTCOLLMISMTCH = 150383194;
+LITDEF	int ERR_GBLNOMAPTOREG = 150383202;
+LITDEF	int ERR_ISSPANGBL = 150383210;
+LITDEF	int ERR_TPNOSUPPORT = 150383218;
+LITDEF	int ERR_GVSUBSERR = 150383226;
+LITDEF	int ERR_TRIGNOSPANGBL = 150383234;
+LITDEF	int ERR_FILTERTIMEDOUT = 150383242;
+LITDEF	int ERR_TLSDLLNOOPEN = 150383250;
+LITDEF	int ERR_TLSINIT = 150383258;
+LITDEF	int ERR_TLSCONVSOCK = 150383266;
+LITDEF	int ERR_TLSHANDSHAKE = 150383274;
+LITDEF	int ERR_TLSCONNINFO = 150383280;
+LITDEF	int ERR_TLSIOERROR = 150383290;
+LITDEF	int ERR_TLSRENEGOTIATE = 150383298;
+LITDEF	int ERR_REPLNOTLS = 150383306;
 
 GBLDEF	err_ctl merrors_ctl = {
 	246,
 	"GTM",
 	&merrors[0],
-	1350};
+	1369};
diff --git a/sr_i386/ttt.c b/sr_i386/ttt.c
index fc23248..beed698 100644
--- a/sr_i386/ttt.c
+++ b/sr_i386/ttt.c
@@ -13,49 +13,49 @@
 #include "vxi.h"
 #include "vxt.h"
 #include "xfer_enum.h"
-LITDEF short ttt[4229] = {
+LITDEF short ttt[4243] = {
 
-/*    0 */	0,0,0,0,324,3399,2842,548,
-/*    8 */	2220,2827,2857,1910,402,3349,2022,2973,
-/*   16 */	2099,2090,3582,3619,2063,2072,2138,2084,
-/*   24 */	2129,2108,2045,748,775,763,802,814,
+/*    0 */	0,0,0,0,324,3410,2851,548,
+/*    8 */	2229,2836,2866,1910,402,3360,2022,2984,
+/*   16 */	2105,2093,3593,3630,2066,2075,2147,2087,
+/*   24 */	2138,2117,2045,748,775,763,802,814,
 /*   32 */	826,844,886,904,922,943,972,1002,
-/*   40 */	1017,1032,1047,1065,1077,2943,2958,1149,
+/*   40 */	1017,1032,1047,1065,1077,2954,2969,1149,
 /*   48 */	1182,1215,1254,1317,1368,1644,1659,1674,
-/*   56 */	1704,1743,1755,1779,1806,1827,1842,3414,
-/*   64 */	3436,0,0,0,0,563,0,504,
-/*   72 */	0,1896,0,2929,0,0,0,0,
-/*   80 */	0,0,356,414,2198,2204,2619,2646,
-/*   88 */	2664,2767,2705,2696,2782,3488,3572,2878,
-/*   96 */	0,2908,3039,3002,2987,3017,3363,3215,
-/*  104 */	3281,3494,3506,3521,3545,3554,3539,3530,
-/*  112 */	3314,3615,3628,3650,3687,3699,3720,3744,
-/*  120 */	3810,0,0,2815,2180,3091,4178,636,
-/*  128 */	4181,690,2676,3057,518,524,4184,2283,
-/*  136 */	2370,2270,471,2306,2390,2054,2328,2400,
-/*  144 */	4187,2165,2156,4191,1386,1404,4192,352,
-/*  152 */	348,3305,426,4196,4199,4202,2894,4205,
-/*  160 */	4208,4211,4214,4217,4220,3385,0,2791,
-/*  168 */	2459,2437,1623,2428,2216,2036,2742,1931,
-/*  176 */	715,2732,0,0,2235,3563,3591,1599,
-/*  184 */	3515,2318,1924,533,3711,1791,2147,1302,
-/*  192 */	339,3043,602,668,586,646,3675,1197,
-/*  200 */	1236,3643,2871,2174,2806,2885,618,1089,
-/*  208 */	2746,4223,2380,3762,3780,3795,495,2761,
-/*  216 */	3035,1869,3831,3822,1440,3377,577,1689,
-/*  224 */	1731,2343,4226,3448,2416,724,862,3074,
-/*  232 */	3603,3472,3458,3465,3454,700,957,2293,
-/*  240 */	1131,2257,1119,2117,1104,1164,2355,1569,
+/*   56 */	1704,1743,1755,1779,1806,1827,1842,3425,
+/*   64 */	3447,0,0,0,0,563,0,504,
+/*   72 */	0,1896,0,2940,0,0,0,0,
+/*   80 */	0,0,356,414,2207,2213,2628,2655,
+/*   88 */	2673,2776,2714,2705,2791,3499,3583,2887,
+/*   96 */	0,2919,3050,3013,2998,3028,3374,3226,
+/*  104 */	3292,3505,3517,3532,3556,3565,3550,3541,
+/*  112 */	3325,3626,3639,3661,3698,3710,3731,3755,
+/*  120 */	3821,0,0,2824,2189,3102,4192,636,
+/*  128 */	4195,690,2685,3068,518,524,4198,2292,
+/*  136 */	2379,2279,471,2315,2399,2054,2337,2409,
+/*  144 */	4201,2174,2165,4205,1386,1404,4206,352,
+/*  152 */	348,3316,426,4210,4213,4216,2905,4219,
+/*  160 */	4222,4225,4228,4231,4234,3396,0,2800,
+/*  168 */	2468,2446,1623,2437,2225,2036,2751,1931,
+/*  176 */	715,2741,0,0,2244,3574,3602,1599,
+/*  184 */	3526,2327,1924,533,3722,1791,2156,1302,
+/*  192 */	339,3054,602,668,586,646,3686,1197,
+/*  200 */	1236,3654,2880,2183,2815,2894,618,1089,
+/*  208 */	2755,4237,2389,3773,3791,3806,495,2770,
+/*  216 */	3046,1869,3842,3833,1440,3388,577,1689,
+/*  224 */	1731,2352,4240,3459,2425,724,862,3085,
+/*  232 */	3614,3483,3469,3476,3465,700,957,2302,
+/*  240 */	1131,2266,1119,2126,1104,1164,2364,1569,
 /*  248 */	1512,1497,1551,1467,1479,1524,1452,1536,
-/*  256 */	1584,0,3335,0,981,990,3194,3260,
-/*  264 */	1818,3173,3239,2244,3867,3837,3843,3855,
-/*  272 */	3877,1341,1353,1275,1287,1329,3426,1719,
-/*  280 */	1854,3891,3906,3942,3969,3924,3101,3113,
-/*  288 */	3125,3137,2655,2670,1611,435,790,1422,
-/*  296 */	627,3149,3161,3954,3960,0,0,0,
-/*  304 */	0,3666,3981,3992,4004,4013,4027,4040,
-/*  312 */	4050,4067,4076,4085,4097,4109,4121,4136,
-/*  320 */	4148,0,0,4157,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,
+/*  256 */	1584,0,3346,0,981,990,3205,3271,
+/*  264 */	1818,3184,3250,2253,3878,3848,3854,3866,
+/*  272 */	3888,1341,1353,1275,1287,1329,3437,1719,
+/*  280 */	1854,3902,3917,3953,3980,3935,3112,3124,
+/*  288 */	3136,3148,2664,2679,1611,435,790,1422,
+/*  296 */	627,3160,3172,3965,3971,0,0,0,
+/*  304 */	0,3677,3992,4003,4015,4024,4038,4051,
+/*  312 */	4061,4078,4090,4099,4111,4123,4135,4150,
+/*  320 */	4162,0,0,4171,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,
 /*  328 */	VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,
 /*  336 */	VXT_XFER,SIZEOF(char *) * (short int)xf_add,VXT_END,
 /*  339 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_bindparm,
@@ -326,368 +326,368 @@ LITDEF short ttt[4229] = {
 /* 2044 */	VXT_END,
 /* 2045 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvdata,
 /* 2053 */	VXT_END,
-/* 2054 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,
-/* 2062 */	VXT_END,
-/* 2063 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
-/* 2071 */	VXT_END,
-/* 2072 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 2080 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
-/* 2084 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
-/* 2090 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,
-/* 2098 */	VXT_END,
-/* 2099 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,
-/* 2107 */	VXT_END,
-/* 2108 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
-/* 2116 */	VXT_END,
-/* 2117 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 2125 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
-/* 2129 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
-/* 2137 */	VXT_END,
-/* 2138 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
+/* 2054 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2062 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,VXT_END,
+/* 2066 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
+/* 2074 */	VXT_END,
+/* 2075 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 2083 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
+/* 2087 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
+/* 2093 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2101 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,VXT_END,
+/* 2105 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2113 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,VXT_END,
+/* 2117 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
+/* 2125 */	VXT_END,
+/* 2126 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 2134 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
+/* 2138 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
 /* 2146 */	VXT_END,
-/* 2147 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
+/* 2147 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
 /* 2155 */	VXT_END,
-/* 2156 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
+/* 2156 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
 /* 2164 */	VXT_END,
-/* 2165 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
+/* 2165 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
 /* 2173 */	VXT_END,
-/* 2174 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
-/* 2180 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 2188 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
-/* 2196 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
-/* 2198 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
-/* 2204 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 2212 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
-/* 2216 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
-/* 2220 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2228 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
-/* 2235 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
-/* 2243 */	VXT_END,
-/* 2244 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2252 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
-/* 2257 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2265 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
-/* 2270 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2278 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
-/* 2283 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2291 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
-/* 2293 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2301 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
-/* 2306 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
-/* 2314 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2318 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2326 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
-/* 2328 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2336 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
-/* 2343 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
-/* 2351 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2355 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2363 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
-/* 2370 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2378 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
-/* 2380 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2388 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
-/* 2390 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2398 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
-/* 2400 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2408 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
-/* 2416 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2424 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
-/* 2428 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
-/* 2436 */	VXT_END,
-/* 2437 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2445 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
-/* 2447 */	VXI_BRB,VXT_JMP,1,VXT_END,
-/* 2451 */	VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2455 */	VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2459 */	VXI_JMP,VXT_VAL,1,VXT_END,
-/* 2463 */	VXI_BEQL,VXT_JMP,1,VXT_END,
-/* 2467 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2474 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2481 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
-/* 2485 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2492 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2499 */	VXI_BGTR,VXT_JMP,1,VXT_END,
-/* 2503 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2510 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2517 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
-/* 2521 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2528 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2535 */	VXI_BLSS,VXT_JMP,1,VXT_END,
-/* 2539 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2546 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2553 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
-/* 2557 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2564 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2571 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2577 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2585 */	VXT_END,
-/* 2586 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2174 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
+/* 2182 */	VXT_END,
+/* 2183 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
+/* 2189 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 2197 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
+/* 2205 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
+/* 2207 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
+/* 2213 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 2221 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
+/* 2225 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
+/* 2229 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2237 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
+/* 2244 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
+/* 2252 */	VXT_END,
+/* 2253 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2261 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
+/* 2266 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2274 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
+/* 2279 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2287 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
+/* 2292 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2300 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
+/* 2302 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2310 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
+/* 2315 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
+/* 2323 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2327 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2335 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
+/* 2337 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2345 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
+/* 2352 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
+/* 2360 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2364 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2372 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
+/* 2379 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2387 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
+/* 2389 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2397 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
+/* 2399 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2407 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
+/* 2409 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2417 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
+/* 2425 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2433 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
+/* 2437 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
+/* 2445 */	VXT_END,
+/* 2446 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2454 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
+/* 2456 */	VXI_BRB,VXT_JMP,1,VXT_END,
+/* 2460 */	VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2464 */	VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2468 */	VXI_JMP,VXT_VAL,1,VXT_END,
+/* 2472 */	VXI_BEQL,VXT_JMP,1,VXT_END,
+/* 2476 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2483 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2490 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
+/* 2494 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2501 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2508 */	VXI_BGTR,VXT_JMP,1,VXT_END,
+/* 2512 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2519 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2526 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
+/* 2530 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2537 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2544 */	VXI_BLSS,VXT_JMP,1,VXT_END,
+/* 2548 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2555 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2562 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
+/* 2566 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2573 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2580 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2586 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
 /* 2594 */	VXT_END,
-/* 2595 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2601 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2609 */	VXT_END,
-/* 2610 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2595 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2603 */	VXT_END,
+/* 2604 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2610 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
 /* 2618 */	VXT_END,
-/* 2619 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
-/* 2627 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
-/* 2635 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
-/* 2643 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
-/* 2646 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
-/* 2654 */	VXT_END,
-/* 2655 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
+/* 2619 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2627 */	VXT_END,
+/* 2628 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
+/* 2636 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
+/* 2644 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
+/* 2652 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
+/* 2655 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
 /* 2663 */	VXT_END,
-/* 2664 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
-/* 2670 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
-/* 2676 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2684 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
-/* 2692 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2696 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
-/* 2704 */	VXT_END,
-/* 2705 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
+/* 2664 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
+/* 2672 */	VXT_END,
+/* 2673 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
+/* 2679 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
+/* 2685 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2693 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
+/* 2701 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2705 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
 /* 2713 */	VXT_END,
-/* 2714 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2720 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2726 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2732 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2740 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
-/* 2742 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
-/* 2746 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 2754 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2761 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
-/* 2767 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2775 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2782 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
-/* 2790 */	VXT_END,
-/* 2791 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2799 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
-/* 2806 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
-/* 2814 */	VXT_END,
-/* 2815 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2823 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
-/* 2827 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2835 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
-/* 2842 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2850 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
-/* 2857 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
-/* 2865 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
-/* 2871 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
-/* 2878 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
-/* 2885 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,
-/* 2893 */	VXT_END,
-/* 2894 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 2902 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
-/* 2908 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 2916 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 2924 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
-/* 2929 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 2937 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
-/* 2943 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2951 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpopulation,VXT_END,
-/* 2958 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2966 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpopulation,VXT_END,
-/* 2973 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
-/* 2981 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 2987 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2995 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
-/* 3002 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 3010 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
-/* 3017 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 3025 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3033 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
-/* 3035 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
-/* 3039 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
-/* 3043 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
-/* 3051 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
-/* 3057 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3065 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3073 */	VXT_END,
-/* 3074 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3082 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3090 */	VXT_END,
-/* 3091 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3099 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
-/* 3101 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3109 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
-/* 3113 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3121 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
-/* 3125 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3133 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
-/* 3137 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3145 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
-/* 3149 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3157 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
-/* 3161 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3169 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
-/* 3173 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3181 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3189 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
-/* 3194 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3202 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3210 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
-/* 3215 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3223 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3231 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
-/* 3239 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3247 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3255 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
-/* 3260 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3268 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3276 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
-/* 3281 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3289 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3297 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
-/* 3305 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,
-/* 3313 */	VXT_END,
-/* 3314 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3322 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
-/* 3330 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
-/* 3335 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3343 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
-/* 3349 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
-/* 3357 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3363 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
-/* 3371 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3377 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
-/* 3385 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
-/* 3393 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3399 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3407 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
-/* 3414 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3422 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
-/* 3426 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3434 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
-/* 3436 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3444 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
-/* 3448 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
-/* 3454 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
-/* 3458 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
-/* 3465 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
-/* 3472 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3480 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
-/* 3488 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
-/* 3494 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3502 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
-/* 3506 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
-/* 3514 */	VXT_END,
-/* 3515 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
-/* 3521 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
-/* 3529 */	VXT_END,
-/* 3530 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
-/* 3538 */	VXT_END,
-/* 3539 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
-/* 3545 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
-/* 3553 */	VXT_END,
-/* 3554 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
-/* 3562 */	VXT_END,
-/* 3563 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
-/* 3571 */	VXT_END,
-/* 3572 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3580 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
-/* 3582 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
-/* 3590 */	VXT_END,
-/* 3591 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3599 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
-/* 3603 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3611 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
-/* 3615 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3619 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
-/* 3627 */	VXT_END,
-/* 3628 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3636 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
-/* 3643 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
-/* 3650 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
-/* 3658 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
-/* 3666 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
-/* 3674 */	VXT_END,
-/* 3675 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3683 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
-/* 3687 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3695 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
-/* 3699 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 3707 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
-/* 3711 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
-/* 3719 */	VXT_END,
-/* 3720 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
-/* 3728 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3736 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
-/* 3744 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
-/* 3752 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3760 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3762 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3770 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3778 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3780 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3788 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3795 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3803 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3810 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3818 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
-/* 3822 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
-/* 3830 */	VXT_END,
-/* 3831 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
-/* 3837 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
-/* 3843 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3851 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 3855 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3863 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 3867 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
-/* 3875 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
-/* 3877 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
-/* 3885 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3891 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3899 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzconvert2,VXT_END,
-/* 3906 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3914 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 3922 */	SIZEOF(char *) * (short int)xf_fnzconvert3,VXT_END,
-/* 3924 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3932 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 3940 */	SIZEOF(char *) * (short int)xf_fnzsubstr,VXT_END,
-/* 3942 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3950 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwidth,VXT_END,
-/* 3954 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztrigger,VXT_END,
-/* 3960 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
-/* 3968 */	VXT_END,
-/* 3969 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3977 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
-/* 3981 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
-/* 3989 */	VXT_ADDR,0,VXT_END,
-/* 3992 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4000 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
-/* 4004 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
-/* 4012 */	VXT_END,
-/* 4013 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
-/* 4021 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 4027 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 4035 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
-/* 4040 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 4048 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
-/* 4050 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4058 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 4066 */	VXT_END,
-/* 4067 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,
-/* 4075 */	VXT_END,
-/* 4076 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
-/* 4084 */	VXT_END,
-/* 4085 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4093 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
-/* 4097 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4105 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
-/* 4109 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4117 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
-/* 4121 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 4129 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
-/* 4136 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 4144 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
-/* 4148 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
-/* 4156 */	VXT_END,
-/* 4157 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 4165 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 4173 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpeek,VXT_END,
-/* 4178 */	360,374,367,2447,2455,2451,2714,2726,
-/* 4186 */	2720,0,0,0,481,457,448,0,
-/* 4194 */	0,444,1965,2003,1984,2595,2610,2601,
-/* 4202 */	2571,2586,2577,2463,2474,2467,2553,2564,
-/* 4210 */	2557,2499,2510,2503,2517,2528,2521,2535,
-/* 4218 */	2546,2539,2481,2492,2485,1944,1958,1951,
-/* 4226 */	381,395,388};
+/* 2714 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
+/* 2722 */	VXT_END,
+/* 2723 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2729 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2735 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2741 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2749 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
+/* 2751 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
+/* 2755 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 2763 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2770 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
+/* 2776 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2784 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2791 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
+/* 2799 */	VXT_END,
+/* 2800 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2808 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
+/* 2815 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
+/* 2823 */	VXT_END,
+/* 2824 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2832 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
+/* 2836 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2844 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
+/* 2851 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2859 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
+/* 2866 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
+/* 2874 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
+/* 2880 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
+/* 2887 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
+/* 2894 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,VXI_MOVL,VXT_REG,0x50,
+/* 2902 */	VXT_ADDR,0,VXT_END,
+/* 2905 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 2913 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
+/* 2919 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 2927 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 2935 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
+/* 2940 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 2948 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
+/* 2954 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2962 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpopulation,VXT_END,
+/* 2969 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2977 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpopulation,VXT_END,
+/* 2984 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
+/* 2992 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 2998 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3006 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
+/* 3013 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3021 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
+/* 3028 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 3036 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3044 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
+/* 3046 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
+/* 3050 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
+/* 3054 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
+/* 3062 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
+/* 3068 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3076 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3084 */	VXT_END,
+/* 3085 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3093 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3101 */	VXT_END,
+/* 3102 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3110 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
+/* 3112 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3120 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
+/* 3124 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3132 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
+/* 3136 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3144 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
+/* 3148 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3156 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
+/* 3160 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3168 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
+/* 3172 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3180 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
+/* 3184 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3192 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3200 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
+/* 3205 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3213 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3221 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
+/* 3226 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3234 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3242 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
+/* 3250 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3258 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3266 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
+/* 3271 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3279 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3287 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
+/* 3292 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3300 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3308 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
+/* 3316 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,
+/* 3324 */	VXT_END,
+/* 3325 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3333 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
+/* 3341 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
+/* 3346 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3354 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
+/* 3360 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
+/* 3368 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3374 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
+/* 3382 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3388 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
+/* 3396 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
+/* 3404 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3410 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3418 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
+/* 3425 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3433 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
+/* 3437 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3445 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
+/* 3447 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3455 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
+/* 3459 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
+/* 3465 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
+/* 3469 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
+/* 3476 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
+/* 3483 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3491 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
+/* 3499 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
+/* 3505 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3513 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
+/* 3517 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
+/* 3525 */	VXT_END,
+/* 3526 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
+/* 3532 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
+/* 3540 */	VXT_END,
+/* 3541 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
+/* 3549 */	VXT_END,
+/* 3550 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
+/* 3556 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
+/* 3564 */	VXT_END,
+/* 3565 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
+/* 3573 */	VXT_END,
+/* 3574 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
+/* 3582 */	VXT_END,
+/* 3583 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3591 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
+/* 3593 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
+/* 3601 */	VXT_END,
+/* 3602 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3610 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
+/* 3614 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3622 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
+/* 3626 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3630 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
+/* 3638 */	VXT_END,
+/* 3639 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3647 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
+/* 3654 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
+/* 3661 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
+/* 3669 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
+/* 3677 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
+/* 3685 */	VXT_END,
+/* 3686 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3694 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
+/* 3698 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3706 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
+/* 3710 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 3718 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
+/* 3722 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
+/* 3730 */	VXT_END,
+/* 3731 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
+/* 3739 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3747 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
+/* 3755 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
+/* 3763 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3771 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3773 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3781 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3789 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3791 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3799 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3806 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3814 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3821 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3829 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
+/* 3833 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
+/* 3841 */	VXT_END,
+/* 3842 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
+/* 3848 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
+/* 3854 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3862 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3866 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3874 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3878 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
+/* 3886 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
+/* 3888 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
+/* 3896 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3902 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3910 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzconvert2,VXT_END,
+/* 3917 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3925 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 3933 */	SIZEOF(char *) * (short int)xf_fnzconvert3,VXT_END,
+/* 3935 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3943 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 3951 */	SIZEOF(char *) * (short int)xf_fnzsubstr,VXT_END,
+/* 3953 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3961 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwidth,VXT_END,
+/* 3965 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztrigger,VXT_END,
+/* 3971 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
+/* 3979 */	VXT_END,
+/* 3980 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3988 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
+/* 3992 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
+/* 4000 */	VXT_ADDR,0,VXT_END,
+/* 4003 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4011 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
+/* 4015 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
+/* 4023 */	VXT_END,
+/* 4024 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
+/* 4032 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 4038 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 4046 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
+/* 4051 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 4059 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
+/* 4061 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4069 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 4077 */	VXT_END,
+/* 4078 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 4086 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,VXT_END,
+/* 4090 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
+/* 4098 */	VXT_END,
+/* 4099 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4107 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
+/* 4111 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4119 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
+/* 4123 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4131 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
+/* 4135 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 4143 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
+/* 4150 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 4158 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
+/* 4162 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
+/* 4170 */	VXT_END,
+/* 4171 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 4179 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 4187 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpeek,VXT_END,
+/* 4192 */	360,374,367,2456,2464,2460,2723,2735,
+/* 4200 */	2729,0,0,0,481,457,448,0,
+/* 4208 */	0,444,1965,2003,1984,2604,2619,2610,
+/* 4216 */	2580,2595,2586,2472,2483,2476,2562,2573,
+/* 4224 */	2566,2508,2519,2512,2526,2537,2530,2544,
+/* 4232 */	2555,2548,2490,2501,2494,1944,1958,1951,
+/* 4240 */	381,395,388};
diff --git a/sr_linux/gtm_env_sp.csh b/sr_linux/gtm_env_sp.csh
index eff718d..1aca060 100644
--- a/sr_linux/gtm_env_sp.csh
+++ b/sr_linux/gtm_env_sp.csh
@@ -142,8 +142,7 @@ if ( $?gtm_version_change == "1" ) then
         setenv  gt_cc_options_common    "$gt_cc_options_common -D_XOPEN_SOURCE=600 -fsigned-char "
 
         if ( "ia64" != $mach_type ) then
-		set tmpgtmval = `echo $gt_cc_compiler | grep icc`
-		if ($status) then
+		if ("$gt_cc_compiler" =~ *icc*) then
         		setenv gt_cc_options_common "$gt_cc_options_common $gt_cc_shl_fpic"
 		else
 			setenv gt_cc_options_common "$gt_cc_options_common $gt_cc_shl_fpic -Wimplicit"
diff --git a/sr_linux/release_name.h b/sr_linux/release_name.h
index e2eb210..099559d 100644
--- a/sr_linux/release_name.h
+++ b/sr_linux/release_name.h
@@ -10,15 +10,15 @@
  ****************************************************************/
 
 #ifdef __CYGWIN__
-#define GTM_RELEASE_NAME 	"GT.M V6.0-003 CYGWIN x86"
+#define GTM_RELEASE_NAME 	"GT.M V6.1-000 CYGWIN x86"
 #elif defined(__ia64)
-#define GTM_RELEASE_NAME 	"GT.M V6.0-003 Linux IA64"
+#define GTM_RELEASE_NAME 	"GT.M V6.1-000 Linux IA64"
 #elif defined(__x86_64__)
-#define GTM_RELEASE_NAME 	"GT.M V6.0-003 Linux x86_64"
+#define GTM_RELEASE_NAME 	"GT.M V6.1-000 Linux x86_64"
 #elif defined(__s390__)
-#define GTM_RELEASE_NAME 	"GT.M V6.0-003 Linux S390X"
+#define GTM_RELEASE_NAME 	"GT.M V6.1-000 Linux S390X"
 #else
-#define GTM_RELEASE_NAME 	"GT.M V6.0-003 Linux x86"
+#define GTM_RELEASE_NAME 	"GT.M V6.1-000 Linux x86"
 #endif
 #define GTM_PRODUCT 		"GT.M"
-#define GTM_VERSION		"V6.0"
+#define GTM_VERSION		"V6.1"
diff --git a/sr_port/act_in_gvt.c b/sr_port/act_in_gvt.c
index c4b6bb7..66a4d97 100644
--- a/sr_port/act_in_gvt.c
+++ b/sr_port/act_in_gvt.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,6 +10,7 @@
  ****************************************************************/
 
 #include "mdef.h"
+
 #include "gdsroot.h"
 #include "gtm_facility.h"
 #include "fileinfo.h"
@@ -23,36 +24,32 @@
 #include "gv_trigger.h"
 #endif
 
-GBLREF gv_namehead	*gv_target;
-GBLREF gv_key		*gv_altkey;
+error_def(ERR_COLLATIONUNDEF);
+error_def(ERR_COLLTYPVERSION);
+error_def(ERR_GVIS);
 
-void act_in_gvt(void)
+void act_in_gvt(gv_namehead *gvt)
 {
 	collseq		*csp;
-	error_def(ERR_COLLATIONUNDEF);
-	error_def(ERR_COLLTYPVERSION);
-	error_def(ERR_GVIS);
 
 #	ifdef GTM_TRIGGER
-	if ((HASHT_GBLNAME_LEN == gv_target->gvname.var_name.len) &&
-			(0 == MEMCMP_LIT(gv_target->gvname.var_name.addr, HASHT_GBLNAME)))
+	if (IS_MNAME_HASHT_GBLNAME(gvt->gvname.var_name))
 		return;		/* No collation for triggers */
 #	endif
-	if (csp = ready_collseq((int)(gv_target->act)))
+	if (csp = ready_collseq((int)(gvt->act)))	/* WARNING: ASSIGNMENT */
 	{
-		if (!do_verify(csp, gv_target->act, gv_target->ver))
+		if (!do_verify(csp, gvt->act, gvt->ver))
 		{
-			gv_target->root = 0;
-			rts_error(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, gv_target->act, gv_target->ver,
-				ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
+			gvt->root = 0;
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_COLLTYPVERSION, 2, gvt->act, gvt->ver,
+				ERR_GVIS, 2, gvt->gvname.var_name.len, gvt->gvname.var_name.addr);
 		}
-	}
-	else
+	} else
 	{
-		gv_target->root = 0;
-		rts_error(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, gv_target->act,
-			ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
+		gvt->root = 0;
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, gvt->act,
+				ERR_GVIS, 2, gvt->gvname.var_name.len, gvt->gvname.var_name.addr);
 	}
-	gv_target->collseq = csp;
+	gvt->collseq = csp;
 	return;
 }
diff --git a/sr_port/alias_funcs.c b/sr_port/alias_funcs.c
index a0f5c0d..1c099a3 100644
--- a/sr_port/alias_funcs.c
+++ b/sr_port/alias_funcs.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -323,7 +323,7 @@ void als_lsymtab_repair(hash_table_mname *table, ht_ent_mname *table_base_orig,
 /* Local routine! condition handler whose sole function is to turn off the flag that says we are in "als_check_xnew_var_alias" */
 CONDITION_HANDLER(als_check_xnew_var_aliases_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	suspend_lvgcol = FALSE;
 	NEXTCH;
 }
diff --git a/sr_port/anticipatory_freeze.h b/sr_port/anticipatory_freeze.h
index ef51450..13a66fd 100644
--- a/sr_port/anticipatory_freeze.h
+++ b/sr_port/anticipatory_freeze.h
@@ -42,16 +42,15 @@ GBLREF	boolean_t				mupip_jnl_recover;
 GBLREF	uint4	  				lseekwrite_target;
 #endif
 
+error_def(ERR_DSKNOSPCAVAIL);
 error_def(ERR_MUINSTFROZEN);
 error_def(ERR_MUINSTUNFROZEN);
-
 error_def(ERR_MUNOACTION);
 error_def(ERR_REPLINSTFREEZECOMMENT);
 error_def(ERR_REPLINSTFROZEN);
 error_def(ERR_REPLINSTUNFROZEN);
 error_def(ERR_TEXT);
 
-
 #define ENABLE_FREEZE_ON_ERROR											\
 {														\
 	if (ANTICIPATORY_FREEZE_AVAILABLE)									\
@@ -118,9 +117,12 @@ error_def(ERR_TEXT);
 								&& ((REPL_ALLOWED(((sgmnt_addrs *)CSA)->hdr))			\
 							    		|| mupip_jnl_recover	/* recover or rollback */	\
 									|| ((sgmnt_addrs *)CSA)->nl->onln_rlbk_pid )))
-#define ANTICIPATORY_FREEZE_ENABLED(CSA)	(INSTANCE_FREEZE_HONORED(CSA)				\
+#define INST_FREEZE_ON_ERROR_ENABLED(CSA)	(INSTANCE_FREEZE_HONORED(CSA)				\
 							&& ANTICIPATORY_FREEZE_AVAILABLE		\
 							&& (((sgmnt_addrs *)CSA)->hdr->freeze_on_fail))
+#define INST_FREEZE_ON_NOSPC_ENABLED(CSA)	(INST_FREEZE_ON_ERROR_ENABLED(CSA)						\
+							&& (NULL != is_anticipatory_freeze_needed_fnptr)			\
+							&& (*is_anticipatory_freeze_needed_fnptr)(CSA, ERR_DSKNOSPCAVAIL))
 #define IS_REPL_INST_FROZEN			((NULL != jnlpool.jnlpool_ctl) && jnlpool.jnlpool_ctl->freeze)
 #define IS_REPL_INST_UNFROZEN			((NULL != jnlpool.jnlpool_ctl) && !jnlpool.jnlpool_ctl->freeze)
 
@@ -147,7 +149,7 @@ error_def(ERR_TEXT);
 /* This is a version of the macro which waits for the instance freeze to be lifted off assuming the process has
  * already attached to the journal pool. We need to wait for the freeze only if the input database cares about
  * anticipatory freeze. Examples of those databases that dont care are non-replicated databases, databases with
- * "freeze_on_fail" field set to FALSE in the file header etc. Hence the use of ANTICIPATORY_FREEZE_ENABLED below.
+ * "freeze_on_fail" field set to FALSE in the file header etc. Hence the use of INST_FREEZE_ON_ERROR_ENABLED below.
  * Note: Do not use "hiber_start" as that uses timers and if we are already in a timer handler now, nested timers
  * wont work. Since SHORT_SLEEP allows a max of 1000, we use 500 (half a second) for now.
  */
@@ -195,7 +197,7 @@ error_def(ERR_TEXT);
 #define	WAIT_FOR_REPL_INST_UNFREEZE_NOCSA						\
 {											\
 	GBLREF	jnlpool_addrs	jnlpool;						\
-	GBLREF	volatile int4	exit_state;						\
+	GBLREF	int4		exit_state;						\
 	GBLREF	int4		exi_condition;						\
 	GBLREF	int4		forced_exit_err;					\
 											\
@@ -335,7 +337,7 @@ void clear_fake_enospc_if_master_dead(void);
 
 #else	/* #ifdef UNIX */
 #	define ANTICIPATORY_FREEZE_AVAILABLE			FALSE
-#	define ANTICIPATORY_FREEZE_ENABLED(CSA)			FALSE
+#	define INST_FREEZE_ON_ERROR_ENABLED(CSA)		FALSE
 #	define REPL_INST_AVAILABLE				FALSE
 #	define WAIT_FOR_REPL_INST_UNFREEZE
 #	define WAIT_FOR_REPL_INST_UNFREEZE_SAFE
diff --git a/sr_port/buddy_list.h b/sr_port/buddy_list.h
index fa5b374..a99a8b4 100644
--- a/sr_port/buddy_list.h
+++ b/sr_port/buddy_list.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -52,7 +52,7 @@ boolean_t	free_last_n_elements(buddy_list *list, int4 num);	/* to free up the la
 void		free_element(buddy_list *list, char *elem);	/* to free up an element and reuse it later */
 char		*get_new_free_element(buddy_list *list);	/* gets a freed-up element if available otherwise gets a new one */
 
-#define	CAREFUL_FREEUP_BUDDY_LIST(list)		\
+#define	PROBE_FREEUP_BUDDY_LIST(list)		\
 {						\
 	if (NULL != list)			\
 		FREEUP_BUDDY_LIST(list);	\
diff --git a/sr_port/cdbg_dump.c b/sr_port/cdbg_dump.c
index 7d3bf5d..e2194d0 100644
--- a/sr_port/cdbg_dump.c
+++ b/sr_port/cdbg_dump.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -23,6 +23,7 @@
 #include "cache.h"
 #include "gtmio.h"
 #include "have_crit.h"
+#include "mdq.h"
 
 LITDEF char *oprtype_names[] =
 {
@@ -74,6 +75,7 @@ GBLREF char	*oc_tab_graphic[];
 GBLREF spdesc	indr_stringpool;
 GBLREF int4	sa_temps_offset[];
 GBLREF int4	sa_temps[];
+GBLREF triple	t_orig;			/* head of triples */
 
 LITREF int4	sa_class_sizes[];
 
@@ -81,6 +83,19 @@ LITREF int4	sa_class_sizes[];
 STATICDEF char	*indent_str;
 STATICDEF int	last_indent = 0;
 
+/* Routine to dump all triples on the current chain - also callable from debugger */
+void cdbg_dump_triple_all(void)
+{
+	triple	*ct;
+
+	dqloop(&t_orig, exorder, ct)
+	{
+		PRINTF("\n ************************ Triple Start **********************\n");
+		cdbg_dump_triple(ct, 0);
+	}
+}
+
+/* Routine to dump a single triple and its followers */
 void cdbg_dump_triple(triple *dtrip, int indent)
 {
 	int		len;
@@ -105,6 +120,7 @@ void cdbg_dump_triple(triple *dtrip, int indent)
 	FFLUSH(stdout);
 }
 
+/* Routine to dump a triple that's been shrunken(?) by shrink_trips() */
 void cdbg_dump_shrunk_triple(triple *dtrip, int old_size, int new_size)
 {
 	PRINTF("Shrunken triple %s [0x"lvaddr"]   fwdptr: 0x"lvaddr"   bkwdptr: 0x"lvaddr"  srcline: %d  colmn: %d  rtaddr: %d\n",
@@ -114,6 +130,7 @@ void cdbg_dump_shrunk_triple(triple *dtrip, int old_size, int new_size)
 	FFLUSH(stdout);
 }
 
+/* Routine to dump a triple operand (note possible recursion) */
 void cdbg_dump_operand(int indent, oprtype *opr, int opnum)
 {
 	triple	*rtrip;
@@ -152,7 +169,7 @@ void cdbg_dump_operand(int indent, oprtype *opr, int opnum)
 				       (long unsigned int) opr->oprval.vref->rson, opr->oprval.vref->mvidx,
 				       cdbg_makstr(opr->oprval.vref->mvname.addr, &buff, opr->oprval.vref->mvname.len),
 				       (long unsigned int) opr->oprval.vref->last_fetch);
-				free(buff);
+				free(buff);	/* allocated by cdbg_makstr */
 			}
 			else
 				PRINTF("%s   ** Warning ** oprval.vref is NULL\n", cdbg_indent(indent));
@@ -230,6 +247,9 @@ void cdbg_dump_operand(int indent, oprtype *opr, int opnum)
 	FFLUSH(stdout);
 }
 
+/* Routine to dump a literal mval - note strings that either aren't setup completely yet or contain $ZCHAR() type
+ * data can come out as garbage. Improvement would be to print value in $ZWRITE() format.
+ */
 void cdbg_dump_mval(int indent, mval *mv)
 {
 	boolean_t	first;
@@ -318,13 +338,12 @@ char *cdbg_indent(int indent)
 {
 	if (10 >= indent)
 		return (char *)indents[indent];
-
 	if (NULL == indent_str)
 		indent_str = malloc(MAX_INDENT);
-	if (MAX_INDENT < indent * 2)
+	if (MAX_INDENT < (indent * 2))
 	{
 		FFLUSH(stdout);
-		GTMASSERT;
+		assertpro(MAX_INDENT < (indent * 2));
 	}
 	if (indent > last_indent)
 		memset(indent_str, ' ', indent * 2);
diff --git a/sr_port/cdbg_dump.h b/sr_port/cdbg_dump.h
index 8255836..8fe6eb3 100644
--- a/sr_port/cdbg_dump.h
+++ b/sr_port/cdbg_dump.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -17,6 +17,7 @@
 #define OP_1 1		/* operand[1] is passed */
 #define OP_DEST 2	/* destination is passed */
 
+void cdbg_dump_triple_all(void);
 void cdbg_dump_triple(triple *dtrip, int indent);
 void cdbg_dump_shrunk_triple(triple *dtrip, int old_size, int new_size);
 void cdbg_dump_operand(int indent, oprtype *opr, int opnum);
diff --git a/sr_port/collseq.h b/sr_port/collseq.h
index 3a64d28..3cfec12 100644
--- a/sr_port/collseq.h
+++ b/sr_port/collseq.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,11 +42,13 @@
 		TREF(lcl_coll_xform_buff) = (char *)malloc(TREF(max_lcl_coll_xform_bufsiz));		\
 	}												\
 }
-/*
-   Following two macros are currently used in replication filters, merge command  and binary load to transform
-   GTM null subscripts collation to standard null subscript collation and vice versa
-*/
 
+#define	STD_NULL_COLL_FALSE	FALSE
+#define	STD_NULL_COLL_TRUE	TRUE
+
+/* Following two macros are currently used in replication filters, merge command  and binary load to transform
+ * GTM null subscripts collation to standard null subscript collation and vice versa
+ */
 #define GTM2STDNULLCOLL(key, len)							\
 {											\
 	unsigned char *currptr, *ptrtop;						\
@@ -96,6 +98,5 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq);
 collseq *ready_collseq(int act);
 int4 do_verify(collseq *csp, unsigned char type, unsigned char ver);
 int find_local_colltype(void);
-void act_in_gvt(void);
 
 #endif /* COLLSEQ_H_INCLUDED */
diff --git a/sr_port/compiler.h b/sr_port/compiler.h
index 21c378c..5aed7a0 100644
--- a/sr_port/compiler.h
+++ b/sr_port/compiler.h
@@ -11,6 +11,34 @@
 #ifndef COMPILER_H_INCLUDED
 #define COMPILER_H_INCLUDED
 
+/* Values for oprclass */
+typedef enum
+{
+	NO_REF,		/* 0 */
+	TVAR_REF,	/* 1 */
+	TVAL_REF,	/* 2 */
+	TINT_REF,	/* 3 */
+	TVAD_REF,	/* 4 */
+	TCAD_REF,	/* 5  - This and all _REFs before are VALUED_REF_TYPES (see alloc_reg.c) */
+	MLIT_REF,	/* 6 */
+	MVAR_REF,	/* 7 */
+	TRIP_REF,	/* 8 */
+	TNXT_REF,	/* 9  */
+	TJMP_REF,	/* 10 */
+	INDR_REF,	/* 11 */
+	MLAB_REF,	/* 12 */
+	ILIT_REF,	/* 13 */
+	CDLT_REF,	/* 14 */
+	TEMP_REF,	/* 15 */
+	MFUN_REF,	/* 16 */
+	MNXL_REF,	/* 17 refer to internalentry of child line */
+	TSIZ_REF,	/* 18 ilit refering to size of given triple codegen */
+	OCNT_REF	/* 19 Offset from Call to Next Triple */
+} operclass;
+#define VALUED_REF_TYPES 6	/* Types 0-6 are specific types used by alloc_reg() in array references
+				 * **** WARNING **** Do NOT reorder
+				 */
+
 typedef unsigned int	opctype;
 
 typedef struct	mvarstruct
@@ -69,7 +97,7 @@ typedef struct	triplesize
 
 typedef struct	oprtypestruct
 {
-	char			oprclass;
+	operclass		oprclass;
 	union
 	{
 		struct	oprtypestruct	*indr;
@@ -87,31 +115,6 @@ typedef struct	oprtypestruct
 	} oprval;
 } oprtype;
 
-/* Values for oprclass */
-#define NO_REF		0
-#define TVAR_REF	1
-#define TVAL_REF	2
-#define TINT_REF	3
-#define TVAD_REF	4
-#define TCAD_REF	5
-#define VALUED_REF_TYPES 6
-#define VREG_REF	6
-#define MLIT_REF	7
-#define MVAR_REF	8
-#define TRIP_REF	9
-#define TNXT_REF	10
-#define TJMP_REF	11
-#define INDR_REF	12
-#define MLAB_REF	13
-#define ILIT_REF	14
-#define CDLT_REF	15
-#define TEMP_REF	16
-#define MFUN_REF	17
-#define MNXL_REF	18	/* refer to internalentry of child line */
-#define TSIZ_REF	19	/* ilit refering to size of given triple codegen */
-#define OCNT_REF	20	/* Offset from Call to Next Triple */
-
-
 typedef struct	tbptype
 {
 	struct
@@ -309,28 +312,6 @@ error_def(ERR_SVNOSET);
 	COMPLITS_HASHTAB_CLEANUP;	\
 	COMPSYMS_HASHTAB_CLEANUP;
 
-/* Macro to compute running checksum of a routine one line at a time. */
-#define RTN_SRC_CHKSUM(srcptr, srclen, chksum)								\
-{													\
-	char	*chkcalc, *cptr;									\
-	uint4	srcint;											\
-	for (chkcalc = srcptr, cptr = srcptr + srclen; chkcalc < cptr; )				\
-	{												\
-		srcint = 0;										\
-		if (INTCAST(cptr - chkcalc) < SIZEOF(uint4))						\
-		{											\
-			memcpy(&srcint, chkcalc, cptr - chkcalc);					\
-			chkcalc = cptr;		/* Stops loop after this iteration is complete */	\
-		} else											\
-		{											\
-			GET_ULONG(srcint, chkcalc);							\
-			chkcalc += SIZEOF(uint4);							\
-		}											\
-		chksum ^= srcint;									\
-		chksum >>= 1;										\
-	}												\
-}
-
 typedef struct
 {
 	triple		*expr_start;
@@ -504,6 +485,19 @@ typedef struct
 		--(TREF(for_stack_ptr));									\
 }
 
+/* $TEXT(+n^rtn) fetches from the most recently ZLINK'd version of rtn. $TEXT(+n) fetches from the currently executing version.
+ * The compiler converts $TEXT(+n) to $TEXT(+n^!), indicating at runtime $TEXT should fetch from the current executing routine.
+ * '!' is not a legal routine name character.
+ */
+#define CURRENT_RTN_STRING		"!"
+#define PUT_CURRENT_RTN			put_str(LIT_AND_LEN(CURRENT_RTN_STRING))
+/* Do we want the current routine? Return TRUE.
+ * Otherwise, return FALSE; we want the latest version of whichever routine name is specified.
+ */
+#define WANT_CURRENT_RTN_MSTR(S)	((STR_LIT_LEN(CURRENT_RTN_STRING) == (S)->len)	\
+						&& (0 == MEMCMP_LIT((S)->addr, CURRENT_RTN_STRING)))
+#define WANT_CURRENT_RTN(R)		WANT_CURRENT_RTN_MSTR(&(R)->str)
+
 int		actuallist(oprtype *opr);
 int		bool_expr(boolean_t op, oprtype *addr);
 void		bx_boolop(triple *t, boolean_t jmp_type_one, boolean_t jmp_to_next, boolean_t sense, oprtype *addr);
@@ -602,7 +596,7 @@ triple		*maketriple(opctype op);
 int		name_glvn(boolean_t gblvn, oprtype *a);
 triple		*newtriple(opctype op);
 int		nref(void);
-void		obj_code(uint4 src_lines, uint4 checksum);
+void		obj_code(uint4 src_lines, void *checksum_ctx);
 int		one_job_param(char **parptr);
 int		parse_until_rparen_or_space(void);
 oprtype		put_ocnt(void);
diff --git a/sr_port/compiler_ch.c b/sr_port/compiler_ch.c
index ea17702..6d6b8ad 100644
--- a/sr_port/compiler_ch.c
+++ b/sr_port/compiler_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -40,7 +40,7 @@ error_def(ERR_OUTOFSPACE);
 CONDITION_HANDLER(compiler_ch)
 {
 
-	START_CH;
+	START_CH(TRUE);
 	if (DUMPABLE)
 	{
 		NEXTCH;
diff --git a/sr_port/compiler_startup.c b/sr_port/compiler_startup.c
index 10ae217..abe5147 100644
--- a/sr_port/compiler_startup.c
+++ b/sr_port/compiler_startup.c
@@ -28,15 +28,14 @@
 #include "comp_esc.h"
 #include "resolve_blocks.h"
 #include "hashtab_str.h"
+#include <rtnhdr.h>
+#include "rtn_src_chksum.h"
 
 #define HOPELESS_COMPILE 128
 
 GBLREF short int source_column, source_line;
 
-/* ensure source_buffer is aligned on a int4 word boundary so that
- * we can calculate the checksum a longword at a time.
- */
-GBLREF int4 			aligned_source_buffer[MAX_SRCLINE / SIZEOF(int4) + 1];
+GBLREF unsigned char		source_file_name[];
 GBLREF unsigned char 		*source_buffer;
 GBLREF src_line_struct 		src_head;
 GBLREF triple			t_orig, *curr_fetch_trip, *curr_fetch_opr;
@@ -53,17 +52,18 @@ LITDEF char compile_terminated[] = "COMPILATION TERMINATED DUE TO EXCESS ERRORS"
 boolean_t compiler_startup(void)
 {
 #ifdef DEBUG
-	void		dumpall();
+	void			dumpall();
 #endif
-	boolean_t	compile_w_err;
-	unsigned char	err_buf[45];
-	unsigned char 	*cp, *cp2;
-	int		errknt;
-	int4            n;
-	uint4		checksum, line_count;
-	mlabel		*null_lab;
-	src_line_struct	*sl;
-	mident		null_mident;
+	boolean_t		compile_w_err;
+	unsigned char		err_buf[45];
+	unsigned char 		*cp, *cp2;
+	int			errknt;
+	int4			n;
+	uint4			line_count;
+	mlabel			*null_lab;
+	src_line_struct		*sl;
+	mident			null_mident;
+	gtm_rtn_src_chksum_ctx	checksum_ctx;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -87,12 +87,13 @@ boolean_t compiler_startup(void)
 	mstr_native_align = FALSE; /* TODO: remove this line and  uncomment the above line */
 	cg_phase = CGP_NOSTATE;
 	TREF(source_error_found) = errknt = 0;
-	if(!open_source_file())
+	if (!open_source_file())
 	{
 		mstr_native_align = save_mstr_native_align;
 		REVERT;
 		return FALSE;
 	}
+	rtn_src_chksum_init(&checksum_ctx);
 	cg_phase = CGP_PARSE;
 	if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
 	{
@@ -109,12 +110,14 @@ boolean_t compiler_startup(void)
 	curr_fetch_trip = curr_fetch_opr = newtriple(OC_LINEFETCH);
 	curr_fetch_count = 0;
 	TREF(code_generated) = FALSE;
-	checksum = 0;
 	line_count = 1;
 	for (source_line = 1;  errknt <= HOPELESS_COMPILE;  source_line++)
 	{
 		if (-1 == (n = read_source_file()))
 			break;
+		rtn_src_chksum_line(&checksum_ctx, source_buffer, n);
+		if ('\n' == source_buffer[n - 1])
+			source_buffer[n - 1] = '\0'; /* compiler doesn't like trailing newlines (gives SPOREOL errors) */
 		if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
 		{
 			if (cmd_qlf.qlf & CQ_MACHINE_CODE)
@@ -130,8 +133,6 @@ boolean_t compiler_startup(void)
 				list_line((char *)source_buffer);
 			}
 		}
-		/* calculate checksum */
-		RTN_SRC_CHKSUM((char *)source_buffer, n, checksum);
 		TREF(source_error_found) = 0;
 		lb_init();
 		if (cmd_qlf.qlf & CQ_CE_PREPROCESS)
@@ -142,6 +143,7 @@ boolean_t compiler_startup(void)
 			errknt++;
 		}
 	}
+	rtn_src_chksum_digest(&checksum_ctx);
 	close_source_file();
 	if (cmd_qlf.qlf & CQ_CE_PREPROCESS)
 		close_ceprep_file();
@@ -186,7 +188,7 @@ boolean_t compiler_startup(void)
 	}
 	if ((!errknt || compile_w_err) && (cmd_qlf.qlf & CQ_OBJECT || cmd_qlf.qlf & CQ_MACHINE_CODE))
 	{
-		obj_code(line_count, checksum);
+		obj_code(line_count, &checksum_ctx);
 		cg_phase = CGP_FINI;
 	}
 	if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
diff --git a/sr_port/cre_jnl_file.c b/sr_port/cre_jnl_file.c
index bcee9e2..2e7fc24 100644
--- a/sr_port/cre_jnl_file.c
+++ b/sr_port/cre_jnl_file.c
@@ -58,19 +58,23 @@
 	if (SS_NORMAL != info->status2)									\
 	{												\
 		if (IS_GTM_IMAGE)									\
-			send_msg(VARLSTCNT(12) ERR_JNLCRESTATUS, 7, CALLFROM, info->jnl_len, info->jnl,	\
-				info->fn_len, info->fn, info->status, 0, info->status2);		\
+			send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(12) ERR_JNLCRESTATUS, 7, CALLFROM,	\
+					info->jnl_len, info->jnl, info->fn_len, info->fn, info->status,	\
+					0, info->status2);						\
 		else											\
-			gtm_putmsg(VARLSTCNT1(11) ERR_JNLCRESTATUS, 7, CALLFROM, info->jnl_len, info->jnl,\
-				info->fn_len, info->fn, info->status, PUT_SYS_ERRNO(info->status2));	\
+			gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT1(11) ERR_JNLCRESTATUS, 7, CALLFROM,	\
+					info->jnl_len, info->jnl, info->fn_len, info->fn, info->status,	\
+					PUT_SYS_ERRNO(info->status2));					\
 	} else if (SS_NORMAL != info->status)								\
 	{												\
 		if (IS_GTM_IMAGE)									\
-			send_msg(VARLSTCNT(10) ERR_JNLCRESTATUS, 7, CALLFROM, info->jnl_len, 		\
-				info->jnl, info->fn_len, info->fn, info->status);			\
+			send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(10) ERR_JNLCRESTATUS, 7, CALLFROM,	\
+					info->jnl_len, info->jnl, info->fn_len, info->fn,		\
+					info->status);							\
 		else											\
-			gtm_putmsg(VARLSTCNT(10) ERR_JNLCRESTATUS, 7, CALLFROM, info->jnl_len, 		\
-				info->jnl, info->fn_len, info->fn, info->status);			\
+			gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT(10) ERR_JNLCRESTATUS, 7, CALLFROM,	\
+					info->jnl_len, info->jnl, info->fn_len, info->fn,		\
+					info->status);							\
 	}												\
 }
 #define RETURN_ON_ERROR(info)						\
@@ -135,9 +139,9 @@ uint4	cre_jnl_file(jnl_create_info *info)
 					return EXIT_ERR;
 				}
 				if (IS_GTM_IMAGE)
-					send_msg(VARLSTCNT(4) ERR_JNLFNF, 2, filestr.len, filestr.addr);
+					send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(4) ERR_JNLFNF, 2, filestr.len, filestr.addr);
 				else
-					gtm_putmsg(VARLSTCNT(4) ERR_JNLFNF, 2, filestr.len, filestr.addr);
+					gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT(4) ERR_JNLFNF, 2, filestr.len, filestr.addr);
 				no_rename = TRUE;
 			}
 			/* Note if info->no_prev_link == TRUE, we do not keep previous link, though rename can happen */
@@ -184,6 +188,7 @@ uint4 cre_jnl_file_common(jnl_create_info *info, char *rename_fn, int rename_fn_
 	int			fstat_res;
 	ZOS_ONLY(int		realfiletag;)
 	int			stat_res;
+	int			user_id;
 	int			group_id;
 	struct stat		sb;
 	int			perm;
@@ -248,24 +253,25 @@ uint4 cre_jnl_file_common(jnl_create_info *info, char *rename_fn, int rename_fn_
 	}
 	/* setup new group and permissions if indicated by the security rules.
 	 */
-	if (gtm_set_group_and_perm(&sb, &group_id, &perm, PERM_FILE, &pdd) < 0)
+	if (gtm_permissions(&sb, &user_id, &group_id, &perm, PERM_FILE, &pdd) < 0)
 	{
-		send_msg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+		send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 			ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("journal file"), RTS_ERROR_STRING(info->fn),
 			PERMGENDIAG_ARGS(pdd));
 		if (IS_GTM_IMAGE)
-			rts_error(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+			rts_error_csa(CSA_ARG(info->csa) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 				ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("journal file"), RTS_ERROR_STRING(info->fn),
 				PERMGENDIAG_ARGS(pdd));
 		else
-			gtm_putmsg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+			gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 				ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("journal file"), RTS_ERROR_STRING(info->fn),
 				PERMGENDIAG_ARGS(pdd));
 		F_CLOSE(channel, status);
 		return EXIT_ERR;
 	}
 	/* if group not the same then change group of temporary file */
-	if ((-1 != group_id) && (group_id != stat_buf.st_gid) && (-1 == fchown(channel, -1, group_id)))
+	if ((((-1 != user_id) && (user_id != stat_buf.st_uid)) || ((-1 != group_id) && (group_id != stat_buf.st_gid)))
+		&& (-1 == fchown(channel, user_id, group_id)))
 	{
 		info->status = errno;
 		STATUS_MSG(info);
@@ -479,9 +485,11 @@ uint4 cre_jnl_file_common(jnl_create_info *info, char *rename_fn, int rename_fn_
 						    (char *)rename_fn, rename_fn_len, &info->status2)))
 	{
 		if (IS_GTM_IMAGE)
-			send_msg(VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
+			send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len,
+					rename_fn);
 		else
-			gtm_putmsg(VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
+			gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len,
+					rename_fn);
 		STATUS_MSG(info);
 		return EXIT_ERR;
 	}
@@ -493,23 +501,27 @@ uint4 cre_jnl_file_common(jnl_create_info *info, char *rename_fn, int rename_fn_
 						     (char *)info->jnl, (int)info->jnl_len, &info->status2)))
 	{
 		if (IS_GTM_IMAGE)
-			send_msg(VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
+			send_msg_csa(CSA_ARG(info->csa) VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len,
+					rename_fn);
 		else
-			gtm_putmsg(VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
+			gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT(6) ERR_RENAMEFAIL, 4, info->jnl_len, info->jnl, rename_fn_len,
+					rename_fn);
 		STATUS_MSG(info);
 		return EXIT_ERR;
 	}
 	if (IS_GTM_IMAGE)
-		send_msg(VARLSTCNT (6) ERR_FILERENAME, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
+		send_msg_csa(CSA_ARG(info->csa) VARLSTCNT (6) ERR_FILERENAME, 4, info->jnl_len, info->jnl, rename_fn_len,
+				rename_fn);
 	else
-		gtm_putmsg(VARLSTCNT (6) ERR_FILERENAME, 4, info->jnl_len, info->jnl, rename_fn_len, rename_fn);
-	DEBUG_ONLY(
+		gtm_putmsg_csa(CSA_ARG(info->csa) VARLSTCNT (6) ERR_FILERENAME, 4, info->jnl_len, info->jnl, rename_fn_len,
+				rename_fn);
+#		ifdef DEBUG
 		if (gtm_white_box_test_case_enabled && (WBTEST_JNL_CREATE_INTERRUPT == gtm_white_box_test_case_number))
 		{
 			UNIX_ONLY(DBGFPF((stderr, "CRE_JNL_FILE: started a wait\n")));	/* this white-box test is for UNIX */
 			LONG_SLEEP(600);
 			assert(FALSE); /* Should be killed before that */
 		}
-	)
+#		endif
 	return EXIT_NRM;
 }
diff --git a/sr_port/cre_private_code_copy.c b/sr_port/cre_private_code_copy.c
index ff89a73..57a3bcd 100644
--- a/sr_port/cre_private_code_copy.c
+++ b/sr_port/cre_private_code_copy.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2002, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2002, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,11 +20,12 @@
 #include "gtm_text_alloc.h"
 #include "gtm_string.h"
 
+error_def(UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY);)
+
 CONDITION_HANDLER(cre_priv_ch)
 {
-	error_def(UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY);)
 
-	START_CH;
+	START_CH(TRUE);
 	if (SIGNAL == UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY))
 	{
 		UNWIND(NULL, NULL); /* ignore "lack-of-memory" error, rather not set breakpoint than error out in such a case */
@@ -37,8 +38,6 @@ uint4 cre_private_code_copy(rhdtyp *rtn)
 	unsigned char	*new_ptext;
 	int		code_size;
 
-	error_def(UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY);)
-
 #ifdef USHBIN_SUPPORTED
 		assert(NULL != rtn->shlib_handle); /* don't need private copy if not shared */
 		assert(NULL == rtn->shared_ptext_adr); /* if already private, we shouldn't be calling this routine */
diff --git a/sr_port/create_dummy_gbldir.c b/sr_port/create_dummy_gbldir.c
index 4741588..7339081 100644
--- a/sr_port/create_dummy_gbldir.c
+++ b/sr_port/create_dummy_gbldir.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,18 +29,6 @@
 #include "hashtab_mname.h"
 #include "hashtab.h"
 
-#ifdef GTM64
-#define SAVE_ADDR_REGION			\
-{						\
-	int4 *tmp = (int *)&(addr->regions);	\
-	*int4_ptr++ = *tmp;			\
-	int4_ptr++;				\
-}
-#else /* GTM64 */
-#define SAVE_ADDR_REGION			\
-	*int4_ptr++ = (int4)addr->regions;
-#endif /* GTM64 */
-
 static gdr_name	*gdr_name_head;
 
 gd_addr *create_dummy_gbldir(void)
@@ -48,78 +36,13 @@ gd_addr *create_dummy_gbldir(void)
 	header_struct	*header;
 	gd_addr		*addr;
 	gdr_name	*name;
-	gd_binding	*map, *map_top;
 	gd_region	*region;
 	gd_region	*region_top;
 	gd_segment	*segment;
-	int4		*int4_ptr;
-	uint4		t_offset, size;
-
-	size = SIZEOF(header_struct) + SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding) + 1 * SIZEOF(gd_region) + 1 * SIZEOF(gd_segment);
-	header = (header_struct *)malloc(ROUND_UP(size, DISK_BLOCK_SIZE));
-	memset(header, 0, ROUND_UP(size, DISK_BLOCK_SIZE));
-	header->filesize = size;
-	size = ROUND_UP(size, DISK_BLOCK_SIZE);
-	memcpy(header->label, GDE_LABEL_LITERAL, SIZEOF(GDE_LABEL_LITERAL));
-	addr = (gd_addr *)((char *)header + SIZEOF(header_struct));
-	addr->max_rec_size = 256;
-	addr->maps = (gd_binding*)((UINTPTR_T)addr + SIZEOF(gd_addr));
-	addr->n_maps = 3;
-	addr->regions = (gd_region*)((INTPTR_T)(addr->maps) + 3 * SIZEOF(gd_binding));
-	addr->n_regions = 1;
-	addr->segments = (gd_segment*)((INTPTR_T)(addr->regions) + SIZEOF(gd_region));
-	addr->n_segments = 1;
-	addr->link = 0;
-	addr->tab_ptr = 0;
-	addr->id = 0;
-	addr->local_locks = 0;
-	addr->end = (UINTPTR_T)(addr->segments + 1 * SIZEOF(gd_segment));
-	int4_ptr = (int4*)(addr->maps);
-	*int4_ptr++ = 0x232FFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	*int4_ptr++ = 0x24FFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	region = (gd_region*)(addr->regions);
-	segment = (gd_segment*)(addr->segments);
-	region->rname_len = 7;
-	memcpy(region->rname,"DEFAULT",7);
+	uint4		size;
 
-	for (map = addr->maps, map_top = map + addr->n_maps; map < map_top ; map++)
-	{
-		t_offset = map->reg.offset;
-		map->reg.addr = (gd_region *)((char *)addr + t_offset);
-	}
-	for (region = addr->regions, region_top = region + addr->n_regions; region < region_top ; region++)
-	{
-		t_offset = region->dyn.offset;
-		region->dyn.addr = (gd_segment *)((char *)addr + t_offset);
-	}
-	/* Should be using gd_id_ptr_t below, but ok for now since malloc won't return > 4G
-	 * and since addr->id is a 4-byte pointer only until we change the format of the global directory.
-	 */
+	DUMMY_GLD_INIT(header, addr, region, segment, size, RELATIVE_OFFSET_FALSE);
+		/* the above macro invocation initializes "header", "addr", "region", "segment" and "size" */
 	addr->id = (gd_id *)malloc(SIZEOF(gd_id));
 	memset(addr->id, 0, SIZEOF(gd_id));
 
diff --git a/sr_port/dbcertify_base_ch.c b/sr_port/dbcertify_base_ch.c
index 1c8b522..09fbd1f 100644
--- a/sr_port/dbcertify_base_ch.c
+++ b/sr_port/dbcertify_base_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2005, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2005, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -59,43 +59,41 @@ CONDITION_HANDLER(dbcertify_base_ch)
 		$DESCRIPTOR(msgbuf, msg_buff);
 	)
 
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
-	if (SUCCESS == SEVERITY || INFO == SEVERITY)
-	{
-		CONTINUE;
-	} else
-	{
-		UNIX_ONLY(
-			if ((DUMPABLE) && !SUPPRESS_DUMP)
-			{
-				need_core = TRUE;
-				gtm_fork_n_core();
-			}
-			/* rts_error sets error_condition, and dbcertify_base_ch is called only if
-			 * exiting thru rts_error. Setup exi_condition to reflect error
-			 * exit status. Note, if the last eight bits (the only relevant bits
-			 * for Unix exit status) of error_condition is non-zero in case of
-			 * errors, we make sure that an error exit status (non-zero value -1)
-			 * is setup. This is a hack.
-			 */
-			if (0 == exi_condition)
-				exi_condition = (((error_condition & UNIX_EXIT_STATUS_MASK) != 0) ? error_condition : -1);
-		)
-		VMS_ONLY(
-			if ((DUMPABLE) && !SUPPRESS_DUMP)
-			{
-				gtm_dump();
-				TERMINATE;
-			}
-			exi_condition = SIGNAL;
-			/* following is a hack to avoid FAO directives getting printed without expanding
-			 * in the error message during EXIT()
-			 */
-			if (IS_GTM_ERROR(SIGNAL))
-			        exi_condition = ERR_DBCNOFINISH;
-		)
-		UNSUPPORTED_PLATFORM_CHECK;
-		EXIT(exi_condition);
-	}
+	UNIX_ONLY(
+		if ((DUMPABLE) && !SUPPRESS_DUMP)
+		{
+			need_core = TRUE;
+			gtm_fork_n_core();
+		}
+		/* rts_error sets error_condition, and dbcertify_base_ch is called only if
+		 * exiting thru rts_error. Setup exi_condition to reflect error
+		 * exit status. Note, if the last eight bits (the only relevant bits
+		 * for Unix exit status) of error_condition is non-zero in case of
+		 * errors, we make sure that an error exit status (non-zero value -1)
+		 * is setup. This is a hack.
+		 */
+		if (0 == exi_condition)
+			exi_condition = (((error_condition & UNIX_EXIT_STATUS_MASK) != 0) ? error_condition : -1);
+	)
+	VMS_ONLY(
+		if (SUCCESS == SEVERITY || INFO == SEVERITY)
+		{
+			CONTINUE;
+		}
+		if ((DUMPABLE) && !SUPPRESS_DUMP)
+		{
+			gtm_dump();
+			TERMINATE;
+		}
+		exi_condition = SIGNAL;
+		/* following is a hack to avoid FAO directives getting printed without expanding
+		 * in the error message during EXIT()
+		 */
+		if (IS_GTM_ERROR(SIGNAL))
+		        exi_condition = ERR_DBCNOFINISH;
+	)
+	UNSUPPORTED_PLATFORM_CHECK;
+	EXIT(exi_condition);
 }
diff --git a/sr_port/dbcertify_scan_phase.c b/sr_port/dbcertify_scan_phase.c
index 10cada3..ba74a7c 100644
--- a/sr_port/dbcertify_scan_phase.c
+++ b/sr_port/dbcertify_scan_phase.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2005, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2005, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -203,7 +203,8 @@ void dbcertify_scan_phase(void)
 			memcpy(badfn, dbfn, len);
 			badfn[len] = 0;
 			strcat((char_ptr_t)badfn, DEFAULT_OUTFILE_SUFFIX);
-			rts_error(VARLSTCNT(6) ERR_FILENAMETOOLONG, 0, ERR_TEXT, 2, RTS_ERROR_STRING((char_ptr_t)badfn));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_FILENAMETOOLONG, 0,
+						ERR_TEXT, 2, RTS_ERROR_STRING((char_ptr_t)badfn));
 		}
 		strcpy((char_ptr_t)psa->outfn, (char_ptr_t)dbfn);
 		strcat((char_ptr_t)psa->outfn, DEFAULT_OUTFILE_SUFFIX);
@@ -211,7 +212,7 @@ void dbcertify_scan_phase(void)
 	/* Build data structures and open database */
 	MALLOC_INIT(psa->dbc_gv_cur_region, SIZEOF(gd_region));
 	MALLOC_INIT(psa->dbc_gv_cur_region->dyn.addr, SIZEOF(gd_segment));
-	psa->dbc_gv_cur_region->dyn.addr->acc_meth = dba_bg;
+	REG_ACC_METH(psa->dbc_gv_cur_region) = dba_bg;
 	len = strlen((char_ptr_t)dbfn);
 	strcpy((char_ptr_t)psa->dbc_gv_cur_region->dyn.addr->fname, (char_ptr_t)dbfn);
 	psa->dbc_gv_cur_region->dyn.addr->fname_len = (unsigned short)len;
@@ -228,14 +229,15 @@ void dbcertify_scan_phase(void)
 	max_max_rec_size = psa->dbc_cs_data->blk_size - SIZEOF(blk_hdr);
 	if (VMS_ONLY(9) UNIX_ONLY(8) > psa->dbc_cs_data->reserved_bytes)
 	{
-		gtm_putmsg(VARLSTCNT(4) ERR_DBMINRESBYTES, 2, VMS_ONLY(9) UNIX_ONLY(8), psa->dbc_cs_data->reserved_bytes);
+		gtm_putmsg_csa(CSA_ARG(NULL)
+			VARLSTCNT(4) ERR_DBMINRESBYTES, 2, VMS_ONLY(9) UNIX_ONLY(8), psa->dbc_cs_data->reserved_bytes);
 		if (!psa->report_only)
 			exit(SS_NORMAL - 1);	/* Gives -1 on UNIX (failure) and 0 on VMS (failure) */
 	}
 	if (psa->dbc_cs_data->max_rec_size > max_max_rec_size)
 	{
-		gtm_putmsg(VARLSTCNT(5) ERR_DBMAXREC2BIG, 3, psa->dbc_cs_data->max_rec_size, psa->dbc_cs_data->blk_size,
-			  max_max_rec_size);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_DBMAXREC2BIG, 3,
+			psa->dbc_cs_data->max_rec_size, psa->dbc_cs_data->blk_size, max_max_rec_size);
 		if (!psa->report_only)
 			exit(SS_NORMAL - 1);
 	}
@@ -249,7 +251,7 @@ void dbcertify_scan_phase(void)
 		{	/* The following STRERROR() extraction necessary for VMS portability */
 			save_errno = errno;
 			errmsg = STRERROR(save_errno);
-			rts_error(VARLSTCNT(8) ERR_DEVOPENFAIL, 2, RTS_ERROR_STRING((char_ptr_t)psa->outfn),
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DEVOPENFAIL, 2, RTS_ERROR_STRING((char_ptr_t)psa->outfn),
 				  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 		}
 #	ifdef __MVS__
@@ -348,7 +350,7 @@ void dbcertify_scan_phase(void)
 		{
 			save_errno = errno;
 			errmsg = STRERROR(save_errno);
-			rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("lseek()"), CALLFROM,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("lseek()"), CALLFROM,
 				  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 		}
 		psa->ofhdr.tn = psa->dbc_cs_data->trans_hist.curr_tn;
@@ -371,7 +373,7 @@ void dbcertify_scan_phase(void)
 		{
 			save_errno = errno;
 			errmsg = STRERROR(save_errno);
-			rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
 				  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 		}
 	}
@@ -435,7 +437,7 @@ void dbc_write_p1out(phase_static_area *psa, void *obuf, int olen)
 	{
 		save_errno = errno;
 		errmsg = STRERROR(save_errno);
-		rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
 			  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 	}
 }
@@ -513,7 +515,7 @@ void dbc_process_block(phase_static_area *psa, int blk_num, gtm_off_t dbptr)
 				assert(0 == ((v15_blk_hdr_ptr_t)psa->block_buff)->levl);
 				psa->gvtlvl0++;
 				key_ptr = dbc_format_key(psa, rec_ptr);	/* Text representation of the key */
-				gtm_putmsg(VARLSTCNT(9) ERR_DBCREC2BIG, 7,
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_DBCREC2BIG, 7,
 					   RTS_ERROR_STRING((char_ptr_t)key_ptr), rec_len,
 					   blk_num, psa->dbc_cs_data->max_rec_size,
 					   psa->dbc_gv_cur_region->dyn.addr->fname_len,
@@ -525,15 +527,17 @@ void dbc_process_block(phase_static_area *psa, int blk_num, gtm_off_t dbptr)
 					{
 						save_errno = errno;
 						errmsg = STRERROR(save_errno);
-						rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
-							  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
+						rts_error_csa(CSA_ARG(NULL)
+							VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
+							ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 					}
 					if (-1 == remove((char_ptr_t)psa->outfn))
 					{	/* Delete bogus output file */
 						save_errno = errno;
 						errmsg = STRERROR(save_errno);
-						rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("remove()"), CALLFROM,
-							  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
+						rts_error_csa(CSA_ARG(NULL)
+							VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("remove()"), CALLFROM,
+							ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 					}
 					psa->report_only = TRUE; /* No more writing to output file */
 				}
@@ -715,14 +719,14 @@ void dbc_integ_error(phase_static_area *psa, block_id blk_num, char_ptr_t emsg)
 			{
 				save_errno = errno;
 				errmsg = STRERROR(save_errno);
-				rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM,
 					  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 			}
 			if (-1 == remove((char_ptr_t)psa->outfn))
 			{	/* Delete bogus output file */
 				save_errno = errno;
 				errmsg = STRERROR(save_errno);
-				rts_error(VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("remove()"), CALLFROM,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(11) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("remove()"), CALLFROM,
 					  ERR_TEXT, 2, RTS_ERROR_STRING(errmsg));
 			}
 			psa->report_only = TRUE; /* No more writing to output file */
@@ -733,7 +737,7 @@ void dbc_integ_error(phase_static_area *psa, block_id blk_num, char_ptr_t emsg)
 		len = strlen((char_ptr_t)intgerrmsg);
 		i2hex(blk_num, &intgerrmsg[len], 8);
 		intgerrmsg[len + 8] = 0;
-		rts_error(VARLSTCNT(8) ERR_DBCINTEGERR, 2, RTS_ERROR_STRING((char_ptr_t)psa->ofhdr.dbfn),
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DBCINTEGERR, 2, RTS_ERROR_STRING((char_ptr_t)psa->ofhdr.dbfn),
 			  ERR_TEXT, 2, RTS_ERROR_STRING((char_ptr_t)intgerrmsg));
 	}
 }
@@ -796,7 +800,7 @@ uchar_ptr_t dbc_format_key(phase_static_area *psa, uchar_ptr_t trec_p)
 	if (NULL == gv_target)
 	{
 		gv_target = malloc(SIZEOF(gv_namehead) + psa->dbc_cs_data->max_key_size);
-		gv_target->clue.prev = 0;
+		/* No need to initialize gv_target->clue.prev as it is not currently used */
 		gv_target->clue.top = psa->first_rec_key->top;
 	}
 	/* Copy our key to gv_target->clue since dbc_gv_key is somewhat different */
@@ -837,7 +841,7 @@ uchar_ptr_t dbc_format_key(phase_static_area *psa, uchar_ptr_t trec_p)
 		}
 		gv_altkey->end = psa->first_rec_key->gvn_len + 1;
 		memcpy(gv_altkey->base, psa->first_rec_key->base, psa->first_rec_key->gvn_len + 1);
-		act_in_gvt();
+		act_in_gvt(gv_target);
 	}
 	assert(gv_target->act || NULL == gv_target->collseq);
 	/* Format the resulting key into the result buffer which is sized appropriately for this task */
diff --git a/sr_port/deviceparameters.c b/sr_port/deviceparameters.c
index fddb059..96a5410 100644
--- a/sr_port/deviceparameters.c
+++ b/sr_port/deviceparameters.c
@@ -20,7 +20,7 @@
 #include "io_params.h"
 #include "zshow_params.h"
 #include "advancewindow.h"
-#include "namelook.h"
+#include "int_namelook.h"
 #include "cvtparm.h"
 #include "deviceparameters.h"
 
@@ -214,6 +214,7 @@ LITDEF nametabent dev_param_names[] =
 	,{2,"SY*"}
 
 	,{2,"TE*"}	,{4,"TERM"}
+	,{3,"TIM*"}
 	,{2,"TM*"}
 	,{3,"TRA*"}
 	,{3,"TRU*"}
@@ -262,16 +263,13 @@ LITDEF nametabent dev_param_names[] =
 	,{4,"ZWRA*"}
 };
 /* Offset of letter in dev_param_names */
-/* Following array has reached the maximum value limit(255) for its entry. Hence adddition of the next deviceparameter needs
- * to change this array to short or int. This will lead to change the interface to namelook() and the type of the first argument
- * passed to it. Once that is implemented, remove this comment.
- */
-LITDEF	unsigned char dev_param_index[27] =
+
+LITDEF	uint4 dev_param_index[27] =
 {
 /*	A    B    C    D    E    F    G    H    I    J    K    L    M    N   */
 	0,   5,   9,   26,  34,  49,  64,  66,  70,  76,  76,  76,  84,  87,
 /*	O    P    Q    R    S    T    U    V    W    X    Y    Z    end	     */
-	153, 158, 177, 178, 191, 209, 218, 224, 225, 240, 241, 242, 255
+	153, 158, 177, 178, 191, 209, 219, 225, 226, 241, 242, 243, 257
 };
 /* Offset of string within letter in dev_param_names */
 /* maintained in conjunction with zshow_params.h   = offset in letter, letter  */
@@ -288,7 +286,7 @@ LITDEF zshow_index zshow_param_index[] =
 /*	NOPAST   NOREADS  NOTTSY   NOTYPE   NOWRAP   OCHSET   PAD     PARSE   PAST     PRMMBX   RCHK    */
 	{39,13}, {44,13}, {55,13}, {57,13}, {63,13}, {1,14},  {8,15}, {11,15}, {13,15}, {17,15}, {1,17},
 /*      READ     READS	  REC      SHAR     SHELL    STDERR   TERM     TTSY     TYPE    UIC      WAIT     WCHK   */
-	{2,17},  {4,17},  {5,17},  {5,18},  {7,18},  {15,18},  {1,19},  {6,19},  {8,19}, {1,20},  {2,22},  {4,22},
+	{2,17},  {4,17},  {5,17},  {5,18},  {7,18},  {15,18},  {1,19},  {7,19},  {9,19}, {1,20},  {2,22},  {4,22},
 /*      WIDTH   WRITE  */
 	{6,22}, {10,22}
 };
@@ -375,7 +373,7 @@ int deviceparameters(oprtype *c, char who_calls)
 		,iop_label
 		,iop_lastpage
 		,iop_length ,iop_length
-		,iop_listen
+		,iop_zlisten			/* Replaces iop_listen. LISTEN is now aliased to ZLISTEN. */
 		,iop_logfile
 		,iop_logqueue
 		,iop_lowercase
@@ -490,6 +488,7 @@ int deviceparameters(oprtype *c, char who_calls)
 		,iop_s_protection
 
 		,iop_terminator, iop_terminator
+		,iop_timeout
 		,iop_tmpmbx
 		,iop_trailer
 		,iop_truncate
@@ -539,14 +538,9 @@ int deviceparameters(oprtype *c, char who_calls)
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	/* The value of dev_param_index[26] should be 256 but is 255 since that is all that can fit in a unsigned char. That is why
-	 * following asserts has (dev_param_index[26] + 1). Once the type of dev_param_index is changed, the "+ 1" in following
-	 * assert should be removed.
-	 */
-	assert((SIZEOF(dev_param_names) / SIZEOF(nametabent) == dev_param_index[26] + 1));
-	assert((SIZEOF(dev_param_data) / SIZEOF(unsigned char)) == dev_param_index[26] + 1);
-	assert(dev_param_index[26] == 255);
-	assert(SIZEOF(dev_param_index[26] == SIZEOF(char)));
+
+	assert((SIZEOF(dev_param_names) / SIZEOF(nametabent) == dev_param_index[26]));
+	assert((SIZEOF(dev_param_data) / SIZEOF(unsigned char)) == dev_param_index[26]);
 	is_parm_list = (TK_LPAREN == TREF(window_token));
 	if (is_parm_list)
 		advancewindow();
@@ -556,8 +550,8 @@ int deviceparameters(oprtype *c, char who_calls)
 	for (;;)
 	{
 		if ((TK_IDENT != TREF(window_token))
-			|| (0
-			 > (n = namelook(dev_param_index, dev_param_names, (TREF(window_ident)).addr, (TREF(window_ident)).len))))
+			|| (0 > (n = int_namelook(dev_param_index, dev_param_names,
+						  (TREF(window_ident)).addr, (TREF(window_ident)).len))))
 		{	/* NOTE assignment above */
 			STX_ERROR_WARN(ERR_DEVPARUNK);	/* sets "parse_warn" to TRUE */
 			break;
diff --git a/sr_port/dfa_calc.c b/sr_port/dfa_calc.c
index e1addc1..9f03251 100644
--- a/sr_port/dfa_calc.c
+++ b/sr_port/dfa_calc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -17,12 +17,12 @@
 #include "gtm_string.h"
 
 /* the following macro checks that a 1 dimensional array reference is valid i.e. array[index] is within defined limits */
-#define check_1dim_array_bound(array, index)    assert((index) < (SIZEOF(array) / SIZEOF(array[0])))
+#define check_1dim_array_bound(array, index)    assert((index) < ARRAYSIZE(array))
 
 /* the following macro checks that a 2 dimensional array reference is valid i.e. array[row][col] is within defined limits */
 #define check_2dim_array_bound(array, row, col)                         \
 {                                                                       \
-        assert((row) < (SIZEOF(array) / SIZEOF(array[0])));             \
+        assert((row) < ARRAYSIZE(array));             			\
         assert((col) < (SIZEOF(array[0]) / SIZEOF(array[0][0])));       \
 }
 
@@ -79,6 +79,8 @@ int dfa_calc(struct leaf *leaves, int leaf_num, struct e_table *expand, uint4 **
 	 * uses may  differ from the ones that are in operation at run-time.
 	 */
 	locoutchar = *outchar_ptr;
+	if (0 == leaf_num)
+		return -1;
 	if (leaf_num > 1)
 	{
 		pattern_mask = PATM_DFA;
@@ -392,8 +394,11 @@ int dfa_calc(struct leaf *leaves, int leaf_num, struct e_table *expand, uint4 **
 								offset[seq + 1] += 3;
 							}
 							if (count == state_num)
+							{
 								state_num++;
-							else
+								if (state_num >= ARRAYSIZE(states))
+									return -1;
+							} else
 								memset(states[state_num], 0, (sym_num + 1) * SIZEOF(states[0][0]));
 						}
 					}
@@ -402,8 +407,7 @@ int dfa_calc(struct leaf *leaves, int leaf_num, struct e_table *expand, uint4 **
 			}
 		}
 		*outchar_ptr += offset[state_num] + 2;
-		if ((*outchar_ptr - *fstchar_ptr > MAX_DFA_SPACE) ||
-		    ((offset[state_num] + 1) > (MAX_PATTERN_LENGTH / 2)))
+		if ((*outchar_ptr - *fstchar_ptr > MAX_DFA_SPACE) || ((offset[state_num] + 1) > (MAX_PATTERN_LENGTH / 2)))
 			return -1;
 		*locoutchar++ = PATM_DFA;
 		*locoutchar++ = offset[state_num];
diff --git a/sr_port/dpgbldir.c b/sr_port/dpgbldir.c
index 2b552a5..7240dff 100644
--- a/sr_port/dpgbldir.c
+++ b/sr_port/dpgbldir.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -131,16 +131,23 @@ Notes:          A) While checking may be done earlier for duplicate names,
 -*/
 gd_addr *gd_load(mstr *v)
 {
-	void		*file_ptr;	/* This is a temporary structure as the file open and manipulations are currently stubs */
-	header_struct	*header, temp_head;
-	gd_addr		*table, *gd_addr_ptr;
-	gd_binding	*map, *map_top;
-	gd_region	*reg, *reg_top;
-	uint4		t_offset, size;
-	short		i;
-
+	void			*file_ptr; /* is a temporary structure as the file open and manipulations are currently stubs */
+	header_struct		*header, temp_head;
+	gd_addr			*table, *gd_addr_ptr;
+	gd_binding		*map, *map_top;
+	gd_region		*reg, *reg_top;
+	uint4			t_offset, size;
+	gd_gblname		*gnam, *gnam_top;
+	int			i, n_regions, arraysize;
+	trans_num		*array;
+#	ifdef DEBUG
+	boolean_t		prevMapIsSpanning, currMapIsSpanning, gdHasSpanGbls;
+	boolean_t		isSpannedReg[256];	/* currently we allow for a max of 256 regions in this dbg code */
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
 	file_ptr = open_gd_file(v);
-
 	for (gd_addr_ptr = gd_addr_head;  gd_addr_ptr;  gd_addr_ptr = gd_addr_ptr->link)
 	{	/* if already open then return old structure */
 		if (comp_gd_addr(gd_addr_ptr, file_ptr))
@@ -158,7 +165,7 @@ gd_addr *gd_load(mstr *v)
 	if (GDE_LABEL_NUM == i)
 	{
 		close_gd_file(file_ptr);
-		rts_error(VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL),
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL),
 				SIZEOF(temp_head.label), temp_head.label);
 	}
 	size = LEGAL_IO_SIZE(temp_head.filesize);
@@ -166,31 +173,73 @@ gd_addr *gd_load(mstr *v)
 	file_read(file_ptr, size, (uchar_ptr_t)header, 1);			/* Read in body of file */
 	table = (gd_addr *)((char *)header + SIZEOF(header_struct));
         table->local_locks = (struct gd_region_struct *)((UINTPTR_T)table->local_locks + (UINTPTR_T)table);
+	assert(table->var_maps_len == ((UINTPTR_T)table->regions - (UINTPTR_T)table->maps) - (table->n_maps * SIZEOF(gd_binding)));
 	table->maps = (struct gd_binding_struct *)((UINTPTR_T)table->maps + (UINTPTR_T)table);
 	table->regions = (struct gd_region_struct *)((UINTPTR_T)table->regions + (UINTPTR_T)table);
 	table->segments = (struct gd_segment_struct *)((UINTPTR_T)table->segments + (UINTPTR_T)table);
+	table->gblnames = (struct gd_gblname_struct *)((UINTPTR_T)table->gblnames + (UINTPTR_T)table);
 	table->end = (table->end + (UINTPTR_T)table);
+	n_regions = table->n_regions;
+	for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++)
+	{
+		t_offset = reg->dyn.offset;
+		reg->dyn.addr = (gd_segment *)((char *)table + t_offset);
+#		ifdef DEBUG
+		assert((reg - table->regions) < ARRAYSIZE(isSpannedReg));
+		isSpannedReg[reg - table->regions] = FALSE;
+#		endif
+	}
+#	ifdef DEBUG
+	prevMapIsSpanning = FALSE;
+	currMapIsSpanning = FALSE;
+	gdHasSpanGbls = FALSE;
+#	endif
 	for (map = table->maps, map_top = map + table->n_maps;  map < map_top;  map++)
 	{
 		t_offset = map->reg.offset;
 		map->reg.addr = (gd_region *)((char *)table + t_offset);
-		assert(SIZEOF(map->name) == (MAX_MIDENT_LEN + 1));
-		map->name[MAX_MIDENT_LEN] = '\0';	/* reset 32nd byte to 0 since only 31 bytes are used in map.
-							 * this is necessary so "mid_len" can be invoked on this
-							 * as it expects a null-terminated string.
-							 */
+#		ifdef DEBUG
+		currMapIsSpanning = ((map->gvname_len + 1) != map->gvkey_len);
+		if (currMapIsSpanning)
+			gdHasSpanGbls = TRUE;
+		if (currMapIsSpanning || prevMapIsSpanning)
+			isSpannedReg[map->reg.addr - table->regions] = TRUE;
+		prevMapIsSpanning = currMapIsSpanning;
+#		endif
+		t_offset = map->gvkey.offset;
+		map->gvkey.addr = (char *)table + t_offset;
+		assert('\0' == map->gvkey.addr[map->gvname_len]);
+		assert('\0' == map->gvkey.addr[map->gvkey_len]);
+		assert('\0' == map->gvkey.addr[map->gvkey_len - 1]);
+		assert((map->gvname_len + 1) <= map->gvkey_len);
 	}
-	for (reg = table->regions, reg_top = reg + table->n_regions;  reg < reg_top;  reg++)
+#	ifdef DEBUG
+	assert(table->has_span_gbls == gdHasSpanGbls);
+	for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++)
+		assert(reg->is_spanned == isSpannedReg[reg - table->regions]);
+	for (gnam = table->gblnames, gnam_top = gnam + table->n_gblnames; gnam < gnam_top; gnam++)
 	{
-		t_offset = reg->dyn.offset;
-		reg->dyn.addr = (gd_segment *)((char *)table + t_offset);
+		assert(SIZEOF(gnam->gblname) == (MAX_MIDENT_LEN + 1));
+		assert('\0' == gnam->gblname[MAX_MIDENT_LEN]);
 	}
+#	endif
 	table->link = gd_addr_head;
 	gd_addr_head = table;
 	fill_gd_addr_id(gd_addr_head, file_ptr);
 	close_gd_file(file_ptr);
 	table->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
 	init_hashtab_mname(table->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
+	if (table->has_span_gbls && (TREF(gd_targ_reg_array_size) < n_regions))
+	{
+		array = TREF(gd_targ_reg_array);
+		if (NULL != array)
+			free(array);
+		arraysize = n_regions * SIZEOF(*array);
+		array = malloc(arraysize);
+		memset(array, 0, arraysize);
+		TREF(gd_targ_reg_array) = array;
+		TREF(gd_targ_reg_array_size) = arraysize;
+	}
 	return table;
 }
 
@@ -313,6 +362,8 @@ void gd_ht_kill(hash_table_mname *table, boolean_t contents)	/* wipe out the has
 	ht_ent_mname	*tabent, *topent;
 	gvnh_reg_t	*gvnh_reg;
 	gv_namehead	*gvt;
+	gvnh_spanreg_t	*gvspan;
+	int		i;
 
 	if (contents)
 	{
@@ -320,10 +371,30 @@ void gd_ht_kill(hash_table_mname *table, boolean_t contents)	/* wipe out the has
 		{
 			if (HTENT_VALID_MNAME(tabent, gvnh_reg_t, gvnh_reg))
 			{
-				gvt = gvnh_reg->gvt;
-				gvt->regcnt--;
-				if (!gvt->regcnt)
-					targ_free(gvt);
+				gvspan = gvnh_reg->gvspan;
+				if (NULL == gvspan)
+				{
+					gvt = gvnh_reg->gvt;
+					DEBUG_ONLY(gvnh_reg->gvt = NULL;)	/* or else targ_free() might assert fail */
+					TARG_FREE_IF_NEEDED(gvt);
+				} else
+				{	/* this global spans more than one region. free up gvts corresponding to those regions */
+					for (i = 0; i < (gvspan->max_reg_index - gvspan->min_reg_index + 1); i++)
+					{
+						gvt = GET_REAL_GVT(gvspan->gvt_array[i]);
+						if (NULL != gvt)
+						{
+#							ifdef DEBUG
+							/* below is needed to ensure "targ_free" does not assert fail */
+							gvspan->gvt_array[i] = NULL;
+							if (gvt == gvnh_reg->gvt)
+								gvnh_reg->gvt = NULL;
+#							endif
+							TARG_FREE_IF_NEEDED(gvt);
+						}
+					}
+					free(gvspan);
+				}
 				free(gvnh_reg);
 			}
 		}
diff --git a/sr_port/dpgbldir.h b/sr_port/dpgbldir.h
index 3a426e7..69c8ede 100644
--- a/sr_port/dpgbldir.h
+++ b/sr_port/dpgbldir.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2008 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -14,7 +14,17 @@
 
 typedef struct gvt_container_struct
 {
-	gvnh_reg_t			*gvnh_reg;
+	gv_namehead			**gvt_ptr;	/* pointer to a location (either the "gvnh_reg_t->gvt" (for globals that
+							 * dont span regions) OR "gvnh_spanreg_t->gvt_array[]" (for globals that
+							 * span regions) that contains a pointer to the "gv_target" and that
+							 * needs to be updated if/when the gv_target gets re-allocated.
+							 */
+	gv_namehead			**gvt_ptr2;	/* only for spanning globals, this points to a SECOND location where the
+							 * gvt corresponding to the region (that maps the unsubscripted global
+							 * reference) is stored (i.e. gvnh_reg_t->gvt). And that needs to be
+							 * updated as well if/when the gv_target gets re-allocated.
+							 */
+	gd_region			*gd_reg;	/* region corresponding to the gv_target that is waiting for reg-open */
 	struct gvt_container_struct	*next_gvtc;
 } gvt_container;
 
diff --git a/sr_port/dse.h b/sr_port/dse.h
index 7341530..a942eb3 100644
--- a/sr_port/dse.h
+++ b/sr_port/dse.h
@@ -102,7 +102,7 @@ enum dse_fmt
 #else
 # define GET_CONFIRM(X, Y)								\
 {											\
-	if(!cli_get_str("CONFIRMATION",(X),&(Y)))					\
+	if (!cli_get_str("CONFIRMATION", (X), &(Y)))					\
 	{										\
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEWCINITCON);		\
 		return;									\
@@ -127,7 +127,7 @@ enum dse_fmt
 #define DSE_WCREINIT(CS_ADDRS)										\
 {													\
 	assert(CS_ADDRS->now_crit);									\
-	if (CS_ADDRS->hdr->acc_meth == dba_bg)								\
+	if (dba_bg == CS_ADDRS->hdr->acc_meth)								\
 		bt_refresh(CS_ADDRS, TRUE);								\
 	db_csh_ref(CS_ADDRS, TRUE);									\
 	send_msg_csa(CSA_ARG(CS_ADDRS) VARLSTCNT(4) ERR_DSEWCREINIT, 2, DB_LEN_STR(gv_cur_region));	\
@@ -139,13 +139,11 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len);
 int dse_is_blk_in(sm_uc_ptr_t rp, sm_uc_ptr_t r_top, short size);
 int dse_ksrch(block_id srch, block_id_ptr_t pp, int4 *off, char *targ_key, int targ_len);
 int dse_key_srch(block_id srch, block_id_ptr_t pp, int4 *off, char *targ_key, int targ_len);
-int dse_order(block_id srch, block_id_ptr_t pp, int4 *op, char *targ_key, short int targ_len,
-	bool dir_data_blk);
+int dse_order(block_id srch, block_id_ptr_t pp, int4 *op, char *targ_key, short int targ_len, bool dir_data_blk);
 void  dse_rmsb(void);
 void dse_ctrlc_handler(int sig);
 void dse_exhaus(int4 pp, int4 op);
-void dse_m_rest(block_id blk, unsigned char *bml_list, int4 bml_size, sm_vuint_ptr_t blks_ptr,
-	bool in_dir_tree);
+void dse_m_rest(block_id blk, unsigned char *bml_list, int4 bml_size, sm_vuint_ptr_t blks_ptr, bool in_dir_tree);
 void dse_rmrec(void);
 void dse_find_roots(block_id index);
 boolean_t dse_fdmp(sm_uc_ptr_t data, int len);
@@ -187,5 +185,6 @@ sm_uc_ptr_t dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr_
 void dse_dmp_fhead (void);
 void dse_ctrlc_handler(int sig);
 void dse_remove(void);
+gv_namehead *dse_find_gvt(gd_region *reg, char *name, int name_len);
 
 #endif
diff --git a/sr_port/dse.hlp b/sr_port/dse.hlp
index b10f29e..84019f7 100644
--- a/sr_port/dse.hlp
+++ b/sr_port/dse.hlp
@@ -125,9 +125,9 @@
 1 Commands
    Commands
 
-   The format for DSE commands is:
+   The general format of DSE commands is:
 
-   DSE> command [-qualifier[...]] [object[,...]]
+   command [-qualifier[...]] [object[,...]]
 
    DSE interprets all numeric input as hexadecimal, except for time values,
    the values for the following qualifiers when used with CHANGE -FILEHEADER:
@@ -568,7 +568,7 @@
    -TIM[ERS_PENDING]=integer
    -TO[TAL_BLKS]=total-blocks
    -TR[IGGER_FLUSH]=trigger-flus
-   -UPD_RESERVED_AREA=reserved- area
+   -UPD_RESERVED_AREA=reserved-area
    -UPD_WRITER_TRIGGER_FACTOR=trigger-factor
    -W[RITES_PER_FLUSH]=writes-per-flush
    -WAIT_DISK=wait-disk
@@ -2496,9 +2496,9 @@
    |             |                                   | -LEVEL, -OFFSET,     |
    |             |                                   | -RECORD, -RSIZ       |
    |-------------+-----------------------------------+----------------------|
-   | -           | AVG_BLKS_READ=Average blocks read |                      |
+   | -           | AVG_BLKS_READ=Average blocks read | -                    |
    |-------------+-----------------------------------+----------------------|
-   | -           | B_B[YTESTREAM]=transaction number |                      |
+   | -           | B_B[YTESTREAM]=transaction number | -                    |
    |-------------+-----------------------------------+----------------------|
    | -           | -B_C[OMPREHENSIVE]=transaction    | Use only with        |
    |             | number                            | -FILEHEADER; decimal |
@@ -2613,7 +2613,7 @@
    | -           | -W[RITES_PER_FLUSH]=writes per    | Use only with        |
    |             | flush                             | -FILEHEADER; decimal |
    |-------------+-----------------------------------+----------------------|
-   | -           | -WAIT_DISK=wait disk              |                      |
+   | -           | -WAIT_DISK=wait disk              | -                    |
    |-------------+-----------------------------------+----------------------|
    | -           | -Zqgblmod_S[EQNO] = sequence      | Use only with        |
    |             | number                            | -FILEHEADER;hexa     |
@@ -2621,7 +2621,6 @@
    | -           | -Zqgblmod_T[rans]=sequence_number | Use only with        |
    |             |                                   | -FILEHEADER;hexa     |
    |-------------+-----------------------------------+----------------------|
-   |-------------+-----------------------------------+----------------------|
    | CL[OSE]     | -                                 | -                    |
    |-------------+-----------------------------------+----------------------|
    | CR[ITICAL]  | -I[NIT]                           | Use only with -RESET |
@@ -2693,7 +2692,7 @@
    |-------------+-----------------------------------+----------------------|
    | H[ELP]      | [help topic]                      | -                    |
    |-------------+-----------------------------------+----------------------|
-   | I[NTEGRIT]  | -B[LOCK]=block&_number            | -                    |
+   | I[NTEGRIT]  | -B[LOCK]=block_number             | -                    |
    |-------------+-----------------------------------+----------------------|
    | M[APS]      | -BL[OCK]=block_number             | Incompatible with    |
    |             |                                   | -RESTORE_ALL         |
@@ -2778,3 +2777,32 @@
 
    * Use these qualifiers only with instructions from FIS.
 
+1 Copyright
+   Copyright
+
+   Copyright 2013
+
+   Fidelity Information Services, Inc. All rights reserved.
+
+   Permission is granted to copy, distribute and/or modify this document
+   under the terms of the GNU Free Documentation License, Version 1.3 or any
+   later version published by the Free Software Foundation; with no Invariant
+   Sections, no Front-Cover Texts and no Back-Cover Texts.
+
+   GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
+   trademarks are the property of their respective owners.
+
+   This document contains a description of GT.M and the operating
+   instructions pertaining to the various functions that comprise the system.
+   This document does not contain any commitment of FIS. FIS believes the
+   information in this publication is accurate as of its publication date;
+   such information is subject to change without notice. FIS is not
+   responsible for any errors or defects.
+
+   **Note**
+
+   This help file is a concise representation of revision V6.1-000 of the
+   UNIX Administration and Operations Guide. To obtain a copy of the current
+   revision, go to www.fis-gtm.com and then click on the User Documentation
+   tab.
+
diff --git a/sr_port/dse_adrec.c b/sr_port/dse_adrec.c
index d0eb367..fc579d2 100644
--- a/sr_port/dse_adrec.c
+++ b/sr_port/dse_adrec.c
@@ -44,12 +44,18 @@ GBLREF srch_hist	dummy_hist;
 GBLREF block_id		patch_curr_blk;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t cs_data;
-GBLREF gd_addr		*gd_header;
 GBLREF char 		patch_comp_key[MAX_KEY_SZ + 1];
 GBLREF unsigned short 	patch_comp_count;
 GBLREF gd_region        *gv_cur_region;
 GBLREF cw_set_element   cw_set[];
 
+error_def(ERR_CPBEYALLOC);
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+error_def(ERR_GVIS);
+error_def(ERR_REC2BIG);
+
 void dse_adrec(void)
 {
 	char		data[MAX_LINE], key[MAX_KEY_SZ + 1];
@@ -63,15 +69,8 @@ void dse_adrec(void)
 	blk_segment	*bs1, *bs_ptr;
 	srch_blk_status	blkhist;
 
-	error_def(ERR_CPBEYALLOC);
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-	error_def(ERR_GVIS);
-	error_def(ERR_REC2BIG);
-
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (cli_present("BLOCK") == CLI_PRESENT)
 	{
@@ -95,7 +94,7 @@ void dse_adrec(void)
 	blk_size = cs_addrs->hdr->blk_size;
 	blkhist.blk_num = patch_curr_blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 
 	lbp = (uchar_ptr_t)malloc(blk_size);
 	memcpy(lbp, blkhist.buffaddr, blk_size);
@@ -147,8 +146,8 @@ void dse_adrec(void)
 		}
 		if (key_len + data_len >  cs_addrs->hdr->max_rec_size)
 		{
- 			rts_error(VARLSTCNT(10) ERR_REC2BIG, 4, key_len + data_len, (int4)cs_addrs->hdr->max_rec_size,
-								REG_LEN_STR(gv_cur_region), ERR_GVIS, 2, LEN_AND_STR(key));
+ 			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(10) ERR_REC2BIG, 4, key_len + data_len,
+				(int4)cs_addrs->hdr->max_rec_size, REG_LEN_STR(gv_cur_region), ERR_GVIS, 2, LEN_AND_STR(key));
 		}
 
 	}
diff --git a/sr_port/dse_adstar.c b/sr_port/dse_adstar.c
index 421ef29..0c622a2 100644
--- a/sr_port/dse_adstar.c
+++ b/sr_port/dse_adstar.c
@@ -43,10 +43,13 @@ GBLREF uint4		update_array_size;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t cs_data;
 GBLREF srch_hist	dummy_hist;
-GBLREF gd_addr		*gd_header;
 GBLREF block_id		patch_curr_blk;
 GBLREF cw_set_element   cw_set[];
 
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+
 void dse_adstar(void)
 {
 	uchar_ptr_t	lbp, b_top;
@@ -57,12 +60,8 @@ void dse_adstar(void)
 	int		tmp_cmpc;
 	srch_blk_status	blkhist;
 
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (cli_present("BLOCK") == CLI_PRESENT)
 	{
@@ -86,7 +85,7 @@ void dse_adstar(void)
 	blk_size = cs_addrs->hdr->blk_size;
 	blkhist.blk_num = patch_curr_blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	lbp = (uchar_ptr_t)malloc(blk_size);
 	memcpy(lbp, blkhist.buffaddr, blk_size);
 
diff --git a/sr_port/dse_all.c b/sr_port/dse_all.c
index c9dd47c..336a57b 100644
--- a/sr_port/dse_all.c
+++ b/sr_port/dse_all.c
@@ -36,8 +36,6 @@
 #include "buddy_list.h"		/* needed for tp.h */
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "dse.h"
 #ifdef UNIX
 # include "mutex.h"
@@ -47,7 +45,6 @@
 
 GBLREF	VSIG_ATOMIC_T	util_interrupt;
 GBLREF	block_id	patch_curr_blk;
-GBLREF	gd_addr		*gd_header;
 GBLREF	gd_region	*gv_cur_region;
 GBLREF	sgmnt_addrs	*cs_addrs;
 GBLREF	short		crash_count;
@@ -62,9 +59,9 @@ error_def(ERR_FREEZECTRL);
 
 void dse_all(void)
 {
-	gd_region	*ptr;
+	gd_region	*reg;
 	tp_region	*region_list, *rg, *rg_last, *rg_new;	/* A handy structure for maintaining a list of regions */
-	int		i, j;
+	int		i;
 	sgmnt_addrs	*old_addrs, *csa;
 	gd_region	*old_region;
 	block_id	old_block;
@@ -80,15 +77,11 @@ void dse_all(void)
 	boolean_t	dump = FALSE;
 	boolean_t	override = FALSE;
 	boolean_t	was_crit;
-	gd_addr         *temp_gdaddr;
-	gd_binding      *map;
 	UNIX_ONLY(char	*fgets_res;)
 
 	old_addrs = cs_addrs;
 	old_region = gv_cur_region;
 	old_block = patch_curr_blk;
-	temp_gdaddr = gd_header;
-	gd_header = original_header;
 	if (cli_present("RENEW") == CLI_PRESENT)
 	{
 		crit = ref = wc = nofreeze = TRUE;
@@ -124,33 +117,31 @@ void dse_all(void)
 			dump = TRUE;
 	}
         if (!dump && gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	region_list = NULL;
-	for (i = 0, ptr = gd_header->regions; i < gd_header->n_regions; i++, ptr++)
+	for (i = 0, reg = original_header->regions; i < original_header->n_regions; i++, reg++)
 	{
-		if (ptr->dyn.addr->acc_meth != dba_bg && ptr->dyn.addr->acc_meth != dba_mm)
+		if ((dba_bg != REG_ACC_METH(reg)) && (dba_mm != REG_ACC_METH(reg)))
 		{
-			util_out_print("Skipping region !AD: not BG or MM access",TRUE,ptr->rname_len,&ptr->rname[0]);
+			util_out_print("Skipping region !AD: not BG or MM access", TRUE, REG_LEN_STR(reg));
 			continue;
 		}
-		if (!ptr->open)
+		if (!reg->open)
 		{
-			util_out_print("Skipping region !AD as it is not bound to any namespace.", TRUE,
-				ptr->rname_len, &ptr->rname[0]);
+			util_out_print("Skipping region !AD as it is not bound to any namespace.", TRUE, REG_LEN_STR(reg));
 			continue;
 		}
 		if (dump)
 		{
-			gv_cur_region = ptr;
+			gv_cur_region = reg;
 			cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
 			dse_all_dump = TRUE;
 			dse_dmp_fhead();
 			assert(!dse_all_dump);	/* should have been reset by "dse_dmp_fhead" */
 		} else
-		{
-			/* put on region list in order of ftok value so processed in same order that crits are obtained */
-			csa = &FILE_INFO(ptr)->s_addrs;
-			insert_region(ptr, &(region_list), NULL, SIZEOF(tp_region));
+		{	/* put on region list in order of ftok value so processed in same order that crits are obtained */
+			csa = &FILE_INFO(reg)->s_addrs;
+			insert_region(reg, &(region_list), NULL, SIZEOF(tp_region));
 		}
 	}
 	if (!dump)
@@ -158,15 +149,8 @@ void dse_all(void)
 		for (rg = region_list; NULL != rg; rg = rg->fPtr)
 		{
 			gv_cur_region = rg->reg;
-			switch(gv_cur_region->dyn.addr->acc_meth)
-			{
-			case dba_mm:
-			case dba_bg:
-				cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
-				break;
-			default:
-				GTMASSERT;
-			}
+			assert((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)));
+			cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
 			patch_curr_blk = get_dir_root();
 			if (crit)
 			{
@@ -185,7 +169,7 @@ void dse_all(void)
 					hiber_start(1000);
 					if (util_interrupt)
 					{
-						gtm_putmsg(VARLSTCNT(1) ERR_FREEZECTRL);
+						gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_FREEZECTRL);
                         	                break;
 					}
 				}
@@ -227,8 +211,8 @@ void dse_all(void)
 			}
 			if (nofreeze)
 			{
-				if (REG_ALREADY_FROZEN == region_freeze(gv_cur_region,FALSE, override, FALSE))
-					util_out_print("Region: !AD is frozen by another user, not releasing freeze",TRUE,
+				if (REG_ALREADY_FROZEN == region_freeze(gv_cur_region, FALSE, override, FALSE))
+					util_out_print("Region: !AD is frozen by another user, not releasing freeze", TRUE,
 						REG_LEN_STR(gv_cur_region));
 				else
 					util_out_print("Region !AD is now UNFROZEN", TRUE, REG_LEN_STR(gv_cur_region));
@@ -240,6 +224,5 @@ void dse_all(void)
 	cs_addrs = old_addrs;
 	gv_cur_region = old_region;
 	patch_curr_blk = old_block;
-	GET_SAVED_GDADDR(gd_header, temp_gdaddr, map, gv_cur_region);
 	return;
 }
diff --git a/sr_port/dse_chng_bhead.c b/sr_port/dse_chng_bhead.c
index fd35dca..0e725b5 100644
--- a/sr_port/dse_chng_bhead.c
+++ b/sr_port/dse_chng_bhead.c
@@ -53,7 +53,6 @@ GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	block_id		patch_curr_blk;
 GBLREF	gd_region		*gv_cur_region;
-GBLREF	gd_addr			*gd_header;
 GBLREF	cache_rec		*cr_array[((MAX_BT_DEPTH * 2) - 1) * 2]; /* Maximum number of blocks that can be in transaction */
 GBLREF	boolean_t		unhandled_stale_timer_pop;
 GBLREF	cw_set_element		cw_set[];
@@ -86,11 +85,11 @@ void dse_chng_bhead(void)
 	gd_segment		*seg;
 #	endif
 
+	csa = cs_addrs;
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	chng_blk = FALSE;
-	csa = cs_addrs;
 	if (cli_present("BLOCK") == CLI_PRESENT)
 	{
 		if (!cli_get_hex("BLOCK", (uint4 *)&blk))
@@ -111,7 +110,7 @@ void dse_chng_bhead(void)
 	t_begin_crit(ERR_DSEFAIL);
 	blkhist.blk_num = patch_curr_blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(csa) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	new_hdr = *(blk_hdr_ptr_t)blkhist.buffaddr;
 
 	if (cli_present("LEVEL") == CLI_PRESENT)
diff --git a/sr_port/dse_chng_rhead.c b/sr_port/dse_chng_rhead.c
index bdab67e..a911029 100644
--- a/sr_port/dse_chng_rhead.c
+++ b/sr_port/dse_chng_rhead.c
@@ -45,9 +45,12 @@ GBLREF block_id		patch_curr_blk;
 GBLREF unsigned short	patch_comp_count;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t cs_data;
-GBLREF gd_addr		*gd_header;
 GBLREF cw_set_element   cw_set[];
 
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+
 void dse_chng_rhead(void)
 {
 	block_id	blk;
@@ -60,12 +63,8 @@ void dse_chng_rhead(void)
 	int		tmp_cmpc;
 	srch_blk_status	blkhist;
 
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (cli_present("BLOCK") == CLI_PRESENT)
 	{
@@ -82,7 +81,7 @@ void dse_chng_rhead(void)
 	t_begin_crit(ERR_DSEFAIL);
 	blkhist.blk_num = patch_curr_blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	bp = blkhist.buffaddr;
 	blk_size = cs_addrs->hdr->blk_size;
 	chng_rec = FALSE;
diff --git a/sr_port/dse_dmp.c b/sr_port/dse_dmp.c
index 8797043..b316076 100644
--- a/sr_port/dse_dmp.c
+++ b/sr_port/dse_dmp.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -33,7 +33,7 @@ GBLREF int		patch_fdmp_recs;
 
 CONDITION_HANDLER(dse_dmp_handler)
 {
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
 	util_out_print("!/DSE is not able to complete the dump to file due to the above reason.!/", TRUE);
 	UNWIND(NULL,NULL);
diff --git a/sr_port/dse_f_blk.c b/sr_port/dse_f_blk.c
index 114837b..3c9c9fd 100644
--- a/sr_port/dse_f_blk.c
+++ b/sr_port/dse_f_blk.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -83,7 +83,7 @@ void dse_f_blk(void)
 	/* ESTABLISH is done here because dse_f_blk_ch() assumes we already have crit. */
 	ESTABLISH(dse_f_blk_ch);
 	if (!(bp = t_qread(patch_find_blk, &dummy_int, &dummy_cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	if (((blk_hdr_ptr_t) bp)->bsiz > cs_addrs->hdr->blk_size)
 		b_top = bp + cs_addrs->hdr->blk_size;
 	else if (SIZEOF(blk_hdr) > ((blk_hdr_ptr_t) bp)->bsiz)
@@ -254,7 +254,7 @@ void dse_f_blk(void)
 			{
 				if (!(sp = t_qread(patch_find_root_search ? patch_path[lvl] : patch_path1[lvl], &dummy_int,
 					&dummy_cr)))
-						rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 				if (((blk_hdr_ptr_t)sp)->bsiz > cs_addrs->hdr->blk_size)
 					s_top = sp + cs_addrs->hdr->blk_size;
 				else if (SIZEOF(blk_hdr) > ((blk_hdr_ptr_t)sp)->bsiz)
@@ -300,7 +300,7 @@ void dse_f_blk(void)
 				for (lvl++; lvl < (patch_find_root_search ? patch_dir_path_count : patch_path_count); lvl++)
 				{
 					if (!(sp = t_qread(last, &dummy_int, &dummy_cr)))
-						rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 					if (((blk_hdr_ptr_t)sp)->bsiz > cs_addrs->hdr->blk_size)
 						s_top = sp + cs_addrs->hdr->blk_size;
 					else if (SIZEOF(blk_hdr) > ((blk_hdr_ptr_t)sp)->bsiz)
@@ -338,7 +338,7 @@ void dse_f_blk(void)
 			{
 				if (!(sp = t_qread(patch_find_root_search ? patch_path[lvl] : patch_path1[lvl], &dummy_int,
 					&dummy_cr)))
-					rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 				if (((blk_hdr_ptr_t)sp)->bsiz > cs_addrs->hdr->blk_size)
 					s_top = sp + cs_addrs->hdr->blk_size;
 				else if (SIZEOF(blk_hdr) > ((blk_hdr_ptr_t)sp)->bsiz)
@@ -389,7 +389,7 @@ void dse_f_blk(void)
 				for (lvl++; lvl < (patch_find_root_search ? patch_dir_path_count : patch_path_count); lvl++)
 				{
 					if (!(sp = t_qread(look, &dummy_int, &dummy_cr)))	/* NOTE assignment */
-						rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 					if (((blk_hdr_ptr_t)sp)->bsiz > cs_addrs->hdr->blk_size)
 						s_top = sp + cs_addrs->hdr->blk_size;
 					else if (SIZEOF(blk_hdr) > ((blk_hdr_ptr_t)sp)->bsiz)
@@ -483,10 +483,10 @@ void dse_f_blk(void)
 /* Control-C condition handler */
 CONDITION_HANDLER(dse_f_blk_ch)
 {
-	START_CH;
+	START_CH(SIGNAL != ERR_CTRLC);
 
 	if (ERR_CTRLC == SIGNAL)
-	DSE_REL_CRIT_AS_APPROPRIATE(was_crit, was_hold_onto_crit, nocrit_present, cs_addrs, gv_cur_region);
+		DSE_REL_CRIT_AS_APPROPRIATE(was_crit, was_hold_onto_crit, nocrit_present, cs_addrs, gv_cur_region);
 	NEXTCH;
 }
 
diff --git a/sr_port/dse_f_key.c b/sr_port/dse_f_key.c
index fc83eb1..ace7252 100644
--- a/sr_port/dse_f_key.c
+++ b/sr_port/dse_f_key.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,22 +21,60 @@
 #include "cli.h"
 #include "util.h"
 #include "dse.h"
+#include "print_target.h"
+#include "gv_trigger_common.h" /* for IS_GVKEY_HASHT_GBLNAME macro */
 
 GBLREF short int	patch_path_count;
 GBLREF block_id		ksrch_root;
 GBLREF bool		patch_find_root_search;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF gd_region	*gv_cur_region;
+GBLREF gd_addr		*original_header;
 
 #define MAX_UTIL_LEN	64
 
+STATICFNDCL void print_reg_if_mismatch(char *key, int keylen);
+
+/* If current region does not match region where TARG_KEY maps to, and if -nogbldir was not specified,
+ * issue an info message indicating the mapping region.
+ */
+STATICFNDEF void print_reg_if_mismatch(char *key, int keylen)
+{
+	gd_binding		*map;
+	gd_region		*reg;
+
+	assert(3 <= keylen);
+	assert(KEY_DELIMITER == key[keylen - 1]);
+	assert(KEY_DELIMITER == key[keylen - 2]);
+	assert(KEY_DELIMITER != key[keylen - 3]);
+	/* If input key is ^#t, then do not call gv_srch_map as it does not belong to a particular region,
+	 * i.e. the gld does not map globals beginning with #. There is no reg mismatch possible in that case.
+	 * So skip this processing entirely.
+	 */
+	if (!IS_GVKEY_HASHT_GBLNAME(keylen -2, key))
+	{
+		map = gv_srch_map(original_header, key, keylen - 2); /* -2 to remove two trailing 0s */
+		reg = map->reg.addr;
+		if (gv_cur_region != reg)
+		{
+			/* At this point, gv_target and gv_target->collseq are already setup (by the dse_getki call in caller).
+			 * This is needed by the "print_target" --> "gvsub2str" call below.
+			 */
+			util_out_print("Key ^", FALSE);
+			print_target((unsigned char *)key);
+			util_out_print(" maps to Region !AD; Run \"find -region=!AD\" before looking for this node",
+					TRUE, REG_LEN_STR(reg), REG_LEN_STR(reg));
+		}
+	}
+}
+
 void dse_f_key(void)
 {
 	block_id	path[MAX_BT_DEPTH + 1], root_path[MAX_BT_DEPTH + 1];
-	int4		offset[MAX_BT_DEPTH + 1], root_offset[MAX_BT_DEPTH + 1], nocrit_present;
+	boolean_t	found, nocrit_present, nogbldir_present, was_crit, was_hold_onto_crit;
 	char		targ_key[MAX_KEY_SZ + 1], targ_key_root[MAX_KEY_SZ + 1], *key_top, util_buff[MAX_UTIL_LEN];
 	int		size, size_root, root_path_count, count, util_len;
-	boolean_t	found, was_crit, was_hold_onto_crit;
+	int4		offset[MAX_BT_DEPTH + 1], root_offset[MAX_BT_DEPTH + 1];
 
 	if (!dse_getki(&targ_key[0], &size, LIT_AND_LEN("KEY")))
 		return;
@@ -46,15 +84,21 @@ void dse_f_key(void)
 		if (!*key_top++)
 			break;
 	size_root = (int)(key_top - &targ_key[0] + 1);
-	memcpy(&targ_key_root[0],&targ_key[0],size_root);
+	memcpy(&targ_key_root[0], &targ_key[0], size_root);
 	targ_key_root[size_root - 1] = targ_key_root[size_root] = 0;
 	patch_find_root_search = TRUE;
 	was_crit = cs_addrs->now_crit;
 	nocrit_present = (CLI_NEGATED == cli_present("CRIT"));
+	/* -NOGBLDIR is currently supported only in Unix */
+	UNIX_ONLY(nogbldir_present = (CLI_NEGATED == cli_present("GBLDIR"));)
+	VMS_ONLY(nogbldir_present = TRUE;)
 	DSE_GRAB_CRIT_AS_APPROPRIATE(was_crit, was_hold_onto_crit, nocrit_present, cs_addrs, gv_cur_region);
 	if (!dse_key_srch(root_path[0], &root_path[1], &root_offset[0], &targ_key_root[0], size_root))
 	{
-		util_out_print("!/Key not found, no root present.!/",TRUE);
+		util_out_print("!/Key not found, no root present.", TRUE);
+		if (!nogbldir_present)
+			print_reg_if_mismatch(&targ_key[0], size);
+		util_out_print("", TRUE);
 		DSE_REL_CRIT_AS_APPROPRIATE(was_crit, was_hold_onto_crit, nocrit_present, cs_addrs, gv_cur_region);
 		return;
 	}
@@ -63,60 +107,62 @@ void dse_f_key(void)
 	path[0] = ksrch_root;
 	patch_find_root_search = FALSE;
 	if (!dse_key_srch(path[0], &path[1], &offset[0], &targ_key[0], size))
-	{	memcpy(util_buff,"!/Key not found, would be in block  ",36);
+	{	memcpy(util_buff, "!/Key not found, would be in block  ", 36);
 		util_len = 36;
 		util_len += i2hex_nofill(path[patch_path_count - 2], (uchar_ptr_t)&util_buff[util_len], 8);
-		memcpy(&util_buff[util_len], ".",1);
+		memcpy(&util_buff[util_len], ".", 1);
 		util_len += 1;
 		util_buff[util_len] = 0;
-		util_out_print(util_buff,FALSE);
+		util_out_print(util_buff, FALSE);
 		patch_path_count -= 1;
-	}else
-	{	memcpy(util_buff,"!/Key found in block  ",22);
+	} else
+	{	memcpy(util_buff, "!/Key found in block  ", 22);
 		util_len = 22;
 		util_len += i2hex_nofill(path[patch_path_count - 1], (uchar_ptr_t)&util_buff[util_len], 8);
-		memcpy(&util_buff[util_len], ".",1);
+		memcpy(&util_buff[util_len], ".", 1);
 		util_len += 1;
 		util_buff[util_len] = 0;
-		util_out_print(util_buff,FALSE);
+		util_out_print(util_buff, FALSE);
 	}
-	util_out_print("!/    Directory path!/    Path--blk:off",TRUE);
+	util_out_print("!/    Directory path!/    Path--blk:off", TRUE);
 	for (count = 0; count < root_path_count ;count++)
-	{	memcpy(util_buff,"	",1);
+	{	memcpy(util_buff, "	", 1);
 		util_len = 1;
-		util_len += i2hex_nofill(root_path[count],(uchar_ptr_t)&util_buff[util_len], 8);
-		memcpy(&util_buff[util_len],":",1);
+		util_len += i2hex_nofill(root_path[count], (uchar_ptr_t)&util_buff[util_len], 8);
+		memcpy(&util_buff[util_len], ":", 1);
 		util_len += 1;
-		util_len += i2hex_nofill(root_offset[count],(uchar_ptr_t)&util_buff[util_len], 4);
-		memcpy(&util_buff[util_len],",",1);
+		util_len += i2hex_nofill(root_offset[count], (uchar_ptr_t)&util_buff[util_len], 4);
+		memcpy(&util_buff[util_len], ", ", 1);
 		util_len += 1;
 		util_buff[util_len] = 0;
-		util_out_print(util_buff,FALSE);
+		util_out_print(util_buff, FALSE);
 	}
-	util_out_print("!/    Global tree path!/    Path--blk:off",TRUE);
+	util_out_print("!/    Global tree path!/    Path--blk:off", TRUE);
 	if (patch_path_count)
 	{	for (count = 0; count < patch_path_count ;count++)
-		{	memcpy(util_buff,"	",1);
+		{	memcpy(util_buff, "	", 1);
 			util_len = 1;
-			util_len += i2hex_nofill(path[count],(uchar_ptr_t)&util_buff[util_len], 8);
-			memcpy(&util_buff[util_len],":",1);
+			util_len += i2hex_nofill(path[count], (uchar_ptr_t)&util_buff[util_len], 8);
+			memcpy(&util_buff[util_len], ":", 1);
 			util_len += 1;
-			util_len += i2hex_nofill(offset[count],(uchar_ptr_t)&util_buff[util_len], 4);
-			memcpy(&util_buff[util_len],",",1);
+			util_len += i2hex_nofill(offset[count], (uchar_ptr_t)&util_buff[util_len], 4);
+			memcpy(&util_buff[util_len], ", ", 1);
 			util_len += 1;
 			util_buff[util_len] = 0;
-			util_out_print(util_buff,FALSE);
+			util_out_print(util_buff, FALSE);
 		}
-		util_out_print(0,TRUE);
+		util_out_print(0, TRUE);
 	} else
-	{	memcpy(util_buff,"	",1);
+	{	memcpy(util_buff, "	", 1);
 		util_len = 1;
-		util_len += i2hex_nofill(root_path[count],(uchar_ptr_t)&util_buff[util_len], 8);
-		memcpy(&util_buff[util_len],"!/",2);
+		util_len += i2hex_nofill(root_path[count], (uchar_ptr_t)&util_buff[util_len], 8);
+		memcpy(&util_buff[util_len], "!/", 2);
 		util_len += 2;
 		util_buff[util_len] = 0;
-		util_out_print(util_buff,TRUE);
+		util_out_print(util_buff, TRUE);
 	}
+	if (!nogbldir_present)
+		print_reg_if_mismatch(&targ_key[0], size);
 	DSE_REL_CRIT_AS_APPROPRIATE(was_crit, was_hold_onto_crit, nocrit_present, cs_addrs, gv_cur_region);
 	return;
 }
diff --git a/sr_port/dse_f_reg.c b/sr_port/dse_f_reg.c
index 4053022..554a891 100644
--- a/sr_port/dse_f_reg.c
+++ b/sr_port/dse_f_reg.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -19,15 +19,12 @@
 #include "gdsbt.h"
 #include "gdsfhead.h"
 #include "filestruct.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "util.h"
 #include "cli.h"
 #include "dse.h"
 
 GBLREF block_id		patch_curr_blk;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_addr		*gd_header;
 GBLREF sgmnt_data_ptr_t	cs_data;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF short		crash_count;
@@ -38,96 +35,72 @@ GBLREF gv_key		*gv_currkey;
 
 void dse_f_reg(void)
 {
-	char rn[MAX_RN_LEN];
-	unsigned short rnlen;
-	int i;
-	bool found;
-	gd_region *ptr;
-	gd_addr *temp_gdaddr;
-	gd_binding *map;
+	char		rn[MAX_RN_LEN];
+	unsigned short	rnlen;
+	int		i;
+	boolean_t	found;
+	gd_region	*ptr;
 
-	temp_gdaddr = gd_header;
-	gd_header = original_header;
 	rnlen = SIZEOF(rn);
-	if (!cli_get_str("REGION",rn,&rnlen))
-	{
-		gd_header = temp_gdaddr;
+	if (!cli_get_str("REGION", rn, &rnlen))
 		return;
-	}
-	if (rn[0] == '*' && rnlen == 1)
+	if (('*' == rn[0]) && (1 == rnlen))
 	{
-		util_out_print("List of global directory:!_!AD!/",TRUE,dollar_zgbldir.str.len,dollar_zgbldir.str.addr);
-		for (i=0, ptr = gd_header->regions; i < gd_header->n_regions ;i++, ptr++)
-		{	util_out_print("!/File  !_!AD",TRUE, ptr->dyn.addr->fname_len,&ptr->dyn.addr->fname[0]);
-			util_out_print("Region!_!AD",TRUE, REG_LEN_STR(ptr));
-                 }
-		gd_header = temp_gdaddr;
-		 return;
+		util_out_print("List of global directory:!_!AD!/", TRUE, dollar_zgbldir.str.len, dollar_zgbldir.str.addr);
+		for (i = 0, ptr = original_header->regions; i < original_header->n_regions; i++, ptr++)
+		{
+			util_out_print("!/File  !_!AD", TRUE, ptr->dyn.addr->fname_len, &ptr->dyn.addr->fname[0]);
+			util_out_print("Region!_!AD", TRUE, REG_LEN_STR(ptr));
+		}
+		return;
 	}
 	assert(rn[0]);
 	found = FALSE;
-	for (i=0, ptr = gd_header->regions; i < gd_header->n_regions ;i++, ptr++)
+	for (i = 0, ptr = original_header->regions; i < original_header->n_regions ;i++, ptr++)
 	{
-		if (found = !memcmp(&ptr->rname[0],&rn[0],MAX_RN_LEN))
+		if (found = !memcmp(&ptr->rname[0], &rn[0], MAX_RN_LEN))
 			break;
 	}
 	if (!found)
 	{
-		util_out_print("Error:  region not found.",TRUE);
-		gd_header = temp_gdaddr;
+		util_out_print("Error:  region not found.", TRUE);
 		return;
 	}
 	if (ptr == gv_cur_region)
 	{
-		util_out_print("Error:  already in region: !AD",TRUE,REG_LEN_STR(gv_cur_region));
-		gd_header = temp_gdaddr;
+		util_out_print("Error:  already in region: !AD", TRUE, REG_LEN_STR(gv_cur_region));
 		return;
 	}
-	if (ptr->dyn.addr->acc_meth == dba_cm)
+	if (dba_cm == REG_ACC_METH(ptr))
 	{
-		util_out_print("Error:  Cannot edit an GT.CM database file.",TRUE);
-		gd_header = temp_gdaddr;
+		util_out_print("Error:  Cannot edit an GT.CM database file.", TRUE);
 		return;
 	}
-	if (ptr->dyn.addr->acc_meth == dba_usr)
+	if (dba_usr == REG_ACC_METH(ptr))
 	{
-		util_out_print("Error:  Cannot edit a non-GDS format database file.",TRUE);
-		gd_header = temp_gdaddr;
+		util_out_print("Error:  Cannot edit a non-GDS format database file.", TRUE);
 		return;
 	}
 	if (!ptr->open)
 	{
-		util_out_print("Error:  that region was not opened because it is not bound to any namespace.",TRUE);
-		gd_header = temp_gdaddr;
+		util_out_print("Error:  that region was not opened because it is not bound to any namespace.", TRUE);
 		return;
 	}
-	if (TRUE == cs_addrs->now_crit)
+	if (cs_addrs->now_crit)
 	{
-		util_out_print("Warning:  now leaving region in critical section: !AD",TRUE, gv_cur_region->rname_len,
+		util_out_print("Warning:  now leaving region in critical section: !AD", TRUE, gv_cur_region->rname_len,
 				gv_cur_region->rname);
 	}
 	gv_cur_region = ptr;
 	gv_target = NULL;	/* to prevent out-of-sync situations between gv_target and cs_addrs */
-	gv_currkey->base[0] = '\0';	/* prevent fast-path from op_gvname from being taken as region has been switched
-					 * and gv_target has been reset to NULL.
-					 */
-	gv_currkey->end = 0;	/* clear end so it is in sync with base[0] */
-	switch (gv_cur_region->dyn.addr->acc_meth)
-	{
-	case dba_mm:
-	case dba_bg:
-		cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
-		cs_data = cs_addrs->hdr;
-		break;
-	default:
-		GTMASSERT;
-	}
+	assert((dba_mm == REG_ACC_METH(gv_cur_region)) || (dba_bg == REG_ACC_METH(gv_cur_region)));
+	cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
+	cs_data = cs_addrs->hdr;
 	if (cs_addrs && cs_addrs->critical)
 		crash_count = cs_addrs->critical->crashcnt;
-	util_out_print("!/File  !_!AD",TRUE, DB_LEN_STR(gv_cur_region));
-	util_out_print("Region!_!AD!/",TRUE, REG_LEN_STR(gv_cur_region));
+	util_out_print("!/File  !_!AD", TRUE, DB_LEN_STR(gv_cur_region));
+	util_out_print("Region!_!AD!/", TRUE, REG_LEN_STR(gv_cur_region));
 	patch_curr_blk = get_dir_root();
 	gv_init_reg(gv_cur_region);
-	GET_SAVED_GDADDR(gd_header, temp_gdaddr, map, gv_cur_region);
 	return;
 }
diff --git a/sr_port/dse_find_gvt.c b/sr_port/dse_find_gvt.c
new file mode 100644
index 0000000..e33b129
--- /dev/null
+++ b/sr_port/dse_find_gvt.c
@@ -0,0 +1,71 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gdsblk.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"
+#include "dse.h"
+#include "min_max.h"
+#include "targ_alloc.h"
+#include "hashtab_mname.h"
+
+GBLREF gd_addr	*original_header;
+
+gv_namehead *dse_find_gvt(gd_region *reg, char *name, int name_len)
+{
+	boolean_t		added;
+	gd_gblname		*gname;
+	gv_namehead		*gvt;
+	hash_table_mname	*gvt_hashtab;
+	ht_ent_mname		*tabent;
+	mname_entry		gvent;
+	sgmnt_addrs		*csa;
+
+	assert(reg->open);
+	assert((dba_mm == REG_ACC_METH(reg)) || (dba_bg == REG_ACC_METH(reg)));
+	csa = &FILE_INFO(reg)->s_addrs;
+	gvt_hashtab = (hash_table_mname *)csa->miscptr;
+	if (NULL == gvt_hashtab)
+	{
+		gvt_hashtab = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
+		csa->miscptr = (void *)gvt_hashtab;
+		init_hashtab_mname(gvt_hashtab, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
+	}
+	gvent.var_name.addr = name;
+	gvent.var_name.len = MIN(name_len, MAX_MIDENT_LEN);
+	COMPUTE_HASH_MNAME(&gvent);
+	if (NULL != (tabent = lookup_hashtab_mname(gvt_hashtab, &gvent)))
+		gvt = (gv_namehead *)tabent->value;
+	else
+	{
+		gvt = (gv_namehead *)targ_alloc(reg->max_key_size, &gvent, reg);
+		added = add_hashtab_mname(gvt_hashtab, &gvt->gvname, gvt, &tabent);
+		assert(added);
+	}
+	if (original_header->n_gblnames)
+	{	/* If a "collation" sequence is specified for current global name in the GBLNAME section of the .GLD file,
+		 * setup gvt with that info */
+		gname = gv_srch_gblname(original_header, gvt->gvname.var_name.addr, gvt->gvname.var_name.len);
+		if (NULL != gname)
+		{
+			gvt->act_specified_in_gld = TRUE;
+			gvt->act = gname->act;
+			gvt->ver = gname->ver;
+		}
+	}
+	return gvt;
+}
diff --git a/sr_port/dse_getki.c b/sr_port/dse_getki.c
index b5dace6..aeac302 100644
--- a/sr_port/dse_getki.c
+++ b/sr_port/dse_getki.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,8 +21,6 @@
 #include "fileinfo.h"
 #include "gdsbt.h"
 #include "gdsfhead.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "util.h"
 #include "cli.h"
 #include "stringpool.h"
@@ -30,21 +28,20 @@
 #include "mvalconv.h"
 #include "op.h"
 #include "format_targ_key.h"
+#include "gvcst_protos.h"
 
 #ifdef GTM_TRIGGER
 #include "hashtab_mname.h"
 #include <rtnhdr.h>
-#include "gv_trigger.h"		/* needed for INIT_ROOT_GVT */
 #include "targ_alloc.h"
 #endif
 #ifdef UNICODE_SUPPORTED
 #include "gtm_utf8.h"
 #endif
 
-GBLREF gv_key		*gv_currkey;
-GBLREF sgmnt_addrs      *cs_addrs;
-GBLREF gd_region    	*gv_cur_region;
-GBLREF mval		curr_gbl_root;
+GBLREF	gv_key		*gv_currkey;
+GBLREF	sgmnt_addrs	*cs_addrs;
+GBLREF	gd_region	*gv_cur_region;
 GBLREF	gv_namehead	*gv_target;
 
 LITREF	mval		literal_hasht;
@@ -54,11 +51,10 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 	char 		buf[MAX_ZWR_KEY_SZ], *src, *temp_dst, *bot, *top, *tmp, slit[MAX_KEY_SZ + 1], key_buf[MAX_KEY_SZ + 1];
 	short int	max_key;
 	unsigned short 	buf_len;
-	int  		key_len, dlr_num, dlr_len;
+	int  		dlr_num, dlr_len;
 	int		num;
 	unsigned char	*ptr;
 	mval 		key_subsc;
-	sgmnt_addrs	*csa;
 	span_subs	subs;
 
 	buf_len = SIZEOF(buf);
@@ -67,14 +63,14 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 	bot = temp_dst = (char *)&key_buf[0];
 	top = &buf[buf_len];
 	src = &buf[0];
-	if (*src++ != '^')
+	if ('^' != *src++)
 	{
 		util_out_print("Error:  invalid key.", TRUE);
 		return FALSE;
 	}
-	if ((*src >= 'A' && *src <= 'Z') ||
-	    (*src >= 'a' && *src <= 'z') ||
-	    (*src == '%') || (*src == '#'))			/* first letter must be an alphabet or % or # */
+	if ((('A' <= *src) && ('Z' >= *src))
+		|| (('a' <= *src) && ('z' >= *src))
+		|| ('%' == *src) || ('#' == *src))			/* first letter must be an alphabet or % or # */
 	{
 		*temp_dst++ = *src++;
 	} else
@@ -82,13 +78,14 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 		util_out_print("Error:  invalid key.", TRUE);
 		return FALSE;
 	}
-	for ( ; *src != '(' && src < top ;src++)
+	for ( ; ('(' != *src) && (src < top); src++)
 	{
-		if ((*src >= 'A' && *src <= 'Z') ||
-		    (*src >= 'a' && *src <= 'z') ||
-		    (*src >= '0' && *src <= '9'))
+		if ((('A' <= *src) && ('Z' >= *src))
+			|| (('a' <= *src) && ('z' >= *src))
+			|| (('0' <= *src) && ('9' >= *src)))
+		{
 			*temp_dst = *src;
-		else
+		} else
 		{
 			util_out_print("Error:  invalid key.", TRUE);
 			return FALSE;
@@ -96,10 +93,9 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 		temp_dst++;
 	}
 	*temp_dst = '\0';
-
-	csa = cs_addrs;
-	key_len = (int )(temp_dst - bot);
-	INIT_ROOT_GVT(bot, key_len, curr_gbl_root);
+	gv_target = dse_find_gvt(gv_cur_region, bot, (int)(temp_dst - bot));
+	SET_GV_CURRKEY_FROM_GVT(gv_target);	/* gv_currkey is needed by GVCST_ROOT_SEARCH AND code after it */
+	GVCST_ROOT_SEARCH; /* sets up gv_target->collseq (needed by mval2subsc below ) */
 	bot = (char *)&gv_currkey->base[0];
 	temp_dst = (char *)&gv_currkey->base[0] + gv_currkey->end;
 	max_key = gv_cur_region->max_key_size;
@@ -131,7 +127,7 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 					return FALSE;
 				}
 				src = src + SPAN_SUBS_LEN + 1;
-				for (num = 0, src++; *src != ')'; num = (num * DECIMAL_BASE + (int)(*src++ - ASCII_0)))
+				for (num = 0, src++; ')' != *src; num = (num * DECIMAL_BASE + (int)(*src++ - ASCII_0)))
 					;
 				ptr = gv_currkey->base + gv_currkey->end;
 				num = num - 1;
@@ -142,11 +138,11 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 				*ptr = KEY_DELIMITER;
 				gv_currkey->end = ptr - gv_currkey->base;
 				break;
-			} else if (*src != '\"')		/* numerical subscript */
+			} else if ('\"' != *src)		/* numerical subscript */
 			{
-				for (key_subsc.str.addr = src ; *src != ')' && *src != ','; src++)
+				for (key_subsc.str.addr = src ; (')' != *src) && (',' != *src); src++)
 				{
-					if (src == top || (*src < '0' || *src > '9') && *src != '-' && *src != '.')
+					if (src == top || (('0' > *src) || ('9' < *src)) && ('-' != *src) && ('.' != *src))
 					{
 						util_out_print("Error:  invalid key.", TRUE);
 						return FALSE;
@@ -166,8 +162,8 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 						util_out_print("Error:  invalid key.", TRUE);
 						return FALSE;
 					}
-					if (*src == '\"')
-						if (*++src != '\"')
+					if ('\"' == *src)
+						if ('\"' != *++src)
 							break;
 					*tmp++ = *src++;
 				}
@@ -179,14 +175,14 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 				util_out_print("Error:  Null subscripts not allowed", TRUE);
 				return FALSE;
 		        }
-			mval2subsc(&key_subsc, gv_currkey);
+			mval2subsc(&key_subsc, gv_currkey, gv_cur_region->std_null_coll);
 			if (gv_currkey->end >= max_key)
-				ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
-			if (*src != ',')
+				ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
+			if (',' != *src)
 				break;
 			src++;
 		}
-		if (*src++ != ')')
+		if (')' != *src++)
 		{
 			util_out_print("Error:  invalid key.", TRUE);
 			return FALSE;
@@ -199,6 +195,10 @@ int dse_getki(char *dst, int *len, char *qual, int qual_len)
 		return FALSE;
 	}
 	*len = (int)(temp_dst - bot + 1);
+	assert(3 <= *len);
+	assert(KEY_DELIMITER != gv_currkey->base[*len - 3]);
+	assert(KEY_DELIMITER == gv_currkey->base[*len - 2]);
+	assert(KEY_DELIMITER == gv_currkey->base[*len - 1]);
 	memcpy(dst, &gv_currkey->base[0], *len);
 	return TRUE;
 }
diff --git a/sr_port/dse_ksrch.c b/sr_port/dse_ksrch.c
index 8139a3f..03953e2 100644
--- a/sr_port/dse_ksrch.c
+++ b/sr_port/dse_ksrch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -52,7 +52,7 @@ int dse_ksrch(block_id srch,
 	cache_rec_ptr_t dummy_cr;
 
 	if(!(bp = t_qread(srch, &dummy_int, &dummy_cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	if (((blk_hdr_ptr_t) bp)->bsiz > cs_addrs->hdr->blk_size)
 		b_top = bp + cs_addrs->hdr->blk_size;
 	else if (((blk_hdr_ptr_t) bp)->bsiz < SIZEOF(blk_hdr))
@@ -124,8 +124,10 @@ int dse_ksrch(block_id srch,
 
 int dse_key_srch(block_id srch, block_id_ptr_t key_path, int4 *off, char *targ_key, int targ_len)
 {
-	int status = dse_ksrch(srch, key_path, off, targ_key, targ_len);
-	if(status)
+	int	status;
+
+	status = dse_ksrch(srch, key_path, off, targ_key, targ_len);
+	if (status)
 		return status;
 	else if(!patch_find_root_search)
 	{	/* We are not searching for the global name in the directory tree and search for the regular-key
@@ -139,7 +141,11 @@ int dse_key_srch(block_id srch, block_id_ptr_t key_path, int4 *off, char *targ_k
 		targ_key[targ_len++] = KEY_DELIMITER;
 		patch_path_count = 1; 	/*This indicates the length of the path of node in gvtree*/
 		patch_find_root_search = FALSE;
-		return(dse_ksrch(srch,key_path, off, targ_key, targ_len));
+		status = dse_ksrch(srch, key_path, off, targ_key, targ_len);
+		/* Undo updates to "targ_key" */
+		targ_len -= (SPAN_SUBS_LEN + 2);
+		targ_key[targ_len] = KEY_DELIMITER;
+		return status;
 	}
 	return FALSE;
 }
diff --git a/sr_port/dse_over.c b/sr_port/dse_over.c
index 823dcd9..68a4f57 100644
--- a/sr_port/dse_over.c
+++ b/sr_port/dse_over.c
@@ -46,7 +46,6 @@
 GBLREF char		*update_array, *update_array_ptr;
 GBLREF gd_region        *gv_cur_region;
 GBLREF uint4		update_array_size;
-GBLREF gd_addr		*gd_header;
 GBLREF srch_hist	dummy_hist;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t cs_data;
@@ -57,9 +56,14 @@ GBLREF iconv_t		dse_over_cvtcd;
 #endif
 GBLREF cw_set_element   cw_set[];
 GBLREF UConverter	*chset_desc[];
-LITREF mstr		chset_names[];
 GBLREF spdesc		stringpool;
 
+LITREF mstr		chset_names[];
+
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+
 void dse_over(void)
 {
 	static char 	*data = NULL;
@@ -79,12 +83,8 @@ void dse_over(void)
 	mstr		cvt_src;
 	int		cvt_len;
 
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	blk_size = cs_addrs->hdr->blk_size;
         if (cli_present("BLOCK") == CLI_PRESENT)
@@ -153,7 +153,7 @@ void dse_over(void)
 	t_begin_crit(ERR_DSEFAIL);
 	blkhist.blk_num = blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 
 	size = ((blk_hdr_ptr_t)blkhist.buffaddr)->bsiz;
 	if (size < SIZEOF(blk_hdr))
diff --git a/sr_port/dse_rest.c b/sr_port/dse_rest.c
index 2e90b9f..3f89fde 100644
--- a/sr_port/dse_rest.c
+++ b/sr_port/dse_rest.c
@@ -23,7 +23,6 @@
 #include "gdscc.h"
 #include "dse.h"
 #include "cli.h"
-#include "init_root_gv.h"
 #include "filestruct.h"
 #include "jnl.h"
 #include "util.h"
@@ -42,7 +41,6 @@ GBLREF char		*update_array, *update_array_ptr;
 GBLREF uint4		update_array_size;
 GBLREF srch_hist	dummy_hist;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_addr		*gd_header;
 GBLREF block_id		patch_curr_blk;
 GBLREF save_strct	patch_save_set[PATCH_SAVE_SIZE];
 GBLREF unsigned short int patch_save_count;
@@ -51,6 +49,10 @@ GBLREF sgmnt_data_ptr_t cs_data;
 GBLREF gd_addr		*original_header;
 GBLREF cw_set_element   cw_set[];
 
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+
 void dse_rest(void)
 {
 	block_id	to, from;
@@ -62,17 +64,12 @@ void dse_rest(void)
 	int4		blk_seg_cnt, blk_size;
 	unsigned short	rn_len;
 	uint4		version;
-	gd_addr		*temp_gdaddr;
 	gd_binding	*map;
 	boolean_t	found;
 	srch_blk_status	blkhist;
 
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-
 	if (gv_cur_region->read_only)
-		rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (cli_present("VERSION") != CLI_PRESENT)
 	{
@@ -106,21 +103,15 @@ void dse_rest(void)
 	 	from = to;
 	if (cli_present("REGION") == CLI_PRESENT)
 	{
-
 		rn_len = SIZEOF(rn);
 		if (!cli_get_str("REGION", rn, &rn_len))
 			return;
 		for (i = rn_len; i < MAX_RN_LEN + 1; i++)
 			rn[i] = 0;
 		found = FALSE;
-
-		temp_gdaddr = gd_header;
-		gd_header = original_header;
-
-		for (i=0, region = gd_header->regions; i < gd_header->n_regions ;i++, region++)
+		for (i = 0, region = original_header->regions; i < original_header->n_regions ;i++, region++)
 			if (found = !memcmp(&region->rname[0], &rn[0], MAX_RN_LEN))
 				break;
-		GET_SAVED_GDADDR(gd_header, temp_gdaddr, map, gv_cur_region);
 		if (!found)
 		{
 			util_out_print("Error:  region not found.", TRUE);
@@ -135,9 +126,11 @@ void dse_rest(void)
 	 	region = gv_cur_region;
 	found = FALSE;
 	for (i = 0; i < patch_save_count; i++)
-	 	if (patch_save_set[i].blk == from && patch_save_set[i].region == region
-	 		&& (found = version == patch_save_set[i].ver))
+	{
+	 	if ((patch_save_set[i].blk == from) && (patch_save_set[i].region == region)
+				&& (found = (version == patch_save_set[i].ver)))
 	 		break;
+	}
 	if (!found)
 	{
 	 	util_out_print("Error:  no such version.", TRUE);
@@ -146,10 +139,10 @@ void dse_rest(void)
 	memcpy(util_buff, "!/Restoring block ", 18);
 	util_len = 18;
 	util_len += i2hex_nofill(to, (uchar_ptr_t)&util_buff[util_len], 8);
-	memcpy(&util_buff[util_len]," from version !UL", 17);
+	memcpy(&util_buff[util_len], " from version !UL", 17);
 	util_len += 17;
 	util_buff[util_len] = 0;
-	util_out_print(util_buff,FALSE,version);
+	util_out_print(util_buff, FALSE, version);
 	if (to != from)
 	{
 		memcpy(util_buff, " of block ", 10);
@@ -160,14 +153,14 @@ void dse_rest(void)
 	}
 	if (region != gv_cur_region)
 		util_out_print(" in region !AD", FALSE, LEN_AND_STR(rn));
-	util_out_print("!/",TRUE);
+	util_out_print("!/", TRUE);
 	if (to > cs_addrs->ti->total_blks)
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	t_begin_crit(ERR_DSEFAIL);
 	blk_size = cs_addrs->hdr->blk_size;
 	blkhist.blk_num = to;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	lbp = (uchar_ptr_t)patch_save_set[i].bp;
 
 	BLK_INIT(bs_ptr, bs1);
diff --git a/sr_port/dse_rmrec.c b/sr_port/dse_rmrec.c
index 31ef91f..59004f0 100644
--- a/sr_port/dse_rmrec.c
+++ b/sr_port/dse_rmrec.c
@@ -41,7 +41,6 @@
 
 GBLREF char		*update_array, *update_array_ptr;
 GBLREF uint4		update_array_size;
-GBLREF gd_addr		*gd_header;
 GBLREF gd_region        *gv_cur_region;
 GBLREF srch_hist	dummy_hist;
 GBLREF sgmnt_addrs	*cs_addrs;
@@ -69,7 +68,7 @@ void dse_rmrec(void)
 	srch_blk_status	blkhist;
 
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (cli_present("BLOCK") == CLI_PRESENT)
 	{
@@ -92,7 +91,7 @@ void dse_rmrec(void)
 	blk_size = cs_addrs->hdr->blk_size;
 	blkhist.blk_num = patch_curr_blk;
 	if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	lbp = (uchar_ptr_t)malloc(blk_size);
 	memcpy(lbp, blkhist.buffaddr, blk_size);
 
diff --git a/sr_port/dse_shift.c b/sr_port/dse_shift.c
index 3096191..04b6911 100644
--- a/sr_port/dse_shift.c
+++ b/sr_port/dse_shift.c
@@ -43,10 +43,13 @@ GBLREF uint4		update_array_size;
 GBLREF srch_hist	dummy_hist;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t cs_data;
-GBLREF gd_addr		*gd_header;
 GBLREF block_id 	patch_curr_blk;
 GBLREF cw_set_element   cw_set[];
 
+error_def(ERR_DBRDONLY);
+error_def(ERR_DSEBLKRDFAIL);
+error_def(ERR_DSEFAIL);
+
 void dse_shift(void)
 {
 	bool		forward;
@@ -58,12 +61,8 @@ void dse_shift(void)
 	int4		blk_seg_cnt, blk_size;
 	srch_blk_status	blkhist;
 
-	error_def(ERR_DBRDONLY);
-	error_def(ERR_DSEBLKRDFAIL);
-	error_def(ERR_DSEFAIL);
-
         if (gv_cur_region->read_only)
-                rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
+                rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
 	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
 	if (patch_curr_blk < 0 || patch_curr_blk >= cs_addrs->ti->total_blks || !(patch_curr_blk % cs_addrs->hdr->bplmap))
 	{
@@ -110,7 +109,7 @@ void dse_shift(void)
 	{
 		if (lbp)
 			free(lbp);
-		rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 	}
 	bp = blkhist.buffaddr;
 	size = ((blk_hdr *)bp)->bsiz;
diff --git a/sr_port/dump_record.c b/sr_port/dump_record.c
index e5518d3..5a09882 100644
--- a/sr_port/dump_record.c
+++ b/sr_port/dump_record.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,17 +24,15 @@
 #include "gdsblk.h"
 #include "cli.h"
 #include "copy.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "util.h"
 #include "dse.h"
 #include "print_target.h"
 #include "op.h"
+#include "gvcst_protos.h"
 
 #ifdef GTM_TRIGGER
 #include "hashtab_mname.h"
 #include <rtnhdr.h>		/* needed for gv_trigger.h */
-#include "gv_trigger.h"		/* needed for INIT_ROOT_GVT */
 #include "targ_alloc.h"
 #endif
 #ifdef UNICODE_SUPPORTED
@@ -42,18 +40,17 @@
 #include "gtm_utf8.h"
 #endif
 
-
 GBLDEF bool             wide_out;
 GBLDEF char             patch_comp_key[MAX_KEY_SZ + 1];
 GBLDEF unsigned short   patch_comp_count;
 GBLDEF int              patch_rec_counter;
+
 GBLREF sgmnt_addrs      *cs_addrs;
 GBLREF VSIG_ATOMIC_T	util_interrupt;
-GBLREF mval             curr_gbl_root;
 GBLREF int              patch_is_fdmp;
 GBLREF int              patch_fdmp_recs;
-GBLREF	gv_key		*gv_currkey;
-GBLREF	gv_namehead	*gv_target;
+GBLREF gd_region    	*gv_cur_region;
+GBLREF gv_namehead	*gv_target;
 
 LITREF	mval		literal_hasht;
 
@@ -74,7 +71,6 @@ sm_uc_ptr_t  dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr
         ssize_t   	chlen;
 	block_id	blk_id;
 	boolean_t	rechdr_displayed = FALSE;
-	sgmnt_addrs	*csa;
 
 	if (rp >= b_top)
 		return NULL;
@@ -106,7 +102,7 @@ sm_uc_ptr_t  dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr
 	r_top = rp + size;
 	if (r_top > b_top)
 		r_top = b_top;
-	else  if (r_top < rp + SIZEOF(rec_hdr))
+	else if (r_top < rp + SIZEOF(rec_hdr))
 		r_top = rp + SIZEOF(rec_hdr);
 	if (cc > patch_comp_count)
 		cc = patch_comp_count;
@@ -123,7 +119,7 @@ sm_uc_ptr_t  dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr
 		size = SIZEOF(patch_comp_key) - 2 - cc;
 	memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size);
 	patch_comp_count = cc + size;
-	patch_comp_key[patch_comp_count] = patch_comp_key[patch_comp_count + 1] = 0;
+	patch_comp_key[patch_comp_count] = patch_comp_key[patch_comp_count + 1] = '\0';
 	if (patch_is_fdmp)
 	{
 		if (dse_fdmp(key_top, (int)(r_top - key_top)))
@@ -145,16 +141,26 @@ sm_uc_ptr_t  dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr
 			}
 		}
 		util_out_print("Key ", FALSE);
-		if (r_top == b_top
+		if ((r_top == b_top)
 			&& ((blk_hdr_ptr_t)bp)->levl && !EVAL_CMPC((rec_hdr_ptr_t)rp)
-			&& r_top - rp == SIZEOF(rec_hdr) + SIZEOF(block_id))
-				util_out_print("*", FALSE);
-		else  if (patch_comp_key[0])
+			&& ((r_top - rp) == (SIZEOF(rec_hdr) + SIZEOF(block_id))))
+		{	/* *-key */
+			assert('\0' == patch_comp_key[0]);
+			assert('\0' == patch_comp_key[1]);
+			util_out_print("*", FALSE);
+			/* it is ok not to set gv_target in this case as "print_target" does not need it */
+		} else if (patch_comp_key[0])
 		{
 			util_out_print("^", FALSE);
-			csa = cs_addrs;
-			RETRIEVE_ROOT_VAL(patch_comp_key, key_buf, temp_ptr, temp_key, buf_len);
-			INIT_ROOT_GVT(key_buf, buf_len, curr_gbl_root);
+			temp_ptr = patch_comp_key;
+			temp_key = key_buf;
+			/* Copy from temp_ptr to temp_key until the first zero byte (copy that as well) */
+			for (buf_len = 0; (*temp_key++ = *temp_ptr++); buf_len++)
+				;
+			*temp_key = KEY_DELIMITER;	/* Set the second zero byte */
+			gv_target = dse_find_gvt(gv_cur_region, key_buf, buf_len); /* sets up gv_target */
+			SET_GV_CURRKEY_FROM_GVT(gv_target);	/* gv_currkey is needed by GVCST_ROOT_SEARCH */
+			GVCST_ROOT_SEARCH; /* sets up gv_target->collseq (needed by print_target --> gvsub2str) */
 		}
 		print_target((uchar_ptr_t)patch_comp_key);
 		util_out_print(0, TRUE);
diff --git a/sr_port/eintr_wrappers.h b/sr_port/eintr_wrappers.h
index 1d9f07a..2e4869f 100644
--- a/sr_port/eintr_wrappers.h
+++ b/sr_port/eintr_wrappers.h
@@ -47,22 +47,25 @@
 	} while(-1 == RC && EINTR == errno);		\
 }
 
-#define CLOSEDIR(DIR, RC)				\
+#define CLOSE(FD, RC)					\
 {							\
 	do						\
 	{						\
-		RC = closedir(DIR);			\
+		RC = close(FD);				\
 	} while(-1 == RC && EINTR == errno);		\
 }
 
-#define CONNECT_SOCKET(SOCKET, ADDR, LEN, RC)		\
+#define CLOSEDIR(DIR, RC)				\
 {							\
 	do						\
 	{						\
-		RC = CONNECT(SOCKET, ADDR, LEN);	\
+		RC = closedir(DIR);			\
 	} while(-1 == RC && EINTR == errno);		\
 }
 
+#define CONNECT_SOCKET(SOCKET, ADDR, LEN, RC)		\
+	RC = gtm_connect(SOCKET, ADDR, LEN)
+
 #define CREATE_FILE(PATHNAME, MODE, RC)			\
 {							\
 	do						\
@@ -169,6 +172,15 @@
 	} while(-1 == RC && EINTR == errno);		\
 }
 
+#define RECV(SOCKET, BUF, LEN, FLAGS, RC)		\
+{							\
+	do						\
+	{						\
+		RC = (int)recv(SOCKET, BUF, (int)(LEN),	\
+			 FLAGS);			\
+	} while(-1 == RC && EINTR == errno);		\
+}
+
 #define RECVFROM_SOCK(SOCKET, BUF, LEN, FLAGS,		\
 		 ADDR, ADDR_LEN, RC)			\
 {							\
diff --git a/sr_port/emit_code.c b/sr_port/emit_code.c
index aa3b0cc..11c756f 100644
--- a/sr_port/emit_code.c
+++ b/sr_port/emit_code.c
@@ -140,7 +140,7 @@ void trip_gen (triple *ct)
 	int		off;
 
 #	if !defined(TRUTH_IN_REG) && (!(defined(__osf__) || defined(__x86_64__) || defined(Linux390)))
-	GTMASSERT;
+	assertpro(FALSE);
 #	endif
 	DEBUG_ONLY(opcode_emitted = FALSE);
 	current_triple = ct;	/* save for possible use by internal rtns */
@@ -242,7 +242,7 @@ void trip_gen (triple *ct)
 				tsp = &ttt[ttt[tp]];
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && ct->opcode);
 		}
 	} else if (oct & OCT_COERCE)
 	{
@@ -258,7 +258,7 @@ void trip_gen (triple *ct)
 				tp = ttt[tp + 4];
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && (oc_tab[ct->operand[0].oprval.tref->opcode].octype & (OCT_VALUE | OCT_BOOL)));
 				break;
 		}
 		tsp = &ttt[tp];
@@ -604,7 +604,7 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						inst++;
 						emit_trip(*(fst_opr + save_inst), addr, GENERIC_OPCODE_LDA, gtm_reg(*inst++));
 					} else
-						GTMASSERT;
+						assertpro(FALSE && *inst);
 					break;
 				case VXI_MOVC3:
 					/* The MOVC3 instruction is only used to copy an mval from one place to another
@@ -712,7 +712,7 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 #								endif
 								inst++;
 							} else
-								GTMASSERT;
+								assertpro(FALSE && *inst);
 						}
 					} else if (*inst == VXT_VAL)
 					{
@@ -724,7 +724,7 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						inst++;
 						emit_trip(*(fst_opr + save_inst), TRUE, GENERIC_OPCODE_LOAD, MOVL_REG_R1);
 					} else
-						GTMASSERT;
+						assertpro(FALSE && *inst);
 					break;
 				case VXT_IREPAB:
 					assert(*inst == VXT_VAL);
@@ -746,7 +746,7 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						inst++;
 						emit_trip(*(fst_opr + *inst++), TRUE, GENERIC_OPCODE_LDA, reg);
 					} else
-						GTMASSERT;
+						assertpro(FALSE && *inst);
 					emit_push(reg);
 					break;
 				case VXT_IREPL:
@@ -772,7 +772,7 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 						inst++;
 						emit_trip(*(fst_opr + *inst++), TRUE, GENERIC_OPCODE_LOAD, reg);
 					} else
-						GTMASSERT;
+						assertpro(FALSE && *inst);
 					emit_push(reg);
 					break;
 				case VXI_TSTL:
@@ -795,12 +795,12 @@ short	*emit_vax_inst (short *inst, oprtype **fst_opr, oprtype **lst_opr)
 					}
 					break;
 				default:
-					GTMASSERT;
+					assertpro(FALSE && sav_in);
 					break;
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 	assert(code_idx < NUM_BUFFERRED_INSTRUCTIONS);
@@ -923,7 +923,7 @@ void	emit_jmp (uint4 branchop, short **instp, int reg)
 							break;
 #						endif
 						default:
-							GTMASSERT;
+							assertpro(FALSE && branchop);
 							break;
 					}
 					RISC_ONLY(
@@ -985,7 +985,7 @@ void	emit_jmp (uint4 branchop, short **instp, int reg)
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 }
@@ -1022,7 +1022,7 @@ void	emit_pcrel(void)
 			emit_base_offset(GTM_REG_CODEGEN_TEMP, INST_SIZE * branch_offset);
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 }
@@ -1129,7 +1129,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							inst_emitted = TRUE;
 							break;
 						default:
-							GTMASSERT;
+							assertpro(FALSE && ct->opcode);
 							break;
 					}
 					break;
@@ -1145,10 +1145,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							REVERT_GENERICINST_TO_WORD(generic_inst);
 						}
 					)
-					NON_GTM64_ONLY(
-						if (offset < 0  ||  offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					emit_base_offset(GTM_REG_FRAME_TMP_PTR, offset);
 					break;
 
@@ -1164,10 +1161,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							REVERT_GENERICINST_TO_WORD(generic_inst);
 						}
 					)
-					NON_GTM64_ONLY(
-						if (offset < 0  ||  offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					if (opr->oprclass == TVAR_REF)
 						reg = GTM_REG_FRAME_VAR_PTR;
 					else
@@ -1281,7 +1275,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							}
 							break;
 						case OC_ILIT:
-							assert(generic_inst == GENERIC_OPCODE_LOAD);
+							assert(GENERIC_OPCODE_LOAD == generic_inst);
 							immediate = ct->operand[0].oprval.ilit;
 							memcpy(obpt, &vdat_immed[0], VDAT_IMMED_SIZE);
 							obpt += VDAT_IMMED_SIZE;
@@ -1297,7 +1291,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							inst_emitted = TRUE;
 							break;
 						default:
-							GTMASSERT;
+							assertpro(FALSE && ct->opcode);
 							break;
 					}
 					break;
@@ -1306,10 +1300,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 					assert(val_output);
 					offset = sa_temps_offset[opr->oprclass];
 					offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass];
-					NON_GTM64_ONLY(
-						if (offset < 0  ||  offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					if (offset < 127)
 					{
 						memcpy(obpt, &vdat_bdisp[0], VDAT_BDISP_SIZE);
@@ -1366,10 +1357,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 						memcpy(obpt, &vdat_r9[0], VDAT_R9_SIZE);
 						obpt += VDAT_R9_SIZE;
 					}
-					NON_GTM64_ONLY(
-						if (offset < 0  ||  offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					if (opr->oprclass == TVAR_REF)
 						reg = GTM_REG_FRAME_VAR_PTR;
 					else
@@ -1416,7 +1404,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 					break;
 
 				default:
-					GTMASSERT;
+					assertpro(FALSE && opr->oprclass);
 					break;
 			}
 			if (!inst_emitted) {
@@ -1484,7 +1472,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							inst_emitted = TRUE;
 							break;
 						default:
-							GTMASSERT;
+							assertpro(FALSE && ct->opcode);
 							break;
 					}
 					break;
@@ -1500,11 +1488,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							REVERT_GENERICINST_TO_WORD(generic_inst);
 						}
 					)
-
-					NON_GTM64_ONLY(
-						if (offset < 0  ||  offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					emit_base_offset(GTM_REG_FRAME_TMP_PTR, offset);
 					break;
 				case TCAD_REF:
@@ -1519,10 +1503,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 							REVERT_GENERICINST_TO_WORD(generic_inst);
 						}
 					)
-					NON_GTM64_ONLY(
-						if (offset < 0 || offset > MAX_OFFSET)
-							GTMASSERT;
-					)
+					NON_GTM64_ONLY(assertpro((0 <= offset) &&  (MAX_OFFSET >= offset));)
 					if (opr->oprclass == TVAR_REF)
 						reg = GTM_REG_FRAME_VAR_PTR;
 					else
@@ -1560,7 +1541,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 					ocnt_ref_opr = opr;
 					break;
 				default:
-					GTMASSERT;
+					assertpro(FALSE && opr->oprclass);
 					break;
 			}
 			/* If we haven't emitted a finished instruction already, finish it now */
@@ -1570,7 +1551,7 @@ void	emit_trip(oprtype *opr, boolean_t val_output, uint4 generic_inst, int trg_r
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 }
@@ -1632,7 +1613,7 @@ int	get_arg_reg(void)
 				arg_reg_i = GTM_REG_ACCUM;
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 	return arg_reg_i;
@@ -1676,7 +1657,7 @@ int	gtm_reg(int vax_reg)
 			reg = GTM_REG_FRAME_POINTER;
 			break;	/* VMS ap */
 		default:
-			GTMASSERT;
+			assertpro(FALSE && (vax_reg & 0x0f));
 			break;
 	}
 	return reg;
@@ -1714,7 +1695,7 @@ void	emit_push(int reg)
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && cg_phase);
 			break;
 	}
 	if (cg_phase == CGP_MACHINE || cg_phase == CGP_ASSEMBLY)
@@ -1766,8 +1747,7 @@ int	next_vax_push_list(void)
 	if (push_list_index >= PUSH_LIST_SIZE)
 	{
 		push_list_index=0;
-		if (current_push_list_ptr->next == 0 )
-			GTMASSERT;
+		assertpro(current_push_list_ptr->next);
 		current_push_list_ptr = current_push_list_ptr->next;
 	}
 	return (current_push_list_ptr->value[push_list_index]);
diff --git a/sr_port/entryref.c b/sr_port/entryref.c
index 0056db7..b05314f 100644
--- a/sr_port/entryref.c
+++ b/sr_port/entryref.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -106,18 +106,27 @@ triple *entryref(opctype op1, opctype op2, mint commargcode, boolean_t can_comma
 			rtn_str.addr = rtnname.addr;
 			advancewindow();
 			if (!IS_MCODE_RUNNING)
-			{	/* Triples for indirect code */
-				same_rout = (MIDENT_EQ(&rtnname, &routine_name) && can_commarg);
+			{	/* Triples for normal compiled code. */
+				NON_USHBIN_ONLY(same_rout = (MIDENT_EQ(&rtnname, &routine_name) && can_commarg));
+				/* On shared binary platforms, we support recursive relink, and it's possible for an old version
+				 * of a routine to invoke a different new version. Therefore, even if a label corresponds to the
+				 * current routine name, we need to treat this as an external reference.
+				 */
 				if (!textname)
 				{	/* Resolve routine and label names to addresses for most calls */
 					if (!label.oprclass && !offset.oprclass)
-					{	/* Routine only (no label or offset) */
+					{	/* Do LABEL^RTN comes here (LABEL is *not* indirect) */
+#						ifndef USHBIN_SUPPORTED
 						if (same_rout)
-						{
+						{	/* Do LABEL^SAMERTN comes here.
+							 * On platforms where we don't support recursive relink, we can treat
+							 * Do LABEL^SAMERTN the same as Do LABEL, and morph this into a local call.
+							 */
 							rettrip = newtriple(op1);
 							rettrip->operand[0] =  put_mlab(&labname);
 						} else
-						{
+#						endif
+						{	/* Create an external reference to LABEL^RTN */
 							rettrip = maketriple(op2);
 							if (rtnname.addr[0] == '%')
 								rtnname.addr[0] = '_';
@@ -127,8 +136,11 @@ triple *entryref(opctype op1, opctype op2, mint commargcode, boolean_t can_comma
 							ins_triple(rettrip);
 						}
 						return rettrip;
-					} else if (!same_rout)
-					{
+					} else NON_USHBIN_ONLY(if (!same_rout))
+					{	/* Do @"LABEL"^RTN comes here (LABEL is indirect).
+						 * Exception: on non-USHBIN platforms, we morph Do @"LABEL"^SAMERTN into a local
+						 * call in the next else-block.
+						 */
 						rte1 = put_str(rtn_str.addr, rtn_str.len);
 						if (rtnname.addr[0] == '%')
 							rtnname.addr[0] = '_';
@@ -137,8 +149,11 @@ triple *entryref(opctype op1, opctype op2, mint commargcode, boolean_t can_comma
 						ref->operand[0] = rte1;
 						ref->operand[1] = routine;
 						routine = put_tref(ref);
-					} else
+					}
+#					ifndef USHBIN_SUPPORTED
+					else	/* Do @"LABEL"^SAMERTN comes here. Again, morph into local call Do @"LABEL" */
 						routine = put_tref(newtriple(OC_CURRHD));
+#					endif
 				} else
 				{	/* Return the actual names used */
 					if (!label.oprclass && !offset.oprclass)
@@ -155,7 +170,7 @@ triple *entryref(opctype op1, opctype op2, mint commargcode, boolean_t can_comma
 						routine = put_str(rtn_str.addr, rtn_str.len);
 				}
 			} else
-			{	/* Triples for normal compiled code */
+			{	/* Triples for indirect code */
 				routine = put_str(rtn_str.addr, rtn_str.len);
 				if (!textname)
 				{	/* If not returning text name, convert text name to routine header address */
@@ -190,15 +205,9 @@ triple *entryref(opctype op1, opctype op2, mint commargcode, boolean_t can_comma
 			routine = put_tref(newtriple(OC_CURRHD));
 		else
 		{	/* If we need a name, the mechanism to retrieve it differs between normal and indirect compilation */
-			if (!IS_MCODE_RUNNING)
 				/* For normal compile, use routine name set when started compile */
-				routine = put_str(routine_name.addr, routine_name.len);
-			else
-				/* For an indirect compile, obtain the currently running routine header and pull the routine
-				 * name out of that.
-				 */
-				routine = put_str(frame_pointer->rvector->routine_name.addr,
-						  frame_pointer->rvector->routine_name.len);
+				/* Routine name can vary. textname=TRUE callers (zgoto) fetch name from frame_pointer at runtime */
+			routine = put_str("",0);
 		}
 	}
 	if (!offset.oprclass)
diff --git a/sr_port/expritem.c b/sr_port/expritem.c
index c687029..cc36267 100644
--- a/sr_port/expritem.c
+++ b/sr_port/expritem.c
@@ -73,6 +73,7 @@ LITDEF nametabent svn_names[] =
 	,{ 2, "ZB" }
 	,{ 2, "ZC" }
 	,{ 3, "ZCH" }, { 6, "ZCHSET" }
+	,{ 3, "ZCL*" }
 	,{ 3, "ZCM*" }
 	,{ 3, "ZCO*" }
 	,{ 3, "ZCS*" }
@@ -87,6 +88,7 @@ LITDEF nametabent svn_names[] =
 	,{ 4, "ZINT*"}
 	,{ 3, "ZIO" }
 	,{ 2, "ZJ" }, { 4, "ZJOB" }
+	,{ 4, "ZKEY" }
 	,{ 2, "ZL*" }
 	,{ 8, "ZMAXTPTI*" }
 	,{ 3, "ZMO*" }
@@ -123,7 +125,7 @@ LITDEF nametabent svn_names[] =
 LITDEF unsigned char svn_index[27] = {
 	 0,  0,  0,  0,  2,  8,  8,  8, 10,	/* a b c d e f g h i */
 	12, 14 ,16, 16, 16, 16, 16, 18, 20,	/* j k l m n o p q r */
-	22, 28, 34 ,34, 34, 34, 35, 36, 90	/* s t u v w x y z ~ */
+	22, 28, 34 ,34, 34, 34, 35, 36, 92	/* s t u v w x y z ~ */
 };
 
 /* These entries correspond to the entries in the svn_names array */
@@ -153,6 +155,7 @@ LITDEF svn_data_type svn_data[] =
 	,{ SV_ZB, FALSE, ALL_SYS }
 	,{ SV_ZC, FALSE, ALL_SYS }
 	,{ SV_ZCHSET, FALSE, ALL_SYS }, { SV_ZCHSET, FALSE, ALL_SYS }
+	,{ SV_ZCLOSE, FALSE, UNIX_OS }
 	,{ SV_ZCMDLINE, FALSE, ALL_SYS }
 	,{ SV_ZCOMPILE, TRUE, ALL_SYS }
 	,{ SV_ZCSTATUS, FALSE, ALL_SYS}
@@ -167,6 +170,7 @@ LITDEF svn_data_type svn_data[] =
 	,{ SV_ZINTERRUPT, TRUE, ALL_SYS}
 	,{ SV_ZIO, FALSE, ALL_SYS }
 	,{ SV_ZJOB, FALSE, ALL_SYS }, { SV_ZJOB, FALSE, ALL_SYS }
+	,{ SV_ZKEY, FALSE , ALL_SYS }
 	,{ SV_ZLEVEL, FALSE, ALL_SYS }
 	,{ SV_ZMAXTPTIME, TRUE, ALL_SYS }
 	,{ SV_ZMODE, FALSE, ALL_SYS }
diff --git a/sr_port/f_text.c b/sr_port/f_text.c
index 5608823..8cc68b7 100644
--- a/sr_port/f_text.c
+++ b/sr_port/f_text.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -94,12 +94,7 @@ int f_text(oprtype *a, opctype op)
 	if (TK_CIRCUMFLEX != TREF(window_token))
 	{	/* No routine specified - default to current routine */
 		if (OC_INDFUN != r->opcode)
-		{
-			if (!run_time)
-				label->operand[1] = put_str(routine_name.addr, routine_name.len);
-			else
-				label->operand[1] = put_tref(newtriple(OC_CURRTN));
-		}
+			label->operand[1] = PUT_CURRENT_RTN; /* tell op_fntext to pick up current routine version */
 	} else
 	{	/* Routine has been specified - pull it */
 		advancewindow();
diff --git a/sr_port/fgncal.h b/sr_port/fgncal.h
index a615f01..f4c068b 100644
--- a/sr_port/fgncal.h
+++ b/sr_port/fgncal.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,4 +18,17 @@ void fgncal_rundown(void);
 
 #include "fgncalsp.h"
 
+/* Checks whether the last bit of the passed mask M is 1. This is how we decide whether an argument is of input-only, input-output,
+ * or output-only type. To be specific, if an argument is of input-only type, its bit will be set in the input mask but not the
+ * output mask; if it is output-only, then the bit is only set in the output mask; finally, if it is input-output, then its bit is
+ * set in the both masks. Note that after checking the mask bit for one argument, the mask needs to be binary shifted, such that the
+ * last bit contains the status of the next argument, and so on.
+ */
+#define MASK_BIT_ON(M)	(M & 1)
+
+/* Checks whether V is defined and marked for use in a specific input/output direction, depending on whether M is an input or output
+ * mask (see the comment for MASK_BIT_ON), which is what determines if the actual or default value should be used.
+ */
+#define MV_ON(M, V)	(MASK_BIT_ON(M) && MV_DEFINED(V))
+
 #endif
diff --git a/sr_port/fgncal_unwind.c b/sr_port/fgncal_unwind.c
index ba1591c..79123be 100644
--- a/sr_port/fgncal_unwind.c
+++ b/sr_port/fgncal_unwind.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,6 +10,7 @@
  ****************************************************************/
 
 #include "mdef.h"
+
 #include <rtnhdr.h>
 #include "stack_frame.h"
 #include "tp_frame.h"
@@ -19,13 +20,23 @@
 #include "op.h"
 #include "fgncal.h"
 #ifdef GTM_TRIGGER
-#include "gdsroot.h"
-#include "gtm_facility.h"
-#include "fileinfo.h"
-#include "gdsbt.h"
-#include "gdsfhead.h"
-#include "gv_trigger.h"
-#include "gtm_trigger.h"
+#  include "gdsroot.h"
+#  include "gtm_facility.h"
+#  include "fileinfo.h"
+#  include "gdsbt.h"
+#  include "gdsfhead.h"
+#  include "gv_trigger.h"
+#  include "gtm_trigger.h"
+#endif
+/* On UNIX, the temp_fgncal_stack threadgbl can override fgncal_stack but VMS does not have
+ * this support so define the FGNCAL_STACK macro here such that they are the same.
+ */
+#ifdef UNIX
+#  include "gtmci.h"	/* Contains FGNCAL_STACK macro */
+#elif defined(VMS)
+#  define FGNCAL_STACK fgncal_stack
+#else
+#  error "Unsupported platform"
 #endif
 
 GBLDEF unsigned char	*fgncal_stack;
@@ -38,11 +49,15 @@ error_def(ERR_STACKUNDERFLO);
 void fgncal_unwind(void)
 {
 	mv_stent	*mvc;
+	unsigned char	*local_fgncal_stack;
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	assert((msp <= stackbase) && (msp > stacktop));
 	assert((mv_chain <= (mv_stent *)stackbase) && (mv_chain > (mv_stent *)stacktop));
 	assert((frame_pointer <= (stack_frame*)stackbase) && (frame_pointer > (stack_frame *)stacktop));
-	while (frame_pointer && (frame_pointer < (stack_frame *)fgncal_stack))
+	local_fgncal_stack = FGNCAL_STACK;
+	while (frame_pointer && (frame_pointer < (stack_frame *)local_fgncal_stack))
 	{
 #		ifdef GTM_TRIGGER
 		if (SFT_TRIGR & frame_pointer->type)
@@ -51,13 +66,11 @@ void fgncal_unwind(void)
 #		endif
 			op_unwind();
 	}
-	for (mvc = mv_chain; mvc < (mv_stent *)fgncal_stack; )
-	{
+	for (mvc = mv_chain; mvc < (mv_stent *)local_fgncal_stack; mvc = (mv_stent *)(mvc->mv_st_next + (char *) mvc))
 		unw_mv_ent(mvc);
-		mvc = (mv_stent *)(mvc->mv_st_next + (char *) mvc);
-	}
 	mv_chain = mvc;
-	msp = fgncal_stack;
+	msp = local_fgncal_stack;
+	UNIX_ONLY(TREF(temp_fgncal_stack) = NULL);
 	if (msp > stackbase)
-		rts_error(VARLSTCNT(1) ERR_STACKUNDERFLO);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_STACKUNDERFLO);
 }
diff --git a/sr_port/find_mvstent.c b/sr_port/find_mvstent.c
index 6a8784c..a5e4123 100644
--- a/sr_port/find_mvstent.c
+++ b/sr_port/find_mvstent.c
@@ -1,12 +1,12 @@
 /****************************************************************
- *                                                              *
- *      Copyright 2011 Fidelity Information Services, Inc *
- *                                                              *
- *      This source code contains the intellectual property     *
- *      of its copyright holder(s), and is made available       *
- *      under a license.  If you do not know the terms of       *
- *      the license, please stop and do not read further.       *
- *                                                              *
+ *								*
+ *	Copyright 2011, 2013 Fidelity Information Services, Inc *
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
  ****************************************************************/
 
 #include "mdef.h"
@@ -14,47 +14,45 @@
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 #include <rtnhdr.h>
 #include "mv_stent.h"
 #include "find_mvstent.h"
 #include "stack_frame.h"
 
-GBLREF  mv_stent                *mv_chain;
-GBLREF  stack_frame             *frame_pointer;
-GBLREF  unsigned char           *stackbase, *stacktop, *msp, *stackwarn;
+GBLREF	mv_stent		*mv_chain;
+GBLREF	stack_frame		*frame_pointer;
+GBLREF	unsigned char		*stackbase, *stacktop, *msp, *stackwarn;
 
 /* Find and optionally clear the mv_stent keeping interrupted device information for us */
 mv_stent *io_find_mvstent(io_desc *io_ptr, boolean_t clear_mvstent)
 {
-        mv_stent        *mvc, *mv_zintdev;
+	mv_stent	*mvc, *mv_zintdev;
 
-        assert(msp <= stackbase && msp > stacktop);
-        assert(mv_chain <= (mv_stent *)stackbase && mv_chain > (mv_stent *)stacktop);
-        assert(frame_pointer <= (stack_frame *)stackbase && frame_pointer > (stack_frame *)stacktop);
-        mv_zintdev = NULL;
-        for (mvc = mv_chain; mvc < (mv_stent *)frame_pointer ; mvc = (mv_stent *)(mvc->mv_st_next + (char *)mvc))
-        {
-                if (MVST_ZINTDEV == mvc->mv_st_type && io_ptr == mvc->mv_st_cont.mvs_zintdev.io_ptr)
-                {
-                        mv_zintdev = mvc;
-                        break;
-                }
-                if (!mvc->mv_st_next)
-                        GTMASSERT;
-        }
-        if (mv_zintdev && clear_mvstent)
-        {
-                if (mv_chain == mv_zintdev)
-                        POP_MV_STENT();         /* just pop if top of stack */
+	assert(msp <= stackbase && msp > stacktop);
+	assert(mv_chain <= (mv_stent *)stackbase && mv_chain > (mv_stent *)stacktop);
+	assert(frame_pointer <= (stack_frame *)stackbase && frame_pointer > (stack_frame *)stacktop);
+	mv_zintdev = NULL;
+	for (mvc = mv_chain; mvc < (mv_stent *)frame_pointer ; mvc = (mv_stent *)(mvc->mv_st_next + (char *)mvc))
+	{
+		if (MVST_ZINTDEV == mvc->mv_st_type && io_ptr == mvc->mv_st_cont.mvs_zintdev.io_ptr)
+		{
+			mv_zintdev = mvc;
+			break;
+		}
+		assertpro(mvc->mv_st_next);
+	}
+	if (mv_zintdev && clear_mvstent)
+	{
+		if (mv_chain == mv_zintdev)
+			POP_MV_STENT();		/* just pop if top of stack */
 		else
 		{
 			mv_zintdev->mv_st_cont.mvs_zintdev.io_ptr = NULL;
 			mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid = FALSE;
 		}
-        }
-        return mv_zintdev;
+	}
+	return mv_zintdev;
 }
 
 /* Find and optionally clear the mv_stent keeping information for interrupted
@@ -64,44 +62,43 @@ mv_stent *io_find_mvstent(io_desc *io_ptr, boolean_t clear_mvstent)
 mv_stent *find_mvstent_cmd(zintcmd_ops match_command, unsigned char *match_restart_pc, unsigned char *match_restart_ctxt,
 	boolean_t clear_mvstent)
 {
-        mv_stent        *mvc, *mv_zintcmd;
+	mv_stent	*mvc, *mv_zintcmd;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-        assert(msp <= stackbase && msp > stacktop);
-        assert(mv_chain <= (mv_stent *)stackbase && mv_chain > (mv_stent *)stacktop);
-        assert(frame_pointer <= (stack_frame *)stackbase && frame_pointer > (stack_frame *)stacktop);
+	assert(msp <= stackbase && msp > stacktop);
+	assert(mv_chain <= (mv_stent *)stackbase && mv_chain > (mv_stent *)stacktop);
+	assert(frame_pointer <= (stack_frame *)stackbase && frame_pointer > (stack_frame *)stacktop);
 	assert((0 < match_command) && (ZINTCMD_LAST > match_command));
-        mv_zintcmd = NULL;
+	mv_zintcmd = NULL;
 	if ((0 >= TAREF1(zintcmd_active, match_command).count)	/* at least one mv_stent for this command */
 		|| (match_restart_pc != TAREF1(zintcmd_active, match_command).restart_pc_last)
 		|| (match_restart_ctxt != TAREF1(zintcmd_active, match_command).restart_ctxt_last))
 		return mv_zintcmd;	/* not ours so no need to search stack */
-        for (mvc = mv_chain; mvc < (mv_stent *)frame_pointer ; mvc = (mv_stent *)(mvc->mv_st_next + (char *)mvc))
-        {
-                if (MVST_ZINTCMD == mvc->mv_st_type && match_command == mvc->mv_st_cont.mvs_zintcmd.command
+	for (mvc = mv_chain; mvc < (mv_stent *)frame_pointer ; mvc = (mv_stent *)(mvc->mv_st_next + (char *)mvc))
+	{
+		if (MVST_ZINTCMD == mvc->mv_st_type && match_command == mvc->mv_st_cont.mvs_zintcmd.command
 			&& match_restart_pc == mvc->mv_st_cont.mvs_zintcmd.restart_pc_check
 			&& match_restart_ctxt == mvc->mv_st_cont.mvs_zintcmd.restart_ctxt_check)
-                {
-                        mv_zintcmd = mvc;
-                        break;
-                }
-                if (!mvc->mv_st_next)
-                        GTMASSERT;
-        }
-        if (mv_zintcmd && clear_mvstent)
-        {	/* restore previous zintcmd_active values before clearing MV_STENT entry */
+		{
+			mv_zintcmd = mvc;
+			break;
+		}
+		assertpro(mvc->mv_st_next);
+	}
+	if (mv_zintcmd && clear_mvstent)
+	{	/* restore previous zintcmd_active values before clearing MV_STENT entry */
 		TAREF1(zintcmd_active, match_command).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior;
 		TAREF1(zintcmd_active, match_command).restart_ctxt_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior;
 		TAREF1(zintcmd_active, match_command).count--;
 		assert(0 <= TAREF1(zintcmd_active, match_command).count);
-                if (mv_chain == mvc)
-                        POP_MV_STENT();         /* just pop if top of stack */
+		if (mv_chain == mvc)
+			POP_MV_STENT();		/* just pop if top of stack */
 		else
 		{
 			mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP;
 			mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL;
 		}
-        }
-        return mv_zintcmd;
+	}
+	return mv_zintcmd;
 }
diff --git a/sr_port/find_rtn_hdr.c b/sr_port/find_rtn_hdr.c
index fe3493f..62aacaa 100644
--- a/sr_port/find_rtn_hdr.c
+++ b/sr_port/find_rtn_hdr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -15,18 +15,42 @@
 #include <rtnhdr.h>
 #include "ident.h"
 #include "min_max.h"
+#include "stack_frame.h"
+#include "compiler.h"	/* for WANT_CURRENT_RTN_MSTR macro */
 
 #define S_CUTOFF 7
 GBLREF rtn_tabent	*rtn_names, *rtn_names_end;
+GBLREF stack_frame	*frame_pointer;
 
 rhdtyp	*find_rtn_hdr(mstr *name)
 {
+	rtn_tabent	*rtabent;
+
+	if (WANT_CURRENT_RTN_MSTR(name))	/* want the *current* version on the stack, not the *newest* ZLINK'd version */
+		return CURRENT_RHEAD_ADR(frame_pointer->rvector);
+	if (find_rtn_tabent(&rtabent, name))
+		return rtabent->rt_adr;
+	else
+		return NULL;
+}
+
+/*
+ * Returns TRUE if a rtn_tabent exists for routine <name>, i.e. if
+ * 	<name> is currently ZLINK'd.
+ * Returns FALSE otherwise.
+ * In either case, also "returns" (via <res>) the rtn_tabent
+ * 	corresponding to the first routine name greater than or equal to
+ * 	<name>.
+ */
+
+boolean_t find_rtn_tabent(rtn_tabent **res, mstr *name)
+{
 	rtn_tabent	*bot, *top, *mid;
 	int4		comp;
 	mident		rtn_name;
 	mident_fixed	rtn_name_buff;
 
-	assert (name->len <= MAX_MIDENT_LEN);
+	assert(name->len <= MAX_MIDENT_LEN);
 	rtn_name.len = name->len;
 #ifdef VMS
 	rtn_name.addr = &rtn_name_buff.c[0];
@@ -37,25 +61,32 @@ rhdtyp	*find_rtn_hdr(mstr *name)
 	bot = rtn_names;
 	top = rtn_names_end;
 	for (;;)
-	{
-		if (top < bot)
-			return 0;
-		else if ((top - bot) < S_CUTOFF)
+	{	/* See if routine exists in list via a binary search which reverts to serial
+		   search when # of items drops below the threshold S_CUTOFF.
+		*/
+		if (S_CUTOFF > (top - bot))
 		{
 			comp = -1;
 			for (mid = bot; comp < 0 && mid <= top; mid++)
 			{
 				MIDENT_CMP(&mid->rt_name, &rtn_name, comp);
 				if (0 == comp)
-					return mid->rt_adr;
+				{
+					*res = mid;
+					return TRUE;
+				} else if (0 < comp)
+					break;
 			}
-			return 0;
+			break;
 		} else
 		{
 			mid = bot + (top - bot) / 2;
 			MIDENT_CMP(&mid->rt_name, &rtn_name, comp);
 			if (0 == comp)
-				return mid->rt_adr;
+			{
+				*res = mid;
+				return TRUE;
+			}
 			else if (comp < 0)
 			{
 				bot = mid + 1;
@@ -67,4 +98,6 @@ rhdtyp	*find_rtn_hdr(mstr *name)
 			}
 		}
 	}
+	*res = mid;
+	return FALSE;
 }
diff --git a/sr_port/fntext_ch.c b/sr_port/fntext_ch.c
index 5919db9..37ce64c 100644
--- a/sr_port/fntext_ch.c
+++ b/sr_port/fntext_ch.c
@@ -25,7 +25,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(fntext_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	GTMTRIG_ONLY(TREF(in_op_fntext) = FALSE);
 	if (!DUMPABLE && (SIGNAL != ERR_TPRETRY))
 	{
diff --git a/sr_port/format_targ_key.c b/sr_port/format_targ_key.c
index 24fa371..5dbf51f 100644
--- a/sr_port/format_targ_key.c
+++ b/sr_port/format_targ_key.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -23,7 +23,7 @@
 /* return a pointer that points after the last char added */
 unsigned char *format_targ_key(unsigned char *out_char_ptr, int4 max_size, gv_key *key, boolean_t dollarc)
 {
-	unsigned char			*gvkey_char_ptr, *out_top, *work_char_ptr, work_buff[MAX_ZWR_KEY_SZ], *work_top;
+	unsigned char			ch, *gvkey_char_ptr, *out_top, *work_char_ptr, work_buff[MAX_ZWR_KEY_SZ], *work_top;
 	boolean_t			is_string;
 	DEBUG_ONLY(unsigned char	*gvkey_top_ptr;)
 
@@ -63,17 +63,44 @@ unsigned char *format_targ_key(unsigned char *out_char_ptr, int4 max_size, gv_ke
 				*out_char_ptr++ = '"';
 			}
 			work_top = gvsub2str(gvkey_char_ptr, work_buff, dollarc);
-			for (work_char_ptr = work_buff;  work_char_ptr < work_top;)
+			if (!is_string)
 			{
+				for (work_char_ptr = work_buff;  work_char_ptr < work_top;)
+				{
+					if (out_char_ptr >= out_top)
+					{
+						assert(FALSE);
+						return (NULL);
+					}
+					*out_char_ptr++ = *work_char_ptr++;
+				}
+			} else
+			{	/* replace double-quote with TWO double-quotes since this subs is already double-quote-enclosed */
+				for (work_char_ptr = work_buff;  work_char_ptr < work_top;)
+				{
+					if (out_char_ptr >= out_top)
+					{
+						assert(FALSE);
+						return (NULL);
+					}
+					*out_char_ptr++ = (ch = *work_char_ptr++);
+					if ('"' == ch)
+					{
+						if (out_char_ptr >= out_top)
+						{
+							assert(FALSE);
+							return (NULL);
+						}
+						*out_char_ptr++ = ch;
+					}
+				}
 				if (out_char_ptr >= out_top)
 				{
 					assert(FALSE);
 					return (NULL);
 				}
-				*out_char_ptr++ = *work_char_ptr++;
-			}
-			if (is_string)
 				*out_char_ptr++ = '"';
+			}
 		}
 		if (out_char_ptr >= out_top)
 		{
diff --git a/sr_port/gbldef.mpt b/sr_port/gbldef.mpt
index 5bde6a9..7fbbef0 100644
--- a/sr_port/gbldef.mpt
+++ b/sr_port/gbldef.mpt
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -13,44 +13,67 @@
 kill(gname)
 	n $et
 	s $et="g error"
+	i $tl zm 150383202	; TPNOSUPPORT error
 	i '$$edit(.gname) q 0
-	i "BGMM"'[$v("GVACCESS_METHOD",$v("REGION",gname)) zm 150376418:$v("REGION",gname); DBREMOTE
-	i $d(@gname) zm 150373626	;Error if there is data in the global
-	s @gname="" k @gname		;make sure that the global is defined
-	s gname=$e(gname,2,32)		;remove circumflex, take at most 31 chars
-	v "YDIRTVAL":$e($v("YDIRTREE",gname),1,4),"YDIRTREE":gname
+	i $zfind($view("REGION",gname),",") zm 150383194:gname	; ISSPANGBL
+	i "BGMM"'[$view("GVACCESS_METHOD",$view("REGION",gname)) zm 150376418:$view("REGION",gname) ; DBREMOTE
+	i $d(@gname) zm 150373626	; Error if there is data in the global
+	s @gname="" k @gname		; make sure that the global is defined
+	s gname=$zextract(gname,2,32)		; remove circumflex, take at most 31 chars
+	v "YDIRTVAL":$zextract($view("YDIRTREE",gname),1,4),"YDIRTREE":gname
 	q 1
 	;
 set(gname,nct,act)
 	n ver,$et
 	s $et="g error"
+	i $tl zm 150383202	; TPNOSUPPORT error
 	i '$$edit(.gname) q 0
-	i "BGMM"'[$v("GVACCESS_METHOD",$v("REGION",gname)) zm 150376418:$v("REGION",gname); DBREMOTE
-	i $d(@gname) zm 150373626 		;Error if there is data in the global
+	i $zfind($view("REGION",gname),",") zm 150383194:gname	; ISSPANGBL
+	i "BGMM"'[$view("GVACCESS_METHOD",$view("REGION",gname)) zm 150376418:$view("REGION",gname) ; DBREMOTE
+	i $d(@gname) zm 150373626 		; Error if there is data in the global
 	s act=+$g(act),nct=+$g(nct) s:nct nct=1
 	i (act>255)!(act<0) zm 150374290:act	; collation type specified is illegal
-	i act s ver=$V("YCOLLATE",act)
-	e  s ver=0
+	s ver=$view("YCOLLATE",act)
 	i ver<0 zm 150376282:act		; doesn't find coll type, or can't get version
-	s @gname="" k @gname			;make sure that the global is defined
-	s gname=$e(gname,2,32)			;remove circumflex, take at most 31 chars
-	v "YDIRTVAL":$e($v("YDIRTREE",gname),1,4)_$c(1,nct,act,ver),"YDIRTREE":gname
+	s @gname="" k @gname			; make sure that the global is defined
+	s gname=$zextract(gname,2,32)			; remove circumflex, take at most 31 chars
+	v "YDIRTVAL":$zextract($view("YDIRTREE",gname),1,4)_$zchar(1,nct,act,ver),"YDIRTREE":gname
 	q 1
 	;
-get(gname)
-	n t,tl,$et
+get(gname,reg)
+	n t,tl,$et,nct,act,ver,ret,dir,error
 	s $et="g error"
 	i '$$edit(.gname) q 0
-	i "BGMM"'[$v("GVACCESS_METHOD",$v("REGION",gname)) zm 150376418:$v("REGION",gname); DBREMOTE
-	s t=$e($v("YDIRTREE",$e(gname,2,32)),5,999),tl=$l(t)	;remove circumflex, take at most 31 chars
+	s gname=$zextract(gname,2,32)
+	i '$d(reg) s reg=$piece($view("REGION","^"_gname),",",1)
+	i "BGMM"'[$view("GVACCESS_METHOD",reg) zm 150376418:reg ; DBREMOTE
+	; -----------------------------------
+	; first check in directory tree
+	s dir=$view("YDIRTREE",gname,reg)
+	s t=$zextract(dir,5,999),tl=$zl(t)	; remove circumflex, take at most 31 chars
 	i tl,tl>4!($a(t,1)'=1) zm 150374058
-	q $s(tl:$a(t,2)_","_$a(t,3)_","_$a(t,4),1:0)
+	i tl s nct=$a(t,2),act=$a(t,3),ver=$a(t,4) q nct_","_act_","_ver
+	; -----------------------------------
+	; db directory tree has no collation information. next check for gld.
+	s t=$view("YGLDCOLL","^"_gname)
+	i t'="0" s nct=$piece(t,",",1),act=$piece(t,",",2),ver=$piece(t,",",3)  q nct_","_act_","_ver
+	; -----------------------------------
+	; no collation information was found in gld. check for coll info from db file hdr
+	s nct=0 d  q:(act=0) 0
+	. d getzpeek("FHREG:"_reg,64,4,"U",.act)
+	. d getzpeek("FHREG:"_reg,68,4,"U",.ver)
+	q nct_","_act_","_ver
 	;
+getzpeek(mnemonic,offset,length,format,result)
+	n xstr
+	i $zver'["VMS" s xstr="s result=$zpeek(mnemonic,offset,length,format)" x xstr  q
+	s result=0
+	q
 edit(gname)
-	i $e(gname)'="^" s gname="^"_gname
-	i $e(gname,2)'="%",$e(gname,2)'?1A zm 150373218		; LKNAMEXPECTED
+	i $zextract(gname)'="^" s gname="^"_gname
+	i $zextract(gname,2)'="%",$zextract(gname,2)'?1A zm 150373218		; LKNAMEXPECTED
 	i gname'?1"^"1E.AN zm 150373218
 	q 1
 	;
-error	s $ec=""
+error	s $ec="",error=1
 	q 0
diff --git a/sr_port/gbldefs.c b/sr_port/gbldefs.c
index 4b01be1..6396654 100644
--- a/sr_port/gbldefs.c
+++ b/sr_port/gbldefs.c
@@ -26,12 +26,10 @@
 #include "gtm_socket.h"
 #include "gtm_unistd.h"
 #include "gtm_limits.h"
+#include "gtm_un.h"
 
 #include <signal.h>
 #include <sys/time.h>
-#ifdef UNIX
-# include <sys/un.h>
-#endif
 #ifdef VMS
 # include <descrip.h>		/* Required for gtmsource.h */
 # include <ssdef.h>
@@ -86,7 +84,6 @@
 # include "gtmsiginfo.h"
 #endif
 #include "gtmimagename.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"	/* needed for socket_pool and MAX_N_SOCKETS */
 #include "ctrlc_handler_dummy.h"
@@ -116,6 +113,7 @@
 #include "repl_sem.h"
 #include "gtm_zlib.h"
 #include "anticipatory_freeze.h"
+#include "mu_rndwn_all.h"
 #endif
 #include "jnl_typedef.h"
 #include "repl_ctl.h"
@@ -134,6 +132,9 @@
 # include "gdsblk.h"
 # include "muextr.h"
 # endif
+#ifdef GTM_TLS
+#include "gtm_tls_interface.h"
+#endif
 #ifdef GTM_TRIGGER
 #include "gv_trigger.h"
 #include "gtm_trigger.h"
@@ -257,6 +258,7 @@ GBLDEF	gv_namehead	*gv_target_list;	/* List of ALL gvts that were allocated (in
 GBLDEF	gv_namehead	*gvt_tp_list;		/* List of gvts that were referenced in the current TP transaction */
 GBLDEF	gvt_container	*gvt_pending_list;	/* list of gvts that need to be re-examined/re-allocated when region is opened */
 GBLDEF	buddy_list	*gvt_pending_buddy_list;/* buddy_list for maintaining memory for gv_targets to be re-examined/allocated */
+GBLDEF	buddy_list	*noisolation_buddy_list;	/* a buddy_list for maintaining the globals that are noisolated */
 GBLDEF	int4		exi_condition;
 GBLDEF	uint4		gtmDebugLevel;
 GBLDEF	caddr_t		smCallerId;			/* Caller of top level malloc/free */
@@ -270,7 +272,6 @@ GBLDEF	boolean_t	certify_all_blocks;		/* If flag is set all blocks are checked a
 							 * written to the database.  Upon error we stay critical
 							 * and report.  This flag can be set via the MUMPS command
 							 * VIEW "GDSCERT":1. */
-GBLDEF	mval		curr_gbl_root;
 GBLDEF	gd_addr		*original_header;
 GBLDEF	hash_table_str	*complits_hashtab;
 GBLDEF	hash_table_str	*compsyms_hashtab;
@@ -480,7 +481,9 @@ GBLDEF	gd_region	*ftok_sem_reg;		/* Last region for which ftok semaphore is grab
 GBLDEF	int		gtm_non_blocked_write_retries; /* number of retries for non-blocked write to pipe */
 #endif
 #ifdef VMS
-/* Following global variables store the state of an erroring sys$qio just before a GTMASSERT in the CHECK_CHANNEL_STATUS macro */
+/* Following global variables store the state of an erroring sys$qio just before a GTMASSERT			BYPASSOK(GTMASSERT)
+ * in the CHECK_CHANNEL_STATUS macro.
+ */
 GBLDEF	uint4	check_channel_status;		/* stores the qio return status */
 GBLDEF	uint4	check_channel_id;		/* stores the qio channel id */
 #endif
@@ -926,14 +929,7 @@ GBLDEF	boolean_t	gtm_tag_utf8_as_ascii = TRUE;
 LITDEF	char			gtmcrypt_repeat_msg[] = "Please look at prior messages related to encryption for more details";
 GBLDEF	boolean_t		gtmcrypt_initialized;	/* Set to TRUE if gtmcrypt_init() completes successfully */
 GBLDEF	char			dl_err[MAX_ERRSTR_LEN];
-GBLDEF	gtmcrypt_init_t			gtmcrypt_init_fnptr;
-GBLDEF  gtmcrypt_close_t        	gtmcrypt_close_fnptr;
-GBLDEF  gtmcrypt_hash_gen_t		gtmcrypt_hash_gen_fnptr;
-GBLDEF  gtmcrypt_encrypt_t		gtmcrypt_encrypt_fnptr;
-GBLDEF  gtmcrypt_decrypt_t		gtmcrypt_decrypt_fnptr;
-GBLDEF	gtmcrypt_getkey_by_hash_t	gtmcrypt_getkey_by_hash_fnptr;
-GBLDEF	gtmcrypt_getkey_by_name_t	gtmcrypt_getkey_by_name_fnptr;
-GBLDEF	gtmcrypt_strerror_t		gtmcrypt_strerror_fnptr;
+GBLDEF	mstr			pvt_crypt_buf;	/* Temporary buffer needed where in-place encryption/decryption is not an option */
 #endif /* GTM_CRYPT */
 #ifdef DEBUG
 /* Following definitions are related to white_box testing */
@@ -961,8 +957,6 @@ GBLDEF	boolean_t	block_is_free;			/* Set to TRUE if the caller wants to let t_qr
 							 */
 GBLDEF	int4		gv_keysize;
 GBLDEF	gd_addr		*gd_header;
-GBLDEF	gd_binding	*gd_map;
-GBLDEF	gd_binding	*gd_map_top;
 #ifdef GTM_TRIGGER
 GBLDEF	int4		gtm_trigger_depth;		/* 0 if no trigger, 1 if inside trigger; 2 if inside nested trigger etc. */
 GBLDEF	int4		tstart_trigger_depth;		/* gtm_trigger_depth at the time of the outermost "op_tstart"
@@ -1078,23 +1072,38 @@ GBLDEF	boolean_t	span_nodes_disallowed; 		/* Indicates whether spanning nodes ar
 GBLDEF	boolean_t	argumentless_rundown;
 GBLDEF	is_anticipatory_freeze_needed_t		is_anticipatory_freeze_needed_fnptr;
 GBLDEF	set_anticipatory_freeze_t		set_anticipatory_freeze_fnptr;
-GBLDEF	boolean_t				is_jnlpool_creator;
+GBLDEF	boolean_t	is_jnlpool_creator;
 GBLDEF	char		gtm_dist[GTM_PATH_MAX];		/* Value of $gtm_dist env variable */
+GBLDEF	semid_queue_elem	*keep_semids;		/* Access semaphores that should be kept because shared memory is up */
 #endif
-GBLDEF	boolean_t	in_jnl_file_autoswitch;	/* Set to TRUE for a short window inside jnl_file_extend when we are about to
-						 * autoswitch; used by jnl_write. */
+GBLDEF	boolean_t	in_jnl_file_autoswitch;		/* Set to TRUE for a short window inside jnl_file_extend when we are about
+							 * to autoswitch; used by jnl_write. */
 #ifdef GTM_PTHREAD
 GBLDEF	pthread_t	gtm_main_thread_id;		/* ID of the main GT.M thread. */
 GBLDEF	boolean_t	gtm_main_thread_id_set;		/* Indicates whether the thread ID is set. */
 GBLDEF	boolean_t	gtm_jvm_process;		/* Indicates whether we are running with JVM or stand-alone. */
 #endif
-GBLDEF	size_t		gtm_max_storalloc;	/* Maximum that GTM allows to be allocated - used for testing */
+GBLDEF	size_t		gtm_max_storalloc;		/* Maximum that GTM allows to be allocated - used for testing */
 #ifdef VMS
-GBLDEF		sgmnt_addrs	*vms_mutex_check_csa;	/* On VMS, mutex_deadlock_check() is directly called from mutex.mar. In
+GBLDEF	sgmnt_addrs	*vms_mutex_check_csa;		/* On VMS, mutex_deadlock_check() is directly called from mutex.mar. In
 							 * order to avoid passing csa parameter from the VMS assembly, we set this
 							 * global from mutex_lock* callers.
 							 */
 #endif
-GBLDEF	boolean_t	ipv4_only;		/* If TRUE, only use AF_INET.
-						 * Reflects the value of the gtm_ipv4_only environment variable, so is process wide.
-						 */
+GBLDEF	boolean_t	ipv4_only;			/* If TRUE, only use AF_INET. Reflects the value of the gtm_ipv4_only
+							 * environment variable, so is process wide.
+							 */
+#ifdef UNIX
+GBLDEF void (*stx_error_fptr)(int in_error, ...);	/* Function pointer for stx_error() so gtm_utf8.c can avoid pulling
+							 * stx_error() into gtmsecshr, and thus just about everything else as well.
+							 */
+GBLDEF void (*show_source_line_fptr)(boolean_t warn);	/* Func pointer for show_source_line() - same purpose as stx_error_fptr */
+#endif
+#ifdef GTM_TLS
+GBLDEF	gtm_tls_ctx_t	*tls_ctx;			/* Process private pointer to SSL/TLS context. Any SSL/TLS connections that
+							 * the process needs to create will be created from this context.
+							 * Currently, SSL/TLS is implemented only for replication, but keep it here
+							 * so that it can be used when SSL/TLS support is implemented for GT.M
+							 * Socket devices.
+							 */
+#endif
diff --git a/sr_port/gde.hlp b/sr_port/gde.hlp
index 150c735..0ba49e9 100644
--- a/sr_port/gde.hlp
+++ b/sr_port/gde.hlp
@@ -1,11 +1,10 @@
 1 Overview
    Overview
 
-   The GT.M Global Directory Editor (GDE) is a utility that enables you to
-   create, examine, and modify a global directory. GDE is a program written
-   in M and you can invoke it from the shell with $gtm_dist/mumps -run ^GDE,
-   with the gtm alias gtm -run GDE, or from inside the direct mode with Do
-   ^GDE.
+   The GT.M Global Directory Editor (GDE) is a utility for creating,
+   examining, and modifying a global directory. GDE is a program written in M
+   and you can invoke it from the shell with $gtm_dist/mumps -run ^GDE, with
+   the gtm alias gtm -run GDE, or from inside the direct mode with Do ^GDE.
 
    **Note**
 
@@ -455,7 +454,7 @@
 
    Command Syntax:
 
-   The general format for GDE commands is:
+   The general format of GDE commands is:
 
    command [-object-type] [object-name] [-qualifier]
 
@@ -521,7 +520,7 @@
    The ADD command inserts a new name, region, or segment into the Global
    Directory.
 
-   The format of the ADD command is one of the f ollowing:
+   The format of the ADD command is one of the following:
 
    A[DD]-N[AME] name-space -R[EGION]=region-name
    A[DD]-R[EGION] region-name -D[YNAMIC]=segment-name [-REGION-qualifier...]
@@ -1007,7 +1006,7 @@
    The following -REGION qualifiers can be used with the ADD, CHANGE, or
    TEMPLATE commands.
 
-   -C[OLLATION_SEQUENCE]=id number
+   -C[OLLATION_DEFAULT]=number
 
    Specifies the number of the collation sequence definition to be used as
    the default for this database file. The number can be any integer from 0
@@ -1018,12 +1017,12 @@
    refer to the "Internationalization" chapter in the GT.M Programmer's
    Guide.
 
-   The minimum COLLATION_SEQUENCE ID number is zero, which is the standard M
+   The minimum COLLATION_DEFAULT number is zero, which is the standard M
    collation sequence.
 
-   The maximum COLLATION_SEQUENCE ID number is 255.
+   The maximum COLLATION_DEFAULT number is 255.
 
-   By default, GDE uses zero (0) as the COLLATION_SEQUENCE ID.
+   By default, GDE uses zero (0) as the COLLATION_DEFAULT.
 
    -D[YNAMIC_SEGMENT]=segment-name
 
@@ -1048,16 +1047,16 @@
    When determining the maximum key size, applications should consider the
    following:
 
-     o A key must fit within one database block and the maximum KEY_SIZE is
+     * A key must fit within one database block and the maximum KEY_SIZE is
        limited to 40 bytes less than the block size. For example, a 1024 byte
        block can support a maximum KEY_SIZE of 984 bytes and a 1536 byte
        block size is the smallest that supports a maximum KEY_SIZE of 1019
        bytes.
-     o GT.M uses packed decimal representation for numeric subscripts which
+     * GT.M uses packed decimal representation for numeric subscripts which
        may be larger or smaller than the original representation.
-     o GT.M substitutes an element terminator for the caret (^), any comma
+     * GT.M substitutes an element terminator for the caret (^), any comma
        (,), and any right parenthesis ()).
-     o GT.M adds an extra byte for every string element, including the global
+     * GT.M adds an extra byte for every string element, including the global
        name.
 
    For example, the key ^ACN ("Name", "Type") internally occupies 17 bytes.
@@ -1067,9 +1066,7 @@
    -R[ECORD_SIZE]=size in bytes
 
    Specifies the maximum size (in bytes) of a global variable node's value
-   that can be stored in a region. The KEY_SIZE must be less than the
-   RECORD_SIZE. GDE rejects the command if the KEY_SIZE is inappropriate for
-   the RECORD_SIZE.
+   that can be stored in a region.
 
    If the size of a global exceeds one database block, GT.M implicitly spans
    that global across multiple database blocks. In the event a global
@@ -1078,7 +1075,10 @@
    performs the entire operation within an implicit TP transaction (just as
    is the case with triggers).
 
-   The minimum RECORD_SIZE is seven or eight, depending on your platform.
+   The minimum RECORD_SIZE is zero. A RECORD_SIZE of zero only allows a
+   global variable node that does not have a value. A typical use of a global
+   variable node with RECORD_SIZE of zero is for creating indices (where the
+   presence of a node is all that is required).
 
    The maximum RECORD_SIZE is 1,048,576 bytes (1MiB).
 
@@ -1100,17 +1100,17 @@
 
    By default, regions have -NULL_SUBSCRIPTS=NEVER.
 
-   -[NO]STDNULLCOLL[=TRUE|FALSE]
+   -[NO]STDNULLCOLL
 
    Determines whether GT.M null subscripts collate in conformance to the M
    standard.
 
-   If -STDNULLCOLL is set to TRUE or -STDNULLCOLL is specified, subscripts of
-   globals in the database follow the M standard where the null subscript
-   collates before all other subscripts.
+   If STDNULLCOLL is specified, subscripts of globals in the database follow
+   the M standard where the null subscript collates before all other
+   subscripts.
 
-   If -STDNULLCOLL is set to FALSE or -NOSTDNULLCOLL is specified, null
-   subscripts collate between numeric and string subscripts.
+   If NOSTDNULLCOLL is specified, null subscripts collate between numeric and
+   string subscripts.
 
    -[NO]INST[_FREEZE_ON_ERROR]
 
@@ -1159,15 +1159,15 @@
 
    The journal-option-list includes:
 
-     o [NO]BE[FORE_IMAGE]
-     o F[ILE_NAME]=file-specification-name
+     * [NO]BE[FORE_IMAGE]
+     * F[ILE_NAME]=file-specification-name
 
-     o AUTOSWITCHLIMIT=blocks
+     * AUTOSWITCHLIMIT=blocks
 
-     o A[LLOCATION]=blocks
+     * A[LLOCATION]=blocks
 
-     o E[XTENSION]=blocks
-     o BU[FFER_SIZE]=pages
+     * E[XTENSION]=blocks
+     * BU[FFER_SIZE]=pages
 
    The following section describes some -JOURNAL options.
 
@@ -1213,7 +1213,7 @@
  |-----------------------------------------------------------------------------|
  |                 QUALIFIER                  | DEFAULT  | MINIMUM |  MAXIMUM  |
  |--------------------------------------------+----------+---------+-----------|
- |-C[OLLATION_SEQUENCE]=id-number (integer)   |0         |0        |255        |
+ |-C[OLLATION_DEFAULT]=number (integer)       |0         |0        |255        |
  |--------------------------------------------+----------+---------+-----------|
  |-D[YNAMIC_SEGMENT] =segment-name (char)     |-         |1        |16         |
  |--------------------------------------------+----------+---------+-----------|
@@ -1250,9 +1250,9 @@
        system may also provide additional buffering). You get the choice of
        using BEFORE_IMAGE or NOBEFORE_IMAGE journaling for your database.
 
-          o BG supports both forward and backward recovery and rollback to
+          * BG supports both forward and backward recovery and rollback to
             recover a database without a restore.
-          o BG is a likely choice when you need faster recovery times from
+          * BG is a likely choice when you need faster recovery times from
             system failures.
 
      o With MM, GT.M bypasses the global buffer pool and relies entirely on
@@ -1260,14 +1260,14 @@
        GT.M has no control over the timing of disk updates, therefore there
        is a greater reliance on the OS/file system for database performance.
 
-          o MM supports NOBEFORE_IMAGE journaling only. GT.M triggers an
+          * MM supports NOBEFORE_IMAGE journaling only. GT.M triggers an
             error if you use MM with BEFORE_IMAGE Journaling. MM also
             supports MUPIP FORWARD -RECOVER and MUPIP JOURNAL -ROLLBACK with
             the -RESYNC or -FETCHRESYNC qualifiers to generate lost and
             broken transaction files. For more information, see the
             Journaling chapter.
-          o MM does not support backward recovery/rollback.
-          o MM is a possible choice when you need performance advantage in
+          * MM does not support backward recovery/rollback.
+          * MM is a possible choice when you need performance advantage in
             situations where the above restrictions are acceptable.
 
      o GDE maintains a separate set of segment qualifier values for each
@@ -1289,14 +1289,14 @@
    creates the file. For GDS files, the number of bytes allocated is the size
    of the database file header plus the ALLOCATION size times the BLOCK_SIZE.
 
-     o The minimum ALLOCATION is 10 blocks.
-     o The maximum ALLOCATION is 1,040,187,392 blocks.
-     o By default, GDE uses an ALLOCATION of 100 blocks.
-     o The maximum size of a database file is 1,040,187,392(992Mi) blocks.
-     o Out of the requested allocation, GT.M always reserves 32 global
+     * The minimum ALLOCATION is 10 blocks.
+     * The maximum ALLOCATION is 1,040,187,392 blocks.
+     * By default, GDE uses an ALLOCATION of 100 blocks.
+     * The maximum size of a database file is 1,040,187,392(992Mi) blocks.
+     * Out of the requested allocation, GT.M always reserves 32 global
        buffers for BG access method for read-only use to ensure that
        non-dirty global buffers are always available.
-     o The default ALLOCATION was chosen for initial development and
+     * The default ALLOCATION was chosen for initial development and
        experimentation with GT.M. Because file fragmentation impairs
        performance, make the initial allocation for production files and
        large projects large enough to hold the anticipated contents of the
@@ -1645,7 +1645,7 @@
    |--------------------------------------------+-------+-----+-------------------+-----+-----+-----|
    |-BL[OCK_SIZE]=size(bytes)                   |1024   |512  |65024              |-    |-    |X    |
    |--------------------------------------------+-------+-----+-------------------+-----+-----+-----|
-   |-C[OLLATION_SEQUENCE]=id-number (integer)   |0      |0    |255                |-    |X    |-    |
+   |-C[OLLATION_DEFAULT]=id-number (integer)    |0      |0    |255                |-    |X    |-    |
    |--------------------------------------------+-------+-----+-------------------+-----+-----+-----|
    |-D[YNAMIC_SEGMENT]=segment-name (chars)     |*      |1A   |16A/N              |-    |X    |-    |
    |--------------------------------------------+-------+-----+-------------------+-----+-----+-----|
@@ -1678,3 +1678,32 @@
    |-R[ESERVED_BYTES]=size (bytes)              |0      |0    |blocksize          |-    |-    |X    |
    +------------------------------------------------------------------------------------------------+
 
+1 Copyright
+   Copyright
+
+   Copyright 2013
+
+   Fidelity Information Services, Inc. All rights reserved.
+
+   Permission is granted to copy, distribute and/or modify this document
+   under the terms of the GNU Free Documentation License, Version 1.3 or any
+   later version published by the Free Software Foundation; with no Invariant
+   Sections, no Front-Cover Texts and no Back-Cover Texts.
+
+   GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
+   trademarks are the property of their respective owners.
+
+   This document contains a description of GT.M and the operating
+   instructions pertaining to the various functions that comprise the system.
+   This document does not contain any commitment of FIS. FIS believes the
+   information in this publication is accurate as of its publication date;
+   such information is subject to change without notice. FIS is not
+   responsible for any errors or defects.
+
+   **Note**
+
+   This help file is a concise representation of revision V6.1-000 of the
+   UNIX Administration and Operations Guide. To obtain a copy of the current
+   revision, go to www.fis-gtm.com and then click on the User Documentation
+   tab.
+
diff --git a/sr_port/gde.m b/sr_port/gde.m
index 0f9605e..56071a0 100644
--- a/sr_port/gde.m
+++ b/sr_port/gde.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2011 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -9,9 +9,29 @@
 ;								;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gde:	;base module - d DEBUG^GDE to debug
-	i $$set^%LCLCOL(0)
+	n  ; clear calling process M variable state (if any) so it does not interfere with GDE variable names
 	s (debug,runtime)=0
 DBG:	;transfer point for DEBUG and "runtime" %gde
+	; Save parent process context before GDE tampers with it for its own necessities.
+	; Most of it is stored in the "gdeEntryState" local variable in subscripted nodes.
+	; Exceptions are local collation related act,ncol,nct values which have to be stored in in unsubscripted variables
+	;	to prevent COLLDATAEXISTS error as part of the $$set^%LCLCOL below.
+	n gdeEntryState,gdeEntryStateAct,gdeEntryStateNcol,gdeEntryStateNct
+	s gdeEntryStateAct=$$get^%LCLCOL
+	s gdeEntryStateNcol=$$getncol^%LCLCOL
+	s gdeEntryStateNct=$$getnct^%LCLCOL
+	; Set local collation to what GDE wants to operate. Errors while doing so will have to exit GDE right away.
+	; Prepare special $etrap to issue error in case VIEW "YLCT" call to set local collation fails below
+	; Need to use this instead of the gde $etrap (set a few lines later below) as that expects some initialization
+	; to have happened whereas we are not yet there since setting local collation is a prerequisite for that init.
+	i $zver'["VMS" s $et="w !,$p($zs,"","",3,999) s $ecode="""" zm 150503603:$zparse(""$gtmgbldir"","""",""*.gld"") quit"
+	else           s $et="w !,$p($zs,"","",3,999) s $ecode="""" zm 150503603:$zparse(""GTM$GBLDIR"","""",""*.GLD"") quit"
+	v "YLCT":0:1:0		; sets local variable alternate collation = 0, null collation = 1, numeric collation = 0
+	; since GDE creates null subscripts, we dont want user level setting of gtm_lvnullsubs to affect us in any way
+	s gdeEntryState("nullsubs")=$v("LVNULLSUBS")
+	v "LVNULLSUBS"
+	s gdeEntryState("zlevel")=$zlevel-1
+	s gdeEntryState("io")=$io
 	s $et=$s(debug:"b:$zs'[""%GDE""!allerrs  ",1:"")_"g:(""%GDE%NONAME""[$p($p($zs,"","",3),""-"")) SHOERR^GDE d ABORT^GDE"
 	s io=$io,useio="io",comlevel=0,combase=$zl,resume(0)=$zl_":INTERACT"
 	i $$set^%PATCODE("M")
@@ -25,27 +45,41 @@ DBG:	;transfer point for DEBUG and "runtime" %gde
 INTERACT
 	f  u io:ctrap=$c(25,26) w !,prompt," " r comline u @useio d comline:$l(comline)
 	q
-comline: s cp=1,ntoken="",ntoktype="TKEOL" s:runtime comline="/"_comline d GETTOK^GDESCAN
+comline:
+	f cp=1:1 s c=$e(comline,cp) q:(c'=" ")&(c'=TAB)	 ; remove extraneous whitespace at beginning of line
+	s ntoken="",ntoktype="TKEOL" s:runtime comline="/"_comline
+	d GETTOK^GDESCAN
+	i ntoktype="TKEOL" q	 ; if comline begins with a ! dont even bother parsing this line anymore
 	i log u @uself w comline,! u @useio
 	i runtime n NAME,REGION,SEGMENT,gqual,lquals zg:"/QUIT"[$tr(comline,lower,upper) combase-1 d SHOW^GDEPARSE q
-	i ntoktype="TKAMPER" s resume(comlevel+1)=$zl d comfile q
+	i ntoktype="TKAT" s resume(comlevel+1)=$zl d comfile q
 	d GDEPARSE^GDEPARSE
 	q
 CTRL
 	i $p($zs,",",3,999)["%GTM-E-CTRAP, Character trap $C(3) encountered" do  zg @resume(comlevel)
-	. i comlevel>0 d comeof; if we take a ctrl-c in a command file then get out of that command file
-	i $p($zs,",",3,999)["%GTM-E-CTRAP, Character trap $C(25) encountered" h
+	. i comlevel>0 d comeof ; if we take a ctrl-c in a command file then get out of that command file
+	i $p($zs,",",3,999)["%GTM-E-CTRAP, Character trap $C(25) encountered" d GETOUT^GDEEXIT h
 	i $p($zs,",",3,999)["%GTM-E-CTRAP, Character trap $C(26) encountered" d EXIT^GDEEXIT
 	i $p($zs,",",3,999)="%GTM-E-IOEOF, Attempt to read past an end-of-file" d comexit
 	i $zeof d EXIT^GDEEXIT
 	d ABORT
 	;
 comexit: i 'update d QUIT^GDEQUIT
-	i $$ALL^GDEVERIF,$$GDEPUT^GDEPUT  h
-DBGCOMX u $i:exception="" s $et="" zm (gdeerr("VERIFY")\2*2):"FAILED"
+	i $$ALL^GDEVERIF,$$GDEPUT^GDEPUT
+	e  w $p($zm(gdeerr("VERIFY")\2*2),"!AD")_"FAILED" w !
+	d GETOUT^GDEEXIT
+	h
+DBGCOMX u $i:exception="" s $et="" zm gdeerr("VERIFY"):"FAILED" w !
+	d GETOUT^GDEEXIT
 	h
 comfile:
-	d GETTOK^GDESCAN,TFSPEC^GDEPARSE
+	d GETTOK^GDESCAN
+	i ntoktype="TKEOL" zm gdeerr("QUALREQD"):"file specification"
+	d TFSPEC^GDEPARSE
+	; remove trailing whitespaces in filename
+	n i
+	f i=$zl(value):-1  s c=$ze(value,i)  q:(c'=" ")&(c'=TAB)  ; remove trailing 0s
+	s value=$ze(value,1,i)
 	s (comfile,comfile(comlevel+1))=$zparse(value,"","",".COM")
 	i '$l($zsearch(comfile)),'$l($zsearch(comfile)) zm gdeerr("FILENOTFND"):comfile
 	e  o comfile:(read:exc="zg "_$zl_":comeof") zm gdeerr("EXECOM"):comfile d SCRIPT
@@ -56,7 +90,7 @@ comeof	c comfile s comlevel=$select(comlevel>1:comlevel-1,1:0)
 	q
 SCRIPT:
 	s comlevel=comlevel+1
-	f  u comfile r comline i $e(comline,1)'="!" u @useio d comline:$l(comline)
+	f  u comfile r comline u @useio d comline:$l(comline)
 	;this loop is terminated by the comfile exception at eof
 SHOERR
 	w !,$p($zs,",",3,999),!
@@ -71,8 +105,9 @@ ABORT
 	; make GDECHECK error fatal except native UNIX
         i $d(gdeerr) zm gdeerr("GDECHECK") Write $ZMessage($Select($ZVersion'["VMS"&(256>abortzs):+abortzs,1:+abortzs\8*8+4)),!
         e  w $zs
-        h
+        d GETOUT^GDEEXIT
+	h
 DEBUG	;entry point to debug gde
-	i $$set^%LCLCOL(0)
+	n  ; clear calling process M variable state (if any) so it does not interfere with GDE variable names
 	s allerrs=0,debug=1,runtime=0 u 0:(ctrap="":exception="") zb DBGCOMX,ABORT
 	g DBG
diff --git a/sr_port/gdeadd.m b/sr_port/gdeadd.m
index af7fc2a..8ce37fb 100644
--- a/sr_port/gdeadd.m
+++ b/sr_port/gdeadd.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,22 +10,25 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 add:	;implement the verb: ADD
 NAME
-	i $d(nams(NAME)) zm gdeerr("OBJDUP"):"Name":NAME
+	i $d(nams(NAME)) zm gdeerr("OBJDUP"):"Name":$$namedisp^GDESHOW(NAME,0)
 	i '$d(lquals("REGION")) zm gdeerr("QUALREQD"):"Region"
+	; check if changing (i.e. adding) a name (with ranges) poses issues with overlap amongst other existing name ranges
+	d namerangeoverlapcheck^GDEPARSE(.NAME,lquals("REGION"))
 	s update=1,nams=nams+1
+	m nams(NAME)=NAME
 	s nams(NAME)=lquals("REGION")
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
 	q
 REGION
 	i $d(regs(REGION)) zm gdeerr("OBJDUP"):"Region":REGION
 	i '$d(lquals("DYNAMIC_SEGMENT")) zm gdeerr("QUALREQD"):"Dynamic_segment"
-	i $d(lquals("JOURNAL")),lquals("JOURNAL"),'$d(lquals("BEFORE_IMAGE")) zm gdeerr("QUALREQD"):"Before_image"
-	i $d(lquals("NULL_SUBSCRIPTS")) d NQUALS^GDEVERIF(.lquals)
 	i '$$RQUALS^GDEVERIF(.lquals) zm gdeerr("OBJNOTADD"):"Region":REGION
 	s update=1,s="",regs=regs+1
 	f  s s=$o(tmpreg(s)) q:'$l(s)  s regs(REGION,s)=tmpreg(s)
 	f  s s=$o(lquals(s)) q:'$l(s)  s regs(REGION,s)=lquals(s)
 	i $d(segs),$d(regs(REGION,"DYNAMIC_SEGMENT")),$d(segs(regs(REGION,"DYNAMIC_SEGMENT"),"ACCESS_METHOD")) d
 	. i "MM"=segs(regs(REGION,"DYNAMIC_SEGMENT"),"ACCESS_METHOD"),'$d(lquals("BEFORE_IMAGE")) s regs(REGION,"BEFORE_IMAGE")=0
+	. i "USER"[segs(regs(REGION,"DYNAMIC_SEGMENT"),"ACCESS_METHOD"),'$d(lquals("JOURNAL")) s regs(REGION,"JOURNAL")=0
 	q
 SEGMENT
 	i $d(segs(SEGMENT)) zm gdeerr("OBJDUP"):"Segment":SEGMENT
@@ -42,3 +45,12 @@ SEGMENT
 seg:	s segs(SEGMENT,"FILE_NAME")=lquals("FILE_NAME")
 	f  s s=$o(tmpseg(am,s)) q:'$l(s)  s segs(SEGMENT,s)=tmpseg(am,s)
 	q
+GBLNAME
+	i $d(gnams(GBLNAME)) zm gdeerr("OBJDUP"):"Global Name":GBLNAME
+	i '$d(lquals("COLLATION")) zm gdeerr("QUALREQD"):"Collation"
+	; check if changing (i.e. adding) collation for GBLNAME poses issues with existing names & ranges
+	d gblnameeditchecks^GDEPARSE(GBLNAME,lquals("COLLATION"))
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
+	s update=1,gnams=gnams+1
+	s gnams(GBLNAME,"COLLATION")=lquals("COLLATION")
+	q
diff --git a/sr_port/gdechang.m b/sr_port/gdechang.m
index b241210..32d56b0 100644
--- a/sr_port/gdechang.m
+++ b/sr_port/gdechang.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,16 +10,17 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 change:	;implement the verb: CHANGE
 NAME
-	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":NAME
+	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":$$namedisp^GDESHOW(NAME,0)
 	i '$d(lquals("REGION")) zm gdeerr("QUALREQD"):"Region"
+	; check if changing the mapping of a name (with ranges) poses issues with overlap amongst other existing name ranges
+	d namerangeoverlapcheck^GDEPARSE(.NAME,lquals("REGION"))
 	s update=1
+	m nams(NAME)=NAME
 	s nams(NAME)=lquals("REGION")
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
 	q
 REGION
 	i '$d(regs(REGION)) zm gdeerr("OBJNOTFND"):"Region":REGION
-	i $d(lquals("JOURNAL")),lquals("JOURNAL"),'regs(REGION,"JOURNAL"),'$d(lquals("BEFORE_IMAGE")) d
-	. zm gdeerr("QUALREQD"):"Before_image"
-	i $d(lquals("NULL_SUBSCRIPTS")) d NQUALS^GDEVERIF(.lquals)
 	i '$$RQUALS^GDEVERIF(.lquals) zm gdeerr("OBJNOTCHG"):"region":REGION
 	s update=1,s=""
 	f  s s=$o(lquals(s)) q:'$l(s)  s regs(REGION,s)=lquals(s)
@@ -34,6 +35,18 @@ SEGMENT
 	f  s s=$o(tmpseg(am,s)) q:'$l(s)  d
 	. i '$l(tmpseg(am,s)) s segs(SEGMENT,s)="" q
 	. i '$l(segs(SEGMENT,s)) s segs(SEGMENT,s)=tmpseg(am,s)
-	i "MM"=am,"MM"'=tmpacc s s="" f  s s=$o(regs(s)) q:'$l(s)  d
-	. i regs(s,"DYNAMIC_SEGMENT")=SEGMENT,'$d(lquals("BEFORE_IMAGE")) s regs(s,"BEFORE_IMAGE")=0
+	i ("MM"=am)!("USER"[am) d
+	. s s="" f  s s=$o(regs(s)) q:'$l(s)  d
+	. . i "MM"=am,(regs(s,"DYNAMIC_SEGMENT")=SEGMENT),'$d(lquals("BEFORE_IMAGE")) s regs(s,"BEFORE_IMAGE")=0
+	. . i "USER"[am,(regs(s,"DYNAMIC_SEGMENT")=SEGMENT),'$d(lquals("JOURNAL")) s regs(s,"JOURNAL")=0
+	q
+GBLNAME
+	i '$d(gnams(GBLNAME)) zm gdeerr("OBJNOTFND"):"Global Name":GBLNAME
+	i '$d(lquals("COLLATION")) zm gdeerr("QUALREQD"):"Collation"
+	i gnams(GBLNAME,"COLLATION")=lquals("COLLATION") zm gdeerr("OBJNOTCHG"):"gblname":GBLNAME
+	; check if changing collation for GBLNAME poses issues with existing names & ranges
+	d gblnameeditchecks^GDEPARSE(GBLNAME,lquals("COLLATION"))
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
+	s update=1
+	s gnams(GBLNAME,"COLLATION")=lquals("COLLATION")
 	q
diff --git a/sr_port/gdedelet.m b/sr_port/gdedelet.m
index a4883e7..192088d 100644
--- a/sr_port/gdedelet.m
+++ b/sr_port/gdedelet.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001 Sanchez Computer Associates, Inc.	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,8 +10,9 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 delete:	;implement the verb: DELETE
 NAME
-	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":NAME
+	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":$$namedisp^GDESHOW(NAME,0)
 	i NAME="*" zm gdeerr("LVSTARALON")
+	; deleting a name should not cause any new range overlap issues so no need to call "namerangeoverlapcheck" here
 	s update=1 k nams(NAME) s nams=nams-1
 	q
 REGION
@@ -22,3 +23,11 @@ SEGMENT
 	i '$d(segs(SEGMENT)) zm gdeerr("OBJNOTFND"):"Segment":SEGMENT
 	s update=1 k segs(SEGMENT) s segs=segs-1
 	q
+GBLNAME
+	i '$d(gnams(GBLNAME)) zm gdeerr("OBJNOTFND"):"Global Name":GBLNAME
+	; check if changing (i.e. deleting) collation for GBLNAME poses issues with existing names & ranges
+	i $d(gnams(GBLNAME,"COLLATION")) d
+	. d gblnameeditchecks^GDEPARSE(GBLNAME,0)
+	. i $d(namrangeoverlap) d namcoalesce^GDEMAP
+	s update=1 k gnams(GBLNAME) s gnams=gnams-1
+	q
diff --git a/sr_port/gdeerrors.msg b/sr_port/gdeerrors.msg
index 4596aef..94278f1 100644
--- a/sr_port/gdeerrors.msg
+++ b/sr_port/gdeerrors.msg
@@ -1,6 +1,6 @@
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !								!
-!	Copyright 2001, 2012 Fidelity Information Services, Inc	!
+!	Copyright 2001, 2013 Fidelity Information Services, Inc	!
 !								!
 !	This source code contains the intellectual property	!
 !	of its copyright holder(s), and is made available	!
@@ -25,14 +25,14 @@ INPINTEG	<Input integrity error -- aborting load>/fatal/fao=0
 KEYTOOBIG	<But record size !AD can only support key size !AD>/info/fao=4
 KEYSIZIS	<Key size is !AD>/info/fao=2
 KEYWRDAMB	<!AD is ambiguous for !AD>/error/fao=4
-KEYWRDBAD	<!AD is not a valid !AD>/error/fao=4
+KEYWRDBAD	<!AD is not a valid !AD in this context>/error/fao=4
 LOADGD		<Loading Global Directory file !/	!AD>/info/fao=2
 LOGOFF		<No longer logging to file !AD>/info/fao=2
 LOGON		<Logging to file !AD>/info/fao=2
 LVSTARALON	<The * name cannot be deleted or renamed>/error/fao=0
 MAPBAD		<!AD !AD for !AD !AD does not exist>/info/fao=8
 MAPDUP		<!AD !AD and !AD both map to !AD !AD>/info/fao=10
-NAMSTARTBAD	<!AD must start with '%' or an alphabetic character>/error/fao=2
+NAMENDBAD	<Subscripted name !AD must end with right parenthesis>/error/fao=2
 NOACTION	<Not updating Global Directory !AD>/info/fao=2
 RPAREN		<List must end with right parenthesis or continue with comma>/error/fao=0
 NOEXIT		<Cannot exit because of verification failure>/info/fao=0
@@ -44,7 +44,7 @@ OBJNOTADD	<Not adding !AD !AD>/error/fao=4
 OBJNOTCHG	<Not changing !AD !AD>/error/fao=4
 OBJNOTFND	<!AD !AD does not exist>/error/fao=4
 OBJREQD		<!AD required>/error/fao=2
-PREFIXBAD	<!AD must start with an alphabetic character to be a !AD>/error/fao=4
+PREFIXBAD	<!AD - !AD !AD must start with an alphabetic character>/error/fao=6
 QUALBAD		<!AD is not a valid qualifier>/error/fao=2
 QUALDUP		<!AD qualifier appears more than once in the list>/error/fao=2
 QUALREQD	<!AD required>/error/fao=2
@@ -69,5 +69,31 @@ WRITEERROR	<Cannot exit because of write failure.  Reason for failure: !AD>/info
 NONASCII	<!AD is illegal for a !AD as it contains non-ASCII characters>/error/fao=4
 CRYPTNOMM	<!AD is an encrypted database. Cannot support MM access method.>/error/fao=2
 JNLALLOCGROW	<Increased Journal ALLOCATION from [!AD blocks] to [!AD blocks] to match AUTOSWITCHLIMIT for !AD !AD>/info/fao=8
-KEYFORBLK	<But block size !AD can only support key size !AD>/info/fao=4
+KEYFORBLK	<But block size !AD and reserved bytes !AD limit key size to !AD>/info/fao=6
+STRMISSQUOTE	<Missing double-quote at end of string specification !AD>/error/fao=2
+GBLNAMEIS	<in gblname !AD>/info/fao=2
+NAMSUBSEMPTY	<Subscript #!UL is empty in name specification>/error/fao=3
+NAMSUBSBAD	<Subscript #!UL with value !AD in name specification is an invalid number or string>/error/fao=3
+NAMNUMSUBSOFLOW	<Subscript #!UL with value !AD in name specification has a numeric overflow>/error/fao=3
+NAMNUMSUBNOTEXACT <Subscript #!UL with value !AD in name specification is not an exact GT.M number>/error/fao=3
+MISSINGDELIM	<Delimiter !AD expected before !AD !AD>/error/fao=6
+NAMRANGELASTSUB	<Ranges in name specification !AD are allowed only in the last subscript>/error/fao=2
+NAMSTARSUBSMIX	<Name specification !AD cannot contain * and subscripts at the same time>/error/fao=2
+NAMLPARENNOTBEG	<Subscripted Name specification !AD needs to have a left parenthesis at the beginning of subscripts>/error/fao=2
+NAMRPARENNOTEND	<Subscripted Name specification !AD cannot have anything following the right parenthesis at the end of subscripts>/error/fao=2
+NAMONECOLON	<Subscripted Name specification !AD must have at most one colon (range) specification>/error/fao=2
+NAMRPARENMISSING <Subscripted Name specification !AD is missing one or more right parentheses at the end of subscripts>/error/fao=2
+NAMGVSUBSMAX	<Subscripted Name specification !AD has more than the maximum # of subscripts (!UL)>/error/fao=3
+NAMNOTSTRSUBS	<Subscript #!UL with value !AD in name specification is not a properly formatted string subscript>/error/fao=3
+NAMSTRSUBSFUN	<Subscript #!UL with value !AD in name specification uses function other than $C/$CHAR/$ZCH/$ZCHAR>/error/fao=3
+NAMSTRSUBSLPAREN <Subscript #!UL with value !AD in name specification does not have left parenthesis following $ specification>/error/fao=3
+NAMSTRSUBSCHINT	<Subscript #!UL with value !AD in name specification does not have a positive integer inside $C/$CHAR/$ZCH/$ZCHAR>/error/fao=3
+NAMSTRSUBSCHARG	<Subscript #!UL with value !AD in name specification specifies a $C/$ZCH with number !UL that is invalid in the current $zchset>/error/fao=4
+GBLNAMCOLLUNDEF	<Error opening shared library of collation sequence #!UL for GBLNAME !AD>/error/fao=3
+NAMRANGEORDER	<Range in name specification !AD specifies out-of-order subscripts using collation sequence #!UL>/error/fao=3
+NAMRANGEOVERLAP	<Range in name specifications !AD and !AD overlap using collation sequence #!UL>/error/fao=5
+NAMGVSUBOFLOW	<Subscripted name !AD...!AD is too long to represent in the database using collation value #!UL>/error/fao=5
+GBLNAMCOLLRANGE	<Collation sequence #!UL is out of range (0 thru 255)>/error/fao=3
+STDNULLCOLLREQ	<Region !AD needs Standard Null Collation enabled because global !AD spans through it>/info/fao=4
+GBLNAMCOLLVER	<Global directory indicates GBLNAME !AD has collation sequence #!UL with a version #!UL but shared library reports different version #!UL>/error/fao=5
 	.end
diff --git a/sr_port/gdeexit.m b/sr_port/gdeexit.m
index cdf0a3e..aa41dbb 100644
--- a/sr_port/gdeexit.m
+++ b/sr_port/gdeexit.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001 Sanchez Computer Associates, Inc.	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -12,5 +12,27 @@ exit:	;implement the verb: EXIT
 EXIT
 	i 'update d QUIT^GDEQUIT
 	i '$$ALL^GDEVERIF  zm gdeerr("NOEXIT")  q
-	i '$$GDEPUT^GDEPUT  q	; zm is issued in GDEPUT.m
+	i '$$GDEPUT^GDEPUT  q	 ; zm is issued in GDEPUT.m
+	d GETOUT^GDEEXIT
 	h
+GETOUT	; Routine executed just before exiting from GDE. This tries to restore the mumps process context
+	;	to what it was at entry into GDE and then does a quit to the parent mumps program.
+	; This context would have been saved in the "gdeEntryState" variable. It is possible this variable
+	; is hidden due to argumentless/exclusive "new"s that happened inside GDE much after entry into GDE.
+	; In that case, there is nothing available to do the restore so skip the restore and "halt" out of
+	; the process to be safe (or else the parent mumps program could get confused).
+	;
+	i '$data(gdeEntryState) h
+	n nullsubs
+	s nullsubs=+gdeEntryState("nullsubs")
+	u gdeEntryState("io"):(exception="")	; restore $io with no exception (as otherwise it would be CTRL^GDE)
+	v $select(nullsubs=0:"NOLVNULLSUBS",nullsubs=1:"LVNULLSUBS",nullsubs=2:"NEVERLVNULLSUBS") ; restore LVNULLSUBS setting
+	; Use unsubscripted variables for local collation related act,ncol,nct values as otherwise we could get
+	; COLLDATAEXISTS error if we are restoring the local collation (before exit from GDE) as part of the $$set^%LCLCOL below.
+	; For the same reason store zlevel info in an unsubscripted variable as it is needed for the zgoto at the end.
+	n gdeEntryStateZlvl
+	s gdeEntryStateZlvl=+gdeEntryState("zlevel")
+	k (gdeEntryStateZlvl,gdeEntryStateAct,gdeEntryStateNcol,gdeEntryStateNct)
+	i $$set^%LCLCOL(gdeEntryStateAct,gdeEntryStateNcol,gdeEntryStateNct) ; restores local variable collation characteristics
+	zg gdeEntryStateZlvl ; this should exit GDE and return control to parent mumps process invocation
+	h  ; to be safe in case control ever reaches here
diff --git a/sr_port/gdeinit.m b/sr_port/gdeinit.m
index 064a6aa..363c915 100644
--- a/sr_port/gdeinit.m
+++ b/sr_port/gdeinit.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -39,7 +39,8 @@ GDEINIT
 	s gtm64=$p($zver," ",4)
 	i "/IA64/RS6000/SPARC/x86_64/x86/S390/S390X"[("/"_gtm64) s encsupportedplat=TRUE,gtm64=$s("x86"=gtm64:FALSE,1:TRUE)
 	e  s (encsupportedplat,gtm64)=FALSE
-	i (gtm64=TRUE) f x=1:1:16 s HEX(x)=HEX(x-1)*16 i x#2=0 s TWO(x*4)=HEX(x)
+	i (gtm64=TRUE) d
+	. f x=1:1:16 s HEX(x)=HEX(x-1)*16 i x#2=0 s TWO(x*4)=HEX(x)
 	e  f x=1:1:8 s HEX(x)=HEX(x-1)*16 i x#2=0 s TWO(x*4)=HEX(x)
 	f i=25:1:30 s TWO(i)=TWO(i-1)*2
 	s TWO(31)=TWO(32)*.5
@@ -48,34 +49,71 @@ GDEINIT
 	s ver=$p($zver," ",3)
 	s defglo=glo(ver)
 	s comline=$zcmdline
-	s nullsubs="\NEVER\FALSE\ALWAYS\TRUE\EXISTING"
-	s nommbi=1              ; this is used in gdeverif and should be removed along with the code when support is added
+	s typevalue("STR2NUM","TNULLSUB","N")=0
+	s typevalue("STR2NUM","TNULLSUB","NE")=0
+	s typevalue("STR2NUM","TNULLSUB","NEV")=0
+	s typevalue("STR2NUM","TNULLSUB","NEVE")=0
+	s typevalue("STR2NUM","TNULLSUB","NEVER")=0
+	s typevalue("STR2NUM","TNULLSUB","F")=0
+	s typevalue("STR2NUM","TNULLSUB","FA")=0
+	s typevalue("STR2NUM","TNULLSUB","FAL")=0
+	s typevalue("STR2NUM","TNULLSUB","FALS")=0
+	s typevalue("STR2NUM","TNULLSUB","FALSE")=0
+	s typevalue("STR2NUM","TNULLSUB","T")=1
+	s typevalue("STR2NUM","TNULLSUB","TR")=1
+	s typevalue("STR2NUM","TNULLSUB","TRU")=1
+	s typevalue("STR2NUM","TNULLSUB","TRUE")=1
+	s typevalue("STR2NUM","TNULLSUB","A")=1
+	s typevalue("STR2NUM","TNULLSUB","AL")=1
+	s typevalue("STR2NUM","TNULLSUB","ALW")=1
+	s typevalue("STR2NUM","TNULLSUB","ALWA")=1
+	s typevalue("STR2NUM","TNULLSUB","ALWAY")=1
+	s typevalue("STR2NUM","TNULLSUB","ALWAYS")=1
+	s typevalue("STR2NUM","TNULLSUB","E")=2
+	s typevalue("STR2NUM","TNULLSUB","EX")=2
+	s typevalue("STR2NUM","TNULLSUB","EXI")=2
+	s typevalue("STR2NUM","TNULLSUB","EXIS")=2
+	s typevalue("STR2NUM","TNULLSUB","EXIST")=2
+	s typevalue("STR2NUM","TNULLSUB","EXISTI")=2
+	s typevalue("STR2NUM","TNULLSUB","EXISTIN")=2
+	s typevalue("STR2NUM","TNULLSUB","EXISTING")=2
+	s typevalue("NUM2STR","TNULLSUB",0)="NEVER"
+	s typevalue("NUM2STR","TNULLSUB",1)="ALWAYS"
+	s typevalue("NUM2STR","TNULLSUB",2)="EXISTING"
+	s typevalue("STR2NUM","TACCMETH","BG")=0
+	s typevalue("STR2NUM","TACCMETH","MM")=1
+	s nommbi=1              ; this is used in GDEVERIF and should be removed along with the code when support is added
 	d UNIX:ver'="VMS"
 	d VMS:ver="VMS"
 	d syntabi
 ;
+	; Explanation of some of the SIZEOF local variable subscripts.
+	;	SIZEOF("gd_segment")		; --> size of the "gd_segment" structure (defined in gdsfhead.h)
+	;
 	i (gtm64=FALSE) d
-	. s SIZEOF("am_offset")=324
-	. s SIZEOF("file_spec")=256
-	. s SIZEOF("gd_header")=16
-	. s SIZEOF("gd_contents")=44
-	. s SIZEOF("gd_map")=36
+	. s SIZEOF("am_offset")=328		; --> offset of "acc_meth" field in the "gd_segment" structure
+	. s SIZEOF("file_spec")=256		; --> maximum size (in bytes) of a file name specified in gde command line
+	. s SIZEOF("gd_header")=16		; --> 16-byte header structure at offset 0 of .gld (12 byte label, 4-byte filesize)
+	. s SIZEOF("gd_contents")=76		; --> size of the "gd_addr" structure (defined in gdsfhead.h)
+	. s SIZEOF("gd_map")=16			; --> size of the "gd_binding" structure (defined in gdsfhead.h)
 	. if ver'="VMS" d
-	. . s SIZEOF("gd_region")=356
-	. . s SIZEOF("gd_region_padding")=0			; not used on VMS
-	. . s SIZEOF("gd_segment")=340
+	. . s SIZEOF("gd_region")=372		; --> size of the "gd_region"  structure (defined in gdsfhead.h)
+	. . s SIZEOF("gd_region_padding")=0	; --> padding at end of "gd_region" structure (4-bytes for 64-bit platforms)
+	. . s SIZEOF("gd_segment")=360		; --> size of the "gd_segment" structure (defined in gdsfhead.h)
 	. e  d
-	. . s SIZEOF("gd_region")=332
-	. . s SIZEOF("gd_segment")=336
+	. . s SIZEOF("gd_region")=348		; --> size of the "gd_region"  structure (defined in gdsfhead.h)
+	. . ; SIZEOF("gd_region_padding")	 is not used in VMS
+	. . s SIZEOF("gd_segment")=356		; --> size of the "gd_segment" structure (defined in gdsfhead.h)
 	e  d
-	. s SIZEOF("am_offset")=332
-	. s SIZEOF("file_spec")=256
-	. s SIZEOF("gd_header")=16
-	. s SIZEOF("gd_contents")=80
-	. s SIZEOF("gd_map")=40
-	. s SIZEOF("gd_region")=368
-	. s SIZEOF("gd_region_padding")=4
-	. s SIZEOF("gd_segment")=360
+	. s SIZEOF("am_offset")=336		; --> offset of "acc_meth" field in the "gd_segment" structure
+	. s SIZEOF("file_spec")=256		; --> maximum size (in bytes) of a file name specified in gde command line
+	. s SIZEOF("gd_header")=16		; --> 16-byte header structure at offset 0 of .gld (12 byte label, 4-byte filesize)
+	. s SIZEOF("gd_contents")=112		; --> size of the "gd_addr" structure (defined in gdsfhead.h)
+	. s SIZEOF("gd_map")=24			; --> size of the "gd_binding" structure (defined in gdsfhead.h)
+	. s SIZEOF("gd_region")=384		; --> size of the "gd_region"  structure (defined in gdsfhead.h)
+	. s SIZEOF("gd_region_padding")=4	; --> padding at end of "gd_region" structure (4-bytes for 64-bit platforms)
+	. s SIZEOF("gd_segment")=384		; --> size of the "gd_segment" structure (defined in gdsfhead.h)
+	s SIZEOF("gd_gblname")=40
 	s SIZEOF("mident")=32
 	s SIZEOF("blk_hdr")=16
 	i ver'="VMS" d
@@ -90,33 +128,37 @@ GDEINIT
 	s SIZEOF("reg_jnl_deq")=4				; not used on VMS
 	s MAXNAMLN=SIZEOF("mident")-1,MAXREGLN=32,MAXSEGLN=32	; maximum name length allowed is 31 characters
 	s PARNAMLN=31,PARREGLN=31,PARSEGLN=31
+	s MAXSTRLEN=(2**20)					; needs to be equal to MAX_STRLEN in mdef.h at all times
+	s MAXGVSUBS=31						; needs to be equal to (MAX_GVSUBSCRIPTS-1) in mdef.h at all times
 ;
-; tokens are used for error reporting only
+; tokens are used for parsing and error reporting
 	s tokens("TKIDENT")="identifier"
-	s tokens("TKNUMLIT")="number"
 	s tokens("TKEOL")="end-of-line"
 	s tokens("""")="TKSTRLIT",tokens("TKSTRLIT")="string literal"
-	s tokens("@")="TKAMPER",tokens("TKAMPER")="ampersand"
-	s tokens("*")="TKASTER",tokens("TKASTER")="asterisk"
-	s tokens(":")="TKCOLON",tokens("TKCOLON")="colon"
+	s tokens("@")="TKAT",tokens("TKAT")="at sign"
 	s tokens(",")="TKCOMMA",tokens("TKCOMMA")="comma"
-	s tokens("$")="TKDOLLAR",tokens("TKDOLLAR")="dollar sign"
 	s tokens("=")="TKEQUAL",tokens("TKEQUAL")="equal sign"
-	s tokens("<")="TKLANGLE",tokens("TKLANGLE")="left angle bracket"
-	s tokens("[")="TKLBRACK",tokens("TKLBRACK")="left bracket"
 	s tokens("(")="TKLPAREN",tokens("TKLPAREN")="left parenthesis"
-	s tokens("-")="TKDASH",tokens("TKDASH")="dash"
-	s tokens("%")="TKPCT",tokens("TKPCT")="percent sign"
-	s tokens(".")="TKPERIOD",tokens("TKPERIOD")="period"
 	s tokens(")")="TKRPAREN",tokens("TKRPAREN")="right parenthesis"
-	s tokens("]")="TKRBRACK",tokens("TKRBRACK")="right bracket"
-	s tokens(">")="TKRANGLE",tokens("TKRANGLE")="right angle bracket"
-	s tokens(";")="TKSCOLON",tokens("TKSCOLON")="semicolon"
-	s tokens("/")="TKSLASH",tokens("TKSLASH")="slash"
-	s tokens("_")="TKUSCORE",tokens("TKUSCORE")="underscore"
 	s tokens("!")="TKEXCLAM",tokens("TKEXCLAM")="exclamation point"
-	s tokens("TKOTHER")="other"
+	i ver'="VMS" s tokens("-")="TKDASH",tokens("TKDASH")="dash"
+	e            s tokens("/")="TKSLASH",tokens("TKSLASH")="slash"
+	s tokens("")="TKEOL"	; for parsing purposes
+; tokendelim is used for parsing; it is defined for all characters that can terminate a valid token during parsing
+	for c=" ",TAB,"=",",",")","" s tokendelim(c)=""
+	; in case of VMS, we want the "/" qualifier separator to be treated as a delimiter even if not preceded by white space
+	; this is how VMS tools work. Whereas in the Unix shell command line, space is by default the separator for multiple
+	; qualifiers. Hence GDE also is similarly different between Unix vs VMS in terms of separator handling ("-" vs "/").
+	i ver="VMS" s tokendelim("/")=""
+; spacedelim is used for parsing when we want to terminate token parsing only if we see a white space (a subset of "tokendelim")
+; this is needed in case we are parsing say a filename and we dont want a "-" or "=" in the file name to terminate the parse.
+	for c=" ",TAB,"" s spacedelim(c)=""
+	i ver="VMS" s spacedelim("/")=""
+	k c
 ; maximums and mimimums
+; gblname
+	s mingnam("COLLATION")=0
+	s maxgnam("COLLATION")=255
 ; region
 	s minreg("ALLOCATION")=$s(ver'="VMS":200,1:10)
 	s minreg("BEFORE_IMAGE")=0,minreg("COLLATION_DEFAULT")=0,minreg("STDNULLCOLL")=0
@@ -139,6 +181,7 @@ GDEINIT
 	i ver="VMS" do
 	. s maxreg("EXTENSION")=HEX(4)-1
 	. s maxreg("BUFFER_SIZE")=2000
+	. s maxreg("KEY_SIZE")=255
 	e  d
 	. s maxreg("EXTENSION")=1073741823
 	. s maxreg("AUTOSWITCHLIMIT")=8388607
@@ -149,29 +192,61 @@ GDEINIT
 	. s maxreg("INST_FREEZE_ON_ERROR")=1
 	. s maxreg("BUFFER_SIZE")=32768
 	. s maxreg("QDBRUNDOWN")=1
-	s maxreg("JOURNAL")=1,maxreg("KEY_SIZE")=1019,maxreg("NULL_SUBSCRIPTS")=2
+	. s maxreg("KEY_SIZE")=1019	; = max value of KEY->end that returns TRUE for CAN_APPEND_HIDDEN_SUBS(KEY) in gdsfhead.h
+	s maxreg("JOURNAL")=1,maxreg("NULL_SUBSCRIPTS")=2
 	s maxreg("RECORD_SIZE")=SIZEOF("max_str")
 ; segments
+	; First define segment characteristics (minimum and maximum) that are identical to BG and MM access methods
+	; Then define overrides specific to BG and MM
+	n minsegcommon,maxsegcommon
+	s minsegcommon("ALLOCATION")=10
+	s maxsegcommon("ALLOCATION")=TWO(27)
+	i ver'="VMS" s maxsegcommon("ALLOCATION")=TWO(30)-TWO(25) ; supports 992M blocks for UNIX only
+	s minsegcommon("BLOCK_SIZE")=SIZEOF("dsk_blk")
+	s maxsegcommon("BLOCK_SIZE")=HEX(4)-SIZEOF("dsk_blk")
+	s minsegcommon("EXTENSION_COUNT")=0
+	s maxsegcommon("EXTENSION_COUNT")=HEX(4)-1
+	s minsegcommon("LOCK_SPACE")=10
+	s maxsegcommon("LOCK_SPACE")=65536
+	s minsegcommon("MUTEX_SLOTS")=64	; keep this in sync with MIN_CRIT_ENTRY in gdsbt.h
+	s maxsegcommon("MUTEX_SLOTS")=32768	; keep this in sync with MAX_CRIT_ENTRY in gdsbt.h
+	s minsegcommon("RESERVED_BYTES")=0
+	s maxsegcommon("RESERVED_BYTES")=HEX(4)-SIZEOF("dsk_blk")
 ; bg
-	s minseg("BG","ALLOCATION")=10,minseg("BG","BLOCK_SIZE")=SIZEOF("dsk_blk"),minseg("BG","EXTENSION_COUNT")=0
-	s minseg("BG","GLOBAL_BUFFER_COUNT")=64,minseg("BG","LOCK_SPACE")=10,minseg("BG","RESERVED_BYTES")=0
-	s maxseg("BG","ALLOCATION")=TWO(27),(maxseg("BG","BLOCK_SIZE"),maxseg("BG","RESERVED_BYTES"))=HEX(4)-SIZEOF("dsk_blk")
-	i ver'="VMS" s maxseg("BG","ALLOCATION")=TWO(30)-TWO(25) ; supports 992M blocks for UNIX only
-	s maxseg("BG","EXTENSION_COUNT")=HEX(4)-1,maxseg("BG","LOCK_SPACE")=65536
+	m minseg("BG")=minsegcommon	; copy over all common stuff into BG access method first
+	m maxseg("BG")=maxsegcommon	; copy over all common stuff into BG access method first
+	; now add BG specific overrides
+	s minseg("BG","GLOBAL_BUFFER_COUNT")=64
 	i (gtm64=TRUE) s maxseg("BG","GLOBAL_BUFFER_COUNT")=2147483647 ; 2G-1
 	e  s maxseg("BG","GLOBAL_BUFFER_COUNT")=65536
 ; mm
-	s minseg("MM","ALLOCATION")=10,minseg("MM","BLOCK_SIZE")=SIZEOF("dsk_blk"),minseg("MM","DEFER")=0
-	s minseg("MM","LOCK_SPACE")=10,minseg("MM","EXTENSION_COUNT")=0,minseg("MM","RESERVED_BYTES")=0
-	s maxseg("MM","ALLOCATION")=TWO(27),(maxseg("MM","BLOCK_SIZE"),maxseg("BG","RESERVED_BYTES"))=HEX(4)-SIZEOF("dsk_blk")
-	i ver'="VMS" s maxseg("MM","ALLOCATION")=TWO(30)-TWO(25) ; supports 992M blocks for UNIX only
-	s maxseg("MM","DEFER")=86400,maxseg("MM","LOCK_SPACE")=1000,maxseg("MM","EXTENSION_COUNT")=HEX(4)-1
+	m minseg("MM")=minsegcommon	; copy over all common stuff into MM access method first
+	m maxseg("MM")=maxsegcommon	; copy over all common stuff into BG access method first
+	; now add MM specific overrides
+	s minseg("MM","DEFER")=0
+	s maxseg("MM","DEFER")=86400
+	; Now define default segment characteristics
+	; This is particularly needed for fields that are only available in more recent .gld formats
+	; So if we are reading an older format .gld file, we can use these as the default values.
+	s defseg("ALLOCATION")=100
+	s defseg("BLOCK_SIZE")=1024
+	s defseg("BUCKET_SIZE")=""
+	s defseg("EXTENSION_COUNT")=100
+	s defseg("FILE_TYPE")="DYNAMIC"
+	s defseg("MUTEX_SLOTS")=1024 ; keep this in sync with DEFAULT_NUM_CRIT_ENTRY in gdsbt.h
+	s defseg("RESERVED_BYTES")=0
+	s defseg("LOCK_SPACE")=40
+	s defseg("WINDOW_SIZE")=""
+	i ver'="VMS" s defseg("ENCRYPTION_FLAG")=0
 	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
 
 ; gde command language syntax table
 syntabi:
+	s syntab("ADD","GBLNAME")=""
+	s syntab("ADD","GBLNAME","COLLATION")="REQUIRED"
+	s syntab("ADD","GBLNAME","COLLATION","TYPE")="TNUMBER"
 	s syntab("ADD","NAME")=""
 	s syntab("ADD","NAME","REGION")="REQUIRED"
 	s syntab("ADD","NAME","REGION","TYPE")="TREGION"
@@ -194,19 +269,16 @@ syntabi:
 	s syntab("ADD","REGION","JOURNAL","EXTENSION","TYPE")="TNUMBER"
 	s syntab("ADD","REGION","JOURNAL","FILE_NAME")="REQUIRED"
 	s syntab("ADD","REGION","JOURNAL","FILE_NAME","TYPE")="TFSPEC"
-	;s syntab("ADD","REGION","JOURNAL","STOP_ENABLED")="NEGATABLE"
 	s syntab("ADD","REGION","KEY_SIZE")="REQUIRED"
 	s syntab("ADD","REGION","KEY_SIZE","TYPE")="TNUMBER"
 	s syntab("ADD","REGION","NULL_SUBSCRIPTS")="NEGATABLE,REQUIRED"
 	s syntab("ADD","REGION","NULL_SUBSCRIPTS","TYPE")="TNULLSUB"
-	s syntab("ADD","REGION","NULL_SUBSCRIPTS","TYPE","VALUES")=nullsubs
 	i ver'="VMS" s syntab("ADD","REGION","QDBRUNDOWN")="NEGATABLE"
 	s syntab("ADD","REGION","RECORD_SIZE")="REQUIRED"
 	s syntab("ADD","REGION","RECORD_SIZE","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT")=""
 	s syntab("ADD","SEGMENT","ACCESS_METHOD")="REQUIRED"
 	s syntab("ADD","SEGMENT","ACCESS_METHOD","TYPE")="TACCMETH"
-	s syntab("ADD","SEGMENT","ACCESS_METHOD","TYPE","VALUES")=accmeth
 	s syntab("ADD","SEGMENT","ALLOCATION")="REQUIRED"
 	s syntab("ADD","SEGMENT","ALLOCATION","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT","BLOCK_SIZE")="REQUIRED"
@@ -219,6 +291,8 @@ syntabi:
 	s syntab("ADD","SEGMENT","EXTENSION_COUNT","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT","FILE_NAME")="REQUIRED"
 	s syntab("ADD","SEGMENT","FILE_NAME","TYPE")="TFSPEC"
+	s syntab("ADD","SEGMENT","MUTEX_SLOTS")="REQUIRED"
+	s syntab("ADD","SEGMENT","MUTEX_SLOTS","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT","GLOBAL_BUFFER_COUNT")="REQUIRED"
 	s syntab("ADD","SEGMENT","GLOBAL_BUFFER_COUNT","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT","LOCK_SPACE")="REQUIRED"
@@ -227,6 +301,9 @@ syntabi:
 	s syntab("ADD","SEGMENT","RESERVED_BYTES","TYPE")="TNUMBER"
 	s syntab("ADD","SEGMENT","WINDOW_SIZE")="REQUIRED"
 	s syntab("ADD","SEGMENT","WINDOW_SIZE","TYPE")="TNUMBER"
+	s syntab("CHANGE","GBLNAME")=""
+	s syntab("CHANGE","GBLNAME","COLLATION")="REQUIRED"
+	s syntab("CHANGE","GBLNAME","COLLATION","TYPE")="TNUMBER"
 	s syntab("CHANGE","NAME")=""
 	s syntab("CHANGE","NAME","REGION")="REQUIRED"
 	s syntab("CHANGE","NAME","REGION","TYPE")="TREGION"
@@ -249,19 +326,16 @@ syntabi:
 	s syntab("CHANGE","REGION","JOURNAL","EXTENSION","TYPE")="TNUMBER"
 	s syntab("CHANGE","REGION","JOURNAL","FILE_NAME")="REQUIRED"
 	s syntab("CHANGE","REGION","JOURNAL","FILE_NAME","TYPE")="TFSPEC"
-	;s syntab("CHANGE","REGION","JOURNAL","STOP_ENABLED")="NEGATABLE"
 	s syntab("CHANGE","REGION","KEY_SIZE")="REQUIRED"
 	s syntab("CHANGE","REGION","KEY_SIZE","TYPE")="TNUMBER"
 	s syntab("CHANGE","REGION","NULL_SUBSCRIPTS")="NEGATABLE,REQUIRED"
 	s syntab("CHANGE","REGION","NULL_SUBSCRIPTS","TYPE")="TNULLSUB"
-	s syntab("CHANGE","REGION","NULL_SUBSCRIPTS","TYPE","VALUES")=nullsubs
 	i ver'="VMS" s syntab("CHANGE","REGION","QDBRUNDOWN")="NEGATABLE"
 	s syntab("CHANGE","REGION","RECORD_SIZE")="REQUIRED"
 	s syntab("CHANGE","REGION","RECORD_SIZE","TYPE")="TNUMBER"
 	s syntab("CHANGE","SEGMENT")=""
 	s syntab("CHANGE","SEGMENT","ACCESS_METHOD")="REQUIRED"
 	s syntab("CHANGE","SEGMENT","ACCESS_METHOD","TYPE")="TACCMETH"
-	s syntab("CHANGE","SEGMENT","ACCESS_METHOD","TYPE","VALUES")=accmeth
 	s syntab("CHANGE","SEGMENT","ALLOCATION")="REQUIRED"
 	s syntab("CHANGE","SEGMENT","ALLOCATION","TYPE")="TNUMBER"
 	s syntab("CHANGE","SEGMENT","BLOCK_SIZE")="REQUIRED"
@@ -274,6 +348,8 @@ syntabi:
 	s syntab("CHANGE","SEGMENT","EXTENSION_COUNT","TYPE")="TNUMBER"
 	s syntab("CHANGE","SEGMENT","FILE_NAME")="REQUIRED"
 	s syntab("CHANGE","SEGMENT","FILE_NAME","TYPE")="TFSPEC"
+	s syntab("CHANGE","SEGMENT","MUTEX_SLOTS")="REQUIRED"
+	s syntab("CHANGE","SEGMENT","MUTEX_SLOTS","TYPE")="TNUMBER"
 	s syntab("CHANGE","SEGMENT","GLOBAL_BUFFER_COUNT")="REQUIRED"
 	s syntab("CHANGE","SEGMENT","GLOBAL_BUFFER_COUNT","TYPE")="TNUMBER"
 	s syntab("CHANGE","SEGMENT","LOCK_SPACE")="REQUIRED"
@@ -288,12 +364,13 @@ syntabi:
 	s syntab("TEMPLATE","REGION","STDNULLCOLL")="NEGATABLE"
 	s syntab("TEMPLATE","REGION","DYNAMIC_SEGMENT")="REQUIRED"
 	s syntab("TEMPLATE","REGION","DYNAMIC_SEGMENT","TYPE")="TSEGMENT"
-	i ver'="VMS" s syntab("TEMPLATE","REGION","INST_FREEZE_ON_ERROR")="NEGATABLE"
 	s syntab("TEMPLATE","REGION","JOURNAL")="NEGATABLE,REQUIRED,LIST"
 	s syntab("TEMPLATE","REGION","JOURNAL","ALLOCATION")="REQUIRED"
 	s syntab("TEMPLATE","REGION","JOURNAL","ALLOCATION","TYPE")="TNUMBER"
-	s syntab("TEMPLATE","REGION","JOURNAL","AUTOSWITCHLIMIT")="REQUIRED"
-	s syntab("TEMPLATE","REGION","JOURNAL","AUTOSWITCHLIMIT","TYPE")="TNUMBER"
+	i ver'="VMS" d
+	. s syntab("TEMPLATE","REGION","INST_FREEZE_ON_ERROR")="NEGATABLE"
+	. s syntab("TEMPLATE","REGION","JOURNAL","AUTOSWITCHLIMIT")="REQUIRED"
+	. s syntab("TEMPLATE","REGION","JOURNAL","AUTOSWITCHLIMIT","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","REGION","JOURNAL","BUFFER_SIZE")="REQUIRED"
 	s syntab("TEMPLATE","REGION","JOURNAL","BUFFER_SIZE","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","REGION","JOURNAL","BEFORE_IMAGE")="NEGATABLE"
@@ -301,19 +378,16 @@ syntabi:
 	s syntab("TEMPLATE","REGION","JOURNAL","EXTENSION","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","REGION","JOURNAL","FILE_NAME")="REQUIRED"
 	s syntab("TEMPLATE","REGION","JOURNAL","FILE_NAME","TYPE")="TFSPEC"
-	;s syntab("TEMPLATE","REGION","JOURNAL","STOP_ENABLED")="NEGATABLE"
 	s syntab("TEMPLATE","REGION","KEY_SIZE")="REQUIRED"
 	s syntab("TEMPLATE","REGION","KEY_SIZE","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","REGION","NULL_SUBSCRIPTS")="NEGATABLE,REQUIRED"
 	s syntab("TEMPLATE","REGION","NULL_SUBSCRIPTS","TYPE")="TNULLSUB"
-	s syntab("TEMPLATE","REGION","NULL_SUBSCRIPTS","TYPE","VALUES")=nullsubs
 	i ver'="VMS" s syntab("TEMPLATE","REGION","QDBRUNDOWN")="NEGATABLE"
 	s syntab("TEMPLATE","REGION","RECORD_SIZE")="REQUIRED"
 	s syntab("TEMPLATE","REGION","RECORD_SIZE","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT")=""
 	s syntab("TEMPLATE","SEGMENT","ACCESS_METHOD")="REQUIRED"
 	s syntab("TEMPLATE","SEGMENT","ACCESS_METHOD","TYPE")="TACCMETH"
-	s syntab("TEMPLATE","SEGMENT","ACCESS_METHOD","TYPE","VALUES")=accmeth
 	s syntab("TEMPLATE","SEGMENT","ALLOCATION")="REQUIRED"
 	s syntab("TEMPLATE","SEGMENT","ALLOCATION","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT","BLOCK_SIZE")="REQUIRED"
@@ -326,6 +400,8 @@ syntabi:
 	s syntab("TEMPLATE","SEGMENT","EXTENSION_COUNT","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT","FILE_NAME")="REQUIRED"
 	s syntab("TEMPLATE","SEGMENT","FILE_NAME","TYPE")="TFSPEC"
+	s syntab("TEMPLATE","SEGMENT","MUTEX_SLOTS")="REQUIRED"
+	s syntab("TEMPLATE","SEGMENT","MUTEX_SLOTS","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT","GLOBAL_BUFFER_COUNT")="REQUIRED"
 	s syntab("TEMPLATE","SEGMENT","GLOBAL_BUFFER_COUNT","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT","LOCK_SPACE")="REQUIRED"
@@ -334,6 +410,7 @@ syntabi:
 	s syntab("TEMPLATE","SEGMENT","RESERVED_BYTES","TYPE")="TNUMBER"
 	s syntab("TEMPLATE","SEGMENT","WINDOW_SIZE")="REQUIRED"
 	s syntab("TEMPLATE","SEGMENT","WINDOW_SIZE","TYPE")="TNUMBER"
+	s syntab("DELETE","GBLNAME")=""
 	s syntab("DELETE","NAME")=""
 	s syntab("DELETE","REGION")=""
 	s syntab("DELETE","SEGMENT")=""
@@ -344,27 +421,30 @@ syntabi:
 	s syntab("LOG","OFF")=""
 	s syntab("LOG","ON")="OPTIONAL"
 	s syntab("LOG","ON","TYPE")="TFSPEC"
-	s syntab("SETGD","FILE")="REQUIRED"
-	s syntab("SETGD","FILE","TYPE")="TFSPEC"
-	s syntab("SETGD","QUIT")=""
 	s syntab("QUIT")=""
+	s syntab("RENAME","GBLNAME")=""
 	s syntab("RENAME","NAME")=""
 	s syntab("RENAME","REGION")=""
 	s syntab("RENAME","SEGMENT")=""
+	s syntab("SETGD","FILE")="REQUIRED"
+	s syntab("SETGD","FILE","TYPE")="TFSPEC"
+	s syntab("SETGD","QUIT")=""
 	s syntab("SHOW")=""
 	s syntab("SHOW","ALL")=""
-	s syntab("SHOW","TEMPLATE")=""
+	s syntab("SHOW","COMMANDS")=""
+	s syntab("SHOW","COMMANDS","FILE")="OPTIONAL"
+	s syntab("SHOW","COMMANDS","FILE","TYPE")="TFSPEC"
+	s syntab("SHOW","GBLNAME")=""
 	s syntab("SHOW","MAP")=""
 	s syntab("SHOW","MAP","REGION")="REQUIRED"
 	s syntab("SHOW","MAP","REGION","TYPE")="TREGION"
 	s syntab("SHOW","NAME")=""
 	s syntab("SHOW","REGION")=""
 	s syntab("SHOW","SEGMENT")=""
-	s syntab("SHOW","COMMANDS")=""
-	s syntab("SHOW","COMMANDS","FILE")="OPTIONAL"
-	s syntab("SHOW","COMMANDS","FILE","TYPE")="TFSPEC"
+	s syntab("SHOW","TEMPLATE")=""
 	s syntab("SPAWN")=""
 	s syntab("VERIFY","ALL")=""
+	s syntab("VERIFY","GBLNAME")=""
 	s syntab("VERIFY","MAP")=""
 	s syntab("VERIFY","NAME")=""
 	s syntab("VERIFY","REGION")=""
@@ -373,9 +453,10 @@ syntabi:
 	q
 VMS
 	s endian=FALSE
-	s hdrlab="GTCGBLDIR009"		; must be concurrently maintained in gbldirnam.h!!!
+	s hdrlab="GTCGBLDIR010"		; must be concurrently maintained in gbldirnam.h!!!
 	s tfile="GTM$GBLDIR"
 	s accmeth="\BG\MM\USER"
+	s typevalue("STR2NUM","TACCMETH","USER")=2
 	s helpfile="GTM$HELP:GDE.HLB"
 	s defdb="MUMPS"
 	s defgld="MUMPS.GLD",defgldext=".GLD"
@@ -387,8 +468,8 @@ VMS
 	q
 
 UNIX:
-	s hdrlab="GTCGBDUNX008"         ; must be concurrently maintained in gbldirnam.h!!!
-	i (gtm64=TRUE) s hdrlab="GTCGBDUNX108" ; the high order digit is a 64-bit flag
+	s hdrlab="GTCGBDUNX009"         ; must be concurrently maintained in gbldirnam.h!!!
+	i (gtm64=TRUE) s hdrlab="GTCGBDUNX109" ; the high order digit is a 64-bit flag
 	s tfile="$gtmgbldir"
 	s accmeth="\BG\MM"
 	s helpfile="$gtm_dist/gdehelp.gld"
diff --git a/sr_port/gdemap.m b/sr_port/gdemap.m
index db15bd6..e47ec58 100644
--- a/sr_port/gdemap.m
+++ b/sr_port/gdemap.m
@@ -9,88 +9,223 @@
 ;								;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 map:	;create maps for put and show, names for get and show
-PUTMAKE
-	k lexnams n t1
-	d SHOWMAKE
-	s s1=$ztr($zj("",SIZEOF("mident"))," ",$zch(255)),t1=$ztr($zj("",SIZEOF("mident"))," ",$zch(0))
-	f  s s2=s1,s1=$o(map(s1),-1),map(s2_$ze(t1,$zl(s2)+1,SIZEOF("mident")))=map(s1) q:s1="$"  k map(s1)
-	s map("#)"_$ze(t1,3,SIZEOF("mident")))=map("#)"),map("%"_$ze(t1,2,SIZEOF("mident")))=map("$")
-	f s2="#","#)","$" k map(s2)
+CREATEGLDMAP ; create map for GDEPUT to write to .gld file
+	k lexnams n suffix,s1,s2
+	d NAM2MAP
+	s s1="",$zpi(s1,$zch(255),SIZEOF("mident"))=""
+	f  s s2=s1,s1=$o(map(s1),-1),map(s2)=map(s1) q:s1="$"  k map(s1)
+	s map("%")=map("$")
+	f s2="#","$" k map(s2)
  	q
 ;----------------------------------------------------------------------------------------------------------------------------------
-SHOWMAKE
+NAM2MAP ;
+	; transform nams() array to map() array
+	;
 	n lexnams s s=""
-	f  s s=$o(nams(s)) q:'$zl(s)  d lexins(s)
-	s map("$")=nams("*"),map("#")=nams("#")
-	s i=1
-	f  s i=$o(lexnams(i)) q:'$zl(i)  d showstar(i)
-	s s=""
-	f  s s=$o(lexnams(0,s),-1) q:'$zl(s)  d pointins(s,lexnams(0,s))
+	s map("$")=nams("*"),map("#")=nams("#")   ; initialize map() array for "*" name and local-locks ("#" name).
+	f  s s=$o(nams(s)) q:'$zl(s)  d lexins(s) ; initializes lexnams() array
+	; convert names into maps. more general names coming ahead of more specific names
+	; i.e. if names are of the form, ABCD, ABCD(1:10), ABCD(3), ABCD(3,7), ABCD(3,5:10), ABC*, AB* AND A*
+	; process them in the order A*, AB*, ABC*, ABCD, ABCD(1:10), ABCD(3), ABCD(3,5:10), ABCD(3,7)
+	s i=1 f  s i=$o(lexnams(i)) q:'$zl(i)  d starins(i)
+	; Insert rest of the names (no * in them). Do unsubscripted names first and then the subscripted names.
+	; This order is important as otherwise the mappings would end up in the wrong region.
+	s s="" f  s s=$o(lexnams(0,s),-1) q:'$zl(s)  d pointins(s,lexnams(0,s))	; insert unsubscripted names
+	s i=0 f  s i=$o(lexnams(i),-1) q:'$zl(i)  d
+	. s s="" f  s s=$o(lexnams(i,s),-1) q:'$zl(s)  d pointins(s,lexnams(i,s))	; insert subscripted names
+	; remove map entries that are contiguous and are mapped to same region. keeps map() array size minimal
 	s s1=$o(map(""),-1)
 	f  s s2=s1,s1=$o(map(s1),-1) q:s2="$"  i map(s1)=map(s2) k map(s2)
 	q
 ;----------------------------------------------------------------------------------------------------------------------------------
 SHOWNAM
-	n lexnams,t1,map
-	d SHOWMAKE
-	s s1=$ztr($zj("",SIZEOF("mident"))," ",$zch(255)),t1=$ztr($zj("",SIZEOF("mident"))," ",$zch(0))
+	; to show names, we transform the NAMES to MAP and then reverse transform the MAP back to NAMES.
+	; this ensure we optimize the names (remove redundant name specifications) before showing it.
+	n lexnams,map
+	d NAM2MAP
+	s s1="",$zpi(s1,$zch(255),SIZEOF("mident"))=""
 	f  s s2=s1,s1=$o(map(s1),-1),map(s2)=map(s1) q:s1="$"  k map(s1)
 	k map("#") i '$$MAP2NAM(.map) zm gdeerr("GDECHECK")\2*2
  	q
 ;----------------------------------------------------------------------------------------------------------------------------------
-MAP2NAM(list)
-	n maxMap,currMap,currMapLen,prevMap,prevMapLen,currReg,prevPrefix,currPrefix
-	n namSpc,currNam,currNamLen,stopLoop,i,startMap,midentSize,prevPrevMap
+MAP2NAM(list1)
+	n maxMap,currMap,currMapLen,prevMap,prevMapLen,currReg,prevReg,nextReg,prevPrefix,currPrefix,gblname,coll,key,key2
+	n namSpc,namSpc2,currNam,currNamLen,i,startMap,midentSize,prevPrevMap,list,mapsublvl,mapisplusplus,nextMap
+	m list=list1
 	s currMap=$o(list("")) q:currMap'="#)" 0
 	s currMap=$o(list(currMap))
 	i currMap="%" s list("$")=list("%")	; if "$" is missing, assign it the same value as "%"
 	e  q:currMap'="$" 0
-	s maxMap=$ztr($zj("",SIZEOF("mident"))," ",$zch(255)),currMap=$o(list(""),-1) q:currMap'=maxMap 0
+	s midentSize=$s(SIZEOF("mident")=8:8,1:SIZEOF("mident")-1)
+	s $zpi(maxMap,$zch(255),midentSize+1)="",currMap=$o(list(""),-1)
+	; In pre-V61 maps, we would have a 32-byte $zch(255) as the final map. But V61 onwards, we have only 31-bytes of $zch(255)
+	; If ever we read a pre-V61 gld file, treat the 32-byte as if it was a 31-byte $zch(255)
+	i currMap'=maxMap i maxMap_$zch(255)=currMap  s list(maxMap)=list(currMap) k list(currMap) s currMap=maxMap
+	i currMap'=maxMap q 0
 	k nams
+	; ----------------------------------------------------------------------------------------------------
+	; Stage 1 : Replace all subscripted global entries in the map with unsubscripted global name entries.
+	; This simplifies processing in later steps. This is in turn divided into sub-stages.
+	;     ------------------------------------------------------------------------------------------------
+	;     Substage (a) : Do some preparatory processing for subscripted map entries.
+	;			1) Calculate the level (# of subscripts) of each map entry.
+	;			2) Note down the map entry based on its level in the "mapsublvl" array.
+	;			3) Note down the ending offset of the map minus the last subscript.
+	;			4) Note down if the map entry is of the ++ form (in the "mapisplusplus" array).
+	;			5) Add a map entry corresponding to the unsubscripted global name if not already present.
+	;		All of these are used in later substages.
+	n mapsublvl
+	s mapsublvl(0)=""	; to be used as a loop terminator later
+	s currMap="" f  s currMap=$o(list(currMap)) q:currMap=""  d
+	. s mapsublvl=$zl(currMap,ZERO)-1
+	. i mapsublvl=0 q
+	. n offset,startoff
+	. s offset=0  f i=1:1:mapsublvl s offset=$zfind(currMap,ZERO,offset) i i=1 s startoff=offset
+	. s mapsublvl(mapsublvl,currMap)=""		; Note down map entries based on their subscript level
+	. s list(currMap,"SUBLEVEL")=mapsublvl		; subscript level of this map entry
+	. s list(currMap,"PRFXOFF")=offset-1		; offset of the prefix which is the map minus the last subscript
+	. s list(currMap,"GBLNAMEOFF")=startoff-2	; ending offset of the unsubscripted global name
+	. s currMapLen=$zl(currMap)
+	. s list(currMap,"MAPLEN")=currMapLen	; length of the full map entry
+	. i $$isplusplus(currMap,currMapLen) s mapisplusplus(mapsublvl,currMap)=""
+	. s gblname=$ze(currMap,1,startoff-2)
+	. i '$d(list(gblname)) s list(gblname)=list($o(list(gblname)))
+	;     ------------------------------------------------------------------------------------------------
+	;     Substage (b) : Process all map entries at the same mapsublvl starting from the highest level.
+	;			Add name entries corresponding to map entries of one level.
+	;			If necessary add map entries of a parent (lower) level as part of removing map entries at one level.
+	;			Also remove any intervals that map to same region and become contiguous due to the above removal.
+	;			Process map entries of the ++ form first. This is easy and once this is done, all we are left
+	;			with are non-++ map entries at a given level and this is much easier to handle.
+	n lvl
+	s lvl="" f  s lvl=$o(mapsublvl(lvl),-1) q:lvl=0  d
+	. ; Case (i) : process ++ entries (if any) at this level first
+	. n map,mapLen
+	. s map="" f  s map=$o(mapisplusplus(lvl,map),-1) q:map=""  d
+	. . s mapLen=list(map,"MAPLEN"),currReg=list(map)
+	. . s gblname=$ze(map,1,list(map,"GBLNAMEOFF")),coll=+$g(gnams(gblname,"COLLATION"))
+	. . s key=$ze(map,1,mapLen-1),namSpc=$view("YGDS2GVN",key_ZERO_ZERO,coll) d add2nams(namSpc,currReg,"POINT")
+	. . i '$d(list(key)) m list(key)=list(map)  s mapsublvl(lvl,key)="",list(key,"MAPLEN")=list(key,"MAPLEN")-1
+	. . e  d
+	. . . ; if we reach here, this means we are going to remove a ++ map entry and did not add anything instead in "list"
+	. . . ; in this case check if the map entries surrounding the ++ entry map to the same region. if so remove the first one
+	. . . d killPrevMapIfPossible(.list,map)
+	. . d killmap(.list,map) ; remove the ++ map entry and associated structures
+	. ; Case (ii) : process non-++ entries (if any) at this level next
+	. n prfxoff1,prfxoff2,parentMap,parentMapLen,offset
+	. n trailingrange	; this indicates whether we need to add a trailing range as part of removing a map entry
+	. s trailingrange=1,map="" f  s map=$o(mapsublvl(lvl,map),-1) q:map=""  d
+	. . s currReg=list(map)
+	. . s gblname=$ze(map,1,list(map,"GBLNAMEOFF")),coll=+$g(gnams(gblname,"COLLATION"))
+	. . i trailingrange d
+	. . . ; Case (iii) : Check if a namespace for the trailing range needs to be added
+	. . . ; e.g. If x(1,2) is the current map entry, check the parent level map entry (i.e. x(1)) to see the region it falls in.
+	. . . ; If the name (not map) x(1) maps to the exact same region as the region following the map entry x(1,2), then there is
+	. . . ; no need to add the trailing namespace since a bigger namespace would get added as part of processing the lower-level
+	. . . ; subscripted map entry x(1). If x(1) maps to a different region, then we need to add the range x(1,2:) so it
+	. . . ; overrides the x(1) namespace that will get added while processing the lower-level subscripted map entry x(1).
+	. . . s nextReg=list($o(list(map))),parentMap=$ze(map,1,list(map,"PRFXOFF")-1),prevReg=list($o(list(parentMap)))
+	. . . i nextReg=prevReg q  ; x(1) and x(1,2:) map to same region
+	. . . ; add range x(1,2:)
+	. . . s mapLen=list(map,"MAPLEN")
+	. . . s key=$ze(map,1,mapLen),namSpc=$view("YGDS2GVN",key_ZERO_ZERO,coll)
+	. . . s nullsub="""""",namSpc=$ze(namSpc,1,$zl(namSpc)-1)_":"_nullsub_")"
+	. . . d add2nams(namSpc,nextReg,"RANGE")
+	. . s prevMap=$o(list(map),-1)
+	. . s prfxoff1=+$g(list(prevMap,"PRFXOFF")),prfxoff2=list(map,"PRFXOFF"),parentMap=$ze(map,1,prfxoff2-1)
+	. . i (prfxoff1=prfxoff2)&($ze(prevMap,1,prfxoff1)=$ze(map,1,prfxoff2)) d  q
+	. . . ; Case (iv) : These are TWO adjacent map entries with different last subscripts (every other subscript identical).
+	. . . ; Can be easily replaced by a RANGE type namespace.
+	. . . ; For example x(1,2) is the current map entry and x(1,1) is the previous map entry.
+	. . . ; Then we can add the name space x(1,1:2) and remove the x(1,2) map entry.
+	. . . ; Similar to the "trailingrange" case, we can check if the parent level map entry maps to same region as the current
+	. . . ; range and if so skip this range altogether.
+	. . . i list($o(list(parentMap)))'=currReg d
+	. . . . s prevMapLen=list(prevMap,"MAPLEN"),namSpc=$view("YGDS2GVN",prevMap_ZERO_ZERO,coll)
+	. . . . n lastSubs
+	. . . . s mapLen=list(map,"MAPLEN"),lastSubs=$ze(map,prfxoff2,mapLen)
+	. . . . s key=gblname_lastSubs,namSpc2=$view("YGDS2GVN",key_ZERO_ZERO,coll)
+	. . . . s namSpc2=$ze(namSpc2,$zl(gblname)+3,$zl(namSpc2)-1) ; extract out the last/ONLY subscript
+	. . . . s namSpc=$ze(namSpc,1,$zl(namSpc)-1)_":"_namSpc2_")"
+	. . . . d add2nams(namSpc,currReg,"RANGE")
+	. . . s trailingrange=0
+	. . . d killmap(.list,map)
+	. . s nextMap=$o(list(map))
+	. . i 'trailingrange  d  i '$d(list(map)) q
+	. . . ; Case (v) : Check if "map" maps to same region as the next map (possible because we skipped the
+	. . . ;            "do killPrevMapIfPossible" call in Case (iv)). If so remove "map".
+	. . . i currReg=list(nextMap) d killmap(.list,map)
+	. . . s trailingrange=1 ; now that we know adjacent map entries cannot be replaced by a RANGE type, set this first
+	. . ; A few cases are possible here.
+	. . ; Case (vi) : The current map is say x(1,2) and the NEXT map is x(1)++. In this case, the map entry x(1)++
+	. . ;             can be removed as it is equivalent to x(1,<max>) (where <max> is the maximum subscript possible)
+	. . ;             and the range x(1,2:) has already been added. In addition IF map entry x(1,2) maps to the same
+	. . ;             region as the map entry AFTER x(1)++, then the map entry x(1,2) can also be removed without adding
+	. . ;             a x(1) namespace. And we can move on to the next iteration. IF not, follow through to Case (vii).
+	. . i $d(mapisplusplus(lvl-1,nextMap))&((parentMap_ONE)=nextMap) d  i '$d(list(map)) q
+	. . . d killPrevMapIfPossible(.list,nextMap) ; this COULD remove list(map)
+	. . . d killmap(.list,nextMap)
+	. . ; Case (vii) : The current map is say x(1,2). The previous map could be x(1) OR could be x(k) where k < 1 or just x
+	. . ;              If previous map is x(1), then we only need to add the NAMESPACE x(1) and delete the MAP x(1,2)
+	. . ;              If previous map is x(k) where k<1 or just x, then add MAP x(1), add NAMESPACE x(1) and delete MAP x(1,2)
+	. . ; As to adding NAMESPACE x(1), similar to the "trailingrange" case, one might be tempted to check if parent level map
+	. . ; entry maps to the same region as x(1) and if so skip this NAMESPACE altogether. But the x(1) name addition is
+	. . ; actually an override to a potential range (e.g. x(0:2) name) at the same level. Therefore dont optimize here.
+	. . i '$d(list(parentMap)) d
+	. . . s list(parentMap)=currReg          ; add MAP x(1)
+	. . . i lvl=1 q
+	. . . s list(parentMap,"SUBLEVEL")=lvl-1,list(parentMap,"MAPLEN")=$zl(parentMap)
+	. . . s list(parentMap,"GBLNAMEOFF")=list(map,"GBLNAMEOFF")
+	. . . s offset=0  f i=1:1:lvl-1 s offset=$zfind(parentMap,ZERO,offset)
+	. . . s list(parentMap,"PRFXOFF")=offset-1
+	. . . s mapsublvl(lvl-1,parentMap)=""    ; complete addition of MAP x(1)
+	. . e  d
+	. . . ; the MAP x(1) already existed and we are about to delete the MAP x(1,2).
+	. . . ; check if the MAP after x(1,2) maps to same region as MAP x(1). If so, MAP x(1) can be removed
+	. . . d killPrevMapIfPossible(.list,map)
+	. . s namSpc=$view("YGDS2GVN",parentMap_ZERO_ZERO,coll)
+	. . d add2nams(namSpc,currReg,"POINT")	; add NAMESPACE x(1)
+	. . d killmap(.list,map)		; delete MAP x(1,2)
+	; ------------------------------------------------------------------------------
+	; Stage 2 : Replace all unsubscripted map entries having ")" at the end (e.g. "abc)") with entries not having the ")".
+	;		Also remove any intervals that map to same region and become contiguous due to the above removal.
+	; This simplifies processing in later steps.
+	s currMap=maxMap,nextReg=""
+	f  q:currMap="$"  s prevMap=$o(list(currMap),-1) d  s currMap=prevMap,nextReg=currReg
+	. s currReg=list(currMap)
+	. i currReg=nextReg k list(currMap)
+	. ; If currMap contains ")" (e.g. "abc)"), it means one of two possibilities.
+	. ;	a) prevMap is "abc". In this case, just add name "abc" (assuming it was not already added in previous stages)
+	. ;		And delete the "abc)" map entry from later processing.
+	. ; 	b) prevMap is not "abc". In this case, add name "abc" (assuming it was not already added in previous stages)
+	. ;		In addition, replace the "abc)" map entry with "abc" for later processing.
+	. s currMapLen=$zl(currMap)
+	. i $ze(currMap,currMapLen)'=")" q
+	. s namSpc=$ze(currMap,1,currMapLen-1)
+	. i '$d(nams(namSpc)) s nams(namSpc)=currReg
+	. k list(currMap)
+	. i prevMap'=namSpc s list(namSpc)=currReg q
+	. ; if we reach here, this means we removed a ")" map entry and did not add anything instead in "list"
+	. ; so update "currReg" to correspond to next map (the map entry we processed in the previous for loop iteration)
+	. s currReg=nextReg
+	; ------------------------------------------------------------------------------
+	; Stage 3 : Now that unsubscripted namespaces are out of the way, add * namespaces as applicable
+	s currMap=maxMap
 	f  q:currMap="$"  s prevMap=$o(list(currMap),-1) d  s currMap=prevMap
 	. s currReg=list(currMap)
-	. ; Note that with the above mapping, all keys in the range [prevMap,currMap) are mapped to currReg.
-	. ;	where [ denotes closed interval and ) denotes open interval i.e. prevMap <= key < currMap
-	. ; Case (1a) : If currMap contains ")" (e.g. "abc)"), it most likely means prevMap would be "abc".
-	. ;		In this case, just add "abc" as a namespace. No more processing needed for currMap.
-	. ; Case (1b) : But it is also possible prevMap is not "abc".
-	. ;		In this case, do the "abc" namespace addition (as if prevMap was "abc").
-	. ;		But also proceed with the current iteration of the for loop as if "currMap" was "abc".
 	. s currMapLen=$zl(currMap)
-	. i $ze(currMap,currMapLen)=")" d  q:prevMap=namSpc
-	. . s namSpc=$ze(currMap,1,currMapLen-1),nams(namSpc)=currReg
-	. . i prevMap'=namSpc s currMap=namSpc,currMapLen=currMapLen-1
-	. ; Case (3) : If prevMap contains ")" (e.g. "abc)"), then check to see if its previous entry (say prevPrevMap)
-	. ; is the same region as currReg. If so, we can coalesce the entire range [prevPrevMap,currMap) into one with the
-	. ; exception of "abc" for which add an explicit namespace. Do this for as many ")" prevMap entries that you can find
-	. ; as long as its prevPrevMap entry is the same region as currReg. This could potentially coalesce a lot of intervals.
-	. ; Note: Need to handle a situation like Case (1b) here too. We do this by keeping prevMap as it is but adjusting
-	. ; just prevMapLen to be 1 byte less (to remove trailing ")").
-	. s stopLoop=0
-	. f  d  q:stopLoop
-	. . s prevMapLen=$zl(prevMap)
-	. . i $ze(prevMap,prevMapLen)'=")" s stopLoop=1 q
-	. . s namSpc=$ze(prevMap,1,$i(prevMapLen,-1))
-	. . s prevPrevMap=$o(list(prevMap),-1)
-	. . i prevPrevMap'=namSpc  s stopLoop=1 q
-	. . s nams(namSpc)=list(prevMap)
-	. . i list(prevMap)'=currReg s stopLoop=1 q
-	. . s prevMap=$o(list(prevMap),-1)
-	. . i prevMap="$" s stoploop=1,prevMapLen=1 q
-	. ; Note: At this point prevMap could contain a trailing ")" but in that case prevMapLen would have been adjusted to
-	. ; not consider that last byte. As long as all following usages of prevMap are of the form $ze(prevMap,1,prevMapLen)
-	. ; we will never see the ")" in prevMap.
-	. ; Case (4) : The map entry "currMap" exists and "prevMap" is the previous map entry.
+	. s prevMapLen=$zl(prevMap)
+	. i (currMap=maxMap)&(prevMap="$") q  ; "$" and maxMap are mapped to same region. Skip processing
+	. ; The map entry "currMap" exists and "prevMap" is the previous map entry.
 	. ; Determine the namespaces that potentially lie between the two map entries.
 	. ; And add them to the "nams" array.
 	. f i=1:1:currMapLen  i $ze(currMap,i)'=$ze(prevMap,i) q
 	. s matchLen=i-1  ; the length of the maximal common prefix between prevMap and currMap
-	. ; Subcase (4a) : matchLen == prevMapLen
+	. ; Case (3a) : matchLen == prevMapLen
 	. ;	In this case we are guaranteed that prevMapLen < currMapLen, and we need to add only ONE namespace.
 	. ;	Example prevMap="ag", currMap="agk". Here, matchLen=2, prevMapLen=2, currMapLen=3. Add only "ag*".
 	. i (matchLen=prevMapLen)&(prevMapLen<currMapLen) s namSpc=$ze(prevMap,1,prevMapLen)_"*",nams(namSpc)=currReg q
-	. ; Subcase (4b) : matchLen < prevMapLen
-	. ;	Again we are guaranteed that matchLen < currMapLen.
+	. ; Case (3b) : matchLen < prevMapLen
 	. ;	Example prevMap="agxy", currMap="ajk". Here, matchLen=1, prevMapLen=4, currMapLen=3
 	. ;	In this case, we need to add namespace for "aj*", "ai*", "ah*" as a first step.
 	. ;	Whether or not we can add "ag*" depends on an optimization check explained below.
@@ -98,7 +233,6 @@ MAP2NAM(list)
 	. ;		If not, then we need to add one or more smaller namespaces under "ag" explained below as the SECOND PART.
 	. ;	To explain the optimization check, let us say the "list" variable contains the following.
 	. ;		list("ag")="DEFAULT"
-	. ;		list("ag)")="STAR2"
 	. ;		list("agQ")="STAR1"
 	. ;		.
 	. ;		.
@@ -107,16 +241,15 @@ MAP2NAM(list)
 	. ;		list("ajk")="STAR1"	<-- currMap points here
 	. ;	Let us say currMap = "ajk". So prevMap = "agxy". In this case, we would definitely add "aj*", "ai*" and "ah*".
 	. ;	To determine whether we need to add "ag*", we take a look at where the start of "ag*" namespace maps to.
-	. ;	And that would be the entry following list("ag") i.e. list("ag)"). This maps to STAR2 but since it is a point
-	. ;	mapping (no * specification), we can skip that as an exception. The next entry list("agQ") maps to STAR1 region.
+	. ;	And that would be the entry following list("ag") i.e. list("agQ"). This maps to the STAR1 region.
 	. ;	Since this is the same region as the region of currMap, we can safely add just one namespace "ag*" to cover
 	. ;	the entire range from list("ag)") to list("ajk") with entries in between covering sub-namespaces that are
 	. ;	exceptions (i.e. those which dont map to STAR1). If list("agQ") maps to a region other than STAR1, we need to
 	. ;	add more sub-namespaces under the "ag*" namespace which is explained in the SECOND PART below.
 	. ;	The FIRST PART of adding "aj*", "ai*" and "ah*" is taken care of by the simple for loop below.
 	. ;	There is one exception though.
-	. ;		a) If prevMap="ER1" and currMap="ER2", matchLen=2, prevMapLen=3, currMapLen=3
-	. ;		   But we should not add the "ER2*" namespace.
+	. ;		a) If prevMap="XY1" and currMap="XY2", matchLen=2, prevMapLen=3, currMapLen=3
+	. ;		   But we should not add the "XY2*" namespace.
 	. ;		   This is achieved by the "i<currMapLen" check before the for loop.
 	. i currMap=maxMap s currMapLen=1,currMap=$zch(1+$za("z")) ; needed to help lexPrev call return "z"
 	. s prevPrefix=$ze(prevMap,1,i),currPrefix=$ze(currMap,1,i)
@@ -127,73 +260,201 @@ MAP2NAM(list)
 	. . s namSpc=currPrefix_"*",nams(namSpc)=currReg
 	. ;	Do the optimization check.
 	. s currPrefix=prevPrefix  ; reset currPrefix to be equal to prevPrefix just in case it is ""
-	. s startMap=$$findStartMap(currPrefix)
+	. s startMap=$o(list(currPrefix))
 	. i list(startMap)=currReg  s i=prevMapLen  ; set i to force skip of SECOND PART of processing below.
 	. ;	The SECOND PART does the additional "ag" specific processing. Since the stop point is "agxy", we need to add
 	. ;	namespaces "agz*", "agy*" first. And then by the same reasoning (for not adding "ag*" in the FIRST PART),
 	. ;	we cannot add "agx*" unless the optimization check says it is okay to do so. Assuming it says that is not okay,
 	. ;	we go further down by adding "agxz*" and then "agxy*" and then stop.
-	. f  s i=i+1  q:i>prevMapLen  d
+	. f  q:$i(i)>prevMapLen  d
 	. . s currPrefix=prevPrefix_"z",prevPrefix=$ze(prevMap,1,i)
 	. . f  q:currPrefix=prevPrefix  s namSpc=currPrefix_"*",nams(namSpc)=currReg,currPrefix=$$lexprev(currPrefix)
 	. . ; Do optimization check at each sub-namespaces level. If it succeeds, stop processing any higher level sub-namespaces.
-	. . s startMap=$$findStartMap(currPrefix)
+	. . s startMap=$o(list(currPrefix))
 	. . i list(startMap)=currReg  s i=prevMapLen  q  ; set i to force quit out of for loop
 	. s namSpc=currPrefix_"*",nams(namSpc)=currReg
-	; Update "nams" variable to contain # of elements in "nams" array
-	; Take this opportunity to remove redundant namespaces.
+	; ------------------------------------------------------------------------------
+	; Stage 4 : Remove redundant unsubscripted namespaces. As for subscripted namespaces, we are guaranteed they are not
+	; 	redundant because of the way Stage 1 processed them.
 	; Example : If "a*" and "ab*" both map to the same region, the namespace "ab*" can be safely removed.
 	; But if "a*" maps to AREG, "aa*" maps to BREG, and "aaa*" maps to AREG, we cannot remove "aaa*" because
 	; "a*" and "aaa*" maps to the same reg. This is because there is a more restrictive mapping "aa*" which
 	; maps to a different region than "aaa*". That should prevail.
 	; Similarly if "ab*" and "abc" both map to the same region, the namespace "abc" can be safely removed.
 	; But if "abc*" also is mapped and to a different region than "abc", then "abc" cannot be removed.
-	s currNam="",nams=0
 	; With SIZEOF("mident")=32, we allow a max of 31-byte global name specifications.
 	; But with SIZEOF("mident")=8 (for older versions with no longnames support, we allow a max of 8-byte global names.
 	; Handle this 1-byte discrepancy for the 8-byte case by setting the variable midentSize accordingly.
 	s midentSize=$s(SIZEOF("mident")=8:9,1:SIZEOF("mident"))
+	n starName
 	s nams("*")=list("$")
+	; Also take this opportunity to update "nams" variable to contain # of elements in "nams" array
+	s currNam="",nams=0
 	f  s currNam=$o(nams(currNam)) q:currNam=""  s nams=nams+1  d
+	. i (+$g(nams(currNam,"NSUBS"))) q  ; subscripted namespace; dont try to optimize
 	. s currNamLen=$zl(currNam)
 	. s currReg=nams(currNam)
-	. s killed=0,quitLoop=0
-	. f i=$s($ze(currNam,currNamLen)="*":(currNamLen-2),1:currNamLen):-1:0  d  q:quitLoop
+	. s killed=0,quitLoop=0,starName=($ze(currNam,currNamLen)="*")
+	. ; If processing a non-"*" name that is already at the max gvname length, remove corresponding "*" name if any exists
+	. ; with the same long name. This is because the non-"*" name overrides the "*" name at the max length (no
+	. ; other names are possible other than the max length name).
+	. i ('starName&(currNamLen=(midentSize-1))&($d(nams(currNam_"*")))) k nams(currNam_"*")
+	. f i=$s(starName:(currNamLen-2),1:currNamLen):-1:0  d  i (""'=prevReg) s:currReg=prevReg nams=nams-1,killed=1 q
 	. . s currPrefix=$ze(currNam,1,i)_"*"
 	. . s prevReg=$g(nams(currPrefix))
-	. . i (""'=prevReg) d
-	. . . s quitLoop=1
-	. . . i currReg=prevReg k nams(currNam) s nams=nams-1,killed=1
-	. i 'killed,currNamLen'<midentSize k nams(currNam)  s nams($ze(currNam,1,midentSize-1))=currReg
+	. k:killed nams(currNam)
+	. ; Replace namespaces of the form "...*" where ... is 31 characters long (max-mident) with the "*" removed.
+	. i 'killed,currNamLen'<midentSize k nams(currNam) s nams($ze(currNam,1,midentSize-1))=currReg
 	; Do some final cleanup
 	s nams("#")=list("#)"),nams=nams+1
 	q 1
 ;----------------------------------------------------------------------------------------------------------------------------------
+add2nams:(nam,reg,type)
+	; add a subscripted namespace to "nams" array
+	n nsubs,len,c,quotestate,start,i,isrange,gvnprefixoff
+	s nsubs=0,len=$zl(nam),start=1,quotestate=0,nam=$ze(nam,2,len)	; remove "^" from beginning of "nam"
+	i $d(nams(nam)) q  ; some lower level processing has already creating this name with a region mapping; dont override it
+	s nams(nam)=reg
+	s nams(nam,"NAME")=nam
+	s nams(nam,"TYPE")=type
+	s isrange=(type="RANGE")
+	f i=1:1:len  d
+	. s c=$ze(nam,i)
+	. i c="""" s quotestate=$s(quotestate=1:2,1:1)
+	. e        s quotestate=$s(quotestate=2:0,1:quotestate) i 'quotestate d
+	. . i ((c="(")!(c=",")!(c=")")!(isrange&(c=":"))) d
+	. . . s nams(nam,"SUBS",nsubs)=$ze(nam,start,i-1),nsubs=nsubs+1,start=i+1
+	. . . i (isrange&((c=",")!(c="("))) s gvnprefixoff=i
+	i isrange s nams(nam,"GVNPREFIX")=$ze(nam,1,gvnprefixoff)
+	s nams(nam,"NSUBS")=$s(nsubs=0:0,1:nsubs-1)
+	q
+killPrevMapIfPossible(list,map)
+	; checks previous and next map entry of input "map". if they map to same region then removes "previous" map entry.
+	; this assumes the input "map" entry is going to be removed after this call.
+	n nextReg,prevReg,prevMap
+	s prevMap=$o(list(map),-1)
+	s nextReg=list($o(list(map))),prevReg=list(prevMap)
+	i nextReg'=prevReg q
+	d killmap(.list,prevMap)
+	q
+killmap(list,map)
+	n lvl
+	s lvl=+$g(list(map,"SUBLEVEL"))
+	k list(map),mapsublvl(lvl,map)
+	k mapisplusplus(lvl,map) ; this node may not exist but kill of non-existent data works fine so do it always.
+	q
 lexins:(s)
-	n x,l
-	i s["*" s l=$zl(s)
-	e       s l=0
+	; Insert names into "lexnams" array.
+	; * names go into lexnams(N,...) where N > 0 and N is the byte length of the name including the *
+	; Amongst the non-* names, unsubscripted names go into lexnams(N,...) where N = 0
+	; Amongst the non-* names, subscripted names go into lexnams(N,...) where N < 0 and N is the # of subscripts
+	;	Within subscripted names with the same # of subscripts, we want to process ranges ahead of points
+	;	Hence the isrange-(subslvl*2) calculation below.
+	; This lets us process the names in that order (N>0 first, N=0 next, N=-1,-2,... last) later in the caller function.
+	; That order is important to ensure correct mappings of names.
+	n l,isrange,subslvl
+	; if range subscript, "NSUBS" node is actually 1 more than the subscript level (# of commas).
+	s isrange=($g(nams(s,"TYPE"))="RANGE"),subslvl=$g(nams(s,"NSUBS"))-isrange
+	; check for subscripted name first; check for * in name afterwards; doing it the other way could give false results
+	; since it is possible for * to be inside a string subscript
+	s l=$s(s["(":isrange-(subslvl*2),s["*":$zl(s),1:0)
 	s lexnams(l,s)=nams(s)
 	q
-showstar:(i)
+starins:(i)
+	n j,s,reg,next
 	s j=""
-	f  s j=$o(lexnams(i,j),-1) q:'$zl(j)  d starins($ze(j,1,$zl(j)-1),lexnams(i,j))
-	q
-starins:(s,reg)
-	n next
-	s next=$$lexnext(s)
-	i $zl(next),'$d(map(next)) s map(next)=map($o(map(next),-1))
-	s map(s)=reg
+	f  s j=$o(lexnams(i,j),-1) q:'$zl(j)  d
+	. s s=$ze(j,1,$zl(j)-1)
+	. s reg=lexnams(i,j)
+	. s next=$$lexnext(s)
+	. i $zl(next),'$d(map(next)) s map(next)=map($o(map(next),-1))
+	. s map(s)=reg
 	q
 pointins:(s,reg)
-	n next
-	s next=$$alphnext(s)
-	i $zl(next),'$d(map(next)) s map(next)=map($o(map(next),-1))
-	s map(s)=reg
+	n keylo,keyhi,nsubs,hasrange,gblname,coll
+	s hasrange=($g(nams(s,"TYPE"))="RANGE")
+	s nsubs=+$g(nams(s,"NSUBS"))
+	i 'hasrange d
+	. ; is a point specification
+	. ;	e.g. X    -> In this case X and X) are the bounding points
+	. ;	e.g. X(1) -> In this case X(1) and X(1)++ are the bounding points
+	. ;		where ++ denotes the immediately "next" valid key (byte sequence)
+	. i 'nsubs s keylo=s,keyhi=$$alphnext(s)
+	. e  d
+	. . ; For a subscripted gvn, the next key is obtained by appending a 0x01 byte at the very end (before the two null bytes)
+	. . ; Such a key is referred to be in the ++ form.
+	. . ; For a numeric subscript, we are guaranteed, 0x01 is never present (as it means the mantissa was 00 which would
+	. . ; 	actually have been ignored during subscript representation).
+	. . ; For a string subscript, it is possible to have 0x01 in the middle of the subscript representation. But in that
+	. . ;	case we expect the 0x01 to be followed by a 0x01 or 0x02 (indicating 0x00 or 0x01 bytes in the original string
+	. . ;	subscript). So if we see a 0x01 at the end of the subscript we need to scan back until we dont see a 0x01 and
+	. . ;	determine if the 0x01 run length is odd or even and accordingly decide if the last 0x01 is a lone byte or not.
+	. . ;	If it is a lone byte, it means this was added as part of the "next" key determination in pointins.
+	. . ;	There are two exceptions to this and that is
+	. . ;		a) if 0x01 run length is 1 and the immediately preceding byte is 0x00.
+	. . ;			In this case, this corresponds to the null ("") string subscript.
+	. . ;		b) if 0x01 run length is 2 and the immediately preceding byte is 0x00.
+	. . ;			In this case, this is a ++ form key (++ of the "" null subscript)
+	. . ; This logic will be used in MAP2NAM.
+	. . s gblname=nams(s,"SUBS",0),coll=+$g(gnams(gblname,"COLLATION"))
+	. . s keylo=$$gvn2gdsnotrailingnulls("^"_s,coll),keyhi=keylo_$zch(1)
+	. i $zl(keyhi),'$d(map(keyhi)) s map(keyhi)=map($o(map(keyhi),-1))
+	e  d
+	. ; is a range specification
+	. ;	e.g. X(1:"abc")      -> In this case X(1) and X("abc") are the bounding points
+	. ;	e.g. X("":"")        -> In this case X("") and X) are the bounding points
+	. ;	e.g. X(2,"":"")      -> In this case X(2,"") and X(2)++ are the bounding points
+	. ;	e.g. X("abc","z":"") -> In this case X("abc","z") and X("abc")++ are the bounding points
+	. ;		where ++ denotes the immediately "next" valid key (byte sequence)
+	. n range,rangelo,rangehi,rlo,rhi,nullsub
+	. s rlo=nams(s,"SUBS",nsubs-1),rhi=nams(s,"SUBS",nsubs)
+	. s nsubs=nams(s,"NSUBS"),range=nams(s,"GVNPREFIX")
+	. s gblname=nams(s,"SUBS",0),coll=+$g(gnams(gblname,"COLLATION"))
+	. s rangelo="^"_range_rlo_")",keylo=$$gvn2gdsnotrailingnulls(rangelo,coll)
+	. s nullsub=""""""
+	. i (rhi'=nullsub) d
+	. . s rangehi="^"_range_rhi_")",keyhi=$$gvn2gdsnotrailingnulls(rangehi,coll)
+	. e  d
+	. . ; if "" is right side of range, this is equivalent to the "next" parent level subscript.
+	. . ; use that to construct the subscript level representation as that is easier than trying
+	. . ; to represent the max-possible-key at this level (using a sequence of 1019 0xFFs or so)
+	. . n gvn
+	. . i nsubs=2 s keyhi=$$alphnext(gblname) ; special case in case range is at FIRST subscript level
+	. . e  s gvn="^"_$ze(range,1,$zl(range)-1)_")",keyhi=$$gvn2gdsnotrailingnulls(gvn,coll),keyhi=keyhi_$zch(1)
+	. i $zl(keyhi),'$d(map(keyhi)) d
+	. . n prevMap
+	. . s prevMap=$o(map(keyhi),-1)
+	. . s map(keyhi)=map(prevMap)
+	. . ; check for sub-range and if so adjust mapping region of previous map entry accordingly
+	. . i (prevMap]keylo) s map(prevMap)=reg
+	s map(keylo)=reg
+	q
+gvn2gds(gvn,coll)
+	; return subscript (gds) representation for input "gvn".
+	; checks for GVSUBOFLOW error and if so issues GDE-specific GVSUBOFLOW error
+	n key
+	n savetrap
+	s savetrap=$etrap
+	n $etrap
+	s $etrap="goto gvsuboflowerr"
+	s key=$view("YGVN2GDS",gvn,coll)
+	q key
+gvsuboflowerr
+	n len
+	i $zstatus'["GVSUBOFLOW" q  ; dont know how a non-GVSUBOFLOW error occured. let parent frame handle it like any other error
+	s $ecode="",len=$zl(gvn)
+	s $etrap=savetrap
+	; Do not attempt to print the full "gvn" value as it might exceed the buffer allocated by zmessage.
+	; So print first 100 bytes and last 100 bytes with a "..." in between
+	zm gdeerr("NAMGVSUBOFLOW"):$ze(gvn,2,100):$ze(gvn,len-100,len):coll	; 2 (instead of 1) to skip ^ at start of gvn
 	q
+gvn2gdsnotrailingnulls:(gvn,coll)
+	; return subscript (gds) representation for input "gvn". Removes trailing double null-byte
+	n key
+	s key=$$gvn2gds(gvn,coll)
+	q $ze(key,1,$zl(key)-2)
 alphnext:(s)
-	i $zl(s)=MAXNAMLN q $$lexnext(s)
-	e  q s_")"
+	q $s($zl(s)=MAXNAMLN:$$lexnext(s),1:s_")")
 	;
 lexnext:(s)
 	n len,last,succ
@@ -206,16 +467,146 @@ lexnext:(s)
 	i "a"]succ q s_"a"
 	q ""
 lexprev:(s)
-	n len,last,prio
+	n len,last,prior
 	s len=$zl(s),last=$ze(s,len)
-	s s=$ze(s,1,len-1),prio=$zch($za(last)-1)
-	i prio?1AN q s_prio
-	i prio]"Z" q s_"Z"
-	i prio]"9" q:len=1 "%" q s_"9"
+	s s=$ze(s,1,len-1),prior=$zch($za(last)-1)
+	i prior?1AN q s_prior
+	i prior]"Z" q s_"Z"
+	i prior]"9" q:len=1 "%" q s_"9"
 	q ""
-findStartMap:(key)
-	n startMap
-	s startMap=$o(list(key))
-	s startMapLen=$zl(startMap)
-	i ($ze(startMap,startMapLen)=")")&($ze(startMap,1,startMapLen-1)=key) s startMap=$o(list(startMap))
-	q startMap
+setinbetween(keylo1,keylo2,keyhi1,keyhi2,keylo1inbetween,keyhi1inbetween)
+	; Allow sub-ranges (i.e. a smaller range completely inside a bigger range) but not allow overlapping ranges.
+	; An easy check for this is IF
+	;	(a) keylo1 and keyhi1 are both in between keylo2 and keyhi2 OR
+	;	(b) keylo1 and keyhi1 are both NOT in between keylo2 and keyhi2
+	; In this case we allow. If not, we dont allow this range.
+	s keylo1inbetween=((keylo1=keylo2)!(keylo1]keylo2))&(keyhi2]keylo1)
+	s keyhi1inbetween=(keyhi1]keylo2)&((keyhi1=keyhi2)!(keyhi2]keyhi1))
+	; adjust keylo1inbetween and keyhi1inbetween to take into account a few edge cases
+	i (keylo1=keylo2) s keylo1inbetween=$s((keyhi1]keyhi2):0,1:1),keyhi1inbetween=keylo1inbetween
+	i (keyhi1=keyhi2) s keylo1inbetween=$s((keylo1]keylo2):1,1:0),keyhi1inbetween=keylo1inbetween
+	q
+namcoalesce
+	n quitLoop,coll,nam1,nam2,namnew,keylo1,keylo2,keyhi1,keyhi2,keylo1inbetween,keyhi1inbetween,prefix,nsubs2,nsubs1
+	n tmpnam1,tmpnam2,range
+	; ASSERT : i '$d(namrangeoverlap)  zsh "*"  h
+	s nam1=""
+	f  s nam1=$o(namrangeoverlap(nam1))  q:nam1=""  d  i quitLoop s nam1=""
+	. s nam2=nam1
+	. s quitLoop=0
+	. s coll=+$g(gnams(nams(nam1,"SUBS",0),"COLLATION"))
+	. f  s nam2=$o(namrangeoverlap(nam2))  q:nam2=""  d  q:quitLoop
+	. . ; if subscripts dont match before the range, there is no chance of a range overlap issue
+	. . s range=nams(nam1,"GVNPREFIX") i range'=nams(nam2,"GVNPREFIX") q
+	. . ; Below code is similar to "namerangeoverlapcheck2^GDEPARSE". See there for comments
+	. . m tmpnam1=nams(nam1) s tmpnam1=nams(nam1)
+	. . m tmpnam2=nams(nam2) s tmpnam2=nams(nam2)
+	. . d getrangelohikey^GDEPARSE(.tmpnam1,.keylo1,.keyhi1,coll,range)
+	. . d getrangelohikey^GDEPARSE(.tmpnam2,.keylo2,.keyhi2,coll,range)
+	. . d setinbetween(keylo1,keylo2,keyhi1,keyhi2,.keylo1inbetween,.keyhi1inbetween)
+	. . ; the above sets keylo1inbetween and keyhi1inbetween
+	. . ; first check overlap case
+	. . s prefix=nams(nam1,"GVNPREFIX"),nsubs1=nams(nam1,"NSUBS"),nsubs2=nams(nam2,"NSUBS")
+	. . i (keylo1inbetween'=keyhi1inbetween) d
+	. . . ; we are guaranteed both nam1 and nam2 map to same region or else NAMRANGEOVERLAP error would have been issued before
+	. . . ; ASSERT : i nams(nam1)'=nams(nam2)  zsh "*"  h
+	. . . s quitLoop=1
+	. . . ; this is a case of overlapping ranges where both ranges map to same region.
+	. . . ; create a new super-range that encompasses both overlapping ranges
+	. . . i keylo1inbetween d
+	. . . . ; merge the ranges [keylo1,keyhi1] and [keylo2,keyhi2] into one super-range [keylo2,keyhi1]
+	. . . . s namnew=prefix_nams(nam2,"SUBS",nsubs2-1)_":"_nams(nam1,"SUBS",nsubs1)_")"
+	. . . . d add2nams("^"_namnew,nams(nam1),"RANGE")
+	. . . . s namrangeoverlap(namnew)=""
+	. . . e  d
+	. . . . ; merge the ranges [keylo1,keyhi1] and [keylo2,keyhi2] into one super-range [keylo1,keyhi2]
+	. . . . s namnew=prefix_nams(nam1,"SUBS",nsubs1-1)_":"_nams(nam2,"SUBS",nsubs2)_")"
+	. . . . d add2nams("^"_namnew,nams(nam1),"RANGE")
+	. . . . s namrangeoverlap(namnew)=""
+	. . . k nams(nam1),namrangeoverlap(nam1)
+	. . . k nams(nam2),namrangeoverlap(nam2)
+	. . ; next check if [keylo1,keyhi1] is completely inside [keylo2,keyhi2]
+	. . e  i (keylo1inbetween) d
+	. . . s quitLoop=1
+	. . . ; keylo1 and keyhi1 are both in between keylo2 and keyhi2
+	. . . ; i.e. [keylo1,keyhi1] lies completely inside [keylo2,keyhi2]
+	. . . i nams(nam1)=nams(nam2) d
+	. . . . ; a sub-range lies completely inside a super-range and both map to same region
+	. . . . ; safely delete the sub-range
+	. . . . k nams(nam1),namrangeoverlap(nam1)
+	. . . e  d
+	. . . . ; a sub-range lies completely inside a super-range and both map to different regions
+	. . . . ; split range [keylo2,keyhi2] into two sub-ranges [keylo2,keylo1] and [keyhi1,keyhi2]
+	. . . . ; create range [keylo2,keylo1]
+	. . . . i keylo2'=keylo1 d
+	. . . . . s namnew=prefix_nams(nam2,"SUBS",nsubs2-1)_":"_nams(nam1,"SUBS",nsubs1-1)_")"
+	. . . . . d add2nams("^"_namnew,nams(nam2),"RANGE")
+	. . . . . s namrangeoverlap(namnew)=""
+	. . . . ; create range [keyhi1,keyhi2]
+	. . . . i keyhi1'=keyhi2 d
+	. . . . . s namnew=prefix_nams(nam1,"SUBS",nsubs1)_":"_nams(nam2,"SUBS",nsubs2)_")"
+	. . . . . d add2nams("^"_namnew,nams(nam2),"RANGE")
+	. . . . . s namrangeoverlap(namnew)=""
+	. . . . ; kill   range [keylo2,keyhi2]
+	. . . . k nams(nam2),namrangeoverlap(nam2)
+	. . ; next check if [keylo2,keyhi2] is completely inside [keylo1,keyhi1]
+	. . e  i ((keylo2=keylo1)!(keylo2]keylo1))&(keyhi1]keylo2) d
+	. . . i nams(nam1)=nams(nam2) d
+	. . . . ; a sub-range lies completely inside a super-range and both map to same region
+	. . . . ; safely delete the sub-range
+	. . . . k nams(nam2),namrangeoverlap(nam2)
+	. . . . ; since only nam2 is killed, and nam1 is untouched, continue in the nam2 loop (i.e. dont set quitLoop to 1)
+	. . . e  d
+	. . . . ; a sub-range lies completely inside a super-range and both map to different regions
+	. . . . ; split range [keylo1,keyhi1] into two sub-ranges [keylo1,keylo2] and [keyhi2,keyhi1]
+	. . . . ; create range [keylo1,keylo2]
+	. . . . i keylo1'=keylo2 d
+	. . . . . s namnew=prefix_nams(nam1,"SUBS",nsubs1-1)_":"_nams(nam2,"SUBS",nsubs2-1)_")"
+	. . . . . d add2nams("^"_namnew,nams(nam1),"RANGE")
+	. . . . . s namrangeoverlap(namnew)=""
+	. . . . ; create range [keyhi2,keyhi1]
+	. . . . i keyhi2'=keyhi1 d
+	. . . . . s namnew=prefix_nams(nam2,"SUBS",nsubs2)_":"_nams(nam1,"SUBS",nsubs1)_")"
+	. . . . . d add2nams("^"_namnew,nams(nam1),"RANGE")
+	. . . . . s namrangeoverlap(namnew)=""
+	. . . . ; kill   range [keylo1,keyhi1]
+	. . . . k nams(nam1),namrangeoverlap(nam1)
+	. . . . s quitLoop=1
+	. . ; next check if [keylo1,keyhi1] is immediately followed by [keylo2,keyhi2] and map to same region
+	. . ; in this case merge the two into one super-range [keylo1,keyhi2]
+	. . e  i (keyhi1=keylo2)&(nams(nam1)=nams(nam2)) d
+	. . . s quitLoop=1
+	. . . ; create range [keylo1,keyhi2]
+	. . . s namnew=prefix_nams(nam1,"SUBS",nsubs1-1)_":"_nams(nam2,"SUBS",nsubs2)_")"
+	. . . d add2nams("^"_namnew,nams(nam1),"RANGE")
+	. . . s namrangeoverlap(namnew)=""
+	. . . ; kill range   [keylo1,keyhi1]
+	. . . k nams(nam1),namrangeoverlap(nam1)
+	. . . ; kill range   [keylo2,keyhi2]
+	. . . k nams(nam2),namrangeoverlap(nam2)
+	. . ; next check if [keylo2,keyhi2] is immediately followed by [keylo1,keyhi1] and map to same region
+	. . ; in this case merge the two into one super-range [keylo2,keyhi1]
+	. . e  i (keyhi2=keylo1)&(nams(nam1)=nams(nam2)) d
+	. . . s quitLoop=1
+	. . . ; create range [keylo2,keyhi1]
+	. . . s namnew=prefix_nams(nam2,"SUBS",nsubs2-1)_":"_nams(nam1,"SUBS",nsubs1)_")"
+	. . . d add2nams("^"_namnew,nams(nam2),"RANGE")
+	. . . s namrangeoverlap(namnew)=""
+	. . . ; kill range   [keylo2,keyhi2]
+	. . . k nams(nam2),namrangeoverlap(nam2)
+	. . . ; kill range   [keylo1,keyhi1]
+	. . . k nams(nam1),namrangeoverlap(nam1)
+	k namrangeoverlap  ; now that all sub-ranges and/or overlapping range coalesces have been automatically taken care of
+	q
+isplusplus(currMap,currMapLen)
+	n c,i
+	; currMap should be a map entry corresponding to a subscripted name (i.e. contain ZERO in it)
+	; Now that we know this is a subscripted gvn, check if the last subscript is of the ++ form.
+	; At a high level, this is the case if the last byte is 0x01. But there is more to it which can be
+	; found in a comment below (search for MAP2NAM in a comment above that also mentions the ++ form).
+	f i=currMapLen:-1:1 s c=$ze(currMap,i) q:c'=ONE
+	s i=(currMapLen-i)
+	; cases for the $s below are "", ""++, 0x01 0x01 byte sequence in a string subscript, unpaired 0x01 at end of subscript
+	; if c=ZERO, then i is guaranteed to be either 1 or 2, nothing more. (1 implies "", 2 implies ""++)
+	q $s((c=ZERO):$s((1=i):0,1:1),(0=(i#2)):0,1:1)
+	q
diff --git a/sr_port/gdemsgin.m b/sr_port/gdemsgin.m
index 72caec7..642dc2b 100644
--- a/sr_port/gdemsgin.m
+++ b/sr_port/gdemsgin.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -20,9 +20,8 @@ GDEMSGIN
 	s gdeerr("GDUSEDEFS")=150503491
 	s gdeerr("ILLCHAR")=150503498
 	s gdeerr("INPINTEG")=150503506
-	s gdeerr("KEYSIZIS")=150503523
 	s gdeerr("KEYTOOBIG")=150503515
-	s gdeerr("KEYFORBLK")=150503891
+	s gdeerr("KEYSIZIS")=150503523
 	s gdeerr("KEYWRDAMB")=150503530
 	s gdeerr("KEYWRDBAD")=150503538
 	s gdeerr("LOADGD")=150503547
@@ -31,13 +30,13 @@ GDEMSGIN
 	s gdeerr("LVSTARALON")=150503570
 	s gdeerr("MAPBAD")=150503579
 	s gdeerr("MAPDUP")=150503587
-	s gdeerr("NAMSTARTBAD")=150503594
+	s gdeerr("NAMENDBAD")=150503594
 	s gdeerr("NOACTION")=150503603
 	s gdeerr("RPAREN")=150503610
 	s gdeerr("NOEXIT")=150503619
 	s gdeerr("NOLOG")=150503627
-	s gdeerr("NONEGATE")=150503642
 	s gdeerr("NOVALUE")=150503634
+	s gdeerr("NONEGATE")=150503642
 	s gdeerr("OBJDUP")=150503650
 	s gdeerr("OBJNOTADD")=150503658
 	s gdeerr("OBJNOTCHG")=150503666
@@ -47,8 +46,8 @@ GDEMSGIN
 	s gdeerr("QUALBAD")=150503698
 	s gdeerr("QUALDUP")=150503706
 	s gdeerr("QUALREQD")=150503714
-	s gdeerr("RECSIZIS")=150503731
 	s gdeerr("RECTOOBIG")=150503723
+	s gdeerr("RECSIZIS")=150503731
 	s gdeerr("REGIS")=150503739
 	s gdeerr("SEGIS")=150503747
 	s gdeerr("VALTOOBIG")=150503755
@@ -68,4 +67,31 @@ GDEMSGIN
 	s gdeerr("NONASCII")=150503866
 	s gdeerr("CRYPTNOMM")=150503874
 	s gdeerr("JNLALLOCGROW")=150503883
+	s gdeerr("KEYFORBLK")=150503891
+	s gdeerr("STRMISSQUOTE")=150503898
+	s gdeerr("GBLNAMEIS")=150503907
+	s gdeerr("NAMSUBSEMPTY")=150503914
+	s gdeerr("NAMSUBSBAD")=150503922
+	s gdeerr("NAMNUMSUBSOFLOW")=150503930
+	s gdeerr("NAMNUMSUBNOTEXACT")=150503938
+	s gdeerr("MISSINGDELIM")=150503946
+	s gdeerr("NAMRANGELASTSUB")=150503954
+	s gdeerr("NAMSTARSUBSMIX")=150503962
+	s gdeerr("NAMLPARENNOTBEG")=150503970
+	s gdeerr("NAMRPARENNOTEND")=150503978
+	s gdeerr("NAMONECOLON")=150503986
+	s gdeerr("NAMRPARENMISSING")=150503994
+	s gdeerr("NAMGVSUBSMAX")=150504002
+	s gdeerr("NAMNOTSTRSUBS")=150504010
+	s gdeerr("NAMSTRSUBSFUN")=150504018
+	s gdeerr("NAMSTRSUBSLPAREN")=150504026
+	s gdeerr("NAMSTRSUBSCHINT")=150504034
+	s gdeerr("NAMSTRSUBSCHARG")=150504042
+	s gdeerr("GBLNAMCOLLUNDEF")=150504050
+	s gdeerr("NAMRANGEORDER")=150504058
+	s gdeerr("NAMRANGEOVERLAP")=150504066
+	s gdeerr("NAMGVSUBOFLOW")=150504074
+	s gdeerr("GBLNAMCOLLRANGE")=150504082
+	s gdeerr("STDNULLCOLLREQ")=150504091
+	s gdeerr("GBLNAMCOLLVER")=150504098
 	q
diff --git a/sr_port/gdeparse.m b/sr_port/gdeparse.m
index 9e8668c..9861ef6 100644
--- a/sr_port/gdeparse.m
+++ b/sr_port/gdeparse.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2010 Fidelity Information Services, Inc	;
+;	Copyright 2010, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,7 +10,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gdeparse:	;command parser
 GDEPARSE
-	n verb,NAME,REGION,SEGMENT,gqual,lquals
+	n verb,NAME,GBLNAME,REGION,SEGMENT,gqual,lquals
 	d matchtok("TKIDENT","Verb") s verb=token
 	d checkkw(.verb,"verb","syntab")
 	d @verb
@@ -21,7 +21,7 @@ qual(qual,ent,s)
 	s qual=token d checkkw(.qual,ent,s) s t=@s@(qual)
  	i negated,t'["NEGATABLE" zm gdeerr("NONEGATE"):qual
 	i t["REQUIRED",ntoktype'="TKEQUAL",'negated zm gdeerr("VALUEREQD"):qual
-	i "NEGATABLE"[t!negated,ntoktype="TKEQUAL" zm gdeerr("NOVALUE"):qual
+	i "NEGATABLE"[t!negated,ntoktype="TKEQUAL" zm gdeerr("NOVALUE"):$s(negated:"NO"_qual,1:qual)
 	i t["NEGATABLE" s qual("value")='negated
 	i ntoktype="TKEQUAL",t'["LIST" s qual("value")=$$getvalue(s,qual) q
 	i ntoktype="TKEQUAL" d list(qual)
@@ -33,9 +33,11 @@ getvalue:(s,qual)
 	q value
 	;
 list:(lhead)
-	n sep
+	n listparsing
+	s listparsing=TRUE
 	s tmp=lqual,v=lqual("value")
-	i $e(comline,cp)="(" d GETTOK^GDESCAN
+	i $ze(comline,cp)="(" d GETTOK^GDESCAN
+	n sep
 	s sep=ntoktype d getlitm
 	i sep="TKLPAREN" s sep=ntoktype f  q:ntoktype="TKRPAREN"  zm:"TKRPAREN|TKCOMMA"'[ntoktype gdeerr("RPAREN") d getlitm
 	i ntoktype="TKRPAREN" d GETTOK^GDESCAN
@@ -43,37 +45,41 @@ list:(lhead)
 	q
 TNUMBER
 	d GETTOK^GDESCAN
-	i toktype'="TKNUMLIT" zm gdeerr("VALUEBAD"):token:"number"
-	i $l(token)'=$zl(token) zm gdeerr("NONASCII"):token:"number"			; error if the token has non-ascii numbers
+	i $l(token)'=$zl(token) zm gdeerr("NONASCII"):token:"number"	; error if the token has non-ascii numbers
+	i token'?1.N zm gdeerr("VALUEBAD"):token:"number"
 	s value=token
 	q
 TFSPEC
-	k filespec
-	i ntoktype="TKEOL" zm gdeerr("QUALREQD"):"file specification"
-	i ntoktype="TKSTRLIT" s filespec=$ze(ntoken,2,$zl(ntoken)-1)
+	n filespec
+	i ntoktype="TKSTRLIT" s filespec=ntoken
 	e  d TFSPECP
- 	d GETTOK^GDESCAN			; put the scanner back on track
+	d GETTOK^GDESCAN
 	i $zl(filespec)>(SIZEOF("file_spec")-1) zm gdeerr("VALUEBAD"):filespec:"file specification"
-	i '$l($zparse(filespec,"","","","SYNTAX_ONLY")) zm gdeerr("VALUEBAD"):filespec:"file specification"
-	s @("value="_$s($l(filexfm):filexfm,1:filespec))	; do system specific file name translation
+	i '$zl($zparse(filespec,"","","","SYNTAX_ONLY")) zm gdeerr("VALUEBAD"):filespec:"file specification"
+	s @("value="_$s($zl(filexfm):filexfm,1:filespec))	; do system specific file name translation
 	q
 TFSPECP						; scan filespec token by token
-	n c,cp1					; unix filenames must be quoted to avoid / conflicts with qualifiers
-	s cp1=cp-$l(ntoken)
-	f i=0:1 s c=$e(comline,cp1+i) q:c'?@dbfilpar!'$l(c)
-	s filespec=$e(comline,cp1,cp1+i-1),cp=cp1+i
+	n c,cp1,i				; unix filenames must be quoted to avoid / conflicts with qualifiers
+	; first undo any whitespace that was skipped
+	f i=1:1 s c=$ze(comline,cp-i) q:(c'=" ")&(c'=TAB)
+	s cp1=cp-(i-1)-$zl(ntoken)
+	i ver'="VMS" s i=$zl(comline)-cp1+1 ; in Unix any byte is considered acceptable in the file name at the end of the line
+	i ver="VMS" f i=0:1 s c=$ze(comline,cp1+i) q:c'?@dbfilpar!'$zl(c)
+	s filespec=$ze(comline,cp1,cp1+i-1),cp=cp1+i
+	i ver="VMS" d skipwhitespace^GDESCAN	; in VMS, spaces at the end of the file name are not part of the file so skip them
 	q
 TACCMETH
 	d GETTOK^GDESCAN
 	i toktype'="TKIDENT" zm gdeerr("VALUEBAD"):token:qual
 	s value=$tr(token,lower,upper)
-	i @s@(qual,"TYPE","VALUES")'[("\"_value) zm gdeerr("VALUEBAD"):token:qual
+	i '$data(typevalue("STR2NUM","TACCMETH",value)) zm gdeerr("VALUEBAD"):token:qual
 	q
 TNULLSUB
 	d GETTOK^GDESCAN
 	i toktype'="TKIDENT" zm gdeerr("VALUEBAD"):token:qual
 	s value=$tr(token,lower,upper)
-	i @s@(qual,"TYPE","VALUES")'[("\"_value) zm gdeerr("VALUEBAD"):token:qual
+	i '$data(typevalue("STR2NUM","TNULLSUB",value)) zm gdeerr("VALUEBAD"):token:qual
+	s value=typevalue("STR2NUM","TNULLSUB",value)
 	q
 TREGION
 	n REGION d REGION s value=REGION
@@ -81,66 +87,372 @@ TREGION
 TSEGMENT
 	n SEGMENT d SEGMENT s value=SEGMENT
 	q
+GBLNAME
+	k GBLNAME
+	n c
+	i ntoktype="TKEOL" zm gdeerr("OBJREQD"):"gblname"
+	d GETTOK^GDESCAN
+	s GBLNAME=token
+	i GBLNAME'?1(1"%",1A).AN zm gdeerr("VALUEBAD"):GBLNAME:"gblname"
+	i $l(GBLNAME)'=$zl(GBLNAME) zm gdeerr("NONASCII"):GBLNAME:"gblname"		; error if the name is non-ascii
+	i $zl(GBLNAME)>PARNAMLN zm gdeerr("VALTOOLONG"):GBLNAME:PARNAMLN:"gblname"
+	q
 NAME
 	k NAME
+	n c,len,j,k,tokname,starti,endi,subcnt,nsubs,gblname,type,rangeprefix,nullsub,lsub
 	i ntoktype="TKEOL" zm gdeerr("OBJREQD"):"name"
-	n c,cp1
-	s cp1=cp-$l(ntoken)
-	f i=0:1 s c=$e(comline,cp1+i) q:c'?.1"%".1AN.1"*"!'$l(c)
-	s NAME=$e(comline,cp1,cp1+i-1),cp=cp1+i d GETTOK^GDESCAN			; put the scanner back on track
-	i '$l(NAME) zm gdeerr("VALUEBAD"):token:"name"
+	m nsubs=NAMEsubs	; before GETTOK overwrites it
+	s type=NAMEtype		; before GETTOK overwrites it
+	d GETTOK^GDESCAN
+	s tokname=token
+	i (MAXGVSUBS<(nsubs-1-$select(type="RANGE":1,1:0))) zm gdeerr("NAMGVSUBSMAX"):tokname:MAXGVSUBS
+	; parse subscripted tokname (potentially with ranges) to ensure individual pieces are well-formatted
+	; One would be tempted to use $NAME to do automatic parsing of subscripts for well-formedness, but there are issues
+	; with it. $NAME does not issue error in various cases (unsubscripted global name longer than 31 characters,
+	; numeric subscript mantissa more than 18 digits etc.). And since we want these cases to error out as well, we parse
+	; the subscript explicitly below.
+	s len=$zl(tokname)
+	s j=$g(nsubs(1))
+	s gblname=$ze(tokname,1,j-2)
+	s NAME=gblname
 	i $l(NAME)'=$zl(NAME) zm gdeerr("NONASCII"):NAME:"name"				; error if the name is non-ascii
-	i NAME'="*" s x=$e(NAME) i x'="%",x'?1A zm gdeerr("NAMSTARTBAD"):NAME
-	i $e(NAME,2,999)'?.AN.1"*" zm gdeerr("VALUEBAD"):NAME:"name"
-	i $l(NAME)>PARNAMLN zm gdeerr("VALTOOLONG"):NAME:PARNAMLN:"name"
+	s NAME("SUBS",0)=gblname
+	i $ze(gblname,j-2)="*" s type="STAR"
+	s NAME("TYPE")=type
+	i ("*"'=gblname)&(gblname'?1(1"%",1A).AN.1"*") zm gdeerr("VALUEBAD"):gblname:"name"
+	i (j-2)>PARNAMLN zm gdeerr("VALTOOLONG"):gblname:PARNAMLN:"name"
+	i j=(len+2) s NAME("NSUBS")=0 q  ; no subscripts to process. done.
+	; have subscripts to process
+	i ver="VMS" zm gdeerr("VALUEBAD"):tokname:"name"	; currently VMS does not support subscripts in namespaces
+	i type="STAR" zm gdeerr("NAMSTARSUBSMIX"):tokname
+	i $ze(tokname,len)'=")" zm gdeerr("NAMENDBAD"):tokname
+	s NAME=NAME_"("
+	s nullsub=""""""
+	f subcnt=1:1:nsubs-1 d
+	. s k=nsubs(subcnt+1)
+	. s sub=$ze(tokname,j,k-2)
+	. i (sub="") d
+	. . ; allow empty subscripts only on left or right side of range
+	. . i (type="RANGE") d
+	. . . i (subcnt=(nsubs-2)) s sub=nullsub q  ; if left  side of range is empty, replace with null subscript
+	. . . i (subcnt=(nsubs-1)) s sub=nullsub q  ; if right side of range is empty, replace with null subscript
+	. i (sub="") zm gdeerr("NAMSUBSEMPTY"):subcnt ; null subscript
+	. s c=$ze(sub,1)
+	. i (c="""")!(c="$") set sub=$$strsub(sub,subcnt)	; string subscript
+	. e  set sub=$$numsub(sub,subcnt)			; numeric subscript
+	. i (type="RANGE")&(subcnt=(nsubs-2)) s rangeprefix=NAME,lsub=sub
+	. s NAME("SUBS",subcnt)=sub,NAME=NAME_sub,j=k
+	. s NAME=NAME_$s(subcnt=(nsubs-1):")",(type="RANGE")&(subcnt=(nsubs-2)):":",1:",")
+	s NAME("NSUBS")=nsubs-1,NAME("NAME")=NAME
+	i type="RANGE" d
+	. ; check if both subscripts are identical; if so morph the RANGE subscript into a POINT type.
+	. ; the only exception is if the range is of the form <nullsub>:<nullsub>. In this case, it is actually a range
+	. ; meaning every possible value in that subscript.
+	. i ((NAME("SUBS",nsubs-1)=lsub)&(lsub'=nullsub)) d  q
+	. . s NAME("NAME")=rangeprefix_lsub_")",NAME("NSUBS")=nsubs-2,NAME("TYPE")="POINT",NAME=NAME("NAME")
+	. . k NAME("SUBS",nsubs-1)
+	. s NAME("GVNPREFIX")=rangeprefix	; subscripted gvn minus the last subscript
+	. ; note the below (which does out-of-order check) also does the max-key-size checks for both sides of the range
+	. d namerangeoutofordercheck(.NAME,+$g(gnams(gblname,"COLLATION")))
+	e  d
+	. ; ensure input NAME is within maximum key-size given current gblname value of collation
+	. n coll,key
+	. s coll=+$g(gblname,"COLLATION")
+	. s key=$$gvn2gds^GDEMAP("^"_NAME,coll)
+	. d keylencheck(NAME,key,coll)
+	q
+namerangeoutofordercheck:(nam,coll)
+	n rlo,rhi,nsubs,nullsub,rangelo,rangehi,keylo,keyhi,range
+	s nullsub=""""""
+	s nsubs=nam("NSUBS")
+	s rlo=nam("SUBS",nsubs-1),rhi=nam("SUBS",nsubs)
+	; if rhi==nullsub then the range is guaranteed to be in order by definition so skip check in that case
+	i (rhi'=nullsub) d
+	. s range=nam("GVNPREFIX")
+	. s rangelo="^"_range_rlo_")",rangehi="^"_range_rhi_")"
+	. s keylo=$$gvn2gds^GDEMAP(rangelo,coll),keyhi=$$gvn2gds^GDEMAP(rangehi,coll)
+	. d keylencheck(rangelo,keylo,coll)
+	. d keylencheck(rangehi,keyhi,coll)
+	. i keylo]keyhi zm gdeerr("NAMRANGEORDER"):$$namedisp^GDESHOW(nam("NAME"),0):coll
+	q
+keylencheck(gvn,key,coll)
+	n text
+	s text="subscripted name in the database using collation #"_coll
+	i $zl(key)>maxreg("KEY_SIZE") zm gdeerr("VALTOOLONG"):gvn:maxreg("KEY_SIZE"):text
+	q
+gblnameeditchecks(gblname,newcoll)
+	; Check if setting collation of "gblname" to "newcoll"
+	;	(a) creates out-of-order ranges in existing names
+	;	(b) creates range overlaps in existing names
+	;	(c) creates subscript representations that exceed the key-size design-maximum (1019)
+	;	(d) check if "newcoll" is a valid collation sequence
+	; If "gblname" is "*", check all EXISTING name-specifications across all EXISTING global-names.
+	;	In this case, "newcoll" is ignored since there is no particular gblname we are interested in.
+	n nam,tmpnam,key
+	; Test (d)
+	d chkcoll(newcoll,gblname)
+	; Test (a)
+	s nam=""
+	f  s nam=$o(nams(nam)) q:'$zl(nam)  d
+	. ; for some unsubscripted name specifications (e.g. "*", "#"), nams(nam) might be an unsubscripted node. skip in that case
+	. i '$d(nams(nam,"TYPE")) q
+	. i (nams(nam,"NSUBS")=0) q  ; if unsubscripted name, then no more checks needed
+	. i ("*"'=gblname)&(nams(nam,"SUBS",0)'=gblname) q
+	. i gblname="*" s newcoll=+$g(gnams(nams(nam,"SUBS",0),"COLLATION"))
+	. i nams(nam,"TYPE")'="RANGE" d  q
+	. . ; No need of test (a) since this name is not a range. But do test (c).
+	. . ; This takes care of Test (c) for subscripted non-range name specifications.
+	. . s key=$$gvn2gds^GDEMAP("^"_nam,newcoll)
+	. . d keylencheck(nam,key,newcoll)
+	. k tmpnam
+	. m tmpnam=nams(nam)
+	. s tmpnam=nams(nam)
+	. ; The below also takes care of Test (c) for subscripted range name specifications
+	. d namerangeoutofordercheck(.tmpnam,newcoll)
+	; Test (b)
+	i gblname="*" d
+	. d namerangeoverlapcheck("")
+	e  d namerangeoverlapcheck("","","",gblname,newcoll)
+	q
+getrangelohikey(nam,keylo,keyhi,coll,range)
+	n nsubs,rlo,rhi,nullsub,rlen
+	s nullsub=""""""
+	s nsubs=nam("NSUBS")
+	s rlo=nam("SUBS",nsubs-1),rhi=nam("SUBS",nsubs)
+	s rlo="^"_range_rlo_")",keylo=$$gvn2gds^GDEMAP(rlo,coll)
+	i (rhi'=nullsub) s rhi="^"_range_rhi_")",keyhi=$$gvn2gds^GDEMAP(rhi,coll)
+	e  d
+	. ; rhi==nullsub implies max possible subscript at that level which means the lexically next subscript at one higher level
+	. s rlen=$zl(range)
+	. i $ze(range,rlen)="(" s keyhi=$ze(range,1,rlen-1)_ONE_ZERO_ZERO q
+	. s rhi="^"_$ze(range,1,rlen-1)_")",keyhi=$$gvn2gds^GDEMAP(rhi,coll)
+	. s rlen=$zl(keyhi),keyhi=$ze(keyhi,1,rlen-2)_ONE_ZERO_ZERO q
+	q
+namerangeoverlapcheck2:(nam1,reg1,nam2,coll)
+	n keylo1,keyhi1,keylo2,keyhi2,range,reg2,maxkey,keylo1inbetween,keyhi1inbetween,overlap
+	s reg2=nam2
+	s range=nam1("GVNPREFIX")
+	i range'=nam2("GVNPREFIX") q  ; if subscripts dont match before the range, there is no chance of a range overlap issue
+	i '$data(coll) s coll=+$g(gnams(nam1("SUBS",0),"COLLATION"))
+	d getrangelohikey(.nam1,.keylo1,.keyhi1,coll,range)
+	d getrangelohikey(.nam2,.keylo2,.keyhi2,coll,range)
+	d setinbetween^GDEMAP(keylo1,keylo2,keyhi1,keyhi2,.keylo1inbetween,.keyhi1inbetween)
+	; the above sets keylo1inbetween and keyhi1inbetween
+	s overlap=0
+	i (keylo1inbetween'=keyhi1inbetween) d
+	. ; if regions match, no range overlap error needs to be issued but coalesce is needed for sure
+	. s overlap=1
+	. i reg1=reg2 q  ; if regions match, no need for range overlap error, but need coalesce
+	. zm gdeerr("NAMRANGEOVERLAP"):$$namedisp^GDESHOW(nam1("NAME"),0):$$namedisp^GDESHOW(nam2("NAME"),0):coll
+	; else check for a few sub-range cases
+	e  i (keylo1inbetween) s overlap=1 ; keylo1 and keyhi1 are both in between keylo2 and keyhi2
+	; else if keylo2 is in between keylo1 and keyhi1, this means another sub-range case
+	e  i ((keylo2=keylo1)!(keylo2]keylo1))&(keyhi1]keylo2) s overlap=1
+	; else check if [keylo1,keyhi1] is immediately followed by [keylo2,keyhi2] and map to same region
+	e  i (keyhi1=keylo2)&(reg1=reg2) s overlap=1
+	; else check if [keylo2,keyhi2] is immediately followed by [keylo1,keyhi1] and map to same region
+	e  i (keyhi2=keylo1)&(reg1=reg2) s overlap=1
+	; namrangeoverlap array	indicates there are ranges with overlaps mapping to same region
+	i (overlap=1) s namrangeoverlap(nam1("NAME"))="",namrangeoverlap(nam2("NAME"))=""
+	q
+namerangeoverlapcheck(newname,newreg,oldname,gblname,newcoll)
+	i (newname'="")&(newname("TYPE")'="RANGE") q  ; if newname is specified and is not a RANGE, there is no overlap possibility
+	k namrangeoverlap	; normally we expect this array to be killed once a command completes cleanly
+				; but in case of errors, it is possible this exists. In that case, just clean it now.
+	n nam1,tmpnam1,nam2,tmpnam2,reg
+	s nam1=""
+	f  s nam1=$o(nams(nam1)) q:""=nam1  d
+	. i nam1=$g(oldname) q  ; if oldname is defined, assume as if that has been deleted from the "nams" array
+	. i '$d(nams(nam1,"TYPE")) q  ; for unsubscripted name specifications, "nam1" is an unsubscripted node
+	. i nams(nam1,"TYPE")'="RANGE" q
+	. i $data(gblname)&(nams(nam1,"SUBS",0)'=gblname) q  ; if called in with a specific gblname, skip other gblname ranges
+	. k tmpnam1
+	. m tmpnam1=nams(nam1)
+	. s tmpnam1=nams(nam1)
+	. i newname'="" d namerangeoverlapcheck2(.newname,newreg,.tmpnam1) q
+	. s reg=tmpnam1
+	. s nam2=""
+	. f  s nam2=$o(nams(nam2)) q:nam1=nam2  d
+	. . i '$d(nams(nam2,"TYPE")) q  ; for unsubscripted name specifications, "nam2" is an unsubscripted node
+	. . i nams(nam2,"TYPE")'="RANGE" q
+	. . i $data(gblname)&(nams(nam2,"SUBS",0)'=gblname) q  ; if called in with a specific gblname, skip other gblname ranges
+	. . k tmpnam2
+	. . m tmpnam2=nams(nam2)
+	. . s tmpnam2=nams(nam2)
+	. . i '$d(newcoll) d
+	. . . d namerangeoverlapcheck2(.tmpnam1,reg,.tmpnam2)
+	. . e  d namerangeoverlapcheck2(.tmpnam1,reg,.tmpnam2,newcoll)
+	q
+chkcoll(coll,gblname,collver)
+	i coll=0 q  ; 0 is always a good collation sequence
+	i (coll<0)!(coll>maxgnam("COLLATION")) zm gdeerr("GBLNAMCOLLRANGE"):coll
+	n savetrap
+	s savetrap=$etrap
+	n $etrap
+	s $etrap="goto collundeferr"
+	v "YCHKCOLL":coll
+	s $etrap=savetrap
+	i $d(collver) d
+	. i (0=$view("YCOLLATE",coll,collver)) d
+	. . n ver
+	. . s ver=$view("YCOLLATE",coll)
+	. . i $view("YCOLLATE",coll,ver) zm gdeerr("GBLNAMCOLLVER"):gblname:coll:collver:ver
+	q
+collundeferr
+	i $zstatus'["COLLATIONUNDEF" q  ; dont know how a non-COLLATIONUNDEF error can occur.
+					; let parent frame handle this like any other error
+	s $ecode=""
+	s $etrap=savetrap
+	zm gdeerr("GBLNAMCOLLUNDEF"):coll:gblname
+	q
+strsub:(sub,subcnt)
+	n state,xstr,len,iszchar,istart,x,y	; iszchar and istart are initialized in lower level invocations
+						; but needed outside that frame too hence the new done here (in parent)
+	n retsub	; the subscript that is returned after doing $c() transformations
+	n i,previ,doublequote
+	; check if string subscript is properly formatted. done using a DFA.
+	s state=0,len=$zl(sub),doublequote="""",retsub=doublequote
+	f i=1:1:len s c=$ze(sub,i) d @state
+	; check if state is terminating
+	i (state'=2)&(state'=6) zm gdeerr("NAMNOTSTRSUBS"):subcnt:sub
+	i (state=2) s retsub=retsub_$ze(sub,previ,i-1)
+	q retsub_doublequote
+0	;
+	i c=doublequote s state=1,previ=i+1
+	e  i c="$" s state=3
+	e  zm gdeerr("NAMNOTSTRSUBS"):subcnt:sub
+	q
+1	;
+	i c=doublequote s state=2
+	; else state stays at 1
+	q
+2	;
+	i c=doublequote s state=1
+	e  i c="_" s state=0,retsub=retsub_$ze(sub,previ,i-2) ; previ would be reset when we execute the label "0" (state=0)
+	e  zm gdeerr("NAMNOTSTRSUBS"):subcnt:sub
+	q
+3	;
+	; the only $ functions allowed are $C, $CHAR, $ZCH, $ZCHAR. check for those.
+	n j,fn
+	s j=$zf(sub,"(",i)
+	s fn=$ze(sub,i,$s(j'=0:j-2,1:$zl(sub)))
+	s fn=$tr(fn,lower,upper)
+	i ((fn="C")!(fn="CHAR")) s iszchar=0
+	e  i ((fn="ZCH")!(fn="ZCHAR")) s iszchar=1
+	e  zm gdeerr("NAMSTRSUBSFUN"):subcnt:sub
+	i j=0 zm gdeerr("NAMSTRSUBSLPAREN"):subcnt:sub	; no "(" found following $
+	s i=j-1,state=4
+	q
+4	;
+	s istart=i
+	i c'?1N zm gdeerr("NAMSTRSUBSCHINT"):subcnt:sub
+	s state=5
+	q
+5	;
+	i c="," d numcheck(istart,i) s state=4 q
+	i c=")" d numcheck(istart,i) s state=6 q
+	i c'?1N zm gdeerr("NAMSTRSUBSCHINT"):subcnt:sub
+	; else state stays at 5
+	q
+6	;
+	i c="_" s state=0
+	e  zm gdeerr("NAMNOTSTRSUBS"):subcnt:sub
+	q
+numcheck(istart,i);
+	n num,dollarc
+	s num=$ze(sub,istart,i-1)
+	d chknumoflow(subcnt,num)
+	d chknumexact(subcnt,num,num)
+	; check if string subscript has $c() usages. If so, check if $zl($c(NNN)) for each number NNN is non-zero
+	i (iszchar&'$zl($zch(num)))!('iszchar&'$zl($c(num))) zm gdeerr("NAMSTRSUBSCHARG"):subcnt:sub:num
+	; now that we know $zch()/$c() is passed a valid number, add this to the string subscript to be returned
+	s dollarc=$s(iszchar:$zch(num),1:$c(num)),retsub=retsub_dollarc
+	i dollarc="""" s retsub=retsub_dollarc	; if double-quote is specified as a $c() expression, use two double-quotes
+						; to indicate this is a double-quote inside the string subscript
+	q
+numsub:(sub,subcnt)
+	n mantissa
+	; check if a valid subscript. if not error right away
+	i sub'?.(.1"+",.1"-").N.1(1".".N).1(1"E"1(.1"+",.1"-")1.N)!(sub=".") zm gdeerr("NAMSUBSBAD"):subcnt:sub
+	; check if number too big to be represented in GT.M. If so issue NAMNUMSUBSOFLOW error
+	d chknumoflow(subcnt,sub)
+	; check if mantissa contains more digits than GT.M can store. If so issue NAMNUMSUBNOTEXACT error
+	s mantissa=$p(sub,"E")
+	s mantissa=$ztr(mantissa,"-+.")	; remove all -, + and . so we get just the mantissa out
+	d chknumexact(subcnt,mantissa,sub)
+	; now that we know this is a valid numeric subscript, make it canonical (if needed) e.g. 1E+000 -> 1 etc.
+	q +sub
+chknumexact(subcnt,mantissa,sub)
+	n i,j
+	s j=$zl(mantissa)
+	f i=1:1:j  q:$ze(mantissa,i)'=0   ; remove leading 0s. keep at least one 0
+	i i<j f j=$zl(mantissa):-1  q:$ze(mantissa,j)'=0  ; remove trailing 0s
+	s mantissa=$ze(mantissa,i,j)	; this is the real mantissa
+	; check if mantissa is non-zero but number too small to be represented in GT.M. If so issue NAMNUMSUBNOTEXACT error
+	i (+mantissa)&(0=+sub) zm gdeerr("NAMNUMSUBNOTEXACT"):subcnt:sub
+	; check if mantissa cannot be accurately represented in GT.M. If so issue NAMNUMSUBNOTEXACT error
+	i +mantissa'=mantissa zm gdeerr("NAMNUMSUBNOTEXACT"):subcnt:sub
+	q
+chknumoflow(subcnt,sub)
+	n $etrap
+	s $et="i $zstatus[""NUMOFLOW"" zg -1:numoflowerr"
+	s sub=+sub
+	q
+numoflowerr
+	s $ecode=""
+	zm gdeerr("NAMNUMSUBSOFLOW"):subcnt:sub
 	q
 REGION
 	k REGION
 	i ntoktype="TKEOL" zm gdeerr("OBJREQD"):renpref_"region"
-	n c,cp1
-	s cp1=cp-$l(ntoken)
-	f i=0:1 s c=$e(comline,cp1+i) q:c'?.1AN.1"$".1"_"!'$l(c)
-	s REGION=$tr($e(comline,cp1,cp1+i-1),lower,upper),cp=cp1+i d GETTOK^GDESCAN		; put the scanner back on track
-	i '$l(REGION) zm gdeerr("VALUEBAD"):token:renpref_"region"
+	d GETTOK^GDESCAN
+	s REGION=$tr(token,lower,upper)
+	i '$zl(REGION) zm gdeerr("VALUEBAD"):token:renpref_"region"
 	i $l(REGION)'=$zl(REGION) zm gdeerr("NONASCII"):REGION:"region"		; error if the name of the region is non-ascii
 	i REGION=defreg q
-	s x=$e(REGION) i x'?1A zm gdeerr("PREFIXBAD"):REGION:renpref_"region"
-	i $l(REGION)>PARREGLN zm gdeerr("VALTOOLONG"):REGION:PARREGLN:renpref_"region"
+	s x=$ze(REGION) i x'?1A d prefixbaderr(REGION,"region")
+	i $ze(REGION,2,999)'?.(1AN,1"_",1"$") zm gdeerr("VALUEBAD"):REGION:"region"
+	i $zl(REGION)>PARREGLN zm gdeerr("VALTOOLONG"):REGION:PARREGLN:renpref_"region"
 	q
 SEGMENT
 	k SEGMENT
 	i ntoktype="TKEOL" zm gdeerr("OBJREQD"):renpref_"segment"
-	n c,cp1
-	s cp1=cp-$l(ntoken)
-	f i=0:1 s c=$e(comline,cp1+i) q:c'?.1AN.1"$".1"_"!'$l(c)
-	s SEGMENT=$tr($e(comline,cp1,cp1+i-1),lower,upper),cp=cp1+i d GETTOK^GDESCAN		; put the scanner back on track
-	i '$l(SEGMENT) zm gdeerr("VALUEBAD"):token:renpref_"segment"
+	d GETTOK^GDESCAN
+	s SEGMENT=$tr(token,lower,upper)
+	i '$zl(SEGMENT) zm gdeerr("VALUEBAD"):token:renpref_"segment"
 	i $l(SEGMENT)'=$zl(SEGMENT) zm gdeerr("NONASCII"):SEGMENT:"segment"	; error if the name of the segment is non-ascii
 	i SEGMENT=defseg q
-	s x=$e(SEGMENT) i x'?1A zm gdeerr("PREFIXBAD"):SEGMENT:renpref_"segment"
-	i $l(SEGMENT)>PARSEGLN zm gdeerr("VALTOOLONG"):SEGMENT:PARSEGLN:renpref_"segment"
+	s x=$ze(SEGMENT) i x'?1A d prefixbaderr(SEGMENT,"segment")
+	i $ze(SEGMENT,2,999)'?.(1AN,1"_",1"$") zm gdeerr("VALUEBAD"):SEGMENT:"segment"
+	i $zl(SEGMENT)>PARSEGLN zm gdeerr("VALTOOLONG"):SEGMENT:PARSEGLN:renpref_"segment"
+	q
+prefixbaderr:(name,str)
+	n namestr
+	s namestr=$s(ver="VMS":"name (other than $DEFAULT)",1:"name")
+	zm gdeerr("PREFIXBAD"):name:renpref_str:namestr
 	q
 matchtok:(tok,ent)
 	d GETTOK^GDESCAN
 	i toktype=tok q
+	i tok=sep zm gdeerr("MISSINGDELIM"):tokens(sep):ent:token q
 	zm gdeerr("VALUEBAD"):token:ent
 	q
-checkkw:(kw,ent,kwlist)
+checkkw(kw,ent,kwlist)
 	n x1,x2
 	s kw=$tr(kw,lower,upper)
-	i $e(kw,1,2)="NO" s negated=1,kw=$e(kw,3,999)
+	i $ze(kw,1,2)="NO" s negated=1,kw=$ze(kw,3,999)
 	e  s negated=0
-	s x1="" f  s x1=$o(@kwlist@(x1)) q:kw=$e(x1,1,$l(kw))!'$l(x1)
-	i '$l(x1) zm gdeerr("KEYWRDBAD"):kw:ent
-	s x2=x1 f  s x2=$o(@kwlist@(x2)) q:kw=$e(x2,1,$l(kw))!'$l(x2)
-	i $l(x2) zm gdeerr("KEYWRDAMB"):kw:ent
+	s x1="" f  s x1=$o(@kwlist@(x1)) q:kw=$ze(x1,1,$zl(kw))!'$zl(x1)
+	i '$zl(x1) zm gdeerr("KEYWRDBAD"):kw:ent
+	s x2=x1 s x2=$o(@kwlist@(x2))
+	i ('$zl(x2))&(kw=$ze(x2,1,$zl(kw))) zm gdeerr("KEYWRDAMB"):kw:ent
 	s kw=x1
 	q
-getqual: d qual(.lqual,"Local qualifier","syntab("""_verb_""","""_gqual_""")")
+getqual: d qual(.lqual,"qualifier","syntab("""_verb_""","""_gqual_""")")
 	i '$d(lquals(lqual)) s lquals(lqual)=$g(lqual("value"))
 	e  zm gdeerr("QUALDUP"):lqual
 	q
-getlitm: d qual(.lqual,"Local qualifier","syntab("""_verb_""","""_gqual_""","""_lhead_""")")
+getlitm: d qual(.lqual,"qualifier","syntab("""_verb_""","""_gqual_""","""_lhead_""")")
 	i '$d(lquals(lqual)) s lquals(lqual)=$g(lqual("value"))
 	e  zm gdeerr("QUALDUP"):lqual
 	q
@@ -149,37 +461,38 @@ getlitm: d qual(.lqual,"Local qualifier","syntab("""_verb_""","""_gqual_""","""_
 
 ADD
 CHANGE
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")"), at gqual
+	d qual(.gqual,"object","syntab("""_verb_""")"), at gqual
 	f  q:ntoktype="TKEOL"  d getqual
-	d @gqual^@("GDE"_$e(verb,1,5))
+	d @gqual^@("GDE"_$ze(verb,1,5))
 	q
 RENAME
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")")
+	n old,new
+	d qual(.gqual,"object","syntab("""_verb_""")")
 	n renpref
-	s renpref="old " d @gqual s old=@gqual
-	s renpref="new " d @gqual s new=@gqual
+	s renpref="old " d @gqual m old=@gqual	; merge needed since subscripted nodes might also be involved
+	s renpref="new " d @gqual m new=@gqual	; merge needed since subscripted nodes might also be involved
 	s renpref="" d matchtok("TKEOL","End of line")
-	d @gqual^GDERENAM(old,new)
+	d @gqual^GDERENAM(.old,.new)	; pass by reference since old and new could have subscripted nodes (in case of -NAME)
 	q
 TEMPLATE
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")")
+	d qual(.gqual,"object","syntab("""_verb_""")")
 	f  q:ntoktype="TKEOL"  d getqual
 	d @gqual^GDETEMPL
 	q
 DELETE
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")"), at gqual,matchtok("TKEOL","End of line"), at gqual^GDEDELET
+	d qual(.gqual,"object","syntab("""_verb_""")"), at gqual,matchtok("TKEOL","End of line"), at gqual^GDEDELET
 	q
 LOCKS
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")"),matchtok("TKEOL","End of line"),LOCKS^GDELOCKS
+	d qual(.gqual,"object","syntab("""_verb_""")"),matchtok("TKEOL","End of line"),LOCKS^GDELOCKS
 	q
 LOG
 	i ntoktype="TKEOL" d INQUIRE^GDELOG q
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")"),matchtok("TKEOL","End of line"),LOG^GDELOG
+	d qual(.gqual,"object","syntab("""_verb_""")"),matchtok("TKEOL","End of line"),LOG^GDELOG
 	q
 SHOW
 	i ntoktype="TKEOL" d ALL^GDESHOW q
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")") s t="NAMEREGIONSEGMENT"[gqual
-	i t,ntoktype="TKEOL" d @("ALL"_$e(gqual,1,5))^GDESHOW q
+	d qual(.gqual,"object","syntab("""_verb_""")") s t="|NAME|GBLNAME|REGION|SEGMENT"[("|"_gqual)
+	i t,ntoktype="TKEOL" d @("ALL"_$ze(gqual,1,5))^GDESHOW q
 	n mapreg
 	i gqual="MAP",ntoktype'="TKEOL" d getqual s mapreg=$g(lquals("REGION"))
 	i 't,"COMMANDS"=gqual,ntoktype'="TKEOL" d getqual s cfile=$g(lquals("FILE"))
@@ -187,11 +500,13 @@ SHOW
 	q
 VERIFY
 	i ntoktype="TKEOL" s x=$$ALL^GDEVERIF q
-	d qual(.gqual,"Global qualifier","syntab("""_verb_""")")
+	d qual(.gqual,"object","syntab("""_verb_""")")
 	i "ALL|MAP"[gqual s x=$$ALL^GDEVERIF q
 	n verified s verified=1
-	i ntoktype="TKEOL" d @("ALL"_$e(gqual,1,3))^GDEVERIF i 1
-	e  i "NAMEREGIONSEGMENT"[gqual d @gqual, at gqual^GDEVERIF i 1
+	i ntoktype="TKEOL" d
+	. d @("ALL"_$ze(gqual,1,3))^GDEVERIF
+	e  i "NAMEGBLNAMEREGIONSEGMENT"[gqual d
+	. d @gqual, at gqual^GDEVERIF
 	e  zm gdeerr("NOVALUE"):gqual
 	i $d(verified) zm gdeerr("VERIFY"):$s(verified:"OK",1:"FAILED") w !
 	q
@@ -201,7 +516,7 @@ QUIT
 	d ^@("GDE"_$tr(verb,lower,upper))
 	q
 SETGD	f  d  q:ntoktype="TKEOL"
-	. d qual(.gqual,"Global qualifier","syntab("""_verb_""")") s:gqual="FILE" tfile=gqual("value") s:gqual="QUIT" update=0
+	. d qual(.gqual,"object","syntab("""_verb_""")") s:gqual="FILE" tfile=gqual("value") s:gqual="QUIT" update=0
 	d GDESETGD^GDESETGD
 	q
 HELP
diff --git a/sr_port/gdequit.m b/sr_port/gdequit.m
index 88414fd..90c4159 100644
--- a/sr_port/gdequit.m
+++ b/sr_port/gdequit.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001 Sanchez Computer Associates, Inc.	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -11,4 +11,5 @@
 quit:	;implement the verb: QUIT
 QUIT
 	zm gdeerr("NOACTION"):$zparse(tfile,"",defgldext)
+	d GETOUT^GDEEXIT
 	h
diff --git a/sr_port/gderenam.m b/sr_port/gderenam.m
index 4ed648c..1109e23 100644
--- a/sr_port/gderenam.m
+++ b/sr_port/gderenam.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001 Sanchez Computer Associates, Inc.	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -14,9 +14,13 @@ NAME(old,new)
 	i old="*" zm gdeerr("LVSTARALON")
 	i '$d(nams(old)) d error1
 	i $d(nams(new)) d error2
-	s update=1,nams(new)=nams(old),s=""
-	f  s s=$o(nams(old,s)) q:'$l(s)  s nams(new,s)=nams(old,s)
+	; check if changing a name (with ranges) poses issues with overlap amongst other existing name ranges
+	d namerangeoverlapcheck^GDEPARSE(.new,nams(old),old)
+	s update=1
+	m nams(new)=new
+	s nams(new)=nams(old)
 	k nams(old)
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
 	q
 REGION(old,new)
 	i old=new q
@@ -37,6 +41,21 @@ SEGMENT(old,new)
 	s segs(new,"ACCESS_METHOD")=am k segs(old)
 	f  s s=$o(regs(s)) q:'$l(s)  i regs(s,"DYNAMIC_SEGMENT")=old s regs(s,"DYNAMIC_SEGMENT")=new
 	q
+GBLNAME(old,new)
+	i old=new q
+	i '$d(gnams(old)) d error1
+	; check if changing (i.e. deleting) collation for "old" GBLNAME poses issues with existing names & ranges
+	i $d(gnams(old,"COLLATION")) d
+	. d gblnameeditchecks^GDEPARSE(old,0)
+	. i $d(namrangeoverlap) d namcoalesce^GDEMAP
+	i $d(gnams(new)) d error2
+	; check if changing (i.e. adding) collation for "new" GBLNAME poses issues with existing names & ranges
+	d gblnameeditchecks^GDEPARSE(new,+$get(gnams(old,"COLLATION")))
+	i $d(namrangeoverlap) d namcoalesce^GDEMAP
+	s update=1
+	m gnams(new)=gnams(old)
+	k gnams(old)
+	q
 error1:
 	zm gdeerr("OBJNOTFND"):"Old "_$tr(gqual,upper,lower):old
 	q
diff --git a/sr_port/gdescan.m b/sr_port/gdescan.m
index 36c702a..5182203 100644
--- a/sr_port/gdescan.m
+++ b/sr_port/gdescan.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2010 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,64 +10,140 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gdescan: ;scanner used by gdeparse
 GETTOK
-	n c
+	n c,tmptok,tokisname
+	; If -name has been seen, then change GETTOK to fetch next token (which is the actual name specification)
+	;   by taking double-quotes into account. Same case with the next TWO tokens (not just one) in case of a
+	;   RENAME command where two names are specified after the -name.
+	; Otherwise use regular token scanning and search only for delimiters (e.g. " ", "," etc.)
+	i ($get(toktype)=sep)&(ntoktype="TKIDENT")&$data(verb)&('$data(gqual))&$data(syntab(verb,"NAME")) d
+	. ; check if the current token is -NAME. if so use special rules to parse the next token
+	. s tmptok=ntoken
+	. d checkkw^GDEPARSE(.tmptok,"object","syntab("""_verb_""")")
+	. i tmptok="NAME" s tokisname=1
+	e  i ($get(verb)="RENAME")&(($get(toktype)=sep)!$data(gqual)) s tokisname=1
 	s token=ntoken,toktype=ntoktype
-	f cp=cp:1 s c=$e(comline,cp) q:(c'=" ")&(c'=TAB)
-	i $c(10,13)[c,cp=$l(comline) s c=""
-	s ntoktype=$s(c?1A:"TKIDENT",c?1N:"TKNUMLIT",c="":"TKEOL",$d(tokens(c)):tokens(c),1:"TKOTHER")
+	; s dbgtoken($incr(dbgtokcnt))=token	; if uncommented, helps debug the GDE token parser
+	d skipwhitespace
+	s c=$ze(comline,cp)
+	i ($c(10)=c)!($c(13)=c) s c="",cp=$zl(comline),ntoktype="TKEOL" d @ntoktype q
+	s ntoktype=$s($d(tokens(c)):tokens(c),1:"TKIDENT")
+	; If "gqual" is not yet filled in, it means we are still parsing either the "verb" or "gqual" but not "lqual".
+	; If we see a double-quote at the start while in this state, parse the token using TKIDENT (and not TKSTRLIT
+	; as we dont expect strings in this context).
+	i (ntoktype="TKSTRLIT")&('$data(gqual)) s ntoktype="TKIDENT" d TKIDENTspacedelims q
+	; Similarly if tokisname is TRUE, then parse the next token as a name-specification
+	i $data(tokisname)  d TKIDENTspacedelims q
 	d @ntoktype
 	q
 shotoks: ; for debugging only
 	w !,"  toktype: ",toktype,?24," token: '",token,"'"
 	w ?48," ntoktype: ",ntoktype,?72,"ntoken: '",ntoken,"'"
 	q
-TKIDENT
+skipwhitespace
 	n i
-	f i=1:1 s c=$e(comline,cp+i) q:(c'?1A)&(c'="_")
-	s ntoken=$e(comline,cp,cp+i-1),cp=cp+i
+	f i=0:1 s c=$ze(comline,cp+i) q:(c'=" ")&(c'=TAB)
+	s cp=cp+i
 	q
-TKNUMLIT
+TKIDENT
+	; if not parsing a list, a "=" is followed by a token that could have special characters (like "=" or "," or "-" etc.)
+	; in this case we dont want these special characters to terminate the parse. Only a whitespace should terminate it.
+	; if parsing inside a list, a "," or ")" or "=" could terminate the parse. So we cannot use the whitespace-only parse
+	; logic in that case.
+	i (toktype="TKEQUAL")&'$data(listparsing) d TKIDENTspacedelims q
+	; by similar logic, if "gqual" is not yet filled in, and we did not see a - as the previous token, it means we are
+	; parsing the "gqual". In that case, end the parse only when whitespace is encountered, not if "=" or "," is seen.
+	i (toktype'=sep)&'$data(gqual) d TKIDENTspacedelims q
 	n i
-	f i=1:1 q:$e(comline,cp+i)'?1N
-	s ntoken=$e(comline,cp,cp+i-1),cp=cp+i
+	d tokscan(.tokendelim)
+	q
+TKIDENTspacedelims
+	d tokscan(.spacedelim)
+	q
+tokscan:(delim)
+	n i,c
+	i '$data(tokisname) d
+	. f i=0:1 s c=$ze(comline,cp+i) q:$data(delim(c))
+	e  d
+	. ; About to parse the token following a -name. Take double-quotes into account.
+	. ; Any delimiter that comes inside a double-quote does NOT terminate the scan/parse.
+	. ; Implement the following DFA (Deterministic Finite Automaton)
+	. ;	  State 0 --> next char is     a double-quote --> State 1
+	. ;	  State 0 --> next char is NOT a double-quote --> State 0
+	. ;	  State 1 --> next char is     a double-quote --> State 2
+	. ;	  State 1 --> next char is NOT a double-quote --> State 1
+	. ;	  State 2 --> next char is     a double-quote --> State 1
+	. ;	  State 2 --> next char is NOT a double-quote --> State 0
+	. ; Also note down (in NAMEsubs) the columns where LPAREN, COMMA and COLON appear. Later used in NAME^GDEPARSE
+	. n quotestate,parenstate,errstate,quitloop
+	. s quotestate=0,parenstate=0,errstate=""
+	. k NAMEsubs ; this records the column where subscript delimiters COMMA or COLON appear in the name specification
+	. k NAMEtype
+	. s NAMEtype="POINT",NAMEsubs=0,quitloop=0
+	. f i=0:1 s c=$ze(comline,cp+i) q:(c="")  d  q:quitloop
+	. . i c="""" s quotestate=$s(quotestate=1:2,1:1)
+	. . e        s quotestate=$s(quotestate=2:0,1:quotestate) i 'quotestate d
+	. . . i $data(delim(c)) s quitloop=1 q
+	. . . i (parenstate=2) i '$zl(errstate) s errstate="NAMRPARENNOTEND"
+	. . . i (c="(") d
+	. . . . i parenstate s parenstate=parenstate+2  q   ; nested parens
+	. . . . s parenstate=1
+	. . . . s NAMEsubs($incr(NAMEsubs))=(i+2)
+	. . . i (c=",") d
+	. . . . i 'parenstate i '$zl(errstate) s errstate="NAMLPARENNOTBEG"
+	. . . . i (1'=parenstate) q   ; nested parens
+	. . . . i NAMEtype="RANGE" i '$zl(errstate) s errstate="NAMRANGELASTSUB"
+	. . . . s NAMEsubs($incr(NAMEsubs))=(i+2)
+	. . . i c=":" d
+	. . . . i 'parenstate i '$zl(errstate) s errstate="NAMLPARENNOTBEG"
+	. . . . i NAMEtype="RANGE" i '$zl(errstate) s errstate="NAMONECOLON"
+	. . . . s NAMEsubs($incr(NAMEsubs))=(i+2),NAMEtype="RANGE"
+	. . . i c=")" d
+	. . . . i 'parenstate i '$zl(errstate) s errstate="NAMLPARENNOTBEG"
+	. . . . i (1'=parenstate) s parenstate=parenstate-2 q   ; nested parens
+	. . . . s parenstate=2
+	. . . . s NAMEsubs($incr(NAMEsubs))=(i+2)
+	. i quotestate i '$zl(errstate) s errstate="STRMISSQUOTE"
+	. i (1=parenstate)!(2<parenstate) i '$zl(errstate) s errstate="NAMRPARENMISSING"
+	. i $zl(errstate) zm gdeerr(errstate):$ze(comline,cp,cp+i-1)
+	. i 'NAMEsubs s NAMEsubs($incr(NAMEsubs))=i+2
+	i c="" d
+	. ; check if tail of last token in line contains $c(13,10) and if so remove it
+	. ; this keeps V61 GDE backward compatible with V60 GDE
+	. n j
+	. f j=1:1 s c=$ze(comline,cp+i-j) q:($c(10)'=c)&($c(13)'=c)
+	. s i=i-j+1
+	s ntoken=$ze(comline,cp,cp+i-1),cp=cp+i
+	d skipwhitespace
+	i (ntoken="!") d TKEXCLAM	; if found a ! instead of a TKIDENT type token, set ntoktype to TKEOL
 	q
 TKSTRLIT
-	n i
-	f i=1:1:$l(comline)-cp q:$e(comline,cp+i)=""""
-	s ntoken=$e(comline,cp,cp+i),cp=cp+i+1
+	n i,len
+	s len=$zl(comline)
+	f i=1:1:(len-cp) q:$ze(comline,cp+i)=""""
+	i (i=(len-cp))&($ze(comline,cp+i)'="""") zm gdeerr("STRMISSQUOTE"):$ze(comline,cp,cp+i)
+	s ntoken=$ze(comline,cp+1,cp+i-1),cp=cp+i+1
+	d skipwhitespace
 	q
-TKAMPER
-TKASTER
-TKCOLON
+TKAT
 TKCOMMA
 TKDASH ; see below for more UNIXy alternative
-TKDOLLAR
 TKEQUAL
-TKLANGLE
-TKLBRACK
 TKLPAREN
-TKPCT
-TKPERIOD
-TKRANGLE
-TKRBRACK
 TKRPAREN
-TKSCOLON
 TKSLASH
-TKUSCORE
 	s ntoken=c,cp=cp+1
+	i (ntoktype="TKRPAREN") d skipwhitespace
 	q
 TKEXCLAM
 	s ntoktype="TKEOL"
 	s ntoken=""
-	s cp=$l(comline)
+	s cp=$zl(comline)
 	q
 ;TKDASH - more UNIXy handling disabled for compatibility with other utilities
 	s ntoken=c,cp=cp+1
-	i sep="TKDASH",$e(comline,cp)?1A s c=$e(comline,cp-2) i c=" "!(c=TAB) q
+	i sep="TKDASH",$ze(comline,cp)?1A s c=$ze(comline,cp-2) i c=" "!(c=TAB) q
 	zm gdeerr("ILLCHAR"):"-"
 	q
 TKEOL
 	s ntoken=""
 	q
-TKOTHER
-	zm gdeerr("ILLCHAR"):c
diff --git a/sr_port/gdeshow.m b/sr_port/gdeshow.m
index 70240d3..6eb5651 100644
--- a/sr_port/gdeshow.m
+++ b/sr_port/gdeshow.m
@@ -10,41 +10,93 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 show:	;implement the verb: SHOW
 ALL
-	d TEMPLATE,ALLNAME,ALLREGIO,ALLSEGME,MAP
+	d TEMPLATE,ALLNAME,ALLGBLNAME,ALLREGIO,ALLSEGME,MAP
 	q
 COMMANDS
+	n tmpreg2,tmpseg2
+	m tmpreg2=tmpreg
+	m tmpseg2=tmpseg
+	n tmpreg,tmpseg
+	m tmpreg=tmpreg2
+	m tmpseg=tmpseg2
+	k tmpreg2,tmpseg2
 	s BOL="!"
 	set delim=$select("VMS"=ver:"/",1:"-")
-	i $l($get(cfile)) o cfile:(newversion:exc="w !,$ztatus c cfile zgoto $zl:cfilefail") u cfile d
-	. d namec,segmentc,regionc,templatec
+	i '$l($get(cfile)) d
+	. f i="@useio",$s(log:"@uself",1:"") q:'$l(i)  u @i d templatec,regionc,segmentc,namec,gblnamec
+	e  o cfile:(newversion:exc="w !,$ztatus c cfile zgoto $zl:cfilefail") u cfile d
+	. d templatec,regionc,segmentc,namec,gblnamec
 	. c cfile
 cfilefail:
-	f i="@useio",$s(log:"@uself",1:"") q:'$l(i)  u @i d templatec,namec,regionc,segmentc
 	s BOL=""
 	q
 NAME
-	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":NAME q
-	d n2
+	n namsdisp,namedispmaxlen
+	i '$d(nams(NAME)) zm gdeerr("OBJNOTFND"):"Name":$$namedisp(NAME,0) q
+	d n2calc,n2
 	i log s BOL="!" u @uself w BOL d n2 w ! u @useio s BOL=""
 	q
-n2:	d namehd w !,BOL,?x(1),NAME,?x(2),nams(NAME)
+n2calc:	s namedispmaxlen=0
+	d namedisplaycalc(NAME) ; sets namedispmaxlen
+	q
+n2:	d namehd,namedisplay(NAME)
 	q
 ALLNAME
-	d SHOWNAM^GDEMAP
+	n namedisp,namedispmaxlen
+	d SHOWNAM^GDEMAP,n1calc
 	d n1
 	i log s BOL="!" u @uself w BOL d n1 w ! u @useio s BOL=""
 	q
-n1:	d namehd s s="#"
-	f  s s=$o(nams(s)) q:'$l(s)  w !,BOL,?x(1),s,?x(2),nams(s)
+n1calc:	s namedispmaxlen=0
+	s s="#"
+	f  s s=$o(nams(s)) q:'$zl(s)  d namedisplaycalc(s)
+	q
+n1:	d namehd
+	d namscollatecalc ; sets "namscollate" array
+	s s="#" ; skip processing "#" name
+	f  s s=$o(namscollate(s)) q:'$zl(s)  d namedisplay(namscollate(s))
+	q
+namedisplay:(name)
+	w !,BOL,?x(1),namsdisp(name),?x(2),nams(name)
 	q
 namec:
+	n s,key,namedisp,namedispmaxlen,namscollate
 	d SHOWNAM^GDEMAP
 	s s="#"
 	w !,"LOCKS "_delim_"REGION=",nams(s)
-	f  s s=$o(nams(s)) q:'$l(s)  d
-	. i "*"'=s w !,"ADD "_delim_"NAME ",s," "_delim_"REGION=",nams(s) q
-	. i defreg'=nams(s) w !,"CHANGE "_delim_"NAME "_s_" "_delim_"REGION=",nams(s)
-	w !
+	d namscollatecalc	; sets "namscollate" array
+	d n1calc		; sets "namedispmaxlen" and "namsdisp" array
+	s key="#" ; skip processing "#" name
+	f  s key=$o(namscollate(key)) q:'$zl(key)  d
+	. s s=namscollate(key)
+	. i "*"'=s w !,"ADD "_delim_"NAME ",namsdisp(s)," "_delim_"REGION=",nams(s) q
+	. i defreg'=nams(s) w !,"CHANGE "_delim_"NAME "_namsdisp(s)_" "_delim_"REGION=",nams(s)
+	w !,BOL
+	q
+GBLNAME
+	i '$d(gnams(GBLNAME)) zm gdeerr("OBJNOTFND"):"Global Name":GBLNAME q
+	d gn2
+	i log s BOL="!" u @uself w BOL d gn2 w ! u @useio s BOL=""
+	q
+gn2:	d gblnamehd,gblnameeach(GBLNAME)
+	q
+gblnameeach(gname)	;
+	w !,BOL,?x(1),gname,?x(2),$j(gnams(gname,"COLLATION"),4),?x(3),$j($view("YCOLLATE",gnams(gname,"COLLATION")),3)
+	q
+ALLGBLNA
+ALLGBLNAME
+	i gnams=0 q
+	d gn1
+	i log s BOL="!" u @uself w BOL d gn1 w ! u @useio s BOL=""
+	q
+gn1:	d gblnamehd
+	s s="" f  s s=$o(gnams(s)) q:'$l(s)  d gblnameeach(s)
+	q
+gblnamec:
+	i gnams=0 q
+	s s=""
+	f  s s=$o(gnams(s)) q:s=""  w !,"ADD "_delim_"GBLNAME ",s," "_delim_"COLLATION=",gnams(s,"COLLATION")
+	w !,BOL
 	q
 REGION
 	i '$d(regs(REGION)) zm gdeerr("OBJNOTFND"):"Region":REGION q
@@ -55,6 +107,7 @@ r2:	d regionhd s s=REGION d onereg
 	i regs(s,"JOURNAL") d jnlhd d onejnl
 	q
 ALLREGIO
+ALLREGION
 	d r1
 	i log s BOL="!" u @uself w BOL d r1 w ! u @useio s BOL=""
 	q
@@ -74,7 +127,7 @@ onereg:
 	i ver'="VMS" w ?x(10),$s(regs(s,"QDBRUNDOWN"):"ENABLED",1:"DISABLED")
 	q
 onejnl:
-	w !,BOL,?x(1),s,?x(2),$s($l(regs(s,"FILE_NAME")):regs(s,"FILE_NAME"),1:"<based on DB file-spec>")
+	w !,BOL,?x(1),s,?x(2),$s($zl(regs(s,"FILE_NAME")):$$namedisp(regs(s,"FILE_NAME"),1),1:"<based on DB file-spec>")
 	i $x'<(x(3)-1) w !,BOL
 	w ?x(3),$s(regs(s,"BEFORE_IMAGE"):"Y",1:"N"),?x(4),$j(regs(s,"BUFFER_SIZE"),5)
 	w ?x(5),$j(regs(s,"ALLOCATION"),10)
@@ -83,27 +136,52 @@ onejnl:
 	w !,BOL
 	q
 regionc:
-	n defseen,cmd
-	s s="",defseen=FALSE
+	n s,q,val,synval,tmpval,type
+	w !,"DELETE "_delim_"REGION "_defreg
+	s s=""
 	f  s s=$o(regs(s)) q:'$l(s)  d
-	. i s=defreg s defseen=TRUE,cmd="CHANGE"
-	. e  s cmd="ADD"
-	. w !,cmd," "_delim_"REGION ",s," "_delim_"DYNAMIC=",regs(s,"DYNAMIC_SEGMENT")
-	. f q="COLLATION_DEFAULT","RECORD_SIZE","KEY_SIZE" w " "_delim,q,"=",regs(s,q)
-	. w " "_delim_"NULL_SUBSCRIPTS=",$s(regs(s,"NULL_SUBSCRIPTS")=1:"ALWAYS",regs(s,"NULL_SUBSCRIPTS")=2:"EXISTING",1:"NEVER")
-	. i regs(s,"STDNULLCOLL") w " "_delim_"STDNULLCOLL"
-	. i regs(s,"JOURNAL") d
-	.. w " "_delim_"JOURNAL=(",$s(regs(s,"BEFORE_IMAGE"):"",1:"NO"),"BEFORE_IMAGE",",BUFFER_SIZE=",regs(s,"BUFFER_SIZE")
-	.. w ",ALLOCATION=",regs(s,"ALLOCATION"),",EXTENSION=",regs(s,"EXTENSION")
-	.. i ver'="VMS" w ",AUTOSWITCHLIMIT=",regs(s,"AUTOSWITCHLIMIT")
-	.. i $l(regs(s,"FILE_NAME")) w ",FILE=""",regs(s,"FILE_NAME"),""""
-	.. w ")"
-	. else  w " "_delim_"NOJOURNAL"
-	. i (ver'="VMS") w " "_delim_$s(regs(s,"INST_FREEZE_ON_ERROR"):"",1:"NO")_"INST_FREEZE_ON_ERROR"
-	. i (ver'="VMS") w " "_delim_$s(regs(s,"QDBRUNDOWN"):"",1:"NO")_"QDBRUNDOWN"
-	i (FALSE=defseen) w !,"DELETE "_delim_"REGION "_defreg
+	. w !,"ADD "_delim_"REGION ",s
+	. s q=""
+	. f  s q=$o(syntab("TEMPLATE","REGION",q)) q:""=q  d
+	. . s synval=syntab("TEMPLATE","REGION",q)
+	. . s val=regs(s,q)
+	. . s tmpval=$get(tmpreg(q))
+	. . i synval["LIST" d  q
+	. . . ; special processing since this option can in turn be an option-list
+	. . . n l,list,lval,lsynval,ltype
+	. . . i (synval["NEGATABLE")&(0=val) d  q
+	. . . . i tmpval=val q
+	. . . . w " "_delim_"NO"_q
+	. . . s list="",l=""
+	. . . f  s l=$o(syntab("TEMPLATE","REGION",q,l)) q:""=l  d
+	. . . . s lval=regs(s,l)
+	. . . . i $get(tmpreg(l))=lval q
+	. . . . s ltype=$get(syntab("TEMPLATE","REGION",q,l,"TYPE"))	; note: possible this is "" for e.g. "BEFORE_IMAGE")
+	. . . . i (ltype'="")&($data(typevalue("NUM2STR",ltype))) s list=list_","_l_"="_typevalue("NUM2STR",ltype,lval) q
+	. . . . s lsynval=syntab("TEMPLATE","REGION",q,l)
+	. . . . i lsynval["NEGATABLE" s list=list_","_$s(lval:"",1:"NO")_l q
+	. . . . d listadd(.list,l,lval)
+	. . . i list="" q
+	. . . w " "_delim_q_"=("_$ze(list,2,MAXSTRLEN)_")"	; strip out leading "," from list hence the 2 in $ze
+	. . i tmpval=val q
+	. . s type=$get(syntab("TEMPLATE","REGION",q,"TYPE"))	; note: possible this is ""
+	. . i (type'="")&($data(typevalue("NUM2STR",type))) w " "_delim_q_"="_typevalue("NUM2STR",type,val) q
+	. . i synval["NEGATABLE" w " "_delim_$s(val:"",1:"NO")_q q
+	. . d qualadd(" ",delim,q,val)
 	w !,BOL
 	q
+listadd:(list,l,lval)
+	i l="FILE_NAME" d
+	. ; FILE_NAME has to be inside double-quotes or else GDE will parse the remainder of the line as the file name
+	. s list=list_","_l_"="""_$$namedisp(lval,0)_""""	; since file name can have control characters use "namedisp"
+	e  s list=list_","_l_"="_lval
+	q
+qualadd:(prefix,delim,qual,val)
+	i qual="FILE_NAME" d
+	. ; FILE_NAME has to be inside double-quotes or else GDE will parse the remainder of the line as the file name
+	. w " "_delim_q_"="""_$$namedisp(val,0)_""""		; since file name can have control characters use "namedisp"
+	e  w prefix_delim_q_"="_val
+	q
 SEGMENT
 	i '$d(segs(SEGMENT)) zm gdeerr("OBJNOTFND"):"Segment":SEGMENT q
 	d s2
@@ -119,7 +197,7 @@ s1:	d seghd s s=""
 	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD") d oneseg
 	q
 oneseg:
-	w !,BOL,?x(1),s,?x(2),segs(s,"FILE_NAME")
+	w !,BOL,?x(1),s,?x(2),$$namedisp(segs(s,"FILE_NAME"),1)
 	i $x'<(x(3)-1) w !,BOL
 	w ?x(3),segs(s,"ACCESS_METHOD")
 	i am="USER" q
@@ -132,55 +210,64 @@ BG	w ?x(8),"GLOB=",$j(segs(s,"GLOBAL_BUFFER_COUNT"),4)
 	w !,BOL,?x(8),"RES =",$j(segs(s,"RESERVED_BYTES"),4)
 	; For non-encryption platforms, always show FLAG as OFF. For VMS dont even display this line
 	i $ZVersion'["VMS" w !,BOL,?x(8),"ENCR=",$S((encsupportedplat=TRUE&segs(s,"ENCRYPTION_FLAG")):"ON",1:"OFF")
+	w !,BOL,?x(8),"MSLT=",$j(segs(s,"MUTEX_SLOTS"),4)
 	q
 MM	w ?x(8),$s(segs(s,"DEFER"):"DEFER",1:"NODEFER")
 	w !,BOL,?x(8),"LOCK=",$j(segs(s,"LOCK_SPACE"),4)
-	w !,BOL,?x(8),"RES = ",$j(segs(s,"RESERVED_BYTES"),4)
+	w !,BOL,?x(8),"RES =",$j(segs(s,"RESERVED_BYTES"),4)
 	i $ZVersion'["VMS" w !,BOL,?x(8),"ENCR=OFF"
+	w !,BOL,?x(8),"MSLT=",$j(segs(s,"MUTEX_SLOTS"),4)
 	q
 segmentc:
-	n defseen,cmd
-	s s="",defseen=FALSE
-	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD") d
-	. i s=defseg s defseen=TRUE,cmd="CHANGE"
-	. e  s cmd="ADD"
-	. w !,cmd," "_delim_"SEGMENT ",s," "_delim_"ACCESS_METHOD=",segs(s,"ACCESS_METHOD")
-	. i am="USER" q
-	. f q="BLOCK_SIZE","ALLOCATION","EXTENSION_COUNT","LOCK_SPACE","RESERVED_BYTES" w " "_delim,q,"=",segs(s,q)
-	. i "BG"=am d
-	.. w " "_delim_"GLOBAL_BUFFER_COUNT=",segs(s,"GLOBAL_BUFFER_COUNT")
-	.. i $zver'["VMS",encsupportedplat=TRUE,segs(s,"ENCRYPTION_FLAG") w " "_delim_"ENCRYPT"
-	. i "MM"=am w " "_delim,$s(segs(s,"DEFER"):"DEFER",1:"NODEFER")
-	. w " "_delim_"FILE=",segs(s,"FILE_NAME")
-	i (FALSE=defseen) w !,"DELETE "_delim_"SEGMENT "_defseg
+	n s,q,val,synval,tmpval,type,am
+	s s=""
+	w !,"DELETE "_delim_"SEGMENT "_defseg
+	f  s s=$o(segs(s)) q:'$l(s)  d
+	. s am=segs(s,"ACCESS_METHOD")
+	. w !,"ADD "_delim_"SEGMENT ",s
+	. i tmpacc'=am w " "_delim_"ACCESS_METHOD=",am
+	. s q=""
+	. f  s q=$o(syntab("TEMPLATE","SEGMENT",q)) q:""=q  d
+	. . i q="ACCESS_METHOD" q  ; already processed
+	. . s synval=syntab("TEMPLATE","SEGMENT",q)
+	. . i synval["LIST" d ABORT^GDE	; segmentc is not designed to handle LIST in segment qualifiers.
+	. . s val=segs(s,q)
+	. . s tmpval=$get(tmpseg(am,q))
+	. . i tmpval=val q
+	. . s type=$get(syntab("TEMPLATE","SEGMENT",q,"TYPE"))	; note: possible this is ""
+	. . i (type'="")&($data(typevalue("NUM2STR",type))) w " "_delim_q_"="_typevalue("NUM2STR",type,val) q
+	. . i synval["NEGATABLE" w " "_delim_$s(val:"",1:"NO")_q q
+	. . d qualadd(" ",delim,q,val)
 	w !,BOL
 	q
 MAP
-	n map
+	n map,mapdisp,mapdispmaxlen
 	i '$d(mapreg) n mapreg s mapreg=""
 	e  i '$d(regs(mapreg)) zm gdeerr("OBJNOTFND"):"Region":mapreg q
-	d SHOWMAKE^GDEMAP
-	d m1
+	d NAM2MAP^GDEMAP,m1
 	i log s BOL="!" u @uself w BOL d m1 w ! u @useio s BOL=""
 	q
 m1:	n l1,s1,s2
+	s mapdispmaxlen=0 d mapdispcalc
 	d maphd
 	s s1=$o(map("$"))
 	i s1'="%" s map("%")=map("$"),s1="%"
-	f  s s2=s1,s1=$o(map(s2)) q:'$l(s1)  d onemap(s1,s2)
+	f  s s2=s1,s1=$o(map(s2)) q:'$zl(s1)  d onemap(s1,s2)
 	d onemap("...",s2)
 	i $d(nams("#")) s s2="LOCAL LOCKS",map(s2)=nams("#") d onemap("",s2) k map(s2)
 	q
 onemap:(s1,s2)
 	i $l(mapreg),mapreg'=map(s2) q
-	s l1=$l(s1)
-	i $l(s2)=l1,$e(s1,l1)=0,$e(s2,l1)=")",$e(s1,1,l1-1)=$e(s2,1,l1-1) q
-	w !,BOL,?x(1),$tr(s2,")","0"),?x(2),$tr(s1,")","0"),?x(3),"REG = ",map(s2)
+	s l1=$zl(s1)
+	i $zl(s2)=l1,$ze(s1,l1)=0,$ze(s2,l1)=")",$ze(s1,1,l1-1)=$ze(s2,1,l1-1) q
+	i '$d(mapdisp(s1)) s mapdisp(s1)=s1 ; e.g. "..." or "LOCAL LOCKS"
+	i '$d(mapdisp(s2)) s mapdisp(s2)=s2 ; e.g. "..." or "LOCAL LOCKS"
+	w !,BOL,?x(1),mapdisp(s2),?x(2),mapdisp(s1),?x(3),"REG = ",map(s2)
 	i '$d(regs(map(s2),"DYNAMIC_SEGMENT")) d  q
 	. w !,BOL,?x(3),"SEG = NONE",!,BOL,?x(3),"FILE = NONE"
 	s j=regs(map(s2),"DYNAMIC_SEGMENT") w !,BOL,?x(3),"SEG = ",j
 	i '$d(segs(j,"ACCESS_METHOD")) w !,BOL,?x(3),"FILE = NONE"
-	e  s s=segs(j,"FILE_NAME") w !,BOL,?x(3),"FILE = ",s
+	e  s s=segs(j,"FILE_NAME") w !,BOL,?x(3),"FILE = ",$$namedisp(s,1)
 	q
 TEMPLATE
 	d t1
@@ -205,14 +292,16 @@ t1:	d tmpreghd
 	w !,BOL,?x(8),"LOCK =",$j(tmpseg("BG","LOCK_SPACE"),3)
 	w !,BOL,?x(8),"RES  =",$j(tmpseg("BG","RESERVED_BYTES"),4)
 	i $ZVersion'["VMS" w !,BOL,?x(8),"ENCR = ",$s((encsupportedplat=TRUE&tmpseg("BG","ENCRYPTION_FLAG")):"ON",1:"OFF")
+	w !,BOL,?x(8),"MSLT =",$j(tmpseg("BG","MUTEX_SLOTS"),4)
 	w !,BOL,?x(1),"<default>",?x(2),$s(tmpacc="MM":"   *",1:""),?x(3),"MM"
 	w ?x(4),$s(tmpseg("MM","FILE_TYPE")="DYNAMIC":"DYN",1:"STA"),?x(5),$j(tmpseg("MM","BLOCK_SIZE"),5)
 	w ?x(6),$j(tmpseg("MM","ALLOCATION"),10),?x(7),$j(tmpseg("MM","EXTENSION_COUNT"),5)
 	w ?x(8),$s(tmpseg("MM","DEFER"):"DEFER",1:"NODEFER")
 	w !,BOL,?x(8),"LOCK =",$j(tmpseg("MM","LOCK_SPACE"),3)
+	w !,BOL,?x(8),"MSLT =",$j(tmpseg("MM","MUTEX_SLOTS"),3)
 	q
 tmpjnlbd:
-	w !,BOL,?x(1),"<default>",?x(2),$s($l(tmpreg("FILE_NAME")):tmpreg("FILE_NAME"),1:"<based on DB file-spec>")
+	w !,BOL,?x(1),"<default>",?x(2),$s($zl(tmpreg("FILE_NAME")):$$namedisp(tmpreg("FILE_NAME"),1),1:"<based on DB file-spec>")
 	i $x'<(x(3)-1) w !,BOL
 	w ?x(3),$s(tmpreg("BEFORE_IMAGE"):"Y",1:"N"),?x(4),$j(tmpreg("BUFFER_SIZE"),5)
 	w ?x(5),$j(tmpreg("ALLOCATION"),10)
@@ -221,33 +310,105 @@ tmpjnlbd:
 	w !,BOL
 	q
 templatec:
-	f am="MM","BG" w !,"TEMPLATE "_delim_"SEGMENT "_delim_"ACCESS_METHOD=",am d
-	. f q="BLOCK_SIZE","ALLOCATION","EXTENSION_COUNT","LOCK_SPACE","RESERVED_BYTES" w " "_delim,q,"=",tmpseg(am,q)
-	. i "BG"=am d
-	.. w " "_delim_"GLOBAL_BUFFER_COUNT=",tmpseg("BG","GLOBAL_BUFFER_COUNT")
-	.. i $zver'["VMS",encsupportedplat=TRUE,tmpseg("BG","ENCRYPTION_FLAG") w " "_delim_"ENCRYPT"
-	. i "MM"=am w " ",$s(tmpseg("MM","DEFER"):delim,1:delim_"NO"),"DEFER"
-	w !,"TEMPLATE "_delim_"REGION"
-	f q="RECORD_SIZE","KEY_SIZE" w " "_delim,q,"=",tmpreg(q)
-	w " "_delim_"NULL_SUBSCRIPTS=",$s(tmpreg("NULL_SUBSCRIPTS")=1:"ALWAYS",tmpreg("NULL_SUBSCRIPTS")=2:"EXISTING",1:"NEVER")
-	i tmpreg("STDNULLCOLL") w " "_delim_"STDNULLCOLL"
-	i (ver'="VMS") w " "_delim_$s(tmpreg("INST_FREEZE_ON_ERROR"):"",1:"NO")_"INST_FREEZE_ON_ERROR"
-	i (ver'="VMS") w " "_delim_$s(tmpreg("QDBRUNDOWN"):"",1:"NO")_"QDBRUNDOWN"
-	i tmpreg("JOURNAL") d
-	. w !,"TEMPLATE "_delim_"REGION "_delim_"JOURNAL=("
-	. w $s(tmpreg("BEFORE_IMAGE"):"",1:"NO"),"BEFORE_IMAGE,BUFFER_SIZE=",tmpreg("BUFFER_SIZE")
-	. w ",ALLOCATION=",tmpreg("ALLOCATION"),",EXTENSION=",tmpreg("EXTENSION")
-	. i ver'="VMS" w ",AUTOSWITCHLIMIT=",tmpreg("AUTOSWITCHLIMIT")
-	. w ")"
-	i $l(tmpreg("FILE_NAME")) w ",FILE=",tmpreg("FILE_NAME")
+	; ---------------------------------------------------------
+	; dump TEMPLATE -REGION section
+	; ---------------------------------------------------------
+	n q,synval,tmpval,type,cmd,defercnt,defercmd,i,am,s,freq,freqx,val
+	; compute template values that are most common across regions and store these into tmpreg
+	s s=""
+	f  s s=$o(regs(s)) q:'$l(s)  d
+	. s q=""
+	. f  s q=$o(tmpreg(q)) q:'$l(q)  d
+	. . i tmpreg(q)="" q  ; if this qualifier has a "" template value, then skip processing it (e.g. "FILE_NAME")
+	. . s val=regs(s,q)
+	. . s freq=$incr(freq(q,val))
+	. . s freqx(q,freq)=val
+	f  s q=$o(tmpreg(q)) q:'$l(q)  d
+	. i tmpreg(q)="" q  ; if this qualifier has a "" template value, then skip processing it (e.g. "FILE_NAME")
+	. s freq=$o(freqx(q,""),-1)
+	. s val=freqx(q,freq)
+	. s tmpreg(q)=val
+	; compute template values that are most common across segments and store these into tmpseg
+	k freq,freqx
+	s s=""
+	f  s s=$o(segs(s)) q:'$l(s)  d
+	. s am=segs(s,"ACCESS_METHOD")
+	. s q=""
+	. f  s q=$o(tmpseg(am,q)) q:'$l(q)  d
+	. . s val=segs(s,q)
+	. . s freq=$incr(freq(am,q,val))
+	. . s freqx(am,q,freq)=val
+	s am=""
+	f  s am=$o(freqx(am)) q:'$l(am)  d
+	. s q=""
+	. f  s q=$o(tmpseg(am,q)) q:'$l(q)  d
+	. . s freq=$o(freqx(am,q,""),-1)
+	. . s val=freqx(am,q,freq)
+	. . s tmpseg(am,q)=val
+	; use more optimal templates (tmpreg/tmpseg) while generating template commands below
+	s q=""
+	s cmd="TEMPLATE "_delim_"REGION ",defercmd="",defercnt=0
+	f  s q=$o(syntab("TEMPLATE","REGION",q)) q:""=q  d
+	. s synval=syntab("TEMPLATE","REGION",q)
+	. s tmpval=$get(tmpreg(q))
+	. i (tmpval="") q	 ; if this qualifier does not have a non-default template value, never mind
+	. i synval["LIST" d  q
+	. . ; special processing since this option can in turn be an option-list
+	. . n l,list,lsynval,ltype
+	. . i (synval["NEGATABLE")&(0=tmpval) s defercmd($incr(defercnt))=cmd_delim_"NO"_q
+	. . s list="",l=""
+	. . f  s l=$o(syntab("TEMPLATE","REGION",q,l)) q:""=l  d
+	. . . s lval=tmpreg(l)
+	. . . s ltype=$get(syntab("TEMPLATE","REGION",q,l,"TYPE"))	; note: possible this is "" for e.g. "BEFORE_IMAGE")
+	. . . i (ltype'="")&($data(typevalue("NUM2STR",ltype))) s list=list_","_l_"="_typevalue("NUM2STR",ltype,lval) q
+	. . . s lsynval=syntab("TEMPLATE","REGION",q,l)
+	. . . i lsynval["NEGATABLE" s list=list_","_$s(lval:"",1:"NO")_l q
+	. . . i (lval="") q	 ; if this qualifier is not applicable to this platform, never mind
+	. . . s list=list_","_l_"="_lval
+	. . i list="" q
+	. . w !,cmd_delim_q_"=("_$ze(list,2,MAXSTRLEN)_")"	; strip out leading "," from list hence the 2 in $ze
+	. s type=$get(syntab("TEMPLATE","REGION",q,"TYPE"))	; note: possible this is ""
+	. i (type'="")&($data(typevalue("NUM2STR",type))) w !,cmd_delim_q_"="_typevalue("NUM2STR",type,tmpval) q
+	. i synval["NEGATABLE" w !,cmd_delim_$s(tmpval:"",1:"NO")_q q
+	. w !
+	. d qualadd(cmd,delim,q,tmpval)
+	w !,BOL
+	f i=1:1:defercnt write !,defercmd(i)	; finish off deferred work (if any)
+	w !,BOL
+	; ---------------------------------------------------------
+	; dump TEMPLATE -SEGMENT -ACCESS_METHOD=MM,BG,USER section
+	; ---------------------------------------------------------
+	s cmd="TEMPLATE "_delim_"SEGMENT "
+	s am=""
+	f  s am=$o(tmpseg(am)) q:""=am  d
+	. w !,cmd,delim_"ACCESS_METHOD=",am
+	. s q=""
+	. f  s q=$o(syntab("TEMPLATE","SEGMENT",q)) q:""=q  d
+	. . i q="ACCESS_METHOD" q  ; already processed
+	. . s synval=syntab("TEMPLATE","SEGMENT",q)
+	. . i synval["LIST" d ABORT^GDE	; segmentc is not designed to handle LIST in segment qualifiers.
+	. . s tmpval=$get(tmpseg(am,q))
+	. . i (tmpval="") q	 ; if this qualifier does not have a non-default template value, never mind
+	. . s type=$get(syntab("TEMPLATE","SEGMENT",q,"TYPE"))	; note: possible this is ""
+	. . i (type'="")&($data(typevalue("NUM2STR",type))) w !,cmd_delim_l_"="_typevalue("NUM2STR",type,tmpval) q
+	. . i synval["NEGATABLE" w !,cmd_delim_$s(tmpval:"",1:"NO")_q q
+	. . w !
+	. . d qualadd(cmd,delim,q,tmpval)
+	. w !,BOL
+	w !,cmd,delim_"ACCESS_METHOD="_tmpacc
 	w !,BOL
 	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
 
 namehd:
-	s x(0)=9,x(1)=1,x(2)=36
+	s x(0)=9,x(1)=1,x(2)=$s(x(1)+2+namedispmaxlen'>36:36,1:namedispmaxlen+x(1)+2)
 	w !,BOL,!,BOL,?x(0),"*** NAMES ***",!,BOL,?x(1),"Global",?x(2),"Region"
+	w !,BOL,?x(1),$tr($j("",$s(x(2)=36:78,1:x(2)+32))," ","-")
+	q
+gblnamehd:
+	s x(0)=9,x(1)=1,x(2)=36,x(3)=42
+	w !,BOL,!,BOL,?x(0),"*** GBLNAMES ***",!,BOL,?x(1),"Global",?x(2),"Coll",?x(3),"Ver"
 	w !,BOL,?x(1),$tr($j("",78)," ","-")
 	q
 regionhd:
@@ -291,11 +452,12 @@ seghd:
 	q
 maphd:
 	s x="*** MAP"_$s($l(mapreg):" for region "_mapreg,1:"")_" ***"
-	s x(0)=80-$l(x)*.5,x(1)=1,x(2)=33,x(3)=66,x(4)=98,x(5)=130
+	s mapdispmaxlen=$s(mapdispmaxlen<32:32,1:mapdispmaxlen+2)
+	s x(0)=80-$l(x)*.5,x(1)=1,x(2)=x(1)+mapdispmaxlen,x(3)=x(2)+mapdispmaxlen+1
 	w !,BOL,!,BOL,?x(0),x
 	w !,BOL,?x(1),"  -  -  -  -  -  -  -  -  -  - Names -  -  - -  -  -  -  -  -  -"
 	w !,BOL,?x(1),"From",?x(2),"Up to",?x(3),"Region / Segment / File(def ext: .dat)"
-	w !,BOL,?x(1),$tr($j("",122)," ","-")
+	w !,BOL,?x(1),$tr($j("",$s(x(3)=66:122,1:x(3)+38))," ","-")
 	q
 tmpreghd:
 	s x(0)=31,x(1)=1,x(2)=19,x(3)=44,x(4)=49
@@ -335,3 +497,87 @@ tmpseghd:
 	w ?x(7),"Exten",?x(8),"Options"
 	w !,BOL,?x(1),$tr($j("",78)," ","-")
 	q
+namscollatecalc:
+	; we want subscripted names printed in collating order of subscripts (so x(2) gets printed before x(10))
+	; whereas they would stored in the "nams" array as nams("x(2)") preceded by nams("x(10)")
+	; so determine the gds representation of the names and sort based on that (this automatically includes collation too).
+	n s,type,nsubs,gvn,key,coll,keylen,i
+	k namscollate
+	s s=""
+	f  s s=$o(nams(s)) q:'$zl(s)  d
+	. s type=$g(nams(s,"TYPE")),nsubs=$g(nams(s,"NSUBS"))
+	. i (""=type)!(0=nsubs) s namscollate(s)=s q  ; if not a subscripted name process right away
+	. i "POINT"=type s gvn="^"_nams(s,"NAME")
+	. e  s gvn="^"_nams(s,"GVNPREFIX")_nams(s,"SUBS",nsubs-1)_")"  ; type="RANGE"
+	. s coll=+$g(gnams(nams(s,"SUBS",0),"COLLATION"))
+	. s key=$$gvn2gds^GDEMAP(gvn,coll)
+	. s key=$ze(key,1,$zl(key)-2)  ; remove trailing 00 00
+	. i "RANGE"=type d
+	. . ; Some processing needed so X(2,4:5) (a range) comes AFTER X(2,4,5:"") (a point within X(2,4)).
+	. . ; Add a 01 at the end of the left subscript of a range.
+	. . s key=key_ONE
+	. ; ASSERT : i $d(namscollate(key)) zsh "*"  h  ; assert that checks for duplicate keys
+	. s namscollate(key)=s
+	q
+namedisp(name,addquote)
+	; returns a name that is displayable (i.e. if it contains control characters, they are replaced by $c() etc.)
+	; if addquote=0, no surrounding double-quotes are added.
+	; if addquote=1 and control characters are seen (which will cause _$c(...) to be added)
+	;	we will surround string with double-quotes before returning.
+	n namezwrlen,namezwr,namedisplen,namedisp,ch,quotestate,starti,i,seenquotestate3
+	s namezwr=$zwrite(name) ; this will convert all control characters to $c()/$zc() notation
+	; But $zwrite will introduce more double-quotes than we want to display; so remove them
+	; e.g. namezwr = "MODELNUM("""_$C(0)_""":"""")"
+	s namezwrlen=$zl(namezwr),namedisp="",doublequote=""""
+	s namedisp="",namedisplen=0,quotestate=0
+	f i=1:1:namezwrlen  s ch=$ze(namezwr,i) d
+	. i (quotestate=0) d  q
+	. . i (ch=doublequote) s quotestate=1,starti=i+1  q
+	. . ; We expect ch to be "$" here
+	. . s quotestate=3
+	. i (quotestate=1) d  q
+	. . i ch'=doublequote q
+	. . s quotestate=2  s namedisp=namedisp_$ze(namezwr,starti,i-1),namedisplen=namedisplen+(i-starti),starti=i+1 q
+	. i (quotestate=2) d  q
+	. . ; At this point ch can be either doublequote or "_"
+	. . s quotestate=$s(ch=doublequote:1,1:0)
+	. . i ch="_" d  q
+	. . . i (($ze(namedisp,namedisplen)'=doublequote)!($ze(namedisp,namedisplen-1)=doublequote)) d  q
+	. . . . s starti=(i-1) ; include previous double-quote
+	. . . ; remove extraneous ""_ before $c()
+	. . . s namedisp=$ze(namedisp,1,namedisplen-1),namedisplen=namedisplen-1,starti=i+1
+	. i (quotestate=3) d  q
+	. . s seenquotestate3=1
+	. . i (ch=doublequote) s quotestate=1 q
+	. . i ((ch="_")&($ze(namezwr,i+1,i+3)=(doublequote_doublequote_doublequote))&($ze(namezwr,i+4)'=doublequote))  d  q
+	. . . ; remove extraneous _"" after $c()
+	. . . s namedisp=namedisp_$ze(namezwr,starti,i-1),namedisplen=namedisplen+(i-starti),starti=i+4,quotestate=1,i=i+3 q
+	i addquote&$d(seenquotestate3) s namedisp=doublequote_namedisp_doublequote
+	; 2 and 3 are the only terminating states; check that. that too 3 only if addquote is 1.
+	; ASSERT : i '((quotestate=2)!(addquote&(quotestate=3)))  zsh "*"  h
+	q namedisp
+namedisplaycalc:(name)
+	; if name is subscripted, make sure control characters are displayed in $c() notation
+	n namedisplen,namedisp
+	i +$g(nams(name,"NSUBS"))=0 s namsdisp(name)=name q  ; unsubscripted case; return right away
+	s namedisp=$$namedisp(name,0)
+	s namsdisp(name)=namedisp,namedisplen=$zwidth(namedisp)
+	i namedispmaxlen<namedisplen s namedispmaxlen=namedisplen
+	q
+mapdispcalc:
+	n m,gblname,offset,coll,isplusplus,mlen,mtmp,name,mapdisplen,namelen,namedisp
+	s m=""
+	f  s m=$o(map(m)) q:'$zl(m)  d
+	. i $l(mapreg),(mapreg'=map(m)) q
+	. s offset=$zfind(m,ZERO,0)
+	. i offset=0  s mapdisp(m)=$tr(m,")","0") q  ; no subscripts case. finish it off first
+	. s gblname=$ze(m,1,offset-2),coll=+$g(gnams(gblname,"COLLATION")),mlen=$zl(m)
+	. s isplusplus=$$isplusplus^GDEMAP(m,mlen)
+	. s mtmp=$s(isplusplus:$ze(m,1,mlen-1),1:m)  ; if ++ type map entry, remove last 01 byte before converting it into gvn
+	. s name=$view("YGDS2GVN",mtmp_ZERO_ZERO,coll)
+	. i isplusplus s name=name_"++"
+	. s namelen=$zl(name),name=$ze(name,2,namelen) ; remove '^' at start of name
+	. s namedisp=$$namedisp(name,0)
+	. s mapdisp(m)=namedisp,mapdisplen=$zwidth(namedisp)
+	. i mapdispmaxlen<mapdisplen s mapdispmaxlen=mapdisplen
+	q
diff --git a/sr_port/gdetempl.m b/sr_port/gdetempl.m
index 1444da8..9a56844 100644
--- a/sr_port/gdetempl.m
+++ b/sr_port/gdetempl.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -12,7 +12,6 @@ template:	;implement the verb: TEMPLATE
 REGION
 	i $d(lquals("JOURNAL")),lquals("JOURNAL"),'tmpreg("JOURNAL"),'$d(lquals("BEFORE_IMAGE")) d
 	. zm gdeerr("QUALREQD"):"Before_image"
-	i $d(lquals("NULL_SUBSCRIPTS")) d NQUALS^GDEVERIF(.lquals)
 	i '$$TRQUALS^GDEVERIF(.lquals) zm gdeerr("OBJNOTCHG"):"region":"template"
 	s update=1,s=""
 	f  s s=$o(lquals(s)) q:'$l(s)  s tmpreg(s)=lquals(s) i s="ALLOCATION" s tmpreg("EXTENSION")=lquals(s)\10
diff --git a/sr_port/gdsbml.h b/sr_port/gdsbml.h
index da27e4d..00f05c8 100644
--- a/sr_port/gdsbml.h
+++ b/sr_port/gdsbml.h
@@ -69,6 +69,7 @@
 #define EXTEND_SUSPECT		-3
 #define FILE_EXTENDED		-4
 #define FINAL_RETRY_FREEZE_PROG	-5
+#define FINAL_RETRY_INST_FREEZE	-6
 
 #define	GET_CDB_SC_CODE(gdsfilext_code, status)			\
 {								\
@@ -80,6 +81,8 @@
 		status = cdb_sc_gbloflow;			\
 	else if (FINAL_RETRY_FREEZE_PROG == gdsfilext_code)	\
 		status = cdb_sc_needcrit;			\
+	else if (FINAL_RETRY_INST_FREEZE == gdsfilext_code)	\
+		status = cdb_sc_instancefreeze;			\
 }
 
 #define MASTER_MAP_BITS_PER_LMAP	1
diff --git a/sr_port/gdsbt.h b/sr_port/gdsbt.h
index 8856aef..64f9115 100644
--- a/sr_port/gdsbt.h
+++ b/sr_port/gdsbt.h
@@ -592,9 +592,9 @@ typedef struct node_local_struct
 #define BT_NOT_ALIGNED(bt, bt_base)		(!IS_PTR_ALIGNED((bt), (bt_base), SIZEOF(bt_rec)))
 #define BT_NOT_IN_RANGE(bt, bt_lo, bt_hi)	(!IS_PTR_IN_RANGE((bt), (bt_lo), (bt_hi)))
 
-#define MIN_CRIT_ENTRY				1024
-#define MAX_CRIT_ENTRY				32768
-#define DEFAULT_NUM_CRIT_ENTRY			1024
+#define MIN_CRIT_ENTRY				64		/* keep this in sync with gdeinit.m minseg("MUTEX_SLOTS") */
+#define MAX_CRIT_ENTRY				32768		/* keep this in sync with gdeinit.m maxseg("MUTEX_SLOTS") */
+#define DEFAULT_NUM_CRIT_ENTRY			1024		/* keep this in sync with gdeget.m tmpseg("MUTEX_SLOTS") */
 #define NUM_CRIT_ENTRY(CSD)			(CSD)->mutex_spin_parms.mutex_que_entry_space_size
 #define CRIT_SPACE(ENTRIES)			((ENTRIES) * SIZEOF(mutex_que_entry) + SIZEOF(mutex_struct))
 #define JNLPOOL_CRIT_SPACE			CRIT_SPACE(DEFAULT_NUM_CRIT_ENTRY)
diff --git a/sr_port/gdsfhead.h b/sr_port/gdsfhead.h
index eba3477..810a0eb 100644
--- a/sr_port/gdsfhead.h
+++ b/sr_port/gdsfhead.h
@@ -35,13 +35,17 @@
 
 #define CACHE_STATE_OFF SIZEOF(que_ent)
 
+error_def(ERR_ACTCOLLMISMTCH);
 error_def(ERR_DBCRERR);
 error_def(ERR_DBENDIAN);
 error_def(ERR_DBFLCORRP);
+error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVIS);
 error_def(ERR_GVSUBOFLOW);
 error_def(ERR_MMFILETOOLARGE);
+error_def(ERR_NCTCOLLSPGBL);
 error_def(ERR_REPLINSTMISMTCH);
+error_def(ERR_REPLINSTNOSHM);
 error_def(ERR_REPLREQROLLBACK);
 error_def(ERR_SCNDDBNOUPD);
 error_def(ERR_SRVLCKWT2LNG);
@@ -49,8 +53,11 @@ error_def(ERR_SSATTACHSHM);
 error_def(ERR_SSFILOPERR);
 error_def(ERR_STACKCRIT);
 error_def(ERR_STACKOFLOW);
+error_def(ERR_TEXT);
 error_def(ERR_TNTOOLARGE);
 error_def(ERR_TNWARN);
+error_def(ERR_TPRETRY);
+error_def(ERR_UNIMPLOP);
 
 /* Cache record */
 typedef struct cache_rec_struct
@@ -251,6 +258,13 @@ void verify_queue(que_head_ptr_t qhdr);
 # define MM_PROT_FLAGS(READ_ONLY)		(READ_ONLY ? PROT_READ : (PROT_READ | PROT_WRITE))
 # define MM_BASE_ADDR(CSA) 			(sm_uc_ptr_t)CSA->db_addrs[0]
 # define SET_MM_BASE_ADDR(CSA, CSD)
+# ifdef _AIX
+#  define MEM_MAP_SYSCALL "shmat()"
+#  define MEM_UNMAP_SYSCALL "shmdt()"
+# else
+#  define MEM_MAP_SYSCALL "mmap()"
+#  define MEM_UNMAP_SYSCALL "munmap()"
+# endif
 #else
 # define MM_BASE_ADDR(CSA)			(sm_uc_ptr_t)CSA->acc_meth.mm.base_addr
 # define SET_MM_BASE_ADDR(CSA, CSD)											\
@@ -259,42 +273,6 @@ void verify_queue(que_head_ptr_t qhdr);
 }
 #endif
 
-/* The following 3 macros were introduced while solving a problem with $view where a call to $view in */
-/* mumps right after a change to $zgbldir gave the old global directory - not the new one.  On VMS it */
-/* caused a core dump.  If one were to access a global variable via $data right after the change, however, */
-/* the $view worked correctly.  The solution was to make sure the gd_map information matched the current */
-/* gd_header in op_fnview.c.  The code used as a template for this change was in gvinit.c.  The first */
-/* macro gets the gd_header using an mval.  The second macro establishes the gd_map from the gd_header. */
-/* The third macro is an assert (when DEBUG_ONLY is defined) for those cases where the gd_header is already */
-/* set to make sure the mapping is correct. The first 2 macros are executed when the gd_header is null, */
-/* and the 3rd macro is associated with an else clause if it is not.  Therefore, they should be maintained */
-/* as a group. */
-
-#define SET_GD_HEADER(inmval)				\
-{							\
-	inmval.mvtype = MV_STR;				\
-	inmval.str.len = 0;				\
-	gd_header = zgbldir(&inmval);			\
-}
-
-#define SET_GD_MAP					\
-{							\
-	GBLREF	gd_binding	*gd_map, *gd_map_top;	\
-							\
-	gd_map = gd_header->maps;			\
-	gd_map_top = gd_map + gd_header->n_maps;	\
-	TREF(gd_targ_addr) = gd_header;			\
-}
-
-#define GD_HEADER_ASSERT					\
-{								\
-	GBLREF	gd_binding	*gd_map, *gd_map_top;		\
-								\
-	assert(gd_map == gd_header->maps);			\
-	assert(gd_map_top == gd_map + gd_header->n_maps);	\
-	assert(TREF(gd_targ_addr) == gd_header);		\
-}
-
 /* If reallocating gv_currkey/gv_altkey, preserve pre-existing values */
 #define	GVKEY_INIT(GVKEY, KEYSIZE)						\
 {										\
@@ -308,8 +286,10 @@ void verify_queue(que_head_ptr_t qhdr);
 	 */									\
 	assert(ROUND_UP2(keySZ, 4) == keySZ);					\
 	new_KEY = (gv_key *)malloc(SIZEOF(gv_key) - 1 + keySZ);			\
+	assert(DBKEYSIZE(MAX_KEY_SZ) == KEYSIZE);				\
 	if (NULL != old_KEY)							\
 	{									\
+		assert(FALSE);	/* dont call GVKEY_INIT twice for same key */	\
 		assert(KEYSIZE >= old_KEY->top);				\
 		assert(old_KEY->top > old_KEY->end);				\
 		memcpy(new_KEY, old_KEY, SIZEOF(gv_key) + old_KEY->end);	\
@@ -333,30 +313,204 @@ void verify_queue(que_head_ptr_t qhdr);
 	}				\
 }
 
-#define	GVKEYSIZE_INCREASE_IF_NEEDED(KEYSIZE)							\
+#define	GVKEYSIZE_INIT_IF_NEEDED									\
+{													\
+	int		keySIZE;									\
+													\
+	GBLREF int4	gv_keysize;									\
+	GBLREF gv_key	*gv_altkey;									\
+	GBLREF gv_key	*gv_currkey;									\
+													\
+	if (!gv_keysize)										\
+	{												\
+		keySIZE = DBKEYSIZE(MAX_KEY_SZ);							\
+		/* Have space to store at least MAX_MIDENT_LEN bytes as otherwise name-level $order	\
+		 * (see op_gvorder/op_zprevious) could have buffer overflow issues in gv_currkey->base.	\
+		 * Do ROUND_UP2(x,4) to keep an assert in GVKEY_INIT macro happy.			\
+		 */											\
+		assert((MAX_MIDENT_LEN + 3) < keySIZE);							\
+		assert(keySIZE);									\
+		gv_keysize = keySIZE;									\
+		GVKEY_INIT(gv_currkey, keySIZE);							\
+		GVKEY_INIT(gv_altkey, keySIZE);								\
+	} else												\
+	{												\
+		assert((NULL != gv_currkey) && (NULL != gv_altkey) && gv_keysize			\
+			&& (DBKEYSIZE(MAX_KEY_SZ) == gv_keysize)					\
+			&& (gv_keysize == gv_currkey->top) && (gv_keysize == gv_altkey->top));		\
+	}												\
+}
+
+/* Transform KEY to look at the immediately next key at the same subscript level as input KEY (like $order(KEY)).
+ * For example if input KEY is ^x(1,2), come up with a key ^x(1,2++).
+ */
+#define	GVKEY_INCREMENT_ORDER(KEY)			\
+{							\
+	int	end;					\
+							\
+	end = KEY->end;					\
+	assert(KEY_DELIMITER == KEY->base[end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[end]);	\
+	assert(end + 1 < KEY->top);			\
+	KEY->base[end - 1] = 1;				\
+	KEY->base[end + 1] = KEY_DELIMITER;		\
+	KEY->end = end + 1;				\
+}
+
+/* Undo work done by GVKEY_INCREMENT_ORDER */
+#define	GVKEY_UNDO_INCREMENT_ORDER(KEY)			\
+{							\
+	int	end;					\
+							\
+	assert(1 < KEY->end);				\
+	end = KEY->end - 1;				\
+	assert(1 == KEY->base[end - 1]);		\
+	assert(KEY_DELIMITER == KEY->base[end]);	\
+	assert(KEY_DELIMITER == KEY->base[end + 1]);	\
+	assert(end + 1 < KEY->top);			\
+	KEY->base[end - 1] = KEY_DELIMITER;		\
+	KEY->base[end + 0] = KEY_DELIMITER;		\
+	KEY->end = end;					\
+}
+
+/* Transform KEY to look at the immediately previous key at the same subscript level as input KEY (like $order(KEY)).
+ * For example if input KEY is ^x(1,2), come up with a key ^x(1,2--).
+ */
+#define	GVKEY_DECREMENT_ORDER(KEY)			\
+{							\
+	int	end;					\
+							\
+	end = KEY->end;					\
+	assert(1 < end);				\
+	assert(KEY_DELIMITER == KEY->base[end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[end]);	\
+	assert(0xFF != KEY->base[end - 2]);		\
+	assert((end + 1) < KEY->top);			\
+	KEY->base[end - 2] -= 1;			\
+	KEY->base[end - 1] = 0xFF;			\
+	KEY->base[end + 1] = KEY_DELIMITER;		\
+	KEY->end = end + 1;				\
+}
+
+/* Undo work done by GVKEY_DECREMENT_ORDER */
+#define	GVKEY_UNDO_DECREMENT_ORDER(KEY)			\
+{							\
+	int	end;					\
+							\
+	assert(2 < KEY->end);				\
+	end = KEY->end - 1;				\
+	assert(0xFF == KEY->base[end - 1]);		\
+	assert(KEY_DELIMITER != KEY->base[end - 2]);	\
+	assert(KEY_DELIMITER == KEY->base[end]);	\
+	assert(KEY_DELIMITER == KEY->base[end + 1]);	\
+	assert((end + 1) < KEY->top);			\
+	KEY->base[end - 2] += 1;			\
+	KEY->base[end - 1] = KEY_DELIMITER;		\
+	KEY->end = end;					\
+}
+/* Transform KEY to look at the immediately next KEY at any subscript level (like $query(KEY)).
+ * For example if input KEY is ^x(1,2), come up with a key ^x(1,2,1) assuming that is the next node.
+ */
+#define	GVKEY_INCREMENT_QUERY(KEY)			\
+{							\
+	int	end;					\
+							\
+	end = KEY->end;					\
+	assert(KEY_DELIMITER == KEY->base[end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[end]);	\
+	assert(end + 2 < KEY->top);			\
+	KEY->base[end] = 1;				\
+	KEY->base[end + 1] = KEY_DELIMITER;		\
+	KEY->base[end + 2] = KEY_DELIMITER;		\
+	KEY->end += 2;					\
+}
+
+/* Transform KEY to look at the immediately previous key at the PREVIOUS subscript level as input KEY.
+ * For example if input KEY is ^x(1,2), come up with a key ^x(1++).
+ */
+#define	GVKEY_INCREMENT_PREVSUBS_ORDER(KEY)			\
+{								\
+	assert(KEY->prev);					\
+	assert(KEY->end > KEY->prev);				\
+	assert(KEY_DELIMITER == KEY->base[KEY->prev - 1]);	\
+	assert(KEY_DELIMITER != KEY->base[KEY->prev]);		\
+	assert(KEY_DELIMITER == KEY->base[KEY->end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[KEY->end]);		\
+	assert(KEY->end + 1 <= KEY->top);			\
+	KEY->base[KEY->prev - 1] = 1;				\
+}
+
+/* Undo work done by GVKEY_INCREMENT_PREVSUBS_ORDER */
+#define	GVKEY_UNDO_INCREMENT_PREVSUBS_ORDER(KEY)		\
+{								\
+	assert(KEY->prev);					\
+	assert(KEY->end > KEY->prev);				\
+	assert(1 == KEY->base[KEY->prev - 1]);			\
+	assert(KEY_DELIMITER != KEY->base[KEY->prev]);		\
+	assert(KEY_DELIMITER == KEY->base[KEY->end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[KEY->end]);		\
+	assert(KEY->end + 1 <= KEY->top);			\
+	KEY->base[KEY->prev - 1] = KEY_DELIMITER;		\
+}
+
+/* Transform KEY to look at the "" subscript at same subscript level as input KEY.
+ * For example if input KEY is ^x(1,2), come up with a key ^x(1,"").
+ */
+#define	GVKEY_SET_SUBS_ZPREVIOUS(KEY, SAVECH)			\
+{								\
+	assert(KEY->prev);					\
+	assert(KEY->end > KEY->prev);				\
+	assert(KEY_DELIMITER == KEY->base[KEY->prev - 1]);	\
+	assert(KEY_DELIMITER != KEY->base[KEY->prev]);		\
+	assert(KEY_DELIMITER == KEY->base[KEY->end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[KEY->end]);		\
+	assert(KEY->end + 1 <= KEY->top);			\
+	SAVECH = KEY->base[KEY->prev];				\
+	KEY->base[KEY->prev] = 1;				\
+}
+
+/* Undo work done by GVKEY_SET_SUBS_ZPREVIOUS */
+#define	GVKEY_UNDO_SET_SUBS_ZPREVIOUS(KEY, SAVECH)		\
+{								\
+	assert(KEY->prev);					\
+	assert(KEY->end > KEY->prev);				\
+	assert(1 == KEY->base[KEY->prev]);			\
+	assert(KEY_DELIMITER == KEY->base[KEY->prev - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[KEY->end - 1]);	\
+	assert(KEY_DELIMITER == KEY->base[KEY->end]);		\
+	assert(KEY->end + 1 <= KEY->top);			\
+	KEY->base[KEY->prev] = SAVECH;				\
+}
+
+/* This macro is used whenever we have found a MAP where a key KEYBASE maps to (using "gv_srch_map*" functions).
+ * If the MAP entry one before EXACTLY matches the KEY, then some callers might want to see MAP-1 instead of MAP.
+ * It is upto the caller to decide which one they want. By default they get MAP from gv_srch_map and can invoke
+ * this macro to get MAP-1 in that special case.
+ */
+#define	BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(KEYBASE, KEYLEN, MAP)				\
+{												\
+	if (!memcmp(KEYBASE, ((MAP) - 1)->gvkey.addr, KEYLEN))					\
+	{	/* KEYBASE starts at "MAP" which means, all keys of interest (just one before	\
+		 * the incremented key) can never map to "MAP" so back off one map entry.	\
+		 */										\
+		(MAP)--;									\
+	}											\
+}
+
+/* Calculate the # of subscripts in "KEY" and stores that in "NSUBS" */
+#define	GET_NSUBS_IN_GVKEY(PTR, LEN, NSUBS)							\
 {												\
-	int		keySIZE;								\
-												\
-	GBLREF int4	gv_keysize;								\
-	GBLREF gv_key	*gv_altkey;								\
-	GBLREF gv_key	*gv_currkey;								\
+	unsigned char	*ptr, *ptrtop;								\
+	int		nSubs;									\
 												\
-	keySIZE = KEYSIZE;									\
-	/* Have space to store at least MAX_MIDENT_LEN bytes as otherwise name-level $order	\
-	 * (see op_gvorder/op_zprevious) could have buffer overflow issues in gv_currkey->base.	\
-	 * Do ROUND_UP2(x,4) to keep an assert in GVKEY_INIT macro happy.			\
-	 */											\
-	if ((MAX_MIDENT_LEN + 3) > keySIZE)							\
-		keySIZE = ROUND_UP2(MAX_MIDENT_LEN + 3, 4);					\
-	assert(keySIZE);									\
-	if (keySIZE > gv_keysize)								\
-	{											\
-		gv_keysize = keySIZE;								\
-		GVKEY_INIT(gv_currkey, keySIZE);						\
-		GVKEY_INIT(gv_altkey, keySIZE);							\
-	} else											\
-		assert((NULL != gv_currkey) && (NULL != gv_altkey) && gv_keysize		\
-			&& (gv_keysize == gv_currkey->top) && (gv_keysize == gv_altkey->top));	\
+	ptr = (unsigned char *)PTR;								\
+	ptrtop  = ptr + LEN;									\
+	assert(ptr < ptrtop);									\
+	nSubs = 0;										\
+	for ( ; ptr < ptrtop; ptr++)								\
+		if (KEY_DELIMITER == *ptr)							\
+			nSubs++;								\
+	NSUBS = nSubs;										\
 }
 
 #define WAS_OPEN_TRUE		TRUE
@@ -364,30 +518,31 @@ void verify_queue(que_head_ptr_t qhdr);
 
 /* Below macro sets open, opening and was_open fields of a given region after the corresponding
  * database for that region is opened. Also, if the region was not already open, the macro
- * invokes GVKEYSIZE_INCREASE_IF_NEEDED to allocate gv_currkey/gv_altkey based on the region's
- * max_key_size.
+ * invokes GVKEYSIZE_INIT_IF_NEEDED to allocate gv_currkey/gv_altkey if not already done.
  */
-#define SET_REGION_OPEN_TRUE(REG, WAS_OPEN)							\
-{												\
-	DEBUG_ONLY(GBLREF int4	gv_keysize;)							\
-												\
-	assert(!REG->was_open);									\
-	assert(!REG->open);									\
-	REG->open = TRUE;									\
-	REG->opening = FALSE;									\
-	if (WAS_OPEN)										\
-	{											\
-		REG->was_open = TRUE;								\
-		assert(DBKEYSIZE(REG->max_key_size) <= gv_keysize);				\
-	}											\
-	else											\
-		GVKEYSIZE_INCREASE_IF_NEEDED(DBKEYSIZE(REG->max_key_size));			\
+#define SET_REGION_OPEN_TRUE(REG, WAS_OPEN)									\
+{														\
+	DEBUG_ONLY(GBLREF int4	gv_keysize;)									\
+														\
+	assert(!REG->was_open);											\
+	assert(!REG->open);											\
+	REG->open = TRUE;											\
+	REG->opening = FALSE;											\
+	if (WAS_OPEN)												\
+	{													\
+		REG->was_open = TRUE;										\
+		assert(DBKEYSIZE(REG->max_key_size) <= gv_keysize);						\
+	} else													\
+		GVKEYSIZE_INIT_IF_NEEDED; /* sets up "gv_keysize", "gv_currkey" and "gv_altkey" in sync */	\
 }
 
+#define	REG_ACC_METH(REG)	(REG->dyn.addr->acc_meth)
+
 #define	SET_CSA_DIR_TREE(csa, keysize, reg)							\
 {												\
 	if (NULL == csa->dir_tree)								\
 	{											\
+		assert((dba_bg == REG_ACC_METH(reg)) || (dba_mm == REG_ACC_METH(reg)));		\
 		csa->dir_tree = targ_alloc(keysize, NULL, reg);					\
 		GTMTRIG_ONLY(assert(NULL == csa->hasht_tree));					\
 	} else											\
@@ -405,21 +560,56 @@ void verify_queue(que_head_ptr_t qhdr);
 		if (NULL != hasht_tree)						\
 		{								\
 			assert(hasht_tree->gd_csa == csa);			\
-			hasht_tree->regcnt--;	/* targ_free relies on this */	\
-			targ_free(hasht_tree);					\
+			/* assert that TARG_FREE_IF_NEEDED will happen below */	\
+			assert(1 == hasht_tree->regcnt);			\
+			TARG_FREE_IF_NEEDED(hasht_tree);			\
 			lcl_csa->hasht_tree = NULL;				\
 		}								\
 	)									\
 	dir_tree = lcl_csa->dir_tree;						\
 	assert(NULL != dir_tree);						\
-	dir_tree->regcnt--;	/* targ_free relies on this */			\
-	targ_free(dir_tree);							\
+	/* assert that TARG_FREE_IF_NEEDED will happen below */			\
+	assert(1 == dir_tree->regcnt);						\
+	TARG_FREE_IF_NEEDED(dir_tree);						\
 	lcl_csa->dir_tree = NULL;						\
 }
 
-#define	PROCESS_GVT_PENDING_LIST(GREG, CSA, GVT_PENDING_LIST)						\
+#define	ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN(REG, GVT_PTR, GVT_PTR2)					\
 {													\
-	if (NULL != GVT_PENDING_LIST)									\
+	gvt_container		*gvtc;									\
+	DEBUG_ONLY(gv_namehead	*gvt;)									\
+													\
+	GBLREF	buddy_list	*gvt_pending_buddy_list;						\
+	GBLREF	gvt_container	*gvt_pending_list;							\
+													\
+	/* For dba_cm or dba_user, dont add to pending list because those regions			\
+	 * will never be opened by the client process (this process).					\
+	 */												\
+	if (!REG->open && ((dba_bg == REG_ACC_METH(REG)) || (dba_mm == REG_ACC_METH(REG))))		\
+	{	/* Record list of all gv_targets that have been allocated BEFORE the			\
+		 * region has been opened. Once the region gets opened, we will re-examine		\
+		 * this list and reallocate them (if needed) since they have now been			\
+		 * allocated using the region's max_key_size value which could potentially		\
+		 * be different from the max_key_size value in the corresponding database		\
+		 * file header.										\
+		 */											\
+		assert(NULL != gvt_pending_buddy_list);	/* should have been allocated by caller */	\
+		DEBUG_ONLY(gvt = *GVT_PTR;)								\
+		assert(NULL == is_gvt_in_pending_list(gvt));	/* do not add duplicates */		\
+		gvtc = (gvt_container *)get_new_free_element(gvt_pending_buddy_list);			\
+		gvtc->gvt_ptr = GVT_PTR;								\
+		gvtc->gvt_ptr2 = GVT_PTR2;								\
+		gvtc->gd_reg = REG;									\
+		gvtc->next_gvtc = (struct gvt_container_struct *)gvt_pending_list;			\
+		gvt_pending_list = gvtc;								\
+	}												\
+}
+
+#define	PROCESS_GVT_PENDING_LIST(GREG, CSA)								\
+{													\
+	GBLREF	gvt_container	*gvt_pending_list;							\
+													\
+	if (NULL != gvt_pending_list)									\
 	{	/* Now that the region has been opened, check if there are any gv_targets that were	\
 		 * allocated for this region BEFORE the open. If so, re-allocate them if necessary.	\
 		 */											\
@@ -427,6 +617,13 @@ void verify_queue(que_head_ptr_t qhdr);
 	}												\
 }
 
+#define	TARG_FREE_IF_NEEDED(GVT)		\
+{						\
+	GVT->regcnt--;				\
+	if (!GVT->regcnt)			\
+		targ_free(GVT);			\
+}
+
 #define		T_COMMIT_CRIT_PHASE1	1	/* csa->t_commit_crit gets set to this in during bg_update_phase1 */
 #define		T_COMMIT_CRIT_PHASE2	2	/* csa->t_commit_crit gets set to this in during bg_update_phase2 */
 
@@ -480,11 +677,11 @@ void verify_queue(que_head_ptr_t qhdr);
 	cache_start = &(CSA)->acc_meth.bg.cache_state->cache_array[0];			\
 	cache_start += CSD->bt_buckets;							\
 	bufstart = (sm_uc_ptr_t)GDS_ANY_REL2ABS((CSA), cache_start->buffaddr);		\
-	bufstart += (gtm_uint64_t)CSD->blk_size * CSD->n_bts;					\
+	bufstart += (gtm_uint64_t)CSD->blk_size * CSD->n_bts;				\
 	assert((PTR) >= bufstart);							\
 	bufindx = (PTR - bufstart) / CSD->blk_size;					\
 	assert(bufindx < CSD->n_bts);							\
-	assert((bufstart + (bufindx * (gtm_uint64_t)CSD->blk_size)) == (PTR));			\
+	assert((bufstart + (bufindx * (gtm_uint64_t)CSD->blk_size)) == (PTR));		\
 }
 
 #define	DBG_ENSURE_OLD_BLOCK_IS_VALID(cse, is_mm, csa, csd)								\
@@ -529,7 +726,7 @@ void verify_queue(que_head_ptr_t qhdr);
 		cache_start = &csa->acc_meth.bg.cache_state->cache_array[0];					\
 		cache_start += csa->hdr->bt_buckets;								\
 		bufstart = (sm_uc_ptr_t)GDS_ANY_REL2ABS(csa, cache_start->buffaddr);				\
-		bufend = bufstart + ((gtm_uint64_t)csa->hdr->n_bts * csa->hdr->blk_size);					\
+		bufend = bufstart + ((gtm_uint64_t)csa->hdr->n_bts * csa->hdr->blk_size);			\
 		bufaddr = (sm_uc_ptr_t)(seg)->addr;								\
 		/* Check if given address is within database shared memory range */				\
 		if ((bufaddr >= bufstart) && (bufaddr < bufend))						\
@@ -605,7 +802,7 @@ void verify_queue(que_head_ptr_t qhdr);
 		cs_data = (sgmnt_data_ptr_t)0;							\
 	} else											\
 	{											\
-		switch (reg->dyn.addr->acc_meth)						\
+		switch (REG_ACC_METH(reg))							\
 		{										\
 			case dba_mm:								\
 			case dba_bg:								\
@@ -618,7 +815,7 @@ void verify_queue(que_head_ptr_t qhdr);
 				cs_data = (sgmnt_data_ptr_t)0;					\
 				break;								\
 			default:								\
-				GTMASSERT;							\
+				assertpro(FALSE);						\
 				break;								\
 		}										\
 	}											\
@@ -630,7 +827,7 @@ void verify_queue(que_head_ptr_t qhdr);
 	if (reg != gv_cur_region)								\
 	{											\
 		gv_cur_region = reg;								\
-		switch (reg->dyn.addr->acc_meth)						\
+		switch (REG_ACC_METH(reg))							\
 		{										\
 			case dba_mm:								\
 			case dba_bg:								\
@@ -644,7 +841,7 @@ void verify_queue(que_head_ptr_t qhdr);
 				cs_data = (sgmnt_data_ptr_t)0;					\
 				break;								\
 			default:								\
-				GTMASSERT;							\
+				assertpro(FALSE);						\
 				break;								\
 		}										\
 	}											\
@@ -688,12 +885,9 @@ void verify_queue(que_head_ptr_t qhdr);
 														\
 	curr_cm_reg_head = (reghead);										\
 	gv_cur_region = curr_cm_reg_head->reg;									\
-	if ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth))	\
-	{													\
-		cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;							\
-		cs_data = cs_addrs->hdr;									\
-	} else													\
-		GTMASSERT;											\
+	assert((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)));		\
+	cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;								\
+	cs_data = cs_addrs->hdr;										\
 }
 
 /* Macro to be used whenever cr->data_invalid needs to be set */
@@ -769,7 +963,7 @@ GBLREF	int4		pin_fail_phase2_commit_pidcnt;	/* Number of processes in phase2 com
 		pin_fail_ref_cnt		= cs_addrs->nl->ref_cnt;				\
 		pin_fail_in_wtstart		= cs_addrs->nl->in_wtstart;				\
 		pin_fail_phase2_commit_pidcnt	= cs_addrs->nl->wcs_phase2_commit_pidcnt;		\
-		GTMASSERT;										\
+		assertpro(0 == in_cw_set);								\
 	}												\
 	/* In VMS we should never set in_cw_set on an OLDER twin. */					\
 	VMS_ONLY(assert(!cr->twin || cr->bt_index));							\
@@ -956,7 +1150,10 @@ GBLREF	int4		pin_fail_phase2_commit_pidcnt;	/* Number of processes in phase2 com
 				jnlpool_detach();										\
 				assert(NULL == jnlpool.jnlpool_ctl);								\
 				assert(FALSE == pool_init);									\
-				rts_error_csa(CSA_ARG(CSA) VARLSTCNT(10) ERR_REPLINSTMISMTCH, 8,				\
+				if (INVALID_SHMID == CNL->jnlpool_shmid)							\
+					rts_error_csa(CSA_ARG(CSA) VARLSTCNT(4) ERR_REPLINSTNOSHM, 2, DB_LEN_STR(REG));		\
+				else												\
+					rts_error_csa(CSA_ARG(CSA) VARLSTCNT(10) ERR_REPLINSTMISMTCH, 8,			\
 						LEN_AND_STR(instfilename_copy), jnlpool_shmid, DB_LEN_STR(REG),			\
 						LEN_AND_STR(CNL->replinstfilename), CNL->jnlpool_shmid);			\
 			}													\
@@ -1345,6 +1542,7 @@ enum tp_blkmod_type		/* used for accounting in cs_data->tp_cdb_sc_blkmod[] */
 #define	DONOTCOMMIT_T_QREAD_BAD_PVT_BUILD		(1 << 5) /* Restartable situation due to bad private build in t_qread */
 #define	DONOTCOMMIT_GVCST_SEARCH_LEAF_BUFFADR_NOTSYNC	(1 << 6) /* Restartable situation encountered in gvcst_search */
 #define	DONOTCOMMIT_GVCST_SEARCH_BLKTARGET_MISMATCH	(1 << 7) /* Restartable situation encountered in gvcst_search */
+#define DONOTCOMMIT_REALLOCATE_BITMAP_BMLMOD		(1 << 8) /* Restartable situation encountered in reallocate_bitmap */
 
 #define TAB_BG_TRC_REC(A,B)	B,
 enum bg_trc_rec_type
@@ -1804,17 +2002,21 @@ typedef struct	gd_addr_struct
 {
 	struct gd_region_struct		*local_locks;
 	int4				max_rec_size;
-	short				n_maps;
-	short				n_regions;
-	short				n_segments;
-	short				filler;
+	uint4				n_maps;
+	uint4				n_regions;
+	uint4				n_segments;
+	uint4				n_gblnames;	/* could be 0 if no global has any collation characteristics defined */
+	uint4				var_maps_len;	/* length (in bytes) of variable MAPS sections in .gld file */
 	struct gd_binding_struct	*maps;
 	struct gd_region_struct		*regions;
 	struct gd_segment_struct	*segments;
+	struct gd_gblname_struct	*gblnames;
 	struct gd_addr_struct		*link;
 	struct hash_table_mname_struct  *tab_ptr;
 	gd_id				*id;
 	UINTPTR_T			end;
+	uint4				has_span_gbls;	/* has at least one global which spans multiple regions */
+	char				filler[12];	/* filler to store runtime structures without changing gdeget/gdeput.m */
 } gd_addr;
 typedef gd_addr *(*gd_addr_fn_ptr)();
 
@@ -1836,10 +2038,12 @@ typedef struct	gd_segment_struct
 	uint4			lock_space;
 	uint4			global_buffers;	/* Was passed in FAB */
 	uint4			reserved_bytes;	/* number of bytes to be left in every database block */
+	uint4			mutex_slots;	/* copied over to NUM_CRIT_ENTRY(CSD) */
 	enum db_acc_method	acc_meth;
 	file_control		*file_cntl;
 	struct gd_region_struct	*repl_list;
-	UNIX_ONLY(boolean_t		is_encrypted;)
+	UNIX_ONLY(boolean_t	is_encrypted;)
+	char			filler[16];	/* filler to store runtime structures without changing gdeget/gdeput.m */
 } gd_segment;
 
 typedef union
@@ -1899,6 +2103,8 @@ typedef struct	gd_region_struct
 
 	int4			node;
 	int4			sec_size;
+	uint4			is_spanned;	/* this is one of the regions that some spanning global maps to */
+	char			filler[12];	/* filler to store runtime structures without changing gdeget/gdeput.m */
 } gd_region;
 
 typedef struct	sgmnt_addrs_struct
@@ -1934,10 +2140,11 @@ typedef struct	sgmnt_addrs_struct
 	gd_region				*region;		/* the region corresponding to this csa */
 	struct hash_table_mname_struct		*gvt_hashtab;		/* NON-NULL only if regcnt > 1;
 								 	 * Maintains all gv_targets mapped to this db file */
-	struct reg_ctl_list_struct	*rctl;	/* pointer to rctl for this region (used only if jgbl.forw_phase_recovery) */
+	void					*miscptr;	/* pointer to rctl for this region (if jgbl.forw_phase_recovery
+								 * or pointer to gvt_hashtab for this region if DSE_IMAGE.
+								 * NULL in all other cases. */
 	struct sgmnt_addrs_struct	*next_csa; /* points to csa of NEXT database that has been opened by this process */
 #	ifdef GTM_CRYPT
-	char					*encrypted_blk_contents;
 	gtmcrypt_key_t				encr_key_handle;
 #	endif
 #	ifdef GTM_SNAPSHOT
@@ -2034,16 +2241,159 @@ typedef struct	sgmnt_addrs_struct
 #	endif
 } sgmnt_addrs;
 
-typedef struct	gd_binding_struct
+typedef struct gd_binding_struct
 {
-	unsigned char	name[MAX_NM_LEN + 1];
+	union
+	{
+		char		*addr;
+		uint4		offset;
+	} gvkey;			/* Any input key GREATER THAN OR EQUAL TO "gvkey" lies OUTSIDE this map */
 	union
 	{
 		gd_region	*addr;
-		int4		offset;
+		uint4		offset;
 	} reg;
+	uint4		gvname_len;	/* the unsubscripted global name length */
+	uint4		gvkey_len;	/* the subscripted global name length excluding the second terminating null byte.
+					 *	Is equal to "gvname_len" + 1 if there are no subscripts.
+					 */
 } gd_binding;
 
+typedef struct gd_gblname_struct
+{
+        unsigned char   gblname[MAX_NM_LEN + 1];
+        uint4           act;    /* alternative collation sequence # */
+        uint4           ver;	/* version of collation library used at gld creation time */
+} gd_gblname;
+
+/* Define constants for a dummy gld file. This is used by dtgbldir.c and create_dummy_gbldir.c */
+#define	IMPOS_GBLNAME_7			"\xFF\xFF\xFF\xFF\xFF\xFF\xFF"	/* 7-bytes of 0xFF */
+#define	IMPOS_GBLNAME_8			IMPOS_GBLNAME_7 "\xFF"		/* 8-bytes of 0xFF */
+#define	IMPOSSIBLE_GBLNAME_31		IMPOS_GBLNAME_8 IMPOS_GBLNAME_8 IMPOS_GBLNAME_8 IMPOS_GBLNAME_7
+#define	DUMMY_GBLDIR_N_MAPS		3		/* one for local locks "#)", one for "%" and one for 0xFFFFFF... */
+#define DUMMY_GBLDIR_FIRST_MAP		"#)"		/* local locks */
+#define DUMMY_GBLDIR_SECOND_MAP		"%"		/* start of valid global name */
+#define DUMMY_GBLDIR_THIRD_MAP		IMPOSSIBLE_GBLNAME_31 /* last map always corresponds to impossible global name */
+#define	DUMMY_GBLDIR_MAP_GVN_SIZE(KEY)	(SIZEOF(KEY)-1)	/* SIZEOF already counts the null byte in the literal so remove it */
+#define	DUMMY_GBLDIR_MAP_KEY_SIZE(KEY)	(SIZEOF(KEY)+1)	/* +1 for second null byte (SIZEOF already counts the 1st null byte) */
+#define	DUMMY_GBLDIR_VAR_MAP_SIZE	ROUND_UP2(DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_FIRST_MAP)		\
+							+ DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_SECOND_MAP)	\
+							+ DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_THIRD_MAP), 8)
+#define	DUMMY_GBLDIR_FIX_MAP_SIZE	(DUMMY_GBLDIR_N_MAPS * SIZEOF(gd_binding))
+#define	DUMMY_GBLDIR_TOT_MAP_SIZE	(DUMMY_GBLDIR_FIX_MAP_SIZE + DUMMY_GBLDIR_VAR_MAP_SIZE)
+#define	DUMMY_GBLDIR_SIZE		(SIZEOF(header_struct) + SIZEOF(gd_addr)			\
+						+ DUMMY_GBLDIR_TOT_MAP_SIZE				\
+						+ 1 * SIZEOF(gd_region) + 1 * SIZEOF(gd_segment))
+
+#define	RELATIVE_OFFSET_FALSE		FALSE
+#define	RELATIVE_OFFSET_TRUE		TRUE
+
+#define	DUMMY_GLD_MAP_INIT(ADDR, RELATIVE, REG)							\
+{												\
+	char		*mapkey_ptr;								\
+	uint4		reg_offset;								\
+												\
+	if (RELATIVE)										\
+		ADDR->maps = (gd_binding *)(SIZEOF(gd_addr));					\
+	else											\
+		ADDR->maps = (gd_binding *)((UINTPTR_T)ADDR + SIZEOF(gd_addr));			\
+	ADDR->var_maps_len = DUMMY_GBLDIR_VAR_MAP_SIZE;						\
+	ADDR->n_maps = DUMMY_GBLDIR_N_MAPS;							\
+	ADDR->n_regions = 1;									\
+	ADDR->n_segments = 1;									\
+	ADDR->n_gblnames = 0;									\
+	ADDR->link = 0;										\
+	ADDR->tab_ptr = 0;									\
+	ADDR->id = 0;										\
+	ADDR->local_locks = 0;									\
+	mapkey_ptr = (char *)((UINTPTR_T)ADDR + SIZEOF(gd_addr) + DUMMY_GBLDIR_FIX_MAP_SIZE);	\
+	reg_offset = (INTPTR_T)(SIZEOF(gd_addr)) + DUMMY_GBLDIR_TOT_MAP_SIZE;			\
+	/* Start MAPS section initialization */							\
+	map = (gd_binding *)((UINTPTR_T)ADDR + SIZEOF(gd_addr));				\
+	/* This is the map for local locks which stores the name "#)" */			\
+	map->gvkey.addr = mapkey_ptr;								\
+	MEMCPY_LIT(mapkey_ptr, DUMMY_GBLDIR_FIRST_MAP);						\
+	if (NULL == REG)									\
+		map->reg.offset = reg_offset;							\
+	else											\
+		map->reg.addr = REG;								\
+	map->gvname_len = DUMMY_GBLDIR_MAP_GVN_SIZE(DUMMY_GBLDIR_FIRST_MAP);			\
+	map->gvkey_len =  DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_FIRST_MAP) - 1;		\
+	mapkey_ptr += map->gvkey_len;								\
+	map++;											\
+	/* This is the map for "%" */								\
+	map->gvkey.addr = mapkey_ptr;								\
+	MEMCPY_LIT(mapkey_ptr, DUMMY_GBLDIR_SECOND_MAP);					\
+	if (NULL == REG)									\
+		map->reg.offset = reg_offset;							\
+	else											\
+		map->reg.addr = REG;								\
+	map->gvname_len = DUMMY_GBLDIR_MAP_GVN_SIZE(DUMMY_GBLDIR_SECOND_MAP);			\
+	map->gvkey_len =  DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_SECOND_MAP) - 1;		\
+	mapkey_ptr += map->gvkey_len;								\
+	map++;											\
+	/* This is the map for the 31-byte '0xFF' byte global name (impossible) */		\
+	map->gvkey.addr = mapkey_ptr;								\
+	MEMCPY_LIT(mapkey_ptr, DUMMY_GBLDIR_THIRD_MAP);						\
+	if (NULL == REG)									\
+		map->reg.offset = reg_offset;							\
+	else											\
+		map->reg.addr = REG;								\
+	map->gvname_len = DUMMY_GBLDIR_MAP_GVN_SIZE(DUMMY_GBLDIR_THIRD_MAP);			\
+	map->gvkey_len =  DUMMY_GBLDIR_MAP_KEY_SIZE(DUMMY_GBLDIR_THIRD_MAP) - 1;		\
+	mapkey_ptr += map->gvkey_len;								\
+	/* MAPS sections (Fixed and Variable) initialization complete */			\
+}
+
+#define	DUMMY_GLD_INIT(header, addr, region, segment, size, relative)				\
+{												\
+	gd_binding	*map, *map_top;								\
+	gd_region	*region_top;								\
+	uint4		t_offset;								\
+												\
+	size = DUMMY_GBLDIR_SIZE;								\
+	header = (header_struct *)malloc(ROUND_UP(size, DISK_BLOCK_SIZE));			\
+	memset(header, 0, ROUND_UP(size, DISK_BLOCK_SIZE));					\
+	header->filesize = size;								\
+	size = ROUND_UP(size, DISK_BLOCK_SIZE);							\
+	MEMCPY_LIT(header->label, GDE_LABEL_LITERAL);						\
+	addr = (gd_addr *)((char *)header + SIZEOF(header_struct));				\
+	addr->max_rec_size = 256;								\
+	DUMMY_GLD_MAP_INIT(addr, relative, NULL);						\
+	addr->regions = (gd_region *)((INTPTR_T)(addr->maps) + DUMMY_GBLDIR_TOT_MAP_SIZE);	\
+	addr->segments = (gd_segment *)((INTPTR_T)(addr->regions) + SIZEOF(gd_region));		\
+	addr->end = (UINTPTR_T)(addr->segments) + SIZEOF(gd_segment);				\
+	region = (gd_region *)(addr->regions);							\
+	segment = (gd_segment *)(addr->segments);						\
+	region->rname_len = STR_LIT_LEN("DEFAULT");						\
+	MEMCPY_LIT(region->rname,"DEFAULT");							\
+	if (!relative)										\
+	{											\
+		for (map = addr->maps, map_top = map + addr->n_maps; map < map_top ; map++)	\
+		{										\
+			t_offset = map->reg.offset;						\
+			map->reg.addr = (gd_region *)((char *)addr + t_offset);			\
+		}										\
+		for (region = addr->regions, region_top = region + addr->n_regions;		\
+			region < region_top ; region++)						\
+		{										\
+			t_offset = region->dyn.offset;						\
+			region->dyn.addr = (gd_segment *)((char *)addr + t_offset);		\
+		}										\
+	} else											\
+	{											\
+		region = (gd_region *)((char *)addr + (INTPTR_T)(addr->regions));		\
+		for (region_top = region + addr->n_regions; region < region_top ; region++)	\
+		{										\
+			t_offset = region->dyn.offset;						\
+			region->dyn.addr = (gd_segment *)(INTPTR_T)t_offset;			\
+		}										\
+		region = region_top - addr->n_regions;	/* Restore "region" to point to		\
+							 * start of region array. */		\
+		segment = (gd_segment*)((char *)addr + (INTPTR_T)(addr->segments));		\
+	}											\
+}
+
 typedef struct
 {
 	unsigned short	offset;
@@ -2131,6 +2481,12 @@ typedef struct	gv_key_struct
 	unsigned char	base[1];	/* Base of the key */
 } gv_key;
 
+/* Define macro that will return the size of an array of "gv_key" structures. This is used to allocate temporary key structures
+ * to save/restore gv_currkey (for example). Defining the array as a "gv_key" array instead of a "char" array ensures we
+ * get the alignment we want (e.g. gv_key->end can be dereferenced without concerns for alignment issues).
+ */
+#define	DBKEYALLOC(KSIZE)	(1 + DIVIDE_ROUND_UP(DBKEYSIZE(KSIZE), SIZEOF(gv_key)))	/* 1 is for "gv_key" structure at start */
+
 /* The direction that the newly added record went after a block split at a given level */
 enum split_dir
 {
@@ -2159,19 +2515,25 @@ typedef struct	gv_namehead_struct
 	boolean_t	noisolation;     		/* whether isolation is turned on or off for this global */
 	block_id	root;				/* Root of global variable tree */
 	mname_entry	gvname;				/* the name of the global */
-	NON_GTM64_ONLY(uint4	filler_8byte_align0;)	/* for 8-byte alignment of "hist" member */
+	NON_GTM64_ONLY(uint4	filler_8byte_align1;)	/* for 8-byte alignment of "hist" member */
 	srch_hist	hist;				/* block history array */
 	int4		regcnt;				/* number of global directories whose hash-tables point to this gv_target.
 							 * 1 by default. > 1 if the same name in TWO DIFFERENT global directories
 							 * maps to the same physical file (i.e. two regions in different global
 							 * directories have the same physical file).
 							 */
-	unsigned char	nct;				/* numerical collation type for internalization */
-	unsigned char	act;				/* alternative collation type for internalization */
-	unsigned char	ver;
-	bool		split_cleanup_needed;
+	uint4		nct;				/* numerical collation type for internalization */
+	uint4		act;				/* alternative collation type for internalization */
+	uint4		ver;
+	boolean_t	act_specified_in_gld;		/* this gvt's global name had its "act" specified in the .gld in its
+							 * -GBLNAME section.
+							 */
+	boolean_t	nct_must_be_zero;		/* this gvt is part of a multi-region spanning global and hence
+							 * its "nct" cannot be anything but zero.
+							 */
+	boolean_t	split_cleanup_needed;
 	char		last_split_direction[MAX_BT_DEPTH - 1];	/* maintain last split direction for each level in the GVT */
-	char		filler_8byte_align1[2];
+	char		filler_8byte_align2[6];
 	block_id	last_split_blk_num[MAX_BT_DEPTH - 1];
 #	ifdef GTM_TRIGGER
 	struct gvt_trigger_struct *gvt_trigger;		/* pointer to trigger info for this global
@@ -2182,30 +2544,146 @@ typedef struct	gv_namehead_struct
 							 * last read/initialized from ^#t global (in gvtr_init) */
 	boolean_t	trig_mismatch_test_done;	/* whether update process has checked once if there is a mismatch
 							 * in trigger definitions between originating and replicating instance */
-	GTM64_ONLY(uint4 filler_8byte_align2;)		/* for 8-byte alignment of "clue" member. (targ_alloc relies on this) */
+	GTM64_ONLY(uint4 filler_8byte_align3;)		/* for 8-byte alignment of "clue" member. (targ_alloc relies on this) */
 #	endif
 	gv_key		clue;				/* Clue key, must be last in namehead struct because of hung buffer. */
 } gv_namehead;
 
+/* Below structure is allocated for every global name that spans across multiple regions in each global directory. */
+typedef struct gvnh_spanreg_struct
+{
+	int		start_map_index;	/* index into the global directory "maps" array corresponding to the
+						 *	FIRST map entry with "gvkey" member containing subscripted
+						 *	keys of the parent (unsubscripted) global name.
+						 */
+	int		end_map_index;		/* index into the global directory "maps" array corresponding to the
+						 *	LAST map entry with "gvkey" member containing subscripted
+						 *	keys of the parent (unsubscripted) global name.
+						 *	"start_map_index" and "end_map_index" serve as two bounds of
+						 *	the array within which a binary search is done to find which
+						 *	map entry contains a given input key.
+						 */
+	int		min_reg_index;		/* index into the global directory "regions" array such that ALL
+						 *	regions that the parent global name spans across lie AFTER
+						 *	this index in the "regions" array.
+						 */
+	int		max_reg_index;		/* index into the global directory "regions" array such that ALL
+						 *	regions that the parent global name spans across lie BEFORE
+						 *	this index in the "regions" array.
+						 *	"max_reg_index" - "min_reg_index" effectively determines the
+						 *	size of the array allocated to store the corresponding
+						 *	gv_targets for each unique region the parent global name spans.
+						 */
+	gv_namehead	*gvt_array[1];		/* array of gv_targets corresponding to each region the global name spans.
+						 *	Although the array is defined to be size 1, the actual size allocated
+						 *	depends on "max_reg_index"-"min_reg_index" and having this defined as
+						 *	an array lets us access the entire allocated size with an array index.
+						 *	Set to INVALID_GV_TARGET for array indices that correspond to regions
+						 *	which the parent global does NOT span across.
+						 */
+} gvnh_spanreg_t;
+
+/* Below structure is allocated for every global name in each global directory
+ * (irrespective of whether it spans across multiple regions or not).
+ */
 typedef struct	gvnh_reg_struct
 {
-	gv_namehead	*gvt;
-	gd_region	*gd_reg;			/* Region of key */
+	gv_namehead	*gvt;			/* Pointer to gv_target for the unsubscripted global name */
+	gd_region	*gd_reg;		/* Region corresponding to the global directory map entry where
+						 *	the unsubscripted global name was found.
+						 */
+	gvnh_spanreg_t	*gvspan;		/* Pointer to a structure containing details of what regions are spanned
+						 *	by this global name. Set to NULL for globals that dont span regions.
+						 */
+	uint4		act;			/* Copy of alternative collation SEQUENCE defined in GBLNAMES section of gbldir */
+	uint4		ver;			/* Copy of collation library VERSION defined in GBLNAMES section of gbldir */
 } gvnh_reg_t;
 
+#define	GVNH_REG_INIT(ADDR, HASHTAB, GD_MAP, GVT, REG, GVNH_REG, TABENT)					\
+{														\
+	boolean_t	added, gbl_spans_regions;								\
+	char		*gvent_name;										\
+	gd_binding	*spanmap;										\
+	int		res, gvent_len;										\
+														\
+	GBLREF	jnl_gbls_t	jgbl;										\
+														\
+	GVNH_REG = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));							\
+	GVNH_REG->gvt = GVT;											\
+	GVNH_REG->gd_reg = REG;											\
+	/* If GD_MAP is NULL, it implies callers like MUPIP JOURNAL -RECOVER or GT.CM GNP server		\
+	 * which dont have a .gld context to map input global names to regions, but instead know		\
+	 * which regions to play input updates. If GD_MAP is non-NULL, it implies the caller has		\
+	 * a .gld with map entries and wants to do more initialization inside this macro if the			\
+	 * input global spans multiple regions. Note that it is possible that even though GD_MAP is NULL,	\
+	 * ADDR could be non-NULL. This is necessary in case we need the gld file for GBLNAME section like	\
+	 * for MUPIP JOURNAL -RECOVER even though it operates on a per-region basis only. The GBLNAME section	\
+	 * is necessary to set correct collation properties in the directory tree if journal recover creates	\
+	 * the directory tree.											\
+	 */													\
+	assert((NULL != ADDR) || (NULL == GD_MAP));								\
+	if (NULL != GD_MAP)											\
+	{	/* check if global spans multiple regions and if so initialize "gvnh_reg->gvspan" */		\
+		gvnh_spanreg_init(GVNH_REG, ADDR, GD_MAP);							\
+		gbl_spans_regions = (NULL != GVNH_REG->gvspan);							\
+	} else													\
+	{	/* GT.CM GNP or MUPIP JOURNAL -RECOVER/ROLLBACK */						\
+		GVNH_REG->gvspan = NULL;									\
+		/* If GT.CM GNP, value of ADDR will be NULL so no need to search the global directory.		\
+		 * Otherwise (i.e. if MUPIP JOURNAL RECOVER/ROLLBACK), find from the gld whether the global	\
+		 * name spans regions. This is necessary to do unconditional collation initialization (as if	\
+		 * the gld specified it) for globals that span multiple regions inside the			\
+		 * COPY_ACT_FROM_GLD_TO_GVNH_REG_AND_GVT macro.	An exception is ^#t (actually all globals that	\
+		 * begin with ^# but ^#t is the only one currently). This does not map to a single region in	\
+		 * the gld map and so gv_srch_map should never be invoked for such globals. This global can	\
+		 * never span regions so treat it accordingly.							\
+		 */												\
+		if ((NULL == ADDR) || IS_MNAME_HASHT_GBLNAME(GVT->gvname.var_name))				\
+			gbl_spans_regions = FALSE;								\
+		else												\
+		{												\
+			assert(jgbl.forw_phase_recovery);							\
+			gvent_name = GVT->gvname.var_name.addr;							\
+			gvent_len = GVT->gvname.var_name.len;							\
+			spanmap = gv_srch_map(ADDR, gvent_name, gvent_len);					\
+			res = memcmp(gvent_name, &(spanmap->gvkey.addr[0]), gvent_len);				\
+			assert((0 != res) || (gvent_len <= spanmap->gvname_len));				\
+			gbl_spans_regions = !((0 > res) || ((0 == res) && (gvent_len < spanmap->gvname_len)));	\
+		}												\
+	}													\
+	COPY_ACT_FROM_GLD_TO_GVNH_REG_AND_GVT(ADDR, GVT, gbl_spans_regions, GVNH_REG, REG);			\
+	/* Add to hash table after all potential error conditions have been checked. If it was the other way	\
+	 * around, we could end up in a situation where an error is issued but pointers are set up incorrectly	\
+	 * so a future global reference will no longer error out and will accept out-of-design updates.		\
+	 * The only drawback of this approach is it might have a memory leak since allocated structures will	\
+	 * no longer have a pointer but that is considered acceptable since these errors are very unlikely	\
+	 * and the alternative (to set up condition handlers etc.) is not considered worth the effort now.	\
+	 */													\
+	added = add_hashtab_mname((hash_table_mname *)HASHTAB, &GVT->gvname, GVNH_REG, &TABENT);		\
+	assert(added);												\
+}
+
 #define INVALID_GV_TARGET (gv_namehead *)-1L
+/* Below macro is used to get the "gvnh_reg->gvspan->gvt_array[]" contents taking into account some
+ * might be set to INVALID_GV_TARGET (done only in DEBUG mode). In that case, we actually want to return NULL
+ * as there is NO gvt defined in that slot.
+ */
+#ifdef DEBUG
+#define	GET_REAL_GVT(gvt)	((INVALID_GV_TARGET == gvt) ? NULL : gvt)
+#else
+#define	GET_REAL_GVT(gvt)	gvt
+#endif
 
 typedef struct gvsavtarg_struct
 {
-	gd_addr			*gd_targ_addr;
-	gd_binding		*gd_map;
 	gd_region		*gv_cur_region;
 	gv_namehead		*gv_target;
-	bool			gv_last_subsc_null;
-	bool			gv_some_subsc_null;
-	short			prev;
-	short			end;
-	short			filler_8byte_align;
+	gvnh_reg_t		*gd_targ_gvnh_reg;
+	gd_binding		*gd_targ_map;
+	boolean_t		gv_last_subsc_null;
+	boolean_t		gv_some_subsc_null;
+	uint4			prev;
+	uint4			end;
 } gvsavtarg_t;
 
 #define	GVSAVTARG_ALIGN_BNDRY	8
@@ -2345,9 +2823,9 @@ GBLREF	gv_namehead	*gvt_tp_list;
 	 * The only exception is if the region was dba_cm but later closed due to an error on		\
 	 * the server side (in which case access method gets reset back to BG. (e.g. gvcmz_error.c)	\
 	 */												\
-	assert((NULL != gvtarg) || (dba_cm == gv_cur_region->dyn.addr->acc_meth)			\
-		|| (dba_usr == gv_cur_region->dyn.addr->acc_meth)					\
-		|| ((FALSE == gv_cur_region->open) && (dba_bg == gv_cur_region->dyn.addr->acc_meth)));	\
+	assert((NULL != gvtarg) || (dba_cm == REG_ACC_METH(gv_cur_region))				\
+		|| (dba_usr == REG_ACC_METH(gv_cur_region))						\
+		|| ((FALSE == gv_cur_region->open) && (dba_bg == REG_ACC_METH(gv_cur_region))));	\
 }
 
 /* If CHECK_CSADDRS input parameter is CHECK_CSA_TRUE, then check that GV_CURRKEY, GV_TARGET and CS_ADDRS are all in sync.
@@ -2464,19 +2942,23 @@ GBLREF	sgmnt_addrs	*cs_addrs;
 	}								\
 }
 
-#define	ISSUE_GVSUBOFLOW_ERROR(GVKEY)								\
-{												\
-	unsigned char *endBuff, fmtBuff[MAX_ZWR_KEY_SZ];					\
-												\
-	/* Assert that input key to format_targ_key is double null terminated */		\
-	assert(KEY_DELIMITER == GVKEY->base[GVKEY->end]);					\
-	endBuff = format_targ_key(fmtBuff, ARRAYSIZE(fmtBuff), GVKEY, TRUE);			\
-	GV_SET_LAST_SUBSCRIPT_INCOMPLETE(fmtBuff, endBuff); /* Note: might update "endBuff" */	\
-	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2,		\
-			endBuff - fmtBuff, fmtBuff);						\
+#define	KEY_COMPLETE_FALSE	FALSE
+#define	KEY_COMPLETE_TRUE	TRUE
+
+#define	ISSUE_GVSUBOFLOW_ERROR(GVKEY, IS_KEY_COMPLETE)							\
+{													\
+	unsigned char *endBuff, fmtBuff[MAX_ZWR_KEY_SZ];						\
+													\
+	/* Assert that input key to format_targ_key is double null terminated */			\
+	assert(KEY_DELIMITER == GVKEY->base[GVKEY->end]);						\
+	endBuff = format_targ_key(fmtBuff, ARRAYSIZE(fmtBuff), GVKEY, TRUE);				\
+	if (!IS_KEY_COMPLETE)										\
+		GV_SET_LAST_SUBSCRIPT_INCOMPLETE(fmtBuff, endBuff); /* Note: might update "endBuff" */	\
+	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2,			\
+			endBuff - fmtBuff, fmtBuff);							\
 }
 
-#define COPY_SUBS_TO_GVCURRKEY(mvarg, max_key, gv_currkey, was_null, is_null)					\
+#define COPY_SUBS_TO_GVCURRKEY(mvarg, reg, gv_currkey, was_null, is_null)					\
 {														\
 	GBLREF mv_stent		*mv_chain;									\
 	GBLREF unsigned char	*msp, *stackwarn, *stacktop;							\
@@ -2492,21 +2974,21 @@ GBLREF	sgmnt_addrs	*cs_addrs;
 		if (gv_target->collseq || gv_target->nct)							\
 		{												\
 			/* collation transformation should be done at the server's end for CM regions */	\
-			assert(dba_cm != gv_cur_region->dyn.addr->acc_meth);					\
+			assert(dba_cm != REG_ACC_METH(reg));							\
 			TREF(transform) = FALSE;								\
 			end = gvsub2str((uchar_ptr_t)mvarg->str.addr, buff, FALSE);				\
 			TREF(transform) = TRUE;									\
 			temp.mvtype = MV_STR;									\
 			temp.str.addr = (char *)buff;								\
 			temp.str.len = (mstr_len_t)(end - buff);						\
-			mval2subsc(&temp, gv_currkey);								\
+			mval2subsc(&temp, gv_currkey, reg->std_null_coll);					\
 		} else												\
 		{												\
 			len = mvarg->str.len;									\
-			if (gv_currkey->end + len - 1 >= max_key)						\
-				ISSUE_GVSUBOFLOW_ERROR(gv_currkey);						\
+			if (gv_currkey->end + len - 1 >= gv_currkey->top)					\
+				ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_FALSE);				\
 			memcpy((gv_currkey->base + gv_currkey->end), mvarg->str.addr, len);			\
-			if (is_null && 0 != gv_cur_region->std_null_coll)					\
+			if (is_null && 0 != reg->std_null_coll)							\
 				gv_currkey->base[gv_currkey->end] = SUBSCRIPT_STDCOL_NULL;			\
 			gv_currkey->prev = gv_currkey->end;							\
 			gv_currkey->end += len - 1;								\
@@ -2514,9 +2996,7 @@ GBLREF	sgmnt_addrs	*cs_addrs;
 	} else													\
 	{													\
 		MV_FORCE_DEFINED(mvarg);									\
-		mval2subsc(mvarg, gv_currkey);									\
-		if (gv_currkey->end >= max_key)									\
-			ISSUE_GVSUBOFLOW_ERROR(gv_currkey);							\
+		mval2subsc(mvarg, gv_currkey, reg->std_null_coll);						\
 		is_null = (MV_IS_STRING(mvarg) && (0 == mvarg->str.len));					\
 	}													\
 }
@@ -2524,27 +3004,43 @@ GBLREF	sgmnt_addrs	*cs_addrs;
 /* Copy GVKEY to GVT->CLUE. Take care NOT to copy cluekey->top to GVKEY->top as they correspond
  * to the allocation sizes of two different memory locations and should stay untouched.
  */
-#define	COPY_CURRKEY_TO_GVTARGET_CLUE(GVT, GVKEY)				\
-{										\
-	gv_key	*cluekey;							\
-										\
-	if (GVT->clue.top <= GVKEY->end)					\
-		GTMASSERT;							\
-	assert(KEY_DELIMITER == GVKEY->base[GVKEY->end]);			\
-	assert(KEY_DELIMITER == GVKEY->base[GVKEY->end - 1]);			\
-	cluekey = &GVT->clue;							\
-	memcpy(cluekey->base, GVKEY->base, GVKEY->end + 1);			\
-	cluekey->end = GVKEY->end;						\
-	cluekey->prev = GVKEY->prev;						\
-	DBG_CHECK_GVTARGET_INTEGRITY(GVT);					\
+#define	COPY_CURRKEY_TO_GVTARGET_CLUE(GVT, GVKEY)					\
+{											\
+	int	keyend;									\
+	DCL_THREADGBL_ACCESS;								\
+											\
+	SETUP_THREADGBL_ACCESS;								\
+	keyend = GVKEY->end;								\
+	if (GVT->clue.top <= keyend)							\
+	{	/* Possible only if GVT corresponds to a global that spans multiple	\
+		 * regions. For example, a gvcst_spr_* function could construct a	\
+		 * gv_currkey starting at one spanned region and might have to do a	\
+		 * gvcst_* operation on another spanned region with a max-key-size	\
+		 * that is smaller than gv_currkey->end. In that case, copy only the	\
+		 * portion of gv_currkey that will fit in the gvt of the target region.	\
+		 */									\
+		assert(TREF(spangbl_seen));						\
+		keyend = GVT->clue.top - 1;						\
+		memcpy(GVT->clue.base, GVKEY->base, keyend - 1);			\
+		GVT->clue.base[keyend - 1] = KEY_DELIMITER;				\
+		GVT->clue.base[keyend] = KEY_DELIMITER;					\
+	} else										\
+	{										\
+		assert(KEY_DELIMITER == GVKEY->base[keyend]);				\
+		assert(KEY_DELIMITER == GVKEY->base[keyend - 1]);			\
+		memcpy(GVT->clue.base, GVKEY->base, keyend + 1);			\
+	}										\
+	GVT->clue.end = keyend;								\
+	/* No need to maintain unused GVT->clue.prev */					\
+	DBG_CHECK_GVTARGET_INTEGRITY(GVT);						\
 }
 
 /* If SRC_KEY->end == 0, make sure to copy the first byte of SRC_KEY->base */
-#define MEMCPY_KEY(TARG_KEY, SRC_KEY)												\
-{																\
-	memcpy((TARG_KEY), (SRC_KEY), OFFSETOF(gv_key, base[0]) + (SRC_KEY)->end + 1);						\
+#define MEMCPY_KEY(TARG_KEY, SRC_KEY)								\
+{												\
+	memcpy((TARG_KEY), (SRC_KEY), OFFSETOF(gv_key, base[0]) + (SRC_KEY)->end + 1);		\
 }
-#define COPY_KEY(TARG_KEY, SRC_KEY)										\
+#define COPY_KEY(TARG_KEY, SRC_KEY)												\
 {																\
 	assert(TARG_KEY->top >= SRC_KEY->end);											\
 	/* ensure proper alignment before dereferencing SRC_KEY->end */								\
@@ -2614,35 +3110,32 @@ GBLREF	sgmnt_addrs	*cs_addrs;
 /* Macro used by $ZPREVIOUS to replace a NULL subscript at the end with the maximum possible subscript
  * that could exist in the database for this global name.
  */
-#define GVZPREVIOUS_APPEND_MAX_SUBS_KEY(GVKEY, GVT)					\
-{											\
-	int		lastsubslen, keysize;						\
-	unsigned char	*ptr;								\
-											\
-	assert(GVT->clue.top || (NULL == GVT->gd_csa));					\
-	assert(!GVT->clue.top || (NULL != GVT->gd_csa) && (GVT->gd_csa == cs_addrs));	\
-	/* keysize can be obtained from GVT->clue.top in case of GT.M.			\
-	 * But for GT.CM client, clue will be uninitialized. So we would need to	\
-	 * compute keysize from gv_cur_region->max_key_size. Since this is true for	\
-	 * GT.M as well, we use the same approach for both to avoid an if check and a	\
-	 * break in the pipeline.							\
-	 */										\
-	keysize = DBKEYSIZE(gv_cur_region->max_key_size);				\
-	assert(!GVT->clue.top || (keysize == GVT->clue.top));				\
-	lastsubslen = keysize - GVKEY->prev - 2;					\
-	if ((0 < lastsubslen) && (GVKEY->top >= keysize) && (GVKEY->end > GVKEY->prev))	\
-	{										\
-		ptr = &GVKEY->base[GVKEY->prev];					\
-		memset(ptr, STR_SUB_MAXVAL, lastsubslen);				\
-		ptr += lastsubslen;							\
-		*ptr++ = KEY_DELIMITER;	 /* terminator for last subscript */		\
-		*ptr = KEY_DELIMITER;    /* terminator for entire key */		\
-		GVKEY->end = GVKEY->prev + lastsubslen + 1;				\
-		assert(GVKEY->end == (ptr - &GVKEY->base[0]));				\
-	} else										\
-		GTMASSERT;								\
-	if (NULL != gv_target->gd_csa)							\
-		DBG_CHECK_GVTARGET_INTEGRITY(GVT);					\
+#define GVZPREVIOUS_APPEND_MAX_SUBS_KEY(GVKEY, GVT)						\
+{												\
+	int		lastsubslen, keysize;							\
+	unsigned char	*ptr;									\
+												\
+	assert(GVT->clue.top || (NULL == GVT->gd_csa));						\
+	assert(!GVT->clue.top || (NULL != GVT->gd_csa) && (GVT->gd_csa == cs_addrs));		\
+	/* keysize can be obtained from GVT->clue.top in case of GT.M.				\
+	 * But for GT.CM client, clue will be uninitialized. So we would need to		\
+	 * compute keysize from gv_cur_region->max_key_size. Since this is true for		\
+	 * GT.M as well, we use the same approach for both to avoid an if check and a		\
+	 * break in the pipeline.								\
+	 */											\
+	keysize = DBKEYSIZE(gv_cur_region->max_key_size);					\
+	assert(!GVT->clue.top || (keysize == GVT->clue.top));					\
+	lastsubslen = keysize - GVKEY->prev - 2;						\
+	assertpro((0 < lastsubslen) && (GVKEY->top >= keysize) && (GVKEY->end > GVKEY->prev));	\
+	ptr = &GVKEY->base[GVKEY->prev];							\
+	memset(ptr, STR_SUB_MAXVAL, lastsubslen);						\
+	ptr += lastsubslen;									\
+	*ptr++ = KEY_DELIMITER;	 /* terminator for last subscript */				\
+	*ptr = KEY_DELIMITER;    /* terminator for entire key */				\
+	GVKEY->end = GVKEY->prev + lastsubslen + 1;						\
+	assert(GVKEY->end == (ptr - &GVKEY->base[0]));						\
+	if (NULL != gv_target->gd_csa)								\
+		DBG_CHECK_GVTARGET_INTEGRITY(GVT);						\
 }
 
 /* Bit masks for the update_trans & si->update_trans variables */
@@ -2832,15 +3325,15 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 	DECR_CNT(&cnl->wcs_phase2_commit_pidcnt, &cnl->wc_var_lock);	\
 }
 
-/* The CAREFUL_DECR_WCS_PHASE2_COMMIT_PIDCNT macro is the same as the DECR_WCS_PHASE2_COMMIT_PIDCNT macro
- * except that it uses CAREFUL_DECR_CNT instead of DECR_CNT. This does alignment checks and is needed by
+/* The PROBE_DECR_WCS_PHASE2_COMMIT_PIDCNT macro is the same as the DECR_WCS_PHASE2_COMMIT_PIDCNT macro
+ * except that it uses PROBE_DECR_CNT instead of DECR_CNT. This does alignment checks and is needed by
  * secshr_db_clnup as it runs in kernel mode in VMS. The two macros should be maintained in parallel.
  */
-#define	CAREFUL_DECR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl)				\
+#define	PROBE_DECR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl)				\
 {										\
 	assert(csa->wcs_pidcnt_incremented);					\
 	csa->wcs_pidcnt_incremented = FALSE;					\
-	CAREFUL_DECR_CNT(&cnl->wcs_phase2_commit_pidcnt, &cnl->wc_var_lock);	\
+	PROBE_DECR_CNT(&cnl->wcs_phase2_commit_pidcnt, &cnl->wc_var_lock);	\
 }
 
 #ifdef UNIX
@@ -2904,7 +3397,7 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 	DECR_CNT(&local_csd->kill_in_prog, &local_csa->nl->wc_var_lock);	\
 	REMOVE_KIP_PID(local_csa);						\
 }
-/* Note that the INCR_KIP and CAREFUL_INCR_KIP macros should be maintained in parallel */
+/* Note that the INCR_KIP and PROBE_INCR_KIP macros should be maintained in parallel */
 #define INCR_KIP(CSD, CSA, KIP_CSA)						\
 {										\
 	sgmnt_data_ptr_t	local_csd;					\
@@ -2917,11 +3410,11 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 	INSERT_KIP_PID(local_csa);						\
 	KIP_CSA = CSA;								\
 }
-/* The CAREFUL_INCR_KIP macro is the same as the INCR_KIP macro except that it uses CAREFUL_INCR_CNT instead of INCR_CNT.
+/* The PROBE_INCR_KIP macro is the same as the INCR_KIP macro except that it uses PROBE_INCR_CNT instead of INCR_CNT.
  * This does alignment checks and is needed by secshr_db_clnup as it runs in kernel mode in VMS.
- * The INCR_KIP and CAREFUL_INCR_KIP macros should be maintained in parallel.
+ * The INCR_KIP and PROBE_INCR_KIP macros should be maintained in parallel.
  */
-#define CAREFUL_INCR_KIP(CSD, CSA, KIP_CSA)						\
+#define PROBE_INCR_KIP(CSD, CSA, KIP_CSA)						\
 {											\
 	sgmnt_data_ptr_t	local_csd;						\
 	sgmnt_addrs		*local_csa;						\
@@ -2929,11 +3422,11 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 	local_csd = CSD;								\
 	local_csa = CSA;								\
 	assert(NULL == KIP_CSA);							\
-	CAREFUL_INCR_CNT(&local_csd->kill_in_prog, &local_csa->nl->wc_var_lock);	\
+	PROBE_INCR_CNT(&local_csd->kill_in_prog, &local_csa->nl->wc_var_lock);	\
 	INSERT_KIP_PID(local_csa);							\
 	KIP_CSA = CSA;									\
 }
-#define CAREFUL_DECR_KIP(CSD, CSA, KIP_CSA)						\
+#define PROBE_DECR_KIP(CSD, CSA, KIP_CSA)						\
 {											\
 	sgmnt_data_ptr_t	local_csd;						\
 	sgmnt_addrs		*local_csa;						\
@@ -2942,13 +3435,13 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 	local_csa = CSA;								\
 	assert(NULL != KIP_CSA);							\
 	KIP_CSA = NULL;									\
-	CAREFUL_DECR_CNT(&local_csd->kill_in_prog, &local_csa->nl->wc_var_lock);	\
+	PROBE_DECR_CNT(&local_csd->kill_in_prog, &local_csa->nl->wc_var_lock);	\
 	REMOVE_KIP_PID(local_csa);							\
 }
 /* Since abandoned_kills counter is only incremented in secshr_db_clnup it does not have its equivalent DECR_ABANDONED_KILLS */
-#define CAREFUL_INCR_ABANDONED_KILLS(CSD, CSA)				\
+#define PROBE_INCR_ABANDONED_KILLS(CSD, CSA)				\
 {									\
-        CAREFUL_INCR_CNT(&CSD->abandoned_kills, &CSA->nl->wc_var_lock);	\
+        PROBE_INCR_CNT(&CSD->abandoned_kills, &CSA->nl->wc_var_lock);	\
 }
 
 #define INCR_INHIBIT_KILLS(CNL)					\
@@ -2962,6 +3455,15 @@ typedef replpool_identifier 	*replpool_id_ptr_t;
 		DECR_CNT(&CNL->inhibit_kills, &CNL->wc_var_lock);	\
 }
 
+/* Unless the pipeline architecture of the machine precludes it, there is a chance for another process to slip in between the IF and
+ * the decrement, but this macro would only be used in relatively unlikely circumstances.
+ */
+#define CAREFUL_DECR_CNT(CNT,LATCH)			\
+{							\
+	if (0 < CNT)					\
+		DECR_CNT(&CNT, &LATCH);			\
+}
+
 /* Commands like MUPIP BACKUP, MUPIP INTEG -REG or MUPIP FREEZE wait for kills-in-prog flag to become zero.
  * While these process wait for ongoing block-freeing KILLs (or reorg actions that free up blocks) to complete,
  * new block-freeing KILLs (or reorg actions that free up blocks) are deferred using inhibit_kills counter.
@@ -3443,7 +3945,7 @@ typedef struct redo_root_search_context_struct
 	uint4		update_trans;
 	uint4		t_err;
 	boolean_t	hold_onto_crit;
-	char		currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_key		currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gv_key		*gv_currkey;
 #	ifdef DEBUG
 	unsigned char	t_fail_hist_dbg[T_FAIL_HIST_DBG_SIZE];
@@ -3452,22 +3954,22 @@ typedef struct redo_root_search_context_struct
 } redo_root_search_context;
 #endif
 
-#define SET_GV_CURRKEY_FROM_REORG_GV_TARGET						\
-{	/* see mupip reorg.c for comment */						\
-	GBLREF	gv_key		*gv_currkey;						\
-	GBLREF	gv_namehead	*reorg_gv_target;	/* for global name */		\
-	GBLREF	boolean_t	mu_reorg_process;					\
-											\
-	mname_entry		*gvent;							\
-	int			end;							\
-											\
-	assert(mu_reorg_process);							\
-	gvent = &reorg_gv_target->gvname;						\
-	memcpy(gv_currkey->base, gvent->var_name.addr, gvent->var_name.len);		\
-	end = gvent->var_name.len + 1;							\
-	gv_currkey->end = end;								\
-	gv_currkey->base[end - 1] = 0;							\
-	gv_currkey->base[end] = 0;							\
+#define SET_GV_CURRKEY_FROM_GVT(GVT)						\
+{										\
+	mname_entry		*gvent;						\
+	int			end;						\
+										\
+	GBLREF	gv_key		*gv_currkey;					\
+	GBLREF	boolean_t	mu_reorg_process;				\
+	GBLREF	gv_namehead	*reorg_gv_target;				\
+										\
+	assert((GVT != reorg_gv_target) || mu_reorg_process);			\
+	gvent = &GVT->gvname;							\
+	memcpy(gv_currkey->base, gvent->var_name.addr, gvent->var_name.len);	\
+	end = gvent->var_name.len + 1;						\
+	gv_currkey->end = end;							\
+	gv_currkey->base[end - 1] = 0;						\
+	gv_currkey->base[end] = 0;						\
 }
 
 #define SET_WANT_ROOT_SEARCH(CDB_STATUS, WANT_ROOT_SEARCH)								\
@@ -3538,56 +4040,262 @@ typedef struct redo_root_search_context_struct
 	assert((NULL == first_sgm_info) || (0 == sgm_info_ptr->num_of_blks));							\
 }
 
-#define GVCST_ROOT_SEARCH													\
-{	/* gvcst_root_search is invoked to establish the root block of a given global (pointed to by gv_target). We always	\
-	 * expect the root block of the directory tree to be 1 and so must never come here with gv_target pointing to directory	\
-	 * tree. Assert that.													\
-	 */															\
-	assert((NULL != gv_target) && (DIR_ROOT != gv_target->root));								\
-	if (!gv_target->root)													\
-		gvcst_root_search(FALSE);											\
+#define GVCST_ROOT_SEARCH							\
+{	/* gvcst_root_search is invoked to establish the root block of a 	\
+	 * given global (pointed to by gv_target). We always expect the root	\
+	 * block of the directory tree to be 1 and so must never come here	\
+	 * with gv_target pointing to directory tree. Assert that.		\
+	 */									\
+	GBLREF gv_namehead	*gv_target;					\
+										\
+	assert((NULL != gv_target) && (DIR_ROOT != gv_target->root));		\
+	if (!gv_target->root)							\
+		gvcst_root_search(FALSE);					\
 }
 
 /* Same as GVCST_ROOT_SEARCH, but tells gvcst_root_search NOT to restart but to return the status code back to the caller */
-#define GVCST_ROOT_SEARCH_DONOT_RESTART(STATUS)											\
-{																\
-	assert((NULL != gv_target) && (DIR_ROOT != gv_target->root));								\
-	STATUS = cdb_sc_normal;													\
-	if (!gv_target->root)													\
-		STATUS = gvcst_root_search(TRUE);										\
+#define GVCST_ROOT_SEARCH_DONOT_RESTART(STATUS)					\
+{										\
+	GBLREF gv_namehead	*gv_target;					\
+										\
+	assert((NULL != gv_target) && (DIR_ROOT != gv_target->root));		\
+	STATUS = cdb_sc_normal;							\
+	if (!gv_target->root)							\
+		STATUS = gvcst_root_search(TRUE);				\
+}
+
+#define GVCST_ROOT_SEARCH_AND_PREP(est_first_pass)								\
+{	/* Before beginning a spanning node (gvcst_xxx) or spanning region (gvcst_spr_xxx) try in a gvcst	\
+	 * routine, make sure the root is established. If we've restarted issue DBROLLEDBACK appropriately.	\
+	 */													\
+	GBLREF	unsigned char		t_fail_hist[CDB_MAX_TRIES]; /* for LAST_RESTART_CODE */			\
+	GBLREF	stack_frame		*frame_pointer;								\
+	GBLREF	uint4			dollar_tlevel;								\
+														\
+	DCL_THREADGBL_ACCESS;											\
+														\
+	SETUP_THREADGBL_ACCESS;											\
+	assert(dollar_tlevel);											\
+	ASSERT_BEGIN_OF_FRESH_TP_TRANS;										\
+	frame_pointer->flags |= SFF_IMPLTSTART_CALLD;								\
+	if (est_first_pass && (cdb_sc_onln_rlbk2 == LAST_RESTART_CODE))						\
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DBROLLEDBACK);					\
+	tp_set_sgm();												\
+	GVCST_ROOT_SEARCH;											\
 }
 
-#define GVCST_ROOT_SEARCH_AND_PREP(est_first_pass)										\
-{	/* Before beginning a spanning node try in a gvcst routine, make sure the root is established. If we've restarted	\
-	 * issue DBROLLEDBACK appropriately.											\
-	 */															\
-	GBLREF	unsigned char		t_fail_hist[CDB_MAX_TRIES]; /* for LAST_RESTART_CODE */					\
-	GBLREF	stack_frame		*frame_pointer;										\
-																\
-	DCL_THREADGBL_ACCESS;													\
-																\
-	SETUP_THREADGBL_ACCESS;													\
-	assert(dollar_tlevel);													\
-	ASSERT_BEGIN_OF_FRESH_TP_TRANS;												\
-	frame_pointer->flags |= SFF_IMPLTSTART_CALLD;										\
-	if (est_first_pass && (cdb_sc_onln_rlbk2 == LAST_RESTART_CODE))								\
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DBROLLEDBACK);							\
-	tp_set_sgm();														\
-	GVCST_ROOT_SEARCH;													\
+#define GV_BIND_NAME_ONLY(ADDR, TARG, GVNH_REG)		GVNH_REG = gv_bind_name(ADDR, TARG)
+
+#define GV_BIND_NAME_AND_ROOT_SEARCH(ADDR, TARG, GVNH_REG)					\
+{												\
+	enum db_acc_method	acc_meth;							\
+												\
+	GBLREF gd_region	*gv_cur_region;							\
+	GBLREF gv_namehead	*gv_target;							\
+												\
+	GV_BIND_NAME_ONLY(ADDR, TARG, GVNH_REG);						\
+	/* Skip GVCST_ROOT_SEARCH in case of spanning global.					\
+	 * See comment at end of gv_bind_name.c for details.					\
+	 */											\
+	if (NULL == GVNH_REG->gvspan)								\
+	{											\
+		acc_meth = REG_ACC_METH(gv_cur_region);						\
+		if ((dba_bg == acc_meth) || (dba_mm == acc_meth))				\
+			GVCST_ROOT_SEARCH;							\
+	} else if (!gv_target->root && gv_target->act_specified_in_gld && gv_target->act)	\
+	{	/* gv_target->root is ZERO which means we have still not done a			\
+		 * gvcst_root_search which implies "act_in_gvt" function has not yet been	\
+		 * invoked. But this global has a non-zero act specified in gld. Invoke		\
+		 * "act_in_gvt" now as this might be needed for transforming string subscripts	\
+		 * as part of op_gvname etc.							\
+		 */										\
+		act_in_gvt(gv_target); /* note: this could issue COLLTYPVERSION error */	\
+	}											\
 }
 
-#define GV_BIND_NAME_ONLY(ADDR, TARG)	gv_bind_name(ADDR, TARG)
+#define	GET_REG_INDEX(ADDR, REG_START, REG, REG_INDEX)				\
+{										\
+	assert((REG >= REG_START) && (REG < &ADDR->regions[ADDR->n_regions]));	\
+	REG_INDEX = REG - REG_START;						\
+}
 
-#define GV_BIND_NAME_AND_ROOT_SEARCH(ADDR, TARG)										\
-{																\
-	enum db_acc_method	acc_meth;											\
-	GBLREF gd_region	*gv_cur_region;											\
-	GBLREF gv_namehead	*gv_target;											\
-																\
-	GV_BIND_NAME_ONLY(ADDR, TARG);												\
-	acc_meth = gv_cur_region->dyn.addr->acc_meth;										\
-	if ((dba_bg == acc_meth) || (dba_mm == acc_meth))									\
-		GVCST_ROOT_SEARCH;												\
+#define	ACT_NOT_SPECIFIED	(MAXUINT4)
+
+#define	DO_NCT_CHECK_FOR_SPANGBLS(GVT, GVNH_REG, REG)								\
+{														\
+	if ((NULL != GVNH_REG->gvspan) && !GVT->nct_must_be_zero)						\
+	{													\
+		if (GVT->nct)											\
+			rts_error_csa(CSA_ARG(GVT->gd_csa) VARLSTCNT(6) ERR_NCTCOLLSPGBL, 4, DB_LEN_STR(REG),	\
+					GVT->gvname.var_name.len, GVT->gvname.var_name.addr);			\
+		GVT->nct_must_be_zero = TRUE;									\
+	}													\
+}
+
+/* Copy "act" from the .gld file (GBLNAME section) to the GVNH_REG structure and in turn the GVT structure */
+#define	COPY_ACT_FROM_GLD_TO_GVNH_REG_AND_GVT(ADDR, GVT, GBL_SPANS_REG, GVNH_REG, REG)			\
+{													\
+	gd_gblname	*gname;										\
+													\
+	if ((NULL != ADDR) && (((gd_addr *)ADDR)->n_gblnames))						\
+	{	/* have some global names with collation characteristics. check if current global	\
+		 * name is part of that list. If so initialize its collation properties.		\
+		 */											\
+		gname = gv_srch_gblname(ADDR, GVT->gvname.var_name.addr, GVT->gvname.var_name.len);	\
+	} else												\
+		gname = NULL;										\
+	if (NULL != gname)										\
+	{	/* Transfer global's collation characteristics into gvnh_reg.				\
+		 * But before that check for error scenarios.						\
+		 */											\
+		GVNH_REG->act = gname->act;								\
+		GVNH_REG->ver = gname->ver;								\
+	} else if (GBL_SPANS_REG)									\
+	{	/* This global spans multiple regions. And the user did not specify a collation for	\
+		 * this global in the GBLNAME section of the gld. In this case force collation to 0	\
+		 * for this global. Not doing so could cause any non-zero default collation properties	\
+		 * in the spanned global db file header to result in different parts of this global	\
+		 * exist with different collation representations in different .dat files creating	\
+		 * an out-of-design situation since the collation property of a spanning global is used	\
+		 * in op_gvname/op_gvextnam/op_gvnaked to come with the subscript representation even	\
+		 * before determining which region a given subscripted key maps to.			\
+		 */											\
+		GVNH_REG->act = 0;									\
+		GVNH_REG->ver = 0;									\
+	} else												\
+		GVNH_REG->act = ACT_NOT_SPECIFIED;							\
+	COPY_ACT_FROM_GVNH_REG_TO_GVT(GVNH_REG, GVT, REG);						\
+}
+
+/* Copy "act" from the GVNH_REG structure to the GVT structure.
+ * Currently the GLD (and in turn GVNH_REG) dont have a way to set "nct" for a gblname.
+ * Therefore only "act" gets copied over currently. This macro needs to change if/when
+ * "nct" support for gblname gets added to the gld.
+ */
+#define	COPY_ACT_FROM_GVNH_REG_TO_GVT(GVNH_REG, GVT, REG)						\
+{													\
+	uint4	gldact;											\
+													\
+	DO_NCT_CHECK_FOR_SPANGBLS(GVT, GVNH_REG, REG);							\
+	gldact = GVNH_REG->act;										\
+	/* Exclude DSE from ERR_ACTCOLLMISMTCH errors (see gvcst_root_search.c comment for details) */	\
+	if (((ACT_NOT_SPECIFIED != gldact) && (gldact != GVT->act) && !IS_DSE_IMAGE)			\
+		&& ((GVT->root) || GVT->act_specified_in_gld))						\
+	{	/* GVT->root case : Global already exists and GVT/GLD act do not match.			\
+		 * GVT->act_specified_in_gld case :							\
+		 *	Global directory defines one alternate collation sequence for global name	\
+		 *	but gv_target already has a different (and non-zero) alternate collation	\
+		 *	sequence defined (from another global directory's GBLNAME characteristics	\
+		 *	or from the "Default Collation" field of the database file header.		\
+		 * In either case, error out.								\
+		 */											\
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_ACTCOLLMISMTCH, 6,			\
+				GVT->gvname.var_name.len, GVT->gvname.var_name.addr,			\
+				gldact, DB_LEN_STR(REG), GVT->act);					\
+	}												\
+	if (!GVT->act_specified_in_gld && (ACT_NOT_SPECIFIED != gldact))				\
+	{												\
+		GVT->act_specified_in_gld = TRUE;							\
+		GVT->act = gldact;									\
+		GVT->ver = GVNH_REG->ver;								\
+	}												\
+	GVT->nct_must_be_zero = (NULL != GVNH_REG->gvspan);						\
+}
+
+/* This macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH (in terms of setting gv_cur_region)
+ * in case the global spans multiple regions.
+ */
+#define	GV_BIND_SUBSNAME_IF_GVSPAN(GVNH_REG, GD_HEADER, GVKEY, REG)			\
+{											\
+	GBLREF gd_region	*gv_cur_region;						\
+											\
+	assert(NULL != GVNH_REG);							\
+	if (NULL != GVNH_REG->gvspan)							\
+	{										\
+		GV_BIND_SUBSNAME(GVNH_REG, GD_HEADER, GVKEY, REG);			\
+	} else										\
+		TREF(gd_targ_gvnh_reg) = NULL;						\
+}
+
+#define	GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(GVNH_REG, GD_HEADER, GVKEY)						\
+{															\
+	gvnh_reg_t			*gvnhReg; /* use unique name to avoid name collisions with macro caller */	\
+	DEBUG_ONLY(													\
+		ht_ent_mname		*tabent;									\
+		GBLREF gv_namehead	*gv_target;									\
+		gvnh_reg_t		*tmp_gvnhReg;									\
+	)														\
+															\
+	gvnhReg = GVNH_REG;	/* set by op_gvname in previous call */							\
+	DEBUG_ONLY(													\
+		tabent = lookup_hashtab_mname((hash_table_mname *)((GD_HEADER)->tab_ptr), &gv_target->gvname);		\
+		assert(NULL != tabent);											\
+		tmp_gvnhReg = (gvnh_reg_t *)tabent->value;								\
+		assert(NULL != tmp_gvnhReg);										\
+		if (NULL != tmp_gvnhReg->gvspan)									\
+			assert(tmp_gvnhReg == gvnhReg);									\
+		else													\
+			assert(NULL == gvnhReg);									\
+	)														\
+	/* A non-NULL value of gvnh_reg indicates a spanning global as confirmed by the assert below */			\
+	assert((NULL == gvnhReg) || (TREF(spangbl_seen) && (NULL != gvnhReg->gvspan)));					\
+	if (NULL != gvnhReg)												\
+		gv_bind_subsname(GD_HEADER, GVKEY, GVNH_REG);								\
+}
+
+/* This macro is similar to GV_BIND_SUBSNAME_IF_GVSPAN except we know for sure this is a spanning global */
+#define	GV_BIND_SUBSNAME(GVNH_REG, GD_HEADER, GVKEY, REG)					\
+{	/* This is a global that spans multiple regions. Re-bind the subscripted reference			\
+	 * just in case this maps to a different region than the unsubscripted global name.			\
+	 */													\
+	TREF(gd_targ_gvnh_reg) = GVNH_REG;									\
+	gv_bind_subsname(GD_HEADER, GVKEY, GVNH_REG);						\
+	/* gv_target/gv_cur_region/cs_addrs/cs_data are now initialized even for non-NULL gvnh_reg->gvspan */	\
+	/* In addition TREF(gd_targ_map) is set as well */							\
+	REG = gv_cur_region;	/* adjust "REG" in case gv_cur_region was modified in the above call */		\
+}
+
+/* sets gv_target to correspond to REG region of spanning global. also sets gv_target->root if not already non-zero.
+ * also sets global variables gv_cur_region/cs_addrs/cs_data to correspond to input region.
+ */
+#define	GV_BIND_SUBSREG(ADDR, REG, GVNH_REG)						\
+{											\
+	gv_namehead			*gvt;						\
+	gvnh_spanreg_t			*gvspan;					\
+	int				min_reg_index, reg_index;			\
+	DEBUG_ONLY(enum db_acc_method	acc_meth;)					\
+											\
+	GBLREF gv_namehead	*gv_target;						\
+											\
+	if (!REG->open)									\
+		gv_init_reg(REG);							\
+	gvspan = GVNH_REG->gvspan;							\
+	assert(NULL != gvspan);								\
+	min_reg_index = gvspan->min_reg_index;						\
+	GET_REG_INDEX(ADDR, &ADDR->regions[0], REG, reg_index);	/* sets "reg_index" */	\
+	assert(reg_index >= min_reg_index);						\
+	assert(reg_index <= gvspan->max_reg_index);					\
+	gvt = gvspan->gvt_array[reg_index - min_reg_index];				\
+	/* Assert that this region is indeed mapped to by the spanning global */	\
+	assert(INVALID_GV_TARGET != gvt);						\
+	if (NULL == gvt)								\
+	{										\
+		gvt = targ_alloc(REG->max_key_size, &GVNH_REG->gvt->gvname, REG);	\
+		COPY_ACT_FROM_GVNH_REG_TO_GVT(GVNH_REG, gvt, REG);			\
+		/* See comment in GVNH_REG_INIT macro for why the below assignment is	\
+		 * placed AFTER all error conditions (in above macro) have passed.	\
+		 */									\
+		gvspan->gvt_array[reg_index - min_reg_index] = gvt;			\
+	}										\
+	gv_target = gvt;								\
+	/* Even though gv_cur_region might already be equal to "REG", need to invoke	\
+	 * "change_reg" in order to do the "tp_set_sgm" in case of TP.			\
+	 */										\
+	gv_cur_region = REG;								\
+	change_reg();									\
+	DEBUG_ONLY(acc_meth = REG_ACC_METH(gv_cur_region);)				\
+	assert((dba_bg == acc_meth) || (dba_mm == acc_meth));				\
+	GVCST_ROOT_SEARCH;								\
 }
 
 /* When invoking grab_lock or grab_gtmsource_srv_latch, use one of the following parameters.
@@ -3761,7 +4469,7 @@ typedef struct
 	{												\
 		int rc;											\
 													\
-		START_CH;										\
+		START_CH(TRUE);										\
 		if ((int)ERR_TPRETRY == SIGNAL)								\
 		{											\
 			rc = tp_restart(1, !TP_RESTART_HANDLES_ERRORS);					\
@@ -3776,9 +4484,6 @@ typedef struct
 {															\
 	GBLREF	boolean_t 		span_nodes_disallowed;								\
 															\
-	error_def(ERR_TEXT); /* BYPASSOK */										\
-	error_def(ERR_UNIMPLOP); /* BYPASSOK */										\
-															\
 	if (span_nodes_disallowed)											\
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_UNIMPLOP, 0,	ERR_TEXT, 2,				\
 					LEN_AND_LIT("GT.CM Server does not support spanning nodes"));			\
@@ -3867,79 +4572,107 @@ typedef struct
 	} else									\
 		break;								\
 }
-#define CHECK_HIDDEN_SUBSCRIPT(KEY, IS_HIDDEN)										\
-{															\
-	sm_uc_ptr_t	keyloc;												\
-															\
-	keyloc = (KEY)->base + (KEY)->end - 5;										\
-	if ((KEY)->end >= 5 && 0 == *keyloc && 2 == *(keyloc+1))							\
-		IS_HIDDEN = TRUE;											\
-	else														\
-		IS_HIDDEN = FALSE;											\
+#define CHECK_HIDDEN_SUBSCRIPT(KEY, IS_HIDDEN)					\
+{										\
+	sm_uc_ptr_t	keyloc;							\
+										\
+	keyloc = (KEY)->base + (KEY)->end - 5;					\
+	if ((KEY)->end >= 5 && 0 == *keyloc && 2 == *(keyloc+1))		\
+		IS_HIDDEN = TRUE;						\
+	else									\
+		IS_HIDDEN = FALSE;						\
 }
-#define SAVE_GV_CURRKEY									\
-{											\
-	assert(NULL != gv_currkey);							\
-	assert((SIZEOF(gv_key) + gv_currkey->end) <= SIZEOF(save_currkey));		\
-	save_gv_currkey = (gv_key *)&save_currkey[0];					\
-	memcpy(save_gv_currkey, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);		\
+#define SAVE_GV_CURRKEY(SAVE_KEY)						\
+{										\
+	assert(NULL != gv_currkey);						\
+	assert((SIZEOF(gv_key) + gv_currkey->end) <= SIZEOF(SAVE_KEY));		\
+	memcpy(&SAVE_KEY[0], gv_currkey, SIZEOF(gv_key) + gv_currkey->end);	\
 }
-#define RESTORE_GV_CURRKEY								\
-{											\
-	assert(gv_currkey->top == save_gv_currkey->top);				\
-	memcpy(gv_currkey, save_gv_currkey, SIZEOF(gv_key) + save_gv_currkey->end);	\
+#define RESTORE_GV_CURRKEY(SAVE_KEY)						\
+{										\
+	assert(gv_currkey->top == SAVE_KEY[0].top);				\
+	memcpy(gv_currkey, &SAVE_KEY[0], SIZEOF(gv_key) + SAVE_KEY[0].end);	\
 }
-#define SAVE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend)			\
+#define SAVE_GV_CURRKEY_LAST_SUBSCRIPT(SAVE_KEY, PREV, OLDEND)				\
 {											\
-	prev = gv_currkey->prev;							\
-	oldend = gv_currkey->end;							\
+	PREV = gv_currkey->prev;							\
+	OLDEND = gv_currkey->end;							\
 	assert('\0' == gv_currkey->base[oldend]);					\
-	if (prev <= oldend)								\
-		memcpy(save_currkey, &gv_currkey->base[prev], oldend - prev + 1);	\
+	if (PREV <= OLDEND)								\
+		memcpy(&SAVE_KEY[0], &gv_currkey->base[PREV], OLDEND - PREV + 1);	\
 }
-#define RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend)			\
+#define RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(SAVE_KEY, PREV, OLDEND)			\
 {											\
-	gv_currkey->prev = prev;							\
-	gv_currkey->end = oldend;							\
-	if (prev <= oldend)								\
-		memcpy(&gv_currkey->base[prev], save_currkey, oldend - prev + 1);	\
-	assert('\0' == gv_currkey->base[oldend]);					\
+	gv_currkey->prev = PREV;							\
+	gv_currkey->end = OLDEND;							\
+	if (PREV <= OLDEND)								\
+		memcpy(&gv_currkey->base[PREV], &SAVE_KEY[0], OLDEND - PREV + 1);	\
+	assert('\0' == gv_currkey->base[OLDEND]);					\
 }
 
 #define CAN_APPEND_HIDDEN_SUBS(KEY)	(((KEY)->end + 5 <= MAX_KEY_SZ) && ((KEY)->end + 5 <= (KEY)->top))
-#define APPEND_HIDDEN_SUB(KEY)										\
-{													\
-	int	end;											\
-													\
-	assert(CAN_APPEND_HIDDEN_SUBS(KEY));								\
-	end = gv_currkey->end;										\
-	gv_currkey->end += 4;										\
-	(KEY)->base[end++] = 2;										\
-	(KEY)->base[end++] = 1;										\
-	(KEY)->base[end++] = 1;										\
-	(KEY)->base[end++] = 0;										\
-	(KEY)->base[end] = 0;										\
-}
-#define NEXT_HIDDEN_SUB(KEY, I)										\
-{													\
-	int	end;											\
-													\
-	end = gv_currkey->end - 4;									\
-	(KEY)->base[end++] = 2;										\
-	(KEY)->base[end++] = 1 + ((I + 1) / 0xFF);							\
-	(KEY)->base[end++] = 1 + ((I + 1) % 0xFF);							\
-	(KEY)->base[end++] = 0;										\
-	(KEY)->base[end] = 0;										\
-}
-#define RESTORE_CURRKEY(KEY, OLDEND)									\
-{													\
-	(KEY)->end = OLDEND;										\
-	(KEY)->base[OLDEND - 1] = 0; 									\
-	(KEY)->base[OLDEND] = 0;									\
+#define APPEND_HIDDEN_SUB(KEY)			\
+{						\
+	assert(CAN_APPEND_HIDDEN_SUBS(KEY));	\
+	(KEY)->end += 4;			\
+	REPLACE_HIDDEN_SUB_TO_LOWEST(KEY, KEY);	\
 }
-#define COMPUTE_CHUNK_SIZE(KEY, BLKSZ, RESERVED)							\
+#define	REPLACE_HIDDEN_SUB_TO_LOWEST(KEY1, KEY2)	\
+{							\
+	int	end;					\
+							\
+	end = (KEY1)->end;				\
+	(KEY2)->base[end - 4] = 2;			\
+	(KEY2)->base[end - 3] = 1;			\
+	(KEY2)->base[end - 2] = 1;			\
+	(KEY2)->base[end - 1] = 0;			\
+	(KEY2)->base[end - 0] = 0;			\
+	assert(end < (KEY2)->top);			\
+	(KEY2)->end = end;				\
+}
+#define	REPLACE_HIDDEN_SUB_TO_HIGHEST(KEY1, KEY2)	\
+{							\
+	int	end;					\
+	end = (KEY1)->end;				\
+	(KEY2)->base[end - 4] = 2;			\
+	(KEY2)->base[end - 3] = 0xFF;			\
+	(KEY2)->base[end - 2] = 0xFF;			\
+	(KEY2)->base[end - 1] = 1;			\
+	(KEY2)->base[end + 0] = 0;			\
+	(KEY2)->base[end + 1] = 0;			\
+	assert((end + 1) < (KEY2)->top);		\
+	(KEY2)->end = end + 1;				\
+}
+
+#define NEXT_HIDDEN_SUB(KEY, I)				\
+{							\
+	int	end;					\
+							\
+	end = gv_currkey->end - 4;			\
+	(KEY)->base[end++] = 2;				\
+	(KEY)->base[end++] = 1 + ((I + 1) / 0xFF);	\
+	(KEY)->base[end++] = 1 + ((I + 1) % 0xFF);	\
+	(KEY)->base[end++] = 0;				\
+	(KEY)->base[end] = 0;				\
+}
+#define RESTORE_CURRKEY(KEY, OLDEND)			\
+{							\
+	(KEY)->end = OLDEND;				\
+	(KEY)->base[OLDEND - 1] = 0; 			\
+	(KEY)->base[OLDEND] = 0;			\
+}
+#define COMPUTE_CHUNK_SIZE(KEY, BLKSZ, RESERVED)					\
 	(BLKSZ - RESERVED - ((KEY)->end + 1) - SIZEOF(blk_hdr) - SIZEOF(rec_hdr))
 
+/* in MM mode, AIX increases native DB file size to adjust to the next nearest multiple of OS_PAGE_SIZE if the file is mapped
+ * using shmat() and last portion of the file is accessed. To take into account this adjustment, following macro adjust the
+ * value of DB file size determined using block count, constant DB HEADER SIZE and constant MASTER MAP size and EOF block.
+ * Since We can change the DB access method using MUPIP SET and we can move the dabtabase from AIX to non-AIX platfrom,
+ * following macro is not just AIX specific.
+ */
+#define ALIGN_DBFILE_SIZE_IF_NEEDED(SZ, NATIVE_SZ)						\
+		SZ = (SZ == NATIVE_SZ) ? SZ : ROUND_UP(SZ, (OS_PAGE_SIZE / DISK_BLOCK_SIZE));
+
 void		assert_jrec_member_offsets(void);
 bt_rec_ptr_t	bt_put(gd_region *r, int4 block);
 void		bt_que_refresh(gd_region *greg);
@@ -3975,7 +4708,12 @@ int4 bmm_find_free(uint4 hint, uchar_ptr_t base_addr, uint4 total_bits);
 
 bool reg_cmcheck(gd_region *reg);
 
-void gv_bind_name(gd_addr *addr, mstr *targ);
+gd_binding	*gv_srch_map(gd_addr *addr, char *key, int key_len);
+gd_binding	*gv_srch_map_linear(gd_binding *start_map, char *key, int key_len);
+gd_binding	*gv_srch_map_linear_backward(gd_binding *start_map, char *key, int key_len);
+gd_gblname	*gv_srch_gblname(gd_addr *addr, char *key, int key_len);
+gvnh_reg_t	*gv_bind_name(gd_addr *addr, mname_entry *targ);
+void 		gv_bind_subsname(gd_addr *addr, gv_key *key, gvnh_reg_t *gvnh_reg);
 
 void db_csh_ini(sgmnt_addrs *cs);
 void db_csh_ref(sgmnt_addrs *cs_addrs, boolean_t init);
@@ -3989,7 +4727,7 @@ sm_uc_ptr_t get_lmap(block_id blk, unsigned char *bits, sm_int_ptr_t cycle, cach
 bool ccp_userwait(struct gd_region_struct *reg, uint4 state, int4 *timadr, unsigned short cycle);
 void ccp_closejnl_ast(struct gd_region_struct *reg);
 bt_rec *ccp_bt_get(sgmnt_addrs *cs_addrs, int4 block);
-unsigned char *mval2subsc(mval *in_val, gv_key *out_key);
+unsigned char *mval2subsc(mval *in_val, gv_key *out_key, boolean_t std_null_coll);
 
 int4	dsk_read(block_id blk, sm_uc_ptr_t buff, enum db_ver *ondisk_blkver, boolean_t blk_free);
 
@@ -4016,6 +4754,8 @@ void	gvstats_rec_csd2cnl(sgmnt_addrs *csa);
 void	gvstats_rec_cnl2csd(sgmnt_addrs *csa);
 void	gvstats_rec_upgrade(sgmnt_addrs *csa);
 
+void act_in_gvt(gv_namehead *gvt);
+
 #include "gdsfheadsp.h"
 
 /* End of gdsfhead.h */
diff --git a/sr_port/iotcp_read.c b/sr_port/get_dlr_zkey.c
similarity index 66%
rename from sr_port/iotcp_read.c
rename to sr_port/get_dlr_zkey.c
index 11dba9c..4d650c0 100644
--- a/sr_port/iotcp_read.c
+++ b/sr_port/get_dlr_zkey.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,8 +11,12 @@
 
 #include "mdef.h"
 #include "io.h"
+#include "stringpool.h"
 
-int	iotcp_read (mval *v, int4 timeout)
+GBLREF io_pair		io_curr_device;
+
+void get_dlr_zkey(mval *v)
 {
-        return iotcp_readfl(v, 0, timeout);	/* 0 means not fixed length */
+	(io_curr_device.out->disp_ptr->dlr_zkey)(&v->str);
+	v->mvtype = MV_STR;
 }
diff --git a/sr_port/get_dollar_stack_info.c b/sr_port/get_dollar_stack_info.c
index 12c9286..8a9edf4 100644
--- a/sr_port/get_dollar_stack_info.c
+++ b/sr_port/get_dollar_stack_info.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,7 +21,7 @@ void	get_dollar_stack_info(int level, stack_mode_t mode,  mval *result)
 {
 	assert(0 <= level);
 	assert(level < dollar_stack.index);
-	switch(mode)
+	switch (mode)
 	{
 		case DOLLAR_STACK_MODE:
 			result->str = dollar_stack.array[level].mode_str;
@@ -42,9 +42,9 @@ void	get_dollar_stack_info(int level, stack_mode_t mode,  mval *result)
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && mode);
 	}
 	s2pool(&result->str);
-	assert(!result->str.len || ((unsigned char *)result->str.addr + result->str.len) == stringpool.free);
+	assert(!result->str.len || IS_AT_END_OF_STRINGPOOL(result->str.addr, result->str.len));
 	return;
 }
diff --git a/sr_port/get_frame_place_mcode.c b/sr_port/get_frame_place_mcode.c
index e9bdea1..11ee846 100644
--- a/sr_port/get_frame_place_mcode.c
+++ b/sr_port/get_frame_place_mcode.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -90,7 +90,7 @@ void	get_frame_place_mcode(int level, stack_mode_t mode, int cur_zlevel, mval *r
 		if (result->str.len)
 		{
 			s2pool(&result->str);
-			assert(((unsigned char *)result->str.addr + result->str.len) == stringpool.free);
+			assert(IS_AT_END_OF_STRINGPOOL(result->str.addr, result->str.len));
 		}
 	}
 	if (DOLLAR_STACK_MCODE == mode)
@@ -162,7 +162,7 @@ void	get_frame_place_mcode(int level, stack_mode_t mode, int cur_zlevel, mval *r
 				assert(0 < indce->refcnt);	/* currently used in the M stack better have a non-zero refcnt */
 				s2pool(&indce->src.str);
 				result->str = indce->src.str;
-				assert(((unsigned char *)result->str.addr + result->str.len) == stringpool.free);
+				assert(IS_AT_END_OF_STRINGPOOL(result->str.addr, result->str.len));
 			} else
 			{	/* Not a real indirect. The mpc may have been reset by error handling to various assembler
 				 * routines or it just may be broken. Whatever the reason, the value to return is that the
diff --git a/sr_port/glvn_pool.h b/sr_port/glvn_pool.h
index aa82f2c..948b444 100644
--- a/sr_port/glvn_pool.h
+++ b/sr_port/glvn_pool.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -131,7 +131,7 @@ void	op_indsavglvn(mval *target, uint4 slot, uint4 do_ref);			/* Used by [SET an
 void	op_indsavlvn(mval *target, uint4 slot);					/* Used by [FOR] */
 void	op_rfrshgvn(uint4 indx, opctype oc);					/* Used by [SET and $ORDER()] */
 lv_val	*op_rfrshlvn(uint4 indx, opctype oc);					/* Used by [FOR, SET and $ORDER()] */
-void	op_savgvn(UNIX_ONLY_COMMA(int argcnt) mval *val_arg, ...);		/* Used by [SET and $ORDER()] */
+void	op_savgvn(UNIX_ONLY_COMMA(int argcnt) int hash_code_dummy, mval *val_arg, ...);	/* Used by [SET and $ORDER()] */
 void	op_savlvn(UNIX_ONLY_COMMA(int argcnt) lv_val *start, ...);		/* Used by [FOR, SET and $ORDER()] */
 void	op_shareslot(uint4 indx, opctype opcode);				/* Used by [FOR, SET and $ORDER()] */
 void	op_stoglvn(uint4 indx, mval *value);					/* Used by [SET] */
diff --git a/sr_port/gtm_common_defs.h b/sr_port/gtm_common_defs.h
index 4b75d9c..14cd3b2 100644
--- a/sr_port/gtm_common_defs.h
+++ b/sr_port/gtm_common_defs.h
@@ -80,6 +80,10 @@
 #  define DIR_SEPARATOR		'/'
 #endif
 
+/* Use the below macros for function declarations and definitions that are part of an API */
+#define _GTM_APIDECL
+#define _GTM_APIDEF
+
 /* the LITERAL version of the macro should be used over STRING whenever possible for efficiency reasons */
 #define	STR_LIT_LEN(LITERAL)			(SIZEOF(LITERAL) - 1)
 #define	LITERAL_AND_LENGTH(LITERAL)		(LITERAL), (SIZEOF(LITERAL) - 1)
diff --git a/sr_port/gtm_connect.c b/sr_port/gtm_connect.c
new file mode 100644
index 0000000..983d9eb
--- /dev/null
+++ b/sr_port/gtm_connect.c
@@ -0,0 +1,58 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+/*  get socket routines address */
+#include "mdef.h"
+
+#include "gtm_netdb.h"
+#include "gtm_unistd.h"
+#include <errno.h>
+#include "gtm_socket.h"
+#include "gtm_inet.h"
+#include "gtm_string.h"
+
+int	gtm_connect(int socket, struct sockaddr *address, size_t address_len)
+{
+	int			res, sockerror;
+	GTM_SOCKLEN_TYPE	sockerrorlen;
+	fd_set			writefds;
+
+	res = connect(socket, address, (GTM_SOCKLEN_TYPE)address_len);
+	if ((-1 == res) && ((EINTR == errno) || (EINPROGRESS == errno)
+#if (defined(__osf__) && defined(__alpha)) || defined(__sun) || defined(__vms)
+			|| (EWOULDBLOCK == errno)
+#endif
+			 ))
+	{/* connection attempt will continue so wait for completion */
+		do
+		{	/* a plain connect will usually timeout after 75 seconds with ETIMEDOUT */
+			FD_ZERO(&writefds);
+			FD_SET(socket, &writefds);
+			res = select(socket + 1, NULL, &writefds, NULL, NULL);
+			if (-1 == res && EINTR == errno)
+				continue;
+			if (0 < res)
+			{	/* check for socket error */
+				sockerrorlen = SIZEOF(sockerror);
+				res = getsockopt(socket, SOL_SOCKET, SO_ERROR, &sockerror, &sockerrorlen);
+				if (0 == res && 0 != sockerror)
+				{	/* return socket error */
+					res = -1;
+					errno = sockerror;
+				}
+			}
+			break;
+		} while (TRUE);
+	} else if (-1 == res && EISCONN == errno)
+		res = 0;		/* socket is already connected */
+
+	return(res);
+}
diff --git a/sr_port/gtm_env_init.c b/sr_port/gtm_env_init.c
index 3c0675c..013c8f7 100644
--- a/sr_port/gtm_env_init.c
+++ b/sr_port/gtm_env_init.c
@@ -25,7 +25,6 @@
 #include "gtm_env_init.h"	/* for gtm_env_init() and gtm_env_init_sp() prototype */
 #include "gt_timer.h"
 #include "io.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 #include "gtm_malloc.h"
 #include "cache.h"
@@ -59,6 +58,11 @@
 #endif
 #define SIZEOF_prombuf ggl_prombuf
 
+/* gtm_dirtree_collhdr_always is only used in dbg code and hence doesn't need checking in the D9I10002703 subtest
+ * Hence this env var is not defined in gtm_logicals.h as that is what the D9I10002703 subtest looks at for a list of env vars.
+ */
+#define	GTM_DIRTREE_COLLHDR_ALWAYS	"$gtm_dirtree_collhdr_always"
+
 GBLREF	boolean_t	dollar_zquit_anyway;	/* if TRUE compile QUITs to not care whether or not they're from an extrinsic */
 GBLREF	uint4		gtmDebugLevel; 		/* Debug level (0 = using default sm module so with
 						   a DEBUG build, even level 0 implies basic debugging) */
@@ -154,6 +158,13 @@ void	gtm_env_init(void)
 		ret = logical_truth_value(&val, FALSE, &is_defined);
 		if (is_defined)
 			TREF(gtm_gvundef_fatal) = ret; /* if logical is not defined, gtm_gvundef_fatal takes the default value */
+		/* GTM_DIRTREE_COLLHDR_ALWAYS environment/logical */
+		val.addr = GTM_DIRTREE_COLLHDR_ALWAYS;
+		val.len = SIZEOF(GTM_DIRTREE_COLLHDR_ALWAYS) - 1;
+		assert(FALSE == TREF(gtm_dirtree_collhdr_always));	/* should have been set to FALSE by gtm_threadgbl_defs */
+		ret = logical_truth_value(&val, FALSE, &is_defined);
+		if (is_defined)
+			TREF(gtm_dirtree_collhdr_always) = ret; /* if logical is not defined, the TREF takes the default value */
 #		endif
 		/* Initialize variable that controls TP allocation clue (for created blocks) */
 		val.addr = GTM_TP_ALLOCATION_CLUE;
diff --git a/sr_port/gtm_imagetype_init.c b/sr_port/gtm_imagetype_init.c
index 3f7146d..cf140fd 100644
--- a/sr_port/gtm_imagetype_init.c
+++ b/sr_port/gtm_imagetype_init.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,6 +10,9 @@
  ****************************************************************/
 
 #include "mdef.h"
+#include "gtm_limits.h"
+#include "gtm_stdlib.h"
+#include "gtm_string.h"
 
 #include "gtmimagename.h"
 #include "gtm_imagetype_init.h"
@@ -23,11 +26,14 @@ GBLREF	enum gtmImageTypes	image_type;
 #ifdef UNIX
 GBLREF	boolean_t		jnlpool_init_needed;
 GBLREF	boolean_t 		span_nodes_disallowed;
+GBLREF	char			gtm_dist[GTM_PATH_MAX];
 #endif
 
 void	gtm_imagetype_init(enum gtmImageTypes img_type)
 {
 	boolean_t		is_svc_or_gtcm;
+	char			*dist;
+	int			len = 0;
 
 	NON_GTMTRIG_ONLY(skip_dbtriggers = TRUE;) /* Do not invoke triggers for trigger non-supporting platforms. */
 	UNIX_ONLY(span_nodes_disallowed = (GTCM_GNP_SERVER_IMAGE == img_type) || (GTCM_SERVER_IMAGE == img_type);)
@@ -53,6 +59,17 @@ void	gtm_imagetype_init(enum gtmImageTypes img_type)
 	 * of first database open (in gvcst_init). So, set jnlpool_init_needed to TRUE if this is GTM_IMAGE.
 	 */
 	jnlpool_init_needed = (GTM_IMAGE == img_type);
+	/* Read gtm_dist here and use this value everywhere else */
+	dist = (char *)GETENV(GTM_DIST);
+	if (dist)
+		len = STRLEN(dist);
+	if(len)
+	{
+		memcpy(gtm_dist, dist, ((len > GTM_PATH_MAX) ? GTM_PATH_MAX : len));
+		gtm_dist[GTM_PATH_MAX - 1] = '\0';
+	}
+	else
+		gtm_dist[0] = '\0';
 #	endif
 	image_type = img_type;
 	return;
diff --git a/sr_port/gtm_malloc_src.h b/sr_port/gtm_malloc_src.h
index 984b125..0236f0f 100644
--- a/sr_port/gtm_malloc_src.h
+++ b/sr_port/gtm_malloc_src.h
@@ -500,11 +500,17 @@ void gtmSmInit(void)	/* Note renamed to gtmSmInit_dbg when included in gtm_mallo
 	/* If this routine is entered and environment vars have not yet been processed with a call to gtm_env_init(),
 	 * then do this now. Since this will likely trigger a call to this routine *again*, verify if we still need
 	 * to do this and if not, just return.
+	 *
+	 * Note that in a pro build, this routine (like several others in this module) has two flavors (pro and dbg)
+	 * with the debug flavor being named gtmSmInitdbg(). If driving gtm_env_init() tells us that we want to use
+	 * the debug storage manager (i.e. gtmDebugLevel is non-zero), then we need to not finish this initialization
+	 * and return to gtm_malloc() which also notes this change and drives gtm_malloc_dbg() which then drives the
+	 * correct initialization routine.
 	 */
 	if (!TREF(gtm_env_init_started))
 	{
 		gtm_env_init();
-		if (gtmSmInitialized)
+		if (gtmSmInitialized PRO_ONLY(|| (0 != gtmDebugLevel)))
 			return;		/* A nested call took care of this already so we're done! */
 	}
 	/* WARNING!! Since this is early initialization, the following asserts are not well behaved if they do
@@ -876,7 +882,12 @@ void *gtm_malloc(size_t size)	/* Note renamed to gtm_malloc_dbg when included in
 			 * call to malloc), we will not record the proper caller id in the storage header or in
 			 * the traceback table. The caller will show up as gtm_malloc(). However, all subsequent
 			 * calls will be correct.
+			 *
+			 * Note, in a pro build, if the call to gtmSmInit() drives gtm_init_env() which discovers
+			 * we should be be doing debug builds, drive the debug flavor of gtm_malloc instead which
+			 * will do its own initialization if it still needs to (see top of gtmSmInit() above).
 			 */
+			PRO_ONLY(if (0 != gtmDebugLevel) return (void *)gtm_malloc_dbg(size));
 			return (void *)gtm_malloc(size);
 		}
 #	ifndef DEBUG
diff --git a/sr_port/gtm_maxstr.c b/sr_port/gtm_maxstr.c
index 32624ae..3c80ef6 100644
--- a/sr_port/gtm_maxstr.c
+++ b/sr_port/gtm_maxstr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2003 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,7 +25,7 @@ GBLDEF  int	maxstr_stack_level = -1;
  * should do the same so that the storage is not kept dangling. */
 CONDITION_HANDLER(gtm_maxstr_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (maxstr_buff[maxstr_stack_level].addr)
 	{
 		free(maxstr_buff[maxstr_stack_level].addr);
diff --git a/sr_port/gtm_netdb.h b/sr_port/gtm_netdb.h
index b38ee61..3ecbaf6 100644
--- a/sr_port/gtm_netdb.h
+++ b/sr_port/gtm_netdb.h
@@ -17,6 +17,24 @@
 
 #define MAX_GETHOST_TRIES	8
 
+#define SA_MAXLEN	NI_MAXHOST	/* NI_MAXHOST is 1025, large enough to hold any IPV6 address format
+					 * e.g.(123:567:901:345:215:0:0:0)
+					 */
+#define SA_MAXLITLEN	NI_MAXHOST	/* large enough to hold any host name, e.g.
+					 * host name google: dfw06s16-in-x12.1e100.net
+					 */
+#define USR_SA_MAXLITLEN	128	/* maximum size of host GTM user can specify
+					 * the reason why the number is so small is because the host name size
+					 * is stored as one byte in socket parameter list (refer to iosocket_use)
+					 */
+
+#ifdef VMS
+#define VMS_MAX_TCP_IO_SIZE	(64 * 1024 - 512)	/* Hard limit for TCP send or recv size. On some implementations, the limit
+							 * is 64K - 1, on others it is 64K - 512. We take the conservative approach
+							 * and choose the lower limit
+						   	 */
+#endif
+
 /* Macro to issue an rts_error_csa() with the results of getaddrinfo() or getnameinfo().
  * Takes ERR_GETADDRINFO or ERR_GETNAMEINFO as the mnemonic.
  */
@@ -39,5 +57,13 @@
 				ERR_TEXT, 2, RTS_ERROR_LITERAL(CONTEXT),			\
 				ERR_TEXT, 2, RTS_ERROR_STRING(gai_strerror(ERRCODE)));		\
 }
+/* Get either string for either system or gai error */
+#define TEXT_ADDRINFO(TEXT, ERRCODE, SAVEERRNO)			\
+{								\
+	if (EAI_SYSTEM == ERRCODE)				\
+		TEXT = (char *)STRERROR(SAVEERRNO);		\
+	else							\
+		TEXT = (char *)gai_strerror(ERRCODE);			\
+}
 
 #endif
diff --git a/sr_port/gtm_repl.h b/sr_port/gtm_repl.h
new file mode 100644
index 0000000..46bdf89
--- /dev/null
+++ b/sr_port/gtm_repl.h
@@ -0,0 +1,74 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#ifndef _GTM_REPL_H
+#define _GTM_REPL_H
+
+#ifdef GTM_TLS
+#include "gtm_tls.h"
+
+typedef enum
+{
+	REPLTLS_RENEG_STATE_NONE,
+	REPLTLS_WAITING_FOR_RENEG_TIMEOUT,
+	REPLTLS_WAITING_FOR_RENEG_ACK,
+	REPLTLS_SKIP_RENEGOTIATION,
+	REPLTLS_WAITING_FOR_RENEG_COMPLETE	/* Used only by the receiver. */
+} repl_tls_reneg_state;
+
+typedef struct repl_tls_info_struct
+{
+	char			id[MAX_TLSID_LEN];
+	boolean_t		plaintext_fallback;
+	boolean_t		enabled;
+	boolean_t		notls_retry;
+	repl_tls_reneg_state	renegotiate_state;
+	gtm_tls_socket_t	*sock;
+} repl_tls_info_t;
+
+GBLREF	repl_tls_info_t		repl_tls;
+
+error_def(ERR_TLSCLOSE);
+
+#define REPL_TLS_REQUESTED		('\0' != repl_tls.id[0])
+#define CLEAR_REPL_TLS_REQUESTED	repl_tls.id[0] = '\0'
+#define REPL_TLS_ENABLED		(repl_tls.enabled)
+#define CLEAR_REPL_TLS_ENABLED		repl_tls.enabled = FALSE
+#define PLAINTEXT_FALLBACK		(repl_tls.plaintext_fallback)
+
+#define DEFAULT_RENEGOTIATE_TIMEOUT	(2 * 60) /* About 2 hours between renegotiation. */
+#define MIN_RENEGOTIATE_TIMEOUT		1
+
+#define REPLTLS_SET_NEXT_RENEGOTIATE_HRTBT(NEXT_RENEG_HRTBT)									\
+{																\
+	if (0 < gtmsource_options.renegotiate_interval)										\
+	{															\
+		repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_TIMEOUT;							\
+		NEXT_RENEG_HRTBT = heartbeat_counter + gtmsource_options.renegotiate_interval;					\
+		gtmsource_local->next_renegotiate_time = (uint4)time(NULL)							\
+							+ gtmsource_options.renegotiate_interval * HEARTBEAT_INTERVAL_IN_SECS;	\
+	}															\
+}
+
+#define ISSUE_REPLNOTLS(ERRID, STR1, STR2)											\
+{																\
+	if (!PLAINTEXT_FALLBACK)												\
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERRID, 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2));			\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERRID), 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2));		\
+}
+
+void	repl_log_tls_info(FILE *logfp, gtm_tls_socket_t *socket);
+int 	repl_do_tls_handshake(FILE *logfp, int sock_fd, boolean_t do_accept, int *poll_direction);
+void	repl_do_tls_init(FILE *logfp);
+
+#endif	/* GTM_TLS */
+
+#endif
diff --git a/sr_unix/iotcp_select.h b/sr_port/gtm_select.h
similarity index 80%
rename from sr_unix/iotcp_select.h
rename to sr_port/gtm_select.h
index e84c408..75b883c 100644
--- a/sr_unix/iotcp_select.h
+++ b/sr_port/gtm_select.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,7 +9,7 @@
  *								*
  ****************************************************************/
 
-/*	iotcp_select.h - include Unix system header files needed by select().  */
+/*	gtm_select.h - include Unix system header files needed by select().  */
 
 #if	defined(_AIX) || defined(__CYGWIN__) || defined(_UWIN)
 #include <sys/select.h>
@@ -29,6 +29,10 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#elif defined(VMS)
+#include <time.h>
+#include <socket.h>
+
 #else
 #error UNSUPPORTED PLATFORM
 
diff --git a/sr_port/gtm_threadgbl_defs.h b/sr_port/gtm_threadgbl_defs.h
index 778cd8c..cacdd7b 100644
--- a/sr_port/gtm_threadgbl_defs.h
+++ b/sr_port/gtm_threadgbl_defs.h
@@ -79,9 +79,46 @@ THREADGBLDEF(dbinit_max_hrtbt_delta,		uint4)				/* max heartbeats before we bail
 THREADGBLDEF(dollar_zmaxtptime, 		int4)				/* tp timeout in seconds */
 THREADGBLDEF(donot_commit,			boolean_t)			/* debug-only - see gdsfhead.h for purpose */
 THREADGBLDEF(donot_write_inctn_in_wcs_recover,	boolean_t)			/* TRUE if wcs_recover should NOT write INCTN */
-THREADGBLDEF(gd_targ_addr,			gd_addr *)			/* current global directory reference */
+THREADGBLDEF(gd_targ_tn,			trans_num)			/* number that is incremented for every gvcst_spr*
+										 * action. helps easily determine whether a region
+										 * has already been seen in this gvcst_spr* action.
+										 */
+THREADGBLDEF(gd_targ_reg_array,			trans_num *)			/* Indicates which regions are already part of
+										 * current spanning-region database action.
+										 * Array is NULL if no spanning globals were
+										 * detected as part of opening global directory.
+										 */
+THREADGBLDEF(gd_targ_reg_array_size,		uint4)				/* Size of current gd_targ_reg_array allocation.
+										 * Non-zero only if at least one spanning global
+										 * has been seen at time of gld open.
+										 */
+THREADGBLDEF(gd_targ_addr,			gd_addr *)			/* current global directory reference. Needed by
+										 * name level $order or $zprevious to know inside
+										 * op_gvorder.c/op_zprevious.c whether the global
+										 * reference went through op_gvname/op_gvextnam.
+										 * Also needed by gvcst_spr_*.c etc.
+										 */
+THREADGBLDEF(gd_targ_gvnh_reg,			gvnh_reg_t *)			/* Pointer to the gvnh_reg corresponding to the
+										 * unsubscripted gvn reference that last went
+										 * through op_gvname/op_gvnaked/op_gvextnam.
+										 * Set to a non-NULL value for spanning globals
+										 * and to NULL for non-spanning globals (because
+										 * it offers an easy way to check for spanning
+										 * globals in op_gv* functions before invoking
+										 * the corresponding gvcst_spr_* functions).
+										 * Needed by op_gvorder etc. to avoid having to
+										 * recompute this based on gd_header & gv_currkey.
+										 */
+THREADGBLDEF(gd_targ_map,			gd_binding *)			/* map entry to which "gv_bind_subsname" bound
+										 * the subscripted gvn. Maintained ONLY for spanning
+										 * globals. Cannot be relied upon in case the
+										 * current reference is for a non-spanning global.
+										 * (i.e. is usable only if gd_targ_gvnh_reg->gvspan
+										 * is non-NULL). This is needed by gvcst_spr_*
+										 * functions to avoid recomputing the map (using
+										 * gv_srch_map) based on gd_header/gv_currkey.
+										 */
 THREADGBLDEF(gtm_custom_errors,			mstr)
-THREADGBLDEF(gtm_gvundef_fatal,			boolean_t)			/* core and die intended for testing */
 THREADGBLDEF(gv_extname_size,			int4)				/* part op_gvextname working memory mechanism */
 THREADGBLDEF(gv_last_subsc_null,		boolean_t)			/* indicates whether the last subscript of
 										 * gv_currkey (aka $reference) is a NULL string */
@@ -95,7 +132,8 @@ THREADGBLDEF(gv_some_subsc_null,		boolean_t)			/* TRUE if SOME subscript other t
 THREADGBLDEF(gv_sparekey,			gv_key *)			/* gv_xform_key working memory */
 THREADGBLDEF(gv_sparekey_mval,			mval)				/* gv_xform_key working memory */
 THREADGBLDEF(gv_sparekey_size,			int4)				/* part gv_xform_key working memory mechanism */
-THREADGBLDEF(gv_tporigkey_ptr,			gv_orig_key_array *)		/* op_tstart tp nesting anchor */
+THREADGBLDEF(gv_tporigkey_ptr,			gv_orig_key_array *)		/* copy of gv_currkey at outermost TSTART */
+THREADGBLDEF(gv_tporig_extnam_str,		mstr)				/* copy of extnam_str at outermost TSTART */
 THREADGBLDEF(in_gvcst_redo_root_search,		boolean_t)			/* TRUE if gvcst_redo_root_search is in C-stack */
 THREADGBLDEF(in_op_gvget,			boolean_t)			/* TRUE if op_gvget() is a C-stack call ancestor */
 THREADGBLDEF(issue_DBROLLEDBACK_anyways,	boolean_t)			/* currently set by MUPIP LOAD */
@@ -161,6 +199,7 @@ THREADGBLDEF(disable_sigcont,			boolean_t)			/* indicates whether the SIGCONT si
 THREADGBLDEF(dollar_zcompile,			mstr)				/* compiler qualifiers */
 THREADGBLDEF(dollar_zmode,			mval)				/* run mode indicator */
 THREADGBLDEF(dollar_zonlnrlbk,			int)				/* ISV (incremented for every online rollback) */
+THREADGBLDEF(dollar_zclose,			int)				/* ISV (set to close status for PIPE device) */
 THREADGBLDEF(dollar_zroutines,			mstr)				/* routine search list */
 THREADGBLDEF(error_on_jnl_file_lost,		unsigned int)			/* controls error handling done by jnl_file_lost.
 										 * 0 (default) : Turn off journaling and continue.
@@ -229,6 +268,7 @@ THREADGBLDEF(pipefifo_interrupt,		int)				/* count of number of times a pipe or
 										 * interrupted */
 #endif
 THREADGBLDEF(prof_fp,				mprof_stack_frame *)		/* Stack frame that mprof currently operates on */
+THREADGBLDEF(relink_allowed,			int)				/* Non-zero if recursive relink permitted */
 THREADGBLDEF(trans_code_pop,			mval *)				/* trans_code holder for $ZTRAP popping */
 THREADGBLDEF(view_ydirt_str,			char *)				/* op_view working storage for ydir* ops */
 THREADGBLDEF(view_ydirt_str_len,		int4)				/* Part of op_view working storage for ydir* ops */
@@ -240,6 +280,8 @@ THREADGBLDEF(zsearch_var,			lv_val *)			/* UNIX $zsearch() lookup variable */
 THREADGBLDEF(zsearch_dir1,			lv_val *)			/* UNIX $zsearch() directory 1 */
 THREADGBLDEF(zsearch_dir2,			lv_val *)			/* UNIX $zsearch() directory 2 */
 #endif
+THREADGBLDEF(poll_fds_buffer,			char *)				/* Buffer for poll() argument */
+THREADGBLDEF(poll_fds_buffer_size,		size_t)				/* Current allocated size of poll_fds_buffer */
 
 /* Larger structures and char strings */
 THREADGBLAR1DEF(director_string,		char,	SIZEOF(mident_fixed))	/* Buffer for director_ident */
@@ -262,7 +304,9 @@ THREADGBLAR1DEF(prombuf,			char,	(MAX_MIDENT_LEN + 1))	/* The prompt buffer size
 										 * commonly used Unicode characters only occupy up
 										 * to 3 bytes, the buffer would at least
 										 * accommodate 10 Unicode characters in a prompt */
+#ifdef VMS
 THREADGBLDEF(rt_name_tbl,			hash_table_mname)		/* Routine hash table for finding $TEXT() info */
+#endif
 THREADGBLAR1DEF(tp_restart_failhist_arry,	char,	FAIL_HIST_ARRAY_SIZE)	/* tp_restart dbg storage of restart history */
 #ifdef UNIX
 THREADGBLDEF(user_id,				uint4)				/* USERID number */
@@ -285,10 +329,8 @@ THREADGBLDEF(ci_table, 				callin_entry_list *)		/* Callin table in the form of
 THREADGBLDEF(extcall_package_root,		struct extcall_package_list *)	/* External call table package list */
 #ifdef UNIX
 THREADGBLDEF(gtmci_nested_level,		unsigned int)			/* Current nested depth of callin environments */
-THREADGBLDEF(in_gtmci,				boolean_t)			/* Indicates if we are in one of the gtm_ci...
-										 * functions. */
+THREADGBLDEF(temp_fgncal_stack,			unsigned char *)		/* Override for fgncal_stack when non-NULL */
 #endif
-
 THREADGBLDEF(want_empty_gvts,			boolean_t)			/* set to TRUE by MUPIP REORG when it is selecting
 										 * globals to be reorged. Need to be able to select
 										 * killed globals for effective truncate. */
@@ -317,6 +359,21 @@ THREADGBLDEF(jnl_extract_nocol,			uint4)				/* If non-zero, MUPIP JOURNAL EXTRAC
 										 * in the extract if globals do use alternative
 										 * collation.
 										 */
+THREADGBLDEF(skip_gtm_putmsg,			boolean_t)			/* currently needed by GDE to avoid gtm_putmsg
+										 * from happening inside map_sym.c/fgn_getinfo.c
+										 * when a VIEW "YCHKCOLL" is done as otherwise this
+										 * pollutes the current device GDE is writing to
+										 * and causes a GDECHECK error. This variable might
+										 * also be useful for others as the need arises.
+										 */
+THREADGBLDEF(spangbl_seen,			boolean_t)	/* The process has referenced at least one global which spans
+								 * multiple regions. Used by op_gvnaked currently.
+								 */
+THREADGBLDEF(no_spangbls,			boolean_t)	/* This process does not need to worry about spanning regions.
+								 * Examples are DSE which operates on a specific region
+								 * irrespective of whether the global spans regions or not.
+								 */
+THREADGBLDEF(max_fid_index,			int)		/* maximum value of csa->fid_index across all open csa's */
 #ifdef GTM_TRIGGER
 THREADGBLDEF(gvt_triggers_read_this_tn,		boolean_t)			/* if non-zero, indicates triggers were read for
 										 * at least one gv_target in this transaction.
@@ -345,4 +402,9 @@ THREADGBLDEF(rts_error_unusable,		boolean_t)			/* Denotes the window in which an
 THREADGBLDEF(rts_error_unusable_seen,		boolean_t)
 THREADGBLAR1DEF(trans_restart_hist_array,	trans_restart_hist_t, TRANS_RESTART_HIST_ARRAY_SZ) /* See tp.h for usage */
 THREADGBLDEF(trans_restart_hist_index,		uint4)
+THREADGBLDEF(skip_mv_num_approx_assert,		boolean_t)		/* TRUE if mval2subsc is invoked from op_fnview */
+THREADGBLDEF(gtm_gvundef_fatal,			boolean_t)			/* core and die intended for testing */
+THREADGBLDEF(gtm_dirtree_collhdr_always,	boolean_t)	/* Initialize 4-byte collation header in directory tree always.
+								 * Used by tests that are sensitive to DT leaf block layout.
+								 */
 #endif
diff --git a/sr_port/gtm_threadgbl_deftypes.c b/sr_port/gtm_threadgbl_deftypes.c
index 4c0ba8d..b4ccd1e 100644
--- a/sr_port/gtm_threadgbl_deftypes.c
+++ b/sr_port/gtm_threadgbl_deftypes.c
@@ -77,7 +77,6 @@
 # include "gtmsiginfo.h"
 #endif
 #include "gtmimagename.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"	/* needed for socket_pool and MAX_N_SOCKETS*/
 #include "ctrlc_handler_dummy.h"
diff --git a/sr_port/gtm_threadgbl_init.c b/sr_port/gtm_threadgbl_init.c
index 0479aec..2449928 100644
--- a/sr_port/gtm_threadgbl_init.c
+++ b/sr_port/gtm_threadgbl_init.c
@@ -87,7 +87,6 @@
 # include "gtmsiginfo.h"
 #endif
 #include "gtmimagename.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"	/* needed for socket_pool and MAX_N_SOCKETS*/
 #include "ctrlc_handler_dummy.h"
diff --git a/sr_port/iotcp_dummy.c b/sr_port/gtm_un.h
similarity index 66%
copy from sr_port/iotcp_dummy.c
copy to sr_port/gtm_un.h
index 6e8ab86..36eb615 100644
--- a/sr_port/iotcp_dummy.c
+++ b/sr_port/gtm_un.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,10 +9,11 @@
  *								*
  ****************************************************************/
 
-#include "mdef.h"
-#include "io.h"
+/* gtm_un.h - interlude to <sys/un.h> system header file.  */
+#ifndef GTM_UNH
+#define GTM_UNH
+#ifndef VMS
+#include <sys/un.h>
+#endif
 
-short iotcp_dummy(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout)
-{
-	return 0;
-}
+#endif
diff --git a/sr_port/gtmrecv_ch.c b/sr_port/gtmrecv_ch.c
index e20596c..12a44ee 100644
--- a/sr_port/gtmrecv_ch.c
+++ b/sr_port/gtmrecv_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,11 +26,14 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(gtmrecv_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (!(IS_GTM_ERROR(SIGNAL)) || DUMPABLE || SEVERITY == ERROR)
 	{
        		NEXTCH;
 	}
-	/* warning, info, or success */
-	CONTINUE;
+	VMS_ONLY(
+		/* warning, info, or success */
+		CONTINUE;
+	)
+	assertpro(FALSE);
 }
diff --git a/sr_port/gtmrecv_get_opt.c b/sr_port/gtmrecv_get_opt.c
index 5282495..8f8ec1f 100644
--- a/sr_port/gtmrecv_get_opt.c
+++ b/sr_port/gtmrecv_get_opt.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc.*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc.*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -33,18 +33,20 @@
 #include "gtm_stdio.h"
 #include "util.h"
 #include "repl_log.h"
-
 #ifdef UNIX
 #include "gtm_zlib.h"
 #endif
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 GBLREF	gtmrecv_options_t	gtmrecv_options;
 
 int gtmrecv_get_opt(void)
 {
 
-	boolean_t	log, log_interval_specified;
-	unsigned short 	log_file_len, filter_cmd_len, instfilename_len, instname_len;
+	boolean_t	log, log_interval_specified, plaintext_fallback;
+	unsigned short 	log_file_len, filter_cmd_len, instfilename_len, instname_len, tlsid_len;
 	boolean_t	buffsize_status;
 	boolean_t	filter;
 	int		status;
@@ -151,8 +153,6 @@ int gtmrecv_get_opt(void)
 		} else
 			gtmrecv_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
 #		endif
-		/* Round up or down buffsize */
-
 		if (filter = (CLI_PRESENT == cli_present("FILTER")))
 		{
 			filter_cmd_len = MAX_FILTER_CMD_LEN;
@@ -165,6 +165,24 @@ int gtmrecv_get_opt(void)
 			gtmrecv_options.filter_cmd[0] = '\0';
 
 		gtmrecv_options.stopsourcefilter = (CLI_PRESENT == cli_present("STOPSOURCEFILTER"));
+		/* Check if SSL/TLS secure communication is requested. */
+#		ifdef GTM_TLS
+		if (CLI_PRESENT == cli_present("TLSID"))
+		{
+			tlsid_len = MAX_TLSID_LEN;
+			if (!cli_get_str("TLSID", repl_tls.id, &tlsid_len))
+			{
+				util_out_print("Error parsing TLSID qualifier", TRUE);
+				return -1;
+			}
+			assert(0 < tlsid_len);
+			/* Check if plaintext-fallback mode is specified. Default option is NOPLAINTEXTFALLBACK. */
+			if (CLI_PRESENT == (plaintext_fallback = cli_present("PLAINTEXTFALLBACK")))
+				repl_tls.plaintext_fallback = (plaintext_fallback != CLI_NEGATED);
+			else
+				repl_tls.plaintext_fallback = FALSE;
+		}
+#		endif
 	}
 
 	if ((gtmrecv_options.start && 0 != gtmrecv_options.listen_port) || gtmrecv_options.statslog || gtmrecv_options.changelog)
diff --git a/sr_port/gtmsource_ch.c b/sr_port/gtmsource_ch.c
index 47eee5d..af37dbd 100644
--- a/sr_port/gtmsource_ch.c
+++ b/sr_port/gtmsource_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -43,7 +43,6 @@
 #include "ftok_sems.h"
 #endif
 
-GBLREF	gd_addr		*gd_header;
 GBLREF	jnlpool_addrs	jnlpool;
 
 error_def(ERR_ASSERT);
@@ -63,7 +62,7 @@ CONDITION_HANDLER(gtmsource_ch)
 	gd_region	*reg_local, *reg_top;
 	sgmnt_addrs	*csa;
 
-	START_CH;
+	START_CH(TRUE);
 	if (!(IS_GTM_ERROR(SIGNAL)) || DUMPABLE || SEVERITY == ERROR)
 	{
 		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
@@ -87,6 +86,9 @@ CONDITION_HANDLER(gtmsource_ch)
 		}
        		NEXTCH;
 	}
-	/* warning, info, or success */
-	CONTINUE;
+	VMS_ONLY (
+		/* warning, info, or success */
+		CONTINUE;
+	)
+	assertpro(FALSE);
 }
diff --git a/sr_port/gv_bind_name.c b/sr_port/gv_bind_name.c
index d1c14fb..1d78ee5 100644
--- a/sr_port/gv_bind_name.c
+++ b/sr_port/gv_bind_name.c
@@ -32,23 +32,22 @@
 #include "targ_alloc.h"
 #include "gvcst_protos.h"	/* for gvcst_root_search prototype */
 #include "min_max.h"
+#include "gtmimagename.h"
+#include "gvnh_spanreg.h"
+#include "gv_trigger_common.h"	/* for *HASHT* macros used inside GVNH_REG_INIT macro */
 
 GBLREF gv_namehead	*gv_target;
 GBLREF gv_key		*gv_currkey;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_binding	*gd_map, *gd_map_top;
 
 error_def(ERR_KEY2BIG);
 error_def(ERR_GVIS);
 
-void gv_bind_name(gd_addr *addr, mstr *targ)
+/* Map an unsubscripted global name to its corresponding region in the gld file */
+gvnh_reg_t *gv_bind_name(gd_addr *addr, mname_entry *gvname)
 {
 	gd_binding		*map;
 	ht_ent_mname		*tabent;
-	mname_entry		 gvent;
-	int			res;
-	boolean_t		added;
-	enum db_acc_method	acc_meth;
 	gd_region		*reg;
 	gvnh_reg_t		*gvnh_reg;
 	int			keylen;
@@ -56,85 +55,54 @@ void gv_bind_name(gd_addr *addr, mstr *targ)
 	gv_namehead		*tmp_gvt;
 	sgmnt_addrs		*csa;
 
-	gd_map = addr->maps;
-	gd_map_top = gd_map + addr->n_maps;
-	gvent.var_name.addr = targ->addr;
-	gvent.var_name.len = MIN(targ->len, MAX_MIDENT_LEN);
-	COMPUTE_HASH_MNAME(&gvent);
-	if ((NULL != (tabent = lookup_hashtab_mname((hash_table_mname *)addr->tab_ptr, &gvent)))
-		&& (NULL != (gvnh_reg = (gvnh_reg_t *)tabent->value)))
+	assert(MAX_MIDENT_LEN >= gvname->var_name.len);
+	if (NULL != (tabent = lookup_hashtab_mname((hash_table_mname *)addr->tab_ptr, gvname)))
 	{
+		gvnh_reg = (gvnh_reg_t *)tabent->value;
+		assert(NULL != gvnh_reg);
 		reg = gvnh_reg->gd_reg;
 		if (!reg->open)
 		{
 			gv_init_reg(reg);	/* could modify gvnh_reg->gvt if multiple regions map to same db file */
 			assert(0 == gvnh_reg->gvt->clue.end);
 		}
-		gv_target = gvnh_reg->gvt;
-		gv_cur_region = reg;
-		acc_meth = gv_cur_region->dyn.addr->acc_meth;
+		tmp_gvt = gvnh_reg->gvt;
 	} else
 	{
-		map = gd_map + 1;	/* get past local locks */
-		for (; (res = memcmp(gvent.var_name.addr, &(map->name[0]), gvent.var_name.len)) >= 0; map++)
-		{
-			assert(map < gd_map_top);
-			if (0 == res && 0 != map->name[gvent.var_name.len])
-				break;
-		}
-		if (!map->reg.addr->open)
-			gv_init_reg(map->reg.addr);
-		gv_cur_region = map->reg.addr;
-		acc_meth = gv_cur_region->dyn.addr->acc_meth;
-		if ((dba_cm == acc_meth) || (dba_usr == acc_meth))
-		{
-			tmp_gvt = malloc(SIZEOF(gv_namehead) + gvent.var_name.len);
-			memset(tmp_gvt, 0, SIZEOF(gv_namehead) + gvent.var_name.len);
-			tmp_gvt->gvname.var_name.addr = (char *)tmp_gvt + SIZEOF(gv_namehead);
-			tmp_gvt->nct = 0;
-			tmp_gvt->collseq = NULL;
-			tmp_gvt->regcnt = 1;
-			memcpy(tmp_gvt->gvname.var_name.addr, gvent.var_name.addr, gvent.var_name.len);
-			tmp_gvt->gvname.var_name.len = gvent.var_name.len;
-			tmp_gvt->gvname.hash_code = gvent.hash_code;
-		} else
-		{
-			assert(gv_cur_region->max_key_size <= MAX_KEY_SZ);
-			tmp_gvt = (gv_namehead *)targ_alloc(gv_cur_region->max_key_size, &gvent, gv_cur_region);
-		}
-		gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
-		gvnh_reg->gvt = tmp_gvt;
-		gvnh_reg->gd_reg = gv_cur_region;
-		if (NULL != tabent)
-		{	/* Since the global name was found but gv_target was null and now we created a new gv_target,
-			 * the hash table key must point to the newly created gv_target->gvname. */
-			tabent->key = tmp_gvt->gvname;
-			tabent->value = (char *)gvnh_reg;
-		} else
-		{
-			added = add_hashtab_mname((hash_table_mname *)addr->tab_ptr, &tmp_gvt->gvname, gvnh_reg, &tabent);
-			assert(added);
-		}
-		gv_target = tmp_gvt;	/* now that any error possibilities (out-of-memory issues in malloc/add_hashtab_mname)
-					 * are all done, it is safe to set gv_target. Setting it before could casue gv_target
-					 * and gv_currkey to get out of sync in case of an error condition.
-					 */
+		map = gv_srch_map(addr, gvname->var_name.addr, gvname->var_name.len);
+		reg = map->reg.addr;
+		if (!reg->open)
+			gv_init_reg(reg);
+		tmp_gvt = targ_alloc(reg->max_key_size, gvname, reg);
+		GVNH_REG_INIT(addr, addr->tab_ptr, map, tmp_gvt, reg, gvnh_reg, tabent);
 	}
-	if ((keylen = gvent.var_name.len + 2) > gv_cur_region->max_key_size)	/* caution: embedded assignment of "keylen" */
+	if (((keylen = gvname->var_name.len) + 2) > reg->max_key_size)	/* caution: embedded assignment of "keylen" */
 	{
-		assert(ARRAYSIZE(format_key) >= (1 + gvent.var_name.len));
+		assert(ARRAYSIZE(format_key) >= (1 + gvname->var_name.len));
 		format_key[0] = '^';
-		memcpy(&format_key[1], gvent.var_name.addr, gvent.var_name.len);
-		csa = &FILE_INFO(gv_cur_region)->s_addrs;
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(10) ERR_KEY2BIG, 4, keylen, (int4)gv_cur_region->max_key_size,
-			REG_LEN_STR(gv_cur_region), ERR_GVIS, 2, 1 + gvent.var_name.len, format_key);
+		memcpy(&format_key[1], gvname->var_name.addr, gvname->var_name.len);
+		csa = &FILE_INFO(reg)->s_addrs;
+		rts_error_csa(CSA_ARG(csa) VARLSTCNT(10) ERR_KEY2BIG, 4, keylen + 2, (int4)reg->max_key_size,
+			REG_LEN_STR(reg), ERR_GVIS, 2, 1 + gvname->var_name.len, format_key);
 	}
-	memcpy(gv_currkey->base, gvent.var_name.addr, gvent.var_name.len);
-	gv_currkey->base[gvent.var_name.len] = 0;
-	gvent.var_name.len++;
-	gv_currkey->base[gvent.var_name.len] = 0;
-	gv_currkey->end = gvent.var_name.len;
+	gv_target = tmp_gvt;	/* now that any rts_error possibilities are all past us, it is safe to set gv_target.
+				 * Setting it before could casue gv_target and gv_currkey to get out of sync in case of
+				 * an error condition and fail asserts in mdb_condition_handler (for example).
+				 */
+	memcpy(gv_currkey->base, gvname->var_name.addr, keylen);
+	gv_currkey->base[keylen] = KEY_DELIMITER;
+	keylen++;
+	gv_currkey->base[keylen] = KEY_DELIMITER;
+	gv_currkey->end = keylen;
 	gv_currkey->prev = 0;
-	change_reg();
-	return;
+	if (NULL == gvnh_reg->gvspan)
+	{	/* Global does not span multiple regions. In that case, open the only region that this global maps to right here.
+		 * In case of spanning globals, the subscripted reference will be used to find the mapping region (potentially
+		 * different from "reg" computed here. And that is the region to do a "change_reg" on. Will be done later
+		 * in "gv_bind_subsname".
+		 */
+		gv_cur_region = reg;
+		change_reg();
+	}
+	return gvnh_reg;
 }
diff --git a/sr_port/gv_bind_subsname.c b/sr_port/gv_bind_subsname.c
new file mode 100644
index 0000000..d80c357
--- /dev/null
+++ b/sr_port/gv_bind_subsname.c
@@ -0,0 +1,41 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"
+#include "targ_alloc.h"
+#include "change_reg.h"
+#include "gvcst_protos.h"	/* for gvcst_root_search prototype used in GV_BIND_SUBSREG macro */
+#include "gtmimagename.h"
+
+GBLREF gd_region	*gv_cur_region;
+GBLREF gv_key		*gv_currkey;
+
+/* Like gv_bind_name but this operates on a subscripted global reference. In addition, this does a gvcst_root_search too. */
+void gv_bind_subsname(gd_addr *addr, gv_key *key, gvnh_reg_t *gvnh_reg)
+{
+	gd_binding	*map;
+	gd_region	*reg;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	map = gv_srch_map(addr, (char *)&key->base[0], key->end - 1);
+	TREF(gd_targ_map) = map;
+	reg = map->reg.addr;
+	GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+}
diff --git a/sr_port/gv_rundown.c b/sr_port/gv_rundown.c
index f2cabb3..acaf5f5 100644
--- a/sr_port/gv_rundown.c
+++ b/sr_port/gv_rundown.c
@@ -140,14 +140,14 @@ void gv_rundown(void)
 						assert((si->tp_csa == cs_addrs) || (NULL == si->tp_csa));
 						if (si->jnl_tail)
 						{
-							CAREFUL_FREEUP_BUDDY_LIST(si->format_buff_list);
-							CAREFUL_FREEUP_BUDDY_LIST(si->jnl_list);
+							PROBE_FREEUP_BUDDY_LIST(si->format_buff_list);
+							PROBE_FREEUP_BUDDY_LIST(si->jnl_list);
 						}
-						CAREFUL_FREEUP_BUDDY_LIST(si->recompute_list);
-						CAREFUL_FREEUP_BUDDY_LIST(si->new_buff_list);
-						CAREFUL_FREEUP_BUDDY_LIST(si->tlvl_info_list);
-						CAREFUL_FREEUP_BUDDY_LIST(si->tlvl_cw_set_list);
-						CAREFUL_FREEUP_BUDDY_LIST(si->cw_set_list);
+						PROBE_FREEUP_BUDDY_LIST(si->recompute_list);
+						PROBE_FREEUP_BUDDY_LIST(si->new_buff_list);
+						PROBE_FREEUP_BUDDY_LIST(si->tlvl_info_list);
+						PROBE_FREEUP_BUDDY_LIST(si->tlvl_cw_set_list);
+						PROBE_FREEUP_BUDDY_LIST(si->cw_set_list);
 						if (NULL != si->blks_in_use)
 						{
 							free_hashtab_int4(si->blks_in_use);
@@ -174,26 +174,22 @@ void gv_rundown(void)
 						}
 						free(cs_addrs->jnl);
 					}
-					GTMCRYPT_ONLY(
-						if (cs_addrs->encrypted_blk_contents)
-							free(cs_addrs->encrypted_blk_contents);
-					)
 				}
 				assert(gv_cur_region->dyn.addr->file_cntl->file_info);
-				VMS_ONLY(
-					gds_info = (vms_gds_info *)gv_cur_region->dyn.addr->file_cntl->file_info;
-					if (gds_info->xabpro)
-						free(gds_info->xabpro);
-					if (gds_info->xabfhc)
-						free(gds_info->xabfhc);
-					if (gds_info->nam)
-					{
-						free(gds_info->nam->nam$l_esa);
-						free(gds_info->nam);
-					}
-					if (gds_info->fab)
-						free(gds_info->fab);
-				)
+#				ifdef VMS
+				gds_info = (vms_gds_info *)gv_cur_region->dyn.addr->file_cntl->file_info;
+				if (gds_info->xabpro)
+					free(gds_info->xabpro);
+				if (gds_info->xabfhc)
+					free(gds_info->xabfhc);
+				if (gds_info->nam)
+				{
+					free(gds_info->nam->nam$l_esa);
+					free(gds_info->nam);
+				}
+				if (gds_info->fab)
+					free(gds_info->fab);
+#				endif
 				free(gv_cur_region->dyn.addr->file_cntl->file_info);
 				free(gv_cur_region->dyn.addr->file_cntl);
 			}
diff --git a/sr_port/gv_select.c b/sr_port/gv_select.c
index 8bf81be..eaa6cdf 100644
--- a/sr_port/gv_select.c
+++ b/sr_port/gv_select.c
@@ -42,6 +42,9 @@
 #include "buddy_list.h"		/* needed for tp.h */
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
+#include "hashtab_mname.h"
+#include "gvnh_spanreg.h"
+#include "change_reg.h"
 
 #define	MAX_GMAP_ENTRIES_PER_ITER	2 /* maximum increase (could even be negative) in gmap array size per call to global_map */
 
@@ -58,27 +61,34 @@ GBLREF gd_region	*gv_cur_region;
 GBLREF sgmnt_data_ptr_t	cs_data;
 GBLREF sgmnt_addrs      *cs_addrs;
 GBLREF tp_region	*grlist;
+GBLREF gd_addr		*gd_header;
 
 static readonly unsigned char	percent_lit = '%';
 static readonly unsigned char	tilde_lit = '~';
 
+STATICFNDCL void gv_select_reg(void *ext_hash, boolean_t freeze, int *reg_max_rec, int *reg_max_key,
+				int *reg_max_blk, boolean_t restrict_reg, gvnh_reg_t *gvnh_reg, glist **gl_tail);
+
 void gv_select(char *cli_buff, int n_len, boolean_t freeze, char opname[], glist *gl_head,
 	       int *reg_max_rec, int *reg_max_key, int *reg_max_blk, boolean_t restrict_reg)
 {
-	boolean_t			stashed = FALSE, append_gbl;
-	int				num_quote, len, gmap_size, new_gmap_size, estimated_entries, count, rslt;
-	char				*ptr, *ptr1, *c;
-	mstr				gmap[512], *gmap_ptr, *gmap_ptr_base, gmap_beg, gmap_end;
-	mval				val, curr_gbl_name;
-	glist				*gl_tail, *gl_ptr;
-	tp_region			*rptr;
-#ifdef GTM64
-	hash_table_int8	        	ext_hash;
-	ht_ent_int8                   	*tabent;
-#else
-	hash_table_int4	        	ext_hash;
-	ht_ent_int4                   	*tabent;
-#endif /* GTM64 */
+	int			num_quote, len, gmap_size, new_gmap_size, estimated_entries, count, rslt, hash_code;
+	int			i, mini, maxi;
+	char			*ptr, *ptr1, *c;
+	mname_entry		gvname;
+	mstr			gmap[512], *gmap_ptr, *gmap_ptr_base, gmap_beg, gmap_end;
+	mval			curr_gbl_name;
+	gd_region		*reg;
+	gv_namehead		*gvt;
+	gvnh_reg_t		*gvnh_reg;
+	gvnh_spanreg_t		*gvspan;
+	ht_ent_mname		*tabent_mname;
+	glist			*gl_tail;
+#	ifdef GTM64
+	hash_table_int8		ext_hash;
+#	else
+	hash_table_int4		ext_hash;
+#	endif
 
 	memset(gmap, 0, SIZEOF(gmap));
 	gmap_size = SIZEOF(gmap) / SIZEOF(gmap[0]);
@@ -212,106 +222,52 @@ void gv_select(char *cli_buff, int n_len, boolean_t freeze, char opname[], glist
 	{
 		curr_gbl_name.mvtype = MV_STR;
 		curr_gbl_name.str = *gmap_ptr++;
-		op_gvname(VARLSTCNT(1) &curr_gbl_name);
-		append_gbl = TRUE;
-		if (dba_cm == gv_cur_region->dyn.addr->acc_meth)
-		{	util_out_print("Can not select globals from region !AD across network",TRUE,gv_cur_region->rname_len,
-					gv_cur_region->rname);
-			mupip_exit(ERR_MUNOFINISH);
-
-		}
-		if (dba_bg != gv_cur_region->dyn.addr->acc_meth && dba_mm != gv_cur_region->dyn.addr->acc_meth)
-		{
-			assert(gv_cur_region->dyn.addr->acc_meth == dba_usr);
-			util_out_print("Can not select globals from non-GDS format region !AD",TRUE,gv_cur_region->rname_len,
-					gv_cur_region->rname);
-			mupip_exit(ERR_MUNOFINISH);
-		}
-		op_gvdata(&val);
-		if (0 == val.m[1])
+		DEBUG_ONLY(MSTRP_CMP(&curr_gbl_name.str, gmap_ptr, rslt);)
+		assert(0 >= rslt);
+		do
 		{
-			op_gvname(VARLSTCNT(1) &curr_gbl_name);
-			op_gvorder(&curr_gbl_name);
-			if (!curr_gbl_name.str.len)
-				break;
-			assert('^' == *curr_gbl_name.str.addr);
-			curr_gbl_name.str.addr++;
-			curr_gbl_name.str.len--;
-		}
-		for (;;)
-		{
-			MSTRP_CMP(&curr_gbl_name.str, gmap_ptr, rslt);
-			if (0 < rslt)
-				break;
-			if (freeze)
-                        {
-				/* Note: We cannot use int4 hash when we will have 64-bit address.
-				 * In that case we may choose to hash the region name or use int8 hash */
-
-			        GTM64_ONLY(if(add_hashtab_int8(&ext_hash,(gtm_uint64_t *)&gv_cur_region, HT_VALUE_DUMMY, &tabent)))
-			        NON_GTM64_ONLY(if (add_hashtab_int4(&ext_hash, (uint4 *)&gv_cur_region, HT_VALUE_DUMMY, &tabent)))
-                                {
-                                        if (cs_addrs->hdr->freeze)
-                                        {
-                                                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FREEZE, 2, gv_cur_region->rname_len,
-							gv_cur_region->rname);
-                                                mupip_exit(ERR_MUNOFINISH);
-                                        }
-					/* Cannot proceed for read-only data files */
-					if (gv_cur_region->read_only)
-					{
-						util_out_print("Cannot freeze the database",TRUE);
-						gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBRDONLY, 2,
-							DB_LEN_STR(gv_cur_region));
-						mupip_exit(ERR_MUNOFINISH);
-					}
-					while (REG_ALREADY_FROZEN == region_freeze(gv_cur_region, TRUE, FALSE, FALSE))
-					{
-						hiber_start(1000);
-						if (mu_ctrly_occurred || mu_ctrlc_occurred)
-						{
-							gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_FREEZECTRL);
-                                                	mupip_exit(ERR_MUNOFINISH);
-						}
-					}
-					wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH);
-                                }
-                        }
-			assert(0 < curr_gbl_name.str.len);
-			gl_ptr = (glist*)malloc(SIZEOF(glist) - 1 + curr_gbl_name.str.len);
-			gl_ptr->name.mvtype = MV_STR;
-			gl_ptr->name.str.addr = (char*)gl_ptr->nbuf;
-			gl_ptr->name.str.len = MIN(curr_gbl_name.str.len, MAX_MIDENT_LEN);
-			memcpy(gl_ptr->nbuf, curr_gbl_name.str.addr, curr_gbl_name.str.len);
-			gl_ptr->next = 0;
-			if (append_gbl)
-			{
-				if (*reg_max_rec < cs_data->max_rec_size)
-					*reg_max_rec = cs_data->max_rec_size;
-				if (*reg_max_key < cs_data->max_key_size)
-					*reg_max_key = cs_data->max_key_size;
-				if (*reg_max_blk < cs_data->blk_size)
-					*reg_max_blk = cs_data->blk_size;
-			}
-			op_gvname(VARLSTCNT(1) &gl_ptr->name);
-			if (restrict_reg)
-			{ /* Only select globals in specified regions */
-				append_gbl = FALSE;
-				for (rptr = grlist; NULL != rptr; rptr = rptr->fPtr)
+			/* User input global names could be arbitrarily large.
+			 * Truncate to max supported length before computing hash.
+			 */
+			if (MAX_MIDENT_LEN < curr_gbl_name.str.len)
+				curr_gbl_name.str.len = MAX_MIDENT_LEN;
+			COMPUTE_HASH_MSTR(curr_gbl_name.str, hash_code);
+			op_gvname_fast(VARLSTCNT(2) hash_code, &curr_gbl_name);
+			assert((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)));
+				/* for dba_cm or dba_usr, op_gvname_fast/gv_bind_name/gv_init_reg would have errored out */
+			gvname.hash_code = hash_code;
+			gvname.var_name = curr_gbl_name.str;
+			tabent_mname = lookup_hashtab_mname((hash_table_mname *)gd_header->tab_ptr, &gvname);
+			assert(NULL != tabent_mname);
+			gvnh_reg = (gvnh_reg_t *)tabent_mname->value;
+			assert(gv_cur_region == gvnh_reg->gd_reg);
+			gvspan = gvnh_reg->gvspan;
+			if (NULL == gvspan)
+				gv_select_reg((void *)&ext_hash, freeze, reg_max_rec, reg_max_key, reg_max_blk,
+										restrict_reg, gvnh_reg, &gl_tail);
+			else
+			{	/* If global spans multiple regions, make sure gv_targets corresponding to ALL spanned regions
+				 * are allocated and gv_target->root is also initialized accordingly for all the spanned regions.
+				 */
+				gvnh_spanreg_subs_gvt_init(gvnh_reg, gd_header, NULL);
+				maxi = gvspan->max_reg_index;
+				mini = gvspan->min_reg_index;
+				for (i = mini; i <= maxi; i++)
 				{
-					if (gv_cur_region == rptr->reg)
+					assert(i >= 0);
+					assert(i < gd_header->n_regions);
+					reg = gd_header->regions + i;
+					gvt = GET_REAL_GVT(gvspan->gvt_array[i - mini]);
+					if (NULL != gvt)
 					{
-						append_gbl = TRUE;
-						break;
+						gv_target = gvt;
+						gv_cur_region = reg;
+						change_reg();
+						gv_select_reg((void *)&ext_hash, freeze, reg_max_rec, reg_max_key,
+										reg_max_blk, restrict_reg, gvnh_reg, &gl_tail);
 					}
 				}
 			}
-			if (append_gbl)
-			{
-				gl_tail->next = gl_ptr;
-				gl_tail = gl_ptr;
-			} else
-				free(gl_ptr);
 			op_gvorder(&curr_gbl_name);
 			if (0 == curr_gbl_name.str.len)
 			{
@@ -321,8 +277,91 @@ void gv_select(char *cli_buff, int n_len, boolean_t freeze, char opname[], glist
 			assert('^' == *curr_gbl_name.str.addr);
 			curr_gbl_name.str.addr++;
 			curr_gbl_name.str.len--;
-		}
+			MSTRP_CMP(&curr_gbl_name.str, gmap_ptr, rslt);
+		} while (0 >= rslt);
 	}
 	if (gmap_ptr_base != &gmap[0])
 		free(gmap_ptr_base);
 }
+
+/* Assumes "gv_target" and "gv_cur_region" are properly setup at function entry */
+STATICFNDEF void gv_select_reg(void *ext_hash, boolean_t freeze, int *reg_max_rec, int *reg_max_key,
+				int *reg_max_blk, boolean_t restrict_reg, gvnh_reg_t *gvnh_reg, glist **gl_tail)
+{
+	tp_region	*rptr;
+	mval		val;
+	glist		*gl_ptr;
+#	ifdef GTM64
+	ht_ent_int8	*tabent;
+#	else
+	ht_ent_int4	*tabent;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	assert(gv_target->gd_csa == cs_addrs);
+	if (restrict_reg)
+	{	/* Only select globals in specified regions */
+		for (rptr = grlist; NULL != rptr; rptr = rptr->fPtr)
+		{
+			if (gv_cur_region == rptr->reg)
+				break;
+		}
+		if (NULL == rptr)
+			return;	/* this region is not part of specified regions. return right away */
+	}
+	TREF(gd_targ_gvnh_reg) = NULL;	/* needed so op_gvdata goes through gvcst_data (i.e. focuses only on the current region)
+					 * and NOT through gvcst_spr_data (which would focus on all spanned regions if any).
+					 */
+	op_gvdata(&val);
+	/* It is okay not to restore TREF(gd_targ_gvnh_reg) since it will be initialized again once gv_select is done
+	 * and the next op_gvname/op_gvextnam/op_gvnaked call is made. It is not needed until then anyways.
+	 */
+	if ((0 == val.m[1]) && ((0 == gv_target->root) || !TREF(want_empty_gvts)))
+		return;	/* global has an empty GVT in this region. return right away */
+	if (freeze)
+        {	/* Note: gv_cur_region pointer is 64-bits on 64-bit platforms. So use hashtable accordingly. */
+	        GTM64_ONLY(if(add_hashtab_int8((hash_table_int8 *)ext_hash,(gtm_uint64_t *)&gv_cur_region,
+											HT_VALUE_DUMMY, &tabent)))
+	        NON_GTM64_ONLY(if (add_hashtab_int4((hash_table_int4 *)ext_hash, (uint4 *)&gv_cur_region,
+											HT_VALUE_DUMMY, &tabent)))
+                {
+                        if (cs_addrs->hdr->freeze)
+                        {
+                                gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_FREEZE, 2, REG_LEN_STR(gv_cur_region));
+                                mupip_exit(ERR_MUNOFINISH);
+                        }
+			/* Cannot proceed for read-only data files */
+			if (gv_cur_region->read_only)
+			{
+				util_out_print("Cannot freeze the database",TRUE);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2,
+					DB_LEN_STR(gv_cur_region));
+				mupip_exit(ERR_MUNOFINISH);
+			}
+			while (REG_ALREADY_FROZEN == region_freeze(gv_cur_region, TRUE, FALSE, FALSE))
+			{
+				hiber_start(1000);
+				if (mu_ctrly_occurred || mu_ctrlc_occurred)
+				{
+					gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_FREEZECTRL);
+                                	mupip_exit(ERR_MUNOFINISH);
+				}
+			}
+			wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH);
+                }
+        }
+	if (*reg_max_rec < cs_data->max_rec_size)
+		*reg_max_rec = cs_data->max_rec_size;
+	if (*reg_max_key < cs_data->max_key_size)
+		*reg_max_key = cs_data->max_key_size;
+	if (*reg_max_blk < cs_data->blk_size)
+		*reg_max_blk = cs_data->blk_size;
+	gl_ptr = (glist *)malloc(SIZEOF(glist));
+	gl_ptr->next = NULL;
+	gl_ptr->reg = gv_cur_region;
+	gl_ptr->gvt = gv_target;
+	gl_ptr->gvnh_reg = gvnh_reg;
+	(*gl_tail)->next = gl_ptr;
+	*gl_tail = gl_ptr;
+}
diff --git a/sr_port/gv_srch_gblname.c b/sr_port/gv_srch_gblname.c
new file mode 100644
index 0000000..4114c7d
--- /dev/null
+++ b/sr_port/gv_srch_gblname.c
@@ -0,0 +1,52 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+
+/* Searches a global directory "gblnames" array for which entry an input "global-name" falls in */
+gd_gblname *gv_srch_gblname(gd_addr *addr, char *name, int name_len)
+{
+	int		res;
+	int		low, high, mid;
+	gd_gblname	*gname_start, *gname;
+
+	assert(addr->n_gblnames);	/* caller should have taken care of this */
+	/* At all times in the loop, "low" corresponds to the smallest possible value for "gname"
+	 * and "high" corresponds to one more than the highest possible value for "gname".
+	 */
+	low = 0;
+	high = addr->n_gblnames;
+	gname_start = &addr->gblnames[low];
+	do
+	{
+		if (low == high)
+			break;
+		assert(low < high);
+		mid = (low + high) / 2;
+		assert(low <= mid);
+		assert(mid < high);
+		gname = &gname_start[mid];
+		res = memcmp(name, gname->gblname, name_len);
+		if (0 > res)
+			high = mid;
+		else if (0 < res)
+			low = mid + 1;
+		else if ('\0' == gname->gblname[name_len])
+			return gname;
+		else
+			high = mid;
+	} while (TRUE);
+	return NULL;
+}
diff --git a/sr_port/gv_srch_map.c b/sr_port/gv_srch_map.c
new file mode 100644
index 0000000..aa65778
--- /dev/null
+++ b/sr_port/gv_srch_map.c
@@ -0,0 +1,139 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+
+/* Searches a global directory map array for which map entry an input "key" falls in.
+ * "key" could be an unsubscripted or subscripted global reference.
+ */
+gd_binding *gv_srch_map(gd_addr *addr, char *key, int key_len)
+{
+	int		res;
+	int		low, high, mid;
+	gd_binding	*map_start, *map;
+	DEBUG_ONLY(
+		int	dbg_match;
+	)
+
+	map_start = addr->maps;
+	assert(('%' == map_start[1].gvkey.addr[0]) && (1 == map_start[1].gvname_len));
+	/* We expect all callers to search for global names that start with "^%" or higher. */
+	assert(0 <= memcmp(key, &(map_start[1].gvkey.addr[0]), key_len));
+	low = 2;	/* get past local locks AND first map entry which is always "%" */
+	high = addr->n_maps - 1;
+	DEBUG_ONLY(dbg_match = -1;)
+	/* At all times in the loop, "low" corresponds to the smallest possible value for "map"
+	 * and "high" corresponds to the highest possible value for "map".
+	 */
+	do
+	{
+		if (low == high)
+		{
+			assert((-1 == dbg_match) || (low == dbg_match));
+			return &map_start[low];
+		}
+		assert(low < high);
+		mid = (low + high) / 2;
+		assert(low <= mid);
+		assert(mid < high);
+		map = &map_start[mid];
+		res = memcmp(key, &(map->gvkey.addr[0]), key_len);
+		if (0 > res)
+			high = mid;
+		else if (0 < res)
+			low = mid + 1;
+		else if (key_len < (map->gvkey_len - 1))
+			high = mid;
+		else
+		{
+			assert(key_len == (map->gvkey_len - 1));
+			low = mid + 1;
+			DEBUG_ONLY(dbg_match = low;)
+			PRO_ONLY(return &map_start[low];)
+		}
+	} while (TRUE);
+}
+
+/* Similar to gv_srch_map except that it does a linear search starting at a specific map and going FORWARD.
+ * We expect this function to be invoked in case the caller expects the target map to be found very close to the current map.
+ * This might be faster in some cases than a binary search of the entire gld map array (done by gv_srch_map).
+ */
+gd_binding *gv_srch_map_linear(gd_binding *start_map, char *key, int key_len)
+{
+	gd_binding	*map;
+	int		res;
+#	ifdef DEBUG
+	gd_addr		*addr;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+#	endif
+	map = start_map;
+	DEBUG_ONLY(
+		addr = TREF(gd_targ_addr);
+		assert(map > addr->maps);
+	)
+	for ( ; ; map++)
+	{
+		assert(map < &addr->maps[addr->n_maps]);
+		res = memcmp(key, &map->gvkey.addr[0], key_len);
+		if (0 < res)
+			continue;
+		if (0 > res)
+			break;
+		/* res == 0 at this point */
+		if (key_len < (map->gvkey_len - 1))
+			break;
+		assert(key_len == (map->gvkey_len - 1));
+		map++;
+		break;
+	}
+	return map;
+}
+
+/* Similar to gv_srch_map_linear except that it does the linear search going BACKWARD. */
+gd_binding *gv_srch_map_linear_backward(gd_binding *start_map, char *key, int key_len)
+{
+	gd_binding	*map;
+	int		res;
+#	ifdef DEBUG
+	gd_addr		*addr;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+#	endif
+	map = start_map;
+	DEBUG_ONLY(
+		addr = TREF(gd_targ_addr);
+		assert(map < &addr->maps[addr->n_maps]);
+	)
+	for ( ; ; map--)
+	{
+		assert(map >= addr->maps);
+		res = memcmp(key, &map->gvkey.addr[0], key_len);
+		if (0 < res)
+			break;
+		if (0 > res)
+			continue;
+		/* res == 0 at this point */
+		if (key_len < (map->gvkey_len - 1))
+			continue;
+		assert(key_len == (map->gvkey_len - 1));
+		break;
+	}
+	map++;
+	assert(map > addr->maps);
+	return map;
+}
diff --git a/sr_port/gv_xform_key.c b/sr_port/gv_xform_key.c
index fcc91da..e693ae5 100644
--- a/sr_port/gv_xform_key.c
+++ b/sr_port/gv_xform_key.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,13 +24,14 @@
 
 GBLREF int4		gv_keysize;
 GBLREF gv_namehead	*gv_target;
+GBLREF gd_region	*gv_cur_region;
 
 /* transform gv_currkey or gv_altkey based on collation sequence
  * if XBACK is true then convert from internal to external format.
  * if XBACK is false, convert from external to internal format
  */
 
-void	gv_xform_key(gv_key *keyp,  boolean_t xback)
+void gv_xform_key(gv_key *keyp,  boolean_t xback)
 {
 	unsigned char		*c0, *c1, *ctop;
 	DCL_THREADGBL_ACCESS;
@@ -68,7 +69,7 @@ void	gv_xform_key(gv_key *keyp,  boolean_t xback)
 	{
 		if (STR_SUB_PREFIX != *c0)
 		{
-			assert(!gv_target->nct);
+			assert(!(gv_target->nct));
 			while (*c1++ = *c0++)
 				;
 			keyp->prev = keyp->end;
@@ -80,7 +81,7 @@ void	gv_xform_key(gv_key *keyp,  boolean_t xback)
 				= gvsub2str(c0, (unsigned char *)((TREF(gv_sparekey_mval)).str.addr), FALSE)
 				- (unsigned char *)(TREF(gv_sparekey_mval)).str.addr;
 			TREF(transform) = !xback;
-			mval2subsc(TADR(gv_sparekey_mval), keyp);
+			mval2subsc(TADR(gv_sparekey_mval), keyp, gv_cur_region->std_null_coll);
 			c1 = &keyp->base[keyp->end];
 			while (*c0++)
 				;
diff --git a/sr_port/gvcst_blk_build.c b/sr_port/gvcst_blk_build.c
index 05ec9f1..4c10304 100644
--- a/sr_port/gvcst_blk_build.c
+++ b/sr_port/gvcst_blk_build.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,6 +30,7 @@
 #include "tp.h"
 #include "gvcst_blk_build.h"
 #include "gtmimagename.h"
+#include "spec_type.h"
 
 #ifdef DEBUG
 GBLREF	boolean_t		skip_block_chain_tail_check;
@@ -50,7 +51,7 @@ void gvcst_blk_build(cw_set_element *cse, sm_uc_ptr_t base_addr, trans_num ctn)
 {
 	blk_segment	*seg, *stop_ptr, *array;
 	off_chain	chain;
-	sm_uc_ptr_t	ptr, ptrtop;
+	sm_uc_ptr_t	ptr, ptrtop, c;
 	sm_ulong_t	n;
 	int4		offset;
 	trans_num	blktn;
@@ -208,16 +209,39 @@ void gvcst_blk_build(cw_set_element *cse, sm_uc_ptr_t base_addr, trans_num ctn)
 						integ_error_found = TRUE;
 						break;
 					}
+					c = ptr;
+					c += SIZEOF(rec_hdr);
+					/* The *-key does not have a key. Everything else has one. Account for that. */
+					if (BSTAR_REC_SIZE != nRecLen)
+					{
+						for ( ; (c < ptrtop) && ((*c++ != KEY_DELIMITER) || (*c != KEY_DELIMITER)); )
+							;
+						if (c >= ptrtop)
+						{
+							assert(NULL == input_base_addr);
+							integ_error_found = TRUE;
+							break;
+						}
+						c++;
+					}
 					ptr += nRecLen;
-					if (ptr - SIZEOF(off_chain) == chainptr)
+					if (c == chainptr)
+					{
+						if (((ptr - SIZEOF(off_chain)) != chainptr)
+							&& ((ptr - SIZEOF(off_chain) - COLL_SPEC_LEN) != chainptr))
+						{
+							assert(NULL == input_base_addr);
+							integ_error_found = TRUE;
+						}
 						break;
-					if ((ptr - SIZEOF(off_chain)) > chainptr)
+					}
+					if (c > chainptr)
 					{
 						assert(NULL == input_base_addr);
 						integ_error_found = TRUE;
 						break;
 					}
-					GET_LONGP(&chain, ptr - SIZEOF(off_chain));
+					GET_LONGP(&chain, c);
 					if (chain.flag)
 					{
 						assert(NULL == input_base_addr);
diff --git a/sr_port/gvcst_data.c b/sr_port/gvcst_data.c
index 30b450b..5baa359 100644
--- a/sr_port/gvcst_data.c
+++ b/sr_port/gvcst_data.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -56,9 +56,7 @@ GBLREF gd_region	*gv_cur_region;
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVDATAFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_data_ch)
 
@@ -85,19 +83,17 @@ mint	gvcst_data(void)
 		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
 		ESTABLISH_NORET(gvcst_data_ch, est_first_pass);
 		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+		/* fix up since it should only be externally counted as one $data */
+		INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_data, (gtm_uint64_t) -1);
+		val = gvcst_data2();
 	} else
 		sn_tpwrapped = FALSE;
-	/* fix up since it should only be externally counted as one $data */
-	INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_data, (gtm_uint64_t) -1);
-	val = gvcst_data2();
 	if (-1 == val)
 	{	/* -1 implies node exists. Need to see if a proper descendant exists */
 		val = 1;
 		/* 0 1 0 0 <-- append that to gv_currkey */
-		gv_currkey->end = oldend + 2;
-		gv_currkey->base[oldend + 0] = 1;
-		gv_currkey->base[oldend + 1] = 0;
-		gv_currkey->base[oldend + 2] = 0;
+		assert(oldend == gv_currkey->end);
+		GVKEY_INCREMENT_QUERY(gv_currkey);
 		found = gvcst_query(); /* want to save gv_altkey? */
 		if (found && (0 == memcmp(gv_currkey->base, gv_altkey->base, oldend)))
 			val += 10;
diff --git a/sr_port/gvcst_dataget.c b/sr_port/gvcst_dataget.c
index 4e22481..b38f582 100644
--- a/sr_port/gvcst_dataget.c
+++ b/sr_port/gvcst_dataget.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -58,10 +58,10 @@ error_def(ERR_GVPUTFAIL);
 
 enum cdb_sc gvcst_dataget(mint *dollar_data, mval *val)
 {
-	boolean_t	gotit, gotspan, gotpiece, gotdummy, sn_tpwrapped, check_rtsib;
+	boolean_t	gotit, gotspan, gotpiece, check_rtsib;
 	mint		dollar_data_ctrl, dollar_data_piece, dollar_data_null, dg_info;
 	mval		val_ctrl, val_piece;
-	int		gblsize, chunk_size, i, total_len, oldend, tmp_numsubs;
+	int		gblsize, i, total_len, oldend, tmp_numsubs;
 	unsigned short	numsubs;
 	sm_uc_ptr_t	sn_ptr;
 	enum cdb_sc	status;
@@ -147,10 +147,7 @@ enum cdb_sc gvcst_dataget(mint *dollar_data, mval *val)
 				if ((11 != dollar_data_piece) && cs_data->std_null_coll)
 				{	/* Check for a null-subscripted descendant. Append null sub to gv_currkey and check $data */
 					RESTORE_CURRKEY(gv_currkey, oldend);
-					gv_currkey->end = oldend + 2;
-					gv_currkey->base[oldend + 0] = 1;
-					gv_currkey->base[oldend + 1] = 0;
-					gv_currkey->base[oldend + 2] = 0;
+					GVKEY_INCREMENT_QUERY(gv_currkey);
 					dollar_data_null = DG_DATAONLY;
 					gvcst_dataget2(&dollar_data_null, &val_piece, NULL);
 					if (dollar_data_null)
diff --git a/sr_port/gvcst_gblmod.c b/sr_port/gvcst_gblmod.c
index d58566f..72d4122 100644
--- a/sr_port/gvcst_gblmod.c
+++ b/sr_port/gvcst_gblmod.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,18 +42,18 @@ LITREF mstr			nsb_dummy;
 
 error_def(ERR_GBLMODFAIL);
 
-bool	gvcst_gblmod(mval *v)
+boolean_t	gvcst_gblmod(mval *v)
 {
-	boolean_t		gblmod, is_dummy;
-	enum cdb_sc		status;
-	int				key_size,  key_size2, data_len;
-	srch_hist		*alt_history;
+	boolean_t	gblmod, is_dummy;
+	enum cdb_sc	status;
+	int		key_size,  key_size2, data_len;
+	srch_hist	*alt_history;
 	blk_hdr_ptr_t	bp;
 	rec_hdr_ptr_t	rp;
 	unsigned short	match, match2, rsiz, offset_to_value, oldend;
 	srch_blk_status	*bh;
-	sm_uc_ptr_t		b_top;
-	trans_num		tn_to_compare;
+	sm_uc_ptr_t	b_top;
+	trans_num	tn_to_compare;
 
 	T_BEGIN_READ_NONTP_OR_TP(ERR_GBLMODFAIL);
 	assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit);	/* we better hold crit in the final retry (TP & non-TP) */
diff --git a/sr_port/gvcst_get.c b/sr_port/gvcst_get.c
index f1c08f4..903f322 100644
--- a/sr_port/gvcst_get.c
+++ b/sr_port/gvcst_get.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -61,9 +61,7 @@ GBLREF	gd_region	*gv_cur_region;
 GBLREF	uint4		dollar_tlevel;
 GBLREF	unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVGETFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_get_ch)
 
@@ -72,7 +70,7 @@ boolean_t gvcst_get(mval *v)
 	boolean_t	gotit, gotspan, gotpiece, gotdummy, sn_tpwrapped;
 	boolean_t	est_first_pass;
 	mval		val_ctrl, val_piece;
-	int		gblsize, chunk_size, i, total_len, oldend, tmp_numsubs;
+	int		gblsize, i, total_len, oldend, tmp_numsubs;
 	unsigned short	numsubs;
 	sm_uc_ptr_t	sn_ptr;
 	int		debug_len;
@@ -91,12 +89,15 @@ boolean_t gvcst_get(mval *v)
 			op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
 			ESTABLISH_NORET(gvcst_get_ch, est_first_pass);
 			GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+			/* fix up since it should only be externally counted as one get */
+			INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_get, (gtm_uint64_t) -1);
+			gotdummy = gvcst_get2(v, NULL);        /* Will be returned if not currently a spanning node */
 		} else
+		{
 			sn_tpwrapped = FALSE;
+			gotdummy = gotit;
+		}
 		oldend = gv_currkey->end;
-		/* fix up since it should only be externally counted as one get */
-		INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_get, (gtm_uint64_t) -1);
-		gotdummy = gvcst_get2(v, NULL);        /* Will be returned if not currently a spanning node */
 		APPEND_HIDDEN_SUB(gv_currkey);
 		/* fix up since it should only be externally counted as one get */
 		INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_get, (gtm_uint64_t) -1);
@@ -181,14 +182,14 @@ boolean_t gvcst_get2(mval *v, unsigned char *sn_ptr)
 	assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit);	/* we better hold crit in the final retry (TP & non-TP) */
 	for (;;)
 	{
-#if defined(DEBUG) && defined(UNIX)
+#		if defined(DEBUG) && defined(UNIX)
 		if (gtm_white_box_test_case_enabled && (WBTEST_ANTIFREEZE_GVGETFAIL == gtm_white_box_test_case_number))
 		{
 			status = cdb_sc_blknumerr;
 			t_retry(status);
 			continue;
 		}
-#endif
+#		endif
 		if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL)))
 		{
 			bh = gv_target->hist.h;
diff --git a/sr_port/gvcst_init.c b/sr_port/gvcst_init.c
index 98000df..f97c6b0 100644
--- a/sr_port/gvcst_init.c
+++ b/sr_port/gvcst_init.c
@@ -25,7 +25,7 @@
 #include "gdsblk.h"
 #include "gdskill.h"
 #include "gdscc.h"
-#include "min_max.h"		/* needed for gdsblkops.h */
+#include "min_max.h"		/* needed for gdsblkops.h and MAX macro used below */
 #include "gdsblkops.h"
 #include "filestruct.h"
 #include "iosp.h"
@@ -52,8 +52,9 @@
 #include "compswap.h"
 #include "send_msg.h"
 #include "targ_alloc.h"		/* for "targ_free" prototype */
-#include "hashtab_mname.h"
+#include "hashtab_mname.h"	/* for CWS_INIT macro */
 #include "process_gvt_pending_list.h"
+#include "gvt_hashtab.h"
 #include "gtmmsg.h"
 #ifdef UNIX
 #include "heartbeat_timer.h"
@@ -92,7 +93,6 @@ GBLREF	sm_uc_ptr_t		reformat_buffer;
 GBLREF	int			reformat_buffer_len;
 GBLREF	volatile int		reformat_buffer_in_use;	/* used only in DEBUG mode */
 GBLREF	volatile int4		fast_lock_count;
-GBLREF	gvt_container		*gvt_pending_list;
 GBLREF	boolean_t		dse_running;
 GBLREF	jnl_gbls_t		jgbl;
 #ifdef UNIX
@@ -219,21 +219,17 @@ void gvcst_init(gd_region *greg)
 	bt_rec_ptr_t		bt;
 	blk_ident		tmp_blk;
 #	endif
+	int			max_fid_index;
 	mstr			log_nam, trans_log_nam;
 	char			trans_buff[MAX_FN_LEN + 1];
 	unique_file_id		*greg_fid, *reg_fid;
-	gd_addr			*addr_ptr;
 	tp_region		*tr;
 	ua_list			*tmp_ua;
 	time_t			curr_time;
 	uint4			curr_time_uint4, next_warn_uint4;
 	unsigned int            minus1 = (unsigned)-1;
 	enum db_acc_method	greg_acc_meth;
-	ht_ent_mname		*tabent, *topent, *stayent;
-	gv_namehead		*gvt, *gvt_stay;
-	gvnh_reg_t		*gvnh_reg;
-	hash_table_mname	*table;
-	boolean_t		added, first_wasopen, onln_rlbk_cycle_mismatch = FALSE;
+	boolean_t		onln_rlbk_cycle_mismatch = FALSE;
 	intrpt_state_t		save_intrpt_ok_state;
 #	ifdef UNIX
 	replpool_identifier	replpool_id;
@@ -271,64 +267,15 @@ void gvcst_init(gd_region *greg)
 	{
 		if (NULL == prev_reg || (gd_region *)-1L == prev_reg) /* (gd_region *)-1 == prev_reg => cm region open attempted */
 			return;
-		/* Found same database already open - prev_reg contains addr of originally openned region */
+		/* Found same database already open - prev_reg contains addr of originally opened region */
 		greg->dyn.addr->file_cntl = prev_reg->dyn.addr->file_cntl;
 		memcpy(greg->dyn.addr->fname, prev_reg->dyn.addr->fname, prev_reg->dyn.addr->fname_len);
 		greg->dyn.addr->fname_len = prev_reg->dyn.addr->fname_len;
 		csa = (sgmnt_addrs *)&FILE_INFO(greg)->s_addrs;
-		PROCESS_GVT_PENDING_LIST(greg, csa, gvt_pending_list);
-		csd = csa->hdr;
 		if (NULL == csa->gvt_hashtab)
-		{	/* Already have another region that points to the same physical database file as this one.
-			 * Since two regions point to the same physical file, start maintaining a list of all global variable
-			 * names whose gv_targets have already been allocated on behalf of the current database file.
-			 * Future targ_allocs will check this list before they allocate (to avoid duplicate allocations).
-			 */
-			csa->gvt_hashtab = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
-			init_hashtab_mname(csa->gvt_hashtab, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
-			assert(1 == csa->regcnt);
-			first_wasopen = TRUE;
-		} else
-			first_wasopen = FALSE;
-		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
-		{
-			table = addr_ptr->tab_ptr;
-			for (tabent = table->base, topent = tabent + table->size; tabent < topent; tabent++)
-			{
-				if (HTENT_VALID_MNAME(tabent, gvnh_reg_t, gvnh_reg))
-				{	/* Check if the gvt's region is the current region.
-					 * If so add gvt's variable name into the csa hashtable.
-					 */
-					gvt = gvnh_reg->gvt;
-					assert((gvnh_reg->gd_reg != greg) || (csa == gvt->gd_csa));
-					/* If this is the first time a was_open region is happening for this csa, then
-					 * we want to merge gv_targets from both the regions into csa->gvt_hashtab. For
-					 * all future was_open cases, we want only to add gv_targets from the was_open region.
-					 */
-					if (first_wasopen && (csa == gvt->gd_csa) || !first_wasopen && (gvnh_reg->gd_reg == greg))
-					{	/* Add gv_target into csa->gvt_hashtab */
-						added = add_hashtab_mname(csa->gvt_hashtab, &gvt->gvname, gvt, &stayent);
-						assert(!added || (1 <= gvt->regcnt));
-						if (!added)
-						{	/* Entry already present. Increment gvt->regcnt.
-							 * If NOISOLATION status differs between the two,
-							 * choose the more pessimistic one.
-							 */
-							gvt_stay = (gv_namehead *)stayent->value;
-							assert(gvt_stay != gvt);
-							if (FALSE == gvt->noisolation)
-								gvt_stay->noisolation = FALSE;
-							assert(1 <= gvt_stay->regcnt);
-							/* Now make gvnh_reg->gvt point to gvt_stay (instead of gvt) */
-							gvt_stay->regcnt++;
-							gvt->regcnt--;
-							gvnh_reg->gvt = gvt_stay;
-							targ_free(gvt);
-						}
-					}
-				}
-			}
-		}
+			gvt_hashtab_init(csa);	/* populate csa->gvt_hashtab; need to do this BEFORE PROCESS_GVT_PENDING_LIST */
+		PROCESS_GVT_PENDING_LIST(greg, csa);
+		csd = csa->hdr;
 		greg->max_rec_size = csd->max_rec_size;
 		greg->max_key_size = csd->max_key_size;
 	 	greg->null_subs = csd->null_subs;
@@ -381,7 +328,7 @@ void gvcst_init(gd_region *greg)
 	csa->db_addrs[0] = csa->db_addrs[1] = NULL;
 	csa->lock_addrs[0] = csa->lock_addrs[1] = NULL;
 #	ifdef VMS
-	greg_acc_meth = greg->dyn.addr->acc_meth;
+	greg_acc_meth = REG_ACC_METH(greg);
 	assert(dba_cm != greg_acc_meth);
 	temp_cs_data = (sgmnt_data_ptr_t)cs_data_buff;
 	fc = greg->dyn.addr->file_cntl;
@@ -396,7 +343,7 @@ void gvcst_init(gd_region *greg)
 	if (greg_acc_meth != temp_cs_data->acc_meth)
 	{
 		greg_acc_meth = temp_cs_data->acc_meth;
-		greg->dyn.addr->acc_meth = greg_acc_meth;
+		REG_ACC_METH(greg) = greg_acc_meth;
 	}
 #	endif
 	/* Here's the shared memory layout:
@@ -513,14 +460,14 @@ void gvcst_init(gd_region *greg)
 	csa->db_trigger_cycle = csd->db_trigger_cycle;
 #	endif
 	/* set csd and fill in selected fields */
-	assert(greg->dyn.addr->acc_meth == csd->acc_meth); /* db_init should have made sure this assert holds good */
+	assert(REG_ACC_METH(greg) == csd->acc_meth); /* db_init should have made sure this assert holds good */
 	greg_acc_meth = csd->acc_meth;
 	/* It is necessary that we do the pending gv_target list reallocation BEFORE db_common_init as the latter resets
 	 * greg->max_key_size to be equal to the csd->max_key_size and hence process_gvt_pending_list might wrongly conclude
 	 * that NO reallocation (since it checks greg->max_key_size with csd->max_key_size) is needed when in fact a
 	 * reallocation might be necessary (if the user changed max_key_size AFTER database creation)
 	 */
-	PROCESS_GVT_PENDING_LIST(greg, csa, gvt_pending_list);
+	PROCESS_GVT_PENDING_LIST(greg, csa);
 	db_common_init(greg, csa, csd);	/* do initialization common to db_init() and mu_rndwn_file() */
 
 	/* If we are not fully upgraded, see if we need to send a warning to the operator console about
@@ -644,7 +591,6 @@ void gvcst_init(gd_region *greg)
 	}
 	assert(!greg->was_open);
 	SET_REGION_OPEN_TRUE(greg, WAS_OPEN_FALSE);
-	csa = (sgmnt_addrs*)&FILE_INFO(greg)->s_addrs;
 	if (NULL != csa->dir_tree)
 	{	/* It is possible that dir_tree has already been targ_alloc'ed. This is because GT.CM or VMS DAL
 		 * calls can run down regions without the process halting out. We don't want to double malloc.
@@ -701,6 +647,7 @@ void gvcst_init(gd_region *greg)
 		 */
 		prevcsa = NULL;
 		greg_fid = &(csa->nl->unique_id);
+		max_fid_index = 1;
 		for (regcsa = cs_addrs_list; NULL != regcsa; regcsa = regcsa->next_csa)
 		{
 			UNIX_ONLY(onln_rlbk_cycle_mismatch |= (regcsa->db_onln_rlbkd_cycle != regcsa->nl->db_onln_rlbkd_cycle));
@@ -713,12 +660,18 @@ void gvcst_init(gd_region *greg)
 				if ((NULL == prevcsa) || (regcsa->fid_index > prevcsa->fid_index))
 					prevcsa = regcsa;
 			} else
+			{
 				regcsa->fid_index++;
+				max_fid_index = MAX(max_fid_index, regcsa->fid_index);
+			}
 		}
 		if (NULL == prevcsa)
 			csa->fid_index = 1;
 		else
+		{
 			csa->fid_index = prevcsa->fid_index + 1;
+			max_fid_index = MAX(max_fid_index, csa->fid_index);
+		}
 		UNIX_ONLY(
 			if (onln_rlbk_cycle_mismatch)
 			{
@@ -734,6 +687,7 @@ void gvcst_init(gd_region *greg)
 		for (tr = tp_reg_list; NULL != tr; tr = tr->fPtr)
 			tr->file.fid_index = (&FILE_INFO(tr->reg)->s_addrs)->fid_index;
 		DBG_CHECK_TP_REG_LIST_SORTING(tp_reg_list);
+		TREF(max_fid_index) = max_fid_index;
 	}
 #	ifdef UNIX
 	if (pool_init && REPL_ALLOWED(csd) && jnlpool_init_needed)
diff --git a/sr_port/gvcst_kill.c b/sr_port/gvcst_kill.c
index d2f99d2..963f3d3 100644
--- a/sr_port/gvcst_kill.c
+++ b/sr_port/gvcst_kill.c
@@ -112,7 +112,6 @@ GBLREF	boolean_t		donot_INVOKE_MUMTSTART;
 #endif
 UNIX_ONLY(GBLREF	boolean_t 		span_nodes_disallowed;)
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_TPRETRY);
 error_def(ERR_GVKILLFAIL);
 
diff --git a/sr_port/gvcst_order.c b/sr_port/gvcst_order.c
index 725e279..e465d96 100644
--- a/sr_port/gvcst_order.c
+++ b/sr_port/gvcst_order.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -60,18 +60,15 @@ GBLREF int4		gv_keysize;
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVORDERFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_order_ch)
 
-bool	gvcst_order(void)
+boolean_t	gvcst_order(void)
 {	/* See gvcst_query.c */
-	bool		found, is_hidden, sn_tpwrapped;
+	boolean_t	found, is_hidden, sn_tpwrapped;
 	boolean_t	est_first_pass;
-	char		save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key		*save_gv_currkey;
+	gv_key		save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	int		end, prev, oldend;
 	int		save_dollar_tlevel;
 
@@ -82,17 +79,17 @@ bool	gvcst_order(void)
 	CHECK_HIDDEN_SUBSCRIPT_AND_RETURN(found, gv_altkey, is_hidden);
 	assert(found && is_hidden);
 	IF_SN_DISALLOWED_AND_NO_SPAN_IN_DB(return found);
-	SAVE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend);
+	SAVE_GV_CURRKEY_LAST_SUBSCRIPT(save_currkey, prev, oldend);
 	if (!dollar_tlevel)
 	{
 		sn_tpwrapped = TRUE;
 		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
 		ESTABLISH_NORET(gvcst_order_ch, est_first_pass);
 		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+		INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_order, (gtm_uint64_t) -1);
+		found = gvcst_order2();
 	} else
 		sn_tpwrapped = FALSE;
-	INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_order, (gtm_uint64_t) -1);
-	found = gvcst_order2();
 	if (found)
 	{
 		CHECK_HIDDEN_SUBSCRIPT(gv_altkey, is_hidden);
@@ -100,14 +97,7 @@ bool	gvcst_order(void)
 		{	/* Replace last subscript to be the highest possible hidden subscript so another
 			 * gvcst_order2 will give us the next non-hidden subscript.
 			 */
-			end = gv_altkey->end;
-			gv_currkey->base[end - 4] = 2;
-			gv_currkey->base[end - 3] = 0xFF;
-			gv_currkey->base[end - 2] = 0xFF;
-			gv_currkey->base[end - 1] = 1;
-			gv_currkey->base[end + 0] = 0;
-			gv_currkey->base[end + 1] = 0;
-			gv_currkey->end = end + 1;
+			REPLACE_HIDDEN_SUB_TO_HIGHEST(gv_altkey, gv_currkey);	/* uses gv_altkey to modify gv_currkey */
 			/* fix up since it should only be externally counted as one $order */
 			INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_order, (gtm_uint64_t) -1);
 			found = gvcst_order2();
@@ -118,13 +108,13 @@ bool	gvcst_order(void)
 		op_tcommit();
 		REVERT; /* remove our condition handler */
 	}
-	RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend);
+	RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(save_currkey, prev, oldend);
 	assert(save_dollar_tlevel == dollar_tlevel);
 #	endif
 	return found;
 }
 
-bool	gvcst_order2(void)
+boolean_t	gvcst_order2(void)
 {
 	blk_hdr_ptr_t	bp;
 	boolean_t	found, two_histories;
diff --git a/sr_port/gvcst_protos.h b/sr_port/gvcst_protos.h
index 343450b..1f6133f 100644
--- a/sr_port/gvcst_protos.h
+++ b/sr_port/gvcst_protos.h
@@ -28,7 +28,7 @@ mint		gvcst_data(void);
 mint		gvcst_data2(void);
 enum cdb_sc	gvcst_dataget(mint *dollar_data, mval *val);
 enum cdb_sc	gvcst_dataget2(mint *dollar_data, mval *val, unsigned char *sn_ptr);
-bool		gvcst_gblmod(mval *v);
+boolean_t	gvcst_gblmod(mval *v);
 boolean_t	gvcst_get(mval *v);
 boolean_t	gvcst_get2(mval *v, unsigned char *sn_ptr);
 void		gvcst_incr(mval *increment, mval *result);
@@ -36,12 +36,12 @@ void		gvcst_init(gd_region *greg);
 void		gvcst_kill(boolean_t do_subtree);
 void		gvcst_kill2(boolean_t do_subtree, boolean_t *span_status, boolean_t killing_chunks);
 enum cdb_sc	gvcst_lftsib(srch_hist *full_hist);
-bool		gvcst_order(void);
-bool		gvcst_order2(void);
+boolean_t	gvcst_order(void);
+boolean_t	gvcst_order2(void);
 void		gvcst_put(mval *v);
 void		gvcst_put2(mval *val, span_parms *parms);
-bool		gvcst_query(void);
-bool		gvcst_query2(void);
+boolean_t	gvcst_query(void);
+boolean_t	gvcst_query2(void);
 boolean_t	gvcst_queryget(mval *val);
 boolean_t	gvcst_queryget2(mval *val, unsigned char *sn_ptr);
 enum cdb_sc	gvcst_root_search(boolean_t donot_restart);
@@ -49,9 +49,27 @@ enum cdb_sc	gvcst_rtsib(srch_hist *full_hist, int level);
 enum cdb_sc	gvcst_search(gv_key *pKey, srch_hist *pHist);
 enum cdb_sc	gvcst_search_blk(gv_key *pKey, srch_blk_status *pStat);
 enum cdb_sc	gvcst_search_tail(gv_key *pKey, srch_blk_status *pStat, gv_key *pOldKey);
+
+#ifdef UNIX
+mint		gvcst_spr_data(void);
+void		gvcst_spr_kill(void);
+boolean_t	gvcst_spr_order(void);
+boolean_t	gvcst_spr_zprevious(void);
+boolean_t	gvcst_spr_query(void);
+boolean_t	gvcst_spr_queryget(mval *cumul_val);
+
+# define INVOKE_GVCST_SPR_XXX(GVNH_REG, STATEMENT)	\
+{							\
+	assert(NULL != GVNH_REG->gvspan);		\
+	STATEMENT;					\
+}
+#else
+# define INVOKE_GVCST_SPR_XXX(GVNH_REG, STMT)	assert(FALSE)
+#endif
+
 void		gvcst_tp_init(gd_region *);
-bool		gvcst_zprevious(void);
-bool		gvcst_zprevious2(void);
+boolean_t	gvcst_zprevious(void);
+boolean_t	gvcst_zprevious2(void);
 
 /* gvcst_dataget and gvcst_dataget2 take the following values as input */
 #define DG_GETONLY	2
@@ -59,6 +77,20 @@ bool		gvcst_zprevious2(void);
 #define DG_DATAGET	4
 #define DG_GETSNDATA	5
 
+#define	INCREMENT_GD_TARG_TN(LCL_TN)								\
+{												\
+	(TREF(gd_targ_tn))++;									\
+	LCL_TN = TREF(gd_targ_tn);								\
+	if (0 == LCL_TN)									\
+	{	/* We have wrapped around after 2**64 increments. Reset gd_targ_reg_array to	\
+		 * avoid incorrect matches of tn (the pre-wrapped tn with the post-wrapped tn).	\
+		 */										\
+		memset(TREF(gd_targ_reg_array), 0, TREF(gd_targ_reg_array_size));		\
+		LCL_TN++;									\
+		TREF(gd_targ_tn) = LCL_TN;							\
+	}											\
+}
+
 GBLREF	boolean_t	gv_play_duplicate_kills;
 
 /* In case "gv_play_duplicate_kills" is TRUE, invoke "gvcst_kill" even if the GVT does not exist. This is so we record
diff --git a/sr_port/gvcst_put.c b/sr_port/gvcst_put.c
index 98bf645..b2586e9 100644
--- a/sr_port/gvcst_put.c
+++ b/sr_port/gvcst_put.c
@@ -75,6 +75,11 @@
 #ifdef UNIX
 #include "preemptive_db_clnup.h"
 #endif
+#include "spec_type.h"
+#include "collseq.h"
+#ifdef DEBUG
+#include "mvalconv.h"
+#endif
 
 #ifdef GTM_TRIGGER
 LITREF	mval	literal_null;
@@ -251,7 +256,7 @@ CONDITION_HANDLER(gvcst_put_ch)
 {
 	int rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{	/* delay tp_restart till after the long jump and some other stuff */
 		UNWIND(NULL, NULL);
@@ -262,7 +267,7 @@ CONDITION_HANDLER(gvcst_put_ch)
 void	gvcst_put(mval *val)
 {
 	boolean_t			sn_tpwrapped, fits;
-	boolean_t			est_first_pass;
+	boolean_t			est_first_pass, found;
 	mval				val_ctrl, val_piece, val_dummy;
 	mval				*pre_incr_mval, *save_val;
 	block_id			lcl_root;
@@ -349,8 +354,11 @@ void	gvcst_put(mval *val)
 		in_gvcst_incr = FALSE;		/* allow gvcst_put2 to do a regular set */
 		PUSH_MV_STENT(MVST_MVAL);       /* protect pre_incr_mval from stp_gcol */
 		pre_incr_mval = &mv_chain->mv_st_cont.mvs_mval;
-		gvcst_get(pre_incr_mval);	/* what if it doesn't exist? needs to be treated as 0 */
-		pre_incr_mval->mvtype = MV_STR;
+		found = gvcst_get(pre_incr_mval);	/* what if it doesn't exist? needs to be treated as 0 */
+		if (found)
+			pre_incr_mval->mvtype = MV_STR;
+		else
+			*pre_incr_mval = literal_null;
 		op_add(pre_incr_mval, &increment_delta_mval, post_incr_mval);
 		POP_MV_STENT();			/* pre_incr_mval */
 		assert(MV_IS_NUMERIC(post_incr_mval));
@@ -417,7 +425,8 @@ void	gvcst_put2(mval *val, span_parms *parms)
 	sgmnt_data_ptr_t	csd;
 	node_local_ptr_t	cnl;
 	int4			blk_size, blk_fill_size, blk_reserved_bytes;
-	const int4		zeroes = 0;
+	const uint4		zeroes4byte = 0;
+	const gtm_uint64_t	zeroes8byte = 0;
 	boolean_t		jnl_format_done, is_dummy, needfmtjnl, fits, lcl_span_status;
 	blk_segment		*bs1, *bs_ptr, *new_blk_bs;
 	block_id		allocation_clue, tp_root, gvt_for_root, blk_num, last_split_blk_num[MAX_BT_DEPTH];
@@ -427,7 +436,7 @@ void	gvcst_put2(mval *val, span_parms *parms)
 	gv_namehead		*save_targ, *split_targ, *dir_tree;
 	enum cdb_sc		status;
 	gv_key			*temp_key;
-	int			tmp_cmpc;
+	uchar_ptr_t		subrec_ptr;
 	mstr			value;
 	off_chain		chain1, curr_chain, prev_chain, chain2;
 	rec_hdr_ptr_t		curr_rec_hdr, extra_rec_hdr, next_rec_hdr, new_star_hdr, rp, tmp_rp;
@@ -436,11 +445,12 @@ void	gvcst_put2(mval *val, span_parms *parms)
 	int			cur_blk_size, blk_seg_cnt, delta, i, j, left_hand_offset, n, ins_chain_offset,
 				new_blk_size_l, new_blk_size_r, new_blk_size_single, new_blk_size, blk_reserved_size,
 				last_possible_left_offset, new_rec_size, next_rec_shrink, next_rec_shrink1, start_len,
-				offset_sum, rec_cmpc, target_key_size, tp_lev, undo_index, cur_val_offset, curr_offset, bh_level;
+				offset_sum, rec_cmpc, tmp_cmpc, target_key_size, tp_lev, undo_index, cur_val_offset,
+				curr_offset, bh_level;
 	uint4			segment_update_array_size, key_top, cp2_len, bs1_2_len, bs1_3_len;
 	char			*va, last_split_direction[MAX_BT_DEPTH];
 	sm_uc_ptr_t		cp1, cp2, curr;
-	unsigned short		extra_record_orig_size, rec_size, temp_short;
+	unsigned short		extra_record_blkid_off, rec_size, tmp_rsiz;
 	unsigned int		prev_rec_offset, prev_rec_match, curr_rec_offset, curr_rec_match;
 	boolean_t		copy_extra_record, level_0, new_rec, no_pointers, succeeded, key_exists;
 	boolean_t		make_it_null, gbl_target_was_set, duplicate_set, new_rec_goes_to_right, need_extra_block_split;
@@ -486,6 +496,7 @@ void	gvcst_put2(mval *val, span_parms *parms)
 	mval			*pval;				/* copy of "value" (an mstr), protected from stp gcol */
 	DEBUG_ONLY(enum cdb_sc	save_cdb_status;)
 #	endif
+	uint4			no_4byte_collhdr;
 #	ifdef DEBUG
 	char			dbg_valbuff[256];
 	mstr_len_t		dbg_vallen;
@@ -519,6 +530,7 @@ void	gvcst_put2(mval *val, span_parms *parms)
 	dbg_trace		dbg_trace_array[16];
 	boolean_t		is_fresh_tn_start;
 	boolean_t		is_mm;
+	mval			tmpmval, *random_mval = &tmpmval;
 #	endif
 	DCL_THREADGBL_ACCESS;
 
@@ -692,7 +704,7 @@ tn_restart:
 		segment_update_array_size = UA_NON_BM_SIZE(csd);
 		ENSURE_UPDATE_ARRAY_SPACE(segment_update_array_size);
 		curr_chain = *(off_chain *)&lcl_root;
-		if (curr_chain.flag == 1)
+		if (curr_chain.flag)
 		{
 			tp_get_cw(si->first_cw_set, (int)curr_chain.cw_index, &cse);
 			tp_root = cse->blk;
@@ -721,7 +733,7 @@ tn_restart:
 			{
 				gvt_for_root = dir_hist->h[0].blk_num;
 				curr_chain = *(off_chain *)&gvt_for_root;
-				if (curr_chain.flag == 1)
+				if (curr_chain.flag)
 					tp_get_cw(si->first_cw_set, curr_chain.cw_index, &cse);
 				else
 				{
@@ -794,7 +806,7 @@ tn_restart:
 		SET_CMPC(curr_rec_hdr, 0);
 		BLK_INIT(bs_ptr, bs1);
 		BLK_SEG(bs_ptr, (sm_uc_ptr_t)curr_rec_hdr, SIZEOF(rec_hdr));
-		BLK_SEG(bs_ptr, (unsigned char *)&zeroes, SIZEOF(block_id));
+		BLK_SEG(bs_ptr, (unsigned char *)&zeroes4byte, SIZEOF(block_id));
 		if (0 == BLK_FINI(bs_ptr, bs1))
 		{
 			assert(CDB_STAGNATE > t_tries);
@@ -803,16 +815,85 @@ tn_restart:
 		}
 		assert(bs1[0].len <= blk_reserved_size); /* Assert that new block has space for reserved bytes */
         	allocation_clue = ALLOCATION_CLUE(csd->trans_hist.total_blks);
-		next_blk_index = t_create(allocation_clue, (uchar_ptr_t)new_blk_bs, 0, 0, 0);
+		next_blk_index = t_create(allocation_clue, (uchar_ptr_t)new_blk_bs, 0, 0, 0);	/* create GVT data block */
 		++allocation_clue;
 		ins_chain_index = t_create(allocation_clue, (uchar_ptr_t)bs1, SIZEOF(blk_hdr) + SIZEOF(rec_hdr), next_blk_index, 1);
+					/* create GVT index block */
 		root_blk_cw_index = ins_chain_index;
 		temp_key = gv_altkey;
 		gv_target->hist.h[0].blk_num = HIST_TERMINATOR;
 		gv_target = dir_tree;
 		bh = &gv_target->hist.h[0];
-		value.len = SIZEOF(block_id);
-		value.addr = (char *)&zeroes;
+		assert(ACT_NOT_SPECIFIED != save_targ->act);
+		/* Global directory OR db file header defined an alternative collation sequence for this global (even if it is 0).
+		 * Store it in directory tree as part of the specific global name. This way future updates to this global will
+		 * continue to use this stored collation even if the db file header collation sequence changes (using DSE) during
+		 * the lifetime of this GVT.
+		 */
+		if (save_targ->act)
+		{
+			act_in_gvt(save_targ); /* verify that collation library version is still compatible */
+			/* The above call sets "save_targ->collseq" to a non-NULL value. need to keep it set so it
+			 * stays set after the GVT gets created. If this transaction restarts (i.e. we did not
+			 * create the GVT, it is okay for save_targ->collseq to be set to a non-NULL value since it
+			 * will be reinitialized when save_targ->root gets set to a non-zero value in gvcst_root_search.
+			 */
+			no_4byte_collhdr = 0;
+		} else if (save_targ->act_specified_in_gld)
+		{	/* If collation has been specified in gld, even though it is zero, we need to store it in
+			 * the directory tree. Or else we could get an incorrect ACTCOLLMISMTCH error later in case
+			 * the db file header has an overriding non-zero default collation field set.
+			 */
+			no_4byte_collhdr = 0;
+		} else
+#		if defined(DEBUG) && defined(UNIX)
+		{	/* Starting V6.1, newly created nodes in the directory tree (DT) leaf block have a 4-byte collation header
+			 * unconditionally but in order to test the code below for correctness on pre-existing DT leaf block
+			 * records which might not contain a 4-byte collation header, we randomly enable the 4-byte collation
+			 * header for now in debug mode. Note that this can be safely done only for globals that have collation #0.
+			 * When V7 is released and the directory tree leaf records are all upgraded to contain the 4-byte collation
+			 * header unconditionally, this randomization will need to be removed.
+			 * Note that if the env var "gtm_dirtree_collhdr_always" is true, then disable this behavior (this is
+			 * usually set by tests that rely on a fixed DT leaf block layout and will fail if the layout changes).
+			 */
+			if (TREF(gtm_dirtree_collhdr_always))
+				no_4byte_collhdr = 0;
+			else
+			{
+				op_fnrandom(2, random_mval);
+				no_4byte_collhdr = MV_FORCE_INT(random_mval);
+			}
+		}
+#		elif defined(UNIX)
+			no_4byte_collhdr = 0;	/* for Unix pro, add the 4-byte collation header even for "act" = 0 */
+#		elif defined(VMS)
+			no_4byte_collhdr = 1;	/* for VMS (pro and dbg) unconditionally disable the 4-byte collation header.
+						 * as otherwise it means fixing test reference files to account for new 4-bytes
+						 */
+#		endif
+		if (no_4byte_collhdr)
+		{	/* No 4-byte collation header */
+			value.addr = (char *)&zeroes4byte;
+			value.len = SIZEOF(block_id);
+			assert(SIZEOF(zeroes4byte) == value.len);
+		} else
+		{
+			value.addr = (char *)&zeroes8byte;
+			value.len = SIZEOF(block_id) + COLL_SPEC_LEN;
+			assert(SIZEOF(zeroes8byte) == value.len);
+			/* The 4-byte "block_id" will be filled in later. Fill the 4-byte collation header now */
+			subrec_ptr = (unsigned char *)value.addr + SIZEOF(block_id);
+			assert(COLL_NCT_OFFSET > 0);
+			assert(COLL_ACT_OFFSET > 0);
+			assert(COLL_VER_OFFSET > 0);
+			assert(COLL_NCT_OFFSET < COLL_SPEC_LEN);
+			assert(COLL_ACT_OFFSET < COLL_SPEC_LEN);
+			assert(COLL_VER_OFFSET < COLL_SPEC_LEN);
+			*subrec_ptr = COLL_SPEC;
+			*(subrec_ptr + COLL_NCT_OFFSET) = save_targ->nct;
+			*(subrec_ptr + COLL_ACT_OFFSET) = save_targ->act;
+			*(subrec_ptr + COLL_VER_OFFSET) = save_targ->ver;
+		}
 		no_pointers = FALSE;
 	} else
 	{
@@ -830,13 +911,13 @@ tn_restart:
 				GOTO_RETRY;
 		}
 #		endif
-#if defined(DEBUG) && defined(UNIX)
+#		if defined(DEBUG) && defined(UNIX)
 		if (gtm_white_box_test_case_enabled && (WBTEST_ANTIFREEZE_GVINCRPUTFAIL == gtm_white_box_test_case_number))
 		{
 			status = cdb_sc_blknumerr;
 			GOTO_RETRY;
 		}
-#endif
+#		endif
 		if (cdb_sc_normal != (status = gvcst_search(gv_currkey, NULL)))
 			GOTO_RETRY;
 		target_key_size = gv_currkey->end + 1;
@@ -1092,7 +1173,14 @@ tn_restart:
 			if (no_pointers)	/* level zero (normal) data block: no deferred pointer chains */
 				ins_chain_offset = 0;
 			else			/* index or directory level block */
-				ins_chain_offset =(int)((sm_uc_ptr_t)rp - buffaddr + new_rec_size - SIZEOF(block_id));
+			{	/* In case a new GVT is being created, it is possible 4-byte collation information is being
+				 * added to the leaf level directory tree record for this global name (after the 4-byte block_id).
+				 * Irrespective of the collation header, make sure ins_chain_offset points to the block_id part.
+				 */
+				assert(((char *)&zeroes4byte == value.addr) || ((char *)&zeroes8byte == value.addr));
+				assert((4 == value.len) || (8 == value.len));
+				ins_chain_offset = (int)(curr_rec_offset + new_rec_size - value.len);
+			}
 			BLK_INIT(bs_ptr, bs1);
 			if (0 == rc_set_fragment)
 			{
@@ -1175,15 +1263,16 @@ tn_restart:
 									&& (buffaddr == cse->low_tlevel->new_buff));
 				assert(0 == cse->next_off);
 				assert(ins_chain_offset > (signed)SIZEOF(blk_hdr));	/* we want signed comparison */
-				assert((curr_rec_offset - SIZEOF(off_chain)) == (ins_chain_offset - new_rec_size));
 				offset_sum = cse->first_off;
 				curr = buffaddr + offset_sum;
+				assert(new_rec);
+				assert(offset_sum != curr_rec_offset);
 				/* The typecast is needed below to enforce a "signed int" (versus "unsigned int") comparison */
 				if (offset_sum >= (signed int)curr_rec_offset)
 				{	/* the new record is prior to the first existing chain record, id the new one as first */
 					/* first_off-------------v--------------------v
 					 * [blk_hdr]...[new rec ( )]...[existing rec ( )]... */
-					cse->next_off = cse->first_off - (ins_chain_offset - new_rec_size) - next_rec_shrink1;
+					cse->next_off = value.len + (offset_sum - curr_rec_offset - next_rec_shrink1);
 					cse->first_off = ins_chain_offset;
 				} else
 				{
@@ -1198,10 +1287,11 @@ tn_restart:
 					for ( ; ; curr += curr_chain.next_off)
 					{	/* try to make offset_sum identify the first chain entry after the new record */
 						GET_LONGP(&curr_chain, curr);
-						assert(curr_chain.flag == 1);
+						assert(1 == curr_chain.flag);
 						if (0 == curr_chain.next_off)
 							break;
 						offset_sum += curr_chain.next_off;
+						assert(offset_sum != curr_rec_offset);
 						/* The typecast is needed below to enforce a "signed int" comparison */
 						if (offset_sum >= (signed int)curr_rec_offset)
 							break;
@@ -1225,7 +1315,7 @@ tn_restart:
 						 * [blk_hdr]...[existing rec ( )]...[new rec ( )]...[existing rec ( )] */
 						curr_chain.next_off = (unsigned int)(ins_chain_offset - (curr - buffaddr));
 						GET_LONGP(curr, &curr_chain);
-						cse->next_off = offset_sum - (ins_chain_offset - new_rec_size) - next_rec_shrink1;
+						cse->next_off = value.len + (offset_sum - curr_rec_offset - next_rec_shrink1);
 					}
 				}
 				assert((ins_chain_offset + (int)cse->next_off) <=
@@ -1303,11 +1393,10 @@ tn_restart:
 			gv_target->clue.end = 0;	/* invalidate clue */
 			/* Potential size of the left and right blocks, including the new record */
 			new_blk_size_l = curr_rec_offset + new_rec_size;
-			new_blk_size_r = SIZEOF(blk_hdr) + SIZEOF(rec_hdr) + target_key_size + value.len + cur_blk_size
+			new_blk_size_r = new_blk_size_single + cur_blk_size
 						- curr_rec_offset - (new_rec ? next_rec_shrink : rec_size);
 			assert(new_blk_size_single <= blk_reserved_size);
 			assert(blk_reserved_size >= blk_fill_size);
-			extra_record_orig_size = 0;
 			prev_rec_offset = bh->prev_rec.offset;
 			/* Decide which side (left or right) the new record goes. Ensure either side has at least one record.
 			 * This means we might not honor the desired FillFactor if the only record in a block exceeds the
@@ -1501,11 +1590,11 @@ tn_restart:
 					left_hand_offset = 0;
 				else
 				{
-					left_hand_offset = curr_rec_offset + SIZEOF(rec_hdr);
+					left_hand_offset = curr_rec_offset + SIZEOF(rec_hdr); /* *-record is usually last record */
 					if (level_0 || copy_extra_record)
-						left_hand_offset += target_key_size - prev_rec_match;
+						left_hand_offset += target_key_size - prev_rec_match; /* exceptions for *-record */
 				}
-				left_hand_index = ins_chain_index;
+				left_hand_index = ins_chain_index;	/* copy over cw_set index from child level block create */
 				ins_chain_index = ins_chain_offset = 0;
 				BLK_SEG(bs_ptr, buffaddr + SIZEOF(blk_hdr), curr_rec_offset - SIZEOF(blk_hdr));
 				if (level_0)
@@ -1590,7 +1679,7 @@ tn_restart:
 					BLK_SEG(bs_ptr, (sm_uc_ptr_t)new_star_hdr, SIZEOF(rec_hdr));
 					if (!copy_extra_record)
 					{
-						BLK_SEG(bs_ptr, (unsigned char *)&zeroes, SIZEOF(block_id));
+						BLK_SEG(bs_ptr, (unsigned char *)&zeroes4byte, SIZEOF(block_id));
 					} else
 						BLK_SEG(bs_ptr, (sm_uc_ptr_t)rp + rec_size - SIZEOF(block_id), SIZEOF(block_id));
 				}
@@ -1614,14 +1703,14 @@ tn_restart:
 				assert(new_rec || !copy_extra_record);
 				if (!new_rec || copy_extra_record)
 				{	/* Should guard for empty block??? */
+					/* Before advancing one record, store rec_size and rec_cmpc for current record */
+					tmp_rp = rp;
 					rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)rp + rec_size);
 					rec_cmpc = EVAL_CMPC(rp);
-					temp_short = rec_size;
 					GET_USHORT(rec_size, &rp->rsiz);
 				}
 				if (copy_extra_record)
 				{
-				        extra_record_orig_size = temp_short;
 					assert(gv_altkey->top == gv_currkey->top);
 					assert(gv_altkey->end < gv_altkey->top);
 					temp_key = gv_altkey;
@@ -1633,10 +1722,9 @@ tn_restart:
 					memcpy(gv_altkey, temp_key, SIZEOF(gv_key) + temp_key->end);
 					temp_key = gv_altkey;
 				}
-				rec_size += rec_cmpc;
 				BLK_INIT(bs_ptr, bs1);
 				BLK_ADDR(next_rec_hdr, SIZEOF(rec_hdr), rec_hdr);
-				next_rec_hdr->rsiz = rec_size;
+				next_rec_hdr->rsiz = rec_size + rec_cmpc;
 				SET_CMPC(next_rec_hdr, 0);
 				BLK_SEG(bs_ptr, (sm_uc_ptr_t)next_rec_hdr, SIZEOF(rec_hdr));
 				BLK_ADDR(cp1, rec_cmpc, unsigned char);
@@ -1671,7 +1759,7 @@ tn_restart:
 			{	/* there may be chains */
 				assert(new_rec);
 				curr_chain = *(off_chain *)&blk_num;
-				if (curr_chain.flag == 1)
+				if (curr_chain.flag)
 					tp_get_cw(si->first_cw_set, curr_chain.cw_index, &cse);
 				else
 				{
@@ -1698,9 +1786,62 @@ tn_restart:
 					offset_sum = cse_first_off;
 					curr = buffaddr + offset_sum;
 					GET_LONGP(&curr_chain, curr);
-					assert(curr_chain.flag == 1);
-					last_possible_left_offset = curr_rec_offset + extra_record_orig_size - SIZEOF(off_chain);
-					/* some of the following logic used to be in tp_split_chain which was nixed */
+					assert(1 == curr_chain.flag);
+					/* Determine "last_possible_left_offset" and "extra_record_blkid_off" */
+					copy_extra_record = !new_rec_goes_to_right && copy_extra_record;
+					if (copy_extra_record)
+					{
+						assert(!new_rec_goes_to_right);
+						GET_USHORT(tmp_rsiz, &tmp_rp->rsiz);
+						tmp_cmpc = EVAL_CMPC(tmp_rp);
+						if (level_0)
+						{	/* Directory Tree leaf level block. Determine the offset within the
+							 * extra record where "block_id" is stored. It is guaranteed to be
+							 * the last 4-bytes of the record for all GVT index and DT index blocks
+							 * but not for DT leaf blocks where it is the first 4-bytes (after the key)
+							 * and a 4-byte collation header could optionally follow it.
+							 */
+							extra_record_blkid_off = SIZEOF(rec_hdr) + temp_key->end + 1 - tmp_cmpc;
+							assert(((tmp_rsiz - extra_record_blkid_off) == SIZEOF(off_chain))
+								|| ((tmp_rsiz - extra_record_blkid_off)
+									== SIZEOF(off_chain) + COLL_SPEC_LEN));
+						} else
+				        		extra_record_blkid_off = tmp_rsiz - SIZEOF(off_chain);
+						assert(extra_record_blkid_off);
+						last_possible_left_offset = curr_rec_offset + extra_record_blkid_off;
+					} else
+					{
+				        	extra_record_blkid_off = 0;
+						if (level_0)
+						{	/* Directory Tree leaf level block. Find end of key in prev_rec
+							 * since block_id starts right after that.
+							 */
+							if (!prev_rec_offset)
+								cp1 = buffaddr;
+							else
+							{
+								cp1 = buffaddr + prev_rec_offset + SIZEOF(rec_hdr);
+								assert(((sm_uc_ptr_t)rp - buffaddr) == curr_rec_offset);
+								assert(cp1 < (sm_uc_ptr_t)rp);
+								for ( ; cp1 < (sm_uc_ptr_t)rp; )
+								{
+									if ((KEY_DELIMITER == *cp1++) && (KEY_DELIMITER == *cp1))
+										break;
+								}
+								if (++cp1 > ((sm_uc_ptr_t)rp - SIZEOF(off_chain)))
+								{
+									assert(CDB_STAGNATE > t_tries);
+									status = cdb_sc_mkblk;
+									GOTO_RETRY;
+								}
+								assert(((cp1 + SIZEOF(off_chain)) == (sm_uc_ptr_t)rp)
+									|| ((cp1 + SIZEOF(off_chain) + COLL_SPEC_LEN)
+													== (sm_uc_ptr_t)rp));
+							}
+						}
+						last_possible_left_offset = level_0 ? INTCAST(cp1 - buffaddr)
+											: curr_rec_offset - SIZEOF(off_chain);
+					}
 					if (offset_sum <= last_possible_left_offset)
 					{	/* the split falls within or after the chain; otherwise entire chain stays right */
 						assert((cse_first_off < curr_rec_offset)
@@ -1755,7 +1896,7 @@ tn_restart:
 							if (left_hand_offset)
 							{
 								assert(!ins_chain_offset);
-								if (!extra_record_orig_size && (offset_sum != cse_first_off))
+								if (!extra_record_blkid_off && (offset_sum != cse_first_off))
 								{	/* bring curr up to the match */
 									curr += curr_chain.next_off;
 									GET_LONGP(&curr_chain, curr);
@@ -1768,7 +1909,7 @@ tn_restart:
 									 * before this offset.
 									 */
 									prev_chain = curr_chain;
-									assert(extra_record_orig_size
+									assert(extra_record_blkid_off
 										|| (BSTAR_REC_SIZE
 											== (left_hand_offset - curr_offset)));
 									prev_chain.next_off = left_hand_offset - curr_offset;
@@ -1787,7 +1928,7 @@ tn_restart:
 									}
 									GET_LONGP(curr, &prev_chain);
 								}
-								if (extra_record_orig_size)
+								if (extra_record_blkid_off)
 								{
 									if (offset_sum != cse_first_off)
 									{	/* bring curr up to the match */
@@ -1875,11 +2016,11 @@ tn_restart:
 							if (left_hand_offset)
 							{	/* there's a new chain rec in left */
 								curr_offset = curr - buffaddr;
-								if (extra_record_orig_size
+								if (extra_record_blkid_off
 									&& (curr_offset == last_possible_left_offset))
 								{
 									assert(level_0);	/* else *-key issues */
-									cse_new->next_off = extra_record_orig_size
+									cse_new->next_off = value.len + extra_record_blkid_off
 													- next_rec_shrink1;
 								}
 								assert(!ins_chain_offset);
@@ -1916,7 +2057,7 @@ tn_restart:
 						/* first_off---------v
 						 * [blk_hdr][new rec( )]... */
 						assert(!left_hand_offset);
-						assert(0 == extra_record_orig_size);
+						assert(0 == extra_record_blkid_off);
 						assert(ins_chain_offset >= (SIZEOF(blk_hdr) + SIZEOF(rec_hdr)));
 						cse->first_off = ins_chain_offset;
 						assert(0 == cse->next_off);
@@ -1925,7 +2066,8 @@ tn_restart:
 							/* first_off---------v--------------------v
 							 * [blk_hdr][new rec( )]...[existing rec ( )] */
 							prev_next_off = cse->next_off;
-							cse->next_off = offset_sum - last_possible_left_offset - next_rec_shrink1;
+							assert(offset_sum >  curr_rec_offset);
+							cse->next_off = offset_sum - curr_rec_offset - next_rec_shrink1 + value.len;
 							assert((int)(cse->next_off + ins_chain_offset) < new_blk_size_r);
 						}
 					} else if (offset_sum <= last_possible_left_offset)
@@ -1936,8 +2078,12 @@ tn_restart:
 						/* first_off------------------v
 						 * [blk_hdr]...[existing rec ( )] */
 						assert(offset_sum >= (int)cse_first_off);
-						cse->first_off =  (block_offset)(offset_sum - last_possible_left_offset + rec_cmpc
-								+ SIZEOF(blk_hdr) - SIZEOF(off_chain));
+						assert(offset_sum > curr_rec_offset);
+						assert((curr_rec_offset == ((sm_uc_ptr_t)rp - buffaddr))
+							|| copy_extra_record
+								&& (curr_rec_offset + tmp_rsiz == ((sm_uc_ptr_t)rp - buffaddr)));
+						cse->first_off = (block_offset)(offset_sum - ((sm_uc_ptr_t)rp - buffaddr)
+								+ rec_cmpc + SIZEOF(blk_hdr));
 						assert(cse->first_off >= (SIZEOF(blk_hdr) + SIZEOF(rec_hdr)));
 					}
 					assert((ins_chain_offset + (int)cse->next_off) <=
@@ -2114,7 +2260,7 @@ tn_restart:
 					cse->write_type |= GDS_WRITE_BLOCK_SPLIT;
 				}
 				value.len = SIZEOF(block_id);
-				value.addr = (char *)&zeroes;
+				value.addr = (char *)&zeroes4byte;
 				++bh;
 				ins_chain_index = next_blk_index;
 			} else
@@ -2170,12 +2316,12 @@ tn_restart:
 				BLK_ADDR(cp1, target_key_size, unsigned char);
 				memcpy(cp1, temp_key->base, target_key_size);
 				BLK_SEG(bs_ptr, cp1, target_key_size);
-				BLK_SEG(bs_ptr, (unsigned char *)&zeroes, SIZEOF(block_id));
+				BLK_SEG(bs_ptr, (unsigned char *)&zeroes4byte, SIZEOF(block_id));
 				BLK_ADDR(next_rec_hdr, SIZEOF(rec_hdr), rec_hdr);
 				next_rec_hdr->rsiz = BSTAR_REC_SIZE;
 				SET_CMPC(next_rec_hdr, 0);
 				BLK_SEG(bs_ptr, (sm_uc_ptr_t)next_rec_hdr, SIZEOF(rec_hdr));
-				BLK_SEG(bs_ptr, (unsigned char *)&zeroes, SIZEOF(block_id));
+				BLK_SEG(bs_ptr, (unsigned char *)&zeroes4byte, SIZEOF(block_id));
 				if (0 == BLK_FINI(bs_ptr, bs1))
 				{
 					assert(CDB_STAGNATE > t_tries);
diff --git a/sr_port/gvcst_query.c b/sr_port/gvcst_query.c
index e8b0dc2..27378fb 100644
--- a/sr_port/gvcst_query.c
+++ b/sr_port/gvcst_query.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -57,13 +57,11 @@ GBLREF gv_key		*gv_currkey, *gv_altkey;
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVQUERYFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_query_ch)
 
-bool gvcst_query(void)
+boolean_t	gvcst_query(void)
 {	/* Similar to gvcst_order and gvcst_zprevious. In each case we skip over hidden subscripts as needed.
 	 *
 	 *     1  2  3  NULL                           <--- order/zprev...
@@ -75,11 +73,10 @@ bool gvcst_query(void)
 	 *     1  2  3  hidden                         <--- ... skip this guy and go to bottom/top, respectively
 	 *     1  2  3  7                                               <--- ... needs to end up here
 	 */
-	bool		found, is_hidden, sn_tpwrapped;
+	boolean_t	found, is_hidden, sn_tpwrapped;
 	boolean_t	est_first_pass;
-	char		save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key		*save_gv_currkey;
-	int		end, i;
+	gv_key		save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
+	int		i;
 	int		save_dollar_tlevel;
 
 	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
@@ -89,7 +86,7 @@ bool gvcst_query(void)
 	CHECK_HIDDEN_SUBSCRIPT_AND_RETURN(found, gv_altkey, is_hidden);
 	IF_SN_DISALLOWED_AND_NO_SPAN_IN_DB(return found);
 	assert(found && is_hidden);
-	SAVE_GV_CURRKEY;
+	SAVE_GV_CURRKEY(save_currkey);
 	if (!dollar_tlevel)
 	{
 		sn_tpwrapped = TRUE;
@@ -107,27 +104,20 @@ bool gvcst_query(void)
 		/* Replace last subscript to be the highest possible hidden subscript so another
 		 * gvcst_query2 will give us the next non-hidden subscript.
 		 */
-		end = gv_altkey->end;
-		gv_currkey->base[end - 4] = 2;
-		gv_currkey->base[end - 3] = 0xFF;
-		gv_currkey->base[end - 2] = 0xFF;
-		gv_currkey->base[end - 1] = 1;
-		gv_currkey->base[end + 0] = 0;
-		gv_currkey->base[end + 1] = 0;
-		gv_currkey->end = end + 1;
+		REPLACE_HIDDEN_SUB_TO_HIGHEST(gv_altkey, gv_currkey);	/* uses gv_altkey to modify gv_currkey */
 	}
 	if (sn_tpwrapped)
 	{
 		op_tcommit();
 		REVERT; /* remove our condition handler */
 	}
-	RESTORE_GV_CURRKEY;
+	RESTORE_GV_CURRKEY(save_currkey);
 	assert(save_dollar_tlevel == dollar_tlevel);
 #	endif
 	return found;
 }
 
-bool gvcst_query2(void)
+boolean_t	gvcst_query2(void)
 {
 	boolean_t	found, two_histories;
 	enum cdb_sc	status;
diff --git a/sr_port/gvcst_queryget.c b/sr_port/gvcst_queryget.c
index f33571b..4aca04c 100644
--- a/sr_port/gvcst_queryget.c
+++ b/sr_port/gvcst_queryget.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -63,9 +63,7 @@ GBLREF spdesc		stringpool;
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVQUERYGETFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_queryget_ch)
 
@@ -73,8 +71,7 @@ boolean_t gvcst_queryget(mval *val)
 {
 	bool		found, is_hidden, is_dummy = FALSE, sn_tpwrapped;
 	boolean_t	est_first_pass;
-	char		save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key		*save_gv_currkey;
+	gv_key		save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	int		save_dollar_tlevel;
 
 	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
@@ -87,7 +84,7 @@ boolean_t gvcst_queryget(mval *val)
 	if (!found || (!is_dummy && !is_hidden))
 		return found;
 	IF_SN_DISALLOWED_AND_NO_SPAN_IN_DB(return found);
-	SAVE_GV_CURRKEY;
+	SAVE_GV_CURRKEY(save_currkey);
 	if (!dollar_tlevel)
 	{
 		sn_tpwrapped = TRUE;
@@ -106,7 +103,7 @@ boolean_t gvcst_queryget(mval *val)
 		op_tcommit();
 		REVERT; /* remove our condition handler */
 	}
-	RESTORE_GV_CURRKEY;
+	RESTORE_GV_CURRKEY(save_currkey);
 	assert(save_dollar_tlevel == dollar_tlevel);
 #	endif
 	return found;
@@ -191,10 +188,10 @@ boolean_t gvcst_queryget2(mval *val, unsigned char *sn_ptr)
 					continue;
 				}
 				ENSURE_STP_FREE_SPACE(data_len);
-				DEBUG_ONLY (
+#				ifdef DEBUG
 				if (!save_strp)
-					save_strp = stringpool.free);
-				assert(stringpool.top - stringpool.free >= data_len);
+					save_strp = stringpool.free;
+#				endif
 				memcpy(stringpool.free, (sm_uc_ptr_t)rp + rsiz - data_len, data_len);
 				/* Assumption: t_end/tp_hist will never cause stp_gcol() call BYPASSOK */
 			}
diff --git a/sr_port/gvcst_root_search.c b/sr_port/gvcst_root_search.c
index 89008fb..ca922cb 100644
--- a/sr_port/gvcst_root_search.c
+++ b/sr_port/gvcst_root_search.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -37,6 +37,7 @@
 #include "gvcst_protos.h"	/* for gvcst_search,gvcst_root_search prototype */
 #include "get_spec.h"
 #include "collseq.h"
+#include "gtmimagename.h"
 #ifdef UNIX
 #include "error.h"
 #endif
@@ -70,7 +71,9 @@ GBLREF	uint4		t_err;
 GBLREF	boolean_t		skip_INVOKE_RESTART;
 #endif
 
+error_def(ERR_ACTCOLLMISMTCH);
 error_def(ERR_GVGETFAIL);
+error_def(ERR_NCTCOLLSPGBL);
 
 static	mstr	global_collation_mstr;
 
@@ -106,6 +109,8 @@ static	mstr	global_collation_mstr;
 	int				idx;							\
 	redo_root_search_context	*rootsrch_ctxt_ptr;					\
 												\
+	GBLREF	gv_namehead		*reorg_gv_target;					\
+												\
 	rootsrch_ctxt_ptr = &(TREF(redo_rootsrch_ctxt));					\
 	rootsrch_ctxt_ptr->t_tries = t_tries;							\
 	for (idx = 0; CDB_MAX_TRIES > idx; idx++)						\
@@ -129,9 +134,9 @@ static	mstr	global_collation_mstr;
 	}											\
 	if (mu_reorg_process)									\
 	{	/* In case gv_currkey/gv_target are out of sync. */				\
-		rootsrch_ctxt_ptr->gv_currkey = (gv_key *)&rootsrch_ctxt_ptr->currkey[0];	\
+		rootsrch_ctxt_ptr->gv_currkey = &rootsrch_ctxt_ptr->currkey[0];			\
 		MEMCPY_KEY(rootsrch_ctxt_ptr->gv_currkey, gv_currkey);				\
-		SET_GV_CURRKEY_FROM_REORG_GV_TARGET;						\
+		SET_GV_CURRKEY_FROM_GVT(reorg_gv_target);					\
 	}											\
 }
 
@@ -163,7 +168,7 @@ static	mstr	global_collation_mstr;
 
 CONDITION_HANDLER(gvcst_redo_root_search_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 
 	RESTORE_ROOTSRCH_ENTRY_STATE;
 
@@ -216,10 +221,11 @@ enum cdb_sc gvcst_root_search(boolean_t donot_restart)
 	int		altkeylen;
 	int		tmp_cmpc;
 	block_id	lcl_root;
+	uint4		oldact, newact, oldnct, oldver;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	assert((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth));
+	assert((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)));
 	SET_GV_ALTKEY_TO_GBLNAME_FROM_GV_CURRKEY;	/* set up gv_altkey to be just the gblname */
 	save_targ = gv_target;
 	/* Check if "gv_target->gvname" matches "gv_altkey->base". If not, there is a name mismatch (out-of-design situation).
@@ -311,32 +317,73 @@ enum cdb_sc gvcst_root_search(boolean_t donot_restart)
 			continue;
 		}
 	}
-	save_targ->root = lcl_root;	/* now that we know the transaction validated fine, set root block in gv_target */
 	RESET_GV_TARGET_LCL_AND_CLR_GBL(save_targ, DO_GVT_GVKEY_CHECK);
-	if (rlen > hdr_len + SIZEOF(block_id))
+	if (lcl_root)
 	{
-		assert(NULL != global_collation_mstr.addr);
-		subrec_ptr = get_spec((uchar_ptr_t)global_collation_mstr.addr,
-				      (int)(rlen - (hdr_len + SIZEOF(block_id))), COLL_SPEC);
-		if (subrec_ptr)
+		oldact = gv_target->act;
+		oldnct = gv_target->nct;
+		if (rlen > hdr_len + SIZEOF(block_id))
 		{
-			gv_target->nct = *(subrec_ptr + COLL_NCT_OFFSET);
-			gv_target->act = *(subrec_ptr + COLL_ACT_OFFSET);
-			gv_target->ver = *(subrec_ptr + COLL_VER_OFFSET);
+			assert(NULL != global_collation_mstr.addr);
+			subrec_ptr = get_spec((uchar_ptr_t)global_collation_mstr.addr,
+					      (int)(rlen - (hdr_len + SIZEOF(block_id))), COLL_SPEC);
+			if (subrec_ptr)
+			{
+				gv_target->nct = *(subrec_ptr + COLL_NCT_OFFSET);
+				gv_target->act = *(subrec_ptr + COLL_ACT_OFFSET);
+				gv_target->ver = *(subrec_ptr + COLL_VER_OFFSET);
+			} else
+			{
+				gv_target->nct = 0;
+				gv_target->act = 0;
+				gv_target->ver = 0;
+			}
+		} else if (gv_target->act_specified_in_gld)
+		{	/* Global directory specified a collation. Directory tree did not specify any non-zero collation.
+			 * So global directory prevails.
+			 */
+			gv_target->nct = 0;
+			/* gv_target->act and gv_target->ver would already have been set in COPY_ACT_FROM_GVNH_REG_TO_GVT macro */
 		} else
-		{
+		{	/* Global directory did not specify a collation. In that case, db file header defaults prevail. */
 			gv_target->nct = 0;
-			gv_target->act = 0;
-			gv_target->ver = 0;
+			gv_target->act = cs_addrs->hdr->def_coll;
+			gv_target->ver = cs_addrs->hdr->def_coll_ver;
 		}
-	} else
-	{
+		/* If DSE, a runtime global directory is created and hence $gtmgbldir is not as effective as it is for GT.M.
+		 * Hence exclude DSE from the below errors which are related to $gtmgbldir.
+		 */
+		if (!IS_DSE_IMAGE)
+		{
+			if (gv_target->nct && gv_target->nct_must_be_zero)
+			{	/* restore gv_target->act and gv_target->nct */
+				gv_target->act = oldact;
+				gv_target->nct = oldnct;
+				rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) ERR_NCTCOLLSPGBL, 4, DB_LEN_STR(gv_cur_region),
+						gv_target->gvname.var_name.len, gv_target->gvname.var_name.addr);
+			}
+			if (gv_target->act_specified_in_gld && (oldact != gv_target->act))
+			{
+				newact = gv_target->act;
+				gv_target->act = oldact;
+				gv_target->nct = oldnct;
+				rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_ACTCOLLMISMTCH, 6,
+						gv_target->gvname.var_name.len, gv_target->gvname.var_name.addr,
+						oldact, DB_LEN_STR(gv_cur_region), newact);
+			}
+		}
+	} else if (!gv_target->act_specified_in_gld)
+	{	/* If GLD did NOT specify an alternative collation sequence for this global name
+		 * but the db file header has a default collation defined, use it.
+		 */
 		gv_target->nct = 0;
+		assert(ACT_NOT_SPECIFIED != cs_addrs->hdr->def_coll);
 		gv_target->act = cs_addrs->hdr->def_coll;
 		gv_target->ver = cs_addrs->hdr->def_coll_ver;
 	}
 	if (gv_target->act)
-		act_in_gvt();
+		act_in_gvt(gv_target); /* note: this could issue COLLTYPVERSION error */
+	gv_target->root = lcl_root;	/* now that we know the transaction validated fine, set root block in gv_target */
 	assert(gv_target->act || NULL == gv_target->collseq);
 	return cdb_sc_normal;
 }
diff --git a/sr_port/gvcst_zprevious.c b/sr_port/gvcst_zprevious.c
index 040b517..d483b64 100644
--- a/sr_port/gvcst_zprevious.c
+++ b/sr_port/gvcst_zprevious.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -59,19 +59,16 @@ GBLREF int4		gv_keysize;
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
 
-error_def(ERR_DBROLLEDBACK);
 error_def(ERR_GVORDERFAIL);
-error_def(ERR_TPRETRY);
 
 DEFINE_NSB_CONDITION_HANDLER(gvcst_zprevious_ch)
 
-bool gvcst_zprevious(void)
+boolean_t	gvcst_zprevious(void)
 {	/* See gvcst_query.c */
-	bool		found, is_hidden, sn_tpwrapped;
+	boolean_t	found, is_hidden, sn_tpwrapped;
 	boolean_t	est_first_pass;
-	char		save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key		*save_gv_currkey;
-	int		end, prev, oldend;
+	gv_key		save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
+	int		prev, oldend;
 	int		save_dollar_tlevel;
 
 	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
@@ -81,7 +78,7 @@ bool gvcst_zprevious(void)
 	CHECK_HIDDEN_SUBSCRIPT_AND_RETURN(found, gv_altkey, is_hidden);
 	assert(found && is_hidden);
 	IF_SN_DISALLOWED_AND_NO_SPAN_IN_DB(return found);
-	SAVE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend);
+	SAVE_GV_CURRKEY_LAST_SUBSCRIPT(save_currkey, prev, oldend);
 	if (!dollar_tlevel)
 	{
 		sn_tpwrapped = TRUE;
@@ -99,13 +96,7 @@ bool gvcst_zprevious(void)
 		{	/* Replace last subscript to be the lowest possible hidden subscript so another
 			 * gvcst_zprevious2 will give us the previous non-hidden subscript.
 			 */
-			end = gv_altkey->end;
-			gv_currkey->base[end - 4] = 2;
-			gv_currkey->base[end - 3] = 1;
-			gv_currkey->base[end - 2] = 1;
-			gv_currkey->base[end - 1] = 0;
-			gv_currkey->base[end + 0] = 0;
-			gv_currkey->end = end;
+			REPLACE_HIDDEN_SUB_TO_LOWEST(gv_altkey, gv_currkey);	/* uses gv_altkey to modify gv_currkey */
 			/* fix up since it should only be externally counted as one $zprevious */
 			INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_zprev, (gtm_uint64_t) -1);
 			found = gvcst_zprevious2();
@@ -116,18 +107,18 @@ bool gvcst_zprevious(void)
 		op_tcommit();
 		REVERT; /* remove our condition handler */
 	}
-	RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(gv_currkey, prev, oldend);
+	RESTORE_GV_CURRKEY_LAST_SUBSCRIPT(save_currkey, prev, oldend);
 	assert(save_dollar_tlevel == dollar_tlevel);
 #	endif
 	return found;
 }
 
-bool gvcst_zprevious2(void)
+boolean_t	gvcst_zprevious2(void)
 {
 	static gv_key	*zprev_temp_key;
 	static int4	zprev_temp_keysize = 0;
 	blk_hdr_ptr_t	bp;
-	bool		found, two_histories;
+	boolean_t	found, two_histories;
 	enum cdb_sc	status;
 	rec_hdr_ptr_t	rp;
 	unsigned char	*c1, *c2, *ctop;
@@ -179,6 +170,7 @@ bool gvcst_zprevious2(void)
 				assert(zprev_temp_keysize <= gv_keysize);
 				if (zprev_temp_keysize < gv_keysize)
 				{
+					assert(DBKEYSIZE(MAX_KEY_SZ) == gv_keysize);
 					zprev_temp_keysize = gv_keysize;
 					GVKEY_INIT(zprev_temp_key, zprev_temp_keysize);
 				}
diff --git a/sr_port/gvinit.c b/sr_port/gvinit.c
index 2a3eb3e..7644dbe 100644
--- a/sr_port/gvinit.c
+++ b/sr_port/gvinit.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -23,19 +23,17 @@ GBLREF	gd_addr		*gd_header;
 void gvinit(void)
 {
 	mval	v;
-	DCL_THREADGBL_ACCESS;
 
-	SETUP_THREADGBL_ACCESS;
-	/* if gd_header is null then get the current one, and update the gd_map */
+	/* if gd_header is null then get the current one */
 	if (!gd_header)
 	{
-		SET_GD_HEADER(v);
-		SET_GD_MAP;
+		v.mvtype = MV_STR;
+		v.str.len = 0;
+		gd_header = zgbldir(&v);
 	}
-	DEBUG_ONLY(else GD_HEADER_ASSERT);
 	/* May get in here after an extended ref call OR in mupip journal recover forward processing (with
 	 * function call graph "mur_output_record/gvcst_put/gvtr_init/gvtr_db_tpwrap/op_tstart").
 	 * In either case it is possible that gv_currkey has already been set up, so dont lose any preexisting keys.
 	 */
-	GVKEYSIZE_INCREASE_IF_NEEDED(DBKEYSIZE(gd_header->regions->max_key_size));
+	GVKEYSIZE_INIT_IF_NEEDED;	/* sets "gv_keysize", "gv_currkey" and "gv_altkey" (if not already done) */
 }
diff --git a/sr_port/gvn.c b/sr_port/gvn.c
index 5ce3e76..4bfcd02 100644
--- a/sr_port/gvn.c
+++ b/sr_port/gvn.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -17,6 +17,7 @@
 #include "advancewindow.h"
 #include "fullbool.h"
 #include "show_source_line.h"
+#include "hashtab_mname.h"
 
 GBLREF	boolean_t	run_time;
 
@@ -32,8 +33,9 @@ int gvn(void)
 {
 	boolean_t	parse_status, shifting, vbar;
 	char		x;
+	int		hash_code;
 	opctype		ox;
-	oprtype		*sb1, *sb2, subscripts[MAX_GVSUBSCRIPTS];
+	oprtype		*sb1, *sb2, subscripts[MAX_GVSUBSCRIPTS + 1];
 	triple		*oldchain, *ref, *s, tmpchain, *triptr;
 	DCL_THREADGBL_ACCESS;
 
@@ -50,6 +52,9 @@ int gvn(void)
 	}
 	if ((TK_LBRACKET == TREF(window_token)) || (TK_VBAR == TREF(window_token)))
 	{
+		assert(sb2 == sb1);
+		/* set "hash_code" as the first operand so OC_GVEXTNAM has it passed in at same spot as op_gvname */
+		sb1++;
 		vbar = (TK_VBAR == TREF(window_token));
 		advancewindow();
 		if (vbar)
@@ -90,8 +95,13 @@ int gvn(void)
 	}
 	if (TK_IDENT == TREF(window_token))
 	{
+		COMPUTE_HASH_MSTR((TREF(window_ident)), hash_code);
 		if (!ox)
+		{
 			ox = OC_GVNAME;
+			*sb1++ = put_ilit((mint)hash_code);
+		} else
+			*sb2 = put_ilit((mint)hash_code);	/* fill in hash_code in the space previously set aside */
 		*sb1++ = put_str((TREF(window_ident)).addr, (TREF(window_ident)).len);
 		advancewindow();
 	} else
@@ -110,6 +120,11 @@ int gvn(void)
 			return FALSE;
 		}
 		ox = OC_GVNAKED;
+		/* pass in a dummy hash_code in case of OC_GVNAKED. We need this so op_gvname_fast, op_gvextnam_fast and
+		 * op_gvnaked_fast have the same call interface. op_savgvn.c relies on this to replace OC_GVNAME, OC_GVEXTNAM
+		 * or OC_GVNAKED opcodes with a OC_SAVGVN opcode.
+		 */
+		*sb1++ = put_ilit((mint)0);
 	}
 	if (TK_LPAREN == TREF(window_token))
 	{
diff --git a/sr_port/gvname_env_restore.c b/sr_port/gvname_env_restore.c
index 0ff3006..fd595b3 100644
--- a/sr_port/gvname_env_restore.c
+++ b/sr_port/gvname_env_restore.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,6 +11,8 @@
 
 #include "mdef.h"
 
+#include <stddef.h>		/* for offsetof macro in VMS */
+
 #include "gdsroot.h"
 #include "gdskill.h"
 #include "gtm_facility.h"
@@ -39,22 +41,25 @@ GBLREF sgm_info         *sgm_info_ptr;
 void gvname_env_restore(gvname_info *curr_gvname_info)
 {
 	DEBUG_ONLY(boolean_t	is_bg_or_mm;)
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	gv_target = curr_gvname_info->s_gv_target;
 	gv_cur_region = curr_gvname_info->s_gv_cur_region;
-	DEBUG_ONLY(is_bg_or_mm = (dba_bg == gv_cur_region->dyn.addr->acc_meth || dba_mm == gv_cur_region->dyn.addr->acc_meth);)
+	DEBUG_ONLY(is_bg_or_mm = (dba_bg == REG_ACC_METH(gv_cur_region) || dba_mm == REG_ACC_METH(gv_cur_region));)
 	cs_addrs = curr_gvname_info->s_cs_addrs;
-	assert((is_bg_or_mm && cs_addrs) || dba_cm == gv_cur_region->dyn.addr->acc_meth ||
-		dba_usr == gv_cur_region->dyn.addr->acc_meth);
-	if (cs_addrs) /* cs_addrs might be NULL for dba_cm/dba_usr region */
+	assert((is_bg_or_mm && cs_addrs)
+		|| (dba_cm == REG_ACC_METH(gv_cur_region)) || (dba_usr == REG_ACC_METH(gv_cur_region)));
+	if (NULL != cs_addrs) /* cs_addrs might be NULL for dba_cm/dba_usr region */
 		cs_data = cs_addrs->hdr;
-	assert(gv_currkey->top <= curr_gvname_info->s_gv_currkey->top);
-	gv_currkey->end = curr_gvname_info->s_gv_currkey->end;
-	gv_currkey->prev = curr_gvname_info->s_gv_currkey->prev;
-	memcpy(gv_currkey->base, curr_gvname_info->s_gv_currkey->base, curr_gvname_info->s_gv_currkey->end + 1);
+	COPY_KEY(gv_currkey, curr_gvname_info->s_gv_currkey);
 	sgm_info_ptr = curr_gvname_info->s_sgm_info_ptr;
 	assert((is_bg_or_mm && ((dollar_tlevel && sgm_info_ptr) || (!dollar_tlevel && !sgm_info_ptr)))
-		|| (dba_cm == gv_cur_region->dyn.addr->acc_meth) || (dba_usr == gv_cur_region->dyn.addr->acc_meth));
+		|| (dba_cm == REG_ACC_METH(gv_cur_region)) || (dba_usr == REG_ACC_METH(gv_cur_region)));
 	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
-
+	TREF(gd_targ_gvnh_reg) = curr_gvname_info->s_gd_targ_gvnh_reg;
+	TREF(gd_targ_map) = curr_gvname_info->s_gd_targ_map;
+	TREF(gd_targ_addr) = curr_gvname_info->s_gd_targ_addr;
+	assert((gv_cur_region >= &(TREF(gd_targ_addr))->regions[0])
+			&& (gv_cur_region < &(TREF(gd_targ_addr))->regions[(TREF(gd_targ_addr))->n_regions]));
 }
diff --git a/sr_port/gvname_env_save.c b/sr_port/gvname_env_save.c
index 6ae7cc4..82b9d34 100644
--- a/sr_port/gvname_env_save.c
+++ b/sr_port/gvname_env_save.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,6 +11,8 @@
 
 #include "mdef.h"
 
+#include <stddef.h>		/* for offsetof macro in VMS */
+
 #include "gdsroot.h"
 #include "gdskill.h"
 #include "gtm_facility.h"
@@ -35,22 +37,27 @@ GBLREF sgmnt_data_ptr_t cs_data;
 GBLREF uint4		dollar_tlevel;
 GBLREF sgm_info         *sgm_info_ptr;
 
-void gvname_env_save(gvname_info *  curr_gvname_info)
+void gvname_env_save(gvname_info *curr_gvname_info)
 {
 	DEBUG_ONLY(boolean_t	is_bg_or_mm;)
+	DEBUG_ONLY(gd_addr	*addr;)
+	DCL_THREADGBL_ACCESS;
 
-	DEBUG_ONLY(is_bg_or_mm = (dba_mm == gv_cur_region->dyn.addr->acc_meth || dba_bg == gv_cur_region->dyn.addr->acc_meth);)
+	SETUP_THREADGBL_ACCESS;
+	DEBUG_ONLY(is_bg_or_mm = (dba_mm == REG_ACC_METH(gv_cur_region) || dba_bg == REG_ACC_METH(gv_cur_region));)
 	curr_gvname_info->s_gv_target = gv_target;
 	curr_gvname_info->s_gv_cur_region = gv_cur_region;
-	assert((is_bg_or_mm && cs_addrs->hdr == cs_data) || dba_cm == gv_cur_region->dyn.addr->acc_meth ||
-		dba_usr == gv_cur_region->dyn.addr->acc_meth);
+	assert((is_bg_or_mm && cs_addrs->hdr == cs_data)
+		|| (dba_cm == REG_ACC_METH(gv_cur_region)) || (dba_usr == REG_ACC_METH(gv_cur_region)));
 	curr_gvname_info->s_cs_addrs = cs_addrs;
 	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
-	assert(gv_currkey->top <= curr_gvname_info->s_gv_currkey->top);
-	curr_gvname_info->s_gv_currkey->end = gv_currkey->end;
-	curr_gvname_info->s_gv_currkey->prev = gv_currkey->prev;
-	memcpy(curr_gvname_info->s_gv_currkey->base, gv_currkey->base, gv_currkey->end + 1);
+	COPY_KEY(curr_gvname_info->s_gv_currkey, gv_currkey);
 	curr_gvname_info->s_sgm_info_ptr = sgm_info_ptr;
-	assert((is_bg_or_mm && ((dollar_tlevel && sgm_info_ptr) || (!dollar_tlevel && !sgm_info_ptr))) ||
-	       dba_cm == gv_cur_region->dyn.addr->acc_meth || dba_usr == gv_cur_region->dyn.addr->acc_meth);
+	assert((is_bg_or_mm && ((dollar_tlevel && sgm_info_ptr) || (!dollar_tlevel && !sgm_info_ptr)))
+		|| (dba_cm == REG_ACC_METH(gv_cur_region)) || (dba_usr == REG_ACC_METH(gv_cur_region)));
+	DEBUG_ONLY(addr = TREF(gd_targ_addr);)
+	assert((gv_cur_region >= &addr->regions[0]) && (gv_cur_region < &addr->regions[addr->n_regions]));
+	curr_gvname_info->s_gd_targ_gvnh_reg = TREF(gd_targ_gvnh_reg);
+	curr_gvname_info->s_gd_targ_map = TREF(gd_targ_map);
+	curr_gvname_info->s_gd_targ_addr = TREF(gd_targ_addr);
 }
diff --git a/sr_port/gvname_info.h b/sr_port/gvname_info.h
index ce7dd5d..9ce5527 100644
--- a/sr_port/gvname_info.h
+++ b/sr_port/gvname_info.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,17 +18,23 @@
  * Also note that it is not easy to call op_gvname with variable arguments again and again.
  */
 #ifndef MERGE_GLOBAL_DEFINED
+
 typedef struct gvname_info_struct {
-        gv_key           *s_gv_currkey;
-        gv_namehead      *s_gv_target;
-        gd_region        *s_gv_cur_region;
-        sgmnt_addrs      *s_cs_addrs;
-	sgm_info         *s_sgm_info_ptr;
+	gv_key		*s_gv_currkey;
+	gv_namehead	*s_gv_target;
+	gd_region	*s_gv_cur_region;
+	sgmnt_addrs	*s_cs_addrs;
+	sgm_info	*s_sgm_info_ptr;
+	gvnh_reg_t	*s_gd_targ_gvnh_reg;
+	gd_binding	*s_gd_targ_map;
+	gd_addr		*s_gd_targ_addr;
+	int		gvkey_nsubs;	/* # of subscripts in s_gv_currkey. Maintained only in case of MERGE LCL=^GBL */
 } gvname_info;
-typedef gvname_info     *gvname_info_ptr;
+
+typedef gvname_info	*gvname_info_ptr;
 
 /* Function Prototypes for M global variable functions of MERGE */
-void 		gvname_env_restore(gvname_info *curr_gvname_info);
-void	 	gvname_env_save(gvname_info *  curr_gvname_info);
+void		gvname_env_restore(gvname_info *curr_gvname_info);
+void		gvname_env_save(gvname_info *  curr_gvname_info);
 #define MERGE_GLOBAL_DEFINED
 #endif
diff --git a/sr_port/gvnh_spanreg.h b/sr_port/gvnh_spanreg.h
new file mode 100644
index 0000000..d2ab160
--- /dev/null
+++ b/sr_port/gvnh_spanreg.h
@@ -0,0 +1,33 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#ifndef GVNH_SPANREG_INCLUDED
+#define GVNH_SPANREG_INCLUDED
+
+#include "view.h"	/* needed for "viewparm" */
+
+#define	ADD_GVT_TO_VIEW_NOISOLATION_LIST(GVT, PARMBLK)					\
+{											\
+	noisolation_element	*gvnh_entry;						\
+											\
+	GBLREF	buddy_list	*noisolation_buddy_list;				\
+											\
+	gvnh_entry = (noisolation_element *)get_new_element(noisolation_buddy_list, 1);	\
+	gvnh_entry->gvnh = GVT;								\
+	gvnh_entry->next = PARMBLK->ni_list.gvnh_list;					\
+	PARMBLK->ni_list.gvnh_list = gvnh_entry;					\
+}
+
+void gvnh_spanreg_init(gvnh_reg_t *gvnh_reg, gd_addr *addr, gd_binding *gvmap_start);
+void gvnh_spanreg_subs_gvt_init(gvnh_reg_t *gvnh_reg, gd_addr *addr, viewparm *parmblk);
+boolean_t gvnh_spanreg_ismapped(gvnh_reg_t *gvnh_reg, gd_addr *addr, gd_region *reg);
+
+#endif /* GVNH_SPANREG_INCLUDED */
diff --git a/sr_port/gvnh_spanreg_init.c b/sr_port/gvnh_spanreg_init.c
new file mode 100644
index 0000000..04c1bf3
--- /dev/null
+++ b/sr_port/gvnh_spanreg_init.c
@@ -0,0 +1,130 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"
+#include "targ_alloc.h"
+#include "gvnh_spanreg.h"
+#include "gvcst_protos.h"
+
+/* Initialize gvnh_reg->gvspan if input global spans multiple regions.
+ * "gvnh_reg" is the gvnh_reg_t structure that has already been allocated for this global name.
+ * "addr" is the corresponding gd_addr (global directory structure) whose hashtable contains "gvnh_reg"
+ * "gvmap_start" is the map entry in the gld file where the unsubscripted global name maps to.
+ */
+void gvnh_spanreg_init(gvnh_reg_t *gvnh_reg, gd_addr *addr, gd_binding *gvmap_start)
+{
+	gvnh_spanreg_t	*gvspan;
+	gd_binding	*gvmap_end, *gdmap_start;
+	mident		*gvname;
+	char		*gvent_name, *c, *c_top;
+	int		gvent_len, res, reg_index, gvspan_size;
+	unsigned int	min_reg_index, max_reg_index;
+	gd_region	*reg, *reg_start;
+#	ifdef DEBUG
+	gd_region	*reg_top;
+	gd_binding	*gdmap_top;
+	trans_num	gd_targ_tn, *tn_array;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	/* At this point "gvnh_reg->gd_reg" and "gvnh_reg->gvt" have already been initialized */
+	/* First check if global spans multiple regions */
+	gvname = &gvnh_reg->gvt->gvname.var_name;
+	gvent_len = gvname->len;
+	gvent_name = gvname->addr;
+	/* Assert that gvname is not subscripted (i.e. does not contain null bytes) */
+#	ifdef DEBUG
+	c = gvent_name;
+	c_top = gvent_name + gvent_len;
+	for ( ; c < c_top; c++)
+		assert(KEY_DELIMITER != *c);
+#	endif
+	gvmap_end = gvmap_start;
+	if (!TREF(no_spangbls))
+	{
+		reg_start = addr->regions;
+		min_reg_index = addr->n_regions;	/* impossible value of index into addr->regions[] array */
+		DEBUG_ONLY(reg_top = reg_start + min_reg_index;)
+		max_reg_index = 0;
+		DEBUG_ONLY(INCREMENT_GD_TARG_TN(gd_targ_tn);)	/* takes a copy of incremented "TREF(gd_targ_tn)"
+								 * into local variable "gd_targ_tn" */
+		DEBUG_ONLY(tn_array = TREF(gd_targ_reg_array);)	/* could be NULL if no spanning globals were seen till now */
+		for ( ; ; gvmap_end++)
+		{
+			res = memcmp(gvent_name, &(gvmap_end->gvkey.addr[0]), gvent_len);
+			assert(0 >= res);
+			reg = gvmap_end->reg.addr;
+			GET_REG_INDEX(addr, reg_start, reg, reg_index);	/* sets "reg_index" */
+#			ifdef DEBUG
+			if (NULL != tn_array)
+				tn_array[reg_index] = gd_targ_tn;
+#			endif
+			if (min_reg_index > reg_index)
+				min_reg_index = reg_index;
+			if (max_reg_index < reg_index)
+				max_reg_index = reg_index;
+			assert((0 != res) || (gvent_len <= gvmap_end->gvname_len));
+			if ((0 > res) || ((0 == res) && (gvent_len < gvmap_end->gvname_len)))
+				break;
+		}
+	}
+	/* else : no_spangbls is TRUE which means this process does not need to worry about globals spanning multiple regions */
+	if (gvmap_end == gvmap_start)
+	{	/* global does not span multiple regions. */
+		gvnh_reg->gvspan = NULL;
+		return;
+	}
+	TREF(spangbl_seen) = TRUE;	/* we found at least one global that spans multiple regions */
+	/* Allocate and initialize a gvnh_spanreg_t structure and link it to gvnh_reg.
+	 * Note gvt_array[] size is max_reg_index - min_reg_index + 1.
+	 */
+	gvspan_size = SIZEOF(gvspan->gvt_array[0]) * (max_reg_index - min_reg_index);
+	gvspan = (gvnh_spanreg_t *)malloc(SIZEOF(gvnh_spanreg_t) + gvspan_size);
+	gvspan->min_reg_index = min_reg_index;
+	gvspan->max_reg_index = max_reg_index;
+	gdmap_start = addr->maps;
+	DEBUG_ONLY(gdmap_top = gdmap_start + addr->n_maps;)
+	assert((gvmap_start >= gdmap_start) && (gvmap_start < gdmap_top));
+	assert((gvmap_end >= gdmap_start) && (gvmap_end < gdmap_top));
+	gvspan->start_map_index = gvmap_start - gdmap_start;
+	gvspan->end_map_index = gvmap_end - gdmap_start;
+	/* Initialize the array of gv_targets (corresponding to each spanned region) to NULL initially.
+	 * As and when each region is referenced, the gv_targets will get allocated.
+	 */
+	memset(&gvspan->gvt_array[0], 0, gvspan_size + SIZEOF(gvspan->gvt_array[0]));
+#	ifdef DEBUG
+		/* Initialize the region slots that are not spanned to by this global with a distinct "invalid" value */
+		assert(tn_array[min_reg_index] == gd_targ_tn);
+		assert(tn_array[max_reg_index] == gd_targ_tn);
+		for (reg_index = min_reg_index; reg_index <= max_reg_index; reg_index++)
+		{
+			if (tn_array[reg_index] != gd_targ_tn)
+				gvspan->gvt_array[reg_index - min_reg_index] = INVALID_GV_TARGET;
+		}
+#	endif
+	gvnh_reg->gvspan = gvspan;
+	/* Initialize gvt for the region that the unsubscripted global name maps to */
+	reg = gvmap_start->reg.addr;
+	GET_REG_INDEX(addr, reg_start, reg, reg_index);	/* sets "reg_index" */
+	assert((reg_index >= min_reg_index) && (reg_index <= max_reg_index));
+	assert(INVALID_GV_TARGET != gvspan->gvt_array[reg_index - min_reg_index]);	/* Assert that this region is indeed
+											 * mapped to by the spanning global */
+	gvspan->gvt_array[reg_index - min_reg_index] = gvnh_reg->gvt;
+	return;
+}
diff --git a/sr_port/gvnh_spanreg_ismapped.c b/sr_port/gvnh_spanreg_ismapped.c
new file mode 100644
index 0000000..205394e
--- /dev/null
+++ b/sr_port/gvnh_spanreg_ismapped.c
@@ -0,0 +1,41 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"
+#include "gvnh_spanreg.h"
+
+/* Check if "reg" is one of the regions that the global corresponding to "gvnh_reg" maps to in the gld file pointed to by "addr" */
+boolean_t gvnh_spanreg_ismapped(gvnh_reg_t *gvnh_reg, gd_addr *addr, gd_region *reg)
+{
+	gvnh_spanreg_t	*gvspan;
+	gd_binding	*map, *map_top;
+
+	gvspan = gvnh_reg->gvspan;
+	assert(NULL != gvspan);
+	assert(gvspan->start_map_index > 0);
+	assert(gvspan->end_map_index > 0);
+	assert(gvspan->start_map_index < addr->n_maps);
+	assert(gvspan->end_map_index < addr->n_maps);
+	map = &addr->maps[gvspan->start_map_index];
+	map_top = &addr->maps[gvspan->end_map_index];
+	assert(map < map_top);
+	for ( ; map <= map_top; map++)
+		if (reg == map->reg.addr)
+			return TRUE;
+	return FALSE;
+}
diff --git a/sr_port/gvnh_spanreg_subs_gvt_init.c b/sr_port/gvnh_spanreg_subs_gvt_init.c
new file mode 100644
index 0000000..5a1d199
--- /dev/null
+++ b/sr_port/gvnh_spanreg_subs_gvt_init.c
@@ -0,0 +1,104 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"
+#include "targ_alloc.h"
+#include "gvnh_spanreg.h"
+#include "buddy_list.h"
+#include "dpgbldir.h"
+#include "change_reg.h"
+#include "gvcst_protos.h"	/* for gvcst_root_search prototype */
+#include "process_gvt_pending_list.h"	/* for "is_gvt_in_pending_list" prototype used in ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN */
+#include "gtmimagename.h"
+
+GBLREF	gd_region			*gv_cur_region;
+
+/* This assumes the input global (whose gvnh_reg_t structure is passed in as "gvnh_reg") spans multiple regions.
+ * This function initializes gvnh_reg->gvspan.gvt_array[] by allocating ALL the gv_targets (if not already done)
+ * 	corresponding to ALL regions that are spanned by subscripted references of the parent global name.
+ * "gvnh_reg" is the gvnh_reg_t structure that has already been allocated for this global name.
+ * "addr" is the corresponding gd_addr (global directory structure) whose hashtable contains "gvnh_reg"
+ * If "parmblk" is non-NULL, this function is being invoked only by view_arg_convert (to set NOISOLATION status for
+ *	all possible gv_targets for a given global name). And hence needs to allocate all the gvt_array[] entries
+ *	even if the region is not open.
+ * If "parmblk" is NULL, initialize gv_target->root as well (by opening the region if needed and doing a gvcst_root_search).
+ */
+void gvnh_spanreg_subs_gvt_init(gvnh_reg_t *gvnh_reg, gd_addr *addr, viewparm *parmblk)
+{
+	gd_binding		*gd_map_start, *map, *map_top;
+	gd_region		*reg, *gd_reg_start, *save_reg;
+	gv_namehead		*gvt, *name_gvt;
+	gvnh_spanreg_t		*gvspan;
+	int			min_reg_index, reg_index;
+	DEBUG_ONLY(
+		gd_binding	*gd_map_top;
+	)
+
+	assert(NULL != gvnh_reg->gvt);
+	gvspan = gvnh_reg->gvspan;
+	/* Determine what regions are spanned across by this global and allocate gv_targets only for those. */
+	gd_map_start = addr->maps;
+	map = gd_map_start + gvspan->start_map_index;
+	map_top = gd_map_start + gvspan->end_map_index + 1;
+	DEBUG_ONLY(gd_map_top = &addr->maps[addr->n_maps]);
+	assert(map_top <= gd_map_top);
+	gd_reg_start = &addr->regions[0];
+	min_reg_index = gvspan->min_reg_index;
+	name_gvt = gvnh_reg->gvt;
+	save_reg = gv_cur_region;
+	for ( ; map < map_top; map++)
+	{
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert(reg_index >= min_reg_index);
+		assert(reg_index <= gvspan->max_reg_index);
+		reg_index -= min_reg_index;
+		gvt = gvspan->gvt_array[reg_index];
+		assert(INVALID_GV_TARGET != gvt);	/* Assert that this region is indeed mapped to by the spanning global */
+		if (NULL == gvt)
+		{	/* If called from VIEW "NOISOLATION" (i.e. parmblk is non-NULL), do NOT open the region here.
+			 * as we are going to add it to the gvt_pending_list anyways.
+			 */
+			if ((NULL == parmblk) && !reg->open)
+				gv_init_reg(reg);
+			gvt = (gv_namehead *)targ_alloc(reg->max_key_size, &name_gvt->gvname, reg);
+			COPY_ACT_FROM_GVNH_REG_TO_GVT(gvnh_reg, gvt, reg);
+			/* See comment in GVNH_REG_INIT macro for why the below assignment is
+			 * placed AFTER all error conditions (in above macro) have passed.
+			 */
+			gvspan->gvt_array[reg_index] = gvt;
+		}
+		if (NULL != parmblk)
+		{
+			if (NULL != name_gvt)
+				ADD_GVT_TO_VIEW_NOISOLATION_LIST(gvt, parmblk);
+			/* else : view_arg_convert would have done the ADD_GVT_TO_VIEW_NOISOLATION_LIST call already */
+			/* Before adding to the pending list, check if this gvt is already there
+			 * (due to a previous VIEW "NOISOLATION" command. If so skip the addition.
+			 */
+			if (NULL == is_gvt_in_pending_list(gvt))
+				ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN(reg, &gvspan->gvt_array[reg_index], NULL);
+		} else
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs/gv_target->root */
+	}
+	if (NULL == parmblk)
+	{
+		gv_cur_region = save_reg;
+		change_reg();	/* restore gv_cur_region to what it was at function entry */
+	}
+}
diff --git a/sr_port/gvsub2str.c b/sr_port/gvsub2str.c
index 5fde359..6a17b36 100644
--- a/sr_port/gvsub2str.c
+++ b/sr_port/gvsub2str.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -27,8 +27,8 @@
 #include "copy.h"
 #include "collseq.h"
 #include "do_xform.h"
-#include "gvstrsub.h"
 #include "gvsub2str.h"
+#include "zshow.h"
 
 #define LARGE_EXP	10000
 
@@ -44,7 +44,7 @@ LITREF	unsigned short	dpos[], dneg[];
  *	sub	- input string in subscript format
  *	targ	- output string buffer
  *	xlat_flg- translate flag.
- *		  If true convert string to MUMPS format
+ *		  If true convert string to MUMPS format (aka ZWRITE format)
  * Return:
  *	(pointer to the last char.
  *	converted in the targ string) + 1.
@@ -52,11 +52,11 @@ LITREF	unsigned short	dpos[], dneg[];
  */
 unsigned char *gvsub2str(unsigned char *sub, unsigned char *targ, boolean_t xlat_flg)
 {
-	unsigned char	buf1[MAX_KEY_SZ + 1], ch, *ptr, trail_ch;
+	unsigned char	buf[MAX_KEY_SZ + 1], buf1[MAX_KEY_SZ + 1], ch, *ptr, trail_ch, *str;
 	unsigned short	*tbl_ptr;
 	int		num, rev_num, trail_zero;
 	span_subs	*subs_ptr;
-	int		expon, in_length, length, tmp;
+	int		expon, in_length, targ_len;
 	mstr		mstr_ch, mstr_targ;
 	DCL_THREADGBL_ACCESS;
 
@@ -64,32 +64,43 @@ unsigned char *gvsub2str(unsigned char *sub, unsigned char *targ, boolean_t xlat
 	ch = *sub++;
 	if (STR_SUB_PREFIX == ch || (SUBSCRIPT_STDCOL_NULL == ch && KEY_DELIMITER == *sub))
 	{	/* If this is a string */
-		if (xlat_flg)
-			return gvstrsub(sub, targ);
-		else
+		in_length = 0;
+		ptr = (xlat_flg ? buf : targ);
+		while ((ch = *sub++))
+		{	/* Copy string to ptr, xlating each char */
+			in_length++;
+			if (STR_SUB_ESCAPE == ch)	/* if this is an escape, demote next char */
+				ch = (*sub++ - 1);
+			*ptr++ = ch;
+		}
+		if (TREF(transform) && gv_target && gv_target->collseq)
 		{
-			in_length = 0;
-			ptr = targ;
-			while ((ch = *sub++))
-			{	/* Copy string to targ, xlating each char */
-				in_length++;
-				if (STR_SUB_ESCAPE == ch)
-				/* if this is an escape, demote next char */
-					ch = (*sub++ - 1);
-				*targ++ = ch;
-			}
-			if (TREF(transform) && gv_target && gv_target->collseq)
+			mstr_ch.len = in_length;
+			mstr_ch.addr = (char *)(xlat_flg ? buf : targ);
+			mstr_targ.len = SIZEOF(buf1);
+			mstr_targ.addr = (char *)buf1;
+			do_xform(gv_target->collseq, XBACK, &mstr_ch, &mstr_targ, &targ_len);
+			if (!xlat_flg)
 			{
-				mstr_ch.len = in_length;
-				mstr_ch.addr = (char *)ptr;
-				mstr_targ.len = SIZEOF(buf1);
-				mstr_targ.addr = (char *)buf1;
-				do_xform(gv_target->collseq, XBACK, &mstr_ch, &mstr_targ, &length);
-				memcpy(ptr, mstr_targ.addr, length); /* mstr_targ.addr is used just in case it is
-								      * reallocated by the XBACK routine
-								      */
-				targ = ptr + length;
+				memcpy(targ, mstr_targ.addr, targ_len);	/* mstr_targ.addr is used just in case it is
+									 * reallocated by the XBACK routine.
+									 */
+				targ = targ + targ_len;
+			} else
+			{
+				in_length = targ_len;
+				ptr = (unsigned char *)mstr_targ.addr;	/* mstr_targ.addr is used just in case it is
+									 * reallocated in the XBACK routine.
+									 */
 			}
+		} else if (xlat_flg)
+			ptr = &buf[0];
+		else
+			targ = ptr;
+		if (xlat_flg)
+		{
+			format2zwr((sm_uc_ptr_t)ptr, in_length, targ, &targ_len);
+			targ = targ + targ_len;
 		}
 	} else
 	{	/* Number */
@@ -179,5 +190,5 @@ unsigned char *gvsub2str(unsigned char *sub, unsigned char *targ, boolean_t xlat
 					*targ++ = '0';
 		}
 	}
-	return (targ);
+	return targ;
 }
diff --git a/sr_port/gvt_hashtab.c b/sr_port/gvt_hashtab.c
new file mode 100644
index 0000000..ed81740
--- /dev/null
+++ b/sr_port/gvt_hashtab.c
@@ -0,0 +1,54 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "dpgbldir.h"
+#include "process_gvt_pending_list.h"
+#include "hashtab_mname.h"
+#include "targ_alloc.h"
+#include "gvt_hashtab.h"
+
+GBLREF	gv_namehead	*gv_target_list;
+
+void gvt_hashtab_init(sgmnt_addrs *csa)
+{
+	gv_namehead	*gvtarg;
+	boolean_t	added;
+	ht_ent_mname	*stayent;
+
+	assert(NULL == csa->gvt_hashtab);
+	/* This is the first time a duplicate region for the same database file is being opened.
+	 * Since two regions point to the same physical file, start maintaining a list of all global variable
+	 * names whose gv_targets have already been allocated on behalf of the current database file (not including
+	 * the region that is currently being opened for which gvt->gd_csa will still be NULL).
+	 * Future targ_allocs will check this list before they allocate (to avoid duplicate allocations).
+	 */
+	csa->gvt_hashtab = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
+	init_hashtab_mname(csa->gvt_hashtab, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
+	assert(1 == csa->regcnt);
+	for (gvtarg = gv_target_list; NULL != gvtarg; gvtarg = gvtarg->next_gvnh)
+	{	/* There is one region that is "open" and has gv_targets allocated for this "csa".
+		 * Add those gv_targets into the hashtable first.
+		 */
+		if (gvtarg->gd_csa != csa)
+			continue;
+		if (DIR_ROOT == gvtarg->root)
+			continue;	/* gvt is csa->dir_tree and does not correspond to a global name */
+		added = add_hashtab_mname(csa->gvt_hashtab, &gvtarg->gvname, gvtarg, &stayent);
+		assert(added && (1 == gvtarg->regcnt));
+	}
+}
diff --git a/sr_unix/dbopen_ch.c b/sr_port/gvt_hashtab.h
similarity index 70%
rename from sr_unix/dbopen_ch.c
rename to sr_port/gvt_hashtab.h
index 3b19bcb..919e47a 100644
--- a/sr_unix/dbopen_ch.c
+++ b/sr_port/gvt_hashtab.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,11 +9,10 @@
  *								*
  ****************************************************************/
 
-#include "mdef.h"
-#include "error.h"
+#ifndef GVT_HASHTAB_DEFINED
 
-CONDITION_HANDLER(dbopen_ch)
-{
-  START_CH;
-  CONTINUE;
-}
+void gvt_hashtab_init(sgmnt_addrs *csa);
+
+#define GVT_HASHTAB_DEFINED
+
+#endif
diff --git a/sr_port/gvzwr_fini.c b/sr_port/gvzwr_fini.c
index 44890b5..c1ed39e 100644
--- a/sr_port/gvzwr_fini.c
+++ b/sr_port/gvzwr_fini.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -28,6 +28,7 @@
 #include "sgnl.h"
 #include "gvzwrite_clnup.h"
 #include "mvalconv.h"
+#include "gtmimagename.h"
 
 GBLDEF zshow_out	*zwr_output;
 
@@ -37,8 +38,7 @@ GBLREF gv_key		*gv_currkey;
 GBLREF gd_region	*gv_cur_region;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF gvzwrite_datablk	*gvzwrite_block;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
+GBLREF gd_addr		*gd_header;
 
 error_def(ERR_GVNAKED);
 
@@ -47,14 +47,13 @@ void gvzwr_fini(zshow_out *out, int pat)
 	char 		m[SIZEOF(mident_fixed)];
 	mval 		local, data;
 	gv_key		*old;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	if (!gv_currkey)
 		gvinit();
-
 	ESTABLISH(gvzwrite_ch);
-
 	zwr_output = out;
 	assert(INVALID_GV_TARGET == reset_gv_target);
 	reset_gv_target = gv_target;
@@ -64,8 +63,6 @@ void gvzwr_fini(zshow_out *out, int pat)
 	old = (gv_key *)malloc(SIZEOF(gv_key) + gv_currkey->end);
 	gvzwrite_block->old_key = (unsigned char *)old;
 	memcpy(gvzwrite_block->old_key, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);
-	gvzwrite_block->old_map = gd_map;
-	gvzwrite_block->old_map_top = gd_map_top;
 	gvzwrite_block->gv_last_subsc_null = TREF(gv_last_subsc_null);
 	gvzwrite_block->gv_some_subsc_null = TREF(gv_some_subsc_null);
 	if (!pat)
@@ -84,14 +81,18 @@ void gvzwr_fini(zshow_out *out, int pat)
 				gvzwrite_block->fixed = (gvzwrite_block->fixed ? TRUE : FALSE);
 				gvzwr_var(MV_FORCE_INTD(&data), 0);
 			}
-		} else               /* Old (naked) reference. Keep previous gv_target reference */
+		} else	/* Old (naked) reference. Keep previous gv_target reference */
 		{
 			if (gv_currkey->prev == 0)
-				rts_error(VARLSTCNT(1) ERR_GVNAKED);
-
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GVNAKED);
 			gv_currkey->end = gv_currkey->prev;
-			gv_currkey->base[ gv_currkey->end ] = 0;
+			gv_currkey->base[gv_currkey->end] = 0;
 			gv_currkey->prev = 0;
+			/* If gvnh_reg corresponds to a spanning global, then determine
+			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+			 */
+			gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname in previous call */
+			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey);
 			op_gvdata(&data);
 			if (!(MV_FORCE_INTD(&data)))
 				sgnl_gvundef();
diff --git a/sr_port/gvzwr_var.c b/sr_port/gvzwr_var.c
index 4ee06b6..8c2ef98 100644
--- a/sr_port/gvzwr_var.c
+++ b/sr_port/gvzwr_var.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,6 +24,7 @@
 #include "mvalconv.h"
 #include "follow.h"
 #include "gtm_string.h"
+#include "gtmimagename.h"
 
 #define eb_less(u, v)	(numcmp(u, v) < 0)
 
@@ -31,6 +32,8 @@ GBLREF gv_key		*gv_currkey;
 GBLREF gvzwrite_datablk *gvzwrite_block;
 GBLREF int4		outofband;
 GBLREF gd_region	*gv_cur_region;
+GBLREF gd_addr		*gd_header;
+
 LITREF mval		literal_null;
 
 void gvzwr_var(uint4 data, int4 n)
@@ -42,6 +45,7 @@ void gvzwr_var(uint4 data, int4 n)
 	char		seen_null;
 	zwr_sub_lst	*zwr_sub;
 	int		loop_condition = 1;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -60,9 +64,14 @@ void gvzwr_var(uint4 data, int4 n)
 	assert(1 < data);
 	end = gv_currkey->end;
 	prev = gv_currkey->prev;
+	gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname call done in gvzwr_fini before call to gvzwr_var */
 	if ((n < gvzwrite_block->subsc_count) && (ZWRITE_VAL == zwr_sub->subsc_list[n].subsc_type))
 	{
-		mval2subsc(zwr_sub->subsc_list[n].first, gv_currkey);
+		mval2subsc(zwr_sub->subsc_list[n].first, gv_currkey, gv_cur_region->std_null_coll);
+		/* If gvnh_reg corresponds to a spanning global, then determine
+		 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+		 */
+		GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey);
 		op_gvdata(&subdata);
 		if (MV_FORCE_INTD(&subdata) && ((10 != (int4)MV_FORCE_INTD(&subdata)) || n < gvzwrite_block->subsc_count - 1))
 		{
@@ -79,13 +88,17 @@ void gvzwr_var(uint4 data, int4 n)
 		    && ZWRITE_PATTERN != zwr_sub->subsc_list[n].subsc_type)
 		{
 			mv = *zwr_sub->subsc_list[n].first;
-			mval2subsc(&mv, gv_currkey);
+			mval2subsc(&mv, gv_currkey, gv_cur_region->std_null_coll);
 			if ((mv.mvtype & MV_STR) && !mv.str.len)
 				seen_null = 1;
+			/* If gvnh_reg corresponds to a spanning global, then determine
+			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+			 */
+			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey);
 			op_gvdata(&subdata);
 		} else
 		{
-			mval2subsc((mval *)&literal_null, gv_currkey);
+			mval2subsc((mval *)&literal_null, gv_currkey, gv_cur_region->std_null_coll);
 			TREF(gv_last_subsc_null) = TRUE;
 			if (0 == gv_cur_region->std_null_coll)
 			{
@@ -108,10 +121,7 @@ void gvzwr_var(uint4 data, int4 n)
 					op_gvdata(&subdata);
 				}
 			} else /* for standard null collation */
-			{
-				/* determine whether $data(^gbl("") == 1 or 11,
-				   if yes, first process that
-				*/
+			{	/* determine whether $data(^gbl("") == 1 or 11, if yes, first process that */
 				if (NEVER == gv_cur_region->null_subs)
 				{
 					op_gvorder(&mv);
@@ -121,6 +131,10 @@ void gvzwr_var(uint4 data, int4 n)
 					op_gvdata(&subdata);
 				} else
 				{
+					/* If gvnh_reg corresponds to a spanning global, then determine
+					 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+					 */
+					GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey);
 					op_gvdata(&subdata);
 					if (MV_FORCE_INTD(&subdata))
 						seen_null = 1;
diff --git a/sr_port/gvzwrite_ch.c b/sr_port/gvzwrite_ch.c
index 52d9ca4..a579e99 100644
--- a/sr_port/gvzwrite_ch.c
+++ b/sr_port/gvzwrite_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,7 @@
 
 CONDITION_HANDLER(gvzwrite_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	gvzwrite_clnup();	/* this routine is called by gvzwr_fini() too */
 	NEXTCH;
 }
diff --git a/sr_port/gvzwrite_clnup.c b/sr_port/gvzwrite_clnup.c
index 98b50a8..0df5462 100644
--- a/sr_port/gvzwrite_clnup.c
+++ b/sr_port/gvzwrite_clnup.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,8 +32,6 @@ GBLREF gv_key		*gv_currkey;
 GBLREF gd_region	*gv_cur_region;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF gvzwrite_datablk	*gvzwrite_block;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 
 void	gvzwrite_clnup(void)
 {
@@ -50,8 +48,6 @@ void	gvzwrite_clnup(void)
 		memcpy(&gv_currkey->base[0], &old->base[0], old->end + 1);
 		gv_currkey->end = old->end;
 		gv_currkey->prev = old->prev;
-		gd_map = gvzwrite_block->old_map;
-		gd_map_top = gvzwrite_block->old_map_top;
 		free(gvzwrite_block->old_key);
 		gvzwrite_block->old_key = gvzwrite_block->old_targ = (unsigned char *)NULL;
 		gvzwrite_block->subsc_count = 0;
diff --git a/sr_port/hashtab_mname.h b/sr_port/hashtab_mname.h
index 61b7fbe..5e87a06 100644
--- a/sr_port/hashtab_mname.h
+++ b/sr_port/hashtab_mname.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -49,6 +49,15 @@ typedef struct hash_table_mname_struct
 	STR_HASH((hkey)->var_name.addr, (hkey)->var_name.len, ((hkey)->hash_code), 0);	\
 }
 
+/* This is the same as the COMPUTE_HASH_MNAME macro except "hkey" is of type mstr (not mname_entry)
+ * and target of the computed hash_code is an input parameter "hash_code" of type "int".
+ */
+#define COMPUTE_HASH_MSTR(hkey, hash_code)				\
+{									\
+	assert((0 < (hkey).len) && (MAX_MIDENT_LEN >= (hkey).len));	\
+	STR_HASH((hkey).addr, (hkey).len, hash_code, 0);		\
+}
+
 /* Prototypes for mname hash routines. See hashtab_implementation.h for detail interface and implementation */
 void init_hashtab_mname(hash_table_mname *table, int minsize, boolean_t dont_compact, boolean_t dont_keep_spare_table);
 void expand_hashtab_mname(hash_table_mname *table, int minsize);
diff --git a/sr_port/hashtab_rehash_ch.c b/sr_port/hashtab_rehash_ch.c
index 96cf45f..cc3d49b 100644
--- a/sr_port/hashtab_rehash_ch.c
+++ b/sr_port/hashtab_rehash_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -14,14 +14,14 @@
 #include "error.h"
 #include "util.h"
 
+error_def(ERR_MEMORY);
+error_def(ERR_MEMORYRECURSIVE);
+error_def(ERR_HTOFLOW);
+
 CONDITION_HANDLER(hashtab_rehash_ch)
 {
 	/* If we cannot alloc memory during rehashing, just continue in normal program flow */
-	error_def(ERR_MEMORY);
-	error_def(ERR_MEMORYRECURSIVE);
-	error_def(ERR_HTOFLOW);
-
-	START_CH;
+	START_CH(TRUE);
 	/* If we cannot allocate memory or any error while doing rehash, just abort any more rehashing.
 	 *  We will continue with old table. Note that we do not ignore VMSMEMORY errors because if a
 	 *  VMS_MEMORY error occurred, gtm_malloc is going to have released the memory cache trying to get
diff --git a/sr_port/have_crit.h b/sr_port/have_crit.h
index c515bf6..5d5d57e 100644
--- a/sr_port/have_crit.h
+++ b/sr_port/have_crit.h
@@ -55,13 +55,13 @@ typedef enum
 	INTRPT_IN_WAIT_FOR_DISK_SPACE,	/* Deferring interrupts during wait_for_disk_space.c */
 	INTRPT_IN_WCS_WTSTART,		/* Deferring interrupts until cnl->intent_wtstart is decremented and dbsync timer is
 					 * started */
-	INTRPT_IN_REFORMAT_BUFFER_USE,	/* Deferring interrupts until buffer is reformatted */
 	INTRPT_IN_X_TIME_FUNCTION,	/* Deferring interrupts in non-nesting functions, such as localtime, ctime, and mktime. */
 	INTRPT_IN_FUNC_WITH_MALLOC,	/* Deferring interrupts while in libc- or system functions that do a malloc internally. */
 	INTRPT_IN_FDOPEN,		/* Deferring interrupts in fdopen. */
 	INTRPT_IN_LOG_FUNCTION,		/* Deferring interrupts in openlog, syslog, or closelog. */
 	INTRPT_IN_FORK_OR_SYSTEM,	/* Deferring interrupts in fork or system. */
 	INTRPT_IN_FSTAT,		/* Deferring interrupts in fstat. */
+	INTRPT_IN_TLS_FUNCTION,		/* Deferring interrupts in TLS functions. */
 	INTRPT_NUM_STATES		/* Should be the *last* one in the enum */
 } intrpt_state_t;
 
@@ -70,12 +70,10 @@ GBLREF	boolean_t	deferred_timers_check_needed;
 
 /* Macro to check if we are in a state that is ok to interrupt (or to do deferred signal handling). We do not want to interrupt if
  * the global variable intrpt_ok_state indicates it is not ok to interrupt, if we are in the midst of a malloc, if we are holding
- * crit, if we are in the midst of commit, or in wcs_wtstart. In the last case, we could be causing another process HOLDING CRIT on
- * the region to wait in bg_update_phase1 if we hold the write interlock. Hence it is important for us to finish that as soon as
- * possible and not interrupt it.
+ * crit, or if we are in the midst of a commit.
  */
 #define	OK_TO_INTERRUPT	((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) && (0 == gtmMallocDepth)			\
-				&& (0 == have_crit(CRIT_HAVE_ANY_REG | CRIT_IN_COMMIT | CRIT_IN_WTSTART)))
+				&& (0 == have_crit(CRIT_HAVE_ANY_REG | CRIT_IN_COMMIT)))
 
 /* Set the value of forced_exit to 1. This should indicate that we want a deferred signal handler to be invoked first upon leaving
  * the current deferred window. Since we do not want forced_exit state to ever regress, and there might be several signals delivered
diff --git a/sr_port/init_root_gv.h b/sr_port/init_root_gv.h
deleted file mode 100644
index 0784b9d..0000000
--- a/sr_port/init_root_gv.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-
-#define INIT_GBL_ROOT() { curr_gbl_root.str.addr = (char *)malloc(SIZEOF(mident_fixed)); }
-
-#define CREATE_DUMMY_GBLDIR(header, saved, region, map, map_top) { \
-		mval	v; \
-		gd_binding *map_temp; \
-\
-		saved = header; \
-		header = 0; \
-		v.mvtype = MV_STR; \
-		header = (gd_addr *)create_dummy_gbldir(); \
-		map = header->maps;	\
-		map_top = map + header->n_maps; \
-		map_temp = map + 1; \
-		map_temp->reg.addr = region; \
-		map_temp = map_temp + 1;\
-		map_temp->reg.addr = region; \
-	}
-
-#define GET_SAVED_GDADDR(header, saved, map, region) {\
-	header = saved;	\
-	map = header->maps; \
-	map  = map + 1; /* get past local locks */ \
-	map->reg.addr = region;  \
-	map  = map + 1; \
-	map->reg.addr = region;  \
-}
-
-#define RESTORE_ORIGINAL_GDADDR (header, saved) { header = saved; }
-
-
-#define RETRIEVE_ROOT_VAL(gbl_name, root_val, temp_gbl_name, temp_root_val, root_val_len)	\
-{												\
-		temp_gbl_name = gbl_name; temp_root_val = root_val;				\
-		for (root_val_len = 0; (*temp_root_val++ = *temp_gbl_name++); root_val_len++);	\
-		*temp_root_val = '\0';								\
-}
-
-#define INIT_ROOT_GVT(curr_gbl_root, root_val_len, curr_gbl_root_mval)							\
-{															\
-	unsigned char		*key;											\
-	gv_namehead		*hasht_tree;										\
-	mname_entry		gvent;											\
-															\
-	GTMTRIG_ONLY(if ((HASHT_GBLNAME_LEN != root_val_len) || (0 != memcmp(HASHT_GBLNAME, curr_gbl_root, root_val_len))))\
-	{														\
-		curr_gbl_root_mval.str.len = MIN(root_val_len, MAX_MIDENT_LEN);						\
-		memcpy(curr_gbl_root_mval.str.addr, curr_gbl_root, curr_gbl_root_mval.str.len);				\
-        	op_gvname(VARLSTCNT(1) &curr_gbl_root_mval);								\
-	} GTMTRIG_ONLY(else												\
-		{													\
-			SETUP_TRIGGER_GLOBAL;										\
-			key = &gv_currkey->base[0];									\
-			memcpy(key, HASHT_GBLNAME, HASHT_GBLNAME_FULL_LEN);						\
-			key += HASHT_GBLNAME_FULL_LEN;									\
-			*key++ = '\0';											\
-			gv_currkey->end = HASHT_GBLNAME_FULL_LEN;							\
-		}													\
-		)													\
-}
diff --git a/sr_port/int_namelook.c b/sr_port/int_namelook.c
new file mode 100644
index 0000000..5b210d3
--- /dev/null
+++ b/sr_port/int_namelook.c
@@ -0,0 +1,52 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gtm_string.h"
+
+#include "compiler.h"
+#include "opcode.h"
+#include "toktyp.h"
+#include "nametabtyp.h"
+#include "gtm_caseconv.h"
+#include "int_namelook.h"
+/* This routine performs the same function as namelook() only the first parameter for this version
+   is an array of type uint4 vs unsigned char in namelook().  This permits a much larger number of
+   deviceparameter names.  The purpose of this function is to search for the character string in
+   in the 3rd input parameter called str.  It can find either an exact match or a match which has an *
+   as its final character.  The table containing names to compare is the 2nd parameter called nametabent.
+   If the name is found then the offset into the nametabent is returned.  If not found, a -1 is returned.
+ */
+
+int int_namelook(const uint4 offset_tab[], const nametabent *name_tab, char *str, int strlength)
+{
+	unsigned char		temp[NAME_ENTRY_SZ], x;
+	const nametabent	*top, *i;
+
+	if (strlength > NAME_ENTRY_SZ)
+		return -1;
+	lower_to_upper(&temp[0], (uchar_ptr_t)str, strlength);
+	if ('%' == (x = temp[0]))
+		return -1;
+	i = name_tab + offset_tab[x -= 'A'];
+	top = name_tab + offset_tab[++x];
+	assert((i == top) || (i->name[0] >= temp[0]));
+	for (; i < top; i++)
+	{
+		if ((strlength == i->len) || ((strlength > i->len) && ('*' == i->name[i->len])))
+		{
+			if (!memcmp(&temp[0], i->name, (int4)(i->len)))
+				return (int)(i - name_tab);
+		}
+	}
+	return -1;
+}
diff --git a/sr_port/iotcp_dummy.c b/sr_port/int_namelook.h
similarity index 62%
rename from sr_port/iotcp_dummy.c
rename to sr_port/int_namelook.h
index 6e8ab86..7c3ebc2 100644
--- a/sr_port/iotcp_dummy.c
+++ b/sr_port/int_namelook.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,10 +9,8 @@
  *								*
  ****************************************************************/
 
-#include "mdef.h"
-#include "io.h"
+#ifndef NAMELOOK_INCLUDED
+#define NAMELOOK_INCLUDED
+int int_namelook(const uint4 offset_tab[], const nametabent *name_tab, char *str, int len);
 
-short iotcp_dummy(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout)
-{
-	return 0;
-}
+#endif /* NAMELOOK_INCLUDED */
diff --git a/sr_port/io.h b/sr_port/io.h
index 5c83006..c5ecc39 100644
--- a/sr_port/io.h
+++ b/sr_port/io.h
@@ -60,6 +60,11 @@ error_def(ERR_BADCHSET);
 #define DEFAULT_IOD_WIDTH	80
 #define DEFAULT_IOD_WRAP	TRUE
 
+#define TCPDEF_WIDTH	255
+#define TCPDEF_LENGTH	66
+
+#define DLRZKEYLEN	1024
+
 #define BADCHAR_DEVICE_MSG "BADCHAR error raised on input"
 #define UNAVAILABLE_DEVICE_MSG "Resource temporarily unavailable"
 
@@ -78,7 +83,6 @@ enum io_dev_type
 	mb,		/* mail box	*/
 	nl,		/* null device	*/
 	ff,		/* fifo device  */
-	tcp,		/* TCP socket  */
 	gtmsocket,	/* socket device, socket is already used by sys/socket.h */
 #ifdef UNIX
 	pi,		/* pipe */
@@ -202,6 +206,7 @@ typedef struct dev_dispatch_struct
 	void	(*iocontrol)(mstr *);
 	void	(*dlr_device)(mstr *);
 	void	(*dlr_key)(mstr *);
+	void	(*dlr_zkey)(mstr *);
 } dev_dispatch_struct;
 
 /* io_ prototypes */
@@ -233,16 +238,19 @@ void io_init_name(void);
 #define xx_iocontrol(X)		void X##_iocontrol(mstr *d)
 #define xx_dlr_device(X)	void X##_dlr_device(mstr *d)
 #define xx_dlr_key(X)		void X##_dlr_key(mstr *d)
+#define xx_dlr_zkey(X)		void X##_dlr_zkey(mstr *d)
 
 /* Following definitions have a pattern that most of the routines follow. Only exceptions are:
  *      1. ioff_open() is an extra routine
  *      2. iopi_open() is an extra routine on unix
  *	3. iopi_iocontrol() is an extra routine on unix to handle write /writeof
+ *	4. iosocket_dlr_zkey() is only for sockets
  */
 
 #define ioxx(X) ioxx_##X(tt); ioxx_##X(mt); ioxx_##X(rm); VMS_ONLY(ioxx_##X(mb);) ioxx_##X(nl); \
 	ioxx_##X(us); ioxx_##X(tcp); ioxx_##X(socket)
 #define xxdlr(X) xx_iocontrol(X); xx_dlr_device(X); xx_dlr_key(X)
+#define xxdlrzk(X) xx_iocontrol(X); xx_dlr_device(X); xx_dlr_key(X); xx_dlr_zkey(X)
 
 /* prototypes for dispatch functions */
 
@@ -258,10 +266,9 @@ ioxx(wteol);
 ioxx(wtff);
 ioxx(dummy);
 ioxx(flush);
-xxdlr(nil);
+xxdlrzk(nil);
 xxdlr(ious);
-xxdlr(iotcp);
-xxdlr(iosocket);
+xxdlrzk(iosocket);
 ioxx_open(ff);
 #ifdef UNIX
 ioxx_open(pi);
@@ -300,11 +307,6 @@ boolean_t iosocket_listen(io_desc *iod, unsigned short len);
 boolean_t iosocket_wait(io_desc *iod, int4 timepar);
 void iosocket_poolinit(void);
 
-/* iotcp_ prototypes */
-int iotcp_fillroutine(void);
-int iotcp_getlsock(io_log_name *dev);
-void iotcp_rmlsock(io_desc *iod);
-
 /* tcp_ prototypes */
 int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive);
 
@@ -315,15 +317,15 @@ int iomb_dataread (int timeout);
 
 bool same_device_check(mstr tname, char *buf);
 
-#define	iotype(O,X,Y) 								\
+#define	iotype(O,X,Y,Z) 								\
 { 										\
 	O##_open, X##_close, X##_use, X##_read, X##_rdone, X##_write, 		\
 	X##_wtone, X##_wteol, X##_wtff, NULL, X##_flush, X##_readfl,		\
-	Y##_iocontrol, Y##_dlr_device, Y##_dlr_key 				\
+	Y##_iocontrol, Y##_dlr_device, Y##_dlr_key, Z##_dlr_zkey 				\
 }
 #define ionil_dev 												\
 {														\
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL	\
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL	\
 }
 
 #ifdef __sparc
@@ -334,6 +336,7 @@ int outc(int ch);
 
 void get_dlr_device(mval *v);
 void get_dlr_key(mval *v);
+void get_dlr_zkey(mval *v);
 
 
 void flush_pio(void);
diff --git a/sr_port/io_dev_dispatch.h b/sr_port/io_dev_dispatch.h
index 3911f1b..746e656 100644
--- a/sr_port/io_dev_dispatch.h
+++ b/sr_port/io_dev_dispatch.h
@@ -18,31 +18,30 @@
 UNIX_ONLY(GBLDEF) VMS_ONLY(LITDEF) dev_dispatch_struct io_dev_dispatch[] =
 {
 #	ifdef UNIX
-	iotype(iott, iott, iott),
+	iotype(iott, iott, iott, nil),
 #	else
-	iotype(iott, iott, nil),
+	iotype(iott, iott, nil, nil),
 #	endif
-	iotype(iomt, iomt, nil),
+	iotype(iomt, iomt, nil, nil),
 #	ifdef UNIX
-	iotype(iorm, iorm, iopi),
+	iotype(iorm, iorm, iopi, nil),
 #	else
-	iotype(iorm, iorm, nil),
+	iotype(iorm, iorm, nil, nil),
 #	endif
-	iotype(ious, ious, ious),
+	iotype(ious, ious, ious, nil),
 #	ifdef UNIX
 	ionil_dev,
 #	else
-	iotype(iomb, iomb, nil),
+	iotype(iomb, iomb, nil, nil),
 #	endif
-	iotype(ionl, ionl, nil),
+	iotype(ionl, ionl, nil, nil),
 #	ifdef UNIX
-	iotype(ioff, iorm, iopi),
+	iotype(ioff, iorm, iopi, nil),
 #	else
-	iotype(ioff, iorm, nil),
+	iotype(ioff, iorm, nil, nil),
 #	endif
-	iotype(iotcp, iotcp, iotcp),
-	iotype(iosocket, iosocket, iosocket)
+	iotype(iosocket, iosocket, iosocket, iosocket)
 #	ifdef UNIX
-	,iotype(iopi, iorm, iopi)
+	,iotype(iopi, iorm, iopi, nil)
 #	endif
 };
diff --git a/sr_port/io_init_ch.c b/sr_port/io_init_ch.c
index 9004225..8b1d1b9 100644
--- a/sr_port/io_init_ch.c
+++ b/sr_port/io_init_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,7 +25,7 @@ CONDITION_HANDLER(io_init_ch)
 {
 	io_log_name	*iol;
 
-	START_CH;
+	START_CH(TRUE);
 	if (INFO == SEVERITY)
 	{
 		PRN_ERROR;
diff --git a/sr_port/iop.h b/sr_port/iop.h
index d7ed558..711216f 100644
--- a/sr_port/iop.h
+++ b/sr_port/iop.h
@@ -169,7 +169,7 @@ IOP_DESC(151, iop_fifo, 0, IOP_OPEN_OK, 0),
 IOP_DESC(152, iop_canonical, 0, IOP_OPEN_OK | IOP_USE_OK, 0),
 IOP_DESC(153, iop_nocanonical, 0, IOP_OPEN_OK | IOP_USE_OK, 0),
 IOP_DESC(154, iop_socket, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_CLOSE_OK | IOP_USE_OK, IOP_SRC_STR),
-IOP_DESC(155, iop_listen, 0, IOP_OPEN_OK | IOP_CLOSE_OK, 0),
+IOP_DESC(155, iop_listen, 0, 0, 0),		/* no longer used - see iop_zlisten */
 IOP_DESC(156, iop_urgent, 0, IOP_USE_OK, 0),
 IOP_DESC(157, iop_nourgent, 0, IOP_USE_OK, 0),
 IOP_DESC(158, iop_delimiter, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_USE_OK, IOP_SRC_STR),
@@ -177,7 +177,7 @@ IOP_DESC(159, iop_connect, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_USE_OK, IOP_SRC_STR),
 IOP_DESC(160, iop_ioerror, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_USE_OK, IOP_SRC_STR),
 IOP_DESC(161, iop_attach, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_USE_OK, IOP_SRC_STR),
 IOP_DESC(162, iop_detach, IOP_VAR_SIZE, IOP_USE_OK, IOP_SRC_STR),
-IOP_DESC(163, iop_zlisten, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_CLOSE_OK | IOP_USE_OK, IOP_SRC_STR),
+IOP_DESC(163, iop_zlisten, IOP_VAR_SIZE, IOP_OPEN_OK | IOP_USE_OK, IOP_SRC_STR),
 IOP_DESC(164, iop_ipchset, IOP_VAR_SIZE, IOP_OPEN_OK, IOP_SRC_STR),
 IOP_DESC(165, iop_opchset, IOP_VAR_SIZE, IOP_OPEN_OK, IOP_SRC_STR),
 IOP_DESC(166, iop_nodelimiter, 0, IOP_OPEN_OK | IOP_USE_OK, 0),
@@ -214,4 +214,5 @@ IOP_DESC(196, iop_follow, 0, IOP_OPEN_OK|IOP_USE_OK, 0),
 IOP_DESC(197, iop_nofollow, 0, IOP_OPEN_OK|IOP_USE_OK, 0),
 IOP_DESC(198, iop_empterm, 0, IOP_OPEN_OK|IOP_USE_OK, 0),
 IOP_DESC(199, iop_noempterm, 0, IOP_OPEN_OK|IOP_USE_OK, 0),
-IOP_DESC(200, n_iops, 0, 0, 0)
+IOP_DESC(200, iop_timeout, SIZEOF(int4), IOP_CLOSE_OK, IOP_SRC_INT),
+IOP_DESC(201, n_iops, 0, 0, 0)
diff --git a/sr_port/iosocket_bind.c b/sr_port/iosocket_bind.c
index f3912d8..f545111 100644
--- a/sr_port/iosocket_bind.c
+++ b/sr_port/iosocket_bind.c
@@ -22,16 +22,17 @@
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
-#include "iotcproutine.h"
 #include "gtm_stdlib.h"
+#include "gtm_unistd.h"
+#ifndef VMS				/* for LOCAL sockets */
+#include "gtm_stat.h"
+#include "eintr_wrappers.h"		/* for STAT_FILE  and CHG_OWNER */
+#endif
 
 #define	BOUND	"BOUND"
 #define IPV6_UNCERTAIN 2
 
-GBLREF	tcp_library_struct	tcp_routines;
-
 error_def(ERR_GETNAMEINFO);
 error_def(ERR_GETSOCKNAMERR);
 error_def(ERR_GETSOCKOPTERR);
@@ -40,14 +41,14 @@ error_def(ERR_SOCKBIND);
 error_def(ERR_SOCKINIT);
 error_def(ERR_TEXT);
 
-boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz)
+boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz, boolean_t newversion)
 {
 	int			temp_1 = 1;
-	char			*errptr;
+	char			*errptr, *charptr;
 	int4			errlen, msec_timeout, real_errno;
 	short			len;
 	in_port_t		actual_port;
-	boolean_t		no_time_left = FALSE;
+	boolean_t		no_time_left = FALSE, ioerror;
 	d_socket_struct		*dsocketptr;
 	struct addrinfo		*ai_ptr;
 	char			port_buffer[NI_MAXSERV];
@@ -55,11 +56,17 @@ boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update
 	ABS_TIME        	cur_time, end_time;
 	GTM_SOCKLEN_TYPE	addrlen;
 	GTM_SOCKLEN_TYPE	sockbuflen;
+#	ifndef VMS
+	struct stat		statbuf;
+	mode_t			filemode;
+#	endif
 
 	dsocketptr = socketptr->dev;
 	ai_ptr = (struct addrinfo*)(&socketptr->local.ai);
 	assert(NULL != dsocketptr);
 	dsocketptr->iod->dollar.key[0] = '\0';
+	dsocketptr->iod->dollar.device[0] = '\0';
+	ioerror = socketptr->ioerror;
 	if (FD_INVALID != socketptr->temp_sd)
 	{
 		socketptr->sd = socketptr->temp_sd;
@@ -75,66 +82,103 @@ boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update
 	do
 	{
 		temp_1 = 1;
-		if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
-				SOL_SOCKET, SO_REUSEADDR, &temp_1, SIZEOF(temp_1)))
-		{
-		        real_errno = errno;
-			errptr = (char *)STRERROR(real_errno);
-			errlen = STRLEN(errptr);
-			SOCKET_FREE(socketptr);
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-					RTS_ERROR_LITERAL("SO_REUSEADDR"), real_errno, errlen, errptr);
-			return FALSE;
-		}
-#ifdef TCP_NODELAY
-		temp_1 = socketptr->nodelay ? 1 : 0;
-		if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
-				IPPROTO_TCP, TCP_NODELAY, &temp_1, SIZEOF(temp_1)))
+		if (socket_local != socketptr->protocol)
 		{
-		        real_errno = errno;
-			errptr = (char *)STRERROR(real_errno);
-			errlen = STRLEN(errptr);
-			SOCKET_FREE(socketptr);
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-					RTS_ERROR_LITERAL("TCP_NODELAY"), real_errno, errlen, errptr);
-			return FALSE;
-		}
-#endif
-		if (update_bufsiz)
-		{
-			if (-1 == tcp_routines.aa_setsockopt(socketptr->sd,
-				SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, SIZEOF(socketptr->bufsiz)))
+			if (-1 == setsockopt(socketptr->sd,
+				SOL_SOCKET, SO_REUSEADDR, &temp_1, SIZEOF(temp_1)))
 			{
-			        real_errno = errno;
+				real_errno = errno;
 				errptr = (char *)STRERROR(real_errno);
 				errlen = STRLEN(errptr);
 				SOCKET_FREE(socketptr);
 				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-						RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
+					RTS_ERROR_LITERAL("SO_REUSEADDR"), real_errno, errlen, errptr);
 				return FALSE;
 			}
-		} else
-		{
-			sockbuflen = SIZEOF(socketptr->bufsiz);
-			if (-1 == tcp_routines.aa_getsockopt(socketptr->sd,
-				SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, &sockbuflen))
+#			ifdef TCP_NODELAY
+			temp_1 = socketptr->nodelay ? 1 : 0;
+			if (-1 == setsockopt(socketptr->sd,
+				IPPROTO_TCP, TCP_NODELAY, &temp_1, SIZEOF(temp_1)))
 			{
 			        real_errno = errno;
 				errptr = (char *)STRERROR(real_errno);
 				errlen = STRLEN(errptr);
 				SOCKET_FREE(socketptr);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
-					RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
+					RTS_ERROR_LITERAL("TCP_NODELAY"), real_errno, errlen, errptr);
 				return FALSE;
 			}
+#			endif
+			if (update_bufsiz)
+			{
+				if (-1 == setsockopt(socketptr->sd,
+					SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, SIZEOF(socketptr->bufsiz)))
+				{
+				        real_errno = errno;
+					errptr = (char *)STRERROR(real_errno);
+					errlen = STRLEN(errptr);
+					SOCKET_FREE(socketptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
+						RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
+					return FALSE;
+				}
+			} else
+			{
+				sockbuflen = SIZEOF(socketptr->bufsiz);
+				if (-1 == getsockopt(socketptr->sd,
+					SOL_SOCKET, SO_RCVBUF, &socketptr->bufsiz, &sockbuflen))
+				{
+				        real_errno = errno;
+					errptr = (char *)STRERROR(real_errno);
+					errlen = STRLEN(errptr);
+					SOCKET_FREE(socketptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
+						RTS_ERROR_LITERAL("SO_RCVBUF"), real_errno, errlen, errptr);
+					return FALSE;
+				}
+			}
+		}
+#		ifndef VMS
+		if (socket_local == socketptr->protocol)
+		{
+			charptr = ((struct sockaddr_un *)(socketptr->local.sa))->sun_path;
+			STAT_FILE(charptr, &statbuf, temp_1);
+			if (!temp_1)
+			{
+				if (!S_ISSOCK(statbuf.st_mode))
+				{
+					temp_1 = -1;	/* bypass unlink and issue error */
+					errno = ENOTSOCK;
+				}
+			}
+			if (!temp_1)
+				if (newversion)
+					temp_1 = UNLINK(charptr);
+			if (temp_1 && ENOENT != errno)
+			{
+					real_errno = errno;
+					if (ioerror)
+						SOCKET_FREE(socketptr);
+					MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+					errptr = (char *)STRERROR(real_errno);
+					errlen = STRLEN(errptr);
+					memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1]
+						, errptr, errlen + 1);   /* + 1 for null */
+					if (ioerror)
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKBIND, 0, real_errno);
+					return FALSE;
+			}
 		}
-		temp_1 = tcp_routines.aa_bind(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), ai_ptr->ai_addrlen);
+#		endif
+		temp_1 = bind(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), ai_ptr->ai_addrlen);
 		if (temp_1 < 0)
 		{
 			real_errno = errno;
 			no_time_left = TRUE;
 			switch (real_errno)
 			{
+				case EINTR:
+					break;
 				case EADDRINUSE:
 					if (NO_M_TIMEOUT != timepar)
 					{
@@ -142,27 +186,40 @@ boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update
 						cur_time = sub_abs_time(&end_time, &cur_time);
 						if (cur_time.at_sec > 0)
 							no_time_left = FALSE;
-					}
-					break;
-				case EINTR:
-					break;
+					} else
+						no_time_left = FALSE;	/* retry */
+					if (socket_local != socketptr->protocol)
+						break;
+					/* fall through for LOCAL sockets since it unlikely the file will go away */
 				default:
-					SOCKET_FREE(socketptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SOCKBIND, 0, real_errno, 0);
-					break;
+					if (ioerror)
+						SOCKET_FREE(socketptr);
+					MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+					errptr = (char *)STRERROR(real_errno);
+					errlen = STRLEN(errptr);
+					memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1]
+						, errptr, errlen + 1);   /* + 1 for null */
+					if (ioerror)
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKBIND, 0, real_errno);
+					return FALSE;
 			}
 			if (no_time_left)
 				return FALSE;
 			hiber_start(100);
-			tcp_routines.aa_close(socketptr->sd);
-			if (-1 == (socketptr->sd = tcp_routines.aa_socket(ai_ptr->ai_family,ai_ptr->ai_socktype,
+			close(socketptr->sd);
+			if (-1 == (socketptr->sd = socket(ai_ptr->ai_family,ai_ptr->ai_socktype,
 									  ai_ptr->ai_protocol)))
 			{
 				real_errno = errno;
 				errptr = (char *)STRERROR(real_errno);
 				errlen = STRLEN(errptr);
-				SOCKET_FREE(socketptr);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, real_errno, errlen, errptr);
+				MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+				memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1], errptr, errlen + 1);   /* get null */
+				if (ioerror)
+				{
+					SOCKET_FREE(socketptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, real_errno, errlen, errptr);
+				}
 				return FALSE;
 			}
 		}
@@ -170,26 +227,89 @@ boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update
 
 	/* obtain actual port from the bound address if port 0 was specified */
 	addrlen = SOCKET_ADDRLEN(socketptr, ai_ptr, local);
-	if (-1 == tcp_routines.aa_getsockname(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), &addrlen))
+	if (-1 == getsockname(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), &addrlen))
 	{
 		real_errno = errno;
 		errptr = (char *)STRERROR(real_errno);
 		errlen = STRLEN(errptr);
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_GETSOCKNAMERR, 3, real_errno, errlen, errptr);
+		MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+		memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1], errptr, errlen + 1);   /* + 1 for null */
+		if (ioerror)
+		{
+			SOCKET_FREE(socketptr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_GETSOCKNAMERR, 3, real_errno, errlen, errptr);
+		}
 	        return FALSE;
 	}
-	assert(ai_ptr->ai_addrlen == addrlen);
-	GETNAMEINFO(SOCKET_LOCAL_ADDR(socketptr), addrlen, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
-	if (0 != errcode)
+	if (socket_local != socketptr->protocol)
 	{
-		SOCKET_FREE(socketptr);
-		RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
-		return FALSE;
+		assert(ai_ptr->ai_addrlen == addrlen);	/* not right for local */
+		GETNAMEINFO(SOCKET_LOCAL_ADDR(socketptr), addrlen, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
+		if (0 != errcode)
+		{
+			real_errno = errno;
+			MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+			TEXT_ADDRINFO(errptr, errcode, real_errno);
+			errlen = STRLEN(errptr);
+			memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1], errptr, errlen + 1);   /* + 1 for null */
+			if (ioerror)
+			{
+				SOCKET_FREE(socketptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GETNAMEINFO, 0, ERR_TEXT, 2, errlen, errptr);
+			}
+			return FALSE;
+		}
+		actual_port = ATOI(port_buffer);
+		if (0 == socketptr->local.port)
+			socketptr->local.port = actual_port;
+		assert(socketptr->local.port == actual_port);
+#	ifndef VMS
+	} else
+	{
+		if (socketptr->filemode_mask)
+		{
+			charptr = ((struct sockaddr_un *)(socketptr->local.sa))->sun_path;
+			STAT_FILE(charptr, &statbuf, temp_1);
+			assertpro(!temp_1);	/* we just created socket so it should be there */
+			filemode = (statbuf.st_mode & ~socketptr->filemode_mask) | socketptr->filemode;
+			temp_1 = CHMOD(charptr, filemode);
+			if (temp_1)
+			{
+				real_errno = errno;
+				errptr = (char *)STRERROR(real_errno);
+				errlen = STRLEN(errptr);
+				MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+				memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1], errptr, errlen + 1);   /* for null */
+				if (ioerror)
+				{
+					SOCKET_FREE(socketptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_SOCKINIT, 3, real_errno, errlen, errptr
+						, ERR_TEXT, 2, RTS_ERROR_LITERAL("setting protection"));
+				}
+				return FALSE;
+			}
+		}
+		if (((gid_t)-1 != socketptr->uic.grp) || ((uid_t)-1 != socketptr->uic.mem))
+		{
+			CHG_OWNER(charptr, socketptr->uic.mem, socketptr->uic.grp, temp_1);
+			if (temp_1)
+			{
+				real_errno = errno;
+				errptr = (char *)STRERROR(real_errno);
+				errlen = STRLEN(errptr);
+				MEMCPY_LIT(dsocketptr->iod->dollar.device, ONE_COMMA);
+				memcpy(&dsocketptr->iod->dollar.device[SIZEOF(ONE_COMMA) - 1], errptr, errlen + 1);   /* for null */
+				if (ioerror)
+				{
+					SOCKET_FREE(socketptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_SOCKINIT, 3, real_errno, errlen, errptr,
+					ERR_TEXT, 2, RTS_ERROR_LITERAL("setting ownership"));
+				}
+				return FALSE;
+			}
+		}
+#	endif
 	}
-	actual_port = ATOI(port_buffer);
-	if (0 == socketptr->local.port)
-		socketptr->local.port = actual_port;
-	assert(socketptr->local.port == actual_port);
 	socketptr->state = socket_bound;
 	len = SIZEOF(BOUND) - 1;
         memcpy(&dsocketptr->iod->dollar.key[0], BOUND, len);
@@ -197,6 +317,13 @@ boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update
         memcpy(&dsocketptr->iod->dollar.key[len], socketptr->handle, socketptr->handle_len);
         len += socketptr->handle_len;
         dsocketptr->iod->dollar.key[len++] = '|';
-        SPRINTF(&dsocketptr->iod->dollar.key[len], "%d", socketptr->local.port);
+	if (socket_local != socketptr->protocol)
+		SPRINTF(&dsocketptr->iod->dollar.key[len], "%d", socketptr->local.port);
+#	ifndef VMS
+	else /* path goes in $key */
+		strncpy(&dsocketptr->iod->dollar.key[len], ((struct sockaddr_un *)(socketptr->local.sa))->sun_path,
+			DD_BUFLEN - len - 1);
+#	endif
+	dsocketptr->iod->dollar.key[DD_BUFLEN - 1] = '\0';
 	return TRUE;
 }
diff --git a/sr_port/iosocket_close.c b/sr_port/iosocket_close.c
index a1b6f87..52d26f0 100644
--- a/sr_port/iosocket_close.c
+++ b/sr_port/iosocket_close.c
@@ -20,7 +20,11 @@
 
 #include "gtm_string.h"
 #include "gtm_iconv.h"
+#ifndef  VMS
+#include "gtm_stat.h"
+#endif
 #include "gtm_stdio.h"
+#include "gtm_unistd.h"
 
 #include "gtm_socket.h"
 #include "gtm_inet.h"
@@ -28,16 +32,19 @@
 #include "copy.h"
 #include "io_params.h"
 #include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "stringpool.h"
+#include "eintr_wrappers.h"
 
-GBLREF tcp_library_struct	tcp_routines;
 GBLREF io_desc		*active_device;
 LITREF unsigned char		io_params_size[];
+
+error_def(ERR_CLOSEFAIL);
 error_def(ERR_SOCKNOTFND);
+error_def(ERR_SYSCALL);
+
+void iosocket_close_range(d_socket_struct *dsocketptr, int start, int end, boolean_t socket_delete, boolean_t socket_specified);
 
 void iosocket_close(io_desc *iod, mval *pp)
 {
@@ -45,11 +52,11 @@ void iosocket_close(io_desc *iod, mval *pp)
 	unsigned char	ch;
 	int		handle_len;
 	d_socket_struct	*dsocketptr;
-	socket_struct	*socketptr;
 	char		sock_handle[MAX_HANDLE_LEN];
-	int4		ii, jj, start, end, index;
+	int4		start, end, index;
 	int		p_offset = 0;
-	boolean_t socket_destroy = FALSE;
+	boolean_t	socket_destroy = FALSE;
+	boolean_t	socket_delete = FALSE;
 
 	assert(iod->type == gtmsocket);
 	dsocketptr = (d_socket_struct *)iod->dev_sp;
@@ -70,7 +77,7 @@ void iosocket_close(io_desc *iod, mval *pp)
 			socket_specified = TRUE;
 			break;
 		case iop_ipchset:
-#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
+#			if defined(KEEP_zOS_EBCDIC) || defined(VMS)
 			if ( (iconv_t)0 != iod->input_conv_cd )
 			{
 				ICONV_CLOSE_CD(iod->input_conv_cd);
@@ -78,10 +85,10 @@ void iosocket_close(io_desc *iod, mval *pp)
 			SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1));
 			if (DEFAULT_CODE_SET != iod->in_code_set)
 				ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1));
-#endif
+#			endif
 			break;
                 case iop_opchset:
-#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
+#			if defined(KEEP_zOS_EBCDIC) || defined(VMS)
 			if ( (iconv_t)0 != iod->output_conv_cd )
 			{
 				ICONV_CLOSE_CD(iod->output_conv_cd);
@@ -89,7 +96,7 @@ void iosocket_close(io_desc *iod, mval *pp)
 			SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1));
 			if (DEFAULT_CODE_SET != iod->out_code_set)
 				ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET);
-#endif
+#			endif
 			break;
 		case iop_destroy:
 			socket_destroy = TRUE;
@@ -97,6 +104,11 @@ void iosocket_close(io_desc *iod, mval *pp)
 		case iop_nodestroy:
 			socket_destroy = FALSE;
 			break;
+#		ifndef VMS
+		case iop_delete:
+			socket_delete = TRUE;
+			break;
+#		endif
 		default:
 			break;
 		}
@@ -117,10 +129,57 @@ void iosocket_close(io_desc *iod, mval *pp)
 		start = dsocketptr->n_socket - 1;
 		end = 0;
 	}
+	iosocket_close_range(dsocketptr, start, end, socket_delete, socket_specified);
+	if (!socket_specified)
+	{
+		iod->state = dev_closed;
+		if (socket_destroy)
+		{
+			active_device = 0;
+			iosocket_destroy(iod);
+		}
+	}
+}
+
+void iosocket_close_range(d_socket_struct *dsocketptr, int start, int end, boolean_t socket_delete, boolean_t socket_specified)
+{
+	int4		ii,jj;
+	int		rc, save_fd, save_rc = 0, save_errno;
+	socket_struct	*socketptr;
+#	ifndef VMS
+	struct stat	statbuf, fstatbuf;
+	char		*path;
+	int		res;
+#	endif
+
 	for (ii = start; ii >= end; ii--)
 	{
 		socketptr = dsocketptr->socket[ii];
-		tcp_routines.aa_close(socketptr->sd);
+#		ifndef VMS
+		if (socket_specified && socket_delete && (socket_local == socketptr->protocol) && socketptr->passive)
+		{	/* only delete if SOCKET= specified  and passive/listening */
+			assertpro(socketptr->local.sa);
+			path = ((struct sockaddr_un *)(socketptr->local.sa))->sun_path;
+			FSTAT_FILE(socketptr->sd, &fstatbuf, res);
+			if (-1 == res)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
+					LEN_AND_LIT("fstat during socket delete"), CALLFROM, errno);
+			STAT_FILE(path, &statbuf, res);
+			if (-1 == res)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
+					LEN_AND_LIT("stat during socket delete"), CALLFROM, errno);
+			if (UNLINK(path) == -1)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
+					LEN_AND_LIT("unlink during socket delete"), CALLFROM, errno);
+		}
+#		endif
+		CLOSE(socketptr->sd, rc);
+		if (-1 == rc)
+		{
+			save_rc = rc;
+			save_fd = socketptr->sd;
+			save_errno = errno;
+		}
 		SOCKET_FREE(socketptr);
 		if (dsocketptr->current_socket >= ii)
 			dsocketptr->current_socket--;
@@ -128,13 +187,13 @@ void iosocket_close(io_desc *iod, mval *pp)
 			dsocketptr->socket[jj - 1] = dsocketptr->socket[jj];
 		dsocketptr->n_socket--;
 	}
-	if (!socket_specified)
+	if (0 != save_rc)
 	{
-		iod->state = dev_closed;
-		if (socket_destroy)
-		{
-			active_device = 0;
-			iosocket_destroy(iod);
-		}
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CLOSEFAIL, 1, save_fd, save_errno);
 	}
 }
+
+void iosocket_close_one(d_socket_struct *dsocketptr, int index)
+{
+	iosocket_close_range(dsocketptr, index, index, FALSE, TRUE);
+}
diff --git a/sr_port/iosocket_connect.c b/sr_port/iosocket_connect.c
index 70626f9..5aaf694 100644
--- a/sr_port/iosocket_connect.c
+++ b/sr_port/iosocket_connect.c
@@ -21,19 +21,18 @@
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
-#include "iotcproutine.h"
 #include <rtnhdr.h>
 #include "stack_frame.h"
 #include "mv_stent.h"
 #include "outofband.h"
 #include "gtm_netdb.h"
 #include "gtm_ipv6.h"
+#include "gtm_unistd.h"
+#include "gtm_select.h"
 
 #define	ESTABLISHED	"ESTABLISHED"
 
-GBLREF	tcp_library_struct	tcp_routines;
 GBLREF	volatile int4           outofband;
 GBLREF	boolean_t               dollar_zininterrupt;
 GBLREF	stack_frame             *frame_pointer;
@@ -90,12 +89,10 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
         /* Check for restart */
         if (dsocketptr->mupintr)
         {       /* We have a pending read restart of some sort - check we aren't recursing on this device */
-                if (sockwhich_invalid == sockintr->who_saved)
-                        GTMASSERT;      /* Interrupt should never have an invalid save state */
+                assertpro(sockwhich_invalid != sockintr->who_saved);	/* Interrupt should never have an invalid save state */
                 if (dollar_zininterrupt)
                         rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
-                if (sockwhich_connect != sockintr->who_saved)
-                        GTMASSERT;      /* ZINTRECURSEIO should have caught */
+                assertpro(sockwhich_connect == sockintr->who_saved);	/* ZINTRECURSEIO should have caught */
                 DBGSOCK((stdout, "socconn: *#*#*#*#*#*#*#  Restarted interrupted connect\n"));
                 mv_zintdev = io_find_mvstent(iod, FALSE);
                 if (mv_zintdev)
@@ -137,11 +134,12 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 		/* If the connect was failed, we may have already changed the remote.
 	 	 * So, the remote ai_addr should be restored.
 	 	 */
-		assertpro(NULL != sockptr->remote.ai_head);
-		memcpy(remote_ai_ptr, sockptr->remote.ai_head, SIZEOF(struct addrinfo));
+		assertpro((socket_tcpip != sockptr->protocol) || (NULL != sockptr->remote.ai_head));
+		if (sockptr->remote.ai_head)
+			memcpy(remote_ai_ptr, sockptr->remote.ai_head, SIZEOF(struct addrinfo));
 		if (need_socket && (FD_INVALID != sockptr->sd))
 		{
-			tcp_routines.aa_close(sockptr->sd);
+			close(sockptr->sd);
 			sockptr->sd = FD_INVALID;
 		}
 		assert(FD_INVALID == -1);
@@ -150,10 +148,13 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 			real_errno = -2;
 			for (raw_ai_ptr = remote_ai_ptr; NULL != raw_ai_ptr; raw_ai_ptr = raw_ai_ptr->ai_next)
 			{
-				if (-1 == (sockptr->sd = tcp_routines.aa_socket(raw_ai_ptr->ai_family, raw_ai_ptr->ai_socktype,
+				if (-1 == (sockptr->sd = socket(raw_ai_ptr->ai_family, raw_ai_ptr->ai_socktype,
 										  raw_ai_ptr->ai_protocol)))
+				{
 					real_errno = errno;
-				else
+					if (socket_local == sockptr->protocol)
+						break;		/* just one attempt */
+				} else
 				{
 					real_errno = 0;
 					break;
@@ -172,59 +173,24 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
 				return FALSE;
 			}
-			assertpro(NULL != raw_ai_ptr);/* either there is an IPv6 or an IPv4 address */
-			memcpy(remote_ai_ptr, raw_ai_ptr, SIZEOF(struct addrinfo));
-			SOCKET_AI_TO_REMOTE_ADDR(sockptr, raw_ai_ptr);
-			remote_ai_ptr->ai_addr = SOCKET_REMOTE_ADDR(sockptr);
-			remote_ai_ptr->ai_addrlen = raw_ai_ptr->ai_addrlen;
-			remote_ai_ptr->ai_next = NULL;
+			assertpro(NULL != raw_ai_ptr);	/* there is a local, IPv6, or IPv4 address */
+			if (remote_ai_ptr != raw_ai_ptr)
+				memcpy(remote_ai_ptr, raw_ai_ptr, SIZEOF(struct addrinfo));
 			need_socket = FALSE;
 			temp_1 = 1;
-			if (-1 == tcp_routines.aa_setsockopt(sockptr->sd, SOL_SOCKET, SO_REUSEADDR, &temp_1, SIZEOF(temp_1)))
-        		{
-				save_errno = errno;
-                		errptr = (char *)STRERROR(save_errno);
-                		errlen = STRLEN(errptr);
-				tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
-				sockptr->sd = FD_INVALID;
-				if (NULL != sockptr->remote.ai_head)
-				{
-					freeaddrinfo(sockptr->remote.ai_head);
-					sockptr->remote.ai_head = NULL;
-				}
-                		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-					  RTS_ERROR_LITERAL("SO_REUSEADDR"), save_errno, errlen, errptr);
-                		return FALSE;
-        		}
-#ifdef			TCP_NODELAY
-			temp_1 = sockptr->nodelay ? 1 : 0;
-			if (-1 == tcp_routines.aa_setsockopt(sockptr->sd,
-						     IPPROTO_TCP, TCP_NODELAY, &temp_1, SIZEOF(temp_1)))
-        		{
-				save_errno = errno;
-                		errptr = (char *)STRERROR(save_errno);
-                		errlen = STRLEN(errptr);
-				tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
-				sockptr->sd = FD_INVALID;
-				if (NULL != sockptr->remote.ai_head)
-				{
-					freeaddrinfo(sockptr->remote.ai_head);
-					sockptr->remote.ai_head = NULL;
-				}
-                		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-					  RTS_ERROR_LITERAL("TCP_NODELAY"), save_errno, errlen, errptr);
-                		return FALSE;
-        		}
-#endif
-			if (update_bufsiz)
+			if (socket_local != sockptr->protocol)
 			{
-				if (-1 == tcp_routines.aa_setsockopt(sockptr->sd,
-							     SOL_SOCKET, SO_RCVBUF, &sockptr->bufsiz, SIZEOF(sockptr->bufsiz)))
-				{
+				SOCKET_AI_TO_REMOTE_ADDR(sockptr, raw_ai_ptr);
+				remote_ai_ptr->ai_addr = SOCKET_REMOTE_ADDR(sockptr);
+				remote_ai_ptr->ai_addrlen = raw_ai_ptr->ai_addrlen;
+				remote_ai_ptr->ai_next = NULL;
+				if (-1 == setsockopt(sockptr->sd, SOL_SOCKET, SO_REUSEADDR,
+					&temp_1, SIZEOF(temp_1)))
+        			{
 					save_errno = errno;
-					errptr = (char *)STRERROR(save_errno);
-         				errlen = STRLEN(errptr);
-					tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
+                			errptr = (char *)STRERROR(save_errno);
+                			errlen = STRLEN(errptr);
+					close(sockptr->sd);	/* Don't leave a dangling socket around */
 					sockptr->sd = FD_INVALID;
 					if (NULL != sockptr->remote.ai_head)
 					{
@@ -232,29 +198,69 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 						sockptr->remote.ai_head = NULL;
 					}
                 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-						  RTS_ERROR_LITERAL("SO_RCVBUF"), save_errno, errlen, errptr);
-					return FALSE;
-				}
-			} else
-			{
-				sockbuflen = SIZEOF(sockptr->bufsiz);
-				if (-1 == tcp_routines.aa_getsockopt(sockptr->sd,
-							     SOL_SOCKET, SO_RCVBUF, &sockptr->bufsiz, &sockbuflen))
+						  RTS_ERROR_LITERAL("SO_REUSEADDR"), save_errno, errlen, errptr);
+                			return FALSE;
+        			}
+#				ifdef TCP_NODELAY
+				temp_1 = sockptr->nodelay ? 1 : 0;
+				if (-1 == setsockopt(sockptr->sd,
+					IPPROTO_TCP, TCP_NODELAY, &temp_1, SIZEOF(temp_1)))
 				{
 					save_errno = errno;
 					errptr = (char *)STRERROR(save_errno);
-         				errlen = STRLEN(errptr);
-					tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
+					errlen = STRLEN(errptr);
+					close(sockptr->sd);	/* Don't leave a dangling socket around */
 					sockptr->sd = FD_INVALID;
 					if (NULL != sockptr->remote.ai_head)
 					{
 						freeaddrinfo(sockptr->remote.ai_head);
 						sockptr->remote.ai_head = NULL;
 					}
-                			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
-						  RTS_ERROR_LITERAL("SO_RCVBUF"), save_errno, errlen, errptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
+						RTS_ERROR_LITERAL("TCP_NODELAY"), save_errno, errlen, errptr);
 					return FALSE;
 				}
+#				endif
+				if (update_bufsiz)
+				{
+					if (-1 == setsockopt(sockptr->sd,
+						     SOL_SOCKET, SO_RCVBUF, &sockptr->bufsiz, SIZEOF(sockptr->bufsiz)))
+					{
+						save_errno = errno;
+						errptr = (char *)STRERROR(save_errno);
+						errlen = STRLEN(errptr);
+						close(sockptr->sd);	/* Don't leave a dangling socket around */
+						sockptr->sd = FD_INVALID;
+						if (NULL != sockptr->remote.ai_head)
+						{
+							freeaddrinfo(sockptr->remote.ai_head);
+							sockptr->remote.ai_head = NULL;
+						}
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
+							RTS_ERROR_LITERAL("SO_RCVBUF"), save_errno, errlen, errptr);
+						return FALSE;
+					}
+				} else
+				{
+					sockbuflen = SIZEOF(sockptr->bufsiz);
+					if (-1 == getsockopt(sockptr->sd,
+						     SOL_SOCKET, SO_RCVBUF, &sockptr->bufsiz, &sockbuflen))
+					{
+						save_errno = errno;
+						errptr = (char *)STRERROR(save_errno);
+						errlen = STRLEN(errptr);
+						close(sockptr->sd);	/* Don't leave a dangling socket around */
+						sockptr->sd = FD_INVALID;
+						if (NULL != sockptr->remote.ai_head)
+						{
+							freeaddrinfo(sockptr->remote.ai_head);
+							sockptr->remote.ai_head = NULL;
+						}
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
+							RTS_ERROR_LITERAL("SO_RCVBUF"), save_errno, errlen, errptr);
+						return FALSE;
+					}
+				}
 			}
 		}
 		save_errno = res = 0;
@@ -262,7 +268,7 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 		{
 			/* Use plain connect to allow jobinterrupt */
 			assert(FD_INVALID != sockptr->sd);
-			res = connect(sockptr->sd, SOCKET_REMOTE_ADDR(sockptr), remote_ai_ptr->ai_addrlen);
+			res = connect(sockptr->sd, SOCKET_REMOTE_ADDR(sockptr), remote_ai_ptr->ai_addrlen);	 /* BYPASSOK */
 			if (res < 0)
 			{
 				save_errno = errno;
@@ -293,6 +299,9 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 					/* fall through */
 					case ETIMEDOUT:	/* the other side bound but not listening */
 					case ECONNREFUSED:
+#					ifndef VMS
+					case ENOENT:	/* LOCAL socket not there */
+#					endif
 						if (!no_time_left && 0 != timepar && NO_M_TIMEOUT != timepar)
 						{
 							sys_get_curr_time(&cur_time);
@@ -304,7 +313,8 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 							no_time_left = TRUE;
 						else if (!no_time_left)
 						{
-							if (ETIMEDOUT == save_errno || ECONNREFUSED == save_errno)
+							if (ETIMEDOUT == save_errno || ECONNREFUSED == save_errno
+								UNIX_ONLY(|| ENOENT == save_errno))
 								need_connect = need_socket = TRUE;
 							save_errno = 0;
 							res = -1;	/* do the outer loop again */
@@ -337,6 +347,8 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 						break;
 					}
 				}
+				assert(FD_INVALID != sockptr->sd);
+				assertpro(FD_SETSIZE > sockptr->sd);
 				FD_ZERO(&writefds);
 				FD_SET(sockptr->sd, &writefds);
 				res = select(sockptr->sd + 1, NULL, &writefds, NULL, sel_time);
@@ -357,7 +369,8 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 							continue;
 						} else
 						{	/* return socket error */
-							if (ECONNREFUSED == sockerror || ETIMEDOUT == sockerror)
+							if (ECONNREFUSED == sockerror || ETIMEDOUT == sockerror
+								UNIX_ONLY(|| ENOENT == sockerror))
 							{	/* try until timeout */
 								last_errno = sockerror;
 								save_errno = 0;
@@ -393,7 +406,7 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 		{
 			if (FD_INVALID != sockptr->sd)
 			{
-				tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
+				close(sockptr->sd);	/* Don't leave a dangling socket around */
 				sockptr->sd = FD_INVALID;
 			}
 			if (NULL != sockptr->remote.ai_head)
@@ -428,18 +441,23 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 		{
 			DBGSOCK((stdout, "socconn: outofband interrupt received (%d) -- "
 				 "queueing mv_stent for wait intr\n", outofband));
+			if (!OUTOFBAND_RESTARTABLE(outofband))
+			{	/* the operation would not be resumed, no need to save socket device states */
+				if (!need_socket)
+				{
+					close(sockptr->sd);
+					sockptr->sd = FD_INVALID;
+				}
+				outofband_action(FALSE);
+				assertpro(FALSE);
+			}
 			if (need_connect)
 			{	/* no connect in progress */
-				tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
+				close(sockptr->sd);	/* Don't leave a dangling socket around */
 				sockptr->sd = FD_INVALID;
 				sockptr->state = socket_created;
 			} else
 				sockptr->state = socket_connect_inprogress;
-			if (NULL != sockptr->remote.ai_head)
-			{
-				freeaddrinfo(sockptr->remote.ai_head);
-				sockptr->remote.ai_head = NULL;
-			}
 			real_sockintr->who_saved = sockintr->who_saved = sockwhich_connect;
 			if (NO_M_TIMEOUT != timepar)
 			{
@@ -466,7 +484,7 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 			DBGSOCK((stdout, "socconn: mv_stent queued - endtime: %d/%d  interrupts: %d\n",
 				 end_time.at_sec, end_time.at_usec, socketus_interruptus));
 			outofband_action(FALSE);
-			GTMASSERT;      /* Should *never* return from outofband_action */
+			assertpro(FALSE);      /* Should *never* return from outofband_action */
 			return FALSE;   /* For the compiler.. */
 		}
 		hiber_start(100);
@@ -488,20 +506,29 @@ boolean_t iosocket_connect(socket_struct *sockptr, int4 timepar, boolean_t updat
 		freeaddrinfo(sockptr->remote.ai_head);
 		sockptr->remote.ai_head = NULL;
 	}
-	GETNAMEINFO(SOCKET_REMOTE_ADDR(sockptr), remote_ai_ptr->ai_addrlen, ipaddr, SA_MAXLEN, NULL, 0, NI_NUMERICHOST, errcode);
-	if (0 != errcode)
+	if (socket_local != sockptr->protocol)
 	{
-		if (FD_INVALID != sockptr->sd)
+		GETNAMEINFO(SOCKET_REMOTE_ADDR(sockptr), remote_ai_ptr->ai_addrlen, ipaddr, SA_MAXLEN, NULL, 0
+			, NI_NUMERICHOST, errcode);
+		if (0 != errcode)
 		{
-			tcp_routines.aa_close(sockptr->sd);	/* Don't leave a dangling socket around */
-			sockptr->sd = FD_INVALID;
+			if (FD_INVALID != sockptr->sd)
+			{
+				close(sockptr->sd);	/* Don't leave a dangling socket around */
+				sockptr->sd = FD_INVALID;
+			}
+			RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
+			return FALSE;
 		}
-		RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
-		return FALSE;
+		STRNDUP(ipaddr, SA_MAXLEN, sockptr->remote.saddr_ip);
+		strncpy(&iod->dollar.key[len], sockptr->remote.saddr_ip, DD_BUFLEN - 1 - len);
+#	ifndef VMS
+	} else
+	{
+		STRNCPY_STR(&iod->dollar.key[len], ((struct sockaddr_un *)(sockptr->remote.sa))->sun_path, DD_BUFLEN - len - 1);
+#	endif
 	}
-	STRNDUP(ipaddr, SA_MAXLEN, sockptr->remote.saddr_ip);
-	strncpy(&iod->dollar.key[len], sockptr->remote.saddr_ip, DD_BUFLEN - 1 - len);
-	iod->dollar.key[DD_BUFLEN-1] = '\0';			/* In case we fill the buffer */
+	iod->dollar.key[DD_BUFLEN - 1] = '\0';			/* In case we fill the buffer */
 
 	return TRUE;
 }
diff --git a/sr_port/iosocket_create.c b/sr_port/iosocket_create.c
index 474d494..e2ba300 100644
--- a/sr_port/iosocket_create.c
+++ b/sr_port/iosocket_create.c
@@ -28,21 +28,23 @@
 #include "gtm_string.h"
 #include "gtm_netdb.h"
 #include "gtm_socket.h"
+#include "gtm_un.h"
 #include "gtm_inet.h"
 #include "gtm_ipv6.h"
 #include "gtm_stdlib.h"
 
 #include "io.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "min_max.h"
 #include "gtm_caseconv.h"
 #include "util.h"
+#ifndef VMS
+#include "trans_log_name.h"
+#endif
 
-GBLREF	tcp_library_struct	tcp_routines;
 
+error_def(ERR_ADDRTOOLONG);
 error_def(ERR_GETSOCKNAMERR);
 error_def(ERR_GETADDRINFO);
 error_def(ERR_GETNAMEINFO);
@@ -56,25 +58,32 @@ error_def(ERR_SOCKINIT);
 #define PORT_PROTO_FORMAT "%hu:%3[^:]"
 #define	SEPARATOR ':'
 
-socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
+socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified)
 {
 	socket_struct		*socketptr;
 	socket_struct		*prev_socketptr;
 	socket_struct		*socklist_head;
-	bool			passive = FALSE;
+	boolean_t			passive = FALSE;
 	unsigned short		port;
-	int			ii, save_errno, tmplen, errlen;
-	char 			temp_addr[SA_MAXLITLEN], tcp[4], *adptr;
+	int			ii, save_errno, tmplen, errlen, sockaddrlen;
+	char 			temp_addr[SA_MAXLITLEN], protocolstr[6], *adptr;
 	const char		*errptr;
 	struct addrinfo		*ai_ptr;
 	struct addrinfo		hints, *addr_info_ptr = NULL;
+#ifndef VMS
+	struct sockaddr_un	*sa_un_ptr, sa_un_trans;
+	mval			localpath;
+	mstr			transpath;
+	int			trans_status;
+#endif
+	enum socket_protocol	protocol;
 	int			af;
 	int			sd;
 	int			errcode;
 	char			port_buffer[NI_MAXSERV];
 	int			port_buffer_len;
-	int			colon_cnt;
-	char			*last_2colon;
+	int			colon_cnt, protooffset;
+	char			*last_2colon = NULL;
 	int			addrlen;
 	GTM_SOCKLEN_TYPE	tmp_addrlen;
 
@@ -82,13 +91,16 @@ socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
 	{	/* no socket descriptor yet */
 		memset(&hints, 0, SIZEOF(hints));
 
-		colon_cnt = 0;
-		for (ii = strlen(sockaddr) - 1; 0 <= ii; ii--)
+		protooffset = colon_cnt = 0;
+		sockaddrlen = STRLEN(sockaddr);
+		for (ii = sockaddrlen - 1; 0 <= ii; ii--)
 		{
 			if (SEPARATOR == sockaddr[ii])
 			{
 				colon_cnt++;
-				if (2 == colon_cnt)
+				if (1 == colon_cnt)
+					protooffset = ii + 1;
+				else
 				{
 					last_2colon = &sockaddr[ii];
 					break;
@@ -100,95 +112,157 @@ socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
 			return NULL;
 		}
-		if (1 == colon_cnt)
-		{	/* for listening socket or broadcasting socket */
-			if (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, tcp) < 2)
-			{
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
-				return NULL;
-			}
-			passive = TRUE;
-			/* We always first try using IPv6 address, if supported */
-			af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
-			if (-1 == (sd = tcp_routines.aa_socket(af, SOCK_STREAM, IPPROTO_TCP)))
-			{
-				/* Try creating IPv4 socket */
-				af = AF_INET;
-				if (-1 == (sd = tcp_routines.aa_socket(af, SOCK_STREAM, IPPROTO_TCP)))
+		tmplen = sockaddrlen - protooffset;
+		if (SIZEOF(protocolstr) <= tmplen)
+		{	/* last piece just too big to be valid */
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
+			return NULL;
+		}
+		lower_to_upper((uchar_ptr_t)protocolstr, (uchar_ptr_t)&sockaddr[protooffset], tmplen);
+		if (((SIZEOF("TCP") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "TCP")))
+			protocol = socket_tcpip;
+#		ifndef VMS
+		else if (((SIZEOF("LOCAL") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "LOCAL")))
+			protocol = socket_local;
+#		endif
+		else
+		{
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
+			return NULL;
+		}
+		if (socket_tcpip == protocol)
+		{
+			if (1 == colon_cnt)
+			{	/* for listening socket or broadcasting socket */
+				if (!listen_specified || (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
 				{
-					save_errno = errno;
-					errptr = (char *)STRERROR(save_errno);
-					errlen = STRLEN(errptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
 					return NULL;
 				}
+				passive = TRUE;
+				/* We always first try using IPv6 address, if supported */
+				af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
+				if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
+				{
+					/* Try creating IPv4 socket */
+					af = AF_INET;
+					if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
+					{
+						save_errno = errno;
+						errptr = (char *)STRERROR(save_errno);
+						errlen = STRLEN(errptr);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno,
+							errlen, errptr);
+						return NULL;
+					}
+				}
+				SERVER_HINTS(hints, af);
+				port_buffer_len = 0;
+				I2A(port_buffer, port_buffer_len, port);
+				port_buffer[port_buffer_len]='\0';
+				if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr)))
+				{
+					close(sd);
+					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
+					return NULL;
+				}
+				SOCKET_ALLOC(socketptr);
+				socketptr->local.port = port;
+				socketptr->temp_sd = sd;
+				socketptr->sd = FD_INVALID;
+				ai_ptr = &(socketptr->local.ai);
+				memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo));
+				SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr);
+				ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr);
+				ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen;
+				ai_ptr->ai_next = NULL;
+				freeaddrinfo(addr_info_ptr);
+			} else
+			{	/* connection socket */
+				assert(2 == colon_cnt);
+				if (listen_specified || (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
+				{
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
+					return NULL;
+				}
+				/* for connection socket */
+				SPRINTF(port_buffer, "%hu", port);
+				addrlen = last_2colon - sockaddr;
+				if ('[' == sockaddr[0])
+				{
+					if (NULL == memchr(sockaddr, ']', addrlen))
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
+						return NULL;
+					}
+					addrlen -= 2;
+					memcpy(temp_addr, &sockaddr[1], addrlen);
+				} else
+					memcpy(temp_addr, sockaddr, addrlen);
+				temp_addr[addrlen] = 0;
+				CLIENT_HINTS(hints);
+				if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr)))
+				{
+					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
+					return NULL;
+				}
+				/*  we will test all address families in iosocket_connect() */
+				SOCKET_ALLOC(socketptr);
+				socketptr->remote.ai_head = addr_info_ptr;
+				socketptr->remote.port = port;
+				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
 			}
-			SERVER_HINTS(hints, af);
-			port_buffer_len = 0;
-			I2A(port_buffer, port_buffer_len, port);
-			port_buffer[port_buffer_len]='\0';
-			if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr)))
-			{
-				tcp_routines.aa_close(sd);
-				RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
-				return NULL;
-			}
+#		ifndef VMS
+		} else if (socket_local == protocol)
+		{	/* should we get_full_path first */
+			/* check protooffset < sizeof sun_path */
+			/* protooffset is after colon */
 			SOCKET_ALLOC(socketptr);
-			socketptr->local.port = port;
-			socketptr->temp_sd = sd;
-			socketptr->sd = FD_INVALID;
-			ai_ptr = &(socketptr->local.ai);
-			memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo));
-			SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr);
-			ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr);
-			ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen;
-			ai_ptr->ai_next = NULL;
-			freeaddrinfo(addr_info_ptr);
-		} else
-		{	/* connection socket */
-			assert(2 == colon_cnt);
-			if (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, tcp) < 2)
-			{
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
+			socketptr->protocol = socket_local;
+			sa_un_ptr = malloc(SIZEOF(struct sockaddr_un));
+			sa_un_ptr->sun_family = AF_UNIX;
+			MV_INIT_STRING(&localpath, protooffset - 1, sockaddr);
+			trans_status = TRANS_LOG_NAME(&localpath.str, &transpath, sa_un_trans.sun_path,
+				(int)SIZEOF(sa_un_trans.sun_path), dont_sendmsg_on_log2long);
+			if (SS_LOG2LONG == trans_status)
+			{	/* if LOG2LONG, returned len not valid so report untranslated length */
+				SOCKET_FREE(socketptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ADDRTOOLONG, 4, localpath.str.len, localpath.str.addr,
+					localpath.str.len, SIZEOF(sa_un_trans.sun_path));
 				return NULL;
 			}
-			/* for connection socket */
-			SPRINTF(port_buffer, "%hu", port);
-			addrlen = last_2colon - sockaddr;
-			if ('[' == sockaddr[0])
+			memcpy(sa_un_ptr->sun_path, transpath.addr, transpath.len);
+			sa_un_ptr->sun_path[transpath.len] = '\0';
+			if (listen_specified)
 			{
-				if (NULL == memchr(sockaddr, ']', addrlen))
+				passive = TRUE;
+				socketptr->local.sa = (struct sockaddr *)sa_un_ptr;
+				socketptr->local.ai.ai_family = AF_UNIX;
+				socketptr->local.ai.ai_socktype = SOCK_STREAM;
+				socketptr->local.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
+				if (-1 == (sd = socket(AF_UNIX, SOCK_STREAM, 0)))
 				{
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
+					save_errno = errno;
+					SOCKET_FREE(socketptr);
+					errptr = (char *)STRERROR(save_errno);
+					errlen = STRLEN(errptr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr);
 					return NULL;
 				}
-				addrlen -= 2;
-				memcpy(temp_addr, &sockaddr[1], addrlen);
+				socketptr->temp_sd = sd;
+				socketptr->sd = FD_INVALID;
 			} else
-				memcpy(temp_addr, sockaddr, addrlen);
-			temp_addr[addrlen] = 0;
-			CLIENT_HINTS(hints);
-			if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr)))
 			{
-				RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
-				return NULL;
+				socketptr->remote.sa = (struct sockaddr *)sa_un_ptr;
+				/* setup remote fields */
+				socketptr->remote.ai.ai_family = AF_UNIX;
+				socketptr->remote.ai.ai_socktype = SOCK_STREAM;
+				socketptr->remote.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
+				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
 			}
-			/*  we will test all address families in iosocket_connect() */
-			SOCKET_ALLOC(socketptr);
-			socketptr->remote.ai_head = addr_info_ptr;
-			socketptr->remote.port = port;
-			socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
-		}
-		lower_to_upper((uchar_ptr_t)tcp, (uchar_ptr_t)tcp, SIZEOF("TCP") - 1);
-		if (0 == MEMCMP_LIT(tcp, "TCP"))
-		{
-			socketptr->protocol = socket_tcpip;
+#		endif
 		} else
-		{
-			SOCKET_FREE(socketptr);
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, MIN(strlen(tcp), SIZEOF("TCP") - 1), tcp);
-			return NULL;
-		}
+			assertpro(socket_tcpip == protocol || socket_local == protocol);	/* protocol already checked */
 		socketptr->state = socket_created;
 		SOCKET_BUFFER_INIT(socketptr, bfsize);
 		socketptr->passive = passive;
@@ -202,7 +276,7 @@ socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
 		socketptr->temp_sd = FD_INVALID;
 		ai_ptr = &(socketptr->local.ai);
 		tmp_addrlen = SIZEOF(struct sockaddr_storage);
-		if (-1 == tcp_routines.aa_getsockname(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), &tmp_addrlen))
+		if (-1 == getsockname(socketptr->sd, SOCKET_LOCAL_ADDR(socketptr), &tmp_addrlen))
 		{
 			save_errno = errno;
 			errptr = (char *)STRERROR(save_errno);
@@ -213,7 +287,8 @@ socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
 		}
 		ai_ptr->ai_addrlen = tmp_addrlen;
 		/* extract port information */
-		GETNAMEINFO(SOCKET_LOCAL_ADDR(socketptr), tmp_addrlen, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
+		GETNAMEINFO(SOCKET_LOCAL_ADDR(socketptr), tmp_addrlen, NULL, 0, port_buffer,
+			NI_MAXSERV, NI_NUMERICSERV, errcode);
 		if (0 != errcode)
 		{
 			SOCKET_FREE(socketptr);
@@ -233,8 +308,8 @@ socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des)
 		}
 		socketptr->remote.ai.ai_addrlen = tmp_addrlen;
 		assert(0 != SOCKET_REMOTE_ADDR(socketptr)->sa_family);
-		GETNAMEINFO(SOCKET_REMOTE_ADDR(socketptr), socketptr->remote.ai.ai_addrlen, NULL, 0, port_buffer, NI_MAXSERV,
-				NI_NUMERICSERV, errcode);
+		GETNAMEINFO(SOCKET_REMOTE_ADDR(socketptr), socketptr->remote.ai.ai_addrlen, NULL, 0,
+			 port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
 		if (0 != errcode)
 		{
 			SOCKET_FREE(socketptr);
diff --git a/sr_port/iosocket_delimiter.c b/sr_port/iosocket_delimiter.c
index eb74541..aa9a23c 100644
--- a/sr_port/iosocket_delimiter.c
+++ b/sr_port/iosocket_delimiter.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,7 +20,6 @@
 
 #include "io.h"
 #include "iottdef.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "gtm_conv.h"
@@ -114,7 +113,7 @@ boolean_t iosocket_delimiter(unsigned char *delimiter_buffer, int4 delimiter_len
 		}
 		if (counter > MAX_DELIM_LEN)
 		{
-			rts_error(VARLSTCNT(1) ERR_DELIMSIZNA);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DELIMSIZNA);
 			return FALSE;
 		}
 	}
@@ -140,7 +139,7 @@ void iosocket_delim_conv(socket_struct *socketptr, gtm_chset_t to_chset)
 		assert(MAX_DELIM_LEN > new_delim_len);
 		if (MAX_DELIM_LEN < new_delim_len)
 		{
-			rts_error(VARLSTCNT(1) ERR_DELIMSIZNA);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DELIMSIZNA);
 			return;
 		}
 		socketptr->idelimiter[delim_index].len = new_delim_len;
diff --git a/sr_port/iosocket_destroy.c b/sr_port/iosocket_destroy.c
index b9fbce9..c312767 100644
--- a/sr_port/iosocket_destroy.c
+++ b/sr_port/iosocket_destroy.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,8 +16,6 @@
 #include "gtm_socket.h"
 
 #include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "iosocketdef.h"
 #include "gtmio.h"
 
diff --git a/sr_port/iosocket_flush.c b/sr_port/iosocket_flush.c
index d5f627c..3160184 100644
--- a/sr_port/iosocket_flush.c
+++ b/sr_port/iosocket_flush.c
@@ -20,13 +20,9 @@
 #include "gtm_string.h"
 
 #include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 
-GBLREF tcp_library_struct       tcp_routines;
-
 error_def(ERR_SOCKWRITE);
 error_def(ERR_TEXT);
 error_def(ERR_CURRSOCKOFR);
@@ -53,8 +49,8 @@ void iosocket_flush(io_desc *iod)
 		return;
 	}
         memcpy(iod->dollar.device, "0", SIZEOF("0"));
-        if ( -1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &on, SIZEOF(on)) ||
-		(-1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &off, SIZEOF(off))))
+        if ( -1 == setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &on, SIZEOF(on)) ||
+		(-1 == setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &off, SIZEOF(off))))
         {
 		errptr = (char *)STRERROR(errno);
                 errlen = strlen(errptr);
diff --git a/sr_port/iosocket_handle.c b/sr_port/iosocket_handle.c
index 754d7a5..f0e0c11 100644
--- a/sr_port/iosocket_handle.c
+++ b/sr_port/iosocket_handle.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -39,8 +39,6 @@
 
 #include "io_params.h"
 #include "io.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 
diff --git a/sr_port/iosocket_iocontrol.c b/sr_port/iosocket_iocontrol.c
index f1fb417..2f5c3e1 100644
--- a/sr_port/iosocket_iocontrol.c
+++ b/sr_port/iosocket_iocontrol.c
@@ -20,17 +20,23 @@
 
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "gtm_caseconv.h"
 #include "stringpool.h"
+#include "min_max.h"
 
 GBLREF spdesc		stringpool;
 GBLREF io_pair		io_curr_device;
 
 error_def(ERR_INVCTLMNE);
 
+/* for iosocket_dlr_zkey */
+#define LISTENING	"LISTENING|"
+#define READ		"READ|"
+#define MAXEVENTLITLEN	(SIZEOF(LISTENING)-1)
+#define MAXZKEYITEMLEN	(MAX_HANDLE_LEN + SA_MAXLITLEN + MAXEVENTLITLEN + 2)	/* 1 pipe and a semicolon */
+
 void	iosocket_iocontrol(mstr *d)
 {
 	char 		action[MAX_DEVCTL_LENGTH];
@@ -99,3 +105,115 @@ void	iosocket_dlr_key(mstr *d)
         d->len = len;
         return;
 }
+
+void iosocket_dlr_zkey(mstr *d)
+{
+	int4		ii;
+	int		len, thislen, totlen;
+	char		*zkeyptr, *charptr;
+	io_desc		*iod;
+	d_socket_struct	*dsocketptr;
+	socket_struct	*socketptr;
+
+	iod = io_curr_device.out;
+	if (gtmsocket != iod->type)
+		iod = io_curr_device.in;
+	assertpro(gtmsocket == iod->type);
+	dsocketptr = (d_socket_struct *)iod->dev_sp;
+	zkeyptr = (char *)stringpool.free;
+	totlen = thislen = len = 0;
+	for (ii = 0; ii < dsocketptr->n_socket; ii++)
+	{
+		socketptr = dsocketptr->socket[ii];
+		if ((socket_listening != socketptr->state) && (socket_connected != socketptr->state))
+			continue;
+		if ((socket_connected == socketptr->state) && (0 < socketptr->buffered_length))
+		{	/* data to be read in buffer */
+			if (!socketptr->pendingevent)
+			{	/* may have been cleared by partial READ */
+				socketptr->pendingevent = TRUE;
+				socketptr->readycycle = dsocketptr->waitcycle;
+			}
+		}
+		if (socketptr->pendingevent)
+		{
+			thislen = len = 0;
+			if (!IS_STP_SPACE_AVAILABLE(totlen + MAXZKEYITEMLEN))
+			{	/* d must be mstr part of mval known to stp_gcol */
+				if (totlen)
+				{
+					d->len = totlen;
+					d->addr = (char *)stringpool.free;
+					stringpool.free += totlen;
+				}
+				INVOKE_STP_GCOL(totlen + MAXZKEYITEMLEN);
+				if (totlen)
+				{
+					if (!IS_AT_END_OF_STRINGPOOL(d->addr, totlen))
+					{	/* need to move to top */
+						memcpy(stringpool.free, d->addr, totlen);
+					} else
+						stringpool.free -= totlen;	/* backup over prior items */
+					d->len = 0;	/* so ignored by stp_gcol */
+				}
+				zkeyptr = (char *)stringpool.free + totlen;
+			}
+			if (totlen)
+			{	/* at least one item already */
+				*zkeyptr++ = ';';
+				totlen++;
+			}
+			/* add READ/LISTENING|handle|remoteinfo;... */
+			if (socket_listening == socketptr->state)
+			{
+				thislen = len = SIZEOF(LISTENING) - 1;
+				memcpy(zkeyptr, LISTENING, len);
+			} else
+			{
+				thislen = len = SIZEOF(READ) - 1;
+				memcpy(zkeyptr, READ, len);
+			}
+			zkeyptr += len;
+			thislen += len;
+			totlen += len;
+			memcpy(zkeyptr, socketptr->handle, socketptr->handle_len);
+			zkeyptr += socketptr->handle_len;
+			*zkeyptr++ = '|';
+			thislen += (socketptr->handle_len + 1);
+			totlen += (socketptr->handle_len + 1);
+			if (socket_local != socketptr->protocol)
+			{
+				if (socket_listening == socketptr->state)
+					len = SPRINTF(zkeyptr, "%d", socketptr->local.port);
+				else
+				{
+					if (NULL != socketptr->remote.saddr_ip)
+					{
+						len = STRLEN(socketptr->remote.saddr_ip);
+						memcpy(zkeyptr, socketptr->remote.saddr_ip, len);
+					} else
+						len = 0;
+				}
+#			ifndef VMS
+			} else
+			{
+				if (NULL != socketptr->local.sa)
+					charptr = ((struct sockaddr_un *)(socketptr->local.sa))->sun_path;
+				else if (NULL != socketptr->remote.sa)
+					charptr = ((struct sockaddr_un *)(socketptr->remote.sa))->sun_path;
+				else
+					charptr = "";
+				len = STRLEN(charptr);
+				len = MIN(len, (MAXZKEYITEMLEN - thislen));
+				memcpy(zkeyptr, charptr, len);
+#			endif
+			}
+			zkeyptr += len;
+			totlen += len;
+		}
+	}
+	d->addr = (char *)stringpool.free;
+	d->len = totlen;
+	stringpool.free += totlen;
+	return;
+}
diff --git a/sr_port/iosocket_listen.c b/sr_port/iosocket_listen.c
index e944291..f0aa18e 100644
--- a/sr_port/iosocket_listen.c
+++ b/sr_port/iosocket_listen.c
@@ -24,16 +24,13 @@
 
 #include "io_params.h"
 #include "io.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 
-GBLREF tcp_library_struct	tcp_routines;
-
 error_def(ERR_CURRSOCKOFR);
 error_def(ERR_LISTENPASSBND);
 error_def(ERR_LQLENGTHNA);
+error_def(ERR_NOSOCKETINDEV);
 error_def(ERR_SOCKLISTEN);
 error_def(ERR_TEXT);
 
@@ -42,32 +39,47 @@ error_def(ERR_TEXT);
 
 boolean_t iosocket_listen(io_desc *iod, unsigned short len)
 {
-	char		*errptr;
-	int4		errlen;
 	d_socket_struct	*dsocketptr;
 	socket_struct	*socketptr;
 
-	if (MAX_LISTEN_QUEUE_LENGTH < len)
+	assert(gtmsocket == iod->type);
+	dsocketptr = (d_socket_struct *)iod->dev_sp;
+	if (0 >= dsocketptr->n_socket)
 	{
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_LQLENGTHNA, 1, len);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
 		return FALSE;
 	}
-	assert(gtmsocket == iod->type);
-	dsocketptr = (d_socket_struct *)iod->dev_sp;
-	socketptr = dsocketptr->socket[dsocketptr->current_socket];
 	if (dsocketptr->current_socket >= dsocketptr->n_socket)
 	{
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
 		return FALSE;
 	}
-	if ((socketptr->state != socket_bound) || (TRUE != socketptr->passive))
+	socketptr = dsocketptr->socket[dsocketptr->current_socket];
+	assert(socketptr && (socketptr->dev == dsocketptr));
+
+	return iosocket_listen_sock(socketptr, len);
+}
+
+boolean_t iosocket_listen_sock(socket_struct *socketptr, unsigned short len)
+{
+	char		*errptr;
+	int4		errlen;
+	d_socket_struct	*dsocketptr;
+
+	if (MAX_LISTEN_QUEUE_LENGTH < len)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_LQLENGTHNA, 1, len);
+		return FALSE;
+	}
+	if (((socketptr->state != socket_bound) && (socketptr->state != socket_listening)) || (TRUE != socketptr->passive))
 	{
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_LISTENPASSBND);
 		return FALSE;
 	}
+	dsocketptr = socketptr->dev;
 	dsocketptr->iod->dollar.key[0] = '\0';
 	/* establish a queue of length len for incoming connections */
-	if (-1 == tcp_routines.aa_listen(socketptr->sd, len))
+	if (-1 == listen(socketptr->sd, len))
 	{
 		errptr = (char *)STRERROR(errno);
 		errlen = STRLEN(errptr);
@@ -81,6 +93,14 @@ boolean_t iosocket_listen(io_desc *iod, unsigned short len)
 	memcpy(&dsocketptr->iod->dollar.key[len], socketptr->handle, socketptr->handle_len);
 	len += socketptr->handle_len;
 	dsocketptr->iod->dollar.key[len++] = '|';
-	SPRINTF(&dsocketptr->iod->dollar.key[len], "%d", socketptr->local.port);
+	if (socket_local != socketptr->protocol)
+		SPRINTF(&dsocketptr->iod->dollar.key[len], "%d", socketptr->local.port);
+#	ifndef VMS
+	else
+	{
+		STRNCPY_STR(&dsocketptr->iod->dollar.key[len],
+			((struct sockaddr_un *)(socketptr->local.sa))->sun_path, DD_BUFLEN - len - 1);
+	}
+#	endif
 	return TRUE;
 }
diff --git a/sr_port/iosocket_open.c b/sr_port/iosocket_open.c
index 7673162..59e260a 100644
--- a/sr_port/iosocket_open.c
+++ b/sr_port/iosocket_open.c
@@ -14,6 +14,10 @@
 
 #include "gtm_string.h"
 #include "gtm_stdio.h"
+#ifndef VMS
+#include "gtm_stdlib.h"
+#include "gtm_stat.h"
+#endif
 #include "gtm_socket.h"
 #include "gtm_inet.h"
 #include "gtm_time.h"
@@ -21,9 +25,6 @@
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcp_select.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "io_params.h"
 #include "iosocketdef.h"
 #include "gtm_caseconv.h"
@@ -31,8 +32,8 @@
 #include "gtm_conv.h"
 #include "gtm_utf8.h"
 #include "gtm_netdb.h"
+#include "gtm_unistd.h"
 
-GBLREF 	tcp_library_struct	tcp_routines;
 GBLREF	d_socket_struct		*socket_pool, *newdsocket;
 GBLREF	io_pair			io_std_device;	/* standard device */
 GBLREF	boolean_t		gtm_utf8_mode;
@@ -62,7 +63,7 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 {
 	char			addr[SA_MAXLITLEN], *errptr, sockaddr[SA_MAXLITLEN],
 		                temp_addr[SA_MAXLITLEN], dev_type[MAX_DEV_TYPE_LEN];
-	unsigned char		ch, *c, *next, *top;
+	unsigned char		ch, *c, *start, *next, *top;
 	int			handle_len, moreread_timeout, len;
 	unsigned short		port;
 	int4			errlen, msec_timeout, real_errno, p_offset = 0, zff_len, delimiter_len;
@@ -72,7 +73,7 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 	fd_set			tcp_fd;
 	uint4			bfsize = DEFAULT_SOCKET_BUFFER_SIZE, ibfsize;
         d_socket_struct         *dsocketptr;
-	socket_struct		*socketptr;
+	socket_struct		*socketptr = NULL;
 	mv_stent		*mv_zintdev;
 	boolean_t		zint_conn_restart = FALSE;
 	socket_interrupt	*sockintr;
@@ -86,6 +87,7 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 		                ibfsize_specified = FALSE,
 		                moreread_specified = FALSE,
 		                is_principal = FALSE,	/* called from inetd */
+				newversion = FALSE,	/* for local sockets */
 		                ichset_specified,
 		                ochset_specified;
 	unsigned char 		delimiter_buffer[MAX_N_DELIMITER * (MAX_DELIM_LEN + 1)], zff_buffer[MAX_ZFF_LEN];
@@ -95,6 +97,12 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 	char			ipaddr[SA_MAXLEN];
 	int			errcode;
 	struct addrinfo		*ai_ptr, *remote_ai_ptr;
+#ifndef VMS
+	uic_struct_int		uic;
+	uint			filemode;
+	uint			filemode_mask;
+	unsigned long		uicvalue;
+#endif
 
 	ioptr = dev->iod;
 	assert((params) *(pp->str.addr + p_offset) < (unsigned char)n_iops);
@@ -127,25 +135,22 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 		ioptr->width	= TCPDEF_WIDTH;
 		ioptr->length	= TCPDEF_LENGTH;
 		ioptr->wrap	= TRUE;
-		if (-1 == iotcp_fillroutine())
-			assert(FALSE);
-		if (!io_std_device.in)
+		dsocketptr->current_socket = -1;	/* 1st socket is 0 */
+		if ((2 > file_des) && (0 <= file_des) && (!io_std_device.in || !io_std_device.out))
 			/* called from io_init */
 			is_principal = TRUE;
 	}
         if (dsocketptr->mupintr)
 	{	/* check if connect was interrupted */
 		sockintr = &dsocketptr->sock_save_state;
-		if (sockwhich_invalid == sockintr->who_saved)
-			GTMASSERT;	/* Interrupt should never have an invalid save state */
+		assertpro(sockwhich_invalid != sockintr->who_saved);	/* Interrupt should never have an invalid save state */
 		if (dollar_zininterrupt)
 		{
 			dsocketptr->mupintr = FALSE;
 			sockintr->who_saved = sockwhich_invalid;
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
 		}
-		if (sockwhich_connect != sockintr->who_saved)
-			GTMASSERT;	/* ZINTRECURSEIO should have caught */
+		assertpro(sockwhich_connect == sockintr->who_saved);	/* ZINTRECURSEIO should have caught */
 		mv_zintdev = io_find_mvstent(dsocketptr->iod, FALSE);
 		if (mv_zintdev && mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid)
 		{	/* mupintr will be reset and mvstent popped in iosocket_connect */
@@ -168,6 +173,11 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 		memcpy(ioptr->dollar.device, "0", SIZEOF("0"));
 		zff_len = -1; /* indicates neither ZFF nor ZNOFF specified */
 		delimiter_len = -1; /* indicates neither DELIM nor NODELIM specified */
+#		ifndef VMS
+		filemode = filemode_mask = 0;
+		uic.mem = (uid_t)-1;		/* flag as not specified */
+		uic.grp = (gid_t)-1;
+#		endif
 		ichset_specified = ochset_specified = FALSE;
 		while (iop_eol != (ch = *(pp->str.addr + p_offset++)))
 		{
@@ -339,6 +349,43 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 								 MAX_MOREREAD_TIMEOUT);
 					moreread_specified = TRUE;
 					break;
+#				ifndef VMS
+				case iop_newversion:
+					newversion = TRUE;
+					break;
+				case iop_uic:
+					start = (unsigned char *)pp->str.addr + p_offset;
+					top = (unsigned char *)pp->str.addr + p_offset + 1 + *start;
+					next = ++start;		/* past length */
+					uicvalue = 0;
+					while ((',' != *next) && (('0' <= *next) && ('9' >= *next)) && (next < top))
+						uicvalue = (10 * uicvalue) + (*next++ - '0');
+					if (start < next)
+						uic.mem = uicvalue;
+					if (',' == *next)
+					{
+						start = ++next;
+						uicvalue = 0;
+						while ((',' != *next) && (('0' <= *next) && ('9' >= *next)) && (next < top))
+							uicvalue = (10 * uicvalue) + (*next++ - '0');
+						if (start < next)
+							uic.grp = uicvalue;
+					}
+					break;
+				case iop_w_protection:
+					filemode_mask |= S_IRWXO;
+					filemode |= *(pp->str.addr + p_offset);
+					break;
+				case iop_g_protection:
+					filemode_mask |= S_IRWXG;
+					filemode |= *(pp->str.addr + p_offset) << 3;
+					break;
+				case iop_s_protection:
+				case iop_o_protection:
+					filemode_mask |= S_IRWXU;
+					filemode |= *(pp->str.addr + p_offset) << 6;
+					break;
+#				endif
 				default:
 					break;
 			}
@@ -367,7 +414,7 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 		}
 		if (listen_specified || connect_specified || is_principal)
 		{
-			if (NULL == (socketptr = iosocket_create(sockaddr, bfsize, is_principal ? file_des : -1)))
+			if (NULL == (socketptr = iosocket_create(sockaddr, bfsize, is_principal ? file_des : -1, listen_specified)))
 				return FALSE;
 			assert(listen_specified == socketptr->passive);
 			if (ioerror_specified)
@@ -380,13 +427,24 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 				socketptr->moreread_timeout = moreread_timeout;
 				socketptr->def_moreread_timeout = TRUE; /* iosocket_readfl.c needs to know user specified */
 			}
+#			ifndef VMS
+			if (listen_specified)
+			{	/* for LOCAL sockets */
+				if (filemode_mask)
+				{
+					socketptr->filemode_mask = filemode_mask;
+					socketptr->filemode = filemode;
+				}
+				socketptr->uic = uic;	/* -1 is no change */
+			}
+#			endif
                	 /* socket handle -- also check for duplication */
 			if (attach_specified)
 			{
 				if (iosocket_handle(sock_handle, &handle_len, FALSE, newdsocket) >= 0)
 				{
 					if (FD_INVALID != socketptr->temp_sd)
-						tcp_routines.aa_close(socketptr->temp_sd);
+						close(socketptr->temp_sd);
 					SOCKET_FREE(socketptr);
 					assert(ioptr->newly_created == FALSE);
 					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SOCKETEXIST, 2, handle_len, sock_handle);
@@ -411,7 +469,7 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 			{
 				assert(ioptr->newly_created == FALSE);
 				if (FD_INVALID != socketptr->temp_sd)
-					tcp_routines.aa_close(socketptr->temp_sd);
+					close(socketptr->temp_sd);
 				SOCKET_FREE(socketptr);
 				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets);
 				return FALSE;
@@ -420,8 +478,8 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 			newdsocket->socket[newdsocket->n_socket++] = socketptr;
 			newdsocket->current_socket = newdsocket->n_socket - 1;
 		}
-		if (0 <= zff_len && /* ZFF or ZNOFF specified */
-		    0 < (socketptr->zff.len = zff_len)) /* assign the new ZFF len, might be 0 from ZNOFF, or ZFF="" */
+		if (socketptr && (0 <= zff_len) && /* ZFF or ZNOFF specified */
+		    (0 < (socketptr->zff.len = zff_len))) /* assign the new ZFF len, might be 0 from ZNOFF, or ZFF="" */
 		{ /* ZFF="non-zero-len-string" specified */
 			if (gtm_utf8_mode) /* Check if ZFF has any invalid UTF-8 character */
 			{ /* Note: the ZFF string originates from the source program, so is in UTF-8 mode or M mode regardless
@@ -434,11 +492,12 @@ short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4
 		}
 	}
 	/* action */
-	if ((listen_specified && (!iosocket_bind(socketptr, timepar, ibfsize_specified))) ||
-	    (connect_specified && (!iosocket_connect(socketptr, timepar, ibfsize_specified))))
-       	{
+	if ((listen_specified && ((!iosocket_bind(socketptr, timepar, ibfsize_specified, newversion))
+			|| (!iosocket_listen_sock(socketptr, DEFAULT_LISTEN_DEPTH))))
+		|| (connect_specified && (!iosocket_connect(socketptr, timepar, ibfsize_specified))))
+	{
 		if (socketptr->sd > 0)
-			(void)tcp_routines.aa_close(socketptr->sd);
+			(void)close(socketptr->sd);
 		SOCKET_FREE(socketptr);
 		return FALSE;
 	} else if (is_principal)
diff --git a/sr_port/iosocket_poolinit.c b/sr_port/iosocket_poolinit.c
index 96de3f5..413f7df 100644
--- a/sr_port/iosocket_poolinit.c
+++ b/sr_port/iosocket_poolinit.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -15,14 +15,13 @@
 
 #include "gtm_string.h"
 
-#include <unistd.h>
+#include "gtm_unistd.h"
 #include "gtm_socket.h"
 #include "gtm_inet.h"
 
 #include "io.h"
 #include "io_params.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "op.h"
diff --git a/sr_port/iosocket_rdone.c b/sr_port/iosocket_rdone.c
index 339acb0..20b7bd6 100644
--- a/sr_port/iosocket_rdone.c
+++ b/sr_port/iosocket_rdone.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,6 @@
 #include "gtm_inet.h"
 #include "io.h"
 #include "gt_timer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 #include "gtm_utf8.h"
 
@@ -51,7 +50,7 @@ int	iosocket_rdone(mint *v, int4 timeout)
 					UTF16LE_MBTOWC(tmp.str.addr, tmp.str.addr + tmp.str.len, codepoint);
 					break;
 				default:
-					GTMASSERT;
+					assertpro(ichset != ichset);
 			}
 			UNICODE_ONLY(assert(WEOF != codepoint));
 		} else
diff --git a/sr_port/iosocket_read.c b/sr_port/iosocket_read.c
index 05162ed..874f88a 100644
--- a/sr_port/iosocket_read.c
+++ b/sr_port/iosocket_read.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,6 @@
 #include "gtm_inet.h"
 #include "io.h"
 #include "gt_timer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 
 int	iosocket_read(mval *v, int4 timeout)
diff --git a/sr_port/iosocket_readfl.c b/sr_port/iosocket_readfl.c
index 814b7b2..8aa9066 100644
--- a/sr_port/iosocket_readfl.c
+++ b/sr_port/iosocket_readfl.c
@@ -27,8 +27,6 @@
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "stringpool.h"
 #include "iosocketdef.h"
 #include "min_max.h"
@@ -247,8 +245,11 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 		bytes_read = 0;
 		chars_read = 0;
 		buffer_start = NULL;
+		socketptr->pendingevent = FALSE;
+		socketptr->lastaction = dsocketptr->waitcycle;
 	} else
 	{
+		assert(bytes_read);
 		max_bufflen = sockintr->max_bufflen;
 		chars_read = sockintr->chars_read;
 		assert(chars_read <= bytes_read);
@@ -259,7 +260,7 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 								     end_time.at_usec)));
 		DBGSOCK((stdout, "socrfl: .. buffer address: 0x"lvaddr"  stringpool: 0x"lvaddr"\n",
 			 buffer_start, stringpool.free));
-		if (stringpool.free != (buffer_start + bytes_read))	/* BYPASSOK */
+		if (!IS_AT_END_OF_STRINGPOOL(buffer_start, bytes_read))
 		{	/* Not @ stringpool.free - must move what we have, so we need room for the whole anticipated message */
 			DBGSOCK2((stdout, "socrfl: .. Stuff put on string pool after our buffer\n"));
 			stp_need = max_bufflen;
@@ -279,14 +280,14 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 			buffer_start = (unsigned char *)v->str.addr;
 			TRCTBL_ENTRY(SOCKRFL_RSTGC, 0, buffer_start, stringpool.free, NULL);
 		}
-		if ((buffer_start + bytes_read) < stringpool.free)		/* BYPASSOK */
+		assert((buffer_start + bytes_read) <= stringpool.free);	/* BYPASSOK */
+		if (!IS_AT_END_OF_STRINGPOOL(buffer_start, bytes_read))
 		{	/* Now need to move it to the top */
 			assert(stp_need == max_bufflen);
 			memcpy(stringpool.free, buffer_start, bytes_read);	/* BYPASSOK */
 			buffer_start = stringpool.free;				/* BYPASSOK */
 		} else
 		{	/* It should still be just under the used space */
-			assert((buffer_start + bytes_read) == stringpool.free);	/* BYPASSOK */
 			stringpool.free = buffer_start;		/* backup the free pointer */
 		}
 		v->str.len = 0;		/* Clear incase interrupt or error -- don't want to hold this buffer */
@@ -406,7 +407,7 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 				assert(stringpool.free <= stringpool.top);					/* BYPASSOK */
 				INVOKE_STP_GCOL(max_bufflen);
 				old_stringpool_free = stringpool.free;						/* BYPASSOK */
-				assert(stringpool.free == (unsigned char *)(v->str.addr + v->str.len));		/* BYPASSOK */
+				assert(IS_AT_END_OF_STRINGPOOL(v->str.addr, v->str.len));
 				stringpool.free = (unsigned char *)v->str.addr;
 				v->str.len = 0; /* If interrupted, don't hold onto old space */
 				TRCTBL_ENTRY(SOCKRFL_EXPBUFGC, bytes_read, stringpool.free, old_stringpool_free, /* BYPASSOK */
@@ -465,7 +466,7 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 							assert(stringpool.free <= stringpool.top);
 							INVOKE_STP_GCOL(max_bufflen);
 							old_stringpool_free = stringpool.free;
-							assert(stringpool.free == (unsigned char *)(v->str.addr + v->str.len));
+							assert(IS_AT_END_OF_STRINGPOOL(v->str.addr, v->str.len));
 							stringpool.free = (unsigned char *)v->str.addr;
 							v->str.len = 0; /* If interrupted, don't hold onto old space */
 							TRCTBL_ENTRY(SOCKRFL_EXPBUFGC, bytes_read, stringpool.free, /* BYPASSOK */
@@ -817,7 +818,7 @@ int	iosocket_readfl(mval *v, int4 width, int4 timeout)
 								    timeout, msec_timeout)));
 		TRCTBL_ENTRY(SOCKRFL_OUTOFBAND, bytes_read, (INTPTR_T)chars_read, stringpool.free, NULL);	/* BYPASSOK */
 		outofband_action(FALSE);
-		GTMASSERT;	/* Should *never* return from outofband_action */
+		assertpro(FALSE);	/* Should *never* return from outofband_action */
 		return FALSE;	/* For the compiler.. */
 	}
 	if (0 < chars_read)
diff --git a/sr_port/iosocket_snr.c b/sr_port/iosocket_snr.c
index b95a8e9..9ed6573 100644
--- a/sr_port/iosocket_snr.c
+++ b/sr_port/iosocket_snr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -44,7 +44,6 @@
 #include "gtm_string.h"
 #ifdef UNIX
 #include "gtm_fcntl.h"
-#include "eintr_wrappers.h"
 static int fcntl_res;
 #ifdef DEBUG
 #include <sys/time.h>		/* for gettimeofday */
@@ -53,11 +52,11 @@ static int fcntl_res;
 #include <sys/poll.h>
 #endif
 #endif
+#include "gtm_select.h"
+#include "eintr_wrappers.h"
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "stringpool.h"
 #include "iosocketdef.h"
 #include "min_max.h"
@@ -77,7 +76,6 @@ static	struct timeval tvbefore, tvafter;
 GBLREF	io_pair 		io_curr_device;
 GBLREF	bool			out_of_time;
 GBLREF	spdesc 			stringpool;
-GBLREF	tcp_library_struct	tcp_routines;
 GBLREF	int4			outofband;
 
 /* Local routine we aren't making static due to increased debugging difficult static routines make */
@@ -149,7 +147,7 @@ ssize_t iosocket_snr_io(socket_struct *socketptr, void *buffer, size_t maxlength
 {
 	int		status, bytesread, real_errno;
 	fd_set		tcp_fd;
-	ABS_TIME	lcl_time_for_read;
+	struct timeval	lcl_time_for_read;
 #	ifdef GTM_USE_POLL_FOR_SUBSECOND_SELECT
 	long		poll_timeout;
 	unsigned long	poll_nfds;
@@ -161,11 +159,13 @@ ssize_t iosocket_snr_io(socket_struct *socketptr, void *buffer, size_t maxlength
 	DBGSOCK2((stdout, "time_for_read->at_sec: %d  usec: %d\n", time_for_read->at_sec, time_for_read->at_usec));
 	DEBUG_ONLY(gettimeofday(&tvbefore, NULL);)
 #ifndef GTM_USE_POLL_FOR_SUBSECOND_SELECT
-        FD_ZERO(&tcp_fd);
-        FD_SET(socketptr->sd, &tcp_fd);
-        assert(0 != FD_ISSET(socketptr->sd, &tcp_fd));
-        lcl_time_for_read = *time_for_read;
-        status = tcp_routines.aa_select(socketptr->sd + 1, (void *)(&tcp_fd), (void *)0, (void *)0, &lcl_time_for_read);
+	assertpro(FD_SETSIZE > socketptr->sd);
+	FD_ZERO(&tcp_fd);
+	FD_SET(socketptr->sd, &tcp_fd);
+	assert(0 != FD_ISSET(socketptr->sd, &tcp_fd));
+	lcl_time_for_read.tv_sec = time_for_read->at_sec;
+	lcl_time_for_read.tv_usec = (gtm_tv_usec_t) time_for_read->at_usec;
+	status = select(socketptr->sd + 1, (void *)(&tcp_fd), (void *)0, (void *)0, &lcl_time_for_read);
 #else
 	poll_fdlist[0].fd = socketptr->sd;
 	poll_fdlist[0].events = POLLIN;
@@ -178,7 +178,7 @@ ssize_t iosocket_snr_io(socket_struct *socketptr, void *buffer, size_t maxlength
 	DBGSOCK2((stdout, "socsnrio: Select return code: %d :: errno: %d\n", status, real_errno));
         if (0 < status)
 	{
-                bytesread = tcp_routines.aa_recv(socketptr->sd, buffer, maxlength, flags);
+                RECV(socketptr->sd, buffer, maxlength, flags, bytesread);
 		real_errno = errno;
 		socketptr->last_recv_errno = (-1 != status) ? 0 : real_errno;	/* Save status of last recv for dbging purposes */
 		DBGSOCK2((stdout, "socsnrio: aa_recv return code: %d :: errno: %d\n", bytesread, errno));
@@ -285,7 +285,7 @@ ssize_t iosocket_snr_utf_prebuffer(io_desc *iod, socket_struct *socketptr, int f
 			}
 			break;
 		default:
-			GTMASSERT;
+			assertpro(iod->ichset != iod->ichset);
 	}
 	mblen++;	/* Include first char we were looking at in the required byte length */
 	DBGSOCK2((stdout, "socsnrupb: Length of char: %d\n", mblen));
diff --git a/sr_port/iosocket_switch.c b/sr_port/iosocket_switch.c
index 6811751..1ec1266 100644
--- a/sr_port/iosocket_switch.c
+++ b/sr_port/iosocket_switch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -19,25 +19,24 @@
 #include "io.h"
 #include "iosp.h"
 #include "io_params.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 
 GBLREF  int4	gtm_max_sockets;
 
+error_def(ERR_SOCKNOTFND);
+error_def(ERR_SOCKETEXIST);
+error_def(ERR_SOCKMAX);
+
 boolean_t iosocket_switch(char *handle, int handle_len, d_socket_struct *from, d_socket_struct *to)
 {
 	int4 		index, ii;
 	socket_struct	*socketptr;
 
-	error_def(ERR_SOCKNOTFND);
-	error_def(ERR_SOCKETEXIST);
-	error_def(ERR_SOCKMAX);
-
 	if ((NULL == from) ||
 		(0 > (index = iosocket_handle(handle, &handle_len, FALSE, from))))
 	{
-		rts_error(VARLSTCNT(4) ERR_SOCKNOTFND, 2, handle_len, handle);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SOCKNOTFND, 2, handle_len, handle);
 		return FALSE;
 	} else
 	{
@@ -46,12 +45,12 @@ boolean_t iosocket_switch(char *handle, int handle_len, d_socket_struct *from, d
 		assert(NULL != to);
 		if (0 <= iosocket_handle(handle, &handle_len, FALSE, to))
 		{
-			rts_error(VARLSTCNT(4) ERR_SOCKETEXIST, 2, handle_len, handle);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SOCKETEXIST, 2, handle_len, handle);
 			return FALSE;
 		}
                 if (gtm_max_sockets <= to->n_socket)
                 {
-                        rts_error(VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets);
+                        rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets);
                         return FALSE;
                 }
 		socketptr = from->socket[index];
diff --git a/sr_port/iosocket_use.c b/sr_port/iosocket_use.c
index 1dc798b..5ab5d0d 100644
--- a/sr_port/iosocket_use.c
+++ b/sr_port/iosocket_use.c
@@ -24,8 +24,6 @@
 #include "io.h"
 #include "io_params.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "nametabtyp.h"
@@ -36,7 +34,6 @@
 GBLREF 	io_pair          	io_curr_device;
 GBLREF  io_pair			io_std_device;
 GBLREF 	io_desc          	*active_device;
-GBLREF	tcp_library_struct	tcp_routines;
 GBLREF	d_socket_struct		*socket_pool;
 GBLREF	boolean_t		gtm_utf8_mode;
 GBLREF	spdesc			stringpool;
@@ -59,6 +56,7 @@ error_def(ERR_DELIMWIDTH);
 error_def(ERR_DEVPARMNEG);
 error_def(ERR_ILLESOCKBFSIZE);
 error_def(ERR_MRTMAXEXCEEDED);
+error_def(ERR_NOSOCKETINDEV);
 error_def(ERR_SETSOCKOPTERR);
 error_def(ERR_SOCKBFNOTEMPTY);
 error_def(ERR_SOCKNOTFND);
@@ -349,7 +347,10 @@ void	iosocket_use(io_desc *iod, mval *pp)
 			return;
 		}
 		if (NULL == socket_pool)
+		{
 			iosocket_poolinit();
+			memcpy(newdsocket, dsocketptr, d_socket_struct_len);
+		}
 		iosocket_switch(handled, handled_len, newdsocket, socket_pool);
 		memcpy(dsocketptr, newdsocket, d_socket_struct_len);
 		if (0 > dsocketptr->current_socket)
@@ -383,13 +384,18 @@ void	iosocket_use(io_desc *iod, mval *pp)
 	if (create_new_socket = (listen_specified || connect_specified))	/* real "=" */
 	{
 		/* allocate the structure for a new socket */
-                if (NULL == (socketptr = iosocket_create(sockaddr, bfsize, -1)))
+                if (NULL == (socketptr = iosocket_create(sockaddr, bfsize, -1, listen_specified)))
                         return;
 		/* give the new socket a handle */
 		iosocket_handle(handles, &handles_len, TRUE, dsocketptr);
                 socketptr->handle_len = handles_len;
                 memcpy(socketptr->handle, handles, handles_len);
 		socketptr->dev = newdsocket;	/* use newdsocket temporarily for the sake of bind/connect */
+#ifndef		VMS
+		socketptr->filemode_mask = 0;
+		socketptr->uic.mem = (uid_t)-1;
+		socketptr->uic.grp = (gid_t)-1;
+#endif
 	} else
 	{
 		if (socket_specified)
@@ -402,9 +408,20 @@ void	iosocket_use(io_desc *iod, mval *pp)
 			}
 			newdsocket->current_socket = index;
 			socketptr = newdsocket->socket[index];
+			if ((1 == n_specified) && (socket_listening == socketptr->state))
+			{	/* accept a new connection if there is one */
+				socketptr->pendingevent = FALSE;
+				iod->dollar.key[0] = '\0';
+				save_errno = iosocket_accept(dsocketptr, socketptr, TRUE);
+				return;
+			}
 		} else
 		{
-			socketptr = newdsocket->socket[newdsocket->current_socket];
+			if (0 >= newdsocket->n_socket)
+			{
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
+				return;
+			}
      			if (newdsocket->n_socket <= newdsocket->current_socket)
 	     		{
 				assert(FALSE);
@@ -412,6 +429,7 @@ void	iosocket_use(io_desc *iod, mval *pp)
 						newdsocket->n_socket);
      				return;
      			}
+			socketptr = newdsocket->socket[newdsocket->current_socket];
 		}
 		socketptr->temp_sd = FD_INVALID;
 	}
@@ -511,7 +529,7 @@ void	iosocket_use(io_desc *iod, mval *pp)
 #ifdef TCP_NODELAY
 		nodelay = newsocket.nodelay ? 1 : 0;
 		if ((socketptr->nodelay != newsocket.nodelay) &&
-		    (-1 == tcp_routines.aa_setsockopt(newsocket.sd, IPPROTO_TCP,
+		    (-1 == setsockopt(newsocket.sd, IPPROTO_TCP,
 						      TCP_NODELAY, &nodelay, SIZEOF(nodelay))))
 		{
 			save_errno = errno;
@@ -522,7 +540,7 @@ void	iosocket_use(io_desc *iod, mval *pp)
 		}
 #endif
 		if ((socketptr->bufsiz != newsocket.bufsiz) &&
-		    (-1 == tcp_routines.aa_setsockopt(newsocket.sd, SOL_SOCKET,
+		    (-1 == setsockopt(newsocket.sd, SOL_SOCKET,
 						      SO_RCVBUF, &newsocket.bufsiz, SIZEOF(newsocket.bufsiz))))
 		{
 			save_errno = errno;
@@ -545,11 +563,12 @@ void	iosocket_use(io_desc *iod, mval *pp)
 		}
 	}
         /* -------------------------------------- action -------------------------------------------- */
-        if ((listen_specified && (!iosocket_bind(&newsocket, NO_M_TIMEOUT, ibfsize_specified))) ||
-	    (connect_specified && (!iosocket_connect(&newsocket, 0, ibfsize_specified))))
+	if ((listen_specified && ((!iosocket_bind(&newsocket, NO_M_TIMEOUT, ibfsize_specified, FALSE))
+			|| (!iosocket_listen_sock(&newsocket, DEFAULT_LISTEN_DEPTH))))
+		|| (connect_specified && (!iosocket_connect(&newsocket, 0, ibfsize_specified))))
         {	/* error message should be printed from bind/connect */
                 if (socketptr->sd > 0)
-                        (void)tcp_routines.aa_close(socketptr->sd);
+                        (void)close(socketptr->sd);
 		SOCKET_FREE(socketptr);
                 return;
         }
diff --git a/sr_port/iosocket_wait.c b/sr_port/iosocket_wait.c
index a4a676f..4ae6883 100644
--- a/sr_port/iosocket_wait.c
+++ b/sr_port/iosocket_wait.c
@@ -24,13 +24,16 @@
 #include "gtm_inet.h"
 #include "gtm_stdio.h"
 #include "gtm_string.h"
+#ifdef USE_POLL
+#include <sys/poll.h>
+#endif
+#ifdef USE_SELECT
+#include "gtm_select.h"
+#endif
 #include "io_params.h"
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcp_select.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 #include "min_max.h"
 #include "outofband.h"
@@ -39,11 +42,11 @@
 #include "mv_stent.h"
 #include "gtm_netdb.h"
 #include "gtm_stdlib.h"
+#include "eintr_wrappers.h"
 
 #define	CONNECTED	"CONNECT"
 #define READ	"READ"
 
-GBLREF tcp_library_struct	tcp_routines;
 GBLREF volatile int4		outofband;
 GBLREF int4			gtm_max_sockets;
 GBLREF int			socketus_interruptus;
@@ -51,6 +54,7 @@ GBLREF boolean_t		dollar_zininterrupt;
 GBLREF stack_frame  	        *frame_pointer;
 GBLREF unsigned char            *stackbase, *stacktop, *msp, *stackwarn;
 GBLREF mv_stent			*mv_chain;
+GBLREF int			dollar_truth;
 
 error_def(ERR_GETNAMEINFO);
 error_def(ERR_SOCKACPT);
@@ -65,40 +69,54 @@ boolean_t iosocket_wait(io_desc *iod, int4 timepar)
 {
 	struct 	timeval  	utimeout;
 	ABS_TIME		cur_time, end_time;
-	struct 	sockaddr_storage    	peer;           /* socket address + port */
-	fd_set    		tcp_fd;
+#ifdef USE_POLL
+	nfds_t			poll_nfds;
+	struct pollfd		*poll_fds;
+	socket_struct		**poll_socketptr;	/* matching poll_fds */
+	size_t			poll_fds_size;
+	int			poll_timeout, poll_fd;
+#endif
+#ifdef USE_SELECT
+	int			select_max_fd;
+	fd_set			select_fdset;
+#endif
 	d_socket_struct 	*dsocketptr;
 	socket_struct   	*socketptr, *newsocketptr;
 	socket_interrupt	*sockintr;
-	char            	*errptr;
-	int4            	errlen, ii, msec_timeout;
+	char            	*errptr, *charptr;
+	int4            	errlen, ii, jj, msec_timeout;
+	int4			nselect, nlisten, nconnected, rlisten, rconnected;
+	int4			oldestconnectedcycle, oldestconnectedindex;
+	int4			oldestlistencycle, oldestlistenindex;
+	int4			oldesteventcycle, oldesteventindex;
 	int			rv, max_fd, len;
-	GTM_SOCKLEN_TYPE	size;
-	boolean_t		zint_restart;
+	boolean_t		zint_restart, retry_accept = FALSE;
 	mv_stent		*mv_zintdev;
-	int			retry_num;
-	struct sockaddr		*peer_sa_ptr;
-	char			port_buffer[NI_MAXSERV], ipaddr[SA_MAXLEN + 1];
 	int			errcode;
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	/* check for validity */
-	assert(iod->type == gtmsocket);
+	assert(gtmsocket == iod->type);
 	dsocketptr = (d_socket_struct *)iod->dev_sp;
 	sockintr = &dsocketptr->sock_save_state;
-	peer_sa_ptr = ((struct sockaddr *)(&peer));
 
 	/* Check for restart */
 	if (!dsocketptr->mupintr)
+	{
 		/* Simple path, no worries*/
 		zint_restart = FALSE;
-	else
+		dsocketptr->waitcycle++;	/* don't count restarts */
+		if (0 == dsocketptr->waitcycle)
+		{	/* wrapped so make it non zero */
+			dsocketptr->waitcycle++;
+		}
+	} else
 	{       /* We have a pending wait restart of some sort - check we aren't recursing on this device */
-		if (sockwhich_invalid == sockintr->who_saved)
-			GTMASSERT;	/* Interrupt should never have an invalid save state */
+		assertpro(sockwhich_invalid != sockintr->who_saved);	/* Interrupt should never have an invalid save state */
 		if (dollar_zininterrupt)
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
-		if (sockwhich_wait != sockintr->who_saved)
-			GTMASSERT;      /* ZINTRECURSEIO should have caught */
+		assertpro(sockwhich_wait == sockintr->who_saved);      /* ZINTRECURSEIO should have caught */
 		DBGSOCK((stdout, "socwait: *#*#*#*#*#*#*#  Restarted interrupted wait\n"));
 		mv_zintdev = io_find_mvstent(iod, FALSE);
 		if (mv_zintdev)
@@ -123,162 +141,239 @@ boolean_t iosocket_wait(io_desc *iod, int4 timepar)
 		sockintr->who_saved = sockwhich_invalid;
 	}
 	/* check for events */
-	FD_ZERO(&tcp_fd);
+#ifdef USE_POLL
+	poll_fds_size = dsocketptr->n_socket * (SIZEOF(struct pollfd) + SIZEOF(socket_struct *));
+	if (NULL == TREF(poll_fds_buffer))
+	{
+		TREF(poll_fds_buffer) = malloc(poll_fds_size);
+		TREF(poll_fds_buffer_size) = poll_fds_size;
+	} else if (poll_fds_size > TREF(poll_fds_buffer_size))
+	{
+		free(TREF(poll_fds_buffer));
+		TREF(poll_fds_buffer) = malloc(poll_fds_size);
+		TREF(poll_fds_buffer_size) = poll_fds_size;
+	}
+	poll_fds = (struct pollfd *) TREF(poll_fds_buffer);
+	poll_socketptr = (socket_struct **)((char *)poll_fds + (dsocketptr->n_socket * SIZEOF(struct pollfd)));
+#endif
+	SELECT_ONLY(FD_ZERO(&select_fdset));
 	while (TRUE)
 	{
-		max_fd = 0;
+		POLL_ONLY(poll_nfds = 0);
+		SELECT_ONLY(select_max_fd = 0);
+		nselect = nlisten = nconnected = rlisten = rconnected = 0;
+		rv = 0;
 		for (ii = 0; ii < dsocketptr->n_socket; ii++)
 		{
 			socketptr = dsocketptr->socket[ii];
 			if ((socket_listening == socketptr->state) || (socket_connected == socketptr->state))
 			{
-				FD_SET(socketptr->sd, &tcp_fd);
-				max_fd = MAX(max_fd, socketptr->sd);
-			}
-		}
-		utimeout.tv_sec = timepar;
-		utimeout.tv_usec = 0;
-		msec_timeout = timeout2msec(timepar);
-		sys_get_curr_time(&cur_time);
-		if (!zint_restart || !sockintr->end_time_valid)
-			add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
-		else
-		{       /* end_time taken from restart data. Compute what msec_timeout should be so timeout timer
-					   gets set correctly below.
-			*/
-			DBGSOCK((stdout, "socwait: Taking timeout end time from wait restart data\n"));
-			cur_time = sub_abs_time(&end_time, &cur_time);
-			if (0 > cur_time.at_sec)
-			{
-				msec_timeout = -1;
-				utimeout.tv_sec = 0;
-				utimeout.tv_usec = 0;
-			} else
-			{
-				msec_timeout = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000);
-				utimeout.tv_sec = cur_time.at_sec;
-				utimeout.tv_usec = (gtm_tv_usec_t)cur_time.at_usec;
+				if (socket_connected == socketptr->state)
+				{ /* if buffer not empty set flag but not FD_SET */
+					nconnected++;
+					if (0 < socketptr->buffered_length)
+					{	/* something in the buffer so ready now */
+						if (!socketptr->pendingevent)
+						{
+							socketptr->pendingevent = TRUE;
+							socketptr->readycycle = dsocketptr->waitcycle;
+						}
+						rconnected++;
+						continue;
+					}
+				} else
+				{
+					nlisten++;
+					if (socketptr->pendingevent)
+					{
+						rlisten++;
+						continue;	/* ready for ACCEPT now */
+					}
+				}
+#ifdef USE_POLL
+				poll_fds[poll_nfds].fd = socketptr->sd;
+				poll_fds[poll_nfds].events = POLLIN;
+				poll_socketptr[poll_nfds] = socketptr;
+				poll_nfds++;
+#endif
+#ifdef USE_SELECT
+				assertpro(FD_SETSIZE > socketptr->sd);
+				FD_SET(socketptr->sd, &select_fdset);
+				select_max_fd = MAX(select_max_fd, socketptr->sd);
+#endif
+				nselect++;
 			}
 		}
-		sockintr->end_time_valid = FALSE;
-		for ( ; ; )
+		if (nselect)
 		{
-			rv = select(max_fd + 1, (void *)&tcp_fd, (void *)0, (void *)0,
-				    (timepar == NO_M_TIMEOUT ? (struct timeval *)0 : &utimeout));
-			if (0 > rv && EINTR == errno)
-			{
-				if (0 != outofband)
-				{
-					DBGSOCK((stdout, "socwait: outofband interrupt received (%d) -- "
-						 "queueing mv_stent for wait intr\n", outofband));
-					PUSH_MV_STENT(MVST_ZINTDEV);
-					mv_chain->mv_st_cont.mvs_zintdev.io_ptr = iod;
-					mv_chain->mv_st_cont.mvs_zintdev.buffer_valid = FALSE;
-					sockintr->who_saved = sockwhich_wait;
-					sockintr->end_time = end_time;
-					sockintr->end_time_valid = TRUE;
-					dsocketptr->mupintr = TRUE;
-					socketus_interruptus++;
-					DBGSOCK((stdout, "socwait: mv_stent queued - endtime: %d/%d  interrupts: %d\n",
-						 end_time.at_sec, end_time.at_usec, socketus_interruptus));
-					outofband_action(FALSE);
-					GTMASSERT;      /* Should *never* return from outofband_action */
-					return FALSE;   /* For the compiler.. */
-				}
-				sys_get_curr_time(&cur_time);
+			utimeout.tv_sec = timepar;
+			utimeout.tv_usec = 0;
+			msec_timeout = timeout2msec(timepar);
+			sys_get_curr_time(&cur_time);
+			if (!retry_accept && (!zint_restart || !sockintr->end_time_valid))
+				add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
+			else
+			{       /* end_time taken from restart data. Compute what msec_timeout should be so timeout timer
+				   gets set correctly below.  Or retry after failed accept.
+				*/
+				DBGSOCK((stdout, "socwait: Taking timeout end time from wait restart data\n"));
 				cur_time = sub_abs_time(&end_time, &cur_time);
 				if (0 > cur_time.at_sec)
 				{
-					rv = 0;		/* time out */
-					break;
+					msec_timeout = -1;
+					utimeout.tv_sec = 0;
+					utimeout.tv_usec = 0;
+				} else
+				{
+					msec_timeout = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000);
+					utimeout.tv_sec = cur_time.at_sec;
+					utimeout.tv_usec = (gtm_tv_usec_t)cur_time.at_usec;
 				}
-				utimeout.tv_sec = cur_time.at_sec;
-				utimeout.tv_usec = (gtm_tv_usec_t)cur_time.at_usec;
-			} else
-				break;	/* either other error or done */
-		}
-		if (rv == 0)
-		{
-			iod->dollar.key[0] = '\0';
-			return FALSE;
-		} else  if (rv < 0)
-		{
-			errptr = (char *)STRERROR(errno);
-			errlen = STRLEN(errptr);
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKWAIT, 0, ERR_TEXT, 2, errlen, errptr);
-			return FALSE;
-		}
-		/* find out which socket is ready */
-		for (ii = 0; ii < dsocketptr->n_socket; ii++)
-		{
-			socketptr = dsocketptr->socket[ii];
-			if (0 != FD_ISSET(socketptr->sd, &tcp_fd))
-				break;
-		}
-		assert(ii < dsocketptr->n_socket);
-		if (socket_listening == socketptr->state)
-		{
-			if (gtm_max_sockets <= dsocketptr->n_socket)
+			}
+			zint_restart = sockintr->end_time_valid = FALSE;
+			for ( ; ; )
 			{
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets);
-				return FALSE;
+#ifdef USE_POLL
+				poll_timeout = (utimeout.tv_sec * 1000) + (utimeout.tv_usec / 1000);
+				poll_fd = -1;
+				rv = poll(poll_fds, poll_nfds, poll_timeout);
+#endif
+#ifdef USE_SELECT
+				rv = select(select_max_fd + 1, (void *)&select_fdset, (void *)0, (void *)0,
+					    (timepar == NO_M_TIMEOUT ? (struct timeval *)NULL : &utimeout));
+#endif
+				if (0 > rv && EINTR == errno)
+				{
+					if (0 != outofband)
+					{
+						if (OUTOFBAND_RESTARTABLE(outofband))
+						{
+							DBGSOCK((stdout, "socwait: outofband interrupt received (%d) -- "
+								"queueing mv_stent for wait intr\n", outofband));
+							PUSH_MV_STENT(MVST_ZINTDEV);
+							mv_chain->mv_st_cont.mvs_zintdev.io_ptr = iod;
+							mv_chain->mv_st_cont.mvs_zintdev.buffer_valid = FALSE;
+							sockintr->who_saved = sockwhich_wait;
+							sockintr->end_time = end_time;
+							sockintr->end_time_valid = TRUE;
+							dsocketptr->mupintr = TRUE;
+							socketus_interruptus++;
+							DBGSOCK((stdout, "socwait: mv_stent queued - endtime: %d/%d"
+								"  interrupts: %d\n", end_time.at_sec, end_time.at_usec,
+								socketus_interruptus));
+						}
+						outofband_action(FALSE);
+						assertpro(FALSE);      /* Should *never* return from outofband_action */
+						return FALSE;   /* For the compiler.. */
+					}
+					sys_get_curr_time(&cur_time);
+					cur_time = sub_abs_time(&end_time, &cur_time);
+					if (0 > cur_time.at_sec)
+					{
+						rv = 0;		/* time out */
+						break;
+					}
+					utimeout.tv_sec = cur_time.at_sec;
+					utimeout.tv_usec = (gtm_tv_usec_t)cur_time.at_usec;
+				} else
+					break;	/* either other error or done */
 			}
-
-			size = SIZEOF(struct sockaddr_storage);
-			rv = tcp_routines.aa_accept(socketptr->sd, peer_sa_ptr, &size);
-			if (-1 == rv)
+			if ((rv == 0) && (0 == rconnected) && (0 == rlisten))
+			{	/* none selected or prior pending event */
+				iod->dollar.key[0] = '\0';
+				if (NO_M_TIMEOUT != timepar)
+					dollar_truth = FALSE;
+				return FALSE;
+			} else  if (rv < 0)
 			{
-#				ifdef __hpux
-				if (ENOBUFS == errno)
-					continue;	/* On HP-UX, ENOBUFS may indicate a transient condition; retry */
-#				endif
 				errptr = (char *)STRERROR(errno);
 				errlen = STRLEN(errptr);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKACPT, 0, ERR_TEXT, 2, errlen, errptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKWAIT, 0, ERR_TEXT, 2, errlen, errptr);
 				return FALSE;
 			}
-			SOCKET_DUP(socketptr, newsocketptr);
-			newsocketptr->sd = rv;
-			SOCKET_ADDR_COPY(newsocketptr->remote, peer_sa_ptr, size);
-			/* translate internal address to numeric ip address */
-			GETNAMEINFO(peer_sa_ptr, size, ipaddr, SA_MAXLEN, NULL, 0, NI_NUMERICHOST, errcode);
-			if (0 != errcode)
-			{
-				SOCKET_FREE(newsocketptr);
-				RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
-				return FALSE;
+		} else if ((0 == rlisten) && (0 == rconnected))
+		{	/* nothing to select and no pending events */
+			iod->dollar.key[0] = '\0';
+			if (NO_M_TIMEOUT != timepar)
+				dollar_truth = FALSE;
+			return FALSE;
+		}
+		/* find out which sockets are ready */
+		oldestlistencycle = oldestconnectedcycle = oldesteventcycle = 0;
+		oldestlistenindex = oldestconnectedindex = oldesteventindex = -1;
+		for (ii = jj = 0; ii < dsocketptr->n_socket; ii++)
+		{
+			socketptr = dsocketptr->socket[ii];
+			if ((socket_listening != socketptr->state) && (socket_connected != socketptr->state))
+				continue;	/* not a candidate for /WAIT */
+#ifdef USE_POLL
+			assertpro((0 == jj) || (jj <= poll_nfds));	/* equal after last polled fd checked */
+			if (nselect && (socketptr->sd == poll_fds[jj].fd) && (poll_fds[jj++].revents & POLLIN))
+#endif
+#ifdef USE_SELECT
+			assertpro(FD_SETSIZE > socketptr->sd);
+			if (nselect && (0 != FD_ISSET(socketptr->sd, &select_fdset)))
+#endif
+			{	/* set flag in socketptr and keep going */
+				socketptr->pendingevent = TRUE;
+				socketptr->readycycle = dsocketptr->waitcycle;
+				if (socket_listening == socketptr->state)
+					rlisten++;
+				else
+					rconnected++;
 			}
-			if (NULL != newsocketptr->remote.saddr_ip)
-				free(newsocketptr->remote.saddr_ip);
-			STRNDUP(ipaddr, SA_MAXLEN, newsocketptr->remote.saddr_ip);
-			/* translate internal address to port number*/
-			GETNAMEINFO(peer_sa_ptr, size, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
-			if (0 != errcode)
+			if (socketptr->pendingevent)	/* may be from prior /WAIT */
 			{
-				SOCKET_FREE(newsocketptr);
-				RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
-				return FALSE;
+				if (socket_listening == socketptr->state)
+				{
+					if (0 == oldestlistencycle)
+					{
+						oldestlistencycle = socketptr->readycycle;
+						oldestlistenindex = ii;
+					} else if (oldestlistencycle > socketptr->readycycle)
+					{	/* this socket waiting longer */
+						oldestlistencycle = socketptr->readycycle;
+						oldestlistenindex = ii;
+					}
+				} else
+				{
+					if (0 == oldestconnectedcycle)
+					{
+						oldestconnectedcycle = socketptr->readycycle;
+						oldestconnectedindex = ii;
+					} else if (oldestconnectedcycle > socketptr->readycycle)
+					{	/* this socket waiting longer */
+						oldestconnectedcycle = socketptr->readycycle;
+						oldestconnectedindex = ii;
+					}
+				}
 			}
-			newsocketptr->remote.port = ATOI(port_buffer);
-			newsocketptr->state = socket_connected;
-			newsocketptr->passive = FALSE;
-			newsocketptr->first_read = newsocketptr->first_write = TRUE;
-			/* put the new-born socket to the list and create a handle for it */
-			iosocket_handle(newsocketptr->handle, &newsocketptr->handle_len, TRUE, dsocketptr);
-			dsocketptr->socket[dsocketptr->n_socket++] = newsocketptr;
-			dsocketptr->current_socket = dsocketptr->n_socket - 1;
-			len = SIZEOF(CONNECTED) - 1;
-			memcpy(&iod->dollar.key[0], CONNECTED, len);
-			iod->dollar.key[len++] = '|';
-			memcpy(&iod->dollar.key[len], newsocketptr->handle, newsocketptr->handle_len);
-			len += newsocketptr->handle_len;
-			iod->dollar.key[len++] = '|';
-			strncpy(&iod->dollar.key[len], newsocketptr->remote.saddr_ip, DD_BUFLEN - 1 - len);
-			iod->dollar.key[DD_BUFLEN-1] = '\0';		/* In case we fill the buffer */
+		}
+		if (0 < oldestlistencycle)
+		{
+			oldesteventcycle = oldestlistencycle;
+			oldesteventindex = oldestlistenindex;
+		} else if (0 < oldestconnectedcycle)
+		{
+			oldesteventcycle = oldestconnectedcycle;
+			oldesteventindex = oldestconnectedindex;
+		} else
+			assertpro((0 < oldestlistencycle) || (0 < oldestconnectedcycle));
+		socketptr = dsocketptr->socket[oldesteventindex];
+		socketptr->pendingevent = FALSE;
+		if (socket_listening == socketptr->state)
+		{
+			rv = iosocket_accept(dsocketptr, socketptr, FALSE);
+			if (0 < rv)
+			{
+				retry_accept = TRUE;
+				continue;	/* pending connection gone so redo */
+			} else if (-1 == rv)
+				return FALSE;	/* error handled in iosocket_accept */
 		} else
 		{
 			assert(socket_connected == socketptr->state);
-			dsocketptr->current_socket = ii;
+			dsocketptr->current_socket = oldesteventindex;
 			len = SIZEOF(READ) - 1;
 			memcpy(&iod->dollar.key[0], READ, len);
 			iod->dollar.key[len++] = '|';
@@ -288,11 +383,141 @@ boolean_t iosocket_wait(io_desc *iod, int4 timepar)
 			if (NULL != socketptr->remote.saddr_ip)
 			{
 				strncpy(&iod->dollar.key[len], socketptr->remote.saddr_ip, DD_BUFLEN - 1 - len);
-				iod->dollar.key[DD_BUFLEN-1] = '\0';
+#			ifndef VMS
 			} else
-				iod->dollar.key[len] = '\0';
+			{
+				assertpro(socket_local == socketptr->protocol);
+				charptr = ((struct sockaddr_un *)(socketptr->local.sa))->sun_path;
+				strncpy(&dsocketptr->iod->dollar.key[len], charptr, DD_BUFLEN - len - 1);
+#			endif
+			}
+			iod->dollar.key[DD_BUFLEN - 1] = '\0';
 		}
 		break;
 	}
+	if (NO_M_TIMEOUT != timepar)
+		dollar_truth = TRUE;
 	return TRUE;
 }
+
+int iosocket_accept(d_socket_struct *dsocketptr, socket_struct *socketptr, boolean_t selectfirst)
+{
+	char            	*errptr;
+	int4            	errlen;
+	int			rv, len, errcode;
+	char			port_buffer[NI_MAXSERV], ipaddr[SA_MAXLEN + 1];
+#ifdef USE_POLL
+	struct pollfd		poll_fds;
+	int			poll_fd;
+#endif
+#ifdef USE_SELECT
+	fd_set			select_fdset;
+#endif
+	struct timeval		utimeout;
+	GTM_SOCKLEN_TYPE	size;
+	socket_struct		*newsocketptr;
+	struct sockaddr_storage	peer;           /* socket address + port */
+	struct sockaddr		*peer_sa_ptr;
+
+	if (gtm_max_sockets <= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets);
+		return -1;
+	}
+	peer_sa_ptr = ((struct sockaddr *)(&peer));
+	if (selectfirst || (dsocketptr->waitcycle > socketptr->readycycle))
+	{	/* if not selected this time do a select first to check if connection still there */
+#ifdef USE_POLL
+		poll_fds.fd = socketptr->sd;
+		poll_fds.events = POLLIN;
+		rv = poll(&poll_fds, 1, 0);
+#endif
+#ifdef USE_SELECT
+		FD_ZERO(&select_fdset);
+		FD_SET(socketptr->sd, &select_fdset);
+		utimeout.tv_sec = utimeout.tv_usec = 0;
+		rv = select(socketptr->sd + 1, (void *)&select_fdset, (void *)0, (void *)0, &utimeout);
+#endif
+		if (0 > rv)
+		{
+			errptr = (char *)STRERROR(errno);
+			errlen = STRLEN(errptr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKWAIT, 0, ERR_TEXT, 2, errlen, errptr);
+			return -1;
+		} else if (0 == rv)
+			return EWOULDBLOCK;	/* signal to find another ready socket */
+	}
+	size = SIZEOF(struct sockaddr_storage);
+	ACCEPT_SOCKET(socketptr->sd, peer_sa_ptr, &size, rv);
+	if (-1 == rv)
+	{
+		switch (errno)
+		{
+			case ENOBUFS:
+			case ECONNABORTED:
+			case ETIMEDOUT:
+			case ECONNRESET:
+			case ENOTCONN:
+#			ifndef VMS
+			case ENOSR:
+#			endif
+				return errno;	/* pending connection gone so retry */
+			default:
+				errptr = (char *)STRERROR(errno);
+				errlen = STRLEN(errptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKACPT, 0, ERR_TEXT, 2, errlen, errptr);
+				return -1;
+		}
+	}
+	SOCKET_DUP(socketptr, newsocketptr);
+	newsocketptr->sd = rv;
+	if (socket_local != newsocketptr->protocol)
+	{	/* translate internal address to numeric ip address */
+		SOCKET_ADDR_COPY(newsocketptr->remote, peer_sa_ptr, size);	/* info not set for socket_local */
+		if (0 != (errcode = getnameinfo(peer_sa_ptr, size, ipaddr, SA_MAXLEN,
+				NULL, 0, NI_NUMERICHOST)))
+		{
+			SOCKET_FREE(newsocketptr);
+			RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
+			return -1;
+		}
+		if (NULL != newsocketptr->remote.saddr_ip)
+			free(newsocketptr->remote.saddr_ip);
+		STRNDUP(ipaddr, SA_MAXLEN, newsocketptr->remote.saddr_ip);
+		/* translate internal address to port number*/
+		GETNAMEINFO(peer_sa_ptr, size, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV, errcode);
+		if (0 != errcode)
+		{
+			SOCKET_FREE(newsocketptr);
+			RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
+			return -1;
+		}
+		newsocketptr->remote.port = ATOI(port_buffer);
+	}
+	newsocketptr->state = socket_connected;
+	newsocketptr->passive = FALSE;
+	newsocketptr->first_read = newsocketptr->first_write = TRUE;
+	/* put the new-born socket to the list and create a handle for it */
+	iosocket_handle(newsocketptr->handle, &newsocketptr->handle_len, TRUE, dsocketptr);
+	socketptr->lastaction = dsocketptr->waitcycle;	/* record cycle for last connect */
+	dsocketptr->socket[dsocketptr->n_socket++] = newsocketptr;
+	dsocketptr->current_socket = dsocketptr->n_socket - 1;
+	len = SIZEOF(CONNECTED) - 1;
+	memcpy(&dsocketptr->iod->dollar.key[0], CONNECTED, len);
+	dsocketptr->iod->dollar.key[len++] = '|';
+	memcpy(&dsocketptr->iod->dollar.key[len], newsocketptr->handle, newsocketptr->handle_len);
+	len += newsocketptr->handle_len;
+	dsocketptr->iod->dollar.key[len++] = '|';
+	if (socket_local != newsocketptr->protocol)
+		strncpy(&dsocketptr->iod->dollar.key[len], newsocketptr->remote.saddr_ip, DD_BUFLEN - 1 - len);
+#	ifndef VMS
+	else
+	{ /* get path from listening socket local side */
+		STRNCPY_STR(&dsocketptr->iod->dollar.key[len], ((struct sockaddr_un *)(socketptr->local.sa))->sun_path,
+			DD_BUFLEN - len);
+		SOCKET_ADDR_COPY(newsocketptr->remote, socketptr->local.sa, SIZEOF(struct sockaddr_un));
+	}
+#	endif
+	dsocketptr->iod->dollar.key[DD_BUFLEN - 1] = '\0';		/* In case we fill the buffer */
+	return 0;
+}
diff --git a/sr_port/iosocket_write.c b/sr_port/iosocket_write.c
index aa97211..02e3944 100644
--- a/sr_port/iosocket_write.c
+++ b/sr_port/iosocket_write.c
@@ -18,10 +18,9 @@
 #include "gtm_inet.h"
 #include "gtm_stdio.h"
 #include "gtm_string.h"
+#include "eintr_wrappers.h"
 
 #include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "dollarx.h"
@@ -37,18 +36,49 @@ GBLREF io_pair			io_std_device;
 GBLREF bool			prin_out_dev_failure;
 #endif
 
-GBLREF tcp_library_struct	tcp_routines;
 GBLREF mstr			chset_names[];
 GBLREF UConverter		*chset_desc[];
 GBLREF spdesc			stringpool;
 
+error_def(ERR_CURRSOCKOFR);
+error_def(ERR_DELIMSIZNA);
+UNIX_ONLY(error_def(ERR_NOPRINCIO);)
+error_def(ERR_NOSOCKETINDEV);
 error_def(ERR_SOCKWRITE);
 error_def(ERR_TEXT);
-error_def(ERR_CURRSOCKOFR);
 error_def(ERR_ZFF2MANY);
-error_def(ERR_DELIMSIZNA);
 error_def(ERR_ZINTRECURSEIO);
-UNIX_ONLY(error_def(ERR_NOPRINCIO);)
+
+#define DOTCPSEND(SDESC, SBUFF, SBUFF_LEN, SFLAGS, RC)									\
+{															\
+	ssize_t		gtmioStatus;											\
+	size_t		gtmioBuffLen;											\
+	size_t		gtmioChunk;											\
+	sm_uc_ptr_t	gtmioBuff;											\
+															\
+	gtmioBuffLen = SBUFF_LEN;											\
+	gtmioBuff = (sm_uc_ptr_t)(SBUFF);										\
+	for (;;)													\
+        {														\
+		gtmioChunk = gtmioBuffLen VMS_ONLY(> VMS_MAX_TCP_IO_SIZE ? VMS_MAX_TCP_IO_SIZE : gtmioBuffLen);		\
+		SEND(SDESC, gtmioBuff, gtmioChunk, SFLAGS, gtmioStatus);						\
+		if ((ssize_t)-1 != gtmioStatus)										\
+	        {													\
+			gtmioBuffLen -= gtmioStatus;									\
+			if (0 == gtmioBuffLen)										\
+				break;											\
+			gtmioBuff += gtmioStatus;									\
+	        }													\
+		else													\
+			break;												\
+        }														\
+	if ((ssize_t)-1 == gtmioStatus)    	/* Had legitimate error - return it */					\
+		RC = errno;												\
+	else if (0 == gtmioBuffLen)											\
+	        RC = 0;													\
+	else														\
+		RC = -1;		/* Something kept us from sending what we wanted */				\
+}
 
 void	iosocket_write(mstr *v)
 {
@@ -69,7 +99,11 @@ void	iosocket_write_real(mstr *v, boolean_t convert_output)
 	iod = io_curr_device.out;
 	assert(gtmsocket == iod->type);
 	dsocketptr = (d_socket_struct *)iod->dev_sp;
-	socketptr = dsocketptr->socket[dsocketptr->current_socket];
+	if (0 >= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
+		return;
+	}
 	if (dsocketptr->n_socket <= dsocketptr->current_socket)
 	{
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
@@ -77,6 +111,7 @@ void	iosocket_write_real(mstr *v, boolean_t convert_output)
 	}
 	if (dsocketptr->mupintr)
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
+	socketptr = dsocketptr->socket[dsocketptr->current_socket];
 #ifdef MSG_NOSIGNAL
 	flags = MSG_NOSIGNAL;		/* return EPIPE instead of SIGPIPE */
 #else
diff --git a/sr_port/iosocket_wteol.c b/sr_port/iosocket_wteol.c
index c265c16..2ecba21 100644
--- a/sr_port/iosocket_wteol.c
+++ b/sr_port/iosocket_wteol.c
@@ -19,12 +19,11 @@
 
 #include "gt_timer.h"
 #include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "iottdef.h"
 #include "iosocketdef.h"
 
-GBLREF tcp_library_struct	tcp_routines;
+error_def(ERR_CURRSOCKOFR);
+error_def(ERR_NOSOCKETINDEV);
 
 void	iosocket_wteol(int4 val, io_desc *io_ptr)
 {
@@ -35,6 +34,16 @@ void	iosocket_wteol(int4 val, io_desc *io_ptr)
 
 	assert(gtmsocket == io_ptr->type);
 	dsocketptr = (d_socket_struct *)io_ptr->dev_sp;
+	if (0 >= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
+		return;
+	}
+	if (dsocketptr->current_socket >= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
+		return;
+	}
 	socketptr = dsocketptr->socket[dsocketptr->current_socket];
 	assert(val);
 	io_ptr->esc_state = START;
diff --git a/sr_port/iosocket_wtff.c b/sr_port/iosocket_wtff.c
index 07794b8..9c2f558 100644
--- a/sr_port/iosocket_wtff.c
+++ b/sr_port/iosocket_wtff.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,11 +16,13 @@
 #include "gtm_inet.h"
 #include "io.h"
 #include "gt_timer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 
 GBLREF io_pair		io_curr_device;
 
+error_def(ERR_CURRSOCKOFR);
+error_def(ERR_NOSOCKETINDEV);
+
 void iosocket_wtff(void)
 {
 	io_desc		*iod;
@@ -31,6 +33,16 @@ void iosocket_wtff(void)
 	assert(gtmsocket == iod->type);
 	iod->esc_state = START;
 	dsocketptr = (d_socket_struct *)iod->dev_sp;
+	if (0 >= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
+		return;
+	}
+	if (dsocketptr->current_socket >= dsocketptr->n_socket)
+	{
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
+		return;
+	}
 	socketptr = dsocketptr->socket[dsocketptr->current_socket];
 	if (socketptr->zff.len)
 		iosocket_write_real(&socketptr->zff, FALSE);
diff --git a/sr_port/iosocket_wtone.c b/sr_port/iosocket_wtone.c
index 08dcc75..fa23854 100644
--- a/sr_port/iosocket_wtone.c
+++ b/sr_port/iosocket_wtone.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,6 @@
 #include "gtm_inet.h"
 #include "io.h"
 #include "gt_timer.h"
-#include "iotcpdef.h"
 #include "iosocketdef.h"
 #include "gtm_utf8.h"
 
@@ -48,7 +47,7 @@ void iosocket_wtone(int ch)
 				endptr = UTF16LE_WCTOMB(ch, uni_c);
 				break;
 			default:
-				GTMASSERT;
+				assertpro(io_curr_device.out->ochset != io_curr_device.out->ochset);
 		}
 		temp.addr = uni_c;
 		temp.len = INTCAST(endptr - uni_c);
diff --git a/sr_port/iosocketdef.h b/sr_port/iosocketdef.h
index 951f67b..a7405d6 100644
--- a/sr_port/iosocketdef.h
+++ b/sr_port/iosocketdef.h
@@ -21,13 +21,29 @@
 #include <sys/types.h>
 #include "gtm_inet.h"
 #include "gtm_netdb.h"
+#ifndef VMS
+#include "gtm_un.h"
+#endif
 #include "gtm_socket.h" /* for using sockaddr_storage */
-#include "iotcpdef.h"
 
 #ifndef GTM_MB_LEN_MAX
 #include "gtm_utf8.h"
 #endif
 
+/* values for lastop in socket_struct */
+
+#define TCP_NOOP		0
+#define TCP_WRITE		1
+#define TCP_READ		2
+
+#ifndef VMS
+typedef struct
+{
+        uid_t   mem;
+        gid_t   grp;
+} uic_struct_int;
+#endif
+
 /* Debugging notes: Some debuging calls as as below. Note that DBGSOCK2 is *always* disabled.
  * disabled. As parts of the code work, the DBGSOCK calls are changed to DBGSOCK2 to get
  * them out of the way without removing them (they may be useful in the future).
@@ -196,6 +212,7 @@ enum socket_protocol
 {
 	socket_tcpip,
 	socket_spx,
+	socket_local,
 	n_socket_protocol
 };
 
@@ -213,6 +230,7 @@ typedef struct socket_address_type
 	struct addrinfo			ai;
 	struct addrinfo			*ai_head; /* store the head of addrinfo linked list */
 	unsigned short                  port;
+	pid_t				process;	/* for LOCAL passfd */
 	char            		*saddr_ip;
 } socket_address;
 
@@ -247,7 +265,16 @@ typedef struct socket_struct_type
 	boolean_t			first_read;
 	boolean_t			first_write;
 	boolean_t			def_moreread_timeout;	/* true if deviceparameter morereadtime defined in open or use */
+#ifndef VMS
+	boolean_t			passedfd;		/* true if WRITE /ACCEPT or /PASS */
+	uint				filemode;		/* for LOCAL */
+	uint				filemode_mask;		/* to tell which modes specified */
+	uic_struct_int			uic;
+#endif
 	mstr				zff;
+	uint4				lastaction;		/* waitcycle  count */
+	uint4				readycycle;		/* when was ready */
+	boolean_t			pendingevent;		/* if listening, needs accept */
 } socket_struct;
 
 typedef struct socket_interrupt_type
@@ -268,22 +295,26 @@ typedef struct d_socket_struct_type
 	boolean_t                     	mupintr;			/* We were mupip interrupted */
 	int4				current_socket;			/* current socket index */
 	int4				n_socket;			/* number of sockets	*/
+	uint4				waitcycle;			/* count waits */
 	struct io_desc_struct		*iod;				/* Point back to main IO descriptor block */
 	struct socket_struct_type 	*socket[1];			/* Array size determined by gtm_max_sockets */
 } d_socket_struct;
 
-boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz);
+boolean_t iosocket_bind(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz, boolean_t newversion);
 boolean_t iosocket_connect(socket_struct *socketptr, int4 timepar, boolean_t update_bufsiz);
 boolean_t iosocket_delimiter(unsigned char *delimiter_buffer, int4 delimiter_len, socket_struct *socketptr, boolean_t rm);
 void iosocket_delim_conv(socket_struct *socketptr, gtm_chset_t to_chset);
 void iosocket_delimiter_copy(socket_struct *from, socket_struct *to);
 boolean_t iosocket_switch(char *handle, int handle_len, d_socket_struct *from, d_socket_struct *to);
 int4 iosocket_handle(char *handle, int *len, boolean_t newhandle, d_socket_struct *dsocketptr);
-socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des);
+socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified);
 ssize_t iosocket_snr(socket_struct *socketptr, void *buffer, size_t maxlength, int flags, ABS_TIME *time_for_read);
 void iosocket_unsnr(socket_struct *socketptr, unsigned char *buffer, size_t len);
 ssize_t iosocket_snr_utf_prebuffer(io_desc *iod, socket_struct *socketptr, int flags, ABS_TIME *time_for_read,
 				   boolean_t wait_for_input);
 void iosocket_write_real(mstr *v, boolean_t convert_output);
 void iosocket_readfl_badchar(mval *vmvalptr, int datalen, int delimlen, unsigned char *delimptr, unsigned char *strend);
+boolean_t iosocket_listen_sock(socket_struct *socketptr, unsigned short len);
+void iosocket_close_one(d_socket_struct *dsocketptr, int index);
+int iosocket_accept(d_socket_struct *dsocketptr, socket_struct *socketptr, boolean_t selectfirst);
 #endif
diff --git a/sr_port/iotcp_close.c b/sr_port/iotcp_close.c
deleted file mode 100644
index 76f2ad9..0000000
--- a/sr_port/iotcp_close.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-/* iotcp_close.c - close a TCP/IP connection
- *  Parameters-
- *  iod - I/O descriptor for the currently open TCP/IP connection.
- *
- *  pp->str.addr   - device parameters
- *
- */
-#include "mdef.h"
-
-#include "gtm_stdio.h"
-#include "gtm_inet.h"
-
-#include "copy.h"
-#include "io_params.h"
-#include "io.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
-#include "stringpool.h"
-
-GBLREF tcp_library_struct	tcp_routines;
-LITREF unsigned char		io_params_size[];
-
-void iotcp_close(io_desc *iod, mval *pp)
-{
-	bool		close_listen_socket = FALSE;
-	unsigned char	c;
-	d_tcp_struct	*tcpptr;
-	int		p_offset;
-
-#ifdef DEBUG_TCP
-	PRINTF("%s >>>\n", __FILE__);
-#endif
-	assert(iod->type == tcp);
-	tcpptr = (d_tcp_struct *)iod->dev_sp;
-	p_offset = 0;
-	while (*(pp->str.addr + p_offset) != iop_eol)
-	{
-		switch (c = *(pp->str.addr + p_offset++))
-		{
-		case iop_listen:
-			/* close the listening socket associated with this connection,
-			 * rather than the actual connection socket.
-			 */
-			close_listen_socket = TRUE;
-			break;
-		case iop_exception:
-			iod->error_handler.len = *(pp->str.addr + p_offset);
-			iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1);
-			s2pool(&iod->error_handler);
-			break;
-		default:
-			break;
-		}
-		p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ?
-			(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]);
-	}
-
-	if (close_listen_socket)
-	{
-		iotcp_rmlsock(iod);
-#ifdef DEBUG_TCP
-		PRINTF("%s (listening socket for %d) <<<\n", __FILE__, tcpptr->socket);
-#endif
-	}
-	else
-	{
-	        if (iod->state != dev_open)
-		        return;
-		tcp_routines.aa_close(tcpptr->socket);
-		iod->state = dev_closed;
-#ifdef DEBUG_TCP
-		PRINTF("%s (%d) <<<\n", __FILE__, tcpptr->socket);
-#endif
-	}
-}
diff --git a/sr_port/iotcp_fillroutine.c b/sr_port/iotcp_fillroutine.c
deleted file mode 100644
index 0126610..0000000
--- a/sr_port/iotcp_fillroutine.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-/*  get socket routines address */
-#include "mdef.h"
-
-#include "gtm_netdb.h"
-#include "gtm_unistd.h"
-#include <errno.h>
-#include "gtm_socket.h"
-#include "gtm_inet.h"
-#include "gtm_string.h"	/* for FD_ZERO */
-
-#include "io.h"
-#include "iotcp_select.h"
-#include "iotcproutine.h"
-
-GBLDEF tcp_library_struct        tcp_routines;
-
-int	gtm_accept(int socket, struct sockaddr *address, sssize_t *address_len);
-int	gtm_recv(int socket, void *buffer, size_t length, int flags);
-int	gtm_send(int socket, void *buffer, size_t length, int flags);
-
-/*
- * Note - the checks for EINTR in these functions are valid and need to stay in,
- * because the functions are being assigned to members of the tcp_routines table,
- * and thus cannot be replaced by EINTR wrapper macros.
- */
-
-int	gtm_accept(int socket, struct sockaddr *address, sssize_t *address_len)
-{
-	int res;
-
-	do
-	{
-		res = accept(socket, address, (GTM_SOCKLEN_TYPE *)address_len);
-	} while (-1 == res && EINTR == errno);
-
-	return(res);
-}
-
-int	gtm_connect(int socket, struct sockaddr *address, size_t address_len)
-{
-	int			res, sockerror;
-	GTM_SOCKLEN_TYPE	sockerrorlen;
-	fd_set			writefds;
-
-	res = connect(socket, address, (GTM_SOCKLEN_TYPE)address_len);
-	if ((-1 == res) && ((EINTR == errno) || (EINPROGRESS == errno)
-#if (defined(__osf__) && defined(__alpha)) || defined(__sun) || defined(__vms)
-			|| (EWOULDBLOCK == errno)
-#endif
-			 ))
-	{/* connection attempt will continue so wait for completion */
-		do
-		{	/* a plain connect will usually timeout after 75 seconds with ETIMEDOUT */
-			FD_ZERO(&writefds);
-			FD_SET(socket, &writefds);
-			res = select(socket + 1, NULL, &writefds, NULL, NULL);
-			if (-1 == res && EINTR == errno)
-				continue;
-			if (0 < res)
-			{	/* check for socket error */
-				sockerrorlen = SIZEOF(sockerror);
-				res = getsockopt(socket, SOL_SOCKET, SO_ERROR, &sockerror, &sockerrorlen);
-				if (0 == res && 0 != sockerror)
-				{	/* return socket error */
-					res = -1;
-					errno = sockerror;
-				}
-			}
-			break;
-		} while (TRUE);
-	} else if (-1 == res && EISCONN == errno)
-		res = 0;		/* socket is already connected */
-
-	return(res);
-}
-
-int	gtm_recv(int socket, void *buffer, size_t length, int flags)
-{
-	int res;
-
-	do
-	{
-		res = (int)(recv(socket, buffer, (int)(length), flags));
-	} while (-1 == res && EINTR == errno);
-
-	return(res);
-}
-
-int	gtm_send(int socket, void *buffer, size_t length, int flags)
-{
-	int res;
-
-	do
-	{
-		res = (int)(send(socket, buffer, (int)(length), flags));
-	} while (-1 == res && EINTR == errno);
-
-	return(res);
-}
-
-int	iotcp_fillroutine(void)
-{
-	if (gtm_accept == tcp_routines.aa_accept)
-		return 0;		/* already done */
-	tcp_routines.aa_accept = gtm_accept;
-	tcp_routines.aa_bind = bind;
-	tcp_routines.aa_close = close;
-	tcp_routines.aa_connect = gtm_connect;
-	tcp_routines.aa_getsockname = getsockname;
-	tcp_routines.aa_getsockopt = getsockopt;
-	tcp_routines.aa_listen = listen;
-	tcp_routines.aa_recv = (int (*)())gtm_recv;
-	tcp_routines.aa_select = select;
-	tcp_routines.aa_send = (int (*)())gtm_send;
-	tcp_routines.aa_setsockopt = setsockopt;
-	tcp_routines.aa_socket = socket;
-
-	return 0;
-}
diff --git a/sr_port/iotcp_flush.c b/sr_port/iotcp_flush.c
deleted file mode 100644
index d731116..0000000
--- a/sr_port/iotcp_flush.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include "gtm_stdio.h"
-#include "gtm_inet.h"
-
-#include "io.h"
-#include "iotcpdef.h"
-
-void iotcp_flush(io_desc *iod)
-{
-#ifdef C9A06001531
-	/* pending change request C9A06001531 */
-
-	d_tcp_struct	*tcpptr;
-
-#ifdef DEBUG_TCP
-	PRINTF("%s >>>\n", __FILE__);
-#endif
-	tcpptr = (d_tcp_struct *)iod->dev_sp;
-	if ((TCP_WRITE == iod->dollar.x && tcpptr->lastop) && !iod->dollar.za)
-		iotcp_wteol(1, iod);
-
-#ifdef DEBUG_TCP
-	PRINTF("%s <<<\n", __FILE__);
-#endif
-
-#endif
-	return;
-}
diff --git a/sr_port/iotcp_iocontrol.c b/sr_port/iotcp_iocontrol.c
deleted file mode 100644
index 76959d8..0000000
--- a/sr_port/iotcp_iocontrol.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include <sys/types.h>
-#include "gtm_inet.h"
-
-#include "gtm_string.h"
-#include "io.h"
-#include "iotcpdef.h"
-
-GBLREF io_pair		io_curr_device;
-
-void	iotcp_iocontrol(mstr *d)
-{
-	return;
-}
-
-
-void	iotcp_dlr_device(mstr *d)
-{
-	io_desc		*iod;
-	int		len;
-
-	iod = io_curr_device.out;
-	len = STRLEN(iod->dollar.device);
-	/* verify internal buffer has enough space for $DEVICE string value */
-	assert((int)d->len > len);
-	memcpy(d->addr, iod->dollar.device, len);
-	d->len = len;
-	return;
-}
-
-
-void	iotcp_dlr_key(mstr *d)
-{
-	io_desc		*iod;
-	int		len;
-
-	iod = io_curr_device.out;
-    	len = STRLEN(iod->dollar.key);
-	/* verify internal buffer has enough space for $KEY string value */
-	assert((int)d->len > len);
-	memcpy(d->addr, iod->dollar.key, len);
-	d->len = len;
-	return;
-}
diff --git a/sr_port/iotcp_list.c b/sr_port/iotcp_list.c
deleted file mode 100644
index d1f5442..0000000
--- a/sr_port/iotcp_list.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-/* iotcp_list.c - routines to maintain a list of TCP/IP listening sockets */
-
-#include "mdef.h"
-
-#include "gtm_stdio.h"
-#include "gtm_string.h"
-#include "gtm_socket.h"
-#include "gtm_inet.h"
-
-#include <errno.h>
-
-#include "io_params.h"
-#include "io.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
-
-error_def(ERR_SOCKINIT);
-error_def(ERR_TEXT);
-
-/* list of listening sockets */
-typedef struct	lsock_rec_s
-{
-	int			socket;
-	struct sockaddr_storage	sas;
-	struct addrinfo		ai;
-	struct lsock_rec_s	*next;
-	io_log_name		*ldev;		/* listening device record */
-} lsock_rec;
-
-static lsock_rec		*lsock_list = NULL;
-
-GBLREF tcp_library_struct        tcp_routines;
-
-int	iotcp_newlsock(io_log_name *dev, d_tcp_struct *tcpptr);
-
-/* find the listening socket associated with the address of this
- * new socket, creating a listening socket if there is none.
- */
-int	iotcp_getlsock(io_log_name *dev)
-{
-	d_tcp_struct *tcpptr;
-	lsock_rec *ls;
-
-#ifdef DEBUG_TCP
-	PRINTF("iotcp_getlsock ---\n");
-#endif
-
-	tcpptr = (d_tcp_struct *)dev->iod->dev_sp;
-
-	for (ls = lsock_list;  ls != NULL;  ls = ls->next)
-		if (0 == memcmp(&(tcpptr->sas), &(ls->sas), SIZEOF(tcpptr->sas)))
-			return ls->socket;
-
-	return iotcp_newlsock(dev, tcpptr);
-}
-
-
-int	iotcp_newlsock(io_log_name *dev, d_tcp_struct *tcpptr)
-{
-	lsock_rec	*new_lsock;
-
-	io_log_name	*ldev;		/* listening device */
-	d_tcp_struct	*lsock_tcp;
-	int		lsock;
-	char		buf[MAX_TRANS_NAME_LEN];
-	static char	ones[] = {1, 1, 1};
-	mstr		ldev_name;
-	int		on = 1;
-	char		*errptr;
-	int4		errlen;
-
-#ifdef DEBUG_TCP
-	PRINTF("iotcp_newlsock ---\n");
-#endif
-
-	lsock = tcp_routines.aa_socket(tcpptr->ai.ai_family, tcpptr->ai.ai_socktype, tcpptr->ai.ai_protocol);
-	if (lsock == -1)
-	{
-		errptr = (char *)STRERROR(errno);
-		errlen = STRLEN(errptr);
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-		return 0;
-	}
-
-	/* allow multiple connections to the same IP address */
-	if (tcp_routines.aa_setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)) == -1)
-	{
-		errptr = (char *)STRERROR(errno);
-		errlen = STRLEN(errptr);
-		(void)tcp_routines.aa_close(lsock);
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-		return 0;
-	}
-
-	if (-1 == tcp_routines.aa_bind(lsock, tcpptr->ai.ai_addr, tcpptr->ai.ai_addrlen))
-	{
-		errptr = (char *)STRERROR(errno);
-		errlen = STRLEN(errptr);
-		(void)tcp_routines.aa_close(lsock);
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-		return 0;
-	}
-
-	/* establish a queue of length 5 for incoming connections */
-	if (tcp_routines.aa_listen(lsock, 5) == -1)
-	{
-		errptr = (char *)STRERROR(errno);
-		errlen = STRLEN(errptr);
-		(void)tcp_routines.aa_close(lsock);
-		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-		return 0;
-	}
-
-	/* create an extra device for the listening socket (device
-	 * name is the user-specified device name with three ^A's
-	 * appended).  We need this device to be on the io_log_name
-	 * list so that it gets closed automatically when the user's
-	 * program exits.
-	 */
-	ldev_name.addr=buf;
-	memcpy(ldev_name.addr, dev->dollar_io, dev->len);
-	memcpy(ldev_name.addr+dev->len, ones, 3);
-	ldev_name.len = dev->len + 2;
-	ldev = get_log_name(&ldev_name, INSERT);
-
-	/* copy all state information from the current device */
-
-	/* io descriptor */
-	ldev->iod = (io_desc *)malloc(SIZEOF(io_desc));
-	memcpy(ldev->iod, dev->iod, SIZEOF(io_desc));
-	ldev->iod->state = dev_open;
-	ldev->iod->pair.in  = ldev->iod;
-	ldev->iod->pair.out = ldev->iod;
-
-	/* tcp-specific information */
-	ldev->iod->dev_sp = (void *)malloc(SIZEOF(d_tcp_struct));
-	lsock_tcp=(d_tcp_struct *)ldev->iod->dev_sp;
-	memcpy(lsock_tcp, tcpptr, SIZEOF(d_tcp_struct));
-
-	lsock_tcp->socket = lsock;
-	ldev->iod->state = dev_open;
-
-	/* add to our list of tcp listening sockets */
-	new_lsock = (lsock_rec *)malloc(SIZEOF(lsock_rec));
-	new_lsock->socket = lsock;
-	new_lsock->ai = tcpptr->ai;
-	new_lsock->sas = tcpptr->sas;
-	new_lsock->ai.ai_addr = (struct sockaddr *)(&new_lsock->sas);
-	new_lsock->next = lsock_list;
-	new_lsock->ldev = ldev;
-	lsock_list = new_lsock;
-
-	return lsock;
-}
-
-
-void iotcp_rmlsock(io_desc *iod)
-{
-	lsock_rec	*ls, *prev, *next;
-	d_tcp_struct	*tcpptr = (d_tcp_struct *)iod->dev_sp;
-
-	for (prev = NULL, ls = lsock_list;  ls != NULL;)
-	{
-		next = ls->next;
-		/* Actually it's enough to just compare the port number, however extracting port from
-		 * sas needs to call getnameinfo(). Same sas can guarantee the same port, so
-		 * it's enough to use sas to detect whether the device is what we want to delete
-		 */
-		if (0 == memcmp(&(tcpptr->sas), &(ls->sas), SIZEOF(tcpptr->sas)))
-		{
-			if (prev)
-				prev->next = ls->next;
-			else
-				lsock_list = ls->next;
-			tcp_routines.aa_close(ls->socket);
-			ls->ldev->iod->state = dev_closed;
-			free(ls);
-		}
-		else
-			prev = ls;
-		ls = next;
-	}
-}
diff --git a/sr_port/iotcp_open.c b/sr_port/iotcp_open.c
deleted file mode 100644
index 262bd15..0000000
--- a/sr_port/iotcp_open.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-/* iotcp_open.c - open a TCP/IP connection
- *  Parameters-
- *	dev		- the logical name associated with this socket (ignored by this routine).
- *	pp->str.addr 	- device parameters.  The "stream" parameter is required.
- *	file_des	- unused. (UNIX only)
- *	mspace		- unused.
- *	t		- maximum time to wait for a connection (in ms).
- *
- *  Returns-
- *	non-zero	- socket successfully opened and ready for I/O
- *	zero		- open operation failed or timed out.
- */
-#include "mdef.h"
-
-#include <errno.h>
-#include "gtm_fcntl.h"
-#include "gtm_time.h"
-#include "gtm_socket.h"
-#include "gtm_netdb.h"	/* gtm_netdb must be in front so that AI_V4MAPPED will be defined */
-#include "gtm_ipv6.h"
-#include "gtm_inet.h"
-#include "gtm_ctype.h"
-#include "gtm_string.h"
-#include "gtm_stdio.h"
-
-#include "copy.h"
-#include "gt_timer.h"
-#include "io.h"
-#include "iotimer.h"
-#include "iotcp_select.h"
-#include "iotcpdef.h"
-#include "iotcpdefsp.h"
-#include "iotcproutine.h"
-#include "io_params.h"
-#include "stringpool.h"
-#include "outofband.h"
-#include "wake_alarm.h"
-#include "util.h"
-
-GBLREF tcp_library_struct	tcp_routines;
-GBLREF bool			out_of_time;
-GBLREF volatile int4		outofband;
-LITREF unsigned char		io_params_size[];
-
-error_def(ERR_DEVPARMNEG);
-error_def(ERR_GETADDRINFO);
-error_def(ERR_GETNAMEINFO);
-error_def(ERR_INVADDRSPEC);
-error_def(ERR_INVPORTSPEC);
-error_def(ERR_IPADDRREQ);
-error_def(ERR_OPENCONN);
-error_def(ERR_SOCKACPT);
-error_def(ERR_SOCKINIT);
-error_def(ERR_SOCKPARMREQ);
-error_def(ERR_SOCKWAIT);
-error_def(ERR_TEXT);
-
-short	iotcp_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4 timeout)
-{
-	boolean_t		no_time_left = FALSE, timed;
-	char			addr[SA_MAXLEN + 1], *errptr, sockaddr[SA_MAXLEN + 1],
-				temp_addr[SA_MAXLEN + 1], temp_ch;
-	char			ipname[SA_MAXLEN];
-	unsigned char		ch, len;
-	int4			length, width;
-	unsigned short		port;
-	int4			errlen, msec_timeout;
-	GTM_SOCKLEN_TYPE	size;
-	int			ii, status,
-				on = 1,
-				p_offset = 0,
-				temp_1 = -2;
-	TID			timer_id;
-	ABS_TIME		cur_time, end_time, time_for_read, lcl_time_for_read;
-	d_tcp_struct		*tcpptr, newtcp;
-	io_desc			*ioptr;
-	struct sockaddr_storage	peer_sas;		/* socket address + port */
-	fd_set			tcp_fd;
-	int			lsock;
-	short 			retry_num;
-	const char		*terrptr;
-	int			errcode;
-	char			port_buffer[NI_MAXSERV];
-	int			port_len;
-	struct addrinfo		*ai_ptr = NULL, *remote_ai_ptr = NULL, *tmp_ai_ptr, hints;
-	int			host_len; /* addr_len + port_len + delimeters */
-	int			af;
-	int			test_ipv6_sd;
-
-#ifdef	DEBUG_TCP
-	PRINTF("iotcp_open.c >>>   tt = %d\n", t);
-#endif
-	ioptr = dev->iod;
-	assert((params) *(pp->str.addr + p_offset) < (unsigned char)n_iops);
-	assert(0 != ioptr);
-	assert(ioptr->state >= 0 && ioptr->state < n_io_dev_states);
-	assert(tcp == ioptr->type);
-	if (dev_never_opened == ioptr->state)
-	{
-		ioptr->dev_sp = (void *)malloc(SIZEOF(d_tcp_struct));
-		memset(ioptr->dev_sp, 0, SIZEOF(d_tcp_struct));
-	}
-	tcpptr = (d_tcp_struct *)ioptr->dev_sp;
-	if (dev_never_opened == ioptr->state)
-	{
-		ioptr->state	= dev_closed;
-		ioptr->width	= TCPDEF_WIDTH;
-		ioptr->length	= TCPDEF_LENGTH;
-		ioptr->wrap	= TRUE;
-		if (-1 == iotcp_fillroutine())
-			assert(FALSE);
-	}
-	ioptr->dollar.zeof = FALSE;
-	newtcp = *tcpptr;
-	memcpy(ioptr->dollar.device, LITZERO, SIZEOF(LITZERO));
-	newtcp.passive = FALSE;
-	while (iop_eol != *(pp->str.addr + p_offset))
-	{
-		switch	(ch = *(pp->str.addr + p_offset++))
-		{
-		case	iop_width:
-			GET_LONG(width, pp->str.addr + p_offset);
-			if (0 == width)
-				newtcp.width = TCPDEF_WIDTH;
-			else if (width > 0)
-				newtcp.width = width;
-			else
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1)	ERR_DEVPARMNEG);
-			break;
-		case	iop_length:
-			GET_LONG(length, pp->str.addr + p_offset);
-			if (0 == length)
-				newtcp.length = TCPDEF_LENGTH;
-			else if (length > 0)
-				newtcp.length = length;
-			else
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DEVPARMNEG);
-			break;
-		case	iop_listen:
-			newtcp.passive = TRUE;
-			break;
-		case	iop_socket:
-			/* test whether ipv6 socket is supported on local system */
-			af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
-			if (AF_INET6 == af)
-			{
-				test_ipv6_sd = tcp_routines.aa_socket(af, SOCK_STREAM, IPPROTO_TCP);
-				if (-1 == test_ipv6_sd)
-					af = AF_INET;
-				else
-					tcp_routines.aa_close(test_ipv6_sd);
-			}
-			len = *(pp->str.addr + p_offset);
-			memset(sockaddr, 0, SA_MAXLEN + 1);
-			memcpy(sockaddr, pp->str.addr + p_offset + 1, (len <= USR_SA_MAXLITLEN) ? len : USR_SA_MAXLITLEN);
-			*temp_addr = '\0';
-			*addr = '\0';
-			port = 0;
-			if (SSCANF(sockaddr, "%[^,], %hu", temp_addr, &port) < 2)
-			{
-				if (SSCANF(sockaddr, ",%hu", &port) < 1)
-				{
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
-					return	FALSE;
-				}
-				SERVER_HINTS(hints, af);
-				port_len = 0;
-				I2A(port_buffer, port_len, port);
-				port_buffer[port_len]='\0';
-				if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &ai_ptr)))
-				{
-					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
-					return FALSE;
-				}
-				memcpy(&(newtcp.ai), ai_ptr, SIZEOF(*ai_ptr));
-				memcpy(&(newtcp.sas), ai_ptr->ai_addr, ai_ptr->ai_addrlen);
-				freeaddrinfo(ai_ptr);
-				newtcp.ai.ai_addr = (struct sockaddr*)(&newtcp.sas);
-
-			} else
-			{	/* client side (connection side) */
-				SPRINTF(addr, "%s", temp_addr);
-				SPRINTF(port_buffer, "%hu", port);
-				CLIENT_HINTS_AF(hints, af);
-				if (0 != (errcode = getaddrinfo(addr, port_buffer, &hints, &remote_ai_ptr)))
-				{
-					if(AF_INET6 == af)
-					{
-						af = AF_INET;
-						CLIENT_HINTS_AF(hints, af);
-						errcode = getaddrinfo(addr, port_buffer, &hints, &remote_ai_ptr);
-					}
-					if(errcode)
-					{
-						RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
-						return FALSE;
-					}
-				}
-				memcpy(&(newtcp.ai), remote_ai_ptr, SIZEOF(struct addrinfo));
-				memcpy(&(newtcp.sas), remote_ai_ptr->ai_addr, remote_ai_ptr->ai_addrlen);
-				newtcp.ai.ai_addr = (struct sockaddr*)(&newtcp.sas);
-				freeaddrinfo(remote_ai_ptr);
-			}
-			break;
-		case	iop_exception:
-			ioptr->error_handler.len = *(pp->str.addr + p_offset);
-			ioptr->error_handler.addr = (char *)(pp->str.addr + p_offset + 1);
-			s2pool(&ioptr->error_handler);
-			break;
-		default:
-			break;
-		}
-		p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ?
-			(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]);
-	}
-	/* the previous check if ((0 == newtcp.sin.sin_port) && (0 == newtcp.sin.sin_addr.s_addr)) is no longer needed as
-   	 * getaddrinfo() will return error for the above case
-	 */
-	/* active connection must have a complete address specification */
-	if (dev_closed == ioptr->state)
-	{
-		if (newtcp.passive)		/* server side */
-		{
-			/* no listening socket for this addr?  make one. */
-			memcpy(ioptr->dev_sp, &newtcp, SIZEOF(d_tcp_struct));
-			if (!(lsock = iotcp_getlsock(dev)))
-				return	FALSE;	/* could not create listening socket */
-			timer_id = (TID)iotcp_open;
-			time_for_read.at_sec = ((0 == timeout) ? 0 : 1);
-			time_for_read.at_usec = 0;
-			while (TRUE)
-			{
-				out_of_time = FALSE;
-				if (NO_M_TIMEOUT == timeout)
-				{
-					timed = FALSE;
-					msec_timeout = NO_M_TIMEOUT;
-				} else
-				{
-					timed = TRUE;
-					msec_timeout = timeout2msec(timeout);
-					if (msec_timeout > 0)
-					{       /* there is time to wait */
-						sys_get_curr_time(&cur_time);
-						add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
-						start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL);
-					} else
-						out_of_time = TRUE;
-				}
-				for (status = 0; 0 == status; )
-				{
-					FD_ZERO(&tcp_fd);
-					FD_SET(lsock, &tcp_fd);
-					/*
-					 * Note: the check for EINTR from the select below should remain, as aa_select is a
-					 * function, and not all callers of aa_select behave the same when EINTR is returned.
-					 */
-					lcl_time_for_read = time_for_read;
-					status = tcp_routines.aa_select(lsock + 1, (void *)&tcp_fd, (void *)0, (void *)0,
-									&lcl_time_for_read);
-					if (0 > status)
-					{
-						if (EINTR == errno && FALSE == out_of_time)
-							/* interrupted by a signal which is not OUR timer */
-							status = 0;
-						else
-							break;
-					}
-					if (outofband)
-						break;
-					if (timed)
-					{
-						if (msec_timeout > 0)
-						{
-							sys_get_curr_time(&cur_time);
-							cur_time = sub_abs_time(&end_time, &cur_time);
-							if (cur_time.at_sec <= 0)
-							{
-								out_of_time = TRUE;
-								cancel_timer(timer_id);
-								break;
-							}
-						} else
-							break;
-					}
-				}
-				if (timed)
-				{
-					if (0 != msec_timeout)
-					{
-						cancel_timer(timer_id);
-						if (out_of_time || outofband)
-							return FALSE;
-						/*if (outofband)
-							outofband_action(FALSE);*/
-					}
-				}
-				if (0 > status)
-				{
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					iotcp_rmlsock((io_desc *)dev->iod);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKWAIT, 0, ERR_TEXT, 2, errlen, errptr);
-					return FALSE;
-				}
-				size = SIZEOF(struct sockaddr_storage);
-				status = tcp_routines.aa_accept(lsock, (struct sockaddr*)&peer_sas, &size);
-				if (-1 == status)
-				{
-#					ifdef __hpux
-					if (ENOBUFS == errno)
-						continue;
-#					endif
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					iotcp_rmlsock((io_desc *)dev->iod);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKACPT, 0, ERR_TEXT, 2, errlen, errptr);
-					return FALSE;
-				}
-				newtcp.socket = status;
-				break;
-			}
-		} else			/* client side */
-		{
-			if (NO_M_TIMEOUT != timeout)
-			{
-				msec_timeout = timeout2msec(timeout);
-				sys_get_curr_time(&cur_time);
-				add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
-			}
-			no_time_left = FALSE;
-			temp_1 = 1;
-			do
-			{
-				if (1 != temp_1)
-					tcp_routines.aa_close(newtcp.socket);
-				newtcp.socket = tcp_routines.aa_socket(newtcp.ai.ai_family, newtcp.ai.ai_socktype,
-								       newtcp.ai.ai_protocol);
-				if (-1 == newtcp.socket)
-				{
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-					return FALSE;
-				}
-				/*	allow multiple connections to the same IP address */
-				if	(-1 == tcp_routines.aa_setsockopt(newtcp.socket, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)))
-				{
-					(void)tcp_routines.aa_close(newtcp.socket);
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-					return FALSE;
-				}
-				size=SIZEOF(newtcp.bufsiz);
-				if (-1 == tcp_routines.aa_getsockopt(newtcp.socket, SOL_SOCKET, SO_RCVBUF, &newtcp.bufsiz, &size))
-				{
-					(void)tcp_routines.aa_close(newtcp.socket);
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, errno, errlen, errptr);
-					return FALSE;
-				}
-				/*
-				 * Note: the check for EINTR from the connect need not be converted to an EINTR wrapper macro,
-				 * since the connect is not retried on EINTR.
-				 */
-				temp_1 = tcp_routines.aa_connect(newtcp.socket, (struct sockaddr *)&newtcp.sas,
-								 newtcp.ai.ai_addrlen);
-				if ((temp_1 < 0) && (ECONNREFUSED != errno) && (EINTR != errno))
-				{
-					(void)tcp_routines.aa_close(newtcp.socket);
-					errptr = (char *)STRERROR(errno);
-					errlen = STRLEN(errptr);
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_OPENCONN, 0, ERR_TEXT, 2, errlen, errptr);
-					return FALSE;
-				}
-				if ((temp_1 < 0) && (EINTR == errno))
-				{
-					(void)tcp_routines.aa_close(newtcp.socket);
-					return FALSE;
-				}
-				if ((temp_1 < 0) && (NO_M_TIMEOUT != timeout))
-				{
-					sys_get_curr_time(&cur_time);
-					cur_time = sub_abs_time(&end_time, &cur_time);
-					if (cur_time.at_sec <= 0)
-						no_time_left = TRUE;
-				}
-				SHORT_SLEEP(100);		/* Sleep for 100 ms */
-			}
-			while ((TRUE != no_time_left) && (temp_1 < 0));
-			if (temp_1 < 0) /* out of time */
-			{
-				tcp_routines.aa_close(newtcp.socket);
-				return FALSE;
-			}
-		}
-		memcpy(ioptr->dev_sp, &newtcp, SIZEOF(d_tcp_struct));
-		ioptr->state = dev_open;
-	}
-#ifdef	DEBUG_TCP
-	PRINTF("%s (%d) <<<\n", __FILE__, tcpptr->socket);
-#endif
-	return TRUE;
-}
diff --git a/sr_port/iotcp_rdone.c b/sr_port/iotcp_rdone.c
deleted file mode 100644
index 18deb0a..0000000
--- a/sr_port/iotcp_rdone.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-#include "io.h"
-
-int	iotcp_rdone (mint *v, int4 timeout) /* timeout in seconds */
-{
-	mval	tmp;
-	int	ret;
-
-	ret = iotcp_readfl(&tmp, 1, timeout);
-	if (ret)
-		*v = (int4)*(unsigned char *)(tmp.str.addr);
-	else
-		*v = -1;
-	return ret;
-}
diff --git a/sr_port/iotcp_readfl.c b/sr_port/iotcp_readfl.c
deleted file mode 100644
index 6bff9ad..0000000
--- a/sr_port/iotcp_readfl.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include <errno.h>
-#include "gtm_stdio.h"
-#include "gtm_time.h"
-#include "gtm_inet.h"
-#include "gtm_string.h"
-
-#ifdef UNIX
-#include "gtm_fcntl.h"
-#include "eintr_wrappers.h"
-static int fcntl_res;
-#endif
-
-#include "gt_timer.h"
-#include "io.h"
-#include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcp_select.h"
-#include "iotcproutine.h"
-#include "stringpool.h"
-#include "wake_alarm.h"
-
-/* Maximum we will read in one read for this device */
-#define MAX_READLEN 32767
-
-GBLREF	io_pair			io_curr_device;
-GBLREF	bool			out_of_time;
-GBLREF	spdesc			stringpool;
-GBLREF	tcp_library_struct	tcp_routines;
-GBLREF	int4			outofband;
-
-error_def(ERR_IOEOF);
-error_def(ERR_TEXT);
-error_def(ERR_GETSOCKOPTERR);
-error_def(ERR_SETSOCKOPTERR);
-
-int	iotcp_readfl(mval *v, int4 width, int4 timeout)
-/* 0 == width is a flag that the caller is read and the length is not actually fixed */
-/* timeout in seconds */
-{
-	/* VMS uses the UCX interface; should support others that emulate it */
-	boolean_t	ret, timed, vari;
-	int		flags, len, real_errno, save_errno;
-	int		i;
-	io_desc		*io_ptr;
-	d_tcp_struct	*tcpptr;
-	int4		status;
-	int4		msec_timeout;	/* timeout in milliseconds */
-	TID		timer_id;
-	ABS_TIME	cur_time, end_time, time_for_read, lcl_time_for_read, zero;
-	fd_set		tcp_fd;
-	char		*errptr;
-	int4		errlen;
-
-#ifdef DEBUG_TCP
-	PRINTF("%s >>>\n", __FILE__);
-#endif
-	assert(stringpool.free >= stringpool.base);
-	assert(stringpool.free <= stringpool.top);
-	if (0 == width)
-	{	/* op_readfl won't do this; must be a call from iotcp_read */
-		vari = TRUE;
-		width = MAX_READLEN;
-	} else
-	{
-		vari = FALSE;
-		width = (width < MAX_READLEN) ? width : MAX_READLEN;
-	}
-	ENSURE_STP_FREE_SPACE(width);
-	io_ptr = io_curr_device.in;
-	assert(dev_open == io_ptr->state);
-	tcpptr = (d_tcp_struct *)(io_ptr->dev_sp);
-	if (io_ptr->dollar.x && (TCP_WRITE == tcpptr->lastop))
-	{	/* switching from write to read */
-#ifdef C9A06001531
-		/* pending change request C9A06-001531 */
-		if (!io_ptr->dollar.za)
-			iotcp_wteol(1, io_ptr);
-#endif
-		io_ptr->dollar.x = 0;
-	}
-	tcpptr->lastop = TCP_READ;
-	ret = TRUE;
-	timer_id = (TID)iotcp_readfl;
-	out_of_time = FALSE;
-	time_for_read.at_sec = ((0 == timeout) ? 0 : 1);
-	time_for_read.at_usec = 0;
-	if (NO_M_TIMEOUT == timeout)
-	{
-		timed = FALSE;
-		msec_timeout = NO_M_TIMEOUT;
-	} else
-	{
-		timed = TRUE;
-		msec_timeout = timeout2msec(timeout);
-		if (msec_timeout > 0)
-		{	/* there is time to wait */
-#ifdef UNIX
-			/* set blocking I/O */
-			FCNTL2(tcpptr->socket, F_GETFL, flags);
-			if (flags < 0)
-			{
-				save_errno = errno;
-				errptr = (char *)STRERROR(errno);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_GETSOCKOPTERR, 5,
-						LEN_AND_LIT("F_GETFL FOR NON BLOCKING I/O"),
-						save_errno, LEN_AND_STR(errptr));
-			}
-			FCNTL3(tcpptr->socket, F_SETFL, flags & (~(O_NDELAY | O_NONBLOCK)), fcntl_res);
-			if (fcntl_res < 0)
-			{
-				save_errno = errno;
-				errptr = (char *)STRERROR(errno);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-						LEN_AND_LIT("F_SETFL FOR NON BLOCKING I/O"),
-						save_errno, LEN_AND_STR(errptr));
-			}
-#endif
-			sys_get_curr_time(&cur_time);
-			add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
-			start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL);
-		} else
-			out_of_time = TRUE;
-	}
-	for (i = 0, status = 0; status >= 0; )
-	{
-		FD_ZERO(&tcp_fd);
-		FD_SET(tcpptr->socket, &tcp_fd);
-		assert(0 != FD_ISSET(tcpptr->socket, &tcp_fd));
-		assert(((1 == time_for_read.at_sec) || (0 == time_for_read.at_sec)) && (0 == time_for_read.at_usec));
-		/*
-		 * the check for EINTR below is valid and should not be converted to an EINTR
-		 * wrapper macro, since it might be a timeout.
-		 */
-		lcl_time_for_read = time_for_read;
-		status = tcp_routines.aa_select(tcpptr->socket + 1, (void *)(&tcp_fd), (void *)0, (void *)0,
-							&lcl_time_for_read);
-		if (status > 0)
-		{
-			status = tcp_routines.aa_recv(tcpptr->socket, (char *)(stringpool.free +  i), width - i, 0);
-			if ((0 == status) || ((-1 == status) && (ECONNRESET == errno || EPIPE == errno || EINVAL == errno)))
-			{ /* lost connection. */
-				if (0 == status)
-					errno = ECONNRESET;
-				real_errno = errno;
-				status = -2;
-				break;
-			}
-
-		}
-		if (status < 0)
-		{
-			if (EINTR == errno && FALSE == out_of_time)
-			{	/* interrupted by a signal which is not OUR timer, continue looping */
-				status = 0;
-			} else
-				real_errno = errno;
-		} else
-			real_errno = 0;
-		if (outofband)
-			break;
-		if (timed)
-		{
-			if (msec_timeout > 0)
-			{
-				sys_get_curr_time(&cur_time);
-				cur_time = sub_abs_time(&end_time, &cur_time);
-				if (cur_time.at_sec <= 0)
-				{
-					out_of_time = TRUE;
-					cancel_timer(timer_id);
-					if (status > 0)
-						i += status;
-					break;
-				}
-			} else
-			{
-				if (status > 0)
-					i += status;
-				break;
-			}
-		}
-		if (0 > status)
-			break;
-		i += status;
-		if ((vari && (0 != i)) || (i >= width))
-			break;
-	}
-	if (EINTR == real_errno)
-		status = 0;	/* don't treat a <CTRL-C> or timeout as an error */
-	if (timed)
-	{
-		if (0 == msec_timeout)
-		{
-			if (0 == status)
-				ret = FALSE;
-		} else
-		{
-#ifdef UNIX
-			real_errno = errno;
-			FCNTL3(tcpptr->socket, F_SETFL, flags, fcntl_res);
-			if (fcntl_res < 0)
-			{
-				save_errno = errno;
-				errptr = (char *)STRERROR(errno);
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
-						LEN_AND_LIT("F_SETFL FOR RESTORING SOCKET OPTIONS"),
-					  	save_errno, LEN_AND_STR(errptr));
-			}
-			errno = real_errno;
-#endif
-			if (out_of_time && (i < width))
-				ret = FALSE;
-			else
-				cancel_timer(timer_id);
-		}
-	}
-	if (i > 0)
-	{	/* there's somthing to return */
-		v->str.len = i;
-		v->str.addr = (char *)stringpool.free;
-		if (((io_ptr->dollar.x += i) >= io_ptr->width) && (TRUE == io_ptr->wrap))
-		{
-			io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width);
-			if (0 != io_ptr->length)
-				io_ptr->dollar.y %= io_ptr->length;
-			io_ptr->dollar.x %= io_ptr->width;
-		}
-	} else
-		v->str.len = 0;
-#ifdef DEBUG_TCP
-	PRINTF("%s <<<\n", __FILE__);
-#endif
-	len = SIZEOF("1,") - 1;
-	if (status >= 0)
-	{	/* no real problems */
-		io_ptr->dollar.za = 0;
-/*	the handling of urgent data doesn't work and never has, the design should be changed to use a /URGENT controlnmemonic
- *	because there is really only one character available at a time
-		zero.at_sec = zero.at_usec = 0;
-		FD_ZERO(&tcp_fd);
-		FD_SET(tcpptr->socket, &tcp_fd);
-		if (tcp_routines.aa_select(tcpptr->socket + 1, (void *)(tcpptr->urgent ? &tcp_fd : 0), (void *)0,
-								(void *)(tcpptr->urgent ? 0 : &tcp_fd), &zero) > 0)
-		{
-			memcpy(io_ptr->dollar.device, "1,", len);
-			if (tcpptr->urgent)
-			{
-				memcpy(&io_ptr->dollar.device[len], "No ",SIZEOF("No "));
-				len += SIZEOF("No ") - 1;
-			}
-			memcpy(&io_ptr->dollar.device[len], "Urgent Data", SIZEOF("Urgent Data"));
-		} else
-*/
-			memcpy(io_ptr->dollar.device, "0", SIZEOF("0"));
-	} else
-	{	/* there's a significant problem */
-		if (0 == i)
-			io_ptr->dollar.x = 0;
-		io_ptr->dollar.za = 9;
-		memcpy(io_ptr->dollar.device, "1,", len);
-		errptr = (char *)STRERROR(errno);
-		errlen = STRLEN(errptr);
-		memcpy(&io_ptr->dollar.device[len], errptr, errlen);
-		if (io_ptr->dollar.zeof || -1 == status || 0 < io_ptr->error_handler.len)
-		{
-			io_ptr->dollar.zeof = TRUE;
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_IOEOF, 0, ERR_TEXT, 2, errlen, errptr);
-		} else
-			io_ptr->dollar.zeof = TRUE;
-	}
-	return (ret);
-}
diff --git a/sr_port/iotcp_use.c b/sr_port/iotcp_use.c
deleted file mode 100644
index 3f6045f..0000000
--- a/sr_port/iotcp_use.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include "gtm_string.h"
-
-#include "gtm_unistd.h"
-#include "gtm_inet.h"
-#include "gtm_iconv.h"
-#include "gtm_stdio.h"
-
-#include "copy.h"
-#include "io.h"
-#include "iosp.h"
-#include "io_params.h"
-#include "iotcpdef.h"
-#include "stringpool.h"
-
-typedef struct
-{
-	unsigned short mem;
-	unsigned short grp;
-} uic_struct;
-
-LITREF unsigned char	io_params_size[];
-
-void	iotcp_use(io_desc *iod, mval *pp)
-{
-	unsigned char	c;
-	int4		length, width;
-	d_tcp_struct	*tcpptr, newtcp;
-	int		p_offset;
-
-	error_def(ERR_DEVPARMNEG);
-	error_def(ERR_RMWIDTHPOS);
-
-#ifdef DEBUG_TCP
-	PRINTF("%s >>>\n", __FILE__);
-#endif
-	p_offset = 0;
-	tcpptr = (d_tcp_struct *)iod->dev_sp;
-	/* copy existing parameters */
-	memcpy(&newtcp, tcpptr, SIZEOF(d_tcp_struct));
-	while (*(pp->str.addr + p_offset) != iop_eol)
-	{
-		assert((params) *(pp->str.addr + p_offset) < (params) n_iops);
-		switch (c = *(pp->str.addr + p_offset++))
-		{
-		case iop_width:
-			GET_LONG(width, pp->str.addr + p_offset);
-			if (width == 0)
-				newtcp.width = TCPDEF_WIDTH;
-			else  if (width > 0)
-				newtcp.width = width;
-			else
-				rts_error(VARLSTCNT(1) ERR_DEVPARMNEG);
-			break;
-		case iop_length:
-			GET_LONG(length, pp->str.addr + p_offset);
-			if (length == 0)
-				newtcp.length = TCPDEF_LENGTH;
-			else  if (length > 0)
-				newtcp.length = length;
-			else
-				rts_error(VARLSTCNT(1) ERR_DEVPARMNEG);
-			break;
-		case iop_urgent:
-			newtcp.urgent = TRUE;
-			break;
-		case iop_nourgent:
-			newtcp.urgent = FALSE;
-			break;
-		case iop_exception:
-			iod->error_handler.len = *(pp->str.addr + p_offset);
-			iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1);
-			s2pool(&iod->error_handler);
-			break;
-		case iop_ipchset:
-#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
-			if ( (iconv_t)0 != iod->input_conv_cd )
-			{
-				ICONV_CLOSE_CD(iod->input_conv_cd);
-			}
-			SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1));
-			if (DEFAULT_CODE_SET != iod->in_code_set)
-				ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1));
-#endif
-			break;
-                case iop_opchset:
-#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
-			if ( (iconv_t)0 != iod->output_conv_cd )
-			{
-				ICONV_CLOSE_CD(iod->output_conv_cd);
-			}
-			SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1));
-			if (DEFAULT_CODE_SET != iod->out_code_set)
-				ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET);
-#endif
-			break;
-		default:
-			break;
-		}
-		p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ?
-			(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]);
-	}
-
-	/* commit changes */
-	memcpy(tcpptr, &newtcp, SIZEOF(d_tcp_struct));
-#ifdef DEBUG_TCP
-	PRINTF("%s <<<\n", __FILE__);
-#endif
-	return;
-}
diff --git a/sr_port/iotcp_write.c b/sr_port/iotcp_write.c
deleted file mode 100644
index a85ff9d..0000000
--- a/sr_port/iotcp_write.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include "gtm_socket.h"
-#include "gtm_stdio.h"
-#include "gtm_string.h"
-#include "gtm_inet.h"
-
-#include <errno.h>
-
-#include "io.h"
-#include "iotcpdef.h"
-#include "iotcpdefsp.h"
-#include "iotcproutine.h"
-
-GBLREF io_pair			io_curr_device;
-GBLREF tcp_library_struct	tcp_routines;
-
-error_def(ERR_SOCKWRITE);
-error_def(ERR_TEXT);
-
-void	iotcp_write(mstr *v)
-{
-	io_desc		*iod;
-	char		*out;
-	int		inlen, outlen, size;
-	d_tcp_struct	*tcpptr;
-	char		*errptr;
-	int4		errlen;
-
-#ifdef DEBUG_TCP
-	PRINTF("%s >>>\n", __FILE__);
-#endif
-	iod = io_curr_device.out;
-	tcpptr = (d_tcp_struct *)iod->dev_sp;
-	tcpptr->lastop = TCP_WRITE;
-	memcpy(iod->dollar.device, LITZERO, SIZEOF(LITZERO));
-	inlen = v->len;
-	outlen = iod->width - iod->dollar.x;
-
-	if (!iod->wrap && inlen > outlen)
-		inlen = outlen;
-	if (!inlen)
-		return;
-	for (out = v->addr;  ;  out += size)
-	{
-		if (outlen > inlen)
-			outlen = inlen;
-		if ((size = tcp_routines.aa_send(tcpptr->socket, out, outlen, (tcpptr->urgent ? MSG_OOB : 0))) == -1)
-		{
-			iod->dollar.za = 9;
-			memcpy(iod->dollar.device, LITONE_COMMA, SIZEOF(LITONE_COMMA));
-			errptr = (char *)STRERROR(errno);
-			errlen = STRLEN(errptr);
-			memcpy(&iod->dollar.device[SIZEOF(LITONE_COMMA) - 1], errptr, errlen);
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKWRITE, 0, ERR_TEXT, 2, errlen, errptr);
-		}
-		assert(size == outlen);
-		iod->dollar.x += size;
-		if ((inlen -= size) <= 0)
-			break;
-
-		iod->dollar.x = 0;	/* don't use wteol to terminate wrapped records for fixed. */
-		iod->dollar.y++;	/* \n is reserved as an end-of-rec delimiter for variable format */
-		if (iod->length)	/* and fixed format requires no padding for wrapped records */
-			iod->dollar.y %= iod->length;
-
-		outlen = iod->width;
-	}
-	iod->dollar.za = 0;
-#ifdef DEBUG_TCP
-	PRINTF("%s <<<\n", __FILE__);
-#endif
-	return;
-}
diff --git a/sr_port/iotcp_wteol.c b/sr_port/iotcp_wteol.c
deleted file mode 100644
index b212352..0000000
--- a/sr_port/iotcp_wteol.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include <sys/types.h>
-#include <errno.h>
-#include <netinet/tcp.h>
-
-#include "gtm_stdio.h"
-#include "gtm_string.h"
-#include "gtm_socket.h"
-#include "gtm_inet.h"
-
-#include "io.h"
-#include "iotcpdef.h"
-#include "iotcpdefsp.h"
-#include "iotcproutine.h"
-
-void	iotcp_wteol(int4 x, io_desc *iod)
-{
-	/* pending a change request C9A06-001531 */
-	return;
-}
diff --git a/sr_port/iotcp_wtff.c b/sr_port/iotcp_wtff.c
deleted file mode 100644
index 8668ea6..0000000
--- a/sr_port/iotcp_wtff.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-#include "gtm_stdio.h"
-#include "io.h"
-
-#define FORM_FEED "\014"
-GBLREF io_pair		io_curr_device;
-
-void iotcp_wtff(void)
-{
-	mstr		temp;
-	io_desc		*iod;
-
-#ifdef DEBUG_TCP
-    PRINTF("%s >>>\n",__FILE__);
-#endif
-	iod = io_curr_device.out;
-#ifdef C9A06001531
-	iotcp_wteol(1,iod);
-#endif
-	temp.len = SIZEOF(FORM_FEED) - 1;
-	temp.addr = FORM_FEED;
-	iotcp_write(&temp);
-#ifdef C9A06001531
-	iotcp_wteol(1,iod);
-#endif
-	iod->dollar.x = 0;
-	iod->dollar.y = 0;
-#ifdef DEBUG_TCP
-    PRINTF("%s <<<\n",__FILE__);
-#endif
-}
diff --git a/sr_port/iotcp_wtone.c b/sr_port/iotcp_wtone.c
deleted file mode 100644
index 8f8104a..0000000
--- a/sr_port/iotcp_wtone.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2006 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-#include "gtm_stdio.h"
-#include "io.h"
-
-void iotcp_wtone(int ch)
-{
-	mstr	temp;
-	char	c;
-
-#ifdef DEBUG_TCP
-    PRINTF("%s >>>\n",__FILE__);
-#endif
-    	c = (char)ch;
-	temp.len = 1;
-	temp.addr = &c;
-	iotcp_write(&temp);
-#ifdef DEBUG_TCP
-	PRINTF("%s <<<\n",__FILE__);
-#endif
-	return;
-}
diff --git a/sr_port/iotcpdef.h b/sr_port/iotcpdef.h
deleted file mode 100644
index f4e97a1..0000000
--- a/sr_port/iotcpdef.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#ifndef __IOTCPDEF_H__
-#define __IOTCPDEF_H__
-#include "gtm_inet.h"
-#include "gtm_socket.h" /* for NI_MAXHOST */
-#include "gtm_netdb.h"
-/* iotcpdef.h UNIX - TCP header file */
-
-#define TCPDEF_WIDTH	255
-#define TCPDEF_LENGTH	66
-
-#define TCP_NOOP		0
-#define TCP_WRITE		1
-#define TCP_READ		2
-
-#define SA_MAXLEN	NI_MAXHOST	/* NI_MAXHOST is 1025, large enough to hold any IPV6 address format
-					 	 * e.g.(123:567:901:345:215:0:0:0)
-						 */
-#define SA_MAXLITLEN	NI_MAXHOST	/* large enough to hold any host name, e.g.
-						 * host name google: dfw06s16-in-x12.1e100.net
-						 */
-#define USR_SA_MAXLITLEN	128  /* maximum size of host GTM user can specify
-					      * the reason why the number is so small is because the host name size
-					      * is stored as one byte in socket parameter list (refer to iosocket_use)
-					      */
-
-
-#ifdef VMS
-#define VMS_MAX_TCP_IO_SIZE	(64 * 1024 - 512) /* Hard limit for TCP send or recv size. On some implementations, the limit is
-						   * 64K - 1, on others it is 64K - 512. We take the conservative approach and
-						   * choose the lower limit
-						   */
-#endif
-
-#define DOTCPSEND(SDESC, SBUFF, SBUFF_LEN, SFLAGS, RC) 								\
-{ 														\
-	ssize_t		gtmioStatus; 										\
-	size_t		gtmioBuffLen; 										\
-	size_t		gtmioChunk; 										\
-	sm_uc_ptr_t	gtmioBuff; 										\
-														\
-	gtmioBuffLen = SBUFF_LEN; 										\
-	gtmioBuff = (sm_uc_ptr_t)(SBUFF); 									\
-	for (;;) 												\
-        { 													\
-		gtmioChunk = gtmioBuffLen VMS_ONLY(> VMS_MAX_TCP_IO_SIZE ? VMS_MAX_TCP_IO_SIZE : gtmioBuffLen); \
-		if ((ssize_t)-1 != (gtmioStatus = tcp_routines.aa_send(SDESC, gtmioBuff, gtmioChunk, SFLAGS))) 	\
-	        { 												\
-			gtmioBuffLen -= gtmioStatus; 								\
-			if (0 == gtmioBuffLen) 									\
-				break; 										\
-			gtmioBuff += gtmioStatus; 								\
-	        } 												\
-		else if (EINTR != errno) 									\
-		  break; 											\
-        } 													\
-	if ((ssize_t)-1 == gtmioStatus)    	/* Had legitimate error - return it */ 				\
-		RC = errno; 											\
-	else if (0 == gtmioBuffLen) 										\
-	        RC = 0; 											\
-	else 													\
-		RC = -1;		/* Something kept us from sending what we wanted */ 			\
-}
-
-/* ***************************************************** */
-/* *********** structures for TCP driver *************** */
-/* ***************************************************** */
-
-typedef struct
-{
-	char	        saddr[SA_MAXLEN];	/* socket address */
-	struct sockaddr_storage	sas;		/* socket address + port */
-	struct addrinfo		ai;
-	unsigned char	lastop;
-	int		bufsiz;			/* OS internal buffer size */
-	int		socket;			/* socket descriptor */
-	int4		width;
-	int4		length;
-	bool		passive;		/* passive connection */
-	bool		urgent;			/* urgent data mode */
-} d_tcp_struct;	/*  tcp		*/
-
-#endif
diff --git a/sr_port/iotcpdefsp.h b/sr_port/iotcpdefsp.h
deleted file mode 100644
index 1656f2f..0000000
--- a/sr_port/iotcpdefsp.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#define ASCII_LITONE_COMMA "1,"
-#define EBCDIC_LITONE_COMMA "\361\153"
-
-#define ASCII_LITZERO "0"
-#define EBCDIC_LITZERO "\360"
-
-#define LITONE_COMMA ASCII_LITONE_COMMA
-#define LITZERO	ASCII_LITZERO
diff --git a/sr_port/iotcproutine.h b/sr_port/iotcproutine.h
deleted file mode 100644
index 1cd0d9a..0000000
--- a/sr_port/iotcproutine.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/****************************************************************
-*								*
-*	Copyright 2001, 2013 Fidelity Information Services, Inc	*
-*								*
-*	This source code contains the intellectual property	*
-*	of its copyright holder(s), and is made available	*
-*	under a license.  If you do not know the terms of	*
-*	the license, please stop and do not read further.	*
-*								*
-****************************************************************/
-
-/* pointers for tcp/ip routines */
-typedef struct
-{
-	int               (*aa_accept)();
-	int               (*aa_bind)();
-	int               (*aa_close)();
-	int               (*aa_connect)();
-	int               (*aa_getsockopt)();
-	int               (*aa_getsockname)();
-	int               (*aa_listen)();
-	int               (*aa_recv)();
-	int               (*aa_select)();
-	int               (*aa_send)();
-	int               (*aa_setsockopt)();
-	int               (*aa_shutdown)();
-	int               (*aa_socket)();
-	bool               using_tcpware;      /* use tcpware(1) or ucx(0) */
-}tcp_library_struct;
-
diff --git a/sr_port/is_canonic_name.c b/sr_port/is_canonic_name.c
index da48b3b..efa774a 100644
--- a/sr_port/is_canonic_name.c
+++ b/sr_port/is_canonic_name.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,7 +26,8 @@ error_def(ERR_BADCHAR);
 /*
  * -----------------------------------------------
  * is_canonic_name()
- * validate a variable name
+ * validate a variable name (unsubscripted or subscripted).
+ * Note: This code is very similar to "gvn2gds()" in op_fnview.c. With some effort, they might even be merged into one.
  *
  * Arguments:
  *	src	   - Pointer to Source Name string mval
@@ -333,7 +334,8 @@ boolean_t is_canonic_name(mval *src, int *subscripts, int *start_off, int *stop_
 		{	/* multi-byte increment */
 			assert(4 > utf8_len);
 			if (0 > utf8_len)
-				rts_error(VARLSTCNT(6) ERR_BADCHAR, 4, 1, &src->str.addr[isrc - 1], LEN_AND_LIT(UTF8_NAME));
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(6) ERR_BADCHAR, 4, 1, &src->str.addr[isrc - 1], LEN_AND_LIT(UTF8_NAME));
 			isrc += utf8_len;
 		}
 #		endif
diff --git a/sr_port/jnl_put_jrt_pini.c b/sr_port/jnl_put_jrt_pini.c
index b6287bb..2244894 100644
--- a/sr_port/jnl_put_jrt_pini.c
+++ b/sr_port/jnl_put_jrt_pini.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -62,7 +62,7 @@ void	jnl_put_jrt_pini(sgmnt_addrs *csa)
 	if (!jgbl.forw_phase_recovery)
 	{
 		assert(NULL == jgbl.mur_pini_addr_reset_fnptr);
-		assert(NULL == csa->rctl);
+		assert((NULL == csa->miscptr) || IS_DSE_IMAGE);
 		mur_plst = NULL;
 		if (IS_GTCM_GNP_SERVER_IMAGE && (NULL != originator_prc_vec))
 		{
@@ -72,8 +72,8 @@ void	jnl_put_jrt_pini(sgmnt_addrs *csa)
 			memset((unsigned char*)&pini_record.process_vector[ORIG_JPV], 0, SIZEOF(jnl_process_vector));
 	} else
 	{
-		assert(NULL != csa->rctl);
-		mur_plst = csa->rctl->mur_plst;
+		assert(NULL != csa->miscptr);
+		mur_plst = ((reg_ctl_list *)csa->miscptr)->mur_plst;
 		if (NULL != jgbl.mur_pini_addr_reset_fnptr)
 		{
 			memcpy((unsigned char*)&pini_record.process_vector[ORIG_JPV],
diff --git a/sr_port/jnl_write_aimg_rec.c b/sr_port/jnl_write_aimg_rec.c
index 31a7589..9816ce2 100644
--- a/sr_port/jnl_write_aimg_rec.c
+++ b/sr_port/jnl_write_aimg_rec.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,7 +32,9 @@
 #ifdef GTM_CRYPT
 #include "gtmcrypt.h"
 #endif
+
 GBLREF 	jnl_gbls_t		jgbl;
+GBLREF	mstr			pvt_crypt_buf;
 
 void jnl_write_aimg_rec(sgmnt_addrs *csa, cw_set_element *cse, uint4 com_csum)
 {
@@ -82,19 +84,21 @@ void jnl_write_aimg_rec(sgmnt_addrs *csa, cw_set_element *cse, uint4 com_csum)
 	save_buffer = buffer;
 #	ifdef GTM_CRYPT
 	in_len = aimg_record.bsiz - SIZEOF(*buffer);
-	if (BLOCK_REQUIRE_ENCRYPTION(csd->is_encrypted, buffer->levl, in_len))
+	if (BLK_NEEDS_ENCRYPTION3(csd->is_encrypted, buffer->levl, in_len))
 	{
 		ASSERT_ENCRYPTION_INITIALIZED;
-		memcpy(csa->encrypted_blk_contents, buffer, SIZEOF(*buffer));
-		in = (char *)(buffer + 1);
-		out = csa->encrypted_blk_contents + SIZEOF(blk_hdr);
+		assert(aimg_record.bsiz <= csa->hdr->blk_size);
+		REALLOC_CRYPTBUF_IF_NEEDED(csa->hdr->blk_size);
+		memcpy(pvt_crypt_buf.addr, buffer, SIZEOF(blk_hdr));	/* copy the block header */
+		in = (char *)(buffer + 1);	/* + 1 because `buffer' is of type blk_hdr_ptr_t */
+		out = pvt_crypt_buf.addr + SIZEOF(blk_hdr);
 		GTMCRYPT_ENCRYPT(csa, csa->encr_key_handle, in, in_len, out, gtmcrypt_errno);
 		if (0 != gtmcrypt_errno)
 		{
 			seg = csa->region->dyn.addr;
 			GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, seg->fname_len, seg->fname);
 		}
-		buffer = (blk_hdr_ptr_t)csa->encrypted_blk_contents;
+		buffer = (blk_hdr_ptr_t)pvt_crypt_buf.addr;
 	}
 #	endif
 	cursum = jnl_get_checksum((uint4 *)buffer, NULL, aimg_record.bsiz);
diff --git a/sr_port/jobexam_process.c b/sr_port/jobexam_process.c
index 5d6942f..9c38463 100644
--- a/sr_port/jobexam_process.c
+++ b/sr_port/jobexam_process.c
@@ -221,7 +221,7 @@ CONDITION_HANDLER(jobexam_dump_ch)
 {
 	boolean_t	save_created_core;
 
-	START_CH;
+	START_CH(TRUE);
 
 	/* Operation:
 	 * 1) Flush out message we came here because of to operator console
diff --git a/sr_port/lastchance3.c b/sr_port/lastchance3.c
index 1dbb575..991e2cd 100644
--- a/sr_port/lastchance3.c
+++ b/sr_port/lastchance3.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,7 +34,7 @@ error_def(ERR_VMSMEMORY);
 CONDITION_HANDLER(lastchance3)
 {
 
-	START_CH;
+	START_CH(TRUE);
 	ESTABLISH(terminate_ch);
 	if (DUMPABLE)
 	{
diff --git a/sr_port/lke.hlp b/sr_port/lke.hlp
index 2a80563..ba71780 100644
--- a/sr_port/lke.hlp
+++ b/sr_port/lke.hlp
@@ -4,12 +4,12 @@
    The M Lock Utility (LKE) is a tool for examining and changing the GT.M
    LOCK environment. For a description of M LOCKs, refer to the LOCKs section
    in the General Language Features of M chapter and the description of the
-   LOCK command in the Commands chapter of the GT.M Programmer's Guide.
+   LOCK command in the Commands chapter of the Programmers Guide.
 
    The two primary functions of the M Lock Utility (LKE) are:
 
-     o SHOW all or specified LOCKs currently active
-     o CLEAR all or specified LOCKs currently active
+    1. SHOW all or specified LOCKs currently active
+    2. CLEAR all or specified LOCKs currently active
 
    When debugging an M application, you may use LKE to identify a possible
    deadlock situation, that is, two or more processes have LOCKs and are
@@ -82,7 +82,7 @@
 1 Commands
    Commands
 
-   The format for the LKE commands is:
+   The general format of LKE commands is:
 
    command [-qualifier[=qualifier-value]]
 
@@ -552,3 +552,32 @@
    | SP[AWN] | none                | shellcommand                      |
    +-------------------------------------------------------------------+
 
+1 Copyright
+   Copyright
+
+   Copyright 2013
+
+   Fidelity Information Services, Inc. All rights reserved.
+
+   Permission is granted to copy, distribute and/or modify this document
+   under the terms of the GNU Free Documentation License, Version 1.3 or any
+   later version published by the Free Software Foundation; with no Invariant
+   Sections, no Front-Cover Texts and no Back-Cover Texts.
+
+   GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
+   trademarks are the property of their respective owners.
+
+   This document contains a description of GT.M and the operating
+   instructions pertaining to the various functions that comprise the system.
+   This document does not contain any commitment of FIS. FIS believes the
+   information in this publication is accurate as of its publication date;
+   such information is subject to change without notice. FIS is not
+   responsible for any errors or defects.
+
+   **Note**
+
+   This help file is a concise representation of revision V6.1-000 of the
+   UNIX Administration and Operations Guide. To obtain a copy of the current
+   revision, go to www.fis-gtm.com and then click on the User Documentation
+   tab.
+
diff --git a/sr_port/lvzwr_out.c b/sr_port/lvzwr_out.c
index f30d9f2..538798c 100644
--- a/sr_port/lvzwr_out.c
+++ b/sr_port/lvzwr_out.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,7 @@
 #include "copy.h"
 #include "jnl.h"
 #include "buddy_list.h"
+#include "hashtab_mname.h"
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
 #include "merge_def.h"
@@ -40,6 +41,8 @@
 #include "stringpool.h"
 #include "alias.h"
 #include "callg.h"
+#include "gtmimagename.h"
+#include "format_targ_key.h"	/* for ISSUE_GVSUBOFLOW_ERROR macro */
 
 GBLREF lvzwrite_datablk	*lvzwrite_block;
 GBLREF zshow_out	*zwr_output;
@@ -104,7 +107,10 @@ void lvzwr_out(lv_val *lvp)
 	mident_fixed		zwrt_varname;
 	lvzwrite_datablk	*newzwrb;
 	gparam_list		param_list;	/* for op_putindx call through callg */
+	gvnh_reg_t		*gvnh_reg;
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	val = &lvp->v;
 	assert(lvzwrite_block);
 	if (!merge_args)
@@ -269,28 +275,43 @@ void lvzwr_out(lv_val *lvp)
 	{	/* MERGE assignment from local variable */
 		nsubs = lvzwrite_block->curr_subsc;
 		if (MARG1_IS_GBL(merge_args))
-		{	/* Target global var */
+		{	/* Target is a global var : i.e. MERGE ^gvn1=lcl1.
+			 * In this case, mglvnp->gblp[IND1]->gvkey_nsubs would have been initialized in op_merge.c already.
+			 * Use that to check if the target node in ^gvn1 exceeds max # of subscripts.
+			 */
+			if (MAX_GVSUBSCRIPTS <= (mglvnp->gblp[IND1]->gvkey_nsubs + nsubs))
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
 			memcpy(gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->end + 1);
 			gv_currkey->end = mglvnp->gblp[IND1]->s_gv_currkey->end;
-			for (n = 0 ; n < nsubs; n++)
+			for (n = 0; n < nsubs; n++)
 			{
 				subscp = ((zwr_sub_lst *)lvzwrite_block->sub)->subsc_list[n].actual;
 				MV_FORCE_STR(subscp);
-				mval2subsc(subscp, gv_currkey);
+				mval2subsc(subscp, gv_currkey, gv_cur_region->std_null_coll);
 				if (!subscp->str.len &&	(ALWAYS != gv_cur_region->null_subs))
 					sgnl_gvnulsubsc();
 			}
 			MV_FORCE_STR(val);
+			gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname/op_gvextnam/op_gvnaked done before op_merge */
+			/* If gvnh_reg corresponds to a spanning global, then determine
+			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+			 */
+			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, (TREF(gd_targ_addr)), gv_currkey);
+			/* For spanning globals, "gv_cur_region" points to the target region for ^gvn1 only now.
+			 * So do the GVSUBOFLOW check (both for spanning and non-spanning globals) now.
+			 */
+			if (gv_currkey->end >= gv_cur_region->max_key_size)
+				ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
 			op_gvput(val);
 		} else
-		{	/* Target local var - pre-process target in case is a container */
+		{	/* Target is a local var : pre-process target in case it is a container */
 			assert(MARG1_IS_LCL(merge_args));
 			dst_lv = mglvnp->lclp[IND1];
 			if (!LV_IS_BASE_VAR(dst_lv))
 			{
 				LV_SBS_DEPTH(dst_lv, FALSE, sbs_depth);
 				if (MAX_LVSUBSCRIPTS < (sbs_depth + nsubs))
-					rts_error(VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
 			}
 			param_list.arg[0] = dst_lv;	/* this is already protected from stp_gcol by op_merge so no need to
 							 * push this into the stack for stp_gcol protection. */
diff --git a/sr_port/m_set.c b/sr_port/m_set.c
index 06a8526..03a9272 100644
--- a/sr_port/m_set.c
+++ b/sr_port/m_set.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -95,31 +95,31 @@ LITREF fun_data_type	fun_data[];
 void	allow_dzwrtac_as_mident(void);
 
 int m_set(void)
-{
-	/* Some comment on "parse_warn". It is set to TRUE whenever the parse encounters an
-	   invalid setleft target.
-
-	   * Note that even if "parse_warn" is TRUE, we should not return FALSE right away but need to continue the parse
-	   * until the end of the current SET command. This way any remaining commands in the current parse line will be
-	   * parsed and triples generated for them. This is necessary just in case the currently parsed invalid SET command
-	   * does not get executed at runtime (due to postconditionals etc.)
-	   *
-	   * Some comment on the need for "first_setleft_invalid". This variable is needed only in the
-	   * case we encounter an invalid-SVN/invalid-FCN/unsettable-SVN as a target of the SET. We need to evaluate the
-	   * right-hand-side of the SET command only if at least one valid setleft target is parsed before an invalid setleft
-	   * target is encountered. This is because we still need to execute the valid setlefts at runtime before triggering
-	   * a runtime error for the invalid setleft. If the first setleft target is an invalid one, then there is no need
-	   * to evaluate the right-hand-side. In fact, in this case, adding triples (corresponding to the right hand side)
-	   * to the execution chain could cause problems with emit_code later in the compilation as the destination
-	   * for the right hand side triples could now be undefined (for example a valid SVN on the left side of the
-	   * SET would have generated an OC_SVPUT triple with one of its operands holding the result of the right
-	   * hand side evaluation, but an invalid SVN on the left side which would have instead caused an OC_RTERROR triple
-	   * to have been generated leaving no triple to receive the result of the right hand side evaluation thus causing
-	   * emit_code to be confused and GTMASSERT). Therefore discard all triples generated by the right hand side in this case.
-	   * By the same reasoning, discard all triples generated by setleft targets AFTER this invalid one as well.
-	   * "first_setleft_invalid" is set to TRUE if the first setleft target is invalid and set to FALSE if the first setleft
-	   * target is valid. It is initialized to -1 before the start of the parse.
-	   */
+{	/* Some comment on "parse_warn". It is set to TRUE whenever the parse encounters an invalid setleft target.
+	 *
+	 * Note that even if "parse_warn" is TRUE, we should not return FALSE right away but need to continue the parse
+	 * until the end of the current SET command. This way any remaining commands in the current parse line will be
+	 * parsed and triples generated for them. This is necessary just in case the currently parsed invalid SET command
+	 * does not get executed at runtime (due to postconditionals etc.)
+	 *
+	 * Some comment on the need for "first_setleft_invalid". This variable is needed only in the
+	 * case we encounter an invalid-SVN/invalid-FCN/unsettable-SVN as a target of the SET. We need to evaluate the
+	 * right-hand-side of the SET command only if at least one valid setleft target is parsed before an invalid setleft
+	 * target is encountered. This is because we still need to execute the valid setlefts at runtime before triggering
+	 * a runtime error for the invalid setleft. If the first setleft target is an invalid one, then there is no need
+	 * to evaluate the right-hand-side. In fact, in this case, adding triples (corresponding to the right hand side)
+	 * to the execution chain could cause problems with emit_code later in the compilation as the destination
+	 * for the right hand side triples could now be undefined (for example a valid SVN on the left side of the
+	 * SET would have generated an OC_SVPUT triple with one of its operands holding the result of the right
+	 * hand side evaluation, but an invalid SVN on the left side which would have instead caused an OC_RTERROR triple
+	 * to have been generated leaving no triple to receive the result of the right hand side evaluation thus causing
+	 * emit_code to be confused and hitting an assertpro()). Therefore discard all triples generated by the right hand
+	 * side in this case.
+	 *
+	 * By the same reasoning, discard all triples generated by setleft targets AFTER this invalid one as well.
+	 * "first_setleft_invalid" is set to TRUE if the first setleft target is invalid and set to FALSE if the first setleft
+	 * target is valid. It is initialized to -1 before the start of the parse.
+	 */
 
 	boolean_t	alias_processing, delim1char, first_is_lit, got_lparen, have_lh_alias, is_extract, last_is_lit, valid_char;
 	boolean_t	parse_warn;	/* set to TRUE in case of an invalid SVN etc. */
@@ -552,30 +552,17 @@ int m_set(void)
 						delim_mval = &delimval.oprval.tref->operand[0].oprval.mlit->v;
 						valid_char = TRUE;	/* Basic assumption unles proven otherwise */
 						if ((OC_LIT == delimval.oprval.tref->opcode)
-							&& (1 == (gtm_utf8_mode ? MV_FORCE_LEN(delim_mval)
-										: delim_mval->str.len)))
+						    && (1 == ((gtm_utf8_mode && (OC_SETPIECE == s->opcode))
+							      ? MV_FORCE_LEN_DEC(delim_mval) : delim_mval->str.len)))
 						{	/* Single char delimiter for set $piece */
-#							ifdef UNICODE_SUPPORTED
-							if (gtm_utf8_mode)
-							{	/*  We have a supposed single char delimiter but it
-								 *  must be a valid utf8 char to be used by
-								 *  op_setp1() and MV_FORCE_LEN won't tell us that.
-								 */
-								valid_char = UTF8_VALID(delim_mval->str.addr,
-									(delim_mval->str.addr + delim_mval->str.len), delimlen);
-								if (!valid_char && !badchar_inhibit)
-									UTF8_BADCHAR(0, delim_mval->str.addr,
-										(delim_mval->str.addr + delim_mval->str.len),
-										0, NULL);
-							}
-#							endif
 							if (valid_char || (1 == delim_mval->str.len))
 							{	/* This reference to a one character literal or a single
 								 * byte invalid utf8 character that needs to be turned into
 								 * an explict formated integer literal instead
 								 */
 								unichar.unichar_val = 0;
-								if (!gtm_utf8_mode)
+								if (!gtm_utf8_mode
+								    UNICODE_ONLY(|| (OC_SETZPIECE == s->opcode)))
 								{	/* Single byte delimiter */
 									assert(1 == delim_mval->str.len);
 									UNIX_ONLY(s->opcode = OC_SETZP1);
diff --git a/sr_port/m_write.c b/sr_port/m_write.c
index 92ab9c6..2e13a61 100644
--- a/sr_port/m_write.c
+++ b/sr_port/m_write.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -132,7 +132,7 @@ int m_write(void)
 				}
 				ref->operand[0].oprval.tref->opcode = OC_NOOP;
 				ref->opcode = OC_NOOP;
-				ref->operand[0].oprval.tref->operand[0].oprclass = OC_NOOP;
+				ref->operand[0].oprval.tref->operand[0].oprclass = NO_REF;
 				ref->operand[0].oprclass = NO_REF;
 			}
 			ptx--;
diff --git a/sr_port/m_zbreak.c b/sr_port/m_zbreak.c
index c7ed796..de7ce40 100644
--- a/sr_port/m_zbreak.c
+++ b/sr_port/m_zbreak.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -74,10 +74,7 @@ int m_zbreak(void)
 			return TRUE;
 		if (TK_CIRCUMFLEX != TREF(window_token))
 		{	/* Routine not specified, assume current routine */
-			if (!run_time)
-				routine = put_str(routine_name.addr, routine_name.len);
-			else
-				routine = put_tref(newtriple(OC_CURRTN));
+			routine = PUT_CURRENT_RTN;
 		} else
 		{
 			advancewindow();
diff --git a/sr_port/m_zprint.c b/sr_port/m_zprint.c
index 0cb062b..b32e759 100644
--- a/sr_port/m_zprint.c
+++ b/sr_port/m_zprint.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,10 +42,7 @@ int m_zprint(void)
 		return TRUE;
 	if (TK_CIRCUMFLEX != TREF(window_token))
 	{	/* Routine not specified, use current routine */
-		if (!run_time)
-			rtn = put_str(routine_name.addr, routine_name.len);
-		else
-			rtn = put_tref(newtriple(OC_CURRTN));
+		rtn = PUT_CURRENT_RTN;
 	} else
 	{
 		got_some = TRUE;
diff --git a/sr_port/make_gvsubsc.c b/sr_port/make_gvsubsc.c
index 6f18b86..5a88fa4 100644
--- a/sr_port/make_gvsubsc.c
+++ b/sr_port/make_gvsubsc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,6 +10,7 @@
  ****************************************************************/
 
 #include "mdef.h"
+
 #include "compiler.h"
 #include "stringpool.h"
 #include "gdsroot.h"
@@ -19,6 +20,7 @@
 #include "gdsbt.h"
 #include "gdsfhead.h"
 #include "mvalconv.h"
+#include "collseq.h"
 
 GBLREF spdesc stringpool;
 
@@ -28,12 +30,12 @@ oprtype make_gvsubsc(mval *v)
 	gv_key	*gp;
 
 	ENSURE_STP_FREE_SPACE(MAX_SRCLINE + SIZEOF(gv_key));
-	if ((INTPTR_T)stringpool.free & 1)
+	if ((INTPTR_T)stringpool.free & 1)	/* BYPASSOK */
 		stringpool.free++;	/* word align key for structure refs */
 	gp = (gv_key *) stringpool.free;
 	gp->top = MAX_SRCLINE;
 	gp->end = gp->prev = 0;
-	mval2subsc(v,gp);
+	mval2subsc(v, gp, STD_NULL_COLL_FALSE);
 	w.mvtype = MV_STR | MV_SUBLIT;
 	w.str.addr = (char *) gp->base;
 	w.str.len = gp->end + 1;
diff --git a/sr_port/md5hash.c b/sr_port/md5hash.c
new file mode 100644
index 0000000..e8bd460
--- /dev/null
+++ b/sr_port/md5hash.c
@@ -0,0 +1,295 @@
+/* md5hash.c is adapted to work with FIS GT.M (http://fis-gtm.com) from
+ * source code at http://cvsweb.xfree86.org/cvsweb/cvs/lib/md5.c?rev=1.1.1.2
+ * to which no claim of Copyright was made by the authors. No claim of
+ * copyright is made by Fidelity Information Services, Inc. with respect
+ * to the changes made to adapt it to GT.M.
+ *
+ * Summary of changes:
+ * 	+ use GT.M includes
+ * 	+ use SIZEOF macro
+ * 	+ remove ASM_MD5 and PROTO preprocessor code
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
+   not require an integer type which is exactly 32 bits.  This work
+   draws on the changes for the same purpose by Tatu Ylonen
+   <ylo at cs.hut.fi> as part of SSH, but since I didn't actually use
+   that code, there is no copyright issue.  I hereby disclaim
+   copyright in any changes I have made; this code remains in the
+   public domain.  */
+
+/* Note regarding cvs_* namespace: this avoids potential conflicts
+   with libraries such as some versions of Kerberos.  No particular
+   need to worry about whether the system supplies an MD5 library, as
+   this file is only about 3k of object code.  */
+
+#include "mdef.h"
+
+#include "gtm_string.h"
+#include "md5hash.h"
+
+/* Little-endian byte-swapping routines.  Note that these do not
+   depend on the size of datatypes such as cvs_uint32, nor do they require
+   us to detect the endianness of the machine we are running on.  It
+   is possible they should be macros for speed, but I would be
+   surprised if they were a performance bottleneck for MD5.  */
+
+static cvs_uint32
+getu32 (addr)
+     const unsigned char *addr;
+{
+	return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
+		| addr[1]) << 8 | addr[0];
+}
+
+static void
+putu32 (data, addr)
+     cvs_uint32 data;
+     unsigned char *addr;
+{
+	addr[0] = (unsigned char)data;
+	addr[1] = (unsigned char)(data >> 8);
+	addr[2] = (unsigned char)(data >> 16);
+	addr[3] = (unsigned char)(data >> 24);
+}
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+cvs_MD5Init (ctx)
+     struct cvs_MD5Context *ctx;
+{
+	ctx->buf[0] = 0x67452301;
+	ctx->buf[1] = 0xefcdab89;
+	ctx->buf[2] = 0x98badcfe;
+	ctx->buf[3] = 0x10325476;
+
+	ctx->bits[0] = 0;
+	ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+cvs_MD5Update (ctx, buf, len)
+     struct cvs_MD5Context *ctx;
+     unsigned char const *buf;
+     unsigned len;
+{
+	cvs_uint32 t;
+
+	/* Update bitcount */
+
+	t = ctx->bits[0];
+	if ((ctx->bits[0] = (t + ((cvs_uint32)len << 3)) & 0xffffffff) < t)
+		ctx->bits[1]++;	/* Carry from low to high */
+	ctx->bits[1] += len >> 29;
+
+	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+
+	/* Handle any leading odd-sized chunks */
+
+	if ( t ) {
+		unsigned char *p = ctx->in + t;
+
+		t = 64-t;
+		if (len < t) {
+			memcpy(p, buf, len);
+			return;
+		}
+		memcpy(p, buf, t);
+		cvs_MD5Transform (ctx->buf, ctx->in);
+		buf += t;
+		len -= t;
+	}
+
+	/* Process data in 64-byte chunks */
+
+	while (len >= 64) {
+		memcpy(ctx->in, buf, 64);
+		cvs_MD5Transform (ctx->buf, ctx->in);
+		buf += 64;
+		len -= 64;
+	}
+
+	/* Handle any remaining bytes of data. */
+
+	memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+cvs_MD5Final (digest, ctx)
+     unsigned char digest[16];
+     struct cvs_MD5Context *ctx;
+{
+	unsigned count;
+	unsigned char *p;
+
+	/* Compute number of bytes mod 64 */
+	count = (ctx->bits[0] >> 3) & 0x3F;
+
+	/* Set the first char of padding to 0x80.  This is safe since there is
+	   always at least one byte free */
+	p = ctx->in + count;
+	*p++ = 0x80;
+
+	/* Bytes of padding needed to make 64 bytes */
+	count = 64 - 1 - count;
+
+	/* Pad out to 56 mod 64 */
+	if (count < 8) {
+		/* Two lots of padding:  Pad the first block to 64 bytes */
+		memset(p, 0, count);
+		cvs_MD5Transform (ctx->buf, ctx->in);
+
+		/* Now fill the next block with 56 bytes */
+		memset(ctx->in, 0, 56);
+	} else {
+		/* Pad block to 56 bytes */
+		memset(p, 0, count-8);
+	}
+
+	/* Append length in bits and transform */
+	putu32(ctx->bits[0], ctx->in + 56);
+	putu32(ctx->bits[1], ctx->in + 60);
+
+	cvs_MD5Transform (ctx->buf, ctx->in);
+	putu32(ctx->buf[0], digest);
+	putu32(ctx->buf[1], digest + 4);
+	putu32(ctx->buf[2], digest + 8);
+	putu32(ctx->buf[3], digest + 12);
+	memset(ctx, 0, SIZEOF(ctx));	/* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+cvs_MD5Transform (buf, inraw)
+     cvs_uint32 buf[4];
+     const unsigned char inraw[64];
+{
+	register cvs_uint32 a, b, c, d;
+	cvs_uint32 in[16];
+	int i;
+
+	for (i = 0; i < 16; ++i)
+		in[i] = getu32 (inraw + 4 * i);
+
+	a = buf[0];
+	b = buf[1];
+	c = buf[2];
+	d = buf[3];
+
+	MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
+	MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
+	MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
+	MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
+	MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
+	MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
+	MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
+	MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
+	MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
+	MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
+	MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
+	MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
+	MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
+	MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
+	MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
+	MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
+	MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
+	MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
+	MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
+	MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
+	MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
+
+	buf[0] += a;
+	buf[1] += b;
+	buf[2] += c;
+	buf[3] += d;
+}
diff --git a/sr_port/md5hash.h b/sr_port/md5hash.h
new file mode 100644
index 0000000..c3fce75
--- /dev/null
+++ b/sr_port/md5hash.h
@@ -0,0 +1,37 @@
+/* md5hash.h is adapted to work with FIS GT.M (http://fis-gtm.com) from
+ * source code at http://cvsweb.xfree86.org/cvsweb/cvs/lib/md5.h?rev=1.6
+ * to which no claim of Copyright was made by the authors. No claim of
+ * copyright is made by Fidelity Information Services, Inc. with respect
+ * to the changes made to adapt it to GT.M.
+ *
+ * Summary of changes:
+ * 	+ add MD5_BLOCK_LENGTH and MD5_DIGEST_LENGTH macros
+ * 	+ add typedef cvs_MD5_CTX
+ * 	+ remove PROTO preprocessor code
+ */
+
+#ifndef MD5HASH_H_INCLUDED
+#define MD5HASH_H_INCLUDED
+
+#define MD5_BLOCK_LENGTH 		64
+#define MD5_DIGEST_LENGTH		16
+
+/* Unlike previous versions of this code, uint32 need not be exactly
+   32 bits, merely 32 bits or more.  Choosing a data type which is 32
+   bits instead of 64 is not important; speed is considerably more
+   important.  ANSI guarantees that "unsigned long" will be big enough,
+   and always using it seems to have few disadvantages.  */
+typedef unsigned long cvs_uint32;
+
+typedef struct cvs_MD5Context {
+	cvs_uint32	buf[4];
+	cvs_uint32	bits[2];
+	unsigned char	in[MD5_BLOCK_LENGTH];
+} cvs_MD5_CTX;
+
+void cvs_MD5Init(struct cvs_MD5Context *context);
+void cvs_MD5Update(struct cvs_MD5Context *context, unsigned char const *buf, unsigned len);
+void cvs_MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct cvs_MD5Context *context);
+void cvs_MD5Transform(cvs_uint32 buf[4], const unsigned char in[MD5_BLOCK_LENGTH]);
+
+#endif /* MD5HASH_H_INCLUDED */
diff --git a/sr_port/mdb_condition_handler.c b/sr_port/mdb_condition_handler.c
index 2fbb902..eed2f1e 100644
--- a/sr_port/mdb_condition_handler.c
+++ b/sr_port/mdb_condition_handler.c
@@ -273,7 +273,7 @@ CONDITION_HANDLER(mdb_condition_handler)
 	mv_stent		*mvst;
 #	endif
 
-	START_CH;
+	START_CH(FALSE);
 	DBGEHND((stderr, "mdb_condition_handler: Entered with SIGNAL=%d frame_pointer=0x"lvaddr"\n", SIGNAL, frame_pointer));
 	if (NULL != gtm_err_dev)
 	{
@@ -457,8 +457,7 @@ CONDITION_HANDLER(mdb_condition_handler)
 				 */
 				gv_cur_region = csa->region;
 				assert(gv_cur_region->open);
-				assert((dba_mm == gv_cur_region->dyn.addr->acc_meth)
-					|| (dba_bg == gv_cur_region->dyn.addr->acc_meth));
+				assert((dba_mm == REG_ACC_METH(gv_cur_region)) || (dba_bg == REG_ACC_METH(gv_cur_region)));
 				/* The above assert is needed to ensure that change_reg/tp_change_reg (invoked below)
 				 * will set cs_addrs, cs_data etc. to non-zero values.
 				 */
@@ -499,7 +498,7 @@ CONDITION_HANDLER(mdb_condition_handler)
 		 */
 		SET_PROCESS_EXITING_TRUE;	/* So zshow doesn't push stuff on stack to "protect" it when
 						 * we potentially already have a stack overflow */
-		cancel_timer(0);		/* No interruptions now that we are dying */
+		CANCEL_TIMERS;			/* No unsafe interruptions now that we are dying */
 		if (!repeat_error UNIX_ONLY(&& (0 == gtmMallocDepth)))
 		{
 			src_line_d.addr = src_line;	/* Setup entry point buffer for set_zstatus() */
@@ -911,7 +910,11 @@ CONDITION_HANDLER(mdb_condition_handler)
 	}
 	if ((SUCCESS == SEVERITY) || (INFO == SEVERITY))
 	{
-		PRN_ERROR;
+		/* skip printing error messages for INFO messages if this variable is set.
+		 * this is currently relied upon by GDE for the VIEW "YCHKCOLL" command.
+		 */
+		if (!TREF(skip_gtm_putmsg))
+			PRN_ERROR;
 		CONTINUE;
 	}
 	/* Error from direct mode actions or "transcendental" code does not invoke MUMPS error handling routines */
diff --git a/sr_port/mdef.h b/sr_port/mdef.h
index 6c474cf..5affbc8 100644
--- a/sr_port/mdef.h
+++ b/sr_port/mdef.h
@@ -530,9 +530,12 @@ mval *underr_strict(mval *start, ...);
 #define	IS_ASCII(X)		((uint4)(X) <= ASCII_MAX)	/* X can be greater than 255 hence the typecast to uint4 */
 
 #ifdef UNICODE_SUPPORTED
-#	define	MV_FORCE_LEN(X) ((!((X)->mvtype & MV_UTF_LEN)) 							\
-				 ? (utf8_len(&(X)->str), ((X)->mvtype |= MV_UTF_LEN), (X)->str.char_len)	\
-				 : (X)->str.char_len)
+#	define	MV_FORCE_LEN(X)	    ((!((X)->mvtype & MV_UTF_LEN)) 							\
+				     ? (utf8_len(&(X)->str), ((X)->mvtype |= MV_UTF_LEN), (X)->str.char_len)		\
+				     : (X)->str.char_len)
+#	define	MV_FORCE_LEN_DEC(X) ((!((X)->mvtype & MV_UTF_LEN)) 							\
+				     ? (utf8_len_dec(&(X)->str), ((X)->mvtype |= MV_UTF_LEN), (X)->str.char_len)	\
+				     : (X)->str.char_len)
 
 /* MV_FORCE_LEN_STRICT() is used to ensure that mval is valid in addition to computing the char_len.
  * Note that the validation is always forced even if MV_UTF_LEN is set since the previously computed
@@ -543,6 +546,7 @@ mval *underr_strict(mval *start, ...);
 #	define	MV_IS_SINGLEBYTE(X)	(((X)->mvtype & MV_UTF_LEN) && ((X)->str.len == (X)->str.char_len))
 #else
 #	define MV_FORCE_LEN(X)		((X)->str.len)
+#	define MV_FORCE_LEN_DEC(X)	((X)->str.len)
 #	define MV_FORCE_LEN_STRICT(X)	((X)->str.len)
 #	define MV_IS_SINGLEBYTE(X)	(TRUE)	/* all characters are single-byte in non-Unicode platforms */
 #endif
@@ -629,11 +633,17 @@ int4 timeout2msec(int4 timeout);
 #define	RTS_ERROR_LITERAL(LITERAL)	LENGTH_AND_LITERAL(LITERAL)
 #define	RTS_ERROR_STRING(STRING)	LENGTH_AND_STRING(STRING)
 
-#define	SET_PROCESS_EXITING_TRUE				\
-{								\
-	GBLREF	int		process_exiting;		\
-								\
-	process_exiting = TRUE;					\
+#define	SET_PROCESS_EXITING_TRUE						\
+{										\
+	GBLREF	int		process_exiting;				\
+	GBLREF	intrpt_state_t	intrpt_ok_state;				\
+										\
+	/* Since the process is exiting at this point, we want to clear the 	\
+	 * interrupt-deferring mode to prevent issues with nesting interrupt-	\
+	 * deferring states and timer delivery.					\
+	 */									\
+	process_exiting = TRUE;							\
+	intrpt_ok_state = INTRPT_OK_TO_INTERRUPT;				\
 }
 
 /* *********************************************************************************************************** */
@@ -741,11 +751,12 @@ int m_usleep(int useconds);
 #endif
 
 /* Note: LONG_SLEEP *MUST*NOT* be the sleep() function because use of the sleep() function in
-   GT.M causes problems with GT.M's timers on some platforms. Specifically, the sleep() function
-   causes the SIGARLM handler to be silently deleted on Solaris systems (through Solaris 9 at least).
-   This leads to lost timer pops and has the potential for system hangs.
+ * GT.M causes problems with GT.M's timers on some platforms. Specifically, the sleep() function
+ * causes the SIGARLM handler to be silently deleted on Solaris systems (through Solaris 9 at least).
+ * This leads to lost timer pops and has the potential for system hangs.
  */
-#define LONG_SLEEP(x)		hiber_start((x) * 1000)
+#define LONG_SLEEP(X)		hiber_start((X) * 1000)
+#define LONG_SLEEP_MSEC(X)	hiber_start(X)
 
 #define OS_PAGE_SIZE		gtm_os_page_size
 #define OS_PAGE_SIZE_DECLARE	GBLREF int4 gtm_os_page_size;
@@ -1627,7 +1638,7 @@ typedef struct repl_histinfo_struct
 	(HISTINFO).strm_seqno = 0;									\
 }
 
-/* A structure to hold ALL aspects of ONE side (could be local or remote) of a replication connection */
+/* A structure to hold ALL aspects of ONE side (could be local or remote) of a replication connection. */
 typedef struct repl_conn_info_struct
 {
 	int4		proto_ver;		/* The replication communication protocol version of this side of the pipe.
@@ -1643,6 +1654,11 @@ typedef struct repl_conn_info_struct
 						 * Non-zero (GTMNULL_TO_STDNULL_COLL or STDNULL_TO_GTMNULL_COLL) if different
 						 */
 	boolean_t	is_supplementary;	/* Whether one side of the connection is a supplementary instance */
+	boolean_t	tls_requested;		/* Whether one side of the connection requests SSL/TLS secure communication */
+	/* Since this structure is a member of jnlpool_ctl_struct which needs to be 16-byte aligned, align this structure to a
+	 * 16-byte boundary.
+	 */
+	char		filler_16[12];
 } repl_conn_info_t;
 
 #endif	/* Replication instance file related structures */
@@ -1669,16 +1685,29 @@ typedef enum
 #define IS_UTF_CHSET(chset) ((CHSET_UTF_MIN <= (chset)) && (CHSET_UTF_MAX >= (chset)))
 
 #define CHK_BOUNDARY_ALIGNMENT(pointer) (((UINTPTR_T)pointer) & (SIZEOF(UINTPTR_T) - 1))
-#if defined(__ia64) || defined(__i386) || defined(__x86_64__) || defined(__sparc) || defined(_AIX) || defined(__MVS__)	\
-				|| defined(__s390__)
-#define GTM_CRYPT
-#define GTMCRYPT_ONLY(X)		X
+
+/* Encryption and TLS related macros */
+#if defined(__ia64) || defined(__i386) || defined(__x86_64__) || defined(__sparc) || defined(_AIX) || defined(__s390__)
+# define GTM_CRYPT
+# define GTMCRYPT_ONLY(X)		X
+# define GTM_TLS
+# define GTMTLS_ONLY(X)			X
+# define GTMTLS_ONLY_COMMA(X)		, X
+# define NON_GTMTLS_ONLY(X)
 #else
-#define GTMCRYPT_ONLY(X)
+# define GTMCRYPT_ONLY(X)
+# define GTMTLS_ONLY(X)
+# define GTMTLS_ONLY_COMMA(X)
+# define NON_GTMTLS_ONLY(X)		X
 #endif
+
 #define GTMCRYPT_HASH_LEN		64
 #define GTMCRYPT_HASH_HEX_LEN		GTMCRYPT_HASH_LEN * 2
 #define GTMCRYPT_RESERVED_HASH_LEN	256
+
+#define GTMCRYPT_PLUGIN_DIR_NAME	"plugin"
+#define GTMCRYPT_UTIL_LIBNAME		"libgtmcryptutil.so"
+
 #define GET_HASH_IN_HEX(in, out, len)						\
 {										\
 	int i;									\
@@ -1788,4 +1817,19 @@ enum
 				      && ((char *)(V) < ((char *)(START) + (INTPTR_T)(END) * SIZEOF(mval))))
 #endif
 
+/* Whenever an M argument (an actual) is skipped (rather than undefined) in a label call, the resulting mval pointer refers to the
+ * skiparg, which is a special mval designated for this purpose. This is ensured by OC_NULLEXP, which is the opcode inserted for all
+ * skipped arguments.
+ */
+#define M_ARG_SKIPPED(V)			((V) == (mval *)&skiparg)
+
+/* Ensures that the argument is defined if it was not skipped. */
+#define MV_FORCE_DEFINED_UNLESS_SKIPARG(V)	((!M_ARG_SKIPPED(V)) ? (MV_FORCE_DEFINED(V)) : (V))
+
+#ifdef _AIX
+#define LIBPATH_ENV	"LIBPATH"
+#else
+#define LIBPATH_ENV	"LD_LIBRARY_PATH"
+#endif
+
 #endif /* MDEF_included */
diff --git a/sr_port/memcoherency.h b/sr_port/memcoherency.h
index 3bd002f..f7a2eb4 100644
--- a/sr_port/memcoherency.h
+++ b/sr_port/memcoherency.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -39,6 +39,8 @@
 
 #define SHM_READ_MEMORY_BARRIER		SHM_WRITE_MEMORY_BARRIER /* same MB instruction for both read and write barriers */
 
+#define MM_WRITE_MEMORY_BARRIER
+
 #ifdef __vms
 #define SECSHR_SHM_WRITE_MEMORY_BARRIER	asm("mb")
 #define SECSHR_SHM_READ_MEMORY_BARRIER	SECSHR_SHM_WRITE_MEMORY_BARRIER
@@ -103,6 +105,12 @@ void do_isync(void);
 	do_isync();			\
 }
 
+#define  MM_WRITE_MEMORY_BARRIER	\
+{					\
+	SHM_WRITE_MEMORY_BARRIER;	\
+	do_eieio();			\
+}
+
 #elif defined(__hppa)
 /* For _PA_RISC1_0, _PA_RISC1_1, accesses to the address space (both to memory and I/O) through load, store and
  * semaphore instructions are strongly ordered. This means that accesses appear to software to be done in program order
@@ -135,18 +143,44 @@ void do_isync(void);
 							  * we load shared fields */
 #elif defined(__ia64)
 
+/* In the database update logic, we must order memory mapped I/O and shared memory accesses with respect to each other.
+ * On Itanium (and on AIX, see eieio above) SHM_WRITE_MEMORY_BARRIER alone is insufficient. We also need an mf.a instruction.
+ *
+ * Refer to http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
+ * 	itanium-architecture-software-developer-rev-2-3-vol-2-manual.pdf - from page 2:616,
+ * "If software needs to ensure that all prior memory operations have been accepted by the platform and have been observed
+ * by all cache coherent agents, both an mf.a and an mf instruction must be issued. The mf.a must be issued first, and the
+ * mf must be issued second."
+ */
+
 #if defined(__hpux)
 
-#include <machine/sys/kern_inline.h>
-#define SHM_WRITE_MEMORY_BARRIER	_MF()
+#	include <machine/sys/kern_inline.h>
+#	define SHM_WRITE_MEMORY_BARRIER	_MF()
+#	define MM_WRITE_MEMORY_BARRIER			\
+{							\
+	_Asm_mf_a();					\
+	SHM_WRITE_MEMORY_BARRIER;			\
+}
 
 #elif defined(__linux__) && defined(__INTEL_COMPILER)
 
 #	define SHM_WRITE_MEMORY_BARRIER		__mf()
+#	define MM_WRITE_MEMORY_BARRIER			\
+{							\
+	__mfa();					\
+	SHM_WRITE_MEMORY_BARRIER;			\
+}
 
 #elif defined(__linux__) /* gcc */
 
 #	define SHM_WRITE_MEMORY_BARRIER		__asm__ __volatile__ ("mf" ::: "memory")
+#	define MM_WRITE_MEMORY_BARRIER			\
+{							\
+	__asm__ __volatile__ ("mf.a" ::: "memory");	\
+	SHM_WRITE_MEMORY_BARRIER;			\
+}
+
 #endif /* __linux__ */
 
 /* On IA64, cross processor notifications of write barriers are automatic so no read barrier is necessary */
@@ -162,6 +196,7 @@ void do_isync(void);
 
 #define SHM_WRITE_MEMORY_BARRIER
 #define SHM_READ_MEMORY_BARRIER
+#define MM_WRITE_MEMORY_BARRIER
 
 #endif
 
diff --git a/sr_port/merge_desc_check.c b/sr_port/merge_desc_check.c
index 5e92415..d06e44a 100644
--- a/sr_port/merge_desc_check.c
+++ b/sr_port/merge_desc_check.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -39,54 +39,183 @@ GBLREF merge_glvn_ptr	mglvnp;
 
 error_def(ERR_MERGEDESC);
 
+/* returns 1 if no descendant issues found;
+ * returns 0 if src and dst keys of merge are identical (i.e. NOOP - merge self);
+ * issues MERGEDESC error otherwise.
+ */
 boolean_t merge_desc_check(void)
 {
-	unsigned char		buff1[MAX_ZWR_KEY_SZ], buff2[MAX_ZWR_KEY_SZ], *end1, *end2;
+	boolean_t		mergereg_array[256], *is_reg_in_array, intersect;
+	char			*base;
 	enum db_acc_method	acc_meth1, acc_meth2;
-	gd_region		*reg1, *reg2;
+	gd_addr			*addr;
+	gd_binding		*map, *start_map1, *end_map1, *start_map2, *end_map2;
+	gd_region		*reg, *reg1, *reg2;
+	gv_key			*gvkey1, *gvkey2;
 	gv_namehead		*gvt1, *gvt2;
+	gvname_info		*gblp1, *gblp2;
+	gvnh_reg_t		*gvnh_reg1, *gvnh_reg2;
+	int			max_fid_index;
+	sgmnt_addrs		*csa;
+	unsigned char		buff1[MAX_ZWR_KEY_SZ], buff2[MAX_ZWR_KEY_SZ], *end1, *end2;
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	if (MARG1_IS_GBL(merge_args) && MARG2_IS_GBL(merge_args))
 	{
-		reg1 = mglvnp->gblp[IND1]->s_gv_cur_region;
-		reg2 = mglvnp->gblp[IND2]->s_gv_cur_region;
-		gvt1 = mglvnp->gblp[IND1]->s_gv_target;
-		gvt2 = mglvnp->gblp[IND2]->s_gv_target;
-		acc_meth1 = reg1->dyn.addr->acc_meth;
-		acc_meth2 = reg2->dyn.addr->acc_meth;
-		assert(!(dba_bg == acc_meth1 || dba_mm == acc_meth1) || (NULL != gvt1->gd_csa));
-		assert(!(dba_bg == acc_meth2 || dba_mm == acc_meth2) || (NULL != gvt2->gd_csa));
-		/* if (!(both are bg/mm regions && dbs are same && same global) &&
-		 *     !(both are cm regions && on the same remote node && same region)
-		 *     !(both are usr regions && in the same volume set))
-		 *   NO DESCENDANTS
-		 * endif
+		gblp1 = mglvnp->gblp[IND1];
+		gblp2 = mglvnp->gblp[IND2];
+		/* Check if one global name is a descent of the other. If not, we know for sure there is no issue.
+		 * If yes, further check if the database files involved in the source and target global are identical/intersect.
+		 * If either of the globals span multiple regions, we need to check if the database files that the subscripted
+		 * global reference (involved in the merge command) span across intersect in the source and destination globals.
+		 * If intersection found issue MERGEDESC error. If not (e.g. two globals have same name but belong to different
+		 * gld/db) no error needed.
 		 */
-		if (!(((dba_bg == acc_meth1 || dba_mm == acc_meth2) && (dba_bg == acc_meth1 || dba_mm == acc_meth2))
-			&& (gvt1->gd_csa == gvt2->gd_csa) && (gvt1->root == gvt2->root))
-		   && !((dba_cm == acc_meth1) && (dba_cm == acc_meth2)
-			&& (reg1->dyn.addr->cm_blk == reg2->dyn.addr->cm_blk) && (reg1->cmx_regnum == reg2->cmx_regnum))
-		   VMS_ONLY (&&
-		   	!((dba_usr == acc_meth1) && (dba_usr == acc_meth2)
-			&& ((ddp_info *)(&FILE_INFO(reg1)->file_id))->volset == ((ddp_info *)(&FILE_INFO(reg2)->file_id))->volset)))
-		{
-			UNIX_ONLY(assert(dba_usr != acc_meth1 && dba_usr != acc_meth2);)
+		gvkey1 = gblp1->s_gv_currkey;
+		gvkey2 = gblp2->s_gv_currkey;
+		if (0 != memcmp(gvkey1->base, gvkey2->base, MIN(gvkey1->end, gvkey2->end)))
 			return 1;
-		}
-		if (0 == memcmp(mglvnp->gblp[IND1]->s_gv_currkey->base, mglvnp->gblp[IND2]->s_gv_currkey->base,
-			        MIN(mglvnp->gblp[IND1]->s_gv_currkey->end, mglvnp->gblp[IND2]->s_gv_currkey->end)))
-		{
-			if (mglvnp->gblp[IND1]->s_gv_currkey->end == mglvnp->gblp[IND2]->s_gv_currkey->end)
-				return 0; /* NOOP - merge self */
-			if (0 == (end1 = format_targ_key(buff1, MAX_ZWR_KEY_SZ, mglvnp->gblp[IND1]->s_gv_currkey, TRUE)))
-				end1 = &buff1[MAX_ZWR_KEY_SZ - 1];
-			if (0 == (end2 = format_targ_key(buff2, MAX_ZWR_KEY_SZ, mglvnp->gblp[IND2]->s_gv_currkey, TRUE)))
-				end2 = &buff2[MAX_ZWR_KEY_SZ - 1];
-			if (mglvnp->gblp[IND1]->s_gv_currkey->end > mglvnp->gblp[IND2]->s_gv_currkey->end)
-				rts_error(VARLSTCNT(6) ERR_MERGEDESC, 4, end1 - buff1, buff1, end2 - buff2, buff2);
-			else
-				rts_error(VARLSTCNT(6) ERR_MERGEDESC, 4, end2 - buff2, buff2, end1 - buff1, buff1);
-		}
+		if (gblp1->s_gd_targ_addr != gblp2->s_gd_targ_addr)
+		{	/* both globals involved in the merge correspond to different gld.
+			 * check if corresponding db files intersect.
+			 */
+			reg1 = gblp1->s_gv_cur_region;
+			reg2 = gblp2->s_gv_cur_region;
+			gvt1 = gblp1->s_gv_target;
+			gvt2 = gblp2->s_gv_target;
+			acc_meth1 = REG_ACC_METH(reg1);
+			acc_meth2 = REG_ACC_METH(reg2);
+			assert(!(dba_bg == acc_meth1 || dba_mm == acc_meth1) || (NULL != gvt1->gd_csa));
+			assert(!(dba_bg == acc_meth2 || dba_mm == acc_meth2) || (NULL != gvt2->gd_csa));
+			assert((dba_bg == acc_meth1) || (dba_mm == acc_meth1) || (NULL == gvt1->gd_csa));
+			assert((dba_bg == acc_meth2) || (dba_mm == acc_meth2) || (NULL == gvt2->gd_csa));
+			gvnh_reg1 = gblp1->s_gd_targ_gvnh_reg;
+			gvnh_reg2 = gblp2->s_gd_targ_gvnh_reg;
+			/* A non-NULL value of gvnh_reg indicates a spanning global as confirmed by the asserts below */
+			assert((NULL == gvnh_reg1) || (NULL != gvnh_reg1->gvspan));
+			assert((NULL == gvnh_reg2) || (NULL != gvnh_reg2->gvspan));
+			if ((NULL != gvnh_reg1) || (NULL != gvnh_reg2))
+			{	/* At least one of src OR dst global spans multiple regions, check for region/db intersections
+				 * between the two.
+				 */
+				assert((NULL == gvnh_reg1) || (NULL != gvt1->gd_csa));
+				assert((NULL == gvnh_reg2) || (NULL != gvt2->gd_csa));
+				if ((NULL == gvt1->gd_csa) || (NULL == gvt2->gd_csa))
+				{	/* One global spans multiple regions, while another is remote. They cannot intersect
+					 * as a global can never span to remote regions (i.e. no dba_usr or dba_cm).
+					 */
+					return 1;
+				}
+				/* The merge command is MERGE ^gvn1(subs1)=^gvn2(subs2) where "subs1" and "subs2" are
+				 * a comma-separated list of one or more subscripts. Find out regions spanned by
+				 * ^gvn1(subs1) as well as ^gvn2(subs2) and check for intersections in these two lists.
+				 */
+				/* Find list of regions corresponding to ^gvn1(subs1) */
+				base = (char *)&gvkey1->base[0];
+				addr = gblp1->s_gd_targ_addr;
+				start_map1 = gv_srch_map(addr, base, gvkey1->end - 1); /* -1 to remove trailing 0 */
+				GVKEY_INCREMENT_ORDER(gvkey1);
+				end_map1 = gv_srch_map(addr, base, gvkey1->end - 1); /* -1 to remove trailing 0 */
+				BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gvkey1->base, gvkey1->end - 1, end_map1);
+				GVKEY_UNDO_INCREMENT_ORDER(gvkey1);
+				/* Find list of regions corresponding to ^gvn2(subs2) */
+				assert(KEY_DELIMITER == gvkey2->base[gvkey2->end - 1]);
+				assert(KEY_DELIMITER == gvkey2->base[gvkey2->end]);
+				base = (char *)&gvkey2->base[0];
+				addr = gblp2->s_gd_targ_addr;
+				start_map2 = gv_srch_map(addr, base, gvkey2->end - 1); /* -1 to remove trailing 0 */
+				GVKEY_INCREMENT_ORDER(gvkey2);
+				end_map2 = gv_srch_map(addr, base, gvkey2->end - 1); /* -1 to remove trailing 0 */
+				BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gvkey2->base, gvkey2->end - 1, end_map2);
+				GVKEY_UNDO_INCREMENT_ORDER(gvkey2);
+				/* At this point, we are sure all regions involved in ^gvn1 and ^gvn2 are dba_mm or dba_bg.
+				 * This means all the regions would have a csa and a csa->fid_index assigned to them.
+				 * We can use this to determine intersections. Note though that some regions could not yet
+				 * be open so we need to open the regions first in that case and then use max_fid_index.
+				 */
+				for (map = start_map1; map <= end_map1; map++)
+				{
+					reg = map->reg.addr;
+					if (!reg->open)
+						gv_init_reg(reg);
+				}
+				for (map = start_map2; map <= end_map2; map++)
+				{
+					reg = map->reg.addr;
+					if (!reg->open)
+						gv_init_reg(reg);
+				}
+				/* At this point, all regions involved in the merge ^gvn1(subs1)=^gvn2(subs2) are open
+				 * so we can use max_fid_index without issues.
+				 */
+				max_fid_index = TREF(max_fid_index);
+				if (max_fid_index < ARRAYSIZE(mergereg_array))
+					is_reg_in_array = &mergereg_array[0];
+				else
+					is_reg_in_array = (boolean_t *)malloc(SIZEOF(boolean_t) * (max_fid_index + 1));
+				memset(is_reg_in_array, 0, SIZEOF(boolean_t) * (max_fid_index + 1));
+				intersect = FALSE;
+				for (map = start_map1; map <= end_map1; map++)
+				{
+					reg = map->reg.addr;
+					csa = (sgmnt_addrs *)&FILE_INFO(reg)->s_addrs;
+					assert(NULL != csa);
+					assert(max_fid_index >= csa->fid_index);
+					is_reg_in_array[csa->fid_index] = TRUE;
+				}
+				for (map = start_map2; map <= end_map2; map++)
+				{
+					reg = map->reg.addr;
+					csa = (sgmnt_addrs *)&FILE_INFO(reg)->s_addrs;
+					assert(NULL != csa);
+					assert(max_fid_index >= csa->fid_index);
+					if (is_reg_in_array[csa->fid_index])
+					{
+						intersect = TRUE;
+						break;
+					}
+				}
+				if (is_reg_in_array != &mergereg_array[0])
+					free(is_reg_in_array);
+				if (!intersect)
+					return 1;
+			} else
+			{	/* Both globals map only to one region (no spanning).
+				 * if (!(both are bg/mm regions && dbs are same) &&
+				 *     !(both are cm regions && on the same remote node && same region)
+				 *     !(both are usr regions && in the same volume set))
+				 *   NO DESCENDANTS
+				 * endif
+				 */
+				assert((NULL == gvt1->gd_csa) || (gvt1->gd_csa != gvt2->gd_csa) || (gvt1->root == gvt2->root));
+				if (!((NULL != gvt1->gd_csa) && (gvt1->gd_csa == gvt2->gd_csa))
+					&& !((dba_cm == acc_meth1) && (dba_cm == acc_meth2)
+						&& (reg1->dyn.addr->cm_blk == reg2->dyn.addr->cm_blk)
+						&& (reg1->cmx_regnum == reg2->cmx_regnum))
+					VMS_ONLY (&&
+						!((dba_usr == acc_meth1) && (dba_usr == acc_meth2)
+							&& ((ddp_info *)(&FILE_INFO(reg1)->file_id))->volset
+								== ((ddp_info *)(&FILE_INFO(reg2)->file_id))->volset)))
+				{
+					UNIX_ONLY(assert((dba_usr != acc_meth1) && (dba_usr != acc_meth2));)
+					return 1;
+				}
+			}
+		} else if (gvkey1->end == gvkey2->end)
+			return 0; /* NOOP - merge self */
+		/* Else glds are identical and global names are identical and one is a descendant of other.
+		 * So need to issue MERGEDESC error for sure (does not matter whether global spans regions
+		 * or not, does not matter if region is remote or not etc.). No other checks necessary.
+		 */
+		if (0 == (end1 = format_targ_key(buff1, MAX_ZWR_KEY_SZ, gvkey1, TRUE)))
+			end1 = &buff1[MAX_ZWR_KEY_SZ - 1];
+		if (0 == (end2 = format_targ_key(buff2, MAX_ZWR_KEY_SZ, gvkey2, TRUE)))
+			end2 = &buff2[MAX_ZWR_KEY_SZ - 1];
+		if (gvkey1->end > gvkey2->end)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MERGEDESC, 4, end1 - buff1, buff1, end2 - buff2, buff2);
+		else
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MERGEDESC, 4, end2 - buff2, buff2, end1 - buff1, buff1);
 	} else if (MARG1_IS_LCL(merge_args) && MARG2_IS_LCL(merge_args))
 	{
 		if (mglvnp->lclp[IND1] == mglvnp->lclp[IND2])
@@ -95,12 +224,12 @@ boolean_t merge_desc_check(void)
 		{
 			end1 = format_key_lv_val(mglvnp->lclp[IND1], buff1, SIZEOF(buff1));
 			end2 = format_key_lv_val(mglvnp->lclp[IND2], buff2, SIZEOF(buff2));
-			rts_error(VARLSTCNT(6) ERR_MERGEDESC, 4, end1 - buff1, buff1, end2 - buff2, buff2);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MERGEDESC, 4, end1 - buff1, buff1, end2 - buff2, buff2);
 		} else if (lcl_arg1_is_desc_of_arg2(mglvnp->lclp[IND2], mglvnp->lclp[IND1]))
 		{
 			end1 = format_key_lv_val(mglvnp->lclp[IND1], buff1, SIZEOF(buff1));
 			end2 = format_key_lv_val(mglvnp->lclp[IND2], buff2, SIZEOF(buff2));
-			rts_error(VARLSTCNT(6) ERR_MERGEDESC, 4, end2 - buff2, buff2, end1 - buff1, buff1);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MERGEDESC, 4, end2 - buff2, buff2, end1 - buff1, buff1);
 		}
 	}
 	return 1;
diff --git a/sr_port/merrors.msg b/sr_port/merrors.msg
index eb1e35f..9345641 100644
--- a/sr_port/merrors.msg
+++ b/sr_port/merrors.msg
@@ -204,7 +204,7 @@ DBOPNERR	<Error opening database file !AD>/error/fao=2!/ansi=0
 DBRDERR		<Cannot read database file !AD after opening>/error/fao=2!/ansi=0
 CCEDUMPNOW	<>/fatal/fao=0!/ansi=0
 DEVPARINAP	<Device parameter inappropriate to this command>/error/fao=0!/ansi=0
-RECORDSTAT	<!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL  max rec len: !UL>/info/fao=6!/ansi=0
+RECORDSTAT	<!AD:!_  Key cnt: !UL  max subsc len: !UL  max rec len: !UL  max node len: !UL>/info/fao=6!/ansi=0
 NOTGBL		<!_!AD!/!_!_!_"^" Expected>/error/fao=2!/ansi=0
 DEVPARPROT	<The protection specification is invalid>/error/fao=0!/ansi=0
 PREMATEOF	<Premature end of file detected>/error/fao=0!/ansi=0
@@ -674,12 +674,12 @@ CCPSIGDMP	<CCP non fatal dump, continuing operation. Report to your GT.M Support
 NOPRINCIO	<Unable to write to principal device>/fatal/fao=0!/ansi=0
 INVPORTSPEC	<Invalid port specification>/error/fao=0!/ansi=0
 INVADDRSPEC	<Invalid IP address specification>/error/fao=0!/ansi=0
-SOCKPARMREQ	<Socket device parameter is required for TCP open>/error/fao=0!/ansi=78
-IPADDRREQ	<Active connection requires IP address>/error/fao=0!/ansi=0
+UNUSEDMSG677	<SOCKPARMREQ last used in V6.0-002>/error/fao=0!/ansi=78
+UNUSEDMSG678	<IPADDRREQ last used in V6.0-002>/error/fao=0!/ansi=0
 SOCKWAIT	<Error waiting for socket connection>/error/fao=0!/ansi=80
 SOCKACPT	<Error accepting socket connection>/error/fao=0!/ansi=81
-SOCKINIT	<Error initializing TCP socket: (errno == !UL) !AD>/error/fao=3!/ansi=80
-OPENCONN	<Error opening TCP connection>/error/fao=0!/ansi=81
+SOCKINIT	<Error initializing socket: (errno == !UL) !AD>/error/fao=3!/ansi=80
+OPENCONN	<Error opening socket connection>/error/fao=0!/ansi=81
 DEVNOTIMP	<!AD device not implemented on in this environment>/error/fao=2!/ansi=0
 JNLEXTR		<Error writing journal extract file: !AD>/error/fao=2!/ansi=0
 DBREMOTE	<Database region !AD is remote; perform maintenance on the server node>/error/fao=2!/ansi=0
@@ -705,7 +705,7 @@ MUSTANDALONE	<Could not get exclusive access to !AD> /info /fao=2!/ansi=0
 MUNOACTION	<MUPIP unable to perform requested action> /error /fao=0!/ansi=0
 RMBIGSHARE	<File with BIGRECORD specified may only be shared if READONLY>/error/fao=0!/ansi=0
 TPRESTART	<Database !AD; code: !AD; blk: 0x!XL in glbl: ^!AD; pvtmods: !UL, blkmods: !UL, blklvl: !UL, type: !UL, readset: !UL, writeset: !UL, local_tn: 0x!16 at XQ> /info /fao=14!/ansi=0
-SOCKWRITE	<Write to a TCP/IP socket failed> /error /fao=0!/ansi=0
+SOCKWRITE	<Write to a socket failed> /error /fao=0!/ansi=0
 DBCNTRLERR	<Database file !AD: control error suspected but not found> /info /fao=2!/ansi=0
 NOTERMENV	<Environment variable TERM not set.  Assuming "unknown."> /info /fao=0!/ansi=0
 NOTERMENTRY	<TERM = "!AD" has no "terminfo" entry.  Possible terminal handling problems.> /info /fao=2!/ansi=0
@@ -778,7 +778,7 @@ BCKUPBUFLUSH	<Unable to flush buffer for online backup>/error/fao=0!/ansi=0
 NOFORKCORE	<Unable to fork off process to create core.  Core creation postponed.>/warning/fao=0!/ansi=0
 JNLREAD		<Error reading from journal file !AD at offset [0x!XL]>/error/fao=3!/ansi=0
 JNLMINALIGN	<Journal Record Alignment !UL is less than the minimum value of !UL>/warning/fao=2!/ansi=0
-UNUSEDMSG781	<JNLDSKALIGN : Last used in V4.3-000>/error/fao=0!/ansi=0
+JOBSTARTCMDFAIL	<JOB command STARTUP script invocation failed>/error/fao=0!/ansi=0
 JNLPOOLSETUP	<Journal Pool setup error>/error/fao=0!/ansi=0
 JNLSTATEOFF	<ROLLBACK or RECOVER BACKWARD cannot proceed as database file !AD does not have journaling ENABLED and ON>/error/fao=2!/ansi=0
 RECVPOOLSETUP	<Receive Pool setup error>/error/fao=0!/ansi=0
@@ -841,7 +841,7 @@ RECSIZENOTEVEN	<RECORDSIZE [!UL] needs to be a multiple of 2 if ICHSET or OCHSET
 BUFFLUFAILED	<Error flushing buffers from !AD for database file !AD>/error/fao=4!/ansi=0
 MUQUALINCOMP	<Incompatible qualifiers - FILE and REGION>/error/fao=0!/ansi=0
 DISTPATHMAX	<$gtm_dist path is greater than maximum (!UL)>/error/fao=1!/ansi=0
-UNUSEDMSG844	<MAXTRACEHEIGHT last used in V5.4-002>/error/fao=0!/ansi=0
+FILEOPENFAIL	<Failed to open file !AD>/error/fao=2!/ansi=0
 IMAGENAME	<The executing module name should be !AD instead of !AD>/error/fao=4!/ansi=0
 GTMSECSHRPERM	<The gtmsecshr module in $gtm_dist does not have the correct permission and uid>/error/fao=0!/ansi=0
 GTMDISTUNDEF	<Environment variable $gtm_dist is not defined>/error/fao=0!/ansi=0
@@ -969,7 +969,7 @@ MUTEXRSRCCLNUP	<Mutex subsystem leftover resource !AD removed>/info/fao=2!/ansi=
 SEMWT2LONG	<Process !UL waited !UL second(s) for the !AD lock for region !AD, lock held by pid !UL>/error/fao=7!/ansi=0
 REPLINSTOPEN	<Error opening replication instance file !AD>/error/fao=2!/ansi=0
 REPLINSTCLOSE	<Error closing replication instance file !AD>/error/fao=2!/ansi=0
-UNUSEDMSG972	<JNLNOTFOUND : Last used in V4.4-000>/error/fao=0!/ansi=0
+JOBSETUP	<Error receiving !AD from parent process>/error/fao=2!/ansi=0
 DBCRERR8	<Database file !AD, cr location 0x!XJ blk = 0x!XL error: !AD was 0x!16 at XQ, expecting 0x!16 at XQ -- called from module !AD at line !UL> /info /fao=11!/ansi=0
 NUMPROCESSORS	<Could not determine number of processors>/warning/fao=0!/ansi=0
 DBADDRANGE8	<Database file !AD, element location 0x!XJ: blk = 0x!XL: control 0x!16 at XQ was outside !AD range 0x!16 at XQ to 0x!16 at XQ> /info /fao=9!/ansi=0
@@ -1104,7 +1104,7 @@ INVZDIRFORM	<Invalid value (!UL) specified for ZDIR_FORM>/error/fao=1!/ansi=0
 ZDIROUTOFSYNC	<$ZDIRECTORY !AD is not the same as its cached value !AD>/warning/fao=4!/ansi=0
 GBLNOEXIST	<Global !AD no longer exists>/info/fao=2!/ansi=0
 MAXBTLEVEL	<Global !AD reached maximum level>/error/fao=2!/ansi=0
-UNUSEDMSG1107	<JNLSTRESTFL : found no evidence it ever was used in a production release>/error/fao=0!/ansi=0
+INVMNEMCSPC	<Unsupported mnemonicspace !AD>/error/fao=2!/ansi=35
 JNLALIGNSZCHG	<Journal ALIGNSIZE is rounded up to !UL blocks (closest next higher power of two)>/info/fao=1!/ansi=0
 UNUSEDMSG1109	<MAXTRACELEVEL : last used in V5.4-002B>/error/fao=0!/ansi=0
 GVFAILCORE	<A core file is being created for later analysis if necessary>/error/fao=0!/ansi=0
@@ -1316,7 +1316,7 @@ CRYPTJNLWRONGHASH	<Encryption key hash mismatch between journal file !AD and cor
 CRYPTKEYFETCHFAILED	<Could not retrieve encryption key corresponding to file !AD. !AD>/error/fao=4!/ansi=0
 CRYPTKEYFETCHFAILEDNF	<Could not retrieve encryption key during !AD operation key. !AD>/error/fao=4!/ansi=0
 CRYPTHASHGENFAILED	<Could not generate cryptographic hash for symmetric key corresponding to file !AD. !AD>/error/fao=4!/ansi=0
-CRYPTNOPSWDINTP	<Cannot prompt for password inside a TP transaction.>/error/fao=0!/ansi=0
+UNUSEDMSG1319	<CRYPTNOPSWDINTP : Last used in V6.0-003>/error/fao=0!/ansi=0
 BADTAG		<Unable to use file !AD (CCSID !UL) with CCSID !UL>/error/fao=4!/ansi=0
 ICUVERLT36	<!AD !UL.!UL. ICU version greater than or equal to 3.6 should be used>/error/fao=4!/ansi=0
 ICUSYMNOTFOUND	<Symbol !AD not found in the ICU libraries. ICU needs to be built with symbol-renaming disabled or gtm_icu_version environment variable needs to be properly specified>/error/fao=2!/ansi=0
@@ -1415,7 +1415,7 @@ MUUSERECOV	<Abnormal shutdown of journaled database !AD detected>/error/fao=2!/a
 SECNOTSUPPLEMENTARY	<!AD is a Supplementary Instance and so cannot act as a source to non-Supplementary Instance !AD >/error/fao=4!/ansi=0
 SUPRCVRNEEDSSUPSRC	<Instance !AD is not configured to perform local updates so it cannot act as a receiver for non-Supplementary Instance !AD>/error/fao=4!/ansi=0
 UNUSEDMSG1417	<SYNCTOSAMETYPE: Never used before so slot free for reuse>/info/fao=0!/ansi=0
-UNUSEDMSG1418	<TARGINSRUNNING: Never used before so slot free for reuse>/info/fao=0!/ansi=0
+SETITIMERFAILED	<A setitimer() call returned an error status of !UL>/fatal/fao=1!/ansi=0
 UPDSYNC2MTINS	<Can only UPDATERESYNC with an empty instance file>/error/fao=0!/ansi=0
 UPDSYNCINSTFILE	<Error with instance file name specified in UPDATERESYNC qualifier>/error/fao=0!/ansi=0
 REUSEINSTNAME	<Error with instance name specified in REUSE qualifier>/error/fao=0!/ansi=0
@@ -1523,10 +1523,29 @@ MALLOCMAXVMS	<Exceeded maximum allocation defined by GTM_MAX_STORALLOC>/error/fa
 HOSTCONFLICT	<Host !AD could not open database file !AD because it is marked as already open on node !AD>/error/fao=6!/ansi=0
 GETADDRINFO	<Error in getting address info>/error/fao=0!/ansi=0
 GETNAMEINFO	<Error in getting name info>/error/fao=0!/ansi=0
-SOCKBIND	<Error in binding TCP socket>/error/fao=0!/ansi=0
+SOCKBIND	<Error in binding socket>/error/fao=0!/ansi=0
 INSTFRZDEFER	<Instance Freeze initiated by !AD error on region !AD deferred due to critical resource conflict>/info/fao=4!/ansi=0
 REGOPENRETRY	<Attempt to open region !AD (!AD) using startup shortcut failed due to conflicting database shutdown. Retrying...>/info/fao=4!/ansi=0
 REGOPENFAIL	<Failed to open region !AD (!AD) due to conflicting database shutdown activity>/error/fao=4!/ansi=0
+REPLINSTNOSHM	<Database !AD has no active connection to a replication journal pool; please verify that the database is listed in your instance file>/error/fao=2!/ansi=0
+DEVPARMTOOSMALL	<Deviceparameter must be greater than zero (0)>/error/fao=0!/ansi=0
+REMOTEDBNOSPGBL	<Database region !AD contains portion of a spanning global and so cannot point to a remote file>/error/fao=2!/ansi=0
+NCTCOLLSPGBL	<Database region !AD contains portion of spanning global ^!AD and so cannot support non-zero numeric collation type>/error/fao=4!/ansi=0
+ACTCOLLMISMTCH	<Global ^!AD inherits alternative collation sequence #!UL from global directory but database file !AD contains different collation sequence #!UL for this global>/error/fao=6!/ansi=0
+GBLNOMAPTOREG	<Global !AD does not map to region !AD in current global directory>/error/fao=4!/ansi=0
+ISSPANGBL	<Operation cannot be performed on global ^!AD as it spans multiple regions in current global directory>/error/fao=2!/ansi=0
+TPNOSUPPORT	<Operation cannot be performed while inside of a TP transaction>/error/fao=0!/ansi=0
+GVSUBSERR	<Invalid subscripted global name specification in $VIEW() function>/error/fao=0!/ansi=0
+TRIGNOSPANGBL	<Triggers cannot be installed/deleted for global name !AD as it spans multiple regions in current global directory>/error/fao=2!/ansi=0
+FILTERTIMEDOUT	<Replication server timed out attempting to read seqno !16 at XQ from external filter>/error/fao=1!/ansi=0
+TLSDLLNOOPEN	<Failed to load GT.M TLS/SSL library for secure communication>/error/fao=0!/ansi=0
+TLSINIT		<Failed to initialize GT.M TLS/SSL library for secure communication>/error/fao=0!/ansi=0
+TLSCONVSOCK	<Failed to convert Unix TCP/IP socket to TLS/SSL aware socket>/error/fao=0!/ansi=0
+TLSHANDSHAKE	<Connection to remote side using TLS/SSL protocol failed>/error/fao=0!/ansi=0
+TLSCONNINFO	<Failed to obtain information on the TLS/SSL connection>/warning/fao=0!/ansi=0
+TLSIOERROR	<Error during TLS/SSL !AD operation>/error/fao=2!/ansi=0
+TLSRENEGOTIATE	<Failed to renegotiate TLS/SSL connection>/error/fao=0!/ansi=0
+REPLNOTLS	<!AD requested TLS/SSL communication but the !AD was either not started with TLSID qualifier or does not support TLS/SSL protocol>/error/fao=4!/ansi=0
 !
 ! If there are UNUSEDMSG* lines unused for more than one year and at least two non-patch releases, use them before adding new lines.
 !
diff --git a/sr_port/mlk_region_lookup.c b/sr_port/mlk_region_lookup.c
index 2eaafc5..ce52555 100644
--- a/sr_port/mlk_region_lookup.c
+++ b/sr_port/mlk_region_lookup.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,6 +21,11 @@
 #include "mlk_region_lookup.h"
 #include "targ_alloc.h"
 #include "hashtab_mname.h"
+#include "gvnh_spanreg.h"
+#include "gtmimagename.h"
+#include "gv_trigger_common.h"	/* for *HASHT* macros used inside GVNH_REG_INIT macro */
+#include "filestruct.h"		/* needed for "jnl.h" used by next line */
+#include "jnl.h"		/* needed for "jgbl" used inside GVNH_REG_INIT macro */
 
 #define DIR_ROOT 1
 
@@ -32,9 +37,7 @@ gd_region *mlk_region_lookup(mval *ptr, gd_addr *addr)
 	gv_namehead		*targ;
 	gd_region		*reg;
 	register char		*p;
-	int			res, plen;
-	boolean_t		added;
-	enum db_acc_method	acc_meth;
+	int			plen;
 	gvnh_reg_t		*gvnh_reg;
 
 	p = ptr->str.addr;
@@ -51,9 +54,10 @@ gd_region *mlk_region_lookup(mval *ptr, gd_addr *addr)
 		gvent.var_name.addr = p;
 		gvent.var_name.len = MIN(plen, MAX_MIDENT_LEN);
 		COMPUTE_HASH_MNAME(&gvent);
-		if ((NULL != (tabent = lookup_hashtab_mname(addr->tab_ptr, &gvent)))
-			&& (NULL != (gvnh_reg = (gvnh_reg_t *)tabent->value)))
+		if (NULL != (tabent = lookup_hashtab_mname(addr->tab_ptr, &gvent)))
 		{
+			gvnh_reg = (gvnh_reg_t *)tabent->value;
+			assert(NULL != gvnh_reg);
 			targ = gvnh_reg->gvt;
 			reg = gvnh_reg->gd_reg;
 			if (!reg->open)
@@ -63,43 +67,12 @@ gd_region *mlk_region_lookup(mval *ptr, gd_addr *addr)
 			}
 		} else
 		{
-			map = addr->maps + 1;	/* get past local locks */
-			for (; (res = memcmp(gvent.var_name.addr, &(map->name[0]), gvent.var_name.len)) >= 0; map++)
-			{
-				assert (map < addr->maps + addr->n_maps);
-				if (0 == res && 0 != map->name[gvent.var_name.len])
-					break;
-			}
+			map = gv_srch_map(addr, gvent.var_name.addr, gvent.var_name.len);
 			reg = map->reg.addr;
 			if (!reg->open)
-				gv_init_reg (reg);
-			acc_meth = reg->dyn.addr->acc_meth;
-			if ((dba_cm == acc_meth) || (dba_usr == acc_meth))
-			{
-				targ = malloc(SIZEOF(gv_namehead) + gvent.var_name.len);
-				memset(targ, 0, SIZEOF(gv_namehead) + gvent.var_name.len);
-				targ->gvname.var_name.addr = (char *)targ + SIZEOF(gv_namehead);
-				targ->nct = 0;
-				targ->collseq = NULL;
-				targ->regcnt = 1;
-				memcpy(targ->gvname.var_name.addr, gvent.var_name.addr, gvent.var_name.len);
-				targ->gvname.var_name.len = gvent.var_name.len;
-				targ->gvname.hash_code = gvent.hash_code;
-			} else
-				targ = (gv_namehead *)targ_alloc(reg->max_key_size, &gvent, reg);
-			gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
-			gvnh_reg->gvt = targ;
-			gvnh_reg->gd_reg = reg;
-			if (NULL != tabent)
-			{	/* Since the global name was found but gv_target was null and now we created a new targ,
-				 * the hash table key must point to the newly created targ->gvname. */
-				tabent->key = targ->gvname;
-				tabent->value = (char *)gvnh_reg;
-			} else
-			{
-				added = add_hashtab_mname((hash_table_mname *)addr->tab_ptr, &targ->gvname, gvnh_reg, &tabent);
-				assert(added);
-			}
+				gv_init_reg(reg);
+			targ = (gv_namehead *)targ_alloc(reg->max_key_size, &gvent, reg);
+			GVNH_REG_INIT(addr, addr->tab_ptr, map, targ, reg, gvnh_reg, tabent);
 		}
 	}
 	return reg;
diff --git a/sr_port/mtables.c b/sr_port/mtables.c
index 97f5c5e..900769f 100644
--- a/sr_port/mtables.c
+++ b/sr_port/mtables.c
@@ -161,12 +161,14 @@ LITDEF unsigned char mvs_size[] =
 
 /* All mv_stent types that need to be preserved are indicated by the mvs_save[] array.
  * MVST_STCK_SP (which is the same as the MVST_STCK type everywhere else) is handled specially here.
- * The MVST_STCK_SP entry is created by mdb_condition_handler to stack the "stackwarn" global variable.
+ * For example, when the MVST_STCK_SP entry is created by mdb_condition_handler to stack the "stackwarn" global variable.
  * This one needs to be preserved since our encountering this type in flush_jmp.c indicates that we are currently
  * in the error-handler of a STACKCRIT error which in turn has "GOTO ..." in the $ZTRAP/$ETRAP that is
  * causing us to mutate the current frame we are executing in with the contents pointed to by the GOTO.
  * In that case, we do not want to restore "stackwarn" to its previous value since we are still handling
- * the STACKCRIT error. So we set MVST_STCK_SP type as needing to be preserved.
+ * the STACKCRIT error. So we set MVST_STCK_SP type as needing to be preserved. So bottom line is MVST_STCK and
+ * MVST_STCK_SP are identical except the former is not kept when a frame is rewritten by ZGOTO (or other) and the
+ * latter *is* kept.
  */
 LITDEF boolean_t mvs_save[] =
 {
@@ -191,6 +193,9 @@ LITDEF boolean_t mvs_save[] =
 	FALSE	/* MVST_MRGZWRSV */
 };
 
+/* The address of this literal is assigned to mval pointers for arguments which are deliberately skipped in label invocations. */
+LITDEF mval skiparg		= DEFINE_MVAL_COMMON(0, 0, 0, 0, 0, 0, 0, 0);
+
 static readonly unsigned char localpool[7] = {'1', '1', '1', '0', '1', '0', '0'};
 LITDEF mval literal_null	= DEFINE_MVAL_LITERAL(MV_STR | MV_NM | MV_INT | MV_NUM_APPROX | MV_UTF_LEN, 0, 0, 0, 0, 0, 0);
 LITDEF mval literal_zero	= DEFINE_MVAL_LITERAL(MV_STR | MV_NM | MV_INT, 0, 0, 1, (char *)&localpool[3], 0,   0);
diff --git a/sr_port/mu_extr_gblout.c b/sr_port/mu_extr_gblout.c
index a765db9..a31cd35 100644
--- a/sr_port/mu_extr_gblout.c
+++ b/sr_port/mu_extr_gblout.c
@@ -19,8 +19,6 @@
 #include <rms.h>
 #include <ssdef.h>
 #include "iormdef.h"
-#else
-#error UNSUPPORTED PLATFORM
 #endif
 #include "gtm_string.h"
 #include "io.h"
@@ -45,12 +43,15 @@
 #endif
 #include "gvcst_protos.h"
 
-#define INTEG_ERROR_RETURN										\
-{													\
-	gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_EXTRFAIL, 2, gn->str.len, gn->str.addr);	\
-	return FALSE;											\
+#define INTEG_ERROR_RETURN											\
+{														\
+	gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_EXTRFAIL, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);	\
+	return FALSE;												\
 }
 
+#define WRITE_4MORE_BYTES_TRUE		TRUE
+#define WRITE_4MORE_BYTES_FALSE		FALSE
+
 GBLREF	bool			mu_ctrlc_occurred;
 GBLREF	bool			mu_ctrly_occurred;
 GBLREF	gd_addr			*gd_header;
@@ -59,48 +60,41 @@ GBLREF	gv_key			*gv_currkey;
 GBLREF	gv_namehead		*gv_target;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
+#ifdef GTM_CRYPT
+GBLREF	mstr			pvt_crypt_buf;
+#endif
 
 error_def(ERR_EXTRFAIL);
 error_def(ERR_RECORDSTAT);
 
-#if defined(UNIX) && defined(GTM_CRYPT)
-boolean_t mu_extr_gblout(mval *gn, mu_extr_stats *st, int format, muext_hash_hdr_ptr_t hash_array,
-							boolean_t is_any_file_encrypted)
+#if defined(GTM_CRYPT)
+boolean_t mu_extr_gblout(glist *gl_ptr, mu_extr_stats *st, int format, boolean_t is_any_file_encrypted)
 #elif defined(UNIX)
-boolean_t mu_extr_gblout(mval *gn, mu_extr_stats *st, int format)
+boolean_t mu_extr_gblout(glist *gl_ptr, mu_extr_stats *st, int format)
 #elif defined(VMS)
-boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int format)
-#else
-#error UNSUPPORTED PLATFORM
+boolean_t mu_extr_gblout(glist *gl_ptr, struct RAB *outrab, mu_extr_stats *st, int format)
 #endif
 {
-	blk_hdr_ptr_t			bp;
-	boolean_t			beg_key;
-	int				data_len, des_len, fmtd_key_len, gname_size;
-	int				tmp_cmpc;
-	rec_hdr_ptr_t			rp, save_rp;
-	sm_uc_ptr_t			blktop, cp1, rectop;
-	unsigned char			*cp2, current, *keytop, last;
-	unsigned short			out_size, rec_size;
 	static gv_key			*beg_gv_currkey; 	/* this is used to check key out of order condition */
-	static int			max_zwr_len = 0;
+	static int			max_zwr_len = 0, index;
 	static unsigned			char	*private_blk = NULL, *zwr_buffer = NULL, *key_buffer = NULL;
 	static uint4			private_blksz = 0;
+	unsigned char			*cp2, current, *keytop, last;
+	unsigned short			out_size, rec_size;
+	int				data_len, des_len, fmtd_key_len, gname_size;
+	int				tmp_cmpc;
+	blk_hdr_ptr_t			bp;
+	boolean_t			beg_key;
+	rec_hdr_ptr_t			rp, save_rp;
+	sm_uc_ptr_t			blktop, cp1, rectop, out;
 	mval				*val_span = NULL;
 	boolean_t			is_hidden, found_dummy = FALSE;
-
+	blk_hdr_ptr_t			encrypted_bp;
 #	ifdef GTM_CRYPT
-	char				*in, *out;
-	gd_region			*reg, *reg_top;
-	int				gtmcrypt_errno;
-	static gtmcrypt_key_t		encr_key_handle;
-	static int4			index, prev_allocated_size;
 	static sgmnt_data_ptr_t		prev_csd;
-	static unsigned char		*unencrypted_blk_buff;
-	gd_segment			*seg;
+	gd_region			*reg, *reg_top;
 #	endif
 
-	op_gvname(VARLSTCNT(1) gn);	/* op_gvname() must be done before any usage of cs_addrs or, gv_currkey */
 	if (0 == gv_target->root)
 		return TRUE; /* possible if ROLLBACK ended up physically removing a global from the database */
 	if (NULL == key_buffer)
@@ -110,7 +104,7 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 		if (NULL != zwr_buffer)
 			free (zwr_buffer);
 		max_zwr_len = ZWR_EXP_RATIO(cs_addrs->hdr->max_rec_size);
-		zwr_buffer = (unsigned char *)malloc(max_zwr_len);
+		zwr_buffer = (unsigned char *)malloc(MAX_ZWR_KEY_SZ + max_zwr_len);
 	}
 	assert(0 < cs_data->blk_size);
 	if (cs_data->blk_size > private_blksz)
@@ -129,7 +123,7 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 #	ifdef GTM_CRYPT
 	if (is_any_file_encrypted && (cs_data->is_encrypted) && (format == MU_FMT_BINARY))
 	{
-		ASSERT_ENCRYPTION_INITIALIZED;	/* due to op_gvname done from gv_select in mu_extract */
+		ASSERT_ENCRYPTION_INITIALIZED;	/* due to op_gvname_fast done from gv_select in mu_extract */
 		if (prev_csd != cs_data)
 		{
 			prev_csd = cs_data;
@@ -140,14 +134,14 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 					break;
 			}
 			assert(gv_cur_region < reg_top);
-			GTMCRYPT_GETKEY(cs_addrs, hash_array[index].gtmcrypt_hash, encr_key_handle, gtmcrypt_errno);
-			if (0 != gtmcrypt_errno)
-			{
-				seg = gv_cur_region->dyn.addr;
-				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, seg->fname_len, seg->fname);
-				return FALSE;
-			}
 		}
+		/* We have to write the encrypted version of the block. Instead of encrypting the plain-text version of the
+		 * block, we just reference the encrypted version of the block that is already maintained in sync with the
+		 * plain-text version by wcs_wtstart and dsk_read (called eventually by mu_extr_getblk below). All we need to
+		 * make sure is that we have a private buffer allocated (of appropriate size) in which mu_extr_getblk can return
+		 * the encrypted version of the block. Do the allocation here.
+		 */
+		REALLOC_CRYPTBUF_IF_NEEDED(cs_data->blk_size);
 	}
 #	endif
 	for ( ; ; )
@@ -157,10 +151,15 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 		if (mu_ctrlc_occurred)
 		{
 			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT("TOTAL"),
-				st->recknt, st->keylen, st->datalen, st->reclen);
+				 st->recknt, st->keylen, st->datalen, st->reclen);
 			mu_ctrlc_occurred = FALSE;
 		}
-		if (!mu_extr_getblk(private_blk))
+		encrypted_bp = NULL;
+#		ifdef GTM_CRYPT
+		if (cs_data->is_encrypted && (MU_FMT_BINARY == format))
+			encrypted_bp = (blk_hdr_ptr_t)pvt_crypt_buf.addr;
+#		endif
+		if (!mu_extr_getblk(private_blk, (unsigned char *)encrypted_bp))
 			break;
 		bp = (blk_hdr_ptr_t)private_blk;
 		if (bp->bsiz == SIZEOF(blk_hdr))
@@ -168,51 +167,42 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 		if (0 != bp->levl || bp->bsiz < SIZEOF(blk_hdr) || bp->bsiz > cs_data->blk_size ||
 				gv_target->hist.h[0].curr_rec.match < gname_size)
 			INTEG_ERROR_RETURN
-		/* Note that rp may not be the beginning of a block */
-		rp = (rec_hdr_ptr_t)(gv_target->hist.h[0].curr_rec.offset + (sm_uc_ptr_t)bp);
 		blktop = (sm_uc_ptr_t)bp + bp->bsiz;
 		if (format == MU_FMT_BINARY)
 		{
+			/* At this point, gv_target->hist.h[0].curr_rec.offset points to the offset within the block at which
+			 * the desired record exists. If this record is *not* the first record in the block (possible due to
+			 * concurrent updates), the compression count for that record would be non-zero which means we cannot
+			 * initiate a write to the extract file starting from this offset as the 'mupip load' command would
+			 * consider this record as corrupted. So, we write the entire block instead. This could increase the
+			 * size of the binary extract file, but the alternative is to expand the curent record and with encryption
+			 * it becomes a performance overhead as we have to encrypt only the tail of a block. If we choose to
+			 * write the whole block, we avoid encryption altogether because we have access to the encrypted block
+			 * from the encrypted twin buffer.
+			 */
+			rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)bp + SIZEOF(blk_hdr));
 			out_size = blktop - (sm_uc_ptr_t)rp;
-			save_rp = rp;
+			out = (sm_uc_ptr_t)rp;
 #			ifdef GTM_CRYPT
-			if (is_any_file_encrypted)
+			if (!is_any_file_encrypted || !cs_data->is_encrypted)
+				index = -1;	/* tells MUPIP LOAD that this block is NOT encrypted */
+			else
 			{
-				if (cs_data->is_encrypted)
-				{
-					in = (char *)(rp);
-					*(int4 *)(cs_addrs->encrypted_blk_contents) = index;
-					out = cs_addrs->encrypted_blk_contents + SIZEOF(int4);
-					GTMCRYPT_ENCRYPT(cs_addrs, encr_key_handle, in, out_size, out, gtmcrypt_errno)
-					if (0 != gtmcrypt_errno)
-					{
-						seg = gv_cur_region->dyn.addr;
-						GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, seg->fname_len, seg->fname);
-						return FALSE;
-					}
-					rp = (rec_hdr_ptr_t)cs_addrs->encrypted_blk_contents;
-				} else
-				{	/* For unencrypted database, we cannot use cs_addrs->encrypted_blk_contents. Instead, use
-					 * a static malloc'ed buffer. The malloc is needed because the buffer that's written out
-					 * to the extract file is prefixed with an int4 indicating the ith database that this block
-					 * corresponds to and -1 (if the database is unencrypted).
-					 */
-					if ((NULL == unencrypted_blk_buff) || (prev_allocated_size < out_size))
-					{
-						if (NULL != unencrypted_blk_buff)
-							free(unencrypted_blk_buff);
-						unencrypted_blk_buff = (unsigned char *) malloc(out_size + SIZEOF(int4));
-						prev_allocated_size = out_size;
-					}
-					*(int4 *)(unencrypted_blk_buff) = -1;
-					memcpy(unencrypted_blk_buff + (SIZEOF(int4)), rp, out_size);
-					rp = (rec_hdr_ptr_t)unencrypted_blk_buff;
-				}
-				out_size += SIZEOF(int4);
+				assert(NULL != encrypted_bp);
+				assert(encrypted_bp->bsiz == bp->bsiz);
+				assert(encrypted_bp->tn == bp->tn);
+				assert(encrypted_bp->levl == bp->levl);
+				assert(out_size == (encrypted_bp->bsiz - SIZEOF(blk_hdr)));
+				out = (sm_uc_ptr_t)encrypted_bp + SIZEOF(blk_hdr);
+				assert(-1 != index);
 			}
+#			else
+			index = -1;
 #			endif
-			WRITE_BIN_EXTR_BLK(rp, out_size); /* output records of current block */
-			rp = save_rp;
+			WRITE_BIN_EXTR_BLK(out, out_size, (-1 != index) ? WRITE_4MORE_BYTES_TRUE : WRITE_4MORE_BYTES_FALSE, index);
+		} else
+		{	/* Note that rp may not be the beginning of a block */
+			rp = (rec_hdr_ptr_t)(gv_target->hist.h[0].curr_rec.offset + (sm_uc_ptr_t)bp);
 		}
 		for (beg_key = TRUE; (sm_uc_ptr_t)rp < blktop; rp = (rec_hdr_ptr_t)rectop)
 		{ 	/* Start scanning a block */
@@ -259,13 +249,14 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 			if (st->keylen < gv_currkey->end + 1)
 				st->keylen = gv_currkey->end + 1;
 			data_len = (int)(rec_size - (cp1 - (sm_uc_ptr_t)rp));
-			if (0 > data_len)
-				INTEG_ERROR_RETURN
-			if (st->datalen < data_len)
-				st->datalen = data_len;
 #			ifdef UNIX
 			if ((1 == data_len) && ('\0' == *cp1))
-			{	/* Possibly (probably) a spanning node. Need to read in more blocks to get the value */
+			{	/* Possibly (probably) a spanning node. Need to read in more blocks to get the value. Note: This
+				 * additional gvcst_get is needed only for ZWR/GO extracts and not for BINARY extracts as the
+				 * latter dumps the entire block content. But, we need to read the value anyways to report accurate
+				 * statistics on the maximum data length (st->datalen). So, do the gvcst_get irrespective of
+				 * whether this is a ZWR/GO/BINARY extract.
+				 */
 				if (!val_span)
 				{	/* protect val_span from stp_gcol in WRITE_EXTR_LINE/op_write */
 					PUSH_MV_STENT(MVST_MVAL);
@@ -275,8 +266,6 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 				cp1 = (unsigned char *)val_span->str.addr;
 				data_len = val_span->str.len;
 				found_dummy = TRUE;
-				if (st->datalen < data_len)
-					st->datalen = data_len;
 			}
 #			endif
 			if (MU_FMT_BINARY != format)
@@ -304,14 +293,15 @@ boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int fo
 				found_dummy = FALSE;
 			}
 #			endif
+			if (0 > data_len)
+				INTEG_ERROR_RETURN
+			if (st->datalen < data_len)
+				st->datalen = data_len;
 		} /* End scanning a block */
-		if ((sm_uc_ptr_t)rp != blktop ||
-			(memcmp(gv_currkey->base, beg_gv_currkey->base, MIN(gv_currkey->end, beg_gv_currkey->end)) < 0))
-			INTEG_ERROR_RETURN
-		gv_currkey->base[gv_currkey->end] = 1;
-		gv_currkey->base[gv_currkey->end + 1] = 0;
-		gv_currkey->base[gv_currkey->end + 2] = 0;
-		gv_currkey->end += 2;
+		if (((sm_uc_ptr_t)rp != blktop)
+				|| (0 > memcmp(gv_currkey->base, beg_gv_currkey->base, MIN(gv_currkey->end, beg_gv_currkey->end))))
+			INTEG_ERROR_RETURN;
+		GVKEY_INCREMENT_QUERY(gv_currkey);
 	} /* end outmost for */
 	return TRUE;
 }
diff --git a/sr_port/mu_extr_getblk.c b/sr_port/mu_extr_getblk.c
index 162bcd0..51bdfb9 100644
--- a/sr_port/mu_extr_getblk.c
+++ b/sr_port/mu_extr_getblk.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,10 @@
 #include <rms.h>		/* needed for muextr.h */
 #endif
 #include "muextr.h"
+#ifdef GTM_CRYPT
+#include "gtmcrypt.h"
+#endif
+#include "min_max.h"
 
 GBLREF gd_region	*gv_cur_region;
 GBLREF gv_namehead	*gv_target;
@@ -40,11 +44,12 @@ GBLREF unsigned int	t_tries;
 
 error_def(ERR_GVGETFAIL);
 
-int mu_extr_getblk(unsigned char *ptr)
+int mu_extr_getblk(unsigned char *ptr, unsigned char *encrypted_buff_ptr)
 {
+	enum cdb_sc		status;
+	int			bsiz;
 	blk_hdr_ptr_t		bp;
 	boolean_t		two_histories, end_of_tree;
-	enum cdb_sc		status;
 	rec_hdr_ptr_t		rp;
 	srch_blk_status		*bh;
 	srch_hist		*rt_history;
@@ -52,6 +57,17 @@ int mu_extr_getblk(unsigned char *ptr)
 	DEBUG_ONLY(unsigned int	lcl_t_tries;)
 	boolean_t		tn_aborted;
 #	endif
+#	ifdef GTM_CRYPT
+	char			*in, *out;
+	int			out_size, gtmcrypt_errno;
+	trans_num		lcl_dirty;
+	gd_segment		*seg;
+	blk_hdr_ptr_t		encrypted_bp;
+#	ifdef DEBUG
+	static unsigned char	*private_blk;
+	static int		private_blksz;
+#	endif
+#	endif
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -88,12 +104,70 @@ int mu_extr_getblk(unsigned char *ptr)
 				continue;
 			}
 		}
-		memcpy(ptr, bp, bp->bsiz);
+		assert(bp->bsiz <= cs_addrs->hdr->blk_size);
+		bsiz = MIN(bp->bsiz, cs_addrs->hdr->blk_size);
+		memcpy(ptr, bp, bsiz);
+#		ifdef GTM_CRYPT
+		if (NULL != encrypted_buff_ptr)
+		{	/* The caller requested the encrypted buffer corresponding to `bp' as well. Take a copy of the encrypted
+			 * twin global buffer. But, do that only if the cache record corresponding to `bp' is not dirty. Otherwise,
+			 * the encrypted twin remains stale (as of dsk_read) until a wcs_wtstart happens at which point it updates
+			 * the twin global buffer to contain the up-to-date encrypted contents. So, in this case, an explicit
+			 * encryption is needed once this transaction succeeds.
+			 */
+			if (0 == (lcl_dirty = bh->cr->dirty))
+			{
+				encrypted_bp = (blk_hdr_ptr_t)GDS_ANY_ENCRYPTGLOBUF(bp, cs_addrs);
+				memcpy(encrypted_buff_ptr, (sm_uc_ptr_t)encrypted_bp, bsiz);
+			}
+		}
+#		endif
 		UNIX_ONLY(DEBUG_ONLY(lcl_t_tries = t_tries));
 		if ((trans_num)0 != t_end(&gv_target->hist, two_histories ? rt_history : NULL, TN_NOT_SPECIFIED))
-		{
+		{	/* Transaction succeeded. */
 			if (two_histories)
 				memcpy(gv_target->hist.h, rt_history->h, SIZEOF(srch_blk_status) * (rt_history->depth + 1));
+#			ifdef GTM_CRYPT
+			if (NULL != encrypted_buff_ptr)
+			{
+				assert(GTMCRYPT_INVALID_KEY_HANDLE != cs_addrs->encr_key_handle);
+				if (lcl_dirty)
+				{
+					/* We did not take a copy of the encrypted twin global buffer. Do explicit encryption now */
+					memcpy(encrypted_buff_ptr, ptr, SIZEOF(blk_hdr));	/* Copy the block header. */
+					in = (char *)ptr + SIZEOF(blk_hdr);
+					out = (char *)encrypted_buff_ptr + SIZEOF(blk_hdr);
+					out_size = bsiz - SIZEOF(blk_hdr);
+					GTMCRYPT_ENCRYPT(cs_addrs, cs_addrs->encr_key_handle, in, out_size, out, gtmcrypt_errno);
+					if (0 != gtmcrypt_errno)
+					{
+						seg = cs_addrs->region->dyn.addr;
+						GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, seg->fname_len, seg->fname);
+					}
+				}
+#				ifdef DEBUG
+				else
+				{	/* We took a copy of the encrypted twin global buffer before t_end. Ensure that we did not
+					 * take a stale copy.
+					 */
+					if ((0 == private_blksz) || (private_blksz < cs_addrs->hdr->blk_size))
+					{	/* [re]allocate space for doing out-of-place encryption. */
+						if (NULL != private_blk)
+							free(private_blk);
+						private_blksz = cs_addrs->hdr->blk_size;
+						private_blk = (unsigned char *)malloc(private_blksz);
+					}
+					memcpy(private_blk, ptr, SIZEOF(blk_hdr));
+					in = (char *)ptr + SIZEOF(blk_hdr);
+					out = (char *)private_blk + SIZEOF(blk_hdr);
+					out_size = bsiz - SIZEOF(blk_hdr);
+					GTMCRYPT_ENCRYPT(cs_addrs, cs_addrs->encr_key_handle, in, out_size, out, gtmcrypt_errno);
+					assert(0 == gtmcrypt_errno);
+					assert(0 == memcmp(private_blk, encrypted_buff_ptr, bsiz));
+				}
+#				endif
+			}
+#			endif
 			return !end_of_tree;
 		}
 #		ifdef UNIX
diff --git a/sr_port/mu_extr_ident.c b/sr_port/mu_extr_ident.c
index 43b2e79..e89928b 100644
--- a/sr_port/mu_extr_ident.c
+++ b/sr_port/mu_extr_ident.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,10 +10,18 @@
  ****************************************************************/
 
 #include "mdef.h"
+
 #ifdef VMS
 #include <rms.h>		/* needed for muextr.h */
 #endif
-#include "muextr.h"
+
+#include "gdsroot.h"
+#include "gdsblk.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"	/* above includes needed for muextr.h */
+#include "muextr.h"	/* needed for "mu_extr_ident" prototype */
 
 #define IDENT_FCHAR(x) (((x) >= 'A' && (x) <= 'Z') || ((x) >= 'a' && (x) <= 'z') || (x) == '%')
 #define IDENT_TAIL(x) (((x) >= 'A' && (x) <= 'Z') || ((x) >= 'a' && (x) <= 'z') || ((x) >= '0' && (x) <= '9'))
diff --git a/sr_port/mu_freeze_ch.c b/sr_port/mu_freeze_ch.c
index 982a375..c57b928 100644
--- a/sr_port/mu_freeze_ch.c
+++ b/sr_port/mu_freeze_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2008 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,7 +32,7 @@ CONDITION_HANDLER(mu_freeze_ch)
 {
 	tp_region	*rptr1;
 
-	START_CH;
+	START_CH(TRUE);
 	for (rptr1 = grlist ; rptr1 != NULL; rptr1 = rptr1->fPtr)
 	{
 		gv_cur_region = rptr1->reg;
diff --git a/sr_port/mu_gv_stack_init.c b/sr_port/mu_gv_stack_init.c
index 931e22f..e488161 100644
--- a/sr_port/mu_gv_stack_init.c
+++ b/sr_port/mu_gv_stack_init.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,11 +25,6 @@
 #include "stack_frame.h"
 #include "mu_gv_stack_init.h"
 
-GBLREF	gv_key			*gv_currkey;
-GBLREF	gv_namehead		*gv_target;
-GBLREF  gd_region               *gv_cur_region;
-GBLREF  int4			gv_keysize;
-GBLREF  gv_key                  *gv_altkey;
 GBLREF  mv_stent                *mv_chain;
 GBLREF  stack_frame             *frame_pointer;
 GBLREF  unsigned char           *msp, *stackbase, *stacktop, *stackwarn;
@@ -41,8 +36,7 @@ void mu_gv_stack_init(void)
 	lnr_tabent	*lnrtbe;
 	unsigned char	*mstack_ptr;
 
-	GVKEY_INIT(gv_currkey, gv_keysize);
-	GVKEY_INIT(gv_altkey, gv_keysize);
+	GVKEYSIZE_INIT_IF_NEEDED;	/* sets "gv_keysize", "gv_currkey" and "gv_altkey" (if not already done) */
 	/* There may be M transactions in the journal files.  If so, op_tstart() and op_tcommit()
 	 * will be called during recovery;  they require a couple of dummy stack frames to be set up.
 	 */
diff --git a/sr_port/mu_int_err.c b/sr_port/mu_int_err.c
index 5b2d4bd..854a974 100644
--- a/sr_port/mu_int_err.c
+++ b/sr_port/mu_int_err.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,7 +18,6 @@
 #include "gdsfhead.h"
 #include "mupint.h"
 #include "min_max.h"
-#include "init_root_gv.h"
 #include "util.h"
 #include "print_target.h"
 #include "gtmmsg.h"
@@ -82,11 +81,11 @@ void	mu_int_err(
 	MEMCPY_LIT(&util_buff[util_len], TEXT2);
 	util_len += SIZEOF(TEXT2) - 1;
 	util_buff[util_len] = 0;
-	if(sndata->sn_type)
-		gtm_putmsg(VARLSTCNT(5) err, 3, LEN_AND_STR((char*)util_buff),
+	if (sndata->sn_type)
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) err, 3, LEN_AND_STR((char*)util_buff),
 				(SPAN_NODE == sndata->sn_type) ? (sndata->span_prev_blk + 2) : (sndata->span_blk_cnt));
 	else
-		gtm_putmsg(VARLSTCNT(4) err, 2, LEN_AND_STR((char*)util_buff));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) err, 2, LEN_AND_STR((char*)util_buff));
 	if (do_path)
 	{
 		if (!master_dir)
diff --git a/sr_port/mu_int_fhead.c b/sr_port/mu_int_fhead.c
index f5135c7..af87436 100644
--- a/sr_port/mu_int_fhead.c
+++ b/sr_port/mu_int_fhead.c
@@ -157,12 +157,12 @@ boolean_t mu_int_fhead(void)
 		mu_int_err(ERR_DBTNNEQ, 0, 0, 0, 0, 0, 0, 0);
         if (0 != mu_data->kill_in_prog)
         {
-                gtm_putmsg(VARLSTCNT(6) ERR_MUKILLIP, 4, DB_LEN_STR(gv_cur_region), LEN_AND_LIT("MUPIP INTEG"));
+                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUKILLIP, 4, DB_LEN_STR(gv_cur_region), LEN_AND_LIT("MUPIP INTEG"));
                 mu_int_errknt++;
         }
         if (0 != mu_data->abandoned_kills)
         {
-                gtm_putmsg(VARLSTCNT(6) ERR_KILLABANDONED, 4, DB_LEN_STR(gv_cur_region),
+                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_KILLABANDONED, 4, DB_LEN_STR(gv_cur_region),
 			LEN_AND_LIT("database could have incorrectly marked busy integrity errors"));
                 mu_int_errknt++;
         }
@@ -190,7 +190,8 @@ boolean_t mu_int_fhead(void)
 		if (max_tn_warn == mu_data->trans_hist.curr_tn)
 		{	/* implies there is not enough transactions to go before reaching MAX_TN (see SET_TN_WARN macro) */
 			temp_tn = mu_data->max_tn - mu_data->trans_hist.curr_tn;
-			gtm_putmsg(VARLSTCNT(6) ERR_MUTNWARN, 4, DB_LEN_STR(gv_cur_region), &temp_tn, &mu_data->max_tn);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUTNWARN, 4,
+						DB_LEN_STR(gv_cur_region), &temp_tn, &mu_data->max_tn);
 			mu_int_errknt++;
 		}
 	}
@@ -243,6 +244,7 @@ boolean_t mu_int_fhead(void)
 	size = mu_int_ovrhd + (off_t)block_factor * mu_data->trans_hist.total_blks;
 	/* If ONLINE INTEG for this region is in progress, then native_size would have been calculated in ss_initiate. */
 	SET_NATIVE_SIZE(native_size);
+	ALIGN_DBFILE_SIZE_IF_NEEDED(size, native_size);
 	/* In the following tests, the EOF block should always be 1 greater
 	 * than the actual size of the file.  This is due to the GDS being
 	 * allocated in even DISK_BLOCK_SIZE-byte blocks. */
@@ -253,13 +255,14 @@ boolean_t mu_int_fhead(void)
 		else
 			mu_int_err(ERR_DBFSTBC, 0, 0, 0, 0, 0, 0, 0);
 		if (native_size % 2) /* Native size should be (64K + n*1K + 512) / DISK_BLOCK_SIZE , so always an odd number. */
-			gtm_putmsg(VARLSTCNT(4) ERR_DBTOTBLK, 2, (uint4)((native_size - mu_data->start_vbn) / block_factor),
-				mu_data->trans_hist.total_blks);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBTOTBLK, 2,
+						(uint4)((native_size - mu_data->start_vbn) / block_factor),
+						mu_data->trans_hist.total_blks);
 		else
 			/* Since native_size is even and the result will be rounded down, we need to add 1 before the division so we
 			 * extend by enough blocks (ie. if current nb. of blocks is 100, and the file size gives 102.5 blocks, we
 			 * need to extend by 3 blocks, not 2). */
-			gtm_putmsg(VARLSTCNT(6) ERR_DBMISALIGN, 4, DB_LEN_STR(gv_cur_region),
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBMISALIGN, 4, DB_LEN_STR(gv_cur_region),
 				(uint4)((native_size - mu_data->start_vbn) / block_factor),
 				(uint4)(((native_size + 1 - mu_data->start_vbn) / block_factor) - mu_data->trans_hist.total_blks));
 	}
diff --git a/sr_port/mu_int_getkey.c b/sr_port/mu_int_getkey.c
index 3563d24..4d9ee26 100644
--- a/sr_port/mu_int_getkey.c
+++ b/sr_port/mu_int_getkey.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,6 +20,7 @@
 #include "util.h"
 #include "mupint.h"
 #include "mvalconv.h"
+#include "collseq.h"
 
 GBLDEF	gv_key		*muint_start_key;
 GBLDEF	gv_key		*muint_end_key;
@@ -43,6 +44,8 @@ int mu_int_getkey(unsigned char *key_buff, int keylen)
 	unsigned char	*top, *startsrc, *src, *dest, slit[MAX_KEY_SZ + 1], *tmp;
 	int		iter;
 	gv_key		*muint_tmpkey;
+	gd_region	*reg;
+	boolean_t	nullsubs_seen;
 
 	src = key_buff;
 	if ('"' == key_buff[keylen - 1])
@@ -61,6 +64,7 @@ int mu_int_getkey(unsigned char *key_buff, int keylen)
 	top = src + keylen;
 	startsrc = src;
 	keysize = DBKEYSIZE(MAX_KEY_SZ);
+	assert(MUINTKEY_FALSE == muint_key);
 	for (iter = 0, top = src + keylen; (iter < 2) && (src < top); iter++)
 	{
 		muint_tmpkey = NULL;	/* GVKEY_INIT macro requires this */
@@ -74,6 +78,7 @@ int mu_int_getkey(unsigned char *key_buff, int keylen)
 			assert(NULL == muint_end_key);
 			muint_end_key = muint_tmpkey;	/* used by CLNUP_AND_RETURN_FALSE macro */
 		}
+		nullsubs_seen = FALSE;
 		dest = muint_tmpkey->base;
 		if ('^' != *src++)
 		{
@@ -158,8 +163,17 @@ int mu_int_getkey(unsigned char *key_buff, int keylen)
 					}
 					tmpmval.str.addr = (char*)slit;
 					tmpmval.str.len = INTCAST(tmp - slit);
+					if (!tmpmval.str.len)
+						nullsubs_seen = TRUE;
 				}
-				mval2subsc(&tmpmval, muint_tmpkey);
+				/* We could be looking for this -subscript=... specification in one of many database files
+				 * each with a different standard null collation setting. As MUPIP INTEG switches to different
+				 * database files, it needs to recompute the subscript representation of the input subscript
+				 * if there are null subscripts in it and the regions have different standard null collation
+				 * properties. For now assume standard null collation is FALSE in all regions. And note down
+				 * if any null subscript was seen. If so do recomputation of key as db files get switched in integ.
+				 */
+				mval2subsc(&tmpmval, muint_tmpkey, STD_NULL_COLL_FALSE);
 				if ((src >= top) || (',' != *src))
 					break;
 				src++;
@@ -181,7 +195,8 @@ int mu_int_getkey(unsigned char *key_buff, int keylen)
 		}
 		if (':' == *src)
 			src++;
-		muint_key = TRUE;
+		if (MUINTKEY_NULLSUBS != muint_key)
+			muint_key = (nullsubs_seen ? MUINTKEY_NULLSUBS : MUINTKEY_TRUE);
 	}
 	if (src < top)
 	{
diff --git a/sr_port/mu_int_maps.c b/sr_port/mu_int_maps.c
index b63d4e2..34d74d6 100644
--- a/sr_port/mu_int_maps.c
+++ b/sr_port/mu_int_maps.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -22,6 +22,7 @@
 #include "mu_int_maps.h"
 #include "util.h"
 #include "mupint.h"
+#include "gtmmsg.h"
 
 /* Include prototypes */
 #include "bit_set.h"
@@ -40,6 +41,8 @@ GBLREF	int			mu_map_errs;
 GBLREF	int			disp_trans_errors;
 GBLREF	int			trans_errors;
 
+GBLREF trans_num        largest_tn;
+
 error_def(ERR_DBREADBM);
 error_def(ERR_DBLVLINC);
 error_def(ERR_DBMBSIZMN);
@@ -56,6 +59,7 @@ error_def(ERR_DBMBPINCFL);
 error_def(ERR_DBMRKFREE);
 error_def(ERR_DBMRKBUSY);
 error_def(ERR_DBMBMINCFRE);
+error_def(ERR_DBTN);
 
 void mu_int_maps(void)
 {
@@ -68,6 +72,7 @@ void mu_int_maps(void)
 	uint4		dskmap, lfree, *lmap, map_blk_size;
 	block_id	blkno, last_bmp;
 	enum db_ver	ondsk_blkver;
+	trans_num map_tn;
 
 	mu_int_offset[0] = 0;
 	maps = (mu_int_data.trans_hist.total_blks + mu_int_data.bplmap - 1) / mu_int_data.bplmap;
@@ -116,20 +121,21 @@ void mu_int_maps(void)
 				mu_int_blks_to_upgrd++;
 		} else if (GDSVCURR != ondsk_blkver)
 			mu_int_blks_to_upgrd++;
-		if (((blk_hdr_ptr_t)disk)->tn >= mu_int_data.trans_hist.curr_tn)
-		{
+		map_tn = ((blk_hdr_ptr_t)disk)->tn;
+ 		if (map_tn >= mu_int_data.trans_hist.curr_tn)
+ 		{
 			if (trans_errors < disp_trans_errors)
 			{
 				mu_int_path[0] = blkno;
 				mu_int_plen = 1;
 				mu_int_err(ERR_DBMBTNSIZMX, 0, 0, 0, 0, 0, 0, level);
-				trans_errors++;
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_DBTN, 1, &map_tn);
 			} else
-			{
-				mu_int_errknt++;
-				trans_errors++;
-			}
-		}
+			   mu_int_errknt++;
+			trans_errors++;
+			if (map_tn > largest_tn)
+				largest_tn = map_tn;
+ 		}
 		master_full = !bit_set(mcnt, mu_int_master);
 		if (last_bmp == blkno)
 			mapsize = (mu_int_data.trans_hist.total_blks - blkno);
diff --git a/sr_port/mu_int_read.c b/sr_port/mu_int_read.c
index ea02947..e08db3a 100644
--- a/sr_port/mu_int_read.c
+++ b/sr_port/mu_int_read.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -72,7 +72,7 @@ uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
 #	ifdef UNIX
 	if (region && csa->nl->onln_rlbk_pid)
 	{
-		gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(1) ERR_DBROLLEDBACK);
 		mupip_exit(ERR_INTEGERRS);
 	}
 #	endif
@@ -91,7 +91,8 @@ uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
 			 * crit as GT.M is the only one that sets it and INTEG (while doing snapshot cleanup) is the only one
 			 * that resets it
 			 */
-			gtm_putmsg(VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid, DB_LEN_STR(gv_cur_region));
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid,
+						DB_LEN_STR(gv_cur_region));
 			mupip_exit(ERR_INTEGERRS);
 		}
 	}
@@ -116,7 +117,8 @@ uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
 				ss_get_block(csa, blk, tmp_ptr);
 			else
 			{
-				gtm_putmsg(VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid, DB_LEN_STR(gv_cur_region));
+				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid,
+							DB_LEN_STR(gv_cur_region));
 				mupip_exit(ERR_INTEGERRS);
 			}
 		}
@@ -124,9 +126,9 @@ uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
 	}
 #	ifdef GTM_CRYPT
 	in_len = MIN(mu_int_data.blk_size, ((blk_hdr_ptr_t)tmp_ptr)->bsiz) - SIZEOF(blk_hdr);
-	if (BLOCK_REQUIRE_ENCRYPTION(mu_int_data.is_encrypted, (((blk_hdr_ptr_t)tmp_ptr)->levl), in_len))
+	if (BLK_NEEDS_ENCRYPTION3(mu_int_data.is_encrypted, (((blk_hdr_ptr_t)tmp_ptr)->levl), in_len))
 	{
-		/* The below assert cannot be moved before BLOCK_REQUIRE_ENCRYPTION check done above as tmp_ptr could
+		/* The below assert cannot be moved before BLK_NEEDS_ENCRYPTION3 check done above as tmp_ptr could
 		 * potentially point to a V4 block in which case the assert might fail when a V4 block is casted to
 		 * a V5 block header.
 		 */
@@ -144,8 +146,8 @@ uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
 	GDS_BLK_UPGRADE_IF_NEEDED(blk, tmp_ptr, tmp_ptr, &mu_int_data, ondsk_blkver, status, mu_int_data.fully_upgraded);
 	if (SS_NORMAL != status)
 		if (ERR_DYNUPGRDFAIL == status)
-			rts_error(VARLSTCNT(5) status, 3, blk, DB_LEN_STR(gv_cur_region));
+			rts_error_csa(CSA_ARG(csa) VARLSTCNT(5) status, 3, blk, DB_LEN_STR(gv_cur_region));
 		else
-			rts_error(VARLSTCNT(1) status);
+			rts_error_csa(CSA_ARG(csa) VARLSTCNT(1) status);
 	return tmp_ptr;
 }
diff --git a/sr_port/mu_int_reg_ch.c b/sr_port/mu_int_reg_ch.c
index 28eca77..6807cf2 100644
--- a/sr_port/mu_int_reg_ch.c
+++ b/sr_port/mu_int_reg_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -41,7 +41,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(mu_int_reg_ch)
 {
-	START_CH
+	START_CH(TRUE);
 	mu_int_skipreg_cnt++;
 	if (DUMPABLE)
 		NEXTCH;
diff --git a/sr_port/mu_reorg.c b/sr_port/mu_reorg.c
index 9a91804..ce1bd28 100644
--- a/sr_port/mu_reorg.c
+++ b/sr_port/mu_reorg.c
@@ -65,19 +65,12 @@
 #include "sleep_cnt.h"
 #include "wcs_sleep.h"
 #include "memcoherency.h"
+#include "change_reg.h"
 
 #ifdef UNIX
 #include "repl_msg.h"
 #include "gtmsource.h"
 #endif
-#ifdef GTM_TRIGGER
-#include "hashtab_mname.h"
-#include "gv_trigger.h"
-#include "gv_trigger_common.h"
-#include "targ_alloc.h"
-#endif
-
-GTMTRIG_ONLY(LITREF	mval	literal_hasht;)
 
 GBLREF	bool			mu_ctrlc_occurred;
 GBLREF	bool			mu_ctrly_occurred;
@@ -121,20 +114,21 @@ error_def(ERR_MUREORGFAIL);
 }
 
 #ifdef UNIX
-# define ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(LCL_T_TRIES)								\
+# define ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(LCL_T_TRIES, GN)								\
 {																\
 	boolean_t		tn_aborted;											\
 																\
 	ABORT_TRANS_IF_GBL_EXIST_NOMORE(LCL_T_TRIES, tn_aborted);								\
 	if (tn_aborted)														\
 	{															\
-		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);			\
+		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GN->len, GN->addr);				\
 		reorg_finish(dest_blk_id, blks_processed, blks_killed, blks_reused, file_extended, lvls_reduced, blks_coalesced,\
 				blks_split, blks_swapped);									\
 		return TRUE; /* It is not an error if the global (that once existed) doesn't exist anymore (due to ROLLBACK) */	\
 	}															\
 }
 #endif
+
 void log_detailed_log(char *X, srch_hist *Y, srch_hist *Z, int level, kill_set *kill_set_list, trans_num tn);
 void reorg_finish(block_id dest_blk_id, int blks_processed, int blks_killed,
 	int blks_reused, int file_extended, int lvls_reduced,
@@ -196,7 +190,7 @@ void log_detailed_log(char *X, srch_hist *Y, srch_hist *Z, int level, kill_set *
 
 /****************************************************************
 Input Parameter:
-	gn = Global name
+	gl_ptr = pointer to glist structure corresponding to global name
 	exclude_glist_ptr = list of globals in EXCLUDE option
 	index_fill_factor = index blocks' fill factor
 	data_fill_factor = data blocks' fill factor
@@ -205,7 +199,8 @@ Input/Output Parameter:
 	reorg_op = What operations to do (coalesce or, swap or, split) [Default is all]
 			[Only for debugging]
  ****************************************************************/
-boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int index_fill_factor, int data_fill_factor, int reorg_op)
+boolean_t mu_reorg(glist *gl_ptr, glist *exclude_glist_ptr, boolean_t *resume,
+				int index_fill_factor, int data_fill_factor, int reorg_op)
 {
 	boolean_t		end_of_tree = FALSE, complete_merge, detailed_log;
 	int			rec_size;
@@ -233,35 +228,18 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 	super_srch_hist		super_dest_hist; /* dir_hist combined with reorg_gv_target->hist */
 	jnl_buffer_ptr_t	jbp;
 	trans_num		ret_tn;
-	sgmnt_addrs		*csa;
+	mstr			*gn;
 #	ifdef UNIX
 	DEBUG_ONLY(unsigned int	lcl_t_tries;)
 #	endif
-#	ifdef GTM_TRIGGER
-	gv_namehead		*hasht_tree;
-	mname_entry		gvent;
-#	endif
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	csa = cs_addrs;
 	t_err = ERR_MUREORGFAIL;
 	kill_set_tail = &kill_set_list;
 	inctn_opcode = inctn_invalid_op; /* temporary reset; satisfy an assert in t_end() */
-#	ifdef GTM_TRIGGER
-	if (IS_MNAME_HASHT_GBLNAME(gn->str))
-	{	/* Initialize ^#t global for this region. Maintain reorg_restart_key as usual since this exists per region. */
-		SETUP_TRIGGER_GLOBAL;
-		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
-		DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
-		if (0 != gv_target->root)
-		{
-			util_out_print("   ", FLUSH);
-			util_out_print("Global: !AD (region !AD)", FLUSH, gn->str.len, gn->str.addr, REG_LEN_STR(gv_cur_region));
-		}
-	} else
-#	endif	/* Initialization for current global */
-		op_gvname(VARLSTCNT(1) gn);
+	DO_OP_GVNAME(gl_ptr);
+		/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 	/* Cannot proceed for read-only data files */
 	if (gv_cur_region->read_only)
 	{
@@ -272,36 +250,34 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 		return TRUE; /* It is not an error that global was killed */
 	dest_blk_id = cs_addrs->reorg_last_dest;
 	inctn_opcode = inctn_mu_reorg;
-
+	gn = &GNAME(gl_ptr);
 	/* If resume option is present, then reorg_restart_key should be not null.
 	 * Skip all globals until we are in the region for that global.
 	 * Get the reorg_restart_key and reorg_restart_block from database header and restart from there.
 	 */
 	if (*resume && 0 != cs_data->reorg_restart_key[0])
-	{
-		/* resume from last key reorged in GVT */
+	{	/* resume from last key reorged in GVT */
 		tkeysize = get_key_len(NULL, &cs_data->reorg_restart_key[0]);
 		memcpy(gv_currkey->base, cs_data->reorg_restart_key, tkeysize);
 		gv_currkey->end = tkeysize - 1;
 		dest_blk_id = cs_data->reorg_restart_block;
 		SET_GV_ALTKEY_TO_GBLNAME_FROM_GV_CURRKEY;
 		altkeylen = gv_altkey->end - 1;
- 		if (altkeylen && (altkeylen == gn->str.len) && (0 == memcmp(gv_altkey->base, gn->str.addr, gn->str.len)))
+ 		if (altkeylen && (altkeylen == gn->len) && (0 == memcmp(gv_altkey->base, gn->addr, gn->len)))
 			/* Going to resume from current global, so it resumed and make it false */
 			*resume = FALSE;
 	} else
-	{
-		/* start from the left most leaf */
-		memcpy(&gv_currkey->base[0], gn->str.addr, gn->str.len);
-		gv_currkey->base[gn->str.len] = gv_currkey->base[gn->str.len + 1] = 0;
-		gv_currkey->end = gn->str.len + 1;
+	{	/* start from the left most leaf */
+		memcpy(&gv_currkey->base[0], gn->addr, gn->len);
+		gv_currkey->base[gn->len] = gv_currkey->base[gn->len + 1] = 0;
+		gv_currkey->end = gn->len + 1;
 	}
 	if (*resume)
 	{
 		util_out_print("REORG cannot be resumed from this point, Skipping this global...", FLUSH);
-		memcpy(&gv_currkey->base[0], gn->str.addr, gn->str.len);
-		gv_currkey->base[gn->str.len] = gv_currkey->base[gn->str.len + 1] = 0;
-		gv_currkey->end = gn->str.len + 1;
+		memcpy(&gv_currkey->base[0], gn->addr, gn->len);
+		gv_currkey->base[gn->len] = gv_currkey->base[gn->len + 1] = 0;
+		gv_currkey->end = gn->len + 1;
 		return TRUE;
 	}
  	memcpy(&gv_currkey_next_reorg->base[0], &gv_currkey->base[0], gv_currkey->end + 1);
@@ -320,7 +296,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 	/* --- more detailed debugging information --- */
 	if (detailed_log = reorg_op & DETAIL)
 		util_out_print("STARTING to work on global ^!AD from region !AD", TRUE,
-			gn->str.len, gn->str.addr, REG_LEN_STR(gv_cur_region));
+			gn->len, gn->addr, REG_LEN_STR(gv_cur_region));
 
 	/* In each iteration of MAIN loop, a working block is processed for a GVT */
 	for (; ;)	/* ================ START MAIN LOOP ================ */
@@ -375,8 +351,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 					status = mu_split(level, i_max_fill, d_max_fill, &cnt1, &cnt2);
 					if (cdb_sc_maxlvl == status)
 					{
-						gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_MAXBTLEVEL, 2, gn->str.len,
-								gn->str.addr);
+						gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_MAXBTLEVEL, 2, gn->len, gn->addr);
 						reorg_finish(dest_blk_id, blks_processed, blks_killed, blks_reused,
 							file_extended, lvls_reduced, blks_coalesced, blks_split, blks_swapped);
 						return FALSE;
@@ -387,7 +362,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 						{
 							need_kip_incr = FALSE;
 							assert(NULL == kip_csa);
-							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 							continue;
 						}
 						if (detailed_log)
@@ -450,7 +425,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 						{
 							need_kip_incr = FALSE;
 							assert(NULL == kip_csa);
-							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 							if (level)
 							{	/* reinitialize level member in rtsib_hist srch_blk_status' */
 								for (count = 0; count < MAX_BT_DEPTH; count++)
@@ -520,7 +495,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 						{
 							need_kip_incr = FALSE;
 							assert(NULL == kip_csa);
-							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 							inctn_opcode = inctn_mu_reorg;	/* reset inctn_opcode to its default */
 							update_trans = UPDTRNS_DB_UPDATED_MASK;/* reset update_trans to old value */
 							continue;
@@ -543,7 +518,6 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 			}/* === SPLIT-COALESCE LOOP END === */
 			t_abort(gv_cur_region, cs_addrs);	/* do crit and other cleanup */
 		}/* === START WHILE COMPLETE_MERGE === */
-
 		if (mu_ctrlc_occurred || mu_ctrly_occurred)
 		{
 			SAVE_REORG_RESTART;
@@ -567,8 +541,9 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
                                 }
 				if (gv_target->hist.depth <= level)
 					break;
-				/* swap working block with appropriate dest_blk_id block.
-				   Historys are sent as gv_target->hist and reorg_gv_target->hist */
+				/* Swap working block with appropriate dest_blk_id block.
+				 * Histories are sent as gv_target->hist and reorg_gv_target->hist.
+				 */
 				mu_reorg_in_swap_blk = TRUE;
 				status = mu_swap_blk(level, &dest_blk_id, &kill_set_list, exclude_glist_ptr);
 				mu_reorg_in_swap_blk = FALSE;
@@ -596,7 +571,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 						{
 							need_kip_incr = FALSE;
 							assert(NULL == kip_csa);
-							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+							UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 							DECR_BLK_NUM(dest_blk_id);
 							continue;
 						}
@@ -620,7 +595,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 					{
 						need_kip_incr = FALSE;
 						assert(NULL == kip_csa);
-						UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+						UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 						DECR_BLK_NUM(dest_blk_id);
 						continue;
 					}
@@ -660,9 +635,9 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 	}		/* ================ END MAIN LOOP ================ */
 
 	/* =========== START REDUCE LEVEL ============== */
-	memcpy(&gv_currkey->base[0], gn->str.addr, gn->str.len);
-	gv_currkey->base[gn->str.len] = gv_currkey->base[gn->str.len + 1] = 0;
-	gv_currkey->end = gn->str.len + 1;
+	memcpy(&gv_currkey->base[0], gn->addr, gn->len);
+	gv_currkey->base[gn->len] = gv_currkey->base[gn->len + 1] = 0;
+	gv_currkey->end = gn->len + 1;
 	for (;;)	/* Reduce level continues until it fails to reduce */
 	{
 		t_begin(ERR_MUREORGFAIL, UPDTRNS_DB_UPDATED_MASK);
@@ -698,7 +673,7 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 				{
 					need_kip_incr = FALSE;
 					assert(NULL == kip_csa);
-					UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries));
+					UNIX_ONLY(ABORT_TRANS_IF_GBL_EXIST_NOMORE_AND_RETURN(lcl_t_tries, gn));
 					continue;
 				}
 				if (detailed_log)
@@ -721,11 +696,9 @@ boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume, int in
 			break;
 	}
 	/* =========== END REDUCE LEVEL ===========*/
-
 	reorg_finish(dest_blk_id, blks_processed, blks_killed, blks_reused,
-		file_extended, lvls_reduced, blks_coalesced, blks_split, blks_swapped);
+			file_extended, lvls_reduced, blks_coalesced, blks_split, blks_swapped);
 	return TRUE;
-
 } /* end mu_reorg() */
 
 /**********************************************
@@ -750,11 +723,8 @@ void reorg_finish(block_id dest_blk_id, int blks_processed, int blks_killed,
 		util_out_print("Levels Eliminated   : !SL ", FLUSH, lvls_reduced);
 	util_out_print("Blocks extended     : !SL ", FLUSH, file_extended);
 	cs_addrs->reorg_last_dest = dest_blk_id;
-
 	/* next attempt for this global will start from the beginning, if RESUME option is present */
 	cs_data->reorg_restart_block = 0;
 	cs_data->reorg_restart_key[0] = 0;
 	cs_data->reorg_restart_key[1] = 0;
 }
-
-/* end of program */
diff --git a/sr_port/mu_reorg_upgrd_dwngrd.c b/sr_port/mu_reorg_upgrd_dwngrd.c
index d249306..5f6f56c 100644
--- a/sr_port/mu_reorg_upgrd_dwngrd.c
+++ b/sr_port/mu_reorg_upgrd_dwngrd.c
@@ -174,9 +174,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 		util_out_print("!/MUPIP REORG !AD cannot proceed with above errors!/", TRUE, LEN_AND_STR(command));
 		mupip_exit(ERR_MUNOACTION);
 	}
-	GVKEYSIZE_INCREASE_IF_NEEDED(DBKEYSIZE(MAX_KEY_SZ)); /* Keep gv_currkey/gv_altkey in sync with respect to gv_keysize
-							      * (now MAX_KEY_SZ) */
-	assert(DBKEYSIZE(MAX_KEY_SZ) == gv_keysize);
+	assert(DBKEYSIZE(MAX_KEY_SZ) == gv_keysize);	/* no need to invoke GVKEYSIZE_INIT_IF_NEEDED macro */
 	gv_target = targ_alloc(gv_keysize, NULL, NULL);	/* t_begin needs this initialized */
 	gv_target_list = NULL;
 	memset(&alt_hist, 0, SIZEOF(alt_hist));	/* null-initialize history */
@@ -200,7 +198,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 		 * the database setting prevails. therefore, the access method check can be done only after opening
 		 * the database (i.e. after the gvcst_init)
 		 */
-		if (dba_bg != reg->dyn.addr->acc_meth)
+		if (dba_bg != REG_ACC_METH(reg))
 		{
 			util_out_print("Region !AD : MUPIP REORG !AD cannot continue as access method is not BG",
 				TRUE, REG_LEN_STR(reg), LEN_AND_STR(command));
@@ -218,7 +216,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 		blk_size = csd->blk_size;	/* "blk_size" is used by the BLK_FINI macro */
 		if (reg->read_only)
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(reg));
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(reg));
 			status = ERR_MUNOFINISH;
 			continue;
 		}
@@ -291,7 +289,8 @@ void	mu_reorg_upgrd_dwngrd(void)
 		if (!wcs_flu(WCSFLU_FLUSH_HDR))	/* wcs_flu assumes gv_cur_region is set (which it is in this routine) */
 		{
 			rel_crit(reg);
-			gtm_putmsg(VARLSTCNT(6) ERR_BUFFLUFAILED, 4, LEN_AND_LIT("MUPIP REORG UPGRADE/DOWNGRADE"), DB_LEN_STR(reg));
+			gtm_putmsg_csa(CSA_ARG(csa)
+				VARLSTCNT(6) ERR_BUFFLUFAILED, 4, LEN_AND_LIT("MUPIP REORG UPGRADE/DOWNGRADE"), DB_LEN_STR(reg));
 			status = ERR_MUNOFINISH;
 			continue;
 		}
@@ -351,7 +350,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 			}
 			bml_sm_buff = t_qread(curbmp, (sm_int_ptr_t)&cycle, &cr); /* now that in crit, note down stable buffer */
 			if (NULL == bml_sm_buff)
-				rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
+				rts_error_csa(CSA_ARG(csa) VARLSTCNT(1) ERR_DSEBLKRDFAIL);
 			ondsk_blkver = cr->ondsk_blkver;	/* note down db fmt on disk for bitmap block */
 			/* Take a copy of the shared memory bitmap buffer into process-private memory before releasing crit.
 			 * We are interested in those blocks that are currently marked as USED in the bitmap.
@@ -418,7 +417,8 @@ void	mu_reorg_upgrd_dwngrd(void)
 								ondsk_blkver = new_db_format;
 							} else
 							{
-								gtm_putmsg(VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(reg), status1);
+								gtm_putmsg_csa(CSA_ARG(csa)
+									VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(reg), status1);
 								util_out_print("Region !AD : Error occurred while reading block "
 									"[0x!XL]", TRUE, REG_LEN_STR(reg), curblk);
 								status1 = ERR_MUNOFINISH;
@@ -671,7 +671,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 			/* flush all changes noted down in the file-header */
 			if (!wcs_flu(WCSFLU_FLUSH_HDR))	/* wcs_flu assumes gv_cur_region is set (which it is in this routine) */
 			{
-				gtm_putmsg(VARLSTCNT(6) ERR_BUFFLUFAILED, 4,
+				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_BUFFLUFAILED, 4,
 					LEN_AND_LIT("MUPIP REORG UPGRADE/DOWNGRADE"), DB_LEN_STR(reg));
 				status = ERR_MUNOFINISH;
 				rel_crit(reg);
@@ -698,7 +698,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 			TRUE, REG_LEN_STR(reg), reorg_stats.blks_converted_nonbmp);
 		if (reorg_entiredb && (SS_NORMAL == status1) && (0 != blocks_left))
 		{	/* file-header counter does not match what reorg on the entire database expected to see */
-			gtm_putmsg(VARLSTCNT(4) ERR_DBBTUWRNG, 2, expected_blks2upgrd, actual_blks2upgrd);
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBBTUWRNG, 2, expected_blks2upgrd, actual_blks2upgrd);
 			util_out_print("Region !AD : Run MUPIP INTEG (without FAST qualifier) to fix the counter",
 				TRUE, REG_LEN_STR(reg));
 			status1 = ERR_MUNOFINISH;
@@ -712,7 +712,8 @@ void	mu_reorg_upgrd_dwngrd(void)
 			if (set_fully_upgraded)
 				util_out_print("Region !AD : Database is now FULLY UPGRADED", TRUE, REG_LEN_STR(reg));
 			util_out_print("Region !AD : MUPIP REORG !AD finished!/", TRUE, REG_LEN_STR(reg), LEN_AND_STR(command));
-			send_msg(VARLSTCNT(7) ERR_MUREUPDWNGRDEND, 5, REG_LEN_STR(reg), process_id, process_id, &curr_tn);
+			send_msg_csa(CSA_ARG(csa) VARLSTCNT(7) ERR_MUREUPDWNGRDEND, 5, REG_LEN_STR(reg),
+										process_id, process_id, &curr_tn);
 		} else
 		{
 			assert(ERR_MUNOFINISH == status1);
@@ -728,7 +729,7 @@ void	mu_reorg_upgrd_dwngrd(void)
 		free(bml_lcl_buff);
 	if (mu_ctrly_occurred || mu_ctrlc_occurred)
 	{
-		gtm_putmsg(VARLSTCNT(1) ERR_REORGCTRLY);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REORGCTRLY);
 		status = ERR_MUNOFINISH;
 	}
 	mupip_exit(status);
diff --git a/sr_port/mu_swap_blk.c b/sr_port/mu_swap_blk.c
index c71b358..fd80d81 100644
--- a/sr_port/mu_swap_blk.c
+++ b/sr_port/mu_swap_blk.c
@@ -594,7 +594,7 @@ enum cdb_sc mu_swap_blk(int level, block_id *pdest_blk_id, kill_set *kill_set_pt
 }
 
 /***************************************************************
-Checks if a key is present in exclude global lists.
+Checks if an input global name is present in exclude global lists.
 	curr_key_ptr = Key pointer
 	key_len = curr_key_ptr length excludeing nulls
 	exclude_glist_ptr = list of globals in -EXCLUDE option
@@ -608,7 +608,8 @@ boolean_t in_exclude_list(unsigned char *curr_key_ptr, int key_len, glist *exclu
 
 	for (gl_ptr = exclude_glist_ptr->next; gl_ptr; gl_ptr = gl_ptr->next)
 	{
-		if (gl_ptr->name.str.len == key_len && 0 == memcmp(gl_ptr->name.str.addr, curr_key_ptr, gl_ptr->name.str.len))
+		if ((GNAME(gl_ptr).len == key_len)
+				&& (0 == memcmp(GNAME(gl_ptr).addr, curr_key_ptr, key_len)))
 			return TRUE;
 	}
 	return FALSE;
diff --git a/sr_port/mucregini.c b/sr_port/mucregini.c
index af74e34..5d3e825 100644
--- a/sr_port/mucregini.c
+++ b/sr_port/mucregini.c
@@ -53,6 +53,7 @@ error_def(ERR_COLLTYPVERSION);
 error_def(ERR_DBFILERR);
 error_def(ERR_FILEPARSE);
 error_def(ERR_GVIS);
+error_def(ERR_JNLALLOCGROW);
 error_def(ERR_MUNOACTION);
 error_def(ERR_TEXT);
 
@@ -62,7 +63,7 @@ void mucregini(int4 blk_init_size)
 	int4			i;
 	th_index_ptr_t 		th;
 	collseq			*csp;
-	uint4			ustatus;
+	uint4			ustatus, reg_autoswitch;
 	mstr 			jnlfile, jnldef, tmpjnlfile;
 	time_t			ctime;
 
@@ -95,7 +96,6 @@ void mucregini(int4 blk_init_size)
 		cs_data->lock_space_size = gv_cur_region->dyn.addr->lock_space * OS_PAGELET_SIZE;
 	else
 		cs_data->lock_space_size = DEF_LOCK_SIZE;
-	NUM_CRIT_ENTRY(cs_data) = DEFAULT_NUM_CRIT_ENTRY;
 	cs_data->staleness[0] = -300000000;	/* staleness timer = 30 seconds */
 	cs_data->staleness[1] = -1;
 	cs_data->ccp_quantum_interval[0] = -20000000;	/* 2 sec */
@@ -120,15 +120,29 @@ void mucregini(int4 blk_init_size)
 #ifdef UNIX
 	if (JNL_ALLOWED(cs_data))
 	{
-		if (cs_data->jnl_alq + cs_data->jnl_deq > gv_cur_region->jnl_autoswitchlimit)
+		reg_autoswitch = gv_cur_region->jnl_autoswitchlimit;
+		if (cs_data->jnl_alq + cs_data->jnl_deq > reg_autoswitch)
 		{
-			cs_data->autoswitchlimit = gv_cur_region->jnl_autoswitchlimit;
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_JNLALLOCGROW, 6, cs_data->jnl_alq,
+					gv_cur_region->jnl_autoswitchlimit, "database file", DB_LEN_STR(gv_cur_region));
+			cs_data->autoswitchlimit = reg_autoswitch;
 			cs_data->jnl_alq = cs_data->autoswitchlimit;
 		} else
-			cs_data->autoswitchlimit = ALIGNED_ROUND_DOWN(gv_cur_region->jnl_autoswitchlimit,
-							cs_data->jnl_alq, cs_data->jnl_deq);
-	}
-	else
+		{
+			cs_data->autoswitchlimit = ALIGNED_ROUND_DOWN(reg_autoswitch, cs_data->jnl_alq, cs_data->jnl_deq);
+			/* If rounding down took us to less than the minimum autoswitch, then bump allocation to be
+			 * equal to the pre-round-down autoswitchlimit this way all values are above their respective
+			 * minimums. Note that the extension can be an arbitrary value because alloc == autoswitch.
+			 */
+			if (JNL_AUTOSWITCHLIMIT_MIN > cs_data->autoswitchlimit)
+			{
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_JNLALLOCGROW, 6, cs_data->jnl_alq,
+						reg_autoswitch, "database file", DB_LEN_STR(gv_cur_region));
+				cs_data->jnl_alq = reg_autoswitch;
+				cs_data->autoswitchlimit = reg_autoswitch;
+			}
+		}
+	} else
 		cs_data->autoswitchlimit = 0;
 	assert(!(MAX_IO_BLOCK_SIZE % DISK_BLOCK_SIZE));
 	if (cs_data->jnl_alq + cs_data->jnl_deq > cs_data->autoswitchlimit)
@@ -154,12 +168,13 @@ void mucregini(int4 blk_init_size)
 			cs_data->def_coll_ver = (csp->version)(cs_data->def_coll);
 			if (!do_verify(csp, cs_data->def_coll, cs_data->def_coll_ver))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_COLLTYPVERSION, 2, cs_data->def_coll, cs_data->def_coll_ver);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs)
+					VARLSTCNT(4) ERR_COLLTYPVERSION, 2, cs_data->def_coll, cs_data->def_coll_ver);
 				mupip_exit(ERR_MUNOACTION);
 			}
 		} else
 		{
-			gtm_putmsg(VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, cs_data->def_coll);
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, cs_data->def_coll);
 			mupip_exit(ERR_MUNOACTION);
 		}
 	}
@@ -194,7 +209,7 @@ void mucregini(int4 blk_init_size)
 		jnldef.len = SIZEOF(JNL_EXT_DEF) - 1;
 		if (FILE_STAT_ERROR == gtm_file_stat(&jnlfile, &jnldef, &tmpjnlfile, TRUE, &ustatus))
 		{
-			gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, JNL_LEN_STR(gv_cur_region), ustatus);
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_FILEPARSE, 2, JNL_LEN_STR(gv_cur_region), ustatus);
 			mupip_exit(ERR_MUNOACTION);
 		}
 		cs_data->jnl_file_len = tmpjnlfile.len;
@@ -220,7 +235,7 @@ void mucregini(int4 blk_init_size)
 				       = (int4)ROUND_UP2(MAX_NON_BITMAP_UPDATE_ARRAY_SIZE(cs_data), UPDATE_ARRAY_ALIGN_SIZE);
 	cs_data->max_update_array_size += (int4)ROUND_UP2(MAX_BITMAP_UPDATE_ARRAY_SIZE, UPDATE_ARRAY_ALIGN_SIZE);
 	/* bt_malloc(cs_addrs) Done by db_init at file open time -- not needed here */
-	if (dba_bg == gv_cur_region->dyn.addr->acc_meth)
+	if (dba_bg == REG_ACC_METH(gv_cur_region))
 		cs_data->flush_time[0] = TIM_FLU_MOD_BG;
 	else
 		cs_data->flush_time[0] = TIM_FLU_MOD_MM;
@@ -229,6 +244,7 @@ void mucregini(int4 blk_init_size)
 	cs_data->mutex_spin_parms.mutex_hard_spin_count = MUTEX_HARD_SPIN_COUNT;
 	cs_data->mutex_spin_parms.mutex_sleep_spin_count = MUTEX_SLEEP_SPIN_COUNT;
 	cs_data->mutex_spin_parms.mutex_spin_sleep_mask = MUTEX_SPIN_SLEEP_MASK;
+	NUM_CRIT_ENTRY(cs_data) = gv_cur_region->dyn.addr->mutex_slots;
 	cs_data->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT;
 	time(&ctime);
 	assert(SIZEOF(ctime) >= SIZEOF(int4));
@@ -236,11 +252,11 @@ void mucregini(int4 blk_init_size)
 	cs_addrs->bmm = MM_ADDR(cs_data);
 	bmm_init();
 	for (i = 0; i < blk_init_size ; i += cs_data->bplmap)
-	{	status = bml_init(i);
+	{
+		status = bml_init(i);
 		if (status != SS_NORMAL)
 		{
-			gtm_putmsg(VARLSTCNT(5) ERR_DBFILERR, 2, gv_cur_region->dyn.addr->fname_len,
-					gv_cur_region->dyn.addr->fname, status);
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), status);
 			mupip_exit(ERR_MUNOACTION);
 		}
 	}
diff --git a/sr_port/muextr.h b/sr_port/muextr.h
index 33f0287..dac85c5 100644
--- a/sr_port/muextr.h
+++ b/sr_port/muextr.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,11 +11,58 @@
 
 typedef	struct glist_struct
 {
-	struct glist_struct *next;
-	mval name;
-	unsigned char nbuf[1]; /* dummy entry */
+	struct glist_struct	*next;
+	gd_region		*reg;
+	gv_namehead		*gvt;
+	gvnh_reg_t		*gvnh_reg;
 } glist;
 
+#define GNAME(GLIST)	((GLIST)->gvt->gvname.var_name)
+
+#define	DO_ROOT_SEARCH_FALSE	FALSE
+#define	DO_ROOT_SEARCH_TRUE	TRUE
+
+#define	RECORDSTAT_REGION_LIT		" (region "
+#define	RECORDSTAT_REGION_LITLEN	STR_LIT_LEN(RECORDSTAT_REGION_LIT)
+
+#define	PRINT_REG_FALSE		FALSE
+#define	PRINT_REG_TRUE		TRUE
+
+#define	ISSUE_RECORDSTAT_MSG(GL_PTR, GBLSTAT, PRINT_REG)						\
+{													\
+	char	gbl_name_buff[MAX_MIDENT_LEN + 2 + RECORDSTAT_REGION_LITLEN + MAX_RN_LEN + 1];		\
+					/* 2 for null and '^', MAX_RN_LEN for region name,		\
+					 * RECORDSTAT_REGION_LITLEN for " (region " and 1 for ")" */	\
+	int	gbl_buff_index;										\
+													\
+	gbl_name_buff[0]='^';										\
+	memcpy(&gbl_name_buff[1], GNAME(GL_PTR).addr, GNAME(GL_PTR).len);				\
+	gbl_buff_index = 1 + GNAME(GL_PTR).len;								\
+	if (PRINT_REG && (NULL != GL_PTR->gvnh_reg->gvspan))						\
+	{												\
+		MEMCPY_LIT(&gbl_name_buff[gbl_buff_index], RECORDSTAT_REGION_LIT);			\
+		gbl_buff_index += RECORDSTAT_REGION_LITLEN;						\
+		memcpy(&gbl_name_buff[gbl_buff_index], gl_ptr->reg->rname, gl_ptr->reg->rname_len);	\
+		gbl_buff_index += gl_ptr->reg->rname_len;						\
+		gbl_name_buff[gbl_buff_index++] = ')';							\
+	}												\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6, gbl_buff_index, gbl_name_buff,	\
+		GBLSTAT.recknt, GBLSTAT.keylen, GBLSTAT.datalen, GBLSTAT.reclen);			\
+}
+
+#define	DO_OP_GVNAME(GL_PTR)								\
+{											\
+	GBLREF	gv_namehead		*gv_target;					\
+	GBLREF	gd_region		*gv_cur_region;					\
+											\
+	gv_target = GL_PTR->gvt;							\
+	gv_cur_region = GL_PTR->reg;							\
+	change_reg();									\
+	assert((NULL != gv_target) && (DIR_ROOT != gv_target->root));			\
+	SET_GV_CURRKEY_FROM_GVT(gv_target);	/* needed by gvcst_root_search */	\
+	GVCST_ROOT_SEARCH;								\
+}
+
 typedef struct
 {
 	int recknt;
@@ -24,6 +71,22 @@ typedef struct
 	int datalen;
 } mu_extr_stats;
 
+#define	MU_EXTR_STATS_INIT(TOT)					\
+{								\
+	TOT.recknt = TOT.reclen = TOT.keylen = TOT.datalen = 0;	\
+}
+
+#define	MU_EXTR_STATS_ADD(DST, SRC)		\
+{						\
+	DST.recknt += SRC.recknt;		\
+	if (DST.reclen < SRC.reclen)		\
+		DST.reclen = SRC.reclen;	\
+	if (DST.keylen < SRC.keylen)		\
+		DST.keylen = SRC.keylen;	\
+	if (DST.datalen < SRC.datalen)		\
+		DST.datalen = SRC.datalen;	\
+}
+
 typedef struct coll_hdr_struct
 {
 	unsigned char	act;
@@ -32,19 +95,6 @@ typedef struct coll_hdr_struct
 	unsigned char	pad;
 } coll_hdr;
 
-#ifdef GTM_CRYPT
-/* The following structure is used by mupip extract/load to store the hash of all the extracted dat files. These hashes will be
- * stored right after the extract header is written. Each hash  will be referred by it's index number at the beginning of each
- * record. This information will be used during mupip load to decrypt a particular record. Although the structure contains only
- * one field, we need to access the hashes by index. */
-typedef struct muextr_hash_hdr_struct
-{
-	char	gtmcrypt_hash[GTMCRYPT_HASH_LEN];
-} muext_hash_hdr;
-
-typedef muext_hash_hdr	*muext_hash_hdr_ptr_t;
-#endif
-
 #define MU_FMT_GO		0
 #define MU_FMT_BINARY		1
 #define MU_FMT_GOQ		2
@@ -92,43 +142,58 @@ typedef muext_hash_hdr	*muext_hash_hdr_ptr_t;
 
 char *mu_extr_ident(mstr *a);
 void  mu_extract(void);
-int mu_extr_getblk(unsigned char *ptr);		/***type int added***/
-#if defined(UNIX) && defined(GTM_CRYPT)
-boolean_t mu_extr_gblout(mval *gn, mu_extr_stats *st, int format, muext_hash_hdr_ptr_t hash_array,
-									boolean_t is_any_file_encrypted);
+int mu_extr_getblk(unsigned char *ptr, unsigned char *encrypted_buff_ptr);
+#if defined(GTM_CRYPT)
+boolean_t mu_extr_gblout(glist *gl_ptr, mu_extr_stats *st, int format, boolean_t is_any_file_encrypted);
 #elif defined(UNIX)
-boolean_t mu_extr_gblout(mval *gn, mu_extr_stats *st, int format);
+boolean_t mu_extr_gblout(glist *gl_ptr, mu_extr_stats *st, int format);
+#else	/* VMS */
+boolean_t mu_extr_gblout(glist *gl_ptr, struct RAB *outrab, mu_extr_stats *st, int format);
 #endif
+
 #ifdef UNIX
-#define WRITE_BIN_EXTR_BLK(BUFF, BSIZE)		\
-{						\
-	GBLREF	io_pair		io_curr_device;	\
-	mval	val;				\
-	val.mvtype = MV_STR;			\
-	val.str.addr = (char *)(&BSIZE);	\
-	val.str.len = SIZEOF(BSIZE);		\
-	op_write(&val);				\
-	val.mvtype = MV_STR;			\
-	val.str.addr = (char *)(BUFF);		\
-	val.str.len = BSIZE;			\
-	op_write(&val);				\
-	io_curr_device.out->dollar.x = 0;	\
-	io_curr_device.out->dollar.y = 0;	\
+#define WRITE_BIN_EXTR_BLK(BUFF, BSIZE, WRITE_4MORE_BYTES, CRYPT_INDEX)		\
+{										\
+	GBLREF	io_pair		io_curr_device;					\
+	mval			val;						\
+	unsigned short		total_size;					\
+										\
+	total_size = BSIZE + ((WRITE_4MORE_BYTES) ? SIZEOF(CRYPT_INDEX) : 0);	\
+	/* Write the cummulative size of the subsequent 2 op_write()s */	\
+	val.mvtype = MV_STR;							\
+	val.str.addr = (char *)(&total_size);					\
+	val.str.len = SIZEOF(total_size);					\
+	op_write(&val);								\
+	if ((WRITE_4MORE_BYTES))						\
+	{									\
+		val.mvtype = MV_STR;						\
+		val.str.addr = (char *)(&CRYPT_INDEX);				\
+		val.str.len = SIZEOF(CRYPT_INDEX);				\
+		op_write(&val);							\
+	}									\
+	/* Write the actual block */						\
+	val.mvtype = MV_STR;							\
+	val.str.addr = (char *)(BUFF);						\
+	val.str.len = BSIZE;							\
+	op_write(&val);								\
+	io_curr_device.out->dollar.x = 0;					\
+	io_curr_device.out->dollar.y = 0;					\
 }
-#define WRITE_EXTR_LINE(BUFF, BSIZE)		\
-{						\
-	mval	val;				\
-	val.mvtype = MV_STR;			\
-	val.str.addr = (char *)(BUFF);		\
-	val.str.len = BSIZE;			\
-	op_write(&val);				\
-	op_wteol(1);				\
+#define WRITE_EXTR_LINE(BUFF, BSIZE)						\
+{										\
+	mval	val;								\
+	val.mvtype = MV_STR;							\
+	val.str.addr = (char *)(BUFF);						\
+	val.str.len = BSIZE;							\
+	op_write(&val);								\
+	op_wteol(1);								\
 }
 #elif defined(VMS)
-#define WRITE_BIN_EXTR_BLK(PTR, SIZE) 						\
+#define WRITE_BIN_EXTR_BLK(PTR, SIZE, DUMMY1, DUMMY2) 				\
 {										\
 	unsigned short size;							\
 	int status;								\
+										\
 	if (MAX_BIN_WRT < (SIZE))						\
 		size = MAX_BIN_WRT;						\
 	else									\
@@ -146,23 +211,18 @@ boolean_t mu_extr_gblout(mval *gn, mu_extr_stats *st, int format);
 	}									\
 	if (!(status & 1)) 							\
 	{									\
-		rts_error(VARLSTCNT(1) status);					\
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);		\
 		mupip_exit(status);						\
 	}									\
 }
-#define WRITE_EXTR_LINE(PTR, SIZE) 			\
-{							\
-	int status;					\
-	(outrab)->rab$l_rbf = (unsigned char *)(PTR);	\
-	(outrab)->rab$w_rsz = (SIZE);			\
-	status = sys$put((outrab));			\
-	if (status != RMS$_NORMAL)			\
-		rts_error(VARLSTCNT(1) status);		\
+#define WRITE_EXTR_LINE(PTR, SIZE)					\
+{									\
+	int status;							\
+	(outrab)->rab$l_rbf = (unsigned char *)(PTR);			\
+	(outrab)->rab$w_rsz = (SIZE);					\
+	status = sys$put((outrab));					\
+	if (status != RMS$_NORMAL)					\
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);	\
 }
-
-
-boolean_t mu_extr_gblout(mval *gn, struct RAB *outrab, mu_extr_stats *st, int format);
-#else
-#error UNSUPPORTED PLATFORM
 #endif
 
diff --git a/sr_port/mumps.hlp b/sr_port/mumps.hlp
index 3e310f9..c40d0ec 100644
--- a/sr_port/mumps.hlp
+++ b/sr_port/mumps.hlp
@@ -1,684 +1,1787 @@
-1 About_GTM
-   GT.M Version 4.4
+2 About_GT.M
+   About GT.M
 
-   UNIX Edition
+   GT.M runs on a wide variety of computer platforms. Consult FIS for the
+   current list of Supported platforms.
 
-   October 2003
+   In addition to preserving the traditional features of M, GT.M also offers
+   an optimized compiler that produces object code that does not require
+   internal interpreters during execution.
 
-   The information in this manual is subject to change without notice and
-   should not be construed as a commitment by Sanchez Computer Associates.
-   The software described in this manual is furnished under a license and
-   may be used or copied only in accordance  with  the  terms  of  such  a
-   license.
+   On all platforms, the GT.M dynamic linking mechanism activates compiled
+   objects. On some platforms, you can link the object modules into shared
+   object libraries.
 
-   Copyright 1987 - 2003
+   In keeping with the focus on creating fully compiled code, GT.M is tightly
+   integrated with the operating system environment and permits the use of
+   operating system utilities for program development.
 
-   Sanchez Computer Associates
+   GT.M also provides a full complement of M tools for creating, compiling,
+   and debugging source code. Many of these tasks are accomplished from the
+   GT.M facility called Direct Mode, which offers the look and feel of an
+   interpreted language that is familiar to the traditional M programmer.
 
-   All rights reserved
+2 Programming_Environment
+   Programming Environment
 
-   GT.M, and GT.CM are trademarks  of  Sanchez  Computer  Associates.  All
-   other company and product names may be  trademarks  of  the  respective
-   companies with which they are associated.
+   The GT.M Programming Environment is described in the following sections.
 
-1 Prog_Dev_Cycle
-   Program Development Cycle
+3 Managing_Data
+   Managing Data
 
-   In contrast to M environments that interpret M code,  GT.M  compiles  M
-   code from source files into  the  target  machine  language.  The  GT.M
-   compiler produces object files, which are dynamically  linked  into  an
-   image. Source files and object files may be managed  independently,  or
-   placed together in a specific directory. GT.M permits access to source
-   and object files in multiple directories.
+   The scope of M data is either process local or global.
 
-   GT.M databases are UNIX files identified  by  a  small  file  called  a
-   Global Directory. Global Directories allow management of  the  database
-   files to  be  independent  of  the  placement  of  files  containing  M
-   routines. By changing the  Global  Directory,  you  can  use  the  same
-   programs to access different databases.
+     * Local variables last only for the duration of the current session;
+       GT.M deletes them when the M process terminates.
+     * Global variables contain data that persists beyond the process. GT.M
+       stores global variables on disk. A Global Directory organizes global
+       variables and describes the organization of a database. The GT.M
+       administrator uses the Global Directory Editor (GDE) to create and
+       manage Global Directories. A Global Directory maps global names to a
+       database file. GT.M uses this mapping when it stores and retrieves
+       globals from the database. Several Global Directories may refer to a
+       single database file.
 
-   Program development may utilize both GT.M and UNIX  development  tools.
-   The development methodology and environment  chosen  for  a  particular
-   installation, and tailored  by  the  individual  user,  determines  the
-   actual mix of tools. These tools  may  vary  from  entirely  GT.M  with
-   little UNIX, to mostly UNIX with a modest use of GT.M.
+4 Database_Management
+   Database Management
 
-   Direct Mode serves as an interactive interface  to  the  GT.M  run-time
-   environment and the  compiler.  In  Direct  Mode,  the  user  enters  M
-   commands at the  GT.M  prompt,  and  GT.M  compiles  and  executes  the
-   command. This feature provides immediate turnaround for  rapid  program
-   development and maintenance.
+   The Global Directory Editor (GDE) creates, modifies, maintains, and
+   displays the characteristics of Global Directories. GDE also maps LOCKs on
+   resource names to the region of the database specified for the
+   corresponding global variables.
 
-        The methods described in the GT.M column assume you are already at
-        the GTM> prompt, which is also called Direct Mode. To get  to  this
-        prompt, type $gtm_dist/mumps -direct.
+   The M Peripheral Interchange Program (MUPIP) creates database files and
+   provides tools for GT.M database management and database journaling.
 
-2 Def_Env_Var
-   Defining Environment Variables
+3 Managing_Source_Code
+   Managing Source Code
 
-   GT.M requires the definition of certain environment variables  as  part
-   of setting up the environment.
+   In the GT.M programming environment, source routines are generated and
+   stored as standard UNIX files. They are created and edited with standard
+   UNIX text editors.
 
-   o    To locate the files that Sanchez Computer  Associates  provides  as
-        part of GT.M
+   GT.M is designed to work with the operating system utilities and enhances
+   them when beneficial. The following sections describe the process of
+   programming and debugging with GT.M and from the operating system.
 
-   o    To hold  some  user-controlled  information  which  GT.M  uses  for
-        run-time operation
+4 Source_File_Management
+   Source File Management
 
-   The procedure below describes how to define  an  environment  variable.
-   Use this procedure to define an  environment  variable  either  at  the
-   shell prompt or in your shell startup file. If you define the variable
-   at the shell prompt, it will be effective only until you logout. If you
-   define it in your .profile file (.cshrc, if using a C  shell  variant),
-   it will be in effect whenever you log in. Your system manager may have
-   already defined some of these variables.
+   In addition to standard M "percent" utilities, GT.M permits the use of the
+   standard UNIX file manipulation tools, for example, the diff, grep, cp,
+   and mv commands. The GT.M programmer can also use the powerful facilities
+   provided by the UNIX directory structure, such as time and date
+   information, tree-structured directories, and file protection codes.
 
-        Each  environment  variable  required  by  GT.M  is  described  and
-        illustrated in individual sections following  the  procedure.  Only
-        gtm_dist,  and  in  some  cases  gtmgbldir,  gtm_principal  and
-        gtmroutines, are required by users who do not  perform  programming
-        activities.
+   GT.M programs are compatible with most source management software, for
+   example, RCS and SCCS.
 
-   To define an environment variable type the following commands:
+4 Program_Debug
+   Program Debug
 
-$ env_variable=env_variable_value
-$ export env_variable
-   The following environment variables hold  information  that  determines
-   some details of GT.M  run-time  operation,  over  which  the  user  has
-   control.
+   The GT.M programmer can use any UNIX text editor to create M source files.
+   If you generate a program from within the Direct Mode, it also accesses
+   the UNIX text editor specified by the environment variable EDITOR and
+   provides additional capabilities to automate and enhance the process.
 
-3 gtm_dist
-   gtm_dist
+   The GT.M programmer also uses the Direct Mode facility to interactively
+   debug, modify, and execute M routines. In Direct Mode, GT.M executes each
+   M command immediately, as if it had been in-line at the point where GT.M
+   initiated Direct Mode.
 
-   gtm_dist is used to  establish  the  location  of  the  installed  GT.M
-   program and support files.
+   The following is a list of additional enhancements available from the
+   Direct Mode:
 
-   The syntax for gtm_dist is as follows:
-
-
-   $ gtm_dist=<GT.M-distribution-directory>
-
-   The standard installation places these files in /gtm/bin.
-
-   Example:
-
-
-   $ gtm_dist=/usr/staff/smith/GTM.dist
-
-   $ export gtm_dist
+5 GT.M_Compiler
+   GT.M Compiler
+
+   The GT.M compiler operates on source files to produce object files
+   consisting of position-independent, native object code, which on some
+   platforms can be linked into shared object libraries. GT.M provides syntax
+   error checking at compile-time and allows you to enable or disable the
+   compile-as-written mode. By default, GT.M produces an object file even if
+   the compiler detects errors in the source code. This compile-as-written
+   mode facilitates a flexible approach to debugging.
+
+4 The_Run-Time_System
+   The Run-Time System
+
+   A GT.M programmer can execute an M routine from the shell or
+   interactively, using the M commands from Direct Mode.
+
+   The run-time system executes compile-as-written code as long as it does
+   not encounter the compile-time errors. If it detects an error, the
+   run-time system suspends execution of a routine immediately and transfers
+   control to Direct Mode or to a user-written error routine.
+
+4 Error_Processing
+   Error Processing
+
+   The GT.M compiler detects and reports syntax errors at the following
+   times:
+
+     * Compile-time - while producing the object module from a source file
+     * Run-time - while compiling code for M indirection and XECUTEs
+     * Run-time - when the user is working in Direct Mode.
+
+   The compile-time error message format displays the line containing the
+   error and the location of the error on the line. The error message also
+   indicates what was incorrect about the M statement.
+
+   GT.M can not detect certain types of errors associated with indirection,
+   the functioning of I/O devices, and program logic until run-time.
+
+   The compile-as-written feature allows compilation to continue and produces
+   an object module despite errors in the code. This permits testing of other
+   pathways through the code. The errors are reported at run-time, when GT.M
+   encounters them in the execution path.
+
+   The GT.M run-time system recognizes execution errors and reports them when
+   they occur. It also reports errors flagged by the compiler when they occur
+   in the execution path.
+
+2 Copyright
+   Copyright
+
+   Copyright 1987 - 2003, 2013
+
+   Fidelity Information Services, Inc. All rights reserved.
+
+   Permission is granted to copy, distribute and/or modify this document
+   under the terms of the GNU Free Documentation License, Version 1.3 or any
+   later version published by the Free Software Foundation; with no Invariant
+   Sections, no Front-Cover Texts and no Back-Cover Texts.
+
+   GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
+   trademarks are the property of their respective owners.
+
+   This document contains a description of GT.M and the operating
+   instructions pertaining to the various functions that comprise the system.
+   This document does not contain any commitment of FIS. FIS believes the
+   information in this publication is accurate as of its publication date;
+   such information is subject to change without notice. FIS is not
+   responsible for any errors or defects.
+
+1 Language_Extensions
+   Language Extensions
+
+   In addition to providing all of the ANSI standard M features, GT.M offers
+   a number of language extensions. In this chapter, the language extensions
+   are grouped by intended function to demonstrate their relationships to
+   each other and to the programming process. A summary table is provided in
+   each section.
+
+   The following sections describe the GT.M language extensions listed below:
+
+     * UNIX interface facilities
+     * Debugging tools
+     * Exception-handling extensions
+     * Journaling extensions
+     * Extensions providing additional capability
+     * Device Handling Extensions
+     * Alias Variables Extensions
+     * Extensions for Unicode Support
+
+2 _Interface_Facilities
+    Interface Facilities
+
+   To improve efficiency and reduce duplication and inconsistency, GT.M is
+   closely integrated with the host operating system environment. With GT.M
+   you can gain access to the operating system facilities to examine:
+
+     * System information, such as quotas and SIDs
+     * Jobs and processes
+     * Directories and files
+     * Devices
+     * Messages
+     * Privileges
+
+   The following table summarizes the GT.M operating system interface
+   facilities.
+
+   +------------------------------------------------------------------------+
+   |                 Operating System Interface Facilities                  |
+   |------------------------------------------------------------------------|
+   |  EXTENSION  |                       EXPLANATION                        |
+   |-------------+----------------------------------------------------------|
+   | ZSYstem     | Provides access to the shell.                            |
+   |-------------+----------------------------------------------------------|
+   | $ZMessage() | Translates an error condition code into text form.       |
+   |-------------+----------------------------------------------------------|
+   | $ZCMdline   | Contains a string value specifying the "excess" portion  |
+   |             | of the command line that invoked the GT.M process.       |
+   |-------------+----------------------------------------------------------|
+   | $ZJob       | Holds the pid of the process created by the last JOB     |
+   |             | command performed by the current process.                |
+   |-------------+----------------------------------------------------------|
+   | $ZPARSE()   | Parses a UNIX filename.                                  |
+   |-------------+----------------------------------------------------------|
+   | $ZSEARCH()  | Searches for one or more UNIX files.                     |
+   |-------------+----------------------------------------------------------|
+   | $ZSYstem    | Contains the status code of the last ZSYSTEM.            |
+   |-------------+----------------------------------------------------------|
+   | $ZTRNLNM()  | Translates an environment variable.                      |
+   |-------------+----------------------------------------------------------|
+   | $ZDIRectory | Contains current working directory.                      |
+   +------------------------------------------------------------------------+
+
+2 Debugging_Facilities
+   Debugging Facilities
+
+   GT.M provides a number of debugging features. These features include the
+   ability to:
+
+     * Interactively execute routines using M commands.
+     * Display lines that may contain errors using the ZPRINT command and the
+       $ZPOSITION special variable.
+     * Redisplay error messages using the $ZSTATUS special variable and the
+       ZMESSAGE command.
+     * Set breakpoints and actions to bypass an error using the ZBREAK
+       command.
+     * Execute a line at a time using the ZSTEP command.
+     * Display information about the M environment using the ZSHOW command.
+     * Modify the invocation stack with QUIT and ZGOTO.
+     * Incrementally add or modify code using the ZLINK and ZEDIT commands.
+     * Continue execution using the ZCONTINUE command.
+     * Establish "watch points" with triggers to trap incorrect accesses on
+       global variable updates.
+
+   The following table summarizes the GT.M language extensions that
+   facilitate debugging.
+
+   +------------------------------------------------------------------------+
+   |                          GT.M Debugging Tools                          |
+   |------------------------------------------------------------------------|
+   |  EXTENSION  |                       EXPLANATION                        |
+   |-------------+----------------------------------------------------------|
+   | ZBreak      | Establishes a temporary breakpoint, with optional M      |
+   |             | action and/or activation count.                          |
+   |-------------+----------------------------------------------------------|
+   | ZContinue   | Continues routine execution from a break.                |
+   |-------------+----------------------------------------------------------|
+   | ZEDit       | Invokes the UNIX text editor specified by the EDITOR     |
+   |             | environment variable.                                    |
+   |-------------+----------------------------------------------------------|
+   | ZGoto       | Removes multiple levels from the M invocation stack and  |
+   |             | transfers control.                                       |
+   |-------------+----------------------------------------------------------|
+   | ZLink       | Includes a new or modified M routine in the current M    |
+   |             | image; automatically recompiles if necessary.            |
+   |-------------+----------------------------------------------------------|
+   | ZMessage    | Signals the specified condition.                         |
+   |-------------+----------------------------------------------------------|
+   | ZPrint      | Displays lines of source code.                           |
+   |-------------+----------------------------------------------------------|
+   | ZSHow       | Displays information about the M environment.            |
+   |-------------+----------------------------------------------------------|
+   | ZSTep       | Incrementally executes a routine to the beginning of the |
+   |             | next line of the same type.                              |
+   |-------------+----------------------------------------------------------|
+   | ZWRite      | Displays all or some local or global variables.          |
+   |-------------+----------------------------------------------------------|
+   | $ZCSTATUS   | Holds the value of the status code for the last compile  |
+   |             | performed by a ZCOMPILE command.                         |
+   |-------------+----------------------------------------------------------|
+   | $ZEDit      | Contains the status code for the last ZEDit.             |
+   |-------------+----------------------------------------------------------|
+   | $ZJOBEXAM() | Performs a ZSHOW "*" to a default file location and      |
+   |             | name, or the one optionally specified by the argument.   |
+   |-------------+----------------------------------------------------------|
+   | $ZLEVel     | Contains the current level of DO/XECUTE nesting.         |
+   |-------------+----------------------------------------------------------|
+   | $ZMessage() | Translates an error condition code into text form.       |
+   |-------------+----------------------------------------------------------|
+   | $ZPOSition  | Contains a string indicating the current execution       |
+   |             | location.                                                |
+   |-------------+----------------------------------------------------------|
+   | $ZPROmpt    | Controls the symbol displayed as the direct mode prompt. |
+   |-------------+----------------------------------------------------------|
+   | $ZROutines  | Contains a string specifying a directory list containing |
+   |             | the object, and optionally the source, files.            |
+   |-------------+----------------------------------------------------------|
+   |             | Contains name of the M source program most recently      |
+   | $ZSOurce    | ZLINKed or ZEDITed; default name for next ZEDIT or       |
+   |             | ZLINK.                                                   |
+   |-------------+----------------------------------------------------------|
+   | $ZStatus    | Contains error condition code and location of the last   |
+   |             | exception condition occurring during routine execution.  |
+   |-------------+----------------------------------------------------------|
+   | $ZSTep      | Controls the default ZSTep action.                       |
+   +------------------------------------------------------------------------+
+
+2 Exception_Handling_Facilities
+   Exception Handling Facilities
+
+   The GT.M exception trapping allows you to do the following:
+
+     * DO a recovery routine and resume the original command stream.
+     * GOTO any special handling; an extended ZGOTO provides for context
+       management.
+     * Report an error and enter Direct Mode for debugging.
+     * OPEN Input/Output devices with specific traps in addition to the main
+       trap.
+     * Trap and process an exception based on a device error.
+     * Trap and process an exception based on terminal input.
+
+   The following table summarizes the GT.M language extensions that
+   facilitate exception handling.
+
+   +------------------------------------------------------------------------+
+   |                   GT.M Exception Handling Extensions                   |
+   |------------------------------------------------------------------------|
+   |  EXTENSION  |                       EXPLANATION                        |
+   |-------------+----------------------------------------------------------|
+   | ZGoto       | Removes zero or more levels from the M Invocation stack  |
+   |             | and, optionally, transfers control.                      |
+   |-------------+----------------------------------------------------------|
+   | ZMessage    | Signals the specified condition.                         |
+   |-------------+----------------------------------------------------------|
+   | $ZCSTATUS   | Holds the value of the status code for the last compile  |
+   |             | performed by a ZCOMPILE command.                         |
+   |-------------+----------------------------------------------------------|
+   | $ZEOF       | Contains indication of whether the last READ reached     |
+   |             | end-of-file.                                             |
+   |-------------+----------------------------------------------------------|
+   | $ZMessage() | Translates an error condition code into text form.       |
+   |-------------+----------------------------------------------------------|
+   | $ZLevel     | Contains current level of DO/XECUTE nesting.             |
+   |-------------+----------------------------------------------------------|
+   | $ZStatus    | Contains error condition code and location of last       |
+   |             | exception condition occurring during routine execution.  |
+   |-------------+----------------------------------------------------------|
+   | $ZSYstem    | Contains the status code of the last ZSYSTEM.            |
+   |-------------+----------------------------------------------------------|
+   | $ZTrap      | Contains an XECUTE string or entryref that GT.M invokes  |
+   |             | upon encountering an exception condition.                |
+   |-------------+----------------------------------------------------------|
+   |             | Provides a deviceparameter specifying an XECUTE string   |
+   | EXCEPTION   | or entryref that GT.M invokes upon encountering a        |
+   |             | device-related exception condition.                      |
+   +------------------------------------------------------------------------+
+
+2 Journaling_Extensions
+   Journaling Extensions
+
+   Journaling records redundant copies of database update information to
+   increase protection against loss of information due to hardware and
+   software failure. GT.M provides the M commands ZTSTART and ZTCOMMIT, to
+   mark the beginning and end of a logical transaction. When ZTSTART and
+   ZTCOMMIT fence a logical transaction, which may consist of multiple global
+   variable updates, journal records can assure recovery of incomplete
+   application transactions.
+
+   The following table summarizes the GT.M language extensions for
+   journaling.
+
+   +------------------------------------------------------------------------+
+   |                         Journaling Extensions                          |
+   |------------------------------------------------------------------------|
+   | EXTENSION |                        EXPLANATION                         |
+   |-----------+------------------------------------------------------------|
+   | View      | Extended to ensure that GT.M has transferred all updates   |
+   |           | to the journal file.                                       |
+   |-----------+------------------------------------------------------------|
+   | ZTCommit  | Marks the completion of a logical transaction.             |
+   |-----------+------------------------------------------------------------|
+   | ZTStart   | Marks the beginning of a logical transaction.              |
+   |-----------+------------------------------------------------------------|
+   | $View()   | Extended for examining journaling status.                  |
+   +------------------------------------------------------------------------+
+
+2 Alias_Variables_Extensions
+   Alias Variables Extensions
+
+   Alias variables provide a layer of abstraction between the name of a local
+   variable and an array analogous to that provided by M pass by reference in
+   routines and function calls. Multiple local variables can be aliased to
+   the same array, and a SET or KILL to one acts as a SET or KILL to all.
+   Alias container variables provide a way of associating a reference to an
+   entire local variable array with a data-cell, which protects the
+   associated array even when it's not accessible through any current local
+   variable name.
+
+   GT.M aliases provide low level facilities on which an application can
+   implement object-oriented techniques. An object can be mapped onto, and
+   stored and manipulated in an array, then saved in an alias container
+   variable whence it can be retrieved for processing. The use of appropriate
+   subscripts in the array used for a container, provides a way to organize
+   the stored objects and retrieve them by using the $ORDER() function to
+   traverse the container array. The use of alias variables to implement
+   objects provides significant efficiencies over traditional local variables
+   because alias variables and alias container variables eliminate the need
+   to execute MERGE commands to move objects.
+
+   Example:
+
+   GTM>kill A,B
+
+   GTM>set A=1,*B=A ; B & A are aliases
+
+   GTM>write B
+   1
+   GTM>
 
-   This  identifies  /usr/staff/smith/GTM.dist  as  the  location  of  the
-   installed GT.M files.
+   The following table summarizes Alias Variables extensions.
+
+   +------------------------------------------------------------------------+
+   |                  GT.M Extensions for Alias Variables                   |
+   |------------------------------------------------------------------------|
+   |      EXTENSION       |                   EXPLANATION                   |
+   |----------------------+-------------------------------------------------|
+   | Set *                | Explicitly creates an alias.                    |
+   |----------------------+-------------------------------------------------|
+   | Kill *               | Removes the association between its arguments,  |
+   |                      | and any associated arrays.                      |
+   |----------------------+-------------------------------------------------|
+   | ZWrite / ZSHow "V"   | Produces Alias Variables format output.         |
+   |----------------------+-------------------------------------------------|
+   | New                  | For the scope of the NEW, a NEW of a name       |
+   |                      | suspends its alias association.                 |
+   |----------------------+-------------------------------------------------|
+   |                      | Create a scope in which only one association    |
+   | Exclusive New        | between a name or an lvn and an array may be    |
+   |                      | visible.                                        |
+   |----------------------+-------------------------------------------------|
+   |                      | returns a unique identifier (handle) for the    |
+   | $ZAHandle()          | array associated with a name or an alias        |
+   |                      | container; for an subscripted lvn, it returns   |
+   |                      | an empty string.                                |
+   |----------------------+-------------------------------------------------|
+   |                      | Extends $DATA() to reflects the current alias   |
+   | $ZDATA()             | state of the lvn or name argument to identify   |
+   |                      | alias and alias container variables.            |
+   |----------------------+-------------------------------------------------|
+   | View and $View()     |                                                 |
+   |----------------------+-------------------------------------------------|
+   |                      | TSTART command can optionally list names whose  |
+   |                      | arrays are restored on a transaction RESTART.   |
+   | TSTART, RESTART, and | If any of these are alias variables or have     |
+   | ROLLBACK             | nodes which are alias container variables,      |
+   |                      | their associations are also restored on         |
+   |                      | transaction RESTART.                            |
+   +------------------------------------------------------------------------+
+
+3 Examples
+   Examples
+
+   Example:
+
+   $ /usr/lib/fis-gtm/V5.4-002B/gtm -run ^tprestart
+   tprestart ; Transaction restart variable association also restored on restart
+     zprint ; Print this program
+     set A="Malvern",C="Pennsylvania",E="USA"
+     set *B=C,*D(19355)=E
+     write "------------",!
+     write "Initial values & association",!
+     zwrite
+     tstart (B,D) ; On restart: A not restored, B,D restored, C,E restored by association
+     if '$TRestart Do  ; Change C,E if first time through
+     .set C="Wales",E="UK"
+     .kill *D(19355)
+     .write "------------",!
+     .write "First time through transaction; B,C,D,E changed",!
+     .zwrite
+     .set A="Brynmawr"
+     .kill *B
+     .write "------------",!
+     .write "A changed; association between B & C and D & E killed; B,D have no value",!
+     .zwrite
+     .trestart
+     else  Do  ; Show restored values on restart
+     write "------------",!
+     write "Second time through transaction; B,C,D,E & association restored",!
+     zwrite
+     tcommit ; No global updates in this transaction!
+     quit
+
+   ------------
+   Initial values & association
+   A="Malvern"
+   B="Pennsylvania" ;*
+   *C=B
+   *D(19355)=E
+   E="USA" ;*
+   ------------
+   First time through transaction; B,C,D,E changed
+   A="Malvern"
+   B="Wales" ;*
+   *C=B
+   E="UK" ;*
+   ------------
+   A changed; association between B & C and D & E killed; B,D have no value
+   A="Brynmawr"
+   C="Wales" ;*
+   E="UK" ;*
+   ------------
+   Second time through transaction; B,C,D,E & association restored
+   A="Brynmawr"
+   B="Pennsylvania" ;*
+   *C=B
+   *D(19355)=E
+   E="USA" ;*
+
+   Note that TROLLBACK does not restore alias variables:
+
+   /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^tprollback
+   tprollback ;
+     zprint ; Print this program
+     set A(1)=1,A(2)=2,A(3)=3
+     set B(1)="1b",*B(2)=A,B(3)=3 ; B includes a container for A
+     set *C(1)=B   ; C includes a container for B
+     kill *A,*B   ; C is the only way to the data
+     write "------------",!
+     write "Only containers before transaction:",!
+     zwrite
+     tstart (C)
+     if '$trestart
+     .set *D=C(1) ; D is now an alias for what used to be B
+     .set D(3)=-D(3)
+     .set *D=D(2) ; D is now an alias for what used to be A
+     .set D(1)=-D(1)
+     .kill *D  ; Kill D after is used to manipulate the arrays
+     .write "------------",!
+     .write "Changed values before restart:",!
+     .zwrite
+     .trestart
+     write "------------",!
+     write "Restored values restart:",!
+     zwrite
+     kill C ; Kill only handle to arrays
+     write "------------",!
+     write "No local arrays left:",!
+     zwrite
+     trollback  ; Rollback transaction, don't commit it
+     write "------------",!
+     write "Rollback doesnt restore names and local arrays",!
+     zwrite
+     quit
+
+   ------------
+   Only containers before transaction:
+   $ZWRTAC=""
+   *C(1)=$ZWRTAC1
+   $ZWRTAC1(1)="1b"
+   *$ZWRTAC1(2)=$ZWRTAC2
+   $ZWRTAC2(1)=1
+   $ZWRTAC2(2)=2
+   $ZWRTAC2(3)=3
+   $ZWRTAC1(3)=3
+   $ZWRTAC=""
+   ------------
+   Restored values restart:
+   $ZWRTAC=""
+   *C(1)=$ZWRTAC1
+   $ZWRTAC1(1)="1b"
+   *$ZWRTAC1(2)=$ZWRTAC2
+   $ZWRTAC2(1)=1
+   $ZWRTAC2(2)=2
+   $ZWRTAC2(3)=3
+   $ZWRTAC1(3)=3
+   $ZWRTAC=""
+   ------------
+   No local arrays left:
+   ------------
+   Rollback doesnt restore names and local arrays
+
+   Example:
+
+   $ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^aliasexample; Extended annotated alias example
+       zprint
+       write "------------",!
+       set x="name level",x(1)=1,x(1,2)="1,2",x("foo")="bar"
+       write $ZDATA(x),! ; x is a conventional lvn - output 11
+       set *y=x ; x an y are now alias variables
+       write $ZDATA(x),! ; output appears as 111
+       set *a(1)=y ; a(1) is now an alias container variable
+       set b="bness",b("b")="bbness" ; b is a conventional lvn
+       set *b=a(1) ; b joins x and y as alias variables for the same data
+       ; prior b values are lost
+       ; set *<name> is equivalent to Kill *<name> Set *<name>
+       set y("hi")="sailor" ; Assignment applies to all of {b,x,y}
+       kill b("foo") ; Kill applies to all of {b,x,y}
+       kill *x ; x is undefined and no longer an alias variable
+       ; b and y still provide access to the data
+       write a(1),"<",! ; output appears as <
+       write a(1)*3,! ; output appears as 0
+       write $length(a(1)),! ; output appears as 0
+       set c=y,c("legs")="tars" ; c is conventional lvn with value "name level"
+       do sub1
+       write $Data(c),! ; output is 1
+       do sub2(.c)
+       set a(1)="" ; a(1) ceases to be an alias container variable
+       ; has the value ""
+       write $D(i),! ; output is 0
+       kill *c,*y ; c and y become undefined lvns
+       zwrite b ; output is b("got")="a match"
+       ; it's no longer an alias variable
+       ; as everything else has gone
+       quit
+   sub1
+       new y ; in this scope y is no longer an alias for b
+       set *y=c ; in this scope c and y are alias variables
+       kill y("legs") ; Kill apples to all of {c,y}
+       kill *y ; in this scope y is no longer an alias for c
+       ; this is really redundant as
+       ; the Quit implicitly does the same thing
+       quit
+   sub2(i) ; i and c are joined due to pass-by-reference
+       write $ZAHandle(c)=$ZAHandle(i),! ; output appears as 1
+       kill b ; data for {b,y} is gone
+       ; both are undefined, but remain alias variables
+       set *c=a(1) ; c joins {b,y} as alias variable; prior value of c lost
+       ; c is no longer alias of i
+       write $ZAHandle(c)=$ZAHandle(i),! ; output appears as 0
+       set i=a(1) ; Assignment applies to i - value is ""
+       wet c("got")="a match" ; Assignment applies to all of {b,c,y)
+       quit
+
+   ------------
+   11
+   111
+   <
+   0
+   0
+   1
+   1
+   0
+   0
+   b("got")="a match"
+
+2 Extensions_for_Unicode(TM)_support
+   Extensions for Unicode(TM) support
+
+   To represent and process strings that use international characters, GT.M
+   processes can use Unicode.
+
+   If the environment variable gtm_chset has a value of UTF-8 and either
+   LC_ALL or LC_CTYPE is set to a locale with UTF-8 support (for example,
+   zh_CN.utf8), a GT.M process interprets strings as containing characters
+   encoded in the UTF-8 representation. In the UTF-8 mode, GT.M no longer
+   assumes that one character is one byte, or that the glyph display width of
+   a character is one. Depending on how ICU is built on a computer system, in
+   order to operate in UTF-8 mode, a GT.M process may well also need a third
+   environment variable, gtm_icu_version set appropriately.
+
+   If the environment variable gtm_chset has no value, the string "M", or any
+   value other than "UTF-8", GT.M treats each 8-bit byte as a character,
+   which suffices for English, and many single-language applications.
+
+   All GT.M components related to M mode reside in the top level directory in
+   which a GT.M release is installed and the environment variable gtm_dist
+   should points to that directory for M mode processes. All Unicode-related
+   components reside in the utf8 subdirectory and the environment variable
+   gtm_dist should point to that subdirectory for UTF-8 mode processes. So,
+   in addition to the values of the environment variables gtm_chset and
+   LC_ALL/LC_CTYPE, gtm_dist for a UTF-8 process should also point to the
+   utf8 subdirectory.
+
+   M mode and UTF-8 mode are set for the process, not for the database. As a
+   subset of Unicode, ASCII characters ($CHAR() values 0 through 127) are
+   interpreted identically by processes in M and UTF-8 modes. The indexes and
+   values in the database are simply sequences of bytes and therefore it is
+   possible for one process to interpret a global node as encoded in UTF-8
+   and for another to interpret the same node as bytecodes. Note that such an
+   application configuration would be extremely unusual, except perhaps
+   during a transition phase or in connection with data import/export.
+
+   In UTF-8 mode, string processing functions (such as $EXTRACT()) operate on
+   strings of multi-byte characters, and can therefore produce different
+   results in M and UTF-8 modes, depending on the actual data processed,
+    Each function has a "Z" alter ego (for example, $ZEXTRACT()) that can be
+   used to operate on  sequences of bytes identically in M and UTF-8 modes
+   (that is, in M mode, $EXTRACT() and $ZEXTRACT() behave identically).
+
+   In M mode, the concept of an illegal character does not exist. In UTF-8
+   mode, a sequence of bytes may not represent a valid character, and
+   generates an error when encountered by functions that expect and process
+   UTF-8 strings. During a migration of an application to add support for
+   Unicode, illegal character errors may be frequent and indicative of
+   application code that is yet to be modified. VIEW "NOBADCHAR" suppresses
+   these errors at times when their presence impedes development.
+
+   In UTF-8 mode, GT.M also supports IO encoded in UTF-16 variants as well as
+   in the traditional one byte per character encoding from devices other than
+   $PRINCIPAL.
+
+   The following table summarizes GT.M Unicode support.
+
+   +------------------------------------------------------------------------+
+   |       EXTENSION        |                  EXPLANATION                  |
+   |------------------------+-----------------------------------------------|
+   |                        | IN UTF-8 mode, the $ASCII() function returns  |
+   |                        | the integer Unicode code-point value of a     |
+   |                        | character in the given string. Note that the  |
+   | $ASCII()               | name $ASCII() is somewhat anomalous for       |
+   |                        | Unicode data but that name is the logical     |
+   |                        | extension of the function from M mode to      |
+   |                        | UTF-8 mode.                                   |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, $CHAR() returns a string       |
+   | $Char()                | composed of characters represented by the     |
+   |                        | integer equivalents of the Unicode            |
+   |                        | code-points specified in its argument(s).     |
+   |------------------------+-----------------------------------------------|
+   | $Extract()             | The $EXTRACT() function returns a substring   |
+   |                        | of a given string.                            |
+   |------------------------+-----------------------------------------------|
+   |                        | The $FIND() function returns an integer       |
+   | $Find()                | character position that locates the           |
+   |                        | occurrence of a substring within a string.    |
+   |------------------------+-----------------------------------------------|
+   | $Justify()             | The $JUSTIFY function returns a formatted     |
+   |                        | string.                                       |
+   |------------------------+-----------------------------------------------|
+   |                        | The $LENGTH() function returns the length of  |
+   | $Length()              | a string measured in characters, or in        |
+   |                        | "pieces" separated by a delimiter specified   |
+   |                        | by its optional second argument.              |
+   |------------------------+-----------------------------------------------|
+   |                        | The $PIECE() function returns a substring     |
+   | $Piece()               | delimited by a specified string delimiter     |
+   |                        | made up of one or more characters.            |
+   |------------------------+-----------------------------------------------|
+   |                        | The $TRANSLATE() function returns a string    |
+   |                        | that results from replacing or dropping       |
+   | $TRanslate()           | characters in the first of its arguments as   |
+   |                        | specified by the patterns of its other        |
+   |                        | arguments.                                    |
+   |------------------------+-----------------------------------------------|
+   |                        | For UTF-8 mode and TRM and SD output, $X      |
+   | $X                     | increases by the display-columns (width in    |
+   |                        | glyphs) of a given string that is written to  |
+   |                        | the current device.                           |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZASCII() function returns the numeric    |
+   | $ZASCII()              | byte value (0 through 255) of a given         |
+   |                        | sequence of octets (8-bit bytes).             |
+   |------------------------+-----------------------------------------------|
+   |                        | The read-only intrinsic special variable      |
+   |                        | $ZCHSET takes its value from the environment  |
+   |                        | variable gtm_chset. An application can obtain |
+   | $ZCHset                | the character set used by a GT.M process by   |
+   |                        | the value of $ZCHSET. $ZCHSET can have only   |
+   |                        | two values "M", or "UTF-8" and it cannot      |
+   |                        | appear on the left of an equal sign in the    |
+   |                        | SET command.                                  |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZCHAR() function returns a byte sequence |
+   | $ZCHar()               | of one or more bytes corresponding to numeric |
+   |                        | byte value (0 through 255) specified in its   |
+   |                        | argument(s).                                  |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZCONVERT() function returns its first    |
+   |                        | argument as a string converted to a different |
+   | $ZCOnvert()            | encoding. The two argument form changes the   |
+   |                        | encoding for case within a character set. The |
+   |                        | three argument form changes the encoding      |
+   |                        | scheme.                                       |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZEXTRACT() function returns a byte       |
+   | $ZExtract()            | sequence of a given sequence of octets (8-bit |
+   |                        | bytes).                                       |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZFIND() function returns an integer byte |
+   | $ZFind()               | position that locates the occurrence of a     |
+   |                        | byte sequence within a sequence of            |
+   |                        | octets(8-bit bytes).                          |
+   |------------------------+-----------------------------------------------|
+   | $ZJustify()            | The $JUSTIFY() function returns a formatted   |
+   |                        | and fixed length byte sequence.               |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZLENGTH() function returns the length of |
+   | $ZLength()             | a sequence of octets measured in bytes, or in |
+   |                        | "pieces" separated by a delimiter specified   |
+   |                        | by its optional second argument.              |
+   |------------------------+-----------------------------------------------|
+   |                        | ZPATN[UMERIC] is a read-only intrinsic        |
+   |                        | special variable that determines how GT.M     |
+   |                        | interprets the patcode N used in the pattern  |
+   |                        | match operator. With $ZPATNUMERIC="UTF-8",    |
+   | $ZPATNumeric           | the patcode N matches any numeric character   |
+   |                        | as defined by Unicode. By default patcode N   |
+   |                        | only matches the ASCII digits, which are the  |
+   |                        | only digits which M actually treats as        |
+   |                        | numerics.                                     |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZPIECE() function returns a sequence of  |
+   |                        | bytes delimited by a specified byte sequence  |
+   | $ZPiece()              | made up of one or more bytes. In M, $ZPIECE() |
+   |                        | typically returns a logical field from a      |
+   |                        | logical record.                               |
+   |------------------------+-----------------------------------------------|
+   |                        | $ZPROM[PT] contains a string value specifying |
+   |                        | the current Direct Mode prompt. By default,   |
+   |                        | GTM> is the Direct Mode prompt. M routines    |
+   |                        | can modify $ZPROMPT by means of a SET         |
+   |                        | command. $ZPROMPT cannot exceed 31 bytes. If  |
+   |                        | an attempt is made to assign $ZPROMPT to a    |
+   | $ZPROMpt               | longer string, GT.M takes only the first 31   |
+   |                        | bytes and truncates the rest. With character  |
+   |                        | set UTF-8 specified, if the 31st byte is not  |
+   |                        | the end of a valid UTF-8 character, GT.M      |
+   |                        | truncates the $ZPROMPT value at the end of    |
+   |                        | last character that completely fits within    |
+   |                        | the 31 byte limit.                            |
+   |------------------------+-----------------------------------------------|
+   | $ZSUBstr()             | The $ZSUBSTR() function returns a properly    |
+   |                        | encoded string from a sequence of bytes.      |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZTRANSLATE() function returns a byte     |
+   |                        | sequence that results from replacing or       |
+   | $ZTRanslate()          | dropping bytes in the first of its arguments  |
+   |                        | as specified by the patterns of its other     |
+   |                        | arguments. $ZTRANSLATE() provides a tool for  |
+   |                        | tasks such as encryption.                     |
+   |------------------------+-----------------------------------------------|
+   |                        | The $ZWIDTH() function returns the numbers of |
+   | $ZWidth()              | columns required to display a given string on |
+   |                        | the screen or printer.                        |
+   |------------------------+-----------------------------------------------|
+   |                        | The GT.M %HEX2UTF utility returns the GT.M    |
+   |                        | encoded character string from the given       |
+   | %HEX2UTF               | bytestream in hexadecimal notation. This      |
+   |                        | routine has entry points for both interactive |
+   |                        | and non-interactive use.                      |
+   |------------------------+-----------------------------------------------|
+   |                        | The GT.M %UTF2HEX utility returns the         |
+   |                        | hexadecimal notation of the internal byte     |
+   | %UTF2HEX               | encoding of a UTF-8 encoded GT.M character    |
+   |                        | string. This routine has entry points for     |
+   |                        | both interactive and non-interactive use.     |
+   |------------------------+-----------------------------------------------|
+   |                        | Enables or disables automatic record          |
+   |                        | termination. When the current record size     |
+   | [NO]WRAP (USE)         | ($X) reaches the maximum WIDTH and the device |
+   |                        | has WRAP enabled, GT.M starts a new record,   |
+   |                        | as if the routine had issued a WRITE !        |
+   |                        | command.                                      |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, DSE and LKE accept characters  |
+   |                        | in Unicode in all their command qualifiers    |
+   | DSE and LKE            | that require file names, keys, or data (such  |
+   |                        | as DSE -KEY, DSE -DATA and LKE -LOCK          |
+   |                        | qualifiers).                                  |
+   |------------------------+-----------------------------------------------|
+   |                        | GDE allows the name of a file to include      |
+   |                        | characters in Unicode                         |
+   | GDE Objects            |                                               |
+   |                        | In UTF-8 mode, GDE considers a text file to   |
+   |                        | be encoded in UTF-8 when it is executed via   |
+   |                        | the "@" command.                              |
+   |------------------------+-----------------------------------------------|
+   |                        | Specifies character filtering for specified   |
+   |                        | cursor movement sequences on devices where    |
+   |                        | FILTER applies.                               |
+   |                        |                                               |
+   |                        | In UTF-8 mode, the usual Unicode line         |
+   | FILTER[=expr]          | terminators (U+000A (LF), U+0000D (CR),       |
+   |                        | U+000D followed by U+000A (CRLF), U+0085      |
+   |                        | (NEL), U+000C (FF), U+2028 (LS) and U+2029    |
+   |                        | (PS)) are recognized. If FILTER=CHARACTER is  |
+   |                        | enabled, all of the terminators are           |
+   |                        | recognized to maintain the values of $X and   |
+   |                        | $Y.                                           |
+   |------------------------+-----------------------------------------------|
+   |                        | The Job command spawns a background process   |
+   |                        | with the same environment as the M process    |
+   |                        | doing the spawning. Therefore, if the parent  |
+   |                        | process is operating in UTF-8 mode, the Job'd |
+   | Job                    | process also operates in UTF-8 mode. In the   |
+   |                        | event that a background process must have a   |
+   |                        | different mode from the parent, create a      |
+   |                        | shell script to alter the environment as      |
+   |                        | needed, and spawn it with a ZSYstem command   |
+   |                        | or start it as a PIPE device.                 |
+   |------------------------+-----------------------------------------------|
+   |                        | MUPIP EXTRACT                                 |
+   |                        |                                               |
+   |                        | In UTF-8 mode, MUPIP EXTRACT, MUPIP JOURNAL   |
+   |                        | -EXTRACT and MUPIP JOURNAL -LOSTTRANS write   |
+   |                        | sequential output files in the UTF-8          |
+   |                        | character encoding form. For example, in      |
+   |                        | UTF-8 mode if ^A has the value of             |
+   |                        | ************, the sequential output file of   |
+   |                        | the MUPIP EXTRACT command is:                 |
+   |                        |                                               |
+   |                        | 09-OCT-2006 04:27:53 ZWR                      |
+   |                        |                                               |
+   |                        | GT.M MUPIP EXTRACT UTF-8                      |
+   |                        |                                               |
+   | MUPIP                  | ^A="************"                             |
+   |                        |                                               |
+   |                        | MUPIP LOAD                                    |
+   |                        |                                               |
+   |                        | MUPIP LOAD command considers a sequential     |
+   |                        | file as encoded in UTF-8 if the environment   |
+   |                        | variable gtm_chset is set to UTF-8. Ensure    |
+   |                        | that MUPIP EXTRACT commands and corresponding |
+   |                        | MUPIP LOAD commands execute with the same     |
+   |                        | setting for the environment variable          |
+   |                        | gtm_chset. The M utility programs %GO and %GI |
+   |                        | have the same requirement for mode matching.  |
+   |                        | For more information on MUPIP EXTRACT and     |
+   |                        | MUPIP LOAD, refer to the General Database     |
+   |                        | Management chapter in GT.M Administration and |
+   |                        | Operations Guide.                             |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, the OPEN command recognizes    |
+   | Open                   | ICHSET, OCHSET, and CHSET as three additional |
+   |                        | deviceparameters to determine the encoding of |
+   |                        | the input / output devices.                   |
+   |------------------------+-----------------------------------------------|
+   |                        | GT.M allows the pattern string literals to    |
+   | Pattern Match Operator | contain the characters in Unicode.            |
+   | (?)                    | Additionally, GT.M extends the M standard     |
+   |                        | pattern codes (patcodes) A, C, N, U, L, P and |
+   |                        | E to the Unicode character set.               |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, the READ command uses the      |
+   |                        | character set value specified on the device   |
+   |                        | OPEN as the character encoding of the input   |
+   |                        | device. If character set "M" or "UTF-8" is    |
+   |                        | specified, the data is read with no           |
+   |                        | transformation. If character set is "UTF-16", |
+   | Read                   | "UTF-16LE", or "UTF-16BE", the data is read   |
+   |                        | with the specified encoding and transformed   |
+   |                        | to UTF-8. If the READ command encounters an   |
+   |                        | illegal character or a character outside the  |
+   |                        | selected representation, it triggers a        |
+   |                        | run-time error. The READ command recognizes   |
+   |                        | all Unicode line terminators for non-FIXED    |
+   |                        | devices.                                      |
+   |------------------------+-----------------------------------------------|
+   |                        | When a number sign (#) and a non-zero integer |
+   |                        | expression immediately follow the variable    |
+   |                        | name, the integer expression determines the   |
+   |                        | maximum number of characters accepted as the  |
+   |                        | input to the READ command. In UTF-8 or UTF-16 |
+   | Read #                 | modes, this can occur in the middle of a      |
+   |                        | sequence of combining code-points (some of    |
+   |                        | which are typically non-spacing). When this   |
+   |                        | happens, any display on the input device, may |
+   |                        | not represent the characters returned by the  |
+   |                        | fixed-length READ (READ #).                   |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 or UTF-16 modes, the READ * command  |
+   | Read *                 | accepts one character in Unicode of input and |
+   |                        | puts the numeric code-point value for that    |
+   |                        | character into the variable.                  |
+   |------------------------+-----------------------------------------------|
+   |                        | As an aid to migrating applications to        |
+   |                        | Unicode, this UTF-8 mode VIEW command         |
+   | View "[NO]BADCHAR"     | determines whether Unicode enabled functions  |
+   |                        | trigger errors when they encounter illegal    |
+   |                        | strings.                                      |
+   |------------------------+-----------------------------------------------|
+   |                        | For some languages (such as Chinese), the     |
+   |                        | ordering of strings according to Unicode      |
+   |                        | code-points (character values) may not be the |
+   |                        | linguistically or culturally correct          |
+   |                        | ordering. Supporting applications in such     |
+   | User-defined Collation | languages requires development of collation   |
+   |                        | modules - GT.M natively supports M collation, |
+   |                        | but does not include pre-built collation      |
+   |                        | modules for any specific natural language.    |
+   |                        | Therefore, applications that use characters   |
+   |                        | in Unicode may need to implement their own    |
+   |                        | collation functions.                          |
+   |------------------------+-----------------------------------------------|
+   |                        | When the ICHSET for a device is not "M", if   |
+   |                        | BOM (U+FEFF) is at the beginning of the       |
+   |                        | initial input for a file or data stream, GT.M |
+   |                        | uses it to determine the endian if the ICHSET |
+   |                        | is UTF-16 and checks for agreement with       |
+   |                        | ICHSET UTF-16BE or UTF-16LE.                  |
+   |                        |                                               |
+   |                        | If character set for a device is UTF-16, GT.M |
+   |                        | uses BOM (U+FEFF) to determine the endians.   |
+   |                        | For this to happen, the BOM must be at at the |
+   |                        | beginning of the initial input for a file or  |
+   |                        | data stream. If there is no BOM present, GT.M |
+   |                        | assumes big endianess.                        |
+   | Unicode Byte Order     |                                               |
+   | Marker (BOM)           | If the character set of a device is UTF-8,    |
+   |                        | GT.M checks for and ignores a BOM on input.   |
+   |                        |                                               |
+   |                        | If the BOM does not match the character set   |
+   |                        | specified at device OPEN, GT.M produces an    |
+   |                        | error. READ does not return BOM to the        |
+   |                        | application and the BOM is not counted as     |
+   |                        | part of the first record.                     |
+   |                        |                                               |
+   |                        | If the output character set for a device is   |
+   |                        | UTF-16 (but not UTF-16BE or UTF-16LE,) GT.M   |
+   |                        | writes a BOM before the initial output. The   |
+   |                        | application code does not need to explicitly  |
+   |                        | write the BOM.                                |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode and TRM and SD output, the      |
+   |                        | WIDTH deviceparameter specifies the           |
+   | WIDTH=intexpr (USE)    | display-columns and is used with $X to        |
+   |                        | control truncation and WRAPing of the visual  |
+   |                        | representation of the stream.                 |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, the WRITE command uses the     |
+   |                        | character set specified on the device OPEN as |
+   |                        | the character encoding of the output device.  |
+   |                        | If character set specifies "M" or "UTF-8",    |
+   | Write                  | GT.M WRITEs the data with no transformation.  |
+   |                        | If character set specifies "UTF-16",          |
+   |                        | "UTF-16LE" or "UTF-16BE", the data is assumed |
+   |                        | to be encoded in UTF-8 and WRITE transforms   |
+   |                        | it to the character encoding specified by     |
+   |                        | character set device parameter.               |
+   |------------------------+-----------------------------------------------|
+   |                        | When the argument of a WRITE command consists |
+   |                        | of a leading asterisk (*) followed by an      |
+   | Write *                | integer expression, the WRITE command outputs |
+   |                        | the character represented by the code-point   |
+   |                        | value of that integer expression.             |
+   |------------------------+-----------------------------------------------|
+   |                        | In UTF-8 mode, the ZSHOW command exhibits     |
+   |                        | byte-oriented and display-oriented behavior   |
+   |                        | as follows:                                   |
+   |                        |                                               |
+   |                        |  1. ZSHOW targeted to a device (ZSHOW "*")    |
+   |                        |     aligns the output according to the        |
+   |                        |     numbers of display columns specified by   |
+   |                        |     the WIDTH deviceparameter.                |
+   | ZSHow                  |  2. ZSHOW targeted to a local (ZSHOW "*":lcl) |
+   |                        |     truncates data exceeding 2048KB at the    |
+   |                        |     last character that fully fits within the |
+   |                        |     2048KB limit.                             |
+   |                        |  3. ZSHOW targeted to a global (ZSHOW         |
+   |                        |     "*":^CC) truncates data exceeding the     |
+   |                        |     maximum record size for the target global |
+   |                        |     at the last character that fully fits     |
+   |                        |     within that record size.                  |
+   +------------------------------------------------------------------------+
+
+3 ICU
+   ICU
+
+   While GT.M provides a framework for handling characters in Unicode, it
+   relies on the ICU (International Components for Unicode) library for
+   language specific information.
+
+   ICU is a widely used, defacto standard package (see http://icu-project.org
+   for more information) that GT.M relies on for most operations that require
+   knowledge of the Unicode character sets, such as text boundary detection,
+   character string conversion between UTF-8 and UTF-16, and calculating
+   glyph display widths.
+
+   **Important**
+
+   Unless Unicode support is sought for a process (that is, unless the
+   environment variable gtm_chset is UTF8"), GT.M processes do not need ICU.
+   In other words, existing, non-Unicode, applications continue to work on
+   supported platforms without ICU.
+
+   An ICU version number is of the form major.minor.milli.micro where major,
+   minor, milli and micro are integers. Two versions that have different
+   major and/or minor version numbers can differ in functionality and API
+   compatibility is not guaranteed. Differences in milli or micro versions
+   are maintenance releases that preserve functionality and API
+   compatibility. ICU reference releases are defined by major and minor
+   version numbers. Note that display widths for some characters changed in
+   ICU 4.0 and may change again in the future, as both languages and ICU
+   evolve.
+
+   An operating system's distribution generally includes an ICU library
+   tailored to the OS and hardware, therefore FIS does not provide any ICU
+   library. In order to support Unicode functionality, GT.M requires an
+   appropriate version of ICU to be installed on the system - check the
+   release notes for your GT.M release for supported ICU versions.
+
+   GT.M expects ICU to be compiled with symbol renaming disabled and will
+   issue an error at startup if the available version of ICU is built with
+   symbol renaming enabled. To use a version of ICU built with symbol
+   renaming enabled, the $gtm_icu_version environment variable indicates the
+   MAJOR VERSION and MINOR VERSION numbers of the desired ICU formatted as
+   MajorVersion.MinorVersion (for example "3.6" to denote ICU-3.6). When
+   $gtm_icu_version is so defined, GT.M attempts to open the specific version
+   of ICU. In this case, GT.M works regardless of whether or not symbols in
+   this ICU have been renamed. A missing or ill-formed value for this
+   environment variable causes GT.M to only look for non-renamed ICU symbols.
+   The release notes for each GT.M release identify the required reference
+   release version number as well as the milli and micro version numbers that
+   were used to test GT.M prior to release. In general, it should be safe to
+   use any version of ICU with the specific ICU reference version number
+   required and milli and micro version numbers greater than those identified
+   in the release notes for that GT.M version.
+
+   ICU supports multiple threads within a process, and an ICU binary library
+   can be compiled from source code to either support or not support multiple
+   threads. In contrast, GT.M does not support multiple threads within a GT.M
+   process. On some platforms, the stock ICU library, which is usually
+   compiled to support multiple threads, may work unaltered with GT.M. On
+   other platforms, it may be required to rebuild ICU from its source files
+   with support for multiple threads turned off. Refer to the release notes
+   for each GT.M release for details about the specific configuration tested
+   and supported. In general, the GT.M team's preference for ICU binaries
+   used for each GT.M version are, in decreasing order of preference:
+
+    1. The stock ICU binary provided with the operating system distribution.
+    2. A binary distribution of ICU from the download section of the ICU
+       project page.
+    3. A version of ICU locally compiled from source code provided by the
+       operating system distribution with a configuration disabling
+       multi-threading.
+    4. A version of ICU locally compiled from the source code from the ICU
+       project page with a configuration disabling multi-threading.
+
+   GT.M uses the POSIX function dlopen() to dynamically link to ICU. In the
+   event you have other applications that require ICU compiled with threads,
+   place the different builds of ICU in different locations, and use the
+   dlopen() search path feature (for example, the LD_LIBRARY_PATH environment
+   variable on Linux) to enable each application to link with its appropriate
+   ICU.
+
+4 Compiling_ICU
+   Compiling ICU
+
+   To compile ICU, refer to the Compiling ICU Appendix in the GT.M
+   Administration and Operations Guide and to the release notes of your GT.M
+   release.
+
+1 Program_Cycle
+   Program Cycle
+
+   In contrast to M environments that interpret M code, GT.M compiles M code
+   from source files into the target machine language. The GT.M compiler
+   produces object files, which are dynamically linked into an image. Source
+   files and object files may be managed independently, or placed together in
+   a specific directory. GT.M permits access to source and object files in
+   multiple directories.
+
+   GT.M databases are UNIX files identified by a small file called a Global
+   Directory. Global Directories allow management of the database files to be
+   independent of the placement of files containing M routines. By changing
+   the Global Directory, you can use the same programs to access different
+   databases.
+
+   Program development may utilize both GT.M and UNIX development tools. The
+   development methodology and environment chosen for a particular
+   installation, and tailored by the individual user, determines the actual
+   mix of tools. These tools may vary from entirely GT.M with little UNIX, to
+   mostly UNIX with a modest use of GT.M.
+
+   Direct Mode serves as an interactive interface to the GT.M run-time
+   environment and the compiler. In Direct Mode, the user enters M commands
+   at the GT.M prompt, and GT.M compiles and executes the command. This
+   feature provides immediate turnaround for rapid program development and
+   maintenance.
+
+2 Overview
+   Overview
+
+   This section provides an overview of the steps involved in generating
+   executable programs in GT.M.
+
+   The steps begin with your initial use of GT.M. The first two steps are
+   part of your initial setup and will generally be performed only the first
+   time you use GT.M. The remaining steps are those you will use regularly
+   when generating your programs.
+
+   Each of these remaining steps can be performed either from the GT.M prompt
+   or the shell prompt. To clearly describe the two ways to perform each
+   step, this section is set up in the format of a table with one column
+   illustrating the GT.M method, and one column illustrating the shell
+   method.
+
+   +------------------------------------------------------------------------+
+   | Creating a GT.M Routine                                                |
+   |------------------------------------------------------------------------|
+   |                       | define                                         |
+   |                       |                                                |
+   | 1) Define environment | gtm_dist                                       |
+   | variables (shell)     |                                                |
+   |                       | gtmgbldir                                      |
+   |                       |                                                |
+   |                       | gtmroutines                                    |
+   |-----------------------+------------------------------------------------|
+   | 2) Prepare database   | define Global Directory with GDE,              |
+   | (GT.M)                |                                                |
+   |                       | create database with MUPIP CREATE              |
+   |-----------------------+------------------------------------------------|
+   | -                     | SHELL                 | GT.M                   |
+   |-----------------------+-----------------------+------------------------|
+   | 3) Create/Edit        | Create file with UNIX | ZEDIT "routine" .m     |
+   | routine               | editor; assign .m     | extension added by     |
+   |                       | extension             | GT.M                   |
+   |-----------------------+-----------------------+------------------------|
+   | 4) Compile routine    | invoke mumps          | ZLINK "routine"        |
+   |                       | routine.m             |                        |
+   |-----------------------+-----------------------+------------------------|
+   |                       | invoke mumps -run     |                        |
+   |                       | routine               | Do ^routine calls from |
+   | 5) Execute routine    |                       | other routines invoke  |
+   |                       | calls from other      | auto-ZLINK             |
+   |                       | routines invoke       |                        |
+   |                       | auto-ZLINK            |                        |
+   |-----------------------+-----------------------+------------------------|
+   |                       |                       | utilize GT.M debug     |
+   |                       |                       | commands such as:      |
+   |                       |                       |                        |
+   |                       |                       | ZGOTO                  |
+   |                       |                       |                        |
+   |                       |                       | ZLINK                  |
+   |                       |                       |                        |
+   |                       |                       | ZMESSAGE               |
+   |                       | edit file with UNIX   |                        |
+   | 6) Debug routine      | editor; repeat steps  | ZPRINT                 |
+   |                       | 4, 5                  |                        |
+   |                       |                       | ZSHOW                  |
+   |                       |                       |                        |
+   |                       |                       | ZSTEP                  |
+   |                       |                       |                        |
+   |                       |                       | ZSYSTEM                |
+   |                       |                       |                        |
+   |                       |                       | ZWRITE                 |
+   |                       |                       |                        |
+   |                       |                       | repeat steps 4, 5      |
+   +------------------------------------------------------------------------+
+
+2 Compile_Source_Program
+   Compile Source Program
+
+   If you wish to focus on program development outside the GT.M environment,
+   skip the next section and continue with the section "Compiling from the
+   Shell".
+
+   GT.M compiles M source code files and produces object files for complete
+   integration into the UNIX enviroment. The object modules have the same
+   name as the compiled M source file with an .o file extension, unless
+   otherwise specified. The object files contain machine instructions and
+   information necessary to connect the routine with other routines, and map
+   it into memory. An M routine source file must be compiled after it is
+   created or modified. You can compile explicitly with the ZLINK command or
+   implicitly with auto-ZLINK. At the shell command line, compile by issuing
+   the mumps command.
+
+   The compiler checks M code for syntax errors and displays error messages
+   on the terminal, when processing is complete. Each error message provides
+   the source line in error with an indicator pointing to the place on the
+   line where the error is occurring. For a list and description of the
+   compiler error messages, refer to the GT.M Message and Recovery Procedures
+   Reference Manual.
+
+   You can generate a listing file containing the compile results by
+   including the -list qualifier as a modifier to the argument to the ZLINK
+   command in Direct Mode. This can also be done by redirecting the compiler
+   messages to a file by adding >filename 2>&1 to the mumps command when
+   compiling a program from the shell. See "Compile from the Shell"
+   for an explanation of the M command describing -list, and other valid
+   qualifiers for the M and ZLINK commands.
+
+   The compiler stops processing a routine line when it detects an error on
+   that line. Under most conditions the compiler continues processing the
+   remaining routine lines. This allows the compiler to produce a more
+   complete error analysis of the routine and to generate code that may have
+   valid executable paths. The compiler does not report multiple syntax
+   errors on the same line. When it detects more than 127 syntax errors in a
+   source file, the compiler ceases to process the file.
+
+3 Compile
+   Compile
 
-   Add gtm_dist to your PATH environment variable to have UNIX search the
-   GT.M installation directory (when processing a command to  activate  or
-   run an image). This allows you  to  activate  GT.M  and  the  utilities
-   without explicitly specifying a path.
+   In Direct Mode, GT.M provides access to the compiler explicitly through
+   the ZLINK and ZCOMPILE commands, and implicitly through automatic
+   invocation of ZLINK functionality (auto-ZLINK) to add required routines to
+   the image. ZCOMPILE is a GT.M routine compilation command, it compiles the
+   routine and creates a new object module. The primary task of ZLINK is to
+   place the object code in memory and "connect" it with other routines.
+   However, under certain circumstances, ZLINK may first use the GT.M
+   compiler to create a new object module.
+
+   The difference between ZCOMPILE and ZLINK is that ZCOMPILE creates a new
+   object module on compiling, whereas the ZLINK command links the object
+   module with other routines and places the object code in memory.
 
-   To add gtm_dist to your PATH type the following commands:
+   ZLINK compiles under these circumstances:
 
+     * ZLINK cannot locate a copy of the object module but can locate a copy
+       of the source module.
+     * ZLINK can locate both object and source module, and finds the object
+       module to be older than the source module.
+     * The file-specification portion of the ZLINK argument includes an
+       explicit extension of .m.
 
-   $ PATH=$PATH:$gtm_dist
+   Auto-ZLINK compiles under the first two circumstances, but can never
+   encounter the last one.
 
-   $ export PATH
+   When a command refers to an M routine that is not part of the current
+   image, GT.M automatically attempts to ZLINK and, if necessary, compile
+   that routine. In Direct Mode, the most common method to invoke the
+   compiler through an auto-ZLINK is to enter DO ^routinename at the GTM>
+   prompt. When the current image does not contain the routine, GT.M does the
+   following:
 
-        Most of the examples in this manual  assume  that  you  have  added
-        gtm_dist to your PATH.
+   By using the DO command, you implicitly instruct GT.M to compile, link,
+   and execute the program. With this method, you can test your routine
+   interactively.
 
-3 gtmgbldir
-   gtmgbldir
+   Example:
 
-   gtmgbldir defines the path to a Global Directory.  A  Global  Directory
-   maps global variables to physical database files, and  is  required  to
-   locate M global variables. gtmgbldir provides  the  initial  value  for
-   $ZGBLDIR,  the  intrinsic  special  variable  that  connects  the  GT.M
-   run-time system to the Global Directory. It also  connects  the  Global
-   Directory to the utilities requiring one.
+   GTM>do ^payroll
+   GTM>do ^taxes
 
-   If you maintain multiple global directories, define  gtmgbldir  to  the
-   Global Directory you currently want to use.
+   This uses the M DO command to invoke the GT.M compiler implicitly from the
+   GTM> prompt if the routine requires new object code. When the compiler
+   runs, it produces two object module files, payroll.o and taxes.o.
 
-   The syntax of a gtmgbldir definition is:
+   If you receive error messages from the compilation, you may fix them
+   immediately by returning to the editor and correcting the source. By
+   default, the GT.M compiler operates in "compile-as-written" mode, and
+   produces object code even when a routine contains syntax errors. This code
+   includes all lines that are correct and all commands on a line with an
+   error, up to the error. Therefore, you may decide to tailor the debugging
+   cycle by running the program without removing the syntax errors.
 
+   **Caution**
 
-   $ gtmgbldir=/directory/filename.gld
+   The DO command does not add an edited routine to the current image if the
+   image already includes a routine matching the DO argument routine name.
+   When the image contains a routine, GT.M simply executes the routine
+   without examining whether a more recent version of the module exists. If
+   you have a routine in your image, and you wish to change it, you must
+   explicitly ZLINK that routine.
 
    Example:
 
+   GTM>zlink "payroll"
+   GTM>zlink "taxes.m"
 
-   $ gtmgbldir=/usr/staff/mumps.gld
+   The first ZLINK compiles payroll.m if it cannot locate payroll, or if it
+   finds that payroll.m has a more recent date/time stamp than payroll.o. The
+   second ZLINK always compiles taxes.m producing a new taxes.o.
 
-   $ export gtmgbldir
+3 Compile_from_the_Shell
+   Compile from the Shell
 
-   This specifies  /usr/staff  as  the  directory  containing  the  Global
-   Directory file named mumps.gld.
+   From the shell, invoke the compiler by entering mumps file-name at the
+   shell prompt.
 
-3 gtm_principal
-   gtm_principal
+   Example:
 
-   The  gtm_principal  environment  variable  specifies  the  value  for
-   $principal, which designates the absolute pathname of the principal $IO
-   device. This is an MDC Type A enhancement to standard M.
+   $ mumps payroll.m
+   $ mumps taxes.m
 
-   The following is an example of gtm_principal definition:
+   This uses the mumps command to invoke the GT.M compiler from the shell
+   prompt, and creates .o versions of these files.
 
+   Use the mumps command at the shell prompt to:
 
-   $ gtm_principal=/usr/filename
+     * Check the syntax of a newly entered program.
+     * Optionally, get a formatted listing of the program.
+     * Ensure that all object code is up to date before linking.
 
-   $ export gtm_principal
+   The mumps command invokes the compiler to translate an M source file into
+   object code.
 
-   This specifies the /usr/filename as the principal $IO device, effective
-   until changed further or until you logout of the particular session.
+   The format for the MUMPS command is:
 
-3 gtmroutines
-   gtmroutines
+   MUMPS [-qualifier[...]] pathname
 
-   The  gtmroutines  environment  variable  specifies  a  search  list  of
-   possible locations for M routines. This value  is  used  to  initialize
-   $ZROUTINES, (the intrinsic special variable that enables GT.M  to  find
-   the routine (program) you want to run).  gtmroutines  is  required  for
-   ZLINKing.  gtmroutines  is  particularly  helpful  in  calling  percent
-   utilities and the Global Directory Editor (GDE), which are in gtm_dist.
+   The * wildcard accepts any legal combination of numbers and characters
+   including a null, in the position the wildcard holds.
 
-   $ gtmroutines="directories in search list"
+   The ? wildcard accepts exactly one legal character in its position.
 
-   The directories in the search list must be separated  by  a  space  and
-   enclosed in quotation marks (" "). Environment variables  are  accepted
-   in the search list.
+   For example, mumps *.m compiles all files in the current default directory
+   with an .m extension. mumps *pay?.m compiles .m files with names that
+   contain any characters followed by pay, followed by one character. Unlike
+   when using ZLINK or ZCOMPILE, the filename must be fully specified when
+   compiling from the shell.
 
-   The following is an example of gtmroutines definition:
+   **Caution**
 
+   When forming routine names, the compiler truncates object filenames to a
+   maximum length of 31 characters. For example, for a source file called
+   Adatabaseenginewithscalabilityproven.m the compiler generates an object
+   file called Adatabaseenginewithscalabilityp.o. Ensure that the first 31
+   characters of source file names are unique.
 
-   $ gtmroutines=". $gtm_dist"
+3 mumps_qualifiers
+   mumps qualifiers
 
-   $ export gtmroutines
+   The mumps command allows qualifiers that customize the type and form of
+   the compiler output to meet specific programming needs. MUMPS command
+   qualifiers may also appear as a modifier to the argument to the GT.M ZLINK
+   and ZCOMPILE commands. The following section describes the mumps command
+   qualifiers. Make sure the arguments are specified ahead of file name and
+   after the command itself.
 
-   This specifies that GT.M search for a  routine  first  in  the  current
-   directory (.), then in the distribution directory (which is identified
-   by the environment variable gtm_dist). The  distribution  directory  is
-   included in the list because it contains the percent routines. You will
-   probably want the search list to contain these two items at a minimum.
-   In addition, you may want to add directories of your own.
+4 di[rect_mode]
+   di[rect_mode]
 
-3 Editor
-   Editor
+   Invokes a small GT.M image that immediately initiates Direct Mode.
 
-   The EDITOR environment variable specifies the  UNIX  text  editor  used
-   when editing a routine either from the shell or with ZEDIT. Since this
-   is a standard part of establishing  your  UNIX  environment,  you  will
-   probably only need to define this when you  want  to  use  a  different
-   editor than the one defined in your shell startup file.
+   -direct_mode does not invoke the M compiler.
 
-   Example:
+   The -direct_mode qualifier is incompatible with a file specification and
+   with all other qualifiers.
 
+4 [no]i[gnore]
+   [no]i[gnore]
 
-   $ EDITOR=/usr/bin/vi
+   Instructs the compiler to produce an object file even when the compiler
+   detects errors in the source code (-ignore), or not to produce an object
+   file when the compiler encounters an error (-noignore).
 
-   $ export EDITOR
+   When used with the -noobject qualifier, the -ignore qualifier has no
+   effect.
 
-   This defines the current text editor to vi.
+   Execution of a routine that compiles with errors produces run-time errors
+   when the execution path encounters any of the compile time errors.
 
-2 Prep_the_DB
-   Preparing the Database
+   This compile-as-written mode facilitates a flexible approach to debugging
+   and expedites conversion to GT.M from an interpreted environment. Many M
+   applications from an interpreted environment contain syntax abnormalities.
+   This feature of compiling and later executing a routine provides the feel
+   of developing in an interpreted environment.
 
-   GT.M databases consist of one or more UNIX files. Most  database  files
-   have a UNIX file structure externally and  a  GT.M  Database  Structure
-   (GDS) internally. Management of the GDS  files  by  the  GT.M  run-time
-   system assures high performance and integrity. GT.M database files are
-   coordinated by a Global  Directory.  The  Global  Directory  identifies
-   which global names belong in which files, and  specifies  the  creation
-   characteristics for each file. To specify access to a database, each M
-   process must define the gtmgbldir environment variable to point to the
-   associated Global Directory.
+   By default, the compiler operates in -ignore mode and produces an object
+   module even when the source routine contains errors.
 
-   To define and maintain a Global Directory,  use  the  Global  Directory
-   Editor (
-   GDE) utility. The GDE utility automatically  upgrades  existing  global
-   directories to the current format.The MUPIP  command  CREATE  uses  the
-   characteristics as defined  in  the  Global  Directory  to  create  the
-   associated database. In a production environment,  the  system  manager
-   typically maintains Global Directories.
+4 le[ngth]=lines
+   le[ngth]=lines
 
-   For more information on GDE and MUPIP refer to  the  "Global  Directory
-   Editor" and "MUPIP" chapters in the GT.M Administration and Operations
-   Guide .
+   Controls the page length of the listing file.
 
-   Example:
+   The M compiler ignores the -length qualifier unless it appears with the
+   -list qualifier.
 
-   This example is a sequence of events that illustrate  steps  you  might
-   typically perform in creating a new global directory,  in  our  example
-   PAYROLL.GLD. To assist you in following the sequence, each actual step
-   appears in typewriter font, as you might see on your  terminal  screen,
-   followed by an explanation in normal text font.
+   By default, the listing has -length=66.
 
+4 [no]li[st][=filename]
+   [no]li[st][=filename]
 
-   $ ls payroll.gld
+   Instructs the compiler to produce a source program listing file, and
+   optionally specifies a name for the listing file. The listing file
+   contains numbered source program text lines. When the routine has errors,
+   the listing file also includes an error count, information about the
+   location, and the cause of the errors.
 
+   When you do not specify a file name for the listing file, the compiler
+   produces a listing file with the same name as the source file with a .lis
+   file extension.
 
-   payroll.gld not found
+   The -length and -space qualifiers modify the format and content of the
+   listing file. The M compiler ignores these qualifiers unless the command
+   includes the -list qualifier.
 
-   The ls command verifies that there are no existing files with the name
+   By default, the compiler operates -nolist and does not produce listings.
 
+4 [no]o[bject][=filename]
+   [no]o[bject][=filename]
 
-   payroll.gld.
+   Instructs the compiler to produce an output object file and optionally
+   specifies a name for the object file using the optional filename argument.
 
-   $ gtmgbldir=payroll.gld
+   When you do not specify a file name, the compiler produces an object file
+   with the same file name as the source file and an .o file extension.
 
-   $ export gtmgbldir
+   When forming routine names, the compiler truncates object filenames to a
+   maximum length of 31 characters. For example, for a source file called
+   Adatabaseenginewithscalabilityproven.m the compiler generates an object
+   file called Adatabaseenginewithscalabilityp.o. Ensure that first 31
+   characters of source file names are unique.
 
-   This  establishes  the  current  value  of  the  environment  variable
-   gtmgbldir as payroll.gld. GT.M uses gtmgbldir to identify  the  current
-   Global Directory. When defined at the shell prompt, gtmgbldir maintains
-   the defined value only for the current login session. The next time you
-   log into UNIX,  you  must  again  define  the  value  of  gtmgbldir  as
-   payroll.gld to use it as the current Global Directory.
+   The -noobject qualifier suppresses the production of an object file and is
+   usually used with the -list qualifier to produce only a listing file.
 
-   This example defines gtmgbldir without a full pathname. The environment
-   variable  points  to  the  payroll.gld  file  in  the  current  working
-   directory. Therefore if the default directory changes, GT.M attempts to
-   locate the Global Directory in the new default directory and cannot use
-   the  original  file.  If  you  intend  for  the  Global  Directory  to
-   consistently point to this file, even if the default directory changes,
-   use a full file-specification for gtmgbldir.
+   By default, the compiler produces object modules.
 
+4 s[pace]=lines
+   s[pace]=lines
 
-   $ gtm
+   Controls the spacing of the output in the listing file. -space=n specifies
+   n-1 blank lines separating every source line in the listing file. If n<1,
+   the M command uses single spacing in the listing.
 
-   GTM>d ^GDE
+   If this qualifier appears without the -list qualifier, the M compiler
+   ignores the -space qualifier.
 
-   %GDE-I-GDUSEDEFS, Using defaults for Global Directory
+   By default, listings use single spaced output (-space=1).
 
-   /staff/payroll.gld
+4 r[un]
+   r[un]
 
-   GDE>
+   Invokes GT.M in Autostart Mode.
 
-   This invokes the Global Directory  Editor  from  the  GT.M  prompt  and
-   produces an informational message. Refer to  the  "Program  Development
-   Cycle" in GT.M Programmer's Guide for more details.
+   The next argument is taken to be an M entryref. That routine is
+   immediately executed, bypassing Direct Mode. Depending on the shell, you
+   may need to put the entryref in quotation marks (""). This qualifier does
+   not invoke the M compiler and is not compatible with any other qualifier.
 
-   Example:
+4 Summary
+   Summary
 
+   +------------------------------------------+
+   |         mumps Command Qualifiers         |
+   |------------------------------------------|
+   |        QUALIFIER         |    Default    |
+   |--------------------------+---------------|
+   | -direct_mode             | N/A           |
+   |--------------------------+---------------|
+   | -[no]i[gnore]            | -ignore       |
+   |--------------------------+---------------|
+   | -la[bels]=upper or lower | -labels=lower |
+   |--------------------------+---------------|
+   | -le[ngth]=n              | -length=66    |
+   |--------------------------+---------------|
+   | -[no]li[st]=[filename]   | -nolist       |
+   |--------------------------+---------------|
+   | -[no]o[bject][=filename] | -object       |
+   |--------------------------+---------------|
+   | -r[un]                   | N/A           |
+   |--------------------------+---------------|
+   | -s[pace]=n               | -space=1      |
+   +------------------------------------------+
 
-   $ mupip load payroll.gld
+2 Execute_Source_Program
+   Execute Source Program
 
-   GT.M
+   M source programs can be executed either from the shell or from GT.M
+   (Direct Mode).
 
-   09-OCT-2001 11:26:44
-   keycnt: 100 max subsc len:12 max data len: 3
+3 Execute_in_Direct_Mode
+   Execute in Direct Mode
 
-   Last record number: 202
+   As discussed in the section on compiling source programs, the GT.M command
+   ZLINK compiles the source code into an object module and adds the object
+   module to the current image.
 
-   This uses the MUPIP LOAD command to load a  sequential  file  into  the
-   database.
+   The run-time system also invokes auto-ZLINKing when an M command, in a
+   program or in Direct Mode, refers to a routine that is not part of the
+   current image.
 
-   Because MUPIP uses the  environment  variable  gtmgbldir  to  locate  a
-   Global Directory, which  identifies  the  database  file(s),  the  LOAD
-   command does not require any information  about  the  target  database.
-   With few exceptions, the GT.M utilities work in the same way.
+   M commands and functions that may initiate auto-ZLINKing are:
 
-        For general information on shareable libraries in HP-UX,  refer  to
-        the "Programming on HP-UX" manual.
-        Refer to the documentation accompanying AIX for more information on
-        shareable libraries on AIX.
+     * DO
+     * GOTO
+     * ZBREAK
+     * ZGOTO
+     * ZPRINT
+     * $TEXT()
 
-   entryref: return-value routine-name
+   GT.M auto-ZLINKs the routine only under these conditions:
 
-   (parameter, parameter, ..)
-   where entryref is an M entryref,
+   $ZROUTINES is a read-write special variable that contains a directory
+   search path used by ZLINK and auto-ZLINK to locate source and object
+   files.
 
-   return-value is xc_long_t, xc_status_t, or void
+   When the argument to a ZLINK command includes a pathname, $ZSOURCE
+   maintains that pathname as a default for ZEDIT and ZLINK. $ZSOURCE is a
+   read-write special variable.
 
-   and parameter are in the format: direction:type.
+   Once you use the ZEDIT or ZLINK commands, $ZSOURCE can contain a partial
+   file specification. The partial file specification can be a directory path
+   (full or relative), a file name, and a file extension. You can set
+   $ZSOURCE with an M SET command. A ZLINK without an argument is equivalent
+   to ZLINK $ZSOURCE.
 
-   len: void length (I:xc_float_t*, o:xc_float_t*)
+   For additional information on $ZSOURCE and $ZROUTINES, refer to Chapter 8:
+   "ISV".
 
    Example:
 
-   % echo $GTMXC_mathpak
-
-2 Cre_Edt_Source_Prog
-   Creating and Editing a Source Program
-
-   The first step in developing a GT.M program is to create a source file.
-   In most cases, the user can create  and  modify  GT.M  source  programs
-   using UNIX text editors.
-
-   When the program is very simple (and its lines  do  not  need  revision
-   after they are entered), you can use the cat command  to  direct  input
-   from your terminal to your source file.
-
-3 Edit_from_GTM
-   Editing from GT.M
-
-   Invoke Direct Mode to create and edit a source program in GT.M. At the
-   GTM> prompt, invoke the editor by typing:
-
-   ZEDIT <filename>
-
-   ZEDIT invokes the editor specified by the EDITOR environment variable,
-   which creates a seperate file for each M source module.
-
-   The GT.M environment works most efficiently if the file  has  the  same
-   name as the M routine it contains, and has an .m extension. Since ZEDIT
-   automatically defaults the.m extension, it is not necessary to specify
-   an extension unless you require a different one.  If  you  use  another
-   extension, you must specify that extension with every reference to the
-   file. Multiple character file extensions are  permitted  for  M  source
-   file names.
-
-3 Edit_from_Shell
-   Editing from the Shell
-
-   To create and edit a source program from the  shell,  invoke  any  text
-   editor at the shell prompt and specify a UNIX file as the  source.  The
-   GT.M environment works best when you give a file  the  name  of  the  M
-   routine that it contains, and an .m extension.
-
-   Example:
-
-   $ vi payroll.m
-
-   The vi command initiates an editing  session  for  payroll.m  from  the
-   shell prompt. If payroll.m does  not  already  exist,  vi  creates  it.
-   Because this example uses UNIX rather than GT.M tools, we must specify
-   the .m file extension.
-
-2 Comp_Source_Prog
-   Compiling a Source Program
-
-   GT.M compiles M  source  code  files  and  produces  object  files  for
-   complete integration into the UNIX enviroment. The object modules have
-   the same name as the compiled M source file with an .o file extension,
-   unless  otherwise  specified.  The  object  files  contain  machine
-   instructions and information necessary  to  connect  the  routine  with
-   other routines, and map it into memory. An M routine source  file  must
-   be compiled after it is created or modified. You can compile explicitly
-   with the ZLINK command or implicitly  with  auto-ZLINK.  At  the  shell
-   command line, compile by issuing the mumps command.
-
-   The compiler checks  M  code  for  syntax  errors  and  displays  error
-   messages on the terminal,  when  processing  is  complete.  Each  error
-   message provides the source line in error with an indicator pointing to
-   the place on the line where the error is  occurring.  For  a  list  and
-   description of the compiler error messages, refer to the  GT.M  Message
-   and Recovery Procedures Reference Manual.
-
-   You can generate a listing  file  containing  the  compile  results  by
-   including the
-   -list qualifier as a modifier to the argument to the ZLINK  command  in
-   Direct Mode. This can also be done by redirecting the compiler messages
-   to a file by adding >filename 2>&1 to the mumps command when compiling
-   a program from the shell. Refer  to  the  "Compiling  from  the  Shell"
-   section for an explanation of the M command describing -list, and other
-   valid qualifiers for the M and ZLINK commands.
-
-   The compiler stops processing a routine line when it detects  an  error
-   on that line. Under most conditions the compiler  continues  processing
-   the remaining routine lines. This allows the compiler to produce a more
-   complete error analysis of the routine and to generate  code  that  may
-   have valid executable paths. The  compiler  does  not  report  multiple
-   syntax errors on the same line. When it detects more  than  127  syntax
-   errors in a source file, the compiler ceases to process the file.
-
-3 Comp_from_GTM
-   Compiling from GT.M
-
-   In Direct Mode, GT.M provides access to the compiler explicitly through
-   the ZLINK and  ZCOMPILE  commands,  and  implicitly  through  automatic
-   invocation of ZLINK functionality (auto-ZLINK) to add required routines
-   to the image. ZCOMPILE  is  a  GT.M  routine  compilation  command,  it
-   compiles the routine and creates a new object module. The primary task
-   of ZLINK is to place the object code in memory and  "connect"  it  with
-   other routines. However, under certain circumstances, ZLINK  may  first
-   use the GT.M compiler to create a new object module.
-
-   The difference between ZCOMPILE and ZLINK is that  ZCOMPILE  creates  a
-   new object module on compiling, whereas the  ZLINK  command  links  the
-   object module with other routines and places the object code in memory.
-
-
-   ZLINK compiles under these circumstances:
-
-   o    ZLINK cannot locate a copy of the object module but  can  locate  a
-        copy of the source module.
-
-   o    ZLINK can locate both object  and  source  module,  and  finds  the
-        object module to be older than the source module.
-
-   o    The file-specification portion of the ZLINK  argument  includes  an
-        explicit extension of .m.
-
-   Auto-ZLINK compiles under the first two circumstances,  but  can  never
-   encounter the last one.
-
-   When a command refers to an M routine that is not part of  the  current
-   image, GT.M automatically attempts to ZLINK and, if necessary, compile
-   that routine. In Direct Mode, the most  common  method  to  invoke  the
-   compiler through an auto-ZLINK is to enter DO ^routinename at the GTM>
-   prompt. When the current image does not contain the routine, GT.M does
-   the following:
+   GTM>ZLINK "taxes"
 
-   o    Locates the source and object
+   If ZLINK finds taxes.m or taxes.o, the command adds the routine taxes to
+   the current image. When ZLINK cannot locate taxes.o, or when it finds
+   taxes.o is older than taxes.m, it compiles taxes.m, producing a new
+   taxes.o. Then, it adds the contents of the new object file to the image.
 
-   o    Determines whether the source has been edited  since  it  was  last
-        compiled
+3 Locate_Source_Directory
+   Locate Source Directory
+
+   A ZLINK command that does not specify a directory uses $ZROUTINES to
+   locate files. When $ZROUTINES is null, ZLINK uses the current directory.
+   $ZROUTINES is initialized to the value of the gtmroutines environment
+   variable.
 
-   o    Compiles the routine, if appropriate
+   When the file being linked includes an explicit directory, ZLINK and
+   auto-ZLINK searches only that directory for both the object and the source
+   files. If compilation is required, ZLINK places the new object file in the
+   named directory.
 
-   o    Adds the object to the image
+   A subsequent ZLINK searching for this object file will never find the
+   object file in the specified directory unless the directory is added to
+   the search path in $ZROUTINES, or the object file is moved to another
+   directory already in the search path.
 
-   By using the DO command, you implicitly instruct GT.M to compile, link,
-   and execute the program. With this method, you can  test  your  routine
-   interactively.
+   ZLINK cannot change a currently active routine, (e.g., a routine displayed
+   in a ZSHOW "S" of the stack). ZLINK a currently active routine by first
+   removing it from the M stack, using ZGOTO, or one or more QUITs.
 
-   For complete  descriptions  of  ZLINK  and  auto-ZLINK,  refer  to  the
-   "Commands" chapter in GT.M Programmer's Guide.
+   To maintain compatibility with other editions of GT.M that do not permit
+   the percent sign (%) in a file name, GT.M uses an underscore (_) in place
+   of the percent in the file name.
 
    Example:
 
+   GTM>zlink "_MGR"
 
-   GTM>do ^payroll
+   This ZLINK links the M routine %MGR into the current image.
 
-   GTM>do ^taxes
+2 Execute_from_Shell
+   Execute from Shell
 
-   This uses the M DO command to invoke the GT.M compiler implicitly from
-   the GTM> prompt if the routine  requires  new  object  code.  When  the
-   compiler runs, it produces  two  object  module  files,  payroll.o  and
-   taxes.o.
-
-   If you receive error messages from the compilation, you  may  fix  them
-   immediately by returning to the editor and correcting  the  source.  By
-   default, the GT.M compiler operates in "compile-as-written"  mode,  and
-   produces object code even when a routine contains syntax  errors.  This
-   code includes all lines that are correct and all  commands  on  a  line
-   with an error, up to the error. Therefore, you may decide to tailor the
-   debugging cycle by running the  program  without  removing  the  syntax
-   errors.
+   You can run a program from the shell prompt using the following command:
 
-3 Comp_from_Shell
-   Compiling from the Shell
+   $ mumps -run ^filename
 
-   From the shell, invoke the compiler by entering mumps file-name at the
-   shell prompt.
+   The mumps command searches the directories specified by the environment
+   variable gtmroutines to locate the specified file name.
 
    Example:
 
+   $ mumps -run ^payroll
 
-   $ mumps payroll.m
-
-   $ mumps taxes.m
-
-   This uses the mumps command to invoke the GT.M compiler from the shell
-   prompt, and creates .o versions of these files.
-
-   Use the mumps command at the shell prompt to:
-
-   o    Check the syntax of a newly entered program.
-
-   o    Optionally, get a formatted listing of the program.
-
-   o    Ensure that all object code is up to date before linking.
-
-   The mumps command invokes the compiler to translate an  M  source  file
-   into object code.
-
-   The format for the MUMPS command is:
-
-   MUMPS [-qualifier[...]] pathname
-
-   o    Source programs must have an extension of .m.
-
-   o    Each pathname identifies an M source program to compile.
-
-   o    Qualifiers determine characteristics of the compiler output.
-
-   o    Qualifiers must appear after the command, but before the file name
-        to be properly applied.
+   This executes a routine named payroll.
 
-   o    GT.M allows the UNIX * and ? wildcards in a file name.
+2 Processing_Errors
+   Processing Errors
 
-   The * wildcard accepts any legal combination of numbers and characters
-   including a null, in the position the wildcard holds.
-   The ? wildcard accepts exactly one legal character in its position.
-
-   For example, mumps *.m  compiles  all  files  in  the  current  default
-   directory with an .m extension. mumps *pay?.m compiles  .m  files  with
-   names that contain any characters followed  by  pay,  followed  by  one
-   character. Unlike when using ZLINK or ZCOMPILE, the  filename  must  be
-   fully specified when compiling from the shell.
+   +------------------------------------------------------------------------+
+   |         |  Executing in Direct  | Executing from the Shell (mumps -run |
+   |         |         Mode          |              ^routine)               |
+   |---------+-----------------------+--------------------------------------|
+   |         | Suitable for          |                                      |
+   | Usage   | development and       | Suitable for production.             |
+   |         | debugging.            |                                      |
+   |---------+-----------------------+--------------------------------------|
+   |         | Not invoked for code  | Errors are suppressed and cause a    |
+   |         | entered at the direct | silent process exit. Set the         |
+   |         | mode prompt; Note     | environment variable gtm_etrap which |
+   |         | that XECUTE code is   | overrides the default $ZTRAP="B".    |
+   |         | treated as not        |                                      |
+   | Error   | entered at the direct | If needed, error handlers can        |
+   | Handler | mode prompt           | include appropriate error            |
+   |         |                       | notification to $PRINCIPAL. For      |
+   |         | The default           | example, the gtmprofile script sets  |
+   |         | $ZTRAP="B" brings a   | a default $ETRAP value of            |
+   |         | process to the Direct | "Write:(0=$STACK) ""Error occurred:  |
+   |         | Mode for debugging.   | "",$ZStatus,!" which you can         |
+   |         |                       | customize to suit your needs.        |
+   |---------+--------------------------------------------------------------|
+   |         | GT.M processes send error messages to stderr only under the  |
+   |         | following conditions:                                        |
+   |         |                                                              |
+   |         |   * The error is fatal which means that the process is about |
+   | stderr  |     to terminate                                             |
+   |         |   * During compilation except of indirection or XECUTE       |
+   |         |   * The process is about to enter direct mode due to a BREAK |
+   |         |     command                                                  |
+   |         |   * The erroneous code was entered at the direct mode prompt |
+   +------------------------------------------------------------------------+
 
 1 Opr_Dbg_Dir_Mode
-   Operating and Debugging in Direct Mode
+   Opr Dbg Dir Mode
 
-   Direct Mode is an important tool in  GT.M  because  it  allows  you  to
-   interactively debug, modify, and execute M routines. Direct Mode  is  a
+   Direct Mode is an important tool in GT.M because it allows you to
+   interactively debug, modify, and execute M routines. Direct Mode is a
    shell that immediately compiles and executes GT.M commands providing an
-   interpretive-like interface. M simplifies debugging by using  the  same
+   interpretive-like interface. M simplifies debugging by using the same
    commands for debugging that are used for programming.
 
-   The focus of this chapter is  to  describe  the  debugging  process  in
-   Direct Mode, and  to  illustrate  the  GT.M  language  extensions  that
-   enhance the process. Command functionality is described only in enough
-   detail to illustrate why a particular command is useful for a debugging
-   activity being described. If you have specific functionality questions
-   about a command or variable, refer to the  "Commands",  "Functions"  or
-   "Intrinsic Special Variables" chapters in GT.M Programmer's Guide.
+2 Operate_Direct_Mode
+   Operate Direct Mode
 
-2 Opr_Dir_Mode
-   Operating in Direct Mode
-
-   This section provides an overview of the  following  basic  operational
+   This section provides an overview of the following basic operational
    issues in Direct Mode:
 
-   o    Entering Direct Mode
-
-   o    Available functionality
+     * Entering Direct Mode
+     * Available functionality
+     * Exiting Direct Mode
 
-   o    Exiting Direct Mode
-
-3 Entr_Dir_Mode
+3 Entering_Direct_Mode
    Entering Direct Mode
 
    To enter Direct Mode, type $gtm_dist/mumps -direct at the shell prompt.
 
-   Example:
-
-
    $ $gtm_dist/mumps -direct
-
    GTM>
 
    This shows using $gtm_dist/mumps -direct at the prompt to enter Direct
    Mode.
 
-   To create a gtm alias in your shell startup file (in the example below
-   the startup file is assumed to be a .profile file):
+   To create a gtm alias in your shell startup file (in the example below the
+   startup file is assumed to be a .profile file):
+
+    1. Open an edition session for your .profile file by typing:
 
-   o    Open an edition session for your .profile file by typing:
-	$vi .profile
+       $vi .profile
 
-   o    Add a function to the file to define your gtm alias
-   o    	gtm()
-	{
-	  $gtm_dist/mumps -direct
-	}
+    2. Add a function to the file to define your gtm alias:
 
-   o    save the file.
+       gtm(){ $gtm_dist/mumps -direct}
 
-   Now, when you want to enter Direct Mode for  an  editing  or  debugging
+    3. save the file.
+
+   Now, when you want to enter Direct Mode for an editing or debugging
    session, simply type gtm at the shell prompt.
 
    Example:
 
    $ gtm
-
    GTM>
 
-   This shows that the gtm alias typed at the shell prompt also takes you
-   to the Direct Mode.
+   This shows that the gtm alias typed at the shell prompt also takes you to
+   the Direct Mode.
 
-3 Func_in_Dir_Mode
+3 Functionality_Available_in_Direct_Mode
    Functionality Available in Direct Mode
 
-   This section provides an overview of basic functionality  and  concepts
-   that enhance your use of Direct Mode.
+   This section provides an overview of basic functionality and concepts that
+   enhance your use of Direct Mode.
 
-4 Comm_Recall
+4 Command_Recall
    Command Recall
 
-   Direct  Mode  includes  a  line  command  recall  function  to  display
-   previously entered command lines. Use the Up  Arrow  key  at  the  GTM>
-   prompt to scroll back through command lines. Usethe Down Arrow  key  to
-   scroll forward through the command lines.  GT.M  displays  one  command
-   line at a time. You may delete and reenter characters starting  at  the
-   end of a recalled line.
+   Direct Mode includes a line command recall function to display previously
+   entered command lines. Use <CTRL-B> or the Up Arrow key at the GTM> prompt
+   to scroll back through command lines. Use the Down Arrow key to scroll
+   forward through the command lines. GT.M displays one command line at a
+   time.You may delete and reenter characters starting at the end of a
+   recalled line.
 
-   The RECALL command is another way to access previously  entered  Direct
-   Mode command lines. RECALL is only valid in Direct Mode and  causes  an
-   error if it appears in other M code.
-
-   The format of the
-   RECALL command is:
+   The RECALL command is another way to access previously entered Direct Mode
+   command lines. RECALL is only valid in Direct Mode and causes an error if
+   it appears in other M code.
 
+   The format of the RECALL command is:
 
    REC[ALL] [intlit|strlit]
 
-   o    The optional integer literal specifies a previously entered command
-        by the counting back from the present.
-
-   o    The optional string literal specifies  the  most  recently  entered
-        command  line  that  starts  with  characters  matching  the
-        (case-sensitive) literal.
-
-   o    When the RECALL command has  no  argument,  it  displays  up  to  a
-        maximum of 99 available past Direct Mode entries.
-
-   If the Direct Mode session has just started, you may not  have  entered
-   99 lines for GT.M to save and therefore you will not have 99  lines  to
-   look at. The most recently entered GT.M command line has the number one
-   (1), older lines have higher numbers. GT.M does not include the RECALL
-   command in the listing. If the RECALL command is issued from a location
-   other than the Direct Mode prompt, GT.M issues a run-time error.
+   If the Direct Mode session has just started, you may not have entered 99
+   lines for GT.M to save and therefore you will not have 99 lines to look
+   at. The most recently entered GT.M command line has the number one (1),
+   older lines have higher numbers. GT.M does not include the RECALL command
+   in the listing. If the RECALL command is issued from a location other than
+   the Direct Mode prompt, GT.M issues a run-time error.
 
    Example:
 
+   GTM>write $zgbldir
+   /usr/lib/fis-gtm/V5.4-002B_x86/mumps.gld
+   GTM>set $zgbldir="test.gld"
 
-   GTM>WRITE $ZGBLDIR
-
-   M.GLD
+   GTM>set a=10
 
-   GTM>SET $ZGBLDIR TEST.GLD
+   GTM>set b=a
 
-   GTM>SET A=10
+   GTM>recall
 
-   GTM>SET B=A
+   1 set b=a
+   2 set a=10
+   3 set $zgbldir="test.gld"
+   4 write $zgbldir
 
-   GTM>REC
+   GTM>
 
-   1 SET B=A
-   2 SET A=10
-   3 SET $ZGBLDIR TEST.GLD
-   4 WRITE $ZGBLDIR
    This REC[ALL] command displays the previously entered commands.
 
    You can also display a selected command by entering RECALL and the line
@@ -686,31 +1789,25 @@ $ export env_variable
 
    Example:
 
-
-   GTM>REC 2
-
-   GTM>SET A=10
+   GTM>recall 2
+   GTM>set a=10
 
    This RECALLs the line number two (2).
 
-   If the RE[CALL] command includes a text parameter,  GT.M  displays  the
-   most recent command matching the text after the RE[CALL] command.
+   If the RE[CALL] command includes a text parameter, GT.M displays the most
+   recent command matching the text after the RE[CALL] command.
 
    Example:
 
+   GTM>recall write
+   GTM>write $zgbldir
 
-   GTM>REC WRITE
-
-   GTM>WRITE $ZGBLDIR
-
-   MUMPS.GLD
-
-   This RECALLs "WRITE", the command most  recently  beginning  with  this
-   text. Note that the RECALL command text is case sensitive.  The  RECALL
-   command with a text argument treats WRITE and write  differently,  that
-   is, it treats them case  sensitively.  If  you  first  type  the  WRITE
-   command in lower-case and then type WRITE in upper-case to  recall  it,
-   the RECALL command does not find a match.
+   This RECALLs "WRITE", the command most recently beginning with this text.
+   Note that the RECALL command text is case sensitive. The RECALL command
+   with a text argument treats WRITE and write differently, that is, it
+   treats them case sensitively. If you first type the WRITE command in
+   lower-case and then type WRITE in upper-case to recall it, the RECALL
+   command does not find a match.
 
 4 Line_Editing
    Line Editing
@@ -721,846 +1818,625 @@ $ export env_variable
 
    The GT.M Direct Mode line editing keys are as follows:
 
+   Backspace: Deletes the character to the left of the cursor
+
+   Delete: Same as backspace
+
+   Up-arrow: Moves to a less recent item in the RECALL list
+
+   Down-arrow: Moves to a more recent item in the RECALL list
+
+   Left-arrow: Moves the cursor one character to the left
+
+   Right-arrow: Moves the cursor one character to the right
 
-        Backspace Deletes the character to the left of the cursor
-        Delete Same as backspace
-        Up-arrow Moves to a less recent item in the RECALL list
-        Down-arrow Moves to a more recent item in the RECALL list
-        Left-arrow Moves the cursor one character to the left
-        Right-arrow Moves the cursor one character to the right
-        <CTRL-A> Moves the cursor to the beginning of the line
-        <CTRL-B> Moves the cursor one character towards  the  beginning  of
-        the line
-        <CTRL-D> Deletes the character at the cursor position
-        <CTRL-E> Moves the cursor to the end of the line
-        <CTRL-F> Moves the cursor one character towards the end of the line
-        <CTRL-K> Deletes all characters from the cursor to the end  of  the
-        line
-        <CTRL-U> Deletes the entire line
-4 M_Invo_Stack
+   <CTRL-A>: Moves the cursor to the beginning of the line
+
+   <CTRL-B>: Moves the cursor one character towards the beginning of the line
+
+   <CTRL-D>: On an empty line, terminates GT.M and returns control to the
+   shell.
+
+   <CTRL-E>: Moves the cursor to the end of the line
+
+   <CTRL-F>: Moves the cursor one character towards the end of the line
+
+   <CTRL-K>: Deletes all characters from the cursor to the end of the line
+
+   <CTRL-U>: Deletes the entire line
+
+   **Note**
+
+   When entering commands at the direct mode prompt, the insert mode can be
+   toggled for that line by using the insert key. When GT.M starts, insert
+   mode is enabled unless the value of the gtm_principal_editing environment
+   variable includes the string NOINSERT. If insert mode is disabled or
+   enabled for the $PRINCIPAL device by an USE statement before returning to
+   direct mode, it will remain disabled or enabled at direct mode. The insert
+   mode can be toggled within a direct mode line using the terminal's INSERT
+   key.
+
+4 The_M_Invocation_Stack
    The M Invocation Stack
 
-   The ANSI M Standard describes certain M operations in terms  of  how  a
+   The ANSI M Standard describes certain M operations in terms of how a
    stack-based virtual machine would operate. A stack is a repository for
    tracking temporary information on a "last-in/first-out" (LIFO) basis. M
-   program behavior can be understood using a stack-based model. However,
-   the standard is not explicit in defining  how  an  implementation  must
-   maintain a stack or even whether it must use one at all.
+   program behavior can be understood using a stack-based model. However, the
+   standard is not explicit in defining how an implementation must maintain a
+   stack or even whether it must use one at all.
 
    The stack model provides a trail of routines currently in progress that
-   shows  the  location  of  all  the  M  operations  that  performed  the
-   invocations leading to the current point.
-
-3 Exit_Dir_Mode
-   Exiting Direct Mode
+   shows the location of all the M operations that performed the invocations
+   leading to the current point.
 
-   Four M commands terminate a Direct Mode session:
+   The ZSHOW command makes this stack information available within GT.M.
 
-   o    HALT
+3 Exiting_Direct_Mode
+   Exiting Direct Mode
 
-   o    ZCONTINUE
+   Five M commands can terminate a Direct Mode session:
 
-   o    GOTO
+     * HALT
+     * ZHALT
+     * ZCONTINUE
+     * GOTO
+     * ZGOTO
 
-   o    ZGOTO
+   The HALT command exits Direct Mode and terminates the M process.
 
-   The
-   HALT command exits Direct Mode and terminates the M process.
+   The ZHALT command exits Direct Mode and returns the exit status to the
+   calling environment.
 
-   The
-   ZCONTINUE command instructs GT.M to exit Direct Mode and resume routine
-   execution at the current point in the M invocation stack. This  may  be
-   the point where GT.M interrupted execution  and  entered  Direct  Mode.
-   However, when the Direct Mode interaction includes a QUIT  command,  it
-   modifies the invocation stack and causes ZCONTINUE to resume execution
-   at another point.
+   The ZCONTINUE command instructs GT.M to exit Direct Mode and resume
+   routine execution at the current point in the M invocation stack. This may
+   be the point where GT.M interrupted execution and entered Direct Mode.
+   However, when the Direct Mode interaction includes a QUIT command, it
+   modifies the invocation stack and causes ZCONTINUE to resume execution at
+   another point.
 
-   The
-   GOTO and
-   ZGOTO commands instruct GT.M to leave Direct Mode, and transfer control
-   to a specified entry reference.
+   The GOTO and ZGOTO commands instruct GT.M to leave Direct Mode, and
+   transfer control to a specified entry reference.
 
-2 Debug_Rtn_Dir_Mode
-   Debugging a Routine in Direct Mode
+2 Debug_Routine
+   Debug Routine
 
    To begin a debugging session on a specific routine, type the following
    command at the GTM prompt:
 
-
    GTM>DO ^routinename
 
-   You can also begin a  debugging  session  by  pressing  <CTRL-C>  after
-   running an M application  at  the  shell.  To  invoke  Direct  Mode  by
-   pressing <CTRL-C>, process  must  have  the  Principal  Device  in  the
-   CENABLE state and not have the device set to CTRAP=$C(3).
+   You can also begin a debugging session by pressing <CTRL-C> after running
+   an M application at the shell. To invoke Direct Mode by pressing <CTRL-C>,
+   process must have the Principal Device in the CENABLE state and not have
+   the device set to CTRAP=$C(3).
 
-   When GT.M receives a <CTRL-C> command from  the  principal  device,  it
-   invokes Direct Mode at  the  next  opportunity,  (usually  at  a  point
+   When GT.M receives a <CTRL-C> command from the principal device, it
+   invokes Direct Mode at the next opportunity, (usually at a point
    corresponding to the beginning of the next source line). GT.M can also
    interrupt at a FOR loop iteration or during a command of indeterminate
-   duration such as  JOB,  LOCK,  OPEN  or  READ.  The  GT.M  USE  command
-   enables/disables  the  <CTRL-C>  interrupt  with  the  [NO]CENABLE
-   deviceparameter. By default, GT.M starts <CTRL-C> enabled. The default
-   setting for <CTRL-C> handling is controlled by GTM$DEFAULTS.M64 and is
-   enabled in the distribution version of that file.
-
-   GT.M displays the GTM> prompt on  the  principal  device.  Direct  Mode
-   accepts commands from, and reports errors  to,  the  principal  device.
-   GT.M uses the current device for all other I/O. If the  current  device
-   does not match the principal device when GT.M enters Direct Mode, GT.M
-   issues a warning message on the principal device. A USE command changes
-   the current device. For more information on the USE command,  refer  to
-   the "Input/Output Processing" chapter.
-
-   The default "compile-as-written" mode of the GT.M compiler lets you run
-   a program with errors as part of the debugging cycle. The  object  code
-   produced includes all lines that are correct and all commands on a line
-   with an error, up to the error.  When  GT.M  encounters  an  error,  it
-   XECUTEs non empty  values  of  $ETRAP  or  $ZTRAP.  By  default  $ZTRAP
-   contains a BREAK command, so GT.M enters Direct Mode.
+   duration such as LOCK, OPEN or READ. The GT.M USE command enables/disables
+   the <CTRL-C> interrupt with the [NO]CENABLE deviceparameter. By default,
+   GT.M starts <CTRL-C> enabled. The default setting for <CTRL-C> is
+   controlled by $gtm_nocenable which controls whether <CTRL-C> is enabled at
+   process startup. If $gtm_nocenable has a value of 1, "TRUE" or "YES"
+   (case-insensitive), and the process principal device is a terminal,
+   $PRINCIPAL is initialized to a NOCENABLE state where the process does not
+   recognize <CTRL-C> as a signal to enter direct mode. No value, or other
+   values of $gtm_nocenable initialize $PRINCIPAL with the CENABLE state. The
+   [NO]CENABLE deviceparameter on a USE command can still control this
+   characteristic from within the process.
 
-   The rest of the chapter illustrates the debugging capabilities of GT.M
-   by taking a sample routine, dmex, through the debugging  process.  dmex
-   is intended to read and edit a name, print the last and first name, and
-   terminate if the name is an upper-case or lower-case "Q".
+   Each of the remaining sections of the chapter uses dmex to illustrate an
+   aspect of the debugging process in GT.M.
 
-   Each of the remaining sections of the chapter uses dmex  to  illustrate
-   an aspect of the debugging process in GT.M.
+3 _Routines
+    Routines
 
-3 Creat_Display_M_Rtn
-   Creating and Displaying M Routines
-
-   To create or edit a routine, use the
-   ZEDIT command.  ZEDIT  invokes  the  editor  specified  by  the  EDITOR
-   environment  variable,  and  opens  the  specified  file.  dmex.m,  for
-   editing.
+   To create or edit a routine, use the ZEDIT command. ZEDIT invokes the
+   editor specified by the EDITOR environment variable, and opens the
+   specified file. dmex.m, for editing.
 
    Example:
 
-
    GTM>ZEDIT "dmex"
 
    Once in the editor, use the standard editing commands to enter and edit
-   text. When you finish editing, save the changes, which returns  you  to
+   text. When you finish editing, save the changes, which returns you to
    Direct Mode.
 
-        For further details and examples, refer to  the  GT.M  Programmer's
-        Guide.
+   **Note**
+
+   For further details and examples, refer to the GT.M Programmer's Guide.
+
+   GTM>ZPRINT ^dmex
+   dmex;dmex - Direct Mode example
+   ;
+   beg   for  read !,"Name: ",name do name
+         quit
+
+   name  set ln=$l(name)
+         if ln,$extract("QUIT",1,ln)=$tr(name,"quit","QUIT") do quit
+         . s name="Q"
+         if ln<30,bame?1.a.1"-".a1","1" "1a.ap do print quit
+         write !,"Please use last-name, "
+         write "first-name middle-initial or 'Q' to Quit."
+         quit
+   print write !,$piece(name,", ",2)," ",$piece(name,", ")
+         quit
+   GTM>
+
+   This uses the ZPRINT command to display the routine dmex.
+
+   **Note**
 
-3 Exec_M_Rtn_Inter
+   The example misspells the variable name as bame.
+
+3 Executing_M_Routines_Interactively
    Executing M Routines Interactively
 
-   To  execute  an  M  routine  interactively,  it  is  not  necessary  to
-   explicitly compile and link your  program.  When  you  refer  to  an  M
-   routine that is not part  of  the  current  image,  GT.M  automatically
-   attempts to compile and
+   To execute an M routine interactively, it is not necessary to explicitly
+   compile and link your program. When you refer to an M routine that is not
+   part of the current image, GT.M automatically attempts to compile and
    ZLINK the program.
 
    Example:
 
-
    GTM>DO ^dmex
-
    Name: Revere, Paul
-
    %GTM-E-UNDEF, Undefined local variable: bame
-
    At M source location name+3^dmex
-
    GTM>
 
    In this example GT.M places you in Direct Mode, but also cites an error
    found in the program with a run-time error message. In this example, it
    was a reference to bame, which is undefined.
 
-   To see additional information about the error message, examine the
-   $ECODE or
-   $ZSTATUS special variables.
+   To see additional information about the error message, examine the $ECODE
+   or $ZSTATUS special variables.
 
-   $ECODE is read-write intrinsic special variable that maintains  a  list
-   of comma delimited codes that describe a history of past errors  -  the
-   most recent ones appear at the end of the  list.  In  $ECODE,  standard
-   errors are prefixed with an "M", user defined errors with  a  "U",  and
-   GT.M errors with a "Z". A GT.M code always follows a standard code.
+   $ECODE is read-write intrinsic special variable that maintains a list of
+   comma delimited codes that describe a history of past errors - the most
+   recent ones appear at the end of the list. In $ECODE, standard errors are
+   prefixed with an "M", user defined errors with a "U", and GT.M errors with
+   a "Z". A GT.M code always follows a standard code.
 
-   $ZSTATUS is a read-write intrinsic special variable  that  maintains  a
-   string containing the error condition code and  location  of  the  last
-   exception condition occurring during routine  execution.  GT.M  updates
-   $ZSTATUS only for errors found in routines and not for  errors  entered
-   at the Direct Mode prompt.
+   $ZSTATUS is a read-write intrinsic special variable that maintains a
+   string containing the error condition code and location of the last
+   exception condition occurring during routine execution. GT.M updates
+   $ZSTATUS only for errors found in routines and not for errors entered at
+   the Direct Mode prompt.
 
-        For further details and examples, refer to  the  GT.M  Programmer's
-        Guide.
-
-3 Proc_with_Runtime_Syn_Err
+3 Processing_with_Run-time_and_Syntax_Errors
    Processing with Run-time and Syntax Errors
 
    When GT.M encounters a run-time or syntax error, it stops executing and
-   displays an error message. GT.M reports the error in  the  message.  In
-   this case, GT.M reports an undefined local variable  and  the  line  in
-   error, name+3^dmex. Note that GT.M re-displays the GTM> prompt so that
-   debugging may continue.
+   displays an error message. GT.M reports the error in the message. In this
+   case, GT.M reports an undefined local variable and the line in error,
+   name+3^dmex. Note that GT.M re-displays the GTM> prompt so that debugging
+   may continue.
 
-   To re-display the line and identify the error, use the
-   ZPRINT command.
+   To re-display the line and identify the error, use the ZPRINT command.
 
    Example:
 
-
    GTM>ZPRINT, name+3
-
-   %GTM-E-SPOREOL, Either a space or an end-of-line was expected  but  not
-   found
+   %GTM-E-SPOREOL, Either a space or an end-of-line was expected but not found
    ZP, name+3
-
    ^_____
-
    GTM>
 
-   This example shows the result of incorrectly entering a ZPRINT command
-   in Direct Mode. GT.M reports the location of the syntax  error  in  the
-   command line with an arrow. $ECODE and $ZSTATUS do  not  maintain  this
-   error message because GT.M did not produce the message  during  routine
-   execution. Enter the  correct  syntax,  (i.e.,  remove  the  comma)  to
-   re-display the routine line in error.
+   This example shows the result of incorrectly entering a ZPRINT command in
+   Direct Mode. GT.M reports the location of the syntax error in the command
+   line with an arrow. $ECODE and $ZSTATUS do not maintain this error message
+   because GT.M did not produce the message during routine execution. Enter
+   the correct syntax, (i.e., remove the comma) to re-display the routine
+   line in error.
 
    Example:
 
-
    GTM>WRITE $ZPOS
-
    name+3^dmex
 
    This example writes the current line position.
 
-   $ZPOSITION is a read-only GT.M special variable that  provides  another
-   tool for locating and displaying the  current  line.  It  contains  the
-   current  entry  reference  as  a  character  string  in  the  format
-   label+offset^routine, where the label is the closest  preceding  label.
-   The current entry reference appears at the top of the
-   M invocation stack, which can also be displayed with a
-   ZSHOW "S" command.
+   $ZPOSITION is a read-only GT.M special variable that provides another tool
+   for locating and displaying the current line. It contains the current
+   entry reference as a character string in the format label+offset^routine,
+   where the label is the closest preceding label. The current entry
+   reference appears at the top of the M invocation stack, which can also be
+   displayed with a ZSHOW "S" command.
 
    To display the current value of every local variable defined, use the
    ZWRITE command with no arguments.
 
    Example:
 
-
    GTM>ZWRITE
-
    ln=12
-
    name="Revere, Paul"
 
-   This ZWRITE displays a listing of all  the  local  variables  currently
+   This ZWRITE displays a listing of all the local variables currently
    defined.
 
-        ZWRITE displays the variable name. ZWRITE does not display a value
-        for bame, confirming that it is not defined.
+   **Note**
+
+   ZWRITE displays the variable name. ZWRITE does not display a value for
+   bame, confirming that it is not defined.
 
 3 Correcting_Errors
    Correcting Errors
 
-   Use the
-   ZBREAK command to establish  a  temporary  breakpoint  and  specify  an
-   action. ZBREAK sets or clears  routine-transparent  breakpoints  during
-   debugging. This command simplifies debugging by interrupting execution
-   at a specific point to examine variables, execute commands, or to start
-   using
+   Use the ZBREAK command to establish a temporary breakpoint and specify an
+   action. ZBREAK sets or clears routine-transparent breakpoints during
+   debugging. This command simplifies debugging by interrupting execution at
+   a specific point to examine variables, execute commands, or to start using
    ZSTEP to execute the routine line by line.
 
-   GT.M suspends execution  during  execution  when  the  entry  reference
-   specified by ZBREAK is encountered. If the ZBREAK does not  specify  an
-   expression "action", the process uses the default,
-   BREAK, and puts GT.M into Direct Mode. If the ZBREAK  does  specify  an
-   expression "action", the process XECUTEs the  value  of  "action",  and
-   does not enter Direct Mode unless the  action  includes  a  BREAK.  The
-   action serves as a "trace-point". The trace-point is silent unless the
-   action specifies terminal output.
+   GT.M suspends execution during execution when the entry reference
+   specified by ZBREAK is encountered. If the ZBREAK does not specify an
+   expression "action", the process uses the default, BREAK, and puts GT.M
+   into Direct Mode. If the ZBREAK does specify an expression "action", the
+   process XECUTEs the value of "action", and does not enter Direct Mode
+   unless the action includes a BREAK. The action serves as a "trace-point".
+   The trace-point is silent unless the action specifies terminal output.
 
    Example:
 
-
    GTM>ZBREAK name+3^dmex:"set bame=name"
 
    This uses a ZBREAK with an action that SETs the variable bame equal to
    name.
 
-3 Stepping_Thru_Rtn
+3 Stepping_Through_a_Routine
    Stepping Through a Routine
 
-   The
-   ZSTEP command provides a powerful tool to direct GT.M  execution.  When
-   you issue a ZSTEP from Direct Mode, GT.M executes the  program  to  the
+   The ZSTEP command provides a powerful tool to direct GT.M execution. When
+   you issue a ZSTEP from Direct Mode, GT.M executes the program to the
    beginning of the next target line and performs the ZSTEP action.
 
-   The optional keyword portion of the argument  specifies  the  class  of
-   lines where ZSTEP pauses its execution, and XECUTEs  the  ZSTEP  action
-   specified by the optional action portion of the ZSTEP argument. If the
-   action is specified, it must be an expression that evaluates  to  valid
-   GT.M code. If no action is specified, ZSTEP XECUTEs the code specified
-   by the $ZSTEP intrinsic special variable; by  default  $ZSTEP  has  the
-   value "B", which causes GT.M to enter Direct Mode.
+   The optional keyword portion of the argument specifies the class of lines
+   where ZSTEP pauses its execution, and XECUTEs the ZSTEP action specified
+   by the optional action portion of the ZSTEP argument. If the action is
+   specified, it must be an expression that evaluates to valid GT.M code. If
+   no action is specified, ZSTEP XECUTEs the code specified by the $ZSTEP
+   intrinsic special variable; by default $ZSTEP has the value "B", which
+   causes GT.M to enter Direct Mode.
 
-   ZSTEP actions, that include commands followed by a BREAK,  perform  the
-   specified action, then enter Direct Mode. ZSTEP  actions  that  do  not
+   ZSTEP actions, that include commands followed by a BREAK, perform the
+   specified action, then enter Direct Mode. ZSTEP actions that do not
    include a BREAK perform the command action and continue execution. Use
-   ZSTEP actions that issue conditional BREAKs and  subsequent  ZSTEPs  to
+   ZSTEP actions that issue conditional BREAKs and subsequent ZSTEPs to
    perform tasks such as test for changes in the value of a variable.
 
-   Use ZSTEP to incrementally execute a routine or a series  of  routines.
+   Use ZSTEP to incrementally execute a routine or a series of routines.
    Execute any GT.M command from Direct Mode at any ZSTEP pause. To resume
    normal execution, use ZCONTINUE. Note that ZSTEP arguments are keywords
    rather than expressions, and they do not allow indirection.
 
    Example:
 
-
    GTM>ZSTEP INTO
-
    Break instruction encountered during ZSTEP action
-
    At M source location print^dmex
-
    GTM>ZSTEP OUTOF
-
    Paul Revere
-
    Name: Q
-
    %GTM-I-BREAKZST, Break instruction encountered during ZSTEP action
-
    At M source location name^dmex
-
    GTM>ZSTEP OVER
-
    Break instruction encountered during ZSTEP action
-
    At M source location name+1^dmex
 
    This example shows using the ZSTEP command to step through the routine
-   dmex,  starting  where  execution  was  interrupted  by  the  undefined
-   variable error.  The  ZSTEP  INTO  command  executes  line  name+3  and
-   interrupts execution at the beginning of line print.
+   dmex, starting where execution was interrupted by the undefined variable
+   error. The ZSTEP INTO command executes line name+3 and interrupts
+   execution at the beginning of line print.
 
-   The ZSTEP OUTOF continues execution until line name.  The  ZSTEP  OVER,
-   which is the default, executes until it encounters  the  next  line  at
-   this level on the M invocation stack. In this case, the  next  line  is
-   name+1. The ZSTEP OVER could be replaced with a ZSTEP with no argument
-   because they do the same thing.
+   The ZSTEP OUTOF continues execution until line name. The ZSTEP OVER, which
+   is the default, executes until it encounters the next line at this level
+   on the M invocation stack. In this case, the next line is name+1. The
+   ZSTEP OVER could be replaced with a ZSTEP with no argument because they do
+   the same thing.
 
-3 Cont_Exec_Frm_Breakpt
+3 Continuing_Execution_From_a_Breakpoint
    Continuing Execution From a Breakpoint
 
-   Use the
-   ZCONTINUE command to continue execution from the breakpoint.
+   Use the ZCONTINUE command to continue execution from the breakpoint.
 
    Example:
 
-
    GTM>ZCONTINUE
-
    Paul Revere
-
    Name: q
-
    Name: QUIT
-
    Name: ?
-
    Please use last-name, first name middle-initial
-
    or 'Q' to Quit.
-
    Name:
 
-   This uses a ZCONTINUE command to resume execution from the point where
-   it was interrupted. As a result of the ZBREAK action, bame  is  defined
-   and the error does not  occur  again.  Because  the  process  does  not
-   terminate as intended when the name read has q as a value, we  need  to
-   continue debugging.
+   This uses a ZCONTINUE command to resume execution from the point where it
+   was interrupted. As a result of the ZBREAK action, bame is defined and the
+   error does not occur again. Because the process does not terminate as
+   intended when the name read has q as a value, we need to continue
+   debugging.
 
-3 Interr_Execution
-   Interruption Execution
+3 Interrupting_Execution
+   Interrupting Execution
 
    Press <CTRL-C> to interrupt execution, and return to the GTM prompt to
    continue debugging the program.
 
    Example:
 
-
    %GTM-I-CTRLC, CTRLC_C encountered.
-
    GTM>
 
    This invokes direct mode with a <CTRL-C>.
 
-3 Using_Invoc_Stac_in_Debug
+3 Using_the_Invocation_Stack_in_Debugging
    Using the Invocation Stack in Debugging
 
-   M DOs, XECUTEs, and extrinsics add a level  to  the  invocation  stack.
+   M DOs, XECUTEs, and extrinsics add a level to the invocation stack.
    Matching QUITs take a level off the stack. When GT.M executes either of
-   these  commands,  an  extrinsic  function,  or  an  extrinsic  special
-   variable, it "pushes" information about  the  new  environment  on  the
-   stack. When GT.M executes the
-   QUIT, it "pops" the information about the discarded environment off the
-   stack. It then reinstates the invoking routine  information  using  the
-   entries that have now arrived at the active end of the stack.
-
-        In the M stack model, a
-        FOR command does not add a stack frame, and a QUIT that terminates
-        a FOR loop does not remove a stack frame.
-
-4 Deter_Levels_of_Nest
+   these commands, an extrinsic function, or an extrinsic special variable,
+   it "pushes" information about the new environment on the stack. When GT.M
+   executes the QUIT, it "pops" the information about the discarded
+   environment off the stack. It then reinstates the invoking routine
+   information using the entries that have now arrived at the active end of
+   the stack.
+
+   **Note**
+
+   In the M stack model, a FOR command does not add a stack frame, and a QUIT
+   that terminates a FOR loop does not remove a stack frame.
+
+4 Determining_Levels_of_Nesting
    Determining Levels of Nesting
 
-   $STACK contains an integer value  indicating  the  "level  of  nesting"
-   caused by DO commands, XECUTE commands, and extrinsic functions in the
-   M virtual stack.
+   $STACK contains an integer value indicating the "level of nesting" caused
+   by DO commands, XECUTE commands, and extrinsic functions in the M virtual
+   stack.
 
-   $STACK has an initial value of zero (0), and  increments  by  one  with
-   each DO,  XECUTE,  or  extrinsic  function.  Any  QUIT  that  does  not
-   terminate a FOR  loop  or  any  ZGOTO  command  decrements  $STACK.  In
-   accordance with the M standard, a FOR command does not increase $STACK.
-   M routines cannot modify $STACK with the SET or KILL commands.
+   $STACK has an initial value of zero (0), and increments by one with each
+   DO, XECUTE, or extrinsic function. Any QUIT that does not terminate a FOR
+   loop or any ZGOTO command decrements $STACK. In accordance with the M
+   standard, a FOR command does not increase $STACK. M routines cannot modify
+   $STACK with the SET or KILL commands.
 
    Example:
 
-
    GTM>WRITE $STACK
-
    2
    GTM>WRITE $ZLEVEL
-
    3
    GTM>
 
-   This example shows the current values for
-   $STACK and
-   $ZLEVEL. $ZLEVEL is like  $STACK  except  that  uses  one  (1)  as  the
-   starting level for the M stack, which $STACK uses zero (0), which means
-   that $ZLEVEL is always one more than $STACK.  Using  $ZLEVEL  with  "Z"
-   commands and functions, and $STACK with standard functions  avoids  the
-   need to calculate the adjustment.
+   This example shows the current values for $STACK and $ZLEVEL. $ZLEVEL is
+   like $STACK except that uses one (1) as the starting level for the M
+   stack, which $STACK uses zero (0), which means that $ZLEVEL is always one
+   more than $STACK. Using $ZLEVEL with "Z" commands and functions, and
+   $STACK with standard functions avoids the need to calculate the
+   adjustment.
 
-4 Look_Invoc_Stack
+4 Looking_at_the_Invocation_Stack
    Looking at the Invocation Stack
 
-   The $STACK intrinsic special variable and the $STACK() function provide
-   a mechanism to access M stack context information.
+   The $STACK intrinsic special variable and the $STACK() function provide a
+   mechanism to access M stack context information.
 
    Example:
 
-
    GTM>WRITE $STACK
-
    2
    GTM>WRITE $STACK(2,"ecode")
-
    ,M6,Z150373850,
-
    GTM>WRITE $STACK(2,"place")
-
    name+3^dmex
-
    GTM>WRITE $STACK(2,"mcode")
-
    if ln<30,bame?1.a.1"-".a1","1" "1a.ap do print q
-
    GTM>
 
-   This example gets the value of $STACK and then uses that value  to  get
-   various types of information about that stack level using the
-   $STACK() function. The "ecode" value of the error information for level
-   two, "place" is similar to
-   $ZPOSITION, "mcode" is the code for the level.
+   This example gets the value of $STACK and then uses that value to get
+   various types of information about that stack level using the $STACK()
+   function. The "ecode" value of the error information for level two,
+   "place" is similar to $ZPOSITION, "mcode" is the code for the level.
 
-   In addition to the $STACK intrinsic special  variable,  which  provides
-   the current stack level, $STACK(-1) gives the highest level  for  which
-   $STACK() can return valid information. Until there is an  error  $STACK
-   and $STACK(-1) are the same, but once
-   $ECODE shows that there is an "current" error, the information returned
-   by $STACK() is frozen to capture the state at the time of the error; it
-   unfreezes after a SET $ECODE="".
+   In addition to the $STACK intrinsic special variable, which provides the
+   current stack level, $STACK(-1) gives the highest level for which $STACK()
+   can return valid information. Until there is an error $STACK and
+   $STACK(-1) are the same, but once $ECODE shows that there is an "current"
+   error, the information returned by $STACK() is frozen to capture the state
+   at the time of the error; it unfreezes after a SET $ECODE="".
 
    Example:
 
-
    GTM>WRITE $STACK
-
    2
    GTM>WRITE $STACK(-1)
-
    2
    GTM>
 
-   This example shows that under the  conditions  created  (in  the  above
+   This example shows that under the conditions created (in the above
    example), $STACK and $STACK(-1) have the same value.
 
    The $STACK() can return information about lower levels.
 
    Example:
 
-
    +1^GTM$DMOD
-
    GTM>WRITE $STACK(1,"ecode")
-
-
    GTM>WRITE $STACK(1,"place")
-
    beg^dmex
-
    GTM>WRITE $STACK(1,"mcode")
-
    beg for read !,"Name:",namde do name
-
    GTM>
 
-   This example shows that there was no error at $STACK level one, as well
-   as the "place" and "mcode" information for that level.
+   This example shows that there was no error at $STACK level one, as well as
+   the "place" and "mcode" information for that level.
 
-4 Using_ZSHOW_Ex_Context_Info
-   Using ZSHOW to Examine Context Information
+3 Transferring_Routine_Control
+   Transferring Routine Control
 
-   The ZSHOW command displays information about the M environment.
+   The ZGOTO command transfers control from one part of the routine to
+   another, or from one routine to another, using the specified entry
+   reference. The ZGOTO command takes an optional integer expression that
+   indicates the M stack level reached by performing the ZGOTO, and an
+   optional entry reference specifying the location to where ZGOTO transfers
+   control. A ZGOTO command, with an entry reference, performs a function
+   similar to the GOTO command with the additional capability of reducing the
+   M stack level. In a single operation, the process executes
+   $ZLEVEL-intexpr, implicit QUITs from DO or extrinsic operations, and a
+   GOTO operation transferring control to the named entry reference.
 
-   Example:
+   The ZGOTO command leaves the invocation stack at the level of the value of
+   the integer expression. GT.M implicitly terminates any intervening FOR
+   loops and unstacks variables stacked with NEW commands, as appropriate.
 
+   ZGOTO $ZLEVEL:LABEL^ROUTINE takes the same action as GO LABEL^ROUTINE.
 
-   GTM>ZSHOW "*"
+   ZGOTO $ZLEVEL-1 produces the same result as QUIT (followed by ZCONTINUE,
+   if in Direct Mode).
 
-   $DEVICE=""
+   If the integer expression evaluates to a value greater than the current
+   value of $ZLEVEL, or less than zero (0), GT.M issues a run-time error.
 
-   $ECODE=",M6,Z150373850,"
+   If ZGOTO has no entry reference, it performs some number of implicit QUITs
+   and transfers control to the next command at the specified level. When no
+   argument is specified, ZGOTO 1 is the result, and operation resumes at the
+   lowest level M routine as displayed by ZSHOW "S". In the image invokedby
+   mumps -direct, or a similar image, a ZGOTO without arguments returns the
+   process to Direct Mode.
 
-   $ESTACK=2
+3 Displaying_Source_Code
+   Displaying Source Code
 
-   $ETRAP=""
+   Use the ZPRINT command to display source code lines selected by its
+   argument. ZPRINT allows you to display the source for the current routine
+   and any other related routines. Use the ZPRINT command to display the last
+   call level.
 
-   $HOROLOG="59149,36200"
+   Example:
 
-   $IO="/dev/pts/17"
+   GTM>ZPRINT beg
+   beg for read !,"Name: ",name do name
 
-   $JOB=310051
+   This example uses a ZPRINT command to print the line indicated as the call
+   at the top of the stack. Notice that the routine has an error in logic.
+   The line starting with the label beg has a FOR loop with no control
+   variable, no QUIT, and no GOTO. There is no way out of the FOR loop.
 
-   $KEY=""
+3 Correcting_Errors_in_an_M_Routine
+   Correcting Errors in an M Routine
 
-   $PRINCIPAL="/dev/pts/17"
+   Now that the routine errors have been identified, correct them in the M
+   source file. Use ZEDIT to invoke the editor and open the file for editing.
+   Correct the errors previously identified and enter to exit the editor.
 
-   $QUIT=0
+   Example:
 
-   $REFERENCE=""
+   GTM>ZEDIT "dmex"
+   dmex;dmex - Direct Mode example
+   ;
+   begfor read !,"Name: ",name do name q:name="Q"
+   quit
+   nameset ln=$l(name)
+   if ln,$e("QUIT",1,ln)=$tr(name,"quit","QUIT") d q
+   . s name="Q"
+   if ln<30,name?1.a.1"-".a1","1" "1a.ap do print q
+   write !,"Please use last-name, "
+   write "first-name middle-initial or 'Q' to Quit."
+   quit
+   printwrite !,$p(name,", ",2)," ",$p(name,", ")
+   quit
+   GTM>
 
-   $STACK=2
+   This example shows the final state of a ZEDIT session of dmex.m. Note that
+   the infinite FOR loop at line beg is corrected.
 
-   $STORAGE=1072300032
+3 Relinking_the_Edited_Routine
+   Relinking the Edited Routine
 
-   $SYSTEM="47,gtm_sysid"
+   Use the ZLINK command to add the edited routine to the current image.
+   ZLINK automatically recompiles and relinks the routine. If the routine was
+   the most recent one ZEDITed or ZLINKed, you do not have to specify the
+   routine name with the ZLINK command.
 
-   $TEST=1
+   **Caution**
 
-   $TLEVEL=0
+   When you issue a DO command, GT.M determines whether the routine is part
+   of the current image, and whether compiling or linking is necessary.
+   Because this routine is already part of the current image, GT.M does not
+   recompile or relink the edited version of the routine if you run the
+   routine again without ZLINKing it first. Therefore, GT.M executes the
+   previous routine image and not the edited routine.
 
-   $TRESTART=0
+   **Note**
 
-   $X=0
+   You may have to issue a ZGOTO or a QUIT command to remove the unedited
+   version of the routine from the M invocation stack before ZLINKing the
+   edited version.
 
-   $Y=23
+   Example:
 
-   $ZA=0
+   GTM>ZLINK
+    Cannot ZLINK an active routine
 
-   $ZB=$C(13)
+   This illustrates a GT.M error report caused by an attempt to ZLINK a
+   routine that is part of the current invocation stack.
 
-   $ZCMDLINE=""
+   To ZLINK the routine, remove any invocation levels for the routine off of
+   the call stack. You may use the ZSHOW "S" command to display the current
+   state of the call stack. Use the QUIT command to remove one level at a
+   time from the call stack. Use the ZGOTO command to remove multiple levels
+   off of the call stack.
 
-   $ZCOMPILE=""
+   **Note**
 
-   $ZCSTATUS=0
+   For further details and examples, refer to the GT.M Programmer's Guide.
 
-   $ZDIRECTORY="/ext1/home/"
+   Example:
 
-   $ZEDITOR=0
+   GTM>ZSHOW "S"
+   name+3^dmex ($ZTRAP) (Direct mode)
+   beg^dmex (Direct mode)
+    ^GTM$DMOD (Direct mode)
 
-   $ZEOF=0
+   GTM>ZGOTO
 
-   $ZERROR="Unprocessed $ZERROR, see $ZSTATUS"
+   GTM>ZSHOW "S"
+    ^GTM$DMOD (Direct mode)
+   GTM>ZLINK
 
-   $ZGBLDIR="/ext1/home/mumps.gld"
+   This example uses a ZSHOW "S" command to display the current state of the
+   call stack. A ZGOTO command without an argument removes all the calling
+   levels above the first from the stack. The ZLINK automatically recompiles
+   and relinks the routine, thereby adding the edited routine to the current
+   image.
 
-   $ZININTERRUPT=0
+3 Re-executing_the_Routine
+   Re-executing the Routine
 
-   $ZINTERRUPT="IF $ZJOBEXAM()"
+   Re-display the DO command using the RECALL command.
 
-   $ZIO="/dev/pts/17"
+   Execute the routine using the DO command.
 
-   $ZJOB=0
-
-   $ZLEVEL=3
-
-   $ZMODE="INTERACTIVE"
-
-   $ZPOSITION="name+3^dmex"
-
-   $ZPROCESS=""
-
-   $ZPROMPT="GTM>"
-
-   $ZROUTINES=". /usr/library/gtm_dist"
-
-   $ZSOURCE=""
-
-   $ZSTATUS="150373850,name+3^dmex,  %GTM-E-UNDEF,  Undefined  local
-   variable: bame"
-   $ZSYSTEM=0
-
-   $ZTRAP="B"
-
-   $ZVERSION="GT.M V4.3-001D AIX RS6000"
-
-   $ZYERROR=""
-
-   bame="?"
-
-   ln=12
-
-   name=""
-
-   /dev/pts/17 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
-
-   name+3^dmex ($ZTRAP)
-
-   (Direct mode)
-
-   beg^dmex
-
-   ^GTM$DMOD (Direct mode)
-
-
-   GTM>
-
-   This example uses the asterisk (*) argument  to  show  all  information
-   that ZSHOW offers in this context.  First  are  the  Intrinsic  Special
-   Variables ($DEVICE-$ZYERROR, also available with ZSHOW "I"),  then  the
-   local variables (bame, ln and name, also  available  with  ZSHOW  "V"),
-   then the ZBREAK locations (name+3^dmex, also available with ZSHOW "B"),
-   then the device information (also available with ZSHOW "D"), then the M
-   stack (also available with ZSHOW "S"). ZSHOW "S"  is  the  default  for
-   ZSHOW with no arguments.
-
-   Context information that does not exist  in  this  example  includes  M
-   LOCKs of this process (
-   ZSHOW "L").
-
-   In addition to directing its output to the current  device,  ZSHOW  can
-   place its output  in  a  local  or  global  variable  array.  For  more
-   information, refer to the ZSHOW section of the  "Commands"  chapter  in
-   GT.M Programmer's Guide.
-
-        ZSHOW "V" produces the same output as ZWRITE with no arguments, but
-        ZSHOW "V" can be directed to a variable as well as a device.
-
-3 Transf_Rtn_Control
-   Transferring Routine Control
-
-   The
-   ZGOTO command transfers  control  from  one  part  of  the  routine  to
-   another, or from one routine to  another,  using  the  specified  entry
-   reference. The ZGOTO command takes an optional integer expression that
-   indicates the M stack level reached by performing  the  ZGOTO,  and  an
-   optional  entry  reference  specifying  the  location  to  where  ZGOTO
-   transfers control. A ZGOTO command, with an entry reference, performs a
-   function similar to the GOTO command with the additional capability of
-   reducing the M stack level. In a single operation, the process executes
-   $ZLEVEL-intexpr, implicit QUITs from DO or extrinsic operations, and a
-   GOTO operation transferring control to the named entry reference.
-
-   The ZGOTO command leaves the invocation stack at the level of the value
-   of the integer expression. GT.M implicitly terminates  any  intervening
-   FOR  loops  and  unstacks  variables  stacked  with  NEW  commands,  as
-   appropriate.
-
-   ZGOTO $ZLEVEL:LABEL^ROUTINE takes the same action as GO LABEL^ROUTINE.
-
-   ZGOTO  $ZLEVEL-1  produces  the  same  result  as  QUIT  (followed  by
-   ZCONTINUE, if in Direct Mode).
-
-   If the integer expression evaluates to a value greater than the current
-   value of $ZLEVEL, or less than zero (0), GT.M issues a run-time error.
-
-   If ZGOTO has no entry reference, it performs some  number  of  implicit
-   QUITs and transfers control to the next command at the specified level.
-   When no argument is specified, ZGOTO 1 is  the  result,  and  operation
-   resumes at the lowest level M routine as displayed by ZSHOW "S". In the
-   image invoked by mumps -direct, or a similar  image,  a  ZGOTO  without
-   arguments returns the process to Direct Mode.
-
-3 Disp_Source_code
-   Displaying Source Code
-
-   Use the
-   ZPRINT command to display source code lines selected by  its  argument.
-   ZPRINT allows you to display the source for the current routine and any
-   other related routines. Use the ZPRINT command to display the last call
-   level.
-
-   Example:
-
-
-   GTM>ZPRINT beg
-
-   beg for read !,"Name: ",name do name
-
-   This example uses a ZPRINT command to print the line indicated  as  the
-   call at the top of the stack. Notice that the routine has an  error  in
-   logic. The line starting with the label beg has  a  FOR  loop  with  no
-   control variable, no QUIT, and no GOTO. There is no way out of the FOR
-   loop.
-
-3 Correct_Errs_in_M_Rtn
-   Correcting Errors in an M Routine
-
-   Now that the routine errors have been identified, correct them in the M
-   source file. Use
-   ZEDIT to invoke the editor and open the file for editing.  Correct  the
-   errors previously identified and exit the editor.
-
-   Example:
-
-
-   GTM>ZEDIT "dmex"
-
-   dmex ;dmex - Direct Mode example
-
-   ;
-
-   beg for read !,"Name: ",name do name q:name="Q"
-
-   quit
-
-   name set ln=$l(name)
-
-   if ln,$e("QUIT",1,ln)=$tr(name,"quit","QUIT") d q
-
-   . s name="Q"
-
-   if ln<30,name?1.a.1"-".a1","1" "1a.ap do print q
-
-   write !,"Please use last-name, "
-
-   write "first-name middle-initial or 'Q' to Quit."
-
-   quit
-
-   print write !,$p(name,", ",2)," ",$p(name,", ")
-
-   quit
-
-   GTM>
-
-   This example shows the final state of a ZEDIT session of  dmex.m.  Note
-   that the infinite FOR loop at line beg is corrected.
-
-3 Relink_Edited_Rtn
-   Relinking the Edited Routine
-
-   Use the ZLINK command to add the edited routine to the  current  image.
-   ZLINK automatically recompiles and relinks the routine. If the routine
-   was the most recent one ZEDITed or ZLINKed, you do not have to specify
-   the routine name with the ZLINK command.
-
-        You may have to issue a ZGOTO or  a  QUIT  command  to  remove  the
-        unedited version of the routine from the M invocation stack before
-        ZLINKing the edited version.
-
-   Example:
-
-
-   GTM>ZLINK
-
-   Cannot ZLINK an active routine
-
-   This illustrates a GT.M error report caused by an attempt  to  ZLINK  a
-   routine that is part of the current invocation stack.
-
-   To ZLINK the routine, remove any invocation levels for the routine off
-   of the call stack. You may use the ZSHOW "S"  command  to  display  the
-   current state of the call stack. Use the QUIT  command  to  remove  one
-   level at a time from the call stack. Use the ZGOTO  command  to  remove
-   multiple levels off of the call stack.
-
-        For further details and examples, refer to  the  GT.M  Programmer's
-        Guide.
-
-3 Reexec_the_Rtn
-   Re-executing the Routine
-
-   Re-display the DO command using the RECALL command.
-
-   Execute the routine using the DO command.
-
-   Example:
-
-
-   GTM>D ^dmex
+   Example:
 
+   GTM>D ^dmex
 
    Name: Revere, Paul
-
    Paul Revere
-
    Name: q
 
    This example illustrates a successful execution of dmex.
 
-3 Using_Forked_Proc
-   Using Forked Processes
-
-   The
-   ZSYSTEM command creates a new process called  the  child  process,  and
-   passes its argument  to  the  shell  for  execution.  The  new  process
-   executes in the same directory  as  the  initiating  process.  The  new
-   process has the same operating system environment, such as environment
-   variables and input/output devices,  as  the  initiating  process.  The
-   initiating process  pauses  until  the  new  process  completes  before
-   continuing execution.
-
-   Example:
-
-
-   GTM>ZSYSTEM
-
-   $ ls dmex.*
-
-   dmex.m dmex.o
-
-
-   $ ps
-
-   PID TTY TIME COMMAND
-
-   7946 ttyp0 0:01 sh
-
-   7953 ttyp0 0:00 gtm
-
-   7955 ttyp0 0:00 ps
+1 M_Lang_Features
+   M Lang Features
 
-   $ exit
-
-
-   GTM>
-
-   This example uses ZSYSTEM to create a child process, perform some shell
-   actions, and return to GT.M.
-
-1 Lang_Features_M
-   General Language Features of M
-
-   MUMPS is a general purpose language with an embedded  database  system.
-   This section of the help file describes the features  of  the  language
-   that are not covered  as  Commands,  Functions,  or  Intrinsic  Special
-   Variables.
+   MUMPS is a general purpose language with an embedded database system. This
+   section describes the features of the language that are not covered as
+   Commands, Functions, or Intrinsic Special Variables chapters.
 
 2 Data_Types
    Data Types
@@ -1568,203 +2444,196 @@ $ export env_variable
    M operates with a single basic data type, string. However, M evaluates
    data using methods that vary according to context.
 
-3 Num_Expressions
+3 Numeric_Expressions
    Numeric Expressions
 
-   When M syntax specifies a numexpr, M evaluates the data as  a  sequence
-   of ASCII characters that specify a number. M stops the  evaluation  and
-   provides the result generated from  successfully  evaluated  characters
-   when it encounters any character that is not the following:
-
-   o    A digit 0-9
-
-   o    A plus sign (+) or minus sign (-) and also the first  character  in
-        the string
+   When M syntax specifies a numexpr, M evaluates the data as a sequence of
+   ASCII characters that specify a number. M stops the evaluation and
+   provides the result generated from successfully evaluated characters when
+   it encounters any character that is not the following:
 
-   o    The first decimal point (.) in the string
+     * A digit 0-9
+     * A plus sign (+) or minus sign (-) and also the first character in the
+       string
+     * The first decimal point (.) in the string
 
-3 Num_Accuracy
+3 Numeric_Accuracy
    Numeric Accuracy
 
-   GT.M provides 18 digits of accuracy, independent of the  decimal  point
-   (.) placement, and a numeric range from 10**(-43) to (10**47). Numbers
-   with three digits or fewer to  the  right  of  the  decimal  point  are
-   precise.
+   GT.M provides 18 digits of accuracy, independent of the decimal point (.)
+   placement, and a numeric range from 10**(-43) to (10**47). Numbers with
+   three digits or fewer to the right of the decimal point are precise.
 
-3 Int_Expressions
+3 Integer_Expressions
    Integer Expressions
 
    When M syntax specifies an intexpr, M evaluates the data as it would a
-   numexpr except that it  stops  the  evaluation  at  any  decimal  point
-   including the first.
+   numexpr except that it stops the evaluation at any decimal point including
+   the first.
 
-3 Truth_valued_Expr
+3 Truth-valued_Expressions
    Truth-valued Expressions
 
-   When M syntax specifies a tvexpr, M evaluates the data  as  a  numeric.
-   However, it stops the evaluation and returns a true value (1)  as  soon
-   as it encounters a non-zero digit, otherwise it returns a  false  value
-   (0). In other words, M treats expressions that have a non-zero numeric
-   value as true, and expressions that have a zero numeric value as false.
-   The sign  and/or  decimal  have  no  affect  on  the  evaluation  of  a
-   truth-valued expression.
+   When M syntax specifies a tvexpr, M evaluates the data as a numeric.
+   However, it stops the evaluation and returns a true value (1) as soon as
+   it encounters a non-zero digit, otherwise it returns a false value (0). In
+   other words, M treats expressions that have a non-zero numeric value as
+   true, and expressions that have a zero numeric value as false. The sign
+   and/or decimal have no affect on the evaluation of a truth-valued
+   expression.
 
 2 M_Names
    M Names
 
-   M uses names for variables, LOCK command arguments,  labels  on  lines,
-   and routine names. M names are alphanumeric  and  must  start  with  an
-   alphabetic character or a percent sign (%).
+   M uses names for variables, LOCK command arguments, labels on lines, and
+   routine names. M names are alphanumeric and must start with an alphabetic
+   character or a percent sign (%).
 
-   The percent sign can only appear as the first character in a  name.  By
-   convention,  names  starting  with  percent  signs  are  generally
+   The percent sign can only appear as the first character in a name. By
+   convention, names starting with percent signs are generally
    application-independent or distinguished in some similar way.
 
-   M does not reserve any names. That is, M always distinguishes keywords
-   by context. Therefore, M permits a variable or a label called SET even
-   though the language has a command called SET.
+   M does not reserve any names. That is, M always distinguishes keywords by
+   context. Therefore, M permits a variable or a label called SET even though
+   the language has a command called SET.
+
+   M names are case sensitive. That is, M treats ABC, Abc, ABc, AbC ABC, and
+   abc as six different names.
 
-   M names are case sensitive. That is, M treats ABC, Abc, ABc,  AbC  ABC,
-   and abc as six different names.
+   M does not restrict the length of names in the main body of the standard.
+   However, the portability section of the standard recommends limiting names
+   to a maximum of eight (8) characters. GT.M's limit of 31 characters
+   applies to:
 
-   M does not restrict the length  of  names  in  the  main  body  of  the
-   standard. However, the portability section of the  standard  recommends
-   limiting names to a maximum of eight (8) characters.  GT.M  effectively
-   limits names to eight characters by ignoring any characters  after  the
-   first eight.
+     * Local variables names
+     * Global variables names
+     * Routine names
+     * Source and object file names (not including the extension)
+     * Label names
+     * Local lock resource names
+     * Global lock resource names
+
+   A trigger name is up to 28 characters and a replication instance name is
+   up to 15 characters.
 
 2 Variables
    Variables
 
-   M does not require predefinition of variable type or size. M variables
-   are either local or  global.  Any  variable  may  be  unsubscripted  or
-   subscripted.
+   M does not require predefinition of variable type or size. M variables are
+   either local or global. Any variable may be unsubscripted or subscripted.
 
-3 Arrays_Subscripts
+3 Arrays_and_Subscripts
    Arrays and Subscripts
 
    In M, subscripted variables identify elements in sparse arrays. Sparse
-   arrays comprise existing subscripts  and  data  nodes  -  no  space  is
-   reserved  for  potential  data  nodes.  These  arrays  generally  serve
-   logical, rather than mathematical, purposes.
+   arrays comprise existing subscripts and data nodes -; no space is reserved
+   for potential data nodes. These arrays generally serve logical, rather
+   than mathematical, purposes.
 
-   M array subscripts are expressions, and are not restricted  to  numeric
+   M array subscripts are expressions, and are not restricted to numeric
    values.
 
    The format for an M global or local variable is:
 
    [^]name[(expr1[,...])]
-   o    The optional leading caret symbol (^) designates a global variable.
-
-   o    The name specifies a particular array.
 
-   o    The optional expressions specify the subscripts
-   o    and must be enclosed in parentheses and separated by commas (,).
-
-   The body of the M standard places no restrictions  on  variable  names.
+   The body of the M standard places no restrictions on variable names.
    However, the portability section of the standard does suggest limits on
-   the length of an individual subscript  expression,  and  on  the  total
-   length of a variable name. The measurement  for  the  length  of  names
-   includes the length of the global variable name itself, the sum of the
-   lengths of all the  evaluated  subscripts,  and  an  allowance  for  an
-   overhead of two (2) times the number of subscripts. The total must not
-   exceed 237. For globals, GT.M permits this total to  be  modified  with
-   GDE up to 255.  For  locals,  GT.M  limits  the  length  of  individual
-   subscripts to the maximum string length of 32,767. GT.M  restricts  the
-   number of subscripts for local or global variables to 32.
-
-3 M_Collation_Seq
+   the length of an individual subscript expression, and on the total length
+   of a variable name. The measurement for the length of names includes the
+   length of the global variable name itself, the sum of the lengths of all
+   the evaluated subscripts, and an allowance for an overhead of two (2)
+   times the number of subscripts. The total must not exceed 237. For
+   globals, GT.M permits this total to be modified with GDE up to 255. For
+   locals, GT.M limits the length of individual subscripts to the maximum
+   string length of 32,767. GT.M restricts the number of subscripts for local
+   or global variables to 31.
+
+3 M_Collation_Sequences
    M Collation Sequences
 
-   M  collates  all  canonic  numeric  subscripts  ahead  of  all  string
-   subscripts, including strings such as those  with  leading  zeros  that
-   represent non-canonic numbers. Numeric subscripts collate from negative
-   to  positive  in  value  order.  String  subscripts  collate  in  ASCII
-   sequence. In addition, GT.M allows the empty string subscript  in  most
-   contexts, (the null, or empty, string collates  ahead  of  all  canonic
-   numeric subscripts).
+   M collates all canonic numeric subscripts ahead of all string subscripts,
+   including strings such as those with leading zeros that represent
+   non-canonic numbers. Numeric subscripts collate from negative to positive
+   in value order. String subscripts collate in ASCII sequence. In addition,
+   GT.M allows the empty string subscript in most contexts, (the null, or
+   empty, string collates ahead of all canonic numeric subscripts).
 
    GT.M allows definition of alternative collation sequences. For complete
-   information  on  enabling  this  functionality,  refer  to  the
-   "Internationalization" chapter in GT.M Programmer's Guide.
+   information on enabling this functionality, refer to the
+   "Internationalization" chapter in the GT.M Programmer's Guide.
 
 3 Local_Variables
    Local Variables
 
-   A local variable in M refers to a variable used solely within the scope
-   of a single process. Local variable names have no leading delimiter.
+   A local variable in M refers to a variable used solely within the scope of
+   a single process. Local variable names have no leading delimiter.
 
-   M makes a local variable available and subject to modification  by  all
+   M makes a local variable available and subject to modification by all
    routines executed within a process from the time that variable is first
-   SET until it is  KILLed,  or  until  the  process  stops  executing  M.
-   However, M "protects" a local variable after that variable  appears  as
-   an argument to a NEW command, or after it appears as an  element  in  a
-   formalist used in parameter passing. When M protects a local variable,
-   it saves a copy  of  the  variable's  value  and  makes  that  variable
-   undefined. M restores the variable to its saved value during execution
-   of the QUIT that terminates the process stack level associated with the
-   "protecting" NEW or formalist. For more information on  NEW  and  QUIT,
-   refer to the "Commands" chapter in GT.M Programmer's Guide.
+   SET until it is KILLed, or until the process stops executing M. However, M
+   "protects" a local variable after that variable appears as an argument to
+   a NEW command, or after it appears as an element in a formalist used in
+   parameter passing. When M protects a local variable, it saves a copy of
+   the variable's value and makes that variable undefined. M restores the
+   variable to its saved value during execution of the QUIT that terminates
+   the process stack level associated with the "protecting" NEW or formalist.
+   For more information on NEW and QUIT, refer to the "Commands" chapter in
+   the GT.M Programmer's Guide.
 
    M restricts the following uses of variables to local variables:
 
-   o    FOR command control variables.
-
-   o    Elements within the parentheses of an "exclusive" KILL.
-
-   o    TSTART [with local variables list].
+     * FOR command control variables.
+     * Elements within the parentheses of an "exclusive" KILL.
+     * TSTART [with local variables list].
+     * A KILL with no arguments removes all current local variables.
+     * NEW command arguments.
+     * Actualnames used by pass-by-reference parameter passing.
 
-   o    A KILL with no arguments removes all current local variables.
+3 GV_and_Resource_Name_Env
+   GV and Resource Name Env
 
-   o    NEW command arguments.
-
-	Actualnames used by pass-by-reference parameter passing.
-
-3 Glob_Var_Resrc_Nam_Env
-   Global Variables and Resource Name Environments
-
-   M recognizes an optional environment specification in global  names  or
-   in the LOCK resource names (nrefs), which have analogous syntax. Global
+   M recognizes an optional environment specification in global names or in
+   the LOCK resource names (nrefs), which have analogous syntax. Global
    variable names have a leading caret symbol (^) as a delimiter.
 
    M makes a global variable available, and subject to modification by all
    routines executed within all processes in an environment, from the time
    that variable is first SET until it is KILLed.
 
-4 Naked_References
+3 Naked_References
    Naked References
 
    M accepts an abbreviation of the global name under some circumstances.
-   When the  leading  caret  symbol  (^)  immediately  precedes  the  left
-   parenthesis delimiting subscripts, the  global  variable  reference  is
-   called a naked reference. M evaluates a naked  reference  by  prefixing
-   the last used global variable name, except for its last  subscript,  to
-   the list of subscripts specified by the naked reference.  The  prefixed
-   portion is known as the naked indicator. An  attempt  to  use  a  naked
-   reference when the prior global reference does not exist,  or  did  not
-   contain a subscript, generates an error.
-
-   Because M has only one process-wide naked indicator which it maintains
-   as a side affect of every evaluation of a global  variable,  using  the
-   naked reference requires an understanding of M  execution  sequence.  M
-   execution generally proceeds from left to right within a line, subject
-   to commands that change the flow of control. However, M  evaluates  the
-   portion of a SET command argument to the right side of the  equal  sign
-   before the left side. Also, M does not evaluate any  further  $SELECT()
-   arguments within the function after  it  encounters  a  true  selection
-   argument.
+   When the leading caret symbol (^) immediately precedes the left
+   parenthesis delimiting subscripts, the global variable reference is called
+   a naked reference. M evaluates a naked reference by prefixing the last
+   used global variable name, except for its last subscript, to the list of
+   subscripts specified by the naked reference. The prefixed portion is known
+   as the naked indicator. An attempt to use a naked reference when the prior
+   global reference does not exist, or did not contain a subscript, generates
+   an error.
+
+   Because M has only one process-wide naked indicator which it maintains as
+   a side affect of every evaluation of a global variable, using the naked
+   reference requires an understanding of M execution sequence. M execution
+   generally proceeds from left to right within a line, subject to commands
+   that change the flow of control. However, M evaluates the portion of a SET
+   command argument to the right side of the equal sign before the left side.
+   Also, M does not evaluate any further $SELECT() arguments within the
+   function after it encounters a true selection argument.
 
-   In general, using naked references only in very  limited  circumstances
+   In general, using naked references only in very limited circumstances
    prevents problems associated with the naked indicator.
 
-4 Glob_Var_Name_Env
+3 Global_Variable_Name_Environments
    Global Variable Name Environments
 
    M recognizes an optional environment specification in global names. The
-   environment specification designates one of  some  set  of  alternative
+   environment specification designates one of some set of alternative
    database files.
 
-   The syntax for  global  variable  names  that  include  an  environment
+   The syntax for global variable names that include an environment
    specification is:
 
    ^|expr|name[(subscript[,...])]
@@ -1772,23 +2641,23 @@ $ export env_variable
    In GT.M, the expression identifies the Global Directory for mapping the
    global variable.
 
-   Environment specifications permit easy access to  global  variables  in
-   alternative databases, including other "copies" of active variables in
-   the current database. Environment specifications are sometimes referred
-   to as extended global syntax or extended value syntax.
+   Environment specifications permit easy access to global variables in
+   alternative databases, including other "copies" of active variables in the
+   current database. Environment specifications are sometimes referred to as
+   extended global syntax or extended value syntax.
 
    GT.M also allows:
 
    ^|expr1,expr2|name[(subscript[,...])]
 
-   Where the first expression identifies  the  Global  Directory  and  the
-   second expression is accepted but ignored by GT.M.
+   Where the first expression identifies the Global Directory and the second
+   expression is accepted but ignored by GT.M.
 
-   To improve compatibility with some other M implementations,  GT.M  also
-   accepts another non-standard syntax. In this syntax,  the  leading  and
-   trailing up-bar (|) are respectively replaced by a left square-bracket
-   ([)  and  a  right  square-bracket  (]).  This  syntax  also  requires
-   expratoms, rather than expressions.
+   To improve compatibility with some other M implementations, GT.M also
+   accepts another non-standard syntax. In this syntax, the leading and
+   trailing up-bar (|) are respectively replaced by a left square-bracket ([)
+   and a right square-bracket (]). This syntax also requires expratoms,
+   rather than expressions.
 
    The formats for this non-standard syntax are:
 
@@ -1798,16440 +2667,14627 @@ $ export env_variable
 
    ^[expratom1,expratom2]name[(subscript...)]
 
-   Where expratom1 identifies the Global  Directory  and  expratom2  is  a
-   dummy variable. Note that the first set of brackets in each  format  is
-   part of the syntax. The second set of square brackets is  part  of  the
-   meta-language identifying an optional element.
+   Where expratom1 identifies the Global Directory and expratom2 is a dummy
+   variable. Note that the first set of brackets in each format is part of
+   the syntax. The second set of square brackets is part of the meta-language
+   identifying an optional element.
 
    Example:
 
-
    $ gtmgbldir=Test.GLD
-
    $ export gtmgbldir
-
    $ GTM
 
    GTM>WRITE $ZGBLDIR
-
    TEST.GLD
-
    GTM>WRITE ^A
-
    THIS IS ^A IN DATABASE RED
-
    GTM>WRITE ^|"M1.GLD"|A
-
    THIS IS ^A IN DATABASE WHITE
-
    GTM>WRITE $ZGBLDIR
-
    TEST.GLD
-
    GTM>HALT
 
    $ echo gtmgbldir
-
    TEST.GLD
 
-   The statement WRITE ^|"M1.GLD"|A writes variable ^A  using  the  Global
+   The statement WRITE ^|"M1.GLD"|A writes variable ^A using the Global
    Directory, M1.GLD, but does not change the current Global Directory.
 
    Example:
 
-
    GTM>WRITE $ZGBLDIR
-
    M1.GLD
-
    GTM>WRITE ^A
-
    THIS IS ^A IN DATABASE WHITE
-
    GTM>WRITE ^|"M1.GLD"|A
-
    THIS IS ^A IN DATABASE WHITE
 
    The statement WRITE ^|"M1.GLD"|A is equivalent to WRITE ^A.
 
-   Specifying separate Global Directories does  not  always  translate  to
-   using separate databases.
+   Specifying separate Global Directories does not always translate to using
+   separate databases.
 
    Example:
 
-
    GTM>WRITE ^|"M1.GLD"|A,!,^|"M2.GLD"|A,!,^|"M3.GLD"
-
-|A,!
+   |A,!
    THIS IS ^A IN DATABASE WHITE
-
    THIS IS ^A IN DATABASE BLUE
-
    THIS IS ^A IN DATABASE WHITE
 
    In this example, the WRITE does not display ^A from three GT.M database
-   files.  Mapping  specified  by  the  Global  Directory  Editor  (GDE)
-   determines the database file to which a Global Directory points.
+   files. Mapping specified by the Global Directory Editor (GDE) determines
+   the database file to which a Global Directory points.
 
    This result could have occurred under the following mapping:
 
-
    ^|"M1.GLD"|A --> REGIONA --> SEGMENTA --> FILE1.DAT
-
    ^|"M2.GLD"|A --> REGIONA --> SEGMENT1 --> FILE2.DAT
-
    ^|"M3.GLD"|A --> REGION3 --> SEGMENT3 --> FILE1.DAT
 
-   For more information  on  Global  Directories,  refer  to  the  "Global
-   Directory Editor" chapter of the  GT.M  Administration  and  Operations
-   Guide.
-
-4 Opt_GTM_Env_Trans_Facility
-   Optional GT.M Environment Translation Facility
+   For more information on Global Directories, refer to the "Global Directory
+   Editor" chapter of the GT.M Administration and Operations Guide.
 
-   For users who wish to dynamically  (at  run-time)  determine  a  global
-   directory from non-global directory information (typically UCI and VOL)
-   in the environment specification, GT.M provides an interface to add an
-   appropriate translation.
+2 Literals
+   Literals
 
-   Using this facility impacts the performance of every global access that
-   uses environment specification. Make sure you use it only  when  static
-   determination of the global directory is not feasible. When used, make
-   every effort to keep the translation routines very efficient.
+   M has both string and numeric literals.
 
-   The  use  of  this  facility  is  enabled  by  the  definition  of  the
-   environment variable gtm_env_translate, which contains the  path  of  a
-   shared library with the following entry point:
+3 String_Literals
+   String Literals
 
-5 gtm_env_xlate
-   gtm_env_xlate
+   A string literal (strlit) is enclosed in quotation marks (" ") and can
+   contain a sequence of ASCII and Unicode characters. While the standard
+   indicates the characters must be graphic, GT.M accepts non-graphic
+   characters and, at compile-time, gives a warning. Using $CHAR() and
+   concatenate to represent non-graphic characters in strings not only avoids
+   the warning but is less error prone and makes for easier understanding. M
+   attempts to use character text that appears outside of quotation mark
+   delimiters according to context, which generally means as a local variable
+   name.
 
-   If the shared object is not  accessible  or  the  entry  point  is  not
-   accessible, GT.M reports an error.
+   To include a quotation mark (") within a strlit, use a set of two
+   quotation marks ("" "").
 
-   The gtm_env_xlate() routine has the following C prototype:
+   Example:
 
+   GTM>write """"
+   "
+   GTM>
 
-   int gtm_env_xlate(xc_string_t *in1, xc_string_t *in2,  xc_string  *in3,
-   xc_string_t *out)
-   where xc_string_t is a structure defined in gtmxc_types.h as follows:
+   The WRITE displays a single quotation mark because the first quotation
+   mark delimits the beginning of the string literal, the next two quotation
+   marks denote a single quote within the string, and the last quotation mark
+   delimits the end of the string literal.
 
+   Use the $CHAR function and the concatenation operator to include control
+   characters within a string.
 
-   typedef struct
+   Example:
 
-   {
+   GTM>WRITE "A"_$CHAR(9)_"B"
+   A B
+   GTM>
 
-   int length;
+   The WRITE displays an "A," followed by a tab (<HT>), followed by a "B"
+   using $CHAR(), to introduce the non-graphic character.
 
-   char *address;
+3 Numeric_Literals
+   Numeric Literals
 
-   } xc_string_t;
+   In M, numeric literals (numlit) are entered without surrounding
+   delimiters.
 
-   The purpose of the function is to use  its  three  input  arguments  to
-   derive and return an output argument that can be used as an environment
-   specification by GT.M. Note that the input values passed (in1, in2 and
-   in3) are the result of M evaluation and must not be modified. The first
-   two arguments are the expressions passed within the up-bars  "|  |"  or
-   the square-brackets "[ ]",  and  the  third  argument  is  the  current
-   working directory as described by $ZDIRECTORY.
+   Example:
 
-   A return value other than zero (0) indicates an error  in  translation,
-   and is reported by a GT.M error
+   GTM>WRITE 1
+   1
+   GTM> WRITE 1.1
+   1.1
 
-   If the length of the  output  argument  is  non-zero,  GT.M  appends  a
-   secondary message of GTM-I-TEXT,  containing  the  text  found  at  the
-   address of the output structure.
+   These display numeric literals that are integer and decimal.
 
-   GT.M does not do any memory management related to the output argument -
-   space for the output should be allocated by the external  routine.  The
-   routine must  place  the  returned  environment  specification  at  the
-   address it has allocated  and  adjust  the  length  accordingly.  On  a
-   successful return, the return value should be zero. If the translation
-   routine must communicate an error to GT.M, it must  return  a  non-zero
-   value, and if it is to communicate additional error information, place
-   the error text at the address where the environment would  normally  go
-   and adjust the length to match the length of the error text.
+   M also accepts numeric literals in the form of a mantissa and an exponent,
+   separated by a delimiter of "E" in uppercase. The mantissa may be an
+   integer or a decimal fraction. The integer exponent may have an optional
+   leading minus sign (-).
 
-   Length of the return value  may  range  from  0-32767,  otherwise  GT.M
-   reports an error.
+   Example:
 
-   A zero-length (empty) string specifies the current value  of  $ZGBLDIR.
-   Non-zero  lengths  must  represent  the  actual  length  of  the  file
-   specification pointed to by address, excluding any <NUL> terminator. If
-   the address field of the output argument is NULL, GT.M issues an error.
+   GTM>WRITE 8E6
+   8000000
+   GTM> WRITE 8E-6
+   .000008
+   GTM>
 
+   **Caution**
+
+   The exponential numeric form may lead to ambiguities in the meaning of
+   subscripts. Because numeric subscripts collate ahead of string subscripts,
+   the string subscript "01E5" is not the same as the numeric subscript 01E5.
+
+   GT.M handles numeric strings which are not canonical within the
+   implementation as strings unless the application specifically requests
+   they be treated as numbers. Any use in a context defined as numeric
+   elicits numeric treatment; this includes operands of numeric operators,
+   numeric literals, and some intrinsic function arguments. When the code
+   creates a large number out of range , GT.M gives a NUMOFLOW error. When
+   the code creates a small fractional number out of range GT.M treats it as
+   zero (0). The GT.M number range is (to the limit of accuracy) 1E-43 to
+   1E47. When the application creates an in-range number that exceeds the
+   GT.M numeric accuracy of 18 significant digits, GT.M silently retains the
+   most significant digits. With standard collation, GT.M collates canonic
+   numeric strings used as subscripts numerically, while it collates
+   non-canonic numbers as strings.
 
-   The file specification may be absolute or relative and may  contain  an
-   environment variable. If the file specified is not  accessible,  or  is
-   not a valid global directory, GT.M reports errors in the  same  way  it
-   does for any invalid global directory.
+2 Expressions
+   Expressions
 
-   It is possible to write this routine in  M  (as  a  call-in),  however,
-   global variables in such a routine would change  the  naked  indicator,
-   which  environment  references  normally  do  not.  Depending  on  the
-   conventions of the application, there  might  be  difficult  name-space
-   management issues such as protecting the local variables used by the M
-   routine.
+   The following items are legal M expression atoms (expratom). An expression
+   atom is a component of an M expression.
 
-   While it is possible for  this  routine  to  take  any  form  that  the
-   application designer  finds  appropriate  within  the  given  interface
-   definition, the following paragraphs make some recommendations based on
-   the expectation that a routine invoked for any more than a  handful  of
-   global references should be efficient.
+     * Local variables
+     * Global variables
+     * Intrinsic special variables
+     * Intrinsic functions
+     * Extrinsic functions
+     * Extrinsic special variables
+     * Numeric literals
+     * String literals
+     * An expression enclosed in parentheses
+     * Any of the above preceded by a unary operator
 
-   It is expected that the routine loads one or  more  tables,  either  at
-   compilation or the first time it is invoked. The logic of  the  routine
-   performs a look up on the entry in the set of tables. The lookup might
-   be based on the length of the strings and some unique set of characters
-   in the names, or a hash, with collision provisions as appropriate.
+   In addition, any of these items may be combined with a binary operator and
+   another expression atom.
 
-   The routine may have to deal with a case  where  one  or  both  of  the
-   inputs have zero length. A subset of these cases  may  have  the  first
-   string holding a comma limited string that needs to  be  re-interpreted
-   as being equivalent to two input strings (note that the  input  strings
-   must never be modified). The routine may  also  have  to  handle  cases
-   where a value (most likely the first) is accidentally or intentionally,
-   already a global directory specification.
+2 Operators
+   Operators
 
-   Example:
+   M has both unary and binary operators.
 
+3 Precedence
+   Precedence
 
-> cat gtm_env_translate.c
-   #include <stdio.h>
+   All unary operations have right to left precedence.
 
-   #include <string.h>
+   All M binary operations have strict left to right precedence. This
+   includes all arithmetic, string, and logical operations. Hierarchies of
+   operations require explicit establishment of precedence using parentheses
+   (). Although this rule is counterintuitive, it is easy to remember and has
+   no exceptions.
 
-   #include "gtmxc_types.h"
+3 Arithmetic_Operators
+   Arithmetic Operators
 
+   All arithmetic operators force M to evaluate the expressions to which they
+   apply as numeric. The arithmetic operators are:
 
-   static int init = 0;
+   + as a unary operator simply forces M to evaluate the expression following
+   as numeric; as a binary operator it causes M to perform addition.
 
-   typedef struct
+   - as a unary operator causes M to negate the expression following; as a
+   binary operator it causes M to perform subtraction.
 
-   {
+   * binary operator for multiplication.
 
-   xc_string_t field1, field2, ret;
+   ** binary operator for exponentiation.
 
-   } line_entry ;
+   / binary operator for fractional division.
 
+   \ binary operator for integer division.
 
-   static line_entry table[5], *line, linetmp;
+   # binary operator for modulo, that is, causes M to produce the remainder
+   from integer division of the first argument by the second.
 
-        /* Since these errors may occur before setup is complete, they are
-        statics */
-   static  char  *errorstring1  =  "Error  in  function  initialization,
-   environment  variable  GTM_CALLIN_START  not  defined.  Environment
-   translation failed.";
-   static char *errorstring2 = "Error in function initialization, function
-   pointers could not be determined. Envrironment translation failed.";
-   #define ENV_VAR "GTM_CALLIN_START"
+   Remember that precedence is left to right for all arithmetic operators.
 
-   typedef int (*int_fptr)();
+   Example:
 
-   int_fptr GTM_MALLOC;
+   GTM>WRITE 1+1
+   2
+   GTM>WRITE 2-1
+   1
+   GTM>WRITE 2*2
+   4
+   GTM>WRITE 3**2
+   9
+   GTM>WRITE 4/2
+   2
+   GTM>WRITE 7
+   2
+   GTM>WRITE 7#3
+   1
+   GTM>
 
+   This simple example demonstrates how each arithmetic binary operation uses
+   numeric literals.
 
-   int init_functable(xc_string_t *ptr)
+   Example:
 
-   {
+   GTM>WRITE +"12ABC"
+   12
+   GTM>WRITE --"-3-4"
+   -3
+   GTM>
 
-        /* This function demonstrates the initialization of other function
-        pointers as well (if the user-code needs them for any reason, they
-        should be defined as globals)*/
-   char *pcAddress;
+   The first WRITE shows the unary plus sign (+) operation forcing the
+   numeric evaluation of a string literal. The second WRITE demonstrates the
+   unary minus sign (-). Note the second minus sign within the string literal
+   does not cause subtraction, but rather, terminates the numeric evaluation
+   with the result of negative three (-3). Each of the leading minus signs
+   causes one negation and therefore, the result is negative three (-3).
 
-   long lAddress;
+3 Logical_Operators
+   Logical Operators
 
-   void **functable;
+   M logical operators always produce a result that is TRUE (1) or FALSE (0).
+   All logical operators force M to evaluate the expressions to which they
+   apply as truth-valued. The logical operators are:
 
-   void (*setup_timer) ();
+   ' unary NOT operator negates current truth-value; M accepts placement of
+   the NOT operator next to a relational operator, for example, A'=B as
+   meaning '(A=B).
 
-   void (*cancel_timer) ();
+   &binary AND operator produces a true result only if both of the
+   expressions are true.
 
+   ! binary OR operator produces a true result if either of the expressions
+   is true.
 
-   pcAddress = getenv(ENV_VAR);
+   Remember that precedence is always left to right, and that logical
+   operators have the same precedence as all other operators.
 
-   if (pcAddress == NULL)
+   Example:
 
-   {
-
-   ptr->length = strlen(errorstring1);
-
-   ptr->address = errorstring1;
-
-   return 1;
-
-   }
-
-   lAddress = -1;
-
-   lAddress = atol(pcAddress);
-
-   if (lAddress == -1)
-
-   {
-
-   ptr->length = strlen(errorstring2);
-
-   ptr->address = errorstring2;
-
-   return 1;
-
-   }
-
-   functable = (void *)lAddress;
-
-   setup_timer = (void(*)()) functable[2];
-
-   cancel_timer = (void(*)()) functable[3];
-
-   GTM_MALLOC = (int_fptr) functable[4];
-
-   return 0;
-
-   }
-
-   void copy_string(char **loc1, char *loc2, int length)
-
-   {
-
-   char *ptr;
-
-   ptr = (char *) GTM_MALLOC(length);
-
-   strncpy( ptr, loc2, length);
-
-   *loc1 = ptr;
-
-   }
-
-
-   int init_table(xc_string_t *ptr)
-
-   {
-
-   int i = 0;
-
-   char buf[100];
-
-   char *buf1, *buf2;
-
-   FILE *tablefile;
-
-   char *space = " ";
-
-   char *errorstr1 = "Error opening table file table.dat";
-
-   char *errorstr2 = "UNDETERMINED ERROR FROM GTM_ENV_XLATE";
-
-
-   if ((tablefile = fopen("table.dat","r")) == (FILE *)NULL)
-
-   {
-
-   ptr->length = strlen(errorstr1);
-
-   copy_string(&(ptr->address), errorstr1, strlen(errorstr1));
-
-   return 1;
-
-   }
-
-   while (fgets(buf, (int)SIZEOF(buf), tablefile) != (char *)NULL)
-
-   {
-
-   line= &table[i++];
-
-   buf1 = buf;
-
-   buf2 =strstr(buf1, space);
-
-   line->field1.length = buf2 - buf1;
-
-   copy_string( &(line->field1.address), buf1, line->field1.length);
-
-   buf1 = buf2+1;
-
-   buf2 = strstr(buf1, space);
-
-   line->field2.length = buf2-buf1;
-
-   copy_string( &(line->field2.address), buf1, line->field2.length);
-
-   buf1 = buf2+1;
-
-   line->ret.length = strlen(buf1) - 1;
-
-   copy_string( &(line->ret.address), buf1, line->ret.length);
-
-   }
-
-   fclose(tablefile);
-
-        /* In this example, the last entry in the table is the error string
-        */
-   line = &table[4];
-
-   copy_string( &(line->ret.address), errorstr2, strlen(errorstr2));
-
-   line->ret.length = strlen(errorstr2);
-
-   return 0;
-
-   }
-
-
-   int cmp_string(xc_string_t str1, xc_string_t str2)
-
-   {
-
-   if (str1.length == str2.length)
-
-   return strncmp(str1.address, str2.address, (int) str1.length);
-
-   else
-
-   return str1.length - str2.length;
-
-   }
-
-
-   int cmp_line(line_entry *line1, line_entry *line2)
-
-   {
-
-   return  (((cmp_string(line1->field1,
-   line2->field1))||(cmp_string(line1->field2, line2->field2))));
-   }
-
-
-   int look_up_table(line_entry *aline, xc_string_t *ret_ptr)
-
-   {
-
-   int i;
-
-   int ret_v;
-
-
-   for(i=0;i<4;i++)
-
-   {
-
-   line = &table[i];
-
-   ret_v = cmp_line( aline, line);
-
-   if (!ret_v)
-
-   {
-
-   ret_ptr->length = line->ret.length;
-
-   ret_ptr->address = line->ret.address;
-
-   return 0;
-
-   }
-
-   }
-
-        /*ERROR OUT*/
-   line = &table[4];
-
-   ret_ptr->length= line->ret.length;
-
-   ret_ptr->address = line->ret.address;
-
-   return 1;
-
-
-   }
-
-
-   int gtm_env_xlate(xc_string_t  *ptr1,  xc_string_t  *ptr2,  xc_string_t
-   *ptr_zdir, xc_string_t *ret_ptr)
-   {
-
-
-   int return_val, return_val_init;
-
-   if (!init)
-
-   {
-
-   return_val_init = init_functable(ret_ptr);
-
-   if (return_val_init) return return_val_init;
-
-   return_val_init = init_table(ret_ptr);
-
-   if (return_val_init) return return_val_init;
-
-   init = 1;
-
-   }
-
-   linetmp.field1.length= ptr1->length;
-
-   linetmp.field1.address= ptr1->address;
-
-   linetmp.field2.length= ptr2->length;
-
-   linetmp.field2.address= ptr2->address;
-
-
-   return_val = look_up_table(&linetmp, ret_ptr);
-
-   return return_val;
-
-   }
-
-
-> cat table.dat
-   day1 week1 mumps
-
-   day2 week1 a
-
-   day3 week2 b
-
-   day4 week2 c.gld
-
-   This example demonstrates the mechanism. A table is set  up  the  first
-   time for proper memory management, and  for  each  reference,  a  table
-   lookup is performed. Note that for the purpose of simplicity, no error
-   checking is done, so table.dat is assumed to be in the correct format,
-   and have exactly four entries.
-
-2 Literals
-   Literals
-
-   M has both string and numeric literals.
-
-3 String_Literals
-   String Literals
-
-   String literals (strlit) are enclosed in quotation marks (" ") and must
-   only contain graphic characters. In  other  words,  control  characters
-   (ASCII 0-31 and 127) cannot appear in  a  strlit.  M  attempts  to  use
-   character text  that  appears  outside  of  quotation  mark  delimiters
-   according to context, which generally means as a local variable name.
-
-   To include a quotation mark (") within a  strlit,  use  a  set  of  two
-   quotation marks ("" "").
-
-   Example:
-
-
-   GTM>WRITE """"
-
-   "
-
-   GTM>
-
-   The WRITE displays a single quotation mark because the first quotation
-   mark delimits the  beginning  of  the  string  literal,  the  next  two
-   quotation marks denote a single quote within the string, and  the  last
-   quotation mark delimits the end of the string literal.
-
-   Use the $CHAR  function  and  the  concatenation  operator  to  include
-   control characters within a string.
-
-   Example:
-
-
-   GTM>WRITE "A"_$CHAR(9)_"B"
-
-   A B
-
-   GTM>
-
-   The WRITE displays an "A," followed by a tab (<HT>), followed by a "B"
-   using $CHAR(), to introduce the non-graphic character.
-
-3 Numeric_Literals
-   Numeric Literals
-
-   In  M,  numeric  literals  (numlit)  are  entered  without  surrounding
-   delimiters.
-
-   Example:
-
-
-   GTM>WRITE 1
-
-   1
-   GTM> WRITE 1.1
-
-   1.1
-   These display numeric literals that are integer and decimal.
-
-   M also accepts numeric literals in  the  form  of  a  mantissa  and  an
-   exponent, separated by a delimiter of "E" in  uppercase.  The  mantissa
-   may be an integer or a decimal fraction. The integer exponent may have
-   an optional leading minus sign (-).
-
-   Example:
-
-
-   GTM>WRITE 8E6
-
-   8000000
-   GTM> WRITE 8E-6
-
-   .000008
-   GTM>
-
-2 Expressions
-   Expressions
-
-   The following  items  are  legal  M  expression  atoms  (expratom).  An
-   expression atom is a component of an M expression.
-
-   o    Local variables
-
-   o    Global variables
-
-   o    Intrinsic special variables
-
-   o    Intrinsic functions
-
-   o    Extrinsic functions
-
-   o    Extrinsic special variables
-
-   o    Numeric literals
-
-   o    String literals
-
-   o    An expression enclosed in parentheses
-
-   o    Any of the above preceded by a unary operator
-
-   In addition, any of these items may be combined with a binary operator
-   and another expression atom.
-
-2 Operators
-   Operators
-
-   M has both unary and binary operators.
-
-3 Precedence
-   Precedence
-
-   All unary operations have right to left precedence.
-
-   All M binary operations have strict  left  to  right  precedence.  This
-   includes all arithmetic, string, and logical operations. Hierarchies of
-   operations  require  explicit  establishment  of  precedence  using
-   parentheses (). Although this rule is counterintuitive, it is  easy  to
-   remember and has no exceptions.
-
-3 Arithmetic_Operators
-   Arithmetic Operators
-
-   All arithmetic operators force M to evaluate the expressions  to  which
-   they apply as numeric. The arithmetic operators are:
-
-        + as a unary operator simply forces M to  evaluate  the  expression
-        following as numeric; as a binary operator it causes M  to  perform
-        addition.
-        - as a unary operator causes M to negate the expression following;
-        as a binary operator it causes M to perform subtraction.
-        * binary operator for multiplication.
-        ** binary operator for exponentiation.
-        / binary operator for fractional division.
-        \ binary operator for integer division.
-        # binary operator for modulo, that is,  causes  M  to  produce  the
-        remainder from integer  division  of  the  first  argument  by  the
-        second.
-   Remember that precedence is left to right for all arithmetic operators.
-
-   Example:
-
-
-   GTM>WRITE 1+1
-
-   2
-   GTM>WRITE 2-1
-
-   1
-   GTM>WRITE 2*2
-
-   4
-   GTM>WRITE 3**2
-
-   9
-   GTM>WRITE 4/2
-
-   2
-   GTM>WRITE 7
-
-   2
-   GTM>WRITE 7#3
-
-   1
-   GTM>
-
-   This simple example demonstrates how each arithmetic  binary  operation
-   uses numeric literals.
-
-   Example:
-
-
-   GTM>WRITE +"12ABC"
-
-   12
-   GTM>WRITE --"-3-4"
-
-   -3
-
-   GTM>
-
-   The first WRITE shows the unary plus sign  (+)  operation  forcing  the
-   numeric evaluation of a string literal. The second  WRITE  demonstrates
-   the unary minus sign (-). Note the second minus sign within the string
-   literal does not cause subtraction, but rather, terminates the numeric
-   evaluation with the result of negative three (-3). Each of the leading
-   minus signs causes one negation and therefore, the result  is  negative
-   three (-3).
-
-3 Logical_Operators
-   Logical Operators
-
-   M logical operators always produce a result that is TRUE (1)  or  FALSE
-   (0). All logical operators force M to evaluate the expressions to which
-   they apply as truth-valued. The logical operators are:
-
-        '  unary  NOT  operator  negates  current  truth-value;  M  accepts
-        placement of the NOT operator next to a  relational  operator,  for
-        example, A'=B as meaning '(A=B).
-        & binary AND operator produces a true result only if  both  of  the
-        expressions are true.
-        ! binary OR operator produces  a  true  result  if  either  of  the
-        expressions is true.
-   Remember that precedence is always left  to  right,  and  that  logical
-   operators have the same precedence as all other operators.
-
-   Example:
-
-
-   GTM>WRITE '0
-
-   1
-   GTM>WRITE '1
-
-   0
-   GTM>WRITE '5689
-
-   0
-   GTM>WRITE '-1
-
-   0
-   GTM>WRITE '"ABC"
-
-   1
-   GTM>
-
-   The above example demonstrates the unary NOT operation. Note  that  any
-   non-zero numeric value is true and has a false negation.
-
-   Example:
-
-
-   GTM>WRITE 0&0
-
-   0
-   GTM>WRITE 1&0
-
-   0
-   GTM>WRITE 0&1
-
-   0
-   GTM>WRITE 1&1
-
-   1
-   GTM>WRITE 2&1
-
-   1
-   GTM>WRITE 0!0
-
-   0
-   GTM>WRITE 1!0
-
-   1
-   GTM>WRITE 0!1
-
-   1
-   GTM>WRITE 1!1
-
-   1
-   GTM>WRITE 2!1
-
-   1
-   GTM>
-
-   The above example demonstrates all cases covered by the binary logical
-   operators.
-
-3 String_Operators
-   String Operators
-
-   All string operators force M to evaluate the expressions to which they
-   apply as strings. The string operator is:
-
-        _ binary operator causes M to  concatenate  the  second  expression
-        with the first expresion
-   Example:
-
-
-   GTM>WRITE "B"_"A"
-
-   BA
-
-   GTM>WRITE "A"_1
-
-   A1
-
-   GTM>
-
-   The above example demonstrates M concatenation.
-
-3 Num_Relational_Operators
-   Numeric Relational Operators
-
-   M relational operators always generate a result of TRUE  (1)  or  FALSE
-   (0).  All  numeric  relational  operators  force  M  to  evaluate  the
-   expressions to which they apply  as  numeric.  The  numeric  relational
-   operators are:
-
-        > binary arithmetic greater than
-        < binary arithmetic less than
-   The equal sign (=) does not force numeric  evaluation,  and  should  be
-   viewed as a string  operator.  However,  the  equal  sign  between  two
-   numeric values tests for numeric equality.
-
-   Other numeric relations are  formed  using  the  logical  NOT  operator
-   apostrophe (') as follows:
-
-        '> not greater than, that is, less than or equal to
-        '< not less than, that is, greater than or equal to
-        '= not equal, numeric or string operation
-   Example:
-
-
-   GTM>WRITE 1>2
-
-   0
-   GTM>WRITE 1<2
-
-   1
-   GTM>
-
-   The  above  example  demonstrates  the  basic  arithmetic  relational
-   operations.
-
-   Example:
-
-
-   GTM>WRITE 1'<2
-
-   0
-   GTM>WRITE 2'<1
-
-   1
-   GTM>
-
-   The above example demonstrates combinations of  arithmetic,  relational
-   operators with the logical NOT operator.
-
-3 Str_Relational_Operators
-   String Relational Operators
-
-   M relational operators always generate a result of TRUE  (1)  or  FALSE
-   (0).  All  string  relational  operators  force  M  to  evaluate  the
-   expressions to which they  apply  as  strings.  The  string  relational
-   operators are:
-
-        = binary operator causes M to produce a TRUE if the expressions are
-        equal.
-        [ binary  operator  causes  M  to  produce  a  TRUE  if  the  first
-        expression contains the  ordered  sequence  of  characters  in  the
-        second expression.
-        ] binary  operator  causes  M  to  produce  a  TRUE  if  the  first
-        expression lexically follows the second expression in the character
-        encoding sequence, which by default is ASCII.
-        ]] binary operator  causes  M  to  produce  a  TRUE  if  the  first
-        expression lexically sorts  after  the  second  expression  in  the
-        subscript collation sequence.
-   Note that all non-empty strings lexically follow the empty string, and
-   every string contains the empty string.
-
-   Other string relations  are  formed  using  the  logical  NOT  operator
-   apostrophe (') as follows:
-
-        '[ does not contain.
-        '] does not follow, that is, lexically less than or equal to.
-        ']] does not sort after, that is, lexically less than or  equal  to
-        in the subscript collation sequence.
-        '= not equal, numeric or string operation.
-   Example:
-
-
-   GTM>WRITE "A"="B"
-
-   0
-   GTM>WRITE "C"="C"
-
-   1
-   GTM>WRITE "A"["B"
-
-   0
-   GTM>WRITE "ABC"["C"
-
-   1
-   GTM>WRITE "A"]"B"
-
-   0
-   GTM>WRITE "B"]"A"
-
-   1
-   GTM>WRITE "A"]]"B"
-
-   0
-   GTM>WRITE "B"]]"A"
-
-   1
-   These examples demonstrate the string relational operators using string
-   literals.
-
-   Example:
-
-
-   GTM>WRITE 2]10
-
-   1
-   GTM>WRITE 2]]10
-
-   0
-   GTM>WRITE 0]"$"
-
-   1
-   GTM>WRITE 0]]"$"
-
-   0
-   These examples illustrate that when using the primary  ASCII  character
-   set, the  main  difference  in  the  "follows"  (])  operator  and  the
-   "sorts-after" (]]) operator is the way they treat numbers.
-
-   Example:
-
-
-   GTM>WRITE 1=1
-
-   1
-   GTM>WRITE 1=2
-
-   0
-   GTM>WRITE 1="1"
-
-   1
-   GTM>WRITE 1=01
-
-   1
-   GTM>WRITE 1="01"
-
-   0
-   GTM>WRITE 1=+"01"
-
-   1
-   GTM>
-
-   These examples illustrate the dual nature of the equal  sign  operator.
-   If both expressions are string or numeric,  the  results  are  straight
-   forward. However, when the expressions are  mixed,  the  native  string
-   data type prevails.
-
-   Example:
-
-
-   GTM>WRITE "a"'="A"
-
-   1
-   GTM>WRITE "FRED"'["RED"
-
-   0
-   GTM>WRITE "ABC"']""
-
-   0
-   These  examples  demonstrate  combinations  of  the  string  relational
-   operators with the NOT operator.
-
-3 Pat_Match_Operator
-   Pattern Match Operator
-
-   The pattern match operator (?)  causes  M  to  return  a  TRUE  if  the
-   expression ahead of the operator matches the characteristics described
-   by  the  pattern  following  the  operator.  The  pattern  is  not  an
-   expression.
-
-   Patterns are made up of two elements:
-
-   o    A repetition count
-
-   o    A pattern code, a string literal or an alternation list
-
-   The element following the pattern match  operator  may  consist  of  an
-   indirection operator, followed  by  an  element  that  evaluates  to  a
-   legitimate pattern.
-
-   The repetition count consists of either a single integer literal  or  a
-   period  (.)  delimiter  with  optional  leading  and  trailing  integer
-   literals. A single integer literal specifies an exact repetition count.
-   The period syntax specifies a range of repetitions  where  the  leading
-   number is a minimum and the trailing number  is  a  maximum.  When  the
-   repetition count is missing the leading number, M assumes there  is  no
-   minimum, (i.e., a minimum  of  zero).  When  the  repetition  count  is
-   missing the trailing number, M does not place a maximum on  the  number
-   of repetitions.
-
-   The pattern codes are:
-
-        A alphabetic characters upper or lower case
-        C control characters ASCII 0-31 and 127
-        E any character; used to pass all characters  in  portions  of  the
-        string where the pattern is not restricted
-        L lower-case alphabetic characters, ASCII 97-122
-        N digits 0-9, ASCII 48-57
-        P punctuation, ASCII 32-47, 58-64, 91-96, 123-126
-        U upper-case alphabetic characters, ASCII 65-90
-   Pattern codes may be upper or lower case and may  be  replaced  with  a
-   string literal. GT.M allows the M pattern match definition of patcodes
-   A, C, N, U, L, and P to be extended or changed, (A can only be modified
-   implicitly by modifying L or U) and new patcodes  added.  For  detailed
-   information  on  enabling  this  functionality,  refer  to  the
-   "Internationalization" chapter in GT.M Programmer's Guide.
-
-        The GT.M compiler accepts pattern codes other than those explicitly
-        defined above. If, at run-time, the pattern codes come into use and
-        no pattern definitions are available, GT.M issues a run-time error
-        (PATNOTFOUND). GT.M does not currently implement a mechanism for Y
-        and Z patterns and continues to treat those as compile-time syntax
-        errors.
-
-   Example:
-
-
-   GTM>WRITE "ABC"?3U
-
-   1
-   GTM>WRITE "123-45-6789"?3N1"-"2N1"-"4N
-
-   1
-   The first WRITE has a simple one-element pattern while the  second  has
-   multiple elements including both codes and  string  literals.  All  the
-   repetition counts are fixed.
-
-   Example:
-
-
-   I x?.E1C.E W !,"Must not contain a control character" Q
-
-   This example uses a pattern match to test for control characters.
-
-   Example:
-
-
-   I acn?1U.20A1","1U.10A D
-
-   .S acn=$G((^ACX($P(acn,","),$P(acn,",",2)))
-
-   This example uses a pattern match with implicit minimums  to  determine
-   that an "account number" is actually a name, and to trigger  a  look-up
-   of the corresponding account number in the ^ACX cross index.
-
-   The pattern match operator accepts the  alteration  syntax.  Alteration
-   consists of a repeat  count  followed  by  a  comma-delimited  list  of
-   patatoms enclosed in parentheses "()". The semantic is that the pattern
-   matches if any of the listed patterns matches the operand  string.  For
-   example, ?1(2N1"-"7N,3N1"-"2N1"-"4N).1U might be a way to match either
-   a social security number or a taxpayer ID. Since alternation is defined
-   as one of the ways of constructing a patatom, alternation can nest (be
-   used recursively).
-
-        Complex pattern matches may not be efficient to evaluate, so every
-        effort should be made to simplify any commonly used pattern and to
-        determine  if  more  efficient  alternative  logic  would  be  more
-        appropriate.
-
-2 Gen_M_Comm
-   General M Commands
-
-   M commands may be abbreviated to a defined prefix. Most  commands  have
-   arguments. However, some commands have either optional arguments or no
-   arguments. When a command has no  argument  and  is  followed  by  more
-   commands on the same line, at least two spaces (<SP>) must  follow  the
-   command without arguments. Commands  that  accept  arguments  generally
-   accept multiple arguments  on  the  same  command.  M  treats  multiple
-   arguments the same as multiple occurrences of the  same  command,  each
-   with its own argument.
-
-3 Postconditionals
-   Postconditionals
-
-   M provides postconditionals as a tool for placing a  condition  on  the
-   execution of a single command and, in  some  cases,  a  single  command
-   argument. A postconditional consists of a colon (:) delimiter followed
-   by a truth-valued expression. When the expression evaluates to true, M
-   executes the command  occurrence.  When  the  expression  evaluates  to
-   false, M does not execute the command occurrence.
-
-4 Comm_Postconditionals
-   Command Postconditionals
-
-   Command postconditionals appear immediately  following  a  command  and
-   apply to all arguments for the command when it has multiple arguments.
-   All commands except commands that themselves have a conditional aspect
-   accept a command postconditional. Among the M standard commands, ELSE,
-   FOR, and IF do  not  accept  command  postconditionals.  All  the  GT.M
-   command extensions accept command postconditionals.
-
-4 Arg_Postconditionals
-   Argument Postconditionals
-
-   Commands that affect the flow of control may accept postconditionals on
-   individual  command  arguments.  Because  multiple  arguments  act  as
-   multiple commands, this is a straight-forward application of  the  same
-   principal as command postconditional. The only M standard commands that
-   accept argument postconditionals are DO, GOTO,  and  XECUTE.  The  GT.M
-   command extensions that accept  argument  postconditionals  are  BREAK,
-   ZGOTO, and ZSYSTEM.
-
-3 Timeouts
-   Timeouts
-
-   M provides timeouts as a tool to retain program control  over  commands
-   of indefinite duration. A timeout consists of a colon (:) delimiter on
-   an argument, followed by a numeric expression specifying the number of
-   seconds for M to attempt to execute the command. When  the  timeout  is
-   zero (0), M makes a single attempt to complete the command.
-
-   GT.M has been designed to allow large timeout values,  and  to  protect
-   against arithmetic overflow when converting  large  timeout  values  to
-   internal representations. When a command has a timeout, M maintains the
-   $TEST intrinsic special variable  as  the  command  completes.  If  the
-   command completes successfully, M  sets  $TEST  to  TRUE  (1).  If  the
-   command times out before successful completion, M sets $TEST  to  FALSE
-   (0). When a command argument does not specify a  timeout,  M  does  not
-   maintain $TEST.
-
-   The following commands accept timeouts:
-
-   o    LOCK
-
-   o    JOB
-
-   o    OPEN
-
-   o    READ
-
-   o    ZALLOCATE
-
-   When a READ times out, M  returns  any  characters  that  have  arrived
-   between the start of the command and the timeout. M  does  not  produce
-   any partial results for any of the other timed commands.
-
-2 Gen_M_Intrin_Func
-   General M Intrinsic Functions
-
-   M Intrinsic Functions start with a single dollar sign ($) and have one
-   or more arguments enclosed in parentheses () and  separated  by  commas
-   (,). These functions provide an expression result by performing actions
-   that would be impossible or difficult to perform using M  commands.  It
-   is now possible to invoke a C function in a package  via  the  external
-   call mechanism.
-
-2 Gen_M_Intr_Spec_Var
-   General M Intrinsic Special Variables
-
-   M Intrinsic Special Variables start with a single dollar sign ($). GT.M
-   provides such variables for program examination.  In  some  cases,  the
-   Intrinsic Special Variables may be SET to modify the corresponding part
-   of the environment.
-
-2 Routines
-   Routines
-
-   M routines have a name and consist of lines  of  code  followed  by  an
-   end-of-record which is a carriage return, formfeed (<CR><FF>) sequence.
-   M separates the name of a routine from the body of the routine with an
-   end-of-line which is a carriage-return, line-feed (<CR><LF>) sequence.
-
-   GT.M stores routine sources in UNIX files and implicitly  supplies  the
-   end-of-record and end-of-line character sequences.
-
-   In M, a routine has no particular impact on variable management and may
-   include code that is invoked at different  times  and  has  no  logical
-   intersection.
-
-3 Lines
-   Lines
-
-   A line of M code consists of the following elements  in  the  following
-   order:
-
-   o    An optional label.
-
-   o    A  line-start  delimiter.  The  standard  defines  the  line-start
-        delimiter as a space (<SP>) character. In order to enhance routine
-        readability, GT.M extends M by accepting one  or  more  tab  (<HT>)
-        characters as line-start delimiters.
-
-   o    Zero or more level indicators, which are  periods  (.).  The  level
-        indicators show the level of nesting for argumentless DO commands:
-        the more periods, the deeper the  nesting.  M  ignores  lines  that
-        contain  level  indicators  unless  they  directly  follow  an
-        argumentless DO command with a matching level of nesting.
-
-   o    Zero or more commands  and  their  arguments.  M  accepts  multiple
-        commands on a line. The argument(s) of one  command  are  separated
-        from the next command by a command-start delimiter,  consisting  of
-        one or more spaces (<SP>).
-
-   o    A terminating end-of-line, which is a carriage  return,  line  feed
-        (<CR><LF>) sequence.
-
-4 Labels
-   Labels
-
-   In addition to labels that follow the rules  for  M  names,  M  accepts
-   labels consisting only of digits. In a label consisting only of digits,
-   leading zeros are considered significant. For example, labels 1 and 01
-   are different. Formalists may immediately follow a label. A Formalists
-   consists of one or more names enclosed in  parentheses  ().  Formalists
-   identify local variables that "receive" passed values  in  M  parameter
-   passing.
-
-   In GT.M, a colon (:) delimiter may be  appended  to  the  label,  which
-   causes the label to be treated as "local." Within the routine in which
-   they appear, they perform exactly as they would  without  the  trailing
-   colon but they are inaccessible to other routines. Using  local  labels
-   reduces object size and linking  overhead,  for  both  ZLINK  and  host
-   linking.
-
-4 Comments
-   Comments
-
-   In addition to commands, a line may also contain a comment that starts
-   with a leading semi-colon (;) delimiter. The scope of a comment is the
-   remainder of the line. In other words, M ignores anything to the right
-   of the comment delimiter. The standard defines  the  comment  delimiter
-   (;) as it would a command, and therefore requires that it always appear
-   after a linestart. GT.M extends the  standard  to  permit  comments  to
-   start at the first character of a line or in an argument position.
-
-3 Entry_Ref
-   Entry References
-
-   M entryrefs provide a generalized target for referring to a line within
-   a routine. An entryref may contain some  combination  of  a  label,  an
-   offset, and a routine name (in that order). The offset is delimited by
-   a plus sign (+) and the routinename is delimited by a caret symbol(^).
-   When an entryref does not contain a label, M assumes the offset is from
-   the beginning of the routine. When an  entryref  does  not  contain  an
-   offset, M uses an offset of zero (0). When an entryref does not contain
-   a routine name, M assumes the routine that is currently executing.
-
-   M permits every  element  in  an  entryref  to  have  the  form  of  an
-   indirection operator, followed  by  an  element  that  evaluates  to  a
-   legitimate occurrence of that portion of the entryref.
-
-        While  most  commands  and  functions  that  use  entryrefs  permit
-        argument indirection, M does not accept indirection  that  resolves
-        to a combination of label and offset or offset and routine name.
-
-   Offsets provide an extremely useful tool for debugging. However, avoid
-   their use in production code because they generally produce maintenance
-   problems.
-
-3 Label_Ref
-   Label References
-
-   M labelrefs are a subset of entryrefs that exclude offsets and separate
-   indirection. Labelrefs are used with parameter passing.
-
-2 Indirection
-   Indirection
-
-   M provides indirection as a means to defer definition  of  elements  of
-   the code until run-time. Indirection names a  variable  that  holds  or
-   "points" to the element. The indirection operator is  the  "at"  symbol
-   (@).
-
-3 Arg_Indirection
-   Argument Indirection
-
-   Most commands accept indirection of their entire argument.
-
-   Example:
-
-
-   GTM>SET x="^INDER"
-
-   GTM>DO @x
-
-   This example is equivalent to DO ^INDER.
-
-3 Atomic_Indirection
-   Atomic Indirection
-
-   Any expratom or any local or global variable name may  be  replaced  by
-   indirection.
-
-   Example:
-
-
-   GTM>SET x="HOOP",b="x"
-
-   GTM>WRITE a="HULA "__ at b
-
-   HULA HOOP
-
-   GTM>
-
-   This example uses indirection within a concatenation operation.
-
-3 Entryref_Indirection
-   Entryref Indirection
-
-   Any element of an entryref may be replaced by indirection.
-
-   Example:
-
-
-   GTM>SET lab="START",routine="PROG"
-
-   GTM>DO @lab^@routine
-
-   This example is equivalent to DO START^PROG.
-
-3 Patt_Code_Indirection
-   Pattern Code Indirection
-
-   A pattern code may be replaced by indirection.
-
-   Example:
-
-
-   GTM>FOR p="1U.20A1"",""1U.20A",5N IF x?@p QUIT
-
-   GTM>ELSE WRITE !,"Incorrect format" QUIT
-
-   This example uses pattern code indirection to test x for either a name
-   or a number.
-
-3 Name_Indirection
-   Name Indirection
-
-   Indirection may replace the prefix of a  subscripted  global  or  local
-   variable  name.  This  "name"  indirection  requires  two  indirection
-   operators,  a  leading  operator  similar  to  the  other  forms  of
-   indirection, and a trailing operator marking the  transition  to  those
-   subscripts that are not specified by indirection.
-
-   Example:
-
-
-   GTM>SET from="B",to="^A(15),x=""
-
-   GTM>FOR SET x=$O(@from@(x)) Q:x="" S @to@(x)=@from@(x)
-
-   This example uses name indirection to copy  the  level  contents  of  a
-   local array to a part of a global array. The example assumes  that  all
-   existing first level nodes of variable B have data.
-
-3 Indirection_Concerns
-   Indirection Concerns
-
-   M indirection provides  a  very  powerful  tool  for  allowing  program
-   abstraction. However, because indirection is frequently unnecessary and
-   has some disadvantages, use it carefully.
-
-   Because routines that use indirection  in  some  ways  do  not  contain
-   adequate information for easy reading, such routines tend  to  be  more
-   difficult to debug and maintain.
-
-   To improve run-time performance, GT.M tends to move work from run-time
-   to compile-time.  Indirection  forces  compiler  actions  to  occur  at
-   run-time, which minimizes the benefits of compilation.
-
-   M allows most forms of indirection to be recursive.  However,  in  real
-   applications, recursive indirection typically makes  the  code  obscure
-   and slow.
-
-   There are circumstances where indirection serves a worthwhile purpose.
-   For instance, certain utility functions with a general  nature  may  be
-   clearly abstracted and coded using indirection. Because M has no "CASE"
-   command, DO (or  GOTO)  with  argument  indirection  provides  a  clear
-   solution to the problem of providing complex branching.
-
-   Some M users prototype with indirection and  then  replace  indirection
-   with generated code that reduces run-time overhead. In any case, always
-   consider whether indirection can be replaced with  a  clearer  or  more
-   efficient approach.
-
-2 Param_Passing
-   Parameter Passing
-
-   Parameter passing provides a way of explicitly controlling some or all
-   of the variable context transferred between M routines.
-
-   M uses parameter passing for:
-
-   o    A DO command with parameters
-
-   o    Extrinsic functions and special variables
-
-   Parameter passing is optional on DO commands.
-
-   Parameter  passing  uses  two  argument  lists:  the  actuallist  that
-   specifies the parameters that M passes to an invoked routine,  and  the
-   formalist that specifies the local variables to  receive  or  associate
-   with the parameters.
-
-3 Actuallists
-   Actuallists
-
-   An actuallist specifies the parameters M passes to the invoked routine.
-   The actuallist contains a list of zero or more parameters  enclosed  in
-   parentheses, immediately following a DO or extrinsic function.
-
-   An actuallist:
-
-   o    Is made up of items separated by commas
-
-   o    Contains expressions and/or actualnames. Items may be missing, that
-        is, two commas may appear next to each other, with nothing between
-        them.
-
-   o    Must be used in an invocation of a label with a formallist, except
-        in the case of extrinsic special variables.
-
-   o    Must not contain undefined variables.
-
-   o    Must not have more items than a formallist with which it is used.
-
-   o    May contain the same item in more than one position.
-
-   Example:
-
-
-   GTM>DO MULT(3,X,.RESULT)
-
-   This example illustrates a DO with parameters. The actuallist contains:
-
-   o    3 - a numeric literal
-
-   o    X - a local variable
-
-   o    .RESULT - an actualname
-
-3 Actualnames
-   Actualnames
-
-   An actualname starts with a leading period (.) delimiter,  followed  by
-   an unsubscripted local variable name.  Actualnames  identify  variables
-   that are passed by reference, as described  in  a  subsequent  section.
-   While expressions in  an  actualname  are  evaluated  when  control  is
-   transferred to a formallabel, the variables identified  by  actualnames
-   are not; therefore, they do not need to be defined at the time control
-   is transferred.
-
-3 Formallists
-   Formallists
-
-   A formallist specifies the variables M uses to hold  passed  values.  A
-   formallist contains a list of  zero  or  more  parameters  enclosed  in
-   parentheses, immediately following a label.
-
-   A formallist:
-
-   o    Is made up of items separated by commas.
-
-   o    Contains unsubscripted local variable names.
-
-   o    Must be used and only used with a label invoked with an actuallist
-        or an extrinsic.
-
-   o    May contain undefined variables.
-
-   o    May have more items than an actuallist with which it is used.
-
-   o    Must not contain the same item in more than one position.
-
-   o    Must contain at least as many items as the actuallist with which it
-        is used.
-
-   Example:
-
-
-   MULT(MP,MC,RES)
-
-   SET RES=MP*MC
-
-   QUIT RES
-
-   In this example,  illustrating  a  simple  parameterized  routine,  the
-   formallist contains the following items:
-
-   o    MP
-
-   o    MC
-
-   o    RES
-
-   An example in the section describing "Actuallists" shows an invocation
-   that matches this routine.
-
-3 Formallabel
-   Formallabel
-
-   A label followed by a formallist is called a formallabel.
-
-3 Param_Pass_Operation
-   Parameter Passing Operation
-
-   M performs an implicit NEW on the formallist  names  and  replaces  the
-   formallist items with the actuallist items.
-
-   M provides the actuallist values to the  invoked  procedure  by  giving
-   each element in the formallist the value or reference provided  by  the
-   corresponding element in the actuallist. M associates the first name in
-   the formallist with the first item in the actuallist, the  second  name
-   in the formallist with the second item in the actuallist and so on. If
-   the actuallist is shorter than  the  formallist,  M  ensures  that  the
-   formallist items with no corresponding value are in  effect  NEWed.  If
-   the formallist  item  has  no  corresponding  item  in  the  actuallist
-   (indicated by two adjacent commas in the actuallist), that item in the
-   formallist becomes undefined.
-
-   If  the  actuallist  item  is  an  expression  and  the  corresponding
-   formallist variable is an array, parameter passing does not affect the
-   subscripted elements of the array. If an actualname  corresponds  to  a
-   formallist variable, M reflects  array  operations  on  the  formallist
-   variable, by reference, in the variable specified by the actualname.
-
-   M treats variables that are not part of the formallist as if parameter
-   passing did not exist (i.e., M makes  them  available  to  the  invoked
-   routine).
-
-   M initiates execution at the first command following the formallabel.
-
-   A QUIT command terminates execution of the invoked routine. At the time
-   of the QUIT, M restores the formallist items to the values they had at
-   the invocation of the routine.
-
-        In the case where a variable name appears as an actualname  in  the
-        actuallist, and also as a variable in the formallist, the restored
-        value reflects any change made by reference.
-
-   A QUIT from a DO does not take  an  argument,  while  a  QUIT  from  an
-   extrinsic must have an argument. This represents one of the  two  major
-   differences between the DO command with parameters and the extrinsics.
-   M returns the value of the QUIT command argument as the  value  of  the
-   extrinsic function or special variable. The other difference is that M
-   stacks $TEST for extrinsics.
-
-   Example:
-
-   SET X=30,Z="Hello"
-
-   DO WRTSQR(X)
-
-   ZWRITE
-
-   QUIT
-
-   WRTSQR(Z)
-
-   SET Z=Z*Z
-
-   WRITE Z,!
-
-   QUIT
-
-   Produces:
-
-
-   900
-   X=30
-
-   Z="Hello"
-
-3 Param_Pass_Mechanism
-   Parameter Passing Mechanisms
-
-   M passes the  actuallist  values  to  the  invoked  routine  using  two
-   parameter-passing mechanisms:
-
-   o    Call-by-Value - where expressions appear
-
-   o    Call-by-Reference - where actualnames appear
-
-   A call-by-value passes a copy of the value of the actuallist expression
-   to the invoked routine by assigning the copy to a formallist variable.
-   If the parameter is a variable, the invoked  routine  may  change  that
-   variable. However, because M constructs that variable to hold the copy,
-   it deletes the variable holding the copy when  the  QUIT  restores  the
-   prior formallist values. This also means that changes to  the  variable
-   by the invoked routine do not affect the value of the variable  in  the
-   invoking routine.
-
-   Example:
-
-
-   SET X=30
-
-   DO SQR(X)
-
-   ZWRITE
-
-   QUIT
-
-   SQR(Z) SET Z=Z*Z
-
-   QUIT
-
-   Produces:
-
-
-   X=30
-
-   A period followed by a name  identifies  an  actualname  and  causes  a
-   call-by-reference.
-
-   A call-by-reference passes a pointer to the  variable  of  the  invoked
-   routine so operations on the assigned formallist variable also  act  on
-   the actualname variable. Changes, including  KILLs  to  the  formallist
-   variable,  immediately  have  the  same  affect  on  the  corresponding
-   actualname variable. This means that M  passes  changes  to  formallist
-   variables in the invoked  routine  back  to  the  invoking  routine  as
-   changes in actualname variables.
-
-   Example:
-
-
-   SET X=30
-
-   DO SQR(.X)
-
-   ZWRITE
-
-   QUIT
-
-   SQR(Z) SET Z=Z*Z
-
-   QUIT
-
-   Produces:
-
-
-   X=900
-
-3 GTM_Param_Pass_Extn
-   GT.M Parameter Passing Extensions
-
-   The standard does not provide for indirection of a labelref because the
-   syntax has an ambiguity.
-
-   Example:
-
-
-   DO @X(1)
-
-   This example could be:
-
-   o    An invocation of the label specified by X with a parameter of 1.
-
-   o    An invocation of the label specified  by  X(1)  with  no  parameter
-        list.
-
-   GT.M  processes  the  latter  interpretation  as  illustrated  in  the
-   following example.
-
-   Example:
-
-   The syntax:
-
-
-   SET A(1)="CUBE",X=5
-
-   DO @A(1)(.X)
-
-   WRITE X,!
-
-   QUIT
-
-   CUBE(C) ;cube a variable
-
-   SET C=C*C*C
-
-   QUIT
-
-   Produces the result:
-
-   125
-   GT.M follows analogous syntax for routine indirection:
-
-   DO ^@X(A) invokes the routine specified by X(A).
-
-   DO ^@(X)(A) invokes the routine specified by X and passes the parameter
-   A.
-
-   DO ^@X(A)(A) invokes the routine  specified  by  X(A)  and  passes  the
-   parameter A.
-
-2 Ext_Calls
-   External Calls
-
-   GT.M allows references to a GT.M  database  from  programs  written  in
-   other programming languages that run under UNIX.
-
-   In GT.M, calls to C language routines may be made  with  the  following
-   syntax:
-
-
-   DO &[packagename.]name[^name][parameter-list]
-
-   or as an expression element,
-
-
-   $&[packagename.]name[^name][parameter-list]
-
-   Where packagename, like the name elements is a valid M name. Because of
-   the parsing conventions of M, the identifier between the ampersand (&)
-   and the optional parameter-list has precisely constrained punctuation -
-   a latersection describes how to  transform  this  into  a  more  richly
-   punctuated name should that be appropriate  for  the  called  function.
-   While the intent of the syntax is to permit the name^name to match an M
-   labelref, there is no semantic implication to any use of  the  up-arrow
-   (^).
-
-2 Extrinsic_Func
-   Extrinsic Functions
-
-   An extrinsic function is an M subroutine that  another  M  routine  can
-   invoke to return a value.
-
-   The format for extrinsic functions is:
-
-
-   $$[label][^routinename]([expr|.lname[,...]])
-
-   o    The optional label and optional routinename make up the formallabel
-        that specifies the name of the subroutine performing the extrinsic
-        function. The formallabel must contain at least one of its optional
-        components.
-
-   o    The optional expressions and actualnames  make  up  the  actuallist
-        that specifies the list  of  actual  parameters  M  passes  to  the
-        invoked routine.
-
-   M stacks $TEST for extrinsic functions. This is one of  the  two  major
-   differences between the DO command with parameters and  extrinsics.  On
-   return from an extrinsic function, M restores the  value  of  $TEST  to
-   what it was before the extrinsic function, regardless  of  the  actions
-   executed by the invoked routine.
-
-   M requires a routine that implements an extrinsic function to terminate
-   with an explicit QUIT command which has  an  argument.  M  returns  the
-   value of the QUIT command  argument  as  the  value  of  the  extrinsic
-   function. This is the other major difference  between  the  DO  command
-   with parameters and extrinsics. It  is  now  possible  to  invoke  a  C
-   function in a package via the external call mechanism.
-
-   Example:
-
-
-   GTM>ZPRINT ^POWER
-
-   POWER(V,X,S,T) ;extrinsic to raise to a power
-
-   ;ignores fractional powers
-
-   SET T=1,S=0
-
-   IF X<0 SET X=-X,S=1
-
-   FOR X=1:1:X S T=T*V
-
-   QUIT $S(S:1/T,1:T)
-
-   GTM> WRITE $$^POWER(3,4)
-
-   81
-   GTM>
-
-        The POWER routine  uses  a  formallist  that  is  longer  than  the
-        "expected" actuallist to  protect  local  working  variables.  Such
-        practice may be encouraged or  discouraged  by  your  institution's
-        standards.
-
-2 Extrinsic_Spc_Vars
-   Extrinsic Special Variables
-
-   An extrinsic special variable  is  a  user-written  M  subroutine  that
-   another M routine can invoke to return a value.
-
-   The format for extrinsic special variables is:
-
-   $$[label][^routinename]
-
-   o    The  optional  label  and  optional  routinename  make  up  the
-        formallabel, which specifies the name of the subroutine performing
-        the extrinsic function. The formallabel must contain at  least  one
-        of its optional component.
-
-   An extrinsic special  variable  can  be  thought  of  as  an  extrinsic
-   function without input parameters. $$x is equivalent  in  operation  to
-   $$x(). Extrinsic special variables are the only case  where  invocation
-   of a formallabel does not require an actuallist.  M  stacks  $TEST  for
-   extrinsic special variables.
-
-   M requires that a routine that implements an extrinsic special variable
-   terminate with an explicit  QUIT  command  which  has  an  argument.  M
-   returns the value of the QUIT command argument  as  the  value  of  the
-   extrinsic special variable.
-
-   Example:
-
-
-   GTM>ZPRINT ^DAYOWEEK
-
-   DAYOWEEK() ;extrinsic special variable to
-
-   ;provide the day of the week
-
-   QUIT $ZD($H,"DAY")
-
-   GTM>WRITE $$DAYOWEEK^DAYOWEEK
-
-   MON
-
-2 Trans_Processing
-   Transaction Processing
-
-   Transaction Processing (TP) provides a way for M programs  to  organize
-   database updates into logical groups  that  occur  as  a  single  event
-   (i.e., either all the database updates in a transaction occur, or none
-   of them occur). No other process may  behave  as  if  it  observed  any
-   intermediate state.
-
-   Transaction  processing  has  been  designed  to  improve  output  and
-   eliminate "live lock" conditions. The number of  attempts  to  complete
-   the transaction is limited to four. The fourth attempt is made inside a
-   "critical section" with all other processes temporarily locked  out  of
-   the database. Between the second and third  tries,  GT.M  waits  for  a
-   random interval between 0 and 500 milliseconds.
-
-3 TP_Def
-   TP Definitions
-
-   In M, a transaction is a sequence of commands that begins with a TSTART
-   command, ends with a TCOMMIT command, and is not within  the  scope  of
-   another transaction.
-
-   A successful transaction ends with a COMMIT that is  triggered  by  the
-   TCOMMIT command at the end of the transaction. A COMMIT causes all the
-   database updates performed within the transaction to  become  available
-   to other processes.
-
-   An unsuccessful transaction ends with a ROLLBACK. ROLLBACK  is  invoked
-   explicitly by  the  TROLLBACK  command,  or  implicitly  at  a  process
-   termination that occurs during a  transaction  in  progress.  An  error
-   within a transaction does not cause an implicit  ROLLBACK.  A  ROLLBACK
-   removes any database updates performed within  the  transaction  before
-   they are made available to other processes. ROLLBACK also releases all
-   resources LOCKed since the start of  the  transaction,  and  makes  the
-   naked reference undefined.
-
-   A RESTART is a transfer of control to the TSTART at  the  beginning  of
-   the  transaction.  RESTART  implicitly  includes  a  ROLLBACK  and  may
-   optionally restore local variables to the  values  they  had  when  the
-   initial TSTART was originally executed. A RESTART always restores $TEST
-   and the naked reference to the values they had when the initial TSTART
-   was executed. RESTART does  not  manage  device  state  information.  A
-   RESTART is invoked by the TRESTART command or by M if it is determined
-   that the transaction  is  in  conflict  with  other  database  updates.
-   RESTART can only successfully occur if the initial TSTART  includes  an
-   argument that enables RESTART.
-
-3 TP_Characteristics
-   TP Characteristics
-
-   Most transaction processing systems try to have transactions  meet  the
-   "ACID" test-Atomic, Consistent, Isolated, and Durable. To conform with
-   the M approach of providing maximum  flexibility  and,  when  possible,
-   backwards  compatibility  with  older  versions  of  the  standard,  M
-   transaction processing requires the use of programming conventions that
-   meet the ACID test.
-
-   For example, some effects of the BREAK, CLOSE,  JOB,  OPEN,  READ,  USE
-   WRITE, and ZSYSTEM commands may be observed by parties to  the  system.
-   Because the effects of these commands might cause an observing process
-   or person to conclude that a transaction executing them was in progress
-   and  perhapsfinished,  they  violate,  in  theory,  the  principle  of
-   Isolation.
-
-   The LOCK command is another example. A program may  attempt  to  use  a
-   LOCK to determine if another process has a transaction in progress. The
-   answer would depend on the management  of  LOCKs  within  transactions,
-   which is implementation-specific. This would therefore clearly violate
-   the principle of Isolation. The LOCK command is discussed later in this
-   section.
-
-   The simplest way to construct a transaction that meets the ACID test is
-   not to use any commands within  a  transaction  whose  affects  may  be
-   immediately "visible" outside the transaction. Unfortunately, because M
-   applications  are  highly  interactive,  this  is  not  entirely
-   straightforward.  When  a  user  interaction  relies  on  database
-   information, one solution is for the program to save the initial values
-   of any global values that could affect the outcome, in local variables.
-   Then, once the  interaction  is  over  and  the  transaction  has  been
-   initiated,  the  program  checks  the  saved  values  against  the
-   corresponding global variables. If they are the same, it  proceeds.  If
-   they differ, some other update has changed  the  information,  and  the
-   program must issue a TROLLBACK, and initiate another interaction  as  a
-   replacement.
-
-   Even when the "visible" commands appear  within  a  transaction,  an  M
-   application may provide wholesome operation by  relying  on  additional
-   programming or operating conventions.
-
-   A program using LOCKs to achieve  serializability  relies  on  properly
-   designed  and  universally  followed  LOCKing  conventions  to  achieve
-   Isolation with respect to database operations. LOCKs placed outside the
-   transaction (usually a LOCK immediately before the TSTART and an unlock
-   immediately after the  TCOMMIT)  achieve  serializability  by  actually
-   serializing any  approximately  concurrent  transaction.  LOCKs  placed
-   inside the transaction (frequently a LOCK immediately after the TSTART
-   and an unlock immediately before the TCOMMIT) signal M to  ensure  that
-   no operations  using  the  same  LOCK  resource(s)  overlap.  Within  a
-   transaction, an M implementation may defer both LOCKing  and  unlocking
-   to achieve its goal of serializability. A program  using  TSTARTs  with
-   the SERIAL keyword replaces the convention with a guarantee from M that
-   all the  database  activity  of  the  transaction  meets  the  test  of
-   Isolation with respect to database activity.
-
-   In GT.M the Durability aspect of the  ACID  properties  relies  on  the
-   journaling  feature.  When  journaling  is  on,  every  transaction  is
-   recorded in the journal file as well as in the  database.  The  journal
-   file constitutes a serial record of database actions and states. It is
-   always written before the database updates and is  designed  to  permit
-   recovery of the database if the database should be damaged. By default
-   when a process commits a transaction, it does not return control to the
-   application code until the transaction has reached  the  journal  file.
-   The  exception  to  this  is  that  when  the  TSTART  specifies
-   TRANSACTIONID="BATCH" the process resumes application execution without
-   waiting for the file system to confirm  the  successful  write  of  the
-   journal record. The  idea  of  the  TRANSACTIONID="BATCH"  has  nothing
-   inherently to do with "batch" processing -  it  is  to  permit  maximum
-   throughput  for  transactions  where  the  application  has  its  own
-   check-pointing mechanism, or method of recreating  the  transaction  in
-   case of a failure. The real durability of transactions is a function of
-   the durability of the journal files. Putting journal files on reliable
-   devices (RAID with UPS protection) and  eliminating  common  points  of
-   failure with the path to the  database  (separate  drives,  controllers
-   cabling) improve durability. The use of  the  replication  feature  can
-   also improve durability by moving the data to a separate site  in  real
-   time.
-
-   Attempting to QUIT (implicitly or explicitly) from code  invoked  by  a
-   DO, XECUTE, or extrinsic after  that  code  issued  a  TSTART  not  yet
-   matched by a TCOMMIT, produces an error. Although this is a consequence
-   of the RESTART capability, it is true  even  when  that  capability  is
-   disabled. For example, this means that  an  XECUTE  containing  only  a
-   TSTART fails, while an XECUTE  that  performs  a  complete  transaction
-   succeeds.
-
-3 TP_Performance
-   TP Performance
-
-   To achieve the best GT.M performance, transactions should:
-
-   o    be as short as possible
-
-   o    consist, as much as possible, only of global updates
-
-   o    be SERIAL with no associated LOCKs
-
-   o    have RESTART enabled with a minimum of local variables protected by
-        a restart portion of the TSTART argument.
-
-   Large concurrent transactions using TCOMMIT may result in repeated and
-   inefficient attempts by competing processes to  capture  needed  scarce
-   resources, resulting in poor performance.
-
-   Example:
-
-
-   TSTART ():SERIAL
-
-   SET (ACCT,^M(0))=^M(0)+1
-
-   SET ^M(ACCT)=PREC,^PN(NAM)=ACCT
-
-   TCOMMIT
-
-   This transaction encapsulates these two SETs. The first increments the
-   tally of patients registered, storing the number in local variable ACCT
-   for faster access in the current program, and in global variable ^M(0).
-   The second SET stores a patient record by account number and the third
-   cross-references the account number with the patient name. Placing the
-   SETs within a single  transaction  ensures  that  the  database  always
-   receive either all of  the  SETs  or  none  of  them,  thus  protecting
-   database  integrity  against  process  or  system  failure.  Similarly,
-   another concurrent process, whether using transactions  or  not,  never
-   finds one of the SETs in place without also finding the other one.
-
-   Example:
-
-   TSTART ():SERIAL
-
-   IF $TRESTART>3 DO QUIT
-
-   .TROLLBACK
-
-   .WRITE !,"Too many RESTARTs"
-
-   .QUIT
-
-   SET (NEXT,^ID(0))=^ID(0)+1
-
-   SET ^ID(NEXT)=RECORD,^XID(ZIP,NEXT)=""
-
-   TCOMMIT
-
-   This transaction will automatically restart if it cannot serialize the
-   SETs to the database, and will terminate with a TROLLBACK if more than
-   3 RESTARTs occur.
-
-   GT.M provides a way to monitor transaction restarts by  reporting  them
-   to  the  operator  logging  facility.  If  the  environment  variable
-   TPRESTART_SYSLOG_DELTA is defined, GT.M reports every Nth restart where
-   N is the numeric evaluation of the value of TPRESTART_SYSLOG_DELTA. If
-   the environment variable TPRESTART_SYSLOG_LIMIT is defined, the restart
-   reporting begins after the number of restarts specified by the value of
-   TPRESTART_SYSLOG_LIMIT. For  example,  defining  both  the  environment
-   variable to the value 1, causes all TP  restarts  to  be  logged.  When
-   TPRESTART_SYSLOG_DELTA  is  defined,  leaving  TPRESTART_SYSLOG_LIMIT
-   undefined is equivalent to giving it the value 1.
-
-        For more information on  enhancements  related  to  TP  performance
-        refer to the "NOISOLATION" section under VIEW command topic in the
-        "Commands" chapter in GT.M Programmer's Guide.
-
-3 TP_Example
-   TP Example
-
-   Here is a transaction processing example that  lets  you  exercise  the
-   concept. If you  use  this  example,  be  mindful  that  the  functions
-   "holdit" and "trestart" are included as tools to allow  you  access  to
-   information within a transaction which would normally  be  hidden  from
-   users. These types of functions would not normally appear in production
-   code. Comments have been inserted into the code to explain the function
-   of various segments.
-
-
-   trans
-
-   ;This sets up the program constants
-
-   ;for doit and trestart
-
-   n
-
-   s $p(peekon,"V",51)=""
-
-   s $p(peekon,"V",25)="Peeking inside Job "_$j
-
-   s $p(peekoff,"^",51)=""
-
-   s $p(peekoff,"^",25)="Leaving peeking Job "_$j
-
-   ;This establishes the main loop
-
-   s CNFLTMSG="Conflict, please reenter"
-
-   f r !,"Name: ",nam q:'$l(nam) d
-
-   .i nam="?" d q
-   ..w !,"Current data in ^trans:",! d:$d(^trans) q
-   ...zwrite ^trans
-   .f s ok=1 d q:ok w !,$C(7),CNFLTMSG,$C(7),!
-   ..s old=$g(^trans(nam),"?")
-   ..i old="?" w !,"Not on file" d q
-   ...;This is the code to add a new name
-   ...f d q:data'="?"
-   ....r !,"Enter any info using '#' delimiter: ",!,data
-   ...i data="" w !,"No entry made for ",nam q
-   ...TSTART ():SERIAL i $$trestart ;$$trestart for demo
-   ...i $d(^trans(nam)) s ok=^trans(nam)=data TRO q
-   ...s ^trans(nam)=data
-   ...TCOMMIT:$$doit ;$$doit for demo
-   ..;This is the beginning of the change and delete loop
-   ..f d q:fld=+fld!'$l(fld) w " must be numeric"
-   ...w !,"Current data: ",!,old
-   ...r !,"Piece no. (negative to delete record) : ",fld
-   ..i 'fld w !,"no change made" q
-   ..;This is the code to delete a new name
-   ..i fld<0 d q ; delete record
-   ...f d q:"YyNn"[x
-   ....w !,"Ok to delete ",nam," Y(es) or N(o) <N>? "
-   ....r x s x=$e(x)
-   ...i "Yy"'[x!'$l(x) w !,"No change made" q
-   ...TSTART ():SERIAL i $$trestart ;$$trestart for demo
-   ...i $g(^trans(nam),"?")'=old TROLLBACK s ok=0 q
-   ...kill ^trans(nam)
-   ...TCOMMIT:$$doit; $$doit for demo
-   ..;This is the code to change a field
-   ..f r !,"Data: ",data q:data'="?"&(data'["#") d
-   ...w " must not be a single '?' or contain any '#'"
-   ..TSTART ():SERIAL i $$trestart ;$$trestart for demo
-   ..i '$d(^trans(nam)) s ok=0 TROLLBACK q
-   ..i $p(^trans(nam),"#",fld)=$p(old,"#",fld) d q
-   ...s ok=$p(^trans(nam),"#",fld)=data TROLLBACK
-   ..s $p(^trans(nam),"#",fld)=data
-   ..TCOMMIT:$$doit; $$doit for demo
-   q
-
-
-   doit()
-
-   ;This inserts delay and an optional
-
-   ;rollback only to show how it works
-
-   w !!,peekon d disp
-
-   f d q:"CR"[act
-
-   .r !,"C(ommit), R(ollback), or W(ait) <C>? ",act
-   .s act=$tr($e(act),"cr","CR")
-   .i act="?" d disp
-   i act="R" TROLLBACK w !,"User requested DISCARD"
-
-   w !,peekoff,!
-
-   q $TLEVEL
-
-
-   trestart()
-
-   ;This is only to show what is happening
-
-   i $TRESTART d
-
-   .w !!,peekon,!,">>>RESTART<<<",! d disp w !,peekoff,!
-   q 1
-
-
-   disp
-
-   w !,"Name: ",nam
-
-   w !,"Original data: ",!,old,!,"Current data: "
-
-   w !,$g(^trans(nam),"KILLED!")
-
-   q
-
-   Generally, this type of program would be receiving data  from  multiple
-   sessions into the same global.
-
-1 BREAK
-   Break
-
-   The BREAK command pauses execution of the  code  and  initiates  Direct
-   Mode.
-
-   The format of the BREAK command is:
-
-
-   B[REAK][:tvexpr] [expr[:tvexpr][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional expression contains a fragment of GT.M code to XECUTE
-        before the process enters Direct Mode.
-
-   o    The BREAK command without an argument causes a pause  in  execution
-        of the routine code and immediately initiates Direct Mode. In this
-        case, at least two (2) spaces must follow the BREAK to separate it
-        from the next command on the line.
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        expression is the argument postconditional  that  controls  whether
-        GT.M XECUTEs  the  argument.  If  present  and  true,  the  process
-        executes the code before  entering  Direct  Mode.  If  present  and
-        false, the process does not execute the code before entering Direct
-        Mode.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more BREAK arguments form a legal argument for a BREAK.
-
-   Issuing a BREAK command inside a transaction destroys the Isolation of
-   that transaction. Beacuse of the way that GT.M  implements  transaction
-   processing, a BREAK within  a  transaction  may  suffer  an  indefinite
-   number of restarts ("live lock").
-
-   Generally, programs in production  must  not  include  BREAK  commands.
-   Therefore, GT.M provides the ZBREAK and ZSTEP  commands,  which  insert
-   temporary breakpoints into the process rather  than  the  source  code.
-   BREAKs inserted with ZBREAK only exist until the  image  terminates  or
-   until explicitly removed by another ZBREAK command. ZSTEP also inserts
-   temporary BREAKs in the image that only exist for the execution of the
-   ZSTEP command. In the GT.M debugging environment,  ZBREAKs  and  ZSTEPs
-   that insert BREAKs provide a more flexible and less  error-prone  means
-   of setting breakpoints than coding BREAKs directly into a routine. For
-   more information on ZBREAK  and  ZSTEP,  refer  to  the  sections  that
-   describe those commands.
-
-   To resume execution of  the  interrupted  program,  use  the  ZCONTINUE
-   command.
-
-   GT.M displays messages identifying the source of a BREAK as:
-
-   o    The body of a program
-
-   o    A
-   o    ZBREAK action
-
-   o    A device EXCEPTION
-
-   o    A ZSTEP action
-
-   The  VIEW  "BREAKMSG"  mask  selectively  enables  or  disables  these
-   messages. See the section on "VIEW" for an explanation of the mask. By
-   default, a process executing a GT.M image displays all BREAK messages.
-
-   When a process encounters a BREAK,  it  displays  a  prompt  indicating
-   readiness to process commands in Direct Mode. By default,  Direct  Mode
-   displays the  GTM>  prompt.  SETting  the  $ZPROMPT  intrinsic  special
-   variable alters the prompt.
-
-2 Ex_of_Break
-   Examples of BREAK
-
-   Example:
-
-
-   LOOP0 F S act=$O(^act(act)) Q:act="" B:debug D LOOP1
-
-   This FOR loop contains a BREAK with a command postconditional.
-
-   Example:
-
-
-   B:$D(x) "W !,""OK""":x,"W !,""Wrong again""":'x
-
-   This uses a BREAK with both command and argument postconditionals. The
-   actions display debugging messages.
-
-1 CLOSE
-   Close
-
-   The CLOSE command breaks the connection between a process and a device.
-
-   The format of the CLOSE command is:
-
-
-   C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required expression specifies the device to CLOSE.
-
-   o    The optional keywords specify device parameters that control device
-        behavior; some device parameters take  arguments  delimited  by  an
-        equal sign (=). If there  is  only  one  keyword,  the  surrounding
-        parentheses are optional.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more CLOSE arguments form a legal argument for a CLOSE.
-
-1 DO
-   Do
-
-   The DO command  makes  an  entry  in  the  GT.M  invocation  stack  and
-   transfers execution to the location specified by the entryref.
-
-   The format of the DO command is:
-
-
-   D[O][:tvexpr] [entryref[(expr|.lvn[,...])][:tvexpr][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional entryref specifies a location (with  some  combination
-        of label, offset, and routinename)  at  which  execution  continues
-        immediately following the DO.
-
-   o    A DO command without an argument (that is, a DO followed by two (2)
-        spaces) transfers execution to the next line in the routine if that
-        line contains a number of periods (.) after the optional label and
-        before the required linestart. These periods indicate  the  current
-        level of "immediate" nesting caused by  argumentless  DOs.  If  the
-        line following the DO contains too many periods,  GT.M  reports  an
-        error; if the line following the DO contains too few periods, GT.M
-        ignores the DO command.
-
-   o    A DO command without an argument stacks the current value of $TEST,
-        in contrast to a DO with an argument, which does  not  protect  the
-        current value of $TEST.
-
-   o    The optional parameter list enclosed in parentheses  (  )  contains
-        parameters to pass to the routine entry point.
-
-   o    If the DO specifies a parameter list, the  entryref  location  must
-        start with a label and an argument list (that  is,  GT.M  prohibits
-        entryrefs with offsets during parameter passing).
-
-   o    If an element in the  parameter  list  starts  with  a  period,  it
-        specifies an unsubscripted local variable name and  the  DO  passes
-        that variable by reference. Otherwise,  the  element  specifies  an
-        expression that the DO evaluates and passes as a value.
-
-   o    The optional truth-valued expression following the parameter list,
-        or the  entryref  if  the  argument  contains  no  parameter  list,
-        specifies the argument postconditional and  controls  whether  GT.M
-        performs a DO with that argument.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more DO arguments form a legal argument for a DO.
-
-   An explicit or implicit QUIT within the scope of the DO, but not within
-   the scope of any other DO, FOR, XECUTE, or extrinsic, returns execution
-   to the instruction following the calling point. This point may  be  the
-   next DO argument or another command. At the end of a  routine,  or  the
-   end of a nesting level created by an argumentless DO, GT.M performs an
-   implicit QUIT. Any line that reduces the current level  of  nesting  by
-   changing the number of leading periods (.)  causes  an  implicit  QUIT,
-   even if that line only contains a comment.
-
-   Terminating the image and execution of ZGOTO commands are the only ways
-   to avoid eventually returning execution to  the  calling  point.  A  DO
-   command may optionally pass parameters to the invoked subroutine.
-
-2 Ex_of_Do
-   Examples of DO
-
-   Example:
-
-
-   GTM>DO ^%RD
-
-   This example invokes the routine directory utility program  (%RD)  from
-   Direct Mode. The caret symbol (^) specifies that the DO command invokes
-   %RD as an external routine.
-
-   Example:
-
-
-   GTM>DO A(3)
-
-   This example invokes the subroutine at label A and passes the  value  3
-   as a parameter. Because the DO argument does not have  a  caret  symbol
-   (^), it identifies A as a label in the current routine.
-
-   Example:
-
-
-   Label A;
-
-   SET di="" U outfile
-
-   FOR SET di=$O(^div(di)) Q:di="" D PREP D D POST
-
-   .SET de="",(nr,gr)=0
-
-   .WRITE "Division ",di,! F S de=$O(^de(di,de)) Q:de="" D
-
-   ..WRITE "Department ",de," Gross Rev: ",^grev(di,de),!
-
-   ..WRITE "Department ",de," Net Rev: ",^nrev(di,de),!
-
-   ..SET gr=gr+^grev(di,de),nr=nr+^nrev(di,de)
-
-   .W "Division Gross Rev: ",gr,!,"Division Net Rev: ",nr,!
-
-   DO PRINT^OUTPUT(outfile)
-
-   QUIT
-
-   This routine first uses a DO with a label argument (PREP)  to  do  some
-   pre-processing. Then, it uses an argumentless DO to loop  through  each
-   division of a company to format a report. Within the first argumentless
-   DO, a second argumentless DO (line 4) loops through  and  formats  each
-   department within a division. After the processing of all departments,
-   control returns to the first argumentless DO, which prints a summary of
-   the division. Following processing of all divisions, a DO with a label
-   argument (POST) does some post-processing. Finally, at the next-to-last
-   line, the routine uses a DO  that  invokes  a  subroutine  at  a  label
-   (PRINT) in an external routine  (^OUTPUT),  passing  the  name  of  the
-   output file (outfile) as a parameter.
-
-1 ELSE
-   Else
-
-   GT.M executes the remainder of the line after  the  ELSE  if  $TEST  is
-   FALSE (0). GT.M does not execute the rest of the line if $TEST is TRUE
-   (1).
-
-   The format of the ELSE command is:
-
-   E[LSE]
-
-   o    Because ELSE is a  conditional  command,  it  does  not  support  a
-        command postconditional.
-
-   o    The scope of the ELSE is the remainder of the line.
-
-   o    Because the ELSE has no argument, at  least  two  (2)  spaces  must
-        follow the command to separate it from  the  next  command  on  the
-        line.
-
-   Because the scopes of both the IF and the ELSE commands extend  to  the
-   rest of the GT.M line,  placing  an  ELSE  on  the  same  line  as  the
-   corresponding IF cannot achieve the desired result.  If  an  ELSE  were
-   placed on the same line as its corresponding IF,  then  the  expression
-   tested by the IF would be either TRUE or FALSE.  If  the  condition  is
-   TRUE, the code following  the  ELSE  would  not  be  executed.  If  the
-   condition is FALSE, the ELSE and everything following it would  not  be
-   executed.
-
-   ELSE is analogous to IF '$TEST, except the  latter  statement  switches
-   $TEST to its complement and ELSE never alters $TEST.
-
-   The scope of an ELSE can be extended with DO or XECUTE commands.
-
-2 Ex_of_Else
-   Examples of Else
-
-   Example:
-
-
-   IF x=+x SET x=x+y
-
-   ELSE WRITE !,x
-
-   The IF command evaluates  the  conditional  expression  x=+x  and  sets
-   $TEST. If $TEST=1 (TRUE), GT.M executes the commands following the IF.
-   The ELSE on the following line specifies an alternative action to take
-   if the expression is false.
-
-   Example:
-
-
-   IF x=+x DO ^GOFISH
-
-   ELSE SET x=x_"^"_y
-
-   The DO with an argument after the IF raises the  possibility  that  the
-   routine ^GOFISH changes the value of $TEST, thus making it possible to
-   execute both the commands following the IF and the  commands  following
-   the ELSE.
-
-   Example:
-
-
-   OPEN dev::0 ELSE WRITE !,"Device unavailable" QUIT
-
-   This ELSE depends on the result of the timeout on the OPEN command. If
-   the OPEN succeeds, it sets $TEST to one (1) and GT.M skips the rest of
-   the line after the ELSE. If the OPEN fails, it sets $TEST to zero (0),
-   and GT.M executes the remainder of the line after the ELSE.
-
-1 FOR
-   For
-
-   The FOR command provides a looping mechanism in  GT.M.  A  FOR  command
-   does not generate an additional level on the GT.M invocation stack.
-
-   The format of the FOR command is:
-
-
-   F[OR][lvn=expr[:numexpr1[:numexpr2]][,...]]]
-
-   o    Because FOR is a conditional command, it does not support a command
-        postconditional.
-
-   o    The scope of the FOR is the remainder of the line.
-
-   o    When the FOR has no argument, at least two (2) spaces  must  follow
-        the command to separate it from the next command on the line. This
-        specifies a loop that must be terminated by a QUIT, HALT, GOTO, or
-        ZGOTO.
-
-   o    The optional local variable name specifies a loop control variable
-        delimited by an equal sign (=). A FOR command has only one control
-        variable, even when it has multiple arguments.
-
-   o    When initiating the FOR, GT.M assigns the loop control variable the
-        value of the expression. When only an initial value  appears,  GT.M
-        executes the remainder of the line once for that  argument  without
-        forcing the control variable to be numeric.
-
-   o    If  the  argument  includes  an  increment  and,  optionally,  a
-        terminator, GT.M treats the initial expression as a number.
-
-   o    The optional numeric expression after the first colon (:) delimiter
-        specifies the increment for each iteration. The  FOR  command  does
-        not increment the control variable on the first iteration.
-
-   o    The  optional  numeric  expression  after  the  second  colon  (:)
-        delimiter specifies the limiting value for  the  control  variable.
-        This expression is evaluated only  when  the  control  variable  is
-        initialized to the corresponding initial value, then used  for  all
-        subsequent iterations.
-
-   o    GT.M does not execute the commands on the same line  following  the
-        FOR if:
-
-   The increment is non-negative and the  initial  value  of  the  control
-   variable is greater than the limiting value.
-   The increment is negative and the initial value of the control variable
-   is less than the limiting value.
-   o    After the first iteration, GT.M does not alter the control variable
-        and ceases execution under the control of the FOR if:
-
-   The increment is non-negative, and altering the control variable by the
-   increment would cause the control  variable  to  be  greater  than  the
-   limiting value.
-   The increment is negative, and altering the  control  variable  by  the
-   increment would cause the control variable to be less than the limiting
-   value.
-   o    When the FOR has multiple arguments,  each  one  affects  the  loop
-        control variable in sequence. For an argument to gain  control,  no
-        prior argument to the FOR can have an increment without a limit.
-
-   Increments and limits may be  positive,  negative,  an  integer,  or  a
-   fraction. GT.M never increments a control variable  "beyond"  a  limit.
-   Other commands may alter a control variable within the  extended  scope
-   of a FOR that it controls. When the argument  includes  a  limit,  such
-   modification can cause the FOR argument to yield control at  the  start
-   of the next iteration.
-
-   The scope of a FOR can be extended with DO or XECUTE commands.
-
-   GT.M terminates the execution of a FOR when  it  executes  an  explicit
-   QUIT or a GOTO (or ZGOTO in GT.M) that appears on the  line  after  the
-   FOR. FOR commands with arguments that have  increments  without  limits
-   and argumentless FORs can be infinite loops. Such FORs  must  terminate
-   with a QUIT or a GOTO within the immediate scope of the FOR. Also, such
-   FORs can, but seldom, terminate by a HALT within the scope of  the  FOR
-   as extended by DOs, XECUTEs, and extrinsics. FORs  terminated  by  such
-   commands act as "while" or "until" control mechanisms.
-
-2 Ex_of_For
-   Examples of FOR
-
-   Example:
-
-
-   GTM>KILL i FOR i=1:1:5 WRITE !,i
-
-   1
-   2
-   3
-   4
-   5
-   GTM>WRITE i
-
-   5
-   GTM>
-
-   This FOR loop has a control variable, i, which has the value one (1) on
-   the first iteration, then the value two (2), and so on,  until  in  the
-   last iteration i has the value five (5).  The  FOR  terminates  because
-   incrementing i would cause it to exceed the limit. Notice that i is not
-   incremented beyond the limit.
-
-   Example:
-
-
-   GTM>FOR x="hello",2,"goodbye" WRITE !,x
-
-   hello
-
-   2
-   goodbye
-
-   GTM>
-
-   This FOR loop uses the control variable x and  a  series  of  arguments
-   that have no increments or limits. Notice that the control variable may
-   have a string value.
-
-   Example:
-
-
-   GTM>FOR x="hello":1:-1 WRITE !,x
-
-   GTM>ZWRITE x
-
-   x=0
-
-   GTM>
-
-   Because the argument has an increment, the FOR initializes the control
-   variable x to the numeric evaluation of "hello" (0). Then,  GT.M  never
-   executes the remainder of the line because the increment  is  positive,
-   and the value of the control variable (0) is greater than the limiting
-   value (-1).
-
-   Example:
-
-
-   GTM>FOR y=-1:-3:-6,y:4:y+10,"end" WRITE !,y
-
-   -1
-
-   -4
-
-   -4
-
-   0
-   4
-   end
-
-   GTM>
-
-   This FOR uses two limited loop arguments and one  value  argument.  The
-   first argument initializes y to negative one (-1), then increments y to
-   negative four (-4). Because another increment would cause y to be less
-   than the limit (-6), the first argument  terminates  with  y  equal  to
-   negative four (-4). The second argument initializes  the  loop  control
-   variable to its current value and establishes a limit of six (6=-4+10).
-   After two iterations, incrementing y again would cause it to be greater
-   than the limit (6), so the second argument terminates with y  equal  to
-   four (4). Because the final argument has no increment, the FOR  sets  y
-   to the value of the argument, and GT.M executes the commands following
-   the FOR one more time.
-
-   Example:
-
-
-   GTM>S x="" F S x=$O(ar(x)) Q:x="" W !,x
-
-   This example shows an argumentless FOR used to examine all first level
-   subscripts of the local array ar. When $ORDER indicates that this level
-   contains  no  more  subscripts,  the  QUIT  with  the  postconditional
-   terminates the loop.
-
-1 GOTO
-   Goto
-
-   The GOTO command transfers execution to a  location  specified  by  its
-   argument.
-
-   The format of the GOTO command is:
-
-
-   G[OTO][:tvexpr] entryref
-
-   [:tvexpr][,...]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required entryref specifies the target location for the control
-        transfer.
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        entryref  specifies  the  argument  postconditional,  and  controls
-        whether GT.M performs a GOTO with that argument.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more GOTO arguments form a legal argument to a GOTO.
-
-   A GOTO command within a line following a FOR  command  terminates  that
-   FOR command.
-
-2 Ex_of_Goto
-   Examples of GOTO
-
-   Example:
-
-
-   GTM>GOTO TIME+4
-
-   This GOTO command transfers control from Direct Mode to the  line  that
-   is four (4) lines after the line labeled TIME (in the currently active
-   routine). Using an offset is typically a debugging technique and rarely
-   used in production code.
-
-   Example:
-
-
-   GOTO A:x<0,^A:x=0,A^B
-
-   This GOTO command transfers control to label A in the current routine,
-   if x is less than zero (0), to routine ^A if x is equal to zero (0), or
-   to label A in routine ^B. Once any of the transfers occurs, the rest of
-   the arguments have no effect.
-
-1 HALT
-   Halt
-
-   The HALT command stops GT.M program execution and causes GT.M to return
-   control to the operating  system  environment  that  invoked  the  GT.M
-   image.
-
-   The format of the HALT command is:
-
-
-   H[ALT][:tvexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional  that  controls  whether  GT.M
-        executes the command.
-
-   o    Because the HALT command has no argument, at least two  (2)  spaces
-        must follow the command to separate it from the next command on the
-        line. Note that additional commands do not serve any purpose unless
-        the HALT has a postconditional.
-
-   A HALT releases all shared resources  held  by  the  process,  such  as
-   devices OPENed in GT.M, databases, and GT.M  LOCKs.  If  the  value  of
-   $TLEVEL is greater than zero (0), a ROLLBACK is performed.
-
-   Because  HALT  and  HANG  share  the  same  abbreviation  (H),  GT.M
-   differentiates them based on whether an argument follows the command.
-
-   Example:
-
-
-   $ gtm
-
-   GTM>HALT
-
-   $
-
-   Because we invoke this GT.M image interactively,  the  HALT  in  Direct
-   Mode leaves the process at the shell prompt.
-
-1 HANG
-   Hang
-
-   The HANG command suspends GT.M program execution for a period  of  time
-   specified by the command argument.
-
-   The format of the HANG command is:
-
-
-   H[ANG][:tvexpr] numexpr[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The numeric expression specifies the  time  in  seconds  to  elapse
-        before resuming execution; actual elapsed time  may  vary  slightly
-        from the specified time. If the  numeric  expression  is  negative,
-        HANG  has  no  effect.  Portability  requirements  for  GT.M  only
-        guarantee accuracy to the nearest second.However, more accuracy can
-        be found on different UNIX systems.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more HANG arguments form a legal argument to a HANG.
-
-   A process that repeatedly tests  for  some  event,  such  as  a  device
-   becoming available or another process modifying a global variable, may
-   use a HANG to limit its consumption of computing resources.
-
-   Because  HALT  and  HANG  share  the  same  abbreviation  (H),  GT.M
-   differentiates them based on whether an argument follows the command.
-
-2 Ex_of_Hang
-   Examples of HANG
-
-   Example:
-
-
-   FOR QUIT:$D(^CTRL(1)) HANG 30
-
-   This FOR loop repeatedly tests  for  the  existence  of  ^CTRL(1),  and
-   terminates when that global  variable  exists.  Otherwise  the  routine
-   HANGs for 30 seconds and tests again.
-
-   Example:
-
-
-   SET t=1 F Q:$D(^CTRL(1)) H t I t<30 S t=t+1
-
-   This is similar to  the  previous  example,  except  that  it  uses  an
-   adaptive time that lengthens from 1 second to a limit of 30 seconds if
-   the routine stays in the loop.
-
-1 IF
-   IF
-
-   The IF command provides conditional execution of the remaining commands
-   on the line. When IF has an argument, it updates $TEST with  the  truth
-   value of its evaluated argument. GT.M executes the remainder of a line
-   after an IF statement when $TEST is 1 (TRUE). When $TEST is 0 (FALSE),
-   GT.M does not execute the rest of the line.
-
-   The format of the IF command is:
-
-
-   I[F] [tvexpr[,...]]
-
-   o    Because IF is a conditional command, it does not support a command
-        postconditional.
-
-   o    The scope of the IF is the remainder of the line.
-
-   o    The action of IF is controlled by the value of the  expression  and
-        by $TEST, if there is no expression.
-
-   o    IF with no argument acts on the existing value of $TEST  (which  it
-        does not change); in this case, at least two (2) spaces must follow
-        the IF to separate it from the next command on the line.
-
-   o    An indirection operator, and an expression  atom  evaluating  to  a
-        list of one or more IF arguments form a legal argument to IF.
-
-   Example:
-
-   IF A,B ...
-
-   is equivalent to
-
-   IF A IF B
-
-   An IF with more than one argument behaves as if  those  arguments  were
-   logically "ANDed." However, execution  of  the  line  ceases  with  the
-   evaluation of the first false argument.  For  IF  argument  expressions
-   containing the "AND" operator (&),  execution  still  ceases  with  the
-   evaluation of the first false argument. Any  global  references  within
-   the expression act in sequence to maintain the naked reference.
-
-   Postconditionals perform a function similar to IF; however, their scope
-   is limited to a single command or argument,  and  they  do  not  modify
-   $TEST. For more information on postconditionals.
-
-2 Ex_of_IF
-   Examples of IF
-
-   Example:
-
-
-   IF x=+x!(x="") DO BAL
-
-   In this example, the DO executes if x  contains  a  number  or  a  null
-   string.
-
-   Example:
-
-
-   WRITE !,?50,BAL IF 'BAL WRITE "****"
-
-   IF S EMPTY(acct)=""
-
-   The IF in the first line changes the value of  $TEST,  determining  the
-   execution of the code following the argumentless IF in the second line.
-   Such argumentless IFs may serve as a form of line continuation.
-
-   Example:
-
-
-   GTM>SET X=1,Y=1,Z=2 KILL UNDEF
-
-   GTM>IF X=1,Y=1,Z=3,UNDEF=0 W "HI"
-
-   GTM>
-
-   The IF command causes  GT.M  to  cease  executing  the  line  after  it
-   determines Z is not equal to three (3). Therefore, GT.M never evaluates
-   the reference to the undefined variable and never generates an error.
-
-   Example:
-
-
-   GTM>SET X=1 KILL UNDEF
-
-   GTM>IF X=1!(UNDEF=3) WRITE "HI"
-
-   HI
-
-   GTM>
-
-   Because GT.M  recognizes  that  the  X=1  fulfills  the  IF,  it  skips
-   evaluation of the UNDEF variable and executes this IF  command  without
-   generating an error. Because GT.M does not require  such  optimizations
-   and in fact discourages them by requiring that  all  global  references
-   maintain the naked indicator, other  implementations  may  generate  an
-   error.
-
-1 JOB
-   Job
-
-   The JOB command initiates another GT.M process that executes the named
-   routine.
-
-   $ZJOB is set to the pid of the process created by the JOB command. For
-   details  refer  to  the  "$ZJOB"  section  in  the  "Intrinsic  Special
-   Variable" chapter of GT.M Programmer's Guide.
-
-   The format of the JOB command is:
-
-
-   J[OB][:tvexpr] entryref
-
-   [(expr[,...])]
-   [:[(keyword[=value][:...])][:numexpr]][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required entryref specifies a location at which the new process
-        starts.
-
-   o    The optional parameter list enclosed  in  parentheses  ()  contains
-        parameters to pass to the routine entry point.
-
-   o    If the JOB specifies a parameter list, the entryref  location  must
-        start with a label and a formallist. GT.M prohibits entryrefs with
-        offsets during parameter passing.
-
-   o    The optional elements in the  parameter  list  specify  expressions
-        that the JOB evaluates and passes as values.
-
-   o    The  keywords  specify  optional  processparameters  that  control
-        aspects of the environment for the new process.
-
-   o    If the JOB command has only one processparameter,  the  surrounding
-        parentheses are optional.
-
-   o    Some keywords take numeric or string literals delimited by an equal
-        sign (=) as arguments. Because the values  are  constants,  strings
-        must be enclosed in quotation marks (" "), and  variable  arguments
-        require that the entire  argument  be  constructed  and  referenced
-        using indirection.
-
-   o    The optional numeric expression specifies a time in  seconds  after
-        which the command should timeout if unsuccessful; 0  results  in  a
-        single attempt.
-
-   o    When a JOB command contains  no  processparameters,  double  colons
-        (::) separate the time-out numeric expression from the entryref.
-
-   o    An indirection operator and an expression  atom,  evaluating  to  a
-        list of one or more JOB command arguments, form  a  legal  argument
-        for a JOB command.
-
-   o    The maximum command-line length from a JOB command is 8192 bytes.
-
-   The operating system deletes the resultant process  when  execution  of
-   its  GT.M  process  is  complete.  The  resultant  process  executes
-   asynchrounously  with  the  current  process.  Once  GT.M  starts  the
-   resultant process, the current process continues.
-
-   If a JOB command specifies a timeout, and GT.M  creates  the  resultant
-   process before the timeout elapses, JOB sets $TEST to true (1). If GT.M
-   cannot create the process within the specified timeout, JOB sets $TEST
-   to false (0). If  a  JOB  command  does  not  specify  a  timeout,  the
-   execution of the command does not affect $TEST.
-
-   If GT.M cannot create the process because of something that is unlikely
-   to  change  during  the  timeout  interval,  such  as  invalid  DEFAULT
-   directory specification, or the parameter list is  too  long,  the  JOB
-   command generates a run-time error. If the command does not  specify  a
-   timeout and the environment does not provide  adequate  resources,  the
-   process waits until resources become available to create the resultant
-   process.
-
-2 The_JOB_Env
-   The JOB Environment
-
-   When the JOB is forked,  UNIX  creates  the  environment  for  the  new
-   process by copying the environment  of  the  process  issuing  the  JOB
-   command and making a few minor modifications.By default,  the  standard
-   input is assigned to the null device, the standard output  is  assigned
-   to  routinename.mjo,  and  the  standard  error  is  assigned  to
-   routinename.mje.
-
-3 JOB_Impl_for_Dir
-   JOB Implications for Directories
-
-   By default, GT.M uses the  current  working  directory  of  the  parent
-   process for the working directory of the initiated process.
-
-   If the files specified by processparameters do not exist, and GT.M does
-   not have permission to create them, the JOBed process terminates. When
-   the corresponding files are  in  the  current  working  directory,  the
-   OUTPUT, INPUT, and  ERROR  processparameters  do  not  require  a  full
-   pathname.
-
-2 JOB_ProcParam
-   JOB Processparameters
-
-   The following sections describe the processparameters available for the
-   JOB command in GT.M.
-
-3 DEFAULT
-   DEF[AULT]=strlit
-
-   The string literal specifies the default directory.
-
-   The maximum directory length is 255 characters.
-
-   If the JOB command does not specify a DEFAULT directory, GT.M uses the
-   current default directory of the parent process.
-
-3 ERROR
-   ERR[OR]=strlit
-
-   The string literal specifies a value for stderr.
-
-   The maximum string length is 255 characters.
-
-   By default, JOB constructs the error file from the routinename using a
-   file extension of .mje: the default directory of the process created by
-   the JOB command.
-
-3 GBLDIR
-   GBL[DIR]=strlit
-
-   The string literal specifies  a  value  for  the  environment  variable
-   gtmgbldir.
-
-   The maximum length of the value permitted is 255 characters.
-
-   By default, the job uses the same specification for gtmgbldir  as  that
-   defined for the process using the JOB command.
-
-3 INPUT
-   IN[PUT]=strlit
-
-   The string literal specifies a value for stdin.
-
-   The maximum string length is 255 characters.
-
-   GT.M does not supply a default file extension.
-
-   By default, the job takes its input from the null device.
-
-3 OUTPUT
-   OUT[PUT]=strlit
-
-   The string literal specifies a value for stdout.
-
-   The maximum string length is 255 characters.
-
-   By  default,  JOB  constructs  the  output  file  pathname  from  the
-   routinename using a file extension of  .mjo  and  the  current  default
-   directory of the process created by the JOB command.
-
-3 STARTUP
-   STA[RTUP]=strlit
-
-   The string literal specifies a command line that GT.M invokes  a  shell
-   to execute before executing the GT.M  routine.  The  command  line  may
-   invoke a shell script or other images.
-
-        The executed command does not affect the environment of  the  JOBed
-        process.
-
-2 Ex_of_JOB
-   Examples of JOB
-
-   Example:
-
-
-   GTM>JOB ^TEST
-
-   This creates a job that starts doing the routine ^TEST in  the  current
-   working directory.
-
-   Example:
-
-
-   JOB PRINTLABELS(TYPE,PRNTR,WAITIM)
-
-   This passes three values (TYPE, PRNTR, and  WAITIM)  to  the  new  job,
-   which starts at the label PRINTLABELS of the current routine.
-
-1 KILL
-   Kill
-
-   The KILL command deletes local or global variables and their descendant
-   nodes.
-
-   The format of the KILL command is:
-
-
-   K[ILL][:tvexpr] [glvn|[(]lvn[,...][)][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional global or local variable name specifies  the  variable
-        to delete; KILL deletes not only  the  variable  specified  in  the
-        argument, but also all variables descended from that variable, that
-        is, those starting with the identical key-prefix.
-
-   o    KILLing a variable that does not currently exist has no effect.
-
-   o    The KILL command without an argument deletes all currently existing
-        local variables; in this case, at least two (2) spaces must follow
-        the KILL to separate it from the next command on the line.
-
-   o    When a KILL argument is enclosed in parentheses,  that  "exclusive"
-        KILL deletes  all  local  variables  except  those  listed  in  the
-        argument.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more KILL arguments
-   o    form a legal argument for a KILL.
-
-   KILL does not affect copies of local variables that have been "stacked"
-   by NEW or parameter passing.
-
-   Because a KILL can have a major impact, use KILL with caution.
-
-2 Ex_of_Kill
-   Examples of KILL
-
-   Example:
-
-
-   GTM>KILL SET a=0,a(1)=1,a(1,1)="under" KILL a(1) ZWR
-
-   a=0
-
-   GTM>
-
-   This uses an argumentless KILL to get a "fresh start" by  deleting  all
-   existing local variables. After SETting a, a(1), and a(1,1),  the  KILL
-   deletes a(1) and its descendants. The ZWRITE shows only a remaining.
-
-   Example:
-
-
-   GTM>KILL (a,b),^AB(a,b)
-
-   The first argument (an exclusive KILL)  specifies  to  KILL  all  local
-   variables except a and b. The second argument deletes ^AB(a,b) and any
-   descendants of that global variable node.
-
-1 LOCK
-   Lock
-
-   The LOCK command  is  used  to  reserve  and  release  resource  names,
-   providing a semaphore capability for GT.M  processes.  This  capability
-   can be used for interprocess synchronization and signaling.
-
-   Assigning a LOCK does not specify any explicit control  over  variables
-   and does not directly effect either read or write access to global (or
-   local) data. However, an application that adheres  to  clearly  defined
-   conventions of LOCKing before any access can indirectly achieve such an
-   effect.
-
-   The format of the LOCK command is:
-
-
-   L[OCK][:tvexpr] [[-|+]nref|(nref[,...])[:numexpr]
-
-   [,...]]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The nref argument specifies a resource name in the  format  of  the
-        GT.M name, with  or  without  subscripts  and  with  or  without  a
-        preceding caret (^). An nref can  optionally  have  an  environment
-        specification, including one without a preceding caret (^).
-
-   o    Outside of transactions, only one process in an environment can own
-        a particular LOCK at any given time.
-
-   o    Because the data storage in GT.M uses hierarchical  sparse  arrays,
-        and LOCK frequently serves to protect that data from inappropriate
-        "simultaneous" access by multiple processes, LOCK  treats  resource
-        names in a hierarchical fashion; a LOCK protects not only the named
-        resource, but also its ancestors and descendants.
-
-   o    When one or  more  nrefs  are  enclosed  in  parentheses  (),  LOCK
-        reserves all the  enclosed  names  "simultaneously,"  that  is,  it
-        reserves none of them until all become available.
-
-   o    A LOCK with no  argument  or  an  argument  with  no  leading  sign
-        releases all names currently reserved with previous  LOCK  commands
-        by the process; when a LOCK has  no  argument,  at  least  two  (2)
-        spaces must follow the LOCK to separate it from the next command on
-        the line.
-
-   o    A LOCK argument with a leading plus sign  (+)  acquires  the  named
-        resources without releasing currently held resources; if the named
-        resource is already LOCKed, such a LOCK  "counts  up"  the  process
-        interest in the resource.
-
-   o    A LOCK argument with a leading minus sign  (-)  "counts  down"  the
-        process interest in a named resource; if the count on a particular
-        lock reaches zero (0), GT.M releases the lock without releasing any
-        other currently held locks; a LOCK that releases a  named  resource
-        not currently owned by the process has no effect.
-
-   o    The optional numeric expression specifies a time in  seconds  after
-        which the command should timeout  if  unsuccessful;  0  provides  a
-        single attempt.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more LOCK arguments form a legal argument for a LOCK.
-
-   GT.M records LOCK and ZALLOCATE information  in  the  "lock  database."
-   GT.M distributes  the  lock  database  in  space  associated  with  the
-   database identified by the current Global Directory. However, the lock
-   database does not overlap or coincide with the  body  of  the  database
-   files holding the global data. Only the LOCK, ZALLOCATE and ZDEALLOCATE
-   commands, and the LKE utility program access the lock database.
-
-   GT.M maps reservations of names starting with ^ to  the  database  file
-   used to map global variables of the same name. If the Global Directory
-   maps the name A to file A.DAT, GT.M maps all reservations on ^A to file
-   space associated with A.DAT.
-
-   GT.M maps reservations on names not starting with ^ to  the  region  of
-   the database specified with the GDE command LOCK -REGION=. By default,
-   when GDE creates a Global Directory any reservations of local names are
-   mapped to the region DEFAULT.
-
-   These two factors  effect  the  following  result  in  the  programming
-   environment:
-
-   o    ^ reservations automatically intersect for all users  of  the  same
-        data in any database  file  independent  of  the  Global  Directory
-        mapping that file.
-
-   o    reservations without a leading ^ intersect in an arbitrary pattern
-        dependent on the Global Directory and  therefore  controlled  by  a
-        design decision made independently of application code design.
-
-   Since GT.M uses  resource  names  as  semaphores  for  signaling  among
-   multiple processes in a database environment, they interlock in a tree
-   structured fashion. When  LOCK  or  ZALLOCATE  reserves  a  subscripted
-   resource name such as ^D(1), other users of the database mapped by the
-   LOCKing (or ZALLOCATEing) process  cannot  reserve  ancestors  of  that
-   name, such as ^D, or  descendants,  such  as  ^D(1,2),  until  LOCK  or
-   ZDEALLOCATE releases that name.
-
-   Execution of the LOCK command does not affect the value or the state of
-   a variable. LOCK tests each argument to determine whether  the  process
-   can claim the name space. If another GT.M process has a  LOCK  on  that
-   name space, GT.M suspends the current process until the  other  process
-   releases the name space. To prevent the potential "infinite" suspension
-   of a routine execution, specify a timeout for the LOCK command.
-
-   LOCK with a leading plus (+) or minus (-)  sign  (incremental  LOCKing)
-   allows the acquisition of locks without releasing currently held locks.
-   This can lead to deadlocks.
-
-   To avoid deadlocks, use LOCK without a leading  +  or  -  sign  on  its
-   arguments  because  such  a  command  releases  all  previously  LOCKed
-   resources; or use a timeout with the LOCK command.
-
-   If a LOCK command specifies a timeout, and GT.M acquires  ownership  of
-   the named resource before the timeout elapses, LOCK
-   sets $TEST to TRUE (1). If GT.M cannot acquire ownership of  the  named
-   resource within the specified timeout, LOCK sets $TEST to FALSE (0). If
-   a LOCK command does not specify a timeout, the execution of the command
-   does not affect $TEST. If a LOCK with  an  argument  having  a  leading
-   minus sign (-) specifies a timeout, the command always  sets  $TEST  to
-   TRUE (1).
-
-   If a process issues  a  LOCK  command  for  a  named  resource  already
-   ZALLOCATEd by that process, the resource is both ZALLOCATEd and LOCKed.
-   LOCK does not release ZALLOCATEd resources. To  release  such  a  named
-   resource, the process must both ZDEALLOCATE and  unLOCK  the  resource.
-   For more information on ZALLOCATE, refer to the "ZALLOCATE".
-
-2 Locks_within_Trans
-   Using Locks within Transactions
-
-   Within transactions LOCKs are used by GT.M to  ensure  the  ability  to
-   serialize. There is no  guarantee,  however,  that  attempts  by  other
-   processes to examine LOCKs held with a  transaction  will  produce  the
-   same results as when LOCKs are  outside  of  a  transaction.  In  other
-   words, LOCKs  within  transactions  should  never  be  used  as  simple
-   semaphores.
-
-   The LOCK command locks a specified resource name that controls  a  tree
-   structured name space. Outside of transactions when one process  in  an
-   environment acquires a LOCK or a ZALLOCATE  on  a  named  resource,  no
-   other GT.M process in that environment can  LOCK  a  resource  with  an
-   "overlapping" name until the first process releases the  LOCK  that  it
-   holds.
-
-2 Ex_of_Lock
-   Examples of LOCK
-
-   Example:
-
-
-   LOCK A,^B, at C
-
-   LOCK (A,B, at C)
-
-   The first LOCK command LOCKs A and unLOCKs A before  LOCKing  ^B,  then
-   unLOCKs ^B before locking the name specified by  the  variable  C.  The
-   second LOCK command acquires all three resources at  once.  GT.M  waits
-   until all the named resources in the  argument  list  become  available
-   before  LOCKing  all  the  resources.  For  example,  if  the  resource
-   specified by the variable C is not available for  LOCKing,  GT.M  waits
-   until that resource becomes available before LOCKing A and ^B.
-
-   Example:
-
-
-   LOCK (A,B)
-
-   LOCK +C
-
-   LOCK -B
-
-   This LOCKs A and B, then incrementally LOCKs C. Finally it releases the
-   LOCK on B, while retaining the LOCKs on A and C.
-
-   Example:
-
-
-   LOCK (A,B,C)
-
-   LOCK +(B,C)
-
-   LOCK -(B)
-
-   This LOCKs A, B and C together. It then increments the lock "counts" of
-   B and C. The last LOCK command removes one "count" of  B,  leaving  one
-   count of A and B and two counts of C.
-
-   Example:
-
-
-   LOCK ^D:5
-
-   This command attempts to LOCK ^D with a timeout  of  five  seconds.  If
-   LOCK acquires the named resource before the timeout elapses, GT.M sets
-   $TEST to 1 (TRUE). If LOCK fails to acquire the named  resource  before
-   the timeout elapses, GT.M sets $TEST to 0 (FALSE).
-
-1 MERGE
-   Merge
-
-   The MERGE command copies  a  variable  and  all  its  descendants  into
-   another variable. MERGE does not delete the destination  variable,  nor
-   any of its descendants.
-
-   The format of MERGE command is:
-
-
-   M[ERGE][:tvexpr] glvn1=glvn2[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command post conditional that controls whether or not
-        GT.M executes the command.
-
-   o    When both glvn1 and glvn2 are local variables, the naked indicator
-        is not changed.
-
-   o    If glvn2 is a global variable and glvn1 is a local  variable,  then
-        the naked indicator references glvn2.
-
-   o    When both are global variables, the state of the naked indicator is
-        unchanged if glvn2 is undefined ($DATA(glvn2)=0).
-
-   o    In all other cases including $DATA(glvn2)=10, the  naked  indicator
-        takes the same value that it would have if the SET command replaced
-        the MERGE command and glvn2 had a value.
-
-   o    If glvn1 is a descendant of glvn2, or if glvn2 is a  descendant  of
-        glvn1; GT.M generates an error.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more MERGE arguments form a legal argument for a MERGE.
-
-   MERGE simplifies the copying  of  a  sub-tree  of  a  local  or  global
-   variable to another local or global variable. A sub-tree is all global
-   or local variables that are descendants of an specified variable. MERGE
-   offers a one-command alternative to the  current  technique  for  doing
-   sub-tree  copy  (that  is,  a  series  of  SET  commands  with  $ORDER
-   references).
-
-        GT.M may permit certain syntax or actions that are described by the
-        standard as in error. For example, a MERGE command  that  specifies
-        an  operation  where  the  source  and  destination  overlap  but
-        $DATA(source)=0 does not produce an error (which is equivalent to a
-        no-operation).
-
-2 Ex_of_Merge
-   Examples of MERGE
-
-   Example:
-
-
-   GTM>SET ^gbl1="one"
-
-   GTM>SET ^gbl1(1,1)="oneone"
-
-   GTM>SET ^gbl1(1,1,3)="oneonethree"
-
-   GTM>SET ^gbl1(1,2,4)="onetwofour"
-
-   GTM>SET ^gbl2(2)="gbl2_2"
-
-   GTM>SET ^gbl2(2,1,3)="gbl2_2_1_3"
-
-   GTM>SET ^gbl2(2,1,4,5)="gbl2_2_1_4_5"
-
-   GTM>MERGE ^gbl1(1)=^gbl2(2)
-
-   GTM>WRITE $REFERENCE
-
-   ^gbl1(1)
-
-   GTM>ZWRITE ^gbl1
-
-   ^gbl1="one"
-
-   ^gbl1(1)="gbl2_2"
-
-   ^gbl1(1,1)="oneone"
-
-   ^gbl1(1,1,3)="gbl2_2_1_3"
-
-   ^gbl1(1,1,4,5)="gbl2_2_1_4_5"
-
-   ^gbl1(1,2,4)="onetwofour"
-
-   GTM>ZWRITE ^gbl2
-
-   ^gbl2(2)="gbl2_2"
-
-   ^gbl2(2,1,3)="gbl2_2_1_3"
-
-   ^gbl2(2,1,4,5)="gbl2_2_1_4_5"
-
-   GTM>
-
-   The example illustrates how MERGE copies a sub-tree of one global into
-   another. The nodes in the sub-tree of ^gbl(2), for which $DATA() value
-   is 1 or 11, are copied to sub-tree of ^gbl1(1) as follows:
-
-   ^gbl1(1) is updated with value of ^gbl2(2)
-
-   ^gbl1(1,1,3) is updated with value of ^gbl2(2,1,3)
-
-   ^gbl1(1,1,4,5) is updated with value of ^gbl2(2,1,4,5)
-
-   Since ^gbl1(2,1) and ^gbl2(2,2,4) do not have values  ($DATA()=0),  the
-   corresponding nodes ^gbl1(1,1) and ^gbl(1,2,4)  respectively  are  left
-   unchanged. The naked indicator  takes  the  value  ^gbl(1)  as  if  SET
-   replaced MERGE. Notice that the MERGE command does not change ^gbl2(2)
-   or its descendants. Ancestor nodes of ^gbl(1) are also left unchanged.
-
-   Example:
-
-
-   GTM>KILL
-
-   GTM>SET ^gbl(1,2)="1,2"
-
-   GTM>MERGE lcl(3,4)=^gbl(1)
-
-   GTM>SET ^("naked")=2
-
-   GTM>ZWRITE ^gbl
-
-   ^gbl(1,2)="1,2"
-
-   ^gbl("naked")=2
-
-   GTM>ZWRITE lcl
-
-   lcl(3,4,2)="1,2"
-
-   GTM>
-
-   The example illustrates how MERGE creates a sub-tree of a variable when
-   the variable does not exist. Also, notice how the  naked  indicator  is
-   set when the source of the MERGE is a  global  and  the  destination  a
-   local.
-
-1 NEW
-   New
-
-   The NEW command "stacks" copies of local  variables  and  reinitializes
-   the variables. An explicit or  implicit  QUIT  from  a  DO,  XECUTE  or
-   extrinsic function "unstacks" the NEWed variables,  that  is,  restores
-   the variable to the stacked value. A NEW lasts  only  for  the  current
-   scope of execution.
-
-   The format of the NEW command is:
-
-
-   N[EW][:tvexpr] [[(]lvn[,...][)][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    NEW arguments are unsubscripted local variable names;  NEW  affects
-        not only the variable specified  in  the  argument,  but  also  all
-        variables descended from that variable.
-
-   o    When an undefined variable is NEWed, the fact that it is undefined
-        is "stacked", and when leaving the current  scope,  it  returns  to
-        being undefined, that is, the variable is KILLed.
-
-   o    Without  an  argument  GT.M  NEWs  all  currently  existing  local
-        variables; in this case, at least two (2) spaces  must  follow  the
-        NEW to separate it from the next command on the line.
-
-   o    When a NEW  argument  is  enclosed  in  parentheses,  that  NEW  is
-        considered "exclusive" and the variables inside the parentheses are
-        excluded from the effect of the NEW.
-
-   o    When the flow of execution leaves the scope of an  argumentless  or
-        an exclusive NEW, GT.M restores  all  stacked  variables  to  their
-        previous values, and deletes all other local variables.
-
-   o    The intrinsic special  variables  $ESTACK,  $ETRAP,  $ZGBLDIR,  and
-        $ZYERROR can be an explicit argument of a NEW.
-
-   o    The intrinsic special variable  $ZTRAP  can  also  be  an  explicit
-        argument of a NEW; this stacks the  current  value  of  $ZTRAP  and
-        assigns $ZTRAP a null value ($ZTRAP="").
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more NEW arguments form a legal argument for a NEW.
-
-   The NEW command provides a  means  of  confining  the  scope  of  local
-   variables. NEW operates only on unsubscripted local names and  acts  on
-   the entire named array.
-
-2 Ex_of_New
-   Examples of NEW
-
-   Example:
-
-
-   SET A(1)=1,B=4,C=5
-
-   WRITE !,"VARIABLES BEFORE NEW:",!
-
-   ZWRITE
-
-   DO LABEL
-
-   WRITE !,"VARIABLES AFTER RETURN:",!
-
-   ZWRITE
-
-   QUIT
-
-   LABEL NEW A SET C=7
-
-   WRITE !,"VARIABLES AFTER NEW:",!
-
-   ZWRITE
-
-   QUIT
-
-   Produces the results:
-
-
-   VARIABLES BEFORE NEW:
-
-   A(1)=1
-
-   B=4
-
-   C=5
-
-   VARIABLES AFTER NEW:
-
-   B=4
-
-   C=7
-
-   VARIABLES AFTER RETURN:
-
-   A(1)=1
-
-   B=4
-
-   C=7
-
-   Example:
-
-
-   SET (A,B,C,D)="TEST"
-
-   DO LABEL
-
-   WRITE !,"VARIABLES AFTER RETURN:",!
-
-   ZWRITE
-
-   QUIT
-
-   LABEL NEW (B,C) SET (A,B,Z)="NEW"
-
-   WRITE !,"VARIABLES AFTER EXCLUSIVE NEW:",!
-
-   ZWRITE
-
-   QUIT
-
-   Produces the results:
-
-
-   VARIABLES AFTER EXCLUSIVE NEW:
-
-   A="NEW"
-
-   B="NEW"
-
-   C="TEST"
-
-   Z="NEW"
-
-   VARIABLES AFTER RETURN:
-
-   A="TEST"
-
-   B="NEW"
-
-   C="TEST"
-
-   D="TEST"
-
-1 OPEN
-   Open
-
-   The OPEN command creates a connection between  a  GT.M  process  and  a
-   device.
-
-   The format of the OPEN command is:
-
-
-   O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])]
-
-   [:numexpr]][,...]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required expression specifies the device to OPEN.
-
-   o    The optional keywords specify deviceparameters that control device
-        behavior; some deviceparameters  take  arguments  delimited  by  an
-        equal sign (=); if the argument only contains one deviceparameter,
-        the surrounding parentheses are optional.
-
-   o    The optional numeric expression specifies a time in  seconds  after
-        which the  command  should  timeout  if  unsuccessful;  choosing  0
-        results in a single attempt to open the device.
-
-   o    When  an  OPEN  command  specifying  a  timeout  contains  no
-        deviceparameters, double colons (::) separate the  timeout  numeric
-        expression from the device expression.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more OPEN arguments form a legal argument for an OPEN.
-
-1 QUIT
-   Quit
-
-   Except when a QUIT appears on a line after  a  FOR,  the  QUIT  command
-   terminates  execution  of  the  current  GT.M  invocation  stack  level
-   initiated by a DO, XECUTE, extrinsic function or special variable, and
-   returns control to the next "lower" level. In this case, QUIT restores
-   any values stacked at  the  current  level  by  NEWs  or  by  parameter
-   passing. When a QUIT appears on the line following a FOR, it terminates
-   execution of the FOR.
-
-   The format of the QUIT command is:
-
-
-   Q[UIT][:tvexpr] [expr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    When a QUIT terminates an  extrinsic  function,  it  must  have  an
-        argument that supplies the value returned by the function;  in  all
-        other cases, QUIT must not have an argument and must be followed by
-        at least two (2) spaces to separate it from the next command on the
-        line.
-
-   o    An indirection operator and an expression atom evaluating to a QUIT
-        argument form a legal argument for a QUIT.
-
-   The QUIT performs two similar, but different,  functions  depending  on
-   its context. Because FORs do not add  levels  to  the  GT.M  invocation
-   stack, QUITs inside FOR loops simply terminate  the  loop.  QUITs  that
-   terminate DOs, XECUTEs and extrinsics remove a  GT.M  invocation  stack
-   level and therefore may adjust the local variable environment resulting
-   from previous NEWs or parameter passing. A QUIT from an extrinsic or a
-   frame created by an argumentless  DO  restores  $TEST  to  its  stacked
-   value.
-
-   Attempting to QUIT (implicitly or explicitly) from code  invoked  by  a
-   DO, XECUTE or extrinsic after that code issued a TSTART not yet matched
-   by a TCOMMIT, produces an error.
-
-2 Ex_of_Quit
-   Examples of QUIT
-
-   Example:
-
-
-   DO A
-
-   QUIT
-
-   A WRITE !,"This is label A"
-
-   The explicit QUIT at the line preceding the label  A  prevents  line  A
-   from executing twice. The sub-routine at line  A  terminates  with  the
-   implicit QUIT at the end of the routine.
-
-   Example:
-
-
-   WRITE $$ESV
-
-   QUIT
-
-   ESV()
-
-   QUIT "value of this Extrinsic Special Variable"
-
-   Because the label ESV has an argument list (which is empty),  GT.M  can
-   only legally reach that label with a extrinsic invocation. The QUIT on
-   the second line prevents execution from erroneously  "falling  through"
-   to the line labelled ESV. Because  ESV  identifies  a  subroutine  that
-   implements an extrinsic special variable, the QUIT on  the  line  after
-   ESV has an argument to provide the value of the extrinsic.
-
-   Example:
-
-
-   SET x="" F S x=$O(^BAL(x)) Q:x]]"AR5999"!'$L(x) D STF
-
-   The postconditional QUIT terminates the FOR loop.
-
-1 READ
-   Read
-
-   The READ command transfers input from the current device to a global or
-   local variable specified as a READ argument. For convenience, READ also
-   accepts arguments that perform limited output to the current device.
-
-   The format of the READ command is:
-
-
-   R[EAD][:tvexpr] (glvn|*glvn|glvn#intexpr)[:numexpr]|strlit|fcc[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    A subscripted  or  unsubscripted  global  or  local  variable  name
-        specifies a variable into which to store the  input;  the  variable
-        does not have to exist prior to the  READ;  if  the  variable  does
-        exist prior to the READ, the READ replaces its old value.
-
-   o    When an asterisk (*) immediately precedes the variable  name,  READ
-        accepts one character of input and places the ASCII code  for  that
-        character into the variable.
-
-   o    When  a  number-sign  (#)  and  a  non-zero  integer  expression
-        immediately  follow  the  variable  name,  the  integer  expression
-        determines the maximum number of characters accepted  as  input  to
-        the read; such reads  terminate  when  GT.M  reads  the  number  of
-        characters specified by the  integer  expression  or  a  terminator
-        character in the input stream, whichever occurs first.
-
-   o    The optional numeric expression specifies  a  time  in  seconds  at
-        most, for which the command waits for input to be terminated. When
-        a timeout is specified, if the input has been terminated before the
-        timeout expires, $TEST is set to 1 (true), otherwise, $TEST is set
-        to 0 (false).
-
-   o    To provide a concise means of issuing prompts,  GT.M  sends  string
-        literal and format control character (!,?intexpr,#) arguments of a
-        READ to the current device as if they were arguments of a WRITE.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more READ arguments form a legal argument for a READ.
-
-1 SET
-   Set
-
-   SET assigns values to variables or to a selected portion of a variable.
-
-   The format of the SET command is:
-
-
-   S[ET][:tvexpr] glvn|$EXTRACT()|$PIECE()|(glvn[,...])=expr[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    A subscripted or unsubscripted local or global variable name on the
-        left of the equal-sign (=) specifies a variable in which  to  store
-        the expression found on the  right  side  of  the  equal-sign;  the
-        variable need not exist prior to the SET; if  the  variable  exists
-        prior to the SET, the SET replaces its old value.
-
-   o    During a SET, GT.M evaluates the  right  side  of  the  equal  sign
-        before the left; this is an exception to the left-to-right order of
-        evaluation  in  GT.M  and  means  that  GT.M  maintains  the  naked
-        indicator using the expression on the right-hand side of the equal
-        sign (=) before setting the variable.
-
-   o    When the portion of the argument to the left of the  equal-sign  is
-        in the form of a list of variables  enclosed  in  parentheses,  SET
-        assigns the value of the expression on the right of the equal sign
-        to all the variables.
-
-   o    When the portion of the argument to the left of the equal  sign  is
-        in the form of a $PIECE function, SET replaces the specified piece
-        or pieces of the variable (specified as the first argument  to  the
-        $PIECE() form) with the value of the expression on the  right  side
-        of the equal-sign; if the variable did not exist prior to  the  SET
-        or does not currently contain the pieces identified by the optional
-        third  and  fourth  arguments  to  the  $PIECE()  form,  SET  adds
-        sufficient leading delimiters, as specified by the second argument
-        to the $PIECE form, to make the assignment fit the  $PIECE()  form.
-        Note that if the fourth argument exceeds the  third  argument,  the
-        target glvn is not changed and the  naked  indicator  is  also  not
-        modifed.
-
-   o    When the portion of the argument to the left of the equal  sign  is
-        in the form of a $EXTRACT  function,  SET  replaces  the  specified
-        character or characters of the variable  (specified  as  the  first
-        argument to the $EXTRACT() form) with the value of  the  expression
-        on the right side of the equal-sign; if the variable did not exist
-        prior to the SET or does not contain the characters  identified  by
-        the optional second and third arguments to the $EXTRACT() form, SET
-        adds sufficient leading spaces  to  make  the  assignment  fit  the
-        $EXTRACT() form. Note that if the third argument exceeds the second
-        argument, the target glvn is not changed and the naked indicator is
-        also not modifed.
-
-   o    The left-hand side of the equal-sign may also contain  any  of  the
-        following Intrinsic Special Variables:
-
-$ECODE
-$ETRAP
-$X
-$Y
-$ZCOMPILE
-$ZDIRECTORY
-$ZERROR
-$ZGBLDIR
-$ZINTERRUPT
-$ZMAXTPTIME
-$ZPROMPT
-$ZROUTINES
-$ZSOURCE
-$ZSTATUS
-$ZSTEP
-$ZTRAP
-$ZYERROR
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more SET arguments form a legal argument for a SET.
-
-   Because GT.M does not require predeclaration or typing of variables, a
-   SET with proper syntax always succeeds regardless of the prior state or
-   value of the variable, as long as GT.M can evaluate the  expression  to
-   the right of the equal sign (=).
-
-2 Ex_of_Set
-   Examples of SET
-
-   Example:
-
-
-   GTM>KILL SET a="x",(b,c)=1, at a="hello" ZWRITE
-
-   a=x
-
-   b=1
-
-   c=1
-
-   x="hello"
-
-   GTM>
-
-   The KILL command deletes any previously defined  local  variables.  The
-   SET command has three  arguments.  The  first  shows  a  simple  direct
-   assignment. The second shows the form that assigns the  same  value  to
-   multiple variables. The third shows atomic indirection on the  left  of
-   the equal  sign.  The  ZWRITE  command  displays  the  results  of  the
-   assignments.
-
-   Example:
-
-
-   GTM>SET ^(3,4)=^X(1,2)
-
-   Because GT.M evaluates the right-hand side of the equal sign before the
-   left-hand  side  within  a  SET  argument,  the  right-hand  expression
-   determines the
-   naked reference indicator prior to evaluation of  the  left-hand  side.
-   Therefore, this example assigns ^X(1,3,4) the value of ^X(1,2).
-
-   Example:
-
-
-   GTM>KILL x SET $P(x,"^",3)="piece 2" ZWRITE x
-
-   x="^^piece 2"
-
-   GTM>
-
-   This SET demonstrates a "setpiece" and shows how SET generates missing
-   delimiters when required.
-
-   Example:
-
-
-   GTM>SET x="I love hotdogs"
-
-   GTM>SET $EXTRACT(x,3,6)="want"
-
-   GTM>WRITE x
-
-   I want hotdogs
-
-   GTM>SET $EXTRACT(x,7)=" many "
-
-   GTM>WRITE x
-
-   I want many hotdogs
-
-   GTM>
-
-   The SET $EXTRACT command replaces and extracts the specified characters
-   with the value of  the  expression  on  the  right  hand  side  of  the
-   equal-sign (=).
-
-1 TCOMMIT
-   TCommit
-
-   The TCOMMIT command marks the end of a transaction  or  sub-transaction
-   and decrements $TLEVEL. If TCOMMIT  marks  the  end  of  a  transaction
-   (decrements $TLEVEL to zero), it invokes  a  COMMIT,  which  makes  the
-   database updates performed by the transaction  generally  available.  A
-   TCOMMIT issued when no transaction is in progress ($TLEVEL=0) produces
-   an error.
-
-   The format of the TCOMMIT command is:
-
-
-   TC[OMMIT][:tvexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    Because TCOMMIT has no argument,  at  least  two  (2)  spaces  must
-        follow the command to separate it from  the  next  command  on  the
-        line.
-
-   For an example of the use of the TCOMMIT command, refer to the chapter
-   on General Language Features of M in GT.M Programmer's Guide.
-
-1 TRESTART
-   TREstart
-
-   The TRESTART command attempts to RESTART  the  current  transaction.  A
-   RESTART transfers control back to the initial TSTART and restores much
-   of the process state to what it was  when  that  TSTART  was  executed.
-   Errors are produced if a TRESTART is used when  no  transaction  is  in
-   progress ($TLEVEL=0) and when the transaction  does  not  have  RESTART
-   enabled.
-
-   The format for the TRESTART command is:
-
-
-   TRE[START][:tvexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    Because TRESTART has no argument, at  least  two  (2)  spaces  must
-        follow the command to separate it from  the  next  command  on  the
-        line.
-
-   TRESTARTs (and implicit RESTARTs) do not  restore  any  device  states;
-   they do restore the following to the state they had when GT.M executed
-   the initial TSTART:
-
-   o    $TEST
-
-   o    The naked indicator
-
-   o    LOCKs held by the process
-
-   They also restore any local variables  named  by  one  or  more  active
-   TSTARTs to the values they had when they were first named.
-
-   For an example of the use of the TRESTART command, refer to the chapter
-   on "General Language Features of M" in the GT.M Programmer's Guide.
-
-1 TROLLBACK
-   TROllback
-
-   The TROLLBACK command terminates a transaction by causing  a  ROLLBACK,
-   which removes all database  updates  performed  within  a  transaction.
-   TROLLBACK also sets $TLEVEL  and  $TRESTART  to  zero  (0).  Issuing  a
-   TROLLBACK when no transaction is in progress  ($TLEVEL=0)  produces  an
-   error.
-
-   The format of the TROLLBACK command is:
-
-
-   TRO[LLBACK][:tvexpr] [intexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional integer expression indicates  an  argument  specifying
-        incremental rollback. If the value of the  argument  expression  is
-        greater than zero, it specifies the value of $TLEVEL to be achieved
-        by the rollback. If the value of the expression is less than zero,
-        the result is the number of levels to  rollback.  For  example;  -1
-        means rollback one level. If the argument expression is  zero,  the
-        effect is same as not specifying the argument, that is, the entire
-        GT.M transaction is rolled back.
-
-   Attempting  to  rollback  more  than  $TLEVEL  levels  (the  outermost
-   transaction) generates an error.
-
-   o    When the TROLLBACK has no argument, at least two  (2)  spaces  must
-        follow the command to separate it from  the  next  command  on  the
-        line.
-
-   In order to allow for  error  recovery  and/or  access  to  the  global
-   context of the  error,  errors  do  not  initiate  implicit  ROLLBACKs.
-   Therefore, the code for  handling  errors  during  transactions  should
-   generally include a TROLLBACK. Because the TROLLBACK releases resources
-   held by the transaction, it should appear as early as possible  in  the
-   error handling code.
-
-        A TROLLBACK does not cause a transfer of control but  is  typically
-        associated with one such as a QUIT or GOTO.
-
-   For an example of the use  of  the  TROLLBACK  command,  refer  to  the
-   chapter on "General Language Features of M" in  the  GT.M  Programmer's
-   Guide.
-
-1 TSTART
-   TStart
-
-   A  TSTART  command  marks  the  beginning  of  a  transaction  or
-   sub-transaction and increments $TLEVEL. When TSTART marks the beginning
-   of a transaction  ($TLEVEL=1),  its  arguments  determine  whether  the
-   transaction may RESTART and whether serializability is enforced.  If  a
-   transaction may RESTART, the TSTART  arguments  determine  which  local
-   variables are restored during a RESTART. Serializability is enforced by
-   LOCK commands or, if the SERIAL keyword is specified, by GT.M.
-
-   The format of the TSTART command is:
-
-
-   TS[TART][:tvexpr] [([lvn...])|lvn|*|][:keyword|(keyword...)]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    If $TLEVEL is 0 before the TSTART, the TSTART starts a transaction;
-        otherwise it starts a sub-transaction.
-
-   o    If the TSTART initiates  a  transaction  and  the  portion  of  the
-        argument before the colon (:) delimiter is empty,  the  transaction
-        is not eligible for RESTART. If the  TSTART  starts  a  transaction
-        ($TLEVEL=0) and the portion of the argument before the colon is not
-        empty, the transaction is eligible for RESTART. If  the  TSTART  is
-        nested (starts a sub-transaction), its arguments have no effect on
-        whether the transaction is eligible for RESTART.
-
-   o    If the portion of the argument before the colon is an asterisk (*),
-        any subsequent RESTART restores all local variables  to  the  value
-        they had when the TSTART was executed.
-
-   o    If the portion of the argument before the colon is an unsubscripted
-        local  variable  name  or  a  list  of  such  names  enclosed  in
-        parentheses, a RESTART restores the named variables  to  the  value
-        they had when the TSTART was executed.
-
-   o    If the portion of the argument before the colon is a set  of  empty
-        parentheses (), a RESTART does not restore any local variables.
-
-   o    The optional portion of the argument after the colon is  a  keyword
-        or a colon-separated list  of  keywords  enclosed  in  parentheses,
-        where the keywords specify transaction characteristics.
-
-   o    An indirection operator and an  expression  atom  evaluating  to  a
-        TSTART argument form a legal argument for a TSTART.
-
-   A TSTART within a transaction starts a sub-transaction. The argument to
-   such a TSTART has no effect on whether  the  existing  transaction  may
-   RESTART or whether serializability of the transaction is enforced. This
-   type of TSTART may add local variables to be restored in a transaction
-   that has RESTART enabled.
-
-   It is good coding  practice  to  synchronize  enabling  of  RESTART  on
-   TSTARTs at all levels of a transaction. A nested TSTART that  does  not
-   permit RESTART where  the  transaction  does,  may  indicate  that  the
-   sub-transaction has not been coded to properly handle RESTART.
-
-   Sub-transactions cannot COMMIT independently from the transaction, nor
-   can they RESTART independently. Sub-transactions  exist  largely  as  a
-   programming convenience to allow flexibility in organizing  code  in  a
-   modular fashion, and in addition to allow incremental ROLLBACKs.
-
-   When journaling, a transaction with  an  initial  TSTART  that  has  an
-   argument specifying TRANSACTIONID=expr, where  expr  is  an  expression
-   that evaluates to the keyword (case insensitive) BA[TCH], does not wait
-   for the journal update to be written before returning  control  to  the
-   application after a successful TCOMMIT. The goal of this feature is to
-   permit application control over any performance impact of journaling on
-   any subset of transactions that can be recreated or recovered by means
-   other than journaling.
-
-   For an example of the use of the TSTART command, refer to  the  chapter
-   on "General Language Features of M" in the GT.M Programmer's Guide.
-
-   The following keywords may appear in a TSTART argument:
-
-2 SERIAL
-   S[ERIAL]
-
-   The SERIAL keyword indicates that GT.M must ensure the serializability
-   of the transaction. When the SERIAL keyword is absent, the GT.M program
-   must ensure serializability by proper use of LOCK commands. On a nested
-   TSTART, this portion of the argument is ignored.
-
-2 TRANSACTIONID
-   T[RANSACTIONID]=expr
-
-   The  TRANSACTIONID  keyword  declares  an  arbitrary  transaction
-   identification.
-
-   If TRANSACTIONID="BATCH" or "BA" at transaction completion, the process
-   immediately continues  execution.  When  a  process  issues  a  [final]
-   TCOMMIT for a transaction and journaling  is  active,  by  default  the
-   process waits until the entire transaction is written  to  the  journal
-   file(s) before executing the next  command.  This  ensures  that  every
-   transaction is durable before the process moves on to the next step.
-
-   Transactions  flagged  as  "BATCH"  have  lower  latency  and  higher
-   throughput, but a lower guarantee of durability. Normally this flag is
-   used when operational procedures (such as a backup) or application code
-   (such as a checkpoint algorithm)  provides  an  acceptable  alternative
-   means of ensuring durability.
-
-1 USE
-   Use
-
-   The USE command selects the current device for READs (input) and WRITEs
-   (output).
-
-   The format of the USE command is:
-
-
-   U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required expression specifies the device to  make  the  current
-        device.
-
-   o    A USE that selects a device not currently  OPENed  by  the  process
-        causes a run-time error.
-
-   o    The optional keywords specify deviceparameters that control device
-        behavior; some deviceparameters  take  arguments  delimited  by  an
-        equal sign (=); if the argument only contains one deviceparameter,
-        the surrounding parentheses are optional.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more USE arguments form a legal argument for a USE.
-
-   For more information on USE, devices and deviceparameters, refer to the
-   "Input/Output Processing" chapter in the GT.M Programmer's Guide.
-
-1 VIEW
-   View
-
-   The VIEW command adjusts an environmental factor selected by a keyword
-   argument.  For  example,  VIEW  controls  journal  buffer  flushing,
-   determines whether GT.M reports undefined variables as errors or treats
-   them as null,  and  determines  which  BREAK  commands  should  display
-   messages.
-
-   The format of the VIEW command is:
-
-
-   V[IEW][:tvexpr] keyword[:expr2[:...]][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The keyword specifies the environmental factor to change.
-
-   o    The optional expression following the keyword specifies the nature
-        of the change to the environmental factor.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more VIEW arguments form a legal argument for a VIEW
-
-2 Key_Words_View
-   Key Words in VIEW Command
-
-   The following sections describe the keywords  available  for  the  VIEW
-   command in GT.M.
-
-3 BREAKMSG
-   "BREAKMSG":value
-
-
-   Sets the value of the BREAK message mask. When GT.M processes  a  BREAK
-   command, the BREAK message mask controls whether to display  a  message
-   describing the source of the BREAK.
-
-   The mask uses the following four values  that  are  added  together  to
-   provide the BREAKMSG value.
-
-   1 - BREAKs within the body of a program
-   2 - BREAKs within a ZBREAK action
-   4 - BREAKs within a device EXCEPTION
-   8 - BREAKs within a ZSTEP action
-   By default GT.M displays all BREAK messages.
-
-   Example:
-
-   GTM>VIEW "BREAKMSG":5
-
-   In this example the BREAKMSG value is 5, representing the sum of 1 and
-   4. This enables BREAKS within the body of a program (value 1) and for a
-   device EXCEPTION (value 4).
-
-3 GDSCERT
-   "GDSCERT":value
-
-
-   Enables (value=1) or disables (value=0) database block certification.
-
-   Database  block  certification  causes  GT.M  to  check  the  internal
-   integrity of every block as it writes the  block.  Block  certification
-   degrades performance and exists primarily as a tool for use by Sanchez.
-   The default is GDSCERT:0.
-
-3 JNLFLUSH
-   "JNLFLUSH"[:region]
-
-
-   Writes or flushes journaling buffers associated with the  given  region
-   to permanent storage, for example, to disk. If the VIEW "JNLFLUSH" does
-   not specify the optional region, GT.M flushes all active regions of the
-   current Global Directory.
-
-   Normally GT.M writes journal buffers when it fills the  journal  buffer
-   pool or when some period of time passes with no journal activity.
-
-   For more information on journaling,  refer  to  the  "GT.M  Journaling"
-   chapter in the GT.M Administration and Operations Guide.
-
-3 JNLWAIT
-   "JNLWAIT"
-
-
-   Causes a process to  pause  until  its  journaling  buffers  have  been
-   written. JNLWAIT ensures that GT.M successfully transfers all database
-   updates issued by the process to the journal file  before  the  process
-   continues. Normally, GT.M performs journal buffer writes asynchronously
-   while the process continues execution.
-
-   For more information on journaling,  refer  to  the  "GT.M  Journaling"
-   chapter in the GT.M Administration and Operations Guide.
-
-3 JOBPID
-   "JOBPID":"value"
-
-
-   Enables (value=1) or disables  (value=0)  the  addition  of  the  child
-   process ID to the output and  error  filenames  generated  by  the  JOB
-   command.
-
-   This option prevents output files generated by  the  JOB  command  from
-   being overwritten each time a new job is spawned from the  GT.M  source
-   file.
-
-3 LABELS
-   "LABELS":"value"
-
-
-   Enables (value="LOWER") or disables  (value="UPPER")  case  sensitivity
-   for labels within routines.
-
-   It is important to have the same  case  handling  at  compile-time  and
-   run-time.
-
-   Because GT.M stores routines as regular files and file names  are  case
-   sensitive on UNIX, GT.M always treates routine names as case sensitive.
-
-3 LVNULLSUBS
-   "[NO]LVNULLSUBS"
-
-
-   Allows or disallows local arrays to have null subscripts.  The  default
-   is LVNULLSUBS.
-
-3 NOISOLATION
-   "NOISOLATION":<expr>
-
-
-   where expr must evaluate to one of the following forms
-
-   o    "", that is, empty string : turn off the feature  for  all  globals
-        for which it has previously been turned on
-
-   o    "^gvn1,^gvn2,..." : turn on the feature  for  the  globals  in  the
-        list, turning it off for globals for which it has  previously  been
-        turned on
-
-   o    "+^gvn1,^gvn2,..." : add these globals to the list of globals that
-        have this feature turned on
-
-   o    "-^gvn1,^gvn2,..." : turn off the feature for these globals leaving
-        the status for other globals unchanged
-
-   GT.M transaction processing permits the application to specify a set of
-   globals that do not require GT.M to  preserve  Isolation,  one  of  the
-   "ACID" properties of TP. This shifts the responsibility  for  Isolation
-   from GT.M to the application logic, and permits GT.M to  relax  its  TP
-   Isolation  rules.  This  avoids  TP  restarts  in  certain  cases  thus
-   improving the performance of the application. For example, if a global
-   variable includes $JOB as a subscript, the application may  be  written
-   and scheduled in such a way that no more than one process uses  a  node
-   of that  global  at  any  given  time.  Specifying  such  a  global  as
-   "NOISOLATED" avoids transaction  restarts  that  occur  when  different
-   processes concurrently update and access nodes that share the same GDS
-   block.
-
-   The  rules  for  enforcement  by  GT.M  of  Isolation,  and  therefore
-   potentially Consistency, are relaxed for  application-specified  global
-   variables in order to allow the application to manage these properties.
-   GT.M is responsible for  Atomicity  and  Durability,  as  well  as  for
-   database integrity for all variables, and for Isolation and Consistency
-   for any global variables for which  the  application  does  not  accept
-   responsibility.
-
-   Note that if an  application  incorrectly  specifies  a  global  to  be
-   NOISOLATED, severe, and possibly intermittent and difficult to diagnose
-   damage to application-level integrity is likely to result.  A  thorough
-   understanding of the application is necessary before declaring a global
-   to be noisolated. GT.M preserves database integrity (accessibility) for
-   NOISOLATED, as well as ISOLATED global variables.
-
-   GT.M ignores attempts to turn on (or off) the feature for globals that
-   already have the feature turned on (or off). It is an error  to  modify
-   the isolation-status of a global variable within a  transaction  across
-   different  references  (either  reads  or  writes)  of  that  global
-   variable.The VIEW command by itself is not considered to be a reference
-   of the global variable. While  not  recommended  programming  practice,
-   this means that a process can change a global's isolation-status within
-   a transaction as long as it hasn't referenced it yet.
-
-   Any reads on a NOISOLATION global are validated at the time of the read
-   and not re-validated at TCOMMIT time. This means that if the value that
-   was read changed after the read but before the TCOMMIT, the transaction
-   would still be committed. Therefore it is important that any reads on a
-   NOISOLATED global (if any) should be of data that does not change with
-   time. Sanchez has not identified applications where this  could  be  an
-   issue.
-
-3 PATCODE
-   "PATCODE":"tablename"
-
-
-   Identifies the alternative table of unique patterns for  use  with  the
-   "?" operator to  be  loaded  from  the  pattern  definition  file.  For
-   additional information refer to the "Internationalization"  chapter  in
-   the GT.M Programmer's Guide.
-
-3 PATLOAD
-   "PATLOAD":"file-specification"
-
-
-   Identifies the file containing definitions of unique patterns  for  use
-   with the "?" operator. These pattern definitions can be used  in  place
-   of, or in addition to, the standard C, N, U, L, and P.
-
-3 UNDEF
-   "[NO]UNDEF"
-
-
-   Enables or disables handling of undefined  variables  as  errors.  With
-   UNDEF, GT.M  handles  all  references  to  undefined  local  or  global
-   variables as errors. With  NOUNDEF,  GT.M  handles  all  references  to
-   undefined local or global variables as if the variable had a  value  of
-   the null string. In other words, GT.M treats all variables appearing in
-   expressions as if they were the argument of an implicit  $GET().  UNDEF
-   is the default.
-
-3 TRACE
-   "TRACE":value<expr>
-
-
-   Traces GT.M program execution and generates profiling information about
-   the lines and functions executed;  with  low  impact  on  the  run-time
-   performance.
-
-   The feature turns on (value=1) or turns off (value=0)  tracing.  <expr>
-   must evaluate to  a  string  containing  the  name  of  a  GT.M  global
-   variable. The global may also have subscripts; however  the  subscripts
-   must be literals or the special variable $JOB.
-
-        The <expr> is optional when turning tracing off, if it  exists,  it
-        overrides the global variable set when tracing was turned on.
-
-   GT.M-tracing uses a technique called Basic Block Counting  where  calls
-   are made to special  profiling  functions  at  key  points  in  a  GT.M
-   program. A trace consists of the following run-time data as output for
-   each GT.M function, as well as for each GT.M statement:
-
-   o    The number of times it is executed.
-
-   o    The total CPU time spent across all invocations for  each  function
-        and each GT.M statement as three values: user  time,  system  time,
-        and total time.
-
-   Instead of modifying the generated code as  done  by  common  profiling
-   tools, such as gprof, GT.M tracing operates entirely  within  the  GT.M
-   run-time system; therefore, this feature does  not  require  a  special
-   compilation,  has  no  effect  on  code  size  and  minimizes  run-time
-   overhead.
-
-   When the feature is turned on, it  gathers  profiling  information  for
-   each line and GT.M function invocation. The reported time  for  a  GT.M
-   line is the time spent in generated code for that line,  and  does  not
-   include time spent in entreyrefs called from that line. When profiling
-   is turned off, the  accumulated  statistics  are  loaded  into  a  GT.M
-   global. GT.M profiling accumulates and provides the data; the user may
-   choose tools and techniques to analyze the data.
-
-   The trace information is  stored  in  the  variable  in  the  following
-   format:
-
-   o    If <expr> is a global variable  without  subscripts  name  such  as
-        "^foo",  the  trace  information  is  stored  in  the  nodes
-        ^foo(<routine>,<label>) and ^foo(<routine>,<label>,<offset>), each
-        of  which  has  a  value  in  the  form
-        "<count>:<usertime>,:<systemtime>,:<total_time>" on UNIX.
-
-   o    If <expr> has a  value  such  as  "^foo("MYTRACE",$J)",  the  trace
-        information  is  stored  in  the  nodes
-        ^foo("MYTRACE",<pid>,<routine>,<label>)  and
-        ^foo("MYTRACE",<pid>,<routine>,<label>,<offset>), each of which has
-        a value in the form "<count>,<usertime>,<systemtime>,<total_time>"
-        on UNIX as described above.
-
-   o    For FOR loops, information for each level of the loop is stored in
-        the nodes as described above, with the extra subscipts "FOR_LOOP".
-        <for_level> is the value of the number of iterations at that level
-        of the FOR loop.
-
-   Thus, if the GT.M program lv1.m is:
-
-
-   lv1 f i=1:1:10 d
-
-   .s l(i)=i
-
-   .d bar
-
-   for i=1:1:5 for j=1:1:4 s lij(i,j)=i+j
-
-   q
-
-   bar s l(-i)=-i
-
-   q
-
-
-   And the program lv2.m is:
-
-   lv2 VIEW "TRACE":1:"^lvtr"
-
-   d ^lv1
-
-   VIEW "TRACE":0:"^lvtr"
-
-   zwr ^lvtr
-
-   q
-
-   On executing lv2, the output looks like this (times in the example were
-   chose for clarity of illustration and are not typical):
-
-
-   ^lvtr("lv1","bar")="10:8:1:9"
-
-   ^lvtr("lv1","bar",0)="10:5:1:6"
-
-   ^lvtr("lv1","bar",1)="10:3:0:3"
-
-   ^lvtr("lv1","lv1")="1:37:2:39"
-
-   ^lvtr("lv1","lv1",0)="1:8:0:8"
-
-   ^lvtr("lv1","lv1",0,"FOR_LOOP",1)=10
-
-   ^lvtr("lv1","lv1",1)="10:3:1:4"
-
-   ^lvtr("lv1","lv1",2)="10:19:2:21"
-
-   ^lvtr("lv1","lv1",3)="1:15:0:15"
-
-   ^lvtr("lv1","lv1",3,"FOR_LOOP",1)=5
-
-   ^lvtr("lv1","lv1",3,"FOR_LOOP",2)=20
-
-   ^lvtr("lv1","lv1",4)="1:0:0:0"
-
-   ^lvtr("lv2","lv2",1)="1:47:3:50"
-
-   In this case, ^lvtr("lv1","bar",0)="10:5:1:6" means that the statement
-   bar s l(-i)=-i was executed 10 times, with a total of 5 microseconds of
-   user  time  and  1  microsecond  of  system  time.
-   ^lvtr("lv1","lv1")="1:37:2:39" means that 37 microseconds of user time
-   was spent within that GT.M frame (lv1^lv1), and does not  include  time
-   spent  in  routines  called  from  it  (such  as  bar^lv1),  whereas
-   ^lvtr("lv1","lv1",3)= "1:15:0:15" includes the time spent at bar^lv1.
-
-   Note  that  there  is  no  data  in  ^lvtr("lv2","lv2",0)  or  for
-   ^lvtr("lv2","lv2",2) because the execution of the lines containing the
-   VIEW commands that turn profiling on and off are not profiled.
-
-   Because of the underlying timers provided  by  the  operating  systems,
-   times of less than a microsecond are measured as zero. Therefore, even
-   if a statement executes one million times, it may report zero  time  if
-   it took less than a microsecond each time.
-
-   GT.M profiling cannot handle more than 1024 levels. If  the  GT.M  code
-   executed has  more  than  1024  levels,  frame  information  cannot  be
-   recorded, and frame information upto the first point where  this  limit
-   is reached is reported with a note (":INCOMPLETE DATA: MAXTRACELEVEL" )
-   appended to the data.
-
-2 Ex_of_View
-   Examples of VIEW
-
-   Example 1:
-
-
-   GTM>KILL A
-
-   GTM>VIEW "NOUNDEF"
-
-   GTM>WRITE A,?10,$L(A)
-
-   0
-
-   GTM>
-
-   This demonstrates how a VIEW that specifies NOUNDEF prevents UNDEFined
-   errors.
-
-   Example 2:
-
-
-   GTM>ZL "NOSENSE"
-
-   %GTM-E-LABELMISSING Label referenced but
-
-   not defined:lab
-
-   %GTM-I-SRCNAM in source module /usr/work/NOSENSE.m
-
-   GTM>
-
-   GTM>ZPRINT ^NOSENSE
-
-
-   NOSENSE;
-
-   DO lab
-
-   QUIT
-
-   LAB WRITE !,"THIS IS NOSENSE"
-
-   QUIT
-
-
-   GTM>VIEW "LABELS":"UPPER"
-
-   GTM>ZLINK "NOSENSE.m"
-
-   GTM>DO ^NOSENSE
-
-   THIS IS NOSENSE
-
-   GTM>
-
-   This demonstrates use of VIEW "LABELS"  to  make  label  handling  case
-   insensitive. Notice that the routine was ZLINKed with an  extension  of
-   .m to force a recompile  and  ensure  that  the  object  code  and  the
-   run-time handling of labels is the same.
-
-1 WRITE
-   Write
-
-   The WRITE  command  transfers  a  character  stream  specified  by  its
-   arguments to the current device.
-
-   The format of the WRITE command is:
-
-
-   W[RITE][:tvexpr] expr|*intexpr|fcc[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    An expression argument supplies the text of a WRITE.
-
-   o    When a WRITE argument consists of a leading asterisk  (*)  followed
-        by  an  integer  expression,  WRITE  outputs  one  ASCII  character
-        associated with the ASCII code specified by the integer evaluation
-        of the expression.
-
-   o    WRITE arguments may  also  be  format  control  characters;  format
-        control characters modify the position  of  a  virtual  cursor:  an
-        exclamation point (!)  produces  a  new  line,  a  number-sign  (#)
-        produces a  new  page  and  a  question-mark  (?)  followed  by  an
-        expression moves the virtual cursor to the column specified by the
-        integer evaluation of the  expression  provided  that  the  virtual
-        cursor is to the "left" of the specified  column;  if  the  virtual
-        cursor is not to the left of the specified column, then the text is
-        printed at the current cursor position.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more WRITE arguments form a legal argument for a WRITE.
-
-   For more information  on  WRITE,  devices,  input,  output  and  format
-   control characters, refer to the "Input/Output Processing"  chapter  in
-   GT.M Programmer's Guide.
-
-1 XECUTE
-   Xecute
-
-   The XECUTE command makes an entry in  the  GT.M  invocation  stack  and
-   executes the argument as GT.M code.
-
-   The format of the XECUTE command is:
-
-
-   X[ECUTE]:tvexpr expr[:tvexpr][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required expression specifies a fragment of GT.M source code.
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        argument expression  specifies  the  argument  postconditional  and
-        controls whether GT.M performs an XECUTE with that argument.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more XECUTE  arguments  form  a  legal  argument  for  an
-        XECUTE.
-
-   An explicit or implicit QUIT within the scope of the  XECUTE,  but  not
-   within the scope of any other DO, FOR,  XECUTE  or  extrinsic,  returns
-   execution to the instruction following the calling point. This  may  be
-   the next XECUTE argument or another command. At the  end  of  the  code
-   specified by the XECUTE argument expression, GT.M performs an implicit
-   QUIT.
-
-   Because XECUTE causes run-time compilation  in  GT.M,  and  because  it
-   tends to obscure code, use XECUTE only when other approaches clearly do
-   not meet your particular requirement.
-
-2 Ex_of_Xecute
-   Examples of XECUTE
-
-   Example:
-
-
-   GTM>SET A="HELLO" XECUTE "WRITE A"
-
-   HELLO
-
-   GTM>
-
-   This demonstrates a simple use of XECUTE.
-
-   Example:
-
-
-   SET x="" F S x=$O(^%x(x)) Q:x="" X x
-
-   This $ORDER() loop XECUTEs code out of the first level  of  the  global
-   array ^%x. Note that, in most cases, having the code in a  GT.M  source
-   file, for example TMPX.m, and using a DO ^TMPX improves efficiency.
-
-1 ZALLOCATE
-   ZAllocate
-
-   The ZALLOCATE command reserves the  specified  name  without  releasing
-   previously reserved names. Other  GT.M  processes  cannot  reserve  the
-   ZALLOCATEd name with a ZALLOCATE or LOCK command.
-
-   The ZALLOCATE command  provides  compatibility  with  some  other  GT.M
-   implementations. The M Development Committee chose to add the +  and  -
-   delimiters to the LOCK command (incremental locking) rather than adopt
-   the ZALLOCATE  and  ZDEALLOCATE  approach.  Therefore,  when  a  design
-   requires an incremental lock mechanism, LOCK +/- has the advantage over
-   ZALLOCATE / ZDEALLOCATE of being part of the M standard. LOCK +/- also
-   has the advantage of working symmetrically when  routines  using  LOCKs
-   are nested. That is, a ZALLOCATE command issued  by  a  process  for  a
-   named resource already ZALLOCATEd by that process results in no change
-   of state. This means that routines that  do  ZALLOCATE  followed  by  a
-   ZDEALLOCATE on a named resource that is already ZALLOCATEd by the same
-   process (at routine entry time), will end up ZDEALLOCATEing  the  named
-   resource (which might not be desired). On the  other  hand,  a  LOCK  +
-   command issued by a process for a named resource already LOCKed by that
-   process causes the LEVEL of the LOCK to be incremented (as  seen  in  a
-   ZSHOW "L" output). Every LOCK - command on that named  resource  causes
-   the LEVEL to be decremented.  When  the  LEVEL  becomes  0,  the  named
-   resource is no longer LOCKed.
-
-   For more information  on  troubleshooting  LOCKs  with  the  GT.M  Lock
-   Utility  (LKE),  refer  to  the  appropriate  chapter  of  the  GT.M
-   Administration and Operations Guide.
-
-   The format of the ZALLOCATE command is:
-
-
-   ZA[LLOCATE][:tvexpr] [(]nref[,...][)][:intexpr][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The nref argument specifies a name in the format  of  a  GT.M  name
-        with or without subscripts, and with or without a  preceding  caret
-        (^).
-
-   o    Outside of transactions, only one process  in  an  environment  can
-        ZALLOCATE (or LOCK) a particular resource name at any given time.
-
-   o    Because the data storage in GT.M uses  hierarchical  sparse  arrays
-        and ZALLOCATE may serve to protect  that  data  from  inappropriate
-        "simultaneous"  access  by  multiple  processes,  ZALLOCATE  treats
-        resource names in a hierarchical fashion; a ZALLOCATE protects not
-        only the named resource, but also its ancestors and descendants.
-
-   o    When one or more nrefs are enclosed in  parentheses  (),  ZALLOCATE
-        reserves all the  enclosed  names  "simultaneously,"  that  is,  it
-        reserves none of them until all become available.
-
-   o    The optional numeric expression specifies a time in  seconds  after
-        which the  command  should  timeout  if  unsuccessful;  choosing  0
-        results in a single attempt.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZALLOCATE arguments form  a  legal  argument  for  a
-        ZALLOCATE.
-
-   For an explanation of the LOCK command see the "LOCK" section in the M
-   LOCK Utility chapter of GT.M Administration and Operations Guide.
-
-   If a ZALLOCATE command specifies a timeout, and GT.M acquires ownership
-   of the named resource before the timeout elapses, ZALLOCATE sets $TEST
-   to TRUE (1). If GT.M cannot acquire ownership  of  the  named  resource
-   within the specified timeout, ZALLOCATE sets $TEST to FALSE (0).  If  a
-   ZALLOCATE command does not specify a  timeout,  the  execution  of  the
-   command does not affect $TEST.
-
-   When given a list of nrefs, ZALLOCATE tries to reserve each  nref  from
-   left to right in the order specified taking into  account  the  timeout
-   specified for each. If the timeout elapses before  reserving  an  nref,
-   GT.M terminates the ZALLOCATE command. Any nrefs  already  acquired  as
-   part of the current ZALLOCATE command stay acquired.
-
-2 Ex_of_ZAllocate
-   Examples of ZALLOCATE
-
-   Examples:
-
-
-   ZALLOCATE A
-
-   ZALLOCATE ^A
-
-   ZALLOCATE ^A(1)
-
-   ZALLOCATE (^B("smith"),^C("jones"))
-
-   ZALLOCATE @A
-
-   The first command ZALLOCATEs A; the second, ^A; the  third,  ^A(1)  and
-   the fourth, both ^B("smith") and ^C("jones") simultaneously.  The  last
-   command ZALLOCATEs the resources named by the value of the variable A.
-
-   Example:
-
-
-   ZALLOCATE A,^B, at C
-
-   ZALLOCATE (A,B,C)
-
-   If ZALLOCATE arguments are enclosed in parentheses, the  command  waits
-   until all names in the argument list become available before reserving
-   any of the names. For example, in the  statement  ZA  (A,B,C),  if  the
-   resource named C is not available,  ZALLOCATE  waits  until  C  becomes
-   available before reserving A and B. Using the format illustrated in the
-   first line above, can cause deadlocks because the  resource  names  are
-   reserved as they come available.
-
-   When a process attempts to ZALLOCATE a  name  currently  ZALLOCATEd  or
-   LOCKed (with the LOCK command) by  another  process,  the  ZALLOCATEing
-   process hangs until the other process releases the name. In  the  event
-   that names remain unavailable for significant periods of time, timeouts
-   allow the process issuing a ZALLOCATE to regain program control.
-
-   Example:
-
-
-   ZALLOCATE ^D:5
-
-   This example specifies a timeout of five seconds. If GT.M  reserves  ^D
-   before the five seconds elapses, ZALLOCATE sets $TEST to TRUE. If GT.M
-   cannot reserve ^D within the five second timeout, ZALLOCATE sets $TEST
-   to FALSE.
-
-   When you ZALLOCATE a name, no names previously reserved with ZALLOCATE
-   or the LOCK command are released (similarly, LOCKing a  name  does  not
-   release  names  that  have  been  ZALLOCATEd).  For  example,  after
-   ZALLOCATEing A and LOCKing  B,  LOCKing  B  does  not  release  A,  and
-   ZALLOCATEing C does not release A or B.
-
-   To  release  a  ZALLOCATEd  name,  use  the  ZDEALLOCATE  command.  The
-   ZDEALLOCATE command can only release previously ZALLOCATEd (not LOCKed)
-   names.
-
-   Resource name arguments for LOCKs and ZALLOCATEs intersect. That is, if
-   one process holds a LOCK or ZALLOCATE, another process can neither LOCK
-   nor ZALLOCATE any name falling in the hierarchy of  the  resource  name
-   held by the first process. When a process holds a  LOCK  or  ZALLOCATE,
-   that same process may also LOCK or ZALLOCATE resource names falling in
-   the hierarchy of the  currently  held  resource  name.  When  a  single
-   process holds both LOCKs and ZALLOCATEs, a LOCK does  not  release  the
-   ZALLOCATEd resource(s) and a ZDEALLOCATE does not  release  the  LOCKed
-   resource(s).
-
-   Example:
-
-
-   L ^AR(PNT)
-
-   .
-   .
-   .
-   ZALLOCATE ^AR(PNT,SUB)
-
-   .
-   .
-   .
-   L ^TOT(TDT)
-
-   .
-   .
-   .
-   ZDEALLOCATE ^AR(PNT,SUB)
-
-
-   This LOCKs ^AR(PNT), then, after performing some unspecified commands,
-   it ZALLOCATEs ^AR(PNT,SUB). Because ZALLOCATE does not imply any change
-   to LOCKs or existing ZALLOCATEd resource names, the  LOCK  of  ^AR(PNT)
-   remains in effect. Assuming the routine does not  modify  the  variable
-   PNT, ^AR(PNT,SUB) is already protected by the LOCK.  Next,  because  an
-   unsigned LOCK releases all  resource  names  currently  LOCKed  by  the
-   process, the routine releases ^AR(PNT) with the LOCK of ^TOT(TDT). This
-   leaves the  ZALLOCATE  of  ^AR(PNT,SUB).  The  name  ^AR  and  all  its
-   subscripts except for  those  that  begin  with  ^AR(PNT,SUB)  are  now
-   available for LOCKing by other processes. Finally the routine releases
-   ^AR(PNT,SUB) with a  ZDEALLOCATE  command.  The  ZDEALLOCATE  does  not
-   affect the LOCK on ^TOT(TDT). Note that this example was constructed to
-   illustrate the interaction between LOCK, ZALLOCATE and ZDEALLOCATE, and
-   not to illustrate sound programming practice.
-
-1 ZBREAK
-   ZBreak
-
-   The ZBREAK command sets or clears routine breakpoints during debugging.
-
-   The format of the ZBREAK command is:
-
-
-   ZB[REAK][:tvexpr] [-]entryref[:[expr][:intexpr]]
-
-   [,...]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required entryref specifies a  location  within  a  routine  at
-        which to set or remove a breakpoint.
-
-   o    The optional minus  sign  (-)  specifies  that  ZBREAK  remove  the
-        breakpoint; -* means remove all breakpoints.
-
-   o    The optional expression specifies a fragment of GT.M code to XECUTE
-        when GT.M  execution  encounters  the  breakpoint;  if  the  ZBREAK
-        argument does not specify an action, the default action is "BREAK".
-
-   o    The  optional  integer  expression  immediately  following  the
-        expression specifies  a  count  of  process  transits  through  the
-        breakpoint before the breakpoint action  takes  effect;  once  GT.M
-        exhausts the count and the action takes effect, the  action  occurs
-        every time the process encounters the  breakpoint.  If  the  action
-        expression is omitted, the  optional  integer  expression  must  be
-        separated from the entryref by two adjacent colons (::).
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZBREAK arguments form a legal argument for a ZBREAK.
-
-   When GT.M encounters the  entryref,  GT.M  suspends  execution  of  the
-   routine code and XECUTEs the breakpoint action before executing any of
-   the commands on the line.
-
-   When the optional  integer  expression  is  used,  GT.M  activates  the
-   breakpoint on the intexpr-th time the process encounters the breakpoint
-   during routine execution. Once  GT.M  activates  the  breakpoint,  that
-   breakpoint remains active for the process until explicitly replaced or
-   removed, or until the process terminates.
-
-2 Ex_of_ZBreak
-   Examples of ZBREAK
-
-   Example:
-
-
-   GTM>ZPRINT ^ZBTEST
-
-   ZBTEST;
-
-   DO SUB
-
-   QUIT
-
-   SUB WRITE !,"This is ZBTEST"
-
-   QUIT
-
-   GTM>ZBREAK SUB^ZBTEST
-
-   GTM>DO ^ZBTEST
-
-   %GTM-I-BREAKZBA, Break instruction encountered
-
-   during ZBREAK action
-
-   At M source location SUB^ZBTEST
-
-   GTM>
-
-   ZSHOW "B"
-
-   SUB^ZBTEST
-
-   This inserts a ZBREAK with a default action at SUB^ZBTEST.  After  GT.M
-   encounters the BREAK, the ZSHOW "B" displays this as the only ZBREAK in
-   the image.
-
-   Example:
-
-
-   GTM>ZBREAK -*
-
-   GTM>ZGOTO
-
-   GTM>ZBREAK SUB^ZBTEST:"W !,""Trace"""
-
-   GTM>DO ^ZBTEST
-
-   Trace
-
-   This is ZBTEST
-
-   GTM>
-
-   This removes all existing ZBREAKs with a ZBREAK -*. Note that it is not
-   necessary to remove ZBREAKs before modifying them. It also  clears  the
-   process invocation stack with an argumentless ZGOTO.  Then  it  uses  a
-   ZBREAK to insert a trace-point. Every time GT.M executes  the  line  to
-   where ZBREAK has established a trace-point, it performs  the  specified
-   action without entering Direct Mode.
-
-   Example:
-
-
-   ZBREAK PRINT^TIME::5
-
-   This BREAKs execution at line PRINT in routine just  before  the  fifth
-   time the line is executed.
-
-   Example:
-
-
-   ZBREAK PRINT^TIME:"WRITE AVE BREAK":3
-
-   This inserts a ZBREAK action of WRITE AVE and BREAK  before  the  third
-   execution of PRINT^TIME.
-
-1 ZCOMPILE
-   ZCOMpile
-
-   The ZCOMPILE command invokes the GT.M compiler  from  within  the  GT.M
-   run-time environment.
-
-   Within GT.M itself, ZCOMPILE provides the functionality  of  the  mumps
-   command, except for mumps -direct.
-
-   The format of the ZCOMPILE command is:
-
-
-   ZCOM[PILE][:tvexpr] expr[,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The expression argument specifies one or more filenames, which must
-        include the .m extension. Wildcards are acceptable in the filename
-        specification.  The  filename  specification  can  be  optionally
-        prefixed by qualifiers valid for a mumps command.
-
-   The $ZCSTATUS intrinsic special variable holds the value of the status
-   code for the compilation performed by a ZCOMPILE command.
-
-2 Ex_of_ZCOMpile
-   Examples of ZCOMPILE
-
-   ZCOMPILE "EXAMPLE.m"
-
-   This compiles EXAMPLE.m in the current working directory.
-
-   Example:
-
-
-   ZCOMPILE "-list A*.m"
-
-   This compiles all files starting with a [capital] A and an extension of
-   .m in the current working directory.
-
-1 ZCONTINUE
-   ZContinue
-
-   The ZCONTINUE command continues routine execution after a BREAK command
-   or a <CTRL-C>.
-
-   The format of the ZCONTINUE command is:
-
-
-   ZC[ONTINUE][:tvexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    Because ZCONTINUE changes the flow of execution away  from  control
-        of the principal device back to the current routine, it is usually
-        the final command on a line; however, if it  is  not,  because  the
-        ZCONTINUE has no argument, at least two (2) spaces must follow the
-        command to separate it from the next command on the line.
-
-   o    If the process is not in Direct Mode, ZCONTINUE has no effect.
-
-1 ZDEALLOCATE
-   ZDeallocate
-
-   The ZDEALLOCATE command releases a specified  resource  name  or  names
-   previously reserved by the ZALLOCATE command. The  ZDEALLOCATE  command
-   releases only the  specified  name(s)  without  releasing  other  names
-   previously reserved with the ZALLOCATE or LOCK command.
-
-   The ZDEALLOCATE command provides compatibility  with  some  other  GT.M
-   implementations. The M Development Committee choose to add the + and -
-   delimiters to the LOCK command rather  than  adopt  the  ZALLOCATE  and
-   ZDEALLOCATE approach. Therefore, when a design requires an incremental
-   lock mechanism, LOCK +/- has the advantage  of  being  part  of  the  M
-   standard. LOCK +/- also has the advantage of working symmetrically when
-   routines using LOCKs are nested.
-
-   The format of the ZDEALLOCATE command is:
-
-
-   ZD[EALLOCATE][:tvexpr] [nref[,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command
-
-   o    The nref argument specifies a name in the format  of  a  GT.M  name
-        with or without subscripts and with or without a leading caret (^).
-
-   o    A  ZDEALLOCATE  with  no  argument  releases  all  names  currently
-        reserved with ZALLOCATE by the process; in this case, at least two
-        (2) spaces must follow the ZDEALLOCATE to separate it from the next
-        command on the line.
-
-   o    ZDEALLOCATEing a named resource that is not currently owned by the
-        process has no effect.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZDEALLOCATE arguments form a legal  argument  for  a
-        ZDEALLOCATE.
-
-1 ZEDIT
-   ZEDit
-
-   The  ZEDIT  command  invokes  the  editor  specified  by  the  EDITOR
-   environment variable for GT.M and opens the specified file for editing.
-   If the EDITOR environment variable is undefined, ZEDIT tries to invoke
-   the UNIX vi editor.
-
-   By default, ZEDIT puts a new file into the first  source  directory  in
-   $ZROUTINES. Previously, it used the current working directory. The old
-   behavior can be obtained by specifying the  current  working  directory
-   explicitly in the argument to the ZEDIT command:
-
-   o    ZEDIT "./file"
-
-   The format of the ZEDIT command is:
-
-
-   ZED[IT][:tvexpr] [expr[,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional expression(s) specifies the name of a  file  to  edit;
-        note the argument is an expression rather than a routinename; ZEDIT
-        rejects arguments with a file extension of .o as illegal.  A  valid
-        GT.M file name with no extension will be given an extension of .m;
-        therefore it is not possible, through ZEDIT, to edit a file with a
-        valid GT.M filename and no extension.
-
-   o    If ZEDIT has an argument, it not only invokes the editor, but also
-        sets $ZSOURCE=expr.
-
-   o    If ZEDIT has no argument or expr="", the command acts  as  a  ZEDIT
-        $ZSOURCE; at least two (2) spaces must follow a ZEDIT command with
-        no argument to separate it from the next command on the line.
-
-   o    GT.M stores source code in files  with  standard  operating  system
-        format; generally the file name is the same as the GT.M routinename
-        with a default type of .m.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZEDIT arguments form a legal argument for a ZEDIT
-
-   If the expression  includes  a  directory,  ZEDIT  searches  only  that
-   directory. If $ZROUTINES is not null, a ZEDIT  command  that  does  not
-   specify a directory uses $ZROUTINES to locate files. If  $ZROUTINES  is
-   null, ZEDIT edits a new file in the first source directory specified in
-   $ZROUTINES.
-
-   When the argument to a ZEDIT includes a file  or  path  name,  $ZSOURCE
-   maintains that as a default for ZEDIT and ZLINK.
-
-2 Ex_of_ZEDit
-   Examples of ZEDIT
-
-   Example:
-
-
-   GTM>ZEDIT "BAL"
-
-   This invokes the editor for a file with a name of BAL and an extension
-   of .m. Notice that BAL is a string literal.
-
-   Example:
-
-
-   GTM>SET prog="BAL"
-
-   GTM>ZEDIT prog
-
-   This is similar to the first example except that  it  uses  a  variable
-   argument rather than a string literal.
-
-   Example:
-
-
-   GTM>zedit ".login"
-
-   This invokes the editor for a file with the name .login. Notice that in
-   this case the file is not a GT.M  file,  since  .login  starts  with  a
-   period, and therefore, cannot be a GT.M file.
-
-1 ZGOTO
-   ZGoto
-
-   The ZGOTO command transfers control  to  various  levels  in  the  GT.M
-   invocation stack. It also can transfer control from  one  part  of  the
-   routine to another or from one routine to another using  the  specified
-   entryref.
-
-   The format of the ZGOTO command is:
-
-
-   ZG[OTO][:tvexpr] [[intexpr][:entryref
-
-   [:tvexpr]],...]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional integer expression specifies the stack  frame  nesting
-        level reached by performing the ZGOTO.
-
-   o    A ZGOTO with no argument returns control to the next command at the
-        bottom of the stack (level 1); in  this  case,  at  least  two  (2)
-        spaces must follow the command to separate it from the next command
-        on the line.
-
-   o    The optional entryref specifies a location to which ZGOTO transfers
-        control.
-
-   o    If ZGOTO specifies no entryref, it  returns  control  to  the  next
-        command at the level specified by the integer expression.
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        entryref  specifies  the  argument  postconditional  and  controls
-        whether GT.M uses the argument.
-
-   o    If the ZGOTO includes the level and  the  argument  postconditional
-        but  not  the  entryref,  two  colons  (::)  separate  the  integer
-        expression from the truth-valued expression.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZGOTO arguments form a legal argument for a ZGOTO.
-
-   A ZGOTO command with an entryref performs a  similar  function  to  the
-   GOTO command, with the additional capability of reducing the GT.M stack
-   level. In a  single  operation,  ZGOTO  executes  ($ZLEVEL  -  intexpr)
-   implicit QUITs and a GOTO operation, transferring control to the named
-   entryref.
-
-   The ZGOTO command leaves the invocation stack at the level specified by
-   the integer expression. GT.M implicitly terminates any intervening FOR
-   loops and unstacks variables stacked with NEW commands as appropriate.
-
-   Using ZGOTO results in an exit from the current GT.M invocation. ZGOTO
-   resembles HALT (and not QUIT) in that it causes an exit  regardless  of
-   the number of active levels in the current invocation. ZGOTO resembles
-   QUIT (and not HALT) in that it destroys the GT.M context and terminates
-   the process only if the current GT.M invocation is at the base  of  the
-   process. Understanding the difference between ZGOTO  and  HALT  has  an
-   impact only in an environment where GT.M is  invoked  recursively  from
-   other languages.
-
-   ZGOTO  $ZLEVEL:LABEL^ROUTINE  produces  identical  results  to  GOTO
-   LABEL^ROUTINE. ZGOTO  $ZLEVEL-1  responds  like  a  QUIT  (followed  by
-   ZCONTINUE, if in Direct Mode). If the integer expression evaluates to a
-   value greater than the current value of $ZLEVEL or less than zero (0),
-   GT.M issues a run-time error.
-
-   If ZGOTO has no entryref, it performs some number of implicit QUITs and
-   transfers control to the next command at the specified level. If ZGOTO
-   has no argument, it behaves like ZGOTO 1, which  resumes  operation  of
-   the lowest level GT.M routine as displayed by ZSHOW "S". In  the  image
-   invoked by $gtm_dist mumps -direct, a ZGOTO without  arguments  returns
-   the process to Direct Mode.
-
-   ZGOTO provides a useful debugging tool in Direct Mode. However, because
-   ZGOTO is not conducive to structured coding, it is best to restrict its
-   use in production programs to error handling.For  more  information  on
-   error handling,  refer  to  the  "Error  Processing"  chapter  in  GT.M
-   Programmer's Guide.
-
-2 Ex_of_ZGOTO
-   Examples of ZGOTO
-
-   Example:
-
-
-   GTM>ZGOTO
-
-   GTM>ZSHOW
-
-
-   +1^GTM$DMOD (Direct mode)
-
-   GTM>
-
-   This uses ZGOTO to clear all levels of the GT.M invocation stack. ZSHOW
-   with no arguments displays the stack.
-
-   Example:
-
-
-   SET $ZTRAP="ZGOTO "_$ZLEVEL_":^ERROR"
-
-   This SETs $ZTRAP to contain a ZGOTO, so if  an  error  causes  GT.M  to
-   XECUTE $ZTRAP, the routine ERROR executes at the same level as the SET
-   command shown in the example.
-
-1 ZHELP
-   ZHelp
-
-   The ZHELP command provides access to help information from the GTM help
-   library or from any help library specified in the command argument.
-
-   The format of the ZHELP command is:
-
-
-   ZH[ELP][:tvexpr] [expr1[:expr2],...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional first expression specifies the help topic.
-
-   o    If ZHELP has no argument or  expr1="",  ZHELP  invokes  base  level
-        help; at least two (2) spaces must follow a ZHELP command  with  no
-        argument to separate it from the next command on the line.
-
-   o    The optional second expression  specifies  the  name  of  a  Global
-        Directory containing ^HELP.
-
-   o    If ZHELP does not specify the second expression, the  name  of  the
-        Global Directory defaults to $gtm_dist/gtmhelp.gld.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZHELP arguments form a legal argument for a ZHELP
-
-2 Ex_of_ZHelp
-   Examples of ZHELP
-
-   Example:
-
-
-   GTM>zhelp "func $data"
-
-   This lists the  help  for  function  $DATA,  which  is  a  subtopic  of
-   functions topic.
-
-   Example:
-
-
-   GTM>zhelp
-
-   This uses ZHELP to list all the keywords in the help library.
-
-   Example:
-
-
-   GTM>zhelp "ZSHOW"
-
-   This lists the help for command ZSHOW.
-
-1 ZLINK
-   ZLink
-
-   If the current process does not contain a copy of a routine, the ZLINK
-   command adds an executable GT.M routine to the current process. If the
-   current process contains a copy of a routine and  the  routine  is  not
-   active, the ZLINK command replaces the current routine process  with  a
-   "new" version. If necessary, the ZLINK  command  compiles  the  routine
-   prior to integrating it with the process.
-
-   The format of the ZLINK command is:
-
-
-   ZL[INK][:tvexpr] [expr1[:expr2][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional first expression specifies the pathname of  a  routine
-        to ZLINK; if ZLINK has an argument, it not only adds the routine to
-        the image, but also sets $ZSOURCE=expr.
-
-   o    If ZLINK has no argument, or expr="", it uses value of $ZSOURCE as
-        the routine specification filename; at least two  (2)  spaces  must
-        follow a ZLINK command with no argument to  separate  it  from  the
-        next command on the line.
-
-   o    The optional second expression specifies  a  string  holding  MUMPS
-        command qualifiers delimited by a dash (-); the qualifiers control
-        compile options when the current ZLINK requires a compile; if ZLINK
-        omits  the  second  expression,  the  command  uses  the  $ZCOMPILE
-        intrinsic special variable to determine the compile qualifiers.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZLINK arguments form a legal argument for a ZLINK.
-
-   ZLINK cannot change a routine that  GT.M  is  currently  executing.  An
-   attempt to ZLINK an active routine results in a run-time error because
-   changing a routine in progress could have unpredictable results. Before
-   ZLINKing the routine, use the ZSHOW command to  display  the  currently
-   active routines, then remove it from the GT.M stack using ZGOTO, or the
-   appropriate number of QUITs.
-
-   When the ZLINK command specifies a file, GT.M  sets  $ZSOURCE  to  that
-   filename. By default, ZLINK and ZEDIT use $ZSOURCE for a filename when
-   they have a missing or null argument. A  subsequent  ZLINK  without  an
-   argument is equivalent to ZLINK $ZSOURCE.
-
-        In order to ensure compatibility with GT.M  versions  that  do  not
-        permit the percent sign (%) in a file name, use an  underscore  (_)
-        in place of the  percent  in  the  ZLINK  file  name  for  routines
-        beginning with a percent sign.
-
-   If the expression includes an explicit directory, ZLINK  searches  only
-   that directory. Otherwise, if $ZROUTINES is not null, a  ZLINK  command
-   uses $ZROUTINES to locate files. If $ZROUTINES is null, ZLINK uses the
-   current directory.
-
-   If the filename contains an explicit file  extension,  ZLINK  processes
-   the file according to the extension, object  (.o)  or  source  (usually
-   .m). If the file name does not specify a file extension, ZLINK attempts
-   to find and match both the object and source for a routine.
-
-2 ZLINK_Compilation
-   ZLINK Compilation
-
-   If ZLINK compiles  a  routine  and  the  -OBJECT=  qualifier  does  not
-   redirect the output,  it  places  the  resulting  object  file  in  the
-   directory indicated by the search criteria. ZLINK incorporates the new
-   object file into the image, regardless of its directory placement.
-
-   If the command does not specify compile  qualifiers  (with  expr2)  and
-   $ZCOMPILE is null, GT.M uses the default M command qualifiers, -ignore,
-   -labels=lower, -nolist, and -object. For more information on $ZCOMPILE,
-   refer to the appropriate section in the "Intrinsic  Special  Variables"
-   chapter in this manual.
-
-   For information on producing object files, but not adding them  to  the
-   current image, refer to ZCOMPILE.
-
-2 Ex_of_ZLink
-   Examples of ZLINK
-
-   Example:
-
-
-   GTM>ZLINK "test"
-
-   If ZLINK finds test.m or test.o,  it  adds  the  routine  test  to  the
-   current image. If ZLINK does not find test.o, or finds that  test.o  is
-   older than test.m, GT.M compiles test.m to produce a  new  test.o,  and
-   adds the contents of the new object file to the image.
-
-   Example:
-
-
-   GTM>
-
-   zlink "test.m":"-noobject -list"
-
-   This compiles the routine "test" and produces a listing but  no  object
-   file. Because the example produces no object file, it does  not  change
-   the current image.
-
-2 Auto_ZLink
-   Auto-ZLINK
-
-   If a GT.M routine refers to a routine that is not linked  to  the  GT.M
-   image, GT.M automatically attempts to ZLINK that routine. An auto-ZLINK
-   is functionally equivalent to an explicit ZLINK of a routine without a
-   specified directory or file extension.
-
-   The following GT.M commands and functions can initiate auto-ZLINKing:
-
-   DO
-
-   GOTO
-
-   ZBREAK
-
-   ZGOTO
-
-   ZPRINT
-
-   $TEXT()
-
-   GT.M auto-ZLINKs the routine if the following conditions are met:
-
-   o    ZLINK can locate and process the routine file, as indicated in the
-        previous ZLINK Operation Summary table
-
-   o    The name of the routine is the same as the name of the source file;
-        the only exception is  in  cases  where  GT.M  converts  a  leading
-        percent sign (%) in a file name to an underscore (_)
-
-2 ZL_AutoZL_and_Rtn_Nam
-   ZLINK, Auto-ZLINK and Routine Names
-
-   In GT.M, the name of the source file determines the name  of  the  GT.M
-   routine. The file name of the object file is not required to match the
-   name of the routine. Linking the object file makes the internal routine
-   name (derived from the source file) known to GT.M.  This  can  lead  to
-   potential confusion, however, since both ZLINK and auto-ZLINK  use  the
-   name of the object file to find the routine. When the object file name
-   differs from the name of the routine, auto-ZLINK generates  a  run-time
-   error.
-
-1 ZKILL
-   ZKill
-
-   The ZKILL command KILLs the data value  for  a  variable  name  without
-   affecting the nodes descended from that node.
-
-   The format of the ZKILL command is:
-
-
-   ZK[ILL][:tvexpr] glvn
-
-   The  functionality  of  ZKILL  is  identical  to  ZWITHDRAW.  For  a
-   comprehensive description of the format and usage, refer to  the  entry
-   for ZWITHDRAW.
-
-1 ZMESSAGE
-   ZMessage
-
-   The ZMESSAGE command signals a specified condition.
-
-   The format of the ZMESSAGE command is:
-
-
-   ZM[ESSAGE][:tvexpr] intexpr
-
-   [:expr...][,...]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required integer expression specifies the  exception  condition
-        to signal.
-
-   o    The additional expressions specify one or more arguments passed to
-        the GT.M message formatter  to  substitute  as  parameters  to  the
-        message text. For example,  if  the  message  associated  with  the
-        condition contains  a  corresponding  !AD  substitution  directive,
-        passing a string as an additional expression causes the  string  to
-        be inserted in the message  text  instead  of  the  !AD.  $ZMESSAGE
-        function returns the message text with the substitution directives
-        for a given message number.
-
-2 Ex_of_ZMessage
-   Examples of ZMESSAGE
-
-   All of the following examples issue ZMESSAGE  from  Direct  Mode  where
-   exception conditions do not invoke $ZTRAP. ZMESSAGE allows you to feed
-   an undefined message number back into GT.M to  try  and  determine  the
-   message and/or mnemonic associated with it.
-
-   Example:
-
-
-   GTM>ZMESSAGE 2
-
-   %SYSTEM-E-ENO2, No such file or directory
-
-   This ZMESSAGE does not specify substitution text and the  message  does
-   not include any substitution directives.
-
-   Example:
-
-
-   GTM>ZMESSAGE 150372994
-
-   %GTM-E-GVUNDEF, Global Variable undefined:
-
-   The message specified by this ZMESSAGE command includes a substitution
-   directive but the command does not supply any text.
-
-   Example:
-
-
-   GTM>ZMESSAGE 150373850:"x"
-
-   %GTM-E-GVUNDEF, Undefined local variable: x
-
-   This ZMESSAGE command supplies the substitution text for the message.
-
-   GT.M treats  odd-numbered  conditions  as  "successful."  GT.M  handles
-   successful  conditions  by  displaying  the  associated  message  and
-   continuing execution. GT.M treats even-numbered conditions as failures.
-   GT.M handles failure conditions by storing  the  error  information  in
-   $ZSTATUS and XECUTEing $ZTRAP or by terminating if $ZTRAP="". In Direct
-   Mode, GT.M only reports failure conditions to the principal device and
-   does not XECUTE $ZTRAP or set $ZSTATUS. For more information  on  error
-   handling, refer to the "Error Processing" chapter in GT.M Programmer's
-   Guide.
-
-1 ZPRINT
-   ZPrint
-
-   The ZPRINT command displays source code lines selected by its argument.
-
-   The format of the ZPRINT command is:
-
-
-   ZP[RINT][:tvexpr][entryref
-
-   [:label[+intexpr]][,...]]
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    A ZPRINT with no argument prints the entire current routine, which
-        is the routine closest to  the  top  of  an  invocation  stack,  as
-        displayed by a ZSHOW "S"; in this case, at  least  two  (2)  spaces
-        must follow the command to separate it from the next command on the
-        line.
-
-   o    The optional entryref specifies the location in a routine at which
-        to start printing; the entryref can include either a routinename or
-        a label plus a  routinename  in  the  format  LABEL^ROUTINENAME  or
-        LABEL+OFFSET^ROUTINENAME;  if  the  entryref  does  not  contain  a
-        routinename, ZPRINT defaults to the current routine.
-
-   o    The optional label following the entryref identifies a location at
-        which to stop printing; the optional integer  expression  specifies
-        an offset from  the  label;  the  label  and  offset  together  are
-        referred to as a lineref and this lineref identifies the last line
-        to print; if the offset is specified without the label, the offset
-        in the optional lineref is always counted from the beginning of the
-        routine, even when the entryref specifies a label.
-
-   o    If the ZPRINT argument includes the colon (:) delimiter,  then  the
-        argument must also include at least one component of  the  optional
-        lineref.
-
-   o    If  the  ZPRINT  argument  contains  only  the  entryref,  with  no
-        components of the optional lineref  and  the  entryref  contains  a
-        label or offset, ZPRINT displays only the one line that  occurs  at
-        that entryref.
-
-   o    If the entryref contains only a routinename,  ZPRINT  displays  the
-        entire routine.
-
-   o    If the entryref  contains  only  a  routinename  and  the  argument
-        includes the optional lineref, ZPRINT starts  the  display  at  the
-        beginning of the routine.
-
-   o    If the optional lineref specifies  a  line  prior  to  the  lineref
-        specified within the entryref, ZPRINT does not display any lines.
-
-   o    If the offset in the optional lineref specifies a line  beyond  the
-        end of the routine, ZPRINT displays the remainder of the routine.
-
-   o    If ZPRINT cannot locate the routine or if either of the labels does
-        not appear in the routine, ZPRINT issues an error.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZPRINT arguments form a legal argument for a ZPRINT.
-
-   Note that  the  routinename  may  only  appear  before  the  colon  (:)
-   delimiter. The integer expression offsets may be positive or negative,
-   but they must always be delimited by a plus sign (+).
-
-2 Ex_of_ZPrint
-   Examples of ZPRINT
-
-   Example:
-
-
-   GTM>ZPRINT X^RTN
-
-   This example displays the line  beginning  with  the  label  X  in  the
-   routine RTN.
-
-   Example:
-
-
-   GTM>ZPRINT X^RTN:X+5
-
-   GTM>ZPRINT X+-5^RTN:X
-
-   GTM>ZPRINT X^RTN:X+-5^RTN
-
-   The first line displays the line beginning with the  label  X  and  the
-   next 5 lines in routine RTN. The  second  line  displays  the  5  lines
-   preceding label X in the same routine and the line beginning with label
-   X. The third line generates a run-time error because the  routine  name
-   must appear only before the colon in the argument.
-
-1 ZSHOW
-   ZSHow
-
-   The  ZSHOW  command  displays  information  about  the  current  GT.M
-   environment.
-
-   The format of the ZSHOW command is:
-
-
-   ZSH[OW][:tvexpr][expr[:glvn][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional expression specifies one or more codes determining the
-        nature of the information displayed.
-
-   o    A ZSHOW with no argument defaults to ZSHOW "S"; in  this  case,  at
-        least two (2) spaces must follow the ZSHOW to separate it from the
-        next command on the line.
-
-   o    The  optional  global  or  local  variable  name  specifies  the
-        destination for the ZSHOW output; if the ZSHOW  argument  does  not
-        contain a global or local variable name, ZSHOW directs its display
-        to the current device ($IO).
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZSHOW arguments form a legal argument for a ZSHOW.
-
-2 ZSH_Info_Codes
-   ZSHOW Information Codes
-
-   A ZSHOW argument is an expression containing  codes  selecting  one  or
-   more types of information.
-
-        B displays active ZBREAK breakpoints
-        C displays available external call table entry names
-        D displays device information
-        I displays the current values of all intrinsic special variables
-        L displays GT.M LOCKs and ZALLOCATEs held by the process
-        S displays the GT.M invocation stack
-        V displays local variables
-        * displays all possible types of ZSHOW information
-   Codes may be upper- or lower-case. Invalid  codes  produce  a  run-time
-   error. Multiple occurrences of the same code in one ZSHOW argument only
-   produce one output instance of the corresponding information. The order
-   of the first appearance of the codes in  the  argument  determines  the
-   order of the corresponding output instances.
-
-        If you are using a local variable  destination  and  place  another
-        code ahead of "V", the effect is to have the results of the earlier
-        code also appear in the results of the "V" code.
-
-   If the wildcard (*) occurs in the list, ZSHOW uses the default order:
-
-   o    intrinsic special variables
-
-   o    local variables
-
-   o    ZBREAK information
-
-   o    device information
-
-   o    LOCK and ZALLOCATE information
-
-   o    the GT.M stack
-
-2 Ex_of_ZSHow
-   Examples of ZSHOW
-
-   Example:
-
-
-   GTM>ZSHOW "db"
-
-   This command displays  all  devices  with  deviceparameters  reflecting
-   their current characteristics followed by any current ZBREAK locations
-   with their corresponding actions.
-
-   Example:
-
-
-   GTM>ZSHOW "dbd"
-
-   This command displays the same output as the previous example.
-
-   Example:
-
-
-   GTM>ZSHOW "ax"
-
-   This command generates a run-time error.
-
-   Example:
-
-
-   LAB1 DO LAB2
-
-   QUIT
-
-   LAB2 DO LAB3
-
-   QUIT
-
-   LAB3 ZSHOW
-
-   QUIT
-
-   Produces the results:
-
-
-   LAB3^RTN
-
-   LAB2^RTN
-
-   LAB1^RTN
-
-2 ZSH_Destination_Vars
-   ZSHOW Destination Variables
-
-   ZSHOW may specify an  unsubscripted  or  subscripted  global  or  local
-   variable name (glvn)  into  which  ZSHOW  places  its  output.  If  the
-   argument does not include  a  global  or  local  variable  name,  ZSHOW
-   directs its output to the current device.
-
-   When ZSHOW directs its output to a variable,  it  adds  two  levels  of
-   descendants to that variable. The  first  level  subscript  contains  a
-   one-character string from the set of  upper-case  ZSHOW  action  codes,
-   identifying  the  type  of  information.  ZSHOW  implicitly  KILLs  all
-   descendants of the first level nodes. ZSHOW stores information elements
-   at the second level using ascending integers, starting at 1.
-
-   When a ZSHOW "V" directs its output to  a  local  variable  (lvn),  the
-   result does not contain a copy of the descendants of the resulting "V"
-   node.
-
-   Example:
-
-
-   GTM>KILL SET b(1,"two")="test" ZSHOW "v":a ZWR
-
-   a("V",1)="b(1,""two"")=""test"""
-
-   b(1,"two")="test"
-
-   GTM>
-
-   This ZSHOW stores all local variables in the  local  variable  a.  Note
-   that ZSHOW does not replicate a("V") and a("V",1).
-
-   Example:
-
-
-   GTM>KILL SET a(1,"D",3,5)="stuff",a(1,"X",2)="",a(1)=1
-
-   GTM>zsh "d":a(1)
-
-   GTM>zwrite
-
-   a(1)=1
-
-   a(1,"D",1)="/dev/ttyp8 OPEN TERMINAL NOPAST NESCA
-
-   NOREADS TYPE WIDTH=80 LENG=52"
-
-   a(1,"X",2)=""
-
-   GTM>
-
-   This ZSHOW stores the  current  open  device  information  under  a(1).
-   Notice how the ZSHOW deletes a(1,"D",3,5).
-
-   Example:
-
-
-   GTM>KILL ^ZSHOW
-
-   GTM>ZB -*,lab^rout ZSH "B":^ZSHOW
-
-   GTM>ZWRITE ^ZSHOW
-
-   ^ZSHOW("B",1)="LAB^ROUT"
-
-   GTM>
-
-   This ZSHOW stores the  current  ZBREAK  information  under  the  global
-   variable ^ZSHOW.
-
-2 Use_of_ZSHow
-   Use of ZSHOW
-
-   Use ZSHOW as
-
-   o    a debugging tool to display information on the environment.
-
-   o    an error-handling tool to  capture  context  information  after  an
-        unpredictable error with output directed to a sequential file or a
-        global.
-
-   o    part of a context-switching mechanism in a server program that must
-        manage multiple contexts.
-
-   o    a development tool to determine the  external  call  table  entries
-        available from the current process.
-
-   To prevent confusing data interactions, avoid  directing  ZSHOW  output
-   into variables holding other kinds of information and  directing  ZSHOW
-   "V" output into local variables. For a  comparison  of  ZSHOW  "V"  and
-   ZWRITE, refer to the ZWRITE section in the "Commands" chapter  in  GT.M
-   Programmer's Guide.
-
-1 ZSTEP
-   ZSTep
-
-   The ZSTEP command provides the ability to control GT.M execution. When
-   a ZSTEP  is  issued  from  Direct  Mode,  execution  continues  to  the
-   beginning of the next target line  and  then  GT.M  XECUTEs  the  ZSTEP
-   action. The keyword in the optional ZSTEP argument determines the class
-   of eligible target lines.
-
-   The format of the ZSTEP command is:
-
-
-   ZST[EP][:tvexpr] [keyword[:expr]][,...]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional keyword specifies the nature of the step; the keywords
-        are INTO, OVER, and OUTOF.
-
-   o    A ZSTEP with no argument performs the default action OVER; in this
-        case, at least two (2) spaces must follow the ZSTEP to separate it
-        from the next command on the line, which will be ignored.
-
-   o    The optional expression specifies GT.M  code  to  XECUTE  when  the
-        ZSTEP arrives at its destination.
-
-   o    If the ZSTEP argument does  not  contain  an  expression  argument,
-        ZSTEP defaults the action to the value of $ZSTEP, which defaults to
-        "BREAK."
-
-   The ZSTEP argument keywords are not  expressions  and  ZSTEP  does  not
-   accept argument indirection.
-
-   In Direct Mode, ZSTEP performs an implicit ZCONTINUE and therefore GT.M
-   ignores all commands on the Direct Mode command line after the ZSTEP.
-
-   The keyword arguments define the class of lines where ZSTEP next pauses
-   execution to XECUTE the ZSTEP action. When a ZSTEP command has multiple
-   arguments, it ignores all arguments except the last.
-
-2 ZSTEP_Into
-   ZSTEP Into
-
-   ZSTEP INTO pauses at the beginning of  the  next  line,  regardless  of
-   transfers of control. When the ZSTEPed line invokes another routine or
-   a subroutine in the current routine, ZSTEP INTO  pauses  at  the  first
-   line of code associated with the new GT.M stack level.
-
-2 ZSTEP_OUtof
-   ZSTEP OUtof
-
-   ZSTEP OUTOF pauses at the beginning of the next line executed after an
-   explicit or implicit QUIT from the current GT.M invocation stack level.
-   A ZSTEP OUTOF does not pause at lines associated with the current GT.M
-   stack level or with levels invoked from the current level.
-
-2 ZSTEP_OVer
-   ZSTEP OVer
-
-   ZSTEP OVER pauses at the  beginning  of  the  next  line  in  the  code
-   associated with either the current GT.M stack level or a previous GT.M
-   stack level if the ZSTEPed line contains an explicit or  implicit  QUIT
-   from the current level. A ZSTEP OVER does not pause  at  lines  invoked
-   from the current line by DOs, XECUTEs or extrinsics.
-
-2 ZSTEP_Actions
-   ZSTEP Actions
-
-   The optional action parameter of a ZSTEP  must  contain  an  expression
-   evaluating to valid GT.M code. By default,  ZSTEP  uses  the  value  of
-   $ZSTEP, which defaults to "B" ("BREAK"), and enters Direct Mode. When a
-   ZSTEP command specifies an action, the process does  not  enter  Direct
-   Mode unless the action explicitly includes a BREAK command.
-
-2 ZSTEP_Interact
-   ZSTEP Interactions
-
-   ZSTEP currently interacts with  certain  other  elements  in  the  GT.M
-   environment.
-
-   o    If a <CTRL-C> or a CTRAP character arrives  at  certain  points  in
-        ZSTEP processing, there is a  small  chance  GT.M  may  ignore  the
-        <CTRL-C> or CTRAP; in a later release,  <CTRL-C>  and  CTRAPs  will
-        always have priority over ZSTEP.
-
-   o    If GT.CM reports an asynchronous network error, a ZSTEP  may  cause
-        the  network  error  to  go  unreported;  the  chance  of  such  an
-        occurrence is small and the chance the error would subsequently be
-        reported is high; in a later release, network errors will always be
-        given priority over ZSTEP.
-
-2 Use_of_ZSTEP
-   Use of ZSTEP
-
-   Use ZSTEP to incrementally execute a routine  or  series  of  routines.
-   Execute any GT.M command from Direct Mode at any ZSTEP pause. To resume
-   normal execution, use ZCONTINUE.
-
-   Note that ZSTEP arguments are keywords rather than expressions. They do
-   not allow indirection, and argument lists have no utility.
-
-   ZSTEP actions that include commands followed by a  BREAK  perform  some
-   action before entering Direct Mode. ZSTEP actions that do not include a
-   BREAK perform the command action  and  continue  execution.  Use  ZSTEP
-   actions that issue conditional BREAKs and subsequent ZSTEPs to do such
-   things as test for changes in the value of a variable.
-
-2 Ex_of_ZSTEP
-   Examples of ZSTEP
-
-   Example:
-
-
-   GTM>ZSTEP INTO:"W ! ZP @
-
-   $ZPOS W !"
-
-   This ZSTEP resumes execution of the current routine. At  the  beginning
-   of the next line executed, the ZSTEP action ZPRINTs the source code for
-   that line. Because the  specified  action  does  not  contain  a  BREAK
-   command, execution continues to the next line and all subsequent lines
-   in the program flow.
-
-   Example:
-
-
-   GTM>S curx=$g(x),zact="ZST:curx=$g(x) I:zact B:curx'=$g(x)"
-
-   GTM>ZSTEP INTO:zact
-
-   This sequence uses ZSTEP to invoke Direct Mode at the beginning of the
-   first line after the line that alters the value of x.
-
-1 ZSYSTEM
-   ZSYstem
-
-   The ZSYSTEM command creates a child of the current process.
-
-   The format of the ZSYSTEM command is:
-
-
-   ZSY[STEM][:tvexpr] [expr[:tvexpr][,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional expression specifies the command passed to the shell;
-        after processing the command, the shell returns control to GT.M.
-
-   o    If ZSYSTEM has no argument or expr="", the shell prompts for input
-        until provided with an exit command; at least two (2)  spaces  must
-        follow a ZSYSTEM command with no argument to separate it  from  the
-        next command on the line.
-
-   o    The  optional  truth-valued  expression  following  the  argument
-        expression specifies  the  argument  postconditional  and  controls
-        whether ZSYSTEM processes that argument.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZSYSTEM  arguments  form  a  legal  argument  for  a
-        ZSYSTEM.
-
-   The ZSYSTEM command creates a new process and passes  its  argument  to
-   the shell for execution. The new process executes in the same directory
-   as the initiating process  using  the  shell  specified  by  the  SHELL
-   environment variable, or if that is not defined, the Bourne shell. The
-   new  process  has  the  same  operating  system  environment,  such  as
-   environment variables  and  input/output  devices,  as  the  initiating
-   process. The initiating process pauses until the new process completes
-   before continuing execution. The return status of the forked process is
-   reflected in $ZSYSTEM.
-
-   If a ZSYSTEM command has multiple arguments, it starts  a  new  process
-   for each argument, one at a time. ZSYSTEM  waits  for  one  process  to
-   complete before starting the next one.
-
-   A ZSYSTEM with a null argument creates a shell with the standard input
-   and output devices. When the shell exits, control is returned to GT.M.
-   For an interactive process, both stdin and  stdout  are  generally  the
-   user's terminal. A ZSYSTEM with no arguments is equivalent to a ZSYSTEM
-   with a single null string argument.
-
-   If a command postconditional  is  false,  GT.M  does  not  process  the
-   ZSYSTEM command. If an argument postconditional is false, GT.M does not
-   process that argument.
-
-   Issuing a ZSYSTEM command inside a transaction destroys  the  Isolation
-   of  that  transaction.  Because  of  the  way  that  GT.M  implements
-   transaction processing, a ZSYSTEM within a transaction  may  suffer  an
-   indefinite number of restarts ("live lock").
-
-2 Ex_of_ZSYSTEM
-   Examples of ZSYstem
-
-   Example:
-
-
-   GTM>ZSYSTEM "ls *.m"
-
-   This uses ZSYSTEM to fork a process that then performs the  ls  command
-   with *.m as an argument to ls. Once the command completes,  the  forked
-   process terminates.
-
-   Example:
-
-
-   GTM>ZSYSTEM
-
-   $
-
-   This ZSYSTEM has no argument so the forked process prompts for input.
-
-1 ZTCOMMIT
-   ZTCommit
-
-   The ZTCOMMIT command marks the end of a logical  transaction  within  a
-   GT.M program. ZTCOMMIT used with ZTSTART  "fences"  transactions  (that
-   is, marks the end and beginning). Fencing transactions allows the MUPIP
-   JOURNAL  facility  to  prevent  incomplete  application  transactions
-   consisting of multiple  global  updates  from  affecting  the  database
-   during a database recovery.
-
-   The format of the ZTCOMMIT command is:
-
-
-   ZTC[OMMIT][:tvexpr] [intexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional integer expression specifies the number  of  currently
-        open ZTSTARTs for the ZTCOMMIT to close.
-
-   o    A ZTCOMMIT with no argument closes one ZTSTART; in  this  case,  at
-        least two (2) spaces must follow the command to  separate  it  from
-        the next command on the line;  with  an  argument  of  0,  ZTCOMMIT
-        closes all open ZTSTARTs.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZTCOMMIT arguments  form  a  legal  argument  for  a
-        ZTCOMMIT.
-
-   When an application requires sub-transactions, it may nest ZTSTARTs and
-   ZTCOMMITs to a maximum depth of 255. However, a ZTCOMMIT  must  "close"
-   the outer-most ZTSTART  before  journaling  accepts  any  part  of  the
-   "transaction" as complete.
-
-2 Ex_of_ZTCommit
-   Examples of ZTCOMMIT
-
-   Example:
-
-
-   GTM>ZTCOMMIT 0
-
-   This ZTCOMMIT issued from Direct Mode would close any open ZTSTARTs.
-
-   Example:
-
-1 ZTSTART
-   ZTStart
-
-   The ZTSTART command marks the beginning of a logical transaction within
-   a GT.M program. ZTSTART and ZTCOMMIT  "fence"  transactions  (that  is,
-   mark the beginning and end).  Fenced  transactions  prevent  the  MUPIP
-   JOURNAL facility from recovering incomplete transactions. All ZTSTARTs
-   must be matched with ZTCOMMITs before the journal  processing  facility
-   recognizes the transaction as complete.
-
-   The format of the ZTSTART command is:
-
-
-   ZTS[TART][:tvexpr]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    Because ZTSTART has no argument,  at  least  two  (2)  spaces  must
-        follow the command to separate it from  the  next  command  on  the
-        line.
-
-   For more information on Journaling and transaction  fencing,  refer  to
-   the section on ZTCOMMIT and the "GT.M Journaling" chapter in  the  GT.M
-   Administration and Operations Guide.
-
-2 Ex_of_ZTStart
-   Examples of ZTSTART
-
-   Example:
-
-
-   LOCK ^P(t)
-
-   ZTSTART
-
-   SET ^P(t)=prec,^($H)=$G(^P(t,+$H))+1,^(+$H,s)=hrec
-
-   ZTCOMMIT
-
-   LOCK
-
-   This uses a LOCK on ^P(t) to serialize  the  transaction.  The  logical
-   transaction consists of three global sets that are  enclosed  within  a
-   ZTSTART and a ZTCOMMIT.
-
-   Example:
-
-
-   BASE DO WORK
-
-   QUIT
-
-   GRP LOCK ^FAM(prn)
-
-   SET b=^FAM(prn)
-
-   ZTSTART
-
-   FOR i=1:1:$L(b,"|") D GET,WORK
-
-   ZTCOMMIT
-
-   LOCK
-
-   QUIT
-
-   WORK LOCK +^ACT(acct)
-
-   ZTSTART
-
-   SET ^ACT(acct)=actrec
-
-   SET ^ACTX(lname,fname,acct)=""
-
-   ZTCOMMIT
-
-   LOCK -^ACT(acct)
-
-   This has a sub-routine  WORK,  which  BASE  invokes  directly  and  GRP
-   invokes to perform a sub-transaction.
-
-1 ZWITHDRAW
-   ZWIthdraw
-
-   The ZWITHDRAW command KILLs the data value for a variable name without
-   affecting the nodes descended from that node.
-
-   The format of the ZWITHDRAW command is:
-
-
-   ZWI[THDRAW][:tvexpr] glvn
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The global or local variable name identifies the variable for which
-        ZWITHDRAW removes the data value.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZWITHDRAW arguments form  a  legal  argument  for  a
-        ZWITHDRAW.
-
-   ZWITHDRAW provides a tool to quickly restore a node to a state where it
-   has descendants and no value-that is, where $DATA for  that  node  will
-   have a value of 10-for the case where such a  state  has  some  control
-   meaning. GT.M also  provides  the  ZKILL  command,  with  functionality
-   identical to ZWITHDRAW.
-
-2 Ex_of_ZWIthdraw
-   Examples of ZWITHDRAW
-
-   Example:
-
-
-   KILL A
-
-   SET A="A",A(1)=1,A(1,1)=1
-
-   WRITE $D(A(1)),!
-
-   ZWITHDRAW A(1)
-
-   WRITE $D(A(1)),!
-
-   ZWRITE A
-
-   QUIT
-
-   produces the result:
-
-
-   11
-   10
-   A="A"
-
-   A(1,1)=1
-
-   This sets up local variables A and A(1) and A(1,1). It then deletes the
-   data for A(1) with ZWITHDRAW. The ZWRITE command shows ZWITHDRAW KILLed
-   A(1) but left A and A(1,1).
-
-1 ZWRITE
-   ZWRite
-
-   The ZWRITE command displays the current value of one or more  local  or
-   global variables. ZWRITE formats its output so that each  item  in  the
-   display forms a valid argument to a SET @ command.  This  means  ZWRITE
-   encloses string values in quotes and represents  non-graphic  (control)
-   characters in $CHAR() syntax.
-
-   The format of the ZWRITE command is:
-
-
-   ZWR[ITE][:tvexpr] [zwrglvn[,...]]
-
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The optional global or local variable name specifies  the  variable
-        for ZWRITE to display.
-
-   o    ZWRITE accepts several alternative syntaxes in place of subscripts;
-        ZWRITE  also  accepts  arguments  specifying  naked  references  to
-        globals. Because ZWRITE is primarily a debugging tool, ZWRITE does
-        not affect the naked indicator.
-
-   o    ZWRITE accepts null subscripts in its  arguments,  when  these  are
-        allowed, and reports array nodes that have null subscripts.
-
-   o    A ZWRITE with no arguments displays  all  the  currently  available
-        local variables; in this case, at least two (2) spaces must follow
-        the command to separate it from the next command on the line.
-
-   o    If the global or  local  variable  name  is  unsubscripted,  ZWRITE
-        displays  the  unsubscripted  variable  and  all  subscripted
-        descendants.
-
-   o    If an asterisk (*) appears in the space normally  occupied  by  the
-        last subscript in a subscripted variable name, ZWRITE displays all
-        variable nodes descended from the previously specified subscripts.
-
-   o    ZWRITE accepts GT.M pattern-match syntax in place of both variable
-        names and subscripts.
-
-   o    ZWRITE <name>(), where <name> is a local or a global is treated as
-        a synonym for ZWRITE <name>.
-
-   o    A colon acts as a  range  operator  for  subscript  values;  ZWRITE
-        displays all subscripts of the variable starting with the value on
-        the left side of the colon and ending with the value on  the  right
-        side of the colon; if the range delimiter has no  left-hand  value,
-        or has the empty string as the left-hand value, the display begins
-        at the first subscript; if the range delimiter  has  no  right-hand
-        value or has the empty string as the right-hand value, the display
-        ends at the last subscript at that level; if  the  range  delimiter
-        has no values or empty strings on either side, ZWRITE displays all
-        subscripts at that level; an empty subscript  level  also  displays
-        all subscripts at that level.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more ZWRITE arguments form a legal argument for a ZWRITE.
-
-   o    Long ZWRITE format records can be loaded.
-
-2 Ex_of_ZWRite
-   Examples of ZWRITE
-
-   Example:
-
-
-   GTM>ZWRITE ^?1"%"2U(0:":",)
-
-   This command displays the descendants of all subscripts between  0  and
-   ":" of all global names starting with a "%" and having two  upper  case
-   letters-for example, "%AB".
-
-   Example:
-
-
-   GTM>ZWRITE A(,:,3)
-
-   This command displays all of the third level nodes with a subscript of
-   3 for local variable A.
-
-   Example:
-
-
-   ZWRITE ?1"A".E(?1"X"3N)
-
-   This would display data for any  local  variables  starting  with  "A",
-   optionally followed  by  any  characters,  and  having  any  subscripts
-   starting with "X" followed by three numerics.
-
-1 Functions
-   Functions
-
-   M Intrinsic Functions start with a single dollar sign ($) and have one
-   or more arguments enclosed in parentheses () and  separated  by  commas
-   (,). These functions provide expression results by  performing  actions
-   that are impossible or difficult to perform using M commands.
-
-2 $ASCII()
-   $ASCII()
-
-   The $ASCII function returns the integer ASCII code for a character in a
-   string.
-
-   The format for the $ASCII function is:
-
-   $A[SCII](expr[,intexpr])
-
-   o    The expression acts  as  the  source  string  from  which  $ASCII()
-        extracts the character it decodes.
-
-   o    The optional integer expression contains the  position  within  the
-        expression of the character that $ASCII() decodes. If this argument
-        is missing, $ASCII() returns a result based on the first character
-        position. $ASCII() starts numbering character positions at one (1),
-        (i.e., the first character of a string is at position one (1)).
-
-   o    If the explicit or implicit position is  before  the  beginning  or
-        after the end of  the  expression,  $ASCII()  returns  a  value  of
-        negative one (-1).
-
-   $ASCII() provides a means of  examining  non-graphic  characters  in  a
-   string. Used with $CHAR(), $ASCII() also provides a  means  to  perform
-   arithmetic operations on the codes associated with characters.
-
-3 Ex_of_$ASCII()
-   Examples of $ASCII()
-
-   Example:
-
-
-   GTM> FOR i=0:1:3 WRITE !,$A("HI",i)
-
-   -1
-
-   72
-   73
-   -1
-
-   GTM>
-
-   This loop displays  the  result  of  $ASCII()  specifying  a  character
-   position before, first and second positions, and after the string.
-
-2 $Char()
-   $CHAR()
-
-   The  $CHAR  function  returns  a  string  of  one  or  more  characters
-   corresponding to integer ASCII codes specified in its argument(s).
-
-   The format for the $CHAR function is:
-
-
-   $C[HAR](intexpr[,...])
-
-   o    The  integer  expression(s)  specify  the  ASCII  codes  of  the
-        character(s) $CHAR() returns.
-
-   The M standard does not restrict the number of  arguments  to  $CHAR().
-   However, GT.M does limit the number of arguments to a maximum  of  254.
-   $CHAR() provides a means of producing non-graphic characters,  as  such
-   characters cannot appear directly within an M string literal. Used with
-   $ASCII(), $CHAR() can also perform arithmetic operations on  the  codes
-   associated with characters.
-
-3 Ex_of_$CHAR()
-   Examples of $CHAR()
-
-   Example:
-
-
-   GTM> WRITE $CHAR(77,85,77,80,83,7)
-
-   MUMPS
-
-   GTM>
-
-   This example uses $CHAR() to  WRITE  the  word  MUMPS  and  signal  the
-   terminal "bell."
-
-   Example:
-
-
-   SET nam=$E(nam,1,$L(nam)-1)_$C($A(nam,$L(nam))-1))
-
-   This example uses $CHAR() and $ASCII() to set the  variable  nam  to  a
-   value that immediately precedes  its  previous  value  in  the  set  of
-   strings of the same length as nam.
-
-2 $Data()
-   $Data()
-
-   The $DATA function returns an integer code  describing  the  value  and
-   descendent status of a local or global variable.
-
-   The format for the $DATA function is:
-
-
-   $D[ATA](glvn)
-
-   o    The subscripted or unsubscripted  global  or  local  variable  name
-        specifies the target node.
-
-   o    If the variable is undefined, $DATA() returns 0.
-
-   o    If the variable has a value but no descendants, $DATA() returns 1.
-
-   o    If the variable has descendants but no value, $DATA() returns 10.
-
-   o    If the variable has a value and descendants, $DATA() returns 11.
-
-3 Ex_of_$Data()
-   Examples of $DATA()
-
-   Example:
-
-
-   GTM> KILL WRITE $DATA(a)
-
-   0
-   GTM> SET a(1)=1 WRITE $DATA(a(1))
-
-   1
-   GTM> WRITE $DATA(a)
-
-   10
-   GTM> SET a=0 WRITE $DATA(a)
-
-   11
-   GTM>
-
-   This uses $DATA to display all possible $DATA() results.
-
-   Example:
-
-   L ^ACCT(0)
-
-   I '$D(^ACCT(0)) S ^ACCT(0)=0
-
-   S (ACCT,^ACCT(0))=^ACCT(0)+1
-
-   L
-
-   This  uses  $DATA()  to  determine  whether  a  global  node  requires
-   initialization.
-
-   Example:
-
-   FOR SET cus=$O(^cus(cus)) Q:cus="" I $D(^(cus))>1 D WORK
-
-   This uses $DATA() to determine whether a global  node  has  descendants
-   and requires additional processing.
-
-2 $Extract()
-   $EXTRACT()
-
-   The $EXTRACT function returns a substring of a given string.
-
-   The format for the $EXTRACT function is:
-
-
-   $E[XTRACT](expr[,intexpr1[,intexpr2]])
-
-   o    The expression specifies a string from which $EXTRACT()  derives  a
-        substring.
-
-   o    The first optional integer expression (second  argument)  specifies
-        the starting character position in the string expr of the substring
-        result.  If  the  starting  position  is  beyond  the  end  of  the
-        expression, $EXTRACT() returns the null  string.  If  the  starting
-        position is zero (0) or negative, $EXTRACT() starts  at  the  first
-        position in the expression; if this argument is omitted, $EXTRACT()
-        returns the first character of the expression.  $EXTRACT()  numbers
-        character positions starting at one (1) (i.e., the first character
-        of a string is at position one (1)).
-
-   o    The second optional integer expression (third  argument)  specifies
-        the ending  character  position  for  the  result.  If  the  ending
-        position is beyond the end of the expression, $EXTRACT() stops with
-        the last character  of  the  expression.  If  the  ending  position
-        precedes the starting position, $EXTRACT() returns the null string.
-        If this argument is omitted, $EXTRACT() returns  one  character  at
-        most.
-
-   $EXTRACT() provides a tool for manipulating strings based on character
-   positions.
-
-   A SET command argument can have something that  has  the  format  of  a
-   $EXTRACT() on the left-hand side of its equal sign (=). This construct
-   permits easy maintenance of individual pieces within a string.  It  can
-   also be used to right justify a value padded with blank characters. For
-   more information on SET $EXTRACT(), refer  to  SET  in  the  "Commands"
-   chapter.
-
-3 Ex_of_$Extract()
-   Examples of $EXTRACT()
-
-   Example:
-
-
-   GTM> FOR i=0:1:3 WRITE !,$EXTRACT("HI",i),"<"
-
-<
-   H<
-
-   I<
-
-<
-   GTM>
-
-   This loop displays the  result  of  $EXTRACT(),  specifying  no  ending
-   character position and a beginning character position "before, " first
-   and second positions, and "after" the string.
-
-   Example:
-
-
-   GTM> FOR i=0:1:3 WRITE !,$E("HI",1,i),"<"
-
-<
-   H<
-
-   HI<
-
-   HI<
-
-   GTM>
-
-   This loop displays the result  of  $EXTRACT()  specifying  a  beginning
-   character position of 1 and an ending  character  position  "before,  "
-   first and second positions, and "after" the string.
-
-   Example:
-
-
-   TRIM(x)
-
-   NEW i,j
-
-   FOR j=$L(x):-1:0 S nx=$E(x,1,j) Q:$EXTRACT(x,j)'=" "
-
-   FOR i=1:1:j S fx=$E(nx,i,$L(x)) Q:$EXTRACT(x,i)'=" "
-
-   QUIT fx
-
-
-   GTM>SET str=" MUMPS "
-
-
-   GTM>WRITE $LENGTH(str)
-
-   7
-   GTM>WRITE $LENGTH($$TRIM^trim(str))
-
-   5
-   This extrinsic function uses $EXTRACT() to  remove  extra  leading  and
-   trailing spaces from its argument.
-
-2 $Find()
-   $FIND()
-
-   The $FIND function returns an integer character position  that  locates
-   the occurrence of a substring within a string.
-
-   The format for the $FIND function is:
-
-
-   $F[IND](expr1,expr2[,intexpr])
-
-   o    The first expression specifies the string in which $FIND() searches
-        for the substring.
-
-   o    The second expression specifies the  substring  for  which  $FIND()
-        searches.
-
-   o    The optional integer expression identifies  the  starting  position
-        for the $FIND() search. If this argument is missing, zero  (0),  or
-        negative, $FIND() begins its search in the first  position  of  the
-        string.
-
-   o    If $FIND() locates the substring, it returns the position after the
-        last character of the  substring.  If  the  end  of  the  substring
-        coincides with the end of the string (expr1), it returns an integer
-        equal to the length of the string plus one ($L(expr1)+1).
-
-   o    If $FIND() does not locate the substring, it returns zero (0).
-
-   $FIND() provides a tool to locate characters. The ( [  )  operator  and
-   the  two-argument  $LENGTH()  are  other  tools  that  provide  related
-   functionality.
-
-3 Ex_of_$Find()
-   Examples of $FIND()
-
-   Example:
-
-
-   GTM> WRITE $FIND("HIFI","I")
-
-   3
-   GTM>
-
-   This example uses $FIND() to WRITE the position of the first occurrence
-   of the character "I." The return of 3  gives  the  position  after  the
-   "found" substring.
-
-   Example:
-
-
-   GTM> WRITE $FIND("HIFI","I",3)
-
-   5
-   GTM>
-
-   This example uses $FIND() to WRITE the position of the next occurrence
-   of the character "I" starting in character position three.
-
-   Example:
-
-
-   GTM> SET t=1 FOR SET t=$FIND("BANANA","AN",t) Q:'t W !,t
-
-   4
-   6
-   GTM>
-
-   This example uses a loop with $FIND() to locate all occurrences of "AN"
-   in "BANANA". The $FIND() returns 4 and 6 giving the positions after the
-   two occurrences of "AN".
-
-   Example:
-
-
-   GTM> SET str="MUMPS databases are hierarchical"
-
-
-   GTM>WRITE $FIND(str," ")
-
-   7
-
-   GTM>WRITE $FIND(str,"Z")
-
-   0
-
-   GTM>WRITE $FIND(str,"d",1)
-
-   8
-
-   GTM>WRITE $FIND(str,"d",10)
-
-   0
-   The above example searches a string for a sub string,  and  returns  an
-   integer value which corresponds to the next  character  position  after
-   locating the sub string.
-
-2 $FNumber()
-   $FNumber()
-
-   The $FNUMBER function returns a string containing a formatted number.
-
-   The format for the $FNUMBER function is:
-
-   $FN[UMBER](numexpr,expr[,intexpr])
-
-   o    The  numeric  expression  specifies  the  number  that  $FNUMBER()
-        formats.
-
-   o    The expression (second argument)  specifies  zero  or  more  single
-        character format control codes;  if  the  expression  contains  any
-        character other than the  defined  codes,  $FNUMBER()  generates  a
-        run-time error.
-
-   o    The optional integer  expression  (third  argument)  specifies  the
-        number of digits after the decimal point. If the numeric expression
-        has more digits than specified by this argument, $FNUMBER() rounds
-        to obtain the result. If the numeric expression  has  fewer  digits
-        than specified by this argument, $FNUMBER()  zero-fills  to  obtain
-        the result.
-
-   o    When the  optional  third  argument  is  specified  and  the  first
-        argument evaluates to a  fraction  between  -1  and  1,  $FNUMBER()
-        returns a number with a leading zero (0) before the  decimal  point
-        (.).
-
-   $FNUMBER() formats or edits numbers, usually for  reporting.  For  more
-   information on rounding performed by $FNUMBER(), refer to  the  section
-   on $JUSTIFY().
-
-   The formatting codes are:
-
-        + Forces a "+" on positive values.
-        - Suppresses the "-" on negative values.
-        , Inserts commas every third position to the left  of  the  decimal
-        within the number.
-        T Represents the number with a  trailing,  rather  than  a  leading
-        sign; positive numbers have a trailing space unless the expression
-        includes a plus sign (+).
-        P Represents negative values in parentheses, positive values with a
-        space on either side; combining with any other  code  except  comma
-        (,) causes a run-time error.
-   M accepts both lower-case and upper-case alphabetic codes. The order of
-   the codes does not affect the result.
-
-3 Ex_of_$FNumber()
-   Examples of $FNUMBER()
-
-   Example:
-
-
-   SET X=-100000,Y=2000
-
-   WRITE "SUPPRESS NEGATIVE SIGN:",?35,$FNUMBER(X,"-"),!
-
-   WRITE "TRAILING SIGN:",?35,$FNUMBER(X,"T"),!
-
-   WRITE "NEGATIVE NUMBERS IN ():",?35,$FNUMBER(X,"P"),!
-
-   WRITE "COMMAS IN NUMBER:",?35,$FNUMBER(X,","),!
-
-   WRITE "NUMBER WITH FRACTION:",?35,$FNUMBER(X,"",2),!
-
-   WRITE "FORCE + SIGN IF POSITIVE:",?35,$FNUMBER(Y,"+"),!
-
-   Produces the results:
-
-
-   SUPPRESS NEGATIVE SIGN: 100000
-
-   TRAILING SIGN: 100000-
-
-   NEGATIVE NUMBERS IN (): (100000)
-
-   COMMAS IN NUMBER: -100,000
-
-   NUMBER WITH FRACTION: -100000.00
-
-   FORCE + SIGN IF POSITIVE: +2000
-
-   Example:
-
-
-   SET x=$FNUMBER(x,"-")
-
-   This example uses $FNUMBER() to SET x equal to its absolute value.
-
-2 $Get()
-   $Get()
-
-   The $GET function returns the value of a local or  global  variable  if
-   the variable has a value. If the variable has no  value,  the  function
-   returns a value specified by an optional second argument, and otherwise
-   returns a null string.
-
-   The format for the $GET function is:
-
-   $G[ET](glvn[,expr])
-
-   o    The subscripted or unsubscripted  global  or  local  variable  name
-        specifies the node for which $GET() returns a value.
-
-   o    If the global or local variable has a data  value,  $GET()  returns
-        the value of the variable.
-
-   o    If the global or local variable has no data value,  $GET()  returns
-        the value of the optional expression (second argument), or  a  null
-        string if the expression is not specified.
-
-   M defines $GET(x,y) as equivalent to:
-
-
-   $SELECT($DATA(x)[0:y,1:x)
-
-   and $GET(x) as equivalent to:
-
-   $GET(x,"")
-
-   $GET()  provides  a  tool  to  eliminate  separate  initialization  of
-   variables. This technique may provide performance benefits when used to
-   increase the density of a sparse global array by eliminating nodes that
-   would otherwise hold absent optional information. On  the  other  hand,
-   some uses of one argument $GET() can mask logic problems.
-
-   GT.M has a "NOUNDEF" mode  of  operation,  which  treats  all  variable
-   references as if they were arguments to a one argument $GET(). The VIEW
-   command controls "NOUNDEF" mode.
-
-3 Ex_of_$Get()
-   Examples of $GET()
-
-   Example:
-
-
-   I '$D(^PNT(NAME,TSTR)) S STATUS="NEW TEST"
-
-   E I ^PNT(NAME,TSTR)="" S STATUS="WAITING FOR RESULT"
-
-   E S STATUS=^PNT(NAME ,TSTR)
-
-   This example can be reduced to two lines of code by using $GET(), shown
-   in the following example. However, by using $GET() in its one-argument
-   form, the distinction between an undefined variable and one with a null
-   value is lost:
-
-
-   S STATUS=$G(^PNT(NAME,TSTR))
-
-   I STATUS="" S STATUS="WAITING FOR RESULT"
-
-   This is solved by using the two-argument form of $GET():
-
-
-   S STATUS=$G(^PNT(NAME,TSTR),"NEW TEST")
-
-   I STATUS="" S STATUS="WAITING FOR RESULT"
-
-2 $Justify()
-   $Justify()
-
-   The $JUSTIFY function returns a formatted string.
-
-   The format for the $JUSTIFY function is:
-
-
-   $J[USTIFY](expr,intexpr1[,intexpr2])
-
-   o    The expression specifies the string formatted by $JUSTIFY().
-
-   o    The  first  integer  expression  (second  argument)  specifies  the
-        minimum  size  of  the  resulting  string.  If  the  first  integer
-        expression is larger than the length of the expression, $JUSTIFY()
-        right justifies the expression to a string of the specified length
-        by  adding  leading  spaces.  Otherwise,  $JUSTIFY()  returns  the
-        expression  unmodified  unless  specified  by  the  second  integer
-        argument.
-
-   o    The optional second integer expression (third  argument)  specifies
-        the number of digits to follow the decimal point in the result, and
-        forces $JUSTIFY() to evaluate the expression  as  numeric.  If  the
-        numeric expression has more digits than  this  argument  specifies,
-        $JUSTIFY() rounds to obtain the result. If the expression had fewer
-        digits than  this  argument  specifies,  $JUSTIFY()  zero-fills  to
-        obtain the result.
-
-   o    When the second  argument  is  specified  and  the  first  argument
-        evaluates to a fraction between -1  and  1,  $JUSTIFY()  returns  a
-        number with a leading zero (0) before the decimal point (.).
-
-   $JUSTIFY() fills expressions to create fixed length values. However, if
-   the length of the specified  expression  exceeds  the  specified  field
-   size, $JUSTIFY() does not truncate the result (although  it  may  still
-   round based on the third argument). When required, $EXTRACT() performs
-   truncation.
-
-   $JUSTIFY() optionally rounds  the  portion  of  the  result  after  the
-   decimal point. In the absence of the third  argument,  $JUSTIFY()  does
-   not restrict the evaluation of the expression. In the presence  of  the
-   third (rounding) argument, $JUSTIFY() evaluates  the  expression  as  a
-   numeric value. The rounding algorithm can be understood as follows:
-
-   o    If necessary, the rounding algorithm extends the expression to the
-        right with 0s  (zeros)  to  have  at  least  one  more  digit  than
-        specified by the rounding argument.
-
-   o    Then, it adds 5 (five)  to  the  digit  position  after  the  digit
-        specified by the rounding argument.
-
-   o    Finally, it truncates the result to the specified number of digits.
-        The algorithm rounds up when excess digits specify a half  or  more
-        of the last retained digit and rounds down when they  specify  less
-        than a half.
-
-3 Ex_of_$Justify()
-   Examples of $JUSTIFY()
-
-   Example:
-
-
-   GTM> WRITE $JUSTIFY("HELLO",10),!,$JUSTIFY("GOODBYE",5)
-
-   HELLO
-
-   GOODBYE
-
-   GTM>
-
-   This uses $JUSTIFY() to display "HELLO" in a field  of  10  spaces  and
-   "GOODBYE" in a field of 5  spaces.  Because  the  length  of  "GOODBYE"
-   exceeds five spaces, the result overflows the specification.
-
-   Example:
-
-
-   GTM> WRITE "1234567890",!,$JUSTIFY(10.545,10,2)
-
-   1234567890
-   10.55
-
-   GTM>
-
-   This uses $JUSTIFY() to WRITE a rounded  value  right  justified  in  a
-   field of 10 spaces. Notice that the result has been rounded up.
-
-   Example:
-
-
-   GTM> WRITE "1234567890",!,$JUSTIFY(10.544,10,2)
-
-   1234567890
-   10.54
-
-   GTM>
-
-   Again, this uses $JUSTIFY() to WRITE a rounded value right justified in
-   a field of 10 spaces. Notice that the result has been rounded down.
-
-   Example:
-
-
-   GTM> WRITE "1234567890",!,$JUSTIFY(10.5,10,2)
-
-   1234567890
-   10.50
-
-   GTM>
-
-   Once again, this  uses  $JUSTIFY()  to  WRITE  a  rounded  value  right
-   justified in a field of 10 spaces. Notice  that  the  result  has  been
-   zero-filled to 2 places.
-
-   Example:
-
-
-   GTM> WRITE $JUSTIFY(.34,0,2)
-
-   0.34
-   GTM>
-
-   This example uses $JUSTIFY to ensure that the fraction  has  a  leading
-   zero. Note the use of a second  argument  of  zero  in  the  case  that
-   rounding is the only function that $JUSTIFY is to perform.
-
-2 $Length()
-   $Length()
-
-   The $LENGTH function  returns  the  length  of  a  string  measured  in
-   characters, or in "pieces" separated by a delimiter specified by one of
-   its arguments.
-
-   The format for the $LENGTH function is:
-
-
-   $L[ENGTH](expr1[,expr2])
-
-   o    The  first  expression  specifies  the  string  that  $LENGTH()
-        "measures."
-
-   o    The optional second expression specifies the delimiter that defines
-        the measure; if this argument is  missing,  $LENGTH()  returns  the
-        number of characters in the string.
-
-   o    If the second argument is present and not a  null  string,  $LENGTH
-        returns one more than the count of the number of occurrences of the
-        second string in the first string; if the second argument is a null
-        string, the M standard specifies that $LENGTH() returns a zero (0).
-
-   $LENGTH() provides a tool for determining the lengths of strings in two
-   ways, characters and pieces. The two  argument  $LENGTH()  returns  the
-   number of existing pieces, while the one argument returns the number of
-   characters.
-
-3 Ex_of_$Length()
-   Examples of $LENGTH()
-
-   Example:
-
-
-   GTM> WRITE $LENGTH("KINGSTON")
-
-   8
-   GTM>
-
-   This uses $LENGTH() to WRITE the length in  characters  of  the  string
-   "KINGSTON".
-
-   Example:
-
-
-   GTM> SET x="Smith/John/M/124 Main Street/Ourtown/KA/USA"
-
-   GTM> WRITE $LENGTH(x,"/")
-
-   7
-   GTM>
-
-   This uses $LENGTH() to WRITE the number  of  pieces  in  a  string,  as
-   delimited by /.
-
-   Example:
-
-
-   GTM> WRITE $LENGTH("/2/3/","/")
-
-   4
-   GTM>
-
-   This also uses $LENGTH() to WRITE the number of pieces in a string, as
-   delimited by /. Notice that GT.M. adds one count to the final number of
-   pieces (in this case 3), in the string (displays 4).
-
-2 $NAme()
-   $NAme()
-
-   The $NAME function returns an evaluated representation of some  or  all
-   of a local or global variable name.
-
-   The format for the $NAME function is:
-
-
-   $NA[ME](glvn[,intexpr])
-
-   o    The subscripted or unsubscripted global  or  local  variable  name,
-        including naked references, specifies the name  for  which  $NAME()
-        returns an evaluated representation.
-
-   o    The optional integer expression  (second  argument)  specifies  the
-        maximum number of subscript levels in the  representation.  If  the
-        integer expression is not provided or exceeds the actual number of
-        subscript levels, $NAME() returns a  representation  of  the  whole
-        name. If the integer expression is zero (0), $NAME()  returns  only
-        the name. A negative integer expression produces a run-time error.
-
-3 Ex_of_$Name()
-   Examples of $NAME()
-
-   Example:
-
-
-   GTM> SET X="A""B",^Y(1,X,"B",4)=""
-
-   GTM> WRITE $NAME(^(3),3)
-
-   ^Y(1,"A""B","B")
-
-   GTM>
-
-   This example sets up a naked reference and then uses $NAME() to display
-   the first three levels of that four-level reference.
-
-   Example:
-
-
-   GTM> WRITE $NAME(^(3),0)
-
-   ^Y
-
-   GTM>
-
-   This example shows the name level for the same naked reference.
-
-2 $Next()
-   $Next()
-
-   The $NEXT  function  returns  the  next  subscripted  local  or  global
-   variable name in collation sequence within the array level specified by
-   its argument.
-
-   $NEXT() has been replaced by $ORDER(). $NEXT has been retained  in  the
-   current standard only for compatibility with earlier  versions  of  the
-   standard. $NEXT() is similar to  $ORDER().  However,  $NEXT()  has  the
-   deficiency that when it encounters negative one (-1) as a subscript, it
-   returns the same result as when it finds no other data  at  the  level.
-   This deficiency is particularly disruptive because  it  occurs  in  the
-   middle of the M collating sequence.
-
-        As $NEXT() has been removed from  the  standard  in  the  MDC,  you
-        should use $ORDER.
-
-   The format for the $NEXT function is:
-
-
-   $N[EXT](glvn)
-
-   o    The subscripted global or local variable name  specifies  the  node
-        following which $NEXT() searches for the next node with data and/or
-        descendants; the number of subscripts  contained  in  the  argument
-        implicitly defines the array level.
-
-   o    If $NEXT() finds no node at the specified level after the specified
-        global or local variable, it returns negative one (-1).
-
-   o    If the last subscript in a subscripted  global  or  local  variable
-        name is null or negative one (-1), $NEXT() returns the  first  node
-        at the specified level.
-
-2 $Order()
-   $Order()
-
-   The $ORDER function returns the subscript of the next or prior local or
-   global variable name in  collation  sequence  within  the  array  level
-   specified by its first argument. In doing so, it moves in the direction
-   specified by the  second  argument.  In  GT.M,  when  $ORDER()  has  an
-   unsubscripted argument, it returns the next or  previous  unsubscripted
-   local or global variable name in collating sequence.
-
-   The format for the $ORDER function is:
-
-
-   $O[RDER](glvn[,expr])
-
-   o    The subscripted global or local variable name  specifies  the  node
-        from which $ORDER() searches for the next or previous node that has
-        data and/or descendants. The number of subscripts contained in the
-        argument implicitly defines the array level.
-
-   o    The optional expression (second argument) specifies  the  direction
-        for the $ORDER(); 1 specifies forward operation  and  -1  specifies
-        reverse operation. Any other values for the expression  will  cause
-        an error.
-
-   o    GT.M extends the M standard to allow unsubscripted names.  In  this
-        case, $ORDER() returns the next or previous unsubscripted name.
-
-   o    If $ORDER() finds no node (or name) at the  specified  level  after
-        (or before) the specified global or local variable,  it  returns  a
-        null string (" ").
-
-   o    If the last subscript in the subscripted global or  local  variable
-        name is null, $ORDER() returns the first  (or  last)  node  at  the
-        specified level.
-
-   $ORDER() provides a tool for retrieving data from M sparse arrays in an
-   ordered fashion, independent of the order in which it was  entered.  In
-   M,  routines  generally  sort  by  SETting  data  into  an  array  with
-   appropriate  subscripts  and  then  retrieving  the  information  with
-   $ORDER().
-
-   $ORDER() returns subscripts, not data values, and does not discriminate
-   between nodes that have data values and nodes  that  have  descendants.
-   Once  $ORDER()  provides  the  subscript,  the  routine  must  use  the
-   subscript to access the data  value,  if  appropriate.  Using  $ORDER()
-   maintains the naked reference indicator, even  if  $ORDER()  returns  a
-   null.
-
-   GT.M optionally permits the use of null  subscripts.  This  feature  is
-   enabled via the VIEW command for local variables and a REGION qualifier
-   in GDE for global variables. When an application uses null subscripts,
-   they are "invisible" in a $ORDER() loop so the  application  must  test
-   for them as a special case, perhaps using $DATA().
-
-3 Ex_of_$Order()
-   Examples of $ORDER()
-
-   Example:
-
-
-   GTM>K S (a(1),a(2000),a("CAT"),a("cat"),a("ALF"), a(12))=1
-
-   GTM>S x="" F S x=$O(a(x)) Q:x="" W !,x
-
-   1
-   12
-   2000
-   ALF
-
-   CAT
-
-   cat
-
-   GTM>K a("CAT") SET a(5,10)="woolworths",a("cat")="last"
-
-   GTM> S x="" F S x=$O(a(x),-1) Q:x="" W !,x
-
-   cat
-
-   ALF
-
-   2000
-   12
-   5
-   1
-   GTM>
-
-   This example uses a $ORDER() loop to display all the subscripts at the
-   first level of local variable a, make  some  changes  in  a,  and  then
-   display all the subscripts  in  reverse  order.  Notice  that  $ORDER()
-   returns only the existing subscripts in the sparse  array  and  returns
-   them in M collation sequence, regardless of the  order  in  which  they
-   were entered. Also, $ORDER() does not differentiate between node A(5),
-   which has only descendants (no data value), and the other nodes, which
-   have data values.
-
-   Example:
-
-
-   GTM>k s (%(1),tiva(2),A(3),tiv(4),Q(5),%a(6))=""
-
-   GTM>s x="%"
-
-   GTM>w:$d(@x) !,x f s x=$order(@x) q:x="" w !,x
-
-   %
-
-   %a
-
-   A
-
-   Q
-
-   tiv
-
-   tiva
-
-   x
-
-   GTM>s x="zzzzzzzz"
-
-   GTM>w:$d(@x) !,x f s x=$order(@x,-1) q:x="" w !,x
-
-   x
-
-   tiva
-
-   tiv
-
-   Q
-
-   A
-
-   %a
-
-   %
-
-   GTM>
-
-   This loop uses $ORDER() to display the current local variable names in
-   both forward and reverse order. Notice that the first ([^]%)  and  last
-   ([^]zzzzzzzz) names require handling as special  cases  and  require  a
-   $DATA() function.
-
-   Example:
-
-
-   SET acct="",cntt=""
-
-   FOR SET acct=$OREDER(^acct(acct)) QUIT:acct="" DO
-
-   . F SET cntt=$ORDER(^acct(acct,cntt)) DO WORK
-
-   QUIT
-
-   This uses two nested $ORDER() loops to cycle through the  ^acct  global
-   array and perform some action for each second level node.
-
-2 $Piece()
-   $Piece()
-
-   The $PIECE function returns a substring delimited by a specified string
-   delimiter made up of one or more characters. In M, $PIECE()  returns  a
-   logical field from a logical record.
-
-   The format for the $PIECE function is:
-
-
-   $P[IECE](expr1,expr2[,intexpr1[,intexpr2]])
-
-   o    The first expression specifies the string from which $PIECE() takes
-        its result.
-
-   o    The  second  expression  specifies  the  delimiting  string  that
-        determines the piece "boundaries";  if  this  argument  is  a  null
-        string, $PIECE() returns a null string.
-
-   o    If the second expression does not  appear  anywhere  in  the  first
-        expression, $PIECE() returns the entire  first  expression  (unless
-        forced to return a null string by the second integer expression).
-
-   o    The optional first integer expression  (third  argument)  specifies
-        the beginning  piece  to  return;  if  this  argument  is  missing,
-        $PIECE() returns the first piece.
-
-   o    The optional second integer expression (fourth argument) specifies
-        the last piece to return. If this  argument  is  missing,  $PIECE()
-        returns only one piece unless the first integer expression is zero
-        (0) or negative, in which case it returns a null  string.  If  this
-        argument is  less  than  the  first  integer  expression,  $PIECE()
-        returns a null string.
-
-   o    If the second integer  expression  exceeds  the  actual  number  of
-        pieces in  the  first  expression,  $PIECE()  returns  all  of  the
-        expression after  the  delimiter  selected  by  the  first  integer
-        expression.
-
-   o    The  $PIECE()  result  never  includes  the  "outside"  delimiters;
-        however,  when  the  second  integer  argument  specifies  multiple
-        pieces,  the  result  contains  the  "inside"  occurrences  of  the
-        delimiter.
-
-   $PIECE() provides a tool for  efficiently  using  values  that  contain
-   multiple elements or fields, each of which may be variable in length.
-
-   Applications typically use a single character for a $PIECE() delimiter
-   (second argument) to minimize storage overhead, and increase efficiency
-   at run-time. The delimiter must be chosen  so  the  data  values  never
-   contain the delimiter. Failure to enforce  this  convention  with  edit
-   checks may result in unanticipated changes in the  position  of  pieces
-   within the data value. The caret symbol (^), backward  slash  (\),  and
-   asterisk (*) characters are examples  of  popular  visible  delimiters.
-   Multiple character delimiters may reduce  the  likelihood  of  conflict
-   with field contents. However, they decrease storage efficiency, and are
-   processed with less efficiency than single character  delimiters.  Some
-   applications use control characters, which reduce the  chances  of  the
-   delimiter appearing in the data but sacrifice the readability provided
-   by visible delimiters.
-
-   A SET command argument can have something that  has  the  format  of  a
-   $PIECE() on the left-hand side of its equal sign  (=).  This  construct
-   permits easy maintenance of individual pieces within a string. It also
-   can be used to generate a string of delimiters. For more information on
-   SET $PIECE(), refer to SET in the "Commands" chapter.
-
-3 Ex_of_$Piece()
-   Examples of $PIECE()
-
-   Example:
-
-
-   GTM> FOR i=0:1:3 WRITE !,$PIECE("1 2"," ",i),"<"
-
-<
-   1<
-   2<
-<
-   GTM>
-
-   This loop displays the result of $PIECE(),  specifying  a  space  as  a
-   delimiter, a piece position "before," first and second, and "after" the
-   string.
-
-   Example:
-
-
-   GTM> FOR i=-1:1:3 WRITE !,$PIECE("1 2"," ",i,i+1),"<"
-
-<
-   1<
-   1 2<
-   2<
-<
-   GTM>
-
-   This example is similar to the previous example except that it displays
-   two pieces on each iteration. Notice the delimiter  (a  space)  in  the
-   middle of the output for  the  third  iteration,  which  displays  both
-   pieces.
-
-   Example:
-
-
-   F p=1:1:$L(x,"/") W ?p-1*10,$piece(x,"/",p)
-
-   This loop uses $LENGTH() and $PIECE() to display all the pieces of x in
-   columnar format.
-
-   Example:
-
-
-   GTM> s $P(x,".",25)="" W x
-
-   ........................
-   This SETs the 25th piece of the variable x to null, with a delimiter of
-   a period. This produces a string of 24 periods preceding the null.
-
-2 $Qlength()
-   $Qlength()
-
-   The $QLENGTH function returns the number of subscripts  in  a  variable
-   name. The format is:
-
-
-   $QL[ENGTH] (namevalue)
-
-   o    The  namevalue  has  the  form  of  an  evaluated  subscripted  or
-        unsubscripted global variable (which yields a length of  zero,  and
-        which may have an environment -  not  counted)  or  local  variable
-        name.
-
-   o    The form returns a  value  which  is  derived  from  namevalue.  If
-        namevalue has the form NAME(s1, s2,..., sn), considering  n  to  be
-        zero, if there are no subscripts, then the function returns n.
-
-   o    This function only affects the naked indicator  if  the  string  in
-        question is stored in a global variable.
-
-3 Ex_of_$Qlength()
-   Examples of $Qlength()
-
-   Example:
-
-
-   WRITE $DATA(^|"XXX"|ABC(1,2,3,4))
-
-
-   GTM>0
-
-
-   SET X=$NAME(^(5,6))
-
-   WRITE $QLENGTH(X)
-
-   GTM>5
-
-   Refer to $NAme() section earlier in this chapter for  an  understanding
-   of the $NAME function.
-
-2 $Qsubscript()
-   $Qsubscript()
-
-   The $QSUBSCRIPT function returns a component of a variable name.
-
-   The format of the $QSUBSCRIPT function is:
-
-
-   $QS[UBSCRIPT](namevalue, intexpr)
-
-   o    The  namevalue  has  the  form  of  an  evaluated  subscripted  or
-        unsubscripted global or local variable name.
-
-   o    The intexpr selects the component of the name as follows:
-
-   -2 is reserved but may be "error",
-
-   -1 for environment,
-
-   0 for the unsubscripted name,
-   1 for the first subscript,
-   2 for the second subscript, and so on.
-   If the second argument selects a component that  is  not  part  of  the
-   specified name, $QSUBSCRIPT() returns an empty string ("").
-
-3 Ex_of_$Qsubscript()
-   Examples of $Qsubscript()
-
-   Example:
-
-   Assume that X is defined as in the "Examples of $Qlength()" earlier in
-   this chapter;
-
-
-   $QLENGTH (X="^|""XXX""|ABC(1,2,3,5,6)")
-
-
-   WRITE $QSUBSCRIPT(X,-2)
-
-   GTM>error
-
-
-   WRITE $QSUBSCRIPT(X,-1)
-
-   GTM>XXX
-
-
-   WRITE $QSUBSCRIPT(X,0)
-
-   GTM>^ABC
-
-
-   WRITE $QSUBSCRIPT(X,1)
-
-   GTM>1
-
-
-   WRITE $QSUBSCRIPT(X,4)
-
-   GTM>5
-
-
-   WRITE $QSUBSCRIPT(X,7)
-
-   GTM>""
-
-2 $Query()
-   $Query()
-
-   The $QUERY function  returns  the  next  subscripted  local  or  global
-   variable node name,  independent  of  level,  which  follows  the  node
-   specified by its argument in M collating sequence and has a data value.
-
-   The format for the $QUERY function is:
-
-
-   $Q[UERY](glvn)
-
-   o    The subscripted or unsubscripted  global  or  local  variable  name
-        specifies the starting node from which $QUERY() searches for a node
-        with a data value.
-
-   o    If $QUERY() finds no node  after  the  specified  global  or  local
-        variable, it returns a null string.
-
-   $QUERY() provides a tool for scanning an entire array  for  nodes  that
-   have data values. Because $QUERY() can return  a  result  specifying  a
-   different level than its argument, the result provides a full variable
-   name. This contrasts with $ORDER(), which returns a subscript value. To
-   access the data value at a node, a $ORDER() return can  be  used  as  a
-   subscript; however, a $QUERY() return must be  used  with  indirection.
-   Because arrays tend to have homogeneous values within a level  but  not
-   between levels, $QUERY() is more useful as a tool in  utility  programs
-   than in application programs. The $QUERY() is useful in avoiding nested
-   $ORDER loops.
-
-   Note that the standard does not unambiguously define the state  of  the
-   naked reference  indicator  after  a  $QUERY().  While  in  GT.M  after
-   $QUERY(), the naked reference indicator reflects the $QUERY() argument,
-   NOT its result.
-
-3 Ex_of_$Query()
-   Examples of $QUERY()
-
-   Example:
-
-
-   SET ^X(1,2,3)="123"
-
-   SET ^X(1,2,3,7)="1237"
-
-   SET ^X(1,2,4)="124"
-
-   SET ^X(1,2,5,9)="1259"
-
-   SET ^X(1,6)="16"
-
-   SET ^X("B",1)="AB"
-
-   The following routine:
-
-
-   SET y="^X"
-
-   FOR SET y=$QUERY(@y) QUIT:y="" WRITE !,y,"=", at y
-
-   produces the results:
-
-
-   ^X(1,2,3)=123
-
-   ^X(1,2,3,7)=1237
-
-   ^X(1,2,4)=124
-
-   ^X(1,2,5,9)=1259
-
-   ^X(1,6)=16
-
-   ^X("B",1)=AB
-
-2 $Random()
-   $Random()
-
-   The $RANDOM function returns a random integer from a range specified by
-   its argument.
-
-   The format for the $RANDOM function is:
-
-
-   $R[ANDOM](intexpr)
-
-   o    The integer expression specifies the upper  exclusive  limit  of  a
-        range of integers from which $RANDOM() may pick a result; $RANDOM()
-        never returns a number less than zero (0).
-
-   o    If $RANDOM() has an argument less than  one  (1),  it  generates  a
-        run-time error.
-
-   o    $RANDOM can generate numbers up to 2147483646 (that is 2GB - 2).
-
-   $RANDOM() provides a tool for generating pseudo-random patterns useful
-   in testing or statistical calculations. $RANDOM() results fall between
-   zero (0) and one less than the argument.
-
-   Random number generators use factors from  the  environment  to  create
-   sequences of numbers. True random number generation requires  a  source
-   of what is known as noise. Pseudo-random  numbers  appear  to  have  no
-   pattern, but are developed using interactions between factors that vary
-   in ways not guaranteed to be entirely random. In accordance with the M
-   standard, the GT.M implementation of $RANDOM()  produces  pseudo-random
-   numbers.
-
-3 Ex_of_$Random()
-   Examples of $RANDOM()
-
-   Example:
-
-
-   GTM> FOR i=1:1:10 WRITE $RANDOM(1)
-
-   0000000000
+   GTM>WRITE '0
+   1
+   GTM>WRITE '1
+   0
+   GTM>WRITE '5689
+   0
+   GTM>WRITE '-1
+   0
+   GTM>WRITE '"ABC"
+   1
    GTM>
 
-   This shows that when $RANDOM() has an argument of one (1),  the  result
-   is too confined to be random.
+   The above example demonstrates the unary NOT operation. Note that any
+   non-zero numeric value is true and has a false negation.
 
    Example:
 
+   GTM>WRITE 0&0
+   0
+   GTM>WRITE 1&0
+   0
+   GTM>WRITE 0&1
+   0
+   GTM>WRITE 1&1
+   1
+   GTM>WRITE 2&1
+   1
+   GTM>WRITE 0!0
+   0
+   GTM>WRITE 1!0
+   1
+   GTM>WRITE 0!1
+   1
+   GTM>WRITE 1!1
+   1
+   GTM>WRITE 2!1
+   1
+   GTM>
 
-   SET x=$RANDOM(100)+1*.01
-
-   This $RANDOM() example produces a number between 0 and 99. The example
-   then shifts with addition, and scales with multiplication to  create  a
-   value between .01 and 1.
-
-2 $Reverse()
-   $Reverse()
-
-   The $REVERSE function returns a  string  with  the  characters  in  the
-   reverse order from that of its argument.
-
-   The format for the $REVERSE function is:
-
+   The above example demonstrates all cases covered by the binary logical
+   operators.
 
-   $RE[VERSE](expr)
+3 String_Operators
+   String Operators
 
-   o    The expr in the syntax is the string to be reversed.
+   All string operators force M to evaluate the expressions to which they
+   apply as strings. The string operator is:
 
-3 Ex_of_$Reverse()
-   Examples of $REVERSE()
+   _binary operator causes M to concatenate the second expression with the
+   first expresion
 
    Example:
 
+   GTM>WRITE "B"_"A"
+   BA
+   GTM>WRITE "A"_1
+   A1
+   GTM>
 
-   WRITE $REVERSE(123)
-
-   GTM>321
-
-
-   WRITE $REVERSE("AbCDe")
-
-   GTM>"eDCbA"
-
-2 $Select()
-   $Select()
+   The above example demonstrates M concatenation.
 
-   The $SELECT function returns a value associated  with  the  first  true
-   truth-valued expression in a list of paired expression arguments.
+3 Numeric_Relational_Operators
+   Numeric Relational Operators
 
-   The format for the $SELECT function is:
+   M relational operators always generate a result of TRUE (1) or FALSE (0).
+   All numeric relational operators force M to evaluate the expressions to
+   which they apply as numeric. The numeric relational operators are:
 
+   >binary arithmetic greater than
 
-   $S[ELECT](tvexpr:expr[,...])
+   <binary arithmetic less than
 
-   o    $SELECT() evaluates expressions from left to right.
+   The equal sign (=) does not force numeric evaluation, and should be viewed
+   as a string operator. However, the equal sign between two numeric values
+   tests for numeric equality.
 
-   o    If a truth-valued expression is TRUE  (1),  $SELECT()  returns  the
-        corresponding expression after the colon (:) delimiter.
+   Other numeric relations are formed using the logical NOT operator
+   apostrophe (') as follows:
 
-   o    Once $SELECT() finds a TRUE, the  function  does  not  process  any
-        remaining arguments.
+   '> not greater than, that is, less than or equal to
 
-   o    If $SELECT() finds no TRUE truth-value in its  list  of  arguments,
-        the function generates a run-time error.
+   '< not less than, that is, greater than or equal to
 
-   $SELECT() is  one  of  a  limited  set  of  functions  that  permit  an
-   indefinite number of arguments. $SELECT() provides a means of selecting
-   from a list of alternatives.
+   >= greater than or equal to, that is, not less than
 
-   Generally, the last $SELECT() argument has numeric literal one (1) for
-   a truth-value to prevent run-time errors, and to  provide  a  "default"
-   value.
+   <= less than or equal to, that is, not greater than
 
-3 Ex_of_$Select()
-   Examples of $SELECT()
+   '= not equal, numeric or string operation
 
    Example:
 
-
-   GTM> F i=3:-1:0 W !,$S(i=1:"here",i=2:"come",i=3: "Watson")
-
-   Watson
-
-   come
-
-   here
-
-   %GTM-E-SELECTFALSE, No argument to $SELECT was true
-
+   GTM>WRITE 1>2
+   0
+   GTM>WRITE 1<2
+   1
    GTM>
 
-   This loop uses $SELECT() to WRITE a series of strings. Because there is
-   no true argument on the fourth iteration, when i=0, $SELECT() produces
-   an error.
-
-   Example:
-
-
-   SET name=$S(sex="M":"Mr. ",sex="F":"Ms. ",1:"")_name
-
-   This example uses $SELECT() to add a prefix to the name based on a sex
-   code held in the variable sex. Notice that the default handles the case
-   of a missing or incorrect code.
+   The above example demonstrates the basic arithmetic relational operations.
 
    Example:
 
+   GTM>WRITE 1'<2
+   0
+   GTM>WRITE 2'<1
+   1
+   GTM>
 
-   IF $S(x=+x:x,x="":0,"JANAPRJULOCT"[x:1,1:0) D THING
-
-   This uses $SELECT()  to  perform  complex  logic  as  the  truth-valued
-   expression argument to an IF command.
-
-2 $Stack()
-   $Stack()
-
-   The $STACK function returns strings describing aspects of the execution
-   environment.
+   The above example demonstrates combinations of arithmetic, relational
+   operators with the logical NOT operator.
 
-   The format for the $STACK function is:
+3 String_Relational_Operators
+   String Relational Operators
 
+   M relational operators always generate a result of TRUE (1) or FALSE (0).
+   All string relational operators force M to evaluate the expressions to
+   which they apply as strings. The string relational operators are:
 
-   $ST[ACK](intexpr[,expr])
+   = binary operator causes M to produce a TRUE if the expressions are equal.
 
-   o    The intexpr identifies  the  M  virtual  machine  stack  level  (as
-        described by the standard), on which the  function  is  to  provide
-        information.
+   [ binary operator causes M to produce a TRUE if the first expression
+   contains the ordered sequence of characters in the second expression.
 
-   o    The optional  second  argument  is  evaluated  as  a  keyword  that
-        specifies a type of information to be returned as follows: "PLACE"
-        for position in the code (for which,  GT.M.  due  to  its  compiled
-        nature, has  no  information),  "MCODE"  for  the  source  code  if
-        available, or "ECODE" for the  $ECODE  value  associated  with  the
-        stack level.
+   ] binary operator causes M to produce a TRUE if the first expression
+   lexically follows the second expression in the character encoding
+   sequence, which by default is ASCII.
 
-   o    When  $STACK  has  only  one  argument,  values  corresponding  to
-        available stack levels specify a return value  that  indicates  how
-        the level was created, as follows:
+   ]] binary operator causes M to produce a TRUE if the first expression
+   lexically sorts after the second expression in the subscript collation
+   sequence.
 
-   o    If intexpr is zero (0), the function  returns  information  on  how
-        GT.M was invoked.
+   Note that all non-empty strings lexically follow the empty string, and
+   every string contains the empty string.
 
-   o    If intexpr is minus one (-1),  the  function  returns  the  highest
-        level for which  $STACK  can  return  information.  Note  that,  if
-        $ECODE="", $STACK(-1) returns the same value as $STACK.
+   Other string relations are formed using the logical NOT operator
+   apostrophe (') as follows:
 
-   o    If intexpr is greater than zero (0)  and  less  than  or  equal  to
-        $STACK (-1), indicates how this level of process stack was created
-        ("DO", "XECUTE", or "$$". "$$" being for an extrinsic function).
+   '[ does not contain.
 
-   o    If intexpr is greater than $STACK (-1),  the  function  returns  an
-        empty string.
+   '] does not follow, that is, lexically less than or equal to.
 
-   o    For any integer value of "level" between 0 and max (inclusive), the
-        function $STACK(level, type) provides the following information:
+   ']] does not sort after, that is, lexically less than or equal to in the
+   subscript collation sequence.
 
-        Type Information
-        "MCODE" the line of code that was executed
-        "PLACE" the address of the above line of  code  or  the  symbol  at
-        ("@") to indicate code executed from a string value
-        "ECODE" either an empty string, or the error code(s) that was added
-        at this execution level.
-3 Ex_of_$Stack()
-   Examples of $STACK()
+   '= not equal, numeric or string operation.
 
    Example:
 
-
-   WRITE !,$STACK
-
-   XECUTE "WRITE !,$STACK"
-
-   DO Label
-
-   WRITE !,$$ELabel
-
-   WRITE !,$STACK
-
-   QUIT
-
-
-   Label
-
-   WRITE !,$STACK
-
-   DO DLabel
-
-   QUIT
-
-
-   ELabel()
-
-   QUIT $STACK
-
-
-   DLabel
-
-   WRITE !,$STACK
-
-   QUIT
-
-   The above example when executed displays the current M stack level. The
-   result of the execution is:
-
-
-   GTM>0
-
+   GTM>WRITE "A"="B"
+   0
+   GTM>WRITE "C"="C"
    1
+   GTM>WRITE "A"["B"
+   0
+   GTM>WRITE "ABC"["C"
    1
-   2
+   GTM>WRITE "A"]"B"
+   0
+   GTM>WRITE "B"]"A"
    1
+   GTM>WRITE "A"]]"B"
    0
-   Example for error processing:
-
-
-   For i=$STACK(-1):-1:1 DO
-
-   . WRITE !,$STACK(i,"PLACE"),":"
-   . WRITE $STACK(i,"MCODE")
-   . QUIT
-   The above example can be used to display a trace of the code path that
-   led to an error.
-
-2 $Text()
-   $Text()
-
-   The $TEXT function returns source text for the line  specified  by  its
-   argument.
-
-   The format for the $TEXT function is:
-
-
-   $T[EXT](entryref)
-
-   o    The entryref specifies the label, offset, and routine of the source
-        line that $TEXT() returns.
-
-   o    If the label+offset combination do not  fall  within  the  routine,
-        $TEXT returns a null string.
-
-   o    If the entryref explicitly or implicitly  specifies  an  offset  of
-        zero (0) from the beginning of the  routine,  $TEXT()  returns  the
-        routine name.
-
-   o    If the entryref does  not  specify  a  routine,  GT.M  assumes  the
-        current routine, that is, the routine at the top of a ZSHOW "S."
-
-   o    A GT.M extension to  $TEXT()  permits  negative  offsets;  however,
-        every offset must still be preceded by a plus sign  (+)  delimiter,
-        (for example, LABEL+-3). If a negative  offset  points  to  a  line
-        prior to the zero line, $TEXT() generates a run-time error.
-
-   $TEXT() provides a tool for examining routine source code and the name
-   of the current routine. $TEXT() assists, along with the ZPRINT command,
-   in debugging programs. $TEXT()  also  allows  the  insertion  of  small
-   tables of driver information into a routine.  Because  $TEXT()  is  not
-   very efficient and the table-driven technique is generally best suited
-   to minimal program changes, this approach is best used for prototyping
-   and the tables should reside in global variables for production.
-
-   If $TEXT() cannot access the source file for the current object, either
-   because it is not in the location from which it was compiled or because
-   the process does not have access to some  piece  of  the  path  to  the
-   source, or if the located source does not match the object currently in
-   use by the process, $TEXT() returns the empty string.
-
-3 Ex_of_$Text()
-   Examples of $TEXT()
-
-   Example:
-
-
-   F i=1:1 S x=$T(+i) Q:x="" W !,x
-
-   This loop uses $TEXT() to write out the entire source for  the  current
-   routine.
-
-   Example:
-
-
-   GTM> WRITE $TEXT(+0)
-
-   GTM$DMOD
-
-   GTM> WRITE $TEXT(+1)
-
-   GTM>
-
-   This uses $TEXT() to WRITE the name of the  current  routine,  then  it
-   tries to access the source and returns an  empty  string.  This  occurs
-   because the default Direct  Mode  image  is  compiled  by  Sanchez  and
-   delivered without source. The exact failure message may vary.
-
-2 $TRanslate()
-   $TRanslate()
-
-   The $TRANSLATE function returns a string that results from replacing or
-   dropping characters in the first of its arguments as specified  by  the
-   patterns of its other arguments.
-
-   The format for the $TRANSLATE function is:
-
-
-   $TR[ANSLATE](expr1[,expr2[,expr3]])
-
-   o    The first expression specifies the  string  on  which  $TRANSLATE()
-        operates. If the other arguments are omitted, $TRANSLATE() returns
-        this expression.
-
-   o    The  optional  second  expression  specifies  the  characters  for
-        $TRANSLATE() to replace. If a character occurs more  than  once  in
-        the  second  expression,  the  first  occurrence  controls  the
-        translation, and $TRANSLATE() ignores  subsequent  occurrences.  If
-        this argument is omitted, $TRANSLATE() returns the first expression
-        without modification.
-
-   o    The optional third expression specifies the replacement characters
-        for the second expression that corresponds  by  position.  If  this
-        argument  is  omitted  or  shorter  than  the  second  expression,
-        $TRANSLATE() drops all occurrences  of  characters  in  the  second
-        expression that have no replacement in the  corresponding  position
-        of the third expression.
-
-   $TRANSLATE() provides a tool for tasks such as changing case and doing
-   encryption. For examples of case translation, refer to the ^%LCASE and
-   ^%UCASE utility routines.
-
-   The $TRANSLATE() algorithm can be understood as follows:
-
-   o    $TRANSLATE() evaluates each  character  in  the  first  expression,
-        comparing it  character  by  character  to  the  second  expression
-        looking for a match. If there is no match in the second expression,
-        the  resulting  expression  contains  the  character  without
-        modification.
-
-   o    When it locates a character match, $TRANSLATE() uses  the  position
-        of the match in the second expression to identify  the  appropriate
-        replacement for the original expression. If the  second  expression
-        has  more  characters  than  the  third  expression,  $TRANSLATE()
-        replaces the original character with a null,  thereby  deleting  it
-        from the result. By extension  of  this  principle,  if  the  third
-        expression is missing, $TRANSLATE() deletes all characters from the
-        first expression that occur in the second expression.
+   GTM>WRITE "B"]]"A"
+   1
 
-3 Ex_of_$TRanslate()
-   Examples of $TRANSLATE()
+   These examples demonstrate the string relational operators using string
+   literals.
 
    Example:
 
+   GTM>WRITE 2]10
+   1
+   GTM>WRITE 2]]10
+   0
+   GTM>WRITE 0]"$"
+   1
+   GTM>WRITE 0]]"$"
+   0
 
-   GTM> WRITE $TR("ABC","CB","1")
-
-   A1
-
-   GTM>
-
-   o    First, $TRANSLATE() searches for "A" (the first  character  in  the
-        first expression, "ABC") within the second expression ("CB"). Since
-        "A" does not exist in the second expression, it  appears  unchanged
-        in the result.
-
-   o    Next, $TRANSLATE() searches for "B" (the second  character  in  the
-        first expression) within the second expression ("CB"). Because "B"
-        holds  the  second  position  in  the  second  expression  ("CB"),
-        $TRANSLATE() searches for the character holding the second position
-        in the third expression. Since there is no second character in the
-        third  expression,  $TRANSLATE()  replaces  "B"  with  a  null,
-        effectively deleting it from the result.
-
-   o    Finally, $TRANSLATE() searches for "C" (the third character in the
-        first expression) within the second expression ("CB"), finds it in
-        the first position, and replaces it with the number 1, which is in
-        the first position of the third expression. The  translated  result
-        is "A1."
+   These examples illustrate that when using the primary ASCII character set,
+   the main difference in the "follows" (]) operator and the "sorts-after"
+   (]]) operator is the way they treat numbers.
 
    Example:
 
-
-   GTM> WRITE $TR("A","AA","BC")
-
-   B
-
+   GTM>WRITE 1=1
+   1
+   GTM>WRITE 1=2
+   0
+   GTM>WRITE 1="1"
+   1
+   GTM>WRITE 1=01
+   1
+   GTM>WRITE 1="01"
+   0
+   GTM>WRITE 1=+"01"
+   1
    GTM>
 
-   This $TRANSLATE() example finds the first  occurrence  of  "A"  in  the
-   second expression,  which  holds  the  first  character  position,  and
-   substitutes  the  character  in  the  first  position  of  the  third
-   expression.
+   These examples illustrate the dual nature of the equal sign operator. If
+   both expressions are string or numeric, the results are straight forward.
+   However, when the expressions are mixed, the native string data type
+   prevails.
 
    Example:
 
+   GTM>WRITE "a"'="A"
+   1
+   GTM>WRITE "FRED"'["RED"
+   0
+   GTM>WRITE "ABC"']""
+   0
 
-   GTM> WRITE $TR("BACKUP","AEIOU")
-
-   BCKP
+   These examples demonstrate combinations of the string relational operators
+   with the NOT operator.
 
-   GTM>
+3 Pattern_Match_Operator
+   Pattern Match Operator
 
-   Because the $TRANSLATE() has only two parameters in  this  example,  it
-   finds the characters in the first expression that  also  exist  in  the
-   second expression and deletes them from the result.
+   The pattern match operator (?) causes M to return a TRUE if the expression
+   ahead of the operator matches the characteristics described by the pattern
+   following the operator. The pattern is not an expression.
 
-2 $View()
-   $View()
+   Patterns are made up of two elements:
 
-   The $VIEW function returns information about  an  environmental  factor
-   selected by the arguments. In  GT.M,  the  first  argument  contains  a
-   keyword identifying the environmental factor  and,  where  appropriate,
-   subsequent arguments select among multiple possible occurrences of that
-   factor.
+    1. A repetition count
+    2. A pattern code, a string literal or an alternation list
 
-   The format for the $VIEW() function is:
+   The element following the pattern match operator may consist of an
+   indirection operator, followed by an element that evaluates to a
+   legitimate pattern.
 
+   The repetition count consists of either a single integer literal or a
+   period (.) delimiter with optional leading and trailing integer literals.
+   A single integer literal specifies an exact repetition count. The period
+   syntax specifies a range of repetitions where the leading number is a
+   minimum and the trailing number is a maximum. When the repetition count is
+   missing the leading number, M assumes there is no minimum, (i.e., a
+   minimum of zero). When the repetition count is missing the trailing
+   number, M does not place a maximum on the number of repetitions.
 
-   $V[IEW](expr1[,expr2])
+   The pattern codes are:
 
-   o    The first expression specifies a  keyword  identifying  the  target
-        factor for $VIEW() to examine.
+   A alphabetic characters upper or lower case
 
-   o    The second  expression  differentiates  between  multiple  possible
-        targets for some keywords. $VIEW() requires the  second  expression
-        for some keywords and does not permit it for others.
+   C control characters ASCII 0-31 and 127
 
-   The $VIEW function returns 1 (true) if the region is frozen by MUPIP or
-   DSE and returns 0 (false) otherwise.
+   E any character; used to pass all characters in portions of the string
+   where the pattern is not restricted
 
-3 Arg_Key_of_$View()
-   Argument Keywords of $VIEW()
+   L lower-case alphabetic characters, ASCII 97-122
 
-   $VIEW() provides a means of accessing GT.M  environmental  information.
-   $VIEW() is similar in purpose to Intrinsic Special Variables. When GT.M
-   permits modification of the factors accessible with $VIEW(),  the  VIEW
-   command generally provides the tool for performing the change.
+   N digits 0-9, ASCII 48-57
 
-3 Ex_of_$View()
-   Examples of $VIEW()
+   P punctuation, ASCII 32-47, 58-64, 91-96, 123-126
 
-   Example:
+   U upper-case alphabetic characters, ASCII 65-90
 
+   Pattern codes may be upper or lower case and may be replaced with a string
+   literal. GT.M allows the M pattern match definition of patcodes A, C, N,
+   U, L, and P to be extended or changed, (A can only be modified implicitly
+   by modifying L or U) and new patcodes added. For detailed information on
+   enabling this functionality, refer to the "Internationalization" chapter
+   in the GT.M Programmer's Guide.
 
-   S len=$L(name)
+   **Note**
 
-   S be4=$EXTRACT(name,1,len-1)_$CHAR($ASCII(name,len)-1)
+   The GT.M compiler accepts pattern codes other than those explicitly
+   defined above. If, at run-time, the pattern codes come into use and no
+   pattern definitions are available, GT.M issues a run-time error
+   (PATNOTFOUND). GT.M does not currently implement a mechanism for Y and Z
+   patterns and continues to treat those as compile-time syntax errors.
 
-   I $V("RTNNEXT",be4_$E("ZZZZZZZ",1,8-len))=name D
+   Example:
 
-   . ZLINK name
-   Given a routine name this uses $VIEW() to determine whether  the  image
-   contains the routine. If the routine already exists the ZLINK replaces
-   it. Otherwise, auto-ZLINK will bring in a new copy.
+   GTM>WRITE "ABC"?3U
+   1
+   GTM>WRITE "123-45-6789"?3N1"-"2N1"-"4N
+   1
 
-2 $ZBIT_Func
-   $ZBIT Functions
+   The first WRITE has a simple one-element pattern while the second has
+   multiple elements including both codes and string literals. All the
+   repetition counts are fixed.
 
-   A series of functions beginning with $ZBIT  let  you  manipulate  bits.
-   Each function is described in its own section, and an  example  at  the
-   end of the last section illustrates the use of several of the functions
-   in context.
+   Example:
 
-3 $ZBITAND()
-   $ZBITAND()
+   I x?.E1C.E W !,"Must not contain a control character" Q
 
-   The $ZBITAND function performs an AND function on two bit  strings  and
-   returns a bit string  equal  in  length  to  the  shorter  of  the  two
-   arguments (containing set bits in those positions  where  both  of  the
-   input strings have set  bits).  Positions  corresponding  to  positions
-   where either of the input strings have a cleared bit, also have cleared
-   bits in the resulting string.
+   This example uses a pattern match to test for control characters.
 
-   The format for the $ZBITAND() function is:
+   Example:
 
+   I acn?1U.20A1","1U.10A D
+   .S acn=$G((^ACX($P(acn,","),$P(acn,",",2)))
 
-   $ZBITAND(expr1,expr2)
+   This example uses a pattern match with implicit minimums to determine that
+   an "account number" is actually a name, and to trigger a look-up of the
+   corresponding account number in the ^ACX cross index.
 
-   o    The first expression specifies one of the bit strings that is input
-        to the AND operation.
+   The pattern match operator accepts the alteration syntax. Alteration
+   consists of a repeat count followed by a comma-delimited list of patatoms
+   enclosed in parentheses "()". The semantic is that the pattern matches if
+   any of the listed patterns matches the operand string. For example,
+   ?1(2N1"-"7N,3N1"-"2N1"-"4N).1U might be a way to match either a social
+   security number or a taxpayer ID. Since alternation is defined as one of
+   the ways of constructing a patatom, alternation can nest (be used
+   recursively).
 
-   o    The second expression specifies the other bit string that is input
-        to the AND operation.
+   **Note**
 
-3 $ZBITCOUNT()
-   $ZBITCOUNT()
+   Complex pattern matches may not be efficient to evaluate, so every effort
+   should be made to simplify any commonly used pattern and to determine if
+   more efficient alternative logic would be more appropriate.
 
-   The $ZBITCOUNT function returns the number of ON bits in a bit string.
+2 Commands
+   Commands
 
-   The format for the $ZBITCOUNT function is:
+   M commands may be abbreviated to a defined prefix. Most commands have
+   arguments. However, some commands have either optional arguments or no
+   arguments. When a command has no argument and is followed by more commands
+   on the same line, at least two spaces (<SP>) must follow the command
+   without arguments. Commands that accept arguments generally accept
+   multiple arguments on the same command. M treats multiple arguments the
+   same as multiple occurrences of the same command, each with its own
+   argument.
 
+3 Postconditionals
+   Postconditionals
 
-   $ZBITCOUNT(expr)
+   M provides postconditionals as a tool for placing a condition on the
+   execution of a single command and, in some cases, a single command
+   argument. A postconditional consists of a colon (:) delimiter followed by
+   a truth-valued expression. When the expression evaluates to true, M
+   executes the command occurrence. When the expression evaluates to false, M
+   does not execute the command occurrence.
 
-   o    The expression specifies the bit string to examine.
+4 Command_Postconditionals
+   Command Postconditionals
 
-3 $ZBITFIND()
-   $ZBITFIND()
+   Command postconditionals appear immediately following a command and apply
+   to all arguments for the command when it has multiple arguments. All
+   commands except commands that themselves have a conditional aspect accept
+   a command postconditional. Among the M standard commands, ELSE, FOR, and
+   IF do not accept command postconditionals. All the GT.M command extensions
+   accept command postconditionals.
 
-   The $ZBITFIND function performs the analog of the $FIND function  on  a
-   bit string. It returns an integer that identifies  the  position  after
-   the first position equal to a truth-valued expression that  occurs  at,
-   or after, the specified starting position.
+4 Argument_Postconditionals
+   Argument Postconditionals
 
-   The format for the $ZBITFIND function is:
+   Commands that affect the flow of control may accept postconditionals on
+   individual command arguments. Because multiple arguments act as multiple
+   commands, this is a straight-forward application of the same principal as
+   command postconditional. The only M standard commands that accept argument
+   postconditionals are DO, GOTO, and XECUTE. The GT.M command extensions
+   that accept argument postconditionals are BREAK, ZGOTO, and ZSYSTEM.
 
+3 Timeouts
+   Timeouts
 
-   $ZBITFIND(expr,tvexpr[,intexpr])
+   M provides timeouts as a tool to retain program control over commands of
+   indefinite duration. A timeout consists of a colon (:) delimiter on an
+   argument, followed by a numeric expression specifying the number of
+   seconds for M to attempt to execute the command. When the timeout is zero
+   (0), M makes a single attempt to complete the command.
 
-   o    The expression specifies the bit string to examine.
+   GT.M has been designed to allow large timeout values, and to protect
+   against arithmetic overflow when converting large timeout values to
+   internal representations. When a command has a timeout, M maintains the
+   $TEST intrinsic special variable as the command completes. If the command
+   completes successfully, M sets $TEST to TRUE (1). If the command times out
+   before successful completion, M sets $TEST to FALSE (0). When a command
+   argument does not specify a timeout, M does not maintain $TEST.
+
+   When a READ times out, M returns any characters that have arrived between
+   the start of the command and the timeout. M does not produce any partial
+   results for any of the other timed commands.
+
+2 M_Locks
+   M Locks
+
+   The LOCK command reserves one or more resource names. Only one process at
+   a time can reserve a resource name. Resource names follow exactly the same
+   formation rules as M variables. They may be unsubscripted or subscripted
+   and may or may not have a leading caret (^) prefix. M code commonly uses
+   LOCKs as flags that control access to global data. Generally, a LOCK
+   specifies the resource with the same name as the global variable that
+   requires protected access. However, this is only a convention. LOCKing
+   does not keep two or more processes from modifying the same global
+   variable. It only keeps another process from LOCKing the same resource
+   name at the same time.
+
+   M LOCKs are hierarchical. If one process holds a LOCK on a resource, no
+   other process can LOCK either an ancestor or a descendant resource. For
+   example, a LOCK on ^A(1,2) blocks LOCKs on either ^A(1), or ^A(1,2,3), but
+   not on, for example, ^A(2) or its descendants.
+
+   A LOCK argument may contain any subscripted or unsubscripted M variable
+   name including a name without a preceding caret symbol (^). As they have
+   the appearance of local variable names, resource names with no preceding
+   caret symbol (^) are commonly referred to as "local LOCKs" even though
+   these LOCKs interact with other processes.
+
+2 Intrinsic_Functions
+   Intrinsic Functions
+
+   M Intrinsic Functions start with a single dollar sign ($) and have one or
+   more arguments enclosed in parentheses () and separated by commas (,).
+   These functions provide an expression result by performing actions that
+   would be impossible or difficult to perform using M commands. It is now
+   possible to invoke a C function in a package via the external call
+   mechanism.
 
-   o    The truth-valued expression  specifies  the  bit  value  for  which
-        $ZBITFIND() searches (1 or 0).
+2 Intrinsic_Special_Variables
+   Intrinsic Special Variables
 
-   o    The optional integer argument specifies the  starting  position  at
-        which to begin the search. If this argument is missing, $ZBITFIND()
-        begins searching  at  the  first  position  of  the  string.  $ZBIT
-        functions count the first bit as position one (1).
+   M Intrinsic Special Variables start with a single dollar sign ($). GT.M
+   provides such variables for program examination. In some cases, the
+   Intrinsic Special Variables may be SET to modify the corresponding part of
+   the environment.
 
-   If the optional integer argument exceeds the length of the  string,  or
-   if the function finds no  further  bits,  $ZBITFIND()  returns  a  zero
-   value.
+2 Routines
+   Routines
 
-3 $ZBITGET()
-   $ZBITGET()
+   M routines have a name and consist of lines of code followed by an
+   end-of-record which is a carriage return, formfeed (<CR><FF>) sequence. M
+   separates the name of a routine from the body of the routine with an
+   end-of-line which is a carriage-return, line-feed (<CR><LF>) sequence.
 
-   The $ZBITGET function returns the value of a specified position in the
-   bit string.
+   GT.M stores routine sources in RMS UNIX files and implicitly supplies the
+   end-of-record and end-of-line character sequences.
 
-   The format for the $ZBITGET function is:
+   In M, a routine has no particular impact on variable management and may
+   include code that is invoked at different times and has no logical
+   intersection.
 
+3 Lines
+   Lines
 
-   $ZBITGET(expr,intexpr)
+   A line of M code consists of the following elements in the following
+   order:
 
-   o    The expression specifies the bit string to examine.
+     * An optional label.
+     * A line-start delimiter. The standard defines the line-start delimiter
+       as a space (<SP>) character. In order to enhance routine readability,
+       GT.M extends M by accepting one or more tab (<HT>) characters as
+       line-start delimiters.
+     * Zero or more level indicators, which are periods (.). The level
+       indicators show the level of nesting for argumentless DO commands: the
+       more periods, the deeper the nesting. M ignores lines that contain
+       level indicators unless they directly follow an argumentless DO
+       command with a matching level of nesting.
+     * Zero or more commands and their arguments. M accepts multiple commands
+       on a line. The argument(s) of one command are separated from the next
+       command by a command-start delimiter, consisting of one or more spaces
+       (<SP>).
+     * A terminating end-of-line, which is a carriage return, line feed
+       (<CR><LF>) sequence.
 
-   o    The integer argument specifies the position in the string for which
-        the value is requested. If the integer argument is negative, zero,
-        or exceeds the length of the bit string,  it  is  rejected  with  a
-        run-time error. $ZBIT functions count the first bit as position one
-        (1).
+4 Labels
+   Labels
 
-3 $ZBITLEN()
-   $ZBITLEN()
+   In addition to labels that follow the rules for M names, M accepts labels
+   consisting only of digits. In a label consisting only of digits, leading
+   zeros are considered significant. For example, labels 1 and 01 are
+   different. Formalists may immediately follow a label. A Formalists
+   consists of one or more names enclosed in parentheses (). Formalists
+   identify local variables that "receive" passed values in M parameter
+   passing. For more information, see "Parameter Passing".
 
-   The $ZBITLEN function returns the length of a bit string, in bits.
+   In GT.M, a colon (:) delimiter may be appended to the label, which causes
+   the label to be treated as "local." Within the routine in which they
+   appear, they perform exactly as they would without the trailing colon but
+   they are inaccessible to other routines. Using local labels reduces object
+   size and linking overhead, for both ZLINK and host linking.
 
-   The format for the $ZBITLEN function is:
+4 Comments
+   Comments
 
+   In addition to commands, a line may also contain a comment that starts
+   with a leading semi-colon (;) delimiter. The scope of a comment is the
+   remainder of the line. In other words, M ignores anything to the right of
+   the comment delimiter. The standard defines the comment delimiter (;) as
+   it would a command, and therefore requires that it always appear after a
+   linestart. GT.M extends the standard to permit comments to start at the
+   first character of a line or in an argument position.
 
-   $ZBITLEN(expr)
+3 Entry_References
+   Entry References
 
-   o    The expression specifies the bit string to examine.
+   M entryrefs provide a generalized target for referring to a line within a
+   routine. An entryref may contain some combination of a label, an offset,
+   and a routine name (in that order). The offset is delimited by a plus sign
+   (+) and the routinename is delimited by a caret symbol(^). When an
+   entryref does not contain a label, M assumes the offset is from the
+   beginning of the routine. When an entryref does not contain an offset, M
+   uses an offset of zero (0). When an entryref does not contain a routine
+   name, M assumes the routine that is currently executing.
 
-3 $ZBITNOT()
-   $ZBITNOT()
+   M permits every element in an entryref to have the form of an indirection
+   operator, followed by an element that evaluates to a legitimate occurrence
+   of that portion of the entryref.
 
-   The $ZBITNOT function returns a copy of the bit string with each input
-   bit position inverted.
+   **Note**
 
-   The format for the $ZBITNOT function is:
+   While most commands and functions that use entryrefs permit argument
+   indirection, M does not accept indirection that resolves to a combination
+   of label and offset or offset and routine name.
 
+   Offsets provide an extremely useful tool for debugging. However, avoid
+   their use in production code because they generally produce maintenance
+   problems.
 
-   $ZBITNOT(expr)
+3 Label_References
+   Label References
 
-   o    The expression specifies the bit string whose inverted bit pattern
-        becomes the result of the function.
+   M labelrefs are a subset of entryrefs that exclude offsets and separate
+   indirection. Labelrefs are used with parameter passing.
 
-3 $ZBITOR()
-   $ZBITOR()
+2 Indirection
+   Indirection
 
-   The $ZBITOR function performs a bitwise OR  on  two  bit  strings,  and
-   returns a bit string equal in length to the longer of the two arguments
-   (containing set bits in those positions where either  or  both  of  the
-   input strings have set bits). Positions that  correspond  to  positions
-   where neither input string has a set  bit  have  cleared  bits  in  the
-   resulting string.
+   M provides indirection as a means to defer definition of elements of the
+   code until run-time. Indirection names a variable that holds or "points"
+   to the element. The indirection operator is the "at" symbol (@).
 
-   The format for the $ZBITOR function is:
+3 Argument_Indirection
+   Argument Indirection
 
-   $ZBITOR(expr1,expr2)
+   Most commands accept indirection of their entire argument.
 
-   o    The first expression specifies one of the bit strings that is input
-        to the OR operation.
+   Example:
 
-   o    The second expression specifies the other bit string that is input
-        to the OR operation.
+   GTM>set x="^INDER"
+   GTM>do @x
 
-3 $ZBITSET()
-   $ZBITSET()
+   This example is equivalent to do ^INDER.
 
-   The $ZBITSET function returns an edited copy of the  input  bit  string
-   with a specified bit set to the value of the truth-valued expression.
+3 Atomic_Indirection
+   Atomic Indirection
 
-   The format for the $ZBITSET function is:
+   Any expratom or any local or global variable name may be replaced by
+   indirection.
 
+   Example:
 
-   $ZBITSET(expr,intexpr,tvexpr)
+   GTM>set x="HOOP",b="x"
+   GTM>write a="HULA "__ at b
+   HULA HOOP
+   GTM>
 
-   o    The expression specifies the input bit string.
+   This example uses indirection within a concatenation operation.
 
-   o    The integer  expression  specifies  the  position  of  the  bit  to
-        manipulate. Arguments that are negative, zero, or exceed the length
-        of the bit string produce a run-time error. $ZBIT  functions  count
-        the first bit as position one (1).
+3 Entryref_Indirection
+   Entryref Indirection
 
-   o    The truth-valued expression specifies the value to which to set the
-        specified bit (0 or 1).
+   Any element of an entryref may be replaced by indirection.
 
-3 $ZBITSTR()
-   $ZBITSTR()
+   Example:
 
-   The $ZBITSTR function returns a bit string of a specified  length  with
-   all bit positions initially set to either zero or one.
+   GTM>set lab="START",routine="PROG"
+   GTM>do @lab^@routine
 
-   The format for the $ZBITSTR function is:
+   This example is equivalent to do START^PROG.
 
+3 Pattern_Code_Indirection
+   Pattern Code Indirection
 
-   $ZBITSTR(intexpr[,tvexpr])
+   A pattern code may be replaced by indirection.
 
-   o    The integer expression specifies the length of the  bit  string  to
-        return; arguments that exceed the maximum length of 253,952 produce
-        a run-time error.
+   Example:
 
-   o    The optional truth-valued expression specifies the value  to  which
-        all bit positions should  initially  be  set  (0  or  1).  If  this
-        argument is missing, the bits are set to zero.
+   GTM>FOR p="1U.20A1"",""1U.20A",5N IF x?@p QUIT
+   GTM>ELSE WRITE !,"Incorrect format" QUIT
 
-3 $ZBITXOR()
-   $ZBITXOR()
+   This example uses pattern code indirection to test x for either a name or
+   a number.
 
-   The $ZBITXOR performs a bitwise exclusive OR on two  bit  strings,  and
-   returns a bit string  equal  in  length  to  the  shorter  of  the  two
-   arguments (containing set bits in those position where either  but  not
-   both of the input strings have set bits). Positions that correspond to
-   positions where neither or both input string has a set bit have cleared
-   bits in the resulting string.
+3 Name_Indirection
+   Name Indirection
 
-   The format for the $ZBITXOR function is:
+   Indirection may replace the prefix of a subscripted global or local
+   variable name. This "name" indirection requires two indirection operators,
+   a leading operator similar to the other forms of indirection, and a
+   trailing operator marking the transition to those subscripts that are not
+   specified by indirection.
 
+   Example:
 
-   $ZBITXOR(expr1,expr2)
+   GTM>SET from="B",to="^A(15),x=""
+   GTM>FOR SET x=$O(@from@(x)) Q:x="" S @to@(x)=@from@(x)
 
-   o    The first expression specifies one of the bit strings that is input
-        to the XOR operation.
+   This example uses name indirection to copy the level contents of a local
+   array to a part of a global array. The example assumes that all existing
+   first level nodes of variable B have data.
 
-   o    The second expression specifies the other bit string that is input
-        to the XOR operation.
+3 Indirection_Concerns
+   Indirection Concerns
 
-3 Ex_of_$ZBIT_Func
-   Examples of $ZBIT Functions
+   M indirection provides a very powerful tool for allowing program
+   abstraction. However, because indirection is frequently unnecessary and
+   has some disadvantages, use it carefully.
 
-   Example:
+   Because routines that use indirection in some ways do not contain adequate
+   information for easy reading, such routines tend to be more difficult to
+   debug and maintain.
 
+   To improve run-time performance, GT.M tends to move work from run-time to
+   compile-time. Indirection forces compiler actions to occur at run-time,
+   which minimizes the benefits of compilation.
 
-   ZCRC(X)
+   M allows most forms of indirection to be recursive. However, in real
+   applications, recursive indirection typically makes the code obscure and
+   slow.
 
-   NEW R,I,J,B,X1,K
+   There are circumstances where indirection serves a worthwhile purpose. For
+   instance, certain utility functions with a general nature may be clearly
+   abstracted and coded using indirection. Because M has no "CASE" command,
+   DO (or GOTO) with argument indirection provides a clear solution to the
+   problem of providing complex branching.
 
-   SET R=$ZBITSTR(8,0)
+   Some M users prototype with indirection and then replace indirection with
+   generated code that reduces run-time overhead. In any case, always
+   consider whether indirection can be replaced with a clearer or more
+   efficient approach.
 
-   FOR I=1:1:$L(X) S R=$ZBITXOR(R,$$BITIN($A(X,I)))
+   Run-time errors from indirection or XECUTEs maintain $STATUS and $ZSTATUS
+   related information and cause normal error handling but do not provide
+   compiler supplied information on the location of any error within the code
+   fragment.
 
-   QUIT $$BITOUT(R)
+2 Parameter_Passing
+   Parameter Passing
 
-   ;CONVERT A BYTE TO A BIT STRING
+   Parameter passing provides a way of explicitly controlling some or all of
+   the variable context transferred between M routines.
 
+   M uses parameter passing for:
 
-   BITIN(X)
+     * A DO command with parameters
+     * Extrinsic functions and special variables
 
-   SET X1=$ZBITSTR(8,0)
+   Parameter passing is optional on DO commands.
 
-   FOR J=1:1:8 S B=X#2,X=X\2 i B s X1=$ZBITSET(X1,J,1)
+   Parameter passing uses two argument lists: the actuallist that specifies
+   the parameters that M passes to an invoked routine, and the formalist that
+   specifies the local variables to receive or associate with the parameters.
 
-   QUIT X1
+3 Actuallists
+   Actuallists
 
-   ; CONVERT A BITSTRING TO A NUMBER
+   An actuallist specifies the parameters M passes to the invoked routine.
+   The actuallist contains a list of zero or more parameters enclosed in
+   parentheses, immediately following a DO or extrinsic function.
 
+   An actuallist:
 
-   BITOUT(X)
+     * Is made up of items separated by commas
+     * Contains expressions and/or actualnames. Items may be missing, that
+       is, two commas may appear next to each other, with nothing between
+       them.
+     * Must be used in an invocation of a label with a formallist, except in
+       the case of extrinsic special variables.
+     * Must not contain undefined variables.
+     * Must not have more items than a formallist with which it is used.
+     * May contain the same item in more than one position.
 
-   SET X1=0
+   Example:
 
-   FOR K=1:1:8 I $ZBITGET(X,K) S X1=X1+(2**(K-1))
+   GTM>DO MULT(3,X,.RESULT)
 
-   QUIT X1
+3 Actualnames
+   Actualnames
 
-   This uses several $ZBIT functions to turn a character into a bit stream
-   and return a coded value.
+   An actualname starts with a leading period (.) delimiter, followed by an
+   unsubscripted local variable name. Actualnames identify variables that are
+   passed by reference, as described in a subsequent section. While
+   expressions in an actualname are evaluated when control is transferred to
+   a formallabel, the variables identified by actualnames are not; therefore,
+   they do not need to be defined at the time control is transferred.
 
-   While this  example  illustrates  the  use  of  several  of  the  $ZBIT
-   functions, the following example produces identical results if you need
-   to code the function illustrated above for production.
+3 Formallists
+   Formallists
 
+   A formallist specifies the variables M uses to hold passed values. A
+   formallist contains a list of zero or more parameters enclosed in
+   parentheses, immediately following a label.
 
-   ZCRC(X)
+   Example:
 
-   NEW R,I,J,B,X1,K
+   MULT(MP,MC,RES)
+   SET RES=MP*MC
+   QUIT RES
 
-   SET R=$ZBITSTR(8,0)
+3 Formallabel
+   Formallabel
 
-   FOR I=1:1:$L(X) S R=$ZBITXOR(R,$C(0)_$E(X,I))
+   A label followed by a formallist is called a formallabel.
 
-   QUIT $A(R,2)
+3 Parameter_Passing_Operation
+   Parameter Passing Operation
 
-   This example illustrates the use of $C to specify the number of invalid
-   bits that exist at the end of the character string. In this case there
-   are zero invalid bits.
+   M performs an implicit NEW on the formallist names and replaces the
+   formallist items with the actuallist items.
 
-2 $ZDate()
-   $ZDate()
+   M provides the actuallist values to the invoked procedure by giving each
+   element in the formallist the value or reference provided by the
+   corresponding element in the actuallist. M associates the first name in
+   the formallist with the first item in the actuallist, the second name in
+   the formallist with the second item in the actuallist and so on. If the
+   actuallist is shorter than the formallist, M ensures that the formallist
+   items with no corresponding value are in effect NEWed. If the formallist
+   item has no corresponding item in the actuallist (indicated by two
+   adjacent commas in the actuallist), that item in the formallist becomes
+   undefined.
+
+   If the actuallist item is an expression and the corresponding formallist
+   variable is an array, parameter passing does not affect the subscripted
+   elements of the array. If an actualname corresponds to a formallist
+   variable, M reflects array operations on the formallist variable, by
+   reference, in the variable specified by the actualname.
 
-   The $ZDATE function returns a date and/or time formatted as text based
-   on an argument formatted in the manner of $HOROLOG. For information on
-   the format of $HOROLOG, refer  to  the  "Intrinsic  Special  Variables"
-   chapter in this manual.
+   M treats variables that are not part of the formallist as if parameter
+   passing did not exist (i.e., M makes them available to the invoked
+   routine).
 
-   The format for the $ZDATE function is:
+   M initiates execution at the first command following the formallabel.
 
+   A QUIT command terminates execution of the invoked routine. At the time of
+   the QUIT, M restores the formallist items to the values they had at the
+   invocation of the routine.
 
-   $ZD[ATE](expr1[,expr2[,expr3[,expr4]]]])
+   **Note**
 
-   o    The first expression specifies in $HOROLOG format the  date  and/or
-        time that $ZDATE() returns in text format. If the  output  requires
-        only the date or the time, the other piece of the argument that is
-        delimited by a comma (,) may be null.
-
-   o    The  optional  second  expression  specifies  a  string  providing
-        $ZDATE() with a "picture" of the desired  output  format.  If  this
-        argument is missing or  null,  $ZDATE()  uses  the  default  format
-        string "MM/DD/YY". If the optional  second  expression  exceeds  64
-        characters, $ZDATE() generates a run-time error.
-
-   o    The optional third expression specifies a list of 12  month  codes,
-        separated by commas (,), that  $ZDATE()  uses  in  formatting  text
-        months called for by the "MON"  picture,  (i.e.,  $ZDATE()  outputs
-        $PIECE(expr3,",",month-number) when "MON"  appears  in  the  second
-        expression). If this argument is missing  or  null,  $ZDATE()  uses
-        three-character English abbreviations for months.
-
-   o    The optional fourth expression specifies a list of seven day codes,
-        separated by commas (,), which $ZDATE()  uses  in  formatting  text
-        days of the week called for by the "DAY" picture, $ZDATE() outputs
-        $PIECE (expr4,",",day-of-week-number) when  "DAY"  appears  in  the
-        second expression; if this argument is missing  or  null,  $ZDATE()
-        uses three-character English abbreviations for days of the week.
-
-   $ZDATE() provides an easy and flexible  tool  for  putting  M  internal
-   date/time ($HOROLOG) formats into more user-friendly formats.
+   In the case where a variable name appears as an actualname in the
+   actuallist, and also as a variable in the formallist, the restored value
+   reflects any change made by reference.
 
-   The Intrinsic Special Variable $ZDATEFORM determines the output format
-   for years. The default value is zero (0), in which case  $ZDATE()  with
-   one argument (no format specification) uses a "YY" (two  digit)  format
-   for all years. If $ZDATEFORM is one (1), a "YYYY" (four  digit)  format
-   is used for years later than 1999. For all other values of $ZDATEFORM,
-   "YYYY" (four digit) format is used for all years. $ZDATEFORM  does  not
-   affect $ZDATE() when the format argument is specified.
+   A QUIT from a DO does not take an argument, while a QUIT from an extrinsic
+   must have an argument. This represents one of the two major differences
+   between the DO command with parameters and the extrinsics. M returns the
+   value of the QUIT command argument as the value of the extrinsic function
+   or special variable. The other difference is that M stacks $TEST for
+   extrinsics.
 
-3 $ZDate_Form_Spec_Ele
-   $ZDATE Format Specification Elements
+   Example:
 
-   This section lists the $ZDATE() format specification elements. $ZDATE()
-   format specifications must appear in upper case.  When  any  alphabetic
-   characters  in  format  specifications  are  in  lower  case,  $ZDATE()
-   generates a run-time error.
-
-        YY Outputs the rightmost two digits of the year.
-        YEAR Outputs the year as a four-digit number.
-        MM Outputs the month as a two-digit zero-filled number  between  01
-        and 12.
-        MON Outputs the month as  a  three-letter  abbreviation.  (You  can
-        modify the output further using expr3).
-        DD Outputs the day of the month as a two-digit  zero-filled  number
-        between 01 and 31.
-        DAY Outputs the day of the week  as  a  three-letter  abbreviation.
-        (You can modify the output further using expr4).
-        24 Outputs the hour of the day as a zero-filled number  between  00
-        and 23.
-        12 Outputs the hour of the day as a zero-filled number  between  01
-        and 12.
-        60 Outputs the minute of the hour as a zero-filled  number  between
-        00 and 59.
-        SS Outputs the second of the minute as a zero-filled number between
-        00 and 59.
-        AM Outputs the letters AM and PM depending on the time.
-        + Inserts a plus sign (+) in the output string
-        - Inserts a minus sign (-) in the output string.
-        . Inserts a period (.) in the output string.
-        , Inserts a comma (,)in the output string.
-        / Inserts a slash (/) in the output string.
-        : Inserts a colon (:) in the output string.
-        ; Inserts a semi-colon (;) in the output string.
-        * Inserts an asterisk (*) in the output string.
-        A blank space inserts a blank space in the output string.
-
-3 Ex_of_$ZDate()
-   Examples of $ZDATE()
-
-   Example:
-
-
-   GTM> WRITE $H,!,$ZDATE($H)
-
-   55243,43223
-   04/01/2002
-   GTM>
+   SET X=30,Z="Hello"
+   DO WRTSQR(X)
+   ZWRITE
+   QUIT
+   WRTSQR(Z)
+   SET Z=Z*Z
+   WRITE Z,!
+   QUIT
 
-   This displays $HOROLOG and then uses $ZDATE() to display today's date.
-   The output shown would appear if today were the first of April, 2002.
+   Produces:
 
-   Example:
+   900
+   X=30
+   Z="Hello"
 
+3 Parameter_Passing_Mechanisms
+   Parameter Passing Mechanisms
 
-   GTM> W $ZDATE($H,"DD-MON-YEAR")
+   M passes the actuallist values to the invoked routine using two
+   parameter-passing mechanisms:
 
-   01-APR-2002
-   GTM>
+     * Call-by-Value - where expressions appear
+     * Call-by-Reference - where actualnames appear
 
-   This uses the second argument to specify a text format  different  from
-   the default.
+   A call-by-value passes a copy of the value of the actuallist expression to
+   the invoked routine by assigning the copy to a formallist variable. If the
+   parameter is a variable, the invoked routine may change that variable.
+   However, because M constructs that variable to hold the copy, it deletes
+   the variable holding the copy when the QUIT restores the prior formallist
+   values. This also means that changes to the variable by the invoked
+   routine do not affect the value of the variable in the invoking routine.
 
    Example:
 
+   SET X=30
+   DO SQR(X)
+   ZWRITE
+   QUIT
+   SQR(Z)SET Z=Z*Z
+   QUIT
 
-   GTM> SET m="Januar,Februar,Marz,April,Mai,Juni,Juli,August,"
-
-   GTM> SET m=m_"September,October,November,Dezember"
+   Produces:
 
-   GTM> WRITE $ZDATE($H,"DD-MON-YEAR",m)
+   X=30
 
-   01-April-2002
-   GTM>
+   A period followed by a name identifies an actualname and causes a
+   call-by-reference.
 
-   This is similar to  the  prior  example,  however  it  uses  the  third
-   argument to specify the months in German.
+   A call-by-reference passes a pointer to the variable of the invoked
+   routine so operations on the assigned formallist variable also act on the
+   actualname variable. Changes, including KILLs to the formallist variable,
+   immediately have the same affect on the corresponding actualname variable.
+   This means that M passes changes to formallist variables in the invoked
+   routine back to the invoking routine as changes in actualname variables.
 
    Example:
 
+   SET X=30
+   DO SQR(.X)
+   ZWRITE
+   QUIT
+   SQR(Z)SET Z=Z*Z
+   QUIT
 
-   GTM> SET d="Dimanche,Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi"
-
-   GTM> WRITE $ZD($H,"DAY, DD/MM/YY","",d)
+   Produces:
 
-   Mercredi, 01/04/2002
+   X=900
 
-   GTM>
+3 Parameter_Passing_Extensions
+   Parameter Passing Extensions
 
-   This example displays the first of April, however it  uses  the  fourth
-   argument to specify the days of the week in French.
+   The standard does not provide for indirection of a labelref because the
+   syntax has an ambiguity.
 
    Example:
 
+   DO @X(1)
 
-   GTM> WRITE !,$ZDATE($H,"12:60:55 AM")
+   This example could be:
 
-   10:35:51 PM
-   GTM>
+     * An invocation of the label specified by X with a parameter of 1.
+     * An invocation of the label specified by X(1) with no parameter list.
 
-   This example shows hours, minutes, and seconds in a 12 hour clock with
-   an AM/PM indicator.
+   GT.M processes the latter interpretation as illustrated in the following
+   example.
 
    Example:
 
+   The syntax:
 
-   GTM> WRITE !,$ZDATE(",36524","24-60")
-
-   10-08
-   GTM>
-
-   This example shows hours and minutes on a 24 hour  clock.  Notice  that
-   the first argument must provide the time in the second comma delimiter
-   piece to match $HOROLOG format.
+   SET A(1)="CUBE",X=5
+   DO @A(1)(.X)
+   WRITE X,!
+   QUIT
+   CUBE(C);cube a variable
+   SET C=C*C*C
+   QUIT
 
-   Example:
+   Produces the result:
 
+   125
 
-   GTM>WRITE $ZDATEFORM
+   GT.M follows analogous syntax for routine indirection:
 
-   0
-   GTM>WRITE $ZDATE($H)
+   DO ^@X(A) invokes the routine specified by X(A).
 
-   11/15/02
-   GTM>SET $ZDATEFORM=1
+   DO ^@(X)(A) invokes the routine specified by X and passes the parameter A.
 
-   GTM>WRITE $ZDATE($H)
+   DO ^@X(A)(A) invokes the routine specified by X(A) and passes the
+   parameter A.
 
-   11/15/2002
-   GTM>WRITE $ZDATE($H,"MM/DD/YY")
+2 External_Calls
+   External Calls
 
-   11/15/02
-   This example converts the output format  for  years  from  the  default
-   ("YY") format to the four digit format  ("YYYY")  using  the  Intrinsic
-   Special Variable $ZDATEFORM.
+   GT.M allows references to a GT.M database from programs written in other
+   programming languages that run under UNIX.
 
-2 $ZJOBEXAM()
-   $ZJOBEXAM()
+   In GT.M, calls to C language routines may be made with the following
+   syntax:
 
-   The $ZJOBEXAM function returns the full specification of the file into
-   which the function places a ZSHOW "*". The return value serves as a way
-   to save, to notify others of the exact location of the  output,  or  to
-   open the file for further processing. GT.M reports each $ZJOBEXAM() to
-   the operator log facility with its file specification.
+   DO &[packagename.]name[^name][parameter-list]
 
-   The  optional  expression  argument  is  a  template  output  device
-   specification. It can be a device, a file directory, or  a  file  name.
-   The template is an expression that is pre-processed to  create  a  file
-   specification as  the  target  for  the  ZSHOW.  The  preprocessing  is
-   equivalent to $ZPARSE(), as illustrated by the following M code:
+   or as an expression element,
 
+   $&[packagename.]name[^name][parameter-list]
 
-   Set deffn="GTM_JOBEXAMINE.ZSHOW_DMP_"_$JOB_"_"_<cntr>
+   Where packagename, like the name elements is a valid M name. Because of
+   the parsing conventions of M, the identifier between the ampersand (&) and
+   the optional parameter-list has precisely constrained punctuation - a
+   later section describes how to transform this into a more richly
+   punctuated name should that be appropriate for the called function. While
+   the intent of the syntax is to permit the name^name to match an M
+   labelref, there is no semantic implication to any use of the caret (^).
 
-   Set filespec=$ZPARSE(expr1,"",deffn)
+   **Note**
 
-   The $ZJOBEXAM()does not trigger error processing except when there is a
-   problem storing its return value,  so  no  error  is  reported  to  the
-   process until after any dump is complete. In the  event  of  any  error
-   encountered during the $ZJOBEXAM(), GT.M sends an  appropriate  message
-   to operator log facility and returns control to the caller.  Note  that
-   this special error handling applies only to the $ZJOBEXAM(), and is not
-   a property of the $ZINTERRUPT interrupt handler, which uses $ZJOBEXAM()
-   by default.
+   For more information on external calls, see Chapter 11: "Integrate
+   External".
 
-   $ZJOBEXAM() dump files contain the context of a process at the time the
-   function executes. Placement  and  management  of  these  files  should
-   consider their potential size and security implications.
+2 Extrinsic_Functions
+   Extrinsic Functions
 
-3 Ex_of_$ZJOBEXAM()
-   Examples of $ZJOBEXAM()
+   An extrinsic function is an M subroutine that another M routine can invoke
+   to return a value.
 
-   Example:
+   The format for extrinsic functions is:
 
+   $$[label][^routinename]([expr|.lname[,...]])
 
-   GTM>Set x=$ZJOBEXAM()
+   M stacks $TEST for extrinsic functions. This is one of the two major
+   differences between the DO command with parameters and extrinsics. On
+   return from an extrinsic function, M restores the value of $TEST to what
+   it was before the extrinsic function, regardless of the actions executed
+   by the invoked routine.
 
+   M requires a routine that implements an extrinsic function to terminate
+   with an explicit QUIT command which has an argument. M returns the value
+   of the QUIT command argument as the value of the extrinsic function. This
+   is the other major difference between the DO command with parameters and
+   extrinsics. It is now possible to invoke a C function in a package via the
+   external call mechanism.
 
-   GTM>Write x
+   Example:
 
-   /home/testarea/demo/GTM_JOBEXAM.ZSHOW_DMP_28760_1
+   POWER(V,X,S,T);extrinsic to raise to a power
+   ;ignores fractional powers
+   SET T=1,S=0
+   IF X<0 SET X=-X,S=1
+   FOR X=1:1:X S T=T*V
+   QUIT $S(S:1/T,1:T)
+   GTM> WRITE $$^POWER(3,4)
+   81
+   GTM>
 
-   GTM>Set x=$ZJOBEXAM("test.file")
+   **Note**
 
+   The POWER routine uses a formallist that is longer than the "expected"
+   actuallist to protect local working variables. Such practice may be
+   encouraged or discouraged by your institution's standards.
 
-   GTM>write x
+2 Extrinsic_Special_Variables
+   Extrinsic Special Variables
 
-   /home/testarea/demo/test.file
+   An extrinsic special variable is a user-written M subroutine that another
+   M routine can invoke to return a value.
 
-   GTM>
+   The format for extrinsic special variables is:
 
+   $$[label][^routinename]
 
-   Shows default file name and type of the files  created  containing  the
-   zshow dump information and the difference when the name  and  type  are
-   specified.
+   An extrinsic special variable can be thought of as an extrinsic function
+   without input parameters. $$x is equivalent in operation to $$x().
+   Extrinsic special variables are the only case where invocation of a
+   formallabel does not require an actuallist. M stacks $TEST for extrinsic
+   special variables.
 
-2 $ZMessage()
-   $ZMessage()
+   M requires that a routine that implements an extrinsic special variable
+   terminate with an explicit QUIT command which has an argument. M returns
+   the value of the QUIT command argument as the value of the extrinsic
+   special variable.
 
-   The $ZMESSAGE function returns  a  message  string  associated  with  a
-   specified status code.
+   Example:
 
-   The format for the $ZMESSAGE function is:
+   GTM>ZPRINT ^DAYOWEEK
+   DAYOWEEK();extrinsic special variable to
+   ;provide the day of the week
+   QUIT $ZD($H,"DAY")
+   GTM>WRITE $$DAYOWEEK^DAYOWEEK
+   MON
 
+2 Transaction_Processing
+   Transaction Processing
 
-   $ZM[ESSAGE](intexpr)
+   Transaction Processing (TP) provides a way for M programs to organize
+   database updates into logical groups that occur as a single event (i.e.,
+   either all the database updates in a transaction occur, or none of them
+   occur). No other process may behave as if it observed any intermediate
+   state.
 
-   o    The  integer  expression  specifies  the  status  code  for  which
-        $ZMESSAGE() returns error message text.
+   Transaction processing has been designed to improve output and eliminate
+   "live lock" conditions. The number of attempts to complete the transaction
+   is limited to four. The fourth attempt is made inside a "critical section"
+   with all other processes temporarily locked out of the database. Between
+   the second and third tries, GT.M waits for a random interval between 0 and
+   500 milliseconds.
 
-   $ZMESSAGE() provides a tool for examining the message associated with a
-   particular message code as reported in $ZSTATUS.
+3 TP_Definitions
+   TP Definitions
 
-   The $ZSTATUS Intrinsic Special Variable holds the message code and the
-   message of the last non-Direct Mode GT.M error. For more information on
-   $ZSTATUS, refer to the "Intrinsic Special Variables"  chapter  in  GT.M
-   Programmer's Guide.
+   In M, a transaction is a sequence of commands that begins with a TSTART
+   command, ends with a TCOMMIT command, and is not within the scope of
+   another transaction.
 
-3 Ex_of_$ZMessage()
-   Examples of $ZMESSAGE()
+   A successful transaction ends with a COMMIT that is triggered by the
+   TCOMMIT command at the end of the transaction. A COMMIT causes all the
+   database updates performed within the transaction to become available to
+   other processes.
+
+   An unsuccessful transaction ends with a ROLLBACK. ROLLBACK is invoked
+   explicitly by the TROLLBACK command, or implicitly at a process
+   termination that occurs during a transaction in progress. An error within
+   a transaction does not cause an implicit ROLLBACK. A ROLLBACK removes any
+   database updates performed within the transaction before they are made
+   available to other processes. ROLLBACK also releases all resources LOCKed
+   since the start of the transaction, and makes the naked reference
+   undefined.
+
+   A RESTART is a transfer of control to the TSTART at the beginning of the
+   transaction. RESTART implicitly includes a ROLLBACK and may optionally
+   restore local variables to the values they had when the initial TSTART was
+   originally executed. A RESTART always restores $TEST and the naked
+   reference to the values they had when the initial TSTART was executed.
+   RESTART does not manage device state information. A RESTART is invoked by
+   the TRESTART command or by M if it is determined that the transaction is
+   in conflict with other database updates. RESTART can only successfully
+   occur if the initial TSTART includes an argument that enables RESTART.
 
-   Example:
+3 TP_Performance
+   TP Performance
 
+   To achieve the best GT.M performance, transactions should:
 
-   GTM> WRITE $ZMESSAGE(36)
+     * be as short as possible
+     * consist, as much as possible, only of global updates
+     * be SERIAL with no associated LOCKs
+     * have RESTART enabled with a minimum of local variables protected by a
+       restart portion of the TSTART argument.
+     * Large concurrent transactions using TCOMMIT may result in repeated and
+       inefficient attempts by competing processes to capture needed scarce
+       resources, resulting in poor performance.
 
-   Interrupted system call
+   Example:
 
-   GTM>
+   TSTART ():SERIAL
+   SET (ACCT,^M(0))=^M(0)+1
+   SET ^M(ACCT)=PREC,^PN(NAM)=ACCT
+   TCOMMIT
 
-   This uses $ZMESSAGE() to display the message  string  corresponding  to
-   code 36.
+   Example:
 
-2 $ZPARSE()
-   $ZPARSE()
+   TSTART ():SERIAL
+   IF $TRESTART>3 DO QUIT
+   .TROLLBACK
+   .WRITE !,"Too many RESTARTs"
+   .QUIT
+   SET (NEXT,^ID(0))=^ID(0)+1
+   SET ^ID(NEXT)=RECORD,^XID(ZIP,NEXT)=""
+   TCOMMIT
 
-   The $ZPARSE function expands a file name to a full  pathname  and  then
-   returns the full pathname or one of its  fields  (directory,  name,  or
-   extension).
+1 Commands
+   Commands
 
-   The format for the $ZPARSE function is:
+   This chapter describes M language commands implemented in GT.M. All
+   commands starting with the letter Z are GT.M additions to the ANSI
+   standard command set. The M standard specifies standard abbreviations for
+   commands and rejects any non-standard abbreviation.
 
+2 Break
+   Break
 
-   $ZPARSE(expr1[,expr2[,expr3[,expr4[,expr5]]]])
+   The BREAK command pauses execution of the code and initiates Direct Mode.
 
-   o    The first expression specifies the file name; if the file  name  is
-        not valid, $ZPARSE() returns  a  null  string;  if  the  file  name
-        contains a wildcard (* and/or ?), $ZPARSE()  returns  a  file  name
-        containing the wildcard(s).
-
-   o    The optional second expression specifies the field of the pathname
-        that $ZPARSE() returns;  if  this  argument  is  missing  or  null,
-        $ZPARSE() returns a full pathname constructed using default values
-        in place of any fields missing for directory, file and extension.
-
-   o    The optional third and fourth expressions specify default values to
-        use during file name expansion for missing fields (directory, name,
-        or extension), if any, in the original file  name.  For  any  field
-        missing in the original file name  specified  in  expr1,  $ZPARSE()
-        will attempt to substitute the corresponding field from  expr3;  if
-        that field is not present in expr3, $ZPARSE() will attempt  to  use
-        the corresponding field from expr4.
-
-   o    If the file extension is missing from all three  of  expr1,  expr3,
-        and  expr4,  $ZPARSE()  will  return  a  null  string  for  the
-        corresponding field. If the file, or directory is missing from all
-        three of expr1, expr3, and expr4,  $ZPARSE()  will  substitute  the
-        information from your current working directory.
-
-   o    The optional fifth expression specifies the mode or type  of  parse
-        that $ZPARSE() performs.
-
-   $ZPARSE()  provides  a  tool  for  verifying  that  a  file  name  is
-   syntactically correct, for examining specific fields of  a  file  name,
-   and for filling in missing pieces in a partial specification based on a
-   hierarchy of defaults. For information about determining whether a file
-   exists, refer to the description of $ZSEARCH().
+   The format of the BREAK command is:
 
-   $ZPARSE() arguments, after the first, are optional. If you use no other
-   arguments, a  single  argument  is  sufficient.  However,  if  you  use
-   selected arguments $ZPARSE() requires that null strings ("") be filled
-   in for the unspecified arguments.
+   B[REAK][:tvexpr] [expr[:tvexpr][,...]]
 
-   The acceptable keywords for the second argument are:
+   Issuing a BREAK command inside an M transaction destroys the Isolation of
+   that transaction. Because of the way that GT.M implements transaction
+   processing, a BREAK within a transaction may cause the transaction to
+   suffer an indefinite number of restarts ("live lock").
 
-        "DIRECTORY" Directory name
-        "NAME" File name (excluding file extension)
-        "TYPE" File typeextension
-   The keywords may be entered in either upper or  lower  case.  Variables
-   that evaluate to these  strings  and  indirection  are  acceptable  for
-   argument two. When the keywords themselves appear as  string  literals,
-   they must be enclosed in quotation marks (" ").
+   ZCONTINUE resumes execution of the interrupted program.
 
-   The following guidelines must be  followed  in  constructing  arguments
-   one, three and four:
+   The VIEW "BREAKMSG" mask selectively enables or disables these messages.
+   By default, a process executing a GT.M image displays all BREAK messages.
 
-   o    Directory specifications must end in a slash;  anything  after  the
-        final slash in the directory specification is assumed to be part of
-        the name specification.
+3 Examples
+   Examples
 
-   o    A file name with an extension must include at least  one  character
-        to the left of the period (.). Thus, "/user/.login" refers  to  the
-        file named ".login", while "/usr/taxes.c" refers to  a  file  named
-        "taxes" with the extension "c". If a file name includes  more  than
-        one period, the extension includes all letters to the right of the
-        rightmost period.
+   Example:
 
-   The keywords for the fifth argument $ZPARSE() are:
+   LOOP0     F  S act=$O(^act(act)) Q:act=""  B:debug  D LOOP1
 
-        NULL ("") Returns a full file-specification or device
-        "SYNTAX_ONLY"
-        Disables checking for the existence of the directory or device.
-3 Ex_of_$ZPARSE()
-   Examples of $ZPARSE()
+   This FOR loop contains a BREAK with a command postconditional.
 
    Example:
 
+   GTM>ZPRINT ^br
+   br;
+         kill
+         for i=1:1:3 do break;
+         quit
+   break;
+         write "Iteration ",i,?15,"x=",$get(x,"<UNDEF>"),!
+         break:$data(x) "write ""OK"",!":x,"write ""Wrong again"",!":'x
+         set x=$increment(x,$data(x))
+         quit
+   GTM>DO ^br
+   Iteration 1    x=<UNDEF>
+   Iteration 2    x=0
+   %GTM-I-BREAK, Break instruction encountered
+               At M source location break+2^br
+   GTM>ZCONTINUE
+   Wrong again
+   %GTM-I-BREAK, Break instruction encountered
+               At M source location break+2^br
+
+   GTM>ZCONTINUE
+   Iteration 3    x=1
+   OK
+   %GTM-I-BREAK, Break instruction encountered
+               At M source location break+2^br
 
-   GTM> WRITE $ZPARSE("test","","/usr/work/","dust.lis")
+   GTM>ZCONTINUE
+   %GTM-I-BREAK, Break instruction encountered
+               At M source location break+2^br
 
-   /usr/work/test.lis
+   GTM>ZCONTINUE
 
    GTM>
 
-   This uses $ZPARSE() to  demonstrate  defaulting  using  the  third  and
-   fourth arguments. The result gets the directory field  from  the  third
-   expression, the name from the first expression, and the type  from  the
-   fourth expression.
+   This uses a BREAK with both command and argument postconditionals. The
+   actions display debugging messages.
 
-   Example:
+2 Close
+   Close
 
+   The CLOSE command breaks the connection between a process and a device.
 
-   GTM>r!,"file :",f w ?20,$zparse(f,"directory")
+   The format of the CLOSE command is:
 
-   file: test.list /usr/work/
+   C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
 
-   GTM>
+2 Do
+   Do
 
-   This uses $ZPARSE() to display the directory for the file name entered
-   as input at the prompt file:  ,  in  this  case,  the  current  working
-   directory.
+   The DO command makes an entry in the GT.M invocation stack and transfers
+   execution to the location specified by the entryref.
 
-   Example:
+   The format of the DO command is:
 
+   D[O][:tvexpr] [entryref[(expr|.lvn[,...])][:tvexpr][,...]]
 
-   $ cd /usr/work/me
+3 Examples
+   Examples
 
-   $ $gtm
+   Example:
 
-   GTM>W $ZPARSE("test","","x.list","y.c")/usr/work/me/test.lis
+   GTM>DO ^%RD
 
-   GTM>W $ZPARSE("test","","/usr/work/","/dev/y.c")/usr/work/test.c
+   This example invokes the routine directory utility program (%RD) from
+   Direct Mode. The caret symbol (^) specifies that the DO command invokes
+   %RD as an external routine.
 
-   GTM>W $ZPARSE("test","","/usr/work","/dev/y.c")/usr/test.c
+   Example:
 
-   GTM>
+   GTM>DO A(3)
 
-   This example illustratest the use of the third and fourth arguments to
-   $ZPARSE(). In the first statement, the first argument has no directory
-   or extension field, so $ZPARSE() substitutes the extension  field  from
-   the third  argument.  Since  neither  the  third  nor  fourth  argument
-   specifies a directory, and because the fourth argument does not contain
-   any fields that are not present  in  the  third  argument,  the  fourth
-   argument is not used.
+   This example invokes the subroutine at label A and passes the value 3 as a
+   parameter. The DO argument does not have a caret symbol (^), therefore, it
+   identifies A as a label in the current routine.
 
-   In the second statement, the  first  argument  to  $ZPARSE()  is  again
-   missing both the directory and extension. In this  instance,  $ZPARSE()
-   uses the directory specified in the third argument and, becuase neither
-   the first nor third argument specifies a file extension, $ZPARSE() uses
-   the file extension from the fourth argument.
+   Example:
 
-   In the third  statement,  because  "/usr/work"  does  not  end  with  a
-   backward slash (/), $ZPARSE() interprets the substring "work" as a file
-   name. Then, $ZPARSE() substitutes "/usr/" for the directory missing in
-   the first argument and substitutes ".c" from the  fourth  argument  for
-   the extension missing from both the first and third arguments.
+   ReportA ; Label for ReportA
+           SET di="" OPEN outfile USE outfile
+           FOR  SET di=$ORDER(^div(di)) QUIT:di=""  DO PREP DO  DO POST
+           .SET de="",(nr,gr)=0
+           .WRITE "Division ",di,! F   S de=$ORDER(^de(di,de)) QUIT:de=""   DO
+           ..WRITE "Department ",de," Gross Rev: ",^grev(di,de),!
+           ..WRITE "Department ",de," Net Rev: ",^nrev(di,de),!
+           ..SET gr=gr+^grev(di,de),nr=nr+^nrev(di,de)
+           .W "Division Gross Rev: ",gr,!,"Division Net Rev: ",nr,!
+            DO PRINT^OUTPUT(outfile)
+            QUIT
 
    Example:
 
+   GTM>zprint ^SQR
+   SQR(z);
+     set revert=0
+     if $view("undef") set revert=1 view "noundef"
+     if z="" write "Missing parameter.",!     view:revert "undef" quit
+     else  write z*z,! view:revert "undef" quit
 
-   $ cd /usr/work/met
+   GTM>do ^SQR(10)
+   100
 
-   $ $gtm_dist/mumps -direct
+   GTM>do ^SQR
+   Missing parameter.
 
-   GTM>f i="DIRECTORY","NAME","TYPE",""d
+   This examples demonstrates label invocations using DO with and without
+   parentheses.
 
-   . W $zparse("test.m",i),!
-   /usr/work/me/
+2 Else
+   Else
 
-   test
+   ELSE executes the remainder of the line after the ELSE if $TEST is FALSE
+   (0). GT.M does not execute the rest of the line if $TEST is TRUE (1).
 
-   .m
-   /usr/work/me/test.m
+   The format of the ELSE command is:
 
-   GTM>
+   E[LSE]
 
-   This example illustrates the output produced for each of  the  possible
-   values for the second argument.
+   ELSE is analogous to IF '$TEST, except the latter statement switches $TEST
+   to its complement and ELSE never alters $TEST.
 
-2 $ZPrevious()
-   $ZPrevious()
+3 Examples
+   Examples
 
-   The $ZPREVIOUS function returns the subscript of the previous local or
-   global variable name in  collation  sequence  within  the  array  level
-   specified by its  argument.  When  $ZPREVIOUS()  has  an  unsubscripted
-   argument,  it  returns  the  previous  unsubscripted  local  or  global
-   variable name in collating sequence.
+   Example:
 
-   The $ZPREVIOUS  function  provides  compatibility  with  some  other  M
-   implementations. The M Development Committee chose  to  implement  this
-   functionality  with  the  optional  second  -1  argument  of  $ORDER().
-   Therefore, when a design requires this functionality $ORDER()  has  the
-   advantage over $ZPREVIOUS of being part of the M standard.
+   If x=+x Set x=x+y
+   Else  Write !,x
 
-   The format for the $ZPREVIOUS function is:
+   The IF command evaluates the conditional expression x=+x and sets $TEST.
+   If $TEST=1 (TRUE), GT.M executes the commands following the IF. The ELSE
+   on the following line specifies an alternative action to take if the
+   expression is false.
 
+   Example:
 
-   $ZP[REVIOUS](glvn)
+   If x=+x Do ^GOFISH
+   Else  Set x=x_"^"_y
 
-   o    The subscripted or unsubscripted  global  or  local  variable  name
-        specifies the node prior to which $ZPREVIOUS()  searches  backwards
-        for a defined node with data  and/or  descendants.  The  number  of
-        subscripts contained in the argument implicitly defines  the  array
-        level.
+   The DO with an argument after the IF raises the possibility that the
+   routine ^GOFISH changes the value of $TEST, thus making it possible to
+   execute both the commands following the IF and the commands following the
+   ELSE.
 
-   o    If $ZPREVIOUS() finds no node at the  specified  level  before  the
-        specified global or local variable, it returns a null string.
+   Example:
 
-   o    If the last subscript in the subscripted global or  local  variable
-        name is null, $ZPREVIOUS() returns the last node at  the  specified
-        level.
+   Open dev::0 Else  Write !,"Device unavailable" QUIT
 
-   $ZPREVIOUS() is equivalent to $ORDER() with a second argument of -1.
+   This ELSE depends on the result of the timeout on the OPEN command. If the
+   OPEN succeeds, it sets $TEST to one (1) and GT.M skips the rest of the
+   line after the ELSE. If the OPEN fails, it sets $TEST to zero (0), and
+   GT.M executes the remainder of the line after the ELSE.
 
-2 $ZQGBLMOD()
-   $ZQGBLMOD()
+2 For
+   For
 
-   The $ZQGBLMOD function enables an application to determine  whether  it
-   can safely apply a lost transaction to the database. A lost transaction
-   is a transaction that  must  be  rolled  off  a  database  to  maintain
-   dual-site consistency.
+   The FOR command provides a looping mechanism in GT.M. FOR does not
+   generate an additional level in the M standard stack model.
 
-   The format for the $ZQGBLMOD function is:
+   The format of the FOR command is:
 
+   F[OR][lvn=expr[:numexpr1[:numexpr2]][,...]]]
 
-   $ZQGBLMOD(gvn)
+3 Examples
+   Examples
 
-   o    The subscripted  or  non-subscripted  global  variable  name  (gvn)
-        specifies the target node.
+   Example:
 
-   o    A return value of zero (0) means the value of the  global  variable
-        has not changed since the last synchronization of the  primary  and
-        secondary.
+   GTM>Kill i For i=1:1:5 Write !,i
+   1
+   2
+   3
+   4
+   5
+   GTM>Write i
+   5
+   GTM>
 
-   o    A return value of one (1) means the value of  the  global  variable
-        may have changed since the last synchronization of the primary and
-        secondary.
+   This FOR loop has a control variable, i, which has the value one (1) on
+   the first iteration, then the value two (2), and so on, until in the last
+   iteration i has the value five (5). The FOR terminates because
+   incrementing i would cause it to exceed the limit. Notice that i is not
+   incremented beyond the limit.
 
-   $ZQGBLMOD function produces an error if you submit an argument that is
-   not a global variable name.
+   Example:
 
-   Internally, $ZQGBLMOD (gvn) compares the GT.M transaction number in the
-   database block in which the global variable name  is  stored  with  the
-   value in the resync_tn field stored in the database file header.
-
-   For example, if x is the transaction number  of  the  level-0  database
-   block in which gvn resides, and y is the value of resync_tn  of  region
-   reg containing gvn, then the following is true:
-
-   o    If x £ y, no transaction modified the level-0 database block z in
-        which gvn resides since the  databases  at  primary  and  secondary
-        became synchronized with each other.  $ZQGBLMOD()  returns  a  zero
-        (0).
-
-   o    If x > y, some transaction modified z, but not necessarily
-❇❖■
-, after the primary and secondary system databases synchronized  with  each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-, after the primary and secondary system databases synchronized with each
-
-   If a transaction is a lost transaction that has been rolled back and it
-   is determined that for  all  the  M  globals  set  and  killed  in  the
-   transaction $ZQGBLMOD() is zero (0), it is probably safe to  apply  the
-   updates automatically. However, this determination of safety  can  only
-   be made by the application designer and not by GT.M. If the $ZQGBLMOD()
-   is one (1) for any set or kill in the transaction, it is  not  safe  to
-   apply the update.
-
-        The  test  of  $ZQGBLMOD()  and  applying  the  updates  must  be
-        encapsulated inside a GT.M transaction.
+   GTM>FOR x="hello",2,"goodbye" WRITE !,x
+   hello
+   2
+   goodbye
+   GTM>
 
-   Another approach to handling lost transactions would be to store in the
-   database the initial message sent by a client, as well as  the  outcome
-   and the response, and to reprocess the  message  with  normal  business
-   logic. If the outcome is  the  same,  the  transaction  can  be  safely
-   applied.
+   This FOR loop uses the control variable x and a series of arguments that
+   have no increments or limits. Notice that the control variable may have a
+   string value.
 
-        If  restartable  batch  operations  are  implemented,  lost  batch
-        transactions can be ignored since a subsequent batch  restart  will
-        process them correctly.
+   Example:
 
-2 $ZSEARCH()
-   $ZSEARCH()
+   GTM>For x="hello":1:-1 Write !,x
+   GTM>ZWRite x
+   x=0
+   GTM>
 
-   The $ZSEARCH function attempts to locate a file matching the specified
-   file name. If the file exists, it returns the file name;  if  the  file
-   does not exist, it returns the null string.
+   Because the argument has an increment, the FOR initializes the control
+   variable x to the numeric evaluation of "hello" (0). Then, GT.M never
+   executes the remainder of the line because the increment is positive, and
+   the value of the control variable (0) initializes to greater than the
+   limiting value (-1).
 
-   The format for the $ZSEARCH function is:
+   Example:
 
+   GTM>For y=-1:-3:-6,y:4:y+10,"end" Write !,y
+   -1
+   -4
+   -4
+   0
+   4
+   end
+   GTM>
 
-   $ZSEARCH(expr[,intexpr])
+   Example:
 
-   o    The expression contains a file name, with or without wildcards, for
-        which $ZSEARCH() attempts to  locate  a  matching  file.  Repeating
-        $ZSEARCH with the same filename uses the same context and return a
-        sequence of matching files when they exist; when  the  sequence  is
-        exhausted, $ZSEARCH() returns an empty string (""). Any  change  to
-        the file name starts a new context.
+   GTM>Set x="" For  Set x=$Order(ar(x)) Quit:x=""  Write !,x
 
-   o    $ZSEARCH() uses the  process  current  working  directory,  if  the
-        expression does not specify a directory.
+2 Goto
+   Goto
 
-   o    The optional integer expression specifies a "stream" number from 0
-        to 255 for each search; streams provide a means of having up to 256
-        $ZSEARCH() contexts simultaneously in progress.
+   The GOTO command transfers execution to a location specified by its
+   argument.
 
-   o    If a $ZSEARCH() stream has never been used  or  if  the  expression
-        differs from the argument to the last $ZSEARCH() of the stream, the
-        function resets the context and returns the first pathname matching
-        the expression; otherwise, it returns the  next  matching  file  in
-        collating sequence; if the last prior  pathname  returned  for  the
-        same expression and same stream  was  the  last  one  matching  the
-        argument, $ZSEARCH() returns a null string.
+   The format of the GOTO command is:
 
-   $ZSEARCH() provides a tool  for  verifying  that  a  file  exists.  For
-   information to help determine the validity of a file name, refer to the
-   section on $ZPARSE()
+   G[OTO][:tvexpr] entryref[:tvexpr][,...]
 
-3 Ex_of_$ZSEARCH()
-   Examples of $ZSEARCH()
+3 Examples
+   Examples
 
    Example:
 
+   GTM>GOTO TIME+4
 
-   GTM> WRITE $ZSEARCH("data.dat")
+   This GOTO command transfers control from Direct Mode to the line that is
+   four (4) lines after the line labeled TIME (in the currently active
+   routine). Using an offset is typically a debugging technique and rarely
+   used in production code.
 
-   /usr/staff/ccc/data.dat
+   Example:
 
-   GTM>
+   GOTO A:x<0,^A:x=0,A^B
 
-   This uses $ZSEARCH() to display the full file path name  of  "data.dat"
-   in the process current default directory.
+   This GOTO command transfers control to label A in the current routine, if
+   x is less than zero (0), to routine ^A if x is equal to zero (0), and
+   otherwise to label A in routine ^B. Once any of the transfers occurs, the
+   rest of the arguments have no effect.
 
-   Example:
+2 Halt
+   Halt
 
+   The HALT command stops the program execution and cause GT.M to return
+   control to the operating system environment that invoked the GT.M image.
 
-   GTM>SET x=$ZSEARCH("*.M")
+   The format of the HALT command is:
 
-   GTM>FOR S x=$ZSEARCH("*.M") Q:x="" W !,$ZPARSE(x,"NAME")
+   H[ALT][:tvexpr]
 
-   This FOR loop uses $ZSEARCH() and $ZPARSE() to display  M  source  file
-   names in the process current working  directory.  To  ensure  that  the
-   search starts at the beginning, the example resets the context by first
-   searching with a different argument.
+   Example:
 
-2 $ZTRNLNM()
-   $ZTRNLNM()
+   $ gtm
+   GTM>HALT
+   $
 
-   The $ZTRNLNM function gives  the  value  of  an  environment  variable.
-   $ZTRNLNM() does iterative translation in cases  where  one  environment
-   variable is set to the name of another environment variable.
+   Because we invoke this GT.M image interactively, the HALT in Direct Mode
+   leaves the process at the shell prompt.
 
-   The format for the $ZTRNLNM function is:
+2 Hang
+   Hang
 
+   The HANG command suspends GT.M program execution for a period of time
+   specified by the command argument.
 
-   $ZTRNLNM(expr)
+   The format of the HANG command is:
 
-   The expression specifies the target environment variable.
+   H[ANG][:tvexpr] numexpr[,...]
 
-3 Ex_of_$ZTRNLNM()
-   Examples of ZTRNLNM()
+3 Examples
+   Examples
 
    Example:
 
+   For  Quit:$Data(^CTRL(1))  Hang 30
 
-   GTM> write $ztrnlnm("gtm_dist")
+   This FOR loop repeatedly tests for the existence of ^CTRL(1), and
+   terminates when that global variable exists. Otherwise the routine HANGs
+   for 30 seconds and tests again.
 
-   /usr/dev/bin
+   Example:
 
-   GTM>
+   SET t=1 For  Quit:$Data(^CTRL(1))  Hang t If t<30 Set t=t+1
 
-   This uses $ZTRNLNM() to display the translation value for gtm_dist.
+   This is similar to the previous example, except that it uses an adaptive
+   time that lengthens from 1 second to a limit of 30 seconds if the routine
+   stays in the loop.
 
-1 Intr_Spe_Vars
-   Intrinsic Special Variables
+2 If
+   If
 
-   M Intrinsic Special Variables start with a single dollar sign ($). GT.M
-   provides such variables for program examination.  In  some  cases,  the
-   Intrinsic Special Variables may be set to modify the corresponding part
-   of the environment.
+   The IF command provides conditional execution of the remaining commands on
+   the line. When IF has an argument, it updates $TEST with the truth value
+   of its evaluated argument. GT.M executes the remainder of a line after an
+   IF statement when $TEST is 1 (TRUE). When $TEST is 0 (FALSE), GT.M does
+   not execute the rest of the line.
 
-        None of the Intrinsic Special Variables can be KILLed.  SETting  or
-        NEWing is generally not allowed, but is specifically noted  in  the
-        descriptions of those that do.
+   The format of the IF command is:
 
-2 $Device
-   $Device
+   I[F] [tvexpr[,...]]
 
-   $D[EVICE] reflects the status of the current device. If the  status  of
-   the device does not reflect any error-condition, the value of $DEVICE,
-   when interpreted as a truth-value is 0 (FALSE). If the  status  of  the
-   device  reflect  any  error-condition,  the  value  of  $DEVICE,  when
-   interpreted as a truth-value is 1 (TRUE).
+   Example:
+
+   IF A,B ...
+   is equivalent to
+   IF A IF B
 
-        The initial value of $DEVICE is implementation dependant. However,
-        if the initial value of $IO is the empty string, then  the  initial
-        value of $DEVICE is also empty string.
+   An IF with more than one argument behaves as if those arguments were
+   logically "ANDed." However, execution of the line ceases with the
+   evaluation of the first false argument. For IF argument expressions
+   containing the "AND" operator (&), execution still ceases with the
+   evaluation of the first false argument. Any global references within the
+   expression act in sequence to maintain the naked reference.
 
-   $DEVICE gives status code and meaning, in one access:
+3 Examples
+   Examples
 
    Example:
 
-   1,Connection reset by peer
-   The above message is displayed on  the  server  side  when  the  socket
-   device is closed on the client side.
-
-2 $ECode
-   $ECode
+   IF x=+x!(x="") Do BAL
 
-   $EC[ODE] contains a list of error codes for "active" errors -the error
-   conditions which are not yet resolved. If there are no  active  errors,
-   $ECODE contains the empty string. Whenever an error occurs, a code for
-   that error is appended to the value of $ECODE in such a  way  that  the
-   value of $ECODE always starts and ends with a comma.
+   In this example, the DO executes if x contains a number or a null string.
 
-   The value of $ECODE can be SET, and when it is set to a non-NULL value,
-   error processing starts.
+   Example:
 
-   List of codes for $ECODE start with comma seperated by commas.  A  code
-   starts with "M", "U", or "Z", with rest numeric. "M" codes are assigned
-   by MDC (MUMPS Development Committee), "U" by application (programmers),
-   and "Z" codes by MUMPS implementors (in this case GT.M).
+   Write !,?50,BAL If 'BAL Write "****"
+   IF  Set EMPTY(acct)=""
 
-   An error always has a GT.M specified code and many errors also have an
-   ANSI Standard code. The complete list of standardized error  codes  can
-   be referenced from  GT.M  Message  and  Recovery  Procedures  Reference
-   Manual version 4.3 and onwards.
+   The IF in the first line changes the value of $TEST, determining the
+   execution of the code following the argumentless IF in the second line.
+   Such argumentless IFs may serve as a form of line continuation.
 
+   Example:
 
-   IF $ECODE[",M61," WRITE "Undefined local variable"
+   GTM>Set X=1,Y=1,Z=2 Kill UNDEF
 
-        The leftmost character of the value of $ECODE is  always  a  comma.
-        This means that every error  code  that  is  stored  in  $ECODE  is
-        surrounded by commas. If $ECODE was  to  contains  the  error  code
-        without the commas (that is, "M61"), the variable would  check  for
-        subset "M6" as well. Thus, it is recommended that you  include  the
-        commas in the value to check. For  example;  check  whether  $ECODE
-        contains ",M61,".
+   GTM>If X=1,Y=1,Z=3,UNDEF=0 Write "HI"
 
-   $ECODE can be SET but not NEW'd. When $ECODE is set to the empty string
-   (" "), error handling becomes "inactive" and therefore  QUIT  does  not
-   trigger additional error handling.
+   GTM>
 
-   When $ECODE is not set to the empty string, M error handling is active,
-   which also affects behaviour in some aspects of $STACK.
+   The IF command causes GT.M to cease executing the line after it determines
+   Z is not equal to three (3). Therefore, GT.M never evaluates the reference
+   to the undefined variable and never generates an error.
 
-2 $EStack
-   $EStack
+   Example:
 
-   $ES[TACK] contains an integer count of the number of M virtual machine
-   stack levels that have been activated and not removed  since  the  last
-   time $ESTACK was NEW'd.
+   GTM>Set X=1 Kill UNDEF
+   GTM>If X=1!(UNDEF=3) Write "HI"
+   HI
+   GTM>
 
-   A NEW $ESTACK saves the value of current  $ESTACK  and  then  sets  its
-   value to zero (0). If  $ESTACK  has  not  been  NEW'd  in  the  current
-   execution path, $ESTACK=$STACK.
+2 Job
+   Job
 
+   The JOB command initiates another GT.M process that executes the named
+   routine.
 
-   SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
+   $ZJOB is set to the pid of the process created by the JOB command.
 
-   $ESTACK maybe used as  a  flag  to  indicate  error  traps  invoked  in
-   particular stack levels needed to  perform  some  different  action(s).
-   $ESTACK can be most useful in  setting  up  a  layered  error  trapping
-   mechanism.
+   The format of the JOB command is:
 
-        GT.M does not permit $ESTACK to be  SET,  however  $ESTACK  can  be
-        NEWed.
+   J[OB][:tvexpr] entryref[(expr[,...])]
+   [:[(keyword[=value][:...])][:numexpr]][,...]
 
-2 $ETrap
-   $ETrap
+3 The_JOB_Environment
+   The JOB Environment
 
-   $ET[RAP] contains a string value that GT.M invokes when an error occurs
-   during routine execution. When a process is initiated, but  before  any
-   commands are processed, the value of $ETRAP is empty string.
+   When the JOB is forked, UNIX creates the environment for the new process
+   by copying the environment of the process issuing the JOB command and
+   making a few minor modifications. By default, the standard input is
+   assigned to the null device, the standard output is assigned to
+   routinename.mjo, and the standard error is assigned to routinename.mje.
 
-   The value of this variable is the M[UMPS] code that gets executed when
-   an error occurs.
+3 JOB_Processparameters
+   JOB Processparameters
 
+   The following sections describe the processparameters available for the
+   JOB command in GT.M.
 
-   SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
+4 CMD[LINE]="strlit"
+   CMD[LINE]="strlit"
 
-   The value of $ETRAP is changed with the SET command. Changing the value
-   of $ETRAP with the SET command initiates a new trap; it does  not  save
-   the old trap.
+   The string literal specifies the $ZCMDLINE of the JOB'd process.
 
-   For more examples of the  use  of  special  variable  $ETRAP,  see  the
-   function $STACK().
+4 DEF[AULT]=strlit
+   DEF[AULT]=strlit
 
-2 $Horolog
-   $Horolog
+   The string literal specifies the default directory.
 
-   $H[OROLOG] contains a string value specifying the number of days since
-   "31 December, 1840," and the number of seconds since  midnight  of  the
-   current day, separated by a comma (,).
+   The maximum directory length is 255 characters.
 
-   At midnight, the piece of the string following the comma resets to zero
-   (0) and the piece preceding the comma increments by one (1). GT.M does
-   not permit the SET command to modify $HOROLOG.
+   If the JOB command does not specify a DEFAULT directory, GT.M uses the
+   current default directory of the parent process.
 
-   Example:
+4 ERR[OR]=strlit
+   ERR[OR]=strlit
 
+   The string literal specifies a value for stderr.
 
-   GTM> WRITE $HOROLOG
+   The maximum string length is 255 characters.
 
-   Produces the result 58883,55555 at 3:25:55 pm on 20 March, 2002.
+   By default, JOB constructs the error file from the routinename using a
+   file extension of .mje: the default directory of the process created by
+   the JOB command.
 
-   For further information on formatting $HOROLOG for  external  use,  see
-   the section on $ZDATE().
+4 GBL[DIR]=strlit
+   GBL[DIR]=strlit
 
-2 $Io
-   $IO
+   The string literal specifies a value for the environment variable
+   gtmgbldir.
 
-   $I[O] contains the name of the current device specified by the last USE
-   command. The M standard does not permit the SET command to modify $IO.
-   USE 0 produces the  same  $IO  as  USE  $P[RINCIPAL],  but  $P  is  the
-   preferred construct.
+   The maximum string length is 255 characters.
 
-2 $Job
-   $Job
+   By default, the job uses the same specification for gtmgbldir as that
+   defined in $ZGBLDIR for the process using the JOB command.
 
-   $J[OB] contains the current process identifier.
+4 IN[PUT]=strlit
+   IN[PUT]=strlit
 
-   $JOB is guaranteed  to  be  unique  for  every  concurrently  operating
-   process on a system. However, operating systems reuse PIDs  over  time.
-   GT.M does not permit the SET command to modify $JOB.
+   The string literal specifies a value for stdin.
 
-   Example:
+   The maximum string length is 255 characters.
 
+   GT.M does not supply a default file extension.
 
-   LOOP0 FOR SET itm=$O(^tmp($J,itm)) Q:itm="" DO LOOP1
+   By default, the job takes its input from the null device.
 
-   This uses $J as the first subscript in a  temporary  global  to  insure
-   that every process uses separate data space in the global ^tmp.
+4 OUT[PUT]=strlit
+   OUT[PUT]=strlit
 
-2 $Key
-   $Key
+   The string literal specifies a value for stdout.
 
-   $K[EY] contains the string that terminated the most recent READ command
-   from the current device  (including  any  introducing  and  terminating
-   characters). If no READ command s issued to the current device or if no
-   terminator is used, the value of $KEY is an empty string. However, when
-   input is terminated by typing a function key,  the  value  of  $KEY  is
-   equal to the string of characters that is transmitted by that function
-   key.
+   The maximum string length is 255 characters.
 
-   The effect of a READ *glvn on $KEY is unspecified.
+   By default, JOB constructs the output file pathname from the routinename
+   using a file extension of .mjo and the current default directory of the
+   process created by the JOB command.
 
-   If a Character Set Profile input-transform is in effect, then  this  is
-   also applied to the value stored in $KEY.
+4 STA[RTUP]="/path/to/shell/script"
+   STA[RTUP]="/path/to/shell/script"
 
-2 $Principal
-   $Principal
+   Specifies the location of the shell script that executes before running
+   the named routine.
 
-   $P[RINCIPAL] contains the absolute pathname of the  principal  (initial
-   $IO) device. $PRINCIPAL is an MDC Type A enhancement to standard M.
+   The JOBbed process spawns a shell session to execute the shell script. If
+   the shell script fails, the JOB'd process terminates without running the
+   named routine. Because STARTUP executes in a separate shell, it has no
+   impact on the environment of the JOB'd process, which is inherited from
+   the parent. STARTUP is useful for things like creating directories, for
+   example. Use PIPE devices instead of the JOB command to control the
+   environment of a spawned process.
 
-   Input and output for a process may come from separate devices, namely,
-   the standard input and output. However, the M I/O model allows only one
-   device to be USEd (or active) at a time. When and  image  starts,  GT.M
-   implicitly OPENs the standard input and standard output  device(s)  and
-   assigns the device(s) to $PRINCIPAL. For USE  deviceparameters,  it  is
-   the standard input that determines the device type.
+3 Examples
+   Examples
 
-   For an image invoked interactively, $PRINCIPAL is the user's terminal.
-   For an image invoked from a  terminal  by  means  of  a  shell  script,
-   $PRINCIPAL is the shell script's standard input (usually the terminal)
-   and standard output (also usually the terminal) for output, unless the
-   shell redirects the input or output.
+   Example:
 
-   GT.M provides a mechanism for the user to create a name for $PRINCIPAL
-   in  the  shell  before  invoking  GT.M.  The  environment  variable
-   gtm_principal, if defined becomes a synonym for the actual  device  and
-   the value for $PRINCIPAL. $IO holds the same value as $PRINCIPAL. $ZIO
-   in this case, holds the fully expanded name of the actual device. Refer
-   to $ZIO section in this chapter for an example of its usage.
+   GTM>JOB ^TEST("V54001","")
 
-   GT.M ignores a CLOSE specifying the principal  device.  GT.M  does  not
-   permit the SET command to modify $PRINCIPAL.
+   This creates a job that starts doing the routine ^TEST (with 2 parameters)
+   in the current working directory.
 
-2 $Quit
-   $Quit
+   Example:
 
-   $Q[UIT] indicates whether the current block of code was  called  as  an
-   extrinsic function or as a subroutine.
+   JOB PRINTLABELS(TYPE,PRNTR,WAITIM)
 
-   If $Q[UIT] contains 1 (when the current process-stack frame is invoked
-   by  an  extrinsic  function),  the  QUIT  would  therefore  require  an
-   argument.
+   This passes three values (TYPE, PRNTR, and WAITIM) to the new job, which
+   starts at the label PRINTLABELS of the current routine.
 
-        When a process is initiated, but before any commands are processed,
-        the value of $Q[UIT] is zero (0).
+2 Kill
+   Kill
 
-   This special variable is mainly used in error-trapping conditions. Its
-   value tells whether the current DO level was  reached  by  means  of  a
-   subroutine call (DO xxx) or by a function call (SET variable=$$xxx).
+   The KILL command deletes local or global variables and their descendant
+   nodes.
 
-   A typical way of exiting from an error trap is:
+   The format of the KILL command is:
 
-   QUIT:$QUIT "" QUIT
+   K[ILL][:tvexpr] [glvn|[(]lvn[,...][)][,...]]
 
-        GT.M does not permit $QUIT to be SET or NEWed.
+3 Examples
+   Examples
 
-2 $Reference
-   $Reference
+   Example:
 
-   $R[EFERENCE] contains the last global reference. Until the first global
-   reference is made by an M program, $REFERENCE contains the empty string
-   (""). This way it is useful in determining if  the  usage  of  a  naked
-   reference is valid.
+   GTM>Kill  Set a=0,a(1)=1,a(1,1)="under" KILL a(1) ZWR
+   a=0
+   GTM>
 
-   A typical way of using this is:
+   This uses an argumentless KILL to get a "fresh start" by deleting all
+   existing local variables. After SETting a, a(1), and a(1,1), the KILL
+   deletes a(1) and its descendants. The ZWRITE shows only a remaining.
 
+   Example:
 
-   IF $REFERENCE="" QUIT "<undefined>"
+   GTM>Kill (a,b),^AB(a,b)
 
-        $R[EFERENCE] being a read-only variable cannot be SET or NEW'd.
+   The first argument (an exclusive KILL) specifies to KILL all local
+   variables except a and b. The second argument deletes ^AB(a,b) and any
+   descendants of that global variable node.
 
-2 $STack
-   $STack
+   Example:
 
-   $ST[ACK] contains an integer value of zero (0)  or  greater  indicating
-   the current level of M execution stack depth.
+       kill *
 
-   When a process is initiated but before any  command  is  executed,  the
-   value of $STACK is zero (0).
+       write !,"gtm_stdxkill=",+$ztrnlnm("gtm_stdxkill"),!
 
-        The difference between $STACK  and  $ESTACK  is  that  $ESTACK  may
-        appear as an argument of the NEW command. NEWing $ESTACK resets its
-        value to zero (0), and can be useful to  set  up  a  layered  error
-        trapping mechanism.
+       set (A,B,C,E)="input"
+       do X(.A,.B)
+       zwrite
 
-   The value of $STACK is "absolute" since the start of a  GT.M.  process,
-   whereas  the  value  of  $ESTACK  is  "relative"  to  the  most  recent
-   "anchoring point".
+       write !,"____________",!
+       set (A,B,C,E)="input"
+       do Y(.A,.B)
+       zwrite
+       write !,"____________",!
+       set (A,B,C,E)="base"
+       set *C=A,*D=B
+       kill (C,D)
+       zwrite
+       quit
+   X(C,D)    set (C,D)="output"
+       kill (C,D)
+       quit
+   Y(C,D)    set (C,D)="output"
+       kill (A,C,D)
+       quit
 
-   For examples on the use of special variable $STACK, refer  to  $STACK()
-   in the "Functions" chapter in this manual.
+   Produces the following output:
 
-2 $Storage
-   $Storage
+   gtm_stdxkill=0
+   A="output"
+   B="output"
+   C="input"
 
-   $S[TORAGE] contains an integer value  specifying  the  number  of  free
-   bytes of address space remaining between  the  memory  currently  under
-   management by the process and the theoretical maximum available to the
-   process.
+   ____________
+   A="output"
+   B="output"
+   C="input"
 
-   GT.M uses memory for code (instructions) and data.  If  the  amount  of
-   virtual memory available to the process exceeds 2,147,483,647 bytes, it
-   is reported as 2,147,483,647 bytes.
+   ____________
+   A="base" ;*
+   B="base" ;*
+   *C=A
+   *D=B
 
-   Instruction space  starts  out  with  the  original  executable  image.
-   However, GT.M may  expand  instruction  space  by  ZLINKing  additional
-   routines.
+2 Kill_*
+   Kill *
 
-   Data space starts out with stack space that  never  expands,  and  pool
-   space which may expand.  Operations  such  as  opening  a  database  or
-   creating a local variable may cause an expansion in  pool  space.  GT.M
-   expands pool space in fairly large increments. Therefore, SETs of local
-   variables may not affect $STORAGE at all or  may  cause  an  apparently
-   disproportionate drop in its value.
+   KILL * removes the association between its arguments, and any associated
+   arrays. The arguments are left undefined, just as with a standard KILL. If
+   the array has no remaining associations after the KILL *, GT.M can reuse
+   the memory it occupied. If there are no array(s) or association(s) the
+   KILL * happily and silently does nothing.
 
-   Once a GT.M process adds either instruction or  data  space,  it  never
-   releases that space.  However,  GT.M  does  reuse  process  space  made
-   available by actions such as KILLs of  local  variables.  $STORAGE  can
-   neither be SET or NEWed.
+   The format of the KILL * command is:
 
-2 $SYstem
-   $SYstem
+   K[ILL][:tvexpr] *{lvn | name}[,...]
 
-   $SY[STEM] contains a string that identifies the executing  M  instance.
-   The value of $SYSTEM is a string that starts with a unique numeric code
-   that identifies the manufacturer. Codes are assigned by the MDC (MUMPS
-   Development Committee).
+3 Examples
+   Examples
 
-   $SYSTEM in GT.M starts with "47" followed by a comma and the evaluation
-   of the environment variable gtm_sysid. If the name has  no  evaluation,
-   the value after the comma is gtm_sysid.
+   Example
 
-2 $Test
-   $Test
+   GTM>Set A=1,*B=A ; Create an array and an association
 
-   $T[EST] contains a truth value specifying the evaluation of the last IF
-   argument or the result of the last operation with timeout. If the last
-   timed operation timed out, $TEST  contains  FALSE  (0);  otherwise,  it
-   contains TRUE (1).
+   GTM>ZWRite ; Show that the array and association exist
+   A=1 ;*
+   *B=A
+   GTM>Kill *A ; Remove the association for A - it now has no association and no array
 
-   $TEST  serves  as  the  implicit  argument  for  ELSE  commands  and
-   argumentless IF commands.
+   GTM>ZWRite ; B is a traditional local variable
+   B=1
 
-   M  stacks  $TEST  when  invoking  an  extrinsic  and  performing  an
-   argumentless DO. After these operations complete with  an  implicit  or
-   explicit QUIT, M restores the  corresponding  stacked  value.  Because,
-   with these two exceptions, $TEST  reflects  the  last  IF  argument  or
-   timeout result on a process wide basis. Use  $TEST  only  in  immediate
-   proximity to the operation that last updated it.
+   Example:
 
-   M routines cannot modify $TEST with the SET command.
+   GTM>Set A=2 ; add a value for A
 
-   Example:
+   GTM>ZWRite ; A and B have different values and both are traditional local variables
+   A=2
+   B=1
+   GTM>
 
+   KILL on the other hand, removes data in the array (and possibly the array
+   itself) without affecting any alias association.
 
-   IF x=+x DO ^WORK
+   GTM>Set A=2,*B=A ; Create an array and an association
 
-   ELSE SET x=0
+   GTM>ZWRite ; Both array and association exist
+   A=2 ;*
+   *B=A
+   GTM>Kill A ; Kill the array
 
-   The ELSE statement causes M to use the  value  of  $TEST  to  determine
-   whether to execute the rest of the line. Because the  code  in  routine
-   WORK may use IFs and timeouts, this use of $TEST is not recommended.
+   GTM>ZWRite ; There's no data to show - only the association
+   *B=A
 
-   Example:
+   GTM>Set B=3 ; Create a new value
 
+   GTM>ZWRite ; The association was unaffected by the Kill
+   A=3 ;*
+   *B=A
+   GTM>
 
-   SET MYFLG=x=+x
+   Example:
 
-   IF MYFLG DO ^WORK
+   $ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^killalias
+   killalias ; Demonstrate Kill * of pass by reference
+          ZPrint ; Print this program
+          Set A=1,C=3
+          Write "------------",!
+          Write "Initial Values:",!
+          ZWRite
+          Do K1(.A,.C) ; Pass A & C by reference
+          Write "------------",!
+          Write "Value of A is unchanged because of Kill *B, but C has changed: ",!
+          ZWRite
+          Quit
+   ;
+   K1(B,D) ; A & C are bound to B & D respectively
+          Write "------------",!
+          Write "A & B are aliases, as are C & D:",!
+          ZWRite
+          Kill *B
+          Set B=2,D=4
+          Write "------------",!
+          Write "After Kill *B, A & B are different but C & D remain associated:",!
+          ZWrite
+          Quit
+   ------------
+   Initial Values:
+   A=1
+   C=3
+   ------------
+   A & B are aliases, as are C & D:
+   A=1 ;*
+   *B=A
+   C=3 ;*
+   *D=C
+   ------------
+   After Kill *B, A & B are different but C & D remain associated:
+   A=1
+   B=2
+   C=4 ;*
+   *D=C
+   ------------
+   Value of A is unchanged because of Kill *B, but C has changed:
+   A=1
+   C=4
+
+   Example:
+
+   GTM>Set A=1,*B=A ; Create an array and association
+   GTM>ZWRite ; Verify that it's there
+   A=1 ;*
+   *B=A
+
+   GTM>Kill (A) ; Kill everything except A
+
+   GTM>ZWRite ; Demonstrate that A also has no array
+
+   GTM>Set A=2 ; Create an array
+
+   GTM>ZWRite ; The association survived the Kill
+   A=2 ;*
+   *B=A
+   GTM>
 
-   IF 'MYFLG SET x=0
+2 Lock
+   Lock
 
-   This example introduces a local variable flag to address  the  problems
-   of the prior example. Note that its behavior results  in  the  opposite
-   $TEST value from the prior example.
+   The LOCK command reserves and releases resource names, and provides a
+   semaphore capability for GT.M processes. This capability can be used for
+   interprocess synchronization and signaling.
 
-   Example:
+   Assigning a LOCK does not specify any explicit control over variables and
+   does not directly effect either read or write access to global (or local)
+   data. However, an application that adheres to clearly defined conventions
+   of LOCKing before any access can indirectly achieve such an effect.
 
+   FIS recommends implementing database Consistency using transaction
+   processing rather than LOCKs. If you wish to avoid GT.M's use of
+   optimistic concurrency for TP, place the LOCK just before the original
+   TSTART and release it after the final TCOMMIT.
 
-   IF x=+x DO ^WORK IF 1
+   The format of the LOCK command is:
 
-   ELSE SET x=0
+   L[OCK][:tvexpr] [[-|+]nref|(nref[,...])[:numexpr] [,...]]
 
-   This example uses the IF 1 to ensure that the ELSE works counter to the
-   IF.
+2 Merge
+   Merge
 
-2 $TLevel
-   $TLevel
+   The MERGE command copies a variable and all its descendants into another
+   variable. MERGE does not delete the destination variable, nor any of its
+   descendants.
 
-   $TL[EVEL] contains a count  of  executed  TSTARTs  that  are  currently
-   unmatched by TCOMMITs. $TLEVEL is zero (0) when there is no TRANSACTION
-   in progress. When $TLEVEL is greater than one (>1), it  indicates  that
-   there are nested sub-transactions  in  progress.  Sub-transactions  are
-   always subject to the completion of the main TRANSACTION and cannot be
-   independently acted upon by COMMIT, ROLLBACK, or RESTART.
+   The format of MERGE command is:
 
-   $TLEVEL can be used to determine whether  there  is  a  TRANSACTION  in
-   progress and to determine the level of nesting of sub-transactions.
+   M[ERGE][:tvexpr] glvn1=glvn2[,...]
 
-   M routines cannot modify $TLEVEL with SET.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>Set ^gbl1="one"
 
-   IF $TLEVEL TROLLBACK
+   GTM>Set ^gbl1(1,1)="oneone"
 
-   This example performs a TROLLBACK if a transaction is  in  progress.  A
-   statement like this should  appear  in  any  error  handler  used  with
-   transaction processing. For more information on transaction processing
-   refer  to  the  "General  Language  Features  of  M"  chapter  in  GT.M
-   Programmer's Guide.
+   GTM>Set ^gbl1(1,1,3)="oneonethree"
 
-2 $TRestart
-   $TRestart
+   GTM>Set ^gbl1(1,2,4)="onetwofour"
 
-   $TR[ESTART] contains a  count  of  the  number  of  times  the  current
-   TRANSACTION has been RESTARTed. A RESTART can be explicit (specified in
-   M as a TRESTART) or implicit (initiated by GT.M as part of its internal
-   concurrency  control  mechanism).  When  there  is  no  TRANSACTION  in
-   progress, $TRESTART is zero (0).
+   GTM>Set ^gbl2(2)="gbl2_2"
 
-   $TRESTART can be used  by  the  application  to  limit  the  number  of
-   RESTARTs, or to cause a routine to perform different actions  during  a
-   RESTART than during the initial execution.
+   GTM>Set ^gbl2(2,1,3)="gbl2_2_1_3"
 
-        GT.M does not permit the SET command to modify $TRESTART.
+   GTM>Set ^gbl2(2,1,4,5)="gbl2_2_1_4_5"
 
-   Example:
+   GTM>Merge ^gbl1(1)=^gbl2(2)
 
+   GTM>WRITE $Reference
+   ^gbl1(1)
+   GTM>ZWRite ^gbl1
+   ^gbl1="one"
+   ^gbl1(1)="gbl2_2"
+   ^gbl1(1,1)="oneone"
+   ^gbl1(1,1,3)="gbl2_2_1_3"
+   ^gbl1(1,1,4,5)="gbl2_2_1_4_5"
+   ^gbl1(1,2,4)="onetwofour"
+   GTM>ZWRITE ^gbl2
+   ^gbl2(2)="gbl2_2"
+   ^gbl2(2,1,3)="gbl2_2_1_3"
+   ^gbl2(2,1,4,5)="gbl2_2_1_4_5"
+   GTM>
 
-   TRANS TSTART ():SERIAL
+   This example illustrates how MERGE copies a sub-tree of one global into
+   another. The nodes in the sub-tree of ^gbl(2), for which $DATA() value is
+   1 or 11, are copied to sub-tree of ^gbl1(1) as follows:
 
-   IF $TRESTART>2 WRITE !;"Access Conflict" QUIT
+   ^gbl1(1) is updated from the value of ^gbl2(2)
+   ^gbl1(1,1,3) is updated from the value of ^gbl2(2,1,3)
+   ^gbl1(1,1,4,5) is updated from the value of ^gbl2(2,1,4,5)
 
-   This example terminates the sub-routine with a message if the number of
-   RESTARTs exceeds 2.
+   Since ^gbl1(2,1) and ^gbl2(2,2,4) do not have values ($DATA()=0), the
+   corresponding nodes ^gbl1(1,1) and ^gbl(1,2,4) respectively are left
+   unchanged. The naked indicator takes the value ^gbl(1) as if SET replaced
+   MERGE. Notice that the MERGE command does not change ^gbl2(2) or its
+   descendants. Ancestor nodes of ^gbl(1) are also left unchanged.
 
-   For more information on transaction processing, refer to the section on
-   that topic in the "General Language Features  of  M"  chapter  in  GT.M
-   Programmer's Guide.
+   Example:
 
-2 $X
-   $X
+   GTM>Kill
 
-   $X contains an integer value ranging from 0 to 65,535,  specifying  the
-   horizontal position of a virtual cursor in the current  output  record.
-   $X=0 represents the left-most position of a record or row.
+   GTM>Set ^gbl(1,2)="1,2"
 
-   Every OPEN device has a $X. However, M only accesses $X of the current
-   device.  Therefore,  exercise  care  in  sequencing  USE  commands  and
-   references to $X.
+   GTM>Merge lcl(3,4)=^gbl(1)
 
-   Generally, GT.M increments $X for every character written to  and  read
-   from the current device. M format control characters, write filtering,
-   and the device WIDTH also have an effect on $X.
+   GTM>Set ^("naked")=2
 
-   $X never equals or exceeds the value of the device WIDTH.  Whenever  it
-   reaches the value equal to the device WIDTH, it gets reset to zero (0).
+   GTM>ZWRite ^gbl
+   ^gbl(1,2)="1,2"
+   ^gbl("naked")=2
+   GTM>ZWRite lcl
+   lcl(3,4,2)="1,2"
+   GTM>
 
-   GT.M follows the MDC Type A recommendation and permits an M routine to
-   SET $X. However, SET $X does not automatically issue device commands or
-   escape sequences to reposition the physical cursor.
+   This example illustrates how MERGE creates a sub-tree of a variable when
+   the variable does not exist. Also, notice how the naked indicator is set
+   when the source of the MERGE is a global and the destination a local.
 
-   For more information on $X,  refer  to  the  "Input/Output  Processing"
-   chapter in GT.M Programmer's Guide.
+2 New
+   New
 
-2 $Y
-   $Y
+   The NEW command "stacks" copies of local variables and reinitializes those
+   variables. An explicit or implicit QUIT from a DO, XECUTE or extrinsic
+   function "unstacks" the NEWed variables, that is, restores the variable to
+   the stacked value. A NEW lasts only while the current scope of execution
+   is active.
 
-   $Y contains an integer value ranging from 0 to  65,535  specifying  the
-   vertical position of a virtual cursor in the current output page. $Y=0
-   represents the top row or line.
+   The format of the NEW command is:
 
-   Every OPEN device has a $Y. However, M only accesses $Y of the current
-   device.  Therefore,  exercise  care  in  sequencing  USE  commands  and
-   references to $Y.
-
-   When GT.M  finishes  the  logical  record  in  progress,  it  generally
-   increments $Y. GT.M recognizes the end of  a  logical  record  when  it
-   processes certain M format  control  characters,  or  when  the  record
-   reaches its maximum size, as determined by the device  WIDTH,  and  the
-   device is set to WRAP. The definition of "logical record"  varies  from
-   device to device. For an exact definition, see  the  sections  on  each
-   device type. Write filtering and the device LENGTH also have an effect
-   on $Y.
+   N[EW][:tvexpr] [[(]lvn[,...][)][,...]]
 
-   $Y never equals or exceeds the value of the device LENGTH. Whenever it
-   reaches the value equal to the device LENGTH, it gets reset to zero (0)
+3 Examples
+   Examples
 
-   GT.M permits an  M  routine  to  SET  $Y.  However,  SET  $Y  does  not
-   automatically issue device commands or escape sequences  to  reposition
-   the physical cursor.
+   Example:
 
-   For more information on $Y,  refer  to  the  "Input/Output  Processing"
-   chapter in GT.M Programmer's Guide.
+   NEW1;
+     Set A(1)=1,B=4,C=5
+     Write !,"VARIABLES BEFORE NEW:",!
+     ZWRite
+     Do LABEL
+     Write !,"VARIABLES AFTER RETURN:",!
+     ZWRite
+     Quit
+   LABEL
+     New A Set C=7
+     Write !,"VARIABLES AFTER NEW:",!
+     ZWRite
+     Quit
 
-2 $ZA
-   $ZA
+   Produces the results:
+
+   VARIABLES BEFORE NEW:
+   A(1)=1
+   B=4
+   C=5
+   VARIABLES AFTER NEW:
+   B=4
+   C=7
+   VARIABLES AFTER RETURN:
+   A(1)=1
+   B=4
+   C=7
 
-   $ZA contains a status determined by the last read on  the  device.  The
-   value is a decimal integer with a meaning determined by the  device  as
-   follows:
+   Example:
 
-   For Terminal I/O:
+   NEW2;
+     Set (A,B,C,D)="TEST"
+     Do LABEL
+     Write !,"VARIABLES AFTER RETURN:",!
+     ZWRite
+     Quit
+   LABEL
+     New (B,C) SET (A,B,Z)="NEW"
+     Write !,"VARIABLES AFTER EXCLUSIVE NEW:",!
+     ZWRite
+     Quit
 
-        0 Indicating normal termination of a read operation
-        1 Indicating a parity error
-        2 Indicating that the terminator sequence was too long
-        9 Indicating a default for all other errors
-   For Sequential Disk Files I/O:
+   Produces the results:
 
-        0 Indicating normal termination of a read operation
-        9 Indicating a failure of a read operation
-   For Fifos I/O:
+   VARIABLES AFTER EXCLUSIVE NEW:
+   A="NEW"
+   B="NEW"
+   C="TEST"
+   Z="NEW"
+   VARIABLES AFTER RETURN:
+   A="TEST"
+   B="NEW"
+   C="TEST"
+   D="TEST"
 
-   Decimal representing $JOB (identifier) of the process  that  wrote  the
-   last message the current process read
-   $ZA refers to the status of the  current  device.  Therefore,  exercise
-   care in sequencing USE commands and references to $ZA.
+   Example:
 
-   GT.M does not permit the SET command to modify $ZA.
+   /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias
+   stackalias ; Demonstrate New with alias
+     ZPrint ; Print this program
+     Set A=1,*B=A,*C(2)=A ; Create some aliases
+     Write "------------",!
+     Write "ZWRite in the caller before subprogram",!
+     ZWRite
+     Do S1 ; Call a subprogram
+     Write "------------",!
+     Write "ZWRite in the caller after subprogram - A association is restored",!
+     ZWRite
+     Quit
+    ;
+   S1  ; Subprogram
+     New A
+     Set A="I am not an alias",B="I am an alias"
+     Write "------------",!
+     Write "ZWRite in the subprogram with new A and modified B",!
+     ZWRite
+     Quit
+   ------------
+   ZWRite in the caller before subprogram
+   A=1 ;*
+   *B=A
+   C=3
+   *C(2)=A
+   D=4
+   ------------
+   ZWRite in the subprogram with new A and modified B
+   A="I am not an alias"
+   B="I am an alias" ;*
+   C=3
+   *C(2)=B
+   D=4
+   ------------
+   ZWRite in the caller after subprogram - A association is restored
+   A="I am an alias" ;*
+   *B=A
+   C=3
+   *C(2)=A
+   D=4
+
+   The following is essentially the same as the prior example but using an
+   exclusive NEW:
+
+   $ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias1
+   stackalias1 ; Demonstrate New with alias
+     ZPrint ; Print this program
+     Set A=1,*B=A,*C(2)=A ; Create some aliases
+     Write "------------",!
+     Write "ZWRite in the caller before subprogram",!
+     ZWRite
+     Do S1 ; Call a subprogram
+     Write "------------",!
+     Write "ZWRite in the caller after subprogram - A association is restored",!
+     ZWRite
+     Quit
+    ;
+   S1  ; Subprogram
+     New (B)
+     Set A="I am not an alias",B="I am an alias"
+     Write "------------",!
+     Write "ZWRite in the subprogram - Notice B is flagged as an alias",!
+     ZWRite
+     Quit
+   ------------
+   ZWRite in the caller before subprogram
+   A=1 ;*
+   *B=A
+   C=3
+   *C(2)=A
+   D=4
+   ------------
+   ZWRite in the subprogram - Notice B is flagged as an alias
+   A="I am not an alias"
+   B="I am an alias" ;*
+   ------------
+   ZWRite in the caller after subprogram - A association is restored
+   A="I am an alias" ;*
+   *B=A
+   C=3
+   *C(2)=A
+   D=4
+
+   An exclusive New can create a scope in which only one association between
+   a name or an lvn and an array may be visible. In this case, ZWRITE
+   nevertheless shows the existence of an alias, even when that array is
+   accessible from only one name or lvn.
 
-   For more information on $ZA, refer  to  the  "Input/Output  Processing"
-   chapter in GT.M Programmer's Guide.
+2 Open
+   Open
 
-2 $ZB
-   $ZB
+   The OPEN command creates a connection between a GT.M process and a device.
 
-   $ZB contains a string specifying the  input  terminator  for  the  last
-   terminal READ. $ZB contains null and  is  not  maintained  for  devices
-   other than terminals. $ZB may contain any legal input terminator, such
-   as <CR> (ASCII 13) or an escape sequence  starting  with  <ESC>  (ASCII
-   27), from zero (0) to 15 bytes in length. $ZB  contains  null  for  any
-   READ terminated by a timeout or any  fixed-length  READ  terminated  by
-   input reaching the maximum length.
+   The format of the OPEN command is:
 
-   $ZB contains the actual character string, not  a  sequence  of  numeric
-   ASCII codes.
+   O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])] [:numexpr]][,...]
 
-   Example:
+2 Quit
+   Quit
 
+   Except when a QUIT appears on a line after a FOR, the QUIT command
+   terminates execution of the current GT.M invocation stack level initiated
+   by a DO, XECUTE, extrinsic function or special variable, and return
+   control to the next "lower" level. In this case, QUIT restores any values
+   stacked at the current level by NEWs or by parameter passing. A QUIT
+   command terminates any closest FOR command on the same line. Note that M
+   overloads the QUIT command to terminate DO, FOR, XECUTE and extrinsics
+   ($$) of which FOR is the most different.
 
-   SET zb=$ZB FOR i=1:1:$L(zb) WRITE !,i,?5,$A(zb,i)
+   The format of the QUIT command is:
 
-   This displays the series of ASCII codes for the characters in $ZB.
+   Q[UIT][:tvexpr] [expr]
 
-   $ZB  refers  to  the  last  READ  terminator  of  the  current  device.
-   Therefore, exercise care in sequencing USE commands and  references  to
-   $ZB.
+3 Examples
+   Examples
 
-   GT.M does not permit the SET command to modify $ZB.
+   Example:
 
-   For more information on $ZB, refer  to  the  "Input/Output  Processing"
-   chapter in GT.M Programmer's Guide.
+        Do A
+        Quit
+   A    Write !,"This is label A"
 
-2 $ZCMdline
-   $ZCMdline
+   The explicit QUIT at the line preceding the label A prevents line A from
+   executing twice. The sub-routine at line A terminates with the implicit
+   QUIT at the end of the routine.
 
-   $ZCM[DLINE] contains a string value specifying the "excess" portion of
-   the command line that invoked the GT.M process. By  "excess"  is  meant
-   the portion of the command line that is left after GT.M has done all of
-   its command line processing. For example, a command line mumps -direct
-   extra1 extra2 causes GT.M  to  process  the  command  line  upto  mumps
-   -direct and place the "excess" of the command  line,  that  is  "extra1
-   extra2" in $ZCMDLINE. $ZCMDLINE gives the M routine access to the shell
-   command line input.
+   Example:
 
-   Note  that  the  actual  user  input  command  line  might  have  been
-   transformed by the shell (for example, removing one  level  of  quotes,
-   filename, and wildcard  substituion,  and  so  on.),  and  it  is  this
-   transformed command line that GT.M processes.
+          Write $$ESV
+           Quit
+   ESV()
+           QUIT "value of this Extrinsic Special Variable"
 
-   M routines cannot modify $ZCMDLINE.
+   Because the label ESV has an argument list (which is empty), GT.M can only
+   legally reach that label with a extrinsic invocation. The QUIT on the
+   second line prevents execution from erroneously "falling through" to the
+   line labelled ESV. Because ESV identifies a subroutine that implements an
+   extrinsic special variable, the QUIT on the line after ESV has an argument
+   to provide the value of the extrinsic.
 
    Example:
 
+   Set x="" For  Set x=$Order(^BAL(x)) Quit:x]]"AR5999"!'$Length(x)  DO STF
 
-   $ cat > test.m
-
-   write " $ZCMDLINE=",$ZCMDLINE,!
+   The postconditional QUIT terminates the FOR loop. Note the two spaces
+   after the QUIT because it has no argment.
 
-   quit
+2 Read
+   Read
 
-   $ mumps -run test OTHER information
+   The READ command transfers the input from the current device to a global
+   or local variable specified as a READ argument. For convenience, READ also
+   accepts arguments that perform limited output to the current device.
 
-   $ZCMDLINE=OTHER information
+   The format of the READ command is:
 
-   $
+   R[EAD][:tvexpr] (glvn|*glvn|glvn#intexpr)[:numexpr]|strlit|fcc[,...]
 
-   This creates the program test.m, which writes the value  of  $ZCMDLINE.
-   Note how the two spaces specified in OTHER information in  the  command
-   line gets transformed  to  just  one  space  in  OTHER  information  in
-   $ZCMDLINE due to the shell's pre-processing.
+2 Set
+   Set
 
-2 $ZCOmpile
-   $ZCOmpile
+   SET assigns values to variables or to a selected portion of a variable.
 
-   $ZCO[MPILE] contains a string value composed of one or more qualifiers
-   that control the GT.M compiler. Explicit  ZLINKs  and  auto-ZLINKs  use
-   these qualifiers as defaults for any compilations that they perform.
+   The format of the SET command is:
 
-   $ZCOMPILE is a read-write ISV, that is, it can appear on the left side
-   of the equal sign (=) in the argument to the SET command.  A  $ZCOMPILE
-   value has the form of a list of M command qualifiers each separated by
-   a space ( ).
+   S[ET][:tvexpr] glvn|$EXTRACT()|$PIECE()|(glvn[,...])=expr[,...]
 
-   When the environment variable gtmcompile is defined,  GT.M  initializes
-   $ZCOMPILE to the translation of gtmcompile. Otherwise GT.M initializes
-   $ZCOMPILE to null. Changes to the value  of  $ZCOMPILE  during  a  GT.M
-   invocation only last for the current invocation and do not  change  the
-   value of the environment variable gtmcompile.
+   Because GT.M does not require predeclaration or typing of variables, a SET
+   withproper syntax always succeeds regardless of the prior state or value
+   of the variable, as long as GT.M can evaluate the expression to the right
+   of the equal sign (=).
 
-   When $ZCOMPILE is null, GT.M uses  the  default  M  command  qualifiers
-   -IGNORE, -LABEL=LOWER, -NOLIST, and  -OBJECT.  Refer  to  the  "Program
-   Development Cycle" chapter in this manual for detailed descriptions of
-   the M command qualifiers.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>Kill  Set a="x",(b,c)=1, at a="hello" ZWRite
+   a=x
+   b=1
+   c=1
+   x="hello"
+   GTM>
 
-   $ setenv gtmcompile "-LIST -LENGTH=56 -SPACE=2"
-
-   $ gtm
+   The KILL command deletes any previously defined local variables. The SET
+   command has three arguments. The first shows a simple direct assignment.
+   The second shows the form that assigns the same value to multiple
+   variables. The third shows atomic indirection on the left of the equal
+   sign. The ZWRITE command displays the results of the assignments.
 
-   GTM>WRITE $ZCOMPILE
+   Example:
 
-   -LIST -LENGTH=56 -SPACE=2
+   GTM>Set ^(3,4)=^X(1,2)
 
-   GTM>SET $ZCOMPILE="-LIST -NOIGNORE"
+   Because GT.M evaluates the right-hand side of the equal sign before the
+   left-hand side within a SET argument, the right-hand expression determines
+   the naked reference indicator prior to evaluation of the left-hand side.
+   Therefore, this example assigns ^X(1,3,4) the value of ^X(1,2).
 
-   GTM>WRITE $ZCOMPILE
+   Example:
 
-   -LIST -NOIGNORE
+   GTM>Kill x Set $Piece(x,"^",2)="piece 3" ZWRite x
+   x="^^piece 3"
+   GTM>
 
-   GTM>ZLINK "A.m"
+   This SET demonstrates a "set piece" and shows how SET generates missing
+   delimiters when required.
 
-   GTM>HALT
+   Example:
 
-   $ echo $gtmcompile
+   GTM>Set x="I love hotdogs"
 
-   -LIST -LENGTH=56 -SPACE=2
+   GTM>Set $Extract(x,3,6)="want"
 
-   This example  uses  the  environment  variable  gtmcompile  to  set  up
-   $ZCOMPILE. Then it modifies $ZCOMPILE with the SET command.  The  ZLINK
-   argument specifies a file with a .m extension (type),  which  forces  a
-   compile. The compile produces a listing for routine A.m  and  does  not
-   produce an object module if A.m contains compilation errors. After GT.M
-   terminates, the shell command echo $gtmcompile  demonstrates  that  the
-   SET command did not change the environment variable.
+   GTM>Write x
+   I want hotdogs
+   GTM>Set $Extract(x,7)=" many "
 
-2 $ZCstatus
-   $ZCstatus
+   GTM>Write x
+   I want many hotdogs
+   GTM>
 
-   $ZC[STATUS] holds the value of the status code for the last compilation
-   performed by a ZCOMPILE command.
+   The SET $EXTRACT command replaces and extracts the specified characters
+   with the value of the expression on the right hand side of the equal-sign
+   (=).
 
-   GT.M does not permit the SET command to modify $ZSTATUS.
+2 Set_*
+   Set *
 
-2 $ZDAteform
-   $ZDAteform
+   A SET * command explicitly creates an alias.
 
-   $ZDA[TEFORM] contains an integer  value,  specifying  the  output  year
-   format of $ZDATE(). $ZDATEFORM can be modified using the  SET  command.
-   GT.M initializes $ZDATEFORM  to  the  translation  of  the  environment
-   variable  gtm_zdate_form.  If  gtm_zdate_form  is  not  defined,  GT.M
-   initializes $ZDATEFORM to zero (0).
+   The format of a SET * command is:
 
-   Refer  to  "Functions"  and  "M  utility  Routines"  chapter  in  GT.M
-   Programmer's Guide for more details.
+   S[ET][:tvexpr] *lvn|name1=name2[,...]
 
    Example:
 
+   GTM>ZWRite ; Nothing there
 
-   GTM>WRITE $ZDATEFROM
+   GTM>Set *A=B ; Create an association
 
-   0
-   GTM>WRITE $ZDATE($H)
+   GTM>ZWRite ; Still no data to look at
 
-   11/15/02
-   GTM>SET $ZDATEFORM=1
+   GTM>Set A("Malvern")="Pennsylvania" ; Create a node
 
-   GTM>WRITE $ZDATE($H)
+   GTM>ZWRite ; Now both have values
+   A("Malvern")="Pennsylvania"
+   *B=A
+   GTM>
 
-   11/15/2002
-2 $ZDirectory
-   $ZDirectory
+   Creating an alias container variable not only creates the association but
+   also assigns data (the empty string) to the alias container node:
+
+   GTM>ZWRite ; Nothing there
+
+   GTM>Set *C("I am a container")=D
 
-   $ZD[IRECTORY] contains the string value of the full path of the current
-   directory. Initially $ZDIRECTORY contains the default/current directory
-   from which the GT.M image/process was activated.
+   GTM>ZWRite ; Both array for C and association for C("I am a container") are visible
+   *C("I am a container")=D
+   GTM>Set D=4,D("Jacksonville")="Florida" ; The array for D comes into existence
+   GTM>ZWRite ; All is revealed
+   *C("I am a container")=D
+   D=4 ;*
+   D("Jacksonville")="Florida"
+   GTM>
 
-   If the current directory does not exist at the  time  of  GT.M  process
-   activation, GT.M errors out.
+   Attempting to create an alias from subscripted lvn that is not an alias
+   container variable triggers an error. Continuing the previous example:
 
-   Example:
+   GTM>Set *E=C("I am a container") ; This works because C("I am a container") is a container
 
+   GTM>Set *F=C(4) ; But this fails because C(4) is not a container
+   %GTM-E-UNDEF, Undefined local variable: C(4)
 
-   GTM>WRITE $ZDIR
+   GTM>ZWRite E,F ; Note that E has the value originally assigned to D but F remains undefined
+   E=4 ;*E("Jacksonville")="Florida"
+   %GTM-E-UNDEF, Undefined local variable: F
 
-   /usr/tmp
+   GTM>
 
-   GTM>SET $ZDIR=".."
+2 TCommit
+   TCommit
 
-   GTM>WRITE $ZDIR
+   The TCOMMIT command marks the end of a transaction or sub-transaction and
+   decrements $TLEVEL. If TCOMMIT marks the end of a transaction (decrements
+   $TLEVEL to zero), it invokes a COMMIT, which makes the database updates
+   performed by the transaction generally available. A TCOMMIT issued when no
+   transaction is in progress ($TLEVEL=0) produces an error.
 
-   /usr
+   The format of the TCOMMIT command is:
 
-   This example displays the current working directory and  changes  $ZDIR
-   to the parent directory.
+   TC[OMMIT][:tvexpr]
 
-   $ZDIRECTORY is a read-write Intrinsic Special Variable, that is, it can
-   appear on the left side of the equal sign (=) in the argument to a SET
-   command. If an attempt is made to set  $ZDIRECTORY  to  a  non-existent
-   directory specification, GT.M issues an error and keeps  the  value  of
-   $ZDIRECTORY unchanged.
+   For an example of the use of the TCOMMIT command, refer to the chapter on
+   General Language Features of M in GT.M Programmer's Guide.
 
-   At image exit, GT.M restores the current  directory  to  the  directory
-   that was the current directory when  GT.M  was  invoked  even  if  that
-   directory does not exist.
+2 TREstart
+   TREstart
 
-2 $ZEDit
-   $ZEDit
+   The TRESTART command attempts to RESTART the current transaction. A
+   RESTART transfers control back to the initial TSTART and restores much of
+   the process state to what it was when that TSTART was originally executed.
+   A TRESTART issued when no transaction is in progress ($TLEVEL=0) or when
+   the transaction does not have RESTART enabled produces an error.
+
+   A TRESTART command causes the TP transaction to RESTART in the same way
+   that GT.M uses to implicitly restart the transaction in case of resource
+   conflicts. All restarts increment the internal transaction retry count to
+   a maximum of three (3), at which point, GT.M performs the entire TP
+   transaction within a critical section on all databases referenced in the
+   transaction.
+
+   GT.M issues a TRESTMAX runtime error when application code attempts a
+   TRESTART more than once during a transaction while $TRESTART=4 (note: in
+   order to be wholesome, TRESTART usage in application code should always be
+   conditional). In the final retry, GT.M holds the critical section lock on
+   all databases involved in the transaction. Since a TRESTART cancels all
+   the work done in the current transaction and transfers control back to the
+   TSTART, limiting the number of times this can be done in the final retry
+   limits the time a process can (by virtue of holding a critical section
+   lock on the databases) prevent other processes from updating the database.
+
+   GT.M limits TP restarts in the final retry due to non-availability of
+   M-locks in a similar fashion. GT.M allows a maximum of 16 such restarts
+   after which it issues a TPLOCKRESTMAX runtime error.
 
-   $ZED[IT] holds the value of the status code for the last  edit  session
-   invoked by a ZEDIT command.
+   The format for the TRESTART command is:
 
-   GT.M does not permit the SET or NEW command to modify $ZEDIT.
+   TRE[START][:tvexpr]
 
-2 $ZEOf
-   $ZEOf
+   For an example of the use of the TRESTART command, refer to the chapter on
+   "General Language Features of M" in the GT.M Programmer's Guide.
 
-   $ZEO[F] contains a truth-valued expression indicating whether the last
-   READ operation reached the end-of-file. $ZEOF equals TRUE  (1)  at  EOF
-   and FALSE (0) at other positions.
+2 TROllback
+   TROllback
 
-   GT.M does not maintain $ZEOF for terminal devices.
+   The TROLLBACK command terminates a transaction by causing a ROLLBACK,
+   which removes all database updates performed within a transaction. A
+   TROLLBACK without an argument also sets $TLEVEL and $TRESTART to zero (0).
+   Issuing a TROLLBACK when no transaction is in progress ($TLEVEL=0)
+   produces an error.
 
-   $ZEOF  refers  to  the  end-of-file  status  of  the  current  device.
-   Therefore, exercise care in sequencing USE commands and  references  to
-   $ZEOF.
+   The format of the TROLLBACK command is:
 
-   GT.M does not permit the SET or NEW command to modify $ZEOF.
+   TRO[LLBACK][:tvexpr] [intexpr]
 
-   For more information on $ZEOF, refer to the  "Input/Output  Processing"
-   chapter.
+   For an example of the use of the TROLLBACK command, refer to the chapter
+   on "General Language Features of M" in the GT.M Programmer's Guide.
 
-2 $ZError
-   $ZError
+2 TStart
+   TStart
 
-   $ZE[RROR] is  supposed  to  hold  the  application-specific  error-code
-   corresponding to the GT.M error-code stored in  $ECODE/$ZSTATUS  (refer
-   to their description in this chapter).
+   The TSTART command marks the beginning of a transaction or sub-transaction
+   and increments $TLEVEL. When TSTART marks the beginning of a transaction
+   ($TLEVEL=1), its arguments determine whether the transaction may RESTART
+   and whether serializability is enforced. If a transaction may RESTART, the
+   TSTART arguments determine which local variables are restored during a
+   RESTART. Serializability is enforced by LOCK commands or, if the SERIAL
+   keyword is specified, by GT.M.
 
-   $ZERROR contains a default value of "Unprocessed $ZERROR, see $ZSTATUS"
-   at process startup.
+   The format of the TSTART command is:
 
-   $ZERROR can be SET but not NEWed.
+   TS[TART][:tvexpr] [([lvn...])|lvn|*|][:keyword|(keyword...)]
 
-   The mapping of a GT.M error-code to the application-specific error-code
-   is  achieved  as  follows.  Whenever  GT.M  encounters  an  error,
-   $ECODE/$ZSTATUS gets set first. It then invokes the code that $ZYERROR
-   (see description later in this chapter) points to if it is not null. It
-   is intended that the code invoked by $ZYERROR use the value of $ZSTATUS
-   to select or construct a value to which it SETs $ZERROR. If an error is
-   encountered by the attempt to execute the code specified  in  $ZYERROR,
-   GT.M sets $ZERROR to the error status encountered. If $ZYERROR is null,
-   GT.M does not change the value of $ZERROR. In all cases, GT.M proceeds
-   to return control to the code  specified  by  $ZTRAP/$ETRAP  or  device
-   EXCEPTION whichever is applicable.
+   For an example of the TSTART command, refer to the chapter on "General
+   Language Features of M" in the GT.M Programmer's Guide.
 
-2 $ZGbldir
-   $ZGbldir
+3 S[ERIAL]
+   S[ERIAL]
 
-   $ZG[BLDIR] contains the value of the current Global Directory filename.
-   When $ZGBLDIR specifies an invalid or inaccessible  file,  GT.M  cannot
-   successfully perform database operations.
+   The SERIAL keyword indicates that GT.M must ensure the serializability of
+   the transaction. Note that GT.M always serializes transactions regardless
+   of the SERIAL keyword. On a nested TSTART, this portion of the argument is
+   irrelevant.
 
-   GT.M  initializes  $ZGBLDIR  to  the  translation  of  the  environment
-   variable gtmgbldir. If  gtmgbldir  is  not  defined,  GT.M  initializes
-   $ZGBLDIR to null. When $ZGBLDIR is null, GT.M constructs  a  file  name
-   for the Global Directory using the name  gtmgbldir  and  the  extension
-   .gld in the current working directory. A $ZGBLDIR value may include an
-   environment variable.
-
-   $ZGBLDIR is a read-write Intrinsic  Special  Variable,  (i.e.,  it  can
-   appear on the left side of the equal sign (=) in the  argument  to  the
-   SET command). SET $ZGBLDIR="" causes GT.M to  assign  $ZGBLDIR  to  the
-   translation of gtmgbldir if that environment variable is defined. If it
-   is not defined, then SET $ZGBLDIR="" causes GT.M to assign  the  string
-   gtmgbldir to $ZGBLDIR. This syntax specifies the file gtmgbldir.gld in
-   the current directory. GT.M permits $ZGBLDIR to be NEW'd.
-
-   SETting $ZGBLDIR also causes GT.M to  attempt  to  open  the  specified
-   file. If the file name is invalid or the  file  is  inaccessible,  GT.M
-   triggers an error without changing the value of $ZGBLDIR.
-
-   To establish a value for $ZGBLDIR outside of  M,  use  the  appropriate
-   shell command to assign a translation to gtmgbldir. Defining gtmgbldir
-   provides a convenient way to use the same  Global  Directory  during  a
-   session where you repeatedly invoke and leave GT.M.
+3 T[RANSACTIONID]=expr
+   T[RANSACTIONID]=expr
 
-   Changes to the value of $ZGBLDIR during a GT.M invocation only last for
-   the current invocation and do not change the value of gtmgbldir.
+   The TRANSACTIONID keyword declares an arbitrary transaction
+   identification.
 
-   Example:
+   If TRANSACTIONID="BATCH" or "BA" at transaction completion, the process
+   immediately continues execution. When a process issues a [final] TCOMMIT
+   for a transaction and journaling is active, by default the process waits
+   until the entire transaction is written to the journal file(s) before
+   executing the next command. This ensures that every transaction is durable
+   before the process moves on to the next step. Transactions flagged as
+   "BATCH" have lower latency and higher throughput, but a lower guarantee of
+   durability. Normally this flag is used when operational procedures (such
+   as a backup) or application code (such as a checkpoint algorithm) provides
+   an acceptable alternative means of ensuring durability.
 
+2 Use
+   Use
 
-   $ gtmgbldir=test.gld
+   The USE command selects the current device for READs (input) and WRITEs
+   (output).
 
-   $ export gtmgbldir
+   The format of the USE command is:
 
-   $ gtm
+   U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
 
-   GTM> WRITE $zgbldir
+2 View
+   View
 
-   /usr/dev/test.gld
+   The VIEW command adjusts an environmental factor selected by a keyword
+   argument. For example, VIEW controls journal buffer flushing, determines
+   whether GT.M reports undefined variables as errors or treats them as null,
+   and determines which BREAK commands should display messages.
 
-   GTM> SET $zgbldir="mumps.gld"
+   The format of the VIEW command is:
 
-   GTM> WRITE $zgbldir
+   V[IEW][:tvexpr] keyword[:expr2[:...]][,...]
 
-   mumps.gld
+3 Key_Words_in_VIEW_Command
+   Key Words in VIEW Command
 
-   GTM> HALT
+4 "BREAKMSG":value
+   "BREAKMSG":value
 
-   $ echo $gtmgbldir
+   Sets the value of the BREAK message mask. When GT.M processes a BREAK
+   command, the BREAK message mask controls whether to display a message
+   describing the source of the BREAK.
 
-   test.gld
+   The mask uses the following four values that are added together to provide
+   the BREAKMSG value.
 
-   This example defines the environment variable gtmgbldir. Upon entering
-   GT.M Direct Mode, $ZGBLDIR has the value supplied by gtmgbldir. The SET
-   command changes the value. After the GT.M image  terminates,  the  echo
-   command demonstrates that gtmgbldir was  not  modified  by  the  M  SET
-   command.
+   1 - BREAKs within the body of a program
 
-   Example:
+   2 - BREAKs within a ZBREAK action
 
+   4 - BREAKs within a device EXCEPTION
 
-   $ ls test.gld
+   8 - BREAKs within a ZSTEP action
 
-   test.gld not found
+   By default GT.M displays all BREAK messages.
 
-   $ gtm
+   Example:
 
-   GTM> WRITE $zgbldir
+   GTM>VIEW "BREAKMSG":5
 
-   /usr/dev/mumps.gld
+   In this example the BREAKMSG value is 5, representing the sum of 1 and 4.
+   This enables BREAKS within the body of a program (value 1) and for a
+   device EXCEPTION (value 4).
 
-   GTM> set $zgbldir="test.gld"
+4 [NO]BADCHAR
+   [NO]BADCHAR
+
+   Enables or disable the gneration of an error when character-oriented
+   functions encounter malformed byte sequences (illegal characters).
+
+   At process startup, GT.M initializes BADCHAR from the environment variable
+   gtm_badchar. Set the environment variable $gtm_badchar to a non-zero
+   number or "YES" (or "Y") to enable VIEW "BADCHAR". Set the environment
+   variable $gtm_badchar to 0 or "NO" or "FALSE" (or "N" or "F") to enable
+   VIEW "NOBADCHAR". By default, GT.M enables VIEW "BADCHAR".
+
+   With VIEW "BADCHAR", GT.M functions generate the BADCHAR error when they
+   encounter malformed byte sequences. With this setting, GT.M detects and
+   clearly reports potential application program logic errors as soon as they
+   appear. As an illegal UTF-8 character in the argument of a
+   character-oriented function likely indicates a logic issue, FIS recommends
+   using VIEW "BADCHAR" in production environments.
+
+   **Note**
+
+   When all strings consist of well-formed characters, the value of VIEW
+   [NO]BADCHAR has no effect whatsoever. With VIEW "NOBADCHAR", the same
+   functions treat malformed byte sequences as valid characters. During the
+   migration of an application to add support for Unicode, illegal character
+   errors are likely to be frequent and indicative of application code that
+   is yet to be modified. VIEW "NOBADCHAR" suppresses these errors at times
+   when their presence impedes development.
+
+4 [NO]FULL_BOOL[EAN][WARN]
+   [NO]FULL_BOOL[EAN][WARN]
+
+   Controls the evaluation of Boolean expressions (expressions evaluated as a
+   logical TRUE or FALSE).
+
+   By default, GT.M enables VIEW "NOFULL_BOOLEAN" which means that GT.M stops
+   evaluating a Boolean expression as soon as it establishes a definitive
+   result. For example, neither 0&$$abc^def() or 1!$$abc^def() ever executes
+   $$abc^def(). However, in the case of global references, such as 0&^a or
+   1!^a, GT.M sets $reference and the naked indicator without actually
+   accessing the global variable.
+
+   With VIEW "FULL_BOOLEAN", GT.M ensures that all side effect expression
+   atoms, extrinsic functions ($$), external functions ($&), and $INCREMENT()
+   execute in left-to-right order.
+
+   With VIEW "FULL_BOOLWARN", GT.M not only evaluates Boolean expressions
+   like "FULL_BOOLEAN" but also produces a FULLBOOLWARN warning every time it
+   bypasses a short-circuit evaluation. It also produces a BOOLSIDEFFECT
+   warning when it encounters Boolean expressions that may induce
+   side-effects; that is: expressions with side effects after the first
+   Boolean operator - extrinsic functions, external calls and $INCREMENT().
+
+   GT.M picks the value of [NO]FULL_BOOL[EAN][WARN] from the environment
+   variable gtm_boolean. If gtm_boolean is undefined or evaluates to an
+   integer zero (0), the initial setting the default "NOFULL_BOOLEAN", if it
+   evaluates to an integer one (1), the initial setting is "FULL_BOOLEAN" and
+   if it evaluates to integer two (2) the initial setting is "FULL_BOOLWARN".
+
+4 "GDSCERT":value
+   "GDSCERT":value
 
-   %GTM-E-ZGBLDIRACC, Cannot access global directory
+   Enables (value=1) or disables (value=0) database block certification.
 
-   "/usr/dev/test.gld". Continuing with
+   Database block certification causes GT.M to check the internal integrity
+   of every block as it writes the block. Block certification degrades
+   performance and exists primarily as a tool for use by FIS. The default is
+   GDSCERT:0.
 
-   /usr/dev/mumps.gld"
+4 "GVDUPSETNOOP":value
+   "GVDUPSETNOOP":value
 
-   %SYSTEM-E-ENO2, No such file or directory
+   Enables (VIEW "GVDUPSETNOOP":1) or disables (VIEW "GVDUPSETNOOP":0)
+   duplication set optimization.
 
-   GTM> WRITE $zgbldir
+   Duplicate set optimization prevents a SET that does not change the value
+   of an existing node from performing the update or executing any trigger
+   code specified for the node. By default, duplicate set optimization is
+   enabled.
 
-   /usr/dev/mumps.gld
+4 "JNLFLUSH"[:region]
+   "JNLFLUSH"[:region]
 
-   GTM> halt
+   Writes or flushes journaling buffers associated with the given region to
+   permanent storage, for example, to disk. If the VIEW "JNLFLUSH" does not
+   specify the optional region, GT.M flushes all journaled regions of the
+   current Global Directory.
 
-   $
+   Normally GT.M writes journal buffers when it completes a transaction
+   (unless TRANSACTIONID="BATCH"), fills the journal buffer or when some
+   period of time passes with no journal activity.
 
-   The SET command attempts to change the value of $ZGBLDIR  to  test.gld.
-   Because the file does not exist, GT.M reports an  error  and  does  not
-   change the value of $ZGBLDIR.
+4 JNLWAIT
+   JNLWAIT
 
-        Attempting to restore an inaccessible initial Global Directory that
-        has been NEW'd, can cause an error.
+   Causes a process to pause until its journaling buffers have been written.
+   JNLWAIT ensures that GT.M successfully transfers all database updates
+   issued by the process to the journal file before the process continues.
+   Normally, GT.M performs journal buffer writes synchronously for TP
+   updates, and asynchronously, while the process continues execution, for
+   non-TP updates or TP updates with TRANSACTIONID=BATCH.
 
-2 $ZINTerrupt
-   $ZINTerrupt
+4 "JOBPID":"value"
+   "JOBPID":"value"
 
-   $ZINT[ERRUPT] specifies the code to be XECUTE'd when an interrupt (for
-   example, through a MUPIP INTRPT)  is  processed.  While  a  $ZINTERRUPT
-   action is in process, any additional interrupt signals  are  discarded.
-   When an interrupt handler is invoked, the current values of $REFERENCE
-   is saved and restored when the interrupt handler returns.  The  current
-   device ($IO) is neither saved nor restored.
+   Enables (value=1) or disables (value=0) the addition of the child process
+   ID to the output and error filenames generated by the JOB command. The
+   default is 0.
 
-   GT.M permits the SET command to modify the value of $ZINTERRUPT.
+   The value=1 option prevents output files generated by the JOB command from
+   being overwritten each time a new job is spawned from the GT.M source
+   file.
 
-   If an interrupt handler changes the current IO device (via USE), it is
-   the responsibility of the interrupt handler to restore the  current  IO
-   device before returning. There are sufficient legitimate possibilities
-   why an interrupt routine would want to change  the  current  IO  device
-   (for example; daily log switching),  that  this  part  of  the  process
-   context is not saved and restored automatically.
+4 "LABELS":"value"
+   "LABELS":"value"
 
-   The initial value for $ZINTERRUPT is taken from  the  UNIX  environment
-   variable gtm_zinterrupt if it is specified, otherwise  it  defaults  to
-   the following string:
+   Enables (value="LOWER") or disables (value="UPPER") case sensitivity for
+   labels within routines.
 
-   IF $ZJOBEXAM()
+   It is important to have the same case handling at compile-time and
+   run-time.
 
-   The IF  statement  executes  the  $ZJOBEXAM  function  but  effectively
-   discards the return value.
-
-        If the default value for $ZINTERRUPT is  modified,  no  $ZJOBEXAM()
-        will occur unless the  replacement  value  directly  or  indirectly
-        invokes that function. In other words, while $ZJOBEXAM() is part of
-        the interrupt handling by default, it is not an  implicit  part  of
-        the interrupt handling.
-
-3 Inter_Handl_GTM
-   Interrupt Handling in GT.M
-
-   The interrupt handler is executed by GT.M when on a statement boundary
-   or on an appropriate boundary in a potentially long running COMMAND (in
-   the same place as <CTRL>-C is recognized). If a GT.M process  is  in  a
-   long running external call (for example; waiting in  a  message  queue)
-   the interrupt handler  cannot  be  driven  immediately.  The  interrupt
-   request is recognized and the handler is driven after the external call
-   returns to GT.M and an appropriate execution boundary is reached.
-
-   Since  sending  an  interrupt  signal  requires  the  sender  to  have
-   appropriate permissions from UNIX, the use of  the  interrupt  facility
-   itself does not present any inherent security  exposures.  Nonetheless,
-   because the dump files created by the default action contain the values
-   of every local variable in the context  at  the  time  they  are  made,
-   inappropriate access to the dump  files  would  constitute  a  security
-   exposure. Make sure the design  and  implementation  of  any  interrupt
-   logic includes careful consideration to security issues.
-
-   If an error occurs while compiling the  $ZINTERRUPT  code,  the  action
-   taken depends on the process  state  at  the  time  the  interrupt  was
-   received and the error handler is not invoked  (the  error  handler  is
-   invoked if an error occurs while executing the  $ZINTERRUPT  code).  If
-   the GT.M process is at a direct mode prompt or is  executing  a  direct
-   mode command (for example, a FOR loop), the error message  is  sent  to
-   the user console along with the GTM-ERRWZINTR error (refer to the GT.M
-   Error and Message Recovery  Manual).  In  addition,  the  GTM-ERRWZINTR
-   error is also sent to the operator log facility. IF the process is not
-   at a direct mode  prompt  or  executing  a  direct  mode  command,  the
-   GTM-ERRWZINTR message and the compiler error message are  sent  to  the
-   operator log facility and nothing is displayed on the  user's  console.
-   In both cases, the interrupted process resumes execution.
-
-   If an error occurs during execution of the  interrupt  handler's  stack
-   frame (before it calls anything),  that  error  is  prefixed  with  the
-   GTM-ERRWZINTR error. The  error  handler  then  executes  normal  error
-   processing associated with the module that was interrupted.  Any  other
-   errors that occur in code called by the interrupt handler  are  handled
-   by normal error handling.
-
-        The interrupt handler does not  operate  "outside"  the  current  M
-        environment but rather within the environment of the process.
-
-   If a TP transaction is in progress (0<$TLEVEL), updates to globals are
-   not safe since a TP restart can be signaled at any time  prior  to  the
-   transaction being committed - even after the interrupt handler returns.
-   A TP restart reverses all global updates and unwinds the M stack so it
-   is as if the interrupt never occurred. The  interrupt  handler  is  not
-   redriven as  part  of  a  transaction  restart.  Referencing  (reading)
-   globals inside an interrupt handler can  trigger  a  TP  restart  if  a
-   transaction is active.  When  programming  interrupt  handling,  either
-   discard interrupts when 0<$TLEVEL (forcing the  interrupting  party  to
-   try again), or use local variables that are not restored by a TRESTART
-   to defer the interrupt action until after the final TCOMMIT.
-
-   Note that it is possible for the interrupt handler to be executed while
-   the process executing the M routine is holding the critical section for
-   one or more regions. Use of this feature may create temporary hangs or
-   pauses while the interrupt handler executes. For the default case where
-   the interrupt handler uses $ZJOBEXAM() to  create  a  dump,  the  pause
-   duration depends on the number of local variables in the process at the
-   time of the dump and on the speed of the disk  being  written  to.  The
-   dumps are slower on a network-mounted disk  than  on  a  disk  directly
-   connected to the local system. Any  interrupt  driven  code  should  be
-   designed to account for this issue.
+   Because GT.M stores routines as regular files and file names are case
+   sensitive on UNIX, GT.M always treates routine names as case sensitive.
 
-2 $ZINInterrupt
-   $ZINInterrupt
+4 LV_GCOL
+   LV_GCOL
 
-   $ZINI[NTERRUPT] evaluates to 1 (TRUE) when a process is executing code
-   initiated by the interrupt mechanism, and otherwise 0 (FALSE).
+   Starts a data-space garbage collection, which normally happens
+   automatically at appropriate times.
 
-   GT.M does not permit the SET or NEW commands to modify $ZININTERRUPT.
+   **Note**
 
-2 $ZIO
-   $ZIO
+   There are no visible effects from LV_GCOL, LV_REHASH, and STP_GCOL except
+   for the passage of time depending on the state of your process. FIS uses
+   these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
+   are documented to ensure completeness in product documentation. You may
+   (or may not) find them useful during application development for debugging
+   or performance testing implementation alternatives.
 
-   $ZIO contains the translated name of the current device, in contrast to
-   $IO, which contains the name as specified by the USE command.
+4 LV_REHASH
+   LV_REHASH
 
-   GT.M does not permit the SET or NEW command to modify $ZIO.
+   Starts a reorganization of the local variable look-up table, which
+   normally happens automatically at appropriate times.
 
-   An example where $ZIO contains a value different from  $IO  is  if  the
-   environment variable gtm_principal is defined.
+   **Note**
 
-   Example:
+   There are no visible effects from LV_REHASH, LV_GCOL, and STP_GCOL except
+   for the passage of time depending on the state of your process. FIS uses
+   these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
+   are documented to ensure completeness in product documentation. You may
+   (or may not) find them useful during application development for debugging
+   or performance testing implementation alternatives.
 
+4 [NEVER]|[NO]LVNULLSUBS
+   [NEVER]|[NO]LVNULLSUBS
 
-   $ gtm_principal="foo"
+   Disallows, partially disallows, or allows local arrays to have empty
+   string subscripts. The default is LVNULLSUBS.
 
-   $ export gtm_principal
+   NOLVNULLSUBS disallows any variant of SET to operate on a local array
+   having an empty string subscript.
 
-   GTM>WRITE $IO
+   NEVERLVNULLSUBS disallows any variant of SET or KILL
+   ($DATA(),$GET(),$ORDER(), and $QUERY()) to operate on a local array having
+   an empty string subscript. An empty string as the last subscript in
+   $ORDER() and $QUERY() has the semantic significance of requesting the next
+   lexical item and is not subject to NULLSUBS errors.
 
-   foo
+   LVNULLSUBS allows local arrays to have empty string subscripts.
 
-   GTM>WRITE $ZIO
+   At process startup, GT.M initializes [NEVER][NO]LVNULLSUBS from
+   $gtm_lvnullsubs. Set the environment variable $gtm_lvnullsubsv to:
 
-   /dev/pts/8
+   **Important**
 
-   Notice that $ZIO contains the actual terminal  device  name  while  $IO
-   contains  the  string  pointed  to  by  the  environment  variable
-   gtm_principal.
+   Remember that for global variables, empty string subscript checking is
+   controlled by a database region characteristic. FIS recommends using
+   LVNULLSUBS, NOLVNULLSUBS, or NEVERLVNULLSUBS for local variables and
+   NULLSUBS options ALWAYS or NEVER for global variables.
 
-2 $ZJob
-   $ZJob
+4 "NOISOLATION":<expr>
+   "NOISOLATION":<expr>
 
-   $ZJ[OB] holds the pid of the process created by the  last  JOB  command
-   performed by the current process.
+   where expr must evaluate to one of the following forms
 
-   GT.M initializes $ZJOB to zero (0)  at  process  startup.  If  the  JOB
-   command fails to spawn a new job, GT.M sets $ZJOB  to  zero  (0).  Note
-   that because of the left to right evaluation order of M, using $ZJOB in
-   the jobparameter string results in using the value created by the last,
-   rather than the current JOB command,  which  is  not  likely  to  match
-   common coding practice.
+     * "", that is, the empty string : turn off the feature for all globals
+       for which it has previously been turned on
+     * "^gvn1,^gvn2,..." : turn on the feature for the globals in the list,
+       turning it off for globals for which it has previously been turned on
+     * "+^gvn1,^gvn2,..." : add these globals to the list of globals that
+       have this feature turned on
+     * "-^gvn1,^gvn2,..." : turn off the feature for these globals leaving
+       the status for other globals unchanged
 
-   GT.M does not permit the SET or NEW command to modify $ZJOB.
+4 "PATCODE":"tablename"
+   "PATCODE":"tablename"
 
-2 $ZLevel
-   $ZLevel
+   Identifies the alternative table of unique patterns for use with the "?"
+   operator to be loaded from the pattern definition file. For additional
+   information, refer to the "Internationalization" chapter in the GT.M
+   Programmer's Guide.
 
-   $ZL[EVEL] contains an integer value indicating the "level  of  nesting"
-   caused by DO commands, XECUTE commands, and extrinsic functions in the
-   M invocation stack.
+4 "PATLOAD":"file-specification"
+   "PATLOAD":"file-specification"
 
-   $ZLEVEL has an initial value of one (1) and increments by one with each
-   DO, XECUTE or extrinsic function. Any QUIT that does  not  terminate  a
-   FOR  loop  decrements  $ZLEVEL.  ZGOTO  may  also  reduce  $ZLEVEL.  In
-   accordance with the  M  standard,  a  FOR  command  does  not  increase
-   $ZLEVEL. M routines cannot modify $ZLEVEL with the SET or NEW commands.
+   Identifies the file containing definitions of unique patterns for use with
+   the "?" operator. These pattern definitions can be used in place of, or in
+   addition to, the standard C, N, U, L, and P.
 
-   Use $ZLEVEL in debugging or in an error-handling mechanism to capture a
-   level for later use in a ZGOTO argument.
+4 RESETGVSTATS
+   RESETGVSTATS
 
-   Example:
+   Resets all the process-private global access statistics to 0. This is
+   particularly useful for long running processes which would periodically
+   like to restart the counting without requiring a shut down and restart.
 
+4 STP_GCOL
+   STP_GCOL
 
-   GTM>ZPRINT ^ZLEV
+   Starts a string-pool garbage collection, which normally happens
+   automatically at appropriate times.
 
-   A DO B
+   **Note**
 
-   WRITE X,!
+   There are no visible effects from STP_GCOL, LV_GCOL and LV_REHASH except
+   for the passage of time depending on the state of your process. FIS uses
+   these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
+   are documented to ensure completeness in product documentation. You may
+   (or may not) find them useful during application development for debugging
+   or performance testing implementation alternatives.
 
-   QUIT
+4 [NO]LOGT[PRESTART][=intexpr]
+   [NO]LOGT[PRESTART][=intexpr]
 
-   B GOTO C
+   Allows a process to dynamically change the logging of TPRESTART messages
+   to the operator log established at process startup by the environment
+   variables gtm_tprestart_log_delta and gtm_tprestart_log_first.
 
-   QUIT
+   VIEW "NOLOGTPRESTART" turns off the logging of TPRESTART messages to the
+   operator log.
 
-   C DO D
+   VIEW "LOGTPRESTART"[=intexpr] turns on logging of TPRESTART messages to
+   the operator log. If no intexpr is specified, GT.M uses the value of
+   environment variable gtm_tprestart_log_delta, if it is defined, and one
+   otherwise (that is, every transaction restart will be logged). A negative
+   value of intexpr turns off the logging of TPRESTART messages.
 
-   QUIT
+   Note that it is not possible to perform the operations of
+   gtm_tprestart_log_first with VIEW "LOGTPRESTART"[=intexpr].
 
-   D SET X=$ZLEVEL
+4 [NO]UNDEF
+   [NO]UNDEF
 
-   QUIT
+   Enables or disables handling of undefined variables as errors. With UNDEF,
+   GT.M handles all references to undefined local or global variables as
+   errors. With NOUNDEF, GT.M handles all references to undefined local or
+   global variables as if the variable had a value of the empty string. In
+   other words, GT.M treats all variables appearing in expressions as if they
+   were the argument of an implicit $GET(). UNDEF is the default.
 
-   GTM>DO ^ZLEV
+   The environment variable $gtm_noundef specifies the initial value value of
+   [NO]UNDEF at process startup. If it is defined, and evaluates to a
+   non-zero integer or any case-independent string or leading substring of
+   "TRUE" or "YES", then GT.M treats undefined variables as having an
+   implicit value of an empty string.
 
-   4
-   This program, executed from Direct Mode, produces  a  value  of  4  for
-   $ZLEVEL. If you run this program from the shell, the value  of  $ZLEVEL
-   is three (3).
+   **Note**
 
-2 $ZMAXTPTIme
-   $ZMAXTPTIme
+   NOUNDEF does not apply to an undefined FOR control variable. This prevents
+   an increment (or decrement) of an undefined FOR control variable from
+   getting into an unintended infinite loop. For example, FOR A=1:1:10 KILL A
+   gives an UNDEF error on the increment from 1 to 2 even with VIEW
+   "NOUNDEF".
 
-   $ZMAXTPTI[ME] contains an integer value indicating  the  time  duration
-   GT.M should wait for the completion of all  activities  fenced  by  the
-   current transaction's outermost TSTART/TCOMMIT pair.
+4 "TRACE":value:<expr>
+   "TRACE":value:<expr>
 
-   $ZMAXTPTIME can be SET but cannot be NEWed.
+   Traces GT.M program execution and generates profiling information about
+   the lines and functions executed; with low impact on the run-time
+   performance.
 
-   The initial value of $ZMAXTPTIME is zero (0) seconds,  which  indicates
-   "no  timeout"  (unlimited  time).  The  value  of  $ZMAXTPTIME  when  a
-   transaction's  outermost  TSTART  operation  executes  determines  the
-   timeout setting for that transaction.
+   The feature turns on (value=1) or turns off (value=0) M-profiling. This
+   expression must evaluate to a string containing the name of a GT.M global
+   variable. The global may also have subscripts; however the subscripts must
+   be literals or the special variable $JOB.
+
+   The expression is optional when turning M-profiling off, if it exists, it
+   overrides the global variable set when M-profiling was turned on.
+
+   gtm_trace_gbl_name enables GT.M tracing at process startup. Setting
+   gtm_trace_gbl_name to a valid global variable name instructs GT.M to
+   report the data in the specified global when a VIEW command disables the
+   tracing, or implicitly at process termination. This setting behaves as if
+   the process issued a VIEW "TRACE" command at process startup. However,
+   gtm_trace_gbl_name has a capability not available with the VIEW command,
+   such that if the environment variable is defined but evaluates to zero (0)
+   or, only on UNIX, to the empty string, GT.M collects the M-profiling data
+   in memory and discards it when the process terminates (this feature is
+   mainly used for in-house testing). Note that having this feature activated
+   for process that otherwise do not open a database file (such as GDE) can
+   cause them to encounter an error.
 
-   When a $ZMAXTPTIME expires, GT.M executes the  $ETRAP/$ZTRAP  exception
-   handler currently in effect.
+   Thus, if the GT.M program lv1.m is:
 
-        Negative values of $ZMAXTPTIME are also treated  as  "no  timeout".
-        Timeouts  apply  only  to  the  outermost  transaction,  that  is,
-        $ZMAXTPTIME has no effect when  TSTART  is  nested  within  another
-        transaction.
+   lv1    for i=1:1:10 do
+          . set l(i)=i
+          . do bar
+          for i=1:1:5 for j=1:1:4 set lij(i,j)=i+j
+          quit
+   bar    set l(-i)=-i
+          quit
 
-   Example:
+   and the program lv2.m is:
 
+   lv2    VIEW "TRACE":1:"^lvtr"
+          do ^lv1
+          VIEW "TRACE":0:"^lvtr"
 
-   Test ;testing TP timeouts
+          zwrite ^lvtr
+          quit
+
+   On executing lv2, the output looks like this (times in the example were
+   chosen for clarity of illustration and are not typical):
 
-   set $ZMAXTPTIME=6,^X=0,^Y=0,^Z=0
+   ^lvtr("*CHILDREN")="0:0:0"
+   ^lvtr("*RUN")="0:0:0"
+   ^lvtr("lv1","bar")="10:8:1:9"
+   ^lvtr("lv1","bar",0)="10:5:1:6"
+   ^lvtr("lv1","bar",1)="10:3:0:3"
+   ^lvtr("lv1","lv1")="1:28:2:30"
+   ^lvtr("lv1","lv1",0)="1:8:0:8"
+   ^lvtr("lv1","lv1",0,"FOR_LOOP",1)=10
+   ^lvtr("lv1","lv1",1)="10:3:1:4"
+   ^lvtr("lv1","lv1",2)="10:2:1:3"
+   ^lvtr("lv1","lv1",3)="1:15:0:15"
+   ^lvtr("lv1","lv1",3,"FOR_LOOP",1)=5
 
-   write "Start with $ZMAXTPTIME=",$ZMAXTPTIME,":",!
+   ^lvtr("lv1","lv1",3,"FOR_LOOP",2)=20
+   ^lvtr("lv1","lv1",4)="1:0:0:0"
+   ^lvtr("lv2","lv2",1)="1:2:0:2"
+   ^lvtr("lv2","lv2",2)="1:2:1:3"
+
+   Example:
+
+   If prof.m is:
+
+   prof;
+       set start=1
+       set finish=1000
+       view "TRACE":1:"^trc"
+       kill cycle S max=$$docycle(start,finish,"cycle")
+       view "TRACE":0:"^trc"
+       zwrite ^trc
+       quit
+       ;
+   docycle(first,last,var)
+       new i,currpath,current,maxcycle,n
+       set maxcycle=1
+       for current=first:1:last do cyclehelper
+       quit maxcycle
+       ;
+   cyclehelper
+       set n=current
+       kill currpath
+       for i=0:1 quit:$data(@var@(n))!(1=n)  D
+       .    set currpath(i)=n
+       .    do iterate
+       if 0<i do
+       .    if 1=n set i=i+1
+       .    else  set i=i+ at var@(n)
+       .    do updatemax
+       .    set n="" for  set n=$O(currpath(n)) Q:""=n  S @var@(currpath(n))=i-n
+       Q
+       ;
+   iterate
+       if 0=(n#2) set n=n/2
+       else  set n=3*n+1
+       quit
+       ;
+   updatemax
+       set:i>maxcycle maxcycle=i
+       quit
+       ;
+
+   On executing prof, the output looks like the following (times in the
+   example were chosen for clarity of illustration and are not typical).
+
+   ^trc("*CHILDREN")="0:0:0"
+   ^trc("*RUN")="224014:12000:236014"
+   ^trc("prof","cyclehelper")="1000:200013:0:200013:206318"
+   ^trc("prof","cyclehelper",1)="1000:12001:0:12001:3202"
+   ^trc("prof","cyclehelper",2)="1000:0:0:0:3766"
+   ^trc("prof","cyclehelper",3)="1000:64004:0:64004:94215"
+   ^trc("prof","cyclehelper",3,"FOR_LOOP",1)=3227
+   ^trc("prof","cyclehelper",4)="2227:0:0:0:9864"
+   ^trc("prof","cyclehelper",5)="2227:0:0:0:7672"
+   ^trc("prof","cyclehelper",6)="1000:12000:0:12000:3758"
+   ^trc("prof","cyclehelper",7)="432:0:0:0:1520"
+   ^trc("prof","cyclehelper",8)="432:8000:0:8000:11003"
+   ^trc("prof","cyclehelper",9)="432:0:0:0:3298"
+   ^trc("prof","cyclehelper",10)="432:104008:0:104008:61564"
+   ^trc("prof","cyclehelper",10,"FOR_LOOP",1)=2659
+   ^trc("prof","cyclehelper",11)="1000:0:0:0:3424"
+   ^trc("prof","docycle")="1:12001:0:12001:4886"
+   ^trc("prof","docycle",0)="1:0:0:0:83"
+   ^trc("prof","docycle",1)="1:0:0:0:36"
+   ^trc("prof","docycle",2)="1:0:0:0:4"
+   ^trc("prof","docycle",3)="1:12001:0:12001:4706"
+   ^trc("prof","docycle",3,"FOR_LOOP",1)=1000
+   ^trc("prof","docycle",4)="1:0:0:0:1718579845"
+   ^trc("prof","iterate")="2227:12000:12000:24000:30240"
+   ^trc("prof","iterate",1)="2227:0:0:0:8271"
+   ^trc("prof","iterate",2)="2227:12000:0:12000:7727"
+   ^trc("prof","iterate",3)="2227:0:0:0:7658"
+   ^trc("prof","prof",4)="1:0:0:0:22"
+   ^trc("prof","prof",5)="1:0:0:0:8"
+   ^trc("prof","updatemax")="432:0:0:0:4276"
+   ^trc("prof","updatemax",1)="432:0:0:0:1465"
+   ^trc("prof","updatemax",2)="432:0:0:0:1496"
+
+   Example:
+
+   If fortypes.m is:
+
+   fortypes;
+       new i,j,k,v
+       set k=1
+       view "TRACE":1:"^trc"
+
+       for i=1:1:3  set v=i
+
+       for i=1:1  set v=0  quit:i=3
+
+       for i=1,2:1:4,6  set v=0
+
+       for i=1:1,2  set v=0  quit:i=3
+
+       for i=1:1:2  for j=1:1:3  set v=0
+
+       for i=1:1:2
+       .    for j=1:1:1  do
+       ..        set v=0
+
+       set j=5  for i=1:1:j  do
+       .    set j=(j-1)
+
+       for i=1:1:2  for j=1:1:3  do
+       .    set v=0
+
+       for i=1:1:2  do
+       .    for j=1:1:3  set v=0
+
+       for i=1:1:2  do
+       .    for j=1:1:3  do
+       ..        set v=0
+
+       for i="foo","bar",1:1  set v=0  quit:i=3
+
+       for  set k=k+1  quit:k=3
+
+       for i=1:1:3  for j=1:1:(3-i)  set v=0
+
+       for i=1:1:3  for j=1:1:(3-i)  for k=1:1:(j+1)  set v=0
+
+       set k=3  view "TRACE":0:"^trc"
+       zwrite ^trc
+
+       quit
+
+   On executing fortypes, the output looks something like the following:
+
+   ^trc("*CHILDREN")="4000:0:4000"
+   ^trc("*RUN")="468029:48003:516032"
+   ^trc("fortypes","fortypes",5)="1:0:0:0:9"
+   ^trc("fortypes","fortypes",5,"FOR_LOOP",1)=3
+   ^trc("fortypes","fortypes",7)="1:0:0:0:6"
+   ^trc("fortypes","fortypes",7,"FOR_LOOP",1)=3
+   ^trc("fortypes","fortypes",9)="1:0:0:0:6"
+   ^trc("fortypes","fortypes",9,"FOR_LOOP",1)=5
+   ^trc("fortypes","fortypes",11)="1:0:0:0:6"
+   ^trc("fortypes","fortypes",11,"FOR_LOOP",1)=3
+   ^trc("fortypes","fortypes",13)="1:0:0:0:8"
+   ^trc("fortypes","fortypes",13,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",13,"FOR_LOOP",2)=6
+   ^trc("fortypes","fortypes",15)="1:0:0:0:4"
+   ^trc("fortypes","fortypes",15,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",19)="1:0:0:0:26"
+   ^trc("fortypes","fortypes",19,"FOR_LOOP",1)=5
+   ^trc("fortypes","fortypes",20)="5:0:0:0:4"
+   ^trc("fortypes","fortypes",22)="1:0:0:0:27"
+   ^trc("fortypes","fortypes",22,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",22,"FOR_LOOP",2)=6
+   ^trc("fortypes","fortypes",23)="6:0:0:0:3"
+   ^trc("fortypes","fortypes",25)="1:0:0:0:11"
+   ^trc("fortypes","fortypes",25,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",26)="2:0:0:0:6"
+   ^trc("fortypes","fortypes",26,"FOR_LOOP",1)=6
+   ^trc("fortypes","fortypes",28)="1:0:0:0:8"
+   ^trc("fortypes","fortypes",28,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",29)="2:0:0:0:26"
+   ^trc("fortypes","fortypes",29,"FOR_LOOP",1)=6
+   ^trc("fortypes","fortypes",30)="6:0:0:0:4"
+   ^trc("fortypes","fortypes",32)="1:0:0:0:8"
+   ^trc("fortypes","fortypes",32,"FOR_LOOP",1)=5
+   ^trc("fortypes","fortypes",34)="1:0:0:0:5"
+   ^trc("fortypes","fortypes",34,"FOR_LOOP",1)=2
+   ^trc("fortypes","fortypes",36)="1:0:0:0:8"
+   ^trc("fortypes","fortypes",36,"FOR_LOOP",1)=3
+   ^trc("fortypes","fortypes",36,"FOR_LOOP",2)=3
+   ^trc("fortypes","fortypes",38)="1:0:0:0:14"
+   ^trc("fortypes","fortypes",38,"FOR_LOOP",1)=3
+   ^trc("fortypes","fortypes",38,"FOR_LOOP",2)=3
+   ^trc("fortypes","fortypes",38,"FOR_LOOP",3)=7
+
+4 "ZDATE_FORM":"value"
+   "ZDATE_FORM":"value"
+
+   Determines whether four digit year code is active for $ZDATE() function.
+   GT.M defaults to zero (0), that is, two digit output.
+
+   If no value is given with the VIEW command, it turns four digit code on.
+   It is equivalent to the intrinsic special variable $ZDATEFORM. Use
+   $ZDATEFORM to set this VIEW keyword. Also, logical name environment
+   variable gtm_zdate_form may be used to set the initial value to this
+   factor.
 
-   for sleep=3:2:9 do
+3 Examples
+   Examples
 
-   . set retlvl=$zl
+   Example:
 
-   . do longtran ;ztrap on longtran
+   GTM>Kill A
 
-   ;continues execution
+   GTM>View "NOUNDEF"
 
-   ;on next line
+   GTM>Write A,?10,$L(A)
+            0
+   GTM>
 
-   . write "(^X,^Y)=(",^X,",",^Y,")",!
+   This demonstrates how a VIEW that specifies NOUNDEF prevents UNDEFined
+   errors.
 
-   write !,"Done TP Timeout test.",!
+   Example 2:
 
-   quit
+   GTM>ZLink "NOSENSE"
+   %GTM-E-LABELMISSING Label referenced but
+   not defined:lab
+   %GTM-I-SRCNAM in source module /home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/
+   NOSENSE.m
+   GTM>ZPrint ^NOSENSE
+   NOSENSE;
+           Do lab
+           Quit
+   LAB  Write !,"THIS IS NOSENSE"
+           Quit
+   GTM>View "LABELS":"UPPER"
 
-   longtran ;I/O in TP doesn't get rolled back
+   GTM>ZLink "NOSENSE.m"
 
-   set newzt="set $ZT="""" ";avoid recursive ZTRAP
+   GTM>Do ^NOSENSE
+   THIS IS NOSENSE
+   GTM>
 
-   set $ZT=newzt_" goto err"
+   This demonstrates use of VIEW "LABELS" to make label handling case
+   insensitive. Notice that the routine was ZLINKed with an extension of .m
+   to force a recompile and ensure that the object code and the run-time
+   handling of labels is the same.
 
-   tstart ():serial ;plain tstart works as well
+2 Write
+   Write
 
-   set ^X=1+^X
+   The WRITE command transfers a character stream specified by its arguments
+   to the current device.
 
-   write !,"^X=",^X,",will set ^Y to ",sleep
+   The format of the WRITE command is:
 
-   write " in ",sleep," seconds..."
+   W[RITE][:tvexpr] expr|*intexpr|fcc[,...]
 
-   hang sleep
+2 Xecute
+   Xecute
 
-   set ^Y=sleep
+   The XECUTE command makes an entry in the GT.M invocation stack and
+   executes the argument as GT.M code.
 
-   write "^Y=",^Y
+   The format of the XECUTE command is:
 
-   tcommit
+   X[ECUTE]:tvexpr expr[:tvexpr][,...]
 
-   write "...committed.",!
+3 Examples
+   Examples
 
-   quit
+   Example:
 
-   err ;
+   GTM>Xecute "Write ""HELLO"""
+   HELLO
+   GTM>
 
-   set $ZT=""
+   This demonstrates a simple use of Xecute.
 
-   write !,"In $ZTRAP handler. Error was: "
+   Example:
 
-   write !," ",$zstatus
+   Set x="" For Set x=$Order(^%x(x)) Quit:x=""  Xecute x
 
-   if $TLEVEL do ;test allows handler use outside of TP
+   This $ORDER() loop XECUTEs code out of the first level of the global array
+   ^%x. Note that, in most cases, having the code in a GT.M source file, for
+   example TMPX.m, and using a Do ^TMPX improves efficiency.
 
-   . trollback
+2 ZAllocate
+   ZAllocate
 
-   . write "Rolled back transaction."
+   The ZALLOCATE command reserves the specified name without releasing
+   previously reserved names. Other GT.M processes cannot reserve the
+   ZALLOCATEd name with a ZALLOCATE or LOCK command.
 
-   write !
+   The ZALLOCATE command provides compatibility with some other GT.M
+   implementations. The M Development Committee chose to add the + and -
+   delimiters to the LOCK command (incremental locking) rather than adopt the
+   ZALLOCATE and ZDEALLOCATE approach. Therefore, when a design requires an
+   incremental lock mechanism, LOCK +/- has the advantage over ZALLOCATE /
+   ZDEALLOCATE of being part of the M standard. LOCK +/- also has the
+   advantage of working symmetrically when routines using LOCKs are nested.
+   That is, a ZALLOCATE command issued by a process for a named resource
+   already ZALLOCATEd by that process results in no change of state. This
+   means that routines that do ZALLOCATE followed by a ZDEALLOCATE on a named
+   resource that is already ZALLOCATEd by the same process (at routine entry
+   time), will end up ZDEALLOCATEing the named resource (which might not be
+   desired). On the other hand, a LOCK + command issued by a process for a
+   named resource already LOCKed by that process causes the LEVEL of the LOCK
+   to be incremented (as seen in a ZSHOW "L" output). Every LOCK - command on
+   that named resource causes the LEVEL to be decremented. When the LEVEL
+   becomes 0, the named resource is no longer LOCKed.
 
-   zgoto retlvl
+   The format of the ZALLOCATE command is:
 
+   ZA[LLOCATE][:tvexpr] [(]nref[,...][)][:intexpr][,...]
 
-   Results:
+3 Examples
+   Examples
 
+   Examples:
 
-   Start with $ZMAXTPTIME=6:
+   ZAllocate A
+   ZAllocate ^A
+   ZAllocate ^A(1)
+   ZAllocate (^B("smith"),^C("jones"))
+   ZAllocate @A
 
+   The first command ZALLOCATEs A; the second, ^A; the third, ^A(1) and the
+   fourth, both ^B("smith") and ^C("jones") simultaneously. The last command
+   ZALLOCATEs the resources named by the value of the variable A.
 
-   ^X=1,will set ^Y to 3 in 3 seconds...^Y=3...committed.
+   Example:
 
+   ZAllocate A,^B, at C
+   ZALLOCATE (A,B,C)
 
-   ^X=2,will set ^Y to 5 in 5 seconds...^Y=5...committed.
+   If ZALLOCATE arguments are enclosed in parentheses, the command waits
+   until all names in the argument list become available before reserving any
+   of the names. For example, in the statement ZA (A,B,C), if the resource
+   named C is not available, ZALLOCATE waits until C becomes available before
+   reserving A and B. Using the format illustrated in the first line above,
+   can cause deadlocks because the resource names are reserved as they come
+   available.
 
+   When a process attempts to ZALLOCATE a name currently ZALLOCATEd or LOCKed
+   (with the LOCK command) by another process, the ZALLOCATEing process hangs
+   until the other process releases the name. In the event that names remain
+   unavailable for significant periods of time, timeouts allow the process
+   issuing a ZALLOCATE to regain program control.
 
-   ^X=3,will set ^Y to 7 in 7 seconds...
+   Example:
 
-   In $ZTRAP handler. Error was:
+   ZAllocate ^D:5
 
-   150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled
-   back transaction.
+   This example specifies a timeout of five seconds. If GT.M reserves ^D
+   before the five seconds elapses, ZALLOCATE sets $TEST to TRUE. If GT.M
+   cannot reserve ^D within the five second timeout, ZALLOCATE sets $TEST to
+   FALSE.
 
-   ^X=3,will set ^Y to 9 in 9 seconds...
+   At the time of ZALLOCATEing a name, no names previously reserved with
+   ZALLOCATE or the LOCK command are released (similarly, LOCKing a name does
+   not release names that have been ZALLOCATEd). For example, after
+   ZALLOCATEing A and LOCKing B, LOCKing B does not release A, and
+   ZALLOCATEing C does not release A or B.
 
-   In $ZTRAP handler. Error was:
+   ZDEALLOCATE releases ZALLOCATED resource names. The ZDEALLOCATE command
+   can only release previously ZALLOCATEd (not LOCKed) names.
 
-   150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled
-   back transaction.
+   Resource name arguments for LOCKs and ZALLOCATEs intersect. That is, if
+   one process holds a LOCK or ZALLOCATE, another process can neither LOCK
+   nor ZALLOCATE any name falling in the hierarchy of the resource name held
+   by the first process. When a process holds a LOCK or ZALLOCATE, that same
+   process may also LOCK or ZALLOCATE resource names falling in the hierarchy
+   of the currently held resource name. When a single process holds both
+   LOCKs and ZALLOCATEs, a LOCK does not release the ZALLOCATEd resource(s)
+   and a ZDEALLOCATE does not release the LOCKed resource(s).
 
-   Done TP Timeout test.
+   Example:
 
-2 $ZMOde
-   $ZMOde
+   Lock ^AR(PNT)
+   .
+   .
+   .
+   ZAllocate ^AR(PNT,SUB)
+   .
+   .
+   .
+   Lock ^TOT(TDT)
+   .
+   .
+   ZDEALLOCATE ^AR(PNT,SUB)
 
-   $ZMO[DE] contains a string value indicating the process execution mode.
+2 ZBreak
+   ZBreak
 
-   The mode can be:
+   The ZBREAK command sets or clears routine breakpoints during debugging.
 
-   o    INTERACTIVE
+   The format of the ZBREAK command is:
 
-   o    OTHER
+   ZB[REAK][:tvexpr] [-]entryref[:[expr][:intexpr]][,...]
 
-   M routines cannot modify $ZMODE.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>ZPRint ^ZBTEST
+   ZBTEST;
+        Do SUB
+        Quit
+   SUB  Write !,"This is ZBTEST"
+        Quit
+   GTM>ZBREAK SUB^ZBTEST
 
-   GTM> WRITE $ZMODE
+   GTM>Do ^ZBTEST
+   %GTM-I-BREAKZBA, Break instruction encountered during ZBREAK action
+   At M source location SUB^ZBTEST
+   GTM>ZSHOW "B"
+   SUB^ZBTEST
 
-   INTERACTIVE
+   This inserts a ZBREAK with a default action at SUB^ZBTEST. After GT.M
+   encounters the BREAK, the ZSHOW "B" displays this as the only ZBREAK in
+   the image.
 
-   This displays the process mode.
+   Example:
 
-2 $ZPOSition
-   $ZPOSition
+   GTM>ZBREAK -*
 
-   $ZPOS[ITION] contains a string value specifying the  current  entryref,
-   where entryref is [label][+offset]^routine, and the offset is evaluated
-   from the closest preceding label.
+   GTM>ZGOTO
 
-   GT.M does not permit the SET or NEW commands to modify $ZPOSITION.
+   GTM>ZBREAK SUB^ZBTEST:"W !,""Trace"""
 
-   Example:
+   GTM>Do ^ZBTEST
+   Trace
+   This is ZBTEST
+   GTM>
 
-   GTM>WRITE !,$ZPOS,! ZPRINT @$ZPOS
+   This removes all existing ZBREAKs with a ZBREAK -*. Note that it is not
+   necessary to remove ZBREAKs before modifying them. It also clears the
+   process invocation stack with an argumentless ZGOTO. Then it uses a ZBREAK
+   to insert a trace-point. Every time GT.M executes the line to where ZBREAK
+   has established a trace-point, it performs the specified action without
+   entering Direct Mode.
 
-   This example displays the current location followed by the source code
-   for that line.
+   Example:
 
-2 $ZPROMpt
-   $ZPROMpt
+   ZBreak PRINT^TIME::5
 
-   $ZPROM[PT] contains a string value specifying the current  Direct  Mode
-   prompt. By default, GTM> is the Direct  Mode  prompt.  M  routines  can
-   modify $ZPROMPT by means of a SET command. $ZPROMPT  cannot  exceed  16
-   characters. If an attempt is  made  to  assign  $ZPROMPT  to  a  longer
-   string, only the first 16 characters will be taken.
+   This BREAKs execution at line PRINT in routine just before the fifth time
+   the line is executed.
 
    Example:
 
+   ZBREAK PRINT^TIME:"WRITE AVE BREAK":3
 
-   GTM>SET $ZPROMPT="NEWZPROMPT>"
+   This inserts a ZBREAK action of WRITE AVE and BREAK before the third
+   execution of PRINT^TIME.
 
-   NEWZPROMPT>
+2 ZCOMpile
+   ZCOMpile
 
-   This example changes the GT.M prompt to be NEWZPROMPT
+   The ZCOMPILE command invokes the GT.M compiler from within the GT.M
+   run-time environment.
 
-2 $ZROutines
-   $ZROutines
+   Within GT.M itself, ZCOMPILE provides the functionality of the mumps
+   command, except for mumps -direct.
 
-   $ZRO[UTINES] contains a string value specifying a directory or list of
-   directories containing object files. Each  object  directory  may  also
-   have an associated directory, or list of  directories,  containing  the
-   corresponding source files. These directory lists are used  by  certain
-   GT.M functions, primarily  auto-ZLINK,  to  locate  object  and  source
-   files. The order in which directories appear in a given list determines
-   the order in which they are searched for the appropriate item.
+   The format of the ZCOMPILE command is:
 
-   Searches that use $ZROUTINES treat files as  either  object  or  source
-   files. GT.M treats files with an extension of .o as  object  files  and
-   files with an extension of .m as source files.
+   ZCOM[PILE][:tvexpr] expr[,...]
 
-        Paths used in  $ZROUTINES  to  locate  routines  must  not  include
-        embedded spaces, as $ZROUTINES uses spaces as delimiters.
+   The $ZCSTATUS intrinsic special variable holds the value of the status
+   code for the compilation performed by a ZCOMPILE command.
 
-3 Est_Val_frm_gtmroutines
-   Establishing the Value from gtmroutines
+3 Examples
+   Examples
 
-   When the environment variable gtmroutines is defined, GT.M initializes
-   $ZROUTINES to the value of  gtmroutines.  Otherwise,  GT.M  initializes
-   $ZROUTINES to a null value. When $ZROUTINES is null, GT.M  attempts  to
-   locate all source and object files in the  current  working  directory.
-   $ZROUTINES="" is equivalent to $ZROUTINES=".".
+   Examples:
 
-   Commands or functions such as DO,  GOTO,  ZGOTO,  ZBREAK,  ZPRINT,  and
-   $TEXT may auto-ZLINK and thereby indirectly use  $ZROUTINES.  If  their
-   argument does not specify a directory, ZEDIT  and  explicit  ZLINK  use
-   $ZROUTINES. ZPRINT and $TEXT use $ZROUTINES to locate a source file if
-   GT.M cannot find the source file pointed to by  the  object  file.  For
-   more information  on  ZLINK  and  auto-ZLINK,  refer  to  the  "Program
-   Development Cycle" and "Commands" chapters in GT.M Programmer's Guide.
-
-3 Set_Val_for_$ZRO
-   Setting a Value for $ZROUTINES
-
-   $ZRO[UTINES] is a read-write Intrinsic Special Variable, so M can also
-   SET the value.
-
-   By default, each directory entry in $ZROUTINES is  assumed  to  contain
-   both object and source files. However, each object directory  may  have
-   an associated directory or  list  of  directories  to  search  for  the
-   corresponding source files. This  is  done  by  specifying  the  source
-   directory  list,  in  parentheses,  following  the  object  directory
-   specification.
+   ZCOMPILE "EXAMPLE'.m"
 
-   If the command specifies more than one source directory for  an  object
-   directory, the source directories must be separated by spaces, and the
-   entire list must be enclosed in parentheses ( )  following  the  object
-   directory-specification.  If  the  object  directory  should  also  be
-   searched for source, the name of that directory must be included in the
-   parentheses,  (usually  as  the  first  element  in  the  list).
-   Directory-specifications may also include empty parentheses, directing
-   GT.M to proceed as if no source files exist for objects located in the
-   qualified directory.
+   This compiles EXAMPLE.m in the current working directory.
 
-   To set $ZROUTINES outside of M, use the appropriate  shell  command  to
-   set gtmroutines. Because gtmroutines is a list, enclose  the  value  in
-   quotation marks (" ").
+   Example:
 
-   Changes to the value of $ZROUTINES during a GT.M invocation  only  last
-   for the current invocation, and do not change the value of gtmroutines.
+   ZCOMPILE "-list A*.m"
 
-   Directory specifications may include an environment variable. When GT.M
-   SETs $ZROUTINES, it translates all environment variables  and  verifies
-   the  syntax  and  the  existence  of  all  specified  directories.  If
-   $ZROUTINES is set to an invalid value, GT.M generates a run-time error
-   and does not change the value of $ZROUTINES.  Because  the  environment
-   variables are translated when $ZROUTINES is set, any changes  to  their
-   definition have no effect until $ZROUTINES is set again.
+   This compiles all files starting with a [capital] A and an extension of .m
+   in the current working directory and produces corresponding listing files
+   for each source / object.
 
-3 $ZRO_Examples
-   $ZROUTINES Examples
+2 ZContinue
+   ZContinue
 
-   Example:
+   The ZCONTINUE command continues routine execution after a BREAK command or
+   a <CTRL-C>.
 
+   The format of the ZCONTINUE command is:
 
-   GTM> s $zroutines=".(../src) $gtm_dist"
+   ZC[ONTINUE][:tvexpr]
 
-   This example directs GTM to look  for  object  modules  first  in  your
-   current directory, then in the distribution directory that contains the
-   percent routines. GT.M locates sources  for  objects  in  your  current
-   directory in the sibling /src directory.
+2 ZDeallocate
+   ZDeallocate
 
-   Example:
+   The ZDEALLOCATE command releases a specified resource name or names
+   previously reserved by the ZALLOCATE command. The ZDEALLOCATE command
+   releases only the specified name(s) without releasing other names
+   previously reserved with the ZALLOCATE or LOCK command.
 
-   $ gtmroutines="/usr/jones /usr/smith"
+   The ZDEALLOCATE command provides compatibility with some other GT.M
+   implementations. The M Development Committee choose to add the + and -
+   delimiters to the LOCK command rather than adopt the ZALLOCATE and
+   ZDEALLOCATE approach. Therefore, when a design requires an incremental
+   lock mechanism, LOCK +/- has the advantage of being part of the M
+   standard. LOCK +/- also has the advantage of working symmetrically when
+   routines using LOCKs are nested.
 
-   $ export gtmroutines
+   The format of the ZDEALLOCATE command is:
 
-   $ gtm
+   ZD[EALLOCATE][:tvexpr] [nref[,...]]
 
-   GTM> write $zroutines
+3 Examples
+   Examples
 
-   "/usr/jones /usr/smith"
+   Example:
 
-   GTM> set $zro="/usr/jones/utl /usr/smith/utl"
+2 ZEDit
+   ZEDit
 
-   GTM> write $zroutines
+   The ZEDIT command invokes the editor specified by the EDITOR environment
+   variable for GT.M and opens the specified file for editing. If the EDITOR
+   environment variable is undefined, ZEDIT tries to invoke the UNIX vi
+   editor.
 
-   "/usr/jones/utl /usr/smith/utl"
+   By default, ZEDIT puts a new file into the first source directory in
+   $ZROUTINES. You can specify a file path explicitly in the argument to the
+   ZEDIT command, for example: the current working directory:
 
-   GTM> halt
+   ZEDIT "./file"
 
-   $ echo $gtmroutines
+   The format of the ZEDIT command is:
 
-   /usr/jones /usr/smith
+   ZED[IT][:tvexpr] [expr[,...]]
+
+   When the argument to a ZEDIT includes a file or path name, $ZSOURCE
+   maintains that as a default for ZEDIT and ZLINK.
 
-   This  example  defines  the  environment  variable  gtmroutines.  Upon
-   entering  GT.M  Direct  Mode  $zroutines  has  the  value  supplied  by
-   gtmroutines. The SET command changes the value.  When  the  GT.M  image
-   terminates, the shell echo command demonstrates  that  gtmroutines  has
-   not been modified by the M SET command.
+3 Examples
+   Examples
 
    Example:
 
-   GTM> SET $ZRO=". /usr/smith"
+   GTM>ZEDIT "BAL"
 
-   This example sets $zroutines to a list containing two directories.
+   This invokes the editor for a file with a name of BAL and an extension of
+   .m. Notice that BAL is a string literal.
 
    Example:
 
+   GTM>Set prog="BAL"
 
-   GTM> set $zro="/usr/smith(/usr/smith/tax /usr/smith/fica)"
+   GTM>ZEDit prog
 
-   This example specifies that GT.M should search the directory /usr/smith
-   for  object  files,  and  the  directories  /usr/smith/tax  and
-   /usr/smith/fica for source files. Note that in this example. GT.M does
-   not search /usr/smith for source files.
+   This is similar to the first example except that it uses a variable
+   argument rather than a string literal.
 
    Example:
 
-   GTM> set $zro="/usr/smith(/usr/smith /usr/smith/tax /usr/smith/fica)"
+   GTM>zedit ".login"
 
-   This example specifies that GT.M should search the directory /usr/smith
-   for object files and the directories /usr/smith/tax and /usr/smith/fica
-   for source files. Note that the difference between this example and the
-   previous one is that GT.M  searches  /usr/smith  for  both  object  and
-   source files.
+   This invokes the editor for a file with the name .login. Notice that in
+   this case the file is not a GT.M file, since .login starts with a period,
+   and therefore, cannot be a GT.M file.
 
-   Example:
+2 ZGoto
+   ZGoto
 
+   The ZGOTO command transfers control to various levels in the GT.M
+   invocation stack. It also can transfer control from one part of the
+   routine to another or from one routine to another using the specified
+   entryref.
 
-   GTM> set $zro="/usr/smith /usr/smith/tax()
+   The format of the ZGOTO command is:
 
-   /usr/smith/fica"
+   ZG[OTO][:tvexpr] [[intexpr][:entryref[:tvexpr]],...]
 
-   This specifies that GT.M should search /usr/smith  and  /usr/smith/fica
-   for object and source files. However,  because  the  empty  parentheses
-   indicate directories searched only for  object  files,  GT.M  does  not
-   search /usr/smith/tax for source files.
+3 Examples
+   Examples
 
-   Omitting the parentheses indicates that GT.M can search  the  directory
-   for both source and object files. $ZROUTINES=/usr/smith  is  equivalent
-   to $ZROUTINES=/usr/smith(/usr/smith).
+   Example:
 
-3 $ZRO_Search_Types
-   $ZROUTINES Search Types
+   GTM>ZGOTO
 
-   GT.M uses $ZRO[UTINES] to perform three types of searches:
+   GTM>ZSHow
+   +1^GTM$DMOD (Direct mode)
+   GTM>
 
-   o    Object-only when the command or function using $ZROUTINES requires
-        a .o file extension.
+   This uses ZGOTO to clear all levels of the GT.M invocation stack. ZSHOW
+   with no arguments displays the stack.
 
-   o    Source-only when the command or function using $ZROUTINES requires
-        a file extension other than .o.
+   Example:
 
-   o    Object-source match when the command or function  using  $ZROUTINES
-        does not specify a file extension.
+   SET $ZTRAP="ZGOTO "_$ZLEVEL_":^ERROR"
 
-   An explicit ZLINK that specifies a non .o extension is considered as a
-   function that  has  not  specified  a  file  extension  for  the  above
-   searching purposes.
+   This SETs $ZTRAP to contain a ZGOTO, so if an error causes GT.M to XECUTE
+   $ZTRAP, the routine ERROR executes at the same level as the SET command
+   shown in the example.
 
-   All searches proceed from left to right through $ZROUTINES. By default,
-   GT.M searches directories  for  both  source  and  object  files.  GT.M
-   searches directories followed by empty parentheses ( ) for object files
-   only. GT.M searches directories in parentheses only for source files.
+2 ZHelp
+   ZHelp
 
-   Once an object-matching search  locates  an  object  file,  the  source
-   search becomes limited. If the directory containing the object file has
-   an attached parenthetical list of directories, GT.M only  searches  the
-   directories in the attached list for  matching  source  files.  If  the
-   directory  containing  the  object  files  does  not  have  following
-   parentheses, GT.M restricts the search for matching source files to the
-   same directory. If the object module is in  a  directory  qualified  by
-   empty parentheses, GT.M cannot perform any operation that refers to the
-   source file.
+   The ZHELP command accesses the help information from the GTM help library
+   or from any help library specified in the command argument.
 
-3 $ZRO_Search_Ex
-   $ZROUTINES Search Examples
+   The format of the ZHELP command is:
 
-   This section describes a model for understanding $ZROUTINES operations
-   and the illustrating examples, which may assist  you  if  you  wish  to
-   examine the topic closely.
+   ZH[ELP][:tvexpr] [expr1[:expr2],...]
 
-   You may think of $ZROUTINES as supplying a two  dimensional  matrix  of
-   places to look for files. The matrix has one or more  rows.  The  first
-   row in the matrix contains places to look for object and the second and
-   following  rows  contain  places  to  look  for  source.  Each  column
-   represents the set of places that contain information  related  to  the
-   object modules in the first row of the column.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>zhelp "func $data"
 
-   GTM> s $zro=". /usr/smi/utl() /usr/jon/utl
+   This lists the help for function $DATA, which is a subtopic of functions
+   topic.
 
-   (/usr/jon/utl/so /usr/smi/utl)"
-3 Sh_Lib_FileSpec_in_$ZRO
-   Shared Library File Specification in $ZROUTINES
+   Example:
 
-   The $ZROUTINES ISV allows individual UNIX shared library file names to
-   be specified in the search path. During a search for auto-ZLINK, when a
-   shared library is encountered, it is probed for a given routine and, if
-   found, that routine is linked/loaded into the image. During an explicit
-   ZLINK, all shared libraries in  $ZROUTINES  are  ignored  and  are  not
-   searched for a given routine.
-
-   Currently GT.M supports this feature on  Tru64  operating  system,  and
-   plans to support other UNIX operating system in near future.
-
-   $ZROUTINES  syntax  contains  a  file-specification  indicating  shared
-   library file path. GT.M does not require any designated  extension  for
-   the shared library component of $ZROUTINES. Any file specification that
-   does not name a directory is treated as shared library. However, it is
-   recommended that the extension commonly used on a  given  platform  for
-   shared library files be given to any GT.M shared libraries.  (Refer  to
-   the following section  on  "Linking  GT.M  Shared  Images").  A  shared
-   library component cannot specify source directories.  GT.M  reports  an
-   error at an attempt to associate any source  directory  with  a  shared
-   library in $ZROUTINES.
+   GTM>zhelp
 
-   The following traits of $ZROUTINES help support shared libraries:
+   This uses ZHELP to list all the keywords in the help library.
+
+   Example:
+
+   GTM>zhelp "ZSHOW"
 
-   o    The $ZROUTINES search continues to find objects in the first place,
-        processing from left to right, that holds a copy;  it  ignores  any
-        copies in subsequent locations. However, now for auto-ZLINK, shared
-        libraries are accepted as object repositories with the same ability
-        to supply objects as directories.
+   This lists the help for command ZSHOW.
 
-   o    Explicit ZLINK, never searches Shared Libraries.  This  is  because
-        explicit ZLINK is used to link a newly created routine or re-link a
-        modified routine and there is no mechanism to load new objects into
-        an active shared library.
+2 ZLink
+   ZLink
 
-   o    ZPRINT and $TEXT() of the routines in a shared library, read source
-        file path from the header of the loaded routine. If the image does
-        not contain the routine, an auto-ZLINK is initiated. If the source
-        file path recorded in  the  routine  header  when  the  module  was
-        compiled cannot be located, ZPRINT and $TEXT()  initiate  a  search
-        from the beginning of $ZROUTINES, skipping over the shared library
-        file specifications. If the located source does not match the code
-        in image (checked via checksum), ZPRINT generates an object-source
-        mismatch status and $TEXT() returns a null string.
+   The ZLINK command adds an executable GT.M routine to the current process
+   if the current process does not contain a copy of a routine. If the
+   current process contains a copy of a routine and the routine is not
+   active, the ZLINK command replaces the current routine process with a
+   "new" version. If necessary, the ZLINK command compiles the routine prior
+   to integrating it with the process.
 
-   o    ZEDIT, when  searching  $ZROUTINES,  skips  shared  libraries  like
-        explicit ZLINK for the same reasons. $ZSOURCE ISV is implicitly set
-        to the appropriate source file.
+   **Important**
 
-   For  example,  if  libshare.so  is  built  with  foo.o  compiled  from
-   ./shrsrc/foo.m, the following commands specify that GT.M should search
-   the library ./libshare.so for symbol foo when do ^foo is encountered.
+   An active routine is displayed with $STACK() or ZSHOW "S. of the M virtual
+   stack. An attempt to replace an active routine results in a run-time error
+   because changing a routine in progress could have unpredictable results.
+   To replace an active routine with a new version, first remove the active
+   routine from the stack using ZGOTO or the appropriate number of QUITs and
+   then execute the ZLINK command.
 
+   The format of the ZLINK command is:
 
-   GTM>SET $ZROUTINES="./libshare.so ./obj(./shrsrc)"
+   ZL[INK][:tvexpr] [expr1[:expr2][,...]]
 
-   GTM>DO ^foo ;auto-ZLINK foo - shared
+3 ZLINK_Compilation
+   ZLINK Compilation
 
-   GTM>ZEDIT "foo" ;edit ./shrsrc/foo.m
+   If ZLINK compiles a routine and the -OBJECT= qualifier does not redirect
+   the output, it places the resulting object file in the directory indicated
+   by the search criteria. ZLINK incorporates the new object file into the
+   image, regardless of its directory placement.
 
-   GTM>W $ZSOURCE,! ;prints foo
+   If the command does not specify compile qualifiers (with expr2) and
+   $ZCOMPILE is null, GT.M uses the default M command qualifiers, -ignore,
+   -labels=lower, -nolist, and -object.
 
-   GTM>ZPRINT +0^foo ;issues a  source-object  mismatch  status  TXTSRCMAT
-   error message
-   GTM>ZLINK "foo" ;re-compile ./shrsrc/foo.m to generate ./obj/foo.o.
+3 Examples
+   Examples
 
-   GTM>W $TEXT(+0^foo) ;prints foo
+   Example:
 
-   Note that ZPRINT reports an error, as foo.m does not match the routine
-   already linked into image. Also note that, to recompile and re-link the
-   ZEDITed foo.m, its source directory needs to be attached to the object
-   directory [./obj] in $ZROUTINES. The example assumes the shared library
-   (libshare.so) has been built using shell  commands.  The  procedure  to
-   build a shared library from a list of GT.M generated object (.o) files
-   is detailed in the following section on "Linking GT.M Shared Images".
+   GTM>ZLINK "test"
 
-4 Link_GTM_Sh_Image
-   Linking GT.M Shared Images
+   If ZLINK finds test.m or test.o, it adds the routine test to the current
+   image. If ZLINK does not find test.o, or finds that test.o is older than
+   test.m, GT.M compiles test.m to produce a new test.o, and adds the
+   contents of the new object file to the image. This example assumes "test"
+   is not on the current M stack - if it is on the stack, GT.M gives an
+   error.
 
-   Following are the steps (UNIX system commands, and GT.M commands) that
-   need to be taken to use GT.M shared image linking with $ZROUTINES.
+   Example:
 
-5 Comp_SrcFile_to_ObjFile
-   Compile Source (.m) Files to Object (.o) Files
+   GTM>zlink "test.m":"-noobject -list"
 
-   In order to share M routines, GT.M generates objects (.o) with position
-   independent code, a  primary  requirement  for  shared  libraries.  All
-   objects must be generated by a release of  GT.M  that  supports  shared
-   binaries linking.
+   This compiles the routine "test" and produces a listing but no object
+   file. Because the example produces no object file, it must locate an
+   existing object file (which might be the same as any copy in the current
+   image); if there is noexisting object file, GT.M produces an error. While
+   this example shows the use of compilation qualifiers with ZLINK, a
+   -noobject -list compilation might better be done with ZCOMPILE.
 
-5 Creat_ShLib_from_ObjFile
-   Create a Shared Library from Object (.o) Files
+3 Auto-ZLINK
+   Auto-ZLINK
 
-   On each UNIX platform, the  native  linker  ld  provides  command  line
-   options to create a shared  library  from  a  list  of  .o  files.  The
-   specific ld options vary depending on the platform.
+   If a GT.M routine refers to a routine that is not linked to the GT.M
+   image, GT.M automatically attempts to ZLINK that routine. An auto-ZLINK is
+   functionally equivalent to an explicit ZLINK of a routine without a
+   specified directory or file extension.
 
-   Although GT.M does not require a specific  file  extension  for  shared
-   libraries, it is recommended that the conventional  extension  (.so  on
-   Tru64) be used on a given platform. For example,  the  following  Tru64
-   linker command
+   The following GT.M commands and functions can initiate auto-ZLINKing:
 
+     * DO
+     * GOTO
+     * ZBREAK
+     * ZGOTO
+     * ZPRINT
+     * $TEXT()
 
-   $ ld -shared -taso -o libabc.so a.o b.o c.o -lc
+   GT.M auto-ZLINKs the routine if the following conditions are met:
 
-   creates a shared library libabc.so from GT.M object files a.o, b.o and
-   c.o. The flag -taso directs the linker to generate  32-bit  addressable
-   Shared Library. Without this option, Tru64 UNIX ld generates  a  64-bit
-   addressable  shared  library  by  default.  Even  though  GT.M  can
-   successfully load 64-bit shared library, Sanchez recommends the use of
-   the -taso option for best compatibility with the GT.M memory model.
+     * ZLINK can locate and process the routine file, as indicated in the
+       previous ZLINK Operation Summary table
+     * The name of the routine is the same as the name of the source file;
+       the only exception is that GT.M converts a leading percent sign (%) in
+       a file name to an underscore (_).
 
-   Notes on Tru64 UNIX linker:
+3 ZLINK,_auto-ZLINK_and_Routine_Names
+   ZLINK, auto-ZLINK and Routine Names
 
-   o    The linker (ld) may have a limit on the number of object files that
-        it can accept on the command line. If ld fails to read all objects
-        from the command line, users  are  recommended  to  use  -input  to
-        specify a text file <command-file> that contains all  object  files
-        as if they were specified on the command line.
+   In GT.M, the name of the source file determines the name of the GT.M
+   routine. The file name of the object file is not required to match the
+   name of the routine. Linking the object file makes the internal routine
+   name (derived from the source file) known to GT.M. This can lead to
+   potential confusion, however, since both ZLINK and auto-ZLINK use the name
+   of the object file to find the routine. When the object file name differs
+   from the name of the routine, auto-ZLINK generates a run-time error.
 
-   o    When creating a shared library, Sanchez suggests linking with the C
-        library (-lc at the end of link line) to prevent ld from reporting
-        various undefined-symbol warnings. These undefines are not relevant
-        to the use of the GT.M shared library routines but linking with the
-        C library eliminates the linker warning messages.
+2 ZKill
+   ZKill
 
-   o    See ld manual pages (UNIX shell command - man ld) for more details
-        of linker options.
+   The ZKILL command KILLs the data value for a variable name without
+   affecting the nodes descended from that node.
 
-5 Est_$ZRO_frm_gtmroutines
-   Establish $ZROUTINES from gtmroutines
+   The format of the ZKILL command is:
 
-   When  the  UNIX  environment  variable  gtmroutines  is  defined,  GT.M
-   initializes $ZROUTINES to the value of gtmroutines. The $ZROUTINES ISV
-   can also be modified using SET command.
+   ZK[ILL][:tvexpr] glvn
 
-   Example:
+2 ZMessage
+   ZMessage
 
+   The ZMESSAGE command raises an exception condition based on the specified
+   message code.
 
-   $ gtmroutines="./libabc.so ./obj(./src)"
+   The format of the ZMESSAGE command is:
 
-   $ export gtmroutines
+   ZM[ESSAGE][:tvexpr] intexpr[:expr2][:...]
 
-   $ mumps -direct
+3 Examples
+   Examples
 
-   GTM>write $ZROUTINES,! ;writes "./libabc.so ./obj(./src)"
+   All of the following examples issue ZMESSAGE from Direct Mode where
+   exception conditions do not invoke $ZTRAP.
 
-   GTM> do ^a ;runs ^a from libabc.so
+   Example:
 
-   GTM> do ^b ;runs ^b from libabc.so
+   GTM>ZMessage 2
 
-   GTM> do ^c ;runs ^c from libabc.so
+   %SYSTEM-E-ENO2, No such file or directory
 
-   GTM> halt
+   This ZMESSAGE does not specify substitution text and the message does not
+   include any substitution directives.
 
-   $
+   Example:
 
-2 $ZSOurce
-   $ZSOurce
+   GTM>ZMESSAGE 150372994
+   %GTM-E-GVUNDEF, Global Variable undefined:
 
-   $ZSO[URCE] contains a string value specifying the default pathname for
-   the ZEDIT and ZLINK commands. ZEDIT or ZLINK  without  an  argument  is
-   equivalent to ZEDIT/ZLINK $ZSOURCE.
+   The message specified by this ZMESSAGE command includes a substitution
+   directive but the command does not supply any text.
 
-   $ZSOURCE initially contains the  null  string.  When  ZEDIT  and  ZLINK
-   commands have a pathname for an argument, they implicitly set $ZSOURCE
-   to that argument. This ZEDIT/ZLINK argument can include a full pathname
-   or a relative one. A relative path could include a file in the current
-   directory, or the path to the file from the current working directory.
-   In the latter instance, do not  include  the  slash  before  the  first
-   directory name. $ZSOURCE will prefix the path to  the  current  working
-   directory including that slash.
+   Example:
 
-   The file name may contain a file extension. If the extension is  .m  or
-   .o, $ZSOURCE  drops  it.  The  ZEDIT  command  accepts  arguments  with
-   extensions other than .m or .o. $ZSOURCE  retains  the  extension  when
-   such arguments are passed.
+   GTM>ZMESSAGE 150373850:"x"
+   %GTM-E-GVUNDEF, Undefined local variable: x
 
-   If $ZSOURCE contains a file with an extension  other  than  .m  or  .o,
-   ZEDIT processes it but ZLINK returns an error message
+   This ZMESSAGE command supplies the substitution text for the message.
 
-   $ZSOURCE is a read-write Intrinsic  Special  Variable,  (i.e.,  it  can
-   appear on the left side of the equal sign (=) in the  argument  to  the
-   SET command). A $ZSOURCE value may include an environment variable.
+   GT.M treats its own odd-numbered conditions as "successful." GT.M handles
+   successful conditions by displaying the associated message and continuing
+   execution. GT.M treats its own even-numbered conditions as failures. GT.M
+   handles failure conditions by storing the error information in $ZSTATUS
+   and XECUTEing $ETRAP or $ZTRAP In Direct Mode, GT.M only reports failure
+   conditions to the principal device and does not XECUTE $ETRAP or $ZTRAP or
+   set $ZSTATUS. System service errors do not follow the GT.M odd/even
+   pattern.
 
-   Example:
+2 ZPrint
+   ZPrint
 
-   GTM> ZEDIT "subr.m"
+   The ZPRINT command displays the source code lines selected by its
+   argument.
 
-   .
+   The format of the ZPRINT command is:
 
-   .
+   ZP[RINT][:tvexpr][entryref[:label[+intexpr]][,...]
 
-   GTM> WRITE $ZSOURCE
+   Note that the routinename may only appear before the colon (:) delimiter.
+   The integer expression offsets may be positive or negative, but they must
+   always be delimited by a plus sign (+).
 
-   subr
+3 Examples
+   Examples
 
    Example:
 
-   GTM> ZEDIT "test"
+   GTM>ZPRINT X^RTN
 
-   .
+   This example displays the line beginning with the label X in the routine
+   RTN.
 
-   .
+   Example:
 
-   .
+   GTM>ZPRINT X^RTN:X+5
+
+   GTM>ZPRINT X+-5^RTN:X
 
-   GTM> WRITE $ZSOURCE
+   GTM>ZPRINT X^RTN:X+-5^RTN
 
-   test
+   The first line displays the line beginning with the label X and the next 5
+   lines in routine RTN. The second line displays the 5 lines preceding label
+   X in the same routine and the line beginning with label X. The third line
+   generates a run-time error because the routine name must appear only
+   before the colon in the argument.
 
    Example:
 
+   GTM>zprint ^A#1#
+    do ^test1
+    do stop^test2
+   GTM>
 
-   GTM> ZEDIT "/usr/smith/report.txt"
+   This command displays the trigger code for trigger name A#1#.
 
-   .
+2 ZSHow
+   ZSHow
 
-   .
+   The ZSHOW command displays information about the current GT.M environment.
 
-   .
+   The format of the ZSHOW command is:
 
-   GTM> WRITE $ZSOURCE
+   ZSH[OW][:tvexpr][expr[:glvn][,...]]
 
-   /usr/smith/report.txt
+3 ZSHOW_Information_Codes
+   ZSHOW Information Codes
+
+   A ZSHOW argument is an expression containing codes selecting one or more
+   types of information.
+
+   B: displays active ZBREAK breakpoints
+
+   C: displays available external call table entry names
+
+   D: displays device information
+
+   G: displays the access statistics for global variables and access to
+   database file since process startup
+
+   I: displays the current values of all intrinsic special variables
+
+   L: displays GT.M LOCKs and ZALLOCATEs held by the process
+
+   S: displays the GT.M invocation stack
+
+   V: displays local and alias variables
+
+   * displays all possible types of ZSHOW information
+
+   Codes may be upper- or lower-case. Invalid codes produce a run-time error.
+   Multiple occurrences of the same code in one ZSHOW argument only produce
+   one output instance of the corresponding information. The order of the
+   first appearance of the codes in the argument determines the order of the
+   corresponding output instances.
+
+   If you are using a local variable destination and place another code ahead
+   of "V", the effect is to have the results of the earlier code also appear
+   in the results of the "V" code.
+
+   If the wildcard (*) occurs in the list, ZSHOW uses the default order
+   (ZSHOW "IVBDLGSC" ):
+
+   If G occurs in the list, the statistics are displayed in the following
+   order in a comma-separated list where each item has its mnemonic followed
+   by a colon and a counter. GT.M maintains the counter in DECIMAL. Each
+   counter has 8-byte (can get as high as 2**64). If these counters exceed 18
+   decimal digits (somewhere between 2**59 and 2**60), which is the current
+   GT.M numeric representation precision threshold, their use in arithmetic
+   expressions in GT.M results in loss of precision. The mnemonics are:
+
+   SET : # of SET operations (TP and non-TP)
+   KIL : # of KILl operations (kill as well as zwithdraw, TP and non-TP)
+   GET : # of GET operations (TP and non-TP)
+   DTA : # of DaTA operations (TP and non-TP)
+   ORD : # of $ORDer() operations (TP and non-TP). The count of $Order(xxx,1) operations are reported under this item.
+   ZPR : # of $ZPRevious() (reverse order) operations (TP and non-TP). The count of $Order(xxx,-1) operations are reported under this item.
+   QRY : # of $QueRY() operations (TP and non-TP)
+   LKS : # of LocK calls (mapped to this db) that Succeeded
+   LKF : # of LocK calls (mapped to this db) that Failed
+   CTN : Current Transaction Number of the database for the last committed read-write transaction (TP and non-TP)
+   DRD : # of Disk ReaDs from the database file (TP and non-TP, committed and rolled-back).This does not include reads that are satisfied by buffered globals for databases that use the BG (Buffered Global) access method. GT.M always reports 0 for databases that use the MM (memory-mapped) access method as this has no real meaning in that mode.
+   DWT : # of Disk WriTes to the database file (TP and non-TP, committed and rolled-back). This does not include writes that are satisfied by buffered globals for databases that use the BG (Buffered Global) access method. GT.M always reports 0 for databases that use the MM (memory-mapped) access method as this has no real meaning in that mode.
+   NTW : # of Non-TP committed Transactions that were read-Write on this database
+   NTR : # of Non-TP committed Transactions that were Read-only on this database
+   NBW : # of Non-TP committed transaction induced Block Writes on this database
+   NBR : # of Non-TP committed transaction induced Block Reads on this database
+   NR0 : # of Non-TP transaction Restarts at try 0
+   NR1 : # of Non-TP transaction Restarts at try 1
+   NR2 : # of Non-TP transaction Restarts at try 2
+   NR3 : # of Non-TP transaction Restarts at try 3
+   TTW : # of TP committed Transactions that were read-Write on this database
+   TTR : # of TP committed Transactions that were Read-only on this database
+   TRB : # of TP read-only or read-write transactions that got Rolled Back (incremental rollbacks are not counted)
+   TBW : # of TP transaction induced Block Writes on this database
+   TBR : # of TP transaction induced Block Reads on this database
+   TR0 : # of TP transaction Restarts at try 0 (counted for all regions participating in restarting TP transaction)
+   TR1 : # of TP transaction Restarts at try 1 (counted for all regions participating in restarting TP transaction)
+   TR2 : # of TP transaction Restarts at try 2 (counted for all regions participating in restarting TP transaction)
+   TR3 : # of TP transaction Restarts at try 3 (counted for all regions participating in restarting TP transaction)
+   TR4 : # of TP transaction Restarts at try 4 and above (restart counted for all regions participating in restarting TP transaction)
+   TC0 : # of TP transaction Conflicts at try 0 (counted only for that region which caused the TP transaction restart)
+   TC1 : # of TP transaction Conflicts at try 1 (counted only for that region which caused the TP transaction restart)
+   TC2 : # of TP transaction Conflicts at try 2 (counted only for that region which caused the TP transaction restart)
+   TC3 : # of TP transaction Conflicts at try 3 (counted only for that region which caused the TP transaction restart)
+   TC4 : # of TP transaction Conflicts at try 4 and above (counted only for that region which caused the TP transaction restart)
+   DFL : # of times a process flushes the entire set of dirty database global buffers in shared memory to disk.
+   DFS : # of times a process does an fsync of the database file. For example: a) after writing an epoch journal record, b) as part of database file extension c) during database rundown d) as part of mupip reorg -truncate etc.
+   JFL : # of times a process flushes all dirty journal buffers in shared memory to disk. For example: when switching journal files etc.
+   JFS : # of times a process does an fsync of the journal file. For example: when writing an epoch record, switching a journal file etc.
+   JBB : # of bytes written to the journal buffer in shared memory.
+   JFB : # of bytes written to the journal file on disk. For performance reasons, GT.M always aligns the beginning of these writes to file system block size boundaries. On Unix, JFB counts all bytes including those needed for alignment in order to reflect the actual IO load on the journal file. Since the bytes required to achieve alignment may have already been counted as part of the previous JFB, processes may write the same bytes more than once, causing the JFB counter to typically be  [...]
+   JFW : # of times a process invokes a write system call for a journal file.
+   JRL : # of logical journal records (e.g. SET, KILL etc.)
+   JRP : # of PBLK and AIMG journal records written to the journal file (these records are seen only in a -detail journal extract)
+   JRE : # of regular EPOCH journal records written to the journal file (only seen in a -detail journal extract); these are written every time an epoch-interval boundary is crossed while processing updates
+   JRI : # of idle EPOCH journal records written to the journal file (only seen in a -detail journal extract); these are written when a burst of updates is followed by an idle period, around 5 seconds of no updates after the database flush timer has flushed all dirty global buffers to the database file on disk
+   JRO : # of all journal records other than logical, PBLK, AIMG and EPOCH records written to the journal file (for example, PINI, PFIN, and so on.)
+   JEX : # of times a process extends the journal file
+   DEX : # of times a process extends the database file
+
+   [NT]B[WR] mnemonics are satisfied by either disk access or, for databases that use the BG (buffered global) access method, global buffers in shared memory.
+
+3 Examples
+   Examples
 
    Example:
 
-   GTM> ZLINK "BASE.O"
+   GTM>ZSHOW "db"
 
-   .
+   This command displays all devices with deviceparameters reflecting their
+   current characteristics followed by any current ZBREAK locations with
+   their corresponding actions.
 
-   .
+   Example:
 
-   .
+   GTM>ZSHOW "dbd"
 
-   GTM> WRITE $ZSOURCE
+   This command displays the same output as the previous example.
 
-   BASE
+   Example:
 
-2 $ZStatus
-   $ZStatus
+   GTM>ZSHOW "ax"
 
-   $ZS[TATUS] contains a string value specifying the error condition code
-   and location of the  last  exception  condition  that  occurred  during
-   routine execution.
+   This command generates a run-time error.
 
-   GT.M maintains $ZSTATUS  as  a  string  consisting  of  three  or  more
-   substrings. The string consists of the following:
+   Example:
 
-   o    An error message number as the first substring.
+   LAB1  DO LAB2
+         Quit
+   LAB2  Do LAB3
+         Quit
+   LAB3  ZSHow
+         Quit
 
-   o    The entryref of the line in error as the second substring; a comma
-        (,) separates the first and second substrings.
+   Produces the results:
+
+   LAB3^RTN
+   LAB2^RTN
+   LAB1^RTN
 
-   o    The message detail as the third substring. The format of this is a
-        percent sign (%) identifying the message  facility,  a  hyphen  (-)
-        identifying the error  severity,  another  hyphen  identifying  the
-        message identification followed by a comma (,), which  is  followed
-        by the message text if any:
+   Example:
 
-   Format: %<FAC>-<SEV>-<ID>, <TEXT>
+   GTM>ZSHOW "G"
 
-   Example: %GTM-E-DIVZERO, Attempt to divide by zero
+   For process that has access to two database files produces results like
+   the following:
+
+   GLD:*,REG:*,SET:205,KIL:0,GET:1,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:9,DWT:15,
+   NTW:203,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,TBW:2,TBR:6,
+   TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
 
-   GT.M sets $ZSTATUS when it encounters errors during program execution,
-   but not when it encounters errors in a Direct Mode command.
+   GLD:/home/gtmuser1/.fis-gtm/V5.4-002B_x86/g/mumps.gld,REG:DEFAULT,SET:205,KIL:0,GET:1,
+   DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:411,DRD:9,DWT:15,NTW:2
+   03,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,TBW:2,TBR:6,TR0:0,
+   TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
 
-   $ZSTATUS is a read-write Intrinsic  Special  Variable,  (i.e.,  it  can
-   occur on the left side of the equal sign (=) in the argument to the SET
-   command). While it will accept any string, Sanchez Computer Associates
-   recommends setting it to null. M routines cannot modify  $ZSTATUS  with
-   the NEW command.
+   GLD:/tmp/tst/test.gld,REG:DEFAULT,SET:205,KIL:0,GET:1,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,
+   CTN:411,DRD:9,DWT:15,NTW:203,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,
+   TBW:2,TBR:6,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
 
    Example:
 
+   GTM>ZSHOW "G"
 
-   GTM> WRITE $ZSTATUS
+   Assuming that a GT.M process uses the global directory "/tmp/x1.gld" and
+   opens two regions REG1 and REG2 corresponding to two database files, the
+   above command produces results like the following:
 
-   150373110,+1^MYFILE,%GTM-E-DIVZERO,
-   Attempt to divide by zero
+   GLD:*,REG:*,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,
+   NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,TTR:0,TRB:0,
+   TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
 
-   This example displays the status generated by a divide by zero (0).
+   GLD:/tmp/x1.gld,REG:REG1,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,
+   DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
+   TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
+   GLD:/tmp/x1.gld,REG:REG2,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,
+   DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
+   TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
 
-2 $ZSTep
-   $ZSTep
+   Example:
 
-   $ZST[EP] contains a string value specifying the default action for the
-   ZSTEP command. $ZSTEP provides the ZSTEP action  only  when  the  ZSTEP
-   command does not specify an action.
+   GTM>ZSHOW "G":zgbl
 
-   $ZSTEP initially contains the string "B" to enter direct  mode.  $ZSTEP
-   is a read-write Intrinsic Special Variable, (i.e., it can appear on the
-   left side of the equal sign (=) in the argument to the SET command).
+   This example redirects the output of ZSHOW "G" into a local variable zgbl:
+
+   zgbl("G",0)="GLD:*,REG:*,SET:0,KIL:0,GET:0,DTA:0,ORD:0,
+   ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
+   TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
+   zgbl("G",1)="GLD:/tmp/x1.gld,REG:REG1,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,
+   LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,
+   NR3:0,TTW:0,TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
+   zgbl("G",2)="GLD:/tmp/x1.gld,REG:REG2,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,
+   LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,
+   NR3:0,TTW:0,TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
 
    Example:
 
-   GTM> WRITE $ZSTEP
+   GTM>LOCK ^FAIL:10
 
-   B
+   GTM>lock (^SUCCESS1,^SUCCESS2)
 
-   GTM>
+   GTM>zshow "L"
+   MLG:1,MLT:1
+   LOCK ^SUCCESS1 LEVEL=1
+   LOCK ^SUCCESS2 LEVEL=1
 
-   This example displays  the  current  value  of  $ZSTEP,  which  is  the
-   default.
+   This output shows that a process locked ^SUCCESS1 and ^SUCCESS2 and
+   another the lock on ^FAIL failed due to time out.
+
+   Note that even though two lock resources ^SUCCESS1 and ^SUCCESS2 were
+   specified in the LOCK command that succeeded, GT.M increments the MLG
+   counter by only 1 because they are part of the same LOCK command. A ZSHOW
+   "L":var by the same process (redirecting the output of ZSHOW into a local
+   or global variable) would result in <var> holding the following contents.
+
+   var("L",0)="MLG:1,MLT:1"
+   var("L",1)="LOCK ^SUCCESS1 LEVEL=1"
+   var("L",2)="LOCK ^SUCCESS2 LEVEL=1"
 
    Example:
 
+   GTM>ZSHOW "L":var
+   GTM>ZWRITE var
+   var("L",0)="MLG:1,MLT:1"
+   var("L",1)="LOCK ^SUCCESS1 LEVEL=1"
+   var("L",2)="LOCK ^SUCCESS2 LEVEL=1"
 
-   GTM> SET $ZSTEP="ZP @$ZPOS B"
+   This example shows how ZSHOW "L" redirects it output into a local variable
+   var.
 
-   This example sets $ZSTEP to code that displays the contents of the next
-   line to execute, and then enters Direct Mode.
+   Example:
 
-2 $ZSYstem
-   $ZSYstem
+   Suppose a process runs LOCK (^SUCCESS1,^SUCCESS2) which succeeds and a
+   LOCK +^FAIL:1 which times out due to another process holding that lock. A
+   ZSHOW "L" at this point displays the following output.
 
-   $ZSY[STEM] holds the value of the status code for the  last  subprocess
-   invoked with the ZSYSTEM command.
+3 ZSHOW_Destination_Variables
+   ZSHOW Destination Variables
 
-2 $ZTExit
-   $ZTExit
+   ZSHOW may specify an unsubscripted or subscripted global or local variable
+   name (glvn) into which ZSHOW places its output. If the argument does not
+   include a global or local variable name, ZSHOW directs its output to the
+   current device.
 
-   $ZTE[XIT] contains a string value  that  controls  the  GT.M  interrupt
-   facility at the transaction  commit  or  rollback.  At  each  outermost
-   TCOMMIT or TROLLBACK, If +$ZTEXIT evaluates to  non-zero  (TRUE),  then
-   $ZINTERRUPT is XECUTEd after completing the commit or rollback.
+   When ZSHOW directs its output to a variable, it adds two levels of
+   descendants to that variable. The first level subscript contains a
+   one-character string from the set of upper-case ZSHOW action codes,
+   identifying the type of information. ZSHOW implicitly KILLs all
+   descendants of the first level nodes. ZSHOW stores information elements at
+   the second level using ascending integers, starting at 1.
 
-   $ZTEXIT is a read-write ISV, that is, it can appear on the left side of
-   the equal sign (=) in the argument  to  the  SET  command.  M  routines
-   cannot NEW $ZTEXIT. GT.M initializes $ZTEXIT to  null  at  the  process
-   startup. Note that the changes to the value of $ZTEXIT  during  a  GT.M
-   invocation last for the entire duration of the process, so  it  is  the
-   application’s responsibility to reset $ZTEXIT  after  $ZINTERRUPT  is
-   delivered in order to turn off redelivering the  interrupt  each  every
-   subsequent transaction commit or rollback.
+   When a ZSHOW "V" directs its output to a local variable (lvn), the result
+   does not contain a copy of the descendants of the resulting "V" node.
 
    Example:
 
-   ztran.m
+   GTM>Kill  Set b(1,"two")="test" ZSHow "v":a ZWRite
+   a("V",1)="b(1,""two"")=""test"""
+   b(1,"two")="test"
+   GTM>
 
-   foo ;
+   This ZSHow stores all local variables in the local variable a. Note that
+   ZSHOW does not replicate a("V") and a("V",1).
 
-   set $ztexit=1
+   Example:
 
-   set $zinterrupt="d ^throwint"
+   GTM>KILL  SET a(1,"D",3,5)="stuff",a(1,"X",2)="",a(1)=1
+   GTM>ZSHow "d":a(1)
 
-   tstart ()
+   GTM>ZWRite
+   a(1)=1
+   a(1,"D",1)="/dev/pts/1 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
+                    EDIT "
+   a(1,"X",2)=""
+   GTM>
 
-   for i=1:1:10 do
+   This ZSHOW stores the current open device information under a(1). Notice
+   how the ZSHOW overlays the prior value of a(1,"D",3,5).
 
-   . set ^ACN(i,"bal")=i*100
+   Example:
 
-   tstart ()
+   GTM>KILL ^ZSHOW
 
-   do ^throwint
+   GTM>ZB -*,lab^rout ZSH "B":^ZSHOW
 
-   do ^proc
+   GTM>ZWRite ^ZSHOW
+   ^ZSHOW("B",1)="LAB^ROUT"
+   GTM>
 
-   tcommit:$tlevel=2
+   This ZSHOW stores the current ZBREAK information under the global variable
+   ^ZSHOW.
 
-   for i=1:1:10 do
+2 ZSTep
+   ZSTep
 
-   . set ^ACN(i,"int")=i*0.05
+   The ZSTEP command provides the ability to control GT.M execution. When a
+   ZSTEP is issued from Direct Mode, execution continues to the beginning of
+   the next target line and then GT.M XECUTEs the ZSTEP action. The keyword
+   in the optional ZSTEP argument determines the class of eligible target
+   lines.
 
-   do ^srv
+   The format of the ZSTEP command is:
 
-   if $tlevel trollback
+   ZST[EP][:tvexpr] [keyword[:expr]][,...]
 
-   do ^exc
+   In Direct Mode, ZSTEP performs an implicit ZCONTINUE and therefore GT.M
+   ignores all commands on the Direct Mode command line after the ZSTEP.
 
-   set $zte="",$zint=""
+   The keyword arguments define the class of lines where ZSTEP next pauses
+   execution to XECUTE the ZSTEP action. When a ZSTEP command has multiple
+   arguments, it ignores all arguments except the last.
 
-   quit
+3 ZSTEP_Into
+   ZSTEP Into
 
-   bar ;
+   ZSTEP INTO pauses at the beginning of the next line, regardless of
+   transfers of control. When the ZSTEPed line invokes another routine or a
+   subroutine in the current routine, ZSTEP INTO pauses at the first line of
+   code associated with the new GT.M stack level.
 
-   write "Begin Transaction",!
+3 ZSTep_OUtof
+   ZSTep OUtof
 
-   set $zte=1
+   ZSTEP OUTOF pauses at the beginning of the next line executed after an
+   explicit or implicit QUIT from the current GT.M invocation stack level. A
+   ZSTEP OUTOF does not pause at lines associated with the current GT.M stack
+   level or with levels invoked from the current level.
 
-   tstart ()
+3 ZSTep_OVer
+   ZSTep OVer
 
-   i '$zsigproc($j,$ztrnlnm("sigusrval")) w "interrupt sent...",!!
+   ZSTEP OVER pauses at the beginning of the next line in the code associated
+   with either the current GT.M stack level or a previous GT.M stack level if
+   the ZSTEPed line contains an explicit or implicit QUIT from the current
+   level. A ZSTEP OVER does not pause at lines invoked from the current line
+   by DOs, XECUTEs or extrinsics.
 
-   for i=1:1:4 set ^B(i)=i*i
+3 ZSTEP_Actions
+   ZSTEP Actions
+
+   The optional action parameter of a ZSTEP must contain an expression
+   evaluating to valid GT.M code. By default, ZSTEP uses the value of $ZSTEP,
+   which defaults to "B" ("BREAK"), and enters Direct Mode. When a ZSTEP
+   command specifies an action, the process does not enter Direct Mode unless
+   the action explicitly includes a BREAK command.
 
-   tcommit
+3 ZSTEP_Interactions
+   ZSTEP Interactions
 
-   write "End Transaction",!
+   ZSTEP currently interacts with certain other elements in the GT.M
+   environment.
 
-   do ^srv
+3 Use_of_ZSTEP
+   Use of ZSTEP
 
-   quit
+   Use ZSTEP to incrementally execute a routine or series of routines.
+   Execute any GT.M command from Direct Mode at any ZSTEP pause. To resume
+   normal execution, use ZCONTINUE.
 
+   Note that ZSTEP arguments are keywords rather than expressions. They do
+   not allow indirection, and argument lists have no utility.
 
-   throwint.m
+   ZSTEP actions that include commands followed by a BREAK perform some
+   action before entering Direct Mode. ZSTEP actions that do not include a
+   BREAK perform the command action and continue execution. Use ZSTEP actions
+   that issue conditional BREAKs and subsequent ZSTEPs to do such things as
+   test for changes in the value of a variable.
 
-   thrint
+3 Examples
+   Examples
 
-   set  $zint="write  !,""interrupt  occurred  at  :
-   "",$stack($stack-1,""PLACE""),! set $zte=1"
-   if  '$zsigproc($j,$ztrnlnm("sigusrval"))  write  "interrupt  sent  to
-   process"
-   write "***************************************",!!
+   Example:
 
-   quit
+   GTM>ZSTEP INTO:"W ! ZP @$ZPOS W !"
 
+   This ZSTEP resumes execution of the current routine. At the beginning of
+   the next line executed, the ZSTEP action ZPRINTs the source code for that
+   line. Because the specified action does not contain a BREAK command,
+   execution continues to the next line and all subsequent lines in the
+   program flow.
 
    Example:
 
+   GTM>Set curx=$get(x),zact="ZSTEP:curx=$get(x) INTO:zact Break:curx'=$get(x)"
+   GTM>ZSTEP INTO:zact
 
-   GTM>d foo^ztran
+   This sequence uses ZSTEP to invoke Direct Mode at the beginning of the
+   first line after the line that alters the value of x.
 
-   interrupt sent to process
+2 ZSYstem
+   ZSYstem
 
-   interrupt occurred at : thrint+3^throwint
+   The ZSYSTEM command creates a child of the current process .
 
-***************************************
+   The format of the ZSYSTEM command is:
 
+   ZSY[STEM][:tvexpr] [expr][,...]]
 
-   interrupt occurred at : foo+13^ztran
+3 Examples
+   Examples
 
+   Example:
 
-   GTM>
+   GTM>ZSYSTEM "ls *.m"
 
-   In the above call to foo^ztran, the interrupt handler is a user-defined
-   routine,  throwint.  The  process  is  sent  a  signal  (SIGUSR1),  and
-   $ZINTERRUPT is executed. At the outermost trollback, the  interrupt  is
-   rethrown, causing $ZINTERRUPT to be executed again.
+   This uses ZSYSTEM to fork a process that then performs the ls command with
+   *.m as an argument to ls. Once the command completes, the forked process
+   terminates.
 
    Example:
 
+   GTM>ZSYSTEM
+   $
 
-   GTM>w $zint
+   This ZSYSTEM has no argument so the forked process prompts for input.
 
-   IF $ZJOBEXAM()
+2 ZTCommit
+   ZTCommit
 
-   GTM>zsy "ls GTM*"
+   The ZTCOMMIT command marks the end of a logical transaction within a GT.M
+   program. ZTCOMMIT used with ZTSTART "fences" transactions (that is, marks
+   the end and beginning). Fencing transactions allows the MUPIP JOURNAL
+   facility to prevent incomplete application transactions consisting of
+   multiple global updates from affecting the database during a database
+   recovery. FIS strongly recommends the use of the M transaction processing
+   commands such as TSTART and TCOMMIT rather than ZTSTART and ZTCOMMIT. FIS
+   no longer tests the deprecated ZTSTART / ZTCOMMIT functionally.
 
-   ls: No match.
+   The format of the ZTCOMMIT command is:
 
+   ZTC[OMMIT][:tvexpr] [intexpr]
 
-   GTM>d bar^ztran
+3 Examples
+   Examples
 
-   Begin Transaction
+   Example:
 
-   interrupt sent...
+   GTM>ZTCOMMIT 0
 
+   This ZTCOMMIT issued from Direct Mode would close any open ZTSTARTs.
 
-   End Transaction
+   Example:
 
+2 ZTRigger
+   ZTRigger
 
-   GTM>zsy "ls GTM*"
+   Invokes all triggers with signatures matching the global variable name and
+   the command type of ZTR[IGGER]. The format of the ZTRIGGER command is:
 
-   GTM_JOBEXAM.ZSHOW_DMP_22551_1 GTM_JOBEXAM.ZSHOW_DMP_22551_2
+   ZTR[IGGER] gvn
 
+   Example:
 
+   GTM>write $ztrigger("S")
+   ;trigger name: C#1#  cycle: 1
+   +^C -commands=ZTR -xecute="write ""ZTR trigger invoked"""
+   1
+   GTM>ztrigger ^C
+   ZTR trigger invoked
    GTM>
 
+2 ZTStart
+   ZTStart
 
-   This uses the default value of $ZINTERRUPT to service interrupts issued
-   to the process. The $ZJOBEXAM function executes a ZSHOW "*", and stores
-   the output in each GTM_ZJOBEXAM_ZSHOW_DMP for  the  initial  interrupt,
-   and at tcommit when the interrupt is rethrown.
-
-2 $ZTrap
-   $ZTrap
-
-   $ZT[RAP] contains a string value that GT.M XECUTEs when an error occurs
-   during routine execution.
+   The ZTSTART command marks the beginning of a logical transaction within a
+   GT.M program. ZTSTART and ZTCOMMIT "fence" transactions (that is, mark the
+   beginning and end). Fenced transactions prevent the MUPIP JOURNAL facility
+   from recovering incomplete transactions. All ZTSTARTs must be matched with
+   ZTCOMMITs before the journal processing facility recognizes the
+   transaction as complete. FIS strongly recommends the use of the M
+   transaction processing commands such as TSTART and TCOMMIT rather than
+   ZTSTART and ZTCOMMIT. FIS no longer tests the deprecated ZTSTART /
+   ZTCOMMIT functionally.
 
-        The following discussion assumes  that  $ETRAP  error  handling  is
-        simultaneously not in effect (that is, $ETRAP="").
+   The format of the ZTSTART command is:
 
-   When the $ZTRAP variable is not  null,  GT.M  executes  $ZTRAP  at  the
-   current level. The $ZTRAP variable has the initial value  of  "B,"  and
-   puts the process in Direct Mode when an error condition occurs. If the
-   value of $ZTRAP is null (""), an exception causes the image to run-down
-   with the condition  code  associated  with  the  exception.  If  $ZTRAP
-   contains invalid source code, GT.M displays an error message  and  puts
-   the process into Direct Mode.
+   ZTS[TART][:tvexpr]
 
-   $ZTRAP is a read-write Intrinsic Special Variable, (i.e., it can appear
-   on the left side of the equal sign (=)  in  the  argument  to  the  SET
-   command).
+   For more information on Journaling and transaction fencing, refer to the
+   "GT.M Journaling" chapter in the GT.M Administration and Operations Guide.
 
-   $ZTRAP may also appear as an argument to an inclusive NEW command. NEW
-   $ZTRAP causes GT.M to set $ZTRAP to null ($ZTRAP="") and to  stack  the
-   old value of $ZTRAP. When the program QUITs from the  invocation  level
-   where the NEW occurred, GT.M restores the value previously  stacked  by
-   the NEW. NEW $ZTRAP  provides  nesting  of  $ZTRAP.  Because  $ZTRAP=""
-   terminates the image  when  an  error  occurs,  SET  $ZTRAP=  generally
-   follows immediately after NEW $ZTRAP. You may  use  this  technique  to
-   construct error handling strategies corresponding  to  the  nesting  of
-   your programs. If the environment variable gtm_ztrap_new  evaluates  to
-   boolean TRUE (case  insensitive  string  "TRUE",  or  case  insensitive
-   string "YES", or a non-zero number), $ZTRAP is  NEWed  when  $ZTRAP  is
-   SET; otherwise $ZTRAP is not stacked when it is SET.
-
-        QUIT from a $ZTRAP terminates the level at  which  the  $ZTRAP  was
-        activated.
+2 ZWIthdraw
+   ZWIthdraw
 
-   Keep $ZTRAP simple and put complicated logic in another routine. If the
-   action specified by $ZTRAP results in  another  run-time  error  before
-   changing the value of $ZTRAP, GT.M invokes $ZTRAP until it exhausts the
-   process stack space, terminating the image. Carefully  debug  exception
-   handling.
+   The ZWITHDRAW command KILLs the data value for a variable name without
+   affecting the nodes descended from that node.
 
-   Example:
+   The format of the ZWITHDRAW command is:
 
+   ZWI[THDRAW][:tvexpr] glvn
 
-   GTM> S $ZTRAP="ZP @$ZPOS B"
+   ZWITHDRAW provides a tool to quickly restore a node to a state where it
+   has descendants and no value-- that is, where $DATA for that node will
+   have a value of 10 -- for the case where such a state has some control
+   meaning. GT.M also provides the ZKILL command, with functionality
+   identical to ZWITHDRAW.
 
-   This example modifies $ZTRAP to display source code for the line where
-   GT.M encounters an error before entering Direct Mode.
+3 Examples
+   Examples
 
-   There are four accepted behavioural forms of $ZTRAP controlled  by  the
-   UNIX environment variable gtm_ztrap_form. If gtm_ztrap_form is defined
-   to "code" (or not defined to one of the subsequently described values),
-   then GT.M treats $ZTRAP as code and handles it as previously described
-   in the documentation.
-
-   The four different behavioural forms of gtm_ztrap_form are:
-
-   o    entryref - If gtm_ztrap_form evaluates  to  "entryref"  then  GT.M
-        treats it as an entryref argument to an implicit GOTO command.
-
-   o    adaptive - If  gtm_ztrap_form  evaluates  to  "adaptive"  then  if
-        $ZTRAP does not compile to valid M code, then $ZTRAP is treated as
-        just described for "entryref." Since  there  is  little  ambiguity,
-        code and entryref forms of $ZTRAP can be  intermixed  in  the  same
-        application.
-
-   Note that GT.M attempts to compile $ZTRAP before evaluating  $ZTRAP  as
-   an entryref. Since GT.M allows commands without arguments such as QUIT,
-   ZGOTO, or HANG as valid labels, be careful not to use such keywords as
-   labels for error handling code in "adaptive" mode.
-
-   o    pope[ntryref] / popa[daptive] -  If  gtm_ztrap_form  evaluates  to
-        "POPE[NTRYREF]" or "POPA[DAPTIVE]" (case  insensitive)  and  $ZTRAP
-        value is in the form of entryref, GT.M unwinds the M stack from the
-        level at which an error occurred to (but not including)  the  level
-        at which $ZTRAP was last SET. Then, GT.M transfers control  to  the
-        entryref in $ZTRAP at the level where the $ZTRAP value was SET. If
-        the UNIX environment variable gtm_zyerror is  defined  to  a  valid
-        entryref, GT.M transfers  control  to  the  entryref  specified  by
-        GTM_ZYERROR (with an implicit DO) after  unwinding  the  stack  and
-        before transferring control to the entyref specified in $ZTRAP.
+   Example:
 
-2 $ZVersion
-   $ZVersion
+   Kill A
+   Set A="A",A(1)=1,A(1,1)=1
+   WRite $Data(A(1)),!
+   ZWIthdraw A(1)
+   WRite $D(A(1)),!
+   ZWRite A
+   Quit
 
-   $ZV[ERSION] contains a string value specifying the currently installed
-   GT.M.  $ZV[ERSION]  is  a  space-delimited  string  with  four  pieces
-   described below:
+   produces the result:
 
-   o    The M product name, for example "GT.M".
+   11
+   10
+   A="A"
+   A(1,1)=1
 
-   o    The M product version identifier; the format is: the capital letter
-        "V" followed by the  major  version  number,  then  a  period  (.),
-        followed by the minor version number, then a patch number.
+   This sets up local variables A and A(1) and A(1,1). It then deletes the
+   data for A(1) with ZWITHDRAW. The ZWRITE command shows ZWITHDRAW KILLed
+   A(1) but left A and A(1,1).
 
-   o    The host operating system name  and  optional  version  identifier;
-        this identifier is only included if different versions  of  the  OS
-        support different, compatible versions of the M product.
+2 ZWRite
+   ZWRite
 
-   o    The host hardware designation and optional chipset identifier; this
-        identifier is only included if different versions of  the  hardware
-        support different compatible versions of the M product.
+   The ZWRITE command displays the current value of one or more local , alias
+   variables, ISVs, or global variables. ZWRITE formats its output so that
+   each item in the display forms a valid argument to a SET @ command. This
+   means ZWRITE encloses string values in quotes and represents non-graphic
+   (control) characters in $CHAR() syntax.
 
-   M routines cannot modify $ZVERSION.
+   The format of the ZWRITE command is:
 
-   Example:
+   ZWR[ITE][:tvexpr] [zwrglvn[,...]]
 
+3 ZWRITE_Format_for_Alias_Variables
+   ZWRITE Format for Alias Variables
+
+   ZWRITE and ZSHOW "V" dump the values of alias variables, alias container
+   variables, and the associated data as described below, in ZWRITE format.
+   In the ZWRITE format, the contents of an array are displayed with the name
+   associated with that array that appears first in the lexical ordering of
+   names. GT.M displays both the unsubscripted and subscripted nodes and
+   values, appending a notational space-semicolon-asterisk (";*") sequence to
+   the unsubscripted value, if any. The ZWRITE format output can be read into
+   a GT.M process with the commands Read x and Set @x (where x is any name)
+   executed in a loop. ";*" acts as a comment ignored by the SET command. In
+   the following example, since A and C are aliases associated with the same
+   array, the nodes of that array are output with A, which occurs lexically
+   before C, even though the values were assigned to C:
+
+   GTM>Set C=1,C("Malvern")="Wales",*A=C,*B(-3.14)=C
+
+   GTM>ZSHow "V" ; ZWRite would produce the same output
+   A=1 ;*
+   A("Malvern")="Wales"
+   *B(-3.14)=A
+   *C=A
+   GTM>ZWRite C ; Only one is name associated with the array on this ZWRite command
+   C=1 ;*
+   C("Malvern")="Wales"
+   GTM>
 
-   GTM> WRITE $ZVERSION
+   Continuing the example, if the variables selected for the ZWRITE command
+   do not include any of the the associated alias variables, the output shows
+   only the reference, not the data:
 
-   GT.M V4.3-001B AIX RS6000
+   GTM>ZWRITE B ; B only has a container
+   *B(-3.14)=A
+   GTM>
 
-   This example displays the current version identifier for GT.M.
+   When ZWRITE / ZSHOW "V" encounters an alias container for an array with no
+   current alias variable, it uses a name $ZWRTACn as the made-up name of an
+   alias variable for that array, where n is an arbitrary but unique integer.
+   The SET command recognizes this special name, thus enabling the output of
+   a ZWRITE / ZSHOW "V" to be used to recreate alias containers without
+   associated alias variables. Continuing the above example:
+
+   GTM>Kill *A,*C ; Delete alias variables and associations, leaving only the container
+
+   GTM>ZWRite
+   $ZWRTAC=""
+   *B(-3.14)=$ZWRTAC1
+   $ZWRTAC1=3 ;*
+   $ZWRTAC1("Malvern")="Wales"
+   $ZWRTAC=""
+   GTM>
 
-2 $ZYERror
-   $ZYERror
+   ZWRITE produces $ZWRTACn names to serve as data cell anchors which SET @
+   accepts as valid set left targets. $ZWRTACn names are created and
+   destroyed when using ZWRITE output to drive restoration of a previously
+   captured variable state. Except for their appearance in ZWRITE output and
+   as left-hand side SET @ targets, they have no function. Other than SET, no
+   other commands can use $ZWRTAC* in their syntax. Although $ZWRTACn
+   superficially looks like an intrinsic special variable (ISV), they are not
+   ISVs. $ZWRTACn with no subscripts can serve as the target (left side of
+   the equals-sign) of a SET * command. SET $ZWRTAC (no trailing integer)
+   deletes all data cell associations with the $ZWRTAC prefixed aliases. GT.M
+   only recognizes the upper-case unabbreviated name and prefix $ZWRTAC.
+
+   When ZWRITE displays values for an alias variable, it appends a " ;*" to
+   the name which visually tags the alias without interfering with use of
+   ZWRITE output as arguments to a SET @. ZWRITE can only identify alias
+   variables when at least two aliases for the same data match its argument.
+   When ZWRITE encounters an alias container variable with no current
+   associated alias, it uses the ZWRTAC mechanism to expose the data; SET @
+   can restore data exposed with the ZWRTAC mechanism.
+
+   **Caution**
+
+   FIS strongly recommends that you should not create or manipulate your own
+   $ZWRTACn "variables". They are not part of the supported functionality for
+   implementing alias variables and containers, but are rather a part of the
+   underlying implementation that is visible to you, the GT.M user. FIS can
+   arbitrarily, for its own convenience change the use of $ZWRTAC in GT.M at
+   any time. They are only documented here since you may see them in the
+   output of ZWRITE and ZSHOW "V".
+
+3 Examples
+   Examples
 
-   $ZYER[ROR] is a read/write ISV that contains a string value pointing to
-   an entryref. After GT.M encounters an  error,  if  $ZYERROR  is  set  a
-   non-null value, GT.M invokes the routine at the entryref  specified  by
-   $ZYERROR with an implicit DO. It is intended that the code  invoked  by
-   $ZYERROR use the value of $ZSTATUS to select or construct  a  value  to
-   which it SETs $ZERROR. If $ZYERROR is not a valid  entryref  or  if  an
-   error occurs while executing the entryref specified by  $ZYERROR,  GT.M
-   SETs $ZERROR to the error status encountered. GT.M then returns control
-   to the M code specified by $ETRAP/$ZTRAP or device EXCEPTION.
-
-   $ZYERROR is implicitly NEWed on  entry  to  the  routine  specified  by
-   $ZYERROR. However, if GT.M fails to compile,  GT.M  does  not  transfer
-   control to the entryref specified by $ZYERROR.
+   Example:
 
-   GT.M permits $ZYERROR to be modified by the SET and NEW commands.
+   GTM>ZWRITE ^?1"%"2U(0:":",)
 
-1 In_Out_Processing
-   Input Output Processing
+   This command displays the descendants of all subscripts between 0 and ":"
+   of all global names starting with a "%" and having two upper case letters
+   -- for example, "%AB".
 
-   OPEN, USE,  and  CLOSE  commands  accept  deviceparameters,  which  are
-   keywords that permit an GT.M program to control the device state. Some
-   deviceparameters accept arguments, and some require them.  The  current
-   ANSI standard for GT.M does not define  the  deviceparameters  for  all
-   devices.
+   Example:
 
-2 IO_ISV
-   I/O Intrinsic Special Variables
+   GTM>ZWRITE A(,:,3)
 
-   GT.M intrinsic special  variables  provide  a  means  of  communication
-   between a device  and  its  device  driver  and  GT.M  routines.  These
-   variables allow a GT.M routine to manage  the  I/O  with  a  particular
-   device.
+   This command displays all of the third level nodes with a subscript of 3
+   for local variable A.
 
-3 Device_Nam_Var
-   Device Name Variables
+   Example:
 
-   GT.M provides three intrinsic special variables that identify devices.
+   ZWRITE ?1"A".E(?1"X"3N)
 
-4 $IO
-   $IO
+   This displays data for any local variables starting with "A", optionally
+   followed by any characters, and having any subscripts starting with "X"
+   followed by three numerics.
 
-   $I[O] contains the name of the current device specified by the last USE
-   command. The M standard does not permit a SET command  to  modify  $IO.
-   USE produces the same $IO as USE $PRINCIPAL, but $P  is  the  preferred
-   construct.
+   Example:
 
-4 $Principal
-   $Principal
+   GTM>Set A=1,*B=A ; Create an array and an alias association
 
-   $P[RINCIPAL] contains the absolute pathname of the  principal  (initial
-   $IO) device.
+   GTM>ZWRite ; Show that the array and association exist
+   A=1 ;*
+   *B=A
 
-   Input and output for a process may come from separate devices, namely,
-   the standard input and output. However, the GT.M I/O model allows only
-   one device to be USEd (or active) at a time. When an image starts, GT.M
-   implicitly OPENs the standard input and standard output  device(s)  and
-   assigns the device(s) to $PRINCIPAL. For USE  deviceparameters,  it  is
-   the standard input that determines the device type.
+2 ZHALT
+   ZHALT
 
-   For an image invoked interactively, $PRINCIPAL is the user's terminal.
-   For an image invoked from a terminal by a shell script,  $PRINCIPAL  is
-   the shell script's standard input (usually the terminal)  and  standard
-   output (also usually the terminal),  unless  the  shell  redirects  the
-   input or output.
+   The ZHALT command stops program execution and causes GT.M to return
+   control to the invoking environment/program with a return code.
 
-   GT.M ignores a CLOSE command specifying the principal device. GT.M does
-   not permit a SET command to modify $PRINCIPAL.
+   The format of the ZHALT command is:
 
-4 $ZIO
-   $ZIO
+   ZHALT[:tvexpr] [intexpr]
 
-   $ZIO contains the translated name of the current device, in contrast to
-   $IO, which contains the name as specified by the USE command.
+3 Examples
+   Examples
 
-3 Cur_Position_Var
-   Cursor Position Variables
+   Example:
 
-   GT.M provides two  intrinsic  special  variables  for  determining  the
-   virtual cursor position. $X refers to  the  current  column,  while  $Y
-   refers to the current row.
+   GTM>zhalt 230
+   $ echo $?
+   230
 
-4 $X
-   $X
+   Example:
 
-   $X contains an integer value ranging from 0 to 65,535,  specifying  the
-   horizontal position of a virtual cursor in the current  output  record.
-   $X=0 represents the left-most position of a record or row.
+   GTM>zhalt 257
+   $ echo $?
+   1
 
-   Every OPENed device has a $X. However, GT.M only has access  to  $X  of
-   the current device. Therefore, be careful when sequencing USE commands
-   and references to $X.
+1 Functions
+   Functions
 
-   Generally, GT.M increments $X for every character written to  and  read
-   from the current device. GT.M format control  characters,  FILTER,  and
-   the device WIDTH and WRAP also have an effect on $X.
+   This chapter describes M language Intrinsic Functions implemented in GT.M.
+   Traditional string processing functions have parallel functions that start
+   with the letter "z". The parallel functions extend the byte-oriented
+   functionality of their counterparts to UTF-8 mode. They are helpful when
+   applications need to process binary data including blobs, binary byte
+   streams, bit-masks, and so on.
 
-   SET $X does not automatically issue device commands or escape sequences
-   to reposition the physical cursor.
+   Other functions that start with the letter "z" and do not have
+   counterparts implement new functionality and are GT.M additions to the
+   ANSI standard Intrinsic Functions. The M standard specifies standard
+   abbreviations for Intrinsic Functions and rejects any non-standard
+   abbreviations.
 
-4 $Y
-   $Y
+   M Intrinsic Functions start with a single dollar sign ($) and have one or
+   more arguments enclosed in parentheses () and separated by commas (,).
+   These functions provide expression results by performing actions that are
+   impossible or difficult to perform using M commands.
 
-   $Y contains an integer value ranging from 0 to 65,535,  specifying  the
-   vertical position of a virtual cursor in  the  current  output  record.
-   $Y=0 represents the top row or line.
-
-   Every OPEN device has a $Y. However,  GT.M  only  accesses  $Y  of  the
-   current device. Therefore, be careful when sequencing USE commands and
-   references to $Y.
-
-   When GT.M  finishes  the  logical  record  in  progress,  it  generally
-   increments $Y. GT.M recognizes the end of  a  logical  record  when  it
-   processes certain GT.M format control characters, or  when  the  record
-   reaches its maximum size, as determined by the device  WIDTH,  and  the
-   device is set to WRAP. The definition of "logical record"  varies  from
-   device to device. For an exact definition, see  the  sections  on  each
-   device type. FILTER and the device LENGTH also have an effect on $Y.
-
-   SET $Y does not automatically issue device commands or escape sequences
-   to reposition the physical cursor.
-
-4 Maint_of_$X_and_&Y
-   Maintenance of $X and $Y
-
-   In GT.M, the following factors affect the maintenance  of  the  virtual
-   cursor position ($X and $Y):
-
-   o    The bounds of the virtual "page"
-
-   o    GT.M format control characters
-
-   o    GT.M character filtering
-
-   Each device has a WIDTH and a LENGTH that define  the  virtual  "page."
-   The WIDTH determines the maximum size of a record for a  device,  while
-   the LENGTH determines how many records fit on a page. GT.M starts a new
-   record when the current record size ($X) reaches the maximum WIDTH and
-   the device has WRAP enabled. When the current  line  ($Y)  reaches  the
-   maximum LENGTH, GT.M starts a new page.
-
-   GT.M has several format control characters that allow the manipulation
-   of the virtual cursor. For all I/O devices,  the  GT.M  format  control
-   characters do the following:
-
-        ! Sets $X to zero (0) and increments $Y, and terminates the logical
-        record in progress. The definition of "logical record" varies from
-        device to device, and is discussed in each device section.
-        # Sets $X and $Y to zero (0), and terminates the logical record in
-        progress.
-        ?n If n is greater than $X,  writes  n-$X  spaces  to  the  device,
-        bringing $X to n. If n is less than or  equal  to  $X,  ?n  has  no
-        effect. When WRAP is enabled and n exceeds the WIDTH of  the  line,
-        WRITE ?n increments $Y and sets $X equal to n#WIDTH, where # is the
-        GT.M modulo operator.
-   GT.M provides two modes  of  character  filtering.  When  filtering  is
-   enabled, certain <CTRL> characters and/or escape sequences have special
-   effects on the cursor position (e.g., <BS> (ASCII 8) may decrement $X,
-   if $X is non-zero). For more information on write filtering,  refer  to
-   the section on the [NO]FILTER deviceparameter.
-
-3 Status_Var
-   Status Variables
-
-   GT.M provides several I/O  status  variables  that  convey  information
-   about the status of individual operations.
-
-4 $ZA
-   $ZA
+2 $ASCII()
+   $ASCII()
 
-   $ZA contains a status determined by the last read on  the  device.  The
-   value is a decimal integer with a meaning determined by the  device  as
-   follows:
+   Returns the integer ASCII code for a character in the given string. For a
+   mumps process started in UTF-8 mode, $ASCII() returns the integer Unicode
+   code-point value of a character in the given string.
 
-   For Terminal I/O:
+   The format for the $ASCII function is:
 
-        0 Indicating normal termination of a read operation
-        1 Indicating a parity error
-        2 Indicating the terminator sequence was too long
-        9 Indicating a default for all other errors
-   For Sequential Disk:
+   $A[SCII](expr[,intexpr])
 
-        0 Indicating normal termination of a read operation
-        9 Indicating a failure of a read operation
-   For FIFO:
+   $ASCII() provides a means of examining non-graphic characters in a string.
+   When used with $CHAR(), $ASCII() also provides a means to perform
+   arithmetic operations on the codes associated with characters.
 
-        0 Indicating normal termination or time out
-        9 Indicating a failure of a read operation
-   For socket:
+   $ZASCII() is the parallel function of $ASCII(). $ZASCII() interprets the
+   string argument as a sequence of bytes (rather than a sequence of
+   characters) and can perform all byte-oriented $ASCII() operations. For
+   more information, refer to "$ZAscii()".
 
-        0 Indicating normal termination or time out
-        9 Indicating failure of a read operation
-   $ZA refers to the status of the  current  device.  Therefore,  exercise
-   care in sequencing USE commands and references to $ZA.
+3 Examples
+   Examples
 
-4 $ZB
-   $ZB
+   Example:
 
-   $ZB contains a string specifying the  input  terminator  for  the  last
-   terminal READ. $ZB is null, and it is not maintained for devices other
-   than terminals. $ZB may contain any legal  input  terminator,  such  as
-   <CR> (ASCII 13) or an escape sequence starting with <ESC>  (ASCII  27),
-   from zero (0) to  15  bytes  in  length.  $ZB  is  null  for  any  READ
-   terminated by a timeout or any fixed-length READ  terminated  by  input
-   reaching the maximum length.
+   GTM>For i=0:1:3 Write !,$Ascii("Hi",i)
+   -1
+   72
+   73
+   -1
+   GTM>
 
-   $ZB contains the actual character string, not  a  sequence  of  numeric
-   ASCII codes.
+   This loop displays the result of $ASCII() specifying a character position
+   before, first and second positions, and after the string.
 
    Example:
 
-   SET zb=$ZB FOR i=1:1:$LENGTH(zb) WRITE !,i,?5,$A(zb,i)
-
-   This example displays the series of ASCII codes for the  characters  in
-   $ZB.
+   GTM>Write $ZCHSET
+   UTF-8
+   GTM>Write $Ascii("*")
+   20027
+   GTM>Write $$FUNC^%DH("20027")
+   00004E3B
 
-   $ZB  refers  to  the  last  READ  terminator  of  the  current  device.
-   Therefore, be careful when sequencing USE commands  and  references  to
-   $ZB.
+   In this example, 20027 is the integer equivalent of the hexadecimal value
+   4E3B. U+4E3B is a character in the CJK Ideograph block of the Unicode
+   Standard.
 
-4 $ZEOF
-   $ZEOF
+2 $Char()
+   $Char()
 
-   $ZEOF contains a truth-valued expression indicating  whether  the  last
-   READ operation reached the end-of-file. $ZEOF is  TRUE(1)  at  EOF  and
-   FALSE (0) at other positions. GT.M does not maintain $ZEOF for terminal
-   devices.
+   Returns a string of one or more characters corresponding to integer ASCII
+   codes specified in its argument(s). For a process started in UTF-8 mode,
+   $CHAR() returns a string composed of characters represented by the integer
+   equivalents of the Unicode code-points specified in its argument(s).
 
-   $ZEOF  refers  to  the  end-of-file  status  of  the  current  device.
-   Therefore, be careful when sequencing USE commands  and  references  to
-   $ZEOF.
+   The format for the $CHAR function is:
 
-2 IO_Devices
-   I/O Devices
+   $C[HAR](intexpr[,...])
 
-   Each device type supported by GT.M responds to a particular  subset  of
-   deviceparameters, while ignoring others. Devices may be programmed in a
-   device-specific  manner,  or  in  a  device-independent  manner.
-   Device-specific I/O routines are intended for use with only one type of
-   device.  Device-independent  I/O  routines  contain  appropriate
-   deviceparameters for all devices to be supported by  the  function,  so
-   the user can redirect to a different device output while using the same
-   program.
+3 Examples
+   Examples
 
-   GT.M supports the following I/O device types:
+   Example:
 
-   o    Terminals and Printers
+   GTM>write $char(77,85,77,80,83,7)
+   MUMPS
+   GTM>
 
-   o    Sequential Disk Files
+   This example uses $CHAR() to WRITE the word MUMPS and signal the terminal
+   "bell."
 
-   o    FIFOs
+   Example:
 
-   o    Null Devices
+   set nam=$extract(nam,1,$length(nam)-1)_$char($ascii(nam,$length(nam))-1)
 
-   o    Socket Devices
+   This example uses $CHAR() and $ASCII() to set the variable nam to a value
+   that immediately precedes its previous value in the set of strings of the
+   same length as nam.
 
-3 IO_Devi_Recog
-   I/O Device Recognition
+   Example:
 
-   GT.M  OPEN,  USE,  and  CLOSE  commands  have  an  argument  expression
-   specifying a device name. In the operating system environment, a device
-   may be referred to either by its physical name or by a name containing
-   one or more environment variables, each with a dollar-sign  ($)  prefix
-   that expand to its physical name. Because environment variables permit
-   program coding independent of  hardware  configuration,  they  tend  to
-   isolate the code from hardware changes.
+   GTM>write $zchset
+   UTF-8
+   GTM>write $char(20027)
+   *
+   GTM>write $char(65)
+   A
 
-   During an OPEN, GT.M attempts to resolve the specified device names to
-   physical names. When GT.M successfully resolves  a  device  name  to  a
-   physical device, that device becomes the target of  the  OPEN.  If  the
-   device name contains a dollar sign ($), GT.M  attempts  an  environment
-   variable translation; the result becomes the name of the device. If it
-   does not find such an environment variable, it assumes that the dollar
-   sign is a part of the filename, and opens a file by that name.
+   In the above example, the integer value 20027 is the Unicode character "*"
+   in the CJK Ideograph block of Unicode. Note that the output of the $CHAR()
+   function for values of integer expression(s) from 0 through 127 does not
+   vary with choice of the character encoding scheme. This is because 7-bit
+   ASCII is a proper subset of UTF-8 character encoding scheme. The
+   representation of characters returned by the $CHAR() function for values
+   128 through 255 differ for each character encoding scheme.
 
-   Once a device is OPEN,  GT.M  establishes  an  internal  correspondence
-   between a name and the device or file. Therefore, while the  device  is
-   OPEN, changing the translation of an environment variable in the device
-   specification does not change the device.
+2 $Data()
+   $Data()
 
-   The following names identify the original $IO for the process:
+   Returns an integer code describing the value and descendent status of a
+   local or global variable.
 
-   o    $PRINCIPAL
+   The format for the $DATA function is:
 
-   0
+   $D[ATA](glvn)
 
-   Some versions of GT.M also treat the empty string  as  identifying  $P.
-   However, Sanchez recommends using the empty string to identify  a  null
-   device, so it would be wise to avoid or eliminate this behavior.
-
-3 Devi_Spec_Defaults
-   Device Specification Defaults
-
-   GT.M uses standard filenames for device specifiers.
-
-   The complete format for a filename is:
-
-   /directory/file
-
-   If the expression specifying a  device  does  not  contain  a  complete
-   filename, the expression may start with an  environment  variable  that
-   translates to one or more leading  components  of  the  filename.  GT.M
-   applies default values for the missing components.
-
-   The GT.M file-name defaults are the following:
-
-        Directory Current working directory
-        File No default (user-defined filename)
-        Filetype No default (user-defined filetype)
-3 How_IO_DeviParam_Work
-   How I/O Deviceparameters Work
-
-   I/O deviceparameters either perform actions that cause the device to do
-   something (for example, CLEARSCREEN), or specify  characteristics  that
-   modify  the  way  the  device  subsequently  behaves  (for  example,
-   BLOCKSIZE). When an I/O command has multiple  action  deviceparameters,
-   GT.M performs the actions in the order of the  deviceparameters  within
-   the  command  argument.  When  a  command  has  characteristic
-   deviceparameters, the last occurrence  of  a  repeated  or  conflicting
-   deviceparameter determines the characteristic.
-
-   Deviceparameters often relate to a specific device type.  GT.M  ignores
-   any deviceparameters that do not  apply  to  the  type  of  the  device
-   specified by the command argument. Specified device characteristics are
-   in force for the duration of the GT.M image, or until  modified  by  an
-   OPEN, USE, or CLOSE command.
-
-   When reopening a device that  it  previously  closed,  a  GT.M  process
-   restores all characteristics not specified on the OPEN  to  the  values
-   the device had when it was last CLOSEd.  GT.M  treats  sequential  disk
-   files differently and uses defaults  for  unspecified  sequential  disk
-   file characteristics on every OPEN  (that  is,  GT.M  does  not  retain
-   sequential disk file characteristics on a CLOSE).
-
-   The ZSHOW  command  with  an  argument  of  "D"  displays  the  current
-   characteristics for all devices OPENed by the process. ZSHOW can direct
-   its output into a GT.M variable.
-
-3 Abbv_DeviParam
-   Abbreviating Deviceparameters
-
-   GT.M  deviceparameters  do  not  have  predefined  abbreviations.  GT.M
-   recognizes  deviceparameters  using  a  minimum  recognizable  prefix
-   technique. Most deviceparameters may be  represented  by  four  leading
-   characters, except ERASELINE, all deviceparameters starting with WRITE,
-   and Z* deviceparameters in a mnemonicspace (such as SOCKET).  The  four
-   leading characters recognized do not include a leading NO for negation.
-
-
-   For compatibility with previous versions, GT.M  may  recognize  certain
-   deviceparameters by abbreviations shorter than the minimum. While it is
-   convenient  in  Direct  Mode  to  use  shorter  abbreviations,  Sanchez
-   Computer Associates may add additional deviceparameters, and therefore,
-   recommends all programs use at  least  four  characters.  Because  GT.M
-   compiles the code, spelling  out  deviceparameters  completely  has  no
-   performance penalty, except  when  used  with  indirection  or  XECUTEd
-   arguments.
+   The following table summarizes $DATA() return values.
 
+   +--------------------------------------------+
+   |              $DATA() Results               |
+   |--------------------------------------------|
+   |                   VALUE                    |
+   |--------------------------------------------|
+   |     | DESCENDANTS (NO) | DESCENDANTS (YES) |
+   |-----+------------------+-------------------|
+   | NO  | 0                | 10                |
+   |-----+------------------+-------------------|
+   | YES | 1                | 11                |
+   +--------------------------------------------+
 
-3 Devi_Independent_Prog
-   Device-Independent Programming
+   $DATA() return values can also be understood as a pair of truth-values
+   where the left describes descendants and the right describes data 1 and
+   where M suppresses any leading zero (representing no descendants).
 
-   When a user may choose a device for I/O, GT.M routines can take one of
-   two basic programming approaches.
+3 Examples
+   Examples
 
-   o    The  user  selection  directs  the  program  into  different  code
-        branches, each of which handles a different device type.
+   Example:
 
-   o    The user selection identifies the device. There is  a  single  code
-        path written with a full complement of deviceparameters  to  handle
-        all selectable device types.
+   GTM>Kill  Write $Data(a)
+   0
+   GTM>Set a(1)=1 Write $Data(a(1))
+   1
+   GTM>Write $Data(a)
+   10
+   GTM>Set a=0 Write $Data(a)
+   11
+   GTM>
 
-   The latter approach is called device-independent programming. To permit
-   device independent programming, GT.M uses the same deviceparameter for
-   all  devices  that  have  an  equivalent  facility,  and  ignores
-   deviceparameters applied  to  a  device  that  does  not  support  that
-   facility.
+   This uses $DATA to display all possible $DATA() results.
 
    Example:
 
-   OPEN dev:(EXCE=exc:REWIND:VARIABLE:WRITEONLY)
+   lock ^ACCT(0)
+   if '$data(^ACCT(0)) set ^ACCT(0)=0
+   set (ACCT,^ACCT(0))=^ACCT(0)+1
+   lock
 
-   This example OPENs a device with deviceparameters that affect different
-   devices. The EXCEPTION has an effect for all device types. When dev is
-   a terminal or a null device, GT.M ignores the  other  deviceparameters.
-   When dev is a sequential file on disk, GT.M uses REWIND  and  VARIABLE.
-   This command performs a valid OPEN for all the different device types.
+   This uses $DATA() to determine whether a global node requires
+   initialization.
 
-        A file that has been previously  created  and  contains  data  that
-        should be retained can also be opened  with  the  device  parameter
-        APPEND.
+   Example:
 
-2 Terminals
-   Using Terminals
+   for  set cus=$O(^cus(cus)) quit:cus=""  if $data(^(cus))>1 do WORK
 
-   A typical GT.M application is largely interactive  and  uses  terminals
-   extensively. By default, a GT.M process directs  its  terminal  I/O  to
-   $PRINCIPAL. $PRINCIPAL identifies the terminal  that  the  user  signed
-   onto in UNIX.
+   This uses $DATA() to determine whether a global node has descendants and
+   requires additional processing.
 
-   While all terminals support the CTRAP deviceparameter, which optionally
-   allows  terminal  input  to  optionally  redirect  program  flow,  only
-   $PRINCIPAL supports CENABLE, which optionally allows the terminal user
-   to invoke the Direct Mode shell.
+2 $Extract()
+   $Extract()
 
-   Directly  connected  printers  often  appear  to  GT.M  as  a  terminal
-   (although printers  generally  do  not  provide  input)  regardless  of
-   whether the printer is connected to the  computer  with  a  high  speed
-   parallel interface, or an asynchronous terminal controller.
+   Returns a substring of a given string.
 
-3 Set_Terminal_Char
-   Setting Terminal Characteristics
+   The format for the $EXTRACT function is:
 
-   GT.M does not isolate its handling of terminal characteristics from the
-   operating system environment at  large.  GT.M  inherits  the  operating
-   system terminal characteristics in effect at the time the GT.M image is
-   invoked. When GT.M exits, the invoking environment retains  the  device
-   characteristics established with GT.M.
+   $E[XTRACT](expr[,intexpr1[,intexpr2]])
 
-   However, if the process temporarily leaves the GT.M environment with a
-   ZSYSTEM command, GT.M does not recognize any changes  to  the  terminal
-   characteristics left  by  the  external  environment.  This  may  cause
-   disparities between the physical behavior  of  the  terminal,  and  the
-   perceived behavior by GT.M.
+   $EXTRACT() provides a tool for manipulating strings based on character
+   positions.
 
-   UNIX enforces standard device security for explicit OPENs of terminals
-   other than the sign-in terminal ($PRINCIPAL). If you are unable to OPEN
-   a terminal, contact your system manager.
+   For a mumps process started in UTF-mode, $EXTRACT interprets the string
+   arguments as UTF-8 encoded. With VIEW "BADCHAR" enabled, $EXTRACT()
+   produces a run-time error when it encounters a character in the reserved
+   range of the Unicode Standard, but it does not process the characters that
+   fall after the span specified by the arguments. The parallel function of
+   $EXTRACT() is $ZEXTRACT(). Use $ZEXTRACT() for byte-oriented operations.
 
-   USE of a terminal causes the device driver to flush the output buffer.
-   This feature of the USE  command  provides  routine  control  over  the
-   timing of output, which is  occasionally  required.  However,  it  also
-   means that redundant USE commands may induce an unnecessary performance
-   penalty. Therefore, Sanchez Computer Associates recommends restricting
-   USE  commands  to  redirecting  I/O,  modifying  deviceparameters,  and
-   initiating specifically required flushes.
+   $EXTRACT() can be used on the left-hand side of the equal sign (=) of a
+   SET command to set a substring of a string. This construct permits easy
+   maintenance of individual pieces within a string. It can also be used to
+   right justify a value padded with blank characters.
 
-3 Logical_Rec_for_Term
-   Logical Records for Terminals
+3 Examples
+   Examples
 
-   A logical record for a terminal equates  to  a  line  on  the  physical
-   screen. The WIDTH device characteristic  specifies  the  width  of  the
-   screen, while the LENGTH device characteristic specifies the number of
-   lines on the screen.
+   Example:
 
-3 READ_Comm_for_Term
-   READ* Command for Terminals
+   GTM>for i=0:1:3 write !,$extract("HI",i),"<"
+   <
+   H<
+   I<
+   <
+   GTM>
 
-   If the terminal has ESCAPE sequencing enabled, and the input contains a
-   valid escape sequence or a terminator character,  the  terminal  device
-   driver stores  the  entire  sequence  in  $ZB  and  returns  the  ASCII
-   representation of the first character.
+   This loop displays the result of $EXTRACT(), specifying no ending
+   character position and a beginning character position "before" first and
+   second positions, and "after" the string.
 
    Example:
 
-   GTM> KILL
+   GTM>For i=0:1:3 write !,$extract("HI",1,i),"<"
+   <
+   H<
+   HI<
+   HI<
+   GTM>
+
+   This loop displays the result of $EXTRACT() specifying a beginning
+   character position of 1 and an ending character position "before, " first
+   and second positions, and "after" the string.
 
-   GTM> USE $P:ESCAPE
+   Example:
 
-   GTM> READ *X SET ZB=$ZB ZWRITE
+   GTM>zprint ^trim
+   trim(x)
+       new i,j
+       for i=1:1:$length(x) quit:" "'=$extract(x,i)
+       for j=$length(x):-1:1 quit:" "'=$extract(x,j)
+       quit $extract(x,i,j)
 
-   (Press the F11 key on the VT220 terminal keyboard)
-   x=27
+   GTM>set str=" MUMPS "
 
-   zb=$C(27)_"[23~"
+   GTM>write $length(str)
+   7
+   GTM>write $length($$^trim(str))
+   5
+   GTM>
 
-   This enters an escape sequence in response to a  READ  *.  The  READ  *
-   assigns the code for <ESC> to the  variable  X.  The  terminal  handler
-   places  the  entire  escape  sequence  in  $ZB.  Because  some  of  the
-   characters are not graphic, that is, visible on a terminal, the example
-   transfers the contents of $ZB to the  local  variable  ZB  and  uses  a
-   ZWRITE so that the non-graphic characters appear in $CHAR() format.
+   This extrinsic function uses $EXTRACT() to remove extra leading and
+   trailing spaces from its argument.
 
-   The READ * command for  terminals  does  not  affect  $ZB  when  escape
-   sequencing is not  enabled.  If  the  input  contains  a  valid  escape
-   sequence and escape sequencing is not enabled,  the  variable  for  the
-   READ * command returns the first character of the escape sequence, for
-   example, ASCII 27. The terminal  device  driver  stores  the  remaining
-   characters of the escape sequence in the read buffer.  A  READ  command
-   following a READ * command returns  the  remaining  characters  of  the
-   escape sequence.  An  application  that  operates  with  NOESCAPE  must
-   provide successive READ *  commands  to  remove  the  remaining  escape
-   characters from the buffer.
+2 $Find()
+   $Find()
 
-   Example:
+   Returns an integer character position that locates the occurrence of a
+   substring within a string.
 
-   GTM> KILL
+   The format for the $FIND function is:
 
-   GTM> USE $P:(NOESCAPE:TERM=$C(13))
+   $F[IND](expr1,expr2[,intexpr])
 
-   GTM> READ *X SET ZB=$ZB READ Y:0 ZWRITE
+   $FIND() provides a tool to locate substrings. The ([) operator and the
+   two-argument $LENGTH() are other tools that provide related functionality.
 
-   (Press the F11 key on the terminal keyboard)
-   [23~i=5
-   x=27
+3 Examples
+   Examples
 
-   y="[23~"
+   Example:
 
-   zb=""
+   GTM>write $find("HIFI","I")
+   3
+   GTM>
 
-   GTM> USE $P:NOECHO READ *X S ZB=$ZB READ Y:0 USE $P:ECHO ZW
+   This example uses $FIND() to WRITE the position of the first occurrence of
+   the character "I." The return of 3 gives the position after the "found"
+   substring.
 
-   i=5
+   Example:
 
-   x=27
+   GTM>write $find("HIFI","I",3)
+   5
+   GTM>
 
-   y="[23~"
+   This example uses $FIND() to WRITE the position of the next occurrence of
+   the character "I" starting in character position three.
 
-   zb=""
+   Example:
 
-   GTM> READ *X SET ZB=$ZB USE $P:FLUSH READ Y:0 ZWRITE
+   GTM>set t=1 for  set t=$find("BANANA","AN",t) quit:'t  write !,t
 
-   i=5
+   4
+   6
+   GTM>
 
-   x=27
+   This example uses a loop with $FIND() to locate all occurrences of "AN" in
+   "BANANA". $FIND() returns 4 and 6 giving the positions after the two
+   occurrences of "AN".
 
-   y=""
+   Example:
 
-   zb=""
+   GTM>set str="MUMPS databases are hierarchical"
+   GTM>Write $find(str," ")
+   7
+   GTM>Write $find(str,"Z")
+   0
+   GTM>Write $find(str,"d",1)
+   8
+   GTM>Write $find(str,"d",10)
+   0
 
-   While the first  READ  Y:0  picks  up  the  sequence  after  the  first
-   character, notice how the graphic portion of the  sequence  appears  on
-   the terminal - this  is  because  the  READ  *X  separated  the  escape
-   character from the  rest  of  the  sequence  thus  preventing  the  VMS
-   terminal  driver  logic  from  recognizing  it  as  a  sequence,  and
-   suppressing its echo. The explicit suppression  of  echo  removes  this
-   visual artifact. In the case of the final READ *X, the FLUSH clears the
-   input buffer so that it is empty by the time of the READ Y:0.
+   The above example searches a string for a sub string, and returns an
+   integer value which corresponds to the next character position after
+   locating the sub string.
 
-3 READmaxlen_Comm_for_Term
-   READ X#maxlen Command for Terminals
+2 $FNumber()
+   $FNumber()
 
-   Generally, GT.M performs  the  same  maintenance  on  $ZB  for  a  READ
-   X#maxlen as for a  READ.  However,  if  the  READ  X#maxlen  terminates
-   because the input has reached the maximum  length,  GT.M  sets  $ZB  to
-   null. When the terminal has ESCAPE sequencing enabled,  and  the  input
-   contains an escape sequence that does not fit in the read buffer, GT.M
-   sets $ZB to contain the escape sequence.
+   Returns a string containing a formatted number.
 
-3 Term_Examples
-   Terminal Examples
+   The format for the $FNUMBER function is:
 
-   This section contains examples of GT.M terminal handling.
+   $FN[UMBER](numexpr,expr[,intexpr])
 
-   Example:
+   $FNUMBER() formats or edits numbers, usually for reporting.
 
-   USE $PIECE:(exception="zg "_$zl_":C^MENU")
+   The formatting codes are:
 
-   This example USEs the  principal  device,  and  sets  up  an  EXCEPTION
-   handler. When an EXCEPTION occurs, it transfers control to label  C  in
-   the routine ^MENU at the process stack level where  the  EXCEPTION  was
-   established.
+3 Examples
+   Examples
 
    Example:
 
-   USE $PIECE:(X=0:Y=0:CLEARSCREEN)
-
-   This example positions the cursor to the  upper  left-hand  corner  and
-   clears the entire screen.
+   GTM>do ^fnum
+   fnum;
+     zprint ^fnum
+     set X=-100000,Y=2000
+     write "SUPPRESS NEGATIVE SIGN:",?35,$FNumber(X,"-"),!
+     write "TRAILING SIGN:",?35,$FNumber(X,"T"),!
+     write "NEGATIVE NUMBERS IN ():",?35,$FNumber(X,"P"),!
+     write "COMMAS IN NUMBER:",?35,$FNumber(X,","),!
+     write "NUMBER WITH FRACTION:",?35,$FNumber(X,"",2),!
+     write "FORCE + SIGN IF POSITIVE:",?35,$FNumber(Y,"+"),!
+   SUPPRESS NEGATIVE SIGN:            100000
+   TRAILING SIGN:                     100000-
+   NEGATIVE NUMBERS IN ():            (100000)
+   COMMAS IN NUMBER:                  -100,000
+   NUMBER WITH FRACTION:              -100000.00
+   FORCE + SIGN IF POSITIVE:          +2000
 
    Example:
 
-   USE $PIECE:(NOECHO:WIDTH=132:WRAP)
+   set x=$fnumber(x,"-")
 
-   This example disables ECHOing, enables automatic WRAPping, and sets the
-   line width to 132 characters.
+   This example uses $FNUMBER() to SET x equal to its absolute value.
 
-   Example:
+2 $Get()
+   $Get()
 
-   USE $PIECE:NOCENABLE
+   Returns the value of a local or global variable if the variable has a
+   value. If the variable has no value, the function returns a value
+   specified by an optional second argument, and otherwise returns an empty
+   string.
 
-   This example disables <CTRL-C>.
+   The format for the $GET function is:
 
-2 Sequential_Files
-   Using Sequential Files
+   $G[ET](glvn[,expr])
 
-   GT.M provides access to sequential files  both  on  disk.  These  files
-   allow linear access to records. Sequential files  are  used  to  create
-   programs, store reports, and to communicate with facilities outside of
-   GT.M.
+   M defines $GET(x,y) as equivalent to:
 
-3 Setting_Seq_File_Charc
-   Setting Sequential File Characteristics
+   $Select($Data(x)[0:y,1:x)
 
-   The ANSI standard specifies that when a process CLOSEs and then reOPENs
-   a device, GT.M restores any characteristics  not  explicitly  specified
-   with deviceparameters to the values they had prior to the  last  CLOSE.
-   However, because it is difficult for a large menu-driven application to
-   ensure the previous OPEN state, GT.M always sets unspecified sequential
-   file characteristics to their default value on OPEN. This approach also
-   reduces potential memory overhead imposed by  OPENing  and  CLOSEing  a
-   large number of sequential files during the life of a process.
+   and $GET(x) as equivalent to:
 
-   GT.M does not restrict multiple OPEN commands. However, if  a  file  is
-   already open, GT.M ignores attempts  to  modify  sequential  file  OPEN
-   characteristics, except for RECORDSIZE and  for  deviceparameters  that
-   also exist for USE.
+   $GET(x,"")
 
-   Sequential files can be READONLY, or read/write (NOREADONLY).
+   $GET() provides a tool to eliminate separate initialization of variables.
+   This technique may provide performance benefits when used to increase the
+   density of a sparse global array by eliminating nodes that would otherwise
+   hold absent optional information. On the other hand, some uses of one
+   argument $GET() can mask logic problems.
 
-   Sequential files can be composed of either FIXED or VARIABLE (NOFIXED)
-   length records. By default, records have VARIABLE length.
+   GT.M has a "NOUNDEF" mode of operation, which treats all variable
+   references as if they were arguments to a one argument $GET(). The VIEW
+   command controls "NOUNDEF" mode.
 
-   UNIX enforces its standard security when GT.M OPENs a sequential file.
-   This includes any directory access required to  locate  or  create  the
-   file. If you are unable to OPEN a file, contact your system manager.
+3 Examples
+   Examples
 
-3 SeqFile_Pointers
-   Sequential File Pointers
+   Example:
 
-   Sequential file I/O operations use a construct called a  file  pointer.
-   The file pointer logically identifies the next record to read or write.
-   OPEN commands position the file pointer at the beginning  of  the  file
-   (REWIND) or at the end-of-file (APPEND).  APPEND  cannot  reposition  a
-   file currently open. Because the position of each record depends on the
-   previous record, a WRITE destroys the ability to reliably position the
-   file pointer to subsequent records in a  file.  Therefore,  by  default
-   (NOTRUNCATE), GT.M  permits  WRITEs  only  when  the  file  pointer  is
-   positioned at the end of the file.
+   setstatus;
+            if '$data(^PNT(NAME,TSTR)) set STATUS="NEW TEST"
+            else  if ^PNT(NAME,TSTR)="" set STATUS="WAITING FOR RESULT"
+            else  set STATUS=^PNT(NAME,TSTR)
 
-   If a device has TRUNCATE enabled, a WRITE issued when the file pointer
-   is not at the end of the file causes all  contents  after  the  current
-   file pointer to be discarded. This effectively moves  the  end  of  the
-   file to the current position and permits the WRITE.
+   This example can be reduced to two lines of code by using $GET(), shown in
+   the following example. However, by using $GET() in its one-argument form,
+   the distinction between an undefined variable and one with a null value is
+   lost:
 
-3 SeqFile_Examples
-   Sequential File Examples
+   set STATUS=$get(^PNT(NAME,TSTR))
+   if STATUS="" set STATUS="WAITING FOR RESULT"
 
-   This section contains a few brief  examples  of  GT.M  sequential  file
-   handling.
+   This is solved by using the two-argument form of $GET():
 
-   Example:
+   set STATUS=$get(^PNT(NAME,TSTR),"NEW TEST")
+   if STATUS="" set STATUS="WAITING FOR RESULT"
 
-   FREAD READ "File > ",sd
+2 $Increment()
+   $Increment()
 
-   OPEN sd:(readonly:exception="g BADOPEN")
+   Atomically adds (increments) a global variable by a numeric value. Note
+   that increment is atomic, but the evaluation of the expression is not,
+   unless inside a transaction (TStart/TCommit). The function also works on
+   local variables, but has less benefit for locals as it does not (need to)
+   provide ACID behavior.
 
-   USE sd:exception="G EOF"
+   The format of the $INCREMENT function is:
 
-   FOR USE sd READ x USE $P WRITE x,!
+   $INCREMENT(glvn[,numexpr])
 
-   EOF IF '
+3 Examples
+   Examples
 
-   $ZEOF ZM +$ZS
+   Example:
 
-   CLOSE sd
+   GTM>set i=1
+   GTM>write $increment(i)
+   2
+   GTM>write $increment(i)
+   3
+   GTM>write $increment(i)
+   4
+   GTM>write $increment(i)
+   5
+   GTM>write i
+   5
+   GTM>write $increment(i,-2)
+   3
+   GTM>write I
+   3
+   GTM>
 
-   QUIT
+   This example increments the value of i by 1 and at the end decrements it
+   by 2. Note that the default value for incrementing a variable is 1.
 
-   BADOPEN IF $P($ZS,",",1)=2 DO QUIT
+2 $Justify()
+   $Justify()
 
-   . WRITE !,"The file ",sd," does not exist."
+   Returns a formatted string.
 
-   IF $P($ZS,",",1)=13 DO QUIT
+   The format for the $JUSTIFY function is:
 
-   . WRITE !,"The file ",sd," is not accessible."
+   $J[USTIFY](expr,intexpr1[,intexpr2])
 
-   ZM +$ZS
+   $JUSTIFY() fills expressions to create fixed length values. However, if
+   the length of the specified expression exceeds the specified field size,
+   $JUSTIFY() does not truncate the result (although it may still round based
+   on the third argument). When required, use $EXTRACT() to perform
+   truncation.
 
-   QUIT
+   $JUSTIFY() optionally rounds the portion of the result after the decimal
+   point. In the absence of the third argument, $JUSTIFY() does not restrict
+   the evaluation of the expression. In the presence of the third (rounding)
+   argument, $JUSTIFY() evaluates the expression as a numeric value. The
+   rounding algorithm can be understood as follows:
 
-   This example OPENs a file READONLY  and  specifies  an  EXCEPTION.  The
-   exception  handler  for  the  OPEN  deals  with  file-not-found  and
-   file-access errors, and reissues all other  errors  with  the  ZMESSAGE
-   command. The first USE sets the EXCEPTION to  handle  end-of-file.  The
-   FOR loop reads the file one record at a time and transfers each record
-   to the principal device. The GOTO in the EXCEPTION terminates  the  FOR
-   loop. At label EOF, if $ZEOF is false, the code reissues the error that
-   triggered the exception. Otherwise, the CLOSE releases the file.
+3 Examples
+   Examples
 
    Example:
 
-   SET sd="temp.dat",acct=""
-
-   OPEN sd:newversion U sd:width=132
+   GTM>write ":",$justify("HELLO",10),":",!,":",$justify("GOODBYE",5),":"
+   :     HELLO:
+   :GOODBYE:
+   GTM>
 
-   FOR SET acct=$O(^ACCT(acct)) QUIT:acct="" DO
+   This uses $JUSTIFY() to display "HELLO" in a field of 10 spaces and
+   "GOODBYE" in a field of 5 spaces. Because the length of "GOODBYE" exceeds
+   five spaces, the result overflows the specification.
 
-   . SET rec=$$FORMAT(acct)
+   Example:
 
-   . WRITE:$Y>55 #,hdr W !,rec
+   GTM>write "1234567890",!,$justify(10.545,10,2)
+   1234567890
+        10.55
+   GTM>
 
-   CLOSE sd
+   This uses $JUSTIFY() to WRITE a rounded value right justified in a field
+   of 10 spaces. Notice that the result has been rounded up.
 
-   This OPENs a NEWVERSION of file temp.dat. The FOR loop  cycles  through
-   the ^ACCT global formatting (not shown in this code fragment) lines and
-   writing them to the  file.  The  FOR  loop  uses  the  argumentless  DO
-   construct to break a long line of code into more manageable blocks. The
-   program writes a header record (set up in initialization not, shown in
-   this code fragment) every 55 lines, because  that  is  the  application
-   page length, allowing for top and bottom margins.
+   Example:
 
-2 FIFO_Charc
-   FIFO Characteristics
+   GTM>write "1234567890",!,$justify(10.544,10,2)
+   1234567890
+        10.54
+   GTM>
 
-   FIFOs have the same characteristics as other sequential  files,  except
-   that READs and WRITEs can occur in any order.
+   Again, this uses $JUSTIFY() to WRITE a rounded value right justified in a
+   field of 10 spaces. Notice that the result has been rounded down.
 
-   The following characteristics of FIFO behavior may be helpful in using
-   them effectively.
+   Example:
 
-   With
-   READ:
+   GTM>write "1234567890",!,$justify(10.5,10,2)
+   1234567890
+        10.50
+   GTM>
 
-   o    If a READ is done while there is no data in the FIFO:
+   Once again, this uses $JUSTIFY() to WRITE a rounded value right justified
+   in a field of 10 spaces. Notice that the result has been zero-filled to 2
+   places.
 
-   The process hangs until data is put into the FIFO by  another  process,
-   or the READ times out, when a timeout is specified.
-   With
-   WRITE:
+   Example:
 
-   o    If a process tries into write to a full  FIFO,  the  process  hangs
-        until another process reads from the FIFO, emptying enough data to
-        make room for the new data.
+   GTM>write $justify(.34,0,2)
+   0.34
+   GTM>
 
-   While it is hung, the process will not respond to <CTRL-C>.
+   This example uses $JUSTIFY to ensure that the fraction has a leading zero.
+   Note the use of a second argument of zero in the case that rounding is the
+   only function that $JUSTIFY is to perform.
 
-   With
-   CLOSE:
+2 $Length()
+   $Length()
 
-   o    The FIFO is not deleted unless the DELETE qualifier is specified.
+   Returns the length of a string measured in characters, or in "pieces"
+   separated by a delimiter specified by one of its arguments.
 
-   o    If a process closes the FIFO with the DELETE  qualifier,  the  FIFO
-        becomes unavailable to new users at that time.
+   The format for the $LENGTH function is:
 
-   o    All processes currently USEing the FIFO may  continue  to  use  it,
-        until the last process attached to it CLOSES it, and is destroyed.
+   $L[ENGTH](expr1[,expr2])
 
-   o    Any process OPENing a FIFO with the same name  as  a  deleted  FIFO
-        creates a new one to which subsequent OPENs attach.
+3 Examples
+   Examples
 
-   A process must have read and write privileges on a FIFO to  access  it.
-   File permissions have no affect on a process that already has the FIFO
-   open.
+   Example:
 
-3 Consider_Impl_FIFOs
-   Considerations in Implementing FIFOs
+   GTM>Write $length("KINGSTON")
+   8
+   GTM>
 
-   As  you  establish  FIFOs  for  interprocess  communication,  consider
-   whether, and how, the following issues will be addressed:
+   This uses $LENGTH() to WRITE the length in characters of the string
+   "KINGSTON".
 
-   o    Do READs occur immediately, or can the process wait?
+   Example:
 
-   o    Are timed READs useful to avoid system hangs and provide a  way  to
-        remove the process?
+   GTM>set x="Smith/John/M/124 Main Street/Ourtown/KA/USA"
+   GTM>write $length(x,"/")
+   7
+   GTM>
 
-   o    Does the WRITE process need to  know  whether  the  READ  data  was
-        received?
+   This uses $LENGTH() to WRITE the number of pieces in a string, as
+   delimited by /.
 
-   o    Will there be multiple processes READing and WRITEing into a single
-        FIFO?
+   Example:
 
-3 GTM_Recog_FIFOs
-   GT.M Recognition of FIFOs
+   GTM>write $length("/2/3/","/")
+   4
+   GTM>
 
-   Like other GT.M  devices  a  FIFO  can  be  specified  as  an  argument
-   expression to the OPEN, USE, and CLOSE commands. A device OPENed with a
-   FIFO qualifier becomes a FIFO unless another device  of  that  name  is
-   already OPEN. In that case, OPENing a device that has  previously  been
-   OPENed by another process as a FIFO causes  the  process  (the  process
-   here is the process trying to open the FIFO) to attach to the existing
-   FIFO.
+   This also uses $LENGTH() to WRITE the number of pieces in a string, as
+   delimited by /. Notice that GT.M. adds one count to the count of
+   delimiters (in this case 3), to get the number of pieces in the string
+   (displays 4).
 
-3 FIFO_Devi_Ex
-   FIFO Device Examples
+2 $NAme()
+   $NAme()
 
-   The following two examples represent a master/slave  arrangement  where
-   the slave waits in a read state on the FIFO until the master  sends  it
-   some data that it then processes.
+   Returns an evaluated representation of some or all of a local or global
+   variable name.
 
-   Example:
+   The format for the $NAME function is:
 
-   set x="named.pipe"
+   $NA[ME](glvn[,intexpr])
 
-   open x:fifo
+3 Examples
+   Examples
 
-   do getres
+   Example:
 
-   use x write res,!
+   GTM>set X="A""B",^Y(1,X,"B",4)=""
+   GTM>write $name(^(3),3)
+   ^Y(1,"A""B","B")
+   GTM>
 
-   This routine opens the FIFO, performs its own processing which includes
-   starting the slave process (not shown in this code fragment).
+   This example sets up a naked reference and then uses $NAME() to display
+   the first three levels of that four-level reference.
 
    Example:
 
-   set x="named.pipe"
-
-   open x:fifo
+   GTM>write $name(^(3),0)
+   ^Y
+   GTM>
 
-   use x read res
+   This example shows the name level for the same naked reference.
 
-   do process(res)
+2 $Next()
+   $Next()
 
-   This routine waits for information from the master process, then begins
-   processing.
+   Returns the next subscripted local or global variable name in collation
+   sequence within the array level specified by its argument.
 
-2 NULL_Devices
-   Using NULL Devices
+   $NEXT() has been replaced by $ORDER(). $NEXT has been retained in the
+   current standard only for compatibility with earlier versions of the
+   standard. $NEXT() is similar to $ORDER(). However, $NEXT() has the
+   deficiency that when it encounters negative one (-1) as a subscript, it
+   returns the same result as when it finds no other data at the level. This
+   deficiency is particularly disruptive because it occurs in the middle of
+   the M collating sequence.
 
-   The null device is accessed through /dev/null. A null  device  fulfills
-   every input request by returning a null string  and  setting  $ZEOF.  A
-   null device discards  all  output.  GT.M  maintains  a  virtual  cursor
-   position for null devices as it does for terminals.  Use  null  devices
-   for program testing and debugging, or for jobs that permit  I/O  to  be
-   discarded under certain circumstances. For example, JOB processes must
-   have input and output devices associated with them, even though they do
-   not use them. Null devices are low overhead never-fail alternatives.
+   **Caution**
 
-3 Null_Dev_Ex
-   Null Device Examples
+   As $NEXT() has been removed from the standard in the MDC, you should use
+   $ORDER.
 
-   Example:
+   The format for the $NEXT function is:
 
-   SET dev="/dev/null"
+   $N[EXT](glvn)
 
-   OPEN dev USE dev
+2 $Order()
+   $Order()
 
-   SET x="" WRITE hdr,!,$ZDATE($h),?30,$J,!
+   Returns the subscript of the next or prior local or global variable name
+   in collation sequence within the array level specified by its first
+   argument. In doing so, it moves in the direction specified by the second
+   argument. In GT.M, when $ORDER() has an unsubscripted argument, it returns
+   the next or previous unsubscripted local or global variable name in
+   collating sequence.
 
-   FOR SET x=$O(^tmp($J,x)) q:x="" DO REPORT
+   The format for the $ORDER function is:
 
-   CLOSE dev
+   $O[RDER](glvn[,expr])
 
-   This program produces a report derived  from  the  information  in  the
-   global variable ^tmp. The unspecified routine  REPORT  may  potentially
-   contain a large amount of code. To see that the basic program functions
-   without error, the programmer may discard the output involved in favor
-   of watching the function. To run the program normally,  the  programmer
-   simply has to change the variable dev to name another device.
+   **Note**
 
-   Example:
+   Name-level $ORDER() always returns an empty string when used with extended
+   references.
 
-   JOB ^X:(IN="/dev/null":OUT="/dev/null":ERR= "error.log")
+3 Examples
+   Examples
 
-   This example issues a GT.M JOB command to execute  the  routine  ^X  in
-   another process. This  routine  processes  a  large  number  of  global
-   variables and produces no output. In the example,  the  JOBbed  process
-   takes its input from a null device, and sends  its  output  to  a  null
-   device. If the JOBbed process encounters an error, it directs the error
-   message to error.log.
+   Example:
 
-2 Socket_Devices
-   Using Socket Devices
+   GTM>zwrite
+   lcl(1)=3
+   lcl("x")=4
+   GTM>write $order(lcl(""))
+   1
 
-   SOCKET devices are used to access  and  manipulate  sockets.  A  SOCKET
-   device can have from zero (0) to 64 associated sockets.  At  any  time,
-   only one socket from the collection can be the current socket. If there
-   is no current socket, an attempt to READ from, or WRITE to the device,
-   generates an error.
+   This example returns the first node, that is 1, because the specified last
+   subscript of the argument is null and lcl has no null subscript.
 
-   Sockets can be attached and detached from  the  collection  of  sockets
-   associated with a device. Detached sockets belong  to  a  pseudo-device
-   called the "socketpool". A process can detach a socket  from  a  device
-   and later attach it to the same device or another device.
+   Example:
 
-        The GT.M socket device interface does not have the ability to pass
-        sockets between related or  unrelated  processes.  Currently  error
-        trapping operates on a device, rather than on a socket.
+   GTM>write $order(lcl(1))
+   x
 
-3 Msg_Mgmt
-   Message Management
+   This example returns the first node after lcl(1) that is x because lcl has
+   no null subscript.
 
-   From an application perspective, the transport layers used by a socket
-   device are stream-oriented  media,  with  no  provisions  for  implicit
-   application messages. Therefore, the following are two common protocols
-   used to segment application messages.
+   Example:
 
-   o    One method is to use  a,  typically  small,  fixed  length  message
-        containing the length of the next,  variable  length,  message.  In
-        GT.M a simplistic writer might be:
+   GTM>write $order(lcl(""),-1)
+   x
 
-   Write $Justify($Length(x),4),x
+   This example returns the last node that is, x, because the last subscript
+   of the first argument is null and second argument is -1.
 
-   A corresponding simplistic reader might be:
+   GTM>set lcl("")=2
+   GTM>zwrite
+   lcl("")=2
+   lcl(1)=3
+   lcl("x")=4
+   GTM>write $order(lcl(""))
+   1
 
-   Read len#4,x#len
+   This example returns the second node at the specified level because the
+   null subscript at the end of the argument is ambiguous (does it specify
+   starting at the beginning or starting at the real node with the null
+   subscript?) and returning the subscript of the first node (an empty
+   string) would tend to create an endless loop.
 
-   The advantage of this approach is that the message content  (the  value
-   of x in the code  fragments  above)  can  contain  any  character.  The
-   disadvantage  is  that  detecting  that  the  protocol  has  become
-   desynchronized is a problem.
-   o    The other common method  is  to  place  a  delimiter  between  each
-        application message. The protocol breaks if a message ever includes
-        a delimiter as part of its content.
+   Example:
 
-   The SOCKET device has  the  capability  to  handle  delimiters  because
-   parsing messages for delimiters is cumbersome.
+   GTM>write $order(lcl(""),-1)
+   x
+   GTM>write $order(lcl("x"),-1)
+   1
 
-3 Msg_Delimi
-   Message Delimiters
-
-   Each device can have from zero (0) to 64 delimiters associated with it.
-   Each delimiter can be from one (1) to 64 characters. All the delimiters
-   declared for a device are  valid  for  any  READ  from  any  associated
-   socket, which means, any of the defined delimiters terminate the READ.
-   The actual terminating delimiter is available in $KEY.  A  WRITE  to  a
-   socket associated with a device with one or more delimiters inserts the
-   first of the delimiters for any WRITE ! format.
-
-3 Read_Comm
-   READ Command
-
-   The READ  command  may  be  used  to  obtain  data  from  a  socket.  A
-   non-fixed-length read, with no timeout and  no  delimiters  requires  a
-   complex implementation of sequence of READs  to  ensure  a  predictable
-   result. This is because the transport layer stream fragments delivered
-   to the reader has only accidental correspondence  with  the  operations
-   performed by the writer. For example, the following
+   Example:
 
-   Write "Message 1","Message 2"
+   GTM>kill  set (a(1),a(2000),a("CAT"),a("cat"),a("ALF"),a(12))=1
 
-   is presented to the reader as the stream "Message1Message2" but it can
-   take from one (1) to 18 READ commands to retrieve the entire stream.
+   GTM>set x="" for  set x=$order(a(x)) quit:x=""  write !,x
 
-3 Write_Comm
-   WRITE Command
+   1
+   12
+   2000
+   ALF
+   CAT
+   cat
+   GTM>kill a("CAT") set a(5,10)="woolworths",a("cat")="last"
 
-   The WRITE command sends data to a socket.
+   GTM>set x="" for  set x=$order(a(x),-1) quit:x=""  write !,x
 
-   The WRITE command for SOCKET devices accepts following controlmnemonics
-   on a bound socket:
+   cat
+   ALF
+   2000
+   12
+   5
+   1
+   GTM>
 
+   This example uses a $ORDER() loop to display all the subscripts at the
+   first level of local variable a, make some changes in a, and then display
+   all the subscripts in reverse order. Notice that $ORDER() returns only the
+   existing subscripts in the sparse array and returns them in M collation
+   sequence, regardless of the order in which they were entered. Also,
+   $ORDER() does not differentiate between node A(5), which has only
+   descendants (no data value), and the other nodes, which have data values.
 
-   /L[ISTEN][(numexpr)]
+   Example:
 
-   Where numexpr is in the range 1-5 and specifies the listen queue depth.
+   GTM>kill set (%(1),tiva(2),A(3),tiv(4),Q(5),%a(6))=""
+   GTM>set x="%"
+   GTM>write:$data(@x) !,x for  set x=$order(@x) quit:x=""  write !,x
 
+   %
+   %a
+   A
+   Q
+   tiv
+   tiva
+   x
+   GTM>set $piece(x,"z",32)=""
+   GTM>write:$data(@x) !,x for  set x=$order(@x,-1) quit:x=""  write !,x
 
-   /W[AIT][(timeout)]
+   x
+   tiva
+   tiv
+   Q
+   A
+   %a
+   %
+   GTM>
 
-   Where timeout is a "numexpr" that specifies how long a server waits for
-   a connect before returning control to the GT.M routine.
+   This example uses $ORDER() to display the current local variable names in
+   both forward and reverse order. Notice that the first ([^]%) and last
+   ([^]zzzzzzzz) names require handling as special cases and require a
+   $DATA() function.
 
-   "WRITE !" inserts the character(s) of the first I/O delimiter (if any)
-   to the sending  buffer.  If  "ZFF=expr"  has  been  used  to  define  a
-   delimiter,  "WRITE  #"  inserts  the  characters  of  that  delimiter.
-   Otherwise WRITE # has no effect on the  stream  content.  WRITE  !  and
-   WRITE # always maintain $X and $Y in a fashion that emulates a terminal
-   cursor position.
+   Example:
 
-3 Socket_Devi_Ops
-   Socket Device Operation
+     set acct="",cntt=""
+     for  fet acct=$order(^acct(acct)) quit:acct=""  do
+     . for  set cntt=$order(^acct(acct,cntt)) do WORK
+     quit
 
-   Each socket may be in one of the following states:
+   This uses two nested $ORDER() loops to cycle through the ^acct global
+   array and perform some action for each second level node.
 
-   o    Created - indicates that the socket exists.
+2 $Piece()
+   $Piece()
 
-   o    Bound - indicates that the socket exists and is bound to a port; a
-        "Bound socket" needs a listen  queue  which  currently  requires  a
-        WRITE /LISTEN [after a USE].
+   Returns a substring delimited by a specified string delimiter made up of
+   one or more characters. In M, $PIECE() returns a logical field from a
+   logical record.
 
-   o    Connected - indicates that the socket exists and has a connection.
+   The format for the $PIECE function is:
 
-   A server socket used for accepting new  connections  goes  through  the
-   first two states in one step with a single OPEN or in two steps with an
-   OPEN and a USE. When a server does a WRITE /WAIT on a Bound  socket,  a
-   client can establish a connection which Creates another  server  socket
-   that is Connected. In server operation, $KEY supplies  the  port  value
-   when a socket is bound (important when port 0 is specified to  get  the
-   system to choose the port), and a socket id when a Connected socket is
-   created. A client socket goes through the first and third states with a
-   single OPEN or in two steps with an OPEN and a USE.
+   $P[IECE](expr1,expr2[,intexpr1[,intexpr2]])
 
-3 Socket_Devi_Ex
-   Socket Device Examples
+3 Examples
+   Examples
 
-   This section contains examples on Socket Device usage.
+   Example:
 
+   GTM>for i=0:1:3 write !,$piece("1 2"," ",i),"<"
+   <
+   1<
+   2<
+   <
+   GTM>
 
-   ;server.m
+   This loop displays the result of $PIECE(), specifying a space as a
+   delimiter, a piece position "before," first and second, and "after" the
+   string.
 
-   Set portno=6321,delim=$c(13)
+   Example:
 
-   Set tcpdev="server$"_$j,timeout=30
+   GTM>for i=-1:1:3 write !,$piece("1 2"," ",i,i+1),"<"
+   <
+   1<
+   1 2<
+   2<
+   <
+   GTM>
 
-   Open tcpdev:(ZLISTEN=portno_":TCP":attach="server"):timeout:"SOCKET"
+   This example is similar to the previous example except that it displays
+   two pieces on each iteration. Notice the delimiter (a space) in the middle
+   of the output for the third iteration, which displays both pieces.
 
-   Use tcpdev
+   Example:
 
-   Write /listen(1)
+   for p=1:1:$length(x,"/") write ?p-1*10,$piece(x,"/",p)
 
-   Write /wait(timeout)
+   This example uses $LENGTH() and $PIECE() to display all the pieces of x in
+   columnar format.
 
-   ;
-   ;dialogue with the client
+   Example:
 
-   ;
-   ;client.m
+   GTM>set $piece(x,".",25)="" write x
+   ........................
 
-   Set host="orlando"
-   Set portno=6321
-   Set delim=$c(13)
-   Set tcpdev="client$"_$j,timeout=30
-   O
-   tcpdev:(connect=host_":"_portno_":TCP":attach="client"):timeout:"SOCKET"
-   Use tcpdev
-   ;
-   ;dialogue with the server
+   This SETs the 25th piece of the variable x to null, with a delimiter of a
+   period. This produces a string of 24 periods preceding the null.
 
-   ;
-2 IO_Comm
-   I/O Commands
+   Example:
 
-   This section describes the following GT.M I/O commands:
+   GTM>set ^x=1,$piece(^a,";",3,2)=^b
 
-   o    OPEN establishes a connection from a GT.M process to a device.
+   This example leaves the naked indicator to pointing to the global ^b.
 
-   o    USE  declares  a  device  as  the  current  source  of  input  and
-        destination for output.
+2 $Qlength()
+   $Qlength()
 
-   o    READ accepts characters from the current device into  a  global  or
-        local variable.
+   Returns the number of subscripts in a variable name. The format is:
 
-   o    WRITE sends characters to the current device.
+   $QL[ENGTH] (namevalue)
 
-   o    CLOSE breaks the connection between a GT.M process and a device.
+3 Examples
+   Examples
 
-2 Open
-   Open
+   Example:
 
-   The OPEN command establishes a connection from  a  GT.M  process  to  a
-   device.
+   GTM>write $data(^|"XXX"|ABC(1,2,3,4))
+   0
+   GTM>set X=$name(^(5,6))
 
-   The format of the OPEN command is:
+   GTM>write $qlength(X)
+   5
 
-   O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])][:numexpr][:expr]][,...]
+   The number of subscripts in x is 5. Notice that the name and the
+   environment preceding it do not contribute to the count. Refer to $NAme()
+   section earlier in this chapter for an understanding of the $NAME
+   function.
 
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    The required expression specifies the device to OPEN.
-
-   o    The optional keywords specify deviceparameters that control device
-        behavior; some deviceparameters  take  arguments  delimited  by  an
-        equal sign (=); if the argument only contains one deviceparameter,
-        the surrounding parentheses are optional.
-
-   o    The optional numeric expression specifies a time in  seconds  after
-        which the command should timeout  if  unsuccessful;  0  provides  a
-        single attempt to open the device.
-
-   o    When  an  OPEN  command  specifying  a  timeout  contains  no
-        deviceparameters, double colons (::) separate the  timeout  numeric
-        expression from the device expression.
-
-   o    The optional expression specifies a mnemonicspace  that  selects  a
-        device binding. The only mnemonicspace that GT.M currently accepts
-        is SOCKET.
-
-   o    When an OPEN command specifies a  mnemonicspace  with  no  timeout,
-        double colons separate the mnemonicspace string expression from the
-        deviceparameters;  if  there  are  neither  a  timeout  nor
-        deviceparameters, triple colons separate the mnemonicspace from the
-        device expression.
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more OPEN arguments form a legal argument for an OPEN.
-
-   With the exception of FIFOs, UNIX device access is exclusive. READONLY
-   sequential disk files may be shared among many readers, but no writers.
-   Spooled devices are devices, usually printers, which buffer output from
-   multiple sources, processing it after the writing  process  CLOSEs  the
-   file. Spooled devices appear to GT.M as a  terminal  type  device.  For
-   more information on spooled devices, refer to the UNIX System Manager's
-   Manual. When one process successfully OPENs a  device  exclusively,  no
-   other process can access that device until  the  first  process  CLOSEs
-   that device.
-
-   By default, when  a  device  is  unavailable,  GT.M  retries  the  OPEN
-   indefinitely  at  approximately  one  second  intervals.  A  device  is
-   unavailable when another process is using it exclusively, or  when  the
-   OPENing process does not have the resources left to open the device.
+2 $QSubscript()
+   $QSubscript()
 
-   All other errors on OPEN raise an error condition and interrupt program
-   flow. A timeout is a tool that  lets  a  GT.M  routine  regain  program
-   control when a device remains unavailable. When the  OPEN  specifies  a
-   timeout, GT.M keeps retrying until either  the  OPEN  succeeds  or  the
-   timeout expires.
-
-   If OPEN establishes a connection  with  a  device  before  the  timeout
-   expires, GT.M sets $TEST to TRUE (1). If the timeout expires, GT.M sets
-   $TEST to FALSE (0). If an OPEN command does not specify a timeout, the
-   execution of the command does not affect $TEST.
-
-   If a process has not previously OPENed a device within the  context  of
-   an image, any deviceparameters not supplied  on  the  OPEN  take  their
-   default values. When reOPENing a device that it  previously  closed,  a
-   GT.M process restores all characteristics not specified on the OPEN to
-   the values the  device  had  when  it  was  last  CLOSEd,  except  with
-   sequential disk files. If you have a menu-driven application that OPENs
-   and CLOSEs devices based on user selections, take care that every OPEN
-   explicitly includes all deviceparameters important to the application.
-
-   GT.M treats sequential disk files differently  and  uses  defaults  for
-   unspecified sequential disk file characteristics on every  OPEN  (i.e.,
-   GT.M does not retain sequential disk file characteristics on a CLOSE).
-
-   If  a  process  OPENs  an  already  OPEN  device,  GT.M  modifies  any
-   characteristics that accept changes when a device is  OPEN  to  reflect
-   any new deviceparameter specifications.
-
-3 Ex_of_Open
-   Examples of OPEN
+   Returns a component of a variable name.
 
-   Example:
+   The format of the $QSUBSCRIPT function is:
 
-   SET sd="report.dat" OPEN sd:NEWVERSION
+   $QS[UBSCRIPT](namevalue, intexpr)
 
-   This OPENs a NEWVERSION of a sequential disk file named report.dat for
-   both read and write access.
+3 Examples
+   Examples
 
-3 Open_DeviParam
-   OPEN Deviceparameters
+   Example:
 
-4 APPEND
-   APPEND Applies to: Sequential Files
+   Assume that X is defined as in the "Examples of $Qlength()" earlier in
+   this chapter;
 
-   Positions the file pointer at  the  end-of-file.  This  deviceparameter
-   only affects the device  on  the  first  OPEN  command.  Re-OPENing  an
-   already OPEN device with this deviceparameter has no effect.
+   write X
+   X="^|""XXX""|ABC(1,2,3,5,6)"
+   GTM>write $qsubscript(X,-2)
+   error
+   GTM>WRITE $qsubscript(X,-1)
+   XXX
+   GTM>WRITE $qsubscript(X,0)
+   ^ABC
+   GTM>WRITE $qsubscript(X,1)
+   1
+   GTM>WRITE $qsubscript(X,4)
+   5
+   GTM>WRITE $qsubscript(X,7)
+   ""
 
-   By default, OPEN sets the file pointer to the beginning-of-file.
+2 $Query()
+   $Query()
 
-4 ATTACH
-   Attach=expr Applies to: Socket Device
+   Returns the next subscripted local or global variable node name,
+   independent of level, which follows the node specified by its argument in
+   M collating sequence and has a data value.
 
-   When ATTACH is used and one of ZLISTEN and CONNECT is specified at the
-   same time, the value of  expr  becomes  the  identifier  of  the  newly
-   created socket. If neither ZLISTEN nor CONNECT is specified, ATTACH is
-   ignored.
+   The format for the $QUERY function is:
 
-4 BLOCKSIZE
-   BLOCKSIZE=intexpr Applies to: Terminals and Printers
+   $Q[UERY](glvn)
 
-   Specifies the size in bytes of the maximum single read or write for the
-   specified device.
+   $QUERY() can be used as a tool for scanning an entire array for nodes that
+   have data values. Because $QUERY() can return a result specifying a
+   different level than its argument, the result provides a full variable
+   name. This contrasts with $ORDER(), which returns a subscript value. To
+   access the data value at a node, a $ORDER() return can be used as a
+   subscript; however, a $QUERY() return must be used with indirection.
+   Because arrays tend to have homogeneous values within a level but not
+   between levels, $QUERY() is more useful as a tool in utility programs than
+   in application programs. The $QUERY() can be useful in avoiding nested
+   $ORDER loops.
 
-4 CANONICAL
-   [NO]CANONICAL Applies to: Terminals and Printers
+   Note that the standard does not unambiguously define the state of the
+   naked reference indicator after a $QUERY(). While in GT.M after $QUERY(),
+   the naked reference indicator reflects the $QUERY() argument, NOT its
+   result.
 
-   Enables or  disables  canonical  input  as  controlled  by  the  ICANON
-   terminal attribute. See the documentation on your platform for details,
-   but in general this would be erase and kill edit functions,  and  lines
-   delimited by NL (usually <LF>), EOF (usually ^D), and EOL (usually not
-   defined).
+3 Examples
+   Examples
 
-   By default, canonical input is enabled.
+   Example:
 
-4 CONNECT
-   CONNECT=expr Applies to: Socket Device
+   The following routine:
 
-   Enables a client connection with a server,  which  is  located  by  the
-   information provided by expr. A new socket is allocated for the client
-   connection and is made the  current  socket  for  the  device,  if  the
-   operation is successful.
+   set y="^X"
+   for  set y=$query(@y) quit:y=""  write !,y,"=", at y
 
-   expr  specifies  the  protocol  and  protocol  specific  information.
-   Currently, TCP/IP is the only protocol GT.M supports. expr should be of
-   the format "<host>:<port>:TCP", where host is either an IP address or a
-   hostname like server.sanchez.com.
+   produces the results:
 
-        CONNECT is not compatible with ZLISTEN.
+   ^X(1,2,3)=123
+   ^X(1,2,3,7)=1237
+   ^X(1,2,4)=124
+   ^X(1,2,5,9)=1259
+   ^X(1,6)=16
+   ^X("B",1)=AB
 
-4 DELIMITER
-   [NO]DELIMITER=expr Applies to: Socket Device
+   Example:
 
-   DELIMITER establishes or replaces the list of delimiters  used  by  the
-   sockets associated with the device. The default for on a  command  that
-   first  OPENs  a  device  is  NODELIMITER.  The  delimiter  list  on  a
-   preexisting device remains the same until it is explicitly replaced or
-   deleted.
+   GTM>zwrite lcl
+   lcl("")=1
+   lcl(1)=1
+   lcl(1,2)=2
+   lcl(1,2,"")=3
+   lcl(1,2,"","")=4
+   lcl(1,2,"","",4)=5
+   lcl(1,2,0)=6
+   lcl(1,2,"abc",5)=7
+   lcl("x")=1
+   GTM>set y="lcl"
 
-   expr must be a string of the following format:
+   GTM>for  set y=$query(@y) quit:y=""  write !,y,"=", at y
 
-   ':'  is  used  to  separate  delimiters  (it  is  the  delimiter  for
-   delimiters).
+   This example produces the results:
 
-   '/' serves as an escape character.
+   lcl("")=1
+   lcl(1)=1
+   lcl(1,2)=2
+   lcl(1,2,"")=3
+   lcl(1,2,"","")=4
+   lcl(1,2,"","",4)=5
+   lcl(1,2,0)=6
+   lcl(1,2,"abc",5)=7
+   lcl("x")=1
 
-   expr "ab:/:://:bc" is interpreted as four delimiters, which  are  "ab",
-   ":", "/", and "bc". One  socket  can  have  0-64  delimiters  and  each
-   delimiter can contain 1-64 characters.
+   Note that the result is the same as the ZWRITE output.
 
-4 EXCEPTION
-   EXCEPTION=expr Applies to: All devices
+2 $Random()
+   $Random()
 
-   Defines an error handler for an I/O device. The expression must contain
-   a fragment of GT.M code (for example, GOTO ERRFILE) that  GT.M  XECUTEs
-   when the driver for the device detects an  error,  or  an  entryref  to
-   which  GT.M  transfers  control,  as  appropriate  for  the  current
-   gtm_ztrap_form.
+   Returns a random integer from a range specified by its argument.
 
-   For more information on error handling, refer to the "Error Processing"
-   chapter in GT.M Programmer's Guide.
+   The format for the $RANDOM function is:
 
-4 FIFO
-   FIFO Applies to: FIFO
+   $R[ANDOM](intexpr)
 
-   Specifies that the device for the OPEN is a FIFO name. GT.M creates the
-   FIFO if it does not already exist  and  if  the  process  has  adequate
-   privileges. However, in the  event  that  the  process  does  not  have
-   adequate privileges, the process generates a run-time error. A process
-   does not require any privileges to OPEN an existing FIFO.
+   $RANDOM() provides a tool for generating pseudo-random patterns useful in
+   testing or statistical calculations. $RANDOM() results fall between zero
+   (0) and one less than the argument.
 
-4 FIXED
-   [NO]FIXED Applies to: Sequential Files and FIFO
+   Random number generators use factors from the environment to create
+   sequences of numbers. True random number generation requires a source of
+   what is known as "noise". Pseudo-random numbers appear to have no pattern,
+   but are developed using interactions between factors that vary in ways not
+   guaranteed to be entirely random. In accordance with the M standard, the
+   GT.M implementation of $RANDOM() produces pseudo-random numbers.
 
-   Selects a fixed record length format for sequential disk  files.  FIXED
-   does not specify the actual length  of  a  record.  Use  RECORDSIZE  to
-   specify the record length.
+3 Examples
+   Examples
 
-   NOFIXED specifies a variable length record format for  sequential  disk
-   files. NOFIXED is a synonym for VARIABLE. FIXED  is  incompatible  with
-   STREAM and VARIABLE.
+   Example:
 
-   By default, records have VARIABLE length.
+   GTM>for i=1:1:10 write $random(1)
+   0000000000
+   GTM>
 
-4 GROUP
-   GROUP=expr Applies to: Sequential Files and FIFO
+   This shows that when $RANDOM() has an argument of one (1), the result is
+   too confined to be random.
 
-   Specifies access permission on a UNIX file for other users in the file
-   owner's group. The expression is a character string evaluating to null
-   or to any combination of the letters RWX, indicating respectively Read,
-   Write, and eXecute access. When  any  of  the  permissions  controlling
-   deviceparameters appears on an OPEN of a new file,  any  user  category
-   (OWNER, SYSTEM, WORLD), that is not explicitly specified is  given  the
-   default access permissions. When  any  one  of  these  deviceparameters
-   appears on an OPEN of an existing device, any user category that is not
-   explicitly specified remains unchanged.
+   Example:
 
-   In order to modify file security, the user who  issues  the  OPEN  must
-   have ownership.
+   set x=$random(100)+1*.01
 
-   By default, OPEN does not modify the permissions on an  existing  file.
-   Unless  otherwise  specified,  when  OPEN  creates  a  new  file,  it
-   establishes security using standard defaulting rules.
+   This $RANDOM() example produces a number between 0 and 99. The example
+   then shifts with addition, and scales with multiplication to create a
+   value between .01 and 1.
 
-4 IOERROR
-   IOERROR=expr Applies to: Socket Device
+2 $REverse()
+   $REverse()
 
-   Enables exception handling in socket devices. expr  specifies  the  I/O
-   error trapping mode. A value equal to "TRAP" specifies that I/O errors
-   on a device raise error conditions. A value equal to "NOTRAP", or when
-   IOERROR is not specified, indicates that I/O error on a device does not
-   raise error conditions.
+   Returns a string with the characters in the reverse order from that of its
+   argument.
 
-        GT.M currently handles exception handling at device  level  instead
-        of socket level.
+   The format for the $REVERSE function is:
 
-4 NEWVERSION
-   NEWVERSION Applies to: Sequential Files and FIFO
+   $RE[VERSE](expr)
 
-   The NEWVERSION deviceparameter assures that when an  existing  file  is
-   used, it is empty upon the OPEN.
+3 Examples
+   Examples
 
-   By default, if any version  of  the  file  exists,  OPEN  accesses  the
-   current version. If  no  version  of  the  file  exists,  OPEN  without
-   READONLY creates a new file.
+   Example:
 
-4 OWNER
-   OWNER=expr Applies to: Sequential Files and FIFO
+   GTM>write $reverse(123)
+   321
+   GTM>write $reverse("AbCDe")
+   "eDCbA"
 
-   Specifies access permission on a UNIX file for the owner of  the  file.
-   The expression is a character string  evaluating  to  null  or  to  any
-   combination of the letters RWX, indicating  Read,  Write,  and  eXecute
-   access. When any one of these deviceparameters appears on an OPEN of a
-   new file, any user category that is not explicitly specified  is  given
-   the default mask. When any one of these deviceparameters appears on an
-   OPEN of an existing file, any user category (GROUP, SYSTEM, WORLD) that
-   is not explicitly specified remains unchanged.
+2 $Select()
+   $Select()
 
-   To modify file security,  the  user  who  issues  the  OPEN  must  have
-   ownership.
+   Returns a value associated with the first true truth-valued expression in
+   a list of paired expression arguments.
 
-   By default, OPEN does not modify the permissions on an  existing  file.
-   Unless otherwise specified, OPEN establishes  security  using  standard
-   defaulting rules when it creates a new file.
+   The format for the $SELECT function is:
 
-4 READONLY
-   [NO]READONLY Applies to: Sequential Files and FIFO
+   $S[ELECT](tvexpr:expr[,...])
 
-   OPENs a device for reading  only  (READONLY)  or  reading  and  writing
-   (NOREADONLY).
+   $SELECT() is one of a limited set of functions that permit an indefinite
+   number of arguments. $SELECT() provides a means of selecting from a list
+   of alternatives.
 
-   To open a sequential file using the READONLY parameter, the  file  must
-   exist on the disk. If it does not, GT.M issues a run-time error.
+   Generally, the last $SELECT() argument has numeric literal one (1) for a
+   truth-value to prevent run-time errors, and to provide a "default" value.
 
-   When GT.M encounters a WRITE directed to a file OPENed  READONLY,  GT.M
-   issues a run-time error.
+3 Examples
+   Examples
 
-   By default, OPEN accesses the device or file NOREADONLY (read-write).
+   Example:
 
-4 RECORDSIZE
-   RECORDSIZE=intexpr Applies to: Sequential Files and FIFO
+   GTM>for i=3:-1:0 write !,$select(i=1:"here",i=2:"come",i=3:"Watson")
 
-   Overrides the default record size for a  disk  and  specifies  the  new
-   maximum record size in bytes.
+   Watson
+   come
+   here
+   %GTM-E-SELECTFALSE, No argument to $SELECT was true
 
-4 REWIND
-   REWIND Applies to: Sequential Files
+   GTM>
 
-   REWIND positions the file pointer of a sequential  disk  to  the  first
-   record.
+   This loop uses $SELECT() to WRITE a series of strings. Because there is no
+   true argument on the fourth iteration, when i=0, $SELECT() produces an
+   error.
 
-   By default, OPEN does not REWIND.
+   Example:
 
-5 [NO]STREAM Applies to: SD
-4 STREAM
-   [NO]STREAM Applies to: Sequential Files
+   set name=$select(sex="M":"Mr. ",sex="F":"Ms. ",1:"")_name
 
-   STREAM and VARIABLE are essentially the same; VARIABLE is preferred.
+   This example uses $SELECT() to add a prefix to the name based on a sex
+   code held in the variable sex. Notice that the default handles the case of
+   a missing or incorrect code.
 
-   The combination of the STREAM and NOWRAP options on disk  files  allows
-   you to write a record of arbitrary length. While each WRITE argument is
-   truncated if it exceeds the WIDTH, the total record can be of arbitrary
-   length. Note that, for efficiency,  the  compiler  combines  sequential
-   literal arguments of a single WRITE into a single string  so  that  the
-   run-time  system  considers  the  combined  length  of  the  sequence.
-   Automatic record termination does not occur when record length exceeds
-   the device width.
+   Example:
 
-   By default, records are VARIABLE, NOSTREAM.
+   if $select(x=+x:x,x="":0,"JANAPRJULOCT"[x:1,1:0) do THING
 
-4 SYSTEM
-   SYSTEM=expr Applies to: Sequential Files
+   This uses $SELECT() to perform complex logic as the truth-valued
+   expression argument to an IF command.
 
-   This deviceparameter is a synonym for OWNER that is maintained in UNIX
-   for compatibility with VMS applications.
+2 $STack()
+   $STack()
 
-4 TRUNCATE
-   [NO]TRUNCATE Applies to: Sequential Files and FIFO
+   Returns strings describing aspects of the execution environment.
 
-   Enables or disables overwriting of existing  data  in  sequential  disk
-   files. Because the position of each record depends on the prior record,
-   a WRITE destroys the ability to reliably position to subsequent records
-   in a file. Therefore, by default (NOTRUNCATE), GT.M permits WRITEs only
-   when the file pointer is positioned at the end-of-file. When  a  device
-   has TRUNCATE enabled, a WRITE issued when the file pointer  is  not  at
-   end-of-file truncates the file by destroying all  data  from  the  file
-   pointer to the end-of-file.
+   The format for the $STACK function is:
 
-   By default, OPEN accesses the file NOTRUNCATE.
+   $ST[ACK](intexpr[,expr])
 
-4 UIC
-   UIC=expr Applies to: Sequential Files and FIFO
+   **Note**
 
-   Specifies the group that has access to the  file.  The  format  of  the
-   string is "g,i" where g is a  decimal  number  representing  the  group
-   portion of  the  UIC  and  i  is  a  decimal  number  representing  the
-   individual portion. A process with the VMS privilege CMKRNL may set the
-   file UIC to a UIC other than the UIC under which it is running, thereby
-   giving ownership of the file to another user.
+   $STACK() returns similar information to ZSHOW "S" when ""=$ECODE, but when
+   $ECODE contains error information, $STACK() returns information as of the
+   time of a prior error, generally the first entry in $ECODE. For $STACK()
+   to return current information, be sure that error handing code does a SET
+   $ECODE="" before restoring the normal flow of control.
 
-   Specifies the owner and affects access  to  the  file.  The  expression
-   evaluates to the numeric identifier of the new owner.
+3 Examples
+   Examples
 
-4 VARIABLE
-   VARIABLE Applies to: Sequential Files and FIFO
+   Example:
 
-   Specifies the VARIABLE record length format for sequential disk files.
+   /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^dstackex
+   dstackex;
+     zprint ^dstackex
+     write !,$STACK
+     xecute "WRITE !,$STACK"
+     do Label
+     write !,$$ELabel
+     write !,$STACK
+     quit
 
-   By default, records have VARIABLE length.
+   Label
+     write !,$STACK
+     do DLabel
+     quit
 
-4 WORLD
-   WORLD=expr Applies to: Sequential Files and FIFO
+   ELabel()
+     quit $STACK
 
-   Specifies access permissions for users not in the owner's  group  on  a
-   UNIX file. The expression is a character string evaluating to  null  or
-   to any combination of the letters RWX,  indicating  respectively  Read,
-   Write, and eXecute access.  When  any  one  of  these  deviceparameters
-   appears on an OPEN of a  new  file,  any  user  category  that  is  not
-   explicitly specified is given the default character  string.  When  any
-   one of these deviceparameters appears on an OPEN of an  existing  file,
-   any user category  (OWNER,  GROUP,  SYSTEM),  that  is  not  explicitly
-   specified remains unchanged.
+   DLabel
+     write !,$STACK
+     quit
 
-   To modify file security,  the  user  who  issues  the  OPEN  must  have
-   ownership.
+   0
+   1
+   1
+   2
+   1
 
-   By default, OPEN and CLOSE do not modify the permissions on an existing
-   file. Unless otherwise specified, when OPEN  creates  a  new  file,  it
-   establishes security using standard defaulting rules.
+   Example for error processing:
 
-4 WRAP
-   [Z][NO]WRAP Applies to: FIFO, Sequential Devices, and Socket Device
+   GTM>zprint ^debugerr
+   debugerr;
+    set dsm1=$stack(-1)
+    write !,"$stack(-1):",dsm1
+    for l=dsm1:-1:0 do
+    . write !,l
+    . for i="ecode","place","mcode" write ?5,i,?15,$stack(l,i),!
 
-   Enables or disables automatic  record  termination.  When  the  current
-   record size ($X) reaches the maximum WIDTH  and  the  device  has  WRAP
-   enabled, GT.M starts a new record, as if the routine had issued a WRITE
-   ! command.
+   GTM>
 
-   NOWRAP causes GT.M to require a WRITE ! to terminate the record. NOWRAP
-   allows $X to become greater than the device  WIDTH  for  terminals  and
-   null devices.
+   The above example can be used to display a trace of the code path that led
+   to an error.
 
-   The combination of STREAM and NOWRAP options on disk files  allows  you
-   to write a record of arbitrary length. Without the STREAM  option,  the
-   WRAP option determines the action taken when the record length exceeds
-   the device WIDTH. NOWRAP causes GT.M to truncate the record, while WRAP
-   causes GT.M to insert a format control character.
+   Example:
 
-   By default, records WRAP.
+   GTM>zprint ^dstacktst
+   dstacktst(x)       ; check $stack() returns with and without clearing $ecode
+    set $etrap="do ^debugerr"
+   label
+    if x>0 set $ecode=",U1," ; if condition
+    else  set $ecode=",U2," ;  else condition
+    quit
 
-4 ZBFSIZE
-   ZBFSIZE Applies to: Socket Devices
+   GTM>do ^dstacktst(0)
 
-   Allocates a buffer used by GT.M when reading from a socket. The ZBFSIZE
-   deviceparameter should be at  least  as  big  as  the  largest  message
-   expected.
+   $stack(-1):2
+   2    ecode
+        place     debugerr+3^debugerr
+        mcode      for l=dsm1:-1:0 do
 
-   By default, the size of ZBFSIZE is 1024 and the maximum it  can  be  is
-   1048576.
-
-4 ZDELAY
-   Z[NO]DELAY Applies to: Socket Devices
+   1    ecode     ,U2,
+        place     label+2^dstacktst
+        mcode      else  set $ecode=",U2," ;  else condition
 
-   Controls buffering of data packets by the system TCP  stack  using  the
-   TCP_NODELAY option to the SETSOCKOPT  system  call.  This  behavior  is
-   sometimes known as the Nagle algorithm. The  default  is  ZDELAY.  This
-   delays sending additional packets until either  an  acknowledgement  of
-   previous packets is received or an interval passes. If several packets
-   are sent from one end of a connection before the  other  end  responds,
-   setting ZNODELAY may be desirable though  at  the  cost  of  additional
-   packets being transmitted over the  network.  ZNODELAY  must  be  fully
-   spelled out.
+   0    ecode
+        place     +1^GTM$DMOD
+        mcode
+   %GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
 
-4 ZFF
-   Z[NO]FF=expr Applies to: Socket Device
+   GTM>do ^dstacktst(1)
 
-   expr specifies a string of characters, typically in $CHAR()  format  to
-   send to socket device, whenever a routine issues a  WRITE  #.  When  no
-   string is specified or when ZFF="", then no characters  are  sent.  The
-   default in GT.M is ZNOFF.
-
-4 ZIBFSIZE
-   ZIBFSIZE Applies to: Socket Device
+   $stack(-1):1
+   1    ecode     ,U2,
+        place     label+2^dstacktst
+        mcode      else  set $ecode=",U2," ;  else condition
 
-   Sets  the  buffer  size  used  by  the  network  software  (setsockopt
-   SO_RCVBUF).
+   0    ecode
+        place     +1^GTM$DMOD
+        mcode
+   %GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
 
-   The default and the maximum values depend on the platform and/or system
-   parameters.
+   GTM>set $ecode=""
 
-4 ZLISTEN
-   ZLISTEN=expr Applies to: Socket Device
+   GTM>do ^dstacktst(1)
 
-   A new socket is allocated to listen for a connection. It  is  made  the
-   current socket for the device, if the  operation  is  successful.  Upon
-   successful completion, $KEY is set to the format of
-   "BOUND|<socket handle>|<port number>"
+   $stack(-1):2
+   2    ecode
+        place     debugerr+3^debugerr
+        mcode      for l=dsm1:-1:0 do
 
-   otherwise, $KEY is assigned the empty string.
+   1    ecode     ,U1,
+        place     label+1^dstacktst
+        mcode      if x>0 set $ecode=",U1," ; if condition
 
-   expr  specifies  the  protocol  and  protocol  specific  information.
-   Currently, TCP/IP is the only protocol GT.M supports. expr must  be  of
-   the format "<port>:TCP", where port specifies the port number at which
-   the socket is waiting for a connection.
+   0    ecode
+        place     +1^GTM$DMOD
+        mcode
+   %GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
 
-        ZLISTEN is not compatible  with  ATTACH  in  the  USE  command  and
-        CONNECT in both USE and OPEN commands.
+   GTM>
 
-2 Use
-   Use Command
+   This example shows how SETing $ECODE=.. makes $STACK() reports current
+   information. Notice how ^do dstacktst(0) and ^dostacktst(1) without
+   clearing $ECODE in between displays information frozen at the time of the
+   first error (else condition).
 
-   The USE command selects the current device for READs (input) and WRITEs
-   (output).
+2 $Text()
+   $Text()
 
-   The format of the USE command is:
+   Returns source text for the line specified by its argument.
 
-   U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
+   The format for the $TEXT function is:
 
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
+   $T[EXT](entryref)
 
-   o    The required expression specifies the device to  make  the  current
-        device.
+   $TEXT() provides a tool for examining routine source code and the name of
+   the current routine or trigger. $TEXT() assists, along with the ZPRINT
+   command, in debugging programs. $TEXT() also allows the insertion of small
+   tables of driver information into a routine. Because $TEXT() is not very
+   efficient and the table-driven technique is generally best suited to
+   minimal program changes, this approach is best used for prototyping and
+   the tables should reside in global variables for production.
 
-   o    A USE that selects a device not currently  OPENed  by  the  process
-        causes a run-time error.
+   If $TEXT() cannot access the source file for the current object, either
+   because it is not in the location from which it was compiled or because
+   the process does not have access to some piece of the path to the source,
+   or if the located source does not match the object currently in use by the
+   process, $TEXT() returns an empty string.
 
-   o    The optional keywords specify deviceparameters that control device
-        behavior; some deviceparameters  take  arguments  delimited  by  an
-        equal  sign  (=).  If  there  is  only  one  deviceparameter,  the
-        surrounding parentheses are optional.
+3 Examples
+   Examples
 
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more USE arguments form a legal argument for a USE.
+   Example:
 
-   The intrinsic special variable $IO identifies the  current  device,  so
-   GT.M directs all READs and WRITEs to $IO. When  a  GT.M  image  starts,
-   $PRINCIPAL is implicitly OPENed and USEd. Once the GT.M  image  USEs  a
-   device, $IO holds the name of that device until the next USE command.
+   for i=1:1 set x=$text(+i) quit:x=""  write !,x
 
-   A  USE  command  modifies  the  device  in  accordance  with  the
-   deviceparameters that apply to the device type and ignores  those  that
-   do not apply. Characteristics set  with  USE  deviceparameters  persist
-   until  another  USE  for  the  same  device  with  the  corresponding
-   deviceparameter. Characteristics persist through USEs of other devices
-   and, except for  sequential  files,  through  a  subsequent  CLOSE  and
-   re-OPEN.
+   This loop uses $TEXT() to write out the entire source for the current
+   routine.
 
    Example:
 
-   USE $P:(X=0:Y=$Y-1:NOECHO)
-
-   This example USEs the principal device. If that device is  a  terminal,
-   the deviceparameters turn off echo  and  position  the  cursor  to  the
-   beginning of the previous line.
+   GTM>write $text(+0)
+   GTM$DMOD
+   GTM>write $text(+1)
+   GTM>
 
-3 Use_DeviParam
-   Use Deviceparameters
+   This uses $TEXT() to WRITE the name of the current routine, then it tries
+   to access the source and returns an empty string. This occurs because the
+   default Direct Mode image is compiled by FIS and delivered without source.
+   The exact failure message may vary.
 
-4 ATTACH
-   ATTACH=expr Applies to: Socket Device
+2 $TRanslate()
+   $TRanslate()
 
-   When ATTACH is used and one of ZLISTEN and CONNECT is specified at the
-   same time, the value of  expr  becomes  the  identifier  of  the  newly
-   created socket. If neither  ZLISTEN  nor  CONNECT  is  specified,  expr
-   specifies the socket to be moved from  the  socketpool  to  the  socket
-   device argument of USE.
+   Returns a string that results from replacing or dropping characters in the
+   first of its arguments as specified by the patterns of its other
+   arguments.
 
-4 CANONICAL
-   [NO]CANONICAL Applies to: Terminals and Printers
+   The format for the $TRANSLATE function is:
 
-   Enables or  disables  canonical  input  as  controlled  by  the  ICANON
-   terminal attribute. See the documentation on your platform for details,
-   but in general this would be erase and kill edit functions,  and  lines
-   delimited by NL (usually <LF>), EOF (usually ^D), and EOL (usually not
-   defined).
+   $TR[ANSLATE](expr1[,expr2[,expr3]])
 
-   By default, canonical input is enabled (that is  [NO]CANONICAL  is  the
-   default).
+   The $TRANSLATE() algorithm can be understood as follows:
 
-4 CENABLE
-   [NO]CENABLE Applies to: Terminals and Printers
+     * $TRANSLATE() evaluates each character in the first expression,
+       comparing it character by character to the second expression looking
+       for a match. If there is no match in the second expression, the
+       resulting expression contains the character without modification.
+     * When it locates a character match, $TRANSLATE() uses the position of
+       the match in the second expression to identify the appropriate
+       replacement for the original expression. If the second expression has
+       more characters than the third expression, $TRANSLATE() replaces the
+       original character with a null, thereby deleting it from the result.
+       By extension of this principle, if the third expression is missing,
+       $TRANSLATE() deletes all characters from the first expression that
+       occur in the second expression.
 
-   Enables or disables the ability to  force  GT.M  into  Direct  Mode  by
-   entering <CTRL-C> at $PRINCIPAL.
+3 Examples
+   Examples
 
-   [NO]CENABLE is subordinate to a CTRAP that includes <CTRL-C> ($C(3)).
+   Example:
 
-   By default, images have CENABLEd.
+   GTM>write $translate("ABC","CB","1")
+   A1
+   GTM>
 
-4 CLEARSCREEN
-   CLEARSCREEN Applies to: Terminals and Printers
+   **Note**
 
-   Clears the terminal screen from the  present  cursor  position  to  the
-   bottom of the screen. The CLEARSCREEN deviceparameter does  not  change
-   the cursor position or the $X and $Y variables.
+   While this example provides an explanation for the work done by
+   $TRANSLATE(), it does not necessarily correspond to how GT.M implements
+   $TRANSLATE().
 
    Example:
 
-   U $P:(X=0:Y=0:CLEAR)
+   GTM>write $translate("A","AA","BC")
+   B
+   GTM>
 
-   This example positions the cursor to "home" in the upper left corner of
-   a VDT and clears the entire current screen "page."
+   This $TRANSLATE() example finds the first occurrence of "A" in the second
+   expression, which holds the first character position, and substitutes the
+   character in the first position of the third expression.
 
-4 CONNECT
-   CONNECT=expr Applies to: Socket Device
+   Example:
 
-   Enables a client connection with a server,  which  is  located  by  the
-   information provided by expr. A new socket is allocated for the client
-   connection and is made the  current  socket  for  the  device,  if  the
-   operation is successful.
+   GTM>write $translate("BACKUP","AEIOU")
+   BCKP
+   GTM>
 
-   expr  specifies  the  protocol  and  protocol  specific  information.
-   Currently, TCP/IP is the only protocol GT.M supports. expr should be of
-   the format "<host>:<port>:TCP", where host is either an IP address or a
-   hostname like server.sanchez.com.
+   Because the $TRANSLATE() has only two parameters in this example, it finds
+   the characters in the first expression that also exist in the second
+   expression and deletes them from the result.
 
-        CONNECT is not compatible with ZLISTEN.
+2 $View()
+   $View()
 
-4 CONVERT
-   [NO]CONVERT Applies to: Terminals and Printers
+   Returns information about an environmental factor selected by the
+   arguments. In GT.M, the first argument contains a keyword identifying the
+   environmental factor and, where appropriate, subsequent arguments select
+   among multiple possible occurrences of that factor.
 
-   Enables  or  disables  the  terminal  device  driver  from  converting
-   lowercase input to uppercase during READs.
+   The format for the $VIEW() function is:
 
-   By default, the terminal device driver operates NOCONVERT.
+   $V[IEW](expr1[,expr2])
 
-4 CTRAP
-   CTRAP=expr Applies to: Terminals and Printers
+3 Argument_Keywords_of_$VIEW()
+   Argument Keywords of $VIEW()
 
-   Establishes the <CTRL> characters in the expression as trap characters
-   for the current device. When the terminal device driver receives a trap
-   character in the input from a device, GT.M issues a run-time exception.
-   The device does not have to be the current device, that is $IO.
+   $VIEW() provides a means of accessing GT.M environmental information.
+   $VIEW() is similar in purpose to Intrinsic Special Variables. When GT.M
+   permits modification of the factors accessible with $VIEW(), the VIEW
+   command generally provides the tool for performing the change.
 
-   The <CTRL> characters are ASCII 0 though 31.
+   +------------------------------------------------------------------------+
+   |                       $VIEW() Argument Keywords                        |
+   |------------------------------------------------------------------------|
+   |       ARG 1       |     ARG 2      |           RETURN VALUE            |
+   |-------------------+----------------+-----------------------------------|
+   | "BREAKMSG"        | none           | Value of the break message mask;  |
+   |                   |                | GT.M defaults this to 31.         |
+   |-------------------+----------------+-----------------------------------|
+   | "FREEBLOCKS"      | region         | Number of free database blocks in |
+   |                   |                | a given region.                   |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Process-id of the process that    |
+   |                   |                | has frozen the database           |
+   |                   |                | associated with the region        |
+   | "FREEZE"          | region         | specified (using DSE or MUPIP).   |
+   |                   |                |                                   |
+   |                   |                | If the region is currently not    |
+   |                   |                | frozen, returns a value of 0.     |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Truth Value indicating whether    |
+   |                   |                | Database block certification is   |
+   |                   |                | currently enabled or disabled.    |
+   | "GDSCERT"         | none           |                                   |
+   |                   |                | To enable or disable Database     |
+   |                   |                | block certification, use the VIEW |
+   |                   |                | "GDSCERT" command.                |
+   |-------------------+----------------+-----------------------------------|
+   | "GVACCESS_METHOD" | region         | Access method of the region.      |
+   |-------------------+----------------+-----------------------------------|
+   | "GVFILE"          | region         | Name of the database associated   |
+   |                   |                | with the region.                  |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Name of the first database region |
+   | "GVFIRST"         | none           | in the current global directory.  |
+   |                   |                | Is functionally equivalent to     |
+   |                   |                | $VIEW("GVNEXT","")                |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Name of the next database region  |
+   | "GVNEXT"          | region         | after the given one; "" for       |
+   |                   |                | region starts with the first      |
+   |                   |                | region.                           |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Encoded information about         |
+   |                   |                | database behavior since segment   |
+   |                   |                | creation. It also includes SET    |
+   |                   |                | operations even if they are       |
+   |                   |                | inside a TP transaction.          |
+   |                   |                |                                   |
+   |                   |                | If you require completely         |
+   |                   |                | accurate GVSTATS, you need to     |
+   | "GVSTAT"          | region         | ensure the last process to close  |
+   |                   |                | a database always has write       |
+   |                   |                | access to the database files. If  |
+   |                   |                | read-only processes are the       |
+   |                   |                | active processes in a database,   |
+   |                   |                | they cannot update the database   |
+   |                   |                | and may delete the shared memory  |
+   |                   |                | where they have stored the counts |
+   |                   |                | of their actions (for examples    |
+   |                   |                | blocks read).                     |
+   |-------------------+----------------+-----------------------------------|
+   | "ICHITS"          | none           | Number of indirection cache hits  |
+   |                   |                | since GT.M image activation.      |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Number of indirection cache       |
+   | "ICMISS"          | none           | misses since GT.M image           |
+   |                   |                | activation.                       |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | can return the following values:  |
+   |                   |                |                                   |
+   |                   |                |   * -1 (internal error)           |
+   | "JNLACTIVE"       | region         |   * 0 journaling is disabled      |
+   |                   |                |   * 1 journaling is enabled but   |
+   |                   |                |     closed (OFF)                  |
+   |                   |                |   * 2 journaling is enabled and   |
+   |                   |                |     open (ON)                     |
+   |-------------------+----------------+-----------------------------------|
+   | "JNLFILE"         | region         | Journal file name associated with |
+   |                   |                | the region.                       |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Index showing how many ZTSTART    |
+   | "JNLTRANSACTION"  | none           | transaction fences have been      |
+   |                   |                | opened (and not closed).          |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Truth value showing whether label |
+   | "LABELS"          | none           | case sensitivity is ON (1 for     |
+   |                   |                | "LOWER") or OFF (0 for "UPPER");  |
+   |                   |                | GT.M defaults to 1.               |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | returns the number of references  |
+   |                   |                | by alias containers to the array  |
+   |                   |                | associated with an unsubscripted  |
+   | "LV_CREF"         | local variable | local variable name specified as  |
+   |                   | name (lvn)     | a second expr (for example a      |
+   |                   |                | quoted string); it returns a zero |
+   |                   |                | for a variable without any        |
+   |                   |                | associated alias container.       |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | returns the number of data-spaces |
+   |                   |                | recovered during a local variable |
+   | "LV_GCOL"         | none           | data-space garbage collection it  |
+   |                   |                | triggers; such collections        |
+   |                   |                | normally happen automatically at  |
+   |                   |                | appropriate times.                |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | returns the total number of       |
+   |                   |                | references to the data-space      |
+   | "LV_REF"          | local variable | associated with an unsubscripted  |
+   |                   | name (lvn)     | local variable name specified as  |
+   |                   |                | a second expr (for example a      |
+   |                   |                | quoted string).                   |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Truth value showing whether null  |
+   |                   |                | subscripts are permitted in local |
+   | "LVNULLSUBS"      | none           | arrays (1 for "LVNULLSUBS") or    |
+   |                   |                | not (o for "NOLVNULLSUBS"); GT.M  |
+   |                   |                | defaults to 1.                    |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | The current isolation-status of   |
+   |                   |                | the specified global variable     |
+   |                   |                | which must have a leading "^" in  |
+   |                   |                | its specification.                |
+   |                   |                |                                   |
+   |                   |                | This function returns 1 if the    |
+   |                   |                | global has isolation turned off   |
+   |                   |                | (that is, noisolation turned on)  |
+   | "NOISOLATION"     | global         | and 0 otherwise.                  |
+   |                   |                |                                   |
+   |                   |                | By default, all globals will have |
+   |                   |                | isolation turned on, that is, a   |
+   |                   |                | $VIEW command will return 0. The  |
+   |                   |                | isolation-status of a global      |
+   |                   |                |                                   |
+   |                   |                | variable can be turned on and off |
+   |                   |                | by the VIEW "NOISOLATION"         |
+   |                   |                | command.                          |
+   |-------------------+----------------+-----------------------------------|
+   | "REGION"          | gvn            | Name of the region holding the    |
+   |                   |                | given global name.                |
+   |-------------------+----------------+-----------------------------------|
+   | "PATCODE"         | none           | Name of the active patcode table; |
+   |                   |                | GT.M defaults this to "M".        |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Name of the next routine in the   |
+   |                   |                | image after the given one; ""     |
+   | "RTNNEXT"         | routine name   | (empty string) for routinename    |
+   |                   |                | starts with the first routine in  |
+   |                   |                | ASCII collating sequence.         |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Number of bytes in the currently  |
+   |                   |                | allocated as process working      |
+   |                   |                | storage. GT.M manages this space  |
+   |                   |                | as what is commonly called a      |
+   |                   |                | heap, and uses the term           |
+   | "SPSIZE"          | none           | stringpool to refer to it. The    |
+   |                   |                | GT.M garbage collector reclaims   |
+   |                   |                | unused space from the stringpool  |
+   |                   |                | from time to time, and GT.M       |
+   |                   |                | automatically expands the         |
+   |                   |                | stringpool as needed by the       |
+   |                   |                | application program.              |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Returns the GT.M stack size in    |
+   |                   |                | bytes. In VMS, the GT.M stack     |
+   | "STKSIZ"          | none           | size is user settable at image    |
+   |                   |                | startup time by means of the      |
+   |                   |                | USER_STACK_SIZE parameter in      |
+   |                   |                | GTM$DEFAULTS.M64.                 |
+   |-------------------+----------------+-----------------------------------|
+   | "TOTALBLOCKS"     | region         | Total number of database blocks   |
+   |                   |                | in a given region.                |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Transaction ID specified in the   |
+   |                   |                | particular level (when the        |
+   |                   |                | transaction level is specified).  |
+   |                   | NULL           | The first level TSTART is         |
+   |                   |                | returned if the level is not      |
+   |                   | or             | specified as second argument.     |
+   | "TRANSACTIONID"   |                |                                   |
+   |                   | transaction    |   **Note**                      |
+   |                   | level          |                                   |
+   |                   |                | A NULL string is returned if the  |
+   |                   |                | specified level (explicitly or    |
+   |                   |                | implicitly) is greater than the   |
+   |                   |                | current value of $TLEVEL.         |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Truth value showing whether       |
+   |                   |                | undefined variables should be     |
+   | "UNDEF"           | none           | treated as having a null value (1 |
+   |                   |                | for "UNDEF"; 0 for "NOUNDEF");    |
+   |                   |                | GT.M defaults to 0.               |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Integer value showing whether     |
+   |                   |                | four digit year code is active    |
+   |                   |                | for $ZDATE(); GT.M defaults to 0  |
+   | "ZDATE_FORM"      | none           | (for "YY" format). Use the        |
+   |                   |                | environment variable              |
+   |                   |                | gtm_zdate_form to set the initial |
+   |                   |                | value of this factor.             |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Truth value showing whether ISV   |
+   |                   |                | $ZDIR stores the whole path       |
+   |                   |                | (including device specification)  |
+   |                   |                | or just the directory path (0 for |
+   | "ZDIR_FORM"       | none           | $ZDIR storing device              |
+   |                   |                | specification and directory path; |
+   |                   |                | 1 for $ZDIR storing only the      |
+   |                   |                | directory path); GT.M defaults to |
+   |                   |                | 0.                                |
+   +------------------------------------------------------------------------+
+
+   **Important**
+
+   FIS uses the LC_CREF, LV_GCOL, LV_REF keywords in testing and is
+   documenting them to ensure completeness in product documentation. They may
+   (or may not) be useful during application development for debugging or
+   performance testing implementation alternatives.
+
+3 Examples
+   Examples
+
+   Example:
+
+     set len=$length(name)
+     set be4=$extract(name,1,len-1)_$char($ascii(name,len)-1)
+     i $view("RTNNEXT",be4_$extract("ZZZZZZZ",1,8-len))=name do
+     . zlink name
+
+   Given a routine name this uses $VIEW() to determine whether the location
+   contains the routine. If the routine already exists the ZLINK replaces it.
+   Otherwise, auto-ZLINK will bring in a new copy.
+
+   Example:
+
+   GTM>Set a=1,*b(1)=a
+
+   GTM>write $view("LV_CREF","a")," ",$view("LV_CREF","b")
+   1 0
+   GTM>write $view("LV_REF","a")," ",$view("LV_REF","b")
+   2 1
+   GTM>
 
-   For example, the command U $P:CTRAP=$C(26,30,7,19) sets a trap for the
-   ASCII characters <SUB>, <RS>, <BEL> and <DC3>.
+   This example creates an alias variable and an alias container variable and
+   checks the number of both container references and total references to the
+   cells associated with both a and b.
 
-   Specifying CTRAP completely replaces the previous CTRAP  list.  Setting
-   CTRAP to the null string ("") disables character trapping.
+   Example:
 
-   A trap character  enabled  by  CTRAP  produces  one  of  the  following
-   actions:
+   GTM>Set *a(1)=b,*b(1)=a
 
-   o    If an EXCEPTION deviceparameter has been issued for the device, the
-        process executes the EXCEPTION argument.
+   GTM>kill *a,*b
 
-   o    Otherwise, if $ETRAP is not the empty string, execute $ETRAP.
+   GTM>write $view("LV_GCOL")
+   2
+   GTM>
 
-   o    Otherwise, if $ZTRAP is not the empty string, the process executes
-        $ZTRAP.
+   This example creates two cross associated alias containers, destroys their
+   ancestor nodes with KILL * and uses $VIEW("LV_GCOL") to force a clean-up
+   of the abandoned data-spaces. In the absence of the $VIEW("LV_GCOL"), GT.M
+   would do this automatically at some subsequent convenient time.
 
-   o    Otherwise, the GT.M image terminates.
+   Example:
 
-   For more information on error handling, refer to the "Error Processing"
-   chapter in GT.M Programmer's Guide.
+   GTM>write $view("GVSTAT","DEFAULT")
+   SET:203,KIL:12,GET:203,DTA:2,ORD:23,ZPR:21,QRY:0,LKS:0,LKF:0,CTN:44,DRD:103,DWT:
+   59,NTW:24,NTR:55,NBW:27,NBR:138,NR0:0,NR1:0,NR2:0,NR3:0,TTW:17,TTR:5,TRB:0,TBW:3
+   2,TBR:80,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0,ZTR:7
+   GTM>
 
-   When CTRAP includes <CTRL-C>,  [NO]CENABLE  has  no  effect.  CTRAPping
-   <CTRL-C> also takes precedence over CENABLE.
+2 $ZAHandle()
+   $ZAHandle()
 
-4 DELIMITER
-   [NO]DELIMITER Applies to: Socket Device
+   $ZAHANDLE() returns a unique identifier (handle) for the array associated
+   with a name or an alias container; for an subscripted lvn, it returns an
+   empty string. To facilitate debugging, the handle is a printable string
+   representation of a hexadecimal number. The only meaningful operation on
+   the value returned by a call to $ZAHANDLE() is to compare it for equality
+   with the value returned by another call. Changing nodes within the array
+   doesn't change its handle. $ZAHANDLE() returns different results for
+   copies of an array.
 
-   DELIMITER establishes or replaces the list of delimiters  used  by  the
-   sockets associated with the device. The default when the socket device
-   is first OPENed is NODELIMITER. The delimiter  list  on  a  preexisting
-   device remains the same until it is explicitly replaced or deleted.
+   Example:
 
-   expr must be a string of the following format:
+   GTM>set A=1,*B(1)=A
 
-   ':'  is  used  to  separate  delimiters  (it  is  the  delimiter  for
-   delimiters).
+   GTM>write "$zahandle(A)=""",$zahandle(A),""" $zahandle(B(1))=""",$zahandle(B(1)),""""
+   $zahandle(A)="17B8810" $zahandle(B(1))="17B8810"
+   GTM>set A("Subscript")="Value" ; Change array - but $ZAHandle() doesn't change
 
-   '/' serves as an escape character.
+   GTM>write "$zahandle(A)=""",$zahandle(A),""" $zahandle(B(1))=""",$zahandle(B(1)),""""
+   $zahandle(A)="17B8810" $zahandle(B(1))="17B8810"
+   GTM>merge D=A ; A copy of the data has a different $zahandle()
 
-   expr "ab:/:://:bc" is interpreted as four delimiters, which  are  "ab",
-   ":", "/", and "bc". One  socket  can  have  0-64  delimiters  and  each
-   delimiter can contain 1-64 characters.
+   GTM>Write "$ZAHandle(A)=""",$ZAHandle(A),""" $ZAHandle(D)=""",$ZAHandle(D),""""
+   $zahandle(A)="17B8810" $zahandle(D)="17B8C10"
+   GTM>
 
-4 DETACH
-   DETACH=expr Applies to: Socket Device
+   Since GT.M does not provide a way for a function to return an array or
+   alias variable as its result, the uniqueness of $ZAHandle() can be
+   exploited to effect this capability, by placing the result in a local
+   variable with an agreed prefix (e.g., "%") and its $ZAHANDLE() as a
+   suffix. The handle can be returned as the value.
+
+   $ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run retval
+   retval        ; Return an array / object from a function
+       ;;Data for the object array
+       ;;Albert Einstein,14-March-1879
+       ;;Arthur Eddington,28-December-1882
+       ;;
+       zprint    ; Print this program
+       new tmp1,tmp2,tmp3
+       for i=3:1 set tmp1=$text(+i),tmp2=$piece(tmp1,";;",2) quit:'$length(tmp2)  do
+       .set tmp3="%"_$$NewPerson($piece(tmp2,",",1),$piece(tmp2,",",2))
+       .set @("*Relativists("_(i-2)_")="_tmp3)
+       .kill @("*"_tmp3)
+       kill tmp1,tmp2,tmp3
+       write "------------",!
+       write "Array of objects of relativists:",!
+       zwrite
+       quit
+       ;
+   NewPerson(name,birthdate)    ; Create new person object
+       new lname,fname,dob,tmp1,tmp2 ; New variables used by this function
+       set lname=$Piece(name," ",2),fname=$Piece(name," ",1)
+       set dob=$$FUNC^%DATE(birthdate)
+       set tmp1("fname")=fname,tmp1("lname")=lname,tmp1("dob")=dob
+       set tmp2=$ZAHandle(tmp1)
+       set @("*%"_tmp2_"=tmp1")
+       quit tmp2
+   ------------
+   Array of objects of relativists:
+   $ZWRTAC=""
+   *Relativists(1)=$ZWRTAC1
+   $ZWRTAC1("dob")=13952
+   $ZWRTAC1("fname")="Albert"
+   $ZWRTAC1("lname")="Einstein"
+   *Relativists(2)=$ZWRTAC2
+   $ZWRTAC2("dob")=15337
+   $ZWRTAC2("fname")="Arthur"
+   $ZWRTAC2("lname")="Eddington"
+   i=5
+   $ZWRTAC=""
+   $
 
-   Removes the socket identified by expr from the current  socket  device,
-   without affecting any existing connection of that socket.  The  removed
-   socket is placed in the socketpool  and  may  be  attached  to  another
-   socket device. If the socket being removed is the current socket, then
-   GT.M does the following:
+2 $ZBIT_Functions
+   $ZBIT Functions
 
-   o    The socket ATTACHed prior to the removed socket, is  made  current,
-        if one such exists.
+   A series of functions beginning with $ZBIT lets you manipulate a bit
+   stream. Internally, GT.M stores a bit stream in the form of a bit string.
+   A bit string embeds a bit stream in such a way that the first byte
+   specifies the number of trailing bits in the last byte that are not part
+   of the bit-stream. In this way, GT.M is able to store bit-streams of
+   lengths other than multiples of 8 bits in byte format. So for example, a
+   first byte of value of zero (0) indicates that all of the bits in the last
+   byte belong to the bit-stream, while a one (1) indicates the last bit is
+   excluded and a seven (7) indicates that only the first bit in the last
+   byte belongs to the bit-stream.
+
+   If you have to convert a character string into a bit string then add a
+   leading byte to that character string so that all $ZBIT functions can
+   recognize it. The most common and straightforward way of doing this is to
+   concatenate a $CHAR(n) on the front of the character string, where the
+   value of n is zero through seven (0-7) - most commonly zero (0). If you
+   pass a bit string as an argument to a routine that is expecting a
+   character string, then that caller routine must strip off the first (and
+   possibly the last) byte so that it can recognize the character string.
+
+   This section contains the description of all $ZBIT function and an example
+   of using $ZBIT functions to turn a character into a bit stream and return
+   a coded value. However, the most appropriate use of these functions may
+   include the formation of checksums, handling of bit-data (say pixels from
+   a scan), or interfacing with a routine that requires bit-oriented
+   arguments.
 
-   o    The socket ATTACHed after the removed socket, is made  current,  if
-        the removed one was the first socket.
+3 $ZBITAND()
+   $ZBITAND()
 
-   o    $PRINCIPAL is made the current device ($IO), if the removed socket
-        was the only one in the current socket device.
+   Performs a logical AND function on two bit strings and returns a bit
+   string equal in length to the shorter of the two arguments (containing set
+   bits in those positions where both of the input strings have set bits).
+   Positions corresponding to positions where either of the input strings
+   have a cleared bit, also have cleared bits in the resulting string.
 
-4 DOWNSCROLL
-   DOWNSCROLL Applies to: Terminals and Printers
+   The format for the $ZBITAND() function is:
 
-   If $Y=0, DOWNSCROLL  does  nothing.  Otherwise,  DOWNSCROLL  moves  the
-   cursor up one line on the terminal screen and  decrements  $Y  by  one.
-   DOWNSCROLL does not change the column position  or  $X.  Some  terminal
-   hardware may not support DOWNSCROLL.
+   $ZBITAND(expr1,expr2)
 
-4 ECHO
-   [NO]ECHO Applies to: Terminals and Printers
+4 Example_of_$ZBITAND()
+   Example of $ZBITAND()
 
-   Enables or disables terminal device driver echo of input.
+   GTM>
+   ; The binary representation of A is 01000001
+   GTM>Set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
+   ; The binary representation of B is 01000010
 
-   By default, terminal device drivers ECHO.
+   GTM>set BITSTRINGAB=$zbitand(BITSTRINGA,BITSTRINGB)
 
-4 ERASELINE
-   ERASELINE Applies to: Terminals and Printers
+   GTM>for i=1:1:8 write $zbitget(BITSTRINGAB,I)
+   01000000
 
-   Clears the current line from the physical cursor position to the end of
-   the line. ERASELINE does not affect the physical cursor position, or $X
-   and $Y.
+   This examples uses $ZBITAND to perform a bitwise AND operation on A and B.
 
-4 ESCAPE
-   [NO]ESCAPE Applies to: Terminals and Printers
+   A= 01000001
+   B= 01000010
+   A bitwise AND B=0100000
 
-   Enables  or  disables  terminal  device  driver  processing  of  escape
-   sequences.
+3 $ZBITCOUNT()
+   $ZBITCOUNT()
 
-   The following events result  when  a  terminal  has  ESCAPE  sequencing
-   enabled. When an <ESC> or <CSI> arrives  in  the  terminal  input,  the
-   device driver verifies the sequence that follows as a valid ANSI escape
-   sequence, terminates the READ, and  sets  $ZB  to  contain  the  entire
-   escape sequence. In this case, if the sequence starts  with  an  <ESC>,
-   READ * returns the decimal ASCII representation for  the  character  of
-   the escape introducer.
+   Returns the number of ON bits in a bit string.
 
-   When escape processing is disabled, READ *x returns  27  in  x  for  an
-   <ESC>. If the escape introducer is also a TERMINATOR, $ZB has a string
-   of length one (1), and a value of the $ASCII()  representation  of  the
-   escape introducer; otherwise, $ZB holds the empty  string.  For  single
-   character and short fixed reads  with  NOESCAPE,  the  terminal  device
-   driver places the remaining characters of the escape  sequence  in  the
-   input buffer for subsequent READs, regardless of [NO]TYPEAHEAD."
+   The format for the $ZBITCOUNT function is:
 
-4 EXCEPTION
-   EXCEPTION=expr Applies to: All devices
+   $ZBITCOUNT(expr)
 
-   Defines an error handler for an I/O device. The expression must contain
-   a fragment of GT.M code (e.g., GOTO ERRFILE) that GT.M XECUTEs when the
-   driver for the device detects an error, or an entryref  to  which  GT.M
-   transfers control, as appropriate for the current gtm_ztrap_form.
+4 Example_of_$ZBITCOUNT()
+   Example of $ZBITCOUNT()
 
-   For more information on error handling, refer to the "Error Processing"
-   chapter in GT.M Programmer's Guide.
+   Example:
 
-4 FILTER
-   [NO]FILTER[=expr] Applies to: Terminals and  Printers,  Socket  Device,
-   and NULL Device
+   GTM>set BITSTRINGA=$ZBITSET($ZBITSET($ZBITSTR(8,0),2,1),8,1)
+   ; The binary representation of A is 01000001
 
-   Specifies  character  filtering  for  valid  filtering  expressions.
-   Filtering requires character by character examination of all output and
-   reduces I/O performance.
+   GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
+   ; The binary representation of B is 01000010
 
-   Each FILTER  deviceparameter  can  have  only  one  argument.  However,
-   multiple FILTER deviceparameters can appear in a  single  USE  command,
-   each with different arguments.
+   GTM>Set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB)
+   ; A OR B=01000011
 
-   The valid values for expr:
+   GTM>write $zbitcount(BITSTRINGA)
+   2
+   GTM>write $zbitcount(BITSTRINGB)
+   2
+   GTM>write $zbitcount(BITSTRINGC)
+   3
+   GTM>
 
-   [NO]CHARACTERS enables or disables maintenance of $X and  $Y  according
-   to the M ANSI standard for the characters <BS>, <LF>,  <CR>  and  <FF>.
-   CHARACTERS causes the device driver to examine all output for the above
-   characters, and to adjust $X  and  $Y  accordingly.  By  default,  GT.M
-   performs special maintenance on $X and $Y only  for  M  format  control
-   characters, WRAPped records, and certain action deviceparameters.
+   This example displays the number of ON bits in BITSTRINGA, BITSTRINGB, and
+   BITSTRINGC.
 
-   [NO]ESCAPE alters the effect of ANSI escape sequences  on  $X  and  $Y.
-   ESCAPE causes GT.M to filter the  output,  searching  for  ANSI  escape
-   sequences and preventing them from updating $X and $Y. By default, GT.M
-   does not screen output for escape sequences.
+3 $ZBITFIND()
+   $ZBITFIND()
 
-   By default, GT.M  does  not  perform  output  filtering.  For  GT.M  to
-   maintain $X for non-graphic characters as described  by  the  standard,
-   FILTER="CHARACTERS" must be enabled. Output filtering  adds  additional
-   overhead to I/O processing.
+   Performs the analog of $FIND() on a bit string. It returns an integer that
+   identifies the position after the first position equal to a truth-valued
+   expression that occurs at, or after, the specified starting position.
 
-4 HOSTSYNC
-   [NO]HOSTSYNC Applies to: Terminals and Printers
+   The format for the $ZBITFIND function is:
 
-   Enables or disables the use of XON/XOFF by the host to  throttle  input
-   and  prevent  impending  buffer  overruns  for  a  terminal.  This
-   deviceparameter  provides  a  control  mechanism  for  the  host  over
-   asynchronous  communication  lines  to  help  prevent  data  loss  when
-   hardware is slow and/or processing load is high.
+   $ZBITFIND(expr,tvexpr[,intexpr])
 
-   By default, the device driver operates HOSTSYNC.
+   If the optional integer argument exceeds the length of the string, or if
+   the function finds no further bits, $ZBITFIND() returns a zero value.
 
-4 IOERROR
-   IOERROR=expr Applies to: Socket Device
+4 Examples
+   Examples
 
-   Enables exception handling in socket devices. expr  specifies  the  I/O
-   error trapping mode. A value equal to "TRAP" specifies that I/O errors
-   on a device raise error conditions. A value equal to "NOTRAP", or when
-   IOERROR is not specified, indicates that I/O error on a device does not
-   raise error conditions.
+   Example:
 
-        GT.M currently handles exception handling at device  level  instead
-        of socket level.
+   GTM>Set BITSTRINGA=$ZBITSET($ZBITSET($ZBITSTR(8,0),2,1),8,1)
+   ; The binary representation of A is 01000001
 
-4 LENGTH
-   [Z]LENGTH=intexpr Applies to: Terminals and  Printers,  Socket  Device,
-   and NULL Device.
+   GTM>write $zbitfind(BITSTRINGA,1,3)
+   9
+   GTM>
 
-   Sets the  virtual  page  length  for  an  I/O  device  to  the  integer
-   expression. The page length controls the  point  at  which  the  device
-   driver automatically resets $Y to 0.
+   This example searches for bit value 1 starting from the 3rd bit of
+   BITSTRINGA.
 
-   By  default,  GT.M  uses  the  LENGTH  specified  by  the  device
-   characteristics at image activation. The terminal  default  depends  on
-   the type of terminal. The default length for  null  device  and  socket
-   device is 66.
+3 $ZBITGET()
+   $ZBITGET()
 
-4 PASTHRU
-   [NO]PASTHRU Applies to: Terminals and Printers
+   Returns the value of a specified position in the bit string.
 
-   Enables or  disables  interpretation  of  the  ERASE  character  for  a
-   terminal. PASTHRU shifts management of handling and response  to  ERASE
-   characters in the input stream from the driver to the GT.M application
-   code.
+   The format for the $ZBITGET function is:
 
-   Exercise caution with PASTHRU in debugging,  because  using  a  PASTHRU
-   terminal in Direct Mode is somewhat awkward.
+   $ZBITGET(expr,intexpr)
 
-   [NO]TTSYNC must be used with [NO]PASTHRU to control XON/XOFF handling.
+4 Examples
+   Examples
 
-   By default, the device driver operates NOPASTHRU.
+   Example:
 
-4 READSYNC
-   [NO]READSYNC Applies to: Terminals and Printers
 
-   Enables or disables automatic output of <XON> before a READ and <XOFF>
-   after a READ.
+   GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
+   ; The binary representation of A is 01000001
 
-   By default, the terminal drivers operate NOREADSYNC.
+   GTM>for i=1:1:8 write $zbitget(BITSTRINGA,I)
+   01000001
+   GTM>
 
-4 REWIND
-   REWIND Applies to: Sequential Files
+   This examples uses $ZBITGET() to display the binary representation of A.
 
-   REWIND for a disk file is a logical rather than a physical operation.
+3 $ZBITLEN()
+   $ZBITLEN()
 
-   By default, USE does not REWIND.
+   Returns the length of a bit string, in bits.
 
-4 SOCKET
-   SOCKET=expr Applies to: Socket Device
+   The format for the $ZBITLEN function is:
 
-   The socket specified in expr is made the current socket.  Specifying  a
-   socket that has not been previously OPENed generates an error.
+   $ZBITLEN(expr)
 
-        SOCKET is compatible with DELIMITER only.
+4 Examples
+   Examples
 
-4 TERMINATOR
-   [NO]TERMINATOR[=expr] Applies to: Terminals and Printers
+   GTM>set BITSTR=$zbitstr(6,1)
 
-   Specifies which of the 256  ASCII  characters  terminate  a  READ.  For
-   example, TERMINATOR=$C(0) makes <NUL> the terminator.
+   GTM>write $zbitlen(BITSTR)
+   6
+   GTM>
 
-   When [NO]ESCAPE is in effect, TERMINATOR controls whether or not <ESC>
-   or <CSI> are treated as terminators, however, when ESCAPE processing is
-   enabled,  the  entire  escape  sequence  is  treated  as  a  terminator
-   regardless of the TERMINATOR specification.
+   This example displays the length of a bit string of 6 bits.
 
-   NOTERMINATOR eliminates  all  terminators.  When  a  terminal  has  all
-   terminators disabled, fixed length READ and READ * terminate on receipt
-   of some number of characters, and a timed READ terminates  on  timeout,
-   but any other READ only terminates when the input  fills  the  terminal
-   read buffer.
+3 $ZBITNOT()
+   $ZBITNOT()
 
-   By default, terminals recognize <CR> and <ESC> as  terminators,  (i.e.,
-   TERMINATOR=$C(13,27)). TERMINATOR=""  restores  the  default.  However,
-   unless the terminal has PASTHRU, the operating system  interprets  some
-   escape sequences rather than passing them to the READ.
+   Returns a copy of the bit string with each input bit position inverted.
 
-   Example:
+   The format for the $ZBITNOT function is:
 
-   GTM> USE $P:TERM=$C(26,13,11,7)
+   $ZBITNOT(expr)
 
-   This example enables the ASCII characters <SUB>, <CR>, <VT>  and  <BEL>
-   as READ terminators.
+4 Examples
+   Examples
 
-4 TRUNCATE
-   [NO]TRUNCATE Applies to: Sequential Files
+   GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
+   ; The binary representation of A is 01000001
 
-   Enables or disables overwriting of existing data in  sequential  files.
-   Because the position of each record depends  on  the  prior  record,  a
-   WRITE destroys the ability to reliably position to  subsequent  records
-   in a file. Therefore, by default (NOTRUNCATE), GT.M permits WRITEs only
-   when the file pointer is positioned at the end-of-file. When  a  device
-   has TRUNCATE enabled, a WRITE issued when the file pointer  is  not  at
-   end-of-file truncates the file by destroying all  data  from  the  file
-   pointer to the end-of-file.
+   GTM>for i=1:1:8 write $zbitget($zbitnot(BITSTRINGA),I)
+   10111110
+   GTM>
 
-   By default, OPEN  accesses  files  NOTRUNCATE,  which  does  not  allow
-   overwriting of sequential files.
+   This example displays inverted bits for all the bits in BITSTRINGA.
 
-   This deviceparameter may not be supported by your platform.
+3 $ZBITOR()
+   $ZBITOR()
 
-4 TTSYNC
-   [NO]TTSYNC Applies to: Terminals and Printers
+   Performs a bitwise logical OR on two bit strings, and returns a bit string
+   equal in length to the longer of the two arguments (containing set bits in
+   those positions where either or both of the input strings have set bits).
+   Positions that correspond to positions where neither input string has a
+   set bit have cleared bits in the resulting string.
 
-        Enables or disables recognition of XON/XOFF for terminal output. A
-        terminal may have its own handling of  XON/XOFF,  controlled  by  a
-        set-up mode or by switches.  If  an  application  requires  program
-        recognition of <CTRL-S> and <CTRL-Q>,  the  terminals  may  require
-        reconfiguration.
+   The format for the $ZBITOR function is:
 
-4 TYPEAHEAD
-   [NO]TYPEAHEAD Applies to: Terminals and Printers
+   $ZBITOR(expr1,expr2)
 
-   Enables  or  disables  type-ahead  buffering  for  a  terminal.  With
-   NOTYPEAHEAD  and  no  outstanding  READ,  the  terminal  device  driver
-   discards  input  entered  at  the  terminal.  With  TYPEAHEAD  and  no
-   outstanding READ,  the  device  driver  stores  input  entered  at  the
-   terminal in a type-ahead buffer. The device driver uses data  from  the
-   type-ahead buffer for subsequent READs.
+4 Examples
+   Examples
 
-   The size of the type-ahead buffer limits the amount of data entered at
-   the terminal that the device driver can store in anticipation of future
-   READs.
+   GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
+   ; The binary representation of A is 01000001
 
-   By default, the terminal device driver accepts TYPEAHEAD.
+   GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
+   ; The binary representation of B is 01000010
 
-4 UPSCROLL
-   UPSCROLL Applies to: Terminals and Printers
+   GTM>set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB)
+   ; A OR B=01000011
 
-   Moves the cursor down one line on the terminal screen. If $Y=LENGTH-1,
-   UPSCROLL sets $Y=0. Otherwise UPSCROLL increments $Y  by  one.  If  the
-   cursor is physically at the bottom of the page, the screen  scrolls  up
-   one line. UPSCROLL does not change the column position or $X.
+   GTM>write BITSTRINGC
+   C
+   GTM>
 
-4 WIDTH
-   [Z]WIDTH=intexpr Applies to: Terminals  and  Printers,  Socket  Device,
-   NULL Device, and Sequential Files
+   This example displays the result of BITSTRINGA bitwise ORed with
+   BITSTRINGB.
 
-   Sets the device's logical record size and enables WRAP.
+3 $ZBITSET()
+   $ZBITSET()
 
-   NOWRAP and WIDTH supersede each other. When  WIDTH  and  NOWRAP  appear
-   together on the same USE command, the final  one  controls  the  device
-   behavior. For a terminal,  WIDTH=0  is  equivalent  to  WIDTH=n:NOWRAP,
-   where n is the default length of a logical record on that terminal.
+   Returns an edited copy of the input bit string with a specified bit set to
+   the value of the truth-valued expression.
 
-   Terminals inherit their default WIDTH in GT.M from the  invoking  shell
-   environment. The default WIDTH for null and socket device is 255.
+   The format for the $ZBITSET function is:
 
-4 WRAP
-   [Z][NO]WRAP Applies to: Terminals and Printers,  FIFO,  Socket  Device,
-   NULL Device, and Sequential Files
+   $ZBITSET(expr,intexpr,tvexpr)
 
-   Enables or disables automatic  record  termination.  When  the  current
-   record size ($X) reaches the maximum WIDTH  and  the  device  has  WRAP
-   enabled, GT.M starts a new record, as if the routine had issued a WRITE
-   ! command.
+4 Examples
+   Examples
 
-   NOWRAP causes GT.M to require a WRITE ! to terminate the record. NOWRAP
-   allows $X to become greater than the device WIDTH for terminals.
+   GTM>set X="A",Y=$extract($zbitset($char(0)_X,3,1),2) zwrite
+   X="A"
+   Y="a"
 
-   By default, WIDTH sets WRAP. When WIDTH and NOWRAP appear  together  on
-   the same USE command, the last one controls the device behavior.
+   This example changes the case of the ASCII letter A to the corresponding
+   lowercase version.
 
-   By default, records WRAP.
+3 $ZBITSTR()
+   $ZBITSTR()
 
-4 X
-   X=intexpr Applies to: Terminals and Printers
+   Returns a bit string of a specified length with all bit positions
+   initially set to either zero or one.
 
-   $X positions the cursor to a vertical column on the terminal. If NOWRAP
-   is  enabled  or  intexpr<WIDTH,  the  terminal  device  driver  sets
-   $X=intexpr.  If  WRAP  is  enabled  and  intexpr>WIDTH,  GT.M  sets
-   $X=intexpr#WIDTH, where # is the GT.M modulo operator. The resulting $X
-   determines the actual physical position.
+   The format for the $ZBITSTR function is:
 
-   To ensure that $Y and $X  match  what  is  occurring  visually  on  the
-   terminal, the GT.M deviceparameters and the device characteristics must
-   match at all times. For example, if a process  initiates  a  subprocess
-   that changes the terminal wrap  setting  from  NOWRAP,  to  WRAP,  GT.M
-   returns to the NOWRAP condition  when  the  subprocess  completes,  and
-   wraps on the terminal do not reflect in the values of $X and $Y.
+   $ZBITSTR(intexpr[,tvexpr])
 
-   The terminal hardware may affect physical  cursor  positioning.  The  X
-   deviceparameter does not change the cursor row or update $Y.
+4 Examples
+   Examples
 
-4 Y
-   Y=intexpr Applies to: Terminals and Printers
+   GTM>set BITSTR=$zbitstr(6,1)
 
-   Positions the cursor to a horizontal row on the terminal.
+   This example sets the value of expression BITSTR to 6 bit with all bits
+   set to 1.
 
-   The terminal device driver sets $Y=intexpr#LENGTH, where # is the GT.M
-   modulo operator. If intexpr<LENGTH, the  resulting  $Y  determines  the
-   physical position. If intexpr>LENGTH, the cursor is positioned so that
-   $Y=intexpr#LENGTH, where # is the GT.M module  operator.  The  terminal
-   hardware may affect physical cursor positioning.
+3 $ZBITXOR()
+   $ZBITXOR()
 
-   To ensure that $Y and $X  match  what  is  occurring  visually  on  the
-   terminal, the GT.M deviceparameters and the device characteristics must
-   match at all times. For example, if a process  initiates  a  subprocess
-   that changes the terminal wrap setting from NOWRAP, previously set with
-   the GT.M USE command to WRAP, GT.M does not reflect the change when the
-   subprocess completes. Therefore, wraps on the terminal do  not  reflect
-   in the values of $X and $Y.
+   Performs a bitwise exclusive OR on two bit strings, and returns a bit
+   string equal in length to the shorter of the two arguments (containing set
+   bits in those position where either but not both of the input strings have
+   set bits). Positions that correspond to positions where neither or both
+   input string has a set bit have cleared bits in the resulting string.
 
-   The Y deviceparameter does not change the cursor column or update $X.
+   The format for the $ZBITXOR function is:
 
-4 ZBFSIZE
-   ZBFSIZE Applies to: Socket Device
+   $ZBITXOR(expr1,expr2)
 
-   Allocates a buffer used by GT.M when reading from a socket. The ZBFSIZE
-   deviceparameter should be at  least  as  big  as  the  largest  message
-   expected.
+4 Examples
+   Examples
 
-   By default, the size of ZBFSIZE is 1024 and the maximum it  can  be  is
-   1048576.
+   GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1) ; The binary representation of A is 01000001
 
-4 ZDELAY
-   Z[NO]DELAY Applies to: Socket Device
+   GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1); The binary representation of B is 01000010
 
-   Controls buffering of data packets by the system TCP  stack  using  the
-   TCP_NODELAY option to the SETSOCKOPT  system  call.  This  behavior  is
-   sometimes known as the Nagle algorithm. The  default  is  ZDELAY.  This
-   delays sending additional packets until either  an  acknowledgement  of
-   previous packets is received or an interval passes. If several packets
-   are sent from one end of a connection before the  other  end  responds,
-   setting ZNODELAY may be desirable though  at  the  cost  of  additional
-   packets being transmitted over the  network.  ZNODELAY  must  be  fully
-   spelled out.
+   GTM>set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB) ; A XOR B=00000011
 
-4 ZFF
-   Z[NO]FF=expr Applies to: Socket Device
+   GTM>for I=1:1:8 write $zbitget(BITSTRINGC,I)
+   00000011
+   GTM>
 
-   expr specifies a string of characters, typically in $CHAR()  format  to
-   send to socket device, whenever a routine issues a  WRITE  #.  When  no
-   string is specified or when ZFF="", then no characters  are  sent.  The
-   default in GT.M is ZNOFF.
+   This example displays the result of the bitwise XOR of A and B.
 
-4 ZIBFSIZE
-   ZIBFSIZE Applies to: Socket Device
+3 Examples
+   Examples
 
-   Sets  the  buffer  size  used  by  the  network  software  (setsockopt
-   SO_RCVBUF).
+   Example:
 
-   The default and the maximum values depend on the platform and/or system
-   parameters.
+   ZCRC(X)
+       new R,I,J,B,X1,K
+       set R=$zbitstr(8,0)
+       for I=1:1:$length(X) Set R=$zbitxor(R,$$bitin($A(X,I)))
+       quit $$bitout(R)
 
-4 ZLISTEN
-   ZLISTEN=expr Applies to: Socket Device
+   bitin(X) ;CONVERT A BYTE TO A BIT STRING
+       set X1=$zbitstr(8,0)
+       for J=1:1:8 set B=X#2,X=X\2 if B set X1=$zbitset(X1,J,1)
+       quit X1
 
-   A new socket is allocated to listen for a connection. It  is  made  the
-   current socket for the device, if the  operation  is  successful.  Upon
-   successful completion, $KEY is set to the format of
-   "BOUND|<socket handle>|<port number>"
+   bitout(X) ; CONVERT A BITSTRING TO A NUMBER
+       set X1=0
+       for K=1:1:8 I $zbitget(X,K) set X1=X1+(2**(K-1))
+       quit X1
 
-   otherwise, $KEY is assigned the empty string.
+   This uses several $ZBIT functions to turn a character into a bit stream
+   and return a coded value.
 
-   expr  specifies  the  protocol  and  protocol  specific  information.
-   Currently, TCP/IP is the only protocol GT.M supports. expr must  be  of
-   the format "<port>:TCP", where port specifies the port number at which
-   the socket is waiting for a connection.
+   While this example illustrates the use of several of the $ZBIT functions,
+   the following example produces identical results if you need to code the
+   function illustrated above for production.
 
-2 Read
-   Read
+   ZCRC(X)
+       new R,I,J,B,X1,K
+       set R=$zbitstr(8,0)
+       for I=1:1:$length(X) Set R=$zbitxor(R,$char(0)_$extract(X,I))
+       quit $ascii(R,2)
 
-   The READ command transfers input from the current device to a global or
-   local variable specified as a READ argument. For convenience, READ also
-   accepts arguments that perform limited output to the current device.
+   This example illustrates the use of $Char() to specify the number of
+   invalid bits that exist at the end of the character string. In this case
+   there are zero invalid bits.
 
-   The format of the READ command is:
+2 $ZAscii()
+   $ZAscii()
 
-   R[EAD][:tvexpr] glvn|*glvn|glvn#intexpr|strlit|fcc[,...]
+   Returns the numeric byte value (0 through 255) of a given sequence of
+   octets (8-bit bytes).
 
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
+   The format for the $ASCII function is:
 
-   o    A subscripted  or  unsubscripted  global  or  local  variable  name
-        specifies a variable into which to store the  input;  the  variable
-        does not have to exist prior to the  READ;  if  the  variable  does
-        exist prior to the READ, the READ replaces its old value.
+   $ZA[SCII](expr[,intexpr])
 
-   o    When an asterisk (*) immediately precedes the variable  name,  READ
-        accepts one character of input and places the ASCII code  for  that
-        character in the variable.
+3 Examples
+   Examples
 
-   o    When  a  number  sign  (#)  and  a  non-zero  integer  expression
-        immediately  follow  the  variable  name,  the  integer  expression
-        determines the maximum number of characters accepted  as  input  to
-        the read; such reads  terminate  when  GT.M  reads  the  number  of
-        characters specified by the integer expression or a  terminator  in
-        the input stream, whichever occurs first.
+   Example:
 
-   o    To provide a concise means of issuing prompts,  GT.M  sends  string
-        literal and format control character (!,?intexpr,#) arguments of a
-        READ to the current device as if they were arguments of a WRITE.
+   GTM>for i=0:1:4 write !,$zascii("*",i)
 
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more READ arguments form a legal argument for a READ.
+   -1
+   228
+   184
+   187
+   -1
+   GTM>
 
-   The maximum length of the input string is the  smaller  of  the  device
-   buffer size limitation  or  the  GT.M  maximum  string  length  (32,767
-   characters). If a record is longer than the maximum record length, GT.M
-   returns the record piece by piece during sequential reads, for devices
-   that allow it.
+   This UTF-8 mode example displays the result of $ZASCII() specifying a byte
+   position before, first, second and third positions, and after the sequence
+   of octets (8-bit bytes) represented by *. In the above example, 228, 184,
+   and 187 represents the numeric byte value of the three-byte in the
+   sequence of octets (8-bit bytes) represented by *.
 
-   When a string literal appears as an argument to a READ,  M  writes  the
-   literal to the current device. String literals appear as READ arguments
-   to serve  as  prompts  for  input.  GT.M  does  not  permit  expression
-   arguments on a READ to act as prompts. Variable prompts must appear as
-   arguments to a WRITE. If a variable appears as an argument to  a  READ,
-   GT.M always interprets it as input, never as output. This  facility  is
-   used mostly with terminal I/O.
+2 $ZCHar()
+   $ZCHar()
 
-   The READ commands adjust $X and $Y, based on the length  of  the  input
-   read.
+   Returns a string composed of bytes represented by the integer octet values
+   specified in its argument(s).
 
-3 Read_Comm
-   READ * Command
+   The format for the $ZCHAR() function is:
 
-   The READ * command reads one character  from  the  current  device  and
-   returns the decimal ASCII representation of  that  character  into  the
-   variable specified  for  the  READ  *  command.  READ  *  appears  most
-   frequently in communication protocols, or in interactive programs where
-   single character answers are appropriate.
+   $ZCH[AR](intexpr[,...])
 
-   The following example reads the value  "A",  and  returns  the  decimal
-   ASCII representation of "A" in the variable X.
+3 Example_of_$ZCHAR()
+   Example of $ZCHAR()
 
    Example:
 
-   GTM> READ *X
-
-   A
+   GTM>write $zchar(228,184,187,7)
+   *
+   GTM>
 
-   GTM> WRITE X
+   This example WRITEs the byte sequence represented by * and signals the
+   terminal bell.
 
-   65
-   If a timeout occurs before GT.M reads a character, the READ * returns a
-   negative one (-1) in the variable.
+2 $ZCOnvert()
+   $ZCOnvert()
 
-3 Read_maxlen_Comm
-   READ X#maxlen Command
+   Returns its first argument as a string converted to a different encoding.
+   The two argument form changes the encoding for case within a character
+   set. The three argument form changes the encoding scheme.
 
-   The READ X#maxlen command limits the maximum size of  the  input  to  a
-   maximum of "maxlen" characters, where maxlen is an integer expression.
+   The format for the $ZCONVERT() function is:
 
-   If a READ follows  a  READ  X#maxlen  command,  the  READ  returns  the
-   remainder of the current record.
+   $ZCO[NVERT](expr1, expr2,[expr3])
 
-   If a terminator arrives before maxlen characters are received the READ
-   X#maxlen terminates.
+   **Note**
 
-2 Write
-   Write
+   When UTF-8 mode is enabled, GT.M uses the ICU Library to perform case
+   conversion. As mentioned in the Theory of Operation section, the case
+   conversion of the strings occurs according to Unicode code-point values.
+   This may not be the linguistically or culturally correct case conversion,
+   for example, of the names in the telephone directories. Therefore,
+   application developers must ensure that the actual case conversion is
+   linguistically and culturally correct for their specific needs. The
+   two-argument form of the $ZCONVERT() function in M mode does not use the
+   ICU Library to perform operation related to the case conversion of the
+   strings.
 
-   The WRITE  command  transfers  a  character  stream  specified  by  its
-   arguments to the current device.
+3 Examples
+   Examples
 
-   The format of the WRITE command is:
+   Example:
 
-   W[RITE][:tvexpr] expr|*intexpr|fcc[,...]
+   GTM>write $zconvert("Happy New Year","U")
+   HAPPY NEW YEAR
 
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
-
-   o    An expression argument supplies the text of a WRITE.
-
-   o    When a WRITE argument consists of a leading asterisk  (*)  followed
-        by an integer expression, WRITE outputs  one  character  associated
-        with the ASCII code specified by  the  integer  evaluation  of  the
-        expression.
-
-   o    WRITE also accepts format control characters as  arguments;  format
-        control characters modify the position  of  a  virtual  cursor:  an
-        exclamation  point  (!)  produces  the  device  specific  record
-        terminator (for example, new line for a terminal),  a  number  sign
-        (#) produces device specific page  terminator  (for  example,  form
-        feed for a terminal)  and  a  question  mark  (?)  followed  by  an
-        expression moves the virtual cursor to the column specified by the
-        integer evaluation of the expression if the virtual  cursor  is  to
-        the "left" of the specified column.
-
-   o    When directed to a device bound  to  a  mnemonicspace,  WRITE  also
-        accepts  controlmnemonics,  which  are  keywords  specific  to  the
-        binding - they are delimited by a slash (/) prefix  and  optionally
-        followed by a parenthetical list of arguments. The  parentheses  "(
-        )" are optional when there are no arguments, but must  appear  even
-        if there is a single argument
-
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more WRITE arguments form a legal argument for a WRITE.
-
-   GT.M can write up to 32,767 bytes (the GT.M maximum string length) as a
-   result of a single WRITE argument. GT.M buffers output into a "logical
-   record"  for  all  devices  except  sockets  without  DELIMITERs  and
-   sequential devices with STREAM enabled. The  WRITE  command  appends  a
-   string to the current record of the current device. GT.M does not write
-   to the output device until the buffer is full, a  GT.M  format  control
-   character forces a write, a USE  command,  a  CLOSE  command,  or,  for
-   terminals, the buffer becomes stale.
-
-   Each device has a WIDTH and a LENGTH that define  the  virtual  "page".
-   The WIDTH determines the maximum size of a record for a  device,  while
-   the LENGTH determines how many records fit on a page. When the current
-   record size ($X) reaches the maximum WIDTH  and  the  device  has  WRAP
-   enabled, GT.M starts a new record. When the current line  ($Y)  reaches
-   the maximum LENGTH, GT.M starts a new page.
-
-   A WRITE with an asterisk preceding the argument, which it would expect
-   to  be  a  decimal  ASCII  representation,  writes  the  character
-   corresponding to the ASCII representation. The WRITE command  also  has
-   several format control characters that allow the  manipulation  of  the
-   virtual cursor. For all I/O devices, the GT.M format control characters
-   do the following:
-
-        WRITE ! Clears $X and increments  $Y  and  terminates  the  logical
-        record in progress. The definition of "logical record" varies from
-        device to device, and is discussed in each device section.
-        WRITE # Clears $X and $Y  and  terminates  the  logical  record  in
-        progress.
-        WRITE ?n If n is greater than $X, writes n-$X spaces to the device,
-        bringing $X to n. If n is less than or equal to $X, WRITE ?n has no
-        effect. When WRAP is enabled and n exceeds the LENGTH of the line,
-        WRITE ?n increments $Y.
-   For more information, refer to the sections on specific I/O devices.
+   Example:
 
-2 Close
-   Close
+   GTM>write $ZCHSET
+   M
+   GTM>Write $zconvert("HAPPY NEW YEAR","T")
+   %GTM-E-BADCASECODE, T is not a valid case conversion code
 
-   The CLOSE command breaks the connection between a process and a device.
+   Example:
 
-   The format of the CLOSE command is:
+   GTM>Set T8="************"
+   GTM>Write $Length(T8)
+   12
+   GTM>Set T16=$zconvert(T8,"UTF-8","UTF-16LE")
 
-   C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
+   GTM>Write $length(T16)
+   %GTM-E-BADCHAR, $ZCHAR(129,137,232,150) is not a valid character in the UTF-8 encoding form
+   GTM>Set T16=$ZCOnvert(T16,"UTF-16LE","UTF-8")
 
-   o    The optional  truth-valued  expression  immediately  following  the
-        command is a command postconditional that controls whether  or  not
-        GT.M executes the command.
+   GTM>Write $length(T16)
+   9
 
-   o    The required expression specifies the device to CLOSE.
+   In the above example, $LENGTH() function triggers an error because it
+   takes only UTF-8 encoding strings as the argument.
 
-   o    The optional keywords specify deviceparameters that control device
-        behavior; some deviceparameters  take  arguments  delimited  by  an
-        equal sign (=); if there  is  only  one  keyword,  the  surrounding
-        parentheses are optional.
+2 $ZDATA()
+   $ZDATA()
 
-   o    An indirection operator and an expression atom evaluating to a list
-        of one or more CLOSE arguments form a legal argument for a CLOSE.
+   Extends $DATA() to reflects the current alias state of the lvn or name
+   argument to identify alias and alias container variables. It treats
+   variables joined through pass-by-reference as well as TP RESTART variables
+   within a transaction as alias variables. However, it does not distinguish
+   nodes having alias containers among their descendants.
 
-   When a CLOSE is issued, GT.M flushes all pending output to the device,
-   and processes any deviceparameters. CLOSEing  a  device  not  currently
-   OPEN has no effect.
+   In addition to the four standard M results from $DATA(), $ZDATA() returns:
 
-   GT.M  retains  the  characteristics  of  all  device  types,  except  a
-   sequential file, for use in case of subsequent re-OPENs. If the device
-   is a sequential file, characteristics  controlled  by  deviceparameters
-   are lost after the CLOSE.
+   Existing $DATA() tests for data and descendants report on alias and alias
+   container variables, as well as other variables in the standard fashion.
+   When an application uses alias and alias container variables $ZDATA()
+   supplies additional information when needed.
 
-   If the device being CLOSEd is $IO,  GT.M  implicitly  USEs  $PRINCIPAL.
-   GT.M ignores CLOSE $PRINCIPAL.
+3 Examples
+   Examples
 
    Example:
 
-   CLOSE SD:RENAME=SD_".SAV"
+   GTM>set a=1,*b(1)=a,*c=d
+   GTM>write $data(a)," ",$zdata(a)
+   1 101
+   GTM>write $data(b)," ",$zdata(b)
+   10 10
+   GTM>write $data(c)," ",$zdata(c)
+   0 100
+   GTM>write $data(d)," ",$zdata(d)
+   0 100
+   GTM>write $data(b(1))," ",$zdata(b(1))
+   1 101
+   GTM>set b(1,2)=2
+
+   GTM>write $data(b(1))," ",$zdata(b(1))
+   11 111
+   GTM>write $data(b(1,2))," ",$zdata(b(1,2))
+   1 1
+   GTM>
 
-   This closes the device and, if it is a disk file, renames  it  to  have
-   the type .SAV.
+2 $ZDate()
+   $ZDate()
 
-3 Close_DeviParam
-   CLOSE Deviceparamenter
+   Returns a date and/or time formatted as text based on an argument
+   formatted in the manner of $HOROLOG.
 
-4 DELETE
-   DELETE Applies to: Sequential Files, and FIFO
+   The format for the $ZDATE function is:
 
-   Instructs GT.M to delete the current version of  the  disk  file  after
-   GT.M closes it.
+   $ZD[ATE](expr1[,expr2[,expr3[,expr4]]]])
 
-4 EXCEPTION
-   EXCEPTION=expr Applies to: All devices
+   $ZDATE() provides an easy and flexible tool for putting M internal
+   date/time ($HOROLOG) formats into more user-friendly formats.
 
-   Defines an error handler for an I/O device. The expression must contain
-   a fragment of GT.M code (for example, GOTO ERRFILE) that  GT.M  XECUTEs
-   when the driver for the device detects an  error,  or  an  entryref  to
-   which  GT.M  transfers  control,  as  appropriate  for  the  current
-   gtm_ztrap_form.
+   **Warning**
+
+   $ZDATE() generates an error for input date values greater than
+   31-Dec-999999 (364570088) or less than 01-JAN-1840 (-365) and for time
+   values greater than a second before midnight (86399) or less than 0
+   (zero).
+
+   The Intrinsic Special Variable $ZDATEFORM determines the output format for
+   years. The default value is zero (0), in which case $ZDATE() with one
+   argument (no format specification) uses a "YY" (two digit) format for all
+   years. If $ZDATEFORM is one (1), a "YYYY" (four digit) format is used for
+   years later than 1999. For all other values of $ZDATEFORM, "YYYY" (four
+   digit) format is used for all years. $ZDATEFORM does not affect $ZDATE()
+   when the format argument is specified.
+
+   The following table summarizes the usage of $ZDATE() when only first
+   argument is specified.
+
+   +------------------------------------------------------------------------+
+   | Value of $ZDATEFORM |              $ZDATE() Output Format              |
+   |---------------------+--------------------------------------------------|
+   | 0                   | 2 digits                                         |
+   |---------------------+--------------------------------------------------|
+   |                     | 4 digits for years 2000 and after                |
+   | 1                   |                                                  |
+   |                     | 2 digits otherwise (for years ranging between    |
+   |                     | 1840, 1999)                                      |
+   |---------------------+--------------------------------------------------|
+   | other               | 4 digits                                         |
+   +------------------------------------------------------------------------+
+
+3 $ZDATE_Format_Specification_Elements
+   $ZDATE Format Specification Elements
 
-   For more information on error handling, refer to the "Error Processing"
-   chapter in GT.M Programmer's Guide.
+   This section lists the $ZDATE format specification elements. $ZDATE()
+   format specifications must appear in upper case. When any alphabetic
+   characters in format specifications are in lower case, $ZDATE() generates
+   a run-time error.
 
-4 GROUP
-   GROUP=expr Applies to: Sequential Disk Files, and FIFO
+   YY: Outputs the rightmost two digits of the year.
 
-   Specifies access permission on a UNIX file for other users in the file
-   owner's group. The expression is a character string evaluating to null
-   or to any combination of the letters RWX, indicating respectively Read,
-   Write, and eXecute access.  When  any  one  of  these  deviceparameters
-   appears on a CLOSE of a  new  file,  any  user  category  that  is  not
-   explicitly specified is given the default character  string.  When  any
-   one of these deviceparameters appears on a CLOSE of an  existing  file,
-   any user category  (OWNER,  SYSTEM,  WORLD),  that  is  not  explicitly
-   specified remains unchanged.
+   YEAR: Outputs the year as a four-digit number.
 
-   In order to modify file security, the user who issues  the  CLOSE  must
-   have ownership.
+   YYYYYY: Outputs the year as a six-digit number.
 
-   By default, CLOSE does not modify the permissions on an existing file.
+   MM: Outputs the month as a two-digit zero-filled number between 01 and 12.
 
-4 OWNER
-   OWNER=expr Applies to: Sequential Disk Files, and FIFO
+   MON: Outputs the month as a three-letter abbreviation. (You can modify the
+   output further using expr3).
 
-   Specifies access permission on a UNIX file for the owner of  the  file.
-   The expression is a character string  evaluating  to  null  or  to  any
-   combination of the letters RWX, indicating  respectively  Read,  Write,
-   and eXecute access. When any one of these deviceparameters appears on a
-   CLOSE of a new file, any user category that is not explicitly specified
-   is given the default mask.  When  any  one  of  these  deviceparameters
-   appears on a CLOSE of an  existing  file,  any  user  category  (GROUP,
-   SYSTEM, WORLD), that is not explicitly specified remains unchanged.
+   DD: Outputs the day of the month as a two-digit zero-filled number between
+   01 and 31.
 
-   In order to modify file security, the user who issues  the  CLOSE  must
-   have ownership.
+   DAY: Outputs the day of the week as a three-letter abbreviation. (You can
+   modify the output further using expr4).
 
-   By default, CLOSE does not modify the permissions on an existing file.
+   24: Outputs the hour of the day as a zero-filled number between 00 and 23.
 
-4 RENAME
-   RENAME=expr Applies to: Sequential Disk Files
+   12: Outputs the hour of the day as a zero-filled number between 01 and 12.
 
-   Changes the file name to the name contained  in  the  argument  string.
-   When the expression omits part of the  pathname,  GT.M  constructs  the
-   full pathname by applying the defaults  discussed  in  the  section  on
-   device specifications.
+   60: Outputs the minute of the hour as a zero-filled number between 00 and
+   59.
 
-   If the process has sufficient access permissions, it may use RENAME to
-   specify a different directory as well as file name. RENAME cannot move
-   a file to a different device.
+   SS: Outputs the second of the minute as a zero-filled number between 00
+   and 59.
 
-4 SOCKET
-   SOCKET=expr Applies to: Socket Device
+   AM: Outputs the letters AM and PM depending on the time.
 
-   The socket specified in expr is closed. Specifying a  socket  that  has
-   not  been  previously  OPENed  generates  an  error.  If  no  SOCKET
-   deviceparameter is specified on a CLOSE for a socket device, the socket
-   device and all sockets associated with it are closed.
+   +: Inserts a plus sign (+) in the output string
 
-4 SYSTEM
-   SYSTEM=expr Applies to: Sequential Disk Files, and FIFO
+   -: Inserts a minus sign (-) in the output string.
 
-   This deviceparameter is a synonym for OWNER that is maintained in UNIX
-   for compatibility with VMS applications.
+   .: Inserts a period (.) in the output string.
 
-   By default, CLOSE does not modify the permissions on an existing file.
+   ,: Inserts a comma (,)in the output string.
 
-4 UIC
-   UIC=exprgroup number Applies to: Sequential Disk Files, and FIFO
+   /: Inserts a slash (/) in the output string.
 
-   Specifies the group that has access to the  file.  The  format  of  the
-   string is "g,i" where g is a  decimal  number  representing  the  group
-   portion of  the  UIC  and  i  is  a  decimal  number  representing  the
-   individual portion. A process with the VMS privilege CMKRNL may set the
-   file UIC to a UIC other than the UIC under which it is running, thereby
-   giving ownership of the file to another user.
+   :: Inserts a colon (:) in the output string.
 
-   Specifies the owner and affects access  to  the  file.  The  expression
-   evaluates to the numeric identifier of the new owner.
+   ;: Inserts a semi-colon (;) in the output string.
 
-4 WORLD
-   WORLD=expr Applies to: Sequential Disk Files, and FIFO
+   *: Inserts an asterisk (*) in the output string.
 
-   Specifies access permissions for users not in the owner's  group  on  a
-   UNIX file. The expression is a character string evaluating to  null  or
-   to any combination of the letters RWX,  indicating  respectively  Read,
-   Write, and eXecute access.  When  any  one  of  these  deviceparameters
-   appears on a CLOSE of a  new  file,  any  user  category  that  is  not
-   explicitly specified is given the default character  string.  When  any
-   one of these deviceparameters appears on a CLOSE of an  existing  file,
-   any user category  (OWNER,  GROUP,  SYSTEM),  that  is  not  explicitly
-   specified remains unchanged.
+   **Note**
 
-   In order to modify file security, the user who issues  the  CLOSE  must
-   have ownership.
-
-   By default, CLOSE and  CLOSE  do  not  modify  the  permissions  on  an
-   existing file. Unless otherwise specified, when  CLOSE  creates  a  new
-   file, it establishes security using standard defaulting rules.
+   A blank space inserts a blank space in the output string.
 
-   In order to modify file security, the user who issues  the  CLOSE  must
-   have ownership.
+3 Examples
+   Examples
 
-   By default, CLOSE does not modify the permissions on an existing file.
+   Example:
 
-1 M_Utility_Rtns
-   M Utility Routines
-
-   GT.M provides library utilities to perform frequently used  tasks,  and
-   to access frequently used information. Most of the  utilities  are  for
-   GT.M programmers, but some provide tools for system administration and
-   operation.
+   GTM>write $horolog,!,$zdate($H)
+   62109,60946
+   01/18/11
+   GTM>
 
-   The GT.M utilities fall into the following general categories:
+   This displays $HOROLOG and then uses $ZDATE() to display today's date. The
+   output shown would appear if today were the eighteenth day of January,
+   2011.
 
-   o    Date and time utilities
+   Example:
 
-   o    Conversion utilities
+   GTM>write $zdate($H,"DD-MON-YEAR")
+   18-JAN-2011
+   GTM>
 
-   o    Mathematic utilities
+   This uses the second argument to specify a text format different from the
+   default.
 
-   o    Global utilities
+   Example:
 
-   o    Routine utilities
+   GTM>set m="Januar,Februar,Marz,April,Mai,Juni,Juli,August,"
+   GTM>set m=m_"September,October,November,Dezember"
+   GTM>write $zdate($horolog,"DD-MON-YEAR",m)
+   18-Januar-2011
+   GTM>
 
-   o    Internationalization utilities
+   This is similar to the prior example, however it uses the third argument
+   to specify the months in German.
 
-   o    System Management utilities
+   Example:
 
-   The GT.M distribution includes the source files  for  these  utilities.
-   The default installation compiles them to produce object modules in the
-   $gtm_dist distribution library.
+   GTM>set d="Dimanche,Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi"
+   GTM>write $zdate($H,"DAY, DD/MM/YY","",d)
+   Mardi, 18/01/2011
+   GTM>
 
-   You may wish to examine the utilities and include some of them in your
-   programs if the programs access the function frequently or you may want
-   to modify the utilities to better fit your  particular  needs.  If  you
-   modify a utility, store your copy in a directory that precedes gtm_dist
-   in the search list $ZROUTINES to prevent a new  release  of  GT.M  from
-   overlaying your copy.
+   This example displays the eighteenth of January, however it uses the
+   fourth argument to specify the days of the week in French.
 
-2 Using_Util
-   Using the Utilities
+   Example:
 
-   You can either use a utility in Direct Mode or include it in  a  source
-   application  program  with  one  or  more  of  the  following  formats.
-   Italicized items are to be supplied by the user:
+   GTM>write !,$zdate($H,"12:60:SS AM")
 
-   o    DO ^%UTILITYNAME
+   10:35:51 PM
+   GTM>
 
-   o    DO LABEL^%UTILITYNAME
+   This example shows hours, minutes, and seconds in a 12 hour clock with an
+   AM/PM indicator.
 
-   o    $$FUNC^%UTILITYNAME[(para1,...)]
+   Example:
 
-   Many utilities contain labels  that  invoke  variations  of  the  basic
-   utility functionality. Some also provide the label FUNC  to  invoke  an
-   extrinsic function with optional or required parameters.
+   GTM>write !,$zdate(",36524","24-60")
 
-   GT.M passes input to non-extrinsic forms of the utilities interactively
-   or by using "input" variables. GT.M passes  output  from  non-extrinsic
-   forms of the utilities using "output" variables.  For  extrinsic  entry
-   points, the utilities receive input as parameters and  pass  output  as
-   the returned result. For  other  entry  points,  GT.M  uses  predefined
-   "input" and "output" variables  to  pass  information.  Some  utilities
-   interactively request user  inputs  and  display  their  results.  Each
-   utility is described individually in  this  chapter  where  appropriate
-   labels, input, and output variables are identified.
+   10-08
+   GTM>
 
-   By convention, the utilities  use  upper-case  variables  for  external
-   input and output. Since M is case-sensitive, when an invocation uses a
-   lower-case or misspelled variable name, the routine does not output the
-   expected information. Instead it  supplies  a  default  value,  if  one
-   exists, or produces an error message.
+   This example shows hours and minutes on a 24 hour clock. Notice that the
+   first argument must provide the time in the second comma delimiter piece
+   to match $HOROLOG format.
 
    Example:
 
+   GTM>write $zdateform
+   0
+   GTM>write $zdate($H)
+   01/18/11
+   GTM>set $zdateform=1
 
-   GTM>SET %ds="11/22/2002"
+   GTM>write $zdate($horolog)
+   01/18/2011
+   GTM>write $zdate($horolog,"MM/DD/YY")
+   01/18/11
 
-   GTM>DO INT^%DATE
+   This example converts the output format for years from the default ("YY")
+   format to the four digit format ("YYYY") using the Intrinsic Special
+   Variable $ZDATEFORM.
 
-   GTM>ZWRITE
+   Example:
 
-   %DN=59123
+   GTM>write $zdate(123456789,"DAY MON DD, YYYYYY")
+   FRI MAR 17, 339854
+   GTM>
 
-   %ds="11/22/2002"
+   This example displays year as a six-digit number.
 
-   This example sets the lowercase variable %ds to  the  date  11/22/2002.
-   Since the %DATE routine  expects  the  input  to  be  provided  in  the
-   uppercase %DS variable, it  returns  a  default  value  in  the  output
-   variable $DN. The default is the $HOROLOG format of the  current  date,
-   which is 11/15/2002 in the example.
+2 $ZExtract()
+   $ZExtract()
 
-2 Date_Time_Util
-   Date and Time Utilities
+   Returns a byte sequence from a given sequence of octets (8-bit bytes).
 
-   The date and time utilities are:
+   The format for the $ZEXTRACT function is:
 
-        %D Displays the current date using the [d]d-mmm-[yy]yy format.
-        %DATE Converts input date to the $HOROLOG format.
-        %H Converts date and time to and from $HOROLOG format.
-        %T Displays the current time in [h]h:mm AM/PM format.
-        %TI Converts time to $HOROLOG format.
-        %TO Converts the current time from $HOROLOG format to [h]h:mm AM/PM
-        format.
-        For details and examples, refer to the GT.M Programmer's Guide.
+   $ZE[XTRACT](expr[,intexpr1[,intexpr2]])
 
-   The  "%"  sign  has  been  removed  from  the  topic  headings  below,
-   intentionally.
+3 Examples
+   Examples
 
-3 D_
-   %D
+   Example:
 
+   GTM>Set A="************"
 
-   The %D utility displays the  current  date  using  the  [d]d-mmm-[yy]yy
-   format. If a routine uses this function repetitively, put  the  utility
-   code directly into the M program.
+   GTM>For i=0:1:$zlength(A)
 
-4 Util_Labels
-   Utility Labels
+   GTM>write !,$zascii($zextract(A,i)),"|"
 
-        INT Sets variable %DAT to current date.
-        FUNC[()] Invokes an extrinsic function returning today's date.
-4 Output_Vars
-   Output Variables
+   GTM>
 
-        %DAT Contains the current date.
-4 Ex_of_D
-   Examples of %D
+   This example displays the numeric byte sequence of the sequence of octets
+   ("************").
 
-        For the following examples, $ZDATEFORM is assumed to be one (1).
+2 $ZFind()
+   $ZFind()
 
-   Example:
+   Returns an integer byte position that locates the occurrence of a byte
+   sequence within a sequence of octets(8-bit bytes).
 
+   The format of the $ZFIND function is:
 
-   GTM>DO ^%D
+   $ZF[IND](expr1,expr2[,intexpr])
 
-   22-NOV-2002
-   This example invokes %D in Direct Mode. Then %D  displays  the  current
-   date.
+3 Examples_of_$ZFind()
+   Examples of $ZFind()
 
    Example:
 
+   GTM>write $zfind("***",$zchar(187))
+   4
+   GTM>
 
-   GTM>DO INT^%D
+   This example uses $ZFIND() to WRITE the position of the first occurrence
+   of the numeric byte code 150. The return of 3 gives the position after the
+   "found" byte.
 
-   GTM>ZWRITE
+   Example:
 
-   %DAT="22-NOV-2002"
+   GTM>write $zfind("***",$zchar(229),5)
+   8
+   GTM>
 
-   This example invokes %D with the label INT (INT^%D). The variable %DAT
-   contains the current date. ZWRITE displays the contents of  the  output
-   variable.
+   This example uses $ZFIND() to WRITE the position of the next occurrence of
+   the byte code 229 starting in byte position five.
 
    Example:
 
+   GTM>set t=1 for  set t=$zfind("***",$zchar(230,150,176),t) quit:'t  write !,t
+
+   4
+   GTM>
 
-   GTM>WRITE $$FUNC^%D
+   This example uses a loop with $ZFIND() to locate all the occurrences of
+   the byte sequence $ZCHAR(230,150,176) in the sequence of octets ("***").
+   The $ZFIND() returns 4 giving the position after the occurrence of byte
+   sequence $ZCHAR(230,150,176).
 
-   22-NOV-2002
-   This example invokes %D as an extrinsic function with the  label  FUNC.
-   $$FUNC^%D returns today's date.
+2 $ZGetjpi()
+   $ZGetjpi()
 
-3 DATE
-   %DATE
+   Returns job or process information of the specified process. The format
+   for the $ZGETJPI function is:
 
+   $ZGETJPI(expr1,expr2)
 
-   The %DATE utility converts an input date to the  $HOROLOG  format.  The
-   $HOROLOG format represents time as the number of  days  since  December
-   31,  1840.  The  routine  has  entry  points  for  interactive  or
-   non-interactive use.
+   Example:
 
-4 Util_Labels
-   Utility Labels
+   GTM>write $zgetjpi(1975,"isprocalive")
+   1
+   GTM>
 
-        INT Converts %DS input non-interactively, if defined, otherwise the
-        current date.
-        FUNC(t) Invokes an extrinsic function returning $HOROLOG format of
-        the argument.
-4 Prompts
-   Prompts
+   This uses $ZGETJPI() to determine whether process 1975 is alive.
 
-        Date: Interactively requests a  date  for  conversion  to  $HOROLOG
-        format.
-4 Input_Vars
-   Input Variables
+   Example:
 
-        %DS Contains input date; refer to %DATE Input Formats table.
-4 Output_Vars
-   Output Variables
+   GTM>set t=$zgetjpi("","cputim")
+   GTM>do ^bench write $zgetjpi("","cputim")-t
+   1738
+   GTM>
 
-        %DN Contains output date in $HOROLOG format
-4 Ex_of_DATE
-   Examples of %DATE
+   This uses $ZGETJPI() to measure the actual CPU time, measured in
+   hundredths of a second, consumed by performing the BENCH routine.
 
-   Example:
+2 $ZJOBEXAM()
+   $ZJOBEXAM()
 
+   Returns the full specification of the file into which the function places
+   a ZSHOW "*". The return value serves as a way to save, to notify others of
+   the exact location of the output, or to open the file for further
+   processing. GT.M reports each $ZJOBEXAM() to the operator log facility
+   with its file specification.
 
-   GTM>DO ^%DATE
+   The optional expression argument is a template output device
+   specification. It can be a device, a file directory, or a file name. The
+   template is an expression that is pre-processed to create a file
+   specification as the target for the ZSHOW. The preprocessing is equivalent
+   to $ZPARSE(), as illustrated by the following M code:
 
-   Date:
+   set deffn="GTM_JOBEXAMINE.ZSHOW_DMP_"_$JOB_"_"_<cntr>
 
-   GTM>ZWRITE
+   set filespec=$zparse(expr1,"",deffn)
+
+   The $ZJOBEXAM()does not trigger error processing except when there is a
+   problem storing its return value, so no error is reported to the process
+   until after any dump is complete. In the event of any error encountered
+   during the $ZJOBEXAM(), GT.M sends an appropriate message to operator log
+   facility and returns control to the caller. Note that this special error
+   handling applies only to the $ZJOBEXAM(), and is not a property of the
+   $ZINTERRUPT interrupt handler, which uses $ZJOBEXAM() by default.
 
-   %DN=59105
+   $ZJOBEXAM() dump files contain the context of a process at the time the
+   function executes. Placement and management of these files should consider
+   their potential size and security implications.
 
-   This example invokes %DATE at the GTM> prompt. After pressing <RETURN>
-   at  the  Date:  prompt,  %DATE  converts  today's  date  (for  example,
-   10/28/2002) to the $HOROLOG format. ZWRITE displays the contents of the
-   output variable.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>set x=$zjobexam()
+   GTM>write x
+   /home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/GTM_JOBEXAM.ZSHOW_DMP_28760_1
+   GTM>set x=$zjobexam("test.file")
 
-   GTM>DO INT^%DATE
-
-   GTM>ZWRITE
+   GTM>write x
+   /home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/test.file
+   GTM>
 
-   %DN=59105
+   Shows default file name and type of the files created containing the zshow
+   dump information and the difference when the name and type are specified.
 
-   This  example  invokes  INT^%DATE,  which  converts  the  current  date
-   non-interactively into $HOROLOG format. ZWRITE displays the contents of
-   the output variable.
+2 $ZJustify()
+   $ZJustify()
 
-   Example:
+   Returns a formatted and fixed length byte sequence.
 
+   The format for the $ZJUSTIFY() function is:
 
-   GTM>SET %DS="10/20/2002"
+   $ZJ[USTIFY](expr,intexpr1[,intexpr2])
 
-   GTM>DO INT^%DATE
+3 Examples
+   Examples
 
-   GTM>ZWRITE
+   Example:
 
-   %DN=59097
+   GTM>write "123456789012345",! write $zjustify("***",15),!,$zjustify("***",5)
+   123456789012345
+        ***
+   ***
+   GTM>
 
-   %DS="10/20/2002"
+   This example uses $ZJUSTIFY() to display the sequence of octets
+   represented by "***" in fields of 15 space octets and 5 space octets.
+   Because the byte length of "***" is 9, it exceeds 5 spaces, the result
+   overflows the specification.
 
-   This example sets the input variable %DS prior to  invoking  INT^%DATE,
-   which converts that date non-interactively to $HOROLOG format.
+2 $ZLength()
+   $ZLength()
 
-   Example:
+   Returns the length of a sequence of octets measured in bytes, or in
+   "pieces" separated by a delimiter specified by one of its arguments.
 
+   The format for the $ZLENGTH() function is:
 
-   GTM>WRITE $$FUNC^%DATE("10/20/2002")
+   $ZL[ENGTH](expr1[,expr2])
 
-   59097
-   This example invokes %DATE with the label FUNC as an extrinsic function
-   to convert an input date to $HOROLOG. If the invocation does not supply
-   a date for $$FUNC^%DATE, FUNC converts the current date.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>write $zlength("************")
+   36
+   GTM>
 
-   GTM>WRITE $ZDATEFORM
+   This uses $ZLENGTH() to WRITE the length in bytes of the sequence of
+   octets "************".
 
-   1975
-   GTM>WRITE $$FUNC^%DATE("10/20/80")
+   Example:
+
+   GTM>set x="*"_$zchar(63)_"*"_$zchar(63)_"*"
+   GTM>write $zlength(x,$zchar(63))
+   2
+   GTM>
 
-   51062
-   GTM>WRITE $ZDATE(51062)
+   This uses $ZLENGTH() to WRITE the number of pieces in a sequence of
+   octets, as delimited by the byte code $ZCHAR(63).
 
-   10/20/1980
-   GTM>WRITE $$FUNC^%DATE("10/20/10")
+   Example:
 
-   62019
-   GTM>WRITE $ZDATE(62019)
+   GTM>set x=$zchar(63)_"*"_$zchar(63)_"*"_$zchar(63)_"*"_$zchar(63)"
+   GTM>write $zlength(x,$zchar(63)
+   4
+   GTM>
 
-   10/20/2010
-   This example shows the use of a year limit  in  $ZDATEFORM.  Two  digit
-   years are  interpreted  to  be  in  the  interval  (1975,  2074)  since
-   $ZDATEFORM is 1975; the input year "80"  is  interpreted  as  the  year
-   "1980" and "10" is interpreted as the year "2010". The example invokes
-   FUNC^%DATE to convert the input date to $HOROLOG  format.  $ZDATE()  is
-   used to convert the $HOROLOG format date to mm/dd/yyyy format.
+   This also uses $ZLENGTH() to WRITE the number of pieces in a sequence of
+   octets, as delimited by byte code $ZCHAR(63). Notice that GT.M. counts
+   both the empty beginning and ending pieces , in the string because they
+   are both delimited.
 
-3 H
-   %H
+2 $ZMessage()
+   $ZMessage()
 
+   Returns a message string associated with a specified status code .
 
-   The %H utility converts date and time to and from $HOROLOG format.
+   The format for the $ZMESSAGE function is:
 
-4 Util_Labels
-   Utility Labels
+   $ZM[ESSAGE](intexpr)
 
-        %CDS Converts %DT $HOROLOG input date to mm/dd/yyyy format.
-        %CTS Converts %TM $HOROLOG input time to external format.
-        %CDN Converts %DT input date to $HOROLOG format.
-        %CTN Converts %TM input time to $HOROLOG format.
-        CDS(dt) Extrinsic entry that  converts  the  $HOROLOG  argument  to
-        external date format.
-        CTS(tm) Extrinsic entry that  converts  the  $HOROLOG  argument  to
-        external time format.
-        CDN(dt) Extrinsic entry that  converts  the  argument  to  $HOROLOG
-        format.
-        CTN(tm) Extrinsic entry that  converts  the  argument  to  $HOROLOG
-        format.
-4 Input_Vars
-   Input Variables
+   $ZMESSAGE() provides a tool for examining the message and/or mnemonic
+   associated with a particular message code as reported in $ZSTATUS.
 
-        %DT Contains input date in either $HOROLOG or mm/dd/[yy]yy format,
-        depending on the format expected by the utility entry point.
-        %TM Contains input time in either $HOROLOG  or  [h]h:mm:ss  format,
-        depending on the format expected by the utility entry point.
-4 Output_Vars
-   Output Variables
+   The $ZSTATUS Intrinsic Special Variable holds the message code and the
+   message of the last non-Direct Mode GT.M error. For more information on
+   $ZSTATUS, refer "Intrinsic Special Variables".
 
-        %DAT Contains converted output date,
-        %TIM Contains converted output time,
-4 Ex_of_H
-   Examples of %H
+3 Examples
+   Examples
 
    Example:
 
+   GTM>write $zmessage(36)
 
-   GTM>SET %DT=+$H DO %CDS^%H
+   Interrupted system call
+   GTM>
 
-   GTM>ZWRITE
+   This uses $ZMESSAGE() to display the message string corresponding to code
+   36.
 
-   %DAT="10/20/2002"
+2 $ZPARSE()
+   $ZPARSE()
 
-   %DT=59097
+   Expands a file name to a full pathname and then returns the full pathname
+   or one of its fields (directory, name, or extension).
 
-   This example sets %DT to  the  current  date  in  $HOROLOG  format  and
-   converts it to mm/dd/yyyy format by invoking %H at the label  %CDS.  %H
-   returns the converted date in the variable %DAT.  ZWRITE  displays  the
-   contents of the variables.
+   The format for the $ZPARSE function is:
 
-   Example:
+   $ZPARSE(expr1[,expr2[,expr3[,expr4[,expr5]]]])
 
+   $ZPARSE() provides a tool for verifying that a file name is syntactically
+   correct, for examining specific fields of a file name, and for filling in
+   missing pieces in a partial specification based on a hierarchy of
+   defaults. For information about determining whether a file exists, see
+   "$ZSEARCH()".
 
-   GTM>SET %DT="10/20/2002" DO %CDN^%H
+   $ZPARSE() arguments, after the first, are optional. If you use no other
+   arguments, a single argument is sufficient. However, if you use selected
+   arguments $ZPARSE() requires that null strings ("") be filled in for the
+   unspecified arguments.
 
-   GTM>ZWRITE
+   The acceptable keywords for the second argument are:
 
-   %DAT=59097
+   "DIRECTORY": Directory name
 
-   %DT="10/20/2002"
+   "NAME": File name (excluding file extension)
 
-   This example sets the variable %DT to a date in mm/dd/yyyy  format  and
-   invokes %H at the label %CDN. %H returns  the  converted  date  in  the
-   variable %DAT. ZWRITE displays the contents of the variables.
+   "TYPE": File type extension
 
-   Example:
+   The keywords may be entered in either upper or lower case. Variables that
+   evaluate to these strings and indirection are acceptable for argument two.
+   When the keywords themselves appear as string literals, they must be
+   enclosed in quotation marks (" ").
 
+   The following guidelines must be followed in constructing arguments one,
+   three and four:
 
-   GTM>SET %TM=$P($H,",",2) DO %CTS^%H
+     o Directory specifications must end in a slash; anything after the final
+       slash in the directory specification is assumed to be part of the name
+       specification.
+     o A file name with an extension must include at least one character to
+       the left of the period (.). Thus, "/user/.login" refers to the file
+       named ".login", while "/usr/taxes.c" refers to a file named "taxes"
+       with the extension "c". If a file name includes more than one period,
+       the extension includes all letters to the right of the rightmost
+       period.
 
-   GTM>ZWRITE
+   The keywords for the fifth argument $ZPARSE() are:
 
-   %TIM="17:41:18"
+   NULL (""): Returns a full file-specification or device
 
-   %TM=63678
+   "SYNTAX_ONLY": Disables checking for the existence of the directory or
+   device.
 
-   This example sets the variable %TM to  the  current  time  in  $HOROLOG
-   format using a $PIECE() function to return only  those  digits  of  the
-   $HOROLOG string that represent the time. The example then invokes %H at
-   the label %CTS. %H returns the converted time  in  the  variable  %TIM.
-   ZWRITE displays the contents of the variables.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>write $zparse("test","","/usr/work/","dust.lis")
+   /usr/work/test.lis
+   GTM>
 
-   GTM>SET %TM="17:41:18" DO %CTN^%H
-
-   GTM>ZWRITE
+   This uses $ZPARSE() to demonstrate defaulting using the third and fourth
+   arguments. The result gets the directory field from the third expression,
+   the name from the first expression, and the type from the fourth
+   expression.
 
-   %TIM=63678
+   Example:
 
-   %TM="17:41:18"
+   GTM>r!,"file :",f w ?20,$zparse(f,"directory")
+   file: test.list /usr/work/
+   GTM>
 
-   This example sets the variable %TM to a time in  hh:mm:ss  format,  and
-   invokes %H at the label %CTN. %H returns  the  converted  time  in  the
-   variable %TIM. ZWRITE displays the contents of the variables.
+   This uses $ZPARSE() to display the directory for the file name entered as
+   input at the prompt file: , in this case, the current working directory.
 
    Example:
 
+   $ cd /usr/work/me
+   $ $gtm
+   GTM>write $zparse("test","","x.list","y.c")/usr/work/me/test.lis
+   GTM>write $zparse("test","","/usr/work/","/dev/y.c")/usr/work/test.c
+   GTM>write $zparse("test","","/usr/work","/dev/y.c")/usr/test.c
+   GTM>
+
+   This example illustratest the use of the third and fourth arguments to
+   $ZPARSE(). In the first statement, the first argument has no directory or
+   extension field, so $ZPARSE() substitutes the extension field from the
+   third argument. Since neither the third nor fourth argument specifies a
+   directory, and because the fourth argument does not contain any fields
+   that are not present in the third argument, the fourth argument is not
+   used.
 
-   GTM>WRITE $$CDS^%H(59130)
+   In the second statement, the first argument to $ZPARSE() is again missing
+   both the directory and extension. In this instance, $ZPARSE() uses the
+   directory specified in the third argument and, becuase neither the first
+   nor third argument specifies a file extension, $ZPARSE() uses the file
+   extension from the fourth argument.
 
-   11/22/2002
-   This invokes CDS^%H as an extrinsic function to  convert  the  external
-   argument to external date format.
+   In the third statement, because "/usr/work" does not end with a backward
+   slash (/), $ZPARSE() interprets the substring "work" as a file name. Then,
+   $ZPARSE() substitutes "/usr/" for the directory missing in the first
+   argument and substitutes ".c" from the fourth argument for the extension
+   missing from both the first and third arguments.
 
    Example:
 
+   $ cd /usr/work/me
+   $ /usr/lib/fis-gtm/V5.4-002B_x86/gtm
+   GTM>For i="DIRECTORY","NAME","TYPE","" Write $ZPARSE("test.m",i),!
+   /usr/work/me/
+   test
+   .m
+   /usr/work/me/test.m
+   GTM>
+
+   This example illustrates the output produced for each of the possible
+   values for the second argument.
 
-   GTM>WRITE $ZDATEFORM
+2 $ZPiece()
+   $ZPiece()
 
-   1980
-   GTM>WRITE $$CDN^%H("10/20/02")
+   Return a sequence of bytes delimited by a specified byte sequence made up
+   of one or more bytes.
 
-   59097
-   GTM>WRITE $ZDATE(59097)
+   The format for the $ZPIECE function is:
 
-   10/20/2002
-   GTM>WRITE $$CDN^%H("10/20/92")
+   $ZP[IECE](expr1,expr2[,intexpr1[,intexpr2]])
 
-   55445
-   GTM>WRITE $ZDATE(55445)
+3 Examples
+   Examples
 
-   10/20/1992
-   This example shows the use of a year limit  in  $ZDATEFORM.  Two  digit
-   years are interpreted to be in the  interval  of  1980  -  2079;  since
-   $ZDATEFORM is 1980, the input year "02" is interpreted  as  "2002"  and
-   "92" is interpreted as "1992". This example invokes CDN^%H  to  convert
-   the argument in mm/dd/yy format to $HOROLOG format. $ZDATE() is used to
-   conver the $HOROLOG format date to mm/dd/yyyy format.
+   Example:
 
-3 T_
-   %T
+   GTM>for i=0:1:3 write !,$zpiece("*"_$zchar(64)_"*",$zchar(64),i),"|"
 
+   |
+   *|
+   *|
+   |
+   GTM>
 
-   The %T utility displays the current time in [h]h:mm AM/PM. If a routine
-   uses this function repetitively, put the utility code directly into the
-   M program.
+   This loop displays the result of $ZPIECE(), specifying $ZCHAR(64) as a
+   delimiter, a piece position "before," first and second, and "after" the
+   sequence of octets.
 
-4 Util_Labels
-   Utility Labels
+   Example:
 
-        INT Sets %TIM to current time in [h]h:mm AM/PM format.
-        FUNC[()] Invokes an extrinsic function returning the current time.
-4 Output_Vars
-   Output Variables
+   GTM>for i=-1:1:3 write !,$zpiece("*"_$zchar(64)_"*",$zchar(64),i,i+1),"|"
 
-   %TIM Contains current time in [h]h:mm AM/PM format.
+   |
+   *|
+   *@*|
+   *|
+   |
 
+   GTM>
 
-4 Ex_of_T
-   Examples of %T
+   This example is similar to the previous example except that it displays
+   two pieces on each iteration. Notice the delimiter () in the middle of the
+   output for the third iteration, which displays both pieces.
 
    Example:
 
+   For p=1:1:$ZLength(x,"/") Write ?p-1*10,$ZPiece(x,"/",p)
 
-   GTM>DO ^%T
-
-   8:30 AM
-   This example invokes %T, which prints the current time and does not set
-   %TIM.
+   This loop uses $ZLENGTH() and $ZPIECE() to display all the pieces of x in
+   columnar format.
 
    Example:
 
+   GTM>Set $piece(x,$zchar(64),25)="" write x
+   ***@@@@@@@@@@@@@@@@@@@@@@@@
 
-   GTM>DO INT^%T
+   This SETs the 25th piece of the variable x to null, with delimiter
+   $ZCHAR(64). This produces a byte sequence of 24 at-signs (@) preceding the
+   null.
 
-   GTM>ZWRITE
+2 $ZPrevious()
+   $ZPrevious()
 
-   %TIM="8:30 AM"
+   The $ZPREVIOUS function returns the subscript of the previous local or
+   global variable name in collation sequence within the array level
+   specified by its argument. When $ZPREVIOUS() has an unsubscripted
+   argument, it returns the previous unsubscripted local or global variable
+   name in collating sequence.
 
-   This example invokes INT^%T,  which  sets  the  variable  %TIM  to  the
-   current time. ZWRITE displays the contents of the variable.
+   The $ZPREVIOUS function provides compatibility with some other M
+   implementations. The M Development Committee chose to implement this
+   functionality with the optional second -1 argument of $ORDER(). Therefore,
+   when a design requires this functionality $ORDER() has the advantage over
+   $ZPREVIOUS of being part of the M standard.
 
-   Example:
+   The format for the $ZPREVIOUS function is:
+
+   $ZP[REVIOUS](glvn)
 
+   $ZPREVIOUS() is equivalent to $ORDER() with a second argument of -1.
 
-   GTM>WRITE $$FUNC^%T
+2 $ZQGBLMOD()
+   $ZQGBLMOD()
 
-   8:30 AM
-   This example invokes FUNC as an extrinsic function, which  returns  the
-   current time.
+   The $ZQGBLMOD function enables an application to determine whether it can
+   safely apply a lost transaction to the database. A lost transaction is a
+   transaction that must be rolled off a database to maintain logical
+   multisite consistency.
 
-3 TI
-   %TI
+   The format for the $ZQGBLMOD function is:
 
+   $ZQGBLMOD(gvn)
 
-   The %TI utility converts time to $HOROLOG format. The  $HOROLOG  format
-   represents time as the number of seconds since  midnight.  %TI  returns
-   the converted time in the variable %TN. The routine  has  entry  points
-   for interactive or non-interactive use.
+   $ZQGBLMOD function produces an error if you submit an argument that is not
+   a global variable name.
 
-4 Util_Labels
-   Utility Labels
+   Internally, $ZQGBLMOD (gvn) compares the GT.M transaction number in the
+   database block in which the global variable name is stored with the value
+   in the Zqgblmod_Trans (and Zqgblmod_Seqno) fields stored in the database
+   file header.
 
-        INT Non-interactively converts %TS to $HOROLOG format;  if  %TS  is
-        not defined, then current time is converted.
-        FUNC[(ts)] Invokes an extrinsic function returning $HOROLOG format
-        of the argument, or if no argument,  the  $HOROLOG  format  of  the
-        current time.
-4 Prompts
-   Prompts
+   For example, if x is the transaction number of the level-0 database block
+   in which gvn resides, and y is the value of Zqgblmod_Seqno of region reg
+   containing gvn, then the following is true:
 
-        Time: Requests time in [h]h:mm:ss format  to  convert  to  $HOROLOG
-        format.
-4 Input_Vars
-   Input Variables
+   If a transaction is a lost transaction that has been rolled back and it is
+   determined that for all the M globals set and killed in the transaction
+   $ZQGBLMOD() is zero (0), it is probably safe to apply the updates
+   automatically. However, this determination of safety can only be made by
+   the application designer and not by GT.M. If the $ZQGBLMOD() is one (1)
+   for any set or kill in the transaction, it is not safe to apply the
+   update.
 
-        %TS Contains input time.
-4 Output_Vars
-   Output Variables
+   **Note**
 
-        %TN Contains output time in $HOROLOG format
-4 Ex_of_TI
-   Examples of %TI
+   The test of $ZQGBLMOD() and applying the updates must be encapsulated
+   inside a GT.M transaction.
 
-   Example:
+   Another approach to handling lost transactions would be to store in the
+   database the initial message sent by a client, as well as the outcome and
+   the response, and to reprocess the message with normal business logic. If
+   the outcome is the same, the transaction can be safely applied.
 
+   **Note**
 
-   GTM>DO ^%TI
+   If restartable batch operations are implemented, lost batch transactions
+   can be ignored since a subsequent batch restart will process them
+   correctly.
 
-   Time: 4:02 PM
+2 $ZSEARCH()
+   $ZSEARCH()
 
-   GTM>ZWRITE
+   The $ZSEARCH function attempts to locate a file matching the specified
+   file name. If the file exists, it returns the file name; if the file does
+   not exist, it returns the null string.
 
-   %TN=57720
+   The format for the $ZSEARCH function is:
 
-   This example invokes %TI,  which  prompts  for  an  input  time.  Press
-   <RETURN> to convert the current time. ZWRITE displays the  contents  of
-   the output variable.
+   $ZSEARCH(expr[,intexpr])
 
-   Example:
+   $ZSEARCH() provides a tool for verifying that a file exists.
 
+   **Note**
 
-   GTM>ZWRITE
+   You can call the POSIX stat() function to access metadata. The optional
+   GT.M POSIX plug-in packages the stat() function for easy access from M
+   application code.
 
-   GTM>DO INT^%TI
+3 Examples
+   Examples
 
-   GTM>ZWRITE
+   Example:
 
-   %TN=40954
+   GTM>write $zsearch("data.dat")
+   /usr/staff/ccc/data.dat
+   GTM>
 
-   This  example  invokes  INT^%TI  to  convert  the  current  time
-   non-interactively. ZWRITE displays the contents of the output variable
-   %TN.
+   This uses $ZSEARCH() to display the full file path name of "data.dat" in
+   the process current default directory.
 
    Example:
 
+   GTM>set x=$zsearch("*.c")
+   GTM>for  set x=$zsearch("*.m") quit:x=""  write !,$zparse(x,"NAME")
 
-   GTM>SET %TS="8:30AM"
-
-   GTM>DO INT^%TI
+   This FOR loop uses $ZSEARCH() and $ZPARSE() to display M source file names
+   in the process current working directory. To ensure that the search starts
+   at the beginning, the example resets the context by first searching with a
+   different argument.
 
-   GTM>ZWRITE
+2 $ZSIGPROC()
+   $ZSIGPROC()
 
-   %TN=30600
+   Sends a signal to a process. The format for the $ZSIGPROC function is:
 
-   %TS="8:30AM"
+   $ZSIGPROC(expr1,expr2)
 
-   This example sets the variable %TS prior to invoking INT^%TI. %TI uses
-   %TS as the input time. ZWRITE displays the contents of the variables.
+   **Caution**
 
-   Example:
+   Although $ZSIGPROC() may work today as a way to invoke the asynchronous
+   interrupt mechanism of GT.M processes to XECUTE $ZINTERRUPT because the
+   underlying mechanism uses the POSIX USR1 signal, FIS reserves the right to
+   change the underlying mechanism to suit its convenience and sending a
+   POSIX USR1 may cease to work as a way to invoke the asynchronous interrupt
+   mechanism. Use MUPIP INTRPT as the supported and stable API to invoke the
+   asynchronous interrupt mechanism.
 
+3 Examples
+   Examples
 
-   GTM>WRITE $$FUNC^%TI("8:30AM")
+   Example:
 
-   30600
-   This example invokes %TI  as  an  extrinsic  function  to  convert  the
-   supplied time to $HOROLOG  format.  If  there  is  no  argument  (i.e.,
-   $$FUNC^%TI), %TI converts the current time.
+   GTM>job ^Somejob
 
-3 TO
-   %TO
+   GTM>set ret=$&gtmposix.signalval("SIGUSR1",.sigusr1) zwrite
+   ret=0
+   sigusr1=10
 
+   GTM>write $zsigproc($zjob,sigusr1)
+   0
+   GTM>
 
-   The %TO utility converts the input time from $HOROLOG format to [h]h:mm
-   AM/PM format. Put the utility code directly into the M program  if  the
-   routine uses this function repetitively.
+   This example sends the SIGUSR1 signal to the pid specified by $zjob.
 
-4 Util_Labels
-   Utility Labels
+2 $ZSUBstr()
+   $ZSUBstr()
 
-        INT Converts non-interactively %TS, or if %TS is  not  defined  the
-        current time to [h]h:mm AM/PM format.
-4 Input_Vars
-   Input Variables
+   Returns a properly encoded string from a sequence of bytes.
 
-        %TN Contains input time in $HOROLOG format.
-4 Output_Vars
-   Output Variables
+   $ZSUB[STR] (expr ,intexpr1 [,intexpr2])
 
-        %TS Contains output time in [h]h:mm AM/PM format.
-4 Ex_of_TO
-   Examples of %TO
+3 Examples
+   Examples
 
    Example:
 
+   GTM>write $ZCHSET
+   M
+   GTM>set char1="a" ; one byte character
 
-   GTM>DO INT^%TI,^%TO
-
-   GTM>ZWRITE
+   GTM>set char2="c,"; two-byte character
 
-   %TN=62074
+   GTM>set char3="*"; three-byte character
 
-   %TS="5:14 PM"
+   GTM>set y=char1_char2_char3
 
-   This example invokes INT^%TI to set %TN to the current time and invokes
-   %TO to convert the time contained in %TN to the [h]h:mm  AM/PM  format.
-   %TO returns the converted time in the variable %TS. ZWRITE displays the
-   contents of the variables.
+   GTM>write $zsubstr(y,1,3)=$zsubstr(y,1,5)
+   0
 
-2 Conversion_Util
-   Conversion Utilities
+   With character set M specified, the expression
+   $ZSUBSTR(y,1,3)=$ZSUBSTR(y,1,5) evaluates to 0 or "false" because the
+   expression $ZSUBSTR(y,1,5) returns more characters than $ZSUBSTR(y,1,3).
 
-   The conversion utilities are:
+   Example:
 
-        %DH Decimal to hexadecimal conversion.
-        %DO Decimal to octal conversion.
-        %HD Hexadecimal to decimal conversion.
-        %HO Hexadecimal to octal conversion.
-        %LCASE Converts a string to all lower case.
-        %OD Octal to decimal conversion.
-        %OH Octal to hexadecimal conversion.
-        %UCASE Converts a string to all upper case.
-   The conversion utilities can be invoked as extrinsic functions.
+   GTM>write $zchset
+   UTF-8
+   GTM>set char1="a" ; one byte character
 
-   The  "%"  sign  has  been  removed  from  the  topic  headings  below,
-   intentionally.
+   GTM>set char2="c,"; two-byte character
 
-3 DH
-   %DH
+   GTM>set char3="*"; three-byte character
 
+   GTM>set y=char1_char2_char3
 
-   The %DH utility converts numeric values from  decimal  to  hexadecimal.
-   %DH defaults the length of its output  to  eight  digits.  However  the
-   input variable %DL overrides the default and controls the length of the
-   output. The routine has entry points for interactive or non-interactive
-   use.
+   GTM>write $zsubstr(y,1,3)=$zsubstr(y,1,5)
+   1
 
-4 Util_Labels
-   Utility Labels
+   For a process started in UTF-8 mode, the expression
+   $ZSUBSTR(y,1,3)=$ZSUBSTR(y,1,5) evaluates to 1 or "true" because the
+   expression $ZSUBSTR(y,1,5) returns a string made up of char1 and char2
+   excluding the three-byte char3 because it was not completely included in
+   the specified byte-length.
+
+   In many ways, the $ZSUBSTR() function is similar to the $ZEXTRACT()
+   function. For example, $ZSUBSTR(expr,intexpr1) is equivalent to
+   $ZEXTRACT(expr,intexpr1,$L(expr)). Note that this means when using the M
+   character set, $ZSUBSTR() behaves identically to $EXTRACT() and
+   $ZEXTRACT(). The differences are as follows:
+
+     * $ZSUBSTR() cannot appear on the left of the equal sign in the SET
+       command where as $ZEXTRACT() can.
+     * In both the modes, the third expression of $ZSUBSTR() is a byte,
+       rather than character, position within the first expression.
+     * $EXTRACT() operates on characters, irrespective of byte length.
+     * $ZEXTRACT() operates on bytes, irrespective of multi-byte character
+       boundaries.
+     * $ZSUBSTR() is the only way to extract as valid UTF-8 encoded
+       characters from a byte string containing mixed UTF-8 and non UTF-8
+       data. It operates on characters in Unicode so that its result does not
+       exceed the given byte length.
+
+2 $ZTRanslate()
+   $ZTRanslate()
+
+   Returns a byte sequence that results from replacing or dropping bytes in
+   the first of its arguments as specified by the patterns of its other
+   arguments.
 
-        INT Converts interactively entered decimal  number  to  hexadecimal
-        number with the number of digits specified.
-        FUNC(d[,l]) Invokes %DH as  an  extrinsic  function  returning  the
-        hexadecimal equivalent of the argument.
-4 Input_Vars
-   Input Variables
+   The format for the $ZTRANSLATE() function is:
 
-        %DH As input, contains input decimal number.
-        %DL Specifies how many digits appear in  the  output,  defaults  to
-        eight.
-4 Prompts
-   Prompts
+   $ZTR[ANSLATE](expr1[,expr2[,expr3]])
 
-        Decimal: Requests a decimal number for conversion to hexadecimal.
-        Digits: Requests the length of  the  output  in  digits;  eight  by
-        default.
-4 Output_Vars
-   Output Variables
+   The $ZTRANSLATE() algorithm can be understood as follows:
 
-        %DH As output, contains the converted number in hexadecimal.
-4 Ex_of_DH
-   Examples of %DH
+3 Examples
+   Examples
 
    Example:
 
+   GTM>set hiraganaA=$char(12354) ; $zchar(227,129,130)
 
-   GTM>DO INT^%DH
+   GTM>set temp1=$zchar(130)
 
-   Decimal: 12
+   GTM>set temp2=$zchar(140)
 
-   Digits: 1
+   GTM>set tr=$ztranslate(hiraganaA,temp1,temp2)
 
-   GTM>ZWRITE
+   GTM>w $ascii(tr)
+   12364
+   GTM>
 
-   %DH="C"
+   In the above example, $ZTRANSLATE() replaces byte $ZCHAR(130) in first
+   expression and matching the first (and only) byte in the second expression
+   with byte $ZCHAR(140) - the corresponding byte in the third expression.
 
-   This example invokes %DH interactively with INT^%DH. %DH prompts for a
-   decimal number and output  length,  then  returns  the  result  in  the
-   variable %DH. ZWRITE displays the contents of the variables.
+2 $ZTRIgger()
+   $ZTRIgger()
 
-   Example:
+   Examine or load trigger definition. The format of the $ZTRIGGER() function
+   is:
 
+   $ZTRIgger(expr1[,expr2])
 
-   GTM>SET %DH=12
+3 Examples_of_$ZTRIGGER()
+   Examples of $ZTRIGGER()
 
-   GTM>DO ^%DH
+   GTM>set X=$ztrigger("S")
+   GTM>
 
-   GTM>ZWRITE
+   This example displays the current trigger definitions stored in the
+   database.
 
-   %DH="0000000C"
+   GTM>set X=$ztrigger("i","+^Acct(sub=:) -command=set -xecute=""set ^X($ztvalue)=sub""")
+   GTM>
 
-   %DL=8
+   This example adds a trigger definition for the first level node of ^Acct.
 
-   This example sets the read-write variable %DH to 12 and invokes %DH to
-   convert the number to a  hexadecimal  number.  Because  the  number  of
-   digits was not specified, %DH used the default of 8 digits. Set %DL to
-   specify the number of output digits.
+2 $ZTRNLNM()
+   $ZTRNLNM()
 
-   Example:
+   The $ZTRNLNM function returns the value of an environment variable.The
+   $ZTRNLNM function is analogous to the DCL Lexical function F$TRNLNM on
+   OpenVMS.
 
+   **Note**
 
-   GTM>WRITE $$FUNC^%DH(12,4)
+   $ZTRNLNM() does not perform iterative translation.
 
-   000C
-   This example invokes %DH as an extrinsic function using the FUNC label.
-   The first argument specifies the input decimal number and the optional,
-   second argument specifies the number of output digits. If the extrinsic
-   does not have a second argument, the length of the output  defaults  to
-   eight characters.
+   The format for the $ZTRNLNM function is:
 
-3 DO
-   %DO
+   $ZTRNLNM(expr1[,expr2[,expr3[,expr4[,expr5[,expr6]]]]])
 
+   expr1 specifies the environment variable whose value needs to be returned.
 
-   The %DO utility converts numeric values  from  decimal  to  octal.  The
-   default length of its output is 12 digits. The value  assigned  to  the
-   input variable %DL overrides the default and controls the length of the
-   output. The routine has entry points for interactive or non-interactive
-   use.
+   expr2 to expr5 are OpenVMS-related expressions that specify logical name
+   table(s), index (numbered from 0), initial mode of the look-up, and a
+   value indicating whether the look-up is case sensitive. To ensure
+   interoperability between UNIX and OpenVMS versions, $ZTRNLNM() on UNIX
+   accepts these expressions and ignores them.
 
-4 Util_Labels
-   Utility Labels
+   expr6 specifies any one of the following keywords:
 
-        INT Converts the specified decimal number to an octal  number  with
-        the specified number of digits, interactively.
-        FUNC(d[,ln]) Invokes %DO as an extrinsic  function,  returning  the
-        octal equivalent of the argument.
-4 Prompts
-   Prompts
+   +-----------------------------------------------------+
+   | ITEM KEYWORD |            DATA RETURNED             |
+   |--------------+--------------------------------------|
+   | FULL         | Returns the translation.             |
+   |--------------+--------------------------------------|
+   | LENGTH       | Length of the return value in bytes. |
+   |--------------+--------------------------------------|
+   | VALUE        | Returns the translation.             |
+   +-----------------------------------------------------+
 
-        Decimal: Requests a decimal number for conversion to octal.
-        Digits: Requests the length of the output in digits; 12 by default.
-4 Input_Vars
-   Input Variables
+3 Examples
+   Examples
 
-        %DO As input, contains input decimal number.
-        %DL Specifies the number of digits in the output, defaults to 12.
-4 Output_Vars
-   Output Variables
+   Example:
 
-        %DO As output, contains the converted number in octal.
-4 Ex_of_DO
-   Examples of %DO
+   GTM>write $ztrnlnm("gtm_dist","","","","","VALUE")
+   /usr/lib/fis-gtm/V6.0-000_x86_64/utf8
+   GTM>
 
-   Example:
+   This uses $ZTRNLNM() to display the translation value for gtm_dist.
 
+2 $ZWidth()
+   $ZWidth()
 
-   GTM>DO INT^%DO
+   Returns the numbers of columns required to display a given string on the
+   screen or printer. The format of the $ZWIDTH() function is:
 
-   Decimal: 12
+   $ZW[IDTH] (expr)
 
-   Digits: 4
+   **Note**
 
-   GTM>ZWRITE
+   The ZWIDTH() function triggers a run-time error if it encounters a
+   malformed byte sequence irrespective of the setting of "BADCHAR".
 
-   %DO="0014"
+   With character set UTF-8 specified, the $ZWIDTH() function uses the ICU's
+   glyph-related conventions to calculate the number of columns required to
+   represent the expression.
 
-   This example invokes %DO interactively with INT^%DO. %DO prompts for a
-   decimal number and an output length. If the output  value  of  %DO  has
-   leading zeros, the value is a string. ZWRITE displays the  contents  of
-   the variables.
+3 Examples
+   Examples
 
    Example:
 
+   GTM>set NG=$char($$FUNC^%HD("200B"))
+   GTM>set S=$char(26032)_NG_$CHAR(26033)
 
-   GTM>SET %DO=12
+   GTM>W $ZWidth(STR)
+   4
+   GTM>
 
-   GTM>DO ^%DO
+   In the above example, the local variable NG contains a non-graphic
+   character which does not display between two double-width characters in
+   Unicode.
 
-   GTM>ZWRITE
+   Example:
 
-   %DO="000000000014"
+   GTM>write $zwidth("The rain in Spain stays mainly in the plain.")
+   44
+   GTM>set A="************"
 
-   This example sets the read-write variable %DO to 12 and invokes %DO to
-   convert the number non-interactively. Because the number of digits was
-   not specified, %DO used the default of 12 digits. Set  %DL  to  specify
-   the number of output  digits.  ZWRITE  displays  the  contents  of  the
-   variables.
+   GTM>write $length(A)
+   12
+   GTM>write $zwidth(A)
+   24
 
-   Example:
+   In the above example, the $ZWIDTH() function returns 24 because each
+   character in A occupies 2 columns when they are displayed on the screen or
+   printer.
 
+2 $ZWRite()
+   $ZWRite()
 
-   GTM>WRITE $$FUNC^%DO(12,7)
+   Takes a single expression argument and returns that expression with the
+   non-graphic characters represented in the $CHAR() format used by the
+   ZWRITE command. Note that the non-graphic characters differ between M mode
+   and UTF-8 mode. The format of the $ZWRITE function is:
 
-   0000014
-   This example invokes %DO as an extrinsic function with the label FUNC.
-   The first argument  specifies  the  number  to  be  converted  and  the
-   optional, second argument specifies the number of output digits. If the
-   second argument is not specified, %DO uses the default of 12 digits.
+   $ZWRITE(expr)
 
-3 HD
-   %HD
+1 ISV
+   ISV
 
+   This chapter describes the M Intrinsic Special Variables implemented in
+   GT.M. All entries starting with the letter Z are GT.M additions to the
+   ANSI standard Intrinsic Special Variables. None of the Intrinsic Special
+   Variables are case sensitive.
 
-   The %HD utility converts numeric values from  hexadecimal  to  decimal.
-   %HD returns the decimal number in  the  read-write  variable  %HD.  %HD
-   rejects input numbers beginning with a minus (-) sign and returns null
-   (""). The routine has entry points for interactive  or  non-interactive
-   use.
+   M Intrinsic Special Variables start with a single dollar sign ($). GT.M
+   provides such variables for program examination. In some cases, the
+   Intrinsic Special Variables may be set to modify the corresponding part of
+   the environment.
 
-4 Util_Labels
-   Utility Labels
+   **Note**
 
-        INT Converts hexadecimal number entered  interactively  to  decimal
-        number.
-        FUNC(h) Invokes %HD as an extrinsic function returning the decimal
-        equivalent of the argument.
-4 Prompts
-   Prompts
+   None of the Intrinsic Special Variables can be KILLed. SETting or NEWing
+   is generally not allowed, but is specifically noted in the descriptions of
+   those that do.
 
-        Hexadecimal:  Requests  a  hexadecimal  number  for  conversion  to
-        decimal.
-4 Input_Vars
-   Input Variables
+2 $Device
+   $Device
 
-        %HD As input, contains input hexadecimal number.
-4 Output_Vars
-   Output Variables
+   $D[EVICE] reflects the status of the current device. If the status of the
+   device does not reflect any error-condition, the value of $DEVICE, when
+   interpreted as a truth-value is 0 (FALSE). If the status of the device
+   reflect any error-condition, the value of $DEVICE, when interpreted as a
+   truth-value is 1 (TRUE).
 
-        %HD As output, contains the converted number in decimal.
-4 Ex_of_HD
-   Examples of %HD
+   **Note**
 
-   Example:
+   The initial value of $DEVICE is implementation dependant. However, if the
+   initial value of $IO is the empty string, then the initial value of
+   $DEVICE is also empty string.
 
+   $DEVICE gives status code and meaning, in one access:
 
-   GTM>DO INT^%HD
+   Example:
 
-   Hexadecimal:E
+   1,Connection reset by peer
 
-   GTM>ZWRITE
+   The above message is displayed on the server side when the socket device
+   is closed on the client side.
 
-   %HD=14
+2 $ECode
+   $ECode
 
-   This example invokes %HD in interactive mode with INT^%HD. %HD prompts
-   for a hexadecimal number, then returns  the  converted  number  in  the
-   variable %HD. ZWRITE displays the contents of the variable.
+   $EC[ODE] contains a list of error codes for "active" errors -the error
+   conditions which are not yet resolved. If there are no active errors,
+   $ECODE contains the empty string. Whenever an error occurs, a code for
+   that error is appended to the value of $ECODE in such a way that the value
+   of $ECODE always starts and ends with a comma.
 
-   Example:
+   The value of $ECODE can be SET, and when it is set to a non-NULL value,
+   error processing starts.
 
+   List of codes for $ECODE start with comma seperated by commas. A code
+   starts with "M", "U", or "Z", with rest numeric. "M" codes are assigned by
+   MDC (MUMPS Development Committee), "U" by application (programmers), and
+   "Z" codes by MUMPS implementors (in this case GT.M).
 
-   GTM>SET %HD="E"
+   An error always has a GT.M specified code and many errors also have an
+   ANSI Standard code. The complete list of standardized error codes can be
+   referenced from GT.M Message and Recovery Procedures Reference Manual
+   version 4.3 and onwards.
 
-   GTM>DO ^%HD
+   IF $ECODE[",M61," WRITE "Undefined local variable"
 
-   GTM>ZWRITE
+   **Note**
 
-   %HD=14
+   The leftmost character of the value of $ECODE is always a comma. This
+   means that every error code that is stored in $ECODE is surrounded by
+   commas. If $ECODE was to contains the error code without the commas (that
+   is, "M61"), the variable would check for subset "M6" as well. Thus, it is
+   recommended that you include the commas in the value to check. For
+   example; check whether $ECODE contains ",M61,".
 
-   This example sets the read-write variable %HD to "E" and invokes %HD to
-   convert non-interactively the value of %HD to  a  decimal  number.  %HD
-   places the converted value into the read-write variable %HD.
+   $ECODE can be SET but not NEW'd. When $ECODE is set to the empty string ("
+   "), error handling becomes "inactive" and therefore QUIT does not trigger
+   additional error handling.
 
-   Example:
+   When $ECODE is not set to the empty string, M error handling is active,
+   which also affects behavior in some aspects of $STACK.
 
+2 $EStack
+   $EStack
 
-   GTM>WRITE $$FUNC^%HD("E")
+   $ES[TACK] contains an integer count of the number of M virtual machine
+   stack levels that have been activated and not removed since the last time
+   $ESTACK was NEW'd.
 
-   14
-   This example invokes %HD as an extrinsic function with the  label  FUNC
-   and writes the results.
+   A NEW $ESTACK saves the value of current $ESTACK and then sets its value
+   to zero (0). If $ESTACK has not been NEW'd in the current execution path,
+   $ESTACK=$STACK.
 
-3 HO
-   %HO
+   SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
 
+   $ESTACK maybe used as a flag to indicate error traps invoked in particular
+   stack levels needed to perform some different action(s). $ESTACK can be
+   most useful in setting up a layered error trapping mechanism.
 
-   The %HO utility converts numeric values from hexadecimal to octal. %HO
-   returns the octal number in the read-write variable  %HO.  %HO  rejects
-   input numbers beginning with a minus (-) sign and  returns  null  ("").
-   The routine has entry points for interactive or non-interactive use.
+   **Note**
 
-4 Util_Labels
-   Utility Labels
+   GT.M does not permit $ESTACK to be SET, however $ESTACK can be NEWed.
 
-        INT Converts hexadecimal  number  entered  interactively  to  octal
-        number.
-        FUNC(h) Invokes %HO as an extrinsic function  returning  the  octal
-        equivalent of the argument.
-4 Prompts
-   Prompts
+2 $ETrap
+   $ETrap
 
-        Hexadecimal: Requests a hexadecimal number for conversion to octal.
-4 Input_Vars
-   Input Variables
+   $ET[RAP] contains a string value that GT.M invokes when an error occurs
+   during routine execution. When a process is initiated, but before any
+   commands are processed, the value of $ETRAP is empty string.
 
-        %HO As input, contains input hexadecimal number.
-4 Output_Vars
-   Output Variables
+   The value of this variable is the M[UMPS] code that gets executed when an
+   error occurs.
 
-        %HO As output, contains the converted number in octal.
-4 Ex_of_HO
-   Examples pf %HO
+   SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
 
-   Example:
+   The value of $ETRAP is changed with the SET command. Changing the value of
+   $ETRAP with the SET command initiates a new trap; it does not save the old
+   trap.
 
+   For more examples of the use of special variable $ETRAP, see the function
+   $STACK().
 
-   GTM>DO INT^%HO
+2 $Horolog
+   $Horolog
 
-   Hexadecimal:C3
+   $H[OROLOG] contains a string value specifying the number of days since "31
+   December, 1840," and the number of seconds since midnight of the current
+   day, separated by a comma (,).
 
-   GTM>ZWRITE
+   At midnight, the piece of the string following the comma resets to zero
+   (0) and the piece preceding the comma increments by one (1). GT.M does not
+   permit the SET command to modify $HOROLOG.
 
-   %HO=303
+   Example:
 
-   This example invokes %HO in interactive mode using INT^%HO. %HO prompts
-   for a hexadecimal number that it converts to an  octal  number.  ZWRITE
-   displays the contents of the variable.
+   GTM>Write $HOROLOG
 
-   Example:
+   Produces the result 58883,55555 at 3:25:55 pm on 20 March, 2002.
 
+   For further information on formatting $HOROLOG for external use, refer to
+   "$ZDate()".
 
-   GTM>SET %HO="C3"
+2 $IO
+   $IO
 
-   GTM>DO ^%HO
+   $I[O] contains the name of the current device specified by the last USE
+   command. The M standard does not permit the SET command to modify $IO. USE
+   0 produces the same $IO as USE $P[RINCIPAL], but $P is the preferred
+   construct.
 
-   GTM>ZWRITE
+2 $Job
+   $Job
 
-   %HO=303
+   $J[OB] the current process identifier.
 
-   This example sets the read-write variable %HO to "C3" and  invokes  %HO
-   to convert the value of  %HO  non-interactively.  ZWRITE  displays  the
-   contents of the variable.
+   GT.M uses the decimal representation of the current process identifier
+   (PID) for the value of $JOB. $JOB is guaranteed to be unique for every
+   concurrently operating process on a system. However, operating systems
+   reuse PIDs over time. GT.M does not permit the SET command to modify $JOB.
 
    Example:
 
+   LOOP0 for  set itm=$order(^tmp($J,itm)) quit:itm=""  do LOOP1
 
-   GTM>WRITE $$FUNC^%HO("C3")
+   This uses $J as the first subscript in a temporary global to insure that
+   every process uses separate data space in the global ^tmp.
 
-   303
-   This example invokes %HO as an extrinsic function with the FUNC label.
+2 $Key
+   $Key
 
-3 LCASE
-   %LCASE
+   $K[EY] contains the string that terminated the most recent READ command
+   from the current device (including any introducing and terminating
+   characters). If no READ command s issued to the current device or if no
+   terminator is used, the value of $KEY is an empty string. However, when
+   input is terminated by typing a function key, the value of $KEY is equal
+   to the string of characters that is transmitted by that function key.
 
+   The effect of a READ *glvn on $KEY is unspecified.
 
-   The %LCASE utility converts a string to all lower-case  letters.  If  a
-   routine uses this function repetitively, put the utility code directly
-   into the M program.
+   If a Character Set Profile input-transform is in effect, then this is also
+   applied to the value stored in $KEY.
 
-4 Util_Labels
-   Utility Labels
+   For terminals, $ZB has the terminator.
 
-        INT Converts interactively a string to lower-case.
-        FUNC(s) Invokes %LCASE  as  an  extrinsic  function  returning  the
-        lower-case form of the argument.
-4 Prompts
-   Prompts
+2 $Principal
+   $Principal
 
-        String: Requests a string for conversion to lower case.
-4 Input_Vars
-   Input Variables
+   $P[RINCIPAL] contains the absolute pathname of the principal (initial $IO)
+   device. $PRINCIPAL is an MDC Type A enhancement to standard M.
 
-        %S As input, contains string to be converted to lower case.
-4 Output_Vars
-   Output Variables
+   Input and output for a process may come from separate devices, namely, the
+   standard input and output. However, the M I/O model allows only one device
+   to be USEd (or active) at a time. When an image starts, GT.M implicitly
+   OPENs the standard input and standard output device(s) and assigns the
+   device(s) to $PRINCIPAL. For USE deviceparameters, it is the standard
+   input that determines the device type.
 
-        %S As output, contains the converted string in lower case.
-4 Ex_of_LCASE
-   Examples of %LCASE
+   For an image invoked interactively, $PRINCIPAL is the user's terminal. For
+   an image invoked from a terminal by means of a shell script, $PRINCIPAL is
+   the shell script's standard input (usually the terminal) and standard
+   output (also usually the terminal) for output, unless the shell redirects
+   the input or output.
 
-   Example:
+   GT.M provides a mechanism for the user to create a name for $PRINCIPAL in
+   the shell before invoking GT.M. The environment variable gtm_principal, if
+   defined becomes a synonym for the actual device and the value for
+   $PRINCIPAL. $IO holds the same value as $PRINCIPAL. $ZIO in this case,
+   holds the fully expanded name of the actual device.
 
+   GT.M ignores a CLOSE specifying the principal device. GT.M does not permit
+   the SET command to modify $PRINCIPAL.
 
-   GTM>DO INT^%LCASE
+2 $Quit
+   $Quit
 
-   String: LABEL
+   $Q[UIT] indicates whether the current block of code was called as an
+   extrinsic function or as a subroutine.
 
-   Lower: label
+   If $Q[UIT] contains 1 (when the current process-stack frame is invoked by
+   an extrinsic function), the QUIT would therefore require an argument.
 
-   This example invokes  %LCASE  in  interactive  mode  using  INT^%LCASE.
-   %LCASE prompts for a string that it converts to all lower case.
+   **Note**
 
-   Example:
+   When a process is initiated, but before any commands are processed, the
+   value of $Q[UIT] is zero (0).
 
+   This special variable is mainly used in error-trapping conditions. Its
+   value tells whether the current DO level was reached by means of a
+   subroutine call (DO xxx) or by a function call (SET variable=$$xxx).
 
-   GTM>SET %S="Hello"
+   A typical way of exiting from an error trap is:
 
-   GTM>do ^%LCASE
+   QUIT:$QUIT "" QUIT
 
-   GTM>zwrite
+   **Note**
 
-   %S="hello"
+   GT.M does not permit $QUIT to be SET or NEWed.
 
-   This example sets the variable %S to the  string  "Hello"  and  invokes
-   %LCASE non-interactively to convert the string.
+2 $Reference
+   $Reference
 
-   Example:
+   $R[EFERENCE] contains the last global reference. Until the first global
+   reference is made by an M program, $REFERENCE contains the empty string
+   (""). This way it is useful in determining if the usage of a naked
+   reference is valid.
 
+   A typical way of using this is:
 
-   GTM>SET ^X="Hello"
+   IF $REFERENCE="" QUIT "<undefined>"
 
-   GTM>WRITE $$FUNC^%LCASE(^X)
+   **Note**
 
-   hello
+   $R[EFERENCE] being a read-only variable cannot be SET or NEW'd.
 
-   This example sets the variable ^X to the  string  "Hello"  and  invokes
-   %LCASE as an extrinsic function that returns "hello" in lower case.
+2 $STack
+   $STack
 
-3 OD
-   %OD
+   $ST[ACK] contains an integer value of zero (0) or greater indicating the
+   current level of M execution stack depth.
 
+   When a process is initiated but before any command is executed, the value
+   of $STACK is zero (0).
 
-   The %OD utility converts numeric values  from  octal  to  decimal.  %OD
-   returns the decimal number in the read-write variable %OD. %OD rejects
-   input numbers beginning with a minus (-) sign and  returns  null  ("").
-   The routine has entry points for interactive or non-interactive use.
+   **Note**
 
-4 Util_Labels
-   Utility Labels
+   The difference between $STACK and $ESTACK is that $ESTACK may appear as an
+   argument of the NEW command. NEWing $ESTACK resets its value to zero (0),
+   and can be useful to set up a layered error trapping mechanism.
 
-        INT Converts octal number entered interactively to decimal number.
-        FUNC(oct) Invokes  %OD  as  an  extrinsic  function  returning  the
-        decimal equivalent of the argument.
-4 Prompts
-   Prompts
+   The value of $STACK is "absolute" since the start of a GT.M. process,
+   whereas the value of $ESTACK is "relative" to the most recent "anchoring
+   point".
 
-        Octal: Requests an octal number for conversion to decimal.
-4 Input_Vars
-   Input Variables
+2 $Storage
+   $Storage
 
-        %OD As input, contains input octal number.
-4 Output_Vars
-   Output Variables
+   $S[TORAGE] contains an integer value specifying the number of free bytes
+   of address space remaining between the memory currently under management
+   by the process and the theoretical maximum available to the process.
 
-        %OD As output, contains the converted number in decimal.
-4 Ex_of_OD
-   Examples of %OD
+   GT.M uses memory for code (instructions) and data. If the amount of
+   virtual memory available to the process exceeds 2,147,483,647 bytes, it is
+   reported as 2,147,483,647 bytes.
 
-   Example:
+   Instruction space starts out with the original executable image. However,
+   GT.M may expand instruction space by ZLINKing additional routines.
 
+   Data space starts out with stack space that never expands, and pool space
+   which may expand. Operations such as opening a database or creating a
+   local variable may cause an expansion in pool space. GT.M expands pool
+   space in fairly large increments. Therefore, SETs of local variables may
+   not affect $STORAGE at all or may cause an apparently disproportionate
+   drop in its value.
 
-   GTM>DO INT^%OD
+   Once a GT.M process adds either instruction or data space, it never
+   releases that space. However, GT.M does reuse process space made available
+   by actions such as KILLs of local variables. $STORAGE can neither be SET
+   or NEWed.
 
-   Octal:14
+2 $SYstem
+   $SYstem
 
-   GTM>ZWRITE
+   $SY[STEM] contains a string that identifies the executing M instance. The
+   value of $SYSTEM is a string that starts with a unique numeric code that
+   identifies the manufacturer. Codes are assigned by the MDC (MUMPS
+   Development Committee).
 
-   %OD=12
+   $SYSTEM in GT.M starts with "47" followed by a comma and the evaluation of
+   the environment variable gtm_sysid. If the name has no evaluation, the
+   value after the comma is gtm_sysid.
 
-   This example invokes INT^%OD to interactively convert the octal number
-   entered. %OD prompts for an octal number that it converts to a decimal.
-   %OD returns the converted value in the variable %OD.
+2 $Test
+   $Test
 
-   Example:
+   $T[EST] contains a truth value specifying the evaluation of the last IF
+   argument or the result of the last operation with timeout. If the last
+   timed operation timed out, $TEST contains FALSE (0); otherwise, it
+   contains TRUE (1).
 
+   $TEST serves as the implicit argument for ELSE commands and argumentless
+   IF commands.
 
-   GTM>SET %OD=14
+   M stacks $TEST when invoking an extrinsic and performing an argumentless
+   DO. After these operations complete with an implicit or explicit QUIT, M
+   restores the corresponding stacked value. Because, with these two
+   exceptions, $TEST reflects the last IF argument or timeout result on a
+   process wide basis. Use $TEST only in immediate proximity to the operation
+   that last updated it.
 
-   GTM>DO ^%OD
+   M routines cannot modify $TEST with the SET command.
 
-   GTM>ZWRITE
+   Example:
 
-   %OD=12
+   IF x=+x DO ^WORK
+   ELSE SET x=0
 
-   This example sets the read-write variable %OD to 14 and invokes %OD to
-   convert the number non-interactively. ZWRITE displays the  contents  of
-   the variables.
+   The ELSE statement causes M to use the value of $TEST to determine whether
+   to execute the rest of the line. Because the code in routine WORK may use
+   IFs and timeouts, this use of $TEST is not recommended.
 
    Example:
 
+   SET MYFLG=x=+x
+   IF MYFLG DO ^WORK
+   IF 'MYFLG SET x=0
 
-   GTM>WRITE $$FUNC^%OD(14)
-
-   12
-   This example invokes %OD as an extrinsic function with the FUNC label.
-   The argument specifies the number to be converted.
-
-3 OH
-   %OH
+   This example introduces a local variable flag to address the problems of
+   the prior example. Note that its behavior results in the opposite $TEST
+   value from the prior example.
 
+   Example:
 
-   The %OH utility converts numeric values from octal to hexadecimal. %OH
-   returns the hexadecimal number in  the  read-write  variable  %OH.  %OH
-   rejects input numbers beginning with a minus (-) sign. The routine has
-   entry points for interactive or  non-interactive  use.  In  interactive
-   mode, %OH rejects non-octal numbers with the following message, "Input
-   must be an octal number". In non-interactive mode, %OH returns  a  null
-   string ("") upon encountering a non-octal number.
+   IF x=+x DO ^WORK IF 1
+   ELSE SET x=0
 
-4 Util_Labels
-   Utility Labels
+   This example uses the IF 1 to ensure that the ELSE works counter to the
+   IF.
 
-        INT Converts interactively  octal  number  entered  to  hexadecimal
-        number.
-        FUNC(oct) Invokes  %OH  as  an  extrinsic  function  returning  the
-        hexadecimal equivalent of the argument.
-4 Prompts
-   Prompts
+2 $TLevel
+   $TLevel
 
-        Octal: Requests an octal number for conversion to hexadecimal.
-4 Input_Vars
-   Input Variables
+   $TL[EVEL] contains a count of executed TSTARTs that are currently
+   unmatched by TCOMMITs. $TLEVEL is zero (0) when there is no TRANSACTION in
+   progress. When $TLEVEL is greater than one (>1), it indicates that there
+   are nested sub-transactions in progress. Sub-transactions are always
+   subject to the completion of the main TRANSACTION and cannot be
+   independently acted upon by COMMIT, ROLLBACK, or RESTART.
 
-        %OH As input, contains input octal number.
-4 Output_Vars
-   Output Variables
+   $TLEVEL can be used to determine whether there is a TRANSACTION in
+   progress and to determine the level of nesting of sub-transactions.
 
-        %OH As output, contains the converted number in hexadecimal.
-4 Ex_of_OH
-   Examples of %OH
+   M routines cannot modify $TLEVEL with SET.
 
    Example:
 
+   IF $TLEVEL TROLLBACK
+
+   This example performs a TROLLBACK if a transaction is in progress. A
+   statement like this should appear in any error handler used with
+   transaction processing.
 
-   GTM>DO INT^%OH
+2 $TRestart
+   $TRestart
 
-   Octal:16
+   $TR[ESTART] contains a count of the number of times the current
+   TRANSACTION has been RESTARTed. A RESTART can be explicit (specified in M
+   as a TRESTART) or implicit (initiated by GT.M as part of its internal
+   concurrency control mechanism). $TRESTART can have values of 0 through 4.
+   When there is no TRANSACTION in progress, $TRESTART is zero (0).
 
-   GTM>ZWRITE
+   $TRESTART can be used by the application to limit the number of RESTARTs,
+   or to cause a routine to perform different actions during a RESTART than
+   during the initial execution.
 
-   %OH="E"
+   **Note**
 
-   This example invokes %OH in interactive mode using INT^%OH. %OH prompts
-   for an octal number that it converts to a  hexadecimal  number.  ZWRITE
-   displays the contents of the variable.
+   GT.M does not permit the SET command to modify $TRESTART.
 
    Example:
 
+   TRANS TSTART ():SERIAL
+   IF $TRESTART>2 WRITE !;"Access Conflict" QUIT
 
-   GTM>SET %OH=16
+   This example terminates the sub-routine with a message if the number of
+   RESTARTs exceeds 2.
 
-   GTM>DO ^%OH
+2 $X
+   $X
 
-   GTM>ZWRITE
+   $X contains an integer value ranging from 0 to 65,535, specifying the
+   horizontal position of a virtual cursor in the current output record. $X=0
+   represents the left-most position of a record or row.
 
-   %OH="E"
+   Every OPEN device has a $X. However, M only accesses $X of the current
+   device. Therefore, exercise care in sequencing USE commands and references
+   to $X.
 
-   This example sets the read-write variable %OH to 16 and invokes %OH to
-   convert  the  value  of  %OH  non-interactively.  ZWRITE  displays  the
-   contents of the variable.
+   Generally, GT.M increments $X for every character written to and read from
+   the current device. Usually, the increment is 1, but for a process in
+   UTF-8 mode, the increment is the number of glyphs or codepoints (depends
+   on the type of device). M format control characters, write filtering, and
+   the device WIDTH also have an effect on $X.
 
-   Example:
+   $X never equals or exceeds the value of the device WIDTH. Whenever it
+   reaches the value equal to the device WIDTH, it gets reset to zero (0).
 
+   GT.M follows the MDC Type A recommendation and permits an M routine to SET
+   $X. However, SET $X does not automatically issue device commands or escape
+   sequences to reposition the physical cursor.
 
-   GTM>WRITE $$FUNC^%OH(16)
+2 $Y
+   $Y
 
-   E
+   $Y contains an integer value ranging from 0 to 65,535 specifying the
+   vertical position of a virtual cursor in the current output page. $Y=0
+   represents the top row or line.
 
-   This example invokes %OH as an extrinsic function with the FUNC label.
+   Every OPEN device has a $Y. However, M only accesses $Y of the current
+   device. Therefore, exercise care in sequencing USE commands and references
+   to $Y.
 
-3 UCASE
-   %UCASE
+   When GT.M finishes the logical record in progress, it generally increments
+   $Y. GT.M recognizes the end of a logical record when it processes certain
+   M format control characters, or when the record reaches its maximum size,
+   as determined by the device WIDTH, and the device is set to WRAP. The
+   definition of "logical record" varies from device to device. For an exact
+   definition, see the sections on each device type. Write filtering and the
+   device LENGTH also have an effect on $Y.
 
+   $Y never equals or exceeds the value of the device LENGTH. Whenever it
+   reaches the value equal to the device LENGTH, it gets reset to zero (0)
 
-   The %UCASE utility converts a string to all upper-case  letters.  If  a
-   routine uses this function repetitively, put the utility code directly
-   into the M program.
+   GT.M permits an M routine to SET $Y. However, SET $Y does not
+   automatically issue device commands or escape sequences to reposition the
+   physical cursor.
 
-4 Util_Labels
-   Utility Labels
+2 $ZA
+   $ZA
 
-        INT Converts a string to upper case interactively.
-        FUNC(s) Invokes %UCASE as  an  extrinsic  function,  returning  the
-        upper-case form of the argument.
-4 Prompts
-   Prompts
+   $ZA contains a status determined by the last read on the device. The value
+   is a decimal integer with a meaning determined by the device as follows:
 
-        String: Requests a string for conversion to upper case.
-4 Input_Vars
-   Input Variables
+   For Terminal I/O:
 
-        %S As input, contains string to be converted to upper case.
-4 Output_Vars
-   Output Variables
+   0Indicating normal termination of a read operation
 
-        %S As output, contains the converted string in upper case.
-4 Ex_of_UCASE
-   Examples of %UCASE
+   1: Indicating a parity error
 
-   Example:
+   2: Indicating that the terminator sequence was too long
 
+   9: Indicating a default for all other errors
 
-   GTM>DO INT^%UCASE
+   For Sequential Disk and Tape Files I/O:
 
-   String: test
+   0: Indicating normal termination of a read operation
 
-   Upper: TEST
+   9: Indicating a failure of a read operation
 
-   This example invokes  %UCASE  in  interactive  mode  using  INT^%UCASE.
-   %UCASE prompts for a string that it converts to all upper case.
+   For Fifos I/O:
 
-   Example:
+   Decimal representing $JOB (identifier) of the process that wrote the last
+   message the current process read
 
+   $ZA refers to the status of the current device. Therefore, exercise care
+   in sequencing USE commands and references to $ZA.
 
-   GTM>SET ^X="hello"
+   GT.M does not permit the SET command to modify $ZA.
 
-   GTM>WRITE $$FUNC^%UCASE(^X)
+   For more information on $ZA, refer "Input/Output Processing".
 
-   HELLO
+2 $ZALlocstor
+   $ZALlocstor
 
-   This example sets the variable X to  the  string  "hello"  and  invokes
-   %UCASE as an extrinsic function that returns "HELLO" in upper case.
+   $ZALLOCSTOR contains the number of bytes that are (sub) allocated
+   (including overhead) by GT.M for various activities. It provides one view
+   (see also $ZREALSTOR and $ZUSEDSTOR) of the process memory utilization and
+   can help identify storage related problems. GT.M does not permit
+   $ZALLOCSTOR to be SET or NEWed.
 
-2 Math_Util
-   Mathematic Utilities
+2 $ZB
+   $ZB
 
-   The mathematic utilities are:
+   $ZB contains a string specifying the input terminator for the last
+   terminal READ. $ZB contains null and is not maintained for devices other
+   than terminals. $ZB may contain any legal input terminator, such as <CR>
+   (ASCII 13) or an escape sequence starting with <ESC> (ASCII 27), from zero
+   (0) to 15 bytes in length. $ZB contains null for any READ terminated by a
+   timeout or any fixed-length READ terminated by input reaching the maximum
+   length.
 
-        %EXP Raises one number to the power of another number.
-        %SQROOT Calculates the square root of a number.
-   The mathematic utilities can be invoked as extrinsic functions.
+   $ZB contains the actual character string, not a sequence of numeric ASCII
+   codes.
 
-   The  "%"  sign  has  been  removed  from  the  topic  headings  below,
-   intentionally.
+   Example:
 
-3 EXP
-   %EXP
+   SET zb=$ZB FOR i=1:1:$L(zb) WRITE !,i,?5,$A(zb,i)
 
+   This displays the series of ASCII codes for the characters in $ZB.
 
-   The %EXP utility raises one number provided to  the  power  of  another
-   number provided. While this utility provides an  interactive  interface
-   for exponential calculations, most production code would perform inline
-   calculation with the "**" operator. The routine has  entry  points  for
-   interactive or non-interactive use.
+   $ZB refers to the last READ terminator of the current device. Therefore,
+   exercise care in sequencing USE commands and references to $ZB.
 
-4 Util_Labels
-   Utility Labels
+   GT.M does not permit the SET command to modify $ZB.
 
-        INT  Calculates  a  number  to  the  power  of  another  number
-        interactively.
-        FUNC(i,j) Invokes %EXP as an extrinsic function returning the first
-        argument raised to the power of the second argument.
-4 Prompts
-   Prompts
+   For more information on $ZB, refer to the "Input/Output Processing"
+   chapter.
 
-        Power: Requests an exponent or power.
-        Number: Requests a base number to raise by the power.
-4 Input_Vars
-   Input Variables
+2 $ZCHset
+   $ZCHset
 
-        %I As input, contains number to be raised to a power.
-        %J Contains exponential power by which to raise %I.
-4 Output_Vars
-   Output Variables
+   $ZCHSET is a read-only intrinsic special variable that takes its value
+   from the environment variable gtm_chset. An application can obtain the
+   character set used by a GT.M process by the value of $ZCHSET. $ZCHSET can
+   have only two values --"M", or "UTF-8".
 
-        %I As output, contains the result of the exponential calculation.
-4 Ex_of_EXP
-   Examples of %EXP
+   GT.M only supports Unicode on certain platforms. On platforms where it is
+   not supported, the intrinsic variable $ZCHSET is always "M" ignoring the
+   value of the environment variable gtm_chset even if it is defined.
 
    Example:
 
+   $ export gtm_chset=UTF-8
+   $ /usr/lib/fis-gtm/V6.0-001_x86/gtm
+   GTM>write $zchset
+   UTF-8
+   GTM>
 
-   GTM>DO INT^%EXP
-
-   Power: 3
+2 $ZCMdline
+   $ZCMdline
 
-   Number: 12
+   $ZCM[DLINE] contains a string value specifying the "excess" portion of the
+   command line that invoked the GT.M process. By "excess" is meant the
+   portion of the command line that is left after GT.M has done all of its
+   command line processing. For example, a command line mumps -direct extra1
+   extra2 causes GT.M to process the command line upto mumps -direct and
+   place the "excess" of the command line, that is "extra1 extra2" in
+   $ZCMDLINE. $ZCMDLINE gives the M routine access to the shell command line
+   input.
 
-   12 raised to 3 is 1728
-   This example invokes %EXP in  interactive  mode  using  INT^%EXP.  %EXP
-   prompts for an exponent (power) and a base number.
+   Note that the actual user input command line might have been transformed
+   by the shell (for example, removing one level of quotes, filename, and
+   wildcard substituion, and so on.), and it is this transformed command line
+   that GT.M processes.
 
    Example:
 
+   $ cat > test.m
+   write " $ZCMDLINE=",$ZCMDLINE,!
+   quit
+   $ mumps -run test OTHER  information
+   $ZCMDLINE=OTHER information
+   $
 
-   GTM>SET %I=2,%J=9
+   This creates the program test.m, which writes the value of $ZCMDLINE. Note
+   how the two spaces specified in OTHER information in the command line gets
+   transformed to just one space in OTHER information in $ZCMDLINE due to the
+   shell's pre-processing.
 
-   GTM>DO ^%EXP
+   Example:
 
-   GTM>ZWRITE
+   $ cat foo.m
+   foo     ; a routine to invoke an arbitrary entry with or without
+    parameters
+      ;
+     set $etrap="" ; exit if the input isn't valid
+     if $length($zcmdline) do @$zcmdline quit
+     quit
 
-   %I=512
+   $ mumps -run foo 'BAR^FOOBAR("hello")'
 
-   %J=9
+   In this example, GT.M processes the shell command line up to foo and puts
+   the rest in $ZCMDLINE. This mechanism allows mumps -run to invoke an
+   arbitrary entryref with or without parameters. Note that this example
+   encloses the command line argument with single quotes to prevent
+   inappropriate expansion in Bourne-type shells. Always remember to use the
+   escaping and quoting conventions of the shell and GT.M to prevent
+   inappropriate expansion.
 
-   This example sets the read-write variable %I to 2, variable  %J  to  9,
-   and invokes %EXP to calculate the result. ZWRITE displays the contents
-   of the variables. %I contains the result.
+   **Important**
 
-   Example:
+   Use the ^%XCMD utility to XECUTEs code from the shell command line and
+   return any error status (truncated to a single byte on UNIX) that the code
+   generates.
 
+2 $ZCOmpile
+   $ZCOmpile
 
-   GTM>WRITE $$FUNC^%EXP(2,9)
+   $ZCO[MPILE] contains a string value composed of one or more qualifiers
+   that control the GT.M compiler. Explicit ZLINKs and auto-ZLINKs use these
+   qualifiers as defaults for any compilations that they perform.
 
-   512
-   This example invokes %EXP as an extrinsic function with the label FUNC.
+   $ZCOMPILE is a read-write ISV, that is, it can appear on the left side of
+   the equal sign (=) in the argument to the SET command. A $ZCOMPILE value
+   has the form of a list of M command qualifiers each separated by a space (
+   ).
 
+   When the environment variable gtmcompile is defined, GT.M initializes
+   $ZCOMPILE to the translation of gtmcompile. Otherwise GT.M initializes
+   $ZCOMPILE to null. Changes to the value of $ZCOMPILE during a GT.M
+   invocation only last for the current invocation and do not change the
+   value of the environment variable gtmcompile.
 
-3 SQROOT
-   %SQROOT
+   ZCOMPILE returns a status of 1 after any error in compilation.
 
+   When $ZCOMPILE is null, GT.M uses the default M command qualifiers
+   -IGNORE, -LABEL=LOWER, -NOLIST, and -OBJECT.
 
-   The %SQROOT utility calculates the square root of  a  number  provided.
-   While this utility provides an interactive interface for taking square
-   roots, most production code would perform inline calculation by raising
-   a number to the .5 power (n**.5). The  routine  has  entry  points  for
-   interactive or non-interactive use.
+   Example:
 
-4 Util_Labels
-   Utility Labels
+   $ export gtmcompile="-LIST -LENGTH=56 -SPACE=2"
+   $ gtm
+   GTM>WRITE $ZCOMPILE
+   -LIST -LENGTH=56 -SPACE=2
+   GTM>SET $ZCOMPILE="-LIST -NOIGNORE"
+   GTM>WRITE $ZCOMPILE
+   -LIST -NOIGNORE
+   GTM>ZLINK "A.m"
+   GTM>HALT
+   $ echo $gtmcompile
+   -LIST -LENGTH=56 -SPACE=2
 
-        INT Calculates the square root of a number interactively.
-        FUNC(s) Invokes %SQROOT as  an  extrinsic  function  returning  the
-        square root of the argument.
-4 Prompts
-   Prompts
+   This example uses the environment variable gtmcompile to set up $ZCOMPILE.
+   Then it modifies $ZCOMPILE with the SET command. The ZLINK argument
+   specifies a file with a .m extension (type), which forces a compile. The
+   compile produces a listing for routine A.m and does not produce an object
+   module if A.m contains compilation errors. After GT.M terminates, the
+   shell command echo $gtmcompile demonstrates that the SET command did not
+   change the environment variable.
 
-        The square root of: Requests a number.
-4 Input_Vars
-   Input Variables
+2 $ZCstatus
+   $ZCstatus
 
-        %X Contains the number for which to calculate the square root.
-4 Output_Vars
-   Output Variables
+   $ZC[STATUS] holds the value of the status code for the last compilation
+   performed by a ZCOMPILE command.
 
-        %Y Contains the square root of %X.
-4 Ex_of_SQROOT
-   Examples of %SQROOT
+   GT.M does not permit the SET command to modify $ZSTATUS.
 
-   Example:
+2 $ZDAteform
+   $ZDAteform
 
+   $ZDA[TEFORM] contains an integer value, specifying the output year format
+   of $ZDATE(). $ZDATEFORM can be modified using the SET command. GT.M
+   initializes $ZDATEFORM to the translation of the environment variable
+   gtm_zdate_form. If gtm_zdate_form is not defined, GT.M initializes
+   $ZDATEFORM to zero (0).
 
-   GTM>SET %X=81
+   Refer to "Functions" and "Utility Routines" chapters in the GT.M
+   Programmer's Guide for more details.
 
-   GTM>DO ^%SQROOT
+   Example:
 
-   GTM>ZWRITE
+   GTM>WRITE $ZDATEFROM
+   0
+   GTM>WRITE $ZDATE($H)
+   11/15/02
+   GTM>SET $ZDATEFORM=1
+   GTM>WRITE $ZDATE($H)
+   11/15/2002
 
-   %X=81
+2 $ZDirectory
+   $ZDirectory
 
-   %Y=9
+   $ZD[IRECTORY] contains the string value of the full path of the current
+   directory. Initially $ZDIRECTORY contains the default/current directory
+   from which the GT.M image/process was activated.
 
-   This example sets  the  variable  %X  to  81  and  invokes  %SQROOT  to
-   calculate  the  square  root  non-interactively.  ZWRITE  displays  the
-   contents of the variables.
+   If the current directory does not exist at the time of GT.M process
+   activation, GT.M errors out.
 
    Example:
 
+   GTM>WRITE $ZDIR
+   /usr/tmp
+   GTM>SET $ZDIR=".."
+   GTM>WRITE $ZDIR
+   /usr
 
-   GTM>DO INT^%SQROOT
-
-   The square root of: 81 is: 9
-
-   The square root of: <RETURN>
-
-   GTM>
+   This example displays the current working directory and changes $ZDIR to
+   the parent directory.
 
-   This example invokes  INT^%SQROOT  interactively  that  prompts  for  a
-   number. The square root of the number appears on the same line. %SQROOT
-   then prompts for another number. Press <RETURN> to exit.
+   $ZDIRECTORY is a read-write Intrinsic Special Variable, that is, it can
+   appear on the left side of the equal sign (=) in the argument to a SET
+   command. If an attempt is made to set $ZDIRECTORY to a non-existent
+   directory specification, GT.M issues an error and keeps the value of
+   $ZDIRECTORY unchanged.
 
-   Example:
+   At image exit, GT.M restores the current directory to the directory that
+   was the current directory when GT.M was invoked even if that directory
+   does not exist.
 
+2 $ZEDit
+   $ZEDit
 
-   GTM>WRITE $$FUNC^%SQROOT(81)
+   $ZED[IT] holds the value of the status code for the last edit session
+   invoked by a ZEDIT command.
 
-   9
-   This example invokes %SQROOT as an extrinsic function  with  the  label
-   FUNC.
+   GT.M does not permit the SET or NEW command to modify $ZEDIT.
 
-2 Glob_Util
-   Global Utilities
+2 $ZEOf
+   $ZEOf
 
-   The Global utilities are:
+   $ZEO[F] contains a truth-valued expression indicating whether the last
+   READ operation reached the end-of-file. $ZEOF equals TRUE (1) at EOF and
+   FALSE (0) at other positions.
 
-        %G Displays global variables and their values.
-        %GC Copies a global or global sub-tree.
-        %GCE Replaces a specified value or part of a  value  in  a  set  of
-        variables.
-        %GD Displays existing  globals  in  the  current  global  directory
-        without displaying their values or descendants.
-        %GED Provides full-screen editing capabilities for global variables
-        and values.
-        %GI Loads global data from a sequential file into a GT.M database.
-        %GO Extracts global data from a GT.M  database  into  a  sequential
-        file.
-        %GSE Displays global variables and their  values  when  the  values
-        contain a specified string or number.
-        %GSEL Selects globals.
-   The  "%"  sign  has  been  removed  from  the  topic  headings  below,
-   intentionally.
+   GT.M does not maintain $ZEOF for terminal devices.
 
-3 G_
-   %G
+   $ZEOF refers to the end-of-file status of the current device. Therefore,
+   exercise care in sequencing USE commands and references to $ZEOF.
 
+   GT.M does not permit the SET or NEW command to modify $ZEOF.
 
-   The %G utility  displays  names,  descendants  and  values  of  globals
-   currently existing in the database. Use %G to examine global variables
-   and their values. Enter a question mark (?) at any  prompt  to  display
-   help information.
+   For more information on $ZEOF, refer to the "Input/Output Processing"
+   chapter.
 
-4 Prompts
-   Prompts
+2 $ZError
+   $ZError
 
-        Output Device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-        List ^ Requests the name, in ZWRITE format, of a global to display.
-4 Ex_of_G
-   Examples of %G
+   $ZE[RROR] is supposed to hold the application-specific error-code
+   corresponding to the GT.M error-code stored in $ECODE/$ZSTATUS.
 
-   Example:
+   $ZERROR contains a default value of "Unprocessed $ZERROR, see $ZSTATUS" at
+   process startup.
 
+   $ZERROR can be SET but not NEWed.
 
-   GTM>do ^%G
+   The mapping of a GT.M error-code to the application-specific error-code is
+   achieved as follows. Whenever GT.M encounters an error, $ECODE/$ZSTATUS
+   gets set first. It then invokes the code that $ZYERROR points to if it is
+   not null. It is intended that the code invoked by $ZYERROR use the value
+   of $ZSTATUS to select or construct a value to which it SETs $ZERROR. If an
+   error is encountered by the attempt to execute the code specified in
+   $ZYERROR, GT.M sets $ZERROR to the error status encountered. If $ZYERROR
+   is null, GT.M does not change the value of $ZERROR. In all cases, GT.M
+   proceeds to return control to the code specified by $ZTRAP/$ETRAP or
+   device EXCEPTION whichever is applicable.
 
-   Output Device: <terminal>: <RETURN>
+2 $ZGbldir
+   $ZGbldir
 
-   List ^C
+   $ZG[BLDIR] contains the value of the current Global Directory filename.
+   When $ZGBLDIR specifies an invalid or inaccessible file, GT.M cannot
+   successfully perform database operations.
 
-   ^C="CLASS"
+   GT.M initializes $ZGBLDIR to the translation of the environment variable
+   gtmgbldir. The value of the gtmgbldir environment variable may include a
+   reference to another environment variable. If gtmgbldir is not defined,
+   GT.M initializes $ZGBLDIR to null. When $ZGBLDIR is null, GT.M constructs
+   a file name for the Global Directory using the name $gtmgbldir and the
+   extension .gld in the current working directory.
+
+   $ZGBLDIR is a read-write Intrinsic Special Variable, (i.e., it can appear
+   on the left side of the equal sign (=) in the argument to the SET
+   command). SET $ZGBLDIR="" causes GT.M to assign $ZGBLDIR to the
+   translation of gtmgbldir if that environment variable is defined. If it is
+   not defined, then SET $ZGBLDIR="" causes GT.M to construct a file name
+   using the name $gtmgbldir.gld in the current directory. GT.M permits
+   $ZGBLDIR to be NEW'd. A $ZGBLDIR value may include an environment
+   variable.
 
-   ^C(1)="MARY"
+   SETting $ZGBLDIR also causes GT.M to attempt to open the specified file.
+   If the file name is invalid or the file is inaccessible, GT.M triggers an
+   error without changing the value of $ZGBLDIR.
 
-   ^C(1,2)="MATH"
+   To establish a value for $ZGBLDIR outside of M, use the appropriate shell
+   command to assign a translation to gtmgbldir. Defining gtmgbldir provides
+   a convenient way to use the same Global Directory during a session where
+   you repeatedly invoke and leave GT.M.
 
-   ^C(1,2,1)=80
+   Changes to the value of $ZGBLDIR during a GT.M invocation only last for
+   the current invocation and do not change the value of gtmgbldir.
 
-   ^C(1,3)="BIO"
+   Example:
 
-   ^C(1,3,1)=90
+   $ gtmgbldir=test.gld
+   $ export gtmgbldir
+   $ gtm
+   GTM>WRITE $zgbldir
+   /usr/dev/test.gld
+   GTM>SET $zgbldir="mumps.gld"
+   GTM>WRITE $zgbldir
+   mumps.gld
+   GTM>HALT
+   $ echo $gtmgbldir
+   test.gld
 
-   ^C(2)="JOHN"
+   This example defines the environment variable gtmgbldir. Upon entering
+   GT.M Direct Mode, $ZGBLDIR has the value supplied by gtmgbldir. The SET
+   command changes the value. After the GT.M image terminates, the echo
+   command demonstrates that gtmgbldir was not modified by the M SET command.
 
-   ^C(3)="PETER"
+   $ ls test.gld
+   test.gld not found
+   $ gtm
+   GTM>WRITE $zgbldir
+   /usr/dev/mumps.gld
+   GTM>set $zgbldir="test.gld"
+   %GTM-E-ZGBLDIRACC, Cannot access global directory
+   "/usr/dev/test.gld". Retaining /usr/dev/mumps.gld"
+   %SYSTEM-E-ENO2, No such file or directory
+   GTM>WRITE $zgbldir
+   /usr/dev/mumps.gld
+   GTM>halt
+   $
 
-   List ^ <RETURN>
+   The SET command attempts to change the value of $ZGBLDIR to test.gld.
+   Because the file does not exist, GT.M reports an error and does not change
+   the value of $ZGBLDIR.
 
-   GTM>
+   **Caution**
 
-   This example lists the nodes of global ^C. %G displays the  global  and
-   its descendants and values, if the node exists.
+   Attempting to restore an inaccessible initial Global Directory that has
+   been NEW'd, can cause an error.
 
-   Example:
+  Note
 
+   Attempting to restore an inaccessible initial Global Directory that has
+   been NEW'd, can cause an error.
 
-   GTM>do ^%G
+2 $ZINTerrupt
+   $ZINTerrupt
 
-   Output Device: <terminal>: <RETURN>
+   $ZINT[ERRUPT] specifies the code to be XECUTE'd when an interrupt (for
+   example, through a MUPIP INTRPT) is processed. While a $ZINTERRUPT action
+   is in process, any additional interrupt signals are discarded. When an
+   interrupt handler is invoked, the current values of $REFERENCE is saved
+   and restored when the interrupt handler returns. The current device ($IO)
+   is neither saved nor restored.
 
-   List ^C(1)
+   GT.M permits the SET command to modify the value of $ZINTERRUPT.
 
-   ^C(1)="MARY"
+   If an interrupt handler changes the current IO device (via USE), it is the
+   responsibility of the interrupt handler to restore the current IO device
+   before returning. There are sufficient legitimate possibilities why an
+   interrupt routine would want to change the current IO device (for example;
+   daily log switching), that this part of the process context is not saved
+   and restored automatically.
 
-   This example lists only the node entered and its value.
+   The initial value for $ZINTERRUPT is taken from the UNIX environment
+   variable gtm_zinterrupt if it is specified, otherwise it defaults to the
+   following string:
 
-   Example:
+   IF $ZJOBEXAM()
 
+   The IF statement executes the $ZJOBEXAM function but effectively discards
+   the return value.
+
+   **Note**
+
+   If the default value for $ZINTERRUPT is modified, no $ZJOBEXAM() will
+   occur unless the replacement value directly or indirectly invokes that
+   function. In other words, while $ZJOBEXAM() is part of the interrupt
+   handling by default, it is not an implicit part of the interrupt handling.
+
+3 Interrupt_Handling
+   Interrupt Handling
+
+   GT.M process execution is interruptible with the following events:
+
+   When GT.M detects any of these events, it transfers control to a vector
+   that depends on the event. For CTRAP characters and ZMAXTPTIME, GT.M uses
+   the $ETRAP or $ZTRAP vectors described in more detail in the Error
+   Processing chapter. For INTRPT and $ZTEXit, it XECUTEs the interrupt
+   handler code placed in $ZINTERRUPT. If $ZINTERRUPT is an empty string,
+   nothing is done in response to a MUPIP INTRPT. The default value of
+   $ZINTERRUPT is "IF $ZJOBEXAM()" which redirects a dump of ZSHOW "*" to a
+   file and reports each such occasion to the operator log. For CTRL+C with
+   CENABLE, it enters Direct Mode to give the programmer control.
+
+   GT.M recognizes most of these events when they occur but transfers control
+   to the interrupt vector at the start of each M line, at each iteration of
+   a FOR LOOP, at certain points during the execution of commands which may
+   take a "long" time. For example, ZWRITE, HANG, LOCK, MERGE, ZSHOW "V",
+   OPENs of disk files and FIFOs, OPENs of SOCKETs with the CONNECT parameter
+   (unless zero timeout,) WRITE /WAIT for SOCKETs, and READ for terminals,
+   SOCKETs, FIFOs, and PIPEs. If +$ZTEXIT evaluates to a truth value at the
+   outermost TCOMMIT or TROLLBACK, GT.M XECUTEs $ZINTERRUPT after completing
+   the commit or rollback. CTRAP characters are recognized when they are
+   typed on OpenVMS but when they are read on UNIX.
+
+   If an interrupt event occurs in a long running external call (for example,
+   waiting in a message queue), GT.M recognizes the event but makes the
+   vector transfer after the external call returns when it reaches the next
+   appropriate execution boundary.
+
+   When an interrupt handler is invoked, GT.M saves and restores the current
+   values of $REFERENCE. However, the current device ($IO) is neither saved
+   nor restored. If an interrupt handler changes $IO (via USE), ensure that
+   the interrupt handler restores the current device before returning. To
+   restore the device which was current when the interrupt handler began,
+   specify USE without any deviceparameters. Any attempt to do IO on a device
+   which was actively doing IO when the interrupt was recognized may result
+   in a ZINTERCURSEIO error.
+
+   Example:
+
+   set $zinterrupt="do ^interrupthandler($io)"
+
+   interrupthandler(currentdev)
+          do ^handleinterrupt ; handle the interrupt
+          use currentdev      ; restore the device which was current when the interrupt was recognized
+          quit
+
+   The use of the INTRPT facility may create a temporary hang or pause while
+   the interrupt handler code is executed. For the default case where the
+   interrupt handler uses IF $ZJOBEXAM() to create a dump, the pause duration
+   depends on the number of local variables in the process at the time of the
+   dump and on the speed of the disk being written to. The dumps are slower
+   on a network-mounted disk than on a disk directly connected to the local
+   system. Any interrupt driven code should be designed to account for this
+   issue.
 
-   GTM>do ^%G
+   **Important**
+
+   Because sending an interrupt signal requires the sender to have
+   appropriate permissions, the use of the job interrupt facility itself does
+   not present any inherent security exposures. Nonetheless, because the dump
+   files created by the default action contain the values of every local
+   variable in the context at the time they are made, inappropriate access to
+   the dump files would constitute a security exposure. Make sure the design
+   and implementation of any interrupt logic includes careful consideration
+   to security issues.
+
+   During the execution of the interrupt handling code, $ZINITERRUPT
+   evaluates to 1 (TRUE).
+
+   If an error occurs while compiling the $ZINTERRUPT code, the error handler
+   is not invoked (the error handler is invoked if an error occurs while
+   executing the $ZINTERRUPT code), GT.M sends the GTM-ERRWZINTR message and
+   the compiler error message to the operator log facility. If the GT.M
+   process is at a direct mode prompt or is executing a direct mode command
+   (for example, a FOR loop), GT.M sends also sends the GTM-ERRWZINTR error
+   message to the user console along with the compilation error. In both
+   cases, the interrupted process resumes execution without performing any
+   action specified by the defective $ZINTERRUPT vector.
+
+   If GT.M encounters an error during creation of the interrupt handler's
+   stack frame (before transferring control to the application code specified
+   by the vector), that error is prefixed with a GTM-ERRWZINTR error. The
+   error handler then executes normal error processing associated with the
+   interrupted routine.
+
+   **Note**
+
+   The interrupt handler does not operate "outside" the current M environment
+   but rather within the environment of the process.
+
+   TP transaction is in progress (0<$TLEVEL), updates to globals are not safe
+   since a TP restart can be signaled at any time prior to the transaction
+   being committed - even after the interrupt handler returns. A TP restart
+   reverses all global updates and unwinds the M stack so it is as if the
+   interrupt never occurred. The interrupt handler is not redriven as part of
+   a transaction restart. Referencing (reading) globals inside an interrupt
+   handler can trigger a TP restart if a transaction is active. When
+   programming interrupt handling, either discard interrupts when 0<$TLEVEL
+   (forcing the interrupting party to try again), or use local variables that
+   are not restored by a TRESTART to defer the interrupt action until after
+   the final TCOMMIT.
 
-   Output Device: <terminal>: <RETURN>
+2 $ZINInterrupt
+   $ZINInterrupt
 
-   List ^C(1,*)
+   $ZINI[NTERRUPT] evaluates to 1 (TRUE) when a process is executing code
+   initiated by the interrupt mechanism, and otherwise 0 (FALSE).
 
-   ^C(1)="MARY"
+   GT.M does not permit the SET or NEW commands to modify $ZININTERRUPT.
 
-   ^C(1,2)="MATH"
+2 $ZIO
+   $ZIO
 
-   ^C(1,2,1)=80
+   $ZIO contains the translated name of the current device, in contrast to
+   $IO, which contains the name as specified by the USE command.
 
-   ^C(1,3)="BIO"
+   GT.M does not permit the SET or NEW command to modify $ZIO.
 
-   ^C(1,3,1)=90
+   An example where $ZIO contains a value different from $IO is if the
+   environment variable gtm_principal is defined.
 
-   List ^ <RETURN>
+   Example:
 
-   GTM>
+   $ gtm_principal="foo"
+   $ export gtm_principal
+   GTM>WRITE $IO
+   foo
+   GTM>WRITE $ZIO
+   /dev/pts/8
 
-   This example uses the asterisk (*) wildcard to  list  node  ^C(1),  its
-   descendants and values.
+   Notice that $ZIO contains the actual terminal device name while $IO
+   contains the string pointed to by the environment variable gtm_principal.
 
-   Example:
+2 $ZJob
+   $ZJob
 
+   $ZJ[OB] holds the pid of the process created by the last JOB command
+   performed by the current process.
 
-   GTM>do ^%G
+   GT.M initializes $ZJOB to zero (0) at process startup. If the JOB command
+   fails to spawn a new job, GT.M sets $ZJOB to zero (0). Note that because
+   of the left to right evaluation order of M, using $ZJOB in the
+   jobparameter string results in using the value created by the last, rather
+   than the current JOB command, which is not likely to match common coding
+   practice.
 
-   Output Device: <terminal>: <RETURN>
+   GT.M does not permit the SET or NEW command to modify $ZJOB.
 
-   List ^?D
+2 $ZLevel
+   $ZLevel
 
-   Global Directory
+   $ZL[EVEL] contains an integer value indicating the "level of nesting"
+   caused by DO commands, XECUTE commands, and extrinsic functions in the M
+   invocation stack.
 
-   Global ^ <RETURN>
+   $ZLEVEL has an initial value of one (1) and increments by one with each
+   DO, XECUTE or extrinsic function. Any QUIT that does not terminate a FOR
+   loop decrements $ZLEVEL. ZGOTO may also reduce $ZLEVEL. In accordance with
+   the M standard, a FOR command does not increase $ZLEVEL. M routines cannot
+   modify $ZLEVEL with the SET or NEW commands.
 
-   ^C ^D ^S ^Y ^a
+   Use $ZLEVEL in debugging or in an error-handling mechanism to capture a
+   level for later use in a ZGOTO argument.
 
-   Total of 5 globals.
+   Example:
 
-   List ^
+   GTM>zprint ^zleve
+   zleve;
+    do B
+    write X,!
+    quit
+   B
+    goto C
+    quit
+   C
+    do D
+    quit
+   D
+    set X=$ZLEVEL
+    quit
+
+   GTM>do ^zleve
+   4
 
    GTM>
 
-   This example specifies "?D" as the global that invokes the %GD utility.
-   %GD displays existing globals in the current global  directory  without
-   displaying their values or descendants.
-
-3 GC_
-   %GC
+   This program, executed from Direct Mode, produces a value of 4 for
+   $ZLEVEL. If you run this program from the shell, the value of $ZLEVEL is
+   three (3).
 
+2 $ZMAXTPTIme
+   $ZMAXTPTIme
 
-   The %GC utility copies values of globals from one global to another. It
-   is useful for testing and for moving misfiled data.
+   $ZMAXTPTI[ME] contains an integer value indicating the time duration GT.M
+   should wait for the completion of all activities fenced by the current
+   transaction's outermost TSTART/TCOMMIT pair.
 
-4 Prompts
-   Prompts
+   $ZMAXTPTIME can be SET but cannot be NEWed.
 
-        Show copied nodes <Yes>?
-        Asks whether to display the "source nodes" on the principal device.
-        From global ^ Requests a global variable name from  which  to  copy
-        variable and descendants.
-        To global ^ Request a global variable name to receive the copy.
-4 Ex_of_GC
-   Example:
+   $ZMAXTPTIME takes its value from the environment variable gtm_zmaxtptime.
+   If gtm_zmaxtptime is not defined, the initial value of $ZMAXTPTIME is zero
+   (0) seconds which indicates "no timeout" (unlimited time). The value of
+   $ZMAXTPTIME when a transaction's outermost TSTART operation executes
+   determines the timeout setting for that transaction.
 
+   When a $ZMAXTPTIME expires, GT.M executes the $ETRAP/$ZTRAP exception
+   handler currently in effect.
 
-   GTM>do ^%GC
+   **Note**
 
-   Global copy
+   Negative values of $ZMAXTPTIME are also treated as "no timeout". Timeouts
+   apply only to the outermost transaction, that is, $ZMAXTPTIME has no
+   effect when TSTART is nested within another transaction.
 
-   Show copied nodes <Yes>? <RETURN>
+   Example:
 
-   From global ^b
+   Test;testing TP timeouts
+     set $ZMAXTPTIME=6,^X=0,^Y=0,^Z=0
+     write "Start with $ZMAXTPTIME=",$ZMAXTPTIME,":",!
+     for sleep=3:2:9 do
+     . set retlvl=$zl
+     . do longtran;ztrap on longtran
+     ;continues execution
+     ;on next line
+     . write "(^X,^Y)=(",^X,",",^Y,")",!
+     write !,"Done TP Timeout test.",!
+    quit
+   longtran ;I/O in TP doesn't get rolled back
+     set newzt="set $ZT="""" ";avoid recursive ZTRAP
+     set $ZT=newzt_" goto err"
+     tstart ():serial ;plain tstart works as well
+     set ^X=1+^X
+     write !,"^X=",^X,",will set ^Y to ",sleep
+     write " in ",sleep," seconds..."
+     hang sleep
+     set ^Y=sleep
+     write "^Y=",^Y
+     tcommit
+     write "...committed.",!
+     quit
+   err;
+     set $ZT=""
+     write !,"In $ZTRAP handler. Error was: "
+     write !," ",$zstatus
+     if $TLEVEL do ;test allows handler use outside of TP
+     . trollback
+     . write "Rolled back transaction."
+     write !
+     zgoto retlvl
 
-   To global ^g
+   Results:
 
-   ^g(1)=1
+   Start with $ZMAXTPTIME=6:
 
-   ^g(2)=2
+   ^X=1,will set ^Y to 3 in 3 seconds...^Y=3...committed.
 
-   ^g(3)=3
+   ^X=2,will set ^Y to 5 in 5 seconds...^Y=5...committed.
 
-   Total 3 nodes copied.
+   ^X=3,will set ^Y to 7 in 7 seconds...
+   In $ZTRAP handler. Error was:
+   150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled back transaction.
 
-   From global ^<RETURN>
+   ^X=3,will set ^Y to 9 in 9 seconds...
 
-   GTM>
+   In $ZTRAP handler. Error was:
+   150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled back transaction.
 
-   This example makes a copy of the nodes  and  values  of  global  ^b  to
-   global ^g.
+   Done TP Timeout test.
 
-3 GCE
-   %GCE
+2 $ZMOde
+   $ZMOde
 
+   $ZMO[DE] contains a string value indicating the process execution mode.
 
-   The %GCE utility changes every occurrence of a string within  the  data
-   of selected global nodes to a replacement  string.  ^%GCE  changes  the
-   string in each place it occurs, even if  it  forms  part  of  a  longer
-   string. For example, changing the string 12 to 55 changes 312 to 355.
+   The mode can be:
 
-4 Prompts
-   Prompts
+     * INTERACTIVE
+     * OTHER
 
-        Global ^ Requests (using %GSEL)  the  name(s)  of  the  globals  to
-        change; <RETURN> ends selection.
-        Old string: Requests an existing string to find.
-        New string: Requests the replacement string.
-        Show changed nodes <Yes>?
-        Asks whether to display the before and after versions  of  modified
-        nodes on the current device.
-        Output Device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-4 Ex_of_GCE
-   Examples of %GCE
+   M routines cannot modify $ZMODE.
 
    Example:
 
+   GTM>WRITE $ZMODE
+   INTERACTIVE
 
-   GTM>DO ^%GCE
+   This displays the process mode.
 
-   Global Change Every occurrence
+2 $ZONLNrlbk
+   $ZONLNrlbk
 
-   Global ^a:^b
+   $ZONLNRLBK increments every time a process detects a concurrent MUPIP
+   JOURNAL -ONLINE -ROLLBACK.
 
-   ^a ^b
+   GT.M initializes $ZONLNRLBK to zero (0) at process startup. GT.M does not
+   permit the SET or NEW commands to modify $ZONLNRLBK.
 
-   Current total of 2 globals.
+2 $ZPATNumeric
+   $ZPATNumeric
 
-   Global ^ <RETURN>
+   $ZPATN[UMERIC] is a read-only intrinsic special variable that determines
+   how GT.M interprets the patcode "N" used in the pattern match operator.
 
-   Old String: hello
+   With $ZPATNUMERIC="UTF-8", the patcode "N" matches any numeric character
+   as defined by UTF-8 encoding. With $ZPATNUMERIC="M", GT.M restricts the
+   patcode "N" to match only ASCII digits 0-9 (that is, ASCII 48-57). When a
+   process starts in UTF-8 mode, intrinsic special variable $ZPATNUMERIC
+   takes its value from the environment variable gtm_patnumeric. GT.M
+   initializes the intrinsic special variable $ZPATNUMERIC to "UTF-8" if the
+   environment variable gtm_patnumeric is defined to "UTF-8". If the
+   environment variable gtm_patnumeric is not defined or set to a value other
+   than "UTF-8", GT.M initializes $ZPATNUMERIC to "M".
 
-   New String: good-bye
+   GT.M populates $ZPATNUMERIC at process initialization from the environment
+   variable gtm_patnumeric and does not allow the process to change the
+   value.
 
-   Show changed nodes <Yes>?: <RETURN>
+   For characters in Unicode, GT.M assigns patcodes based on the default
+   classification of the Unicode character set by the ICU library with three
+   adjustments:
+
+    1. If $ZPATNUMERIC is not "UTF-8", non-ASCII decimal digits are
+       classified as A.
+    2. Non-decimal numerics (Nl and No) are classified as A.
+    3. The remaining characters (those not classified by ICU functions:
+       u_isalpha, u_isdigit, u_ispunct, u_iscntrl, 1), or 2) above) are
+       classified into either patcode P or C. The ICU function u_isprint is
+       used since is returns "TRUE" for non-control characters.
+
+   The following table contains the resulting Unicode general category to M
+   patcode mapping:
+
+   +------------------------------------------------------------------------+
+   |   Unicode General Category   |           GT.M patcode Class            |
+   |------------------------------+-----------------------------------------|
+   | L* (all letters)             | A                                       |
+   |------------------------------+-----------------------------------------|
+   | M* (all marks)               | P                                       |
+   |------------------------------+-----------------------------------------|
+   | Nd (decimal numbers)         | N (if decimal digit is ASCII or         |
+   |                              | $ZPATNUMERIC is "UTF-8", otherwise A    |
+   |------------------------------+-----------------------------------------|
+   | Nl (letter numbers)          | A (examples of Nl are Roman numerals)   |
+   |------------------------------+-----------------------------------------|
+   | No (other numbers)           | A (examples of No are fractions)        |
+   |------------------------------+-----------------------------------------|
+   | P* (all punctuation)         | P                                       |
+   |------------------------------+-----------------------------------------|
+   | S* (all symbols)             | P                                       |
+   |------------------------------+-----------------------------------------|
+   | Zs (spaces)                  | P                                       |
+   |------------------------------+-----------------------------------------|
+   | Zl (line separators)         | C                                       |
+   |------------------------------+-----------------------------------------|
+   | Zp (paragraph separators)    | C                                       |
+   |------------------------------+-----------------------------------------|
+   | C* (all control code points) | C                                       |
+   +------------------------------------------------------------------------+
+
+   For a description of the Unicode general categories, refer to
+   http://unicode.org/charts/.
+
+   Example:
+
+   GTM>write $zpatnumeric
+   UTF-8
+   GTM>Write $Char($$FUNC^%HD("D67"))?.N ; This is the Malayalam decimal digit 1
+   1
+   GTM>Write 1+$Char($$FUNC^%HD("D67"))
+   1
+   GTM>Write 1+$Char($$FUNC^%HD("31")) ; This is the ASCII digit 1
+   2
 
-   Output Device: <terminal>: <RETURN>
+2 $ZPOSition
+   $ZPOSition
 
-   ^a
+   $ZPOS[ITION] contains a string value specifying the current entryref,
+   where entryref is [label][+offset]^routine, and the offset is evaluated
+   from the closest preceding label.
 
-   No changes made in total 1 nodes.
+   GT.M does not permit the SET or NEW commands to modify $ZPOSITION.
 
-   ^b
+   Example:
 
-   ^b(10)
+   GTM>WRITE !,$ZPOS,! ZPRINT @$ZPOS
 
-   Was : hello Adam
+   This example displays the current location followed by the source code for
+   that line.
 
-   Now : good-bye Adam
+2 $ZPROMpt
+   $ZPROMpt
 
-   1 changes made in total 25 nodes.
-   Global ^ <RETURN>
+   $ZPROM[PT] contains a string value specifying the current Direct Mode
+   prompt. By default, GTM>is the Direct Mode prompt. M routines can modify
+   $ZPROMPT by means of a SET command. $ZPROMPT cannot exceed 16 characters.
+   If an attempt is made to assign $ZPROMPT to a longer string, only the
+   first 16 characters will be taken.
 
-   GTM>
+   In UTF-8 mode, if the 31st byte is not the end of a valid UTF-8 character,
+   GT.M truncates the $ZPROMPT value at the end of last character that
+   completely fits within the 31 byte limit.
 
-   This example searches a range of globals and  its  nodes  for  the  old
-   string value entered.  GT.M  searches  each  global  and  displays  the
-   changes and number of nodes changed and checked.
+   The environment gtm_prompt initializes $ZPROMPT at process startup.
 
    Example:
 
+   GTM>set $zprompt="Test01">"
+   Test01>set $zprompt="GTM>"
 
-   GTM>set ^b(12)=12
-
-   GTM>set ^b(122)=122
+   This example changes the GT.M prompt to Test01> and then back to GTM>.
 
-   GTM>set ^b(30)=656
+2 $ZREalstor
+   $ZREalstor
 
-   GTM>set ^b(45)=344
+   $ZREALSTOR contains the total memory (in bytes) allocated by the GT.M
+   process, which may or may not actually be in use. It provides one view
+   (see also $ZALLOCSTOR and ZUSEDSTOR) of the process memory utilization and
+   can help identify storage related problems. GT.M does not permit
+   $ZREALSTOR to be SET or NEWed.
 
-   GTM>set ^b(1212)=012212
-
-   GTM>DO ^%GCE
-
-   Global Change Every occurrence
+2 $ZROutines
+   $ZROutines
 
-   Global ^b
+   $ZRO[UTINES] contains a string value specifying a directory or list of
+   directories containing object files. Each object directory may also have
+   an associated directory, or list of directories, containing the
+   corresponding source files. These directory lists are used by certain GT.M
+   functions, primarily auto-ZLINK, to locate object and source files. The
+   order in which directories appear in a given list determines the order in
+   which they are searched for the appropriate item.
 
-   Current total of 1 global.
+   Searches that use $ZROUTINES treat files as either object or source files.
+   GT.M treats files with an extension of .o as object files and files with
+   an extension of .m as source files.
 
-   Global ^ <RETURN>
+   **Note**
 
-   Old String: 12
+   Paths used in $ZROUTINES to locate routines must not include embedded
+   spaces, as $ZROUTINES uses spaces as delimiters.
 
-   New String: 35
+3 Establishing_the_Value_from_$gtmroutines
+   Establishing the Value from $gtmroutines
 
-   Show changed nodes <Yes>?: <RETURN>
+   When the environment variable gtmroutines is defined, GT.M initializes
+   $ZROUTINES to the value of gtmroutines. Otherwise, GT.M initializes
+   $ZROUTINES to a null value. When $ZROUTINES is null, GT.M attempts to
+   locate all source and object files in the current working directory.
+   $ZROUTINES="" is equivalent to $ZROUTINES=".".
 
-   Output Device: <terminal>: <RETURN>
+   Commands or functions such as DO, GOTO, ZGOTO, ZBREAK, ZPRINT, and $TEXT
+   may auto-ZLINK and thereby indirectly use $ZROUTINES. If their argument
+   does not specify a directory, ZEDIT and explicit ZLINK use $ZROUTINES.
+   ZPRINT and $TEXT use $ZROUTINES to locate a source file if GT.M cannot
+   find the source file pointed to by the object file.
 
-   ^b(12)
+3 Setting_a_Value_for_$ZROutines
+   Setting a Value for $ZROutines
 
-   Was : 12
+   $ZRO[UTINES] is a read-write Intrinsic Special Variable, so M can also SET
+   the value.
 
-   Now : 35
+   By default, each directory entry in $ZROUTINES is assumed to contain both
+   object and source files. However, each object directory may have an
+   associated directory or list of directories to search for the
+   corresponding source files. This is done by specifying the source
+   directory list, in parentheses, following the object directory
+   specification.
 
-   ^b(122)
+   If the command specifies more than one source directory for an object
+   directory, the source directories must be separated by spaces, and the
+   entire list must be enclosed in parentheses ( ) following the object
+   directory-specification. If the object directory should also be searched
+   for source, the name of that directory must be included in the
+   parentheses, (usually as the first element in the list).
+   Directory-specifications may also include empty parentheses, directing
+   GT.M to proceed as if no source files exist for objects located in the
+   qualified directory.
 
-   Was : 122
+   To set $ZROUTINES outside of M, use the appropriate shell command to set
+   gtmroutines. Because gtmroutines is a list, enclose the value in quotation
+   marks (" ").
 
-   Now : 352
+   Changes to the value of $ZROUTINES during a GT.M invocation only last for
+   the current invocation, and do not change the value of gtmroutines.
 
-   ^b(1212)
+   Directory specifications may include an environment variable. When GT.M
+   SETs $ZROUTINES, it translates all environment variables and verifies the
+   syntax and the existence of all specified directories. If $ZROUTINES is
+   set to an invalid value, GT.M generates a run-time error and does not
+   change the value of $ZROUTINES. Because the environment variables are
+   translated when $ZROUTINES is set, any changes to their definition have no
+   effect until $ZROUTINES is set again.
 
-   Was : 12212
+3 $ZROutines_Examples
+   $ZROutines Examples
 
-   Now : 35235
+   Example:
 
-   5 changes made in total 5 nodes
-   Global ^ <RETURN>
+   GTM>s $zroutines=".(../src) $gtm_dist"
 
-   GTM>DO ^%G
+   This example directs GTM to look for object modules first in your current
+   directory, then in the distribution directory that contains the percent
+   routines. GT.M locates sources for objects in your current directory in
+   the sibling /src directory.
 
-   Output device: <terminal>: <RETURN>
+   Example:
 
-   List ^b
+   $ gtmroutines="/usr/jones /usr/smith"
+   $ export gtmroutines
+   $ gtm
+   GTM>write $zroutines
+   "/usr/jones /usr/smith"
+   GTM>set $zro="/usr/jones/utl /usr/smith/utl"
+   GTM>write $zroutines
+   "/usr/jones/utl /usr/smith/utl"
+   GTM>halt
+   $ echo $gtmroutines
+   /usr/jones /usr/smith
 
-   ^b(12)=35
+   This example defines the environment variable gtmroutines. Upon entering
+   GT.M Direct Mode $zroutines has the value supplied by gtmroutines. The SET
+   command changes the value. When the GT.M image terminates, the shell echo
+   command demonstrates that gtmroutines has not been modified by the M SET
+   command.
 
-   ^b(30)=656
+   Example:
 
-   ^b(45)=344
+   GTM>SET $ZRO=". /usr/smith"
 
-   ^b(122)=352
+   This example sets $zroutines to a list containing two directories.
 
-   ^b(1212)=35235
+   Example:
 
-   This example shows that executing %GCE replaces all occurrences of "12"
-   in the data stored in the global ^b with "35" and displays the affected
-   nodes before and after the change. Then the %G demonstrates  that  "12"
-   as data was changed, while "12" in the subscripts remained untouched.
+   GTM>set $zro="/usr/smith(/usr/smith/tax /usr/smith/fica)"
 
-3 GD
-   %GD
+   This example specifies that GT.M should search the directory /usr/smith
+   for object files, and the directories /usr/smith/tax and /usr/smith/fica
+   for source files. Note that in this example. GT.M does not search
+   /usr/smith for source files.
 
+   Example:
 
-   The %GD  utility  displays  existing  globals  in  the  current  global
-   directory without displaying their values or descendants.
+   GTM>set $zro="/usr/smith(/usr/smith /usr/smith/tax /usr/smith/fica)"
 
-   %GD prompts for a global name and redisplays the name  if  that  global
-   exists.
+   This example specifies that GT.M should search the directory /usr/smith
+   for object files and the directories /usr/smith/tax and /usr/smith/fica
+   for source files. Note that the difference between this example and the
+   previous one is that GT.M searches /usr/smith for both object and source
+   files.
 
-   %GD interprets a percent sign (%) in the first  position  of  a  global
-   name literally.
+   Example:
 
-   %GD allows the wildcard characters asterisk (*) and question mark (?).
-   The wildcards carry their usual meanings, an  asterisk  (*)  denotes  a
-   field or a portion of a field, and a question mark (?) denotes a single
-   character.
+   GTM>set $zro="/usr/smith /usr/smith/tax() /usr/smith/fica"
 
-   A colon (:)  between  two  globals  specifies  a  range.  %GD  displays
-   existing globals within that range.
+   This specifies that GT.M should search /usr/smith and /usr/smith/fica for
+   object and source files. However, because the empty parentheses indicate
+   directories searched only for object files, GT.M does not search
+   /usr/smith/tax for source files.
 
-   After each selection %GD reports the number of globals selected by the
-   input.
+   Omitting the parentheses indicates that GT.M can search the directory for
+   both source and object files. $ZROUTINES=/usr/smith is equivalent to
+   $ZROUTINES=/usr/smith(/usr/smith).
 
-   A question mark (?) entered at  a  prompt  displays  help  information.
-   Pressing <RETURN> exits %GD.
+3 $ZROutines_Search_Types
+   $ZROutines Search Types
 
-4 Prompts
-   Prompts
+   GT.M uses $ZRO[UTINES] to perform three types of searches:
 
-        Global ^  Requests  (using  %GSEL)  a  global  name  with  optional
-        wildcards or a range of names; <RETURN> terminates %GD.
-4 Ex_of_GD
-   Exampels of %GD
+     * Object-only when the command or function using $ZROUTINES requires a
+       .o file extension.
+     * Source-only when the command or function using $ZROUTINES requires a
+       file extension other than .o.
+     * Object-source match when the command or function using $ZROUTINES does
+       not specify a file extension.
 
-   Example:
+   An explicit ZLINK that specifies a non .OBJ .o extension is considered as
+   a function that has not specified a file extension for the above searching
+   purposes.
 
+   All searches proceed from left to right through $ZROUTINES. By default,
+   GT.M searches directories for both source and object files. GT.M searches
+   directories followed by empty parentheses ( ) for object files only. GT.M
+   searches directories in parentheses only for source files.
+
+   Once an object-matching search locates an object file, the source search
+   becomes limited. If the directory containing the object file has an
+   attached parenthetical list of directories, GT.M only searches the
+   directories in the attached list for matching source files. If the
+   directory containing the object files does not have following parentheses,
+   GT.M restricts the search for matching source files to the same directory.
+   If the object module is in a directory qualified by empty parentheses,
+   GT.M cannot perform any operation that refers to the source file.
+
+   The following table shows GT.M commands and functions using $ZROUTINES and
+   the search types they support.
+
+   +------------------------------------------------------+
+   |      GT.M Commands and $ZROUTINES Search Types       |
+   |------------------------------------------------------|
+   |  SEARCH/   |   FILE    |                             |
+   |  FUNCTION  | EXTENSION |         SEARCH TYPE         |
+   |            | SPECIFIED |                             |
+   |------------+-----------+-----------------------------|
+   |            |           | OBJ-ONLY | SRC-ONLY | MATCH |
+   |------------+-----------+----------+----------+-------|
+   | EXPLICIT   |           |          |          |       |
+   |            | .o        | X        |          |       |
+   | ZLINK      |           |          |          |       |
+   |------------+-----------+----------+----------+-------|
+   |            | Not .o    |          |          | X     |
+   |------------+-----------+----------+----------+-------|
+   |            | None      |          |          | X     |
+   |------------+-----------+----------+----------+-------|
+   | AUTO-ZLINK | None      |          |          | X     |
+   |------------+-----------+----------+----------+-------|
+   | ZEDIT      | Not .o    |          | X        |       |
+   |------------+-----------+----------+----------+-------|
+   | ZPRINT     | None      |          | X        |       |
+   |------------+-----------+----------+----------+-------|
+   | $TEXT      | None      |          | X        |       |
+   +------------------------------------------------------+
+
+   If ZPRINT or $TEXT() require a source module for a routine that is not in
+   the current image, GT.M first performs an auto-ZLINK with a matching
+   search.
+
+   ZPRINT or $TEXT locate the source module using a file specification for
+   the source file located in the object module. If GT.M finds the source
+   module in the directory where it was when it was compiled, the run-time
+   system does not use $ZROUTINES. If GT.M cannot find the source file in the
+   indicated location, the run-time system uses $ZROUTINES.
+
+3 $ZROutines_Search_Examples
+   $ZROutines Search Examples
+
+   This section describes a model for understanding $ZROUTINES operations and
+   the illustrating examples, which may assist you if you wish to examine the
+   topic closely.
+
+   You may think of $ZROUTINES as supplying a two dimensional matrix of
+   places to look for files. The matrix has one or more rows. The first row
+   in the matrix contains places to look for object and the second and
+   following rows contain places to look for source. Each column represents
+   the set of places that contain information related to the object modules
+   in the first row of the column.
+
+   Example:
+
+   GTM>s $zro=". /usr/smi/utl() /usr/jon/utl
+   (/usr/jon/utl/so /usr/smi/utl)"
 
-   GTM>DO ^%GD
+   The following table illustrates the matrix view of this $ZROUTINES.
+
+   +--------------------------------------------------------+
+   |                $ZROUTINES Search Matrix                |
+   |--------------------------------------------------------|
+   | SEARCH FOR | Column 1 |   Column 2   |    Column 3     |
+   |------------+----------+--------------+-----------------|
+   | OBJECTS    | .        | /usr/smi/utl | /usr/jon/utl    |
+   |------------+----------+--------------+-----------------|
+   | SOURCE     | .        |              | /usr/jon/utl/so |
+   |------------+----------+--------------+-----------------|
+   |            |          |              | /usr/smi/utl    |
+   +--------------------------------------------------------+
+
+   To perform object-only searches, GT.M searches only the directories or
+   object libraries in the top 'objects' row for each column starting at
+   column one. If GT.M does not locate the object file in a directory or
+   object library in the 'objects' row of a column, GT.M begins searching
+   again in the next column. If GT.M cannot locate the file in any of the
+   columns, it issues a run-time error.
+
+   As illustrated in the preceding table, GT.M searches for object files in
+   the directories . ,/usr/smi/utl and /usr/jon/utl.
+
+   To perform source-only searches, GT.M looks down to the 'source' row at
+   the bottom of each column, excluding columns headed by object-only
+   directories (that is, those object directories, which consist of an empty
+   list of source directories) or object libraries. If GT.M cannot locate the
+   source file in the 'source' row of a column, it searches the next eligible
+   column.
+
+   To perform object-source match searches, GT.M looks at each column
+   starting at column one. GT.M does an object-only search in the 'objects'
+   row of a column and a source-only search in the 'source' row(s) of a
+   column. If GT.M locates either the object-file or the souce-file, the
+   search is completed. Else, GT.M starts searching the next column. If GT.M
+   cannot locate either the object file or the source file in any of the
+   columns, it issues a run-time error.
+
+   As illustrated in the preceding table, GT.M searches for source-files in
+   the directory "." in column one. If GT.M cannot locate the source file in
+   ".", it omits column two because it is an object-only directory and
+   instead searches column three. Since column three specifies
+   /usr/jon/utl/so and /usr/smi/utl, GT.M searches for the source-file in
+   these directories in column three and not in /usr/jon/utl. If GT.M cannot
+   locate the source-file in column three, it terminates the search and
+   issues a run-time error.
 
-   Global directory
+   Once the object-source match search is done, GT.M now has either the
+   object-file or source-file or both available. GT.M then recompiles the
+   source-file based on certain conditions, before linking the object-file
+   into the current image.
 
-   Global ^k
+   If auto-ZLINK or ZLINK determines that the source file requires
+   [re]compilation, GT.M places the object file in the above object directory
+   in the same column as the source file. For example, if GT.M locates the
+   source file in /usr/smi/utl in column three, GT.M places the resultant
+   object file in /usr/jon/utl.
 
-   ^k
+3 Shared_Library_File_Specification_in_$ZROUTINES
+   Shared Library File Specification in $ZROUTINES
 
-   Total of 1 global.
+   The $ZROUTINES ISV allows individual UNIX shared library file names to be
+   specified in the search path. During a search for auto-ZLINK, when a
+   shared library is encountered, it is probed for a given routine and, if
+   found, that routine is linked/loaded into the image. During an explicit
+   ZLINK, all shared libraries in $ZROUTINES are ignored and are not searched
+   for a given routine.
+
+   $ZROUTINES syntax contains a file-specification indicating shared library
+   file path. GT.M does not require any designated extension for the shared
+   library component of $ZROUTINES. Any file specification that does not name
+   a directory is treated as shared library. However, it is recommended that
+   the extension commonly used on a given platform for shared library files
+   be given to any GT.M shared libraries. A shared library component cannot
+   specify source directories. GT.M reports an error at an attempt to
+   associate any source directory with a shared library in $ZROUTINES.
 
-   Global ^ <RETURN>
+   The following traits of $ZROUTINES help support shared libraries:
 
-   GTM>
+     * The $ZROUTINES search continues to find objects in the first place,
+       processing from left to right, that holds a copy; it ignores any
+       copies in subsequent locations. However, now for auto-ZLINK, shared
+       libraries are accepted as object repositories with the same ability to
+       supply objects as directories.
+     * Explicit ZLINK, never searches Shared Libraries. This is because
+       explicit ZLINK is used to link a newly created routine or re-link a
+       modified routine and there is no mechanism to load new objects into an
+       active shared library.
+     * ZPRINT and $TEXT() of the routines in a shared library, read source
+       file path from the header of the loaded routine. If the image does not
+       contain the routine, an auto-ZLINK is initiated. If the source file
+       path recorded in the routine header when the module was compiled
+       cannot be located, ZPRINT and $TEXT() initiate a search from the
+       beginning of $ZROUTINES, skipping over the shared library file
+       specifications. If the located source does not match the code in image
+       (checked via checksum), ZPRINT generates an object-source mismatch
+       status and $TEXT() returns a null string.
+     * ZEDIT, when searching $ZROUTINES, skips shared libraries like explicit
+       ZLINK for the same reasons. $ZSOURCE ISV is implicitly set to the
+       appropriate source file.
+
+   For example, if libshare.so is built with foo.o compiled from
+   ./shrsrc/foo.m, the following commands specify that GT.M should search the
+   library ./libshare.so for symbol foo when do ^foo is encountered.
 
-   This example verifies that ^k exists in the global directory.
+   GTM>SET $ZROUTINES="./libshare.so ./obj(./shrsrc)"
+   GTM>DO ^foo;auto-ZLINK foo - shared
+   GTM>ZEDIT "foo";edit ./shrsrc/foo.m
+   GTM>W $ZSOURCE,!;prints foo
+   GTM>ZPRINT +0^foo;issues a source-object mismatch status TXTSRCMAT error message
+   GTM>ZLINK "foo";re-compile ./shrsrc/foo.m to generate ./obj/foo.o.
+   GTM>W $TEXT(+0^foo);prints foo
 
-   Example:
+   Note that ZPRINT reports an error, as foo.m does not match the routine
+   already linked into image. Also note that, to recompile and re-link the
+   ZEDITed foo.m, its source directory needs to be attached to the object
+   directory [./obj] in $ZROUTINES. The example assumes the shared library
+   (libshare.so) has been built using shell commands.
 
+2 $ZSOurce
+   $ZSOurce
 
-   GTM>DO ^%GD
+   $ZSO[URCE] contains a string value specifying the default pathname for the
+   ZEDIT and ZLINK commands. ZEDIT or ZLINK without an argument is equivalent
+   to ZEDIT/ZLINK $ZSOURCE.
 
-   Global directory
+   $ZSOURCE initially contains the null string. When ZEDIT and ZLINK commands
+   have a pathname for an argument, they implicitly set $ZSOURCE to that
+   argument. This ZEDIT/ZLINK argument can include a full pathname or a
+   relative one. A relative path could include a file in the current
+   directory, or the path to the file from the current working directory. In
+   the latter instance, do not include the slash before the first directory
+   name. $ZSOURCE will prefix the path to the current working directory
+   including that slash.
 
-   Global ^C:S
+   The file name may contain a file extension. If the extension is .m or .o,
+   $ZSOURCE drops it. The ZEDIT command accepts arguments with extensions
+   other than .m or .o. $ZSOURCE retains the extension when such arguments
+   are passed.
 
-   ^C ^D ^S
+   If $ZSOURCE contains a file with an extension other than .m or .o, ZEDIT
+   processes it but ZLINK returns an error message
 
-   Total of 3 globals
+   $ZSOURCE is a read-write Intrinsic Special Variable, (i.e., it can appear
+   on the left side of the equal sign (=) in the argument to the SET
+   command). A $ZSOURCE value may include an environment variable. GT.M
+   handles logical names that translate to other logical names by performing
+   iterative translations according to VMS conventions. If a logical name
+   translates to a VMS search list, GT.M uses only the first name in the
+   list.
 
-   Global ^ <RETURN>
+   Example:
 
-   GTM>
+   GTM>ZEDIT "subr.m"
+   .
+   .
+   GTM>WRITE $ZSOURCE
 
-   This example displays a range of globals that exist from ^C to ^S.
+   subr
 
    Example:
 
+   GTM>ZEDIT "test"
+   .
+   .
+   .
+   GTM>WRITE $ZSOURCE
 
-   GTM>DO ^%GD Global directory
-
-   Global ^*
+   "test"
 
-   ^C ^D ^S ^Y ^a
+   Example:
 
-   Total of 5 globals
+   GTM>ZEDIT "/usr/smith/report.txt"
+   .
+   .
+   .
+   GTM>WRITE $ZSOURCE
 
-   Global ^ <RETURN>
+   /usr/smith/report.txt
 
-   GTM>
+   Example:
 
-   The asterisk (*) wildcard at the Global ^ prompt displays  all  globals
-   in the global directory.
+   GTM>ZLINK "BASE.O"
+   .
+   .
+   .
+   GTM>WRITE $ZSOURCE
+   BASE
 
-3 GED
-   %GED
+2 $ZStatus
+   $ZStatus
 
+   $ZS[TATUS] contains a string value specifying the error condition code and
+   location of the last exception condition that occurred during routine
+   execution.
 
-   The %GED utility enables you to  edit  the  globals  in  a  full-screen
-   editor environment. %GED invokes your default editor  as  specified  by
-   the EDITOR environment variable. When you  finish  the  edit,  use  the
-   [save and] exit command(s) of the editor you are using, to exit.
+   GT.M maintains $ZSTATUS as a string consisting of three or more
+   substrings. The string consists of the following:
 
-4 Prompts
-   Prompts
+   Format: %<FAC>-<SEV>-<ID>, <TEXT>
+   Example: %GTM-E-DIVZERO, Attempt to divide by zero
 
-        Edit ^ Requests the name, in ZWRITE format, of a global to edit.
-   Only one global can be edited at  a  time  with  %GED,  refer  to  GT.M
-   Programmer's Guide for descriptions of valid input for subscripts.
+   GT.M sets $ZSTATUS when it encounters errors during program execution, but
+   not when it encounters errors in a Direct Mode command.
 
-4 Ex_of_GED
-   Examples of %GED
+   $ZSTATUS is a read-write Intrinsic Special Variable, (i.e., it can occur
+   on the left side of the equal sign (=) in the argument to the SET
+   command). While it will accept any string, FIS recommends setting it to
+   null. M routines cannot modify $ZSTATUS with the NEW command.
 
    Example:
 
+   GTM>WRITE $ZSTATUS
+   150373110,+1^MYFILE,%GTM-E-DIVZERO,
+   Attempt to divide by zero
 
-   GTM>DO ^%GED
-
-   edit ^ b
+   This example displays the status generated by a divide by zero (0).
 
-   Beginning screen:
+2 $ZSTep
+   $ZSTep
 
-   ^b(1)="melons"
+   $ZST[EP] contains a string value specifying the default action for the
+   ZSTEP command. $ZSTEP provides the ZSTEP action only when the ZSTEP
+   command does not specify an action.
 
-   ^b(2)="oranges"
+   $ZSTEP initially contains the string "B" to enter direct mode. $ZSTEP is a
+   read-write Intrinsic Special Variable, (i.e., it can appear on the left
+   side of the equal sign (=) in the argument to the SET command).
 
-   ^b(3)="bananas"
+   Example:
 
-   Screen with a change to  ^b(1),  elimination  of  ^b(3),  and  two  new
-   entries ^b(4) and ^b(5):
+   GTM>WRITE $ZSTEP
+   B
+   GTM>
 
-   ^b(1)="apples"
+   This example displays the current value of $ZSTEP, which is the default.
 
-   ^b(2)="oranges"
+   Example:
 
-   ^b(4)=pears
+   GTM>SET $ZSTEP="ZP @$ZPOS B"
 
-   ^b(5)="grapes"
+   This example sets $ZSTEP to code that displays the contents of the next
+   line to execute, and then enters Direct Mode.
 
+2 $ZSYstem
+   $ZSYstem
 
-   %GED responds:
+   $ZSY[STEM] holds the value of the status code for the last subprocess
+   invoked with the ZSYSTEM command.
 
+2 $ZTExit
+   $ZTExit
 
-   Invalid syntax: b(4)=pears
+   $ZTE[XIT] contains a string value that controls the GT.M interrupt
+   facility at the transaction commit or rollback. At each outermost TCOMMIT
+   or TROLLBACK, If +$ZTEXIT evaluates to non-zero (TRUE), then $ZINTERRUPT
+   is XECUTEd after completing the commit or rollback.
 
-   return to continue:
+   $ZTEXIT is a read-write ISV, that is, it can appear on the left side of
+   the equal sign (=) in the argument to the SET command. M routines cannot
+   NEW $ZTEXIT. GT.M initializes $ZTEXIT to null at the process startup. Note
+   that the changes to the value of $ZTEXIT during a GT.M invocation last for
+   the entire duration of the process, so it is the application's
+   responsibility to reset $ZTEXIT after $ZINTERRUPT is delivered in order to
+   turn off redelivering the interrupt every subsequent transaction commit or
+   rollback.
 
-   After screen:
+   Example:
 
-   ^b(1)="apples"
+   ztran.m
+   foo;
+   set $ztexit=1
+   set $zinterrupt="d ^throwint"
+   tstart ()
+   for i=1:1:10 do
+   . set ^ACN(i,"bal")=i*100
+   tstart ()
+   do ^throwint
+   do ^proc
+   tcommit:$tlevel=2
+   for i=1:1:10 do
+   . set ^ACN(i,"int")=i*0.05
+   do ^srv
+   if $tlevel trollback
+   do ^exc
+   set $zte="",$zint=""
+   quit
+   bar;
+   write "Begin Transaction",!
+   set $zte=1
+   tstart ()
+   i '$zsigproc($j,$ztrnlnm("sigusrval")) w "interrupt sent...",!!
+   for i=1:1:4 set ^B(i)=i*i
+   tcommit
+   write "End Transaction",!
+   do ^srv
+   quit
+   throwint.m
+   thrint
+   set $zint="write !,""interrupt occurred at : "",$stack($stack-1,""PLACE""),! set $zte=1"
+   if '$zsigproc($j,$ztrnlnm("sigusrval")) write "interrupt sent to process"
+   write "***************************************",!!
+   quit
 
-   ^b(2)="oranges"
+   Example:
 
-   ^b(4)="pears"
+   GTM>d foo^ztran
+   interrupt sent to process
+   nterrupt occurred at : thrint+3^throwint
+   ***************************************
 
-   ^b(5)="grapes"
+   interrupt occurred at : foo+13^ztran
+   GTM>
 
-   %GED responds:
+   In the above call to foo^ztran, the interrupt handler is a user-defined
+   routine, throwint. The process is sent a signal (SIGUSR1), and $ZINTERRUPT
+   is executed. At the outermost trollback, the interrupt is rethrown,
+   causing $ZINTERRUPT to be executed again.
 
+   Example:
 
-   node : ^b
+   GTM>w $zint
+   IF $ZJOBEXAM()
+   GTM>zsy "ls GTM*"
+   ls: No match.
 
-   selected : 3
+   GTM>d bar^ztran
+   Begin Transaction
+   interrupt sent...
 
-   changed : 1
+   End Transaction
 
-   added : 2
+   GTM>zsy "ls GTM*"
+   GTM_JOBEXAM.ZSHOW_DMP_22551_1 GTM_JOBEXAM.ZSHOW_DMP_22551_2
 
-   killed : 1
+   GTM>
 
-   Edit ^ <RETURN>
+   This uses the default value of $ZINTERRUPT to service interrupts issued to
+   the process. The $ZJOBEXAM function executes a ZSHOW "*", and stores the
+   output in each GTM_ZJOBEXAM_ZSHOW_DMP for the initial interrupt, and at
+   tcommit when the interrupt is rethrown.
 
-   GTM>
+2 $ZTrap
+   $ZTrap
 
-   This example shows the use of the full-screen editor  to  change,  add,
-   and delete (kill) nodes. When you exit from the editor, %GED checks the
-   syntax and reports any problems. By pressing <RETURN>,  return  to  the
-   full-screen editor to fix the error. At the end of  the  session,  %GED
-   reports how many nodes were selected, changed, killed, and added.
+   $ZT[RAP] contains a string value that GT.M XECUTEs when an error occurs
+   during routine execution.
 
-3 GI
-   %GI
+   **Note**
 
+   The following discussion assumes that $ETRAP error handling is
+   simultaneously not in effect (that is, $ETRAP="").
 
-   %GI loads global variable names and  their  corresponding  data  values
-   into a GT.M database from  a  sequential  file.  %GI  uses  the  global
-   directory to determine which database files to  use.  %GI  may  operate
-   concurrently with normal GT.M database access. However, a %GI does not
-   use M LOCKs and may produce application-level integrity problems if run
-   concurrently with many applications.
+   When the $ZTRAP variable is not null, GT.M executes $ZTRAP at the current
+   level. The $ZTRAP variable has the initial value of "B," and puts the
+   process in Direct Mode when an error condition occurs. If the value of
+   $ZTRAP is null (""), an exception causes the image to run-down with the
+   condition code associated with the exception. If $ZTRAP contains invalid
+   source code, GT.M displays an error message and puts the process into
+   Direct Mode.
 
-   The %GI utility corresponds to MUPIP LOAD. The format of the input file
-   (GO or ZWRITE) is automatically detected.
+   $ZTRAP is a read-write Intrinsic Special Variable, (that is, it can appear
+   on the left side of the equal sign (=) in the argument to the SET
+   command).
 
-4 Prompts
-   Prompts
+   $ZTRAP may also appear as an argument to an inclusive NEW command. NEW
+   $ZTRAP causes GT.M to set $ZTRAP to null ($ZTRAP="") and to stack the old
+   value of $ZTRAP. When the program QUITs from the invocation level where
+   the NEW occurred, GT.M restores the value previously stacked by the NEW.
+   NEW $ZTRAP provides nesting of $ZTRAP. Because $ZTRAP="" terminates the
+   image when an error occurs, SET $ZTRAP= generally follows immediately
+   after NEW $ZTRAP. You may use this technique to construct error handling
+   strategies corresponding to the nesting of your programs. If the
+   environment variable gtm_ztrap_new evaluates to boolean TRUE (case
+   insensitive string "TRUE", or case insensitive string "YES", or a non-zero
+   number), $ZTRAP is NEWed when $ZTRAP is SET; otherwise $ZTRAP is not
+   stacked when it is SET.
+
+   **Note**
+
+   QUIT from a $ZTRAP terminates the level at which the $ZTRAP was activated.
 
-        Enter input file:
-        Requests name of a file; file should be in standard  Global  Output
-        (GO) format or Zwrite (ZWR) format .
-        OK <Yes>?: Asks for confirmation.
-4 Ex_of_GI
-   Examples of %GI
+   Keep $ZTRAP simple and put complicated logic in another routine. If the
+   action specified by $ZTRAP results in another run-time error before
+   changing the value of $ZTRAP, GT.M invokes $ZTRAP until it exhausts the
+   process stack space, terminating the image. Carefully debug exception
+   handling. For more information on error handling, refer "Error
+   Processing".
 
    Example:
 
+   GTM>S $ZTRAP="ZP @$ZPOS B"
 
-   GTM>DO ^%GI
+   This example modifies $ZTRAP to display source code for the line where
+   GT.M encounters an error before entering Direct Mode.
 
-   Global Input Utility
+   There are four settings of $ZTRAP controlled by the UNIX environment
+   variable gtm_ztrap_form.
+
+   The four settings of gtm_ztrap_form are:
+
+     * code - If gtm_ztrap_form evaluates to "code" (or a value that is not
+       one of the subsequently described values), then GT.M treats $ZTRAP as
+       code and handles it as previously described in the documentation.
+     * entryref - If gtm_ztrap_form evaluates to "entryref" then GT.M treats
+       it as an entryref argument to an implicit GOTO command.
+     * adaptive - If gtm_ztrap_form evaluates to "adaptive" then if $ZTRAP
+       does not compile to valid M code, then $ZTRAP is treated as just
+       described for "entryref." Since there is little ambiguity, code and
+       entryref forms of $ZTRAP can be intermixed in the same application.
+
+   **Important**
+
+       GT.M attempts to compile $ZTRAP before evaluating $ZTRAP as an
+       entryref. Because GT.M allows commands without arguments such as QUIT,
+       ZGOTO, or HANG as valid labels, be careful not to use such keywords as
+       labels for error handling code in "adaptive" mode.
+
+     * pope[ntryref] / popa[daptive] - If gtm_ztrap_form evaluates to
+       "POPE[NTRYREF]" or "POPA[DAPTIVE]" (case insensitive) and $ZTRAP value
+       is in the form of entryref, GT.M unwinds the M stack from the level at
+       which an error occurred to (but not including) the level at which
+       $ZTRAP was last SET. Then, GT.M transfers control to the entryref in
+       $ZTRAP at the level where the $ZTRAP value was SET. If the UNIX
+       environment variable gtm_zyerror is defined to a valid entryref, GT.M
+       transfers control to the entryref specified by GTM_ZYERROR (with an
+       implicit DO) after unwinding the stack and before transferring control
+       to the entyref specified in $ZTRAP.
+
+   **Note**
+
+   Like $ZTRAP values, invocation of device EXCEPTION values follow the
+   pattern specified by the current gtm_ztrap_form setting.
+
+2 $ZUSedstor
+   $ZUSedstor
+
+   $ZUSEDSTOR is the value in $ZALLOCSTOR minus storage management overhead
+   and represents the actual memory, in bytes, requested by current
+   activities. It provides one view (see also $ZALLOCSTOR and $ZREALSTOR) of
+   the process memory utilization and can help identify storage related
+   problems. GT.M does not permit $ZUSEDSTOR to be SET or NEWed.
 
-   Input device <terminal>: DATA.GBL
+2 $ZVersion
+   $ZVersion
 
-   Saved from user's development area
+   $ZV[ERSION] contains a string value specifying the currently installed
+   GT.M. $ZV[ERSION] is a space-delimited string with four pieces described
+   as follows:
+
+     * The M product name, for example "GT.M".
+     * The M product version identifier; the format is: the capital letter
+       "V" followed by the major version number, then a period (.), followed
+       by the minor version number, then a patch number.
+     * The host operating system name and optional version identifier; this
+       identifier is only included if different versions of the OS support
+       different, compatible versions of the M product.
+     * The host hardware designation and optional chipset identifier; this
+       identifier is only included if different versions of the hardware
+       support different compatible versions of the M product.
 
-   GT.M 07-MAY-2002 14:14:09
+   M routines cannot modify $ZVERSION.
 
-   OK <Yes>? <RETURN>
+   Example:
 
-   ^IB ^INFO
+   GTM>WRITE $ZVERSION
+   GT.M V4.3-001B AIX RS6000
 
-   Restored 10 nodes in 2 globals
+   This example displays the current version identifier for GT.M.
 
-   GTM>
+2 $ZYERror
+   $ZYERror
 
-3 GO
-   %GO
+   $ZYER[ROR] is a read/write ISV that contains a string value pointing to an
+   entryref. After GT.M encounters an error, if $ZYERROR is set a non-null
+   value, GT.M invokes the routine at the entryref specified by $ZYERROR with
+   an implicit DO. It is intended that the code invoked by $ZYERROR use the
+   value of $ZSTATUS to select or construct a value to which it SETs $ZERROR.
+   If $ZYERROR is not a valid entryref or if an error occurs while executing
+   the entryref specified by $ZYERROR, GT.M SETs $ZERROR to the error status
+   encountered. GT.M then returns control to the M code specified by
+   $ETRAP/$ZTRAP or device EXCEPTION.
+
+   $ZYERROR is implicitly NEWed on entry to the routine specified by
+   $ZYERROR. However, if GT.M fails to compile, GT.M does not transfer
+   control to the entryref specified by $ZYERROR.
 
+   GT.M permits $ZYERROR to be modified by the SET and NEW commands.
 
-   %GO copies specified globals from the current database to a sequential
-   output file in either GO or ZWR format. Use %GO  to  back  up  specific
-   globals or when extracting data from the database for  use  by  another
-   system. %GO uses the global directory to determine which database files
-   to use. %GO may operate concurrently with normal GT.M database access.
-   To ensure that a %GO reflects a consistent application  state,  suspend
-   database updates to all regions involved in the extract.
+2 Triggers_ISVs
+   Triggers ISVs
 
-   The %GO utility corresponds to MUPIP EXTRACT (FORMAT=GO or FORMAT=ZWR).
+   GT.M provides nine ISVs (Intrinsic Special Variables) to facilitate
+   trigger operations. With the exception of $ZTWORMHOLE, all numeric
+   trigger-related ISVs return zero (0) outside of a trigger context;
+   non-numeric ISVs return the empty string.
 
-4 Prompts
-   Prompts
+3 $ZTDAta
+   $ZTDAta
 
-        Global ^ Requests (using %GSEL)  the  name(s)  of  the  globals  to
-        search; <RETURN> ends selection.
-        Header label: Requests text describing contents of extract file.
-        Output Format: GO or ZWR:
-        Requests the format to output the data. Defaults to ZWR.
-        Output Device: <terminal>:
-        Requests destination device, which may be any legal filename.
-4 Ex_of_GO
-   Examples of %GO
+   Within trigger context, $ZTDATA returns $DATA(@$REFERENCE)#2 for a SET or
+   $DATA(@$REFERENCE) for a KILL, ZKILL or ZWITHDRAW prior to the explicit
+   update. This provides a fast path alternative, avoiding the need for
+   indirection in trigger code, to help trigger code determine the
+   characteristics of the triggering node prior to the triggering update. For
+   a SET, it shows whether the node did or did not hold data - whether a SET
+   is modifying the contents of an existing node or creating data at a new
+   node. For a KILL it shows whether the node had descendants and whether it
+   had data.
 
-   Example:
+3 $ZTLevel
+   $ZTLevel
 
+   Within trigger context, $ZTLEVEL returns the current level of trigger
+   nesting (invocation by a trigger of an additional trigger by an update in
+   trigger context).
 
-   GTM>DO ^%GO
+   $ZTLEVEL greater than one (>1) indicates that there are nested triggers in
+   progress. When a single update invokes multiple triggers solely because of
+   multiple trigger matches of that initial (non-trigger) update, they are
+   not nested (they are chained) and thus all have same $ZTLEVEL.
 
-   Global Output Utility
+   Example:
 
-   Global ^A
+   +^Cycle(1) -commands=Set -xecute="Write ""$ZTLevel for ^Cycle(1) is: "",$ZTLevel Set ^Cycle(2)=1"
+   +^Cycle(2) -commands=Set -xecute="Write ""$ZTLevel for ^Cycle(2) is: "",$ZTLevel Set ^Cycle(1)=1"
 
-   ^A
+   These trigger definitions show different values of $ZTLEVEL when two
+   triggers are called recursively (and pathologically).
 
-   Current total of 1 global
+   +^Acct("ID") -commands=set -xecute="set ^Acct(1)=$ztvalue+1"
+   +^Acct(sub=:) -command=set -xecute="set ^X($ztvalue)=sub"
 
-   Global ^<RETURN>
+   SET ^Acct("ID")=10 invokes both the above triggers in some order and
+   $ZTLEVEL will have the same value in both because these triggers are
+   chained rather than nested.
 
-   Header label: Revenues May, 2002
+3 $ZTNAME
+   $ZTNAME
 
-   Output Format: GO or ZWR: ZWR
+   Within a trigger context, $ZTNAME returns the trigger name. Outside a
+   trigger context, $ZTNAME returns an empty string.
 
-   Output device: /usr/dev/out.go
+3 $ZTOLdval
+   $ZTOLdval
 
-   ^A
+   Within trigger context, $ZTOLDVAL returns the prior (old) value of the
+   global node whose update caused the trigger invocation. This provides a
+   fast path alternative to $GET(@$REFERENCE) at trigger entry (which avoids
+   the heavyweight indirection ). If there are multiple triggers matching the
+   same node (chained), $ZTOLDVAL returns the same result for each of them.
 
-   Total of 1 node in 1 global.
+   Example:
 
-   GTM>
+   +^Acct(1,"ID") -commands=Set -xecute="Write:$ZTOLdval ""The prior value of ^Acct(1,ID) was: "",$ZTOLdval"
 
-3 GSE_
-   %GSE
+   This trigger gets invoked with a SET and displays the prior value (if it
+   exists) of ^Acct(1,"ID").
 
+   GTM>w ^Acct(1,"ID")
+   1975
+   GTM>s ^Acct(1,"ID")=2011
+   The prior value of ^Acct(1,ID) was: 1975
+
+3 $ZTRIggerop
+   $ZTRIggerop
+
+   Within trigger context, for SET (including MERGE and $INCREMENT()
+   operations), $ZTRIGGEROP has the value "S". For KILL, $ZTRIGGEROP has the
+   value "K" For ZKILL or ZWITHDRAW, $ZTRIGGEROP has the value "ZK".
+
+3 $ZTSlate
+   $ZTSlate
+
+   $ZTSLATE allows you to specify a string that you want to make available in
+   chained or nested triggers invoked for an outermost transaction (when a
+   TSTART takes $TLEVEL from 0 to 1). You might use $ZTSLATE to accumulate
+   transaction-related information, for example $ZTOLDVAL and $ZTVALUE,
+   available within trigger context for use in a subsequent trigger later in
+   the same transaction. For example, you can use $ZTSLATE to build up an
+   application history or journal record to be written when a transaction is
+   about to commit.
+
+   You can SET $ZTSLATE only while a database trigger is active. GT.M clears
+   $ZTSLATE for the outermost transaction or on a TRESTART. However, GT.M
+   retains $ZTSLATE for all sub-transactions (where $TLEVEL>1).
+
+   Example:
+
+    TSTART ()       ; Implicitly clears $ZTSLAT
+    SET ^ACC(ACN1,BAL)=AMT          ; Trigger sets $ZTSLATE=ACN_"|"
+    SET ^ACC(ACN2,BAL)=-AMT         ; Trigger sets $ZTSLATE=$ZTSLATE_ACN_"|"
+    ZTRIGGER ^ACT("TRANS")          ; Trigger uses $ZTSLATE to update transaction log
+    TCOMMIT
+
+3 $ZTUPdate
+   $ZTUPdate
+
+   Within trigger context, for SET commands where the GT.M trigger specifies
+   a piece separator, $ZTUPDATE provides a comma separated list of piece
+   numbers of pieces that differ between the current values of $ZTOLDVAL and
+   $ZTVALUE. If the trigger specifies a piece separator, but does not specify
+   any pieces of interest, $ZTUPDATE identifies all changed pieces. $ZTUPDATE
+   is 0 in all other cases (that is: for SET commands where the GT.M trigger
+   does not specify a piece separator or for KILLs). Note that if an update
+   matches more than one trigger, all matching triggers see the same
+   $ZTOLDVAL at trigger entry but potentially different values of $ZTVALUE so
+   $ZTUPDATE could change due to the actions of each matching trigger even
+   though all matching triggers have identical -[z]delim and -piece
+   specifications.
+
+   Example:
+
+   +^trigvn -commands=Set -pieces=1;3:6 -delim="|" -xecute="Write !,$ZTUPDATE"
+
+   In the above trigger definition entry, $ZTUPDATE displays a comma
+   separated list of the changed piece numbers if on of the pieces of
+   interest: 1,3,4,5,or 6 are modified by the update.
+
+   GTM>write ^trigvn
+   Window|Table|Chair|Curtain|Cushion|Air Conditioner
+   GTM>set ^trigvn="Window|Dining Table|Chair|Vignette|Pillow|Air Conditioner"
+   4,5
+
+   Note that even though piece numbers 2,4 and 5 are changed, $ZTUPDATE
+   displays only 4,5 because the trigger is not defined for updates for the
+   second piece.
+
+3 $ZTVAlue
+   $ZTVAlue
+
+   For SET, $ZTVALUE has the value assigned to the node by the explicit SET
+   operation. Modifying $ZTVALUE within a trigger modifies the eventual value
+   GT.M assigns to the node. Note that changing $ZTVALUE has a small
+   performance impact because it causes an additional update operation on the
+   node once all trigger code completes. If a node has multiple associated
+   triggers each trigger receives the current value of $ZTVALUE, however,
+   because the triggers run in arbitrary order, FIS strongly recommends no
+   more than one trigger change any given element of application data, for
+   example, a particular piece. For KILL and its variants, $ZTVALUE returns
+   the empty string. While GT.M accepts updates to $ZTVALUE within the
+   trigger code invoked for a KILL or any of its variants, it ultimately
+   discards any such value. Outside trigger context, attempting to SET
+   $ZTVALUE produces a SETINTRIGONLY error.
+
+3 $ZTWOrmhole
+   $ZTWOrmhole
+
+   $ZTWORMHOLE allows you to specify a string up to 128KB of information you
+   want to make available during trigger execution. You can use $ZTWORMHOLE
+   to supply an application-context or process context to your trigger logic.
+   Because GT.M makes $ZTWORMHOLE available throughout the duration of the
+   process, you can access or update $ZTWORMHOLE both from inside and outside
+   a trigger.
+
+   $ZTWORMHOLE provides a mechanism to access information from a
+   process/application context that is otherwise unavailable in trigger
+   context. GT.M records any non-empty string value of $ZTWORMHOLE in the
+   GT.M database journal file as part of any update that invokes at least one
+   trigger which references $ZTWORMHOLE. GT.M also transmits any non-NULL
+   $ZTWORMHOLE value in the replication stream, thus providing the same
+   context to triggers invoked by MUPIP processes (either as part of the
+   replicating instance update process or as part of MUPIP journal
+   recovery/rollback). Therefore, whenever you use $ZTWORMHOLE in a trigger,
+   you create something like a wormhole for process context that is otherwise
+   NEWed in the run-time or non-existent in MUPIP.
+
+   Note that if trigger code does not reference $ZTMORMHOLE, GT.M does not
+   make it available to MUPIP (via the journal files or replication stream).
+   Therefore, if a replicating secondary has different trigger code than the
+   initiating primary (an unusual configuration) and the triggers on the
+   replicating node require information from $ZTWORMHOLE, the triggers on the
+   initiating node must reference $ZTWORMHOLE to ensure GT.M maintains the
+   data it contains for use by the update process on the replicating node.
+   While you can change $ZTWORMHOLE within trigger code, because of the
+   arbitrary ordering of triggers on the same node, such an approach requires
+   careful design and implementation. GTM allows $ZTWORMHOLE to be NEW'd.
+   NEWing $ZTWORMHOLE is slightly different from NEWing other ISVs/variables
+   in the sense that the former retains its original value whereas the latter
+   does not. However, like other NEWs, GT.M restores $ZTWORMHOLE's value when
+   the stack level pops.
+
+   The following table summarizes the read/write permissions assigned to all
+   trigger-related ISVs within trigger context and outside trigger context.
+
+   +------------------------------------------------------------------------+
+   | Intrinsic Special | Within Trigger |               Notes               |
+   |     Variable      |    Context     |                                   |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Set to gtm_trigger_etrap or the   |
+   | $ETRAP            | Read / Write   | empty string when entering        |
+   |                   |                | trigger context.                  |
+   |-------------------+----------------+-----------------------------------|
+   | $REFERENCE        | Read only      | Restored at the completion of a   |
+   |                   |                | trigger.                          |
+   |-------------------+----------------+-----------------------------------|
+   | $TEST             | Read only      | Restored at the completion of a   |
+   |                   |                | trigger.                          |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Always >=1 in trigger code; must  |
+   | $TLEVEL           | Read only      | be the same as the completion of  |
+   |                   |                | processing a trigger as it was at |
+   |                   |                | the start.                        |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTNAME           | Read only      | Returns the trigger name.         |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTDATA           | Read only      | Shows prior state.                |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTLEVEL          | Read only      | Shows trigger nesting.            |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTOLDVAL         | Read only      | Shows the pre-update value.       |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTRAP            | Read only - "" | Must use $ETRAP in trigger code.  |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTRIGGEROP       | Read only      | Shows the triggering command.     |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTUPDATE         | Read only      | Lists modified pieces (if         |
+   |                   |                | requested) for SET.               |
+   |-------------------+----------------+-----------------------------------|
+   | $ZTVALUE          | Read / Write   | Can change the eventual applied   |
+   |                   |                | value for SET.                    |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Holds application context because |
+   | $ZTWORMHOLE       | Read / Write   | trigger code has no access to the |
+   |                   |                | local variable context.           |
+   |-------------------+----------------+-----------------------------------|
+   |                   |                | Holds outermost transaction       |
+   | $ZTSLATE          | Read/ Write    | context for chained or nested     |
+   |                   |                | triggers.                         |
+   +------------------------------------------------------------------------+
+
+1 IO_Processing
+   IO Processing
+
+   This chapter describes the following topics which relate to input and
+   output processing:
+
+     * Input/Output Intrinsic Special Variables, and their Maintenance.
+
+       GT.M provides several intrinsic special variables that allow processes
+       to examine, and in some cases change, certain aspects of the
+       input/output (I/O) processing. The focus in this chapter is how GT.M
+       handles the standard ones, such as $IO, $X, $Y, and those that are
+       GT.M-specific (for example, $ZA, $ZB).
+
+     * Input/Output Devices
+
+       Each device type supported by GT.M responds to a particular subset of
+       deviceparameters, while ignoring others. Devices may be programmed in
+       a device-specific manner, or in a device-independent manner. This
+       chapter discusses each device type, and provides tables of their
+       deviceparameters.
+
+     * Input/Output Commands and their Deviceparameters
+
+       GT.M bases its I/O processing on a simple character stream model. GT.M
+       does not use any pre-declared formats. This chapter describes the GT.M
+       I/O commands OPEN, USE, READ, WRITE, and CLOSE.
+
+   OPEN, USE, and CLOSE commands accept deviceparameters, which are keywords
+   that permit a GT.M program to control the device state. Some
+   deviceparameters require arguments. The current ANSI standard for GT.M
+   does not define the deviceparameters for all devices. This chapter
+   includes descriptions of the GT.M deviceparameters in the sections
+   describing each command.
+
+2 Using_Terminals
+   Using Terminals
 
-   The %GSE utility finds occurrences of a string within the  data  values
-   for selected global nodes and displays the variable name and data on a
-   specified output device.
+   A GT.M process assigns $PRINCIPAL to the UNIX standard input of the
+   process (for READ) and standard output (for WRITE). For a local
+   interactive process, $PRINCIPAL identifies the "terminal" from which the
+   user is signed on.
 
-4 Prompts
-   Prompts
+   While all terminals support the CTRAP deviceparameter, only $PRINCIPAL
+   supports CENABLE. While CTRAP allows terminal input to redirect program
+   flow, CENABLE allows the terminal user to invoke the Direct Mode.
 
-        Output Device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-        Global ^ Requests (using %GSEL)  the  name(s)  of  the  globals  to
-        search; <RETURN> ends selection.
-        String: Requests a search string.
-4 Ex_of_GSE
-   Examples of %GSE
+   Directly connected printers often appear to GT.M as a terminal (although
+   printers generally do not provide input) regardless of whether the printer
+   is connected to the computer with a high speed parallel interface, or an
+   asynchronous terminal controller.
 
-   Example:
+3 Set_Characteristics
+   Set Characteristics
 
+   GT.M does not isolate its handling of terminal characteristics from the
+   operating system environment at large. GT.M inherits the operating system
+   terminal characteristics in effect at the time the GT.M image is invoked.
+   When GT.M exits, the terminal characteristics known by the operating
+   system are restored.
 
-   GTM>do ^%GSE
+   However, if the process temporarily leaves the GT.M environment with a
+   ZSYSTEM command , GT.M does not recognize any changes to the terminal
+   characteristics left by the external environment. This may cause
+   disparities between the physical behavior of the terminal, and the
+   perceived behavior by GT.M.
 
-   Global Search For Every Occurence
+   UNIX enforces standard device security for explicit OPENs of terminals
+   other than the sign-in terminal ($PRINCIPAL). If you are unable to OPEN a
+   terminal, contact your system manager.
 
-   Output device: <terminal>: Test.dat
+   USE of a terminal causes the device driver to flush the output buffer.
+   This feature of the USE command provides routine control over the timing
+   of output, which is occasionally required. However, it also means that
+   redundant USE commands may induce an unnecessary performance penalty.
+   Therefore, FIS recommends restricting USE commands to redirecting I/O,
+   modifying deviceparameters, and initiating specifically required flushes.
+
+   The terminal input buffer size is fixed at 1024 on UNIX and a variable
+   read terminates after 1023 characters.
+
+4 Set_TERM
+   Set TERM
+
+   The environment variable $TERM must specify a terminfo entry that
+   accurately matches the terminal (or terminal emulator) settings. Refer to
+   the terminfo man pages for more information on the terminal settings of
+   the platform where GT.M needs to run.
+
+   Some terminfo entries may seem to work properly but fail to recognize
+   function key sequences or position the cursor properly in response to
+   escape sequences from GT.M. GT.M itself does not have any knowledge of
+   specific terminal control characteristics. Therefore, it is important to
+   specify the right terminfo entry to let GT.M communicate correctly with
+   the terminal. You may need to add new terminfo entries depending on their
+   specific platform and implementation. The terminal (emulator) vendor may
+   also be able to help.
+
+   GT.M uses the following terminfo capabilities. The full variable name is
+   followed by the capname in parenthesis:
+
+   auto_right_margin(am), clr_eos(ed), clr_eol(el), columns(cols), cursor_address(cup), cursor_down(cud1),cursor_left(cub1), cursor_right(cuf1), cursor_up(cuu1), eat_newline_glitch(xenl), key_backspace(kbs), key_dc(kdch1),key_down(kcud1), key_left(kcub1), key_right(kcuf1), key_up(kcuu1), key_insert(kich1), keypad_local(rmkx),keypad_xmit(smkx), lines(lines).
+
+   GT.M sends keypad_xmit before terminal reads for direct mode and READs
+   (other than READ *) if EDITING is enabled. GT.M sends keypad_local after
+   these terminal reads.
+
+3 Summary
+   Summary
+
+   The following tables provide a brief summary of deviceparameters for
+   terminals, grouped into related areas.
+
+   +----------------------------------------------------------------------+
+   |                  Error Processing Deviceparameters                   |
+   |----------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                 COMMENT                  |
+   |-----------------+---------+------------------------------------------|
+   | EXCEPTION=expr  | O/U/C   | Controls device-specific error handling. |
+   +----------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                Interaction Management Deviceparameters                 |
+   |------------------------------------------------------------------------|
+   |    DEVICEPARAMETER    | COMMAND |               COMMENT                |
+   |-----------------------+---------+--------------------------------------|
+   |                       |         | Controls whether <CTRL-C> on         |
+   | [NO]CENABLE           | U       | $PRINCIPAL causes GT.M to go to      |
+   |                       |         | direct mode.                         |
+   |-----------------------+---------+--------------------------------------|
+   | CTRAP=expr            | U       | Controls vectoring on trapped <CTRL> |
+   |                       |         | characters.                          |
+   |-----------------------+---------+--------------------------------------|
+   | [NO]ESCAPE            | U       | Controls escape sequence processing. |
+   |-----------------------+---------+--------------------------------------|
+   |                       |         | Controls interpretation by the       |
+   | [NO]PASTHRU           | U       | operating system of special control  |
+   |                       |         | characters (for example <CTRL-B>).   |
+   |-----------------------+---------+--------------------------------------|
+   | [NO]TERMINATOR[=expr] | U       | Controls characters that end a READ  |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------+
+   |                  Flow Control Deviceparameters                   |
+   |------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |               COMMENT                |
+   |-----------------+---------+--------------------------------------|
+   | [NO]CONVERT     | U       | Controls forcing input to uppercase. |
+   |-----------------+---------+--------------------------------------|
+   | [NO]FILTER      | U       | Controls some $X, $Y maintenance.    |
+   |-----------------+---------+--------------------------------------|
+   | FLUSH           | U       | Clears the typeahead buffer.         |
+   |-----------------+---------+--------------------------------------|
+   | [NO]HOSTSYNC    | U       | Controls host's use of XON/XOFF.     |
+   |-----------------+---------+--------------------------------------|
+   | [NO]READSYNC    | U       | Controls wrapping READs in XON/XOFF. |
+   |-----------------+---------+--------------------------------------|
+   | [NO]TTSYNC      | U       | Controls input response to XON/XOFF. |
+   |-----------------+---------+--------------------------------------|
+   | [NO]TYPEAHEAD   | U       | Controls unsolicited input handling. |
+   +------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                   Screen Management Deviceparameters                   |
+   |------------------------------------------------------------------------|
+   |  DEVICEPARAMETER  | COMMAND |                 COMMENT                  |
+   |-------------------+---------+------------------------------------------|
+   | CLEARSCREEN       | U       | Clears from cursor to end-of-screen.     |
+   |-------------------+---------+------------------------------------------|
+   | DOWNSCROLL        | U       | Moves display down one line.             |
+   |-------------------+---------+------------------------------------------|
+   | [NO]ECHO          | U       | Controls the host echo of input.         |
+   |-------------------+---------+------------------------------------------|
+   | ERASELINE         | U       | Clears from cursor to end-of-line.       |
+   |-------------------+---------+------------------------------------------|
+   | [Z]LENGTH=intexpr | U       | Controls maximum number of lines on a    |
+   |                   |         | page ($Y).                               |
+   |-------------------+---------+------------------------------------------|
+   | UPSCROLL          | U       | Moves display up one line.               |
+   |-------------------+---------+------------------------------------------|
+   | [Z]WIDTH=intexpr  | U       | Controls the maximum width of an output  |
+   |                   |         | line ($X).                               |
+   |-------------------+---------+------------------------------------------|
+   | [Z][NO]WRAP       | U       | Controls handling of output lines longer |
+   |                   |         | than the maximum width.                  |
+   |-------------------+---------+------------------------------------------|
+   | X=intexpr         | U       | Positions the cursor to column intexpr.  |
+   |-------------------+---------+------------------------------------------|
+   | Y=intexpr         | U       | Positions the cursor to row intexpr.     |
+   +------------------------------------------------------------------------+
+
+   O: Applies to the OPEN command
+
+   U: Applies to the USE command
+
+   C: Applies to the CLOSE command
+
+2 _Sequential_Files
+    Sequential Files
+
+   GT.M provides access to sequential files. These files allow linear access
+   to records. Sequential files are used to create programs, store reports,
+   and to communicate with facilities outside of GT.M.
+
+3 Sequential_File_Pointers
+   Sequential File Pointers
 
-   Global ^a <RETURN>
+   Sequential file I/O operations use a construct called a file pointer. The
+   file pointer logically identifies the next record to read or write. OPEN
+   commands position the file pointer at the beginning of the file (REWIND)
+   or at the end-of-file (APPEND). APPEND cannot reposition a file currently
+   open. Because the position of each record depends on the previous record,
+   a WRITE destroys the ability to reliably position the file pointer to
+   subsequent records in a file. Therefore, by default (NOTRUNCATE), GT.M
+   permits WRITEs only when the file pointer is positioned at the end of the
+   file.
 
-   ^a
+   A file that has been previously created and contains data that should be
+   retained can also be opened with the device parameter APPEND.
+
+   If a device has TRUNCATE enabled, a WRITE issued when the file pointer is
+   not at the end of the file causes all contents after the current file
+   pointer to be discarded. This effectively moves the end of the file to the
+   current position and permits the WRITE.
+
+3 Line_Terminators
+   Line Terminators
+
+   LF ($CHAR(10)) terminates the logical record for all M mode sequential
+   files, TRM, PIPE, and FIFO. For non FIXED format sequential files and
+   terminal devices for which character set is not M, all the standard
+   Unicode line terminators terminate the logical record. These are U+000A
+   (LF), U+0000D (CR), U+000D followed by U+000A (CRLF), U+0085 (NEL), U+000C
+   (FF), U+2028 (LS) and U+2029 (PS).
+
+3 _Binary_Files
+    Binary Files
+
+   To write a binary data file, open it with FIXED:WRAP:CHSET="M" and set $X
+   to zero before the WRITE to avoid filling the last record with spaces (the
+   default PAD byte value).
+
+   **Note**
+
+   With CHSET not "M", FIXED has a different definition. Each record is
+   really the same number of bytes as specified by RECORDSIZE. Padding bytes
+   are added as needed to each record.
+
+   Example:
+
+   GTM>zprint ^gtmcp
+   gtmcp   ; Copy a file using GT.M
+     new dest,line,max,src
+     if 2>$length($zcmdline," ") write "Usage: $gtm_dist/mumps -run gtmcp srcfile destfile",!
+     set dest=$piece($zcmdline," ",2)
+     set src=$piece($zcmdline," ",1)
+     set max=1024*1024
+     open src:(readonly:fixed:wrap:chset="M")
+     open dest:(newversion:fixed:wrap:chset="M")
+     for  k line use src read line#max quit:$zeof  do
+     . use $principal write $length(line),!
+     . use dest write line set $x=0
+     use $principal
+     if $length(line) use dest write line s $x=0 use $principal
+     close src
+     close dest
+     quit
+
+3 Summary
+   Summary
+
+   The following tables provide a brief summary of deviceparameters for
+   sequential files grouped into related areas.
+
+   +----------------------------------------------------------------------+
+   |                  Error Processing Deviceparameters                   |
+   |----------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                 COMMENT                  |
+   |-----------------+---------+------------------------------------------|
+   | EXCEPTION=expr  | O/U/C   | Controls device-specific error handling. |
+   +----------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |               File Pointer Positioning Deviceparameters                |
+   |------------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                  COMMENT                   |
+   |-----------------+---------+--------------------------------------------|
+   | APPEND          | O       | Positions file pointer at EOF.             |
+   |-----------------+---------+--------------------------------------------|
+   | REWIND          | O/U/C   | Positions file pointer at start of the     |
+   |                 |         | file.                                      |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                      File Format Deviceparameters                      |
+   |------------------------------------------------------------------------|
+   |  DEVICEPARAMETERS  | COMMAND |                 COMMENT                 |
+   |--------------------+---------+-----------------------------------------|
+   | [NO]FIXED          | O       | Controls whether records have fixed     |
+   |                    |         | length.                                 |
+   |--------------------+---------+-----------------------------------------|
+   | [Z]LENGTH=intexpr  | U       | Controls virtual page length.           |
+   |--------------------+---------+-----------------------------------------|
+   | RECORDSIZE=intexpr | O       | Specifies maximum record size.          |
+   |--------------------+---------+-----------------------------------------|
+   | STREAM             | O       | Specifies the STREAM format.            |
+   |--------------------+---------+-----------------------------------------|
+   | VARIABLE           | O       | Controls whether records have variable  |
+   |                    |         | length.                                 |
+   |--------------------+---------+-----------------------------------------|
+   | [Z]WIDTH=intexpr   | U       | Controls maximum width of an output     |
+   |                    |         | line.                                   |
+   |--------------------+---------+-----------------------------------------|
+   | [Z][NO]WRAP        | O/U     | Controls handling of records longer     |
+   |                    |         | than device width.                      |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                      File Access Deviceparameters                      |
+   |------------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                  COMMENT                   |
+   |-----------------+---------+--------------------------------------------|
+   | DELETE          | C       | Specifies file be deleted by CLOSE.        |
+   |-----------------+---------+--------------------------------------------|
+   | GROUP=expr      | O/C     | Specifies file permissions for other users |
+   |                 |         | in the owner's group.                      |
+   |-----------------+---------+--------------------------------------------|
+   | NEWVERSION      | O       | Specifies GT.M create a new version of     |
+   |                 |         | file.                                      |
+   |-----------------+---------+--------------------------------------------|
+   | OWNER=expr      | O/C     | Specifies file permissions for the owner   |
+   |                 |         | of file.                                   |
+   |-----------------+---------+--------------------------------------------|
+   | [NO]READONLY    | O       | Controls read-only file access.            |
+   |-----------------+---------+--------------------------------------------|
+   | RENAME=expr     | C       | Specifies CLOSE replace name of a disk     |
+   |                 |         | file with name specified by expression.    |
+   |-----------------+---------+--------------------------------------------|
+   | SYSTEM=expr     | O/C     | Specifies file permissions for the owner   |
+   |                 |         | of the file (same as OWNER).               |
+   |-----------------+---------+--------------------------------------------|
+   | [NO]TRUNCATE    | O/U     | Controls overwriting of existing data in   |
+   |                 |         | file.                                      |
+   |-----------------+---------+--------------------------------------------|
+   | UIC=expr        | O/C     | Specifies file's owner ID.                 |
+   |-----------------+---------+--------------------------------------------|
+   | WORLD=expr      | O/C     | Specifies file permissions for users not   |
+   |                 |         | in the owner's group.                      |
+   +------------------------------------------------------------------------+
+
+   O: Applies to the OPEN command
+
+   U: Applies to the USE command
+
+   C: Applies to the CLOSE command
+
+2 _FIFO_Characteristics
+    FIFO Characteristics
+
+   FIFOs have most of the same characteristics as other sequential files,
+   except that READs and WRITEs can occur in any order.
 
-   Current total of 1 global.
+   The following characteristics of FIFO behavior may be helpful in using
+   them effectively.
 
-   Global ^ <RETURN>
+   With READ:
+
+     * If a READ is done while there is no data in the FIFO:
+
+   The process hangs until data is put into the FIFO by another process, or
+   the READ times out, when a timeout is specified.
+
+   The following table shows the result and the values of I/O status
+   variables for different types of READ operations on a FIFO device.
+
+   +------------------------------------------------------------------------+
+   | Operation |    Result     |  $DEVICE   | $ZA | $TEST |    X    | $ZEOF |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:n  | Normal        | 0          | 0   | 1     | Data    | 0     |
+   |           | Termination   |            |     |       | Read    |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:n  | Timeout with  | 0          | 0   | 0     | empty   | 0     |
+   |           | no data read  |            |     |       | string  |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           | Timeout with  |            |     |       | Partial |       |
+   | READ X:n  | partial data  | 0          | 0   | 0     | data    | 0     |
+   |           | read          |            |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           |               | 1,Device   |     |       | empty   |       |
+   | READ X:n  | End of File   | detected   | 9   | 1     | string  | 1     |
+   |           |               | EOF        |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:0  | Normal        | 0          | 0   | 1     | Data    | 0     |
+   |           | Termination   |            |     |       | Read    |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:0  | No data       | 0          | 0   | 0     | empty   | 0     |
+   |           | available     |            |     |       | string  |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           | Timeout with  |            |     |       | Partial |       |
+   | READ X:0  | partial data  | 0          | 0   | 0     | data    | 0     |
+   |           | read          |            |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           |               | 1,Device   |     |       | empty   |       |
+   | READ X:0  | End of File   | detected   | 9   | 1     | string  | 1     |
+   |           |               | EOF        |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X    | Error         | 1,<error   | 9   | n/c   | empty   | 0     |
+   |           |               | signature> |     |       | string  |       |
+   +------------------------------------------------------------------------+
+
+   With WRITE:
+
+     * The FIFO device does non-blocking writes. If a process tries to WRITE
+       to a full FIFO and the WRITE would block, the device implicitly tries
+       to complete the operation up to a default of 10 times. If the
+       gtm_non_blocked_write_retries environment variable is defined, this
+       overrides the default number of retries. If the retries do not succeed
+       (remain blocked), the WRITE sets $DEVICE to "1,Resource temporarily
+       unavailable", $ZA to 9, and produces an error. If the GT.M process has
+       defined an EXCEPTION, $ETRAP or $ZTRAP, the error trap may choose to
+       retry the WRITE after some action or delay that might remove data from
+       the FIFO device.
+     * While it is hung, the process will not respond to <CTRL-C>.
+
+   With CLOSE:
+
+     * The FIFO is not deleted unless the DELETE qualifier is specified.
+     * If a process closes the FIFO with the DELETE qualifier, the FIFO
+       becomes unavailable to new users at that time.
+     * All processes currently USEing the FIFO may continue to use it, until
+       the last process attached to it CLOSES it, and is destroyed.
+     * Any process OPENing a FIFO with the same name as a deleted FIFO
+       creates a new one to which subsequent OPENs attach.
+
+   A process must have read and write privileges on a FIFO to access it. File
+   permissions have no affect on a process that already has the FIFO open.
+
+3 FIFO_Deviceparameter_Summary
+   FIFO Deviceparameter Summary
+
+   The following table summarizes the deviceparameters that can be used with
+   FIFOs.
+
+   +------------------------------------------------------------------------+
+   |                      File Format Deviceparameters                      |
+   |------------------------------------------------------------------------|
+   |  DEVICEPARAMETER   | CMD |                 DESCRIPTION                 |
+   |--------------------+-----+---------------------------------------------|
+   | [NO]FIXED          | O   | Controls whether records have fixed length. |
+   |--------------------+-----+---------------------------------------------|
+   | [Z]LENGTH=intexpr  | U   | Controls the virtual page length.           |
+   |--------------------+-----+---------------------------------------------|
+   | RECORDSIZE=intexpr | O   | Specifies the maximum record size.          |
+   |--------------------+-----+---------------------------------------------|
+   | VARIABLE           | O   | Controls whether records have variable      |
+   |                    |     | length.                                     |
+   |--------------------+-----+---------------------------------------------|
+   | [Z]WIDTH=intexpr   | U   | Sets the device's logical record size and   |
+   |                    |     | enables WRAP.                               |
+   |--------------------+-----+---------------------------------------------|
+   | [Z][NO]WRAP        | O/U | Controls the handling of records longer     |
+   |                    |     | than the device width.                      |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                      File Access Deviceparameters                      |
+   |------------------------------------------------------------------------|
+   | DEVICEPARAMETER | CMD |                    COMMENT                     |
+   |-----------------+-----+------------------------------------------------|
+   |                 |     | Specifies that the FIFO should be deleted when |
+   |                 |     | the last user closes it. If specified on an    |
+   |                 |     | OPEN, DELETE is activated only at the time of  |
+   | DELETE          | C   | the close. No new attachements are allowed to  |
+   |                 |     | a deleted FIFO and any new attempt to use a    |
+   |                 |     | FIFO with the name of the deleted device       |
+   |                 |     | creates a new device.                          |
+   |-----------------+-----+------------------------------------------------|
+   | GROUP=expr      | O/C | Specifies file permissions for other users in  |
+   |                 |     | owner's group.                                 |
+   |-----------------+-----+------------------------------------------------|
+   | OWNER=expr      | O/C | Specifies file permissions for owner of file.  |
+   |-----------------+-----+------------------------------------------------|
+   |                 |     | Specifies that CLOSE replace the name of a     |
+   | RENAME=expr     | C   | disk file with the name specified by the       |
+   |                 |     | expression.                                    |
+   |-----------------+-----+------------------------------------------------|
+   | SYSTEM=expr     | O/C | Specifies file permissions for owner of file   |
+   |                 |     | (same as OWNER).                               |
+   |-----------------+-----+------------------------------------------------|
+   | UIC=expr        | O/C | Specifies the file's owner ID.                 |
+   |-----------------+-----+------------------------------------------------|
+   | WORLD=expr      | O/C | Specifies file permissions for users not in    |
+   |                 |     | the owner's group.                             |
+   +------------------------------------------------------------------------+
+
+2 Using_Null_Devices
+   Using Null Devices
+
+   Null devices comprise of a collection of system purpose devices that
+   include /dev/null, /dev/zero, /dev/random, and /dev/urandom.
+
+     o /dev/null returns a null string on READ and sets $ZEOF
+     o /dev/random and /dev/urandom return a random value on READ and set
+       $ZEOF
+     o /dev/zero returns 0's on READ and does not set $ZEOF
+
+   A null device discards all output. GT.M maintains a virtual cursor
+   position for null devices as it does for terminals on output. Use null
+   devices for program testing and debugging, or for jobs that permit I/O to
+   be discarded under certain circumstances. For example, JOB processes must
+   have input and output devices associated with them, even though they do
+   not use them. Null devices are low overhead never-fail alternatives for
+   certain classes of I/O.
+
+3 Null_Deviceparameter_Summary
+   Null Deviceparameter Summary
+
+   +------------------------------------------------------------------------+
+   |                         Null Deviceparameters                          |
+   |------------------------------------------------------------------------|
+   |  DEVICEPARAMETER  | COMMAND |                 COMMENT                  |
+   |------------------------------------------------------------------------|
+   |                     O: Applies to the OPEN command                     |
+   |                                                                        |
+   |                     U: Applies to the USE command                      |
+   |                                                                        |
+   |                    C: Applies to the CLOSE command                     |
+   |------------------------------------------------------------------------|
+   |                   |         | Controls device-specified error          |
+   |                   |         | handling. For the null device this is    |
+   | EXCEPTION=expr    | O/U/C   | only EOF handling and therefore          |
+   |                   |         | exceptions can never be invoked except   |
+   |                   |         | by a READ.                               |
+   |-------------------+---------+------------------------------------------|
+   | [NO]FILTER[=expr] | U       | Controls some $X,$Y maintenance.         |
+   |-------------------+---------+------------------------------------------|
+   | [Z]LENGTH=intexpr | U       | Controls the length of the virtual page. |
+   |-------------------+---------+------------------------------------------|
+   | [Z]WIDTH=intexpr  | U       | Controls maximum size of a record.       |
+   |-------------------+---------+------------------------------------------|
+   | [Z][NO]WRAP       | O/U     | Controls handling of records longer than |
+   |                   |         | the maximum width.                       |
+   |-------------------+---------+------------------------------------------|
+   | X=intexpr         | U       | Sets $X to intexpr.                      |
+   |-------------------+---------+------------------------------------------|
+   | Y=intexpr         | U       | Sets $Y to intexpr.                      |
+   +------------------------------------------------------------------------+
+
+3 Null_Device_Examples
+   Null Device Examples
 
-   String: Hello
+   This section contains examples of null device usage.
+
+   Example:
+
+   GTM>do ^runrep
+   runrep;
+    zprint ^runrep
+    set dev="/dev/null"
+    set hdr="********* REPORT HEADER ************"
+    open dev use dev
+    set x="" write hdr,!,$zdate($horolog),?30,$job,!
+    for  set x=$order(^tmp($job,x)) quit:x=""  do REPORT
+    quit
+   REPORT;
+    ;large amount of code
+    quit;
+
+   This program produces a report derived from the information in the global
+   variable ^tmp. The unspecified routine REPORT may potentially contain a
+   large amount of code. To see that the basic program functions without
+   error, the programmer may discard the output involved in favor of watching
+   the function. To run the program normally, the programmer simply has to
+   change the variable dev to name another device and the routine REPORT
+   writes to the dev device.
+
+   Example:
+
+   job ^X:(in="/dev/null":out="/dev/null":err="error.log")
+   JOB ^X:(IN="/dev/null":OUT="/dev/null":ERR="error.log")
+
+   This example issues a GT.M JOB command to execute the routine ^X in
+   another process. This routine processes a large number of global variables
+   and produces no output. In the example, the JOBbed process takes its input
+   from a null device, and sends its output to a null device. If the JOBbed
+   process encounters an error, it directs the error message to error.log.
+
+2 Using_PIPE_Devices
+   Using PIPE Devices
+
+   A PIPE device is used to access and manipulate the input and/or output of
+   a shell command as a GT.M I/O device. GT.M maintains I/O status variables
+   for a PIPE device just as it does for other devices. An OPEN of the device
+   starts a sub-process. Data written to the device by the M program is
+   available to the process on its STDIN. The M program can read the STDOUT
+   and STDERR of the sub-process. This facilitates output only applications,
+   such as printing directly from a GT.M program to an lp command; input only
+   applications, such as reading the output of a command such as ps; and
+   co-processing applications, such as using iconv to convert data from one
+   encoding to another.
+
+   A PIPE is akin to a FIFO device. Both FIFO and PIPE map GT.M devices to
+   UNIX pipes, the conceptual difference being that whereas a FIFO device
+   specifies a named pipe, but does not specify the process on the other end
+   of the pipe, a PIPE device specifies a process to communicate with, but
+   the pipes are unnamed. Specifically, an OPEN of a PIPE creates a
+   subprocess with which the GT.M process communicates.
+
+   A PIPE device is specified with a "PIPE" value for mnemonicspace on an
+   OPEN command.
+
+   **Note**
+
+   GT.M ignores the mnemonicspace specification on an OPEN of a previously
+   OPEN device and leaves the existing device with its original
+   characteristics.
+
+3 PIPE_Characteristics
+   PIPE Characteristics
+
+   The following characteristics of PIPE may be helpful in using them
+   effectively.
+
+   With Read:
+
+   A READ with no timeout reads whatever data is available to be read; if
+   there is no data to be read, the process hangs until some data becomes
+   available.
+
+   A READ with a timeout reads whatever data is available to be read, and
+   returns; if there is no data to be read, the process waits for a maximum
+   of the timeout period, an integer number of seconds, for data to become
+   available (if the timeout is zero, it returns immediately, whether or not
+   any data was read). If the READ returns before the timeout expires, it
+   sets $TEST to TRUE(1); if the timeout expires, it sets $TEST to FALSE (0).
+   When the READ command does not specify a timeout, it does not change
+   $TEST. READ specifying a maximum length (for example, READ X#10 for ten
+   characters) reads until either the PIPE has supplied the specified number
+   of characters, or a terminating delimiter.
+
+   The following table shows the result and values of I/O status variables
+   for various READ operations on a PIPE device.
+
+   +------------------------------------------------------------------------+
+   | Operation |    Result     |  $DEVICE   | $ZA | $TEST |    X    | $ZEOF |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:n  | Normal        | 0          | 0   | 1     | Data    | 0     |
+   |           | Termination   |            |     |       | Read    |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:n  | Timeout with  | 0          | 0   | 0     | empty   | 0     |
+   |           | no data read  |            |     |       | string  |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           | Timeout with  |            |     |       | Partial |       |
+   | READ X:n  | partial data  | 0          | 0   | 0     | data    | 0     |
+   |           | read          |            |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           |               | 1,Device   |     |       | empty   |       |
+   | READ X:n  | End of File   | detected   | 9   | 1     | string  | 1     |
+   |           |               | EOF        |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:0  | Normal        | 0          | 0   | 1     | Data    | 0     |
+   |           | Termination   |            |     |       | Read    |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X:0  | No data       | 0          | 0   | 0     | empty   | 0     |
+   |           | available     |            |     |       | string  |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           | Timeout with  |            |     |       | Partial |       |
+   | READ X:0  | partial data  | 0          | 0   | 0     | data    | 0     |
+   |           | read          |            |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   |           |               | 1,Device   |     |       | empty   |       |
+   | READ X:0  | End of File   | detected   | 9   | 1     | string  | 1     |
+   |           |               | EOF        |     |       |         |       |
+   |-----------+---------------+------------+-----+-------+---------+-------|
+   | READ X    | Error         | 1,<error   | 9   | n/c   | empty   | 0     |
+   |           |               | signature> |     |       | string  |       |
+   +------------------------------------------------------------------------+
+
+   With WRITE:
+
+   The PIPE device does non-blocking writes. If a process tries to WRITE to a
+   full PIPE and the WRITE would block, the device implicitly tries to
+   complete the operation up to a default of 10 times. If the
+   gtm_non_blocked_write_retries environment variable is defined, this
+   overrides the default number of retries. If the retries do not succeed
+   (remain blocked), the WRITE sets $DEVICE to "1,Resource temporarily
+   unavailable", $ZA to 9, and produces an error. If the GT.M process has
+   defined an EXCEPTION, $ETRAP or $ZTRAP, the error trap may choose to retry
+   the WRITE after some action or delay that might remove data from the PIPE
+   device.
 
-   ^a
+   With WRITE /EOF:
+
+   WRITE /EOF to a PIPE device flushes, sets $X to zero (0) and terminates
+   output to the created process, but does not CLOSE the PIPE device. After a
+   WRITE /EOF, any additional WRITE to the device discards the content, but
+   READs continue to work as before. A WRITE /EOF signals the receiving
+   process to expect no further input, which may cause it to flush any output
+   it has buffered and terminate. You should explicitly CLOSE the PIPE device
+   after finishing all READs. If you do not want WRITE /EOF to flush any
+   pending output including padding in FIXED mode or a terminating EOL in
+   NOFIXED mode, SET $X=0 prior to the WRITE /EOF.
+
+   To avoid an indefinite hang doing a READ from a created process that
+   buffers its output to the input of the PIPE device, READ with timeout
+   (typically 0).
+
+   With CLOSE:
+
+   The CLOSE of a PIPE device prevents all subsequent access to the pipes
+   associated with the device. Unless the OPEN that created the device
+   specified INDEPENDENT, the process terminates. Note that any subsequent
+   attempt by the created process to read from its stdin (which would be a
+   closed pipe) returns an EOF and typical UNIX behavior would be to
+   terminate on such an event.
+
+3 PIPE_Device_Examples
+   PIPE Device Examples
+
+   The following examples show the use of deviceparameters and status
+   variables with PIPE devices.
+
+   Example:
+
+   pipe1;
+     set p1="test1"
+     open p1:(shell="/bin/sh":comm="cat")::"PIPE"
+     for i=1:1:10 do
+     . use p1
+     . write i,":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ",!
+     . read x
+     . use $P
+     . write x,!
+     close p1
+     quit
+
+   This WRITEs 10 lines of output to the cat command and reads the cat output
+   back into the local variable x. The GT.M process WRITEs each line READ
+   from the PIPE to the principal device. This example works because "cat" is
+   not a buffering command. The example above would not work for a command
+   such as tr that buffers its input.
+
+   Example :
+
+   pipe3;
+     set p1="test1"
+     open p1:(shell="/bin/sh":command="tr -d e")::"PIPE"
+     for i=1:1:1000 do
+     . use p1
+     . write i,":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ",!
+     . read x:0
+     . if '+$device use $principal write x,!
+     use p1
+     write /EOF
+     for  read x quit:$zeof  use $principal write x,! use p1
+     close p1
+     quit
+
+   This shows the use of tr (a buffering command) in the created process for
+   the PIPE device. To see the buffering effect the GT.M process WRITEs 1000
+   lines to the PIPE device. Different operating systems may have different
+   buffer sizes. Notice the use of the r x:0 and the check on $DEVICE in the
+   loop. If $DEVICE is 0, WRITE x writes the data read to the principal
+   device. No actual READs complete, however, until tr reaches its buffer
+   size and writes to its stdout. The final few lines remain buffered by tr
+   after the process finishes the first loop. The GT.M process then issues a
+   WRITE /EOF to the PIPE causing tr to flush its buffered lines. In the
+   final for loop the GT.M process uses the simple form of READ x from the
+   PIPE followed by a WRITE of each line to the principal device until $zeof
+   becomes TRUE.
+
+   Example :
+
+   pipe4;
+     set a="test"
+     open a:(command="nestin":independent)::"PIPE"
+     use a
+     set key=$KEY
+     write "Show ntestin still running after CLOSE of a",!
+     write "The parent process of 1 shows the parent shell has exited after CLOSE of a"
+     read line1,line2
+     use $principal
+     write !,line1,!,line2,!,!
+     set k="ps -ef | grep -v grep | grep -v sh | grep -w '"_key_"' | awk '{print $2}'"
+     set b="getpid"
+     open b:(command=k:readonly)::"PIPE"
+     use b
+     read pid
+     close a
+     close b
+     set k2="ps -ef | grep -v grep | grep -v sh | grep -w '"_pid_"'"
+     set c="psout"
+     open c:(command=k2:writeonly)::"PIPE"
+     close c
+     quit
+
+   This demonstrates that the created process nestin keeps running as an
+   INDEPENDENT process after the GT.M process CLOSEs the pipe. This GT.M
+   process uses another PIPE device to return the process id of ntestin and
+   READ it into pid so that it may be killed by this or another process,
+   should that be appropriate.
+
+   **Note**
+
+   "nestin.c" is a program which reads from standard input and writes to
+   standard output until it see and EOF. It then loops for 300 1sec sleeps
+   doing nothing. The purpose of using independent is as a server process
+   which continues until it receives some other signal for termination.
+
+   Example:
+
+   GTM>kill ^a
+
+   GTM>zprint ^indepserver
+   indepserver;
+     read x
+     write "received = ",x,!
+     set ^quit=0
+     for  do  quit:^quit
+     . if $data(^a) write "^a = ",^a,!
+     . Hang 5
+
+   GTM>set a="test"
+
+   GTM>open a:(command="mumps -run ^indepserver>indout":independent)::"pipe"
+
+   GTM>use a
+
+   GTM>write "instructions",!
+
+   GTM>close a
+
+   GTM>zsystem "cat indout"
+   received = instructions
+
+   GTM>set ^a=1
+
+   GTM>zsystem "cat indout"
+   received = instructions
+   ^a = 1
+   ^a = 1
+   ^a = 1
+
+   GTM>s ^quit=1
+
+   GTM>zsystem "cat indout"
+   received = instructions
+   ^a = 1
+   ^a = 1
+   ^a = 1
+   ^a = 1
+   GTM>
 
-   ^a(10) Hello Adam
+   This is a simple example using a mumps process as a server.
+
+   Example:
+
+   pipe5;
+     set p1="test1"
+     set a=0
+     open p1:(shell="/bin/sh":command="cat":exception="goto cont1")::"PIPE"
+     set c=":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"
+     for i=1:1:10000  do
+     . use p1
+     . write i_c,!
+     . use $principal write i,!
+     use p1
+     write /EOF
+     for  read x quit:$zeof  use $principal write x,! use p1
+     close p1
+     quit
+     cont1
+     if $zeof quit
+     if a=0 set a=i/2
+     set z=$za
+     ; use $device to make sure ztrap is caused by blocked write to pipe
+     set d=$device
+     if "1,Resource temporarily unavailable"=d DO
+     . use $p
+     . write "pipe full, i= ",i," $ZA = ",z,!
+     . set i=i-1
+     . use p1
+     . for j=1:1:a  read x use $principal write j,"-",x,! use p1
+     quit
+
+   This demonstrates WRITEs to a PIPE device with blocking. The WRITE loop
+   has no READ to force the input pipe to fill up which blocks the cat
+   output, causing cat to stop reading its input, letting the pipe acting as
+   input on the PIPE device to fill up and creating the blocked condition.
+   When the process takes the $ZTRAP to cont1 it tests $DEVICE to determine
+   if the trap is caused by the full pipe. If so, it uses the for loop to
+   read half the number of lines output by the main loop. It decrements i and
+   returns to the original WRITE loop to retry the failed line and continue
+   with the WRITEs to the pipe. Depending upon the configuration of the
+   environment, it may trap several times before processing all lines.
+
+3 PIPE_Deviceparameter_Summary
+   PIPE Deviceparameter Summary
+
+   The following table summarizes the PIPE format deviceparameters.
+
+   +------------------------------------------------------------------------+
+   | DEVICE PARAMETER   | CMD | DESCRIPTION                                 |
+   |--------------------+-----+---------------------------------------------|
+   | [NO]FIXED          | O   | Controls whether records have fixed length  |
+   |--------------------+-----+---------------------------------------------|
+   | RECORDSIZE=intexpr | O   | Specifies the maximum record size.          |
+   |--------------------+-----+---------------------------------------------|
+   | VARIABLE           | O   | Controls whether records have variable      |
+   |                    |     | length.                                     |
+   |--------------------+-----+---------------------------------------------|
+   | [Z]WIDTH=intexpr   | U   | Sets the device's logical record size and   |
+   |                    |     | enables WRAP.                               |
+   |--------------------+-----+---------------------------------------------|
+   | [Z][NO]WRAP        | O/U | Controls the handling of records longer     |
+   |                    |     | than the device width.                      |
+   +------------------------------------------------------------------------+
+
+   The following table summarizes PIPE access deviceparamters.
+
+   +------------------------------------------------------------------------+
+   |                |   | Specifies the command string to execut in a       |
+   |                |   | created process for the PIPE device. GT.M uses    |
+   | COMMAND=string | o | the default searching mechanism of the UNIX shell |
+   |                |   | for creating the process and initiating its       |
+   |                |   | command(s).                                       |
+   |----------------+---+---------------------------------------------------|
+   | SHELL=string   | o | Specifies the path to a shell to be used instead  |
+   |                |   | of the default shell                              |
+   |----------------+---+---------------------------------------------------|
+   |                |   | Specifies a device handle for a return pipe to    |
+   |                |   | which the created process writes any standard     |
+   | STDERR=string  | o | error output. The GT.M process can USE, READ, and |
+   |                |   | CLOSE it, but cannot WRITE to it. When the GT.M   |
+   |                |   | process CLOSEs the PIPE device the PIPE device    |
+   |                |   | CLOSEs STDERR, if still OPEN.                     |
+   |----------------+---+---------------------------------------------------|
+   | WRITEONLY      | o | Specifies that the GT.M process may only WRITE to |
+   |                |   | the created process via the PIPE device.          |
+   |----------------+---+---------------------------------------------------|
+   |                |   | Specifies that the GT.M process may only READ     |
+   |                |   | from the created process via the PIPE device.     |
+   | READONLY       | o | Output from both the standard output and the      |
+   |                |   | standard error output of the created process is   |
+   |                |   | available unless STDERR is specified.             |
+   |----------------+---+---------------------------------------------------|
+   | PARSE          | o | Specifies that GT.M parse the COMMAND and issue   |
+   |                |   | an OPEN exception for any invalid command.        |
+   |----------------+---+---------------------------------------------------|
+   | INDEPENDENT    | o | Specifies that the created process continues to   |
+   |                |   | execute after the PIPE device is CLOSEd.          |
+   +------------------------------------------------------------------------+
+
+2 Using_Socket_Devices
+   Using Socket Devices
 
-   Total 1 matches found in 25 nodes.
+   SOCKET devices are used to access and manipulate sockets. A SOCKET device
+   can have unlimited associated sockets. The default limit is 64. Set the
+   environment variable gtm_max_sockets to the number of maximum associated
+   sockets sockets that you wish to set for a GT.M process.
+   $VIEW("MAX_SOCKETS") returns the current value of the maximum number of
+   associated sockets.
 
-   Global ^ <RETURN>
+   At any time, only one socket from the collection can be the current
+   socket. If there is no current socket, an attempt to READ from, or WRITE
+   to the device, generates an error.
 
-   GTM>
+   Sockets can be attached and detached from the collection of sockets
+   associated with a device. Detached sockets belong to a pseudo-device
+   called the "socketpool". A process can detach a socket from a device and
+   later attach it to the same device or another device.
 
-   This example searches global ^a for the string "Hello" and displays all
-   nodes that contain that string.
+   **Caution**
 
-3 GSEL
-   %GSEL
+   Currently, GT.M does not produce an error if a socket is attached to a
+   device having a different CHSET.
 
+   **Note**
 
-   The %GSEL utility selects globals. %GSEL creates a variable %ZG that is
-   a local array of the  selected  globals.  After  each  selection  %GSEL
-   displays the number of globals in %ZG.
+   The GT.M socket device interface does not have the ability to pass sockets
+   between related or unrelated processes. Currently error trapping operates
+   on a device, rather than on a socket.
 
-   %GSEL accepts the wildcard characters asterisk (*),  percent  sign  (%)
-   and question mark  (?).  The  wildcards  carry  their  usual  meanings,
-   asterisk (*) denoting a field or a portion of  a  field,  and  question
-   mark (?) or percent sign (%) denoting a single character. The wildcards
-   question mark (?) and percent sign (%) lose their meanings when in the
-   first position of a global name. %GSEL interprets a percent sign (%) in
-   the first position of a global name literally.
+3 Message_Management
+   Message Management
 
-   A colon (:) between two globals specifies a range.
+   From an application perspective, the transport layers used by a socket
+   device are stream-oriented, with no provisions for implicit application
+   messages. Therefore, the following are two common protocols used to
+   segment application messages.
 
-   A minus sign (-) or quotation mark (') preceding a global name removes
-   that global from the %ZG array. A question  mark  (?)  provides  online
-   help, and "?D" displays global names currently in the array.
+    1. One method is to use a, typically small, fixed length message
+       containing the length of the next, variable length, message. In GT.M a
+       simplistic writer might be:
 
-4 Util_Labels
-   Utility Labels
+       Write $Justify($Length(x),4),x
 
-        CALL Runs %GSEL without reinitializing %ZG.
-4 Output_Vars
-   Output Variables
+       A corresponding simplistic reader might be:
 
-        %ZG Contains array of all globals selected.
-4 Prompts
-   Prompts
+       read len#4,x#len
 
-        Global ^ Requests a global name with optional wildcards or a range
-        of names.
-4 Ex_of_GSEL
-   Examples of %GSEL
+       The advantage of this approach is that the message content (the value
+       of x in the code fragments above) can contain any character. The
+       disadvantage is that detecting that the protocol has become
+       desynchronized is a problem.
 
-   Example:
+    2. The other common method is to place a delimiter between each
+       application message. The protocol breaks if a message ever includes a
+       delimiter as part of its content.
 
+   The SOCKET device provides a facility for recognizing delimiters because
+   parsing messages for delimiters is cumbersome.
 
-   GTM>DO ^%GSEL
+3 Socket_Read_Operation
+   Socket Read Operation
+
+   TCP/IP is a stream-based protocol that guarantees that bytes arrive in the
+   order in which they were sent. However, it does not guarantee that they
+   will be grouped in the same packets.
+
+   If packets arrive infrequently, or at varying rates that are sometimes
+   slow, a short interval can waste CPU cycles checking for an unlikely
+   event. On the other hand, if the handling of packets is time critical, a
+   long interval can introduce an undesirable latency. If packets arrive in a
+   rapid and constant flow (an unusual situation), the interval doesn't
+   matter as much, as there is always something in the buffer for the READ to
+   work with. If you do not specify MOREREADTIME, SOCKET READ implements a
+   dynamic approach of using a longer first interval of 200 ms when it finds
+   no data, then shortening the interval to 10 ms when data starts to arrive.
+   If you specify an interval, the SOCKET device always uses the specified
+   interval and does not adjust dynamically.
+
+   Most SOCKET READ operations terminate as a result of the first condition
+   detected from (a) receipt of delimiters, (b) receipt of the maximum number
+   of characters, or (c) expiration of a timeout. Note that all of these
+   conditions are optional, and a specific READ may specify zero or more of
+   them. This section refers to these three conditions as "defined
+   terminating conditions". If a SOCKET READ is not subject to any of the
+   defined terminating conditions, it terminates after it has received at
+   least one character followed by an interval with no new characters. An
+   error can also terminate a READ. While none of the terminating conditions
+   is satisfied, the READ continues.
+
+   The following flowchart represents the logic of a SOCKET READ.
+
+3 Socket_Read_Termination_Conditions
+   Socket Read Termination Conditions
+
+   A SOCKET READ operation terminates if any of the following conditions are
+   met:
+
+   +------------------------------------------------------------------------+
+   |  Terminating   |    Argument Contains    | $Device |   $Key    | $Test |
+   |   Conditions   |                         |         |           |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   | Error          | Empty String            | Error   | Empty     | 1     |
+   |                |                         | String  | String    |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   | Timeout*       | Data received before    | Empty   | Empty     | 0     |
+   |                | timeout                 | String  | String    |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   | Delimiter*     | Data up to, but not     | Empty   | Delimiter | 1     |
+   |                | including the delimiter | String  | String    |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   | Fixed Length   | String of Fixed Length  | Empty   | Empty     | 1     |
+   | Met*           |                         | String  | String    |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   | Width          | Full width String       | Empty   | Empty     | 1     |
+   |                |                         | String  | String    |       |
+   |----------------+-------------------------+---------+-----------+-------|
+   |                | One (1) to as many      |         |           |       |
+   |                | characters as provided  |         |           |       |
+   |                | by the transport        |         |           |       |
+   |                | interface before        |         |           |       |
+   |                | waiting for an interval |         |           |       |
+   |                | (in milliseconds)       |         |           |       |
+   |                | specified by            |         |           |       |
+   |                | MOREREADTIME with no    |         |           |       |
+   |                | additional input. If    |         |           |       |
+   |                | MOREREADTIME is not     |         |           |       |
+   |                | specified, buffer is    |         |           |       |
+   | Buffer Emptied | checked every 200       | Empty   | Empty     | 1     |
+   |                | milliseconds for its    | String  | String    |       |
+   |                | first input and then    |         |           |       |
+   |                | every 10 milliseconds   |         |           |       |
+   |                | until no new input      |         |           |       |
+   |                | arrives and no other    |         |           |       |
+   |                | terminating conditions  |         |           |       |
+   |                | are met.                |         |           |       |
+   |                |                         |         |           |       |
+   |                | IF MOREREADTIME is      |         |           |       |
+   |                | specified, READ uses    |         |           |       |
+   |                | that value exclusively  |         |           |       |
+   |                | for buffer checks.      |         |           |       |
+   +------------------------------------------------------------------------+
+
+   * denotes Defined Terminating Conditions
+
+   A non-fixed-length read, with no timeout and no delimiters (the sixth row
+   in the above table) requires a complex implementation of sequence of READs
+   to ensure a predictable result. This is because the transport layer stream
+   fragments delivered to the reader has only accidental correspondence with
+   the operations performed by the writer. For example, the following:
+
+   Write "Message 1","Message 2" is presented to the reader as the stream
+   "Message1Message2" but it can take from one (1) to 18 READ commands to
+   retrieve the entire stream.
+
+   Messaging protocol should implement READ in any of the following ways:
+
+    1. Use a delimiter to separate messages (generic READ and possibly a
+       larger value for MOREREADTIME).
+    2. Specify messages as <length, value> pairs (a pair of fixed-length
+       READs (READ # ) and possibly a larger value for MOREREADTIME).
+    3. Parse the bytes or characters as they come in (possibly a smaller
+       value for MOREADTIME)
+
+3 Read_Command
+   Read Command
+
+   The READ command may be used to obtain data from a socket. A READ
+   operation terminates if any of the following are detected, in the order
+   specified below:
+
+   +------------------------------------------------------------------------+
+   |   Terminating    |     Argument Contains      | $Device |     $Key     |
+   |    Condition     |                            |         | (Continued)  |
+   |------------------+----------------------------+---------+--------------|
+   | Error            | Empty string               | Error   | Empty string |
+   |                  |                            | string  |              |
+   |------------------+----------------------------+---------+--------------|
+   | Timeout          | Data received before       | Empty   | Empty string |
+   |                  | timeout                    | string  |              |
+   |------------------+----------------------------+---------+--------------|
+   | Delimiter        | Data up to, but not        | Empty   | Delimiter    |
+   |                  | including the delimiter    | string  | string       |
+   |------------------+----------------------------+---------+--------------|
+   | Fixed length met | String of fixed length     | Empty   | Empty string |
+   |                  |                            | string  |              |
+   |------------------+----------------------------+---------+--------------|
+   |                  | One (1) to as many         |         |              |
+   | Buffer emptied   | characters as happen to be | Empty   | Empty string |
+   |                  | provided by the transport  | string  |              |
+   |                  | interface                  |         |              |
+   +------------------------------------------------------------------------+
+
+   A non-fixed-length read, with no timeout and no delimiters requires a
+   complex implementation of sequence of READs to ensure a predictable
+   result. This is because the transport layer stream fragments delivered to
+   the reader has only accidental correspondence with the operations
+   performed by the writer. For example, the following
 
-   Global ^C
+   Write "Message 1","Message 2"
 
-   ^C
+   is presented to the reader as the stream "Message1Message2" but it can
+   take from one (1) to 18 READ commands to retrieve the entire stream.
 
-   Current total of 1 global
+3 WRITE_Command
+   WRITE Command
 
-   Global ^*
+   The WRITE command sends data to a socket.
 
-   ^S ^Y ^c ^class
+   The WRITE command for SOCKET devices accepts following controlmnemonics on
+   a bound socket:
 
-   Current total of 5 globals
+   /L[ISTEN][(numexpr)]
 
-   Global ^-S
+   Where numexpr is in the range 1-5 and specifies the listen queue depth.
 
-   ^S
+   /W[AIT][(timeout)]
 
-   Current total of 4 globals
+   Where timeout is a "numexpr" that specifies how long a server waits for a
+   connect before returning control to the GT.M routine.
 
-   Global ^'Y
+   WRITE /WAIT can also be used to wait for data to be available for reading
+   in addition to waiting for a connection.
 
-   ^Y
+   "WRITE !" inserts the character(s) of the first I/O delimiter (if any) to
+   the sending buffer. If "ZFF=expr" has been used to define a delimiter,
+   "WRITE #" inserts the characters of that delimiter. Otherwise WRITE # has
+   no effect on the stream content. WRITE ! and WRITE # always maintain $X
+   and $Y in a fashion that emulates a terminal cursor position except when
+   the device is OPENed with a UTF CHSET because terminals are in display
+   columns while sockets are in codepoints.
 
-   Current total of 3 globals
+3 Socket_Device_Operation
+   Socket Device Operation
 
-   Global ^?D
+   Each socket may be in one of the following states:
 
-   ^C ^c ^class
+     * Created - indicates that the socket exists.
+     * Bound - indicates that the socket exists and is bound to a port; a
+       "Bound socket" needs a listen queue which is established by a WRITE
+       /LISTEN [after a USE].
+     * Connected - indicates that the socket exists and has a connection.
+
+   A server socket used for accepting new connections goes through the first
+   two states in one step with a single OPEN or in two steps with an OPEN and
+   a USE. When a server does a WRITE /WAIT on a Bound socket, a client can
+   establish a connection which Creates another server socket that is
+   Connected. In server operation, $KEY supplies the port value when a socket
+   is bound (important when port 0 is specified to get the system to choose
+   the port), and a socket handle when a Connected socket is created. A
+   client socket goes through the first and third states with a single OPEN
+   or in two steps with an OPEN and a USE.
+
+3 Socket_Deviceparameter_Summary
+   Socket Deviceparameter Summary
+
+   +------------------------------------------------------------------------+
+   |                   Error Processing Deviceparameters                    |
+   |------------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                  COMMENT                   |
+   |-----------------+---------+--------------------------------------------|
+   | EXCEPTION=expr  | O/U/C   | Controls device-specific error handling.   |
+   |-----------------+---------+--------------------------------------------|
+   |                 |         | If $LENGTH(expr) and ("Tt"[$EXTRACT(expr)) |
+   | IOERROR=expr    | O/U     | then Error Trapping is enabled; otherwise  |
+   |                 |         | the application must check $DEVICE for     |
+   |                 |         | errors.                                    |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |                        Format Deviceparameters                         |
+   |------------------------------------------------------------------------|
+   |  DEVICEPARAMETER   | COMMAND |                 COMMENT                 |
+   |--------------------+---------+-----------------------------------------|
+   | [NO]DELIMITER=expr | O/U     | Specifies socket delimiter(s).          |
+   |--------------------+---------+-----------------------------------------|
+   | [NO]FILTER=expr    | U       | Specifies character filtering for       |
+   |                    |         | socket output.                          |
+   |--------------------+---------+-----------------------------------------|
+   | LENGTH=expr, or    |         | Sets virtual page length for socket     |
+   |                    | U       | device.                                 |
+   | ZLENGTH=expr       |         |                                         |
+   |--------------------+---------+-----------------------------------------|
+   | ICHSET=expr        | O/U/C   | Specifies input character set           |
+   |--------------------+---------+-----------------------------------------|
+   | OCHSET=expr        | O/U/C   | Specifies output character set          |
+   |--------------------+---------+-----------------------------------------|
+   | [Z][NO]WRAP        | O/U     | Controls handling of records longer     |
+   |                    |         | than the device width.                  |
+   |--------------------+---------+-----------------------------------------|
+   | [Z]WIDTH=expr      | U       | Controls the maximum length of an       |
+   |                    |         | output message.                         |
+   |--------------------+---------+-----------------------------------------|
+   | Z[NO]FF=expr       | O/U     | Controls whether and what characters to |
+   |                    |         | send in response to a WRITE #.          |
+   +------------------------------------------------------------------------+
+
+   +------------------------------------------------------------------------+
+   |            Socket Establishment/Disconnect Deviceparameters            |
+   |------------------------------------------------------------------------|
+   | DEVICEPARAMETER | COMMAND |                  COMMENT                   |
+   |-----------------+---------+--------------------------------------------|
+   | CONNECT=expr    | O/U     | expr specifies protocol, and protocol      |
+   |                 |         | specific information                       |
+   |-----------------+---------+--------------------------------------------|
+   | ZLISTEN=expr    | O/U     | Similar to CONNECT but binds the socket    |
+   |                 |         | for subsequent /LISTEN and /WAIT           |
+   +------------------------------------------------------------------------+
+
+3 Socket_Device_Examples
+   Socket Device Examples
 
-   Current total of 3 globals
+   This section contains examples on Socket Device usage.
 
-   Global ^ <RETURN>
+   server;
+           set portno=6321,delim=$c(13)
+           set tcpdev="server$"_$j,timeout=30
+           open tcpdev:(ZLISTEN=portno_":TCP":delim=$c(13):attach="server"):timeout:"SOCKET"
+           use tcpdev
+           write /listen(1)
+           write /wait(timeout)
+           write !,"Hello Client------I am Server",!
+           read x:10
 
-   GTM>ZWRITE
+   ;client.m
+   client;
+           set host="localhost"
+           set portno=6321
+           set delim=$c(13)
+           set tcpdev="client$"_$j,timeout=30
+           open tcpdev:(connect=host_":"_portno_":TCP":delim=$c(13):attach="client"):timeout:"SOCKET"
+           use tcpdev
+           read x:10
+           read y:10
+           use $P
+           write "y=",y,!
+
+   This example transmits the message "Hello Client ---- I am Server" from
+   the Server to the client.
+
+   You can start a GT.M process in response to a connection request made
+   using inetd/xinetd. The following example uses inetd/xinetd to implement a
+   listener which responds to connections and messages just as the prior
+   example.
+
+   In the configuration file for xinetd, define a new service called
+   gtmserver. Set socket_type to "stream" and wait should be "no" as in the
+   following snippet:
+
+   service gtmserver
+   {
+   disable = no
+   type = UNLISTED
+   port = 7777
+   socket_type = stream
+   wait = no
+   user = gtmuser
+   server = /path/to/startgtm
+   }
 
-   %ZG=3
+   If you define the server in /etc/services, the type and port options are
+   not needed. For more information, the xinetd.conf man page for more
+   details.
 
-   %ZG("^C")=""
+   If you are using inetd, a line should be added to /etc/inetd.conf with the
+   sockettype "stream", protocol "tcp", and the "nowait" flag should be
+   specified as in the example below, which assumes a gtmserver service is
+   defined in /etc/services:
 
-   %ZG("^c")=""
+   gtmserver stream tcp nowait gtmuser /path/to/startgtm
 
-   %ZG("^class")=""
+   In both of the above examples, "gtmuser" is the name of the user the
+   service gtmserver should be run as, and "/path/to/startgtm" is the name of
+   a script which defines some environment variables needed by GT.M before
+   starting it. Please check the man page for inetd.conf on your system since
+   the details may be slightly different.
 
-   GTM>
+   The minimum variables are $gtm_dist which should specify the directory
+   containing the GT.M distribution and $gtmroutines. As an example:
 
-   This example adds and subtracts  globals  from  the  list  of  selected
-   globals. "?D"  displays  all  globals  selected.  ZWRITE  displays  the
-   contents of the %ZG array.
+   #!/bin/bash
+   cd /path/to/workarea
+   export gtm_dist=/usr/local/gtm
+   export gtmroutines="/var/myApp/o(/var/myApp/r) $gtm_dist"
+   export gtmgbldir=/var/myApp/g/mumps.dat
+   $gtm_dist/mumps -r start^server
 
-   Example:
+   When start^server begins, the $PRINCIPAL device will already be connected
+   and $KEY will contain "ESTABLISHED|socket_handle|remote_ip_address". In
+   most cases, a USE should be executed to set various device parameters such
+   as delimiters.
 
+   The ZSHOW "D" command provides both the local and remote addresses and
+   ports:
 
-   GTM>DO ^%GSEL
+   0 OPEN SOCKET TOTAL=1 CURRENT=0
+   SOCKET[0]=h11135182870 DESC=0 CONNECTED ACTIVE NOTRAP
+   REMOTE=10.1.2.3 at 53731 LOCAL=10.2.3.4 at 7777
+   ZDELAY ZBFSIZE=1024 ZIBFSIZE=0
 
-   Global ^a
+2 I/O_Commands
+   I/O Commands
 
-   ^a
+   This section describes the following GT.M I/O commands:
 
-   Current total of 1 global.
+     * OPEN establishes a connection from a GT.M process to a device.
+     * USE declares a device as the current source of input and destination
+       for output.
+     * READ accepts characters from the current device into a global or local
+       variable.
+     * WRITE sends characters to the current device.
+     * CLOSE breaks the connection between a GT.M process and a device.
 
-   Global ^<RETURN>
+3 Open
+   Open
 
-   GTM>ZWRITE
+   The OPEN command establishes a connection from a GT.M process to a device.
 
-   %ZG=1
+   The format of the OPEN command is:
 
-   %ZG("^a")=""
+   O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])][:numexpr][:expr]][,...]
 
-   GTM>DO CALL^%GSEL
+   By default, when a device is unavailable, GT.M retries the OPEN
+   indefinitely at approximately one second intervals. A device is
+   unavailable when another process is using it exclusively, or when the
+   OPENing process does not have the resources left to open the device.
 
-   Global ^?d
+   All other errors on OPEN raise an error condition and interrupt program
+   flow. A timeout is a tool that lets a GT.M routine regain program control
+   when a device remains unavailable. When the OPEN specifies a timeout, GT.M
+   keeps retrying until either the OPEN succeeds or the timeout expires.
+
+   If OPEN establishes a connection with a device before the timeout expires,
+   GT.M sets $TEST to TRUE (1). If the timeout expires, GT.M sets $TEST to
+   FALSE (0). If an OPEN command does not specify a timeout, the execution of
+   the command does not affect $TEST.
+
+   If a process has not previously OPENed a device, any deviceparameters not
+   supplied on the OPEN take their default values. When reOPENing a device
+   that it previously closed, a GT.M process restores all characteristics not
+   specified on the OPEN to the values the device had when it was last
+   CLOSEd, except with SD, FIFO, and PIPE. If you have a menu-driven
+   application that OPENs and CLOSEs devices based on user selections, take
+   care that every OPEN explicitly includes all deviceparameters important to
+   the application.
+
+   GT.M treats sequential disk files differently and uses defaults for
+   unspecified sequential disk file characteristics on every OPEN (i.e., GT.M
+   does not retain sequential disk file characteristics on a CLOSE).
+
+   If a process OPENs an already OPEN device, GT.M modifies any
+   characteristics that accept changes when a device is OPEN to reflect any
+   new deviceparameter specifications.
+
+   In UTF-8 mode, the OPEN command recognizes ICHSET, OCHSET, and CHSET as
+   three additional deviceparameters to determine the encoding of the the
+   input / output devices.
+
+   In M mode, the OPEN command ignores ICHSET, OCHSET, CHSET, and PAD device
+   parameters.
 
-   ^a
+   If an I/O device uses a multi-byte character encoding, every READ and
+   WRITE operation of that device checks for well-formed characters according
+   to the specified character encoding with ICHSET or OCHSET. If the I/O
+   commands encounter an illegal sequence of bytes, they always trigger a
+   run-time error; a VIEW "NOBADCHAR" does not prevent such errors. Strings
+   created by $ZCHAR() and other Z equivalent functions may contain illegal
+   sequences. The only way to input or output such illegal sequences is to
+   specify character set "M" with one of these deviceparameters.
 
-   Global ^iv
+4 Examples_of_OPEN
+   Examples of OPEN
 
-   ^iv
+   Example:
 
-   Current total of 2 globals.
+   set sd="report.dat" open sd:newversion
 
-   Global ^<RETURN>
+   This OPENs a NEWVERSION of a sequential disk file named report.dat for
+   both read and write access.
 
-   GTM>ZWRITE
+4 OPEN_Deviceparameters
+   OPEN Deviceparameters
 
-   %ZG=2
+4 OPEN_Deviceparameter_Table
+   OPEN Deviceparameter Table
+
+   +------------------------------------------------------------+
+   |                   OPEN Deviceparameters                    |
+   |------------------------------------------------------------|
+   | OPEN DEVICEPARAMETER | TRM | SD | FIFO | PIPE | NULL | SOC |
+   |------------------------------------------------------------|
+   |           TRM: Valid for terminals and printers            |
+   |                                                            |
+   |            SD: Valid for sequential disk files             |
+   |                                                            |
+   |                   FIFO: Valid for FIFOs                    |
+   |                                                            |
+   |                NULL: Valid for null devices                |
+   |                                                            |
+   |                   PIPE: Valid for PIPEs                    |
+   |                                                            |
+   |               SOC: Valid for Socket devices                |
+   |------------------------------------------------------------|
+   | APPEND               |     | X  |      |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | ATTACH=expr          |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | CHSET=encoding       | X   | X  | X    | X    | X    | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | COMMAND=expr         |     |    |      | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | CONNECT=expr         |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]DELIMITER        |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | EXCEPTION=expr       | X   | X  | X    |      | X    | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | FIFO                 |     |    | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]FIXED            |     | X  | X    | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | GROUP=expr           |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | ICHSET=encoding      | X   | X  | X    | X    | X    | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | INDEPENDENT          |     |    |      | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | IOERROR=expr         |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]NEWVERSION       |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | OCHSET=encoding      | X   | X  | X    | X    | X    | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | OWNER=expr           |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | PARSE                |     |    |      | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]READONLY         |     | X  | X    | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | RECORDSIZE=intexpr   |     | X  | X    | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | REWIND               |     | X  |      |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | SHELL=expr           |     |    |      | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | STDERR=expr          |     |    |      | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]STREAM           |     | X  |      |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | SYSTEM=expr          |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | [NO]TRUNCATE         |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | UIC=expr             |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | VARIABLE             |     | X  | X    | X    |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | WORLD=expr           |     | X  | X    |      |      |     |
+   |----------------------+-----+----+------+------+------+-----|
+   | [Z][NO]WRAP          | X   | X  | X    | X    | X    | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | ZBFSIZE              |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | Z[NO]DELAY           |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | Z[NO]FF              |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | ZIBFSIZE             |     |    |      |      |      | X   |
+   |----------------------+-----+----+------+------+------+-----|
+   | ZLISTEN=expr         |     |    |      |      |      | X   |
+   +------------------------------------------------------------+
+
+3 Use
+   Use
 
-   %ZG("^a")=""
+   The USE command selects the current device for READs (input) and WRITEs
+   (output).
 
-   %ZG("^iv")=""
+   The format of the USE command is:
 
-   GTM>
+   U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
 
-   This example uses CALL^%GSEL  to  add  to  an  existing  %ZG  array  of
-   selected globals.
+   Example:
 
-2 Rtn_Util
-   Routine Utilities
+   USE $P:(X=0:Y=$Y-1:NOECHO)
 
-   The routine utilities are:
+   This example USEs the principal device. If that device is a terminal, the
+   deviceparameters turn off echo and position the cursor to the beginning of
+   the previous line.
+
+4 Summary
+   Summary
+
+   +-----------------------------------------------------------+
+   |                   USE Deviceparameters                    |
+   |-----------------------------------------------------------|
+   | USE DEVICEPARAMETER | TRM | SD | FIFO | PIPE | NULL | SOC |
+   |-----------------------------------------------------------|
+   |           TRM: Valid for terminals and printers           |
+   |                                                           |
+   |              SD: Valid for sequential files               |
+   |                                                           |
+   |                   FIFO: Valid for FIFOs                   |
+   |                                                           |
+   |               PIPE: Valid for PIPE devices                |
+   |                                                           |
+   |               NULL: Valid for null devices                |
+   |                                                           |
+   |               SOC: Valid for socket devices               |
+   |-----------------------------------------------------------|
+   | ATTACH              |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | CANONICAL           | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]CENABLE         | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | CLEARSCREEN         | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | CONNECT             |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]CONVERT         | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | CTRAP=expr          | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]DELIMITER       |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | DETACH=expr         |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | DOWNSCROLL          | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]EBCDIC          |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]ECHO            | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | ERASELINE           | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | ERASETAPE           |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]ESCAPE          | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | EXCEPTION=expr      | X   | X  | X    |      | X    | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]FILTER[=expr]   | X   |    |      |      | X    | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | FLUSH               | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]HOSTSYNC        | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | IOERROR             |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | [Z]LENGTH=expr      | X   | X  | X    |      | X    | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]PASTHRU         | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]RCHK            |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]RETRY           |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | REWIND              |     | X  |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | SKIPFILE=intexpr    |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | SOCKET              |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | SPACE=intexpr       |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]STREAM          |     | X  |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | TERMINATOR[=expr]   | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]TRUNCATE        |     | X  |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]TYPEAHEAD       | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | UPSCROLL            | X   |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [NO]WCHK            |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | [Z]WIDTH=intexpr    | X   | X  | X    | X    | X    | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | [Z][NO]WRAP         | X   | X  | X    |      | X    | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | WRITELB=expr        |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | WRITETM             |     |    |      |      |      |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | X=intexpr           | X   |    |      |      | X    |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | Y=intexpr           | X   |    |      |      | X    |     |
+   |---------------------+-----+----+------+------+------+-----|
+   | ZBFSIZE             |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | Z[NO]DELAY          |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | Z[NO]FF             |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | ZIBUFSIZE           |     |    |      |      |      | X   |
+   |---------------------+-----+----+------+------+------+-----|
+   | ZLISTEN             |     |    |      |      |      | X   |
+   +-----------------------------------------------------------+
+
+3 Close
+   Close
 
-        %FL Lists the comment lines at the beginning of source programs.
-        %RCE Replaces every occurrence of a text string with  another  text
-        string in a routine or a list of routines.
-        %RD Lists routine names available through $ZROUTINES.
-        %RI Loads routines from RO file to *.m files in GT.M format.
-        %RO Writes M source code for one or more routines to  a  sequential
-        device such as a terminal, or a disk file.
-        %RSE Searches for every occurrence of a text string in a routine or
-        a list of routines.
-        %RSEL Selects M routines and places their directories and names in
-        a local array.
-   The  "%"  sign  has  been  removed  from  the  topic  headings  below,
-   intentionally.
+   The CLOSE command breaks the connection between a process and a device.
 
-3 FL
-   %FL
+   The format of the CLOSE command is:
 
+   C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
 
-   The %FL utility lists the comment lines  at  the  beginning  of  source
-   programs.  %FL  writes  the  routines  in  alphabetical  order  to  the
-   specified device. If the output device is not the principal device, %FL
-   displays the name of each routine on the principal device as it writes
-   the routine to the output device.
+   When a CLOSE is issued, GT.M flushes all pending output to the device, and
+   processes any deviceparameters. CLOSEing a device not currently OPEN has
+   no effect.
 
-   %FL uses %RSEL to select routines. For more information, refer  to  the
-   section on %RSEL in this chapter.
+   If a partial record has been output, a WRITE ! is done to complete it. To
+   suppress this action, set $X to zero before the CLOSE.
 
-4 Prompts
-   Prompts
+   GT.M retains the characteristics of all device types, except a sequential
+   file, for use in case of subsequent re-OPENs. If the device is a
+   sequential file, characteristics controlled by deviceparameters are lost
+   after the CLOSE.
 
-        Routine: Requests  the  name(s)  of  the  routines  (using  %RSEL);
-        <RETURN> ends the selection.
-        Output Device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-4 Ex_of_FL
-   Examples of %FL
+   If the device being CLOSEd is $IO, GT.M implicitly USEs $PRINCIPAL. GT.M
+   ignores CLOSE $PRINCIPAL.
 
    Example:
 
+   CLOSE SD:RENAME=SD_".SAV"
 
-   GTM>DO ^%FL
-
-   First Line Lister
-
-   Routine: %D
+   This closes the device and, if it is a disk file, renames it to have the
+   type .SAV.
+
+4 CLOSE_Deviceparameters_Table
+   CLOSE Deviceparameters Table
+
+   +-----------------------------------------------+
+   |            CLOSE Deviceparameters             |
+   |-----------------------------------------------|
+   | CLOSE DEVICEPARAMETER | TRM | SD | FIFO | SOC |
+   |-----------------------------------------------|
+   |      SD: Valid for sequential disk files      |
+   |                                               |
+   |     TRM: Valid for terminals and printers     |
+   |                                               |
+   |             FIFO: Valid for FIFOs             |
+   |                                               |
+   |         NULL: Valid for NULL devices          |
+   |                                               |
+   |         SOC: Valid for Socket devices         |
+   |-----------------------------------------------|
+   | DELETE                |     | X  | X    |     |
+   |-----------------------+-----+----+------+-----|
+   | DESTROY               |     | X  | X    | X   |
+   |-----------------------+-----+----+------+-----|
+   | ERASETAPE=expr        |     |    |      |     |
+   |-----------------------+-----+----+------+-----|
+   | EXCEPTION=expr        | X   | X  | X    | X   |
+   |-----------------------+-----+----+------+-----|
+   | GROUP=expr            |     | X  |      |     |
+   |-----------------------+-----+----+------+-----|
+   | OWNER=expr            |     | X  |      |     |
+   |-----------------------+-----+----+------+-----|
+   | RENAME=expr           |     | X  |      |     |
+   |-----------------------+-----+----+------+-----|
+   | REWIND                |     |    |      |     |
+   |-----------------------+-----+----+------+-----|
+   | SOCKET                |     |    |      | X   |
+   |-----------------------+-----+----+------+-----|
+   | SPACE                 |     |    |      |     |
+   |-----------------------+-----+----+------+-----|
+   | SYSTEM=expr           |     | X  |      |     |
+   |-----------------------+-----+----+------+-----|
+   | UIC=group name        |     | X  |      |     |
+   |-----------------------+-----+----+------+-----|
+   | WORLD=expr            |     | X  |      |     |
+   +-----------------------------------------------+
+
+   **Note**
+
+   Since EXCEPTION is the only CLOSE deviceparameter that applies to NULL,
+   the NULL device column is not shown in the table above.
+
+3 Deviceparameter_Summary
+   Deviceparameter Summary
+
+   +-----------------------------------------+
+   |         Deviceparameter Summary         |
+   |-----------------------------------------|
+   |  DEVICEPARAMETER   | OPEN | USE | CLOSE |
+   |--------------------+------+-----+-------|
+   | APPEND             | X    |     |       |
+   |--------------------+------+-----+-------|
+   | ATTACH             |      | X   |       |
+   |--------------------+------+-----+-------|
+   | BLOCKSIZE=intexpr  | X    |     |       |
+   |--------------------+------+-----+-------|
+   | [NO]CENABLE        |      | X   |       |
+   |--------------------+------+-----+-------|
+   | CLEARSCREEN        |      | X   |       |
+   |--------------------+------+-----+-------|
+   | CONNECT            | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]CONVERT        |      | X   |       |
+   |--------------------+------+-----+-------|
+   | CTRAP              |      | X   |       |
+   |--------------------+------+-----+-------|
+   | DELETE             |      |     | X     |
+   |--------------------+------+-----+-------|
+   | [NO]DELIMITER      | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | DETACH             |      | X   |       |
+   |--------------------+------+-----+-------|
+   | DOWNSCROLL         |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]ECHO           |      | X   |       |
+   |--------------------+------+-----+-------|
+   | ERASELINE          |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]ESCAPE         |      | X   |       |
+   |--------------------+------+-----+-------|
+   | EXCEPTION=expr     | X    | X   | X     |
+   |--------------------+------+-----+-------|
+   | [NO]FILTER[=expr]  |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]FIXED          | X    |     |       |
+   |--------------------+------+-----+-------|
+   | FLUSH              |      | X   |       |
+   |--------------------+------+-----+-------|
+   | GROUP=expr         | X    | X   | X     |
+   |--------------------+------+-----+-------|
+   | IOERROR=expr       | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]HOSTSYNC       |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [Z]LENGTH=intexpr  |      | X   |       |
+   |--------------------+------+-----+-------|
+   | NEWVERSION         | X    |     |       |
+   |--------------------+------+-----+-------|
+   | OWNER=expr         | X    | X   | X     |
+   |--------------------+------+-----+-------|
+   | [NO]PASTHRU        |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]RCHK           | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]READONLY       | X    |     |       |
+   |--------------------+------+-----+-------|
+   | RECORDSIZE=intexpr | X    |     |       |
+   |--------------------+------+-----+-------|
+   | RENAME=expr        |      |     | X     |
+   |--------------------+------+-----+-------|
+   | [NO]RETRY          | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | REWIND             | X    | X   | X     |
+   |--------------------+------+-----+-------|
+   | SKIPFILE=intexpr   |      | X   |       |
+   |--------------------+------+-----+-------|
+   | SOCKET             |      | X   | X     |
+   |--------------------+------+-----+-------|
+   | SPACE=intexpr      |      | X   | X     |
+   |--------------------+------+-----+-------|
+   | [NO]STREAM         | X    |     |       |
+   |--------------------+------+-----+-------|
+   | SYSTEM=expr        | X    |     | X     |
+   |--------------------+------+-----+-------|
+   | TERMINATOR=expr    |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]TRUNCATE       | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]TTSYNC         |      | X   |       |
+   |--------------------+------+-----+-------|
+   | [NO]TYPEAHEAD      |      | X   |       |
+   |--------------------+------+-----+-------|
+   | UIC=expr           | X    |     | X     |
+   |--------------------+------+-----+-------|
+   | UPSCROLL           |      | X   |       |
+   |--------------------+------+-----+-------|
+   | VARIABLE           | X    |     |       |
+   |--------------------+------+-----+-------|
+   | [Z]WIDTH=intexpr   |      | X   |       |
+   |--------------------+------+-----+-------|
+   | WORLD=expr         | X    |     | X     |
+   |--------------------+------+-----+-------|
+   | [Z][NO]WRAP        | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | WRITELB=expr       |      | X   |       |
+   |--------------------+------+-----+-------|
+   | X=intexpr          |      | X   |       |
+   |--------------------+------+-----+-------|
+   | Y=intexpr          |      | X   |       |
+   |--------------------+------+-----+-------|
+   | ZBFSIZE            | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | Z[NO]DELAY         | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | Z[NO]FF            | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | ZIBFSIZE           | X    | X   |       |
+   |--------------------+------+-----+-------|
+   | ZLISTEN=expr       | X    | X   |       |
+   +-----------------------------------------+
+
+1 Utility_Routines
+   Utility Routines
+
+   GT.M provides library utilities to perform frequently used tasks, and to
+   access frequently used information. Most of the utilities are for GT.M
+   programmers, but some provide tools for system administration and
+   operation.
 
-   %D
+   The GT.M distribution includes the source files for these utilities. The
+   default installation compiles them to produce object modules in the
+   $gtm_dist distribution library.
 
-   Current total of 1 routine.
+   You may wish to examine the utilities and include some of them in your
+   programs if the programs access the function frequently or you may want to
+   modify the utilities to better fit your particular needs. If you modify a
+   utility, store your copy in a directory that precedes gtm_dist in the
+   search list $ZROUTINES to prevent a new release of GT.M from overwriting
+   your copy.
 
-   Routine: %GS*
+2 Using_the_Utilities
+   Using the Utilities
 
-   %GSE %GSEL
+   You can either use a utility in Direct Mode or include it in a source
+   application program with one or more of the following formats.
 
-   Current total of 3 routines.
+     * DO ^%UTILITYNAME
+     * DO LABEL^%UTILITYNAME
+     * $$FUNC^%UTILITYNAME[(para1,...)]
 
-   Routine: - %D
+   Many utilities contain labels that invoke variations of the basic utility
+   functionality. Some also provide the label FUNC to invoke an extrinsic
+   function with optional or required parameters.
 
-   %D
+   Example:
 
-   Current total of 2 routines.
+   GTM>SET %ds="11/22/2010"
+   GTM>DO INT^%DATE
+   GTM>ZWRITE
+   %DN=62047
+   %ds="11/22/2010"
+
+3 GT.M_Utilities_Summary_Table
+   GT.M Utilities Summary Table
+
+   +------------------------------------------------------------------------+
+   | GT.M Utilities Summary                                                 |
+   |------------------------------------------------------------------------|
+   | UTILITY NAME | DESCRIPTION                                             |
+   |--------------+---------------------------------------------------------|
+   | %D           | Displays the current date in [d]d-mmm-[yy]yy format.    |
+   |--------------+---------------------------------------------------------|
+   | %DATE        | Converts input date to $HOROLOG format.                 |
+   |--------------+---------------------------------------------------------|
+   | %DH          | Converts decimal numbers to hexadecimal.                |
+   |--------------+---------------------------------------------------------|
+   | %DO          | Converts decimal numbers to octal.                      |
+   |--------------+---------------------------------------------------------|
+   | %EXP         | Raises number to the power of another number.           |
+   |--------------+---------------------------------------------------------|
+   | %FL          | Lists comment lines at the beginning of the source      |
+   |              | programs.                                               |
+   |--------------+---------------------------------------------------------|
+   | %FREECNT     | Displays the number of free blocks in the database      |
+   |              | files associated with the current global directory.     |
+   |--------------+---------------------------------------------------------|
+   | %G           | Displays global variables and their values.             |
+   |--------------+---------------------------------------------------------|
+   | %GBLDEF      | Manipulates the collation sequence assigned to a        |
+   |              | global.                                                 |
+   |--------------+---------------------------------------------------------|
+   | %GC          | Copies a global or global sub-tree.                     |
+   |--------------+---------------------------------------------------------|
+   | %GCE         | Replaces a specified value or part of a value in a set  |
+   |              | of global variables.                                    |
+   |--------------+---------------------------------------------------------|
+   |              | Displays existing globals in the current global         |
+   | %GD          | directory without displaying their values or            |
+   |              | descendants.                                            |
+   |--------------+---------------------------------------------------------|
+   | %GED         | Provides full-screen editing capabilities for global    |
+   |              | variables and values.                                   |
+   |--------------+---------------------------------------------------------|
+   | %GI          | Enters global variables and their values from a         |
+   |              | sequential file into a database.                        |
+   |--------------+---------------------------------------------------------|
+   | %GO          | Copies globals from the current database to a           |
+   |              | sequential output file.                                 |
+   |--------------+---------------------------------------------------------|
+   | %GSE         | Displays global variables and their values when the     |
+   |              | values contain a specified string or number.            |
+   |--------------+---------------------------------------------------------|
+   | %GSEL        | Selects globals by name.                                |
+   |--------------+---------------------------------------------------------|
+   | %H           | Converts date and time to and from $HOROLOG format.     |
+   |--------------+---------------------------------------------------------|
+   | %HD          | Converts hexadecimal numbers to decimal.                |
+   |--------------+---------------------------------------------------------|
+   | %HEX2UTF     | Converts the given bytestream in hexadecimal notation   |
+   |              | to GT.M encoded character string.                       |
+   |--------------+---------------------------------------------------------|
+   | %HO          | Converts hexadecimal numbers to octal.                  |
+   |--------------+---------------------------------------------------------|
+   | %LCASE       | Converts a string to all lower case.                    |
+   |--------------+---------------------------------------------------------|
+   | %LCLCOL      | Manipulates the collation sequence assigned to local    |
+   |              | variables.                                              |
+   |--------------+---------------------------------------------------------|
+   | %OD          | Converts octal numbers to decimal.                      |
+   |--------------+---------------------------------------------------------|
+   | %OH          | Converts octal numbers to hexadecimal.                  |
+   |--------------+---------------------------------------------------------|
+   | %PATCODE     | Loads pattern definition files for use within an active |
+   |              | database.                                               |
+   |--------------+---------------------------------------------------------|
+   | %RCE         | Replaces every occurrence of a text string with another |
+   |              | string in a routine or list of routines.                |
+   |--------------+---------------------------------------------------------|
+   | %RD          | Lists routine names available through your $ZROUTINES   |
+   |              | search list.                                            |
+   |--------------+---------------------------------------------------------|
+   | %RI          | Transfers routines from ANSI sequential format into     |
+   |              | individual .m files in GT.M format.                     |
+   |--------------+---------------------------------------------------------|
+   | %RO          | Writes M routines in ANSI transfer format.              |
+   |--------------+---------------------------------------------------------|
+   | %RSE         | Searches for every occurrence of a text string in a     |
+   |              | routine or a list of routines.                          |
+   |--------------+---------------------------------------------------------|
+   | %RSEL        | Selects M routines and places their directories and     |
+   |              | names in a local array.                                 |
+   |--------------+---------------------------------------------------------|
+   | %SQROOT      | Calculates the square root of a number.                 |
+   |--------------+---------------------------------------------------------|
+   | %T           | Displays the current time in [h]h:mm AM/PM format.      |
+   |--------------+---------------------------------------------------------|
+   | %TI          | Converts time to $HOROLOG format.                       |
+   |--------------+---------------------------------------------------------|
+   | %TO          | Converts the current time from $HOROLOG format to       |
+   |              | [h]h:mm AM/PM format.                                   |
+   |--------------+---------------------------------------------------------|
+   | %UCASE       | Converts a string to all upper case.                    |
+   |--------------+---------------------------------------------------------|
+   | %UTF2HEX     | Converts UTF-8 encoded GT.M character string to         |
+   |              | bytestream in hexadecimal notation.                     |
+   +------------------------------------------------------------------------+
+
+1 Integrate_External
+   Integrate External
+
+2 Introduction
+   Introduction
+
+   Application code written in M can call application code written in C (or
+   which uses a C compatible call) and vice versa.
+
+   **Note**
+
+   This C code shares the process address space with the GT.M run-time
+   library and M application code. Bugs in C code may result in difficult to
+   diagnose failures to occur in places not obviously related to the cause of
+   the failure.
+
+2 Access_Non-M_Routines
+   Access Non-M Routines
+
+   In GT.M, calls to C language routines may be made with the following
+   syntax:
 
-   Routine: ?D
+   DO &[packagename.]name[^name][parameter-list]
 
-   %GSE %GSEL
+   or as an expression element,
 
-   Routine: <RETURN>
+   $&[packagename.]name[^name][parameter-list]
 
-   Output Device: <RETURN>
+   Where packagename, like the name elements is a valid M name. Because of
+   the parsing conventions of M, the identifier between the ampersand (&) and
+   the optional parameter-list has precisely constrained punctuation - a
+   later section describes how to transform this into a more richly
+   punctuated name should that be appropriate for the called function. While
+   the intent of the syntax is to permit the name^name to match an M
+   labelref, there is no semantic implication to any use of the up-arrow (^).
 
-   Routine First Line Lister Utility
+   Example:
 
-   GT.M 21-MAR-2002 16:44:09
+   ;Call external routine rtn1
+   DO &rtn1
+   ;Call int^exp in package "mathpak" with one parameter: the expression val/2
+   DO &mathpak.int^exp(val/2)
+   ;Call the routine sqrt with the value "2"
+   WRITE $&sqrt(2)
+   ;Call the routine get parms, with the parameter "INPUT" and the variable "inval", passed by reference.
+   DO &getparms("INPUT",.inval)
 
-   %GSE
+   The called routines follow the C calling conventions. They must be
+   compiled as position independent code and linked as a shareable library.
 
-   %GSE ;GT.M %GSE utility - global search
+2 Create_Shareable_Library
+   Create Shareable Library
 
-   ;
+   The method of creating a shareable library varies by the operating system.
+   The following examples illustrate the commands to be used on an HP-UX
+   system, a Hewlett-Packard UNIX system, and an IBM pSeries (formerly
+   RS/6000) AIX system.
 
-   %GSEL ;
+   Example:
 
-   %GSEL ;GT.M %GSEL utility - global select into a local array
+   $ cat increment.c
+   int increment(int count, float *invar, float *outvar)
+   {
+       *outvar=*invar+1.0;
+       return 0;
+   }
+   $ cat decrement.c
+   int decrement(int count, float *invar, float *outvar)
+   {
+        *outvar=*invar-1.0;
+        return 0;
+   }
 
-   ;
+   On HP-UX:
 
-   ;invoke ^%GSEL to create %ZG -  a  local  array  of  existing  globals,
-   interactively
-   ;
+   Example:
 
-   Total 5 lines in of 2 routines.
+   $ cc -Aa -c +z -I$gtm_dist increment.c
+   decrement.c
+   $ ld -b -o libcrement.sl increment.o
+   decrement.o -lc
 
-   GTM>
+   **Note**
 
-   This example selects %D, then selects %GSE and %GSEL and deselects %D.
-   Because the example enters <RETURN> at the Output  Device:  <terminal>:
-   prompt, the output goes to the principal device.
+   Refer to the "Programming on HP-UX" manual for information on shareable
+   libraries under HP-UX.
 
-3 RCE
-   %RCE
+   On Hewlett-Packard Tru64 UNIX:
 
+   Example:
 
-   The %RCE utility replaces  every  occurrence  of  a  text  string  with
-   another text string in a routine or a list of routines.
+   $ cc -c -xtaso -xtaso_short -I$gtm_dist increment.c decrement.c
+   $ ld -shared -taso -o libcrement.sl increment.o derement.o -lc
 
-   %RCE uses %RSEL to select routines. For more information, refer to the
-   section on %RSEL in this chapter.
+   **Note**
 
-   %RCE prompts for a text string to replace  and  its  replacement.  %RCE
-   searches for text strings in a case-sensitive  manner.  %RCE  issues  a
-   warning message if you specify a control character such as a  <TAB>  in
-   the text string or its replacement. %RCE  confirms  your  selection  by
-   displaying the text string and its replacement between a left and right
-   arrow. The arrows highlight  any  blank  spaces  that  you  might  have
-   included in the text string or its replacement.
+   Refer to the "Tru64 Programmer's Guide" for information on shareable
+   libraries under HP UNIX.
 
-   Regardless of whether you  select  a  display  of  every  change,  %RCE
-   displays the name of each routine as  it  is  processed  and  completes
-   processing with a count of replacements and routines changed.
+   On IBM pSeries AIX:
 
-4 Prompts
-   Prompts
+   Example:
 
-        Routine: Requests (using %RSEL) the  name(s)  of  the  routines  to
-        change; <RETURN> ends the selection.
-        Old string: Requests string to be replaced.
-        New string: Requests replacement string.
-        Show changed lines <Yes>?:
-        Asks whether to display  the  before  and  after  versions  of  the
-        modified lines on an output device.
-        Output Device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-4 Util_Labels
-   Utility Labels
+   $ cc -c -I$gtm_dist increment.c decrement.c
+   $ ld -o libcrement.so increment.o decrement.o -G -bexpall -bnoentry -bh:4 -lc
 
-        CALL Works without user interaction unless %ZR is not defined.
-4 Input_Vars
-   Input Variable
+   **Note**
 
-   The  following  input  variables  are  only  applicable  when  invoking
-   CALL^%RCE.
+   Refer to the AIX V4.2 documentation of the ld(1) AIX command for
+   information on shareable libraries under AIX V4.2.
 
-        %ZR Contains an array of routines provided or generated with %RSEL.
-        %ZF Contains string to find.
-        %ZN Contains a replacement string.
-        %ZD Identifies the device to display the change trail, defaults to
-        principal device. Make sure you open the device if  the  device  is
-        not the principal device.
-        %ZC Truth-value indicating whether to  display  the  change  trail,
-        defaults to 0 (no).
-4 Ex_of_RCE
-   Examples of %RCE
+   On Sun Solaris (Solaris 2.6 & higher):
 
    Example:
 
+   %/opt/SUNWspro/bin/cc -c -KPIC -I$gtm_dist increment.c decrement.c
+   % ld -o libincrement.so -G increment.o decrement -lc
 
-   GTM>DO ^%RCE
-
-   Routine Change Every occurrence
-
-   Routine: BES*
+   **Note**
 
-   BEST BEST2 BEST3 BEST4
+   The environment variable GTMXC_RPC has to be set (export GTMXC_RPC=1) to
+   use the RPC mechanisms, which is not described in this manual.
 
-   Current total of 4 routines
+   On Linux x86:
 
-   Routine: <RETURN>
-
-   Old string:^NAME
-
-   New string:^STUDENT
+   Example:
 
-   Replace all occurrences of:
+   % gcc -c -fPIC -I$gtm_dist increment.c decrement.c
+   % gcc -o libincrement.so -shared increment.o decrement.o
 
->^NAME<
-   With
+2 External_Calls
+   External Calls
 
->^STUDENT<
-   Show changed lines <Yes>?: <RETURN>
+   The functions in programs increment and decrement are now available to
+   GT.M through the shareable library libcrement.sl or libcrement.so, or
+   though the DLL as libcrement.dll, depending on the specific platform. The
+   suffix .sl is used throughout the following examples to represent .sl,
+   .so, or .dll. Be sure to use the appropriate suffix for your platform.
 
-   Output Device: <RETURN>
+   GT.M uses an "external call table" to map the typeless data of M into the
+   typed data of C, and vice versa. The external call table has a first line
+   containing the pathname of the shareable library file followed by one or
+   more specification lines in the following format:
 
-   /usr/smith/work/BEST.m
+   entryref: return-value routine-name (parameter, parameter, ... )
 
-   Was: S ^NAME=SMITH
+   where entryref is an M entryref,
 
-   Now: S ^STUDENT=SMITH
+   return-value is gtm_long_t, gtm_status_t, or void.
 
-   Was: S ^NAME(1)=JOHN
+   and
 
-   Now: S ^STUDENT(1)=JOHN
+   parameters are in the format: direction:type [num]
 
-   /usr/smith/work/BEST2.m
+   where [num] indicates a pre-allocation value explained later in this
+   chapter.
 
-   /usr/smith/work/BEST3.m
+   Legal directions are I, O, or IO for input, output, or input/output,
+   respectively.
 
-   Was: S ^NAME=X
+   The following table describes the legal types defined in the C header file
+   $gtm_dist/gtmxc_types.h:
 
-   Now: S ^STUDENT=X
+   Type : Usage
 
-   Was: W ^NAME
+   Void: Specifies that the function does not return a value.
 
-   Now: W ^STUDENT
+   gtm_status_t : Type int. If the function returns zero (0), then the call
+   was successful. If it returns a non-zero value, GT.M will signal an error
+   upon returning to M.
 
-   /usr/smith/work/BEST4.m
+   gtm_long_t : 32-bit signed integer on 32-bit platforms and 64-bit signed
+   integer on 64-bit platforms (except on Tru64 UNIX where GT.M remains a
+   32-bit application).
 
-   Total of 4 routines parsed.
+   gtm_ulong_t : 32-bit unsigned integer on 32-bit platforms and 64-bit
+   signed integer on 64-bit platforms.
 
-   4 occurrences changed in 2 routines.
-   GTM>
+   gtm_long_t* : For passing a pointer to long [integers].
 
-   This example selects a list of routines that change the string "^NAME"
-   to the string "^STUDENT," and displays a trail of the changes.
+   gtm_float_t* : For passing a pointer to floating point numbers.
 
-   Example:
+   gtm_double_t* : Same as above, but double precision.
 
+   gtm_char_t*: For passing a "C" style string - null terminated.
 
-   GTM>DO ^%RCE
+   gtm_char_t** : For passing a pointer to a "C" style string.
 
-   Routine Change Every occurrence
+   gtm_string_t* : For passing a structure in the form {int length;char
+   *address}. Useful for moving blocks of memory to or from GT.M.
 
-   Routine: BES*
+   gtm_pointertofunc_t : For passing callback function pointers.
 
-   BEST BEST2 BEST3 BEST4
+   gtmxc_types.h also includes definitions for the following entry points
+   exported from libgtmshr:
 
-   Current total of 4 routines
+   void gtm_hiber_start(gtm_uint_t mssleep);
+   void gtm_hiber_start_wait_any(gtm_uint_t mssleep)
+   void gtm_start_timer(gtm_tid_t tid, gtm_int_t time_to_expir, void (*handler)(), gtm_int_t hdata_len, void \*hdata);
+   void gtm_cancel_timer(gtm_tid_t tid);
 
-   Routine: <RETURN>
+   where:
 
-   Old String:<TAB>
+     * mssleep - milliseconds to sleep
+     * tid - unique timer id value
+     * time_to_expir - milliseconds until timer drives given handler
+     * handler - function pointer to handler to be driven
+     * hdata_len - 0 or length of data to pass to handler as a parameter
+     * hdata - NULL or address of data to pass to handler as a parameter
 
-   The find string contains control characters
+   gtm_hiber_start() always sleeps until the time expires;
+   gtm_hiber_start_wait_any() sleeps until the time expires or an interrupt
+   by any signal (including another timer). gtm_start_timer() starts a timer
+   but returns immediately (no sleeping) and drives the given handler when
+   time expires unless the timer is canceled.
 
-   New string: <RETURN>
+   **Important**
 
-   Replace all occurrences of:
+   GT.M continues to support xc_* equivalent types of gtm_* for upward
+   compatibility. gtmxc_types.h explicitly marks the xc_* equivalent types as
+   deprecated.
 
-><TAB><
-   With:
+   The first parameter of each called routine is an int (for example, int
+   argc in decrement.c and increment.c) that specifies the number of
+   parameters passed. This parameter is implicit and only appears in the
+   called routine. It does not appear in the call table specification, or in
+   the M invocation. If there are no explicit parameters, the call table
+   specification will have a zero (0) value because this value does not
+   include itself in the count. If there are fewer actual parameters than
+   formal parameters, the call is determined from the parameters specified by
+   the values supplied by the M program. The remaining parameters are
+   undefined. If there are more actual parameters than formal parameters,
+   GT.M reports an error.
 
-><
-   Show changed lines <Yes>?: N
+   There may be only a single occurrence of the type gtm_status_t for each
+   entryref.
 
-   BEST BEST2 BEST3 BEST4
+3 Encryption_Extensions
+   Encryption Extensions
+
+   To support Database Encryption, GT.M provides a reference implementation
+   which resides in $gtm_dist/plugin/gtmcrypt.
+
+   The reference implementation includes:
+
+     * A $gtm_dist/plugin/gtmcrypt sub-directory with all source files and
+       scripts. The scripts include those needed to build/install
+       libgtmcrypt.so and "helper" scripts, for example, add_db_key.sh (see
+       below).
+     * The plugin interface that GT.M expects is defined in
+       gtmcrypt_interface.h. Never modify this file - it defines the
+       interface that the plugin must provide.
+     * $gtm_dist/plugin/libgtmcrypt.so is the shared library containing the
+       executables which is dynamically linked by GT.M and which in turn
+       calls the encryption packages. If the $gtm_dist/utf8 directory exists,
+       then it should contain a symbolic link to ../plugin.
+     * Source code is provided in the file
+       $gtm_dist/plugin/gtmcrypt/source.tar which includes build.sh and
+       install.sh scripts to respectively compile and install libgtmcrypt.so
+       from the source code.
+
+   To support the implementation of a reference implementation, GT.M provides
+   additional C structure types (in the gtmxc_types.h file):
+
+     * gtmcrypt_key_t - a datatype that is a handle to a key. The GT.M
+       database engine itself does not manipulate keys. The plug-in keeps the
+       keys, and provides handles to keys that the GT.M database engine uses
+       to refer to keys.
+     * xc_fileid_ptr_t - a pointer to a structure maintained by GT.M to
+       uniquely identify a file. Note that a file may have multiple names -
+       not only as a consequence of absolute and relative path names, but
+       also because of symbolic links and also because a file system can be
+       mounted at more than one place in the file name hierarchy. GT.M needs
+       to be able to uniquely identify files.
+
+   Although not required to be used by a customized plugin implementation,
+   GT.M provides (and the reference implementation uses) the following
+   functions for uniquely identifying files:
+
+     * xc_status_t gtm_filename_to_id(xc_string_t *filename, xc_fileid_ptr_t
+       *fileid) - function that takes a file name and provides the file id
+       structure for that file.
+     * xc_status_t gtm_is_file_identical(xc_fileid_ptr_t fileid1,
+       xc_fileid_ptr_t fileid2) - function that determines whether two file
+       ids map to the same file.
+     * gtm_xcfileid_free(xc_fileid_ptr_t fileid) - function to release a file
+       id structure.
+
+   Mumps, MUPIP and DSE processes dynamically link to the plugin interface
+   functions that reside in the shared library. The functions serve as
+   software "shims" to interface with an encryption library such as libmcrypt
+   or libgpgme / libgcrypt.
+
+   The plugin interface functions are:
+
+     * gtmcrypt_init()
+     * gtmcrypt_getkey_by_name()
+     * gtmcrypt_getkey_by_hash()
+     * gtmcrypt_hash_gen()
+     * gtmcrypt_encode()
+     * gtmcrypt_decode()
+     * gtmcrypt_close()
+     * and gtmcrypt_strerror()
+
+   A GT.M database consists of multiple database files, each of which has its
+   own encryption key, although you can use the same key for multiple files.
+   Thus, the gtmcrypt* functions are capable of managing multiple keys for
+   multiple database files. Prototypes for these functions are in
+   gtmcrypt_interface.h.
+
+   The core plugin interface functions, all of which return a value of type
+   gtm_status_t are:
+
+     * gtmcrypt_init() performs initialization. If the environment variable
+       $gtm_passwd exists and has an empty string value, GT.M calls
+       gtmcrypt_init() before the first M program is loaded; otherwise it
+       calls gtmcrypt_init() when it attempts the first operation on an
+       encrypted database file.
+     * Generally, gtmcrypt_getkey_by_hash or, for MUPIP CREATE,
+       gtmcrypt_getkey_by_name perform key acquisition, and place the keys
+       where gtmcrypt_decode() and gtmcrypt_encode() can find them when they
+       are called.
+     * Whenever GT.M needs to decode a block of bytes, it calls
+       gtmcrypt_decode() to decode the encrypted data. At the level at which
+       GT.M database encryption operates, it does not matter what the data is
+       - numeric data, string data whether in M or UTF-8 mode and whether or
+       not modified by a collation algorithm. Encryption and decryption
+       simply operate on a series of bytes.
+     * Whenever GT.M needs to encode a block of bytes, it calls
+       gtmcrypt_encode() to encode the data.
+     * If encryption has been used (if gtmcrypt_init() was previously called
+       and returned success), GT.M calls gtmcrypt_close() at process exit and
+       before generating a core file. gtmcrypt_close() must erase keys in
+       memory to ensure that no cleartext keys are visible in the core file.
+
+   More detailed descriptions follow.
+
+     * gtmcrypt_key_t *gtmcrypt_getkey_by_name(gtm_string_t *filename) -
+       MUPIP CREATE uses this function to get the key for a database file.
+       This function searches for the given filename in the memory key ring
+       and returns a handle to its symmetric cipher key. If there is more
+       than one entry for the given filename , the reference implementation
+       returns the entry matching the last occurrence of that filename in the
+       master key file.
+     * gtm_status_t gtmcrypt_hash_gen(gtmcrypt_key_t *key, gtm_string_t
+       *hash) - MUPIP CREATE uses this function to generate a hash from the
+       key then copies that hash into the database file header. The first
+       parameter is a handle to the key and the second parameter points to
+       256 byte buffer. In the event the hash algorithm used provides hashes
+       smaller than 256 bytes, gtmcrypt_hash_gen() must fill any unused space
+       in the 256 byte buffer with zeros.
+     * gtmcrypt_key_t *gtmcrypt_getkey_by_hash(gtm_string_t *hash) - GT.M
+       uses this function at database file open time to obtain the correct
+       key using its hash from the database file header. This function
+       searches for the given hash in the memory key ring and returns a
+       handle to the matching symmetric cipher key. MUPIP LOAD, MUPIP
+       RESTORE, MUPIP EXTRACT, MUPIP JOURNAL and MUPIP BACKUP -BYTESTREAM all
+       use this to find keys corresponding to the current or prior databases
+       from which the files they use for input were derived.
+     * gtm_status_t gtmcrypt_encode(gtmcrypt_key_t *key, gtm_string_t *inbuf,
+       gtm_string_t *outbuf) and gtm_status_t gtmcrypt_decode(gtmcrypt_key_t
+       *key, gtm_string_t *inbuf, gtm_string_t *outbuf)- GT.M uses these
+       functions to encode and decode data. The first parameter is a handle
+       to the symmetric cipher key, the second a pointer to the block of data
+       to encode or decode, and the third a pointer to the resulting block of
+       encoded or decoded data. Using the appropriate key (same key for a
+       symmetric cipher), gtmcrypt_decode() must be able to decode any data
+       buffer encoded by gtmcrypt_encode(), otherwise the encrypted data is
+       rendered unrecoverable.7 As discussed earlier, GT.M requires the
+       encrypted and cleartext versions of a string to have the same length.
+     * char *gtmcrypt_strerror() - GT.M uses this function to retrieve
+       addtional error context from the plug-in after the plug-in returns an
+       error status. This function returns a pointer to additional text
+       related to the last error that occurred. GT.M displays this text as
+       part of an error report. In a case where an error has no additional
+       context or description, this function returns a null string.
+
+   The complete source code for reference implementations of these functions
+   is provided, licensed under the same terms as GT.M. You are at liberty to
+   modify them to suit your specific GT.M database encryption needs. Check
+   your GT.M license if you wish to consider redistributing your changes to
+   others.
+
+   For more information and examples, refer to the Database Encryption
+   Technical Bulletin.
+
+3 Pre-allocation
+   Pre-allocation
+
+   The definition of parameters passed by reference with direction output can
+   include specification of a pre-allocation value. This is the number of
+   units of memory that the user wants GT.M to allocate before passing the
+   parameter to the external routine. For example, in the case of type
+   gtm_char_t *, the pre-allocation value would be the number of bytes to be
+   allocated before the call to the external routine.
+
+   Specification of a pre-allocation value should follow these rules:
+
+     * Pre-allocation is an unsigned integer value specifying the number of
+       bytes allocated on the system heap to the pointer passed into the
+       external call.
+     * Pre-allocating on a type with a direction input or input/output
+       results in a GT.M error.
+     * Pre-allocation is meaningful only on types char * and gtm_string_t *.
+       On all other types the pre-allocation value specified will be ignored
+       and the parameter will be allocated a default value for that type.
+     * If the user does not specify any value, then the default
+       pre-allocation value would be assigned to the parameter.
+     * Specification of pre-allocation for "scalar" types (parameters which
+       are passed by value) is an error.
+
+   **Important**
+
+   Pre-allocation is optional for all output-only parameters except
+   gtm_string_t * and char *. Pre-allocation yields better management of
+   memory for the external call.
+
+3 Callback_Mechanism
+   Callback Mechanism
+
+   GT.M exposes certain functions that are internal to the GT.M runtime
+   library for the external calls via a callback mechanism. While making an
+   external call, GT.M populates and exposes a table of function pointers
+   containing addresses to call-back functions.
+
+ +-----------------------------------------------------------------------------+
+ |Index|      Function      |   Argument   |   Type   |      Description       |
+ |-----+--------------------+--------------+----------+------------------------|
+ |0    |hiber_start         |              |          |sleep for a specified   |
+ |     |                    |              |          |time                    |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |slp_time      |integer   |milliseconds to sleep   |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |sleep for a specified   |
+ |1    |hiber_start_wait_any|              |          |time or until any       |
+ |     |                    |              |          |interrupt, whichever    |
+ |     |                    |              |          |comes first             |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |slp_time      |integer   |milliseconds to sleep   |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |start a timer and invoke|
+ |2    |start_timer         |              |          |a handler function when |
+ |     |                    |              |          |the timer expires       |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |unique user specified   |
+ |     |                    |tid           |integer   |identifier for this     |
+ |     |                    |              |          |timer                   |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |time_to_expire|integer   |milliseconds before     |
+ |     |                    |              |          |handler is invoked      |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |pointer to|specifies the entry of  |
+ |     |                    |handler       |function  |the handler function to |
+ |     |                    |              |          |invoke                  |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |length of data to be    |
+ |     |                    |hlen          |integer   |passed via the hdata    |
+ |     |                    |              |          |argument                |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |hdata         |pointer to|data (if any) to pass to|
+ |     |                    |              |char      |the handler function    |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |stop a timer previously |
+ |3    |cancel_timer        |              |          |started with            |
+ |     |                    |              |          |start_timer(), if it has|
+ |     |                    |              |          |not yet expired         |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |unique user specified   |
+ |     |                    |tid           |integer   |identifier of the timer |
+ |     |                    |              |          |to cancel               |
+ |-----+--------------------+--------------+----------+------------------------|
+ |4    |gtm_malloc          |              |          |allocates process memory|
+ |     |                    |              |          |from the heap           |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |<return-value>|pointer to|address of the allocated|
+ |     |                    |              |void      |space                   |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |32-bit    |                        |
+ |     |                    |              |platforms:|                        |
+ |     |                    |              |32-bit    |                        |
+ |     |                    |              |unsigned  |bytes of space to       |
+ |     |                    |              |integer   |allocate. This has the  |
+ |     |                    |space_needed  |          |same signature as the   |
+ |     |                    |              |64-bit    |system malloc() call.   |
+ |     |                    |              |platforms:|                        |
+ |     |                    |              |64-bit    |                        |
+ |     |                    |              |unsigned  |                        |
+ |     |                    |              |integer   |                        |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |          |return memory previously|
+ |5    |gtm_free            |              |          |allocated with          |
+ |     |                    |              |          |gtm_malloc()            |
+ |-----+--------------------+--------------+----------+------------------------|
+ |     |                    |              |pointer to|address of the          |
+ |     |                    |free_address  |void      |previously allocated    |
+ |     |                    |              |          |space                   |
+ +-----------------------------------------------------------------------------+
+
+   The external routine can access and invoke a call-back function in any of
+   the following mechanisms:
+
+     * While making an external call, GT.M sets the environment variable
+       GTM_CALLIN_START to point to a string containing the start address
+       (decimal integer value) of the table described above. The external
+       routine needs to read this environment variable, convert the string
+       into an integer value and should index into the appropriate entry to
+       call the appropriate GT.M function.
+     * GT.M also provides an input-only parameter type gtm_pointertofunc_t
+       that can be used to obtain call-back function pointers via parameters
+       in the external routine. If a parameter is specified as
+       I:gtm_pointertofunc_t and if a numeric value (between 0-5) is passed
+       for this parameter in M, GT.M interprets this value as the index into
+       the callback table and passes the appropriate callback function
+       pointer to the external routine.
+
+   **Note**
+
+   FIS strongly discourages the use of signals, especially SIGALARM, in user
+   written C functions. GT.M assumes that it has complete control over any
+   signals that occur and depends on that behavior for recovery if anything
+   should go wrong. The use of exposed timer APIs should be considered for
+   timer needs.
+
+3 Limitations
+   Limitations
+
+   Since both GT.M runtime environment and the external C functions execute
+   in the same process space, the following restrictions apply to the
+   external functions:
+
+    1. GT.M is designed to use signals and has signal handlers that must
+       function for GT.M to operate properly. The timer related call-backs
+       should be used in place of any library or system call which uses
+       SIGALRM such as sleep(). Use of signals by external call code may
+       cause GT.M to fail.
+    2. Use of the GT.M provided malloc and free, creates an integrated heap
+       management system, which has a number of debugging tools. FIS
+       recommends the usage of gtm_malloc/gtm_free in the external functions
+       that provides better debugging capability in case memory management
+       problems occur with external calls.
+    3. Use of exit system call in external functions is strongly discouraged.
+       Since GT.M uses exit handlers to properly shutdown runtime environment
+       and any active resources, the system call _exit should never be used
+       in external functions.
+    4. GT.M uses timer signals so often that the likelihood of a system call
+       being interrupted is high. So, all system calls in the external
+       program can return EINTR if interrupted by a signal.
+    5. Handler functions invoked with start_timer must not invoke services
+       that are identified by the Operating System documentation as unsafe
+       for signal handlers (or not identified as safe) - consult the system
+       documentation or man pages for this information. Such services cause
+       non-deterministic failures when they are interrupted by a function
+       that then attempts to call them, wrongly assuming they are reentrant.
+
+3 Examples
+   Examples
+
+   foo: void bar (I:gtm_float_t*, O:gtm_float_t*)
+
+   There is one external call table for each package. The environment
+   variable "GTMXC" must name the external call table file for the default
+   package. External call table files for packages other than the default
+   must be identified by environment variables of the form "GTMXC_name".
+
+   The first of the external call tables is the location of the shareable
+   library. The location can include environment variable names.
 
-   Total 4 routines parsed.
+   Example:
 
-   4 occurrences changed in 2 routines.
+   % echo $GTMXC_mathpak
+   /user/joe/mathpak.xc
+   % echo lib /usr/
+   % cat mathpak.xc
+   $lib/mathpak.sl
+   exp: gtm_status_t xexp(I:gtm_float_t*, O:gtm_float_t*)
+   % cat exp.c
+   ...
+   int xexp(count, invar, outvar)
+   int count;
+   float *invar;
+   float *outvar;
+          {
+           ...
+          }
+   % gtm
+   ...
+   GTM>d &mathpak.exp(inval,.outval)
    GTM>
 
-   This example removes all occurrences of the <TAB>  key  from  specified
-   routines and suppresses the display trail of changes.
-
-3 RD
-   %RD
+   Example : For preallocation:
 
+   % echo $GTMXC
+   /usr/joe/extcall.xc
+   % cat extcall.xc
+   /usr/lib/extcall.sl
+   prealloc: void gtm_pre_alloc(O:gtm_char_t *[12])
+   % cat extcall.c
+   #include <stdio.h>
+   #include "gtmxc_types.h"
 
-   The %RD utility lists routine  names  accessible  through  the  current
-   $ZROUTINES. %RD  calls  %RSEL  and  displays  any  routines  accessible
-   through %RSEL. Use %RD to locate routines.
-
-   %RD accepts the wildcard characters asterisk (*) and question mark (?).
-   The wildcards carry their usual meanings, an  asterisk  (*)  denotes  a
-   field or a portion of a field, and a question mark (?) denotes a single
-   character in positions other than the first.
+   void gtm_pre_alloc_a (int count, char *arg_prealloca)
+   {
+       strcpy(arg_prealloca, "New Message");
+       return;
+   }
 
-   A colon (:) between two routine names specifies a  range  of  routines.
-   %RD displays only those routine names accessible  through  the  current
-   $ZROUTINES.
+   Example : for call-back mechanism
 
-   After each selection %RD displays the total number of routines listed.
+   % echo $GTMXC
+   /usr/joe/callback.xc
+   % cat /usr/joe/callback.xc
+   $MYLIB/callback.sl
+   init:     void   init_callbacks()
+   tstslp:  void   tst_sleep(I:gtm_long_t)
+   strtmr: void   start_timer(I:gtm_long_t, I:gtm_long_t)
+   % cat /usr/joe/callback.c
+   #include <stdio.h>
+   #include <stdlib.h>
 
-   Pressing <RETURN> exits %RD.
+   #include "gtmxc_types.h"
 
-4 Prompts
-   Prompts
+   void **functable;
+   void (*setup_timer)(int , int , void (*)() , int , char *);
+   void (*cancel_timer)(int );
+   void (*sleep_interrupted)(int );
+   void (*sleep_uninterrupted)(int );
+   void* (*malloc_fn)(int);
+   void (*free_fn)(void*);
+
+   void  init_callbacks (int count)
+   {
+      char *start_address;
+
+      start_address = (char *)getenv("GTM_CALLIN_START");
+
+      if (start_address == (char *)0)
+      {
+              fprintf(stderr,"GTM_CALLIN_START is not set\n");
+         return;
+      }
+      functable = (void **)atoi(start_address);
+      if (functable == (void **)0)
+      {
+        perror("atoi : ");
+        fprintf(stderr,"addresses defined by GTM_CALLIN_START not a number\n");
+        return;
+      }
+      sleep_uninterrupted = (void (*)(int )) functable[0];
+      sleep_interrupted = (void (*)(int )) functable[1];
+      setup_timer = (void (*)(int , int, void (*)(), int, char *)) functable[2];
+      cancel_timer = (void (*)(int )) functable[3];
+
+      malloc_fn = (void* (*)(int)) functable[4];
+      free_fn = (void (*)(void*)) functable[5];
+
+      return;
+   }
 
-        Routine: Requests (using %RSEL) the  name(s)  of  the  routines  to
-        list; <RETURN> ends the selection.
-4 Util_Labels
-   Utility Labels
+   void  sleep (int count, int time)
+   {
+      (*sleep_uninterrupted)(time);
+   }
 
-        OBJ Lists object modules accessible through the current $ZROUTINES.
-        LIB Lists percent  (%)  routines  accessible  through  the  current
-        $ZROUTINES.
-        SRC  Lists  the  source  modules  accessible  through  the  current
-        $ZROUTINES (same as %RD).
-4 Ex_of_RD
-   Examples of %RD
+   void timer_handler ()
+   {
+      fprintf(stderr,"Timer Handler called\n");
+      /* Do something */
+   }
 
-   Example:
+   void  start_timer (int count, int time_to_int, int time_to_sleep)
+   {
+      (*setup_timer)((int )start_timer, time_to_int, timer_handler, 0, 0);
+      return;
+   }
+   void* xmalloc (int count)
+   {
+   return (*malloc_fn)(count);
+   }
 
+   void  xfree(void* ptr)
+   {
+      (*free_fn)(ptr);
+   }
 
-   GTM>DO ^%RD
+   Example:gtm_malloc/gtm_free callbacks using gtm_pointertofunc_t
 
-   Routine directory
+   % echo $GTMXC
+   /usr/joe/callback.xc
+   % cat /usr/joe/callback.xc
+   /usr/lib/callback.sl
+   init: void init_callbacks(I:gtm_pointertofunc_t, I:gtm_pointertofunc_t)
 
-   Routine: TAXES
+   % gtm
+   GTM> do &.init(4,5)
+   GTM>
 
-   TAXES
+   % cat /usr/joe/callback.c
+   #include <stdio.h>
+   #include <stdlib.h>
 
-   Total of 1 routine
+   #include "gtmxc_types.h"
 
-   Routine:*
+   void* (*malloc_fn)(int);
 
-   EMP FICA PAYROLL TAXES YTD
+   void (*free_fn)(void*);
 
-   Total of 5 Routines
+   void init_callbacks(int count, void* (*m)(int), void (*f)(void*))
+   {
+       malloc_fn = m;
+       free_fn = f;
+   }
 
-   Routine: <RETURN>
+2 Call-Ins
+   Call-Ins
+
+   Call-In is a framework supported by GT.M that allows a C/C++ program to
+   invoke an M routine within the same process context. GT.M provides a
+   well-defined Call-In interface packaged as a run-time shared library that
+   can be linked into an external C/C++ program.
+
+3 Relevant_files
+   Relevant files
+
+   To facilitate Call-Ins to M routines, the GT.M distribution directory
+   ($gtm_dist) contains the following files:
+
+    1. libgtmshr.so - A shared library that implements the GT.M run-time
+       system, including the Call-In API. If Call-Ins are used from a
+       standalone C/C++ program, this library needs to be explicitly linked
+       into the program.
+
+   **Note**
+
+       .so is the recognized shared library file extension on most UNIX
+       platforms, except on HP-UX, wherein it is .sl.
+
+    2. mumps - The GT.M startup program that dynamically links with
+       libgtmshr.so.
+    3. gtmxc_types.h - A C-header file containing the declarations of Call-In
+       API.
+
+   The following sections describe the files relevant to using Call-Ins.
+
+5 gtmxc_types.h
+   gtmxc_types.h
+
+   The header file provides signatures of all Call-In interface functions and
+   definitions of those valid data types that can be passed from C to M. FIS
+   strongly recommends that these types be used instead of native types (int,
+   char, float, and so on), to avoid possible mismatch problems during
+   parameter passing.
+
+   gtmxc_types.h defines the following types that can be used in Call-Ins.
+
+   +------------------------------------------------------------------------+
+   |     Type     |                          Usage                          |
+   |--------------+---------------------------------------------------------|
+   | void         | Used to express that there is no function return value  |
+   |--------------+---------------------------------------------------------|
+   | gtm_int_t    | gtm_int_t has 32-bit length on all platforms.           |
+   |--------------+---------------------------------------------------------|
+   | gtm_uint_t   | gtm_uint_t has 32-bit length on all platforms           |
+   |--------------+---------------------------------------------------------|
+   |              | gtm_long_t has 32-bit length on 32-bit platforms and    |
+   | gtm_long_t   | 64-bit length on 64-bit platforms. It is much the same  |
+   |              | as the C language long type, except on Tru64 UNIX,      |
+   |              | where GT.M remains a 32-bit application.                |
+   |--------------+---------------------------------------------------------|
+   | gtm_ulong_t  | gtm_ulong_t is much the same as the C language unsigned |
+   |              | long type.                                              |
+   |--------------+---------------------------------------------------------|
+   | gtm_float_t  | floating point number                                   |
+   |--------------+---------------------------------------------------------|
+   | gtm_double_t | Same as above but double precision.                     |
+   |--------------+---------------------------------------------------------|
+   |              | type int. If it returns zero then the call was          |
+   | gtm_status_t | successful. If it is non-zero, when control returns to  |
+   |              | GT.M, it issues a trappable error.                      |
+   |--------------+---------------------------------------------------------|
+   | gtm_long_t*  | Pointer to gtm_long_t. Good for returning integers.     |
+   |--------------+---------------------------------------------------------|
+   | gtm_ulong_t* | Pointer to gtm_ulong_t. Good for returning unsigned     |
+   |              | integers.                                               |
+   +------------------------------------------------------------------------+
+
+   typedef struct {
+       gtm_long_t length;
+       gtm_char_t* address;
+   } gtm_string_t;
+
+   The pointer types defined above are 32-bit addresses on all 32-platforms
+   (including Tru64 UNIX where GT.M remains a 32-bit application). For other
+   64-bit platforms, gtm_string_t* is a pointer is a 64-bit address.
+
+   gtmxc_types.h also provides an input-only parameter type
+   gtm_pointertofunc_t that can be used to obtain call-back function pointers
+   via parameters in the external routine. If a parameter is specified as
+   I:gtm_pointertofunc_t and if a numeric value (between 0-5) is passed for
+   this parameter in M, GT.M interprets this value as the index into the
+   callback table and passes the appropriate callback function pointer to the
+   external routine.
+
+   **Note**
+
+   GT.M represents values that fit in 18 digits as numeric values, and values
+   that require more than 18 digits as strings.
+
+   gtmxc_types.h also includes definitions for the following entry points
+   exported from libgtmshr:
+
+   void gtm_hiber_start(gtm_uint_t mssleep);
+   void gtm_hiber_start_wait_any(gtm_uint_t mssleep)
+   void gtm_start_timer(gtm_tid_t tid, gtm_int_t time_to_expir, void (*handler)(), gtm_int_t hdata_len, void \*hdata);
+   void gtm_cancel_timer(gtm_tid_t tid);
+
+   where:
+
+     * mssleep - milliseconds to sleep
+     * tid - unique timer id value
+     * time_to_expir - milliseconds until timer drives given handler
+     * handler - function pointer to handler to be driven
+     * hdata_len - 0 or length of data to pass to handler as a parameter
+     * hdata - NULL or address of data to pass to handler as a parameter
+
+   gtm_hiber_start() always sleeps until the time expires;
+   gtm_hiber_start_wait_any() sleeps until the time expires or an interrupt
+   by any signal (including another timer). gtm_start_timer() starts a timer
+   but returns immediately (no sleeping) and drives the given handler when
+   time expires unless the timer is canceled.
+
+   **Important**
+
+   GT.M continues to support xc_* equivalent types of gtm_* for upward
+   compatibility. gtmxc_types.h explicitly marks the xc_* equivalent types as
+   deprecated.
+
+4 Call-In_Table
+   Call-In Table
+
+   The Call-In table file is a text file that contains the signatures of all
+   M label references that get called from C. In order to pass the typed C
+   arguments to the type-less M formallist, the enviroment variable GTMCI
+   must be defined to point to the Call-In table file path. Each signature
+   must be specified separately in a single line. GT.M reads this file and
+   interprets each line according to the following convention (specifications
+   withint box brackets "[]", are optional):
+
+   <c-call-name> : <ret-type> <label-ref> ([<direction>:<param-type>,...])
+
+   where,
+
+   <label-ref>: is the entry point (that is a valid label reference) at which
+   GT.M starts executing the M routine being called-in
+
+   <c-call-name>: is a unique C identifier that is actually used within C to
+   refer to <label-ref>
+
+   <direction>: is either I (input-only), O (output-only), or IO
+   (input-output)
+
+   <ret-type>: is the return type of <label-ref>
+
+   **Note**
+
+   Since the return type is considered as an output-only (O) parameter, the
+   only types allowed are pointer types and void. Void cannot be specified as
+   parameter.
+
+   <param-type>: is a valid parameter type. Empty parenthese must be
+   specified if no argument is passed to <label-ref>
+
+   The <direction> indicates the type of operation that GT.M performs on the
+   parameter read-only (I), write-only (O), or read-write (IO). All O and IO
+   parameters must be passed by reference, that is as pointers since GT.M
+   writes to these locations. All pointers that are being passed to GT.M must
+   be pre-allocated. The following table details valid type specifications
+   for each direction.
+
+   +------------------------------------------------------------------------+
+   | Directions |                  Allowed Parameter types                  |
+   |------------+-----------------------------------------------------------|
+   |            | gtm_long_t, gtm_ulong_t, gtm_float_t,                     |
+   | I          | gtm_double_t,_gtm_long_t*, gtm_ulong_t*, gtm_float_t*,    |
+   |            | gtm_double_t*,_gtm_char_t*, gtm_string_t*                 |
+   |------------+-----------------------------------------------------------|
+   | O/IO       | gtm_long_t*, gtm_ulong_t*, gtm_float_t*,                  |
+   |            | gtm_double_t*,_gtm_char_t*, gtm_string_t*                 |
+   +------------------------------------------------------------------------+
 
-   GTM>
+   Here is an example of Call-In table (calltab.ci) for piece.m:
+
+   print     :void            display^piece()
+   getpiece  :gtm_char_t*     get^piece(I:gtm_char_t*, I:gtm_char_t*, I:gtm_long_t)
+   setpiece  :void            set^piece(IO:gtm_char_t*, I:gtm_char_t*, I:gtm_long_t, I:gtm_char_t*)
+   pow       :gtm_double_t*   pow^piece(I:gtm_double_t, I:gtm_long_t)
+   powequal  :void            powequal^piece(IO:gtm_double_t*, I:gtm_long_t)
+   piece     :gtm_double_t*   pow^piece(I:gtm_double_t, I:gtm_long_t)
 
-   This example invokes  %RD  that  prompts  for  routine  TAXES  and  the
-   wildcard (*). %RD lists five routines accessible  through  the  current
-   $ZROUTINES.
+   **Note**
 
-   Example:
+   The same entryref can be called by different C call names (for example,
+   pow, and piece). However, if there are multiple lines with the same call
+   name, only the first entry will be used by GT.M. GT.M ignores all
+   subsequent entries using a call name. Also, note that the second and third
+   entries, although shown here as wrapped across lines, must be specified as
+   a single line in the file.
 
+3 Interface
+   Interface
 
-   GTM>DO OBJ^%RD
+   This section is further broken down into 6 subsections for an easy
+   understanding of the Call-In interface. The section is concluded with an
+   elaborate example.
 
-   Routine directory
+5 Initialize_GT.M
+   Initialize GT.M
 
-   Routine:*
+   gtm_status_t gtm_init(void);
+
+   If the base program is not an M routine but a standalone C program,
+   gtm_init() must be called (before calling any GT.M functions), to
+   initialize the GT.M run-time system.
 
-   EMP FICA
+   gtm_init() returns zero (0) on success. On failure, it returns the GT.M
+   error status code whose message can be read into a buffer by immediately
+   calling gtm_zstatus(). Duplicate invocations of gtm_init() are ignored by
+   GT.M.
 
-   Total of 2 routines
+   If Call-Ins are used from an external call function (that is, a C function
+   that has itself been called from M code), gtm_init() is not needed,
+   because GT.M is initialized before the External Call. All gtm_init() calls
+   from External Calls functions are ignored by GT.M.
 
-   Routine: <RETURN>
+4 Call_from_C
+   Call from C
 
-   GTM>
+   GT.M provides 2 interfaces for calling a M routine from C. These are:
 
-   This example invokes %RD with the label  OBJ  that  lists  only  object
-   modules accessible through the current $ZROUTINES.
+     * gtm_cip
+     * gtm_ci
 
-   Example:
+   gtm_cip offers better performance on calls after the first one.
 
+5 gtm_cip
+   gtm_cip
 
-   GTM>DO LIB^%RD
+   gtm_status_t gtm_cip(ci_name_descriptor *ci_info, ...);
 
-   Routine directory
+   The variable argument function gtm_cip() is the interface that invokes the
+   specified M routine and returns the results via parameters.
 
-   %D %DATE %DH %G %GD %GSEL
+   ci_name_descriptor has the following structure:
 
-   GTM>
+   typedef struct
+   {
+     gtm_string_t rtn_name;
+     void* handle;
+   } ci_name_descriptor;
+
+   rtn_name is a C character string indicating the corresponding <lab-ref>
+   entry in the Call-In table.
+
+   The handle is GT.M private information initialized by GT.M on the first
+   call-in and to be provided unmodified to GT.M on subsequent calls. If
+   application code modifies it, it will corrupt the address space of the
+   process, and potentially cause just about any bad behavior that it is
+   possible for the process to cause, including but not limited to process
+   death, database damage and security violations.
+
+   The gtm_cip() call must follow the following format:
+
+   status = gtm_cip(<ci_name_descriptor> [, ret_val] [, arg1] ...);
+
+   First argument: ci_name_descriptor, a null-terminated C character string
+   indicating the alias name for the corresponding <lab-ref> entry in the
+   Call-In table.
+
+   Optional second argument: ret_val, a pre-allocated pointer through which
+   GT.M returns the value of QUIT argument from the (extrinsic) M routine.
+   ret_val must be the same type as specified for <ret-type> in the Call-In
+   table entry. The ret_val argument is needed if and only if <ret-type> is
+   not void.
+
+   Optional list of arguments to be passed to the M routine's formallist: the
+   number of arguments and the type of each argument must match the number of
+   parameters, and parameter types specified in the corresponding Call-In
+   table entry. All pointer arguments must be pre-allocated. GT.M assumes
+   that any pointer, which is passed for O/IO-parameter points to valid
+   write-able memory.
+
+   The status value returned by gtm_cip() indicates the GT.M status code;
+   zero (0), if successful, or a non-zero; $ZSTATUS error code on failure.
+   The $ZSTATUS message of the failure can be read into a buffer by
+   immediately calling gtm_zstatus().
+
+5 gtm_ci
+   gtm_ci
+
+   gtm_status_t gtm_ci(const gtm_char_t* c_call_name, ...);
+
+   The variable argument function gtm_ci() is the interface that actually
+   invokes the specified M routine and returns the results via parameters.
+   The gtm_ci() call must be in the following format:
+
+   status = gtm_ci(<c_call_name> [, ret_val] [, arg1] ...);
+
+   First argument: c_call_name, a null-terminated C character string
+   indicating the alias name for the corresponding <lab-ref> entry in the
+   Call-In table.
+
+   Optional second argument: ret_val, a pre-allocated pointer through which
+   GT.M returns the value of QUIT argument from the (extrinsic) M routine.
+   ret_val must be the same type as specified for <ret-type> in the Call-In
+   table entry. The ret_val argument is needed if and only if <ret-type> is
+   not void.
+
+   Optional list of arguments to be passed to the M routine's formallist: the
+   number of arguments and the type of each argument must match the number of
+   parameters, and parameter types specified in the corresponding Call-In
+   table entry. All pointer arguments must be pre-allocated. GT.M assumes
+   that any pointer, which is passed for O/IO-parameter points to valid
+   write-able memory.
+
+   The status value returned by gtm_ci() indicates the GT.M status code; zero
+   (0), if successful, or a non-zero; $ZSTATUS error code on failure. The
+   $ZSTATUS message of the failure can be read into a buffer by immediately
+   calling gtm_zstatus().
+
+4 Error_Messages
+   Error Messages
+
+   void gtm_zstatus (gtm_char_t* msg_buffer, gtm_long_t buf_len);
+
+   This function returns the null-terminated $ZSTATUS message of the last
+   failure via the buffer pointed by msg_buffer of size buf_len. The message
+   is truncated to size buf_len if it does not fit into the buffer.
+   gtm_zstatus() is useful if the external application needs the text message
+   corresponding to the last GT.M failure. A buffer of 2048 is sufficient to
+   fit in any GT.M message.
+
+4 Exit
+   Exit
+
+   gtm_status_t  gtm_exit (void);
+
+   gtm_exit() can be used to shut down all databases and exit from the GT.M
+   environment that was created by a previous gtm_init().
+
+   Note that gtm_init() creates various GT.M resources and keeps them open
+   across multiple invocations of gtm_ci() until gtm_exit() is called to
+   close all such resources. On successful exit, gtm_exit() returns zero (0),
+   else it returns the $ZSTATUS error code.
+
+   gtm_exit() cannot be called from an external call function. GT.M reports
+   the error GTM-E-INVGTMEXIT if an external call function invokes
+   gtm_exit(). Since the GT.M run-time system must be operational even after
+   the external call function returns, gtm_exit() is meant to be called only
+   once during a process lifetime, and only from the base C/C++ program when
+   GT.M functions are no longer required by the program.
+
+3 Standalone_Programs
+   Standalone Programs
+
+   All external C functions that use call-ins should include the header file
+   gtmxc_types.h that defines various types and provides signatures of
+   call-in functions. To avoid potential size mismatches with the parameter
+   types, FIS strongly recommends that gtm *t types defined in gtmxc_types.h
+   be used instead of the native types (int, float, char, etc).
+
+   To use call-ins from a standalone C program, it is necessary that the GT.M
+   runtime library (libgtmshr.so) is explicitly linked into the program. If
+   call-ins are used from an External Call function (which in turn was called
+   from GT.M through the existing external call mechanism), the External Call
+   library does not need to be linked explicitly with libgtmshr.so since GT.M
+   would have already loaded it.
+
+3 Nested_Call-Ins
+   Nested Call-Ins
+
+   Call-ins can be nested by making an external call function in-turn call
+   back into GT.M. Each gtm_ci() called from an External Call library creates
+   a call-in base frame at $ZLEVEL 1 and executes the M routine at $ZLEVEL 2.
+   The nested call-in stack unwinds automatically when the External Call
+   function returns to GT.M.
+
+   GT.M currently allows up to 10 levels of nesting, if TP is not used, and
+   less than 10 if GT.M supports call-ins from a transaction. GT.M reports
+   the error GTM-E-CIMAXLEVELS when the nesting reaches its limit.
+
+   Following are the GT.M commands, Intrinsic Special Variables, and
+   functions whose behavior changes in the context of every new nested
+   call-in environment.
+
+   ZGOTO operates only within the current nested M stack. ZGOTO zero (0)
+   unwinds all frames in the current nested call-in M stack (including the
+   call-in base frame) and returns to C. ZGOTO one (1) unwinds all current
+   stack frame levels up to (but not inclusive) the call-in base frame and
+   returns to C, while keeping the current nested call-in environment active
+   for any following gtm_ci() calls.
+
+   $ZTRAP/$ETRAP NEW'd at level 1 (in GTM$CI frame).
+
+   $ZLEVEL initializes to one (1) in GTM$CI frame, and increments for every
+   new stack level.
+
+   $STACK initializes to zero (0) in GTM$CI frame, and increments for every
+   new stack level.
+
+   $ESTACK NEW'd at level one (1) in GTM$CI frame.
+
+   $ECODE/$STACK() initialized to null at level one (1) in GTM$CI frame.
+
+   **Note**
+
+   After a nested call-in environment exits and the external call C function
+   returns to M, the above ISVs and Functions restore their old values.
+
+3 Rules_to_Follow_in_Call-Ins
+   Rules to Follow in Call-Ins
+
+    1. External calls must not be fenced with TSTART/TCOMMIT if the external
+       routine calls back into mumps using call-in mechanism. GT.M reports
+       the error GTM-E-CITPNESTED if nested call-ins are invoked within a TP
+       fence since GT.M currently does not handle TP support across multiple
+       call-in invocations.
+    2. The external application should never call exit() unless it has called
+       gtm_exit() previously. GT.M internally installs an exit handler that
+       should never be bypassed to have a clean shutdown of GT.M.
+    3. The external application should never use any signals when GT.M is
+       active since GT.M reserves them for its internal use. GT.M provides
+       the ability to handle SIGUSR1 within M. An interface is provided by
+       GT.M for timers. Although not required, FIS recommends the use of
+       gtm_malloc() and gtm_free() for memory management by C code that
+       executes in a GT.M process space for enhanced performance and improved
+       debugging.
+
+1 Internationalization
+   Internationalization
+
+   This chapter describes GT.M facilities for applications using characters
+   encoded in other than eight-bit bytes (octets). The underlying software
+   libraries necessary to implement the GT.M internationalization facilities
+   may not be available on your system. Before continuing with the
+   implementation provided in this chapter refer to the product release notes
+   that accompanied your GT.M shipment. These facilities address the specific
+   issues of defining alternative collation sequences, and defining unique
+   patterns for use with the pattern match operator. The details of each
+   facility are described in separate sections of this chapter.
+
+   Alternative collation sequences (or an alternative ordering of strings)
+   can be defined for global and local variable subscripts. They can be
+   established for specified globals or for an entire database. The
+   alternative sequences are defined by a series of routines in an executable
+   file pointed to by an environment variable. As the collation sequence is
+   implemented by a user-supplied program, virtually any collation policy may
+   be implemented. Detailed information on establishing alternative collation
+   sequences and defining the environment variable is provided in Collation
+   Sequence Definitions.
+
+   M has defined pattern classes that serve as arguments to the pattern match
+   operator. GT.M supports user definition of additional pattern classes as
+   well as redefinition of the standard pattern classes. Specific patterns
+   are defined in a text file that is pointed to by an environment variable.
+   Pattern classes may be re-defined dynamically. The details of defining
+   these pattern classes and the environment variable are described in the
+   section called Match Alternative Patterns.
+
+   For some languages (such as Chinese), the ordering of strings according to
+   Unicode code-points (character values) may or may not be the
+   linguistically or culturally correct ordering. Supporting applications in
+   such languages requires development of collation modules - GT.M natively
+   supports M collation, but does not include pre-built collation modules for
+   any specific natural language. Therefore, applications that use characters
+   in Unicode may need to implement their own collation functions.
+
+2 Collation_Sequence_Definitions
+   Collation Sequence Definitions
+
+   Normally, GT.M orders data with numeric values first, followed by strings
+   sequenced by ASCII values. To use an alternative collating sequence the
+   following items must be provided at GT.M process intialization.
+
+     * A shared library containing the routines for each alternative
+       collation sequence
+     * An environment variable of the form gtm_collate_n, specifying the
+       shared library containing the routines for alternative collation
+       sequence n.
+
+3 Shared_Library
+   Shared Library
+
+   A shared library for an alternative collation sequence must contain the
+   following four routines:
+
+    1. gtm_ac_xform_1: Transforms subscripts up to the maximum supported
+       string length to the alternative collation sequence, or
+
+       gtm_ac_xform: Transforms subscripts up to 32,767 bytes to the
+       alternative collation sequence.
+
+    2. gtm_ac_xback_1: Use with gtm_ac_xform_1 to transform the alternative
+       collation keys back to the original subscript representation, or
+
+       gtm_ac_xback: Use with gtm_ac_xform to transforms the alternative
+       collation keys back to the original subscript representation.
+
+    3. gtm_ac_version: Returns a numeric version identifier for the
+       "currently active" set of collation routines.
+    4. gtm_ac_verify: Returns the success (odd) or failure (even) in matching
+       a collation sequence with a given version number.
+
+   GT.M searches the shared library for the gtm_ac_xform_1 and gtm_ac_xback_1
+   before searching for the gtm_ac_xform and gtm_ac_xback routines. If the
+   shared library contains gtm_ac_xform_1, GT.M ignores gtm_ac_xform even if
+   it is present. If GT.M finds gtm_ac_xform_1 but does not find
+   gtm_ac_xback_1, it reports a GTM-E-COLLATIONUNDEF error with an additional
+   mismatch warning GTM-E-COLLFNMISSING.
+
+   If the application does not use strings longer than 32,767 bytes, the
+   alternative collation library need not contain the gtm_ac_xform_1 and
+   gtm_ac_xback_1 routines. On the other hand, if the application passes
+   strings greater than 32,767 bytes (but less than the maximum support
+   string length) and does not provide gtm_xc_xform_1 and gtm_xc_xback_1,
+   GT.M issues the run-time error GTM-E-COLLARGLONG.
+
+3 Environment_Variable
+   Environment Variable
+
+   GT.M locates the alternative collation sequences through the environment
+   variable gtm_collate_n where n is an integer from 1 to 255 that identifies
+   the collation sequence, and pathname identifies the shared library
+   containing the routines for that collation sequence, for example:
+
+   $ gtm_collate_1=/opt/fis-gtm/collation
+   $ export gtm_collate_1
+
+   Multiple alternative collation sequence definitions can co-exist.
+
+4 Establish_Alternative_Collations
+   Establish Alternative Collations
+
+   Alternative collation sequences for a global must be set when the global
+   contains no data. When the global is defined the collation sequence is
+   stored in the global. This ensures the future integrity of the global's
+   collation. If it becomes necessary to change the collation sequence of a
+   global containing data, you must copy the data to a temporary repository,
+   modify the variable's collation sequence, and restore the data from the
+   temporary repository.
 
-   This example invokes %RD with the  LIB  label  that  lists  all  the  %
-   routines accessible through the current $ZROUTINES.
+   Be careful when creating the transformation and inverse transformation
+   routines. The transformation routine must unambiguously and reliably
+   encode every possible input value. The inverse routine must faithfully
+   return the original value in every case. Errors in these routines can
+   produce delayed symptoms that could be hard to debug. These routines may
+   not be written in M.
 
-   Example:
+3 Collation_Method
+   Collation Method
 
+   GT.M lets you define an alternative collation sequence as the default when
+   creating a new database. Subsequently, this default is applied when each
+   new global is created.
 
-   GTM>DO SRC^%RD
+   This default collation sequence is set as a GDE qualifier for the ADD,
+   CHANGE, and TEMPLATE commands using the following syntax:
 
-   Routine directory
+   GDE>CHANGE -REGION DEFAULT -COLLATION_DEFAULT=<0-255>
 
-   Routine:*
+   This qualifier always applies to regions, and takes effect when a database
+   is created with MUPIP CREATE. The output of GDE SHOW displays this value,
+   and DSE DUMP -FILEHEADER also includes this information. In the absence of
+   an alternative default collations sequence, the default used is 0, or
+   ASCII.
 
-   DATACHG
+   The value cannot be changed once a database file is created, and will be
+   in effect for the life of the database file. The same restriction applies
+   to the version of the collation sequence. The version of a collation
+   sequence implementation is also stored in the database fileheader and
+   cannot be modified except by recreating the file.
 
-   Total of 1 routines
+   If the code of the collation sequence changes, making it incompatible with
+   the collation sequence in use when the database was created, use the
+   following procedure to ensure the continued validity of the database.
+   MUPIP EXTRACT the database using the older compatible collation routines,
+   then recreate and MUPIP LOAD using the newer collation routines.
 
-   Routine: <RETURN>
+3 Establishing_A_Local_Collation_Sequence
+   Establishing A Local Collation Sequence
 
-   GTM>
+   All subscripted local variables for a process must use the same collation
+   sequence. The collation sequence used by local variables can be
+   established as a default or in the current process. The local collation
+   sequence can only be changed when a process has no subscripted local
+   variables defined.
 
-   This example invokes %RD with the label  SRC  that  lists  only  source
-   modules accessible through the current $ZROUTINES.
+   To establish a default local collation sequence provide a numeric value to
+   the environment variable gtm_local_collate to select one of the collation
+   tables, for example:
 
-3 RI
-   %RI
+   $ gtm_local_collate=n
+   $ export gtm_local_collate
 
+   where n is the number of a collation sequence that matches a valid
+   collation number defined by an environment variable in the form
+   gtm_collate_n.
 
-   %RI transforms M routines in the sequential  format  described  in  the
-   ANSI standard into individual .m files in GT.M format. Use %RI to make
-   M RO format accessible as GT.M routines.
+   An active process can use the %LCLCOL utility to define the collation
+   sequence for subscripts of local variables. %LCLCOL has these extrinsic
+   entry points:
 
-4 Prompts
-   Prompts
+   set^%LCLCOL(n)changes the local collation to the type specified by n.
 
-        Formfeed delimited <No>?
-        Requests whether lines should be delimited by  formfeed  characters
-        rather than carriage returns.
-        Input Device: <terminal>:
-        Requests name of RO file containing M routines.
-        Output Directory:
-        Requests name of directory to output M routines.
-4 Ex_of_RI
-   Examples of %RI
+   If the collation sequence is not available, the routine returns a false
+   (0) and does not modify the local collation sequence.
 
    Example:
 
+   IF '$$set^%LCLCOL(3) D
+   . Write "local collation sequence not changed",! Break
 
-   GTM>DO ^%RI
-
-   Routine Input utility - Converts RO file to *.m files
+   This piece of code illustrates $$set^LCLCOL used as an extrinsic. It would
+   write an error message and BREAK if the local collation sequence was not
+   set to 3.
 
-   Formfeed delimited <No>? <RETURN>
+   set^%LCLCOL(n,ncol) determines the null collation type to be used with the
+   collation type n.
 
-   Input device: <terminal>: file.ro
+   With set^%LCLCOL(,ncol), the null collation order can be changed while
+   keeping the alternate collation order unchanged. If subscripted local
+   variables exist, null collation order cannot be changed. In this case,
+   GT.M issues GTM-E-COLLDATAEXISTS.
 
-   Files saved from FILEMAN directory
+   get^%LCLCOL returns the current local type.
 
-   GT.M 07-MAY-2002 15:17:54
+   Example:
 
-   Output directory: /usr/smith/work/
+   GTM>Write $$get^%LCLCOL
+   0
 
-   DI DIA DIAO DIAI DIB DIBI
+   This example uses $$get^%LCLCOL as an extrinsic that returns 0, indicating
+   that the effective local collation sequence is the standard M collation
+   sequence.
 
-   Restored 753 lines in 6 routines.
+   If set^%LCLCOL is not specified and gtm_local_collate is not defined, or
+   is invalid, the process uses M standard collation. The following would be
+   considered invalid values:
 
-   GTM>
+     * A value less than 0
+     * A value greater than 255
+     * A legal collation sequence that is inaccessible to the shared library
 
-3 RO
-   %RO
+   Inaccessibility could be caused by a missing environment variable, a
+   missing image, or by security denial of access.
 
+2 Alternate_Collation
+   Alternate Collation
 
-   The %RO utility writes M source code for one  or  more  routines  to  a
-   sequential device such as a disk file or a printer.
+   Each alternative collation sequence requires a set of four user-created
+   routines--gtm_ac_xform_1 (or gtm_ac_xform), gtm_ac_xback_1 (or
+   gtm_ac_xback), gtm_ac_version, and gtm_ac_verify. The original and
+   transformed strings are passed between GT.M and the user-created routines
+   using parameters of type gtm_descriptor or gtm32_descriptor. An "include
+   file" gtm_descript.h, located in the GT.M distribution directory, defines
+   gtm_descriptor (used with gtm_ac_xform and gtm_ac_xback) as:
 
-   %RO uses %RSEL to select routines. For more information, refer  to  the
-   section on %RSEL in this chapter.
+   typedef struct
+   {
+       short len;
+       short type;
+       void *val;
+   } gtm_descriptor;
 
-   %RO writes the routines in alphabetical order to the specified device.
-   %RO displays the name of each routine as it writes the routine  to  the
-   device.
+   **Note**
 
-4 Prompts
-   Prompts
+   On 64-bit UNIX platforms, gtm_descriptor may grow by up to 8 bytes as a
+   result of compiler padding to meet platform alignment requirements.
+   gtm_descriptor is 4 bytes on 32-bit UNIX platforms.
 
-        Routine: Requests (using %RSEL) the  name(s)  of  the  routines  to
-        output; <RETURN> ends selection.
-        Output device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-        Header label: Requests text to place in the first of the two header
-        records.
-        Strip comments <No>?:
-        Asks whether to remove all comment  lines  except  those  with  two
-        adjacent semicolons.
-4 Util_Labels
-   Utility Labels
+   gtm_descript.h defines gtm32_descriptor (used with gtm_xc_xform_1 and
+   gtm_xc_xback_2) as:
 
-        CALL Works without user interaction unless %ZR is not defined.
-4 Input_Vars
-   Input Variables
+   typedef struct
+   {
+       unsigned int len;
+       unsigned int type;
+       void *val;
+   } gtm32_descriptor;
 
-   The  following  input  variables  are  only  applicable  when  invoking
-   CALL^%RO.
+   where len is the length of the data, type is set to DSC_K_DTYPE_T
+   (indicating that this is an M string), and val points to the text of the
+   string.
 
-        %ZR Contains an array of routines provided or generated with %RSEL.
-        %ZD Identifies the device to display output, defaults to principal
-        device.
-4 Ex_of_RO
-   Examples of %RO
+   The interface to each routine is described below.
 
-   Example:
+3 Transformation
+   Transformation
 
+   gtm_ac_xform_1 or gtm_ac_xform routines transforms subscripts to the
+   alternative collation sequence.>
 
-   GTM>DO ^%RO
+   If the application uses strings use strings longer than 32,767 (but less
+   than 1,048,576) bytes, the alternative collation library must contain the
+   gtm_ac_xform_1 and gtm_ac_xback_1 routines. Otherwise, the alternative
+   collation library should contain gtm_ac_xform and gtm_ac_xback.
 
-   Routine Output - Save selected routines into RO file.
+   The syntax of this routine is:
 
-   Routine: %D
+   #include "gtm_descript.h"
+   int gtm_ac_xform_1(gtm32_descriptor* in, int level, gtm32_descriptor* out, int* outlen);
 
-   %D
+4 Input_Arguments
+   Input Arguments
 
-   Current total of 1 routines.
+   The input arguments for gtm_ac_xform are:
 
-   Routine: -%D
+   in: a gtm32_descriptor containing the string to be transformed.
 
-   %D
+   level: an integer; this is not used currently, but is reserved for future
+   facilities.
 
-   Current total of 0 routines.
+   out: a gtm32_descriptor to be filled with the transformed key.
 
-   Routine: BEST*
+4 Output_Arguments
+   Output Arguments
 
-   BEST BEST1 BEST2
+   return value: A long word status code.
 
-   Current total of 3 routines.
+   out: A transformed subscript in the string buffer, passed by
+   gtm32_descriptor.
 
-   Routine: ?D
+   outlen: A 32-bit signed integer, passed by reference, returning the actual
+   length of the transformed key.
 
-   BEST BEST1 BEST2
+   The syntax of gtm_ac_xform routine is:
 
-   Routine: <RETURN>
+   #include "gtm_descript.h"
+   long gtm_ac_xform(gtm_descriptor *in, int level, gtm_descriptor *out, int *outlen)
 
-   Output Device: <terminal>: output.txt
+5 Input_Arguments
+   Input Arguments
 
-   Header Label: Source code for the BEST modules.
+   The input arguments for gtm_ac_xform are:
 
-   Strip comments <No>?:<RETURN>
+   in: a gtm_descriptor containing the string to be transformed.
 
-   BEST BEST1 BEST2
+   level: an integer; this is not used currently, but is reserved for future
+   facilities.
 
-   Total of 53 lines in 3 routines
+   out: a gtm_descriptor to be filled with the transformed key.
 
-   GTM>
+5 Output_Arguments
+   Output Arguments
 
-   This example adds and subtracts %D from the selection,  then  adds  all
-   routines starting with "BEST" and confirms the current  selection.  The
-   example sends output to the  designated  output  file  output.txt.  %RO
-   displays the label at the beginning  of  the  output  file.  The  first
-   record of the header label is the  text  entered  at  the  prompt.  The
-   second record of the header label consists of the word "GT.M"  and  the
-   current date and time.
+   The output arguments for gtm_ac_xform are:
 
-3 RSE_
-   %RSE
+   return value: a long result providing a status code; it indicates the
+   success (zero) or failure (non-zero) of the transformation.
 
+   out: a gtm_descriptor containing the transformed key.
 
-   The %RSE utility searches for every occurrence of a text  string  in  a
-   routine or a list of routines.
+   outlen: an unsigned long, passed by reference, giving the actual length of
+   the output key.
 
-   %RSE uses %RSEL to select routines. For more information, refer to the
-   section on %RSEL in this chapter.
+   Example:
 
-   %RSE searches for  text  strings  are  case-sensitive.  %RSE  issues  a
-   warning message if you specify a control character such as a  <TAB>  in
-   the text string. %RSE confirms your selection by  displaying  the  text
-   string between a left and right arrow. The  arrows  display  any  blank
-   spaces included in the text string.
+   #include "gtm_descript.h"
+   #define MYAPP_SUBSC2LONG 12345678
+   static unsigned char xform_table[256] =
+   {
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+    64, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93,
+    95, 97, 99,101,103,105,107,109,111,113,115,117,118,119,120,121,
+   122, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+    96, 98,100,102,104,106,108,110,112,114,116,123,124,125,126,127,
+   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
+   };
+
+   long
+   gtm_ac_xform (in, level, out, outlen)
+        gtm_descriptor *in;    /* the input string */
+        int level;            /* the subscript level */
+        gtm_descriptor *out;    /* the output buffer */
+        int *outlen;        /* the length of the output string */
+   {
+     int n;
+     unsigned char *cp, *cout;
+   /* Ensure space in the output buffer for the string. */
+     n = in->len;
+     if (n > out->len)
+       return MYAPP_SUBSC2LONG;
+   /* There is space, copy the string, transforming, if necessary */
+     cp = in->val;            /* Address of first byte of input string */
+     cout = out->val;        /* Address of first byte of output buffer */
+     while (n-- > 0)
+       *cout++ = xform_table[*cp++];
+     *outlen = in->len;
+     return 0;
+   }
 
-   %RSE completes processing with a count of occurrences found.
+3 Inverse_Transformation
+   Inverse Transformation
 
+   This routine returns altered keys to the original subscripts. The syntax
+   of this routine is:
 
-4 Prompts
-   Prompts
+   #include "gtm_descript.h"
+   long gtm_ac_xback(gtm_descriptor *in, int level, gtm_descriptor *out, int *outlen)
 
-        Routine: Requests (using %RSEL) the  name(s)  of  the  routines  to
-        search; <RETURN> ends selection.
-        Find string: Requests string for which to search.
-        Output device: <terminal>:
-        Requests a destination device; defaults to the principal device.
-4 Util_Labels
-   Utility Labels
+   The arguments of gtm_ac_xback are identical to those of gtm_ac_xform.
 
-        CALL Works without user interaction unless %ZR is not defined.
-4 Input_Vars
-   Input Variables
+   The syntax of gtm_ac_xback_1 is:
 
-   The  following  input  variables  are  only  applicable  when  invoking
-   CALL^%RSE.
+   #include "gtm_descript.h"
+   long gtm_ac_xback_1 ( gtm32_descriptor *src, int level, gtm32_descriptor *dst, int *dstlen)
 
-        %ZR Contains an array of routines provided or generated with %RSEL.
-        %ZF Contains the string to find.
-        %ZD Identifies the device  to  display  the  results,  defaults  to
-        principal device. Make sure you open the device if  the  device  is
-        not the principal device.
-4 Ex_of_RSE
-   Examples of %RSE
+   The arguments of gtm_ac_xback_1 are identical to those of gtm_ac_xform_1.
 
    Example:
 
+   #include "gtm_descript.h"
+   #define MYAPP_SUBSC2LONG 12345678
+   static unsigned char inverse_table[256] =
+   {
+   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+   64, 65, 97, 66, 98, 67, 99, 68,100, 69,101, 70,102, 71,103, 72,
+   104, 73,105, 74,106, 75,107, 76,108, 77,109, 78,110, 79,111, 80,
+   112, 81,113, 82,114, 83,115, 84,116, 85,117, 86,118, 87,119, 88,
+   120, 89,121, 90,122, 91, 92, 93, 94, 95, 96,123,124,125,126,127,
+   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
+   };
+
+   long gtm_ac_xback (in, level, out, outlen)
+        gtm_descriptor *in;    /* the input string */
+        int level;            /* the subscript level */
+        gtm_descriptor *out;    /* output buffer */
+        int *outlen;        /* the length of the output string */
+   {
+     int n;
+     unsigned char *cp, *cout;
+   /* Ensure space in the output buffer for the string. */
+     n = in->len;
+     if (n > out->len)
+       return MYAPP_SUBSC2LONG;
+   /* There is enough space, copy the string, transforming, if necessary */
+     cp = in->val;            /* Address of first byte of input string */
+     cout = out->val;        /* Address of first byte of output buffer */
+     while (n-- > 0)
+       *cout++ = inverse_table[*cp++];
+     *outlen = in->len;
+     return 0;
+   }
 
-   GTM>DO ^%RSE
-
-   Routine Search for Every occurrence
-
-   Routine: BES*
-
-   BEST BEST2 BEST3 BEST4
-
-   Current total of 4 routines
-
-   Routine: <RETURN>
+3 Version_Control
+   Version Control
 
-   Find string:^NAME
+   Two user-defined version control routines provide a safety mechanism to
+   guard against a collation routine being used on the wrong global, or an
+   attempt being made to modify a collation routine for an existing global.
+   Either of these situations could cause incorrect collation or damage to
+   subscripts.
 
-   Find all occurrences of:
+   When a global is assigned an alternative collation sequence, GT.M invokes
+   a user-supplied routine that returns a numeric version identifier for the
+   set of collation routines, which was stored with the global. The first
+   time a process accesses the global, GT.M determines the assigned collation
+   sequence, then invokes another user-supplied routine. The second routine
+   matches the collation sequence and version identifier assigned to the
+   global with those of the current set of collation routines.
 
->^NAME<
-   Output device: <terminal>:
+   When you write the code that matches the type and version, you can decide
+   whether to modify the version identifier and whether to allow support of
+   globals created using a previous version of the routine.
 
-   /usr/smith/work/BEST.m
+4 Version_Identifier
+   Version Identifier
 
-   S ^NAME=SMITH
+   This routine returns an integer identifier between 0 and 255. This integer
+   provides a mechanism to enforce compatibility as a collation sequence
+   potentially evolves. When GT.M first uses an alternate collation sequence
+   for a database or global, it captures the version and if it finds the
+   version has changed it at some later startup, it generates an error. The
+   syntax is:
 
-   S ^NAME(1)=JOHN
+   int gtm_ac_version()
 
-   /usr/smith/work/BEST2.m
+   Example:
 
-   /usr/smith/work/BEST3.m
+   int gtm_ac_version()
+   {
+       return 1;
+   }
 
-   S ^NAME=X
+4 Verification
+   Verification
 
-   W ^NAME
+   This routine verifies that the type and version associated with a global
+   are compatible with the active set of routines. Both the type and version
+   are unsigned characters passed by value. The syntax is:
 
-   /usr/smith/work/BEST4.m
+   #include "gtm_descript.h"
+   int gtm_ac_verify(unsigned char type, unsigned char ver)
 
-   Total of 4 routines parsed.
+   Example:
 
-   4 occurrences found in 2 routines.
-   GTM>
+   Example:
+   #include "gtm_descript.h"
+   #define MYAPP_WRONGVERSION 20406080    /* User condition */
 
-   This example invokes %RSE that searches and finds a given  string.  The
-   output device specifies a terminal display of all lines where the text
-   string occurs.
+   gtm_ac_verify (type, ver)
+        unsigned char type, ver;
+   {
+     if (type == 3)
+       {
+         if (ver > 2)        /* version checking may be more complex */
+       {
+         return 0;
+       }
+   }
+     return MYAPP_WRONGVERSION;
+   }
 
-   Example:
+3 %GBLDEF
+   %GBLDEF
 
+   The %GBLDEF utility is available to assign a collation sequence to a
+   global, check the collation sequence assigned to a global, or delete an
+   existing collation sequence from a global. %GBLDEF will not modify the
+   collation sequence for a global containing data.
 
-   GTM>DO ^%RSE
+4 Assigning
+   Assigning
 
-   Routine Search for Every occurrence
+   To assign a collation sequence to an individual global use the following
+   extrinsic entry point:
 
-   Routine: BEST
+   set^%GBLDEF(gname,nct,act)
 
-   BEST
+   where:
 
-   Current total of 1 routine
+     * The first argument, gname, is the name of the global. If the global
+       name appears as a literal, it must be enclosed in quotation marks ("
+       "). The leading caret symbol (^) must be included, and the name must
+       be a legal M variable name.
+     * The second argument, nct, is an integer that determines how numeric
+       subscripts are to be handled. The value is FALSE (0) if numeric
+       subscripts are to collate before strings, as in standard M, and TRUE
+       (1) if numeric subscripts are to be handled like strings.
+     * The third argument, act, is an integer specifying the active collation
+       sequence - from 0, standard M collation, to 255.
 
-   Routine: <RETURN>
+   **Note**
 
-   Find string:^NAME
+   set^%GBLDEF(gname) returns global specific characteristics, which do not
+   reflect any [collation] characteristics defined for the database file at
+   MUPIP CREATE time [from settings in the global directory]. Region
+   collation may be seen by using the DSE DUMP -FILEHEADER command,
+   implicitly in the case of M standard collation, as in that case no
+   collation information is displayed.
 
-   Find all occurrences of:
+   If the global contains data, this function returns a FALSE (0) and does
+   not modify the global.
 
->^NAME<
-   Output Device: out.lis
+   Example:
 
-   BEST
+   GTM>kill ^G
 
+   GTM>write $select($$set^%GBLDEF("^G",0,3):"ok",1:"failed")
+   ok
    GTM>
 
-   This example instructs ^%RSE to write all lines where the  text  string
-   occurs to an output file, out.lis.
+   This deletes the global variable ^G, then uses the $$set%GBLDEF as an
+   extrinsic to set ^G to the collation sequence number 3 with numeric
+   subscripts collating before strings. Using $$set%GBLDEF as an argument to
+   $SELECT results in a return message notifying whether or not the SET was
+   successful. $SELECT will return a "FAILED" message if the collation
+   sequence requested is undefined.
 
-3 RSEL
-   %RSEL
+4 Examining
+   Examining
 
+   To examine the collation characteristics currently assigned to a global
+   use the extrinsic entry point:
 
-   The %RSEL utility selects M  routines.  %RSEL  selects  routines  using
-   directories  specified  by  the  GT.M  special  variable  $ZROUTINES.
-   $ZROUTINES contains an ordered list of UNIX  directories  that  certain
-   GT.M functions use to locate source and object files. If $ZROUTINES is
-   not defined, %RSEL searches only the current default  directory.  Other
-   GT.M utilities call %RSEL.
+   get^%GBLDEF(gname)
 
-   %RSEL prompts for the name of a routine(s).
+   which returns the data associated with the global name as a comma
+   delimited string having these pieces:
 
+     * A truth-valued integer specifying FALSE (0) if numeric subscripts are
+       to collate before strings, as in standard M, and TRUE (1) if numeric
+       subscripts are to be handled like strings.
+     * An integer specifying the collation sequence.
+     * An integer specifying the version, or revision level, of the currently
+       implemented collation sequence.
 
-   %RSEL accepts the wildcard characters asterisk (*)  and  question  mark
-   (?). The wildcards carry their usual meanings: an asterisk (*) denotes
-   a field or a portion of a field, and a  question  mark  (?)  denotes  a
-   single character in positions other than the first.
+   **Note**
 
-   A colon (:) between two routines specifies a range.
+   A "0" return from $$get^%gbldef(gname) indicates that the global has no
+   special characteristics and uses the region default collation, while a
+   "0,0,0" return indicates that the global is explicitly defined to M
+   collation.
 
-   %RSEL creates a read-write variable %ZR, which  is  a  local  array  of
-   selected routines. After each selection, %RSEL reports  the  number  of
-   routines in %ZR. A minus  sign  (-)  or  an  apostrophe  (')  character
-   preceding a routine name removes that routine from  the  %ZR  array.  A
-   question mark (?) provides online help, and "?D"  displays  M  routines
-   currently in the array.
-
-        If a local variable %ZRSET is  defined,  %RSEL  places  the  output
-        information into a global variable (^%RSET) instead  of  the  local
-        variable %ZR.
+   Example:
 
-4 Prompts
-   Prompts
+   GTM>Write $$get^%GBLDEF("^G")
+   1,3,1
 
-        Routine: Requests  the  name(s)  of  the  routines;  <RETURN>  ends
-        selection.
-4 Util_Labels
-   Utility Labels
+   This example returns the collation sequence information currently assigned
+   to the global ^G.
 
-        CALL Performs %RSEL without reinitializing %ZR.
-        OBJ Searches only object files.
-        SRC Searches only source files (same as %RSEL).
-4 Input_Vars
-   Input Variables
+   This function returns the value of the characteristics defined for the
+   global, in contrast to $DATA(@gname), which returns information about data
+   and descendants at the name level of the global.
 
-   The following input variables are only valid when invoking CALL^%RSEL:
+4 Deleting
+   Deleting
 
-        %ZE Contains the file extension, usually either .m for source files
-        or .o for object files.
-        %ZR As input, contains an existing list of routines to be modified.
-        %ZRSET On being set, requests %RSEL to  place  the  output  in  the
-        global variable ^%RSET.
-4 Output_Vars
-   Output Variables
+   To delete the collation characteristics currently assigned to a global,
+   use the following extrinsic entry point:
 
-        %ZR As output, contains list of  directories  indexed  by  selected
-        routine names.
-        ^%RSET($JOB) The output global variable ^%RSET is used  instead  of
-        the local variable %RD if the input variable %ZRSET is set.  It  is
-        indexed by job number $JOB and the selected routine names.
-4 Ex_of_RSEL
-   Examples of %RSEL
+   kill^%GBLDEF(gname)
 
-   Example:
+   If the global contains data, the function returns a false (0) and does not
+   modify the global.
 
+2 Matching_Alternative_Patterns
+   Matching Alternative Patterns
 
-   GTM>DO ^%RSEL
+   GT.M allows the definition of unique patterns for use with the pattern
+   match operator, in place of, or in addition to, the standard C, N, U, L,
+   and P. You can redefine existing pattern codes (patcodes), or add new
+   ones. These codes are defined in a specification file. The format is
+   described in the next section.
 
-   Routine: TES*
+3 Pattern_Code_Definition
+   Pattern Code Definition
 
-   TEST2 TEST3
+   This section explains the requirements for specifying alternative pattern
+   codes. These specifications are created as a table in a file which GT.M
+   loads at run time.
 
-   Current total of 2 routines
+   Use the following keywords to construct your text file. Each keyword must:
 
-   Routine: <RETURN>
+     * Appear as the first non-whitespace entry on a line.
+     * Be upper case.
 
-   GTM>DO OBJ^%RSEL
+   The table names also must be uppercase. The patcodes are not
+   case-sensitive.
 
-   Routine:TEST?
+   PATSTART indicates the beginning of the definition text and must appear
+   before the first table definition.
 
-   Current total of 0 routines
+   PATTABLE indicates the beginning of the table definition. The keyword
+   PATTABLE is followed by whitespace, then the table name. The text file can
+   contain multiple PATTABLEs.
 
-   Routine: <RETURN>
+   PATCODE indicates the beginning of a patcode definition. The keyword
+   PATCODE is followed by whitespace, then the patcode identifying character.
+   On the next line enter a comma-delimited list of integer codes that
+   satisfy the patcode. A PATCODE definition is always included in the most
+   recently named PATTABLE. A PATTABLE can contain multiple PATCODEs.
 
-   GTM>ZWRITE
+   PATEND indicates the end of the definition text; it must appear after the
+   last table definition.
 
-   %ZR=0
+   To continue the comma-delimited list on multiple lines, place a dash (-)
+   at the end of each line that is not the last one in the sequence. To enter
+   comments in the file, begin the line with a semi-colon (;).
 
-   This example selects two source routines starting  with  "TES"  as  the
-   first three characters. Then, the example  invokes  %RSEL  at  the  OBJ
-   label to select object modules only. OBJ^%RSEL returns a %ZR=0 because
-   object modules for the TEST routines do not exist.
+   The following example illustrates a possible patcode table called
+   "NEWLANGUAGE," The example has definitions for patcodes "S," which would
+   be a non-standard pattern character, and "L," which would substitute
+   alternative definitions for the standard "L" (or lower case) pattern
+   characters.
 
    Example:
 
+   PATSTART
+     PATTABLE NEWLANGUAGE
+     PATCODE S
+       144,145,146,147,148,149,150
+     PATCODE L
+       230,231,232,233,234,235,236,237,238,239,240,241-,242,243,244,245,246,247,248,249,250,251,252,253,254,255
+   PATEND
 
-   GTM>DO ^%RSEL
+   Be mindful of the following items as you define your patcode table.
 
-   Routine: BES*
+     * A table name can only be loaded once during an invocation of GT.M. It
+       cannot be edited and reloaded, while the M process is running.
+     * The table name "M" is a reserved designation for standard M, which is
+       included in the GT.M run-time library.
+     * Standard patcodes A and E cannot be explicitly redefined.
 
-   BEST BEST2 BEST3 BEST4
+       A is always the union of codes U and L; E always designates the set of
+       all characters.
 
-   Current total of 4 routines
+     * The C pattern code you define is used by GT.M to determine those
+       characters which are to be treated as unprintable.
+     * In UTF-8 mode, M standard patcodes (A,C,L,U,N,P,E) work with Unicode
+       characters. Application developers can neither change their default
+       classification nor define the non-standard patcodes
+       ((B,D,F-K,M,O,Q-T,V-X) beyond the ASCII subset. This means that the
+       pattern tables cannot contain characters with codes greater than the
+       maximum ASCII code 127.
 
-   Routine: - BEST
+   All characters not defined as C are treated as printable.
 
-   BEST
+3 Code_Selection
+   Code Selection
 
-   Current total of 3 routines
+   To establish a default patcode table for a database define the environment
+   variable:
 
-   Routine: ?D
+   $ gtm_pattern_file=pathname
+   $ export gtm_pattern_file
 
-   BEST2 BEST3 BEST4
+   where filename is the text file containing the patcode table definition,
+   and
 
-   Routine: 'BEST2
+   $ gtm_pattern_table=tablename
+   $ export gtm_pattern_table
 
-   BEST2
+   where tablename is the name of the patcode table within the file pointed
+   to by gtm_pattern_file.
 
-   Current total of 2 routines
+   Within an active process, the patcode table is established using the M
+   VIEW command and the %PATCODE utility. Before invoking the %PATCODE
+   utility, you may use VIEW to load pattern definition files for GT.M. The
+   required keyword and value are:
 
-   Routine: ?D
+   VIEW "PATLOAD":"pathname"
 
-   BEST3 BEST4
+   This allows you to use the %PATCODE utility or the VIEW command to set
+   current patcode table. The format of the VIEW command to set the patcode
+   table is:
 
-   Routine: <RETURN>
+   VIEW "PATCODE":"tablename"
 
-   GTM>ZWRITE
+   This is equivalent to set ^%PATCODE explained below.
 
-   %ZR=2
+   %PATCODE has the following extrinsic entry points:
 
-   %ZR("BEST3")="/usr/smith/work/"
+   set^%PATCODE(tn)
 
-   %ZR("BEST4")="/usr/smith/test/"
+   sets the current patcode table to the one having the name specified by tn,
+   in the defined file specification.
 
-   GTM>
+   Example:
 
-   This example selects the routines using the asterisk (*)  wildcard  and
-   illustrates how to tailor your selection list. Note that  %ZR  contains
-   two routines from different directories.
+   GTM>Write $$set^%PATCODE("NEWLANGUAGE")
+   1
+
+   If there is no table with that name, the function returns a false (0) and
+   does not modify the current patcode table.
 
-   By default, %RSEL bases the contents of %ZR on source files that have a
-   .m extension.
+   get^%PATCODE
+
+   returns the current patcode table name.
 
    Example:
 
+   GTM>Write $$get^%PATCODE
+   NEWLANGUAGE
 
-   GTM>DO ^%RSEL
+1 Err_Processing
+   Err Processing
 
-   Routine:BEST*
+   This chapter describes GT.M features and techniques for handling errors.
+   Errors in programs may be classified as "predictable" meaning foreseen, or
+   "unpredictable" meaning unforeseen.
 
-   BEST2 BEST3
+   M programs may attempt to recover from predictable errors. Device errors
+   that can be remedied by an operator are the most common class of errors
+   for which recovery provides a large benefit. Predictable errors from which
+   the program does not attempt to recover are generally treated the same as
+   unpredictable errors.
 
-   Current total of 2 routines
+   A typical application handles unpredictable errors by logging as much
+   information about the error as the designer considers useful, then
+   terminating or restarting the application from a known point.
 
-   Routine: <RETURN>
+   Because GT.M invokes error handling when things are not normal, careful
+   design and implementation of error handling are required to minimize the
+   impact of errors and the cost of subsequent prevention.
 
-   GTM>ZWRITE
+   The GT.M compiler detects and reports syntax errors at:
 
-   %ZR=2
+     * Compile time while producing the object module from a source file.
+     * Run time while compiling code for M indirection and XECUTEs.
+     * Run time when the user is working in Direct Mode.
 
-   %ZR("BEST2")="/usr/smith/test/"
+   The GT.M run-time system:
 
-   %ZR("BEST3")="/usr/smith/test/"
+     * Recognizes and reports execution errors when they occur.
+     * Reports errors flagged by the compiler when they fall in the execution
+       path.
 
-   This example creates a %ZR array with BEST2 and BEST3.
+2 Compile_Time
+   Compile Time
 
-   Example:
+   To understand the compile-time error message format, consider this
+   incorrect source line:
 
+   S =B+C
 
-   GTM>DO ^%RSEL
+   If this were line 7 of a source file ADD2.m, the compiler reports the
+   compile-time error with the message:
 
-   Routine:LOCK
+   S =B+C ^-----
 
-   LOCK
+   At column 4, line 7, source module ADD2
+    Variable expected in this context
 
-   Current total of 1 routine
+   The compile-time error message format consists of three lines. The first
+   two lines tell you the line and location where the error occurred. The
+   last line describes the M syntax error. If you requested a listing file,
+   it contains the same information and looks as follows:
 
-   Routine: <RETURN>
+   .
+   .
+   6 .  .  .
+   7 S =B+C
+   ^-----
+    Variable expected in this context
+   8 . . .
+   .
+   .
 
-   GTM>ZWRITE
+2 Process_Compile_Errors
+   Process Compile Errors
+
+   At compile-time, the compiler stops processing a routine line as soon as
+   it detects the first error on that line. By default, the compiler displays
+   the line in error on stderr , and also in a listing file when the compiler
+   options include -list. By default, the compiler processes the remaining
+   source lines until it exceeds the maximum error count of 127.
+
+   The compile-time error message format displays the line containing the
+   error and the location of the error on the line. The error message also
+   indicates what was incorrect about the M statement. For more information
+   on the error message format, refer to the GT.M Message and Recovery
+   Procedures Reference Manual.
+
+   You may correct compile-time errors immediately by activating an editor
+   and entering the correct syntax in the source program. Because several
+   errors may occur on a line, examine the line carefully to avoid compiling
+   the routine several times.
+
+   The MUMPS command qualifier -ignore, which is the default, instructs GT.M
+   to produce an object file even if the compiler detects errors in the
+   source code. As long as the execution path does not encounter the
+   compile-time errors, the GT.M run-time system executes the
+   compiled-as-written routine. You may take advantage of this feature to
+   exercise some parts of your program before correcting errors detected by
+   the compiler.
+
+2 Run-time_Error
+   Run-time Error
+
+   To understand the run-time error message format, consider this short
+   program printsum.m:
+
+   SET A=17
+   GO SET B=21
+   WRITE A+C
+
+   When you try to execute this program, the last statement causes an error
+   since the variable C is undefined. If $ETRAP="B", GT.M displays the
+   run-time error message:
+
+   $ mumps -run printsum
+   %GTM-E-UNDEF, Undefined local variable: C
+   At MUMPS source location GO+1^printsum
+   GTM>
 
-   %ZR=1
+   GT.M informs you of the error (Undefined local variable) and where in the
+   routine the error occurred (GO+1). Note that the run-time system displays
+   the GTM> prompt, indicating that the process has entered Direct Mode. GT.M
+   places run time error information in the intrinsic Special Variable $ECODE
+   and $ZSTATUS.
+
+   Compile-time error messages may appear at run time. This is because errors
+   in indirection and the compile-as-written feature leave errors that are
+   subsequently reported at run time.
+
+   The GT.M utilities use portions of the run-time system and therefore may
+   issue run-time errors as well as their own unique errors.
+
+2 Processing_Run-time
+   Processing Run-time
+
+   GT.M does not detect certain types of errors associated with indirection,
+   the functioning of I/O devices, and program logic until run-time. Also,
+   the compile-as-written feature may leave errors which GT.M reports at
+   run-time when it encounters them in the execution path. At run-time, GT.M
+   reports any error encountered to stderr. The run-time system suspends
+   normal execution of the routine as soon as it detects an error.
+
+   GT.M responds to errors differently depending on whether it encounters
+   them in Direct Mode (at the command line) or during normal program
+   execution.
+
+   When an executing GT.M image encounters an error:
+
+     * if Direct Mode is active at the top of the invocation stack, GT.M
+       stays in Direct Mode.
+     * otherwise, if the error comes from a device that has an EXCEPTION,
+       GT.M executes the EXCEPTION string.
+     * otherwise, if $ETRAP'="" GT.M transfers control to the code defined by
+       $ETRAP as if it had been inserted at the point of the error, unless
+       $ECODE'="", in which case it executes a TROLLBACK:$TLEVEL followed by
+       a QUIT:$QUIT "" QUIT.
+     * otherwise, if $ZTRAP'="" GT.M executes $ZTRAP.
+     * otherwise, GT.M performs a QUIT:$QUIT "" QUIT and reissues the error
+       at the new stack level, if no other error traps ($ETRAP or $ZTRAP) are
+       uncovered by decending the stack, GT.M reports the error on the
+       principal device and terminates the image.
+
+   After the action, if any, invoked by $ETRAP, $ZTRAP or EXCEPTION:
+
+     * if the process ends in Direct Mode - as a result either of performing
+       a BREAK in the executed string or of starting in Direct Mode - GT.M
+       reports the error on the principal device.
+     * otherwise, if the executed string contains an unstacked transfer of
+       control, the only implicit behavior is that as long as $ECODE'="" and
+       $ZTRAP'="" an attempt to QUIT from the level of the current error
+       causes that error to be reissued at the new stack level.
+     * otherwise, if $ETRAP'="" GT.M performs a QUIT$QUIT "" QUIT and
+       reissues the error at the new stack level.
+     * otherwise, $ZTRAP must contain code and GT.M retries the line of M on
+       which the error occurred.
+
+3 Direct_Mode
+   Direct Mode
+
+   When GT.M detects an error in Direct Mode, it reports the error with a
+   message and leaves the process at the GTM> prompt.
+
+   Example:
+
+   GTM>ZW
+   ZW
+   ^_____
+   %GTM-E-INVCMD, Invalid command keyword encountered
+   GTM>
 
-   %ZR("LOCK")="/usr/smith/work/"
+   In Direct Mode, GT.M provides access to the RECALL command. RECALL allows
+   you to retrieve a Direct Mode command line with a minimum of typing. A
+   GT.M line editor allows you to make quick changes or corrections to the
+   command line.
 
-   GTM>DO CALL^%RSEL
+3 Run-time_Errors_Outside_of_Direct_Mode
+   Run-time Errors Outside of Direct Mode
 
-   Routine:BEST*
+   If GT.M encounters an error outside of code entered in Direct Mode, GT.M
+   executes the $ETRAP or $ZTRAP special variable, if either of them have a
+   length greater than zero, which only one can have at a given point in
+   time.
 
-   BEST2 BEST3
+   The $ETRAP and $ZTRAP special variables specifiy an action that GT.M
+   should perform when an error occurs during routine execution. $ETRAP and
+   $ZTRAP can establish one or more error handling "actions".
+
+2 Program_Handling_of_Errors
+   Program Handling of Errors
+
+   GT.M provides the error handling facilities described in the M standard.
+   In addition, GT.M provides a number of extensions for error handling. Both
+   are discussed in the following sections. The following table summarizes
+   some of the tools, which are then described in more detail within the
+   context of various techniques and examples.
+
+   +------------------------------------------------------------------------+
+   |               Summary of GT.M Error-Handling Facilities                |
+   |------------------------------------------------------------------------|
+   |        EXTENSION         |                 EXPLANATION                 |
+   |--------------------------+---------------------------------------------|
+   |                          | Provides a deviceparameter specifying an    |
+   | OPEN/USE/CLOSE EXCEPTION | XECUTE string or entryref that GT.M invokes |
+   |                          | upon encountering a device-related          |
+   |                          | exception condition.                        |
+   |--------------------------+---------------------------------------------|
+   |                          | Creates a listing file of all the errors    |
+   | MUMPS -list ZLINK        | detected by the compiler. Detects syntax    |
+   | :"-list"                 | errors. Useful in the process of re-editing |
+   |                          | program to correct errors.                  |
+   |--------------------------+---------------------------------------------|
+   | ZGoto                    | Provides for removing multiple levels from  |
+   |                          | the M invocation stack.                     |
+   |--------------------------+---------------------------------------------|
+   | ZMESSAGE                 | Creates or emulates arbitrary errors.       |
+   |--------------------------+---------------------------------------------|
+   | $STACK                   | Contains the current level of M execution   |
+   |                          | stack depth.                                |
+   |--------------------------+---------------------------------------------|
+   | $STACK()                 | Returns values describing aspects of the    |
+   |                          | execution environment.                      |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains a list of error codes for "active" |
+   | $ECODE                   | errors; these are the errors that have      |
+   |                          | occurred, but have not yet been cleared.    |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains an integer count of M virtual      |
+   | $ESTACK                  | machine stack levels that have been         |
+   |                          | activated and not removed, since the last   |
+   |                          | time $ESTACK was NEW'd.                     |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains a string value that GT.M invokes   |
+   | $ETRAP                   | when an error occurs during routine         |
+   |                          | execution.                                  |
+   |--------------------------+---------------------------------------------|
+   |                          | Indicates whether the current block of code |
+   | $QUIT                    | was called as an extrinsic function or a    |
+   |                          | subroutine.                                 |
+   |--------------------------+---------------------------------------------|
+   |                          | Holds the value of the status code for the  |
+   | $ZCSTATUS                | last compilation performed by a ZCOMPILE    |
+   |                          | command.                                    |
+   |--------------------------+---------------------------------------------|
+   |                          | Holds the value of the status code for the  |
+   | $ZEDIT                   | last edit session invoked by a ZEDIT        |
+   |                          | command.                                    |
+   |--------------------------+---------------------------------------------|
+   |                          | Holds the value '1' (TRUE) if the last READ |
+   | $ZEOF                    | on the current device reached end-of-file,  |
+   |                          | otherwise holds a '0' (FALSE).              |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains a string supplied by the           |
+   | $ZERROR                  | application, typically one generated by the |
+   |                          | code specified in $ZYERROR.                 |
+   |--------------------------+---------------------------------------------|
+   | $ZLEVEL                  | Contains current level of DO/EXECUTE        |
+   |                          | nesting ($STACK+1).                         |
+   |--------------------------+---------------------------------------------|
+   | $ZMESSAGE()              | Translates a UNIX/GT.M condition code into  |
+   |                          | text form.                                  |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains the error condition code and       |
+   | $ZSTATUS                 | location of last exception condition        |
+   |                          | occurring during routine execution.         |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains an XECUTE string or entryref that  |
+   | $ZTRAP                   | GT.M invokes upon encountering an exception |
+   |                          | condition.                                  |
+   |--------------------------+---------------------------------------------|
+   |                          | Contains an entryref to invoke when an      |
+   | $ZYERROR                 | error occurs; typically used to maintain    |
+   |                          | $ZERROR.                                    |
+   +------------------------------------------------------------------------+
+
+3 $ECODE
+   $ECODE
+
+   The value of $ECODE is a string that may reflect multiple error
+   conditions. As long as no error has occured, the value of $ECODE is equal
+   to the empty string.
+
+   $ECODE contains a list of errors codes for "active" errors - the error
+   conditions which are not yet resolved. If there are no active errors,
+   $ECODE contains the empty string. The value of $ECODE can be SET.
+
+   The most recent error in $ECODE appears first, the oldest last. If the
+   error is defined by the M standard, the code starts with an "M", GT.M
+   error codes including those provided by OS services start with "Z", and
+   application defined codes must start with "U". Every code is separated by
+   a coma (,) and there is always a coma at the beginning and at the end of a
+   list. GT.M provided codes are those reported in $ZSTATUS, interpreted by
+   $ZMESSAGE() and recognized as arguments to ZMESSAGE command. When GT.M
+   supplies a standard error code in $ECODE, it also supplies a corresponding
+   'Z' code.
+
+   Example (setting $ECODE):
+
+   SET $ECODE="" ;sets $ECODE to the empty string
+   SET $ECODE=",M20," ;an ANSI M standardized error code
+   SET $ECODE=",U14," ;user defined error code
+   SET $PIECE($ECODE,",",2)="Z3," ;insert a non-ANSI error code
+   SET $PIECE($ECODE,",",$LENGTH($ECODE,",")+1)="An..," ;append
+
+   Standard Error processing affects the flow of control in the following
+   manner. Detection of an error causes GOTO implicit sub-routine. When
+   $ECODE="", the implicit subroutine is $ETRAP and QUIT:$QUIT "" QUIT.
+   Otherwise the implicit subroutine is $ETRAP followed by TROLLBACK:$TLEVEL
+   and then QUIT:$QUIT "" QUIT.
+
+   The QUIT command behaves in a special fashion while the value of $ECODE is
+   non-empty. If a QUIT command is executed that returns control to a less
+   nested level than the one where the error occurred, and the value of
+   $ECODE is still non-empty, first all normal activity related to the QUIT
+   command occurs (especially the unstacking of NEWed variables) and then the
+   current value of $ETRAP is executed. Note that, if $ETRAP had been NEWed
+   at the current or intervening level, the unstacked value of $ETRAP is
+   executed.
 
-   Current total of 2 routines
+   SETting $ECODE to an invalid value is an error. SETting $ECODE to a valid
+   error behaves like detection of error. SETting $ECODE="" does not cause a
+   change in the flow, but effects $STACK(), subsequent $QUITs and errors.
 
-   Routine: <RETURN>
+   **Note**
 
-   GTM>ZWRITE
+   To force execution of an error trap or to flag a user-defined error ("U"
+   errors), make the value of $ECODE non-empty:
 
-   %ZR=3
+   SET $ECODE=",U13-User defined error trap,"
 
-   %ZR("BEST2")="/usr/smith/work/"
+   **Note**
 
-   %ZR("BEST3")="/usr/smith/work/"
+   The value of $ECODE provides information about errors that have occurred
+   since the last time it was reset to an empty string. In addition to the
+   information in this variable, more detailed information can be obtained
+   from the intrinsic function $STACK. .
 
-   %ZR("LOCK")="/usr/smith/work/"
+3 $ZSTATUS_Content
+   $ZSTATUS Content
 
-   GTM>
+   $ZSTATUS contains a string value specifying the error condition code and
+   location of the last exception condition that occurred during routine
+   execution.
 
-   This example creates a %ZR  array  with  LOCK  and  adds  to  it  using
-   CALL%RSEL.
+3 $ZERROR_and_$ZYERROR
+   $ZERROR and $ZYERROR
 
-2 Internationalization_Util
-   Internationalization Utilities
+   After an error occurs, if $ZYERROR is set to a valid entryref that exists
+   in the current environment, GT.M invokes the routine at that entryref with
+   an implicit DO before returning control to M code specified by $ZTRAP or
+   device EXCEPTION. It is intended that the code invoked by $ZYERROR use the
+   value of $ZSTATUS to select or construct a value to which it SETs $ZERROR.
 
-   The internationalization utilities are:
+   If $ZYERROR is empty, $ZYERROR="unprocessed $ZERROR, see $ZSTATUS".
 
-        %GBLDEF Manipulates the collation sequence assigned to a global.
-        %LCLCOL  Manipulates  the  collation  sequence  assigned  to  local
-        variables in an active process.
-        %PATCODE Loads pattern definition files for use  within  an  active
-        database.
-   These utilities are an integral part of  the  GT.M  functionality  that
-   permits  you  to  customize  your  applications  for  use  with  other
-   languages.  For  a  description  of  these  utilities,  refer  to  the
-   "Internationalization" chapter in GT.M Programmers Guide.
+   If there is a problem with the content of $ZYERROR or if the execution of
+   the code it invokes, GT.M sets $ZERROR=$ZSTATUS for the secondary error
+   and terminates the attempt to use $ZYERROR. During code evoked by
+   $ZYERROR, the value of $ZERROR is the empty string.
 
-2 Sys_Mgmt_Util
-   System Management Utilities
+3 $ETRAP_Behavior
+   $ETRAP Behavior
 
-   The System Management utilities are:
+   If, at the time of any error, the value of $ETRAP is non-empty, GT.M
+   proceeds as if the next instruction to be excuted were the first one on
+   "the next line" and the code on that next line would be the same as the
+   text in the value of $ETRAP. Furthermore, GT.M behaves as if the line
+   following "the next line" looks like:
 
-        %FREECNT Displays the number of free blocks in the  database  files
-        associated with the current global directory.
-3 FREECNT
-   %FREECNT
+   QUIT:$QUIT "" QUIT
 
+   When a value is assigned to $ETRAP, the new value replaces the previous
+   value. If the value of $ZTRAP is a non-empty one, $ZTRAP is implicitly
+   NEWed, and the value of $ZTRAP becomes equal to the empty string; this
+   ensures that at most one of $ETRAP and $ZTRAP is not the empty string.
+
+3 Nesting_$ETRAP_and_using_$ESTACK
+   Nesting $ETRAP and using $ESTACK
+
+   When you need to set up a stratified scheme where one level of subroutines
+   use one error trap setting and another more nested subroutine uses a
+   different one; the more nested subroutine must NEW $ETRAP. When $ETRAP is
+   NEWed, its old value is saved, and its current value is made equal to the
+   empty string. A subsequent SET $ETRAP=<new-value> then establishes the
+   error trapping code for the current execution level.
+
+   The QUIT command that reverts to the calling routine causes the NEWed
+   values to be unstacked, including the one for $ETRAP.
+
+   If an error occurs while executing at the current execution level (or at
+   an execution level farther from the initial base stack frame), the code
+   from the current $ETRAP gets executed. Unless there is a GOTO or ZGOTO,
+   when the execution of that code is complete, control reverts to the
+   implicit QUIT command that returns to the calling routine. At this time,
+   any prior value of $ETRAP is reinstated.
+
+   While at the more nested execution level(s), if an error occurs, the code
+   from the current $ETRAP is executed. After the QUIT to a less nested
+   level, the code from the current $ETRAP gets executed. The current $ETRAP
+   may be different from the $ETRAP at the time of the error due to
+   unstacking. This behavior continues until one of the following possible
+   situations occur:
+
+     * $ECODE is empty. When the value of $ECODE is equal to the empty
+       string, error processing is no longer active, and normal processing
+       resumes.
+     * An execution level is reached where the value of $ETRAP is empty
+       ($ZTRAP might be non-empty at that level). When the values of both
+       $ZTRAP and $ETRAP are equal to the empty string, no error trapping is
+       active and the process repeats.
+     * The stack is reduced to an empty state. When there is no previous
+       level left to QUIT into, GT.M returns to the operating system level
+       shell. A frame that is in direct mode stops the process by putting the
+       user back into the Direct Mode shell.
+
+   When dealing with stratified error trapping, it is important to be aware
+   of two additional intrinsic variables: $STACK and $ESTACK. The values of
+   both of these variables indicate the current execution level. The value of
+   $STACK is an "absolute" value that counts from the start of the GT.M
+   process, whereas the value of $ESTACK restarts at zero (0) each time
+   $ESTACK is NEWed.
+
+   It is often beneficial to NEW both $ETRAP and $ESTACK a the same time.
+
+3 Behavior
+   Behavior
+
+   If, at the time of any error, the value of $ZTRAP is non-empty, GT.M uses
+   the $ZTRAP contents to direct execution of the next action.
+
+   By default, execution proceeds as if the next instruction to be executed
+   were the first one on "the next line", and the code on that next line
+   would be the same as the text in the value of $ZTRAP. Unless there is a
+   GOTO or ZGOTO, after the code in $ZTRAP has been executed, GT.M attempts
+   to execute the line with the error again. When a value is assigned to
+   $ZTRAP, the new value replaces the previous value. If the value of $ETRAP
+   is a non-empty one, $ETRAP is implicitly NEWed, and the value of $ETRAP
+   becomes equal to the empty string; this ensures that at most one of $ETRAP
+   and $ZTRAP is not the empty string. If the environment variable
+   gtm_ztrap_new evaluates to boolean TRUE (case insensitive string "TRUE",
+   or case insensitive string "YES", or a non-zero number), $ZTRAP is NEWed
+   when $ZTRAP is SET; otherwise $ZTRAP is not stacked when it is SET.
+
+   Other than the default behavior, $ZTRAP settings are controlled by the
+   environment variable gtm_ztrap_form as described in the following table.
+
+   +------------------------------------------------------------------------+
+   | gtm_ztrap_form |             $ZTRAP and EXCEPTION Behavior             |
+   |----------------+-------------------------------------------------------|
+   |                | Content is code executed after the error; in the      |
+   | code           | absence of GOTO, ZGOTO, or QUIT, execution resumes at |
+   |                | the beginnig of the line containing the error -       |
+   |                | default behavior                                      |
+   |----------------+-------------------------------------------------------|
+   | entryref       | Content is an entryref to which control is            |
+   |                | transferred by an implicit GOTO                       |
+   |----------------+-------------------------------------------------------|
+   | adaptive       | If content is valid code treat it as described for    |
+   |                | "code", otherwise attempt to treat it as an entryref  |
+   |----------------+-------------------------------------------------------|
+   |                | Content is entryref - remove M virtual stack levels   |
+   | popentryref    | until the level at which $ZTRAP was SET, then GOTO    |
+   |                | the entryref; the stack manipulation occurs only for  |
+   |                | $ZTRAP and not for EXCEPTION                          |
+   |----------------+-------------------------------------------------------|
+   |                | If content is valid code treat it as described for    |
+   | popadaptive    | code, otherwise attempt to treat it as an entryref    |
+   |                | used as described for popentryref                     |
+   +------------------------------------------------------------------------+
+
+   Although the "adaptive" and "popadaptive" behaviors permit mixing of two
+   behaviors based on the current value of $ZTRAP, the $ZTRAP behavior type
+   is selected at process startup from gtm_ztrap_form and cannot be modified
+   during the life of the process.
+
+  Note
+
+   Like $ZTRAP values, invocation of device EXCEPTION values follow the
+   pattern specified by the current gtm_ztrap_form setting.
+
+3 $ETRAP_and_$ZTRAP
+   $ETRAP and $ZTRAP
+
+   The activation of $ETRAP and $ZTRAP are the same, however there are a
+   number of differences in their subsequent behavior.
+
+   For subsequent errors the then current $ZTRAP is invoked, while with
+   $ETRAP, behavior is controlled by the state of $ECODE. This means that
+   when using $ZTRAP, it is important to change $ZTRAP, possibly to the empty
+   string, at the beginning of the action in order to protect against
+   recursion caused by any errors in $ZTRAP itself or in the code it invokes.
+
+   If there is no explicit or implicit GOTO or ZGOTO in the action, once a
+   $ZTRAP action completes, execution resumes at the beginning of the line
+   where the error occurred, while once a $ETRAP action completes, there is
+   an implicit QUIT. This means that $ZTRAP actions that are not intended to
+   permit a successful retry of the failing code should contain a GOTO, or
+   more typically a ZGOTO. In contrast, $ETRAP actions that are intended to
+   cause a retry must explicitly reinvoke the code where the error occurred.
+
+   For QUITs from the level at which an error occurred, $ZTRAP has no effect,
+   where $ETRAP behavior is controlled by the state of $ECODE. This means
+   that to invoke an error handler nested at the lower level, $ZTRAP actions
+   need to use an explicit ZMESSAGE command, while $ETRAP does such
+   invocations implicitly unless $ECODE is SET to the empty string.
+
+3 $ZTRAP_With_$ETRAP
+   $ZTRAP With $ETRAP
+
+   It is important to be aware of which of the trap mechanisms is in place to
+   avoid unintended interactions, and aware of which conditions may cause a
+   switch-over from one mode of error handling to the other.
+
+   Whenever a SET command is executed that assigns a value to either $ZTRAP
+   or $ETRAP, the value of the other error handling variable is examined. If
+   the other value is non-empty, an implicit NEW command is executed that
+   saves the current value of that variable, and then the value of that
+   variable is set to the empty string. After this, the requested assignment
+   is made effective.
+
+   For example, re-setting $ETRAP is internally processed as:
+
+   NEW:$LENGTH($ZTRAP) $ZTRAP SET $ETRAP=code
+
+   Whereas, SET $ZTRAP=value is internally processed as:
+
+   NEW:$LENGTH($ETRAP) $ETRAP SET $ZTRAP=value
+
+   Note that NEW of $ETRAP or $ZTRAP implicitly sets the value of the empty
+   string after saving the prior value. As a result, at most one of the two
+   error handling machanisms can be effective at any given point in time.
+
+   If an error handling procedure was invoked through the $ETRAP method, and
+   the value of $ECODE is non-empty when QUITing from the level of which the
+   error occurred, the behavior is to transfer control to the error handler
+   associated with the newly unstacked level. However, if the QUIT command at
+   the end of error level happens to unstack a saved value of $ZTRAP (and
+   thus cause the value of $ETRAP to become empty), the error handling
+   mechanism switches from $ETRAP-based to $ZTRAP-based.
+
+   **Note**
+
+   At the end of an error handling procedure invoked through $ZTRAP, the
+   value of $ECODE is not examined, and this value (if any) does not cause
+   any transfer to another error handling procedure. However, if not cleared
+   it may later trigger a $ETRAP unstacked by a QUIT.
+
+3 $ETRAP_or_$ZTRAP
+   $ETRAP or $ZTRAP
+
+   Making a choice between the two mechanisms for error handling is mostly a
+   matter of compatibility. If compatibility with existing GT.M code is
+   important, and that code happens to use $ZTRAP, then $ZTRAP is the best
+   effort choice. If compatibility with code written in MUMPS dialects from
+   other vendors is important, then $ETRAP or a non-default form of $ZTRAP
+   probably is the better choice.
+
+   When no pre-existing code exists that favors one mechanism, the features
+   of the mechanisms themselves should be examined.
+
+   Almost any effect that can be achieved using one mechanism can also be
+   achieved using the other. However, some effects are easier to achieve
+   using one method, and some are easier using with the other.
+
+   If the mechanisms are mixed, or there is a desire to refer to $ECODE in an
+   environment using $ZTRAP, it is recommended to have $ZTRAP error code SET
+   $ECODE="" at some appropriate time, so that $ECODE does not become
+   cluttered with errors that have been successfully handled.
+
+   **Note**
+
+   A device EXCEPTION gets control after a non-fatal device error and
+   $ETRAP/$ZTRAP get control after other non-fatal errors.
+
+3 IO_Errors
+   IO Errors
+
+   When GT.M encounters an error in the operation of an I/O device, GT.M
+   executes the EXCEPTION deviceparameter for the OPEN/USE/CLOSE commands. An
+   EXCEPTION deviceparameter specifies an action to take when an error occurs
+   in the operation of an I/O device. The form of the EXCEPTION action is
+   subject to the gtm_ztrap_form setting described for $ZTRAP, except that
+   there is never any implicit popping with EXCEPTION actions. If a device
+   has no current EXCEPTION, GT.M uses $ETRAP or $ZTRAP to handle an error
+   from that device.
+
+   GT.M provides the option to:
+
+     * Trap or process an exception based on device error.
+     * Trap or process an exception based on terminal input.
+
+   An EXCEPTION based on an error for the device applies only to that device,
+   and provides a specific error handler for a specific I/O device.
+
+   The CTRAP deviceparameter for USE establishes a set of trap characters for
+   terminal input. When GT.M encounters an input character in that set, GT.M
+   executes the EXCEPTION deviceparamenter, or, $ETRAP or $ZTRAP if the
+   device has no current EXCEPTION.
+
+   Example:
+
+   GTM>ZPRINT ^EP12
+   EP12    WRITE !,"THIS IS ",$TEXT(+0)
+           SET $ECODE="";this only affects $ETRAP
+           SET $ETRAP="GOTO ET"
+           ;N $ZT S $ZT="W !,"CAN'T TAKE RECIPROCAL OF 0"",*7"
+           USE $P:(EXCEPTION="D BYE":CTRAP=$C(3))
+           WRITE !,"TYPE <CTRL-C> TO STOP"
+   LOOP    FOR DO
+           . READ !,"TYPE A NUMBER: ",X
+           . WRITE ?20,"HAS RECIPROCAL OF: ",1/X
+           . QUIT
+   ET      . WRITE !,"CAN'T TAKE RECIRPOCAL OF 0",*7
+           . SET $ECODE=""
+           QUIT
+   BYE     WRITE !,"YOU TYPED <CTRL-C> YOU MUST BE DONE!"
+           USE $P:(EXCEPTION="":CTRAP="")
+           WRITE !,"$ZSTATUS=",$ZSTATUS
+           ZGOTO 1
+   GTM>DO ^EP12
+   THIS IS EP12
+   TYPE <CTRL-C> TO STOP
+   TYPE A NUMBER: 1 HAS RECIPROCAL OF: 1
+   TYPE A NUMBER: 2 HAS RECIRPOCAL OF: .5
+   TYPE A NUMBER: 3 HAS RECIPROCAL OF: .33333333333333
+   TYPE A NUMBER: 4 HAS RECIPROCAL OF: .25
+   TYPE A NUMBER: HAS RECIPROCAL OF:
+   CAN'T TAKE RECIPROCAL OF 0
+   TYPE A NUMBER:
+   YOU TYPED <CTRL-C> YOU MUST BE DONE!
+   $ZSTATUS=150372498,LOOP+1^EP12,%GTM-E-CTRAP,Character trap $C(3) encountered
+   GTM>
 
-   The %FREECNT utility displays the number of free blocks in the database
-   files associated with the current global directory.
+   This routine prompts the user to enter a number at the terminal. If the
+   user enters a zero, GT.M encounters an error and executes $ETRAP (or
+   $ZTRAP). The action specified reports the error and returns to prompt the
+   user to enter a number. With $ZTRAP, this is very straightforward. With
+   $ETRAP, some care is required to get the code to resume at the proper
+   place. The CTRAP deviceparameter establishes <CTRL-C> as a trap character.
+   When GT.M encounters a <CTRL-C>, GT.M executes the EXCEPTION string whcih
+   transfers control to the label BYE. At the label BYE, the routine
+   terminates execution with an error message. Using the EXCEPTION
+   deviceparameter with CTRAP generally simplifies $ETRAP or $ZTRAP handling.
+
+   $ZSTATUS allows the routine to find out which trap character GT.M
+   encountered. When a routine has several character traps set, $ZSTATUS
+   provides useful information for identifying which character triggered the
+   trap, and thereby allows a custom response to a specific input.
+
+1 Triggers
+   Triggers
+
+2 Overview
+   Overview
+
+   GT.M allows you to set up a trigger mechanism that automatically executes
+   a defined action in response to a database update operation on a matching
+   global node.The trigger mechanism executes a fragment of M code (trigger
+   code) "before" or "as part of" a database update. You can define the
+   specifications of this mechanism in a Trigger Definition File. For a
+   trigger on KILL (and ZKILL), GT.M executes trigger code "before" the KILL
+   operation. For example, a trigger on KILL ^CIF(:,1) might clear old cross
+   references. For a trigger on SET, GT.M executes trigger code "as part of"
+   the SET operation. Within trigger logic, the ISV $ZTOLDVAL provides read
+   access to the value of global node prior to the update and $ZTVALUE
+   provides read/write access to the tentative SET value. This allows you to
+   modify the tentative SET value before GT.M commits it to the database. The
+   term "as part of" means that SET triggers execute intertwined with the SET
+   operation. Although it is not yet committed the database, the tentative
+   new value appears to the process as assigned but the process must SET
+   $ZTVALUE to make any revision to the tentative value, because a SET of the
+   global node would nest the trigger recursively - a pathological condition.
+   GT.M executes SET triggers during a MERGE update where GT.M internally
+   performs a series of SET operations and while performing a $INCREMENT()
+   operation where GT.M internally performs a SET operation.For all triggers,
+   GT.M handles the database update event and the triggered actions as an
+   Atomic (all or nothing) transaction.
+
+   Triggers meet many application needs including (but not limited to) the
+   following:
+
+    1. Enforce schema-level consistency: Since database schema created in a
+       normal M application are implicit, M applications implement logic to
+       maintain and enforce conformance with an application schema. Using
+       triggers to enforce schema-level consistency ensures all processes
+       invoke the code uniformly, and increases code modularity and
+       maintainability.
+    2. Allow an application to maintain one or more non-primary key indexes.
+       For example, a trigger on updates to global nodes containing a
+       customer id can maintain an index on the last name.
+    3. Implement business logic: For example, an update to an account could
+       automatically trigger updates to related accounts.
+    4. Reducing replication traffic: Since the GT.M replication stream
+       carries only the triggering updates, not the triggered updates,
+       triggers reduce network traffic.
+    5. Automate application defined logging or journaling of updates or
+       maintaining historical records. Triggers can be used to control these.
+    6. Implement referential integrity: For example, a trigger can prevent
+       the posting of a bank transaction for an inactive account and display
+       a rule violation message.
+    7. Debugging: Debugging an application with multiple concurrent accesses
+       is hard. You can use triggers to establish "watch points" on global
+       variable updates to trap incorrect accesses. For example, if an
+       application is failing because certain global variable nodes either
+       have incorrect values or when previously set values disappear. A
+       trigger can be used to trap all such accesses.
+    8. Implement a dataflow based programming paradigm. Although not a
+       primary goal of the implementation of triggers, you can use them to
+       implement applications that use a dataflow programming paradigm.
+
+2 Trigger_Definition
+   Trigger Definition
+
+   A trigger definition file is a text file used for adding new triggers,
+   modifying existing triggers, or removing obsolete triggers. A trigger
+   definition file consists of one or more trigger definitions. A trigger
+   definition includes the following information:
+
+     * Trigger signature: A trigger signature consists of global variable,
+       subscripts, value, command, and trigger code. GT.M uses a combination
+       of global variable, subscripts, value, and command to find the
+       matching trigger to invoke for a database update.
+
+         1. Global Variable: The name of a specific global to which this
+            trigger applies.
+         2. Subscripts: Subscripts for global variable nodes of the named
+            global, specified using the same patterns as the ZWRITE command.
+         3. Value: For commands that SET or update the value at a node, GT.M
+            honors an optional pattern to screen for changes to delimited
+            parts of the value. A value pattern includes a piece separator
+            and a list of pieces of interest.
+         4. Command: There are four commands: SET, KILL, ZTRIGGER, and ZKILL
+            (ZWITHDRAW is identical to ZKILL) the shorter name for the
+            command is used when specifying triggers. MERGE is logically
+            treated as equivalent to a series of SET operations performed in
+            a loop. GT.M handles $INCREMENT() of a global matching a SET
+            trigger definition as a triggering update.
+         5. Trigger code: A string containing M code that GT.M executes when
+            application code updates, including deletions by KILL and like
+            commands, a global node with a matching trigger. The specified
+            code can invoke additional routines and subroutines.
+
+   **Note**
+
+            While GT.M does not restrict trigger code from performing I/O
+            operations, FIS recommends against using OPEN, USE, READ, WRITE
+            and CLOSE within trigger application code. Such operations may be
+            useful for development and diagnostic purposes. However, triggers
+            implicitly run as TP transactions and I/O violates the ACID
+            property of Isolation. In addition, MUPIP has somewhat different
+            I/O handling characteristics than the main GT.M run-time, so I/O
+            within triggers run by MUPIP may behave differently than within
+            the originating application environment.
+
+     * ACID property modifiers for triggered database updates: Currently,
+       GT.M merely performs a syntax check on this part of a trigger
+       definition. GT.M ensures the triggering database update, and any
+       updates generated by trigger logic executed with transaction
+       semantics. With the VIEW "NOISOLATION" command, GT.M transaction
+       processing has long provided a mechanism for an application to inform
+       the GT.M runtime system that it need not enforce Isolation. In such a
+       case, the application and schema design provides Isolation by ensuring
+       only one process ever updates nodes in a particular global at any
+       given time, say by using $JOB as a subscript. This property
+       anticipates a time when a trigger specification can provide
+       NOISOLATION for particular nodes, in contrast to entire globals, and
+       for every update to that node, in contrast to by process use of a VIEW
+       command. Currently, the GT.M runtime system enforces Consistency for
+       application logic inside a transaction and for triggered updates. This
+       property anticipates a time when a trigger specification permits an
+       application to inform the runtime system the application and schema
+       design ensures appropriate Consistency for a trigger and its logic,
+       thus relieving the GT.M runtime system from that task.
+     * Trigger Name: You can optionally specify a trigger name that uniquely
+       identifies each trigger. GT.M uses a trigger name for error reporting
+       and configuration management of triggers - for example, a ZSHOW "S"
+       reports the name of each trigger on the stack. If you do not specify a
+       trigger name, GT.M automatically generates one using the global name
+       as a base. Both user-specified trigger name and automatically
+       generated trigger names occupy different name space and last for the
+       life of the definition. A user-specified trigger name is an
+       alphanumeric string of up to 28 characters. It must start with an
+       alphabetic character or a percent sign (%). For a trigger name, GT.M
+       uses the same naming convention as an M name. In other contexts, GT.M
+       truncates M names at 31 characters. However, GT.M treats a trigger
+       name of over 28 characters as an error. This is because a trigger name
+       uniquely identifies a trigger and truncation may cause duplication.
+
+   An automatically generated trigger name is a string comprised of two
+   parts. Using the global name as a base, GT.M takes the first part as an
+   alphanumeric string of up to 21 characters starting with an alphabetic
+   character or a percent sign (%). The trailing part consists of an
+   automatically incremented number in the form of #n# where n is a whole
+   number that monotonically increases from 1 to 9999999 that uniquely
+   identifies a trigger for the same update. For example, if no trigger names
+   are specified in the trigger definition file, GT.M automatically generates
+   trigger names Account#1#, Account#2#, and Account#3# for the first three
+   triggers defined for global variable ^Account. An attempt to use automatic
+   assignment for more than a million triggers produces an error. Once the
+   numeric portion of the auto generated names reaches 999999, you must
+   reload all triggers associated with the global variables that use the auto
+   generated name space. At run-time GT.M generates a trailing suffix of a
+   hash-sign (#) followed by up to two characters to ensure that every
+   trigger has a unique designation, even when the environment is complex.
+   The run-time suffix applies to both user-specified and automatically
+   generated trigger names. It helps in differentiating triggers in different
+   database files with the same name.
+
+   To apply this trigger definition file to GT.M, all you do is to load it
+   using MUPIP TRIGGER -TRIGGERFILE or $ZTRIGGER(). GT.M would invoke trigger
+   name TrigAcct on every SET operation on ^Acct("ID"). Internally, GT.M
+   stores trigger TrigAcct in the same database file where ^Acct is stored.
+   The syntax of an entry in a trigger definition file is:
+
+   {-triggername|-triggername-prefix*|-*|{+|-}trigvn -commands=cmd[,...]
+   -xecute=strlit1 [-[z]delim=expr][-pieces=[lvn=]int1[:int2][;...]]
+   [-options={[no]i[solation]|[no]c[onsistencycheck]}...] [-name=strlit2]}
+
+2 Semantics
+   Semantics
+
+   GT.M stores Triggers for each global variable in the database file for
+   that global variable. When a global directory maps a global variable to
+   its database file, it also maps triggers for that global variable to the
+   same database file. When an extended reference uses a different global
+   directory to map a global variable to a database file, that global
+   directory also maps triggers for that global variable to that same
+   database file.
+
+   Although triggers for SET and KILL / ZKILL commands can be specified
+   together, the command invoking a trigger is always unique. The ISV
+   $ZTRIGGEROP provides the trigger code which matched the triggering
+   command.
 
+   Whenever a command updates a global variable, the GT.M runtime system
+   first determines whether there are any triggers for that global variable.
+   If there are any triggers, it scans the signatures for subscripts and node
+   values to identify matching triggers. If multiple triggers match, GT.M
+   invokes them in an arbitrary order. Since a future version of GT.M,
+   potentially multi-threaded, may well choose to execute multiple triggers
+   in parallel, you should ensure that when a node has multiple triggers,
+   they are coded so that correct application behavior does not rely on the
+   order in which they execute.
+
+   When a process executes a KILL, ZKILL or SET command, the target is the
+   global variable node specified by the command argument for modification.
+   With SET and ZKILL, the target is a single node. In the case of KILL, the
+   target may represent an entire sub-tree of nodes. GT.M only matches the
+   trigger against the target node, and only invokes the trigger once for
+   each KILL command. GT.M does not check nodes in sub-trees to see whether
+   they have matching triggers.
 
diff --git a/sr_port/mupint.h b/sr_port/mupint.h
index 9c7f522..8f56bca 100644
--- a/sr_port/mupint.h
+++ b/sr_port/mupint.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -14,6 +14,10 @@
 
 /*  requires gdsroot.h */
 
+#define	MUINTKEY_FALSE		0 /* -subscript was NOT specified as part of mupip integ */
+#define	MUINTKEY_TRUE		1 /* -subscript was specified as part of mupip integ */
+#define	MUINTKEY_NULLSUBS	2 /* -subscript was specified as part of mupip integ AND there was at least one null subscript */
+
 #define	NO_ONLINE_ERR_MSG	"ONLINE qualifier for this region will be ignored"
 
 typedef	struct global_list_struct
diff --git a/sr_port/mupip.hlp b/sr_port/mupip.hlp
index 906036f..29749d4 100644
--- a/sr_port/mupip.hlp
+++ b/sr_port/mupip.hlp
@@ -43,8 +43,7 @@
    The environment variable gtmgbldir specifies the active global directory.
 
    A gtmgbldir value of mumps.gld tells MUPIP to look for a global directory
-   file mumps.gld in the current directory. See the "Global Directory Editor"
-   chapter for more information on the global directory.
+   file mumps.gld in the current directory.
 
 2 Operations
    Operations
@@ -64,93 +63,7 @@
    require database access, but may require other privileges; EXTRACT, which
    requires read access; and INTEG, which may require write access, depending
    on the circumstances it encounters and the qualifiers with which it is
-   invoked. The following table displays some of the MUPIP operations and
-   their database access requirements.
-
-   +------------------------------------------------------------------------+
-   |       Operations       | MUPIP command | Database Access Requirements  |
-   |------------------------+---------------+-------------------------------|
-   |                        |               | Backup never requires         |
-   | Backup database files  | MUPIP BACKUP  | standalone access and         |
-   |                        |               | concurrent write access is    |
-   |                        |               | controlled by -[NO]ONLINE.    |
-   |------------------------+---------------+-------------------------------|
-   | Create and initialize  | MUPIP CREATE  | Standalone access             |
-   | database files         |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Converts a database    |               |                               |
-   | file from one endian   | MUPIP         |                               |
-   | format to the other    | ENDIANCVT     | Standalone access             |
-   | (BIG to LITTLE or      |               |                               |
-   | LITTLE to BIG)         |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Recover database files |               |                               |
-   | (for example, after a  |               |                               |
-   | system crash) and      | MUPIP JOURNAL | Standalone access             |
-   | extract journal        |               |                               |
-   | records                |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Restore databases from |               |                               |
-   | bytestream backup      | MUPIP RESTORE | Standalone access             |
-   | files                  |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Properly close         |               |                               |
-   | database files when    | MUPIP RUNDOWN | Standalone access             |
-   | processes terminate    |               |                               |
-   | abnormally.            |               |                               |
-   |------------------------+---------------+-------------------------------|
-   |                        |               | Standalone access is required |
-   |                        |               | if the MUPIP SET command      |
-   | Modify database and/or |               | specifies -ACCESS_METHOD,     |
-   | journal file           | MUPIP SET     | -GLOBAL_BUFFERS, LOCK_SPACE   |
-   | characteristics        |               | or -NOJOURNAL, or if any of   |
-   |                        |               | the -JOURNAL options ENABLE,  |
-   |                        |               | DISABLE, or BUFFER_SIZE are   |
-   |                        |               | specified.                    |
-   |------------------------+---------------+-------------------------------|
-   | Backup database files  | MUPIP BACKUP  | Concurrent access.            |
-   |------------------------+---------------+-------------------------------|
-   | Grow the size of BG    | MUPIP EXTEND  | Concurrent access.            |
-   | database files         |               |                               |
-   |------------------------+---------------+-------------------------------|
-   |                        |               | Although MUPIP EXTRACT        |
-   |                        |               | command works with concurrent |
-   | Export data from       |               | access, it implicitly freezes |
-   | database files into    |               | the database to prevent       |
-   | sequential (flat) or   | MUPIP EXTRACT | updates. Therefore, from an   |
-   | binary files           |               | application standpoint, you   |
-   |                        |               | might plan for a standalone   |
-   |                        |               | access during a MUPIP EXTRACT |
-   |                        |               | operation.                    |
-   |------------------------+---------------+-------------------------------|
-   | Prevent updates to     | MUPIP FREEZE  | Standalone access.            |
-   | database files         |               |                               |
-   |------------------------+---------------+-------------------------------|
-   |                        |               | Concurrent access. However,   |
-   | Check the integrity of | MUPIP INTEG   | standalone access is required |
-   | GDS databases          |               | if MUPIP INTEG specifies      |
-   |                        |               | -FILE.                        |
-   |------------------------+---------------+-------------------------------|
-   |                        |               | Although MUPIP LOAD works     |
-   |                        |               | with concurrent access, you   |
-   |                        |               | should always assess the      |
-   | Import data into       |               | significance of performing a  |
-   | databases              | MUPIP LOAD    | MUPIP LOAD operation when an  |
-   |                        |               | application is running        |
-   |                        |               | because it may result in an   |
-   |                        |               | inconsistent application      |
-   |                        |               | state for the database.       |
-   |------------------------+---------------+-------------------------------|
-   | Defragment database    |               |                               |
-   | files to improve       | MUPIP REORG   | Concurrent access.            |
-   | performance            |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Send an asynchronous   |               |                               |
-   | signal to a GT.M       | MUPIP INTRPT  | Non-database access.          |
-   | process                |               |                               |
-   |------------------------+---------------+-------------------------------|
-   | Stop GT.M processes    | MUPIP STOP    | Non-database access.          |
-   +------------------------------------------------------------------------+
+   invoked.
 
 2 Syntax
    Syntax
@@ -173,7 +86,7 @@
    the full format of the command is too long for a single line of print, the
    presentation wraps around into additional lines.
 
-   mupip backup -bytestream -transaction=1 accounts,history,tables,miscellaneous /var/production/backup/
+   $ mupip backup -bytestream -transaction=1 accounts,history,tables,miscellaneous /var/production/backup/
 
    When you enter a MUPIP command, one of its variable arguments is the
    region-list. region-list identify the target of the command and may
@@ -190,7 +103,7 @@
 1 GDM
    GDM
 
-   The MUPIP commands described in this seciton are used for common database
+   The MUPIP commands described in this section are used for common database
    operations and serves as the foundation for more advanced functionality
    like Journaling and Replication.
 
@@ -284,23 +197,23 @@
 
    Perform the following tasks before you begin a database backup.
 
-     o Ensure adequate disk space for target location and temporary files.
+     * Ensure adequate disk space for target location and temporary files.
        Set the environment variable gtm_baktmpdir to specify the directory
        where MUPIP BACKUP creates temporary files. If gtm_baktmpdir is not
        defined, GT.M uses the deprecated GTM_BAKTMPDIR environment variable
        if defined, and otherwise uses the current working directory. Do not
        place temporary files in the current directory for large databases in
        production environments.
-     o When using replication, ensure that the Source/Receiver process is
+     * When using replication, ensure that the Source/Receiver process is
        alive (MUPIP REPLIC -SOURCE/-RECEIVER -CHECKHEALTH). Always backup the
        replicating instance file with the database (BACKUP -REPLINST).
-     o If you intend to use a -DATABASE backup at the same time in the same
+     * If you intend to use a -DATABASE backup at the same time in the same
        computer system as the source database, be sure to disable journaling
        in the backed up database with -BKUPDBJNL=DISABLE.
-     o When doing a complete backup, switch journal files as part of the
+     * When doing a complete backup, switch journal files as part of the
        backup command using -NEWJNLFILES=NOPREVLINK. This aligns the journal
        files with the backup and simplifies journal file retention.
-     o If you follow separate procedures for backup and archive (moving to
+     * If you follow separate procedures for backup and archive (moving to
        secondary storage), you can save time by starting archive as soon as
        MUPIP BACKUP completes the process of creating a backup database file
        for a region. You do not need to wait for MUPIP BACKUP to complete
@@ -312,12 +225,12 @@
 
        confirms that gtm.dat is backed up correctly and is ready for archive.
 
-     o Determine an appropriate frequency, timing, and backup method
+     * Determine an appropriate frequency, timing, and backup method
        (-BYTESTREAM or -COMPREHENSIVE) based on the situation.
-     o Ensure the user issuing backup commands has appropriate permissions
-       before starting the backup. Backup files hav e the ownership of the
+     * Ensure the user issuing backup commands has appropriate permissions
+       before starting the backup. Backup files have the ownership of the
        user running MUPIP BACKUP.
-     o There is one circumstance under which a MUPIP BACKUP is not advised.
+     * There is one circumstance under which a MUPIP BACKUP is not advised.
        When your operational procedures call for taking backups of unmodified
        databases and journal files on rebooting a system after a crash, then
        use an underlying operating system command (cp, cpio, gzip, tar, and
@@ -431,11 +344,11 @@
 
      o -NEWJNLFILES can take the following three values:
 
-          o PREVLINK: Back links new journal files with the prior generation
+         1. PREVLINK: Back links new journal files with the prior generation
             journal files. This is the default value.
-          o NOPREVLINK: Indicates that there should be no back link between
+         2. NOPREVLINK: Indicates that there should be no back link between
             the newly created journals and prior generation journal files.
-          o SYNC_IO: Specifies that every WRITE to a journal file to be
+         3. SYNC_IO: Specifies that every WRITE to a journal file to be
             committed directly to disk. On high-end disk subsystems (for
             example, those that include non-volatile cache and that consider
             the data to be committed when it reaches this cache), this might
@@ -533,17 +446,14 @@
 
    -S[INCE]={DATABASE|BYTESTREAM|RECORD}
 
-     o keyword can include any one of the following:
+     * D[ATABASE] - Backup all changes since the last MUPIP BACKUP -DATABASE.
+     * B[YTESTREAM] - Backup all changes since the last MUPIP BACKUP
+       -BYTESTREAM.
+     * R[ECORD] - Backup all changes since the last MUPIP BACKUP -RECORD.
 
-          o D[ATABASE] - Backup all changes since the last MUPIP BACKUP
-            -DATABASE.
-          o B[YTESTREAM] - Backup all changes since the last MUPIP BACKUP
-            -BYTESTREAM.
-          o R[ECORD] - Backup all changes since the last MUPIP BACKUP
-            -RECORD.
+   By default, MUPIP BACKUP -BYTESTREAM operates as -SINCE=DATABASE.
 
-     o By default, MUPIP BACKUP -BYTESTREAM operates as -SINCE=DATABASE.
-     o Incompatible with: -TRANSACTION.
+   Incompatible with: -TRANSACTION.
 
 3 Transaction
    Transaction
@@ -931,10 +841,6 @@
 
    Magnetic tapes may have a smaller maximum file size than disks.
 
-   For information on extracting globals with the %GO utility, refer to "M
-   Utility Routines" chapter of the GT.M Programmer's Guide. MUPIP EXTRACT is
-   typically faster, but %GO can be customized.
-
    The following sections describe the qualifiers of MUPIP EXTRACT command.
 
 3 FOrmat
@@ -947,7 +853,7 @@
 
    The format code is any one of the following:
 
-     o B[INARY] - Binary format, used for database reorganization or short
+    1. B[INARY] - Binary format, used for database reorganization or short
        term backups. MUPIP EXTRACT -FORMAT=BINARY works much faster than
        MUPIP EXTRACT -FORMAT=GO and MUPIP EXTRACT -FORMAT=ZWR. Note: There is
        no defined standard to transport binary data from one GT.M
@@ -983,12 +889,12 @@
        |            | EXTRACT"                                              |
        +--------------------------------------------------------------------+
 
-     o GO - Global Output format, used for files to transport or archive.
+    2. GO - Global Output format, used for files to transport or archive.
        -FORMAT=GO stores the data in record pairs. Each global node produces
        one record for the key and one for the data. MUPIP EXTRACT -FORMAT=GO
        has two header records - the first is a test label (refer to the LABEL
        qualifier) and the second contains a data, and time.
-     o ZWR - ZWRITE format, used for files to transport or archive that may
+    3. ZWR - ZWRITE format, used for files to transport or archive that may
        contain non-graphical information. Each global node produces one
        record with both key and data. MUPIP EXTRACT -FORMAT=ZWR has two
        header records, which are the same as for FORMAT=GO, except that the
@@ -1197,8 +1103,8 @@
 
    Incompatible with: -OFF, -OVERRIDE
 
-3 OVERRIDE
-   OVERRIDE
+3 OVerride
+   OVerride
 
    Release a freeze set by a process with a different userid. GT.M provides
    OVERRIDE to allow error recovery in case a procedure with a freeze fails
@@ -1317,13 +1223,13 @@
 
    Always use MUPIP INTEG in the following conditions:
 
-     o Periodically - to ensure ongoing integrity of the database(s); regular
+     * Periodically - to ensure ongoing integrity of the database(s); regular
        INTEGs help detect any integrity problems before they spread and
        extensively damage the database file.
-     o After a crash - to ensure the database was not corrupted. (Note: When
+     * After a crash - to ensure the database was not corrupted. (Note: When
        using before-image journaling, when the database is recovered from the
        journal file after a crash, an integ is not required).
-     o When database errors are reported - to troubleshoot the problem.
+     * When database errors are reported - to troubleshoot the problem.
 
    Improving the logical and physical adjacency of global nodes may result in
    faster disk I/O. A global node is logically adjacent when it is stored
@@ -1384,18 +1290,18 @@
    database integrity. If operations continue without fixes to serious
    errors, the following problems may occur:
 
-     o Invalid application operation due to missing or incorrect data.
-     o Process errors, including inappropriate indefinite looping, when a
+     * Invalid application operation due to missing or incorrect data.
+     * Process errors, including inappropriate indefinite looping, when a
        database access encounters an error.
-     o Degrading application level consistency as a result of incomplete
+     * Degrading application level consistency as a result of incomplete
        update sequences caused by the prior symptoms.
 
    FIS strongly recommends fixing the following errors as soon as they are
    discovered:
 
-     o Blocks incorrectly marked free - these may cause accelerating damage
+     * Blocks incorrectly marked free - these may cause accelerating damage
        when processes make updates to any part of the database region.
-     o Integrity errors in an index block - these may cause accelerating
+     * Integrity errors in an index block - these may cause accelerating
        damage when processes make updates to that area of the database region
        using the faulty index.
 
@@ -1554,8 +1460,8 @@
 
    -[NO]MAX[KEYSIZE][=integer]
 
-     o By default, INTEG reports a maximum of 10 key size errors (-
-       MAXKEYSIZE=10).
+     o By default, INTEG reports a maximum of 10 key size errors
+       (-MAXKEYSIZE=10).
      o -NOMAXKEYSIZE removes limits on key size reporting so that INTEG
        reports all key size too large errors.
      o -NOMAXKEYSIZE does not accept assignment of an argument.
@@ -1617,15 +1523,15 @@
        immediately terminates. If an online integ does not successfully
        complete, GT.M cleans it up in one of the following ways:
 
-          o A subsequent online integ detects that an earlier one did not
+         1. A subsequent online integ detects that an earlier one did not
             successfully complete and releases the resources held by the
             prior online integ before proceeding.
-          o If a MUPIP STOP was issued to the online integ process, the
+         2. If a MUPIP STOP was issued to the online integ process, the
             process cleans up any resources it held. Note: since the process
             was stopped the results of the integ may not be valid.
-          o subsequent MUPIP RUNDOWN ensures the release of resources held by
+         3. subsequent MUPIP RUNDOWN ensures the release of resources held by
             prior unsuccessful online integs for the specified regions.
-          o For every 64K transactions after the online integ initiation,
+         4. For every 64K transactions after the online integ initiation,
             online integ checks GT.M health for improperly abandoned online
             integs and releases resources held by any it finds.
 
@@ -2187,7 +2093,7 @@
 
    No errors detected by integ.
 
-   Type            Blocks         Records          % Used      Adjacent
+   Type           Blocks         Records          % Used      Adjacent
 
    Directory           2               2           2.490            NA
    Index             153            3902          29.211            57
@@ -2771,7 +2677,7 @@
 
    $ mupip set -version=V4 -file mumps.dat
 
-   Database file mumps.dat now has d esired DB format V4
+   Database file mumps.dat now has desired DB format V4
 
    This example sets the block format to V4 for all subsequent new blocks in
    V6 database file mumps.dat.
@@ -2829,7 +2735,7 @@
 
    estimation-technique is one of the following:
 
-     o scan,level=<lvl>
+     * scan,level=<lvl>
 
        Traverses the global variable tree and counts the actual number of
        records and blocks at levels from the root down to the level specified
@@ -2840,19 +2746,19 @@
        a negative level from the root of the global tree where -1 means
        children of the root.
 
-     o arsample,samples=<smpls>
+     * arsample,samples=<smpls>
 
        Uses acceptance/rejection sampling of random tree traversals to
        estimate the number of blocks at each level. It continues until the
        specified number of samples (default is 1,000) is accepted.
 
-     o impsample,samples=<smpls>
+     * impsample,samples=<smpls>
 
        Uses importance sampling of random tree traversals to weight each
        sample of the specified number of samples (default is 1,000) in order
        to estimate size of the tree at each level.
 
-     o If -HEURISTIC is not specified, MUPIP SIZE uses the
+     * If -HEURISTIC is not specified, MUPIP SIZE uses the
        ARSAMPLE,SAMPLE=1000 estimation technique.
 
    **Important**
@@ -2874,12 +2780,12 @@
 
    global-name-list can be:
 
-     o A comma separated list of global variables.
-     o A range of global variables denoted by start:end syntax. For example,
+     * A comma separated list of global variables.
+     * A range of global variables denoted by start:end syntax. For example,
        -select="g1:g4".
-     o A global variable with wildcards, for example, "g*" (the name must be
+     * A global variable with wildcards, for example, "g*" (the name must be
        escaped to avoid shell filename expansion)
-     o "*" to select all global variables.
+     * "*" to select all global variables.
 
    -Region
 
@@ -3380,7 +3286,7 @@
      o Whenever MUPIP SET creates a new journal file, it uses all values for
        journal-file-options that the user explicitly specifies in the command
        line for the new journal file. If you do not specify a
-       journal-file-option, MUPIP SET takes the char acteristics of the
+       journal-file-option, MUPIP SET takes the characteristics of the
        existing journal file.
      o MUPIP SET supports qualifiers (like -ACCESS_METHOD, and so on) to
        change non-journaling characteristics of database file(s). If you
@@ -3480,13 +3386,11 @@
 
    The default value for AUTOSWITCHLIMIT is 8388600 & the maximum value is
    8388607 blocks (4GB-512 bytes). The minimum value for AUTOSWITCHLIMIT is
-   16384. GT.M produces an error if the AUTOSWITCHLIMIT value is less than
-   the sum of allocation and extension values. If the difference between the
-   AUTOSWITCHLIMIT and the allocation value is not a multiple of the
-   extension value, GT.M rounds-down the value to make it a multiple of the
-   extension value and displays an informational message. GT.M produces an
-   error when the rounded value of AUTOSWITCHLIMIT is less that the minimum
-   value.
+   16384. If the difference between the AUTOSWITCHLIMIT and the allocation
+   value is not a multiple of the extension value, GT.M rounds-down the value
+   to make it a multiple of the extension value and displays an informational
+   message. GT.M produces an error when the rounded value of AUTOSWITCHLIMIT
+   is less that the minimum value.
 
    If you specify values for ALLOCATION, EXTENSION, and AUTOSWITCHLIMIT for a
    region such that (ALLOCATION+EXTENSION>AUTOSWITCHLIMIT), either using GDE
@@ -3944,7 +3848,7 @@
    16. -USER is compatible only with -EXTRACT and -SHOW.
    17. file list must not be asterisk (*) for -REDIRECT.
    18. file list must be asterisk (*) for -ROLLBACK.
-   19. Journal selection qualifiers are incompatib le with -RECOVER,
+   19. Journal selection qualifiers are incompatible with -RECOVER,
        -ROLLBACK, and -VERIFY.
    20. Journal time qualifiers are incompatible with -ROLLBACK.
 
@@ -4272,22 +4176,22 @@
 
    The show-option-list includes (these are not case-sensitive):
 
-     o AL[L]
+    1. AL[L]
 
        Displays all the available type of information about the journal file.
        ALL is the default if you omits the show-option-list.
 
-     o AC[TIVE_PROCESSES]
+    2. AC[TIVE_PROCESSES]
 
        Displays all processes active at the end of the period specified
        implicitly or explicitly by the JOURNAL command time qualifiers.
 
-     o B[ROKEN_TRANSACTIONS]
+    3. B[ROKEN_TRANSACTIONS]
 
        Display all processes that had incomplete fenced transactions at the
        end of the period covered by the JOURNAL command.
 
-     o H[EADER]
+    4. H[EADER]
 
        Displays the journal file header information. If the MUPIP JOURNAL
        command includes only the -SHOW=HEADER action qualifier, GT.M
@@ -4349,12 +4253,12 @@
        ---------------------------------------------------------
        0000006706 jdoe-laptop jdoe    0    2012/11/06 17:30:33
 
-     o P[ROCESSES]
+    5. P[ROCESSES]
 
        Displays all processes active during the period specified implicitly
        or explicitly by the JOURNAL command time qualifiers.
 
-     o S[TATISTICS]
+    6. S[TATISTICS]
 
        Displays a count of all journal record types processed during the
        period specified implicitly or explicitly by the JOURNAL command time
@@ -4534,7 +4438,7 @@
 
    If -BEFORE= time exceeds the last time recorded in journal files, JOURNAL
    processing effectively ignores the qualifier and terminates at the end of
-   the journal file. By default, JOURNAL processing terminates a t the end of
+   the journal file. By default, JOURNAL processing terminates at the end of
    the journal file.
 
    -[NO]LOO[KBACK_LIMIT][=lookback-option-list]
@@ -5143,8 +5047,7 @@
    TZKILL  time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodeflags\node
    TZTWORM time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\ztwormhole
    TZTRIG  time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodeflags\node
-   USET    time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodef
-   lags\node=sarg
+   USET    time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodeflags\node=sarg
    UKILL   time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodeflags\node
    UZKILL  time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\nodeflags\node
    UZTWORM time\tnum\chksum\pid\clntpid\token_seq\strm_num\strm_seq\updnum\ztwormhole
@@ -6156,12 +6059,12 @@
 
    -changelog
 
+   Instructs the Source Server to change its log file.
+
    -instsecondary=<instance_name>
 
    Identifies a Source Server process.
 
-   Instructs the Source Server to change its log file.
-
    -log=<log file name>
 
    Use this mandatory qualifier to specify the name of the new log file. If
@@ -6366,7 +6269,7 @@
    appropriately. Hence, this command checks whether the replicating instance
    where the lost transaction was previously generated has communicated with
    the current originating instance after it came up as the originating
-   instance. If it is affirmative, the Zqgblmod Seqno and Zqgbl mod Trans
+   instance. If it is affirmative, the Zqgblmod Seqno and Zqgblmod Trans
    fields would have been appropriately set and hence $ZQGBLMOD() values will
    be correct.
 
@@ -6930,7 +6833,7 @@
    |             |                |-STA[RTBLK]=hexa                               |
    |             |                |-STO[PBLK]=hexa                                |
    |             |                |-T[RUNCATE][=percentage]                       |
-   |             |                |-UP[GRAD E]                                    |
+   |             |                |-UP[GRADE]                                     |
    |             |                |-USER_DEFINED_REORG=reorg_list                 |
    |-------------+----------------+-----------------------------------------------|
    |             |                |-E[DITINSTANCE]                                |
@@ -7129,3 +7032,32 @@
    |                                      |                          |-TIMEOUT=seconds                          |
    +------------------------------------------------------------------------------------------------------------+
 
+1 Copyright
+   Copyright
+
+   Copyright 2013
+
+   Fidelity Information Services, Inc. All rights reserved.
+
+   Permission is granted to copy, distribute and/or modify this document
+   under the terms of the GNU Free Documentation License, Version 1.3 or any
+   later version published by the Free Software Foundation; with no Invariant
+   Sections, no Front-Cover Texts and no Back-Cover Texts.
+
+   GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
+   trademarks are the property of their respective owners.
+
+   This document contains a description of GT.M and the operating
+   instructions pertaining to the various functions that comprise the system.
+   This document does not contain any commitment of FIS. FIS believes the
+   information in this publication is accurate as of its publication date;
+   such information is subject to change without notice. FIS is not
+   responsible for any errors or defects.
+
+   **Note**
+
+   This help file is a concise representation of revision V6.1-000 of the
+   UNIX Administration and Operations Guide. To obtain a copy of the current
+   revision, go to www.fis-gtm.com and then click on the User Documentation
+   tab.
+
diff --git a/sr_port/mupip_backup.c b/sr_port/mupip_backup.c
index eb7bbcb..8dd0d0a 100644
--- a/sr_port/mupip_backup.c
+++ b/sr_port/mupip_backup.c
@@ -284,6 +284,7 @@ void mupip_backup(void)
 	int4			shm_id, sem_id;
 	replpool_identifier	replpool_id;
 	sm_uc_ptr_t		start_addr;
+	int			user_id;
 	int			group_id;
 	int			perm;
 	struct perm_diag_data	pdd;
@@ -701,7 +702,7 @@ void mupip_backup(void)
 			/* give temporary files the group and permissions as other shared resources - like journal files */
 			FSTAT_FILE(((unix_db_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fd, &stat_buf, fstat_res);
 			if (-1 != fstat_res)
-				if (gtm_set_group_and_perm(&stat_buf, &group_id, &perm, PERM_FILE, &pdd) < 0)
+				if (gtm_permissions(&stat_buf, &user_id, &group_id, &perm, PERM_FILE, &pdd) < 0)
 				{
 					send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 						ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("backup file"),
@@ -720,7 +721,7 @@ void mupip_backup(void)
 			 * 0770 anded with current mode for the new mode if masked permission selected.
 			 */
 			if ((-1 == fstat_res) || (-1 == FCHMOD(rptr->backup_fd, perm))
-				|| ((-1 != group_id) && (-1 == fchown(rptr->backup_fd, -1, group_id))))
+				|| (((-1 != user_id) || (-1 != group_id)) && (-1 == fchown(rptr->backup_fd, user_id, group_id))))
 			{
 				status = errno;
 				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) status);
diff --git a/sr_port/mupip_integ.c b/sr_port/mupip_integ.c
index 8502492..1cadd70 100644
--- a/sr_port/mupip_integ.c
+++ b/sr_port/mupip_integ.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -110,7 +110,7 @@ GBLDEF int			trans_errors = 0;
 GBLDEF boolean_t		block = FALSE;
 GBLDEF boolean_t		muint_fast = FALSE;
 GBLDEF boolean_t		master_dir;
-GBLDEF boolean_t		muint_key = FALSE;
+GBLDEF boolean_t		muint_key = MUINTKEY_FALSE;
 GBLDEF boolean_t		muint_subsc = FALSE;
 GBLDEF boolean_t		mu_int_err_ranges;
 GBLDEF boolean_t		tn_reset_specified;	/* use this to avoid recomputing cli_present("TN_RESET") in the loop */
@@ -129,6 +129,13 @@ GBLDEF span_node_integ		*sndata;
 GTMCRYPT_ONLY(
 	GBLDEF	gtmcrypt_key_t	mu_int_encrypt_key_handle;
 )
+GBLDEF boolean_t		ointeg_this_reg;
+GTM_SNAPSHOT_ONLY(
+	GBLDEF util_snapshot_ptr_t	util_ss_ptr;
+	GBLDEF boolean_t		preserve_snapshot;
+	GBLDEF boolean_t		online_specified;
+)
+
 GBLREF bool			mu_ctrly_occurred;
 GBLREF bool			mu_ctrlc_occurred;
 GBLREF bool			error_mupip;
@@ -141,12 +148,8 @@ GBLREF sgmnt_addrs		*cs_addrs;
 GBLREF tp_region		*grlist;
 GBLREF bool			region;
 GBLREF boolean_t		debug_mupip;
-GBLDEF boolean_t		ointeg_this_reg;
-GTM_SNAPSHOT_ONLY(
-	GBLDEF util_snapshot_ptr_t	util_ss_ptr;
-	GBLDEF boolean_t		preserve_snapshot;
-	GBLDEF boolean_t		online_specified;
-)
+GBLREF gv_key			*muint_end_key;
+GBLREF gv_key			*muint_start_key;
 
 error_def(ERR_CTRLC);
 error_def(ERR_CTRLY);
@@ -190,6 +193,7 @@ void mupip_integ(void)
 		char		ss_filename[GTM_PATH_MAX];
 		unsigned short	ss_file_len = GTM_PATH_MAX;
 	)
+	sgmnt_addrs		*csa;
 	sgmnt_data_ptr_t	csd;
 	span_node_integ		span_node_data;
 
@@ -274,7 +278,7 @@ void mupip_integ(void)
                 if (!grlist)
                 {
 			error_mupip = TRUE;
-			gtm_putmsg(VARLSTCNT(1) ERR_DBNOREGION);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DBNOREGION);
 			mupip_exit(ERR_MUNOACTION);
                 }
 		rptr = grlist;
@@ -283,6 +287,7 @@ void mupip_integ(void)
 	GTM_SNAPSHOT_ONLY(online_integ = ((TRUE != cli_negated("ONLINE")) && region)); /* Default option for INTEG is -ONLINE */
 	GTM_SNAPSHOT_ONLY(preserve_snapshot = (CLI_PRESENT == cli_present("PRESERVE"))); /* Should snapshot file be preserved ? */
 	GTM_SNAPSHOT_ONLY(assert(!online_integ || (region && !tn_reset_specified)));
+	assert(MUINTKEY_FALSE == muint_key);
 	if (CLI_PRESENT == cli_present("SUBSCRIPT"))
 	{
 		keylen = SIZEOF(key_buff);
@@ -319,8 +324,7 @@ void mupip_integ(void)
 			util_ss_ptr->master_map = mu_int_master;
 			util_ss_ptr->native_size = 0;
 #			endif
-		}
-		else /* Establish the condition handler ONLY if ONLINE INTEG was not requested */
+		} else /* Establish the condition handler ONLY if ONLINE INTEG was not requested */
 			ESTABLISH(mu_freeze_ch);
 	}
 	for (total_errors = mu_int_errknt = 0;  ;  total_errors += mu_int_errknt, mu_int_errknt = 0)
@@ -363,7 +367,7 @@ void mupip_integ(void)
 		{
 			util_out_print("!/!/Integ of region !AD", TRUE, REG_LEN_STR(rptr->reg));
 			ointeg_this_reg = online_integ;
-			mu_int_reg(rptr->reg, &retvalue_mu_int_reg);
+			mu_int_reg(rptr->reg, &retvalue_mu_int_reg);	/* sets "gv_cur_region" */
 			region_was_frozen = !ointeg_this_reg;
 			if (TRUE != retvalue_mu_int_reg)
 			{
@@ -372,19 +376,21 @@ void mupip_integ(void)
 					break;
 				continue;
 			}
+			csa = cs_addrs;
 			/* If the region was frozen (INTEG -REG -NOONLINE) then use cs_addrs->hdr for verification of
 			 * blks_to_upgrd, free blocks calculation. Otherwise (ONLINE INTEG) then use mu_int_data for
 			 * the verification.
 			 */
 			if (region_was_frozen)
-				csd = cs_addrs->hdr;
+				csd = csa->hdr;
 			else
 				csd = &mu_int_data;
 		} else
 		{
 			region_was_frozen = FALSE; /* For INTEG -FILE, region is not frozen as we would have standalone access */
-			if (FALSE == mu_int_init())
+			if (FALSE == mu_int_init())	/* sets "gv_cur_region" */
 				mupip_exit(ERR_INTEGERRS);
+			csa = NULL;
 			/* Since we have standalone access, there is no need for cs_addrs->hdr. So, use mu_int_data for
 			 * verifications
 			 */
@@ -402,7 +408,7 @@ void mupip_integ(void)
 		{
 			if (gv_cur_region->read_only)
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, gv_cur_region->dyn.addr->fname_len,
+				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBRDONLY, 2, gv_cur_region->dyn.addr->fname_len,
 					gv_cur_region->dyn.addr->fname);
 				mu_int_errknt++;
 				mu_int_err(ERR_DBTNRESET, 0, 0, 0, 0, 0, 0, 0);
@@ -417,6 +423,14 @@ void mupip_integ(void)
 			master_dir = FALSE;
 			trees->root = muint_block;
 		}
+		if ((MUINTKEY_NULLSUBS == muint_key) && gv_cur_region->std_null_coll)
+		{	/* -SUBSCRIPT was specified AND at least one null-subscript was specified in it.
+			 * muint_start_key and muint_end_key have been constructed assuming gv_cur_region->std_null_coll is FALSE.
+			 * Update muint_start_key and muint_end_key to reflect the current gv_cur_region->std_null_coll value.
+			 */
+			GTM2STDNULLCOLL(muint_start_key->base, muint_start_key->end);
+			GTM2STDNULLCOLL(muint_end_key->base, muint_end_key->end);
+		}
 		for (trees->link = 0;  ;  master_dir = FALSE, temp = (char*)trees,  trees = trees->link,  free(temp))
 		{
 			if (mu_ctrly_occurred || mu_ctrlc_occurred)
@@ -434,7 +448,7 @@ void mupip_integ(void)
 						dbfilop(fc);
 					}
 				}
-				gtm_putmsg(VARLSTCNT(1) mu_ctrly_occurred ? ERR_CTRLY : ERR_CTRLC);
+				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(1) mu_ctrly_occurred ? ERR_CTRLY : ERR_CTRLC);
 				mupip_exit(ERR_MUNOFINISH);
 			}
 			if (!trees)
@@ -469,7 +483,7 @@ void mupip_integ(void)
  			gv_altkey->base[gv_altkey->end++] = '\0';
  			gv_altkey->base[gv_altkey->end] = '\0';
  			if (gv_target->act)
- 				act_in_gvt();
+				act_in_gvt(gv_target);
 			if (mu_int_blk(trees->root, MAX_BT_DEPTH, TRUE, gv_altkey->base, gv_altkey->end, &dummy, 0, 0))
 			{
 				/* We are done with the INTEG CHECK for the current GVT, but if the spanning node INTEG
@@ -570,6 +584,11 @@ void mupip_integ(void)
 				mu_int_errknt--; /* if this error is not supposed to increment the error count */
 			}
 		}
+		if ((MUINTKEY_NULLSUBS == muint_key) && gv_cur_region->std_null_coll)
+		{	/* muint_start_key and muint_end_key have been modified for this region. Undo that change. */
+			STD2GTMNULLCOLL(muint_start_key->base, muint_start_key->end);
+			STD2GTMNULLCOLL(muint_end_key->base, muint_end_key->end);
+		}
 		if (muint_all_index_blocks)
 		{
 			mu_int_maps();
@@ -600,11 +619,12 @@ void mupip_integ(void)
 			}
 			if (!muint_fast && (mu_int_blks_to_upgrd != csd->blks_to_upgrd))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_DBBTUWRNG, 2, mu_int_blks_to_upgrd, csd->blks_to_upgrd);
+				gtm_putmsg_csa(CSA_ARG(csa)
+					VARLSTCNT(4) ERR_DBBTUWRNG, 2, mu_int_blks_to_upgrd, csd->blks_to_upgrd);
 				if (gv_cur_region->read_only || mu_int_errknt)
 					mu_int_errknt++;
 				else
-					gtm_putmsg(VARLSTCNT(1) ERR_DBBTUFIXED);
+					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(1) ERR_DBBTUFIXED);
 			}
 			if (((0 != mu_int_data.kill_in_prog) || (0 != mu_int_data.abandoned_kills)) && (!mu_map_errs) && !region
 				&& !gv_cur_region->read_only)
@@ -641,7 +661,7 @@ void mupip_integ(void)
 			util_out_print("Data     !12UL    !12UL    !8UL.!3ZL  !12UL", TRUE, mu_data_blks, mu_data_recs,
 					leftpt, rightpt, mu_data_adj);
 		}
-		if ((FALSE == block) && (FALSE == muint_key))
+		if ((FALSE == block) && (MUINTKEY_FALSE == muint_key))
 			util_out_print("Free     !12UL              NA              NA            NA", TRUE,
 				mu_int_data.trans_hist.total_blks -
 				(mu_int_data.trans_hist.total_blks + mu_int_data.bplmap - 1) / mu_int_data.bplmap -
@@ -726,10 +746,10 @@ void mupip_integ(void)
 #			ifdef GTM_SNAPSHOT
 			else
 			{
-				assert(SNAPSHOTS_IN_PROG(cs_addrs));
-				assert(NULL != cs_addrs->ss_ctx);
-				ss_release(&cs_addrs->ss_ctx);
-				CLEAR_SNAPSHOTS_IN_PROG(cs_addrs);
+				assert(SNAPSHOTS_IN_PROG(csa));
+				assert(NULL != csa->ss_ctx);
+				ss_release(&csa->ss_ctx);
+				CLEAR_SNAPSHOTS_IN_PROG(csa);
 			}
 #			endif
 			rptr = rptr->fPtr;
@@ -810,7 +830,7 @@ void mupip_integ(void)
 		total_errors++;
 	if (mu_ctrly_occurred || mu_ctrlc_occurred)
 	{
-		gtm_putmsg(VARLSTCNT(1) mu_ctrly_occurred ? ERR_CTRLY : ERR_CTRLC);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) mu_ctrly_occurred ? ERR_CTRLY : ERR_CTRLC);
 		mupip_exit(ERR_MUNOFINISH);
 	}
 	if (0 != total_errors)
diff --git a/sr_port/mupip_io_dev_dispatch.h b/sr_port/mupip_io_dev_dispatch.h
index cc5fe00..a08ac3a 100644
--- a/sr_port/mupip_io_dev_dispatch.h
+++ b/sr_port/mupip_io_dev_dispatch.h
@@ -20,23 +20,23 @@
 UNIX_ONLY(GBLDEF) VMS_ONLY(LITDEF) dev_dispatch_struct io_dev_dispatch_mupip[] =
 {
 #	ifdef UNIX
-	iotype(iott, iott, iott),
+	iotype(iott, iott, iott, nil),
 #	else
 	ionil_dev,
 #	endif
 	ionil_dev,
 #	ifdef UNIX
-	iotype(iorm, iorm, iopi),
+	iotype(iorm, iorm, iopi, nil),
 #	else
-	iotype(iorm, iorm, nil),
+	iotype(iorm, iorm, nil, nil),
 #	endif
 	ionil_dev,
 	ionil_dev,
 	ionil_dev,
 #	ifdef UNIX
-	iotype(ioff, iorm, iopi),
+	iotype(ioff, iorm, iopi, nil),
 #	else
-	iotype(ioff, iorm, nil),
+	iotype(ioff, iorm, nil, nil),
 #	endif
 	ionil_dev,
 	ionil_dev
diff --git a/sr_port/mupip_load_ch.c b/sr_port/mupip_load_ch.c
index 4c4e8f5..ac964d6 100644
--- a/sr_port/mupip_load_ch.c
+++ b/sr_port/mupip_load_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,7 +29,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(mupip_load_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (DUMP)
 	{
 		NEXTCH;
diff --git a/sr_port/mupip_recover.c b/sr_port/mupip_recover.c
index 9d97e42..572d7b1 100644
--- a/sr_port/mupip_recover.c
+++ b/sr_port/mupip_recover.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -62,9 +62,6 @@ GBLREF	gv_namehead		*gv_target;
 GBLREF	gd_region		*gv_cur_region;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
-GBLREF  gd_addr         	*gd_header;
-GBLREF	gd_binding      	*gd_map;
-GBLREF	gd_binding      	*gd_map_top;
 #ifdef VMS
 GBLREF	struct chf$signal_array	*tp_restart_fail_sig;
 GBLREF	boolean_t		tp_restart_fail_sig_used;
@@ -117,7 +114,7 @@ CONDITION_HANDLER(mupip_recover_ch)
 {
 	int	rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 		assert(gtm_white_box_test_case_enabled && (WBTEST_TP_HIST_CDB_SC_BLKMOD == gtm_white_box_test_case_number));
@@ -125,24 +122,19 @@ CONDITION_HANDLER(mupip_recover_ch)
 		rc = tp_restart(1, TP_RESTART_HANDLES_ERRORS);	/* This SHOULD generate an error (TPFAIL or other) */
 		GTMTRIG_ONLY(assert(ERR_TPRETRY != rc));
 #		ifdef UNIX
-		if (ERR_TPRETRY == SIGNAL)		/* (signal value undisturbed) */
+		assertpro(ERR_TPRETRY != SIGNAL);		/* (signal value undisturbed) */
 #		elif defined VMS
-		if (!tp_restart_fail_sig_used)	/* If tp_restart ran clean */
+		assertpro(tp_restart_fail_sig_used);	/* If tp_restart ran clean */
 #		else
 #		error unsupported platform
 #		endif
-		{
-			GTMASSERT;		/* It should *not* run clean */
-		}
 #		ifdef VMS
-		else
-		{	/* Otherwise tp_restart had a signal that we must now deal with -- replace the TPRETRY
-			   information with that saved from tp_restart. */
-			/* Assert we have room for these arguments - the array malloc is in tp_restart */
-			assert(TPRESTART_ARG_CNT >= tp_restart_fail_sig->chf$is_sig_args);
-			memcpy(sig, tp_restart_fail_sig, (tp_restart_fail_sig->chf$l_sig_args + 1) * SIZEOF(int));
-			tp_restart_fail_sig_used = FALSE;
-		}
+		/* Otherwise tp_restart had a signal that we must now deal with -- replace the TPRETRY
+		   information with that saved from tp_restart. */
+		/* Assert we have room for these arguments - the array malloc is in tp_restart */
+		assert(TPRESTART_ARG_CNT >= tp_restart_fail_sig->chf$is_sig_args);
+		memcpy(sig, tp_restart_fail_sig, (tp_restart_fail_sig->chf$l_sig_args + 1) * SIZEOF(int));
+		tp_restart_fail_sig_used = FALSE;
 #		endif
 		/* At this point SIGNAL would correspond to TPFAIL (not a TPRETRY) error */
 	}
@@ -273,14 +265,14 @@ void	mupip_recover(void)
 		{
 			TREF(jnl_extract_nocol) = !mur_options.update && jgbl.mur_extract && TREF(jnl_extract_nocol);
 			if (db_absent)
-				gtm_putmsg(VARLSTCNT(6) ERR_DBCOLLREQ, 4, LEN_AND_LIT("Mising Database file"),
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBCOLLREQ, 4, LEN_AND_LIT("Mising Database file"),
 						DB_LEN_STR(db_absent_rctl->gd));
 			else
-				gtm_putmsg(VARLSTCNT(6) ERR_DBCOLLREQ, 4, LEN_AND_LIT("Instance is frozen."),
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBCOLLREQ, 4, LEN_AND_LIT("Instance is frozen."),
 						LEN_AND_LIT(""));
 		} else
 		{
-			gtm_putmsg(VARLSTCNT(1) ERR_SETEXTRENV);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_SETEXTRENV);
 			mupip_exit(ERR_MUNOACTION);
 		}
 	} else
@@ -307,7 +299,7 @@ void	mupip_recover(void)
 		if (!jnlpool.repl_inst_filehdr->crash && (0 != replinst_seqno) && (max_reg_seqno != replinst_seqno))
 		{
 			udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
-			gtm_putmsg(VARLSTCNT(6) ERR_REPLINSTDBMATCH, 4,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLINSTDBMATCH, 4,
 				LEN_AND_STR(udi->fn), &replinst_seqno, &max_reg_seqno);
 			mupip_exit(ERR_MUNOACTION);
 		}
@@ -341,7 +333,7 @@ void	mupip_recover(void)
 	}
 	if (murgbl.intrpt_recovery && mur_options.update && mur_options.forward)
 	{
-		gtm_putmsg(VARLSTCNT(4) ERR_MUPJNLINTERRUPT, 2, DB_LEN_STR(rctl->gd));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUPJNLINTERRUPT, 2, DB_LEN_STR(rctl->gd));
 		mupip_exit(ERR_MUNOACTION);
 	}
 	if (mur_options.update && intrrupted_recov_processing)
@@ -358,7 +350,7 @@ void	mupip_recover(void)
 	}
 	assert(FALSE == murgbl.ok_to_update_db);
 	if (mur_options.rollback_losttnonly)
-		gtm_putmsg(VARLSTCNT(1) ERR_RLBKLOSTTNONLY);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_RLBKLOSTTNONLY);
 	/* The current resync_seqno of this replication instance needs to be calculated before the call to "gtmrecv_fetchresync" */
 	VMS_ONLY(jgbl.max_resync_seqno = 0;)
 	for (regno = 0; regno < reg_total; regno++)
@@ -395,19 +387,20 @@ void	mupip_recover(void)
 		{
 			UNIX_ONLY(
 				if ((INVALID_SUPPL_STRM != murgbl.resync_strm_index) && !remote_side->is_supplementary)
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4,
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4,
 						LEN_AND_LIT("Gtmrecv_fetchresync returned strm_index"),
 							murgbl.resync_strm_index, murgbl.resync_strm_index);
 			)
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("Gtmrecv_fetchresync returned resync_seqno"),
-				&murgbl.resync_seqno, &murgbl.resync_seqno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4,
+					LEN_AND_LIT("Gtmrecv_fetchresync returned resync_seqno"),
+					&murgbl.resync_seqno, &murgbl.resync_seqno);
 		}
 		VMS_ONLY(
 			if (jgbl.max_resync_seqno < murgbl.resync_seqno)
 			{
 				murgbl.resync_seqno = jgbl.max_resync_seqno;
 				if (mur_options.verbose)
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4,
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4,
 						LEN_AND_LIT("Resync_seqno is reset to max_resync_seqno"),
 						&murgbl.resync_seqno, &murgbl.resync_seqno);
 			}
@@ -420,7 +413,7 @@ void	mupip_recover(void)
 		 */
 		if (!jnlpool.repl_inst_filehdr->is_supplementary)
 		{
-			gtm_putmsg(VARLSTCNT(1) ERR_RSYNCSTRMSUPPLONLY);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_RSYNCSTRMSUPPLONLY);
 			mupip_exit(ERR_MUNOACTION);
 		}
 		if (0 < murgbl.resync_strm_index)
@@ -441,7 +434,8 @@ void	mupip_recover(void)
 				SPRINTF(histdetail, "Stream Seqno "INT8_FMT" "INT8_FMTX" (Stream # %2d) ",
 					murgbl.resync_seqno - 1, murgbl.resync_seqno - 1, murgbl.resync_strm_index);
 				udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
-				gtm_putmsg(VARLSTCNT(6) ERR_REPLINSTNOHIST, 4, LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLINSTNOHIST, 4,
+						LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
 				mupip_exit(ERR_MUNOACTION);
 			}
 		}
@@ -482,8 +476,9 @@ void	mupip_recover(void)
 		 * 	ztp_broken = TRUE, if any ztp entry is broken */
 		min_broken_time = mur_process_token_table(&ztp_broken);
 		if (mur_options.verbose)
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("mur_process_token_table returns min_broken_time"),
-				min_broken_time, min_broken_time);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4,
+					LEN_AND_LIT("mur_process_token_table returns min_broken_time"),
+					min_broken_time, min_broken_time);
 		min_broken_seqno = losttn_seqno = MAXUINT8;
 	} else
 		assert(0 != losttn_seqno);
@@ -557,10 +552,12 @@ void	mupip_recover(void)
 		mur_process_seqno_table(&min_broken_seqno, &losttn_seqno);
 		if (mur_options.verbose)
 		{
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("mur_process_seqno_table returns min_broken_seqno"),
-				&min_broken_seqno, &min_broken_seqno);
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("mur_process_seqno_table returns losttn_seqno"),
-				&losttn_seqno, &losttn_seqno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4,
+					LEN_AND_LIT("mur_process_seqno_table returns min_broken_seqno"),
+					&min_broken_seqno, &min_broken_seqno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4,
+					LEN_AND_LIT("mur_process_seqno_table returns losttn_seqno"),
+					&losttn_seqno, &losttn_seqno);
 		}
 		min_broken_time = MAXUINT4;
 	}
@@ -585,7 +582,7 @@ void	mupip_recover(void)
 	{
 		assert(murgbl.consist_jnl_seqno <= losttn_seqno);
 		assert(murgbl.consist_jnl_seqno <= min_broken_seqno);
-		gtm_putmsg(VARLSTCNT(4) ERR_RLBKJNSEQ, 2, &murgbl.consist_jnl_seqno, &murgbl.consist_jnl_seqno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_RLBKJNSEQ, 2, &murgbl.consist_jnl_seqno, &murgbl.consist_jnl_seqno);
 	}
 	if (murgbl.wrn_count)
 		mupip_exit(ERR_JNLACTINCMPLT);
diff --git a/sr_port/mupip_reorg.c b/sr_port/mupip_reorg.c
index 45a2882..227ffa8 100644
--- a/sr_port/mupip_reorg.c
+++ b/sr_port/mupip_reorg.c
@@ -51,6 +51,11 @@
 #include "buddy_list.h"		/* needed for tp.h */
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
+#ifdef GTM_TRIGGER
+#include "hashtab_mname.h"
+#include "gv_trigger.h"
+#include "gv_trigger_common.h"
+#endif
 
 /* Prototypes */
 #include "mupip_reorg.h"
@@ -61,6 +66,7 @@
 #include "mu_outofband_setup.h"
 #include "gtmmsg.h"
 #include "mu_getlst.h"
+#include "gvcst_protos.h"	/* for gvcst_root_search prototype */
 
 error_def(ERR_CONCURTRUNCINPROG);
 error_def(ERR_DBRDONLY);
@@ -81,7 +87,6 @@ GTMTRIG_ONLY(LITREF mval		literal_hasht;)
 GBLREF bool		mu_ctrlc_occurred;
 GBLREF bool		mu_ctrly_occurred;
 GBLREF boolean_t	mu_reorg_process;
-GBLREF gd_addr 		*gd_header;
 GBLREF gd_region	*gv_cur_region;
 GBLREF gv_key           *gv_currkey_next_reorg, *gv_currkey, *gv_altkey;
 GBLREF int		gv_keysize;
@@ -91,6 +96,7 @@ GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF uint4		process_id;
 GBLREF tp_region	*grlist;
 GBLREF bool		error_mupip;
+GBLREF inctn_opcode_t	inctn_opcode;
 #ifdef UNIX
 GBLREF	boolean_t	jnlpool_init_needed;
 #endif
@@ -100,12 +106,11 @@ void mupip_reorg(void)
 	int			data_fill_factor, index_fill_factor;
 	int			reorg_op, reg_max_rec, reg_max_key, reg_max_blk;
 	char			cli_buff[MAX_LINE], *ptr;
-	glist			gl_head, exclude_gl_head, *gl_ptr;
+	glist			gl_head, exclude_gl_head, *gl_ptr, hasht_gl;
 	uint4			cli_status;
 	unsigned short		n_len;
 	boolean_t		truncate, cur_success, restrict_reg, arg_present;
 	int			root_swap_statistic;
-	mval			gn;
 #	ifdef GTM_TRUNCATE
 	int4			truncate_percent;
 	boolean_t		gotlock;
@@ -244,35 +249,34 @@ void mupip_reorg(void)
 	root_swap_statistic = 0;
 	mu_reorg_process = TRUE;
 	assert(NULL == gv_currkey_next_reorg);
-	gv_keysize = DBKEYSIZE(MAX_KEY_SZ);
+	GVKEYSIZE_INIT_IF_NEEDED;	/* sets "gv_keysize", "gv_currkey" and "gv_altkey" (if not already done) */
 	GVKEY_INIT(gv_currkey_next_reorg, gv_keysize);
-	GVKEY_INIT(gv_currkey, gv_keysize);
-	GVKEY_INIT(gv_altkey, gv_keysize);
 	reorg_gv_target = targ_alloc(MAX_KEY_SZ, NULL, NULL);
 	reorg_gv_target->hist.depth = 0;
 	reorg_gv_target->alt_hist->depth = 0;
 	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
 	{
 		util_out_print("   ", FLUSH);
-		util_out_print("Global: !AD ", FLUSH, gl_ptr->name.str.len, gl_ptr->name.str.addr);
-		if (in_exclude_list((uchar_ptr_t)gl_ptr->name.str.addr, gl_ptr->name.str.len, &exclude_gl_head))
+		util_out_print("Global: !AD (region !AD)", FLUSH, GNAME(gl_ptr).len, GNAME(gl_ptr).addr, REG_LEN_STR(gl_ptr->reg));
+		if (in_exclude_list((unsigned char *)GNAME(gl_ptr).addr, GNAME(gl_ptr).len, &exclude_gl_head))
 		{
-			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_EXCLUDEREORG, 2, gl_ptr->name.str.len, gl_ptr->name.str.addr);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_EXCLUDEREORG, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 			reorg_success = FALSE;
 			continue;
 		}
 		/* Save the global name in reorg_gv_target. Via gv_currkey_next_reorg, it's possible for gv_currkey to become
 		 * out of sync with gv_target. We'll use reorg_gv_target->gvname to make sure the correct root block is found.
 		 */
-		reorg_gv_target->gvname.var_name.addr = gl_ptr->name.str.addr;
-		reorg_gv_target->gvname.var_name.len = gl_ptr->name.str.len;
-		cur_success = mu_reorg(&gl_ptr->name, &exclude_gl_head, &resume, index_fill_factor, data_fill_factor, reorg_op);
+		reorg_gv_target->gvname.var_name = GNAME(gl_ptr);
+		GTMTRIG_ONLY(assert(!IS_MNAME_HASHT_GBLNAME(reorg_gv_target->gvname.var_name));)
+		cur_success = mu_reorg(gl_ptr, &exclude_gl_head, &resume, index_fill_factor, data_fill_factor, reorg_op);
 		reorg_success &= cur_success;
-		SET_GV_CURRKEY_FROM_REORG_GV_TARGET;
+		SET_GV_CURRKEY_FROM_GVT(reorg_gv_target);
 #		ifdef GTM_TRUNCATE
 		if (truncate)
 		{	/* No need to move root blocks unless truncating */
-			cur_success &= mu_swap_root(&gl_ptr->name, &root_swap_statistic);
+			cur_success &= mu_swap_root(gl_ptr, &root_swap_statistic);
+			assert(gv_cur_region == gl_ptr->reg);	/* should have been set inside "mu_reorg" call done above */
 			if (cur_success)
 			{	/* add region corresponding to this global to the set (list) of regions to truncate */
 				for (reg_iter = reg_list, prev_reg = reg_list; reg_iter; reg_iter = reg_iter->next)
@@ -292,14 +296,31 @@ void mupip_reorg(void)
 #					ifdef GTM_TRIGGER
 					if (truncate)
 					{	/* Reorg ^#t in this region to move it out of the way. */
-						gn = literal_hasht;
-						reorg_gv_target->gvname.var_name.addr = gn.str.addr;
-						reorg_gv_target->gvname.var_name.len = gn.str.len;
-						cur_success = mu_reorg(&gn, &exclude_gl_head, &resume, index_fill_factor,
-								data_fill_factor, reorg_op);
-						reorg_success &= cur_success;
-						SET_GV_CURRKEY_FROM_REORG_GV_TARGET;
-						reorg_success &= mu_swap_root(&gn, &root_swap_statistic);
+						SET_GVTARGET_TO_HASHT_GBL(cs_addrs);	/* sets gv_target */
+						hasht_gl.next = NULL;
+						hasht_gl.reg = gv_cur_region;
+						hasht_gl.gvt = gv_target;
+						inctn_opcode = inctn_invalid_op;	/* needed for *ROOT_SEARCH */
+						INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;	/* sets gv_target->root */
+						DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+						if (0 != gv_target->root)
+						{
+							util_out_print("   ", FLUSH);
+							util_out_print("Global: !AD (region !AD)", FLUSH,
+								GNAME(&hasht_gl).len, GNAME(&hasht_gl).addr,
+								REG_LEN_STR(gv_cur_region));
+							reorg_gv_target->gvname.var_name = literal_hasht.str;
+							cur_success = mu_reorg(&hasht_gl, &exclude_gl_head, &resume,
+										index_fill_factor, data_fill_factor, reorg_op);
+							reorg_success &= cur_success;
+							SET_GV_CURRKEY_FROM_GVT(reorg_gv_target);
+							/* Recompute gv_target->root in case mu_reorg changed things around */
+							gv_target->root = 0;
+							inctn_opcode = inctn_invalid_op;	/* needed for GVCST_ROOT_SEARCH */
+							GVCST_ROOT_SEARCH;	/* set gv_target->root */
+							if (gv_target->root)
+								reorg_success &= mu_swap_root(&hasht_gl, &root_swap_statistic);
+						}
 					}
 #					endif
 				}
@@ -364,8 +385,6 @@ void mupip_reorg(void)
 		}
 #		endif
 		mupip_exit(SS_NORMAL);
-	}
-	else
+	} else
 		mupip_exit(SS_NORMAL);
 }
-
diff --git a/sr_port/mupip_reorg.h b/sr_port/mupip_reorg.h
index d6a749d..3ece520 100644
--- a/sr_port/mupip_reorg.h
+++ b/sr_port/mupip_reorg.h
@@ -13,10 +13,10 @@
 
 /* prototypes */
 
-boolean_t mu_reorg(mval *gn, glist *exclude_glist_ptr, boolean_t *resume,
+boolean_t mu_reorg(glist *gl_ptr, glist *exclude_glist_ptr, boolean_t *resume,
 			int index_fill_factor, int data_fill_factor, int reorg_op);
 # ifdef UNIX
-boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr);
+boolean_t mu_swap_root(glist *gl_ptr, int *root_swap_statistic_ptr);
 block_id swap_root_or_directory_block(int parent_blk_lvl, int level, srch_hist *dir_hist_ptr, block_id child_blk_id,
 		sm_uc_ptr_t child_blk_ptr, kill_set *kill_set_list, trans_num curr_tn);
 # endif
diff --git a/sr_port/mupip_set_jnl_ch.c b/sr_port/mupip_set_jnl_ch.c
index e5a02de..c75660d 100644
--- a/sr_port/mupip_set_jnl_ch.c
+++ b/sr_port/mupip_set_jnl_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -27,7 +27,7 @@ error_def(ERR_MUNOFINISH);
 
 CONDITION_HANDLER(mupip_set_jnl_ch)
 {
-	START_CH
+	START_CH(TRUE);
 	mupip_set_jnl_cleanup();
 	PRN_ERROR
 	if (SEVERITY == ERROR  ||  SEVERITY == SEVERE)
diff --git a/sr_port/muprec.h b/sr_port/muprec.h
index c175e98..ba06666 100644
--- a/sr_port/muprec.h
+++ b/sr_port/muprec.h
@@ -110,27 +110,27 @@ error_def(ERR_MUJNLSTAT);
 	EXTINT(plst->origjpv.jpv_pid);			\
 }
 
-#define JNL_PUT_MSG_PROGRESS(LIT)								\
-{												\
-	now_t	now;	/* for GET_CUR_TIME macro */						\
-	char	*time_ptr, time_str[CTIME_BEFORE_NL + 2];					\
-												\
-	GET_CUR_TIME;										\
-	gtm_putmsg(VARLSTCNT(6) ERR_MUJNLSTAT, 4, LEN_AND_LIT(LIT), CTIME_BEFORE_NL, time_ptr);	\
+#define JNL_PUT_MSG_PROGRESS(LIT)											\
+{															\
+	now_t	now;	/* for GET_CUR_TIME macro */									\
+	char	*time_ptr, time_str[CTIME_BEFORE_NL + 2];								\
+															\
+	GET_CUR_TIME;													\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJNLSTAT, 4, LEN_AND_LIT(LIT), CTIME_BEFORE_NL, time_ptr);	\
 }
 
-#define JNL_SUCCESS_MSG(mur_options)									\
-{													\
-	if (mur_options.show)										\
-		gtm_putmsg(VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(SHOW_STR));			\
-	if (mur_options.extr[GOOD_TN])									\
-		gtm_putmsg(VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(EXTRACT_STR));			\
-	if (mur_options.verify)										\
-		gtm_putmsg(VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(VERIFY_STR));			\
-	if (mur_options.rollback)									\
-		gtm_putmsg(VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(ROLLBACK_STR));			\
-	else if (mur_options.update)									\
-		gtm_putmsg(VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(RECOVER_STR));			\
+#define JNL_SUCCESS_MSG(mur_options)										\
+{														\
+	if (mur_options.show)											\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(SHOW_STR));		\
+	if (mur_options.extr[GOOD_TN])										\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(EXTRACT_STR));	\
+	if (mur_options.verify)											\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(VERIFY_STR));		\
+	if (mur_options.rollback)										\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(ROLLBACK_STR));	\
+	else if (mur_options.update)										\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLSUCCESS, 2, LEN_AND_LIT(RECOVER_STR));	\
 }
 
 #define	MUR_FIX_JCTL_BACK_POINTER_TO_RCTL(JCTL, NEW_RCTL, OLD_RCTL, CHK_PREV_GEN)	\
@@ -1013,59 +1013,59 @@ typedef struct onln_rlbk_reg_list_struct
 #define MUR_TOKEN_LOOKUP(token, image_count, rec_time, fence) mur_token_lookup(token, image_count, rec_time, fence)
 #endif
 
-#define PRINT_VERBOSE_STAT(JCTL, MODULE)   									\
-{										   				\
-	GBLREF 	jnl_gbls_t	jgbl;			   							\
-	UNIX_ONLY(                             									\
-	uint4 days;                            									\
-	time_t seconds;)											\
-	VMS_ONLY(mval val;)											\
+#define PRINT_VERBOSE_STAT(JCTL, MODULE)											   \
+{																   \
+	GBLREF 	jnl_gbls_t	jgbl;												   \
+	UNIX_ONLY(														   \
+	uint4 days;														   \
+	time_t seconds;)													   \
+	VMS_ONLY(mval val;)													   \
+	if (mur_options.verbose)												   \
+	{															   \
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,   LEN_AND_LIT("Module"),				   \
+				LEN_AND_LIT(MODULE));										   \
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,   LEN_AND_LIT("    Journal file"),			   \
+			JCTL->jnl_fn_len, JCTL->jnl_fn);									   \
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Record Offset"),		   \
+			JCTL->rec_offset, JCTL->rec_offset);									   \
+		if (!jgbl.forw_phase_recovery)											   \
+		{														   \
+			gtm_putmsg_csa(CSA_ARG(NULL)VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Turn around Offset"),	   \
+				JCTL->turn_around_offset, JCTL->turn_around_offset);						   \
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Turn around timestamp"),   \
+				JCTL->turn_around_time, JCTL->turn_around_time);						   \
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("    Turn around transaction"), \
+				&JCTL->turn_around_tn, &JCTL->turn_around_tn);							   \
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("    Turn around seqno"),	   \
+				&JCTL->turn_around_seqno, &JCTL->turn_around_seqno);						   \
+			UNIX_ONLY(												   \
+				dollarh(jgbl.mur_tp_resolve_time, &days, &seconds);						   \
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_MUINFOUINT6, 6, LEN_AND_LIT("    Tp_resolve_time"), \
+				jgbl.mur_tp_resolve_time, jgbl.mur_tp_resolve_time, days, seconds);				   \
+			)													   \
+			VMS_ONLY(												   \
+				op_horolog(&val);										   \
+            			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_MUINFOUINT6, 6, LEN_AND_LIT("    Tp_resolve_time"), \
+                		jgbl.mur_tp_resolve_time, jgbl.mur_tp_resolve_time, val.str.len, val.str.addr)			   \
+			);													   \
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Token total"),		   \
+			murgbl.token_table.count, murgbl.token_table.count);							   \
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Token broken"),		   \
+				murgbl.broken_cnt, murgbl.broken_cnt);								   \
+		}														   \
+	}															   \
+}
+
+#define PRINT_VERBOSE_TAIL_BAD(JCTL)										\
+{														\
 	if (mur_options.verbose)										\
 	{													\
-		gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4,   LEN_AND_LIT("Module"),				\
-				LEN_AND_LIT(MODULE));								\
-		gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4,   LEN_AND_LIT("    Journal file"),			\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,					\
+			LEN_AND_LIT("Tail analysis found bad record for journal file"),				\
 			JCTL->jnl_fn_len, JCTL->jnl_fn);							\
-		gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Record Offset"),			\
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("Record Offset"),	\
 			JCTL->rec_offset, JCTL->rec_offset);							\
-		if (!jgbl.forw_phase_recovery)									\
-		{												\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Turn around Offset"), 	\
-				JCTL->turn_around_offset, JCTL->turn_around_offset);   				\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Turn around timestamp"),	\
-				JCTL->turn_around_time, JCTL->turn_around_time);  				\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("    Turn around transaction"),	\
-				&JCTL->turn_around_tn, &JCTL->turn_around_tn);  				\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT8, 4, LEN_AND_LIT("    Turn around seqno"), 	\
-				&JCTL->turn_around_seqno, &JCTL->turn_around_seqno);   				\
-			UNIX_ONLY(										\
-				dollarh(jgbl.mur_tp_resolve_time, &days, &seconds);        			\
-				gtm_putmsg(VARLSTCNT(8) ERR_MUINFOUINT6, 6, LEN_AND_LIT("    Tp_resolve_time"), \
-				jgbl.mur_tp_resolve_time, jgbl.mur_tp_resolve_time, days, seconds);		\
-			)	 										\
-			VMS_ONLY(										\
-				op_horolog(&val);	                                                 	\
-            			gtm_putmsg(VARLSTCNT(8) ERR_MUINFOUINT6, 6,  LEN_AND_LIT("    Tp_resolve_time"),\
-                		jgbl.mur_tp_resolve_time, jgbl.mur_tp_resolve_time, val.str.len, val.str.addr)	\
-			);     											\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Token total"), 		\
-			murgbl.token_table.count, murgbl.token_table.count);					\
-			gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Token broken"), 		\
-				murgbl.broken_cnt, murgbl.broken_cnt);  					\
-		}								   				\
-	}									   				\
-}
-
-#define PRINT_VERBOSE_TAIL_BAD(JCTL)									\
-{													\
-	if (mur_options.verbose)									\
-	{												\
-		gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4,						\
-			LEN_AND_LIT("Tail analysis found bad record for journal file"),			\
-			JCTL->jnl_fn_len, JCTL->jnl_fn);						\
-		gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("Record Offset"),		\
-			JCTL->rec_offset, JCTL->rec_offset);						\
-	}												\
+	}													\
 }
 
 #define ASSERT_HOLD_REPLPOOL_SEMS				\
diff --git a/sr_port/mur_apply_pblk.c b/sr_port/mur_apply_pblk.c
index b9e7a1a..5ddfc02 100644
--- a/sr_port/mur_apply_pblk.c
+++ b/sr_port/mur_apply_pblk.c
@@ -422,12 +422,12 @@ uint4 mur_output_pblk(reg_ctl_list *rctl)
 	bp = (blk_hdr_ptr_t) pblkcontents;
 	in_len = MIN(csd->blk_size, bp->bsiz) - SIZEOF(*bp);
 	jctl = rctl->jctl;
-	if (!jctl->is_same_hash_as_db && BLOCK_REQUIRE_ENCRYPTION(csd->is_encrypted, bp->levl, in_len))
+	if (!jctl->is_same_hash_as_db && BLK_NEEDS_ENCRYPTION3(csd->is_encrypted, bp->levl, in_len))
 	{	/* Database and Journals are setup with different encryption keys. So, decrypt the PBLK records with the journal's
 		 * encryption key and encrypt it with the database's encryption key before writing it to the database file.
 		 */
 		ASSERT_ENCRYPTION_INITIALIZED;
-		/* The below assert cannot be moved before BLOCK_REQUIRE_ENCRYPTION check done above as tmp_ptr could
+		/* The below assert cannot be moved before BLK_NEEDS_ENCRYPTION3 check done above as tmp_ptr could
 		 * potentially point to a V4 block in which case the assert might fail when a V4 block is casted to
 		 * a V5 block header.
 		 */
diff --git a/sr_port/mur_block_count_correct.c b/sr_port/mur_block_count_correct.c
index 3746950..6792439 100644
--- a/sr_port/mur_block_count_correct.c
+++ b/sr_port/mur_block_count_correct.c
@@ -51,30 +51,20 @@ uint4 mur_block_count_correct(reg_ctl_list *rctl)
 	int4			mu_int_ovrhd;
 	uint4			total_blks;
 	uint4			status;
-	uint4                   new_bit_maps, bplmap, new_blocks;
+	uint4                   new_bit_maps, bplmap, new_blocks, tmpcnt;
+	enum db_acc_method      acc_meth;
 
 	MUR_CHANGE_REG(rctl);
 	mu_data = cs_data;
-	switch (mu_data->acc_meth)
+	acc_meth = mu_data->acc_meth;
+	switch (acc_meth)
 	{
-		default:
-			GTMASSERT;
-			break;
-#if defined(VMS) && defined(GT_CX_DEF)
-		case dba_bg:	/* necessary to do calculation in this manner to prevent double rounding causing an error */
-			if (mu_data->unbacked_cache)
-				mu_int_ovrhd = DIVIDE_ROUND_UP(SIZEOF_FILE_HDR(mu_data) + mu_data->free_space +
-					mu_data->lock_space_size, DISK_BLOCK_SIZE);
-			else
-				mu_int_ovrhd = DIVIDE_ROUND_UP(SIZEOF_FILE_HDR(mu_data) + BT_SIZE(mu_data)
-					+ mu_data->free_space + mu_data->lock_space_size, DISK_BLOCK_SIZE);
-			break;
-#else
 		case dba_bg:
-#endif
 		case dba_mm:
 			mu_int_ovrhd = (int4)DIVIDE_ROUND_UP(SIZEOF_FILE_HDR(mu_data) + mu_data->free_space, DISK_BLOCK_SIZE);
-		break;
+			break;
+		default:
+			assertpro(FALSE && acc_meth);
 	}
 	mu_int_ovrhd += 1;
 	assert(mu_int_ovrhd == mu_data->start_vbn);
@@ -85,7 +75,7 @@ uint4 mur_block_count_correct(reg_ctl_list *rctl)
 	 */
 	if (native_size && (size < native_size))
 	{
-		total_blks = (dba_mm == mu_data->acc_meth) ? cs_addrs->total_blks : cs_addrs->ti->total_blks;
+		total_blks = (dba_mm == acc_meth) ? cs_addrs->total_blks : cs_addrs->ti->total_blks;
 		if (JNL_ENABLED(cs_addrs))
 			cs_addrs->jnl->pini_addr = 0; /* Stop simulation of GTM process journal record writing (if any active)*/
 		/* If journaling, gdsfilext will need to write an inctn record. The timestamp of that journal record will
@@ -102,18 +92,24 @@ uint4 mur_block_count_correct(reg_ctl_list *rctl)
 		bplmap = cs_data->bplmap;
 		new_blocks = (native_size - size)/(mu_data->blk_size / DISK_BLOCK_SIZE);
 		new_bit_maps = DIVIDE_ROUND_UP(total_blks + new_blocks, bplmap) - DIVIDE_ROUND_UP(total_blks, bplmap);
-		if (SS_NORMAL != (status = GDSFILEXT(new_blocks - new_bit_maps, total_blks, TRANS_IN_PROG_FALSE)))
+		tmpcnt = new_blocks - new_bit_maps;
+		/* Call GDSFILEXT only if the no of blocks by which DB needs to be extended is not '0' since GDSFILEXT() treats
+		 * extension by count 0 as unavailability of space(NO_FREE_SPACE error). And in the following case, tmpcnt could
+		 * be '0' on AIX because in MM mode AIX increases the native_size to the nearest multiple of OS_PAGE_SIZE.
+		 * And this increase could be less than GT.M block size.*/
+		if (tmpcnt && SS_NORMAL != (status = GDSFILEXT(new_blocks - new_bit_maps, total_blks, TRANS_IN_PROG_FALSE)))
 		{
 			jgbl.dont_reset_gbl_jrec_time = TRUE;
 			return (status);
 		}
 		jgbl.dont_reset_gbl_jrec_time = TRUE;
-		DEBUG_ONLY(
-			/* Check that the filesize and blockcount in the fileheader match now after the extend */
-			size = mu_int_ovrhd + (off_t)(mu_data->blk_size / DISK_BLOCK_SIZE) * mu_data->trans_hist.total_blks;
-			native_size = gds_file_size(gv_cur_region->dyn.addr->file_cntl);
-			assert(size == native_size);
-		)
+#		ifdef DEBUG
+		/* Check that the filesize and blockcount in the fileheader match now after the extend */
+		size = mu_int_ovrhd + (off_t)(mu_data->blk_size / DISK_BLOCK_SIZE) * mu_data->trans_hist.total_blks;
+		native_size = gds_file_size(gv_cur_region->dyn.addr->file_cntl);
+		ALIGN_DBFILE_SIZE_IF_NEEDED(size, native_size);
+		assert(size == native_size);
+#		endif
 	}
 	return SS_NORMAL;
 }
diff --git a/sr_port/mur_close_files.c b/sr_port/mur_close_files.c
index 4393974..adbfe7b 100644
--- a/sr_port/mur_close_files.c
+++ b/sr_port/mur_close_files.c
@@ -45,6 +45,7 @@
 #include "gtmmsg.h"
 #include "file_head_read.h"
 #include "file_head_write.h"
+#include "have_crit.h"
 #if defined(UNIX)
 #include "repl_msg.h"
 #include "gtmsource.h"
@@ -54,7 +55,6 @@
 #include "repl_instance.h"
 #include "repl_sem.h"
 #include "ftok_sems.h"
-#include "have_crit.h"
 #include "gtmsource_srv_latch.h"
 #include <signal.h>
 #include "anticipatory_freeze.h"
@@ -474,7 +474,7 @@ boolean_t mur_close_files(void)
 				assert(jctl->turn_around_offset);
 				jctl->jfh->turn_around_offset = 0;
 				jctl->jfh->turn_around_time = 0;
-				jctl->jfh->crash = 0;
+				jctl->jfh->crash = FALSE;
 				jctl->jfh->end_of_data = jctl->turn_around_offset;
 				jctl->jfh->eov_timestamp = jctl->turn_around_time;
 				jctl->jfh->eov_tn = jctl->turn_around_tn;
@@ -831,7 +831,6 @@ boolean_t mur_close_files(void)
 		mu_replpool_release_sem(&repl_instance, RECVPOOL_SEGMENT, got_ftok);
 		if (got_ftok)
 			ftok_sem_release(jnlpool.jnlpool_dummy_reg, FALSE, TRUE); /* immediate=TRUE */
-		murgbl.repl_standalone = FALSE;
 		ASSERT_DONOT_HOLD_REPLPOOL_SEMS;
 		assert(jgbl.onlnrlbk ||
 			((INVALID_SEMID == repl_instance.jnlpool_semid) && (0 == repl_instance.jnlpool_semid_ctime)));
@@ -851,10 +850,9 @@ boolean_t mur_close_files(void)
 	{	/* Signal completion */
 		assert(((NULL != inst_hdr) && (udi == FILE_INFO(jnlpool.jnlpool_dummy_reg))) || !murgbl.clean_exit);
 		finish_err_code = murgbl.clean_exit ? ERR_ORLBKCMPLT : ERR_ORLBKTERMNTD;
-		if (NULL != inst_hdr)
-		{	/* If inst_hdr is NULL, it means we exited even before getting standalone access on the journal pool.
-			 * No point issuing the ORLBKCMPLT or ORLBKTERMNTD message because ORLBKSTART will not even be issued.
-			 */
+		assert(!murgbl.repl_standalone || ((NULL != inst_hdr) && (NULL != udi)));
+		if (murgbl.repl_standalone)
+		{
 			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) finish_err_code, 4,
 					LEN_AND_STR(inst_hdr->inst_info.this_instname), LEN_AND_STR(udi->fn));
 			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) finish_err_code, 4,
diff --git a/sr_port/mur_forward.c b/sr_port/mur_forward.c
index e273751..9da42b3 100644
--- a/sr_port/mur_forward.c
+++ b/sr_port/mur_forward.c
@@ -116,7 +116,6 @@ uint4	mur_forward(jnl_tm_t min_broken_time, seq_num min_broken_seqno, seq_num lo
 	jgbl.dont_reset_gbl_jrec_time = jgbl.forw_phase_recovery = TRUE;
 	assert(NULL == jgbl.mur_pini_addr_reset_fnptr);
 	jgbl.mur_pini_addr_reset_fnptr = (pini_addr_reset_fnptr)mur_pini_addr_reset;
-	gv_keysize = DBKEYSIZE(MAX_KEY_SZ);
 	mu_gv_stack_init();
 	murgbl.consist_jnl_seqno = 0;
 	/* Note down passed in values in murgbl global so "mur_forward_play_cur_jrec" function can see it as well */
@@ -166,7 +165,7 @@ uint4	mur_forward(jnl_tm_t min_broken_time, seq_num min_broken_seqno, seq_num lo
 			tp_change_reg();	/* note : sets cs_addrs to non-NULL value even if gv_cur_region->open is FALSE
 						 * (cs_data could still be NULL). */
 			rctl->csa = cs_addrs;
-			cs_addrs->rctl = rctl;
+			cs_addrs->miscptr = (void *)rctl;
 			rctl->csd = cs_data;
 			rctl->sgm_info_ptr = cs_addrs->sgm_info_ptr;
 			assert(!reg->open || (NULL != cs_addrs->dir_tree));
@@ -253,8 +252,7 @@ uint4	mur_forward(jnl_tm_t min_broken_time, seq_num min_broken_seqno, seq_num lo
 		if (NULL != rctl->forw_multi)
 		{	/* This region's current journal record is part of a TP transaction waiting for other regions */
 			regcnt_stuck++;
-			if (regcnt_stuck >= murgbl.regcnt_remaining)
-				GTMASSERT;	/* Out-of-design situation. Stuck in ALL regions. */
+			assertpro(regcnt_stuck < murgbl.regcnt_remaining); /* Out-of-design situation. Stuck in ALL regions. */
 			rctl = rctl->next_rctl;	/* Move on to the next available region */
 			assert(NULL != rctl);
 			continue;
@@ -423,9 +421,9 @@ uint4	mur_forward(jnl_tm_t min_broken_time, seq_num min_broken_seqno, seq_num lo
 		assert(murgbl.ok_to_update_db || !rctl->db_updated);
 		rctl->mur_plst = NULL;	/* reset now that simulation of GT.M updates is done */
 		/* Ensure mur_block_count_correct is called if updates allowed*/
-		if ((murgbl.ok_to_update_db) && (SS_NORMAL != mur_block_count_correct(rctl)))
+		if (murgbl.ok_to_update_db && (SS_NORMAL != mur_block_count_correct(rctl)))
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_BLKCNTEDITFAIL, 2, DB_LEN_STR(rctl->gd));
+			gtm_putmsg_csa(CSA_ARG(rctl->csa) VARLSTCNT(4) ERR_BLKCNTEDITFAIL, 2, DB_LEN_STR(rctl->gd));
 			murgbl.wrn_count++;
 		}
 	}
diff --git a/sr_port/mur_forward_play_cur_jrec.c b/sr_port/mur_forward_play_cur_jrec.c
index d1f4047..d61d67b 100644
--- a/sr_port/mur_forward_play_cur_jrec.c
+++ b/sr_port/mur_forward_play_cur_jrec.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -46,10 +46,14 @@
 #include "tp_set_sgm.h"
 #include "tp_frame.h"
 #include "wbox_test_init.h"
+#include "gvnh_spanreg.h"
+#include "gtmimagename.h"
+#include "gv_trigger_common.h"	/* for *HASHT* macros used inside GVNH_REG_INIT macro */
 #ifdef GTM_CRYPT
 #include "gtmcrypt.h"
 #endif
 
+GBLREF	gd_addr			*gd_header;
 GBLREF	gv_key			*gv_currkey;
 GBLREF	gv_namehead		*gv_target;
 GBLREF  gd_region		*gv_cur_region;
@@ -72,7 +76,7 @@ static	void	(* const extraction_routine[])() =
 uint4	mur_forward_play_cur_jrec(reg_ctl_list *rctl)
 {
 	boolean_t		process_losttn;
-	boolean_t		is_set_kill_zkill_ztrig_ztworm, is_set_kill_zkill_ztrig, added;
+	boolean_t		is_set_kill_zkill_ztrig_ztworm, is_set_kill_zkill_ztrig;
 	trans_num		curr_tn;
 	enum jnl_record_type	rectype;
 	enum rec_fence_type	rec_fence;
@@ -262,7 +266,7 @@ uint4	mur_forward_play_cur_jrec(reg_ctl_list *rctl)
 		{
 			assert(FALSE);
 			murgbl.wrn_count++;
-			gtm_putmsg(VARLSTCNT(6) ERR_JNLTPNEST, 4, jctl->jnl_fn_len,
+			gtm_putmsg_csa(CSA_ARG(rctl->csa) VARLSTCNT(6) ERR_JNLTPNEST, 4, jctl->jnl_fn_len,
 				jctl->jnl_fn, jctl->rec_offset, &rec->prefix.tn);
 			OP_TROLLBACK(0);
 		}
@@ -293,36 +297,22 @@ uint4	mur_forward_play_cur_jrec(reg_ctl_list *rctl)
 		gv_currkey->base[keystr->length] = '\0';
 		gv_currkey->end = keystr->length;
 		if (gv_cur_region->open)
-		{/* find out collation of key in the jnl-record from the database corresponding to the jnl file */
+		{	/* find out collation of key in the jnl-record from the database corresponding to the jnl file */
 			gvent.var_name.addr = (char *)gv_currkey->base;
 			gvent.var_name.len = STRLEN((char *)gv_currkey->base);
 			COMPUTE_HASH_MNAME(&gvent);
-			if ((NULL !=  (tabent = lookup_hashtab_mname(&rctl->gvntab, &gvent)))
-				&& (NULL != (gvnh_reg = (gvnh_reg_t *)tabent->value)))
+			if (NULL != (tabent = lookup_hashtab_mname(&rctl->gvntab, &gvent)))	/* WARNING ASSIGNMENT */
 			{
+				gvnh_reg = (gvnh_reg_t *)tabent->value;
+				assert(NULL != gvnh_reg);
 				gv_target = gvnh_reg->gvt;
 				gv_cur_region = gvnh_reg->gd_reg;
 				assert(gv_cur_region->open);
 			} else
 			{
-				assert(gv_cur_region->max_key_size <= MAX_KEY_SZ);
-				gv_target = (gv_namehead *)targ_alloc(gv_cur_region->max_key_size,
-					&gvent, gv_cur_region);
-				gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
-				gvnh_reg->gvt = gv_target;
-				gvnh_reg->gd_reg = gv_cur_region;
-				if (NULL != tabent)
-				{	/* Since the global name was found but gv_target was null and
-					 * now we created a new gv_target, the hash table key must point
-					 * to the newly created gv_target->gvname. */
-					tabent->key = gv_target->gvname;
-					tabent->value = (char *)gvnh_reg;
-				} else
-				{
-					added = add_hashtab_mname(&rctl->gvntab, &gv_target->gvname,
-							gvnh_reg, &tabent);
-					assert(added);
-				}
+				assert((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)));
+				gv_target = (gv_namehead *)targ_alloc(gv_cur_region->max_key_size, &gvent, gv_cur_region);
+				GVNH_REG_INIT(gd_header, &rctl->gvntab, NULL, gv_target, gv_cur_region, gvnh_reg, tabent);
 			}
 			if (!TREF(jnl_extract_nocol))
 				GVCST_ROOT_SEARCH;
@@ -347,7 +337,8 @@ uint4	mur_forward_play_cur_jrec(reg_ctl_list *rctl)
 			{
 				assert(FALSE); /* We want to debug this */
 				murgbl.wrn_count++;
-				gtm_putmsg(VARLSTCNT(6) ERR_DUPTN, 4, &curr_tn, jctl->rec_offset, jctl->jnl_fn_len, jctl->jnl_fn);
+				gtm_putmsg_csa(CSA_ARG(rctl->csa)
+					VARLSTCNT(6) ERR_DUPTN, 4, &curr_tn, jctl->rec_offset, jctl->jnl_fn_len, jctl->jnl_fn);
 				if (dollar_tlevel)
 				{
 					assert(murgbl.ok_to_update_db);
diff --git a/sr_port/mur_jnl_ext.c b/sr_port/mur_jnl_ext.c
index cc5818c..d17a6ca 100644
--- a/sr_port/mur_jnl_ext.c
+++ b/sr_port/mur_jnl_ext.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,9 +29,8 @@
 #include "muprec.h"
 #include "jnl_typedef.h"
 #include "copy.h"
-#include "init_root_gv.h"
-#include "min_max.h"          	/* needed for init_root_gv.h */
-#include "format_targ_key.h"   	/* needed for init_root_gv.h */
+#include "min_max.h"
+#include "format_targ_key.h"
 #include "mlkdef.h"
 #include "zshow.h"
 #include "mur_jnl_ext.h"
@@ -43,7 +42,6 @@ GBLREF	gv_key		*gv_currkey;
 GBLREF 	mur_gbls_t	murgbl;
 GBLREF	mur_opt_struct	mur_options;
 GBLREF	boolean_t	is_updproc;
-GBLREF  mval            curr_gbl_root;
 GBLREF	char		muext_code[][2];
 LITREF	char		*jrt_label[JRT_RECTYPES];
 
@@ -192,15 +190,15 @@ void	mur_extract_set(jnl_ctl_list *jctl, fi_type *fi, jnl_record *rec, pini_list
 			extract_len += val_extr_len;
 		} else
 		{
-			gtm_putmsg(VARLSTCNT(9) ERR_JNLBADRECFMT,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_JNLBADRECFMT,
 				3, jctl->jnl_fn_len, jctl->jnl_fn, jctl->rec_offset,
 				ERR_TEXT, 2, LEN_AND_LIT("Length of the record is too high for zwr format"));
 			if (mur_options.verbose || mur_options.detail)
 			{
-				gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4,
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4,
 					LEN_AND_LIT("After max expansion record length"),
 					ZWR_EXP_RATIO(val_len), ZWR_EXP_RATIO(val_len));
-				gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("Buffer size"),
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("Buffer size"),
 					murgbl.max_extr_record_length - extract_len,
 					murgbl.max_extr_record_length - extract_len);
 			}
diff --git a/sr_port/mur_open_files.c b/sr_port/mur_open_files.c
index d6d40da..a76ae23 100644
--- a/sr_port/mur_open_files.c
+++ b/sr_port/mur_open_files.c
@@ -84,57 +84,57 @@
 #include "is_proc_alive.h"
 #include "anticipatory_freeze.h"
 
-#define RELEASE_ACCESS_CONTROL(REGLIST)									\
-{													\
-	unix_db_info		*lcl_udi;								\
-	gd_region		*lcl_reg;								\
-	reg_ctl_list		*lcl_rctl;								\
-	int			save_errno;								\
-													\
-	lcl_reg = REGLIST->reg;										\
-	lcl_rctl = REGLIST->rctl;									\
-	lcl_udi = FILE_INFO(lcl_reg);									\
-	assert(INVALID_SEMID != lcl_udi->semid);							\
-	assert(lcl_udi->grabbed_access_sem && lcl_rctl->standalone);					\
-	if (0 != (save_errno = do_semop(lcl_udi->semid, DB_CONTROL_SEM, -1, SEM_UNDO)))			\
-	{												\
-		assert(FALSE);	/* we hold it, so we should be able to release it*/			\
-		rts_error(VARLSTCNT(12) ERR_CRITSEMFAIL, 2, DB_LEN_STR(lcl_reg), ERR_SYSCALL, 5,	\
-				RTS_ERROR_LITERAL("semop()"), CALLFROM, save_errno);			\
-	}												\
-	lcl_udi->grabbed_access_sem = FALSE;								\
-	lcl_rctl->standalone = FALSE;									\
+#define RELEASE_ACCESS_CONTROL(REGLIST)												\
+{																\
+	unix_db_info		*lcl_udi;											\
+	gd_region		*lcl_reg;											\
+	reg_ctl_list		*lcl_rctl;											\
+	int			save_errno;											\
+																\
+	lcl_reg = REGLIST->reg;													\
+	lcl_rctl = REGLIST->rctl;												\
+	lcl_udi = FILE_INFO(lcl_reg);												\
+	assert(INVALID_SEMID != lcl_udi->semid);										\
+	assert(lcl_udi->grabbed_access_sem && lcl_rctl->standalone);								\
+	if (0 != (save_errno = do_semop(lcl_udi->semid, DB_CONTROL_SEM, -1, SEM_UNDO)))						\
+	{															\
+		assert(FALSE);	/* we hold it, so we should be able to release it*/						\
+		rts_error_csa(CSA_ARG(REG2CSA(lcl_reg)) VARLSTCNT(12) ERR_CRITSEMFAIL, 2, DB_LEN_STR(lcl_reg), ERR_SYSCALL, 5,	\
+				RTS_ERROR_LITERAL("semop()"), CALLFROM, save_errno);						\
+	}															\
+	lcl_udi->grabbed_access_sem = FALSE;											\
+	lcl_rctl->standalone = FALSE;												\
 }
 
-#define GRAB_ACCESS_CONTROL(REGLIST)									\
-{													\
-	unix_db_info		*lcl_udi;								\
-	gd_region		*lcl_reg;								\
-	reg_ctl_list		*lcl_rctl;								\
-	int			save_errno, sopcnt, status;						\
-	struct sembuf		sop[3];									\
-													\
-	SET_GTM_SOP_ARRAY(sop, sopcnt, FALSE, SEM_UNDO);						\
-	assert(2 == sopcnt);										\
-	lcl_reg = REGLIST->reg;										\
-	lcl_rctl = REGLIST->rctl;									\
-	lcl_udi = FILE_INFO(lcl_reg);									\
-	assert(INVALID_SEMID != lcl_udi->semid);							\
-	if (lcl_udi->grabbed_access_sem)								\
-		assert(lcl_rctl->standalone);								\
-	else												\
-	{												\
-		SEMOP(lcl_udi->semid, sop, sopcnt, status, NO_WAIT);					\
-		if (0 != status)									\
-		{											\
-			save_errno = errno;								\
-			assert(FALSE);									\
-			rts_error(VARLSTCNT(12) ERR_CRITSEMFAIL, 2, DB_LEN_STR(lcl_reg), ERR_SYSCALL, 5,\
-					RTS_ERROR_LITERAL("semop()"), CALLFROM, save_errno);		\
-		}											\
-		lcl_udi->grabbed_access_sem = TRUE;					\
-		lcl_rctl->standalone = TRUE;								\
-	}												\
+#define GRAB_ACCESS_CONTROL(REGLIST)											\
+{															\
+	unix_db_info		*lcl_udi;										\
+	gd_region		*lcl_reg;										\
+	reg_ctl_list		*lcl_rctl;										\
+	int			save_errno, sopcnt, status;								\
+	struct sembuf		sop[3];											\
+															\
+	SET_GTM_SOP_ARRAY(sop, sopcnt, FALSE, SEM_UNDO);								\
+	assert(2 == sopcnt);												\
+	lcl_reg = REGLIST->reg;												\
+	lcl_rctl = REGLIST->rctl;											\
+	lcl_udi = FILE_INFO(lcl_reg);											\
+	assert(INVALID_SEMID != lcl_udi->semid);									\
+	if (lcl_udi->grabbed_access_sem)										\
+		assert(lcl_rctl->standalone);										\
+	else														\
+	{														\
+		SEMOP(lcl_udi->semid, sop, sopcnt, status, NO_WAIT);							\
+		if (0 != status)											\
+		{													\
+			save_errno = errno;										\
+			assert(FALSE);											\
+			rts_error_csa(CSA_ARG(REG2CSA(lcl_reg)) VARLSTCNT(12) ERR_CRITSEMFAIL, 2, DB_LEN_STR(lcl_reg),	\
+					ERR_SYSCALL, 5, RTS_ERROR_LITERAL("semop()"), CALLFROM, save_errno);		\
+		}													\
+		lcl_udi->grabbed_access_sem = TRUE;									\
+		lcl_rctl->standalone = TRUE;										\
+	}														\
 }
 #endif
 
@@ -244,6 +244,7 @@ boolean_t mur_open_files()
 	DEBUG_ONLY(int			semval;)
 	DEBUG_ONLY(jnl_buffer_ptr_t	jb;)
 #	endif
+	boolean_t			recov_interrupted;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -258,7 +259,7 @@ boolean_t mur_open_files()
 		star_specified = TRUE;
 		if (NULL != mur_options.redirect)
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_STARFILE, 2, LEN_AND_LIT("REDIRECT qualifier"));
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STARFILE, 2, LEN_AND_LIT("REDIRECT qualifier"));
 			mupip_exit(ERR_MUPCLIERR);
 		}
 	} else
@@ -266,7 +267,7 @@ boolean_t mur_open_files()
 		star_specified = FALSE;
 		if (mur_options.rollback)
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_NOSTARFILE, 2, LEN_AND_LIT("ROLLBACK qualifier"));
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_NOSTARFILE, 2, LEN_AND_LIT("ROLLBACK qualifier"));
 			mupip_exit(ERR_MUPCLIERR);
 		}
 	}
@@ -331,7 +332,7 @@ boolean_t mur_open_files()
 		if (!get_full_path(replpool_id.gtmgbldir, tran_name->len,
 				replpool_id.gtmgbldir, &full_len, MAX_TRANS_NAME_LEN, &status))
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_FILENOTFND, 2, tran_name->len, tran_name->addr);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FILENOTFND, 2, tran_name->len, tran_name->addr);
 			return FALSE;
 		}
 		else
@@ -344,11 +345,11 @@ boolean_t mur_open_files()
 			replpool_id.pool_type = JNLPOOL_SEGMENT;
 			sgmnt_found = FALSE;
 			if (mu_rndwn_replpool(&replpool_id, FALSE, &sgmnt_found) && sgmnt_found)
-				gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
 						tran_name->len, replpool_id.gtmgbldir);
 			else if (sgmnt_found)
 			{
-				gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, res_name[0], &res_name[1],
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, res_name[0], &res_name[1],
 						tran_name->len, replpool_id.gtmgbldir);
 				return FALSE;
 			}
@@ -358,11 +359,11 @@ boolean_t mur_open_files()
 			replpool_id.pool_type = RECVPOOL_SEGMENT;
 			sgmnt_found = FALSE;
 			if (mu_rndwn_replpool(&replpool_id, FALSE, &sgmnt_found) && sgmnt_found)
-				gtm_putmsg(VARLSTCNT(6) ERR_MURPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MURPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
 						tran_name->len, replpool_id.gtmgbldir);
 			else if (sgmnt_found)
 			{
-				gtm_putmsg(VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, res_name[0], &res_name[1],
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, res_name[0], &res_name[1],
 					tran_name->len, replpool_id.gtmgbldir);
 				return FALSE;
 			}
@@ -405,7 +406,7 @@ boolean_t mur_open_files()
 			rctl->db_present = FALSE;
 			if (mur_options.update || star_specified)
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_FILENOTFND, 2, DB_LEN_STR(rctl->gd));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FILENOTFND, 2, DB_LEN_STR(rctl->gd));
 				return FALSE;
 			}
 		} else
@@ -420,7 +421,8 @@ boolean_t mur_open_files()
 					VMS_ONLY(gv_cur_region = rctl->gd); /* VMS mu_rndwn_file() assumes gv_cur_region is set */
 					if (!STANDALONE(rctl->gd))	/* STANDALONE macro calls mu_rndwn_file() */
 					{
-						gtm_putmsg(VARLSTCNT(4) ERR_MUSTANDALONE, 2, DB_LEN_STR(rctl->gd));
+						gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSTANDALONE, 2,
+							       DB_LEN_STR(rctl->gd));
 						return FALSE;
 					}
 					rctl->standalone = TRUE;
@@ -437,8 +439,8 @@ boolean_t mur_open_files()
 				{
 					if (!cs_data->fully_upgraded)
 					{
-						gtm_putmsg(VARLSTCNT(6) ERR_ORLBKNOV4BLK, 4, REG_LEN_STR(gv_cur_region),
-								DB_LEN_STR(gv_cur_region));
+						gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) ERR_ORLBKNOV4BLK, 4,
+							       REG_LEN_STR(gv_cur_region), DB_LEN_STR(gv_cur_region));
 						return FALSE;
 					}
 					max_epoch_interval = MAX(cs_data->epoch_interval, max_epoch_interval);
@@ -452,7 +454,8 @@ boolean_t mur_open_files()
 					UNIX_ONLY(assert((FILE_INFO(rctl->gd))->grabbed_access_sem));
 					if (rctl->gd->read_only)
 					{	/* recover/rollback cannot proceed if the process has read-only permissions */
-						gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(rctl->gd));
+						gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2,
+							       DB_LEN_STR(rctl->gd));
 						return FALSE;
 					}
 				}
@@ -469,10 +472,10 @@ boolean_t mur_open_files()
 	{
 		inst_requires_rlbk = FALSE;
 		udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
-		send_msg(VARLSTCNT(6) ERR_ORLBKSTART, 4, LEN_AND_STR(jnlpool.repl_inst_filehdr->inst_info.this_instname),
-				LEN_AND_STR(udi->fn));
-		gtm_putmsg(VARLSTCNT(6) ERR_ORLBKSTART, 4, LEN_AND_STR(jnlpool.repl_inst_filehdr->inst_info.this_instname),
-				LEN_AND_STR(udi->fn));
+		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ORLBKSTART, 4,
+			     LEN_AND_STR(jnlpool.repl_inst_filehdr->inst_info.this_instname), LEN_AND_STR(udi->fn));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ORLBKSTART, 4,
+			       LEN_AND_STR(jnlpool.repl_inst_filehdr->inst_info.this_instname), LEN_AND_STR(udi->fn));
 		/* Need to get the gtmsource_srv_latch BEFORE grab_crit to avoid deadlocks */
 		if (NULL != jnlpool_ctl)
 		{
@@ -539,10 +542,10 @@ boolean_t mur_open_files()
 			}
 			assert((NULL != save_rl) && (tmpcsa->region == save_rl->reg));
 			GET_CUR_TIME;
-			send_msg(VARLSTCNT(8) ERR_ORLBKFRZPROG, 6, CTIME_BEFORE_NL, time_ptr, REG_LEN_STR(save_rl->reg),
-					DB_LEN_STR(save_rl->reg));
-			gtm_putmsg(VARLSTCNT(8) ERR_ORLBKFRZPROG, 6, CTIME_BEFORE_NL, time_ptr, REG_LEN_STR(save_rl->reg),
-					DB_LEN_STR(save_rl->reg));
+			send_msg_csa(CSA_ARG(REG2CSA(save_rl->reg)) VARLSTCNT(8) ERR_ORLBKFRZPROG, 6, CTIME_BEFORE_NL, time_ptr,
+				     REG_LEN_STR(save_rl->reg), DB_LEN_STR(save_rl->reg));
+			gtm_putmsg_csa(CSA_ARG(REG2CSA(save_rl->reg)) VARLSTCNT(8) ERR_ORLBKFRZPROG, 6, CTIME_BEFORE_NL, time_ptr,
+				       REG_LEN_STR(save_rl->reg), DB_LEN_STR(save_rl->reg));
 			while (tmpcsd->freeze)
 			{
 				if (MAXHARDCRITS < llcnt)
@@ -550,10 +553,10 @@ boolean_t mur_open_files()
 				llcnt++;
 			}
 			GET_CUR_TIME;
-			send_msg(VARLSTCNT(8) ERR_ORLBKFRZOVER, 6, CTIME_BEFORE_NL, time_ptr, REG_LEN_STR(save_rl->reg),
-					DB_LEN_STR(save_rl->reg));
-			gtm_putmsg(VARLSTCNT(8) ERR_ORLBKFRZOVER, 6, CTIME_BEFORE_NL, time_ptr, REG_LEN_STR(save_rl->reg),
-					DB_LEN_STR(save_rl->reg));
+			send_msg_csa(CSA_ARG(REG2CSA(save_rl->reg)) VARLSTCNT(8) ERR_ORLBKFRZOVER, 6, CTIME_BEFORE_NL, time_ptr,
+				     REG_LEN_STR(save_rl->reg), DB_LEN_STR(save_rl->reg));
+			gtm_putmsg_csa(CSA_ARG(REG2CSA(save_rl->reg)) VARLSTCNT(8) ERR_ORLBKFRZOVER, 6, CTIME_BEFORE_NL, time_ptr,
+				       REG_LEN_STR(save_rl->reg), DB_LEN_STR(save_rl->reg));
 		}
 		inst_requires_rlbk |= TREF(wcs_recover_done);
 		assert(x_lock); /* Now we have crit on all the regions (for this global directory) */
@@ -601,16 +604,15 @@ boolean_t mur_open_files()
 				assert(cs_addrs->nl->wcs_phase2_commit_pidcnt); /* only reason why wcs_flu can fail */
 				SET_TRACEABLE_VAR(cs_addrs->nl->wc_blocked, TRUE);
 				BG_TRACE_PRO_ANY(cs_addrs, wc_blocked_onln_rlbk);
-				send_msg(VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wc_blocked_onln_rlbk"),
-						process_id, &cs_addrs->ti->curr_tn, DB_LEN_STR(gv_cur_region));
+				send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wc_blocked_onln_rlbk"),
+					 process_id, &cs_addrs->ti->curr_tn, DB_LEN_STR(gv_cur_region));
 				inst_requires_rlbk = TRUE;
 				assert(TREF(donot_write_inctn_in_wcs_recover)); /* should still be set to TRUE */
 				wcs_recover(reg);
 				/* Now that wcs_recover is done, do a wcs_flu(WCSFLU_NONE) once again. This time we don't expect
 				 * wcs_flu to error out.
 				 */
-				if (!wcs_flu(WCSFLU_NONE))
-					GTMASSERT;
+				assertpro(wcs_flu(WCSFLU_NONE));
 			}
 			assert(0 == cs_addrs->nl->wcs_phase2_commit_pidcnt); /* should be zero after wcs_flu and wcs_recover */
 			/* we played with access control lock before, make sure we hold it on all regions now */
@@ -628,7 +630,8 @@ boolean_t mur_open_files()
 			}
 #			endif
 			if (cs_data->kill_in_prog)
-				gtm_putmsg(VARLSTCNT(6) ERR_MUKILLIP, 4, DB_LEN_STR(reg), LEN_AND_LIT("ONLINE ROLLBACK"));
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) ERR_MUKILLIP, 4, DB_LEN_STR(reg),
+					       LEN_AND_LIT("ONLINE ROLLBACK"));
 			/* Ensure that inhibit_kills is ZERO at this point. This is because, we hold crit at this point and anyone
 			 * who wants to set inhibit_kills need crit. The reason this is important is because t_end/tp_tend has
 			 * logic to restart if inhibit_kills is set to TRUE and we don't want online rollback to restart
@@ -666,7 +669,8 @@ boolean_t mur_open_files()
 					 */
 					if (mur_options.forward)
 					{	/* error out. need fresh backup of database for forward recovery */
-						gtm_putmsg(VARLSTCNT(4) ERR_MUPJNLINTERRUPT, 2, DB_LEN_STR(rctl->gd));
+						gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_MUPJNLINTERRUPT, 2,
+							       DB_LEN_STR(rctl->gd));
 						ENABLE_INTERRUPTS(INTRPT_IN_MUR_OPEN_FILES);
 						return FALSE;
 					}
@@ -694,7 +698,8 @@ boolean_t mur_open_files()
 #						endif
 						if (interrupted_rollback)
 						{
-							gtm_putmsg(VARLSTCNT(4) ERR_ROLLBKINTERRUPT, 2, DB_LEN_STR(rctl->gd));
+							gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_ROLLBKINTERRUPT, 2,
+								       DB_LEN_STR(rctl->gd));
 							ENABLE_INTERRUPTS(INTRPT_IN_MUR_OPEN_FILES);
 							return FALSE;
 						}
@@ -716,7 +721,8 @@ boolean_t mur_open_files()
 						{
 							if (!star_specified)
 							{
-								gtm_putmsg(VARLSTCNT(4) ERR_JNLSTATEOFF, 2, DB_LEN_STR(rctl->gd));
+								gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_JNLSTATEOFF, 2,
+									       DB_LEN_STR(rctl->gd));
 								return FALSE;
 							}
 							continue;
@@ -731,7 +737,8 @@ boolean_t mur_open_files()
 							 */
 							if (REPL_ALLOWED(csd) || JNL_ENABLED(csd))
 							{
-								gtm_putmsg(VARLSTCNT(4) ERR_REPLSTATEOFF, 2, DB_LEN_STR(rctl->gd));
+								gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_REPLSTATEOFF, 2,
+									       DB_LEN_STR(rctl->gd));
 								return FALSE;
 							}
 							continue;
@@ -743,7 +750,8 @@ boolean_t mur_open_files()
 							 */
 							if (!mur_options.fetchresync_port && !mur_options.resync_specified)
 							{
-								gtm_putmsg(VARLSTCNT(4) ERR_RLBKNOBIMG, 2, DB_LEN_STR(rctl->gd));
+								gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_RLBKNOBIMG, 2,
+									       DB_LEN_STR(rctl->gd));
 								return FALSE;
 							}
 							mur_options.rollback_losttnonly = TRUE;
@@ -762,10 +770,12 @@ boolean_t mur_open_files()
 						assert(REG_FREEZE_SUCCESS == reg_frz_status);
 						if (REG_ALREADY_FROZEN == reg_frz_status)
 						{
-							gtm_putmsg(VARLSTCNT(4) ERR_DBFRZRESETFL, 2, DB_LEN_STR(rctl->gd));
+							gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBFRZRESETFL, 2,
+								       DB_LEN_STR(rctl->gd));
 							return FALSE;
 						}
-						gtm_putmsg(VARLSTCNT(4) ERR_DBFRZRESETSUC, 2, DB_LEN_STR(rctl->gd));
+						gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_DBFRZRESETSUC, 2,
+							       DB_LEN_STR(rctl->gd));
 					}
 					/* save current jnl/repl state before changing in case recovery is interrupted */
 					csd->intrpt_recov_jnl_state = csd->jnl_state;
@@ -800,7 +810,7 @@ boolean_t mur_open_files()
 				 * In this case csa is NULL */
 				if (!file_head_read((char *)rctl->gd->dyn.addr->fname, rctl->csd, SGMNT_HDR_LEN))
 				{
-					gtm_putmsg(VARLSTCNT(4) ERR_DBFILOPERR, 2, REG_LEN_STR(rctl->gd));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBFILOPERR, 2, REG_LEN_STR(rctl->gd));
 					return FALSE;
 				}
 				rctl->jnl_state = csd->jnl_state;
@@ -828,8 +838,9 @@ boolean_t mur_open_files()
 				}
 				if (SS_NORMAL != (jctl->status = mur_fread_eof(jctl, rctl)))
 				{
-					gtm_putmsg(VARLSTCNT(9) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len, jctl->jnl_fn,
-						jctl->rec_offset, ERR_TEXT, 2, LEN_AND_LIT("mur_fread_eof failed"));
+					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len,
+						       jctl->jnl_fn, jctl->rec_offset, ERR_TEXT, 2,
+						       LEN_AND_LIT("mur_fread_eof failed"));
 					return FALSE;
 				}
 				assert((csa == rctl->csa) || !mur_options.update);
@@ -849,25 +860,28 @@ boolean_t mur_open_files()
 				}
 				if (mur_options.verbose)
 				{
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4, LEN_AND_LIT("Module : mur_open_files"),
-							LEN_AND_LIT("Post mur_fread_eof details"));
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4, LEN_AND_LIT("    Journal file"),
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,
+						       LEN_AND_LIT("Module : mur_open_files"),
+						       LEN_AND_LIT("Post mur_fread_eof details"));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4, LEN_AND_LIT("    Journal file"),
 							JNL_LEN_STR(rctl->csd));
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Last valid record offset"),
-							jctl->lvrec_off, jctl->lvrec_off);
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOUINT4, 4, LEN_AND_LIT("    Last valid record time"),
-							jctl->lvrec_time, jctl->lvrec_time);
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4,
+						       LEN_AND_LIT("    Last valid record offset"),
+						       jctl->lvrec_off, jctl->lvrec_off);
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOUINT4, 4,
+						       LEN_AND_LIT("    Last valid record time"), jctl->lvrec_time,
+						       jctl->lvrec_time);
 					verbose_ptr = jctl->tail_analysis ? "TRUE" : "FALSE";
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4, LEN_AND_LIT("      Tail analysis done"),
-							LEN_AND_STR(verbose_ptr));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,
+						       LEN_AND_LIT("      Tail analysis done"), LEN_AND_STR(verbose_ptr));
 					verbose_ptr = jctl->properly_closed ? "TRUE" : "FALSE";
-					gtm_putmsg(VARLSTCNT(6) ERR_MUINFOSTR, 4, LEN_AND_LIT("      Properly closed"),
-							LEN_AND_STR(verbose_ptr));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUINFOSTR, 4,
+						       LEN_AND_LIT("      Properly closed"), LEN_AND_STR(verbose_ptr));
 				}
 #				endif
 				if (!is_file_identical((char *)jctl->jfh->data_file_name, (char *)rctl->gd->dyn.addr->fname))
 				{
-					gtm_putmsg(VARLSTCNT(8) ERR_DBJNLNOTMATCH, 6, DB_LEN_STR(rctl->gd),
+					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_DBJNLNOTMATCH, 6, DB_LEN_STR(rctl->gd),
 						jctl->jnl_fn_len, jctl->jnl_fn,
 						jctl->jfh->data_file_name_length, jctl->jfh->data_file_name);
 					return FALSE;
@@ -898,7 +912,8 @@ boolean_t mur_open_files()
 			if (!get_full_path(cptr_last, (unsigned int)(cptr - cptr_last),
 						(char *)jctl->jnl_fn, &jctl->jnl_fn_len, MAX_FN_LEN, &jctl->status2))
 			{
-				gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, cptr_last, cptr - cptr_last, jctl->status2);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_FILEPARSE, 2, cptr_last, cptr - cptr_last,
+					       jctl->status2);
 				return FALSE;
 			}
 			cptr++;	/* skip separator */
@@ -933,8 +948,8 @@ boolean_t mur_open_files()
 							break;
 					}
 				}
-				if (rctl == rctl_top)
-					GTMASSERT;/* db list was created from journal file header. So it is not possible */
+				/* db list was created from journal file header. So it is not possible */
+				assertpro(rctl != rctl_top);
 			}
 			/* Detect and report 1st case of any duplicated files in mupip forward recovery command. */
 			if (mur_options.forward)
@@ -949,8 +964,9 @@ boolean_t mur_open_files()
 						if (UNIX_ONLY(is_gdid_identical(&jctl->fid, &temp_jctl->fid))
 							VMS_ONLY(is_gdid_gdid_identical(&jctl->fid, &temp_jctl->fid)))
 						{
-							gtm_putmsg(VARLSTCNT(6) ERR_JNLFILEDUP, 4, jctl->jnl_fn_len,
-								jctl->jnl_fn, temp_jctl->jnl_fn_len, temp_jctl->jnl_fn);
+							gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(6) ERR_JNLFILEDUP, 4,
+								       jctl->jnl_fn_len, jctl->jnl_fn, temp_jctl->jnl_fn_len,
+								       temp_jctl->jnl_fn);
 							return FALSE;
 						}
 					}
@@ -958,15 +974,16 @@ boolean_t mur_open_files()
 				}
 				else
 				{
-					gtm_putmsg(VARLSTCNT(11) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn,
-						ERR_SYSCALL, 5, LEN_AND_LIT("fstat"), CALLFROM, errno);
+					gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(11) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len,
+						       jctl->jnl_fn, ERR_SYSCALL, 5, LEN_AND_LIT("fstat"), CALLFROM, errno);
 					return FALSE;
 				}
 #				endif
 			}
 			if (SS_NORMAL != (jctl->status = mur_fread_eof(jctl, rctl)))
 			{
-				gtm_putmsg(VARLSTCNT(5) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len, jctl->jnl_fn, jctl->rec_offset);
+				gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(5) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len,
+					       jctl->jnl_fn, jctl->rec_offset);
 				return FALSE;
 			}
 			/* Now, we have found the region for this jctl */
@@ -976,8 +993,8 @@ boolean_t mur_open_files()
 				rctl->jctl = rctl->jctl_head = jctl;
 				if (mur_options.update && !is_file_identical((char *)csd->jnl_file_name, (char *)jctl->jnl_fn))
 				{
-					gtm_putmsg(VARLSTCNT(8) ERR_JNLNMBKNOTPRCD, 6, jctl->jnl_fn_len, jctl->jnl_fn,
-							JNL_LEN_STR(csd), DB_LEN_STR(rctl->gd));
+					gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(8) ERR_JNLNMBKNOTPRCD, 6, jctl->jnl_fn_len,
+						       jctl->jnl_fn, JNL_LEN_STR(csd), DB_LEN_STR(rctl->gd));
 					return FALSE;
 				}
 			} else
@@ -1043,9 +1060,9 @@ boolean_t mur_open_files()
 	}
 	assert(murgbl.reg_full_total == max_reg_total);
 	if (!mur_options.rollback && murgbl.reg_total < murgbl.reg_full_total)
-		gtm_putmsg(VARLSTCNT (1) ERR_NOTALLJNLEN);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT (1) ERR_NOTALLJNLEN);
 	else if (mur_options.rollback && murgbl.reg_total < murgbl.reg_full_total)
-		gtm_putmsg(VARLSTCNT (1) ERR_NOTALLREPLON);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT (1) ERR_NOTALLREPLON);
 	if (0 == murgbl.reg_total)
 		return FALSE;
 	/* From this point consider only regions with journals to be processed (murgbl.reg_total)
@@ -1064,10 +1081,11 @@ boolean_t mur_open_files()
 				{
 					if (0 == jctl->jfh->prev_jnl_file_name_length)
 					{
-						gtm_putmsg(VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9,jctl->jnl_fn_len, jctl->jnl_fn,
-							LEN_AND_LIT("beginning"), &jctl->jfh->bov_tn,
-							DB_LEN_STR(rctl->gd), &csd->trans_hist.curr_tn, &csd->jnl_eovtn);
-						gtm_putmsg(VARLSTCNT(4) ERR_NOPREVLINK, 2,
+						gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9,
+							       jctl->jnl_fn_len, jctl->jnl_fn, LEN_AND_LIT("beginning"),
+							       &jctl->jfh->bov_tn, DB_LEN_STR(rctl->gd), &csd->trans_hist.curr_tn,
+							       &csd->jnl_eovtn);
+						gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(4) ERR_NOPREVLINK, 2,
 								jctl->jnl_fn_len, jctl->jnl_fn);
 						return FALSE;
 					} else if (!mur_insert_prev(&jctl))
@@ -1078,15 +1096,19 @@ boolean_t mur_open_files()
 			{
 				if (!mur_options.notncheck && (jctl->jfh->bov_tn != csd->trans_hist.curr_tn))
 				{
-					gtm_putmsg(VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9, jctl->jnl_fn_len, jctl->jnl_fn,
-						LEN_AND_LIT("beginning"), &jctl->jfh->bov_tn,
-						DB_LEN_STR(rctl->gd), &csd->trans_hist.curr_tn, &csd->jnl_eovtn);
+					gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9,
+						       jctl->jnl_fn_len, jctl->jnl_fn, LEN_AND_LIT("beginning"),
+						       &jctl->jfh->bov_tn, DB_LEN_STR(rctl->gd),
+						       &csd->trans_hist.curr_tn, &csd->jnl_eovtn);
 					return FALSE;
 				}
 			} else /* Backward Recovery */
 			{
 				if (jctl->jfh->eov_tn != csd->trans_hist.curr_tn)
-				{	/* 'outofsync' variable identifies situations in which backward recovery
+				{
+					recov_interrupted = rctl->recov_interrupted || csd->intrpt_recov_resync_seqno
+								|| csd->intrpt_recov_tp_resolve_time;
+					/* 'outofsync' variable identifies situations in which backward recovery
 					 * proceeds if inequality (csd->jnl_eovtn <= jfh->eov_tn <= csd->curr_tn) is TRUE.
 					 * So if,
 					 * i)   backward recovery is interrupted at any time except at turn around point just after
@@ -1100,16 +1122,17 @@ boolean_t mur_open_files()
 					 *iii)  outofsync is TRUE but above mentioned inequality is FALSE and
 					 *      interruption or crash did not occur while processing turn around point
 					 */
-					outofsync = (rctl->recov_interrupted ||
+					outofsync = (recov_interrupted ||
 					  	     (jctl->jfh->crash && (jctl->jfh->eov_tn < csd->trans_hist.curr_tn)));
 					if ((jctl->jfh->crash && (jctl->jfh->eov_tn > csd->trans_hist.curr_tn) &&
-						!rctl->recov_interrupted) || (!jctl->jfh->crash && !outofsync) ||
+						!recov_interrupted) || (!jctl->jfh->crash && !outofsync) ||
 						(outofsync && !csd->turn_around_point && (csd->jnl_eovtn != csd->trans_hist.curr_tn)
 						  && (csd->jnl_eovtn > jctl->jfh->eov_tn)))
 					{
-						gtm_putmsg(VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9,	jctl->jnl_fn_len, jctl->jnl_fn,
-						LEN_AND_LIT("end"), &jctl->jfh->eov_tn, DB_LEN_STR(rctl->gd),
-						&csd->trans_hist.curr_tn, &csd->jnl_eovtn);
+						gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(11) ERR_JNLDBTNNOMATCH, 9,
+							       jctl->jnl_fn_len, jctl->jnl_fn, LEN_AND_LIT("end"),
+							       &jctl->jfh->eov_tn, DB_LEN_STR(rctl->gd), &csd->trans_hist.curr_tn,
+							       &csd->jnl_eovtn);
 						return FALSE;
 					}
 				}
@@ -1132,9 +1155,9 @@ boolean_t mur_open_files()
 		{
 			if (!mur_options.notncheck && (jctl->next_gen->jfh->bov_tn != jctl->jfh->eov_tn))
 			{
-				gtm_putmsg(VARLSTCNT(8) ERR_JNLTNOUTOFSEQ, 6,
-					&jctl->jfh->eov_tn, jctl->jnl_fn_len, jctl->jnl_fn,
-					&jctl->next_gen->jfh->bov_tn, jctl->next_gen->jnl_fn_len, jctl->next_gen->jnl_fn);
+				gtm_putmsg_csa(CSA_ARG(JCTL2CSA(jctl)) VARLSTCNT(8) ERR_JNLTNOUTOFSEQ, 6,
+					       &jctl->jfh->eov_tn, jctl->jnl_fn_len, jctl->jnl_fn,
+					       &jctl->next_gen->jfh->bov_tn, jctl->next_gen->jnl_fn_len, jctl->next_gen->jnl_fn);
 				return FALSE;
 			}
 			jctl = jctl->next_gen;
diff --git a/sr_port/mur_output_record.c b/sr_port/mur_output_record.c
index 621d085..181d12b 100644
--- a/sr_port/mur_output_record.c
+++ b/sr_port/mur_output_record.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -99,7 +99,9 @@ uint4	mur_output_record(reg_ctl_list *rctl)
 	blk_hdr_ptr_t		aimg_blk_ptr;
 	int			in_len, gtmcrypt_errno ;
 #	endif
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	assert(mur_options.update);
 	rec = rctl->mur_desc->jnlrec;
 	rectype = (enum jnl_record_type)rec->prefix.jrec_type;
@@ -155,6 +157,16 @@ uint4	mur_output_record(reg_ctl_list *rctl)
 			)
 		}
 	}
+	/* Assert that TREF(gd_targ_gvnh_reg) is NULL for every update that journal recovery/rollback plays forward;
+	 * This is necessary to ensure every update is played in only the database file where the journal record is seen
+	 * instead of across all regions that span the particular global reference. For example if ^a(1) spans db files
+	 * a.dat and b.dat, and a KILL ^a(1) is done at the user level, we would see KILL ^a(1) journal records in a.mjl
+	 * and b.mjl. When journal recovery processes the journal record in a.mjl, it should do the kill only in a.dat
+	 * When it gets to the same journal record in b.mjl, it would do the same kill in b.dat and effectively complete
+	 * the user level KILL ^a(1). If instead recovery does the KILL across all spanned regions, we would be basically
+	 * doing duplicate work let alone do it out-of-order since recovery goes region by region for the most part.
+	 */
+	assert(NULL == TREF(gd_targ_gvnh_reg));
 	if (IS_SET_KILL_ZKILL_ZTRIG(rectype))
 	{	/* TP and non-TP has same format */
 		keystr = (jnl_string *)&rec->jrec_set_kill.mumps_node;
@@ -360,9 +372,10 @@ uint4	mur_output_record(reg_ctl_list *rctl)
 			} else
 			{
 				if (SS_NORMAL != csa->jnl->status)
-					rts_error(VARLSTCNT(7) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg), csa->jnl->status);
+					rts_error_csa(CSA_ARG(csa)
+						VARLSTCNT(7) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg), csa->jnl->status);
 				else
-					rts_error(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg));
+					rts_error_csa(CSA_ARG(csa) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg));
 			}
 			if (!was_crit)
 				rel_crit(reg);
diff --git a/sr_port/mur_pini_addr_reset.c b/sr_port/mur_pini_addr_reset.c
index 6250ec9..b092d58 100644
--- a/sr_port/mur_pini_addr_reset.c
+++ b/sr_port/mur_pini_addr_reset.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,7 +34,7 @@ void	mur_pini_addr_reset(sgmnt_addrs *csa)
 	pini_list_struct	*plst;
 	ht_ent_int4 		*tabent, *topent;
 
-	rctl = csa->rctl;
+	rctl = (reg_ctl_list *)csa->miscptr;
 	assert(NULL != rctl);
 	jctl = rctl->jctl;
 	assert(NULL != jctl);
diff --git a/sr_port/mutex_deadlock_check.c b/sr_port/mutex_deadlock_check.c
index 9875827..fc1de9a 100644
--- a/sr_port/mutex_deadlock_check.c
+++ b/sr_port/mutex_deadlock_check.c
@@ -126,8 +126,12 @@ void mutex_deadlock_check(mutex_struct_ptr_t criticalPtr, sgmnt_addrs *csa)
 			{	/* grab_lock going for crit on the jnlpool region. gv_cur_region points to the current region of
 				 * interest, which better have REPL_ENABLED or REPL_WAS_ENABLED, and be now crit
 				 */
-				assert(cs_addrs == &FILE_INFO(gv_cur_region)->s_addrs);
-				cs_addrs->crit_check_cycle = crit_deadlock_check_cycle; /* allow for crit in gv_cur_region */
+				if ((NULL != cs_addrs) && cs_addrs->now_crit)
+				{	/* cs_addrs can be NULL if it is open, but there is no update on that region */
+					assert(cs_addrs == &FILE_INFO(gv_cur_region)->s_addrs);
+					/* allow for crit in gv_cur_region */
+					cs_addrs->crit_check_cycle = crit_deadlock_check_cycle;
+				}
 			}
 		} else
                 {       /* Need to mark the regions allowed to have crit as follows: Place the current cycle into the csa's of
diff --git a/sr_port/mval2subsc.c b/sr_port/mval2subsc.c
index cc8eae8..50ca367 100644
--- a/sr_port/mval2subsc.c
+++ b/sr_port/mval2subsc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -23,8 +23,7 @@
 #include "do_xform.h"
 #include "format_targ_key.h"
 
-GBLREF gv_namehead	*gv_target;
-GBLREF gd_region       *gv_cur_region;
+GBLREF	gv_namehead	*gv_target;
 
 static readonly unsigned char pos_code[100] =
 {
@@ -54,7 +53,7 @@ static readonly unsigned char neg_code[100] =
 	0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65
 };
 
-unsigned char *mval2subsc(mval *in_val, gv_key *out_key)
+unsigned char *mval2subsc(mval *in_val, gv_key *out_key, boolean_t std_null_coll)
 {
 	boolean_t	is_negative;
 	unsigned char	buf1[MAX_KEY_SZ + 1], ch, *cvt_table, *in_ptr, *out_ptr;
@@ -75,8 +74,11 @@ unsigned char *mval2subsc(mval *in_val, gv_key *out_key)
 	 * of trouble with $ORDER in a database when -1 was treated as a string. This assert is not a 100%
 	 * catchall of invalid settings but it provides at least some barrier. A full barrier would require
 	 * complete conversion which is a bit expensive to always re-do at this point - even in a dbg version.
+	 * There is an exception though and that is if the caller is op_fnview. In that case, it could set
+	 * MV_NUM_APPROX to indicate a number needs to be treated as a string subscript. Skip that in the assert.
 	 */
-	assert(!(MV_NUM_APPROX & in_val->mvtype) || (NUM_DEC_DG_2L < in_val->str.len) || !val_iscan(in_val));
+	assert(!(MV_NUM_APPROX & in_val->mvtype) || (NUM_DEC_DG_2L < in_val->str.len) || !val_iscan(in_val)
+		|| TREF(skip_mv_num_approx_assert));
 	out_ptr = out_key->base + out_key->end;
 	if (TREF(transform) && gv_target->nct)
 	{
@@ -120,7 +122,7 @@ unsigned char *mval2subsc(mval *in_val, gv_key *out_key)
 		 */
 		avail_bytes = out_key->top - (out_key->end + tmp_len + 3);
 		if (0 > avail_bytes)
-			ISSUE_GVSUBOFLOW_ERROR(out_key);
+			ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE);
 		if (0 < tmp_len)
 		{
 			*out_ptr++ = STR_SUB_PREFIX;
@@ -135,17 +137,14 @@ unsigned char *mval2subsc(mval *in_val, gv_key *out_key)
 						/* Ensure input key to format_targ_key is double null terminated */
 						assert(STR_SUB_PREFIX == out_key->base[out_key->end]);
 						out_key->base[out_key->end] = KEY_DELIMITER;
-						ISSUE_GVSUBOFLOW_ERROR(out_key);
+						ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE);
 					}
 					ch++;	/* promote character */
 				}
 				*out_ptr++ = ch;
 			} while (--tmp_len > 0);
 		} else
-		{
-			*out_ptr++ = (!TREF(transform) || (0 == gv_cur_region->std_null_coll))
-				? STR_SUB_PREFIX : SUBSCRIPT_STDCOL_NULL;
-		}
+			*out_ptr++ = (0 == std_null_coll) ? STR_SUB_PREFIX : SUBSCRIPT_STDCOL_NULL;
 		goto ALLDONE;
 	}
 	/* Its a number, is it an integer? But before this assert that we have enough allocated space in the key
@@ -300,6 +299,6 @@ ALLDONE:
 	 * If not, we have overflown the original max-key-size length. Issue error.
 	 */
 	if ((MAX_GVKEY_PADDING_LEN + 1) > (int)(out_key->top - out_key->end))
-		ISSUE_GVSUBOFLOW_ERROR(out_key);
+		ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE);
 	return out_ptr;
 }
diff --git a/sr_port/nil_iocontrol.c b/sr_port/nil_iocontrol.c
index be38a6f..5fa9a10 100644
--- a/sr_port/nil_iocontrol.c
+++ b/sr_port/nil_iocontrol.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,3 +29,9 @@ void nil_dlr_key(mstr *d)
 	d->len = 0;
 	return;
 }
+
+void nil_dlr_zkey(mstr *d)
+{
+	d->len = 0;
+	return;
+}
diff --git a/sr_port/objlabel.h b/sr_port/objlabel.h
index be31810..032d736 100644
--- a/sr_port/objlabel.h
+++ b/sr_port/objlabel.h
@@ -33,7 +33,7 @@
  * Note that OBJ_UNIX_LABEL and OBJ_PLATFORM_LABEL should not exceed 255.
  */
 
-#define OBJ_UNIX_LABEL	25	/* When changed, be sure to zero the platform specific numbers below (if any non-0) */
+#define OBJ_UNIX_LABEL	27	/* When changed, be sure to zero the platform specific numbers below (if any non-0) */
 
 #if defined(__osf__)
 #	define	OBJ_PLATFORM_LABEL	0		/* Alpha/Tru64 */
diff --git a/sr_port/one_job_param.c b/sr_port/one_job_param.c
index beffda0..9bdf0be 100644
--- a/sr_port/one_job_param.c
+++ b/sr_port/one_job_param.c
@@ -44,8 +44,8 @@ const static readonly unsigned char job_param_index[27] =
       /* A(2)    B(0)   C(2)   D(4)   E(2)   F(0)  G(2)  H(0)  I(4)   J(0)  K(0)  L(2)  M(0) */
 	 0,	2,    	 2,     4,     8,    10,     10,   12,   12,    16,   16,   16,   18,
       /* N(6)	O(2)	P(4)	Q(0)	R(0)	S(6)	T(0)   U(0)	V(0)	W(0)   X(0)	Y(0)	Z(0) */
-	18,	24,	26,	30,	30,	30,	36,	36,	36,	36,	36,	36,	36,
-	36
+	18,	24,	26,	30,	30,	30,	37,	37,	37,	37,	37,	37,	37,
+	37
 };
 #else
 const static readonly unsigned char job_param_index[27] =
@@ -134,7 +134,7 @@ int one_job_param (char **parptr)
 			*parptr += len;
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && job_param_datatypes[job_param_data[x]]);
 		}
 		advancewindow ();
 	} else if (TK_EQUAL == TREF(window_token))
diff --git a/sr_port/op.h b/sr_port/op.h
index 07f1140..e8eba3b 100644
--- a/sr_port/op.h
+++ b/sr_port/op.h
@@ -161,11 +161,14 @@ void	op_forintrrpt();
 int	op_forloop();
 void	op_gvdata(mval *v);
 void	op_gvextnam(UNIX_ONLY_COMMA(int4 count) mval *val1, ...);
+void	op_gvextnam_fast(UNIX_ONLY_COMMA(int4 count) int hash_code, mval *val1, ...);
 boolean_t op_gvget(mval *v);
 void	op_gvincr(mval *increment, mval *result);
 void	op_gvkill(void);
 void	op_gvnaked(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...);
+void	op_gvnaked_fast(UNIX_ONLY_COMMA(int count_arg) int hash_code, mval *val_arg, ...);
 void	op_gvname(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...);
+void	op_gvname_fast(UNIX_ONLY_COMMA(int count_arg) int hash_code, mval *val_arg, ...);
 void	op_gvnext(mval *v);
 void	op_gvo2(mval *dst, mval *direct);
 void	op_gvorder(mval *v);
@@ -226,7 +229,7 @@ int	op_mproflinestart();
 void	op_mul(mval *u, mval *v, mval *p);
 void	op_newintrinsic(int intrtype);
 void	op_newvar(uint4 arg1);
-void	op_nullexp(mval *v);
+mval	*op_nullexp(void);
 void	op_oldvar(void);
 int	op_open(mval *device, mval *devparms, int timeout, mval *mspace);
 int	op_open_dummy(mval *v, mval *p, int t, mval *mspace);
diff --git a/sr_port/op_close.c b/sr_port/op_close.c
index 5ffb4b5..3eb9bac 100644
--- a/sr_port/op_close.c
+++ b/sr_port/op_close.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -50,7 +50,7 @@ void op_close(mval *v, mval *p)
 			return;
 		ciod = tl->iod;
 		if (0 == ciod || TRUE == ciod->perm ||
-		    (ciod->state != dev_open && tcp != ciod->type))
+		    (ciod->state != dev_open))
 			return;
 
 		for (prev = io_root_log_name, l = prev->next;  l != 0;  prev = l, l = l->next)
@@ -67,15 +67,15 @@ void op_close(mval *v, mval *p)
 	        if (0 == (l = get_log_name(&v->str, NO_INSERT)))
 			return;
 		else if (0 == (ciod = l->iod) || TRUE == ciod->perm
-			 || (dev_open != ciod->state && tcp != ciod->type))
+			 || (dev_open != ciod->state))
 			return;
 	}
 #	ifdef UNIX
 	else if (SS_LOG2LONG == stat)
-		rts_error(VARLSTCNT(5) ERR_LOGTOOLONG, 3, v->str.len, v->str.addr, SIZEOF(buf) - 1);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, v->str.len, v->str.addr, SIZEOF(buf) - 1);
 #	endif
 	else
-		rts_error(VARLSTCNT(1) stat);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) stat);
 
 	active_device = ciod;
 	if (io_curr_device.in == ciod)
diff --git a/sr_port/op_fnfnumber.c b/sr_port/op_fnfnumber.c
index 786b4f8..b7cdb9d 100644
--- a/sr_port/op_fnfnumber.c
+++ b/sr_port/op_fnfnumber.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -36,17 +36,16 @@ void op_fnfnumber(mval *src, mval *fmt, boolean_t use_fract, int fract, mval *ds
 	unsigned char	*ch, *cp, *ff, *ff_top, fncode, sign, *t;
 
 	if (!MV_DEFINED(fmt))		/* catch this up front so noundef mode can't cause trouble - so fmt no empty context */
-		rts_error(VARLSTCNT(2) ERR_FNUMARG, 0);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(2) ERR_FNUMARG, 0);
 	t_src_p = &t_src;		/* operate on src in a temp, so conversions are possible without modifying src */
 	*t_src_p = *src;
 	if (use_fract)
 		op_fnj3(t_src_p, 0, fract, t_src_p);
-	else if (MV_DEFINED(t_src_p))
-	{	/* if the source operand is not a canonical number, force conversion */
+	else
+	{
 		MV_FORCE_NUM(t_src_p);
-		MV_FORCE_CANONICAL(t_src_p);
-	} else
-		t_src_p = underr(t_src_p);
+		MV_FORCE_CANONICAL(t_src_p);	/* if the source operand is not a canonical number, force conversion */
+	}
 	assert (stringpool.free >= stringpool.base);
 	assert (stringpool.free <= stringpool.top);
 	/* assure there is adequate space for two string forms of a number as a local
@@ -86,12 +85,12 @@ void op_fnfnumber(mval *src, mval *fmt, boolean_t use_fract, int fract, mval *ds
 				fncode |= PAREN;
 				break;
 			default:
-				rts_error(VARLSTCNT(6) ERR_FNUMARG, 4, fmt->str.len, fmt->str.addr, 1, --ff);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_FNUMARG, 4, fmt->str.len, fmt->str.addr, 1, --ff);
 			break;
 		}
 	}
 	if ((0 != (fncode & PAREN)) && (0 != (fncode & FNERROR)))
-		rts_error(VARLSTCNT(4) ERR_FNARGINC, 2, fmt->str.len, fmt->str.addr);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FNARGINC, 2, fmt->str.len, fmt->str.addr);
 	else
 	{
 		sign = 0;
diff --git a/sr_port/op_fnquery.c b/sr_port/op_fnquery.c
index 28e47f0..173df12 100644
--- a/sr_port/op_fnquery.c
+++ b/sr_port/op_fnquery.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -97,7 +97,7 @@ void op_fnquery(UNIX_ONLY_COMMA(int sbscnt) mval *dst, ...)
 			if ((0 == arg1->str.len) && (i + 1 != sbscnt) && (LVNULLSUBS_NEVER == TREF(lv_null_subs)))
 			{	/* This is not the last subscript, we don't allow nulls subs and it was null */
 				va_end(var);
-				rts_error(VARLSTCNT(1) ERR_LVNULLSUBS);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_LVNULLSUBS);
 			}
 			if (is_num = MV_IS_CANONICAL(arg1))
 				MV_FORCE_NUM(arg1);
@@ -297,7 +297,7 @@ void op_fnquery(UNIX_ONLY_COMMA(int sbscnt) mval *dst, ...)
 			{
 				v1->str.len = INTCAST((char *)stringpool.free - v1->str.addr);
 				INVOKE_STP_GCOL(MAX_NUM_SIZE);
-				assert((char *)stringpool.free - v1->str.addr == v1->str.len);
+				assert(IS_AT_END_OF_STRINGPOOL(v1->str.addr, v1->str.len));
 			}
 			*v2 = *mv;
 			/* Now that we have ensured enough space in the stringpool, we dont expect any more
@@ -371,7 +371,7 @@ void op_fnquery(UNIX_ONLY_COMMA(int sbscnt) mval *dst, ...)
 		{
 			v1->str.len = INTCAST((char *)stringpool.free - v1->str.addr);
 			INVOKE_STP_GCOL(1);
-			assert((char *)stringpool.free - v1->str.addr == v1->str.len);
+			assert(IS_AT_END_OF_STRINGPOOL(v1->str.addr, v1->str.len));
 		}
 		*stringpool.free++ = (h2 < h1 ? ',' : ')');
 	}
diff --git a/sr_port/op_fntext.c b/sr_port/op_fntext.c
index 4687862..b59caa4 100644
--- a/sr_port/op_fntext.c
+++ b/sr_port/op_fntext.c
@@ -19,11 +19,14 @@
 #include "srcline.h"
 #include "op.h"
 #include "stringpool.h"
+#include "compiler.h"
 #ifdef GTM_TRIGGER
 # include "gtm_trigger_trc.h"
 #endif
+#include "stack_frame.h"
 
-GBLREF spdesc stringpool;
+GBLREF spdesc 		stringpool;
+GBLREF stack_frame	*frame_pointer;
 
 error_def(ERR_TXTSRCMAT);
 error_def(ERR_ZLINKFILE);
@@ -40,7 +43,7 @@ void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret)
 	mstr		*sld;
 	uint4		stat;
 	rhdtyp		*rtn_vector;
-	boolean_t	is_trigger;
+	boolean_t	is_trigger, current_rtn = FALSE;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -48,6 +51,8 @@ void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret)
 	MV_FORCE_STR(rtn);
 	temp_rtn = &temp_mval;
 	*temp_rtn = *rtn;	/* make a copy of the routine in case the caller used the same mval for rtn and ret */
+	if (WANT_CURRENT_RTN(temp_rtn)) /* we want $TEXT for the routine currently executing. */
+		current_rtn = TRUE;
 	ret->str.len = 0;	/* make ret an emptystring in case the return is by way of the condition handler */
 	ret->mvtype = MV_STR;
 	sld = (mstr *)NULL;
@@ -72,10 +77,13 @@ void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret)
 	{
 		if (stat & ZEROLINE)
 		{
-			if (NULL == (rtn_vector = find_rtn_hdr(&temp_rtn->str)))
-			{	/* not here, so try to bring it in */
-				GTMTRIG_ONLY(if (!is_trigger))	/* Triggers cannot be loaded in this fashion */
-				{
+			if (current_rtn)
+				rtn_vector = frame_pointer->rvector;
+			else
+			{
+				rtn_vector = find_rtn_hdr(&temp_rtn->str);
+				if ((NULL == rtn_vector) GTMTRIG_ONLY(&& !is_trigger))
+				{	/* not here, so try to bring it in... Triggers cannot be loaded in this fashion */
 					op_zlink(temp_rtn, 0);
 					rtn_vector = find_rtn_hdr(&temp_rtn->str);
 				}
diff --git a/sr_port/op_fnview.c b/sr_port/op_fnview.c
index adcef90..588c801 100644
--- a/sr_port/op_fnview.c
+++ b/sr_port/op_fnview.c
@@ -39,15 +39,24 @@
 #include "gtmimagename.h"
 #include "fullbool.h"
 #include "wbox_test_init.h"
+#include "format_targ_key.h"
+#include "str2gvkey.h"
+#include "gvcst_protos.h"
+#include "gvnh_spanreg.h"
+#include "targ_alloc.h"
+#include "change_reg.h"
+#ifdef UNIX
+# include "gtmlink.h"
+#endif
+#include "gtm_ctype.h"		/* for ISDIGIT_ASCII macro */
 
 GBLREF spdesc		stringpool;
 GBLREF int4		cache_hits, cache_fails;
 GBLREF unsigned char	*stackbase, *stacktop;
 GBLREF gd_addr		*gd_header;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 GBLREF boolean_t	certify_all_blocks;
 GBLREF sgmnt_addrs	*cs_addrs;
+GBLREF gd_region	*gv_cur_region;
 GBLREF gv_namehead	*gv_target;
 GBLREF gv_namehead	*reset_gv_target;
 GBLREF jnl_fence_control jnl_fence_ctl;
@@ -61,50 +70,92 @@ GBLREF boolean_t	badchar_inhibit;
 GBLREF boolean_t	gvdupsetnoop; /* if TRUE, duplicate SETs update journal but not database blocks */
 GBLREF int		gv_fillfactor;
 GBLREF int4		gtm_max_sockets;
+GBLREF gv_key		*gv_currkey;
+GBLREF boolean_t	is_gtm_chset_utf8;
 
+error_def(ERR_COLLATIONUNDEF);
+error_def(ERR_GBLNOMAPTOREG);
+error_def(ERR_GVSUBSERR);
 error_def(ERR_VIEWFN);
+error_def(ERR_VIEWGVN);
+
+LITREF	gtmImageName	gtmImageNames[];
+LITREF	mstr		relink_allowed_mstr[];
+LITREF	mval		literal_zero;
+LITREF	mval		literal_one;
+LITREF	mval		literal_null;
+
+STATICFNDCL unsigned char *gvn2gds(mval *gvn, gv_key *gvkey, int act);
 
-LITREF gtmImageName	gtmImageNames[];
-LITREF mval		literal_zero;
-LITREF mval		literal_one;
+#define	COPY_ARG_TO_STRINGPOOL(DST, KEYEND, KEYSTART)			\
+{									\
+	int	keylen;							\
+									\
+	keylen = (unsigned char *)KEYEND - (unsigned char *)(KEYSTART);	\
+	ENSURE_STP_FREE_SPACE(keylen);					\
+	assert(stringpool.top - stringpool.free >= keylen);		\
+	memcpy(stringpool.free, KEYSTART, keylen);			\
+	DST->mvtype = MV_STR;						\
+	DST->str.len = keylen;						\
+	DST->str.addr = (char *)stringpool.free;			\
+	stringpool.free += keylen;					\
+}
 
 void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 {
-	va_list		var;
 	VMS_ONLY(int	numarg;)
+	boolean_t	save_transform;
+	gv_key		save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
+	unsigned char	*key;
+	unsigned char	buff[MAX_ZWR_KEY_SZ];
+	collseq		*csp;
+	gd_binding	*map, *start_map, *end_map;
+	gd_region	*reg, *reg_start;
+	gv_key		*gvkey;
+	gv_namehead	temp_gv_target;
+	gvnh_reg_t	*gvnh_reg;
+	gvnh_spanreg_t	*gvspan;
+	int		n, tl, newlevel, res, reg_index, collver, nct, act, ver;
+	lv_val		*lv;
+	gd_gblname	*gname;
+	mstr		tmpstr, commastr, *gblnamestr;
+	mval		*arg1, *arg2, tmpmval;
 	mval		*keyword;
-	mval		*arg;
-	mstr		tmpstr;
-	int		n;
-	mval	        v;
-	viewparm	parmblk;
-	gd_binding	*map;
-	gd_region	*reg;
 	sgmnt_addrs	*csa;
-	short		tl, newlevel;
 	tp_frame	*tf;
+	trans_num	gd_targ_tn, *tn_array;
+	unsigned char	*c, *c_top;
+	va_list		var;
+	viewparm	parmblk, parmblk2;
 	viewtab_entry	*vtp;
-	collseq		*csp;
-	lv_val		*lv;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	VMS_ONLY(va_count(numarg));
-	if (numarg < 2)
-		GTMASSERT;
+	assertpro(2 <= numarg);
 	VAR_START(var, dst);
 	keyword = va_arg(var, mval *);
 	MV_FORCE_STR(keyword);
 	numarg -= 2;	/* remove destination and keyword from count */
 	if (numarg > 0)
 	{
-		arg = va_arg(var, mval *);
-		MV_FORCE_STR(arg);
+		arg1 = va_arg(var, mval *);
+		MV_FORCE_STR(arg1);
+		if (--numarg > 0)
+		{
+			arg2 = va_arg(var, mval *);
+			DEBUG_ONLY(--numarg;)
+		} else
+			arg2 = (mval *)NULL;
 	} else
-		arg = (mval *)NULL;
+	{
+		arg1 = (mval *)NULL;
+		arg2 = (mval *)NULL;
+	}
+	assert(!numarg);
 	va_end(var);
 	vtp = viewkeys(&keyword->str);
-	view_arg_convert(vtp, arg, &parmblk);
+	view_arg_convert(vtp, (int)vtp->parm, arg1, &parmblk, IS_DOLLAR_VIEW_TRUE);
 	switch (vtp->keycode)
 	{
 #		ifdef UNICODE_SUPPORTED
@@ -148,7 +199,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			if (!parmblk.gv_ptr->open)
 				gv_init_reg(parmblk.gv_ptr);
 			assert(parmblk.gv_ptr->open);
-			switch (parmblk.gv_ptr->dyn.addr->acc_meth)
+			switch (REG_ACC_METH(parmblk.gv_ptr))
 			{
 				case dba_mm:
 					tmpstr.addr = "MM";
@@ -167,7 +218,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 					tmpstr.len = SIZEOF("USR")-1;
 					break;
 				default:
-					GTMASSERT;
+					assertpro(FALSE && REG_ACC_METH(parmblk.gv_ptr));
 			}
 			dst->str = tmpstr;
 			break;
@@ -187,7 +238,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 					tmpstr.len = SIZEOF("Boolean side-effect warning")-1;
 					break;
 				default:
-					GTMASSERT;
+					assertpro(FALSE && TREF(gtm_fullbool));
 			}
 			dst->str = tmpstr;
 			break;
@@ -208,7 +259,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			dst->str = tmpstr;
 			break;
 		case VTK_GVFIRST:
-			if (!gd_header)		/* IF GD_HEADER ==0 THEN OPEN GBLDIR */
+			if (!gd_header)
 				gvinit();
 			tmpstr.addr = (char *)gd_header->regions->rname;
 			tmpstr.len = gd_header->regions->rname_len;
@@ -217,7 +268,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			break;
 		case VTK_GVNEXT:
 			assert(gd_header);
-			if (arg->str.len)
+			if (arg1->str.len)
 				parmblk.gv_ptr++;
 			if (parmblk.gv_ptr - gd_header->regions >= gd_header->n_regions)
 				dst->str.len = 0;
@@ -279,7 +330,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			break;
 #ifdef		DEBUG
 		case VTK_PROBECRIT:
-			if (!gd_header)		/* IF GD_HEADER ==0 THEN OPEN GBLDIR */
+			if (!gd_header)
 				gvinit();
 			if (!parmblk.gv_ptr->open)
 				gv_init_reg(parmblk.gv_ptr);
@@ -290,23 +341,58 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			break;
 #endif
 		case VTK_REGION:
-			/* if gd_header is null then get the current one, and update the gd_map */
-			if (!gd_header)
+			gblnamestr = &parmblk.str;
+			assert(NULL != gd_header); /* "view_arg_convert" call done above would have set this (for VTP_DBKEY case) */
+			if (gd_header->n_gblnames)
+			{
+				gname = gv_srch_gblname(gd_header, gblnamestr->addr, gblnamestr->len);
+				n = (NULL != gname) ? gname->act : 0;
+			} else
+				n = 0;
+			gvkey = &save_currkey[0];
+			key = gvn2gds(arg1, gvkey, n);
+			assert(key > &gvkey->base[0]);
+			assert(gvkey->end == key - &gvkey->base[0] - 1);
+			start_map = gv_srch_map(gd_header, (char *)&gvkey->base[0], gvkey->end - 1); /* -1 to remove trailing 0 */
+			GVKEY_INCREMENT_ORDER(gvkey);
+			end_map = gv_srch_map(gd_header, (char *)&gvkey->base[0], gvkey->end - 1); /* -1 to remove trailing 0 */
+			BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gvkey->base, gvkey->end - 1, end_map);
+			INCREMENT_GD_TARG_TN(gd_targ_tn);	/* takes a copy of incremented "TREF(gd_targ_tn)"
+								 * into local variable "gd_targ_tn" */
+			tn_array = TREF(gd_targ_reg_array);	/* could be NULL if no spanning globals were seen as
+								 * part of gld open till now.
+								 */
+			reg_start = &gd_header->regions[0];
+			commastr.len = 1;
+			commastr.addr = ",";
+			for (map = start_map; map <= end_map; map++)
 			{
-				SET_GD_HEADER(v);
-				SET_GD_MAP;
+				reg = map->reg.addr;
+				GET_REG_INDEX(gd_header, reg_start, reg, reg_index);	/* sets "reg_index" */
+				assert((NULL == tn_array) || (TREF(gd_targ_reg_array_size) > reg_index));
+				assert((map == start_map) || (NULL != tn_array));
+				if ((NULL == tn_array) || (tn_array[reg_index] != gd_targ_tn))
+				{	/* this region first encountered now. note it down in region-list to be returned */
+					tmpstr.addr = (char *)reg->rname;
+					tmpstr.len = reg->rname_len;
+					if (map == start_map)
+					{
+						s2pool(&tmpstr);
+						dst->str = tmpstr;
+						dst->mvtype = vtp->restype;
+					} else
+					{
+						s2pool_concat(dst, &commastr);
+						s2pool_concat(dst, &tmpstr);
+					}
+					if (NULL != tn_array)
+						tn_array[reg_index] = gd_targ_tn;
+				}
 			}
-			DEBUG_ONLY(else GD_HEADER_ASSERT);
-			map = gd_map;
-			map++;	/* get past local locks */
-			for (; memcmp(parmblk.ident.c, map->name, SIZEOF(mident_fixed)) >= 0; map++)
-				assert(map < gd_map_top);
-			reg = map->reg.addr;
-			tmpstr.addr = (char *)reg->rname;
-			tmpstr.len = reg->rname_len;
-			s2pool(&tmpstr);
-			dst->str = tmpstr;
-		  break;
+			break;
+		case VTK_RTNCHECKSUM:
+			view_routines_checksum(dst, &parmblk.ident);
+			break;
 		case VTK_RTNEXT:
 			view_routines(dst, &parmblk.ident);
 			break;
@@ -399,28 +485,143 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 		case VTK_YCOLLATE:
 			n = MV_FORCE_INT(parmblk.value);
 			csp = ready_collseq(n);
-			if (csp)
+			if (NULL == arg2)
+			{	/* $VIEW("YCOLLATE",coll) : Determine version corresponding to collation sequence "coll" */
+				if (0 == n)
+					break;	/* collation sequence # is 0, version is 0 in this case */
+				if (csp)
+				{
+					n = (*csp->version)();
+					n &= 0x000000FF;	/* make an unsigned char, essentially */
+				} else
+					n = -1;
+			} else
+			{	/* $VIEW("YCOLLATE",coll,ver) : Check if collsequence "coll" version is compatible with "ver" */
+				if (0 == n)
+					break;	/* collation sequence # is 0, any version is compatible with it */
+				collver = mval2i(arg2);
+				n = do_verify(csp, n, collver);
+			}
+			break;
+		case VTK_YGLDCOLL:
+			assert(NULL != gd_header);
+			if (gd_header->n_gblnames)
 			{
-				n = (*csp->version)();
-				n &= 0x000000FF;	/* make an unsigned char, essentially */
+				gblnamestr = &parmblk.str;
+				gname = gv_srch_gblname(gd_header, gblnamestr->addr, gblnamestr->len);
 			} else
-				n = -1;
+				gname = NULL;
+			if (NULL != gname)
+			{
+				nct = 0;	/* currently gname->nct cannot be non-zero */
+				act = gname->act;
+				ver = gname->ver;
+				commastr.len = 1;
+				commastr.addr = ",";
+				MV_FORCE_MVAL(dst, nct);
+				MV_FORCE_STR(dst);
+				dst->mvtype = vtp->restype;
+				s2pool_concat(dst, &commastr);
+				arg2 = &tmpmval;
+				MV_FORCE_MVAL(arg2, act);
+				MV_FORCE_STR(arg2);
+				s2pool_concat(dst, &arg2->str);
+				s2pool_concat(dst, &commastr);
+				MV_FORCE_MVAL(arg2, ver);
+				MV_FORCE_STR(arg2);
+				s2pool_concat(dst, &arg2->str);
+			} else
+			{	/* Return string "0" (no commas) to indicate nothing defined in gld for this global.
+				 * Do not return "0,0,0" as this might not be distinguishable from the case where
+				 * act of 0, ver of 0 was defined explicitly for this global in the gld.
+				 */
+				*dst = literal_zero;
+			}
 			break;
 		case VTK_YDIRTREE:
 			op_gvname(VARLSTCNT(1) parmblk.value);
+			if (NULL != arg2)
+			{
+				view_arg_convert(vtp, VTP_DBREGION, arg2, &parmblk2, IS_DOLLAR_VIEW_TRUE);
+				reg = parmblk2.gv_ptr;
+				/* Determine if "reg" is mapped to by global name. If not issue error */
+				gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set up by op_gvname */
+				gvspan = (NULL == gvnh_reg) ? NULL : gvnh_reg->gvspan;
+				if (((NULL != gvspan) && !gvnh_spanreg_ismapped(gvnh_reg, gd_header, reg))
+					|| ((NULL == gvspan) && (reg != gv_cur_region)))
+				{
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GBLNOMAPTOREG, 4,
+						parmblk.value->str.len, parmblk.value->str.addr, REG_LEN_STR(reg));
+				}
+				if (NULL != gvspan)
+					GV_BIND_SUBSREG(gd_header, reg, gvnh_reg);
+			}
 			assert(INVALID_GV_TARGET == reset_gv_target);
 			reset_gv_target = gv_target;
 			gv_target = cs_addrs->dir_tree;	/* Trick the get program into using the directory tree */
-			op_gvget(dst);
+			op_fngvget(dst);
+			RESET_GV_TARGET(DO_GVT_GVKEY_CHECK);
+			break;
+		case VTK_YGDS2GVN:
+			if (NULL != arg2)
+			{
+				n = mval2i(arg2);
+				if (0 != n)
+				{
+					csp = ready_collseq(n);
+					if (NULL == csp)
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, n);
+						break;
+					}
+				} else
+					csp = NULL;	/* Do not issue COLLATIONUNDEF for 0 collation */
+			}
+			/* Temporarily repoint global variables "gv_target" and "transform".
+			 * They are needed by format_targ_key/gvsub2str "transform" and "gv_target->collseq".
+			 */
+			save_transform = TREF(transform);
+			assert(save_transform);
+			TREF(transform) = TRUE;
+			reset_gv_target = gv_target;
+			gv_target = &temp_gv_target;
+			memset(gv_target, 0, SIZEOF(gv_namehead));
+			if (NULL != arg2)
+				gv_target->collseq = csp;
+			assert(MV_IS_STRING(arg1));
+			gvkey = &save_currkey[0];
+			gvkey->prev = 0;
+			gvkey->top = DBKEYSIZE(MAX_KEY_SZ);
+			if ((gvkey->top < arg1->str.len) || (2 > arg1->str.len)
+					|| (KEY_DELIMITER != arg1->str.addr[arg1->str.len-1])
+					|| (KEY_DELIMITER != arg1->str.addr[arg1->str.len-2]))
+				*dst = literal_null;
+			else
+			{
+				memcpy(&gvkey->base[0], arg1->str.addr, arg1->str.len);
+				DEBUG_ONLY(gvkey->end = arg1->str.len - 1;)	/* for an assert in format_targ_key */
+				if (0 == (c = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gvkey, FALSE)))
+					c = &buff[MAX_ZWR_KEY_SZ - 1];
+				COPY_ARG_TO_STRINGPOOL(dst, c, &buff[0]);
+			}
+			/* Restore global variables "gv_target" and "transform" back to their original state */
 			RESET_GV_TARGET(DO_GVT_GVKEY_CHECK);
+			TREF(transform) = save_transform;
+			break;
+		case VTK_YGVN2GDS:
+			n = (NULL != arg2) ? mval2i(arg2) : 0;
+			gvkey = &save_currkey[0];
+			key = gvn2gds(arg1, gvkey, n);
+			/* If input has error at some point, copy whatever subscripts (+ gblname) have been successfully parsed */
+			COPY_ARG_TO_STRINGPOOL(dst, key, &gvkey->base[0]);
 			break;
 		case VTK_YLCT:
 			n = -1;
-			if (arg)
+			if (arg1)
 			{
-				if (0 == MEMCMP_LIT(arg->str.addr, "nct"))
+				if (0 == MEMCMP_LIT(arg1->str.addr, "nct"))
 					n = TREF(local_coll_nums_as_strings) ? 1 : 0;
-				else if (0 == MEMCMP_LIT(arg->str.addr, "ncol"))
+				else if (0 == MEMCMP_LIT(arg1->str.addr, "ncol"))
 					n = TREF(local_collseq_stdnull);
 			} else
 				n = TREF(local_collseq) ? (TREF(local_collseq))->act : 0;
@@ -431,7 +632,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			if (!parmblk.gv_ptr->open)
 				gv_init_reg(parmblk.gv_ptr);
 			reg = parmblk.gv_ptr;
-			if (dba_cm == reg->dyn.addr->acc_meth)
+			if (dba_cm == REG_ACC_METH(reg))
 				n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffer_size;
 			break;
 		case VTK_ZDEFCNT:
@@ -440,7 +641,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			if (!parmblk.gv_ptr->open)
 				gv_init_reg(parmblk.gv_ptr);
 			reg = parmblk.gv_ptr;
-			if (dba_cm == reg->dyn.addr->acc_meth)
+			if (dba_cm == REG_ACC_METH(reg))
 				n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffered_count;
 			break;
 		case VTK_ZDEFSIZE:
@@ -449,7 +650,7 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 			if (!parmblk.gv_ptr->open)
 				gv_init_reg(parmblk.gv_ptr);
 			reg = parmblk.gv_ptr;
-			if (dba_cm == reg->dyn.addr->acc_meth)
+			if (dba_cm == REG_ACC_METH(reg))
 				n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffer_used;
 			break;
 		case VTK_ZDIR_FORM:
@@ -481,10 +682,15 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 		case VTK_LOGTPRESTART:
 			n = TREF(tprestart_syslog_delta);
 			break;
-#		ifndef VMS
+#		ifdef UNIX
 		case VTK_JNLERROR:
 			n = TREF(error_on_jnl_file_lost);
 			break;
+		case VTK_LINK:
+			assert((0 <= TREF(relink_allowed)) && (TREF(relink_allowed) < LINK_MAXTYPE));
+			dst->str = relink_allowed_mstr[TREF(relink_allowed)];
+			s2pool(&dst->str);
+			break;
 #		endif
 		default:
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_VIEWFN);
@@ -493,3 +699,278 @@ void	op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
 	if (MV_NM == vtp->restype)
 		MV_FORCE_MVAL(dst, n);
 }
+
+/* Converts a GVN in string representation into a key in subscript representation.
+ * Note: This code is very similar to "is_canonic_name()". With some effort, they might even be merged into one.
+ */
+STATICFNDEF unsigned char *gvn2gds(mval *gvn, gv_key *gvkey, int act)
+{
+	boolean_t	save_transform, is_zchar;
+	collseq		*csp;
+	gd_region	tmpreg, *save_gv_cur_region;
+	gv_namehead	temp_gv_target;
+	int		quotestate, clen;
+	int4		num;
+	unsigned char	strbuff[MAX_KEY_SZ + 1], *key, *key_start, *key_top, *c, *c_top, ch, *str, *str_top, *c1, *c2, *numptr;
+	char		fnname[6];	/* to hold the function name $CHAR or $ZCHAR */
+	char		number[32];	/* to hold a codepoint numeric value for $char or $zchar; 32 digits is more than enough */
+	mval		tmpmval, *mvptr, dollarcharmval;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	if (0 != act)
+	{
+		csp = ready_collseq(act);
+		if (NULL == csp)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, act);
+	} else
+		csp = NULL;	/* Do not issue COLLATIONUNDEF for 0 collation */
+	assert(MV_IS_STRING(gvn));
+	c = (unsigned char *)gvn->str.addr;
+	c_top = c + gvn->str.len;
+	key_start = &gvkey->base[0];
+	key = key_start;
+	if ((c >= c_top) || ('^' != *c++))
+		return key;
+	gvkey->prev = 0;
+	gvkey->top = DBKEYSIZE(MAX_KEY_SZ);
+	key_top = key_start + gvkey->top;
+	/* Parse GBLNAME */
+	for ( ; (c < c_top) && (key < key_top); )
+	{
+		if ('(' == *c)
+			break;
+		*key++ = *c++;
+	}
+	if (key >= key_top)
+		return key_start;
+	if (c == c_top)
+	{
+		*key++ = KEY_DELIMITER;
+		gvkey->end = key - key_start;
+		*key++ = KEY_DELIMITER;
+		return key;
+	}
+	assert('(' == *c);
+	c++; /* skip past "(" */
+	*key++ = KEY_DELIMITER;
+	gvkey->end = key - key_start;
+	str = &strbuff[0];
+	str_top = str + ARRAYSIZE(strbuff);
+	/* Temporarily repoint global variables "gv_cur_region", "gv_target" and "transform".
+	 * They are needed by mval2subsc for the following
+	 *	"transform", "gv_target->nct", "gv_target->collseq" and "gv_cur_region->std_null_coll"
+	 */
+	save_transform = TREF(transform);
+	assert(save_transform);
+	TREF(transform) = TRUE;
+	reset_gv_target = gv_target;
+	gv_target = &temp_gv_target;
+	memset(gv_target, 0, SIZEOF(gv_namehead));
+	gv_target->collseq = csp;
+	save_gv_cur_region = gv_cur_region;
+	gv_cur_region = &tmpreg;
+	memset(gv_cur_region, 0, SIZEOF(gd_region));
+	/* Note that the primary caller of the YGVN2GDS functionality is going to be GDE for globals that
+	 * span regions. And since such globals need to reside in regions that have standard null collation
+	 * defined, we set the std_null_coll field to TRUE above.
+	 */
+	gv_cur_region->std_null_coll = TRUE;
+	/* Parse subscripts */
+	quotestate = 0;
+	for ( ; (c < c_top) && (str < str_top); c++)
+	{
+		ch = *c;
+		switch (quotestate)
+		{
+			case 0:
+			case 6:
+				if (('"' == ch) || ('$' == ch))
+				{	/* start of a string subscript */
+					if (0 == quotestate)
+					{
+						tmpmval.mvtype = (MV_STR | MV_NUM_APPROX);
+							/* MV_NUM_APPROX needed by mval2subsc to skip val_iscan call */
+						str = &strbuff[0];
+						tmpmval.str.addr = (char *)str;
+					}
+					quotestate = ('"' == ch) ? 1 : 3;
+				} else if (6 == quotestate)
+				{	/* Defer rts_error until after global variables "gv_cur_region" etc. are restored. */
+					quotestate = -1;/* error in input */
+					c = c_top;	/* do not parse remaining input as subscripted gvn is complete now */
+				} else
+				{	/* quotestate is 0, in this case this is the start of a number */
+					quotestate = 4;	/* start of a number */
+					tmpmval.mvtype = MV_STR;
+					tmpmval.str.addr = (char *)c;
+				}
+				break;
+			case 1:
+				if ('"' == ch)
+					quotestate = 2;
+				else
+					*str++ = ch;	/* and quotestate stays at 1 */
+				break;
+			case 2:
+			case 9:
+				if ((2 == quotestate) && ('"' == ch))
+				{
+					*str++ = '"';
+					quotestate = 1;
+					break;
+				} else if (')' == ch)
+					quotestate = 5;
+				else if (',' == ch)
+					quotestate = 0;
+				else if ('_' == ch)
+				{
+					quotestate = 6;
+					break;
+				} else
+				{	/* Defer rts_error until after global variables "gv_cur_region" etc. are restored. */
+					quotestate = -1;	/* error in input */
+					c = c_top;		/* force break from for loop */
+					break;
+				}
+				assert((')' == ch) || (',' == ch));
+				tmpmval.str.len = str - (unsigned char *)tmpmval.str.addr;
+				DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = TRUE;)
+				mval2subsc(&tmpmval, gvkey, gv_cur_region->std_null_coll);
+				DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = FALSE;)
+				assert(gvkey->end < gvkey->top); /* else GVSUBOFLOW error would have been issued */
+				key = &gvkey->base[gvkey->end];
+				break;
+			case 3:
+				/* Allow only one of $C( or $CHAR( or $ZCH( or $ZCHAR( */
+				c1 = c;
+				for ( ; (c < c_top) && ('(' != *c); c++)
+					;
+				if (c == c_top)
+					break;
+				clen = c - c1;
+				if (clen >= ARRAYSIZE(fnname))
+				{
+					c = c_top;	/* force break from for loop */
+					break;		/* bad function name. issue error after breaking from for loop */
+				}
+				for (c2 = (unsigned char *)&fnname[0]; c1 < c; c2++, c1++)
+					*c2 = toupper(*c1);
+				if (!MEMCMP_LIT(fnname, "ZCHAR") || !MEMCMP_LIT(fnname, "ZCH"))
+					is_zchar = 1;
+				else if (!MEMCMP_LIT(fnname, "CHAR") || !MEMCMP_LIT(fnname, "C"))
+					is_zchar = 0;
+				else
+				{
+					c = c_top;	/* force break from for loop */
+					break;		/* bad function name. issue error after breaking from for loop */
+				}
+				assert('(' == *c);
+				quotestate = 7;
+				break;
+			case 4:
+				if (',' == ch)
+					quotestate = 0;
+				else if (')' == ch)
+					quotestate = 5;
+				else
+					break;
+				tmpmval.str.len = c - (unsigned char *)tmpmval.str.addr;
+				mvptr = &tmpmval;
+				MV_FORCE_NUM(mvptr);
+				if (MVTYPE_IS_NUM_APPROX(tmpmval.mvtype))
+				{	/* User specified either a non-numeric or an imprecise numeric.
+					 * Defer rts_error until after global variables "gv_cur_region" etc. are restored.
+					 */
+					quotestate = -1;/* error in input */
+					c = c_top;	/* do not parse remaining input as subscripted gvn is complete now */
+					break;
+				}
+				mval2subsc(&tmpmval, gvkey, gv_cur_region->std_null_coll);
+				assert(gvkey->end < gvkey->top); /* else GVSUBOFLOW error would have been issued */
+				key = &gvkey->base[gvkey->end];
+				break;
+			case 5:
+				/* Defer rts_error until after global variables "gv_cur_region" etc. are restored. */
+				quotestate = -1;/* error in input */
+				c = c_top;	/* do not parse remaining input as subscripted gvn is complete now */
+				break;
+			case 7:
+				if (!ISDIGIT_ASCII(ch))
+				{	/* Not an ascii numeric digit.
+					 * Defer rts_error until after global variables "gv_cur_region" etc. are restored.
+					 */
+					quotestate = -1;/* error in input */
+					c = c_top;	/* do not parse remaining input as subscripted gvn is complete now */
+					break;
+				}
+				numptr = c;	/* record start of number */
+				quotestate = 8;
+				break;
+			case 8:
+				if (')' == ch)
+					quotestate = 9;
+				else if (',' == ch)
+					quotestate = 7;
+				else if (!ISDIGIT_ASCII(ch))
+				{	/* Not an ascii numeric digit
+					 * Defer rts_error until after global variables "gv_cur_region" etc. are restored.
+					 */
+					quotestate = -1;/* error in input */
+					c = c_top;	/* do not parse remaining input as subscripted gvn is complete now */
+					break;
+				} else
+					break;	/* continue processing numeric argument to $c or $zch */
+				/* end of the $c() number. find its zchar value */
+				if ((c - numptr) >= ARRAYSIZE(number))
+				{	/* number specified to $c or $zch is more than 32 digits long. error out */
+					c = c_top;	/* force break from for loop */
+					break;		/* bad function name. issue error after breaking from for loop */
+				}
+				memcpy(number, numptr, c - numptr);
+				number[c - numptr] = '\0';
+				num = (int4)STRTOUL(number, NULL, 10);
+				if (0 > num)
+				{	/* number is negative. issue error */
+					c = c_top;	/* force break from for loop */
+					break;		/* bad function name. issue error after breaking from for loop */
+				}
+#				ifdef UNICODE_SUPPORTED
+				if (!is_zchar && is_gtm_chset_utf8)
+					op_fnchar(2, &dollarcharmval, num);
+				else
+#				endif
+					op_fnzchar(2, &dollarcharmval, num);
+				assert(MV_IS_STRING(&dollarcharmval));
+				if (dollarcharmval.str.len)
+				{
+					if (str + dollarcharmval.str.len > str_top)
+					{	/* String overflows capacity.
+						 * Defer rts_error until after global variables "gv_cur_region" etc. are restored.
+						 */
+						quotestate = -1;/* error in input */
+						c = c_top; /* do not parse remaining input as subscripted gvn is complete now */
+						break;
+					}
+					memcpy(str, dollarcharmval.str.addr, dollarcharmval.str.len);
+					str += dollarcharmval.str.len;
+				}
+				break;
+			default:
+				assertpro(FALSE && quotestate);
+				break;
+		}
+	}
+	/* Restore global variables "gv_cur_region", "gv_target" and "transform" back to their original state */
+	gv_cur_region = save_gv_cur_region;
+	RESET_GV_TARGET(DO_GVT_GVKEY_CHECK);
+	TREF(transform) = save_transform;
+	if ((str >= str_top) || !CAN_APPEND_HIDDEN_SUBS(gvkey))
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, gvn->str.len, gvn->str.addr);
+	if (5 == quotestate)
+		*key++ = KEY_DELIMITER;	/* add double terminating null byte */
+	else
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GVSUBSERR);
+	assert(key <= key_top);
+	return key;
+}
diff --git a/sr_port/op_fnztrigger.c b/sr_port/op_fnztrigger.c
index 9372f3f..9347884 100644
--- a/sr_port/op_fnztrigger.c
+++ b/sr_port/op_fnztrigger.c
@@ -41,7 +41,6 @@
 GBLREF	sgmnt_data_ptr_t cs_data;
 GBLREF  uint4		dollar_tlevel;
 GBLREF	gd_addr		*gd_header;
-GBLREF	gd_binding	*gd_map;
 GBLREF	gd_region	*gv_cur_region;
 GBLREF	gv_key		*gv_currkey;
 GBLREF	gv_namehead	*gv_target;
@@ -55,9 +54,8 @@ GBLREF	boolean_t	donot_INVOKE_MUMTSTART;
 LITREF	mval	literal_zero;
 LITREF	mval	literal_one;
 
-STATICDEF char		save_currkey[SIZEOF(gv_key) + SIZEOF(short) + DBKEYSIZE(MAX_KEY_SZ)];	/* SIZEOF(short) for alignment */
+STATICDEF gv_key	save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 STATICDEF gd_addr	*save_gd_header;
-STATICDEF gd_binding	*save_gd_map;
 STATICDEF gv_key	*save_gv_currkey;
 STATICDEF gv_namehead	*save_gv_target;
 STATICDEF gd_region	*save_gv_cur_region;
@@ -100,12 +98,10 @@ LITDEF enum ztrprms ztrprm_data[] =
 /* reset global variables from the values noted down at op_fnztrigger entry */
 #define RESTORE_ZTRIGGER_ENTRY_STATE												\
 {																\
-	unsigned short	top;													\
 	DCL_THREADGBL_ACCESS;													\
 																\
 	SETUP_THREADGBL_ACCESS;													\
 	/* Reset global variables noted down at function entry */								\
-	gd_map = save_gd_map;													\
 	gd_header = save_gd_header;												\
 	if (NULL != save_gv_cur_region)												\
 	{															\
@@ -118,9 +114,7 @@ LITDEF enum ztrprms ztrprm_data[] =
 		 * inside the trigger* functions above. Therefore take care not to overwrite that				\
 		 * part of the gv_currkey structure. Restore everything else.							\
 		 */														\
-		top = gv_currkey->top;												\
-		memcpy(gv_currkey, save_gv_currkey, SIZEOF(gv_key) + save_gv_currkey->end);					\
-		gv_currkey->top = top;												\
+		COPY_KEY(gv_currkey, save_gv_currkey);										\
 	} else if (NULL != gv_currkey)												\
 	{															\
 		gv_currkey->end = 0;												\
@@ -136,7 +130,7 @@ LITDEF enum ztrprms ztrprm_data[] =
  */
 CONDITION_HANDLER(op_fnztrigger_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 
 	RESTORE_ZTRIGGER_ENTRY_STATE;
 	DEBUG_ONLY(donot_INVOKE_MUMTSTART = FALSE);
@@ -160,7 +154,7 @@ void op_fnztrigger(mval *func, mval *arg1, mval *arg2, mval *dst)
 	if (0 < gtm_trigger_depth)
 	{
 		DEBUG_ONLY(in_op_fnztrigger = FALSE);
-		rts_error(VARLSTCNT(4) ERR_DZTRIGINTRIG, 2, dollar_ztname->len, dollar_ztname->addr);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DZTRIGINTRIG, 2, dollar_ztname->len, dollar_ztname->addr);
 	}
 	MV_FORCE_STR(func);
 	MV_FORCE_STR(arg1);
@@ -170,29 +164,27 @@ void op_fnztrigger(mval *func, mval *arg1, mval *arg2, mval *dst)
 	{
 		DEBUG_ONLY(in_op_fnztrigger = FALSE;)
 		/* We have a wrong-sized keyword */
-		rts_error(VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 1);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 1);
 	}
 	if (0 > (index = namelook(ztrprm_index, ztrprm_names, func->str.addr, inparm_len)))	/* Note assignment */
 	{
 		DEBUG_ONLY(in_op_fnztrigger = FALSE);
 		/* Specified parm was not found */
-		rts_error(VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 1);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 1);
 	}
 	if ((0 < arg1->str.len) && (0 == arg1->str.addr[0]))
 	{
 		DEBUG_ONLY(in_op_fnztrigger = FALSE);
 		/* 2nd parameter is invalid */
-		rts_error(VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
 	}
 	save_gd_header = gd_header;
 	save_gv_target = gv_target;
-	save_gd_map = gd_map;
 	save_gv_cur_region = gv_cur_region;
 	if (NULL != gv_currkey)
-	{	/* Align save_gv_currkey on a "short" boundary, but first we check that field "gv_currkey->end" is truly short */
-		assert(SIZEOF(short) == SIZEOF(save_gv_currkey->end));
-		save_gv_currkey = (gv_key *)ROUND_UP2((INTPTR_T)&save_currkey[0], SIZEOF(gv_currkey->end));
-		memcpy(save_gv_currkey, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);
+	{
+		save_gv_currkey = (gv_key *)&save_currkey[0];
+		MEMCPY_KEY(save_gv_currkey, gv_currkey);
 		save_gv_last_subsc_null = TREF(gv_last_subsc_null);
 		save_gv_some_subsc_null = TREF(gv_some_subsc_null);
 	} else
@@ -221,9 +213,9 @@ void op_fnztrigger(mval *func, mval *arg1, mval *arg2, mval *dst)
 		case ZTRP_FILE:
 			if (0 == arg1->str.len)
 				/* 2nd parameter is missing */
-				rts_error(VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
 			if (MAX_FN_LEN < arg1->str.len)
-				rts_error(VARLSTCNT(1) ERR_FILENAMETOOLONG);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_FILENAMETOOLONG);
 			/* The file name is in string pool so make a local copy in case GC happens */
 			strncpy(filename, arg1->str.addr, arg1->str.len);
 			filename_len = arg1->str.len;
@@ -233,14 +225,15 @@ void op_fnztrigger(mval *func, mval *arg1, mval *arg2, mval *dst)
 		case ZTRP_ITEM:
 			if (0 == arg1->str.len)
 				/* 2nd parameter is missing */
-				rts_error(VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZTRIGINVACT, 1, 2);
 			failed = trigger_update(arg1->str.addr, arg1->str.len);
 			break;
 		case ZTRP_SELECT:
 			failed = (TRIG_FAILURE == trigger_select(arg1->str.addr, arg1->str.len, NULL, 0));
 			break;
 		default:
-			GTMASSERT;	/* Should never happen with checks above */
+			assertpro(FALSE && ztrprm_data[index]);	/* Should never happen with checks above */
+			break;
 	}
 	REVERT;
 	RESTORE_ZTRIGGER_ENTRY_STATE;
@@ -253,6 +246,6 @@ error_def(ERR_UNIMPLOP);
 
 void op_fnztrigger(mval *func, mval *arg1, mval *arg2, mval *dst)
 {
-	rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 }
 #endif
diff --git a/sr_port/op_gvdata.c b/sr_port/op_gvdata.c
index 2399ae8..be7a60a 100644
--- a/sr_port/op_gvdata.c
+++ b/sr_port/op_gvdata.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,19 +29,23 @@ LITREF mval		*fndata_table[2][2];
 
 void op_gvdata(mval *v)
 {
-	mint x;
+	mint			x;
+	gvnh_reg_t		*gvnh_reg;
+	enum db_acc_method	acc_meth;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	if (TREF(gv_last_subsc_null) && NEVER == gv_cur_region->null_subs)
 		sgnl_gvnulsubsc();
-
-	x = 0;
-	if (gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm)
+	acc_meth = REG_ACC_METH(gv_cur_region);
+	if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 	{
-		if (gv_target->root)
-			x = gvcst_data();
-	} else if (gv_cur_region->dyn.addr->acc_meth == dba_cm)
+		gvnh_reg = TREF(gd_targ_gvnh_reg);
+		if (NULL == gvnh_reg)
+			x = (gv_target->root ? gvcst_data() : 0);
+		else
+			INVOKE_GVCST_SPR_XXX(gvnh_reg, x = gvcst_spr_data());
+	} else if (REG_ACC_METH(gv_cur_region) == dba_cm)
 		x = gvcmx_data();
 	else
 		x = gvusr_data();
diff --git a/sr_port/op_gvextnam.c b/sr_port/op_gvextnam.c
index 633676d..39a5b8e 100644
--- a/sr_port/op_gvextnam.c
+++ b/sr_port/op_gvextnam.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -41,24 +41,55 @@
 
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_namehead	*gv_target;
-GBLREF gd_region	*gv_cur_region;
 GBLREF mstr             extnam_str;
 GBLREF mval		dollar_zgbldir;
 GBLREF gd_addr		*gd_header;
+GBLREF gd_region	*gv_cur_region;
+
+STATICFNDCL void op_gvextnam_common(int count, int hash_code, mval *val1, va_list var);
+
+void op_gvextnam(UNIX_ONLY_COMMA(int count_arg) mval *val1, ...)
+{
+	int	 hash_code;
+	mval	*val2, *gblname_mval;
+	va_list	var, var_dup;
+	VMS_ONLY(int	count;)
 
-void op_gvextnam(UNIX_ONLY_COMMA(int4 count) mval *val1, ...)
+	VAR_START(var, val1);
+	VAR_COPY(var_dup, var);
+	val2 = va_arg(var_dup, mval *);	/* skip env translate mval */
+	gblname_mval = va_arg(var_dup, mval *);	/* get at the gblname mval */
+	COMPUTE_HASH_MSTR(gblname_mval->str, hash_code);
+	VMS_ONLY(va_count(count);)
+	op_gvextnam_common(UNIX_ONLY_COMMA(count_arg+1) VMS_ONLY_COMMA(count+1) hash_code, val1, var);
+	va_end(var);
+	va_end(var_dup);
+}
+
+void op_gvextnam_fast(UNIX_ONLY_COMMA(int count_arg) int hash_code, mval *val1, ...)
 {
 	va_list		var;
-	VMS_ONLY(int4	count;)
-	bool		was_null, is_null;
+	VMS_ONLY(int	count;)
+
+	VAR_START(var, val1);
+	VMS_ONLY(va_count(count);)
+	op_gvextnam_common(UNIX_ONLY_COMMA(count_arg) VMS_ONLY_COMMA(count) hash_code, val1, var);
+	va_end(var);
+}
+
+STATICFNDEF void op_gvextnam_common(int count, int hash_code, mval *val1, va_list var)
+{
+	boolean_t	was_null, is_null;
 	mstr		*tmp_mstr_ptr;
 	mval		*val, *val2, val_xlated;
-	short		max_key;
+	mname_entry	gvname;
+	uint4		max_key;
+	gd_addr		*tmpgd;
+	gvnh_reg_t	*gvnh_reg;
+	gd_region	*reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	VAR_START(var, val1);
-	VMS_ONLY(va_count(count));
 	val2 = va_arg(var, mval *);
 	MV_FORCE_STR(val1);
 	val1 = gtm_env_translate(val1, val2, &val_xlated);
@@ -68,11 +99,11 @@ void op_gvextnam(UNIX_ONLY_COMMA(int4 count) mval *val1, ...)
 	if (val1->str.len)
 	{
 		tmp_mstr_ptr = &val1->str;
-		TREF(gd_targ_addr) = zgbldir(val1);
+		tmpgd = zgbldir(val1);
 	} else
 	{
 		tmp_mstr_ptr = &dollar_zgbldir.str;
-		TREF(gd_targ_addr) = gd_header;
+		tmpgd = gd_header;
 	}
 	extnam_str.len = tmp_mstr_ptr->len;
 	if (extnam_str.len > TREF(gv_extname_size))
@@ -85,21 +116,32 @@ void op_gvextnam(UNIX_ONLY_COMMA(int4 count) mval *val1, ...)
 	memcpy(extnam_str.addr, tmp_mstr_ptr->addr, tmp_mstr_ptr->len);
 	assert((NULL == gv_target) || (INVALID_GV_TARGET != gv_target));
 	val = va_arg(var, mval *);
-	if (!MV_IS_STRING(val))
-		GTMASSERT;
-	GV_BIND_NAME_AND_ROOT_SEARCH(TREF(gd_targ_addr), &(val->str));
+	assertpro(MV_IS_STRING(val));
+	gvname.var_name = val->str;
+	gvname.hash_code = hash_code;
+	GV_BIND_NAME_AND_ROOT_SEARCH(tmpgd, &gvname, gvnh_reg);
+	/* cs_addrs is not initialized in case gvnh_reg->gvspan is non-NULL. Assert accordingly */
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC((NULL == gvnh_reg->gvspan) ? CHECK_CSA_TRUE : CHECK_CSA_FALSE);
+	TREF(gd_targ_addr) = tmpgd;		/* needed by name-level $order/$zprevious and various other functions */
 	was_null = is_null = FALSE;
-	max_key = gv_cur_region->max_key_size;
-	for (count -= 3;  count > 0;  count--)
+	/* gv_cur_region will not be set in case gvnh_reg->gvspan is non-NULL. So use region from gvnh_reg */
+	reg = gvnh_reg->gd_reg;
+	for (count -= 4;  count > 0;  count--)
 	{
 		val = va_arg(var, mval *);
-		COPY_SUBS_TO_GVCURRKEY(val, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey, was_null, is_null */
+		COPY_SUBS_TO_GVCURRKEY(val, reg, gv_currkey, was_null, is_null);
+			/* updates gv_currkey, was_null, is_null */
 	}
-	va_end(var);
+	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH (e.g. setting gv_cur_region for spanning globals) */
+	GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, tmpgd, gv_currkey, reg);
+	/* Now that "gv_cur_region" is setup correctly for both spanning and non-spanning globals, do GVSUBOFLOW check */
+	max_key = gv_cur_region->max_key_size;
+	if (gv_currkey->end >= max_key)
+		ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
 	TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (other than the last subscript)
 						in current key */
 	TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */
-	if (was_null && (NEVER == gv_cur_region->null_subs))
+	if (was_null && (NEVER == reg->null_subs))
 		sgnl_gvnulsubsc();
 	return;
 }
diff --git a/sr_port/op_gvkill.c b/sr_port/op_gvkill.c
index 38ab549..a6451a9 100644
--- a/sr_port/op_gvkill.c
+++ b/sr_port/op_gvkill.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,6 +30,7 @@
 
 GBLREF	gv_namehead	*gv_target;
 GBLREF	gd_region	*gv_cur_region;
+GBLREF	sgmnt_addrs	*cs_addrs;
 GBLREF	gv_key		*gv_currkey;
 GBLREF	bool		gv_replication_error;
 GBLREF	bool		gv_replopen_error;
@@ -48,18 +49,27 @@ void kill_var(void);
 void op_gvkill(void)
 {
 	gd_region	*reg;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	if (gv_cur_region->read_only)
-		rts_error(VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region));
+	{
+		assert(cs_addrs == &FILE_INFO(gv_cur_region)->s_addrs);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region));
+	}
 	if (TREF(gv_last_subsc_null) && NEVER == gv_cur_region->null_subs)
 		sgnl_gvnulsubsc();
-	if (gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm)
+	if (REG_ACC_METH(gv_cur_region) == dba_bg || REG_ACC_METH(gv_cur_region) == dba_mm)
 	{
-		if (IS_OK_TO_INVOKE_GVCST_KILL(gv_target))
-			gvcst_kill(TRUE);
-	} else if (gv_cur_region->dyn.addr->acc_meth == dba_cm)
+		gvnh_reg = TREF(gd_targ_gvnh_reg);
+		if (NULL == gvnh_reg)
+		{
+			if (IS_OK_TO_INVOKE_GVCST_KILL(gv_target))
+				gvcst_kill(TRUE);
+		} else
+			INVOKE_GVCST_SPR_XXX(gvnh_reg, gvcst_spr_kill());
+	} else if (REG_ACC_METH(gv_cur_region) == dba_cm)
 		gvcmx_kill(TRUE);
 	else
 		gvusr_kill(TRUE);
@@ -93,7 +103,7 @@ void kill_var(void)
 		REVERT;
 		return;
 	}
-	assert(gv_cur_region->dyn.addr->acc_meth == dba_cm);
+	assert(REG_ACC_METH(gv_cur_region) == dba_cm);
 	gvcmx_kill(TRUE);
 	REVERT;
 }
diff --git a/sr_port/op_gvnaked.c b/sr_port/op_gvnaked.c
index 12063d9..86cc01d 100644
--- a/sr_port/op_gvnaked.c
+++ b/sr_port/op_gvnaked.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,78 +38,139 @@
 #include "sgnl.h"
 #include "mvalconv.h"
 #include "tp_set_sgm.h"
+#include "dpgbldir.h"
 
-GBLREF uint4		dollar_tlevel;
-GBLREF gd_addr		*gd_header;
-GBLREF gv_key		*gv_currkey;
-GBLREF gv_namehead	*gv_target;
-GBLREF sgmnt_addrs      *cs_addrs;
-GBLREF gd_region	*gv_cur_region;
-GBLREF sgm_info         *first_sgm_info;
-GBLREF mstr		extnam_str;
+GBLREF	uint4		dollar_tlevel;
+GBLREF	gv_key		*gv_currkey;
+GBLREF	gv_namehead	*gv_target;
+GBLREF	sgmnt_addrs	*cs_addrs;
+GBLREF	gd_region	*gv_cur_region;
 
 error_def(ERR_GVNAKED);
 error_def(ERR_MAXNRSUBSCRIPTS);
 
+STATICFNDCL void op_gvnaked_common(int count, int hash_code_dummy, mval *val_arg, va_list var);
+
 void op_gvnaked(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...)
 {
 	va_list		var;
-	int		count;
-	bool		was_null, is_null, sbs_cnt;
+	VMS_ONLY(int	count;)
+
+	VAR_START(var, val_arg);
+	VMS_ONLY(va_count(count);)
+	op_gvnaked_common(UNIX_ONLY_COMMA(count_arg+1) VMS_ONLY_COMMA(count+1) 0, val_arg, var);
+	va_end(var);
+}
+
+/* See comment in "gvn.c" (search for OC_GVNAKED) for why hash_code_dummy is needed */
+void op_gvnaked_fast(UNIX_ONLY_COMMA(int count_arg) int hash_code_dummy, mval *val_arg, ...)
+{
+	va_list		var;
+	VMS_ONLY(int	count;)
+
+	VAR_START(var, val_arg);
+	VMS_ONLY(va_count(count);)
+	op_gvnaked_common(UNIX_ONLY_COMMA(count_arg) VMS_ONLY_COMMA(count) hash_code_dummy, val_arg, var);
+	va_end(var);
+}
+
+STATICFNDEF void op_gvnaked_common(int count, int hash_code_dummy, mval *val_arg, va_list var)
+{
+	boolean_t	was_null, is_null, sbs_cnt;
 	mval		*val;
-	short 		max_key;
+	int		max_key;
 	unsigned char	*ptr, *end_ptr;
+	gd_region	*reg, *reg_start, *reg_top;
+	gd_addr		*addr_ptr;
+	ht_ent_mname	*tabent;
+	gv_namehead	*gvt;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	extnam_str.len = 0;
 	if (!gv_currkey || (0 == gv_currkey->prev) || (0 == gv_currkey->end))
-		rts_error(VARLSTCNT(1) ERR_GVNAKED);
-	if ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth))
-	{
-		assert(INVALID_GV_TARGET != gv_target);
-                if (dollar_tlevel)
-			tp_set_sgm();
-		GVCST_ROOT_SEARCH;
-		assert(gv_target->gd_csa == cs_addrs);
-	}
-	VMS_ONLY(va_count(count));
-	UNIX_ONLY(count = count_arg;)	/* i386 assembler modules may depend on unchanged count */
-	if (0 >= count)
-		GTMASSERT;
-	is_null = FALSE;
-	assert(gv_currkey->prev);
-	was_null = TREF(gv_some_subsc_null);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GVNAKED);
+	assertpro(1 <= --count);	/* -- is to ignore "hash_code_dummy" parameter from count */
 	sbs_cnt = 0;
 	if (1 < count)
-	{
-		/* Use of naked reference can cause increase in number of subscripts.   So count the subscripts */
+	{	/* Use of naked reference can cause increase in number of subscripts.   So count the subscripts */
 		ptr = gv_currkey->base;
 		end_ptr = ptr + gv_currkey->prev;
 		while (ptr < end_ptr)
 			if (KEY_DELIMITER == *ptr++)
 				sbs_cnt++;
 		if (MAX_GVSUBSCRIPTS < (count + sbs_cnt))
-			rts_error(VARLSTCNT(1) ERR_MAXNRSUBSCRIPTS);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXNRSUBSCRIPTS);
 	}
 	/* else naked reference will not increase number of subscripts, so do not worry about exceeding the limit */
+	reg = gv_cur_region;
+	assert(NULL != reg);
+	/* If no global that this process has referenced spans regions, we can be sure whatever region
+	 * "gv_cur_region" points to is the region where the naked reference will map to as well.
+	 */
+	if (TREF(spangbl_seen))
+	{	/* It is possible the unsubscripted global name corresponding to this naked reference spans multiple
+		 * regions. In this case, we need to figure out what region the complete naked reference maps to
+		 * But before that, we need to find out which global directory (of all the ones this process has opened
+		 * in its lifetime) contains "gv_cur_region". And from there figure out the gvnh_reg_t structure
+		 * corresponding to the unsubscripted global name.
+		 */
+		for (addr_ptr = get_next_gdr(NULL); NULL != addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
+		{
+			reg_start = addr_ptr->regions;
+			reg_top = reg_start + addr_ptr->n_regions;
+			if ((reg >= reg_start) && (reg < reg_top))
+				break;
+		}
+		assert(NULL != addr_ptr);
+		tabent = lookup_hashtab_mname((hash_table_mname *)addr_ptr->tab_ptr, &gv_target->gvname);
+		assert(NULL != tabent);
+		gvnh_reg = (gvnh_reg_t *)tabent->value;
+		gvt = gvnh_reg->gvt;
+		/* Assert that the unsubscripted gv_target has the same collation characteristics as the current "gv_target".
+		 * This makes it safe to use the current "gv_target" for the COPY_SUBS_TO_GVCURRKEY macro.
+		 */
+		assert(gv_target->collseq == gvt->collseq);
+		assert(gv_target->nct == gvt->nct);
+	} else
+		gvnh_reg = NULL;
 	gv_currkey->end = gv_currkey->prev;
-	VAR_START(var, val_arg);
 	val = val_arg;
-	max_key = gv_cur_region->max_key_size;
+	is_null = FALSE;
+	was_null = TREF(gv_some_subsc_null);
 	for ( ; ; )
 	{
-		COPY_SUBS_TO_GVCURRKEY(val, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey, was_null, is_null */
+		COPY_SUBS_TO_GVCURRKEY(val, reg, gv_currkey, was_null, is_null);
+			/* updates gv_currkey, was_null, is_null */
 		if (0 < --count)
 			val = va_arg(var, mval *);
 		else
 			break;
 	}
-	va_end(var);
+	if (TREF(spangbl_seen))
+	{	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+		 * (e.g. setting gv_cur_region for spanning globals).
+		 */
+		GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, addr_ptr, gv_currkey, reg);
+	} else
+		TREF(gd_targ_gvnh_reg) = NULL;
+	/* Now that "gv_cur_region" is setup correctly for both spanning and non-spanning globals, do GVSUBOFLOW check */
+	max_key = gv_cur_region->max_key_size;
+	if (gv_currkey->end >= max_key)
+		ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if ((dba_bg == REG_ACC_METH(reg)) || (dba_mm == REG_ACC_METH(reg)))
+	{
+		assert(INVALID_GV_TARGET != gv_target);
+                if (dollar_tlevel)
+			tp_set_sgm();
+		GVCST_ROOT_SEARCH;
+		assert(gv_target->gd_csa == cs_addrs);
+	}
 	TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (other than the last subscript)
 						in current key */
 	TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */
-	if (was_null && (NEVER == gv_cur_region->null_subs))
+	if (was_null && (NEVER == reg->null_subs))
 		sgnl_gvnulsubsc();
 	return;
 }
diff --git a/sr_port/op_gvname.c b/sr_port/op_gvname.c
index 16103c7..94731e2 100644
--- a/sr_port/op_gvname.c
+++ b/sr_port/op_gvname.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -37,31 +37,57 @@
 #include "sgnl.h"
 #include "mvalconv.h"
 #include "tp_set_sgm.h"
+#include "min_max.h"
 
 GBLREF gd_addr		*gd_header;
 GBLREF gv_key		*gv_currkey;
-GBLREF gd_region	*gv_cur_region;
 GBLREF gv_namehead	*gv_target;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF sgmnt_data_ptr_t	cs_data;
-GBLREF gd_binding	*gd_map;
 GBLREF sgm_info		*first_sgm_info;
 GBLREF sgm_info		*sgm_info_ptr;
 GBLREF uint4		dollar_tlevel;
 GBLREF mstr		extnam_str;
+GBLREF gd_region	*gv_cur_region;
 
-#ifdef DEBUG
-GBLDEF	boolean_t	dbg_opgvname_fast_path;
-#endif
+STATICFNDCL void op_gvname_common(int count, int hash_code, mval *val_arg, va_list var);
 
 void op_gvname(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...)
 {
-	int		count;
-	bool		was_null, is_null;
+	int	 	hash_code;
+	mval		tmpval;
+	va_list		var;
+	VMS_ONLY(int	count;)
+
+	tmpval = *val_arg;
+	tmpval.str.len = MIN(tmpval.str.len, MAX_MIDENT_LEN);
+	COMPUTE_HASH_MSTR(tmpval.str, hash_code);
+	VAR_START(var, val_arg);
+	VMS_ONLY(va_count(count);)
+	op_gvname_common(UNIX_ONLY_COMMA(count_arg+1) VMS_ONLY_COMMA(count+1) hash_code, &tmpval, var);
+	va_end(var);
+}
+
+void op_gvname_fast(UNIX_ONLY_COMMA(int count_arg) int hash_code, mval *val_arg, ...)
+{
+	va_list		var;
+	VMS_ONLY(int	count;)
+
+	VAR_START(var, val_arg);
+	VMS_ONLY(va_count(count);)
+	op_gvname_common(UNIX_ONLY_COMMA(count_arg) VMS_ONLY_COMMA(count) hash_code, val_arg, var);
+	va_end(var);
+}
+
+STATICFNDEF void op_gvname_common(int count, int hash_code, mval *val_arg, va_list var)
+{
+	boolean_t	was_null, is_null;
 	boolean_t	bgormm;
 	mval		*val;
-	short int	max_key;
-	va_list		var;
+	mname_entry	gvname;
+	int		max_key;
+	gvnh_reg_t	*gvnh_reg;
+	gd_region	*reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -69,62 +95,42 @@ void op_gvname(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...)
 	extnam_str.len = 0;
 	if (!gd_header)
 		gvinit();
-	TREF(gd_targ_addr) = gd_header;
-	VAR_START(var, val_arg);
-	VMS_ONLY(va_count(count));
-	UNIX_ONLY(count = count_arg);	/* need to preserve stack copy for i386 */
-	count--;
 	val = val_arg;
-	if ((gd_header->maps == gd_map) && gv_currkey && (0 == gv_currkey->base[val->str.len]) &&
-			(0 == memcmp(gv_currkey->base, val->str.addr, val->str.len)))
-	{
-		DEBUG_ONLY(dbg_opgvname_fast_path = TRUE);
-		gv_currkey->end = val->str.len + 1;
-		gv_currkey->base[gv_currkey->end] = 0;
-		gv_currkey->prev = 0;
-		bgormm = ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth));
-		if (bgormm)
-		{
-			if (dollar_tlevel)
-				tp_set_sgm();
-			assert(INVALID_GV_TARGET != gv_target);
-			GVCST_ROOT_SEARCH;
-		}
-		/* IF gv_target and cs_addrs are out of sync at this point, we could end up in database damage.
-		 * Hence the assertpro. In the else block, we do a GV_BIND_NAME which ensures they are in sync
-		 * (asserted by the DBG_CHECK_GVTARGET_CSADDRS_IN_SYNC check later) hence this assertpro check
-		 * is not done in that case.
-		 */
-		assertpro(gv_target->gd_csa == cs_addrs);
-	} else
-	{
-		DEBUG_ONLY(dbg_opgvname_fast_path = FALSE);
-		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &(val->str));
-		DEBUG_ONLY(
-			bgormm = ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth)));
-	}
-	assert(!bgormm || (gv_cur_region && &FILE_INFO(gv_cur_region)->s_addrs == cs_addrs && cs_addrs->hdr == cs_data));
+	count -= 2;
+	gvname.hash_code = hash_code;
+	gvname.var_name = val->str;
+	/* Bind the unsubscripted global name to corresponding region in the global directory map */
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	TREF(gd_targ_addr) = gd_header;		/* needed by name-level $order/$zprevious and various other functions */
+	/* gv_cur_region will not be set in case gvnh_reg->gvspan is non-NULL. So use region from gvnh_reg */
+	reg = gvnh_reg->gd_reg;
+	DEBUG_ONLY(bgormm = ((dba_bg == REG_ACC_METH(reg)) || (dba_mm == REG_ACC_METH(reg)));)
 	assert(bgormm || !dollar_tlevel);
-	assert(!dollar_tlevel || sgm_info_ptr && (sgm_info_ptr->tp_csa == cs_addrs));
 	assert(NULL != gv_target);
 	assert(gv_currkey->end);
 	assert('\0' != gv_currkey->base[0]);	/* ensure the below DBG_CHECK_... assert does a proper check (which it wont
 						 * if it finds gv_currkey->base[0] is '\0'
 						 */
-	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
-	assert(TREF(gd_targ_addr) == gd_header);
+	/* cs_addrs is not initialized in case gvnh_reg->gvspan is non-NULL. Assert accordingly */
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC((NULL == gvnh_reg->gvspan) ? CHECK_CSA_TRUE : CHECK_CSA_FALSE);
 	was_null = is_null = FALSE;
-	max_key = gv_cur_region->max_key_size;
 	for ( ; count > 0; count--)
 	{
 		val = va_arg(var, mval *);
-		COPY_SUBS_TO_GVCURRKEY(val, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey, was_null, is_null */
+		COPY_SUBS_TO_GVCURRKEY(val, reg, gv_currkey, was_null, is_null);
+			/* updates gv_currkey, was_null, is_null */
 	}
-	va_end(var);
+	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH (e.g. setting gv_cur_region for spanning globals) */
+	GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey, reg);
+	/* Now that "gv_cur_region" is setup correctly for both spanning and non-spanning globals, do GVSUBOFLOW check */
+	max_key = gv_cur_region->max_key_size;
+	if (gv_currkey->end >= max_key)
+		ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
+	assert(!dollar_tlevel || sgm_info_ptr && (sgm_info_ptr->tp_csa == cs_addrs));
 	TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (other than the last subscript)
 						in current key */
 	TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */
-	if (was_null && NEVER == gv_cur_region->null_subs)
+	if (was_null && (NEVER == reg->null_subs))
 		sgnl_gvnulsubsc();
 	TREF(prev_gv_target) = gv_target;	/* note down gv_target in another global for debugging purposes (C9I09-003039) */
 	return;
diff --git a/sr_port/op_gvnext.c b/sr_port/op_gvnext.c
index e5fd09e..ab1cdfd 100644
--- a/sr_port/op_gvnext.c
+++ b/sr_port/op_gvnext.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,6 +10,7 @@
  ****************************************************************/
 
 #include "mdef.h"
+
 #include "gdsroot.h"
 #include "gtm_facility.h"
 #include "fileinfo.h"
@@ -38,10 +39,11 @@ void op_gvnext(mval *v)
 	enum db_acc_method 	acc_meth;
 	int4			n;
 	register char		*c;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	acc_meth = gv_cur_region->dyn.addr->acc_meth;
+	acc_meth = REG_ACC_METH(gv_cur_region);
 	/* if the lowest subscript is -1, then make it null */
 	if ((gv_currkey->end == gv_currkey->prev + 4)
 		&& *(gv_currkey->base + gv_currkey->prev) == 0x40
@@ -64,18 +66,17 @@ void op_gvnext(mval *v)
 	{
 		if (!TREF(gv_last_subsc_null) || gv_cur_region->std_null_coll)
 		{
-			*(gv_currkey->base + gv_currkey->end - 1) = 1;
-			*(gv_currkey->base + gv_currkey->end + 1) = KEY_DELIMITER;
-			gv_currkey->end += 1;
+			GVKEY_INCREMENT_ORDER(gv_currkey);
 		} else
 			*(gv_currkey->base + gv_currkey->prev) = 01;
 	}
-	if ((acc_meth == dba_bg) || (acc_meth == dba_mm))
+	if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 	{
-		if (gv_target->root)
-			found = gvcst_order();
+		gvnh_reg = TREF(gd_targ_gvnh_reg);
+		if (NULL == gvnh_reg)
+			found = (gv_target->root ? gvcst_order() : FALSE);
 		else
-			found = FALSE;		/* global does not exist */
+			INVOKE_GVCST_SPR_XXX(gvnh_reg, found = gvcst_spr_order());
 	} else if (acc_meth == dba_cm)
 		found = gvcmx_order();
 	else
diff --git a/sr_port/op_gvorder.c b/sr_port/op_gvorder.c
index 935e7b1..b22051a 100644
--- a/sr_port/op_gvorder.c
+++ b/sr_port/op_gvorder.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,30 +25,38 @@
 #include "gvsub2str.h"
 #include "gvcmx.h"
 #include "gvusr.h"
+#include "hashtab_mname.h"
+#include "targ_alloc.h"		/* for GV_BIND_SUBSREG macro which needs "targ_alloc" prototype */
+#include "gtmimagename.h"
+#include "mvalconv.h"
 
 GBLREF gv_namehead	*gv_target;
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_key		*gv_altkey;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_addr		*gd_header;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF spdesc		stringpool;
 
 /* op_zprevious should generally be maintained in parallel */
 
-void op_gvorder (mval *v)
+void op_gvorder(mval *v)
 {
 	int4			n;
-	gd_binding		*map;
-	mstr			name;
+	int			min_reg_index, reg_index, res;
+	int			i, mini, maxi;
+	mname_entry		gvname;
+	mval			tmpmval, *datamval;
 	enum db_acc_method	acc_meth;
 	boolean_t		found, ok_to_change_currkey;
+	gd_binding		*gd_map_start, *map, *map_top;
+	gd_addr			*gd_targ;
+	gv_namehead		*gvt;
+	gvnh_reg_t		*gvnh_reg;
+	gvnh_spanreg_t		*gvspan;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	acc_meth = gv_cur_region->dyn.addr->acc_meth;
+	acc_meth = REG_ACC_METH(gv_cur_region);
 	/* Modify gv_currkey such that a gvcst_search of the resulting gv_currkey will find the next available subscript.
 	 * But in case of dba_usr (the custom implementation of $ORDER which is overloaded for DDP but could be more in the
 	 * future) it is better to hand over gv_currkey as it is so the custom implementation can decide what to do with it.
@@ -58,9 +66,7 @@ void op_gvorder (mval *v)
 	{	/* Modify gv_currkey to reflect the next possible key value in collating order */
 		if (!TREF(gv_last_subsc_null) || gv_cur_region->std_null_coll)
 		{
-			*(&gv_currkey->base[0] + gv_currkey->end - 1) = 1;
-			*(&gv_currkey->base[0] + gv_currkey->end + 1) = 0;
-			gv_currkey->end += 1;
+			GVKEY_INCREMENT_ORDER(gv_currkey);
 		} else
 		{
 			assert(STR_SUB_PREFIX == gv_currkey->base[gv_currkey->prev]);
@@ -72,38 +78,38 @@ void op_gvorder (mval *v)
 	}
 	if (gv_currkey->prev)
 	{
-		if (acc_meth == dba_bg || acc_meth == dba_mm)
+		if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 		{
-			if (gv_target->root == 0)	/* global does not exist */
-				found = FALSE;
+			gvnh_reg = TREF(gd_targ_gvnh_reg);
+			if (NULL == gvnh_reg)
+				found = (gv_target->root ? gvcst_order() : FALSE);
 			else
-				found = gvcst_order();
-		} else if (acc_meth == dba_cm)
+				INVOKE_GVCST_SPR_XXX(gvnh_reg, found = gvcst_spr_order());
+		} else if (dba_cm == acc_meth)
 			found = gvcmx_order();
 		else
-		 	found = gvusr_order();
+			found = gvusr_order();
 		v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by (BYPASSOK)
 				* this to-be-overwritten mval */
 		if (found)
 		{
 			gv_altkey->prev = gv_currkey->prev;
-
 			if (!(IS_STP_SPACE_AVAILABLE(MAX_KEY_SZ)))
- 			{
+			{
 				if (*(&gv_altkey->base[0] + gv_altkey->prev) != 0xFF)
-		 			n = MAX_FORM_NUM_SUBLEN;
+					n = MAX_FORM_NUM_SUBLEN;
 				else
 				{
 					n = gv_altkey->end - gv_altkey->prev;
-					assert (n > 0);
+					assert(n > 0);
 				}
 				ENSURE_STP_FREE_SPACE(n);
 			}
-	 		v->str.addr = (char *)stringpool.free;
-	 		stringpool.free = gvsub2str (&gv_altkey->base[0] + gv_altkey->prev, stringpool.free, FALSE);
-	 		v->str.len = INTCAST((char *)stringpool.free - v->str.addr);
-			assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
-			assert (v->str.addr + v->str.len <= (char *)stringpool.top &&
+			v->str.addr = (char *)stringpool.free;
+			stringpool.free = gvsub2str (&gv_altkey->base[0] + gv_altkey->prev, stringpool.free, FALSE);
+			v->str.len = INTCAST((char *)stringpool.free - v->str.addr);
+			assert(v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
+			assert(v->str.addr + v->str.len <= (char *)stringpool.top &&
 				v->str.addr + v->str.len >= (char *)stringpool.base);
 		} else
 			v->str.len = 0;
@@ -125,74 +131,109 @@ void op_gvorder (mval *v)
 		}
 	} else	/* the following section is for $O(^gname) */
 	{
-		assert (2 < gv_currkey->end);
-		assert (gv_currkey->end < (MAX_MIDENT_LEN + 3));	/* until names are not in midents */
-		map = gd_map + 1;
-		while (map < gd_map_top &&
-			(memcmp(gv_currkey->base, map->name,
-				gv_currkey->end == (MAX_MIDENT_LEN + 2) ? MAX_MIDENT_LEN : gv_currkey->end - 1) >= 0))
-		{
-			map++;
-		}
-
-		for (; map < gd_map_top; ++map)
+		assert(2 < gv_currkey->end);
+		assert(gv_currkey->end < (MAX_MIDENT_LEN + 3));	/* until names are not in midents */
+		assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end]);
+		assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end - 1]);
+		gd_targ = TREF(gd_targ_addr);
+		gd_map_start = gd_targ->maps;
+		map_top = gd_map_start + gd_targ->n_maps;
+		map = gv_srch_map(gd_targ, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+		for ( ; map < map_top; ++map)
 		{
 			gv_cur_region = map->reg.addr;
 			if (!gv_cur_region->open)
 				gv_init_reg(gv_cur_region);
 			change_reg();
-			acc_meth = gv_cur_region->dyn.addr->acc_meth;
-
-			for (; ;)		/* search region, entries in directory tree could be empty */
+			acc_meth = REG_ACC_METH(gv_cur_region);
+			/* search region, entries in directory tree could have empty GVT in which case move on to next entry */
+			for ( ; ; )
 			{
-				if (acc_meth == dba_bg || acc_meth == dba_mm)
+				if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 				{
 					gv_target = cs_addrs->dir_tree;
-					found = gvcst_order ();
+					found = gvcst_order();
 				} else if (acc_meth == dba_cm)
-					found = gvcmx_order ();
+					found = gvcmx_order();
 				else
-				 	found = gvusr_order();
+					found = gvusr_order();
 				if (!found)
 					break;
-				assert (1 < gv_altkey->end);
-				assert (gv_altkey->end < (MAX_MIDENT_LEN + 2));	/* until names are not in midents */
-				if (memcmp(gv_altkey->base, map->name, gv_altkey->end - 1) > 0)
-				{
+				/* At this point, gv_altkey contains the result of the gvcst_order */
+				assert(1 < gv_altkey->end);
+				assert((MAX_MIDENT_LEN + 2) > gv_altkey->end);	/* until names are not in midents */
+				res = memcmp(gv_altkey->base, map->gvkey.addr, gv_altkey->end);
+				assert((0 != res) || (gv_altkey->end <= map->gvkey_len));
+				if ((0 < res) || ((0 == res) && (map->gvkey_len == (map->gvname_len + 1))))
+				{	/* The global name we found is greater than the maximum value in this map OR
+					 * it is exactly equal to the upper bound of this map so this name cannot be
+					 * found in current map for sure. Move on to next map.
+					 */
 					found = FALSE;
 					break;
 				}
-				name.addr = (char *)&gv_altkey->base[0];
-				name.len = gv_altkey->end - 1;
-				if (acc_meth == dba_cm)
-					break;
-				GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &name);
-				if (gv_cur_region != map->reg.addr)
-				{
-					found = FALSE;
+				gvname.var_name.addr = (char *)&gv_altkey->base[0];
+				gvname.var_name.len = gv_altkey->end - 1;
+				if (dba_cm == acc_meth)
 					break;
+				COMPUTE_HASH_MNAME(&gvname);
+				GV_BIND_NAME_AND_ROOT_SEARCH(gd_targ, &gvname, gvnh_reg);	/* updates "gv_currkey" */
+				gvspan = gvnh_reg->gvspan;
+				assert((NULL != gvspan) || (gv_cur_region == map->reg.addr));
+				if (NULL != gvspan)
+				{	/* gv_target would NOT have been initialized by GV_BIND_NAME in this case.
+					 * So finish that initialization.
+					 */
+					datamval = &tmpmval;
+					/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+					 * 	(e.g. setting gv_cur_region for spanning globals)
+					 */
+					GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_targ, gv_currkey, gvnh_reg->gd_reg);
+					op_gvdata(datamval);
+					if (MV_FORCE_INT(datamval))
+						break;
+					if (TREF(want_empty_gvts))
+ 					{	/* For effective reorg truncates, we need to move empty data blocks in reorg,
+						 * so it sets want_empty_gvts before calling gv_select which then calls op_gvorder
+						 * Check if any of the spanned regions have a non-zero gv_target->root.
+						 * If so, treat it as if op_gvdata is non-zero. That is the only way truncate
+						 * can work on this empty GVT.
+						 */
+						maxi = gvspan->max_reg_index;
+						mini = gvspan->min_reg_index;
+						for (i = mini; i <= maxi; i++)
+						{
+							assert(i >= 0);
+							assert(i < gd_targ->n_regions);
+							gvt = GET_REAL_GVT(gvspan->gvt_array[i - mini]);
+							if ((NULL != gvt) && (0 != gvt->root))
+								break;
+						}
+						if (i <= maxi)
+							break;	/* found at least one spanned region with non-zero gvt->root */
+					}
+				} else
+				{	/* else gv_target->root would have been initialized by GV_BIND_NAME_AND_ROOT_SEARCH */
+					/* For effective truncates , we want to be able to move empty data blocks in reorg.
+					 * Reorg truncate calls gv_select which in turn calls op_gvorder.
+					 */
+					if ((0 != gv_target->root) && (TREF(want_empty_gvts) || (0 != gvcst_data())))
+						break;
 				}
-				/* For effective truncates, we want to be able to move empty data blocks in reorg */
-				if ((gv_target->root != 0) && (TREF(want_empty_gvts) || gvcst_data() != 0))
-					break;
-				*(&gv_currkey->base[0] + gv_currkey->end - 1) = 1;
-				*(&gv_currkey->base[0] + gv_currkey->end + 1) = 0;
-				gv_currkey->end += 1;
+				GVKEY_INCREMENT_ORDER(gv_currkey);
 			}
 			if (found)
 				break;
-			else
+			/* do not invoke GVKEY_DECREMENT_ORDER on last map since it contains 0xFFs and will fail an assert */
+			if ((map + 1) != map_top)
 			{
-				assert(SIZEOF(map->name) == SIZEOF(mident_fixed));
-				gv_currkey->end = mid_len((mident_fixed *)map->name);
-				assert(gv_currkey->end <= MAX_MIDENT_LEN);
-				memcpy(&gv_currkey->base[0], map->name, gv_currkey->end);
-				gv_currkey->base[ gv_currkey->end - 1 ] -= 1;
-				gv_currkey->base[ gv_currkey->end ] = 0xFF;	/* back off 1 spot from map */
-				gv_currkey->base[ gv_currkey->end + 1] = 0;
-				gv_currkey->base[ gv_currkey->end + 2] = 0;
-				gv_currkey->end += 2;
-				assert(gv_currkey->top > gv_currkey->end);	/* ensure we are within allocated bounds */
+				assert(strlen(map->gvkey.addr) == map->gvname_len);
+				gv_currkey->end = map->gvname_len + 1;
+				assert(gv_currkey->end <= (1 + MAX_MIDENT_LEN));
+				memcpy(&gv_currkey->base[0], map->gvkey.addr, gv_currkey->end);
+				assert(gv_currkey->end < gv_currkey->top);
+				gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
+				GVKEY_DECREMENT_ORDER(gv_currkey); /* back off 1 spot from map */
 			}
 		}
 		/* Reset gv_currkey as we have potentially skipped one or more regions so we no
@@ -204,22 +245,18 @@ void op_gvorder (mval *v)
 				* this to-be-overwritten mval */
 		if (found)
 		{
-			if (!IS_STP_SPACE_AVAILABLE(name.len + 1))
+			if (!IS_STP_SPACE_AVAILABLE(gvname.var_name.len + 1))
 			{
 				v->str.len = 0;	/* so stp_gcol ignores otherwise incompletely setup mval (BYPASSOK) */
-				INVOKE_STP_GCOL(name.len + 1);
+				INVOKE_STP_GCOL(gvname.var_name.len + 1);
 			}
-#ifdef mips
-			/* the following line works around a tandem compiler bug. */
-			v->str.addr = (char *)0;
-#endif
 			v->str.addr = (char *)stringpool.free;
 			*stringpool.free++ = '^';
-			memcpy (stringpool.free, name.addr, name.len);
-			stringpool.free += name.len;
-			v->str.len = name.len + 1;
-			assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
-			assert (v->str.addr + v->str.len <= (char *)stringpool.top &&
+			memcpy (stringpool.free, gvname.var_name.addr, gvname.var_name.len);
+			stringpool.free += gvname.var_name.len;
+			v->str.len = gvname.var_name.len + 1;
+			assert(v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
+			assert(v->str.addr + v->str.len <= (char *)stringpool.top &&
 				v->str.addr + v->str.len >= (char *)stringpool.base);
 		} else
 			v->str.len = 0;
diff --git a/sr_port/op_gvquery.c b/sr_port/op_gvquery.c
index acd1481..9ed622e 100644
--- a/sr_port/op_gvquery.c
+++ b/sr_port/op_gvquery.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -41,12 +41,13 @@ void op_gvquery (mval *v)
 	int			maxlen;
 	char			extnamdelim[] = "^|\"\"|";
 	mval			val;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	/* We want to turn QUERY into QUERYGET for all types of access methods so that we can cache the value of the key returned
 	 * by $QUERY. The value is very likely to be used shortly after $QUERY - Vinaya, Aug 13, 2001 */
-	acc_meth = gv_cur_region->dyn.addr->acc_meth;
+	acc_meth = REG_ACC_METH(gv_cur_region);
 	/* Modify gv_currkey such that a gvcst_search of the resulting key will find the next available record in collation order.
 	 * But in case of dba_usr (the custom implementation of $ORDER which is overloaded for DDP now but could be more in the
 	 * future) it is better to hand over gv_currkey as it is so the custom implementation can decide what to do with it.
@@ -71,7 +72,11 @@ void op_gvquery (mval *v)
 	{
 		case dba_bg:
 		case dba_mm:
-			found = ((0 != gv_target->root) ? gvcst_query() : FALSE); /* global does not exist if root is 0 */
+			gvnh_reg = TREF(gd_targ_gvnh_reg);
+			if (NULL == gvnh_reg)
+				found = ((0 != gv_target->root) ? gvcst_query() : FALSE); /* global does not exist if root is 0 */
+			else
+				INVOKE_GVCST_SPR_XXX(gvnh_reg, found = gvcst_spr_query());
 			break;
 		case dba_cm:
 			found = gvcmx_query(&val); /* val ignored currently - Vinaya Aug 13, 2001*/
@@ -100,7 +105,7 @@ void op_gvquery (mval *v)
 			gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
 		}
 	}
-	v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by this to-be-overwritten mval */
+	v->mvtype = 0; /* so STP_GCOL (if invoked below) can free up space currently occupied by this to-be-overwritten mval */
 	if (found)
 	{
 		if (acc_meth != dba_usr)
@@ -133,7 +138,6 @@ void op_gvquery (mval *v)
 			}
 			*extnamdst++ = extnamdelim[3];
 			*extnamdst++ = extnamdelim[4];
-			extnam_str.len = 0;
 		}
 		memcpy(extnamdst, glob_begin, size);
 		v->str.len = INTCAST(extnamdst - stringpool.free + size);
diff --git a/sr_port/op_gvqueryget.c b/sr_port/op_gvqueryget.c
index b6c3d56..0b7ceee 100644
--- a/sr_port/op_gvqueryget.c
+++ b/sr_port/op_gvqueryget.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,16 +34,21 @@ boolean_t op_gvqueryget(mval *key, mval *val)
 {
 	boolean_t 	gotit;
 	gv_key		*save_key;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	if (TREF(gv_last_subsc_null) && NEVER == gv_cur_region->null_subs)
 		sgnl_gvnulsubsc();
-	switch (gv_cur_region->dyn.addr->acc_meth)
+	switch (REG_ACC_METH(gv_cur_region))
 	{
 	case dba_bg:
 	case dba_mm:
-		gotit = (0 != gv_target->root) ? gvcst_queryget(val) : FALSE;
+		gvnh_reg = TREF(gd_targ_gvnh_reg);
+		if (NULL == gvnh_reg)
+			gotit = ((0 != gv_target->root) ? gvcst_queryget(val) : FALSE); /* global does not exist if root is 0 */
+		else
+			INVOKE_GVCST_SPR_XXX(gvnh_reg, gotit = gvcst_spr_queryget(val));
 		break;
 	case dba_cm:
 		gotit = gvcmx_query(val);
@@ -60,7 +65,7 @@ boolean_t op_gvqueryget(mval *key, mval *val)
 		gv_currkey = save_key;
 		break;
 	default:
-		GTMASSERT;
+		assertpro(FALSE && REG_ACC_METH(gv_cur_region));
 	}
 	if (gotit)
 	{
diff --git a/sr_port/op_gvrectarg.c b/sr_port/op_gvrectarg.c
index 52d75b4..5c96b0c 100644
--- a/sr_port/op_gvrectarg.c
+++ b/sr_port/op_gvrectarg.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,7 +30,6 @@
 
 #define DIR_ROOT 1
 
-GBLREF	gd_binding	*gd_map;
 GBLREF	gd_region	*gv_cur_region;
 GBLREF	gv_key		*gv_currkey;
 GBLREF	gv_namehead	*gv_target;
@@ -90,8 +89,6 @@ void op_gvrectarg(mval *v)
 		gvsavtarg = &gvst_tmp;
 		memcpy(gvsavtarg, c, GVSAVTARG_FIXED_SIZE);
 	}
-	TREF(gd_targ_addr) = gvsavtarg->gd_targ_addr;
-	gd_map = gvsavtarg->gd_map;
 	reg = gvsavtarg->gv_cur_region;
 	TP_CHANGE_REG(reg);	/* sets gv_cur_region, cs_addrs, cs_data */
 	gv_target = gvsavtarg->gv_target;
@@ -127,6 +124,8 @@ void op_gvrectarg(mval *v)
 		}
 		assert((NULL != first_sgm_info) || (NULL == sgm_info_ptr));
 	}
+	TREF(gd_targ_gvnh_reg)   = gvsavtarg->gd_targ_gvnh_reg;	/* non-zero only for spanning globals */
+	TREF(gd_targ_map)        = gvsavtarg->gd_targ_map;	/* initialized only if gd_targ_gvnh_reg is non-NULL */
 	TREF(gv_last_subsc_null) = gvsavtarg->gv_last_subsc_null;
 	TREF(gv_some_subsc_null) = gvsavtarg->gv_some_subsc_null;
 	gv_currkey->prev = gvsavtarg->prev;
diff --git a/sr_port/op_gvsavtarg.c b/sr_port/op_gvsavtarg.c
index 6f29f36..d161a7b 100644
--- a/sr_port/op_gvsavtarg.c
+++ b/sr_port/op_gvsavtarg.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -27,9 +27,9 @@
 #include "buddy_list.h"		/* needed for tp.h */
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
+#include "dpgbldir.h"
 #include "process_gvt_pending_list.h"
 
-GBLREF	gd_binding	*gd_map;
 GBLREF	gd_region	*gv_cur_region;
 GBLREF	gv_key		*gv_currkey;
 GBLREF	gv_namehead	*gv_target;
@@ -52,13 +52,12 @@ void op_gvsavtarg(mval *v)
 	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
 	v->mvtype = 0;	/* BYPASSOK */ /* so stp_gcol (if invoked below) can free up space currently
 					* occupied by this to-be-overwritten mval */
-	if (NULL == gv_currkey)
+	if ((NULL == gv_currkey) || (0 == gv_currkey->end))
 	{	/* Simplest case, finish it off */
 		v->str.len = 0;
 		v->mvtype = MV_STR;
 		return;
 	}
-	assert(NULL != TREF(gd_targ_addr));
 	assert((NULL != gv_target) || (0 == gv_currkey->end));
 	/* The way savtarg/rectarg works is by saving and restoring a copy of "gv_target". This assumes that once gv_target
 	 * has been allocated and used in a savtarg, the memory is never freed at least until the rectarg is completed.
@@ -66,7 +65,7 @@ void op_gvsavtarg(mval *v)
 	 * "gv_target" global in case we are in savtarg (or else at rectarg time the saved gv_target could have been freed).
 	 * Assert accordingly.
 	 */
-	assert((NULL == gv_target) || !is_gvt_in_pending_list(gv_target));
+	assert((NULL == gv_target) || (NULL == is_gvt_in_pending_list(gv_target)));
 	end = gv_currkey->end;
 	len = (int)(end + GVSAVTARG_FIXED_SIZE);
 	align_len = len + (GVSAVTARG_ALIGN_BNDRY - 1); /* is for 8-byte alignment of v->str.addr */
@@ -86,10 +85,14 @@ void op_gvsavtarg(mval *v)
 		if (dollar_tlevel && (NULL != sgm_info_ptr))
 			DBG_CHECK_IN_FIRST_SGM_INFO_LIST(sgm_info_ptr);
 	)
-	gvsavtarg->gd_targ_addr = TREF(gd_targ_addr);
-	gvsavtarg->gd_map = gd_map;
 	gvsavtarg->gv_cur_region = gv_cur_region;
 	gvsavtarg->gv_target = gv_target;
+	/* op_gv* functions use TREF(gd_targ_gvnh_reg) to determine whether the global name corresponding to current
+	 * global reference spans multiple regions or not. If it is, then TREF(gd_targ_map) is also additionally used.
+	 * So save/restore these as well.
+	 */
+	gvsavtarg->gd_targ_gvnh_reg   = TREF(gd_targ_gvnh_reg);	/* non-zero only for spanning globals */
+	gvsavtarg->gd_targ_map        = TREF(gd_targ_map);	/* initialized only if gd_targ_gvnh_reg is non-NULL */
 	gvsavtarg->gv_last_subsc_null = TREF(gv_last_subsc_null);
 	gvsavtarg->gv_some_subsc_null = TREF(gv_some_subsc_null);
 	gvsavtarg->prev = gv_currkey->prev;
diff --git a/sr_port/op_gvzwithdraw.c b/sr_port/op_gvzwithdraw.c
index d90009e..d63242a 100644
--- a/sr_port/op_gvzwithdraw.c
+++ b/sr_port/op_gvzwithdraw.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -52,14 +52,21 @@ void op_gvzwithdraw(void)
 
 	SETUP_THREADGBL_ACCESS;
 	if (gv_cur_region->read_only)
-		rts_error(VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region));
+	{
+		assert(cs_addrs == &FILE_INFO(gv_cur_region)->s_addrs);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region));
+	}
 	if (TREF(gv_last_subsc_null) && NEVER == gv_cur_region->null_subs)
 		sgnl_gvnulsubsc();
-	if (gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm)
+	if (REG_ACC_METH(gv_cur_region) == dba_bg || REG_ACC_METH(gv_cur_region) == dba_mm)
 	{
+		/* No special code needed for spanning globals here since we are in the region we want to be
+		 * and all we want to do is kill one node in this region (not a subtree underneath) even if
+		 * the global spans multiple regions. Hence there is no need to invoke gvcst_spr_kill here.
+		 */
 		if (IS_OK_TO_INVOKE_GVCST_KILL(gv_target))
 			gvcst_kill(FALSE);
-	} else if (gv_cur_region->dyn.addr->acc_meth == dba_cm)
+	} else if (REG_ACC_METH(gv_cur_region) == dba_cm)
 		gvcmx_kill(FALSE);
 	else
 		gvusr_kill(FALSE);
@@ -93,7 +100,7 @@ void with_var(void)
 		REVERT;
 		return;
 	}
-	assert(gv_cur_region->dyn.addr->acc_meth == dba_cm);
+	assert(REG_ACC_METH(gv_cur_region) == dba_cm);
 	gvcmx_kill(FALSE);
 	REVERT;
 }
diff --git a/sr_port/op_indtext.c b/sr_port/op_indtext.c
index 45c6b73..4533996 100644
--- a/sr_port/op_indtext.c
+++ b/sr_port/op_indtext.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,12 +26,14 @@
 #include "toktyp.h"
 #include <rtnhdr.h>
 #include "mv_stent.h"
+#include "stack_frame.h"
 
 GBLREF unsigned char 		*source_buffer;
 GBLREF short int 		source_column;
 GBLREF spdesc 			stringpool;
 GBLREF mv_stent			*mv_chain;
 GBLREF unsigned char		*msp, *stackwarn, *stacktop;
+GBLREF stack_frame		*frame_pointer;
 
 error_def(ERR_STACKOFLOW);
 error_def(ERR_STACKCRIT);
@@ -44,10 +46,17 @@ void op_indtext(mval *lab, mint offset, mval *rtn, mval *dst)
 	mval		mv_off;
 	oprtype		opt, getdst;
 	triple		*ref;
+	mval 		m;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	MV_FORCE_STR(lab);
+	if (WANT_CURRENT_RTN(rtn))
+	{
+		m = *rtn;
+		rtn = &m;
+		rtn->str = frame_pointer->rvector->routine_name;
+	}
 	indir_src.str.len = lab->str.len;
 	indir_src.str.len += SIZEOF("+^") - 1;
 	indir_src.str.len += MAX_NUM_SIZE;
diff --git a/sr_port/op_merge.c b/sr_port/op_merge.c
index 4a63f89..a0cf9f2 100644
--- a/sr_port/op_merge.c
+++ b/sr_port/op_merge.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -64,6 +64,7 @@
 #include "util.h"
 #include "collseq.h"
 #include "alias.h"
+#include "gtmimagename.h"
 
 #define UNDO_ACTIVE_LV								\
 {										\
@@ -97,14 +98,22 @@ error_def(ERR_STACKOFLOW);
 
 void op_merge(void)
 {
-	boolean_t		found, check_for_null_subs, is_base_var, nontp_and_bgormm;
+	boolean_t		found, check_for_null_subs, is_base_var, nontp_and_bgormm, nospan, act_mismatch;
 	lv_val			*dst_lv;
-	mval 			*mkey, *value, *subsc;
+	mval 			*mkey, *value, *subsc, tmp_mval;
 	int			org_glvn1_keysz, org_glvn2_keysz, delta2, dollardata_src, dollardata_dst, sbs_depth;
-	unsigned char		*ptr, *ptr2;
+	int			gvn1subs, gvn2subs, nsubs, keylen;
+	unsigned char		*ptr, *ptr2, *ptr_top;
 	unsigned char  		buff[MAX_ZWR_KEY_SZ];
 	unsigned char		nullcoll_src, nullcoll_dst;
 	zshow_out		output;
+	gd_addr			*gbl1_gd_addr, *gbl2_gd_addr;
+	gd_binding		*map;
+	gd_region		*reg1, *reg2;
+	gv_key           	*key, *mergekey2;
+	gv_namehead		*gvt1, *gvt2;
+	gvnh_reg_t		*gvnh_reg1, *gvnh_reg2;
+	gvname_info		*gblp1, *gblp2;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -118,12 +127,15 @@ void op_merge(void)
 	PUSH_MV_STENT(MVST_MVAL);
 	value = &mv_chain->mv_st_cont.mvs_mval;
 	value->mvtype = 0; /* initialize mval in the M-stack in case stp_gcol gets called before value gets initialized below */
+	gblp1 = mglvnp->gblp[IND1];
+	gblp2 = mglvnp->gblp[IND2];
 	if (MARG2_IS_GBL(merge_args))
 	{	/* Need to protect mkey returned from gvcst_queryget from stpgcol */
 		PUSH_MV_STENT(MVST_MVAL);
 		mkey = &mv_chain->mv_st_cont.mvs_mval;
 		mkey->mvtype = 0; /* initialize mval in M-stack in case stp_gcol gets called before mkey gets initialized below */
-		gvname_env_restore(mglvnp->gblp[IND2]);
+		gvname_env_restore(gblp2);
+		gbl2_gd_addr = TREF(gd_targ_addr);
 		/* now $DATA will be done for gvn2. op_gvdata input parameters are set in the form of some GBLREF */
 		op_gvdata(value);
 		dollardata_src = MV_FORCE_INT(value);
@@ -133,66 +145,82 @@ void op_merge(void)
 			POP_MV_STENT();	/* value */
 			POP_MV_STENT(); /* mkey */
 			if (MARG1_IS_GBL(merge_args))
-				gvname_env_restore(mglvnp->gblp[IND1]);	 /* store destination as naked indicator in gv_currkey */
+				gvname_env_restore(gblp1);	 /* store destination as naked indicator in gv_currkey */
 			merge_args = 0;	/* Must reset to zero to reuse the Global */
 			return;
 		}
-		nontp_and_bgormm = ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth))
+		nontp_and_bgormm = ((dba_bg == REG_ACC_METH(gv_cur_region)) || (dba_mm == REG_ACC_METH(gv_cur_region)))
 				&& !dollar_tlevel;
-		assert(!nontp_and_bgormm || gv_target->root);
 		if (NULL == TREF(gv_mergekey2))
 		{	/* We need to initialize gvn2 (right hand side). */
 			GVKEY_INIT(TREF(gv_mergekey2), DBKEYSIZE(MAX_KEY_SZ));
 		}
-		org_glvn1_keysz = mglvnp->gblp[IND1]->s_gv_currkey->end + 1;
+		mergekey2 = TREF(gv_mergekey2);
+		org_glvn1_keysz = gblp1->s_gv_currkey->end + 1;
 		org_glvn2_keysz = gv_currkey->end + 1;
-		(TREF(gv_mergekey2))->end = gv_currkey->end;
-		(TREF(gv_mergekey2))->prev = gv_currkey->prev;
-		memcpy((TREF(gv_mergekey2))->base, gv_currkey->base, gv_currkey->end + 1);
+		mergekey2->end = gv_currkey->end;
+		mergekey2->prev = gv_currkey->prev;
+		memcpy(mergekey2->base, gv_currkey->base, gv_currkey->end + 1);
 		if (MARG1_IS_GBL(merge_args))
 		{	/*==================== MERGE ^gvn1=^gvn2 =====================*/
-			if (mglvnp->gblp[IND2]->s_gv_target->nct != mglvnp->gblp[IND1]->s_gv_target->nct)
-				rts_error(VARLSTCNT(1) ERR_NCTCOLLDIFF);
-			/* if self merge then NOOP*/
+			gvt1 = gblp1->s_gv_target;
+			gvt2 = gblp2->s_gv_target;
+			if (gvt2->nct != gvt1->nct)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NCTCOLLDIFF);
 			if (!merge_desc_check()) /* will not proceed if one is descendant of another */
-			{
-				gvname_env_restore(mglvnp->gblp[IND1]);	 /* store destination as naked indicator in gv_currkey */
+			{	/* 0 return implies self merge i.e. NOOP */
+				gvname_env_restore(gblp1);	 /* store destination as naked indicator in gv_currkey */
 				POP_MV_STENT();	/* value */
 				merge_args = 0;	/* Must reset to zero to reuse the Global */
 				return;
 			}
-			nullcoll_src = mglvnp->gblp[IND2]->s_gv_cur_region->std_null_coll;
-			nullcoll_dst = mglvnp->gblp[IND1]->s_gv_cur_region->std_null_coll;
+			gvnh_reg1 = gblp1->s_gd_targ_gvnh_reg;
+			gvnh_reg2 = gblp2->s_gd_targ_gvnh_reg;
+			/* A non-NULL value of gvnh_reg indicates a spanning global as confirmed by the asserts below */
+			assert((NULL == gvnh_reg1) || (NULL != gvnh_reg1->gvspan));
+			assert((NULL == gvnh_reg2) || (NULL != gvnh_reg2->gvspan));
+			reg1 = gblp1->s_gv_cur_region;
+			reg2 = gblp2->s_gv_cur_region;
+			nullcoll_src = reg2->std_null_coll;
+			assert((NULL == gvnh_reg2) || nullcoll_src);	/* spanning globals => std_null_coll only option */
+			nullcoll_dst = reg1->std_null_coll;
+			assert((NULL == gvnh_reg1) || nullcoll_dst);	/* spanning globals => std_null_coll only option */
+			act_mismatch = (gvt2->act != gvt1->act);	/* this is accurate for spanning globals too */
 			if (1 == dollardata_src || 11 == dollardata_src)
 			{
 				found = op_gvget(value);  /* value of ^glvn2 */
 				if (found)
 				{	/* SET ^gvn1=^gvn2 */
-					gvname_env_restore(mglvnp->gblp[IND1]);
+					gvname_env_restore(gblp1);
 					op_gvput(value);
 					/* Note: If ^gvn1's null_sub=ALLOWEXISTING and say ^gvn1("")=^gvn,
 					 * this will give NULL_SUBC error
 					 */
 				}
 			}
-			check_for_null_subs = (NEVER != mglvnp->gblp[IND2]->s_gv_cur_region->null_subs) &&
-				(ALWAYS != mglvnp->gblp[IND1]->s_gv_cur_region->null_subs);
+			gbl1_gd_addr = gblp1->s_gd_targ_addr;
+			check_for_null_subs = (NEVER != reg2->null_subs) && (ALWAYS != reg1->null_subs);
+			key = gblp1->s_gv_currkey;
+			GET_NSUBS_IN_GVKEY(key->base, key->end - 1, gvn1subs);	/* sets "gvn1subs" */
+			key = gblp2->s_gv_currkey;
+			GET_NSUBS_IN_GVKEY(key->base, key->end - 1, gvn2subs);	/* sets "gvn2subs" */
+			nospan = (NULL == gvnh_reg1) && (NULL == gvnh_reg2);
 			/* Traverse descendant of ^gvn2 and copy into ^gvn1 */
 			for (; ;)
 			{
 				if (outofband)
 				{
-					gvname_env_restore(mglvnp->gblp[IND1]); /* naked indicator is restored into gv_currkey */
+					gvname_env_restore(gblp1); /* naked indicator is restored into gv_currkey */
 					outofband_action(FALSE);
 				}
-				/* Restore last key under ^gvn2 we worked */
-				gvname_env_restore(mglvnp->gblp[IND2]);
-				assert(0 == gv_currkey->base[gv_currkey->end - 1] && 0 == gv_currkey->base[gv_currkey->end]);
-				/* following is an attempt to find immidiate right sibling */
-				gv_currkey->base[gv_currkey->end] = 1;
-				gv_currkey->base[gv_currkey->end + 1] = 0;
-				gv_currkey->base[gv_currkey->end + 2] = 0;
-				gv_currkey->end += 2;
+				gvname_env_restore(gblp2);	/* Restore last key under ^gvn2 we worked */
+				/* If gblp2 corresponds to a spanning global, then determine
+				 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+				 */
+				assert((NULL == gvnh_reg2) || (TREF(gd_targ_gvnh_reg) == gvnh_reg2));
+				GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg2, gbl2_gd_addr, gv_currkey);
+				/* following is an attempt to find immediate right sibling */
+				GVKEY_INCREMENT_QUERY(gv_currkey);
 #				ifdef UNIX
 				if (nontp_and_bgormm && (0 == gv_target->root))
 				{	/* This is to handle root blocks moved by REORG. Merge alternates between two
@@ -214,46 +242,108 @@ void op_merge(void)
 				assert(MV_IS_STRING(mkey));
 				if (mkey->str.len < org_glvn2_keysz)
 					break;
-				if (0 != *((unsigned char *)mkey->str.addr + (TREF(gv_mergekey2))->end - 1) ||
-					memcmp(mkey->str.addr, (TREF(gv_mergekey2))->base, (TREF(gv_mergekey2))->end - 1))
+				if (0 != *((unsigned char *)mkey->str.addr + mergekey2->end - 1)
+						|| memcmp(mkey->str.addr, mergekey2->base, mergekey2->end - 1))
 					break; 					/* mkey is not under the sub-tree */
-				delta2 = mkey->str.len - org_glvn2_keysz; 	/* length increase of source key */
+				delta2 = mkey->str.len - org_glvn2_keysz; 	/* compute length increase of source key */
 				assert (0 < delta2);
-				/* Save the new source key for next iteration */
-				memcpy(mglvnp->gblp[IND2]->s_gv_currkey->base + org_glvn2_keysz - 2,
-					mkey->str.addr + org_glvn2_keysz - 2, delta2 + 2);
-				mglvnp->gblp[IND2]->s_gv_currkey->end = mkey->str.len - 1;
-				/* Create the destination key for this iteration (under ^glvn1) */
-				gvname_env_restore(mglvnp->gblp[IND1]);
-				if (gv_cur_region->max_key_size < org_glvn1_keysz + delta2)
-					ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
-				assert(gv_currkey->end == org_glvn1_keysz - 1);
-				memcpy(gv_currkey->base + org_glvn1_keysz - 2,
-					mkey->str.addr + org_glvn2_keysz - 2, delta2 + 2);
-				gv_currkey->end = org_glvn1_keysz + delta2 - 1;
-				if (nullcoll_src != nullcoll_dst)
+				GET_NSUBS_IN_GVKEY(mkey->str.addr + org_glvn2_keysz - 2, delta2, nsubs); /* sets "nsubs" */
+				/* Check if the target node in ^gvn1 exceeds max # of subscripts */
+				if (MAX_GVSUBSCRIPTS <= (gvn1subs + gvn2subs + nsubs))
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
+				/* Save the new source key for next iteration. Do not use gvname_env_save since that relies
+				 * on gv_currkey holding the key to be saved which is not the case here. Also gvname_env_save
+				 * has a lot of other save code which is redundant.
+				 */
+				assert(gblp2->s_gv_currkey->top >= mkey->str.len);
+				memcpy(gblp2->s_gv_currkey->base + org_glvn2_keysz - 2,
+							mkey->str.addr + org_glvn2_keysz - 2, delta2 + 2);
+				gblp2->s_gv_currkey->end = mkey->str.len - 1;
+				if (!nospan)
 				{
-					if (0 == nullcoll_dst)
-					{	/* Standard to GTM null subscript conversion*/
-						STD2GTMNULLCOLL((unsigned char *)gv_currkey->base + org_glvn1_keysz - 1,
-								delta2 - 1);
-					} else
-					{	/*  GTM to standard null subscript conversion */
-						GTM2STDNULLCOLL((unsigned char *)gv_currkey->base + org_glvn1_keysz - 1,
-								delta2 - 1);
+					if (NULL != gvnh_reg2)
+					{	/* ^gvn2 spans multiple regions. Find region where the current key was obtained */
+						map = gv_srch_map(gbl2_gd_addr, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+						reg2 = map->reg.addr;
 					}
 				}
-				/* check null subscripts in destination key, note that we have already restored, destination global
-				 * and curresponding region, key information
+				/* Create the destination key for this iteration (under ^glvn1) */
+				gvname_env_restore(gblp1);
+				/* For non-spanning globals, "gv_cur_region" points to the target region for ^gvn1 now.
+				 * For spanning globals though, "gv_cur_region" is not set appropriately until a little later.
+				 * Wait until then to issue GVSUBOFLOW error (if needed).
+				 */
+				if (act_mismatch)
+				{	/* Need to convert subscripts from gvt2->act collation to gvt1->act collation */
+					/* Copy prefix of subscripts that have been pre-computed outside the for loop */
+					gv_currkey->end = org_glvn1_keysz - 1;
+					/* Transform trailing subscripts of ^gvn2 from src collation to dst */
+					ptr = (unsigned char *)mkey->str.addr + mergekey2->end;
+					ptr_top = (unsigned char *)mkey->str.addr + mkey->str.len - 1;
+					for ( ; ptr < ptr_top; )
+					{
+						assert(gv_target == gvt1);
+						gv_target = gvt2;	/* switch gv_target for "mval2subsc" */
+						ptr2 = gvsub2str(ptr, buff, FALSE);
+						gv_target = gvt1;	/* restore "gv_target" */
+						tmp_mval.mvtype = MV_STR;
+						tmp_mval.str.addr = (char *)buff;
+						tmp_mval.str.len = INTCAST(ptr2 - buff);
+						mval2subsc(&tmp_mval, gv_currkey, nullcoll_dst);
+						/* we have now appended the correctly transformed subscript */
+						while (*ptr++)
+							;	/* skip to start of next subscript */
+					}
+					assert(ptr == ptr_top);
+
+				} else
+				{	/* No transformations needed. Key can be copied as is except for null-collation issues
+					 * which are easily handled by the STD2GTMNULLCOLL/GTM2STDNULLCOLL macros.
+					 */
+					assert(gv_currkey->end == org_glvn1_keysz - 1);
+					memcpy(gv_currkey->base + org_glvn1_keysz - 2,
+							mkey->str.addr + org_glvn2_keysz - 2, delta2 + 2);
+					gv_currkey->end = org_glvn1_keysz + delta2 - 1;
+					if (nullcoll_src != nullcoll_dst)
+					{
+						if (0 == nullcoll_dst)
+						{	/* Standard to GTM null subscript conversion*/
+							STD2GTMNULLCOLL((unsigned char *)gv_currkey->base + org_glvn1_keysz - 1,
+									delta2 - 1);
+						} else
+						{	/*  GTM to standard null subscript conversion */
+							GTM2STDNULLCOLL((unsigned char *)gv_currkey->base + org_glvn1_keysz - 1,
+									delta2 - 1);
+						}
+					}
+				}
+				/* If gblp1 corresponds to a spanning global, then determine
+				 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+				 */
+				assert((NULL == gvnh_reg1) || (TREF(gd_targ_gvnh_reg) == gvnh_reg1));
+				GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg1, gbl1_gd_addr, gv_currkey);
+				/* For spanning globals, "gv_cur_region" points to the target region for ^gvn1 only now */
+				if (gv_currkey->end >= gv_cur_region->max_key_size)
+					ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
+				if (!nospan)
+				{	/* At least one of ^gvn1 or ^gvn2 spans multiple regions. Recompute check_for_null_subs
+					 * in that case by looking at the specific region that the subscripted reference of
+					 * ^gvn1 or ^gvn2 maps to.
+					 */
+					check_for_null_subs = (NEVER != reg2->null_subs) && (ALWAYS != gv_cur_region->null_subs);
+				}
+				/* Check null subscripts in destination key. Note that we have already restored,
+				 * destination global and curresponding region, key information
 				 */
 				if (check_for_null_subs)
 				{
 					ptr2 = gv_currkey->base + gv_currkey->end - 1;
 					for (ptr = gv_currkey->base + org_glvn1_keysz - 2; ptr < ptr2; )
 					{
-						if (KEY_DELIMITER == *ptr++ && KEY_DELIMITER == *(ptr + 1) &&
-							(0 == gv_cur_region->std_null_coll ? (STR_SUB_PREFIX == *ptr) :
-							(SUBSCRIPT_STDCOL_NULL == *ptr)))
+						if ((KEY_DELIMITER == *ptr++) && (KEY_DELIMITER == *(ptr + 1))
+							&& ((0 == gv_cur_region->std_null_coll)
+								? (STR_SUB_PREFIX == *ptr)
+								: (SUBSCRIPT_STDCOL_NULL == *ptr)))
 							/* Note: For sgnl_gvnulsubsc/rts_error
 							 * 	 we do not restore proper naked indicator.
 							 * The standard states that the effect of a MERGE command
@@ -273,7 +363,7 @@ void op_merge(void)
 				/* Now put value of ^glvn2 descendant into corresponding descendant under ^glvn1 */
 				op_gvput(value);
 			}
-			gvname_env_restore(mglvnp->gblp[IND1]);	 /* store destination as naked indicator in gv_currkey */
+			gvname_env_restore(gblp1);	 /* store destination as naked indicator in gv_currkey */
 		} else
 		{	/*==================== MERGE lvn1=^gvn2 =====================*/
 			assert(MARG1_IS_LCL(merge_args));
@@ -281,36 +371,38 @@ void op_merge(void)
 			/* Need to protect subsc created from global variable subscripts from stpgcol */
 			PUSH_MV_STENT(MVST_MVAL);
 			subsc = &mv_chain->mv_st_cont.mvs_mval;
-			/* Restore ^gvn2 we will work */
-			gvname_env_save(mglvnp->gblp[IND2]);
+			/* At this time gv_currkey already points to gblp2 */
 			if (1 == dollardata_src || 11 == dollardata_src)
 			{	/* SET lvn1=^gvn2 */
 				found = op_gvget(value);
 				if (found)
 					mglvnp->lclp[IND1]->v = *value;
 			}
+			gvnh_reg2 = gblp2->s_gd_targ_gvnh_reg;
+			gbl2_gd_addr = TREF(gd_targ_addr);
 			for (; ;)
 			{
 				if (outofband)
 				{
-					gvname_env_restore(mglvnp->gblp[IND2]);	 /* naked indicator is restored into gv_currkey */
+					gvname_env_restore(gblp2);	 /* naked indicator is restored into gv_currkey */
 					outofband_action(FALSE);
 				}
-				assert(0 == gv_currkey->base[gv_currkey->end - 1] && 0 == gv_currkey->base[gv_currkey->end]);
-				/* following is an attempt to find immidiate right sibling */
-				gv_currkey->base[gv_currkey->end] = 1;
-				gv_currkey->base[gv_currkey->end + 1] = 0;
-				gv_currkey->base[gv_currkey->end + 2] = 0;
-				gv_currkey->end += 2;
+				/* If gblp2 corresponds to a spanning global, then determine
+				 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+				 */
+				assert((NULL == gvnh_reg2) || (TREF(gd_targ_gvnh_reg) == gvnh_reg2));
+				GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg2, gbl2_gd_addr, gv_currkey);
+				/* following is an attempt to find immediate right sibling */
+				GVKEY_INCREMENT_QUERY(gv_currkey);
 				/* Do $QUERY and $GET of current glvn2. Result will be in mkey and value respectively.
 				 * mkey->str contains data as database format. So no conversion necessary
 				 */
 				if (!op_gvqueryget(mkey, value))
 					break;
-				if (mkey->str.len < (TREF(gv_mergekey2))->end + 1)
+				if (mkey->str.len < mergekey2->end + 1)
 					break;
-				ptr = (unsigned char *)mkey->str.addr +  (TREF(gv_mergekey2))->end - 1;
-				if (0 != *ptr || memcmp(mkey->str.addr, (TREF(gv_mergekey2))->base, (TREF(gv_mergekey2))->end - 1))
+				ptr = (unsigned char *)mkey->str.addr +  mergekey2->end - 1;
+				if (0 != *ptr || memcmp(mkey->str.addr, mergekey2->base, mergekey2->end - 1))
 					break;
 				assert(MV_IS_STRING(mkey));
 				delta2 = mkey->str.len - org_glvn2_keysz; /* length increase of key */
@@ -327,14 +419,15 @@ void op_merge(void)
 				{
 					LV_SBS_DEPTH(dst_lv, is_base_var, sbs_depth);
 					if (MAX_LVSUBSCRIPTS <= sbs_depth)
-						rts_error(VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
 					ptr2 = gvsub2str(ptr, buff, FALSE);
 					subsc->mvtype = MV_STR;
 					subsc->str.addr = (char *)buff;
 					subsc->str.len = INTCAST(ptr2 - buff);
 					s2pool(&subsc->str);
 					dst_lv = op_putindx(VARLSTCNT(2) dst_lv, subsc);
-					while (*ptr++);	/* skip to start of next subscript */
+					while (*ptr++)
+						;	/* skip to start of next subscript */
 					is_base_var = FALSE;
 				} while (*ptr);
 				/* We created the key. Pre-process the node in case a container is being replaced,
@@ -344,7 +437,7 @@ void op_merge(void)
 				DECR_AC_REF(dst_lv, TRUE);
 				dst_lv->v = *value;
 			}
-			gvname_env_restore(mglvnp->gblp[IND2]);	 /* naked indicator is restored into gv_currkey */
+			gvname_env_restore(gblp2);	 /* naked indicator is restored into gv_currkey */
 			POP_MV_STENT();     /* subsc */
 		}
 		POP_MV_STENT();     /* mkey */
@@ -357,7 +450,7 @@ void op_merge(void)
 			UNDO_ACTIVE_LV;
 			POP_MV_STENT();	/* value */
 			if (MARG1_IS_GBL(merge_args))
-				gvname_env_restore(mglvnp->gblp[IND1]);	 /* store destination as naked indicator in gv_currkey */
+				gvname_env_restore(gblp1);	 /* store destination as naked indicator in gv_currkey */
 			merge_args = 0;	/* Must reset to zero to reuse the Global */
 			return;
 		}
@@ -389,7 +482,10 @@ void op_merge(void)
 		} else
 		{	/*==================== MERGE ^gvn1=lvn2 =====================*/
 			assert(MARG1_IS_GBL(merge_args) && MARG2_IS_LCL(merge_args));
-			gvname_env_save(mglvnp->gblp[IND1]);
+			gvname_env_save(gblp1);
+			key = gblp1->s_gv_currkey;
+			GET_NSUBS_IN_GVKEY(key->base, key->end - 1, gvn1subs);	/* sets "gvn1subs" */
+			gblp1->gvkey_nsubs = gvn1subs;	/* used later in lvzwr_out */
 			output.buff = (char *)buff;
 			output.ptr = output.buff;
 			output.out_var.gv.end = gv_currkey->end;
@@ -398,7 +494,7 @@ void op_merge(void)
 			lvzwr_init(zwr_patrn_mident, &mglvnp->lclp[IND2]->v);
 			lvzwr_arg(ZWRITE_ASTERISK, 0, 0);
 			lvzwr_var(mglvnp->lclp[IND2], 0);
-			gvname_env_restore(mglvnp->gblp[IND1]);	 /* store destination as naked indicator in gv_currkey */
+			gvname_env_restore(gblp1);	 /* store destination as naked indicator in gv_currkey */
 		}
 	}
 	POP_MV_STENT();	/* value */
diff --git a/sr_port/op_newintrinsic.c b/sr_port/op_newintrinsic.c
index fd0edcc..5fec53d 100644
--- a/sr_port/op_newintrinsic.c
+++ b/sr_port/op_newintrinsic.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,8 +29,6 @@
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_namehead	*gv_target;
 GBLREF gd_addr		*gd_header;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 GBLREF mval		dollar_ztrap;
 GBLREF mval		dollar_etrap;
 GBLREF mval		dollar_estack_delta;
@@ -54,15 +52,13 @@ void op_newintrinsic(int intrtype)
 {
 	mval		*intrinsic;
 	boolean_t	stored_explicit_null;
-	DCL_THREADGBL_ACCESS;
 
-	SETUP_THREADGBL_ACCESS;
-	switch(intrtype)
+	switch (intrtype)
 	{
 		case SV_ZTRAP:
 #			ifdef GTM_TRIGGER
 			if (0 < gtm_trigger_depth)
-				rts_error(VARLSTCNT(1) ERR_NOZTRAPINTRIG);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOZTRAPINTRIG);
 #			endif
 			/* Due to the potential intermix of $ETRAP and $ZTRAP, we put a condition on the
 			   explicit NEWing of these two special variables. If "the other" trap handler
@@ -111,7 +107,7 @@ void op_newintrinsic(int intrtype)
 			break;
 #		endif
 		default:	/* Only above types defined by compiler */
-			GTMASSERT;
+			assertpro(FALSE && intrtype);
 	}
 	gtm_newintrinsic(intrinsic);
 	if (SV_ESTACK == intrtype)
@@ -125,17 +121,14 @@ void op_newintrinsic(int intrtype)
 	} else if (SV_ZGBLDIR == intrtype)
 	{
 		if (dollar_zgbldir.str.len != 0)
-		{
 			gd_header = zgbldir(&dollar_zgbldir);
-			/* update the gd_map */
-			SET_GD_MAP;
-		} else
-		{
-			dpzgbini();
-        		gd_header = NULL;
-		}
+		else
+			dpzgbini();	/* sets gd_header to NULL */
 		if (gv_currkey)
+		{
 			gv_currkey->base[0] = 0;
+			gv_currkey->prev = gv_currkey->end = 0;
+		}
 		if (gv_target)
 			gv_target->clue.end = 0;
 	}
diff --git a/sr_port/op_nullexp.c b/sr_port/op_nullexp.c
index c198843..c490992 100644
--- a/sr_port/op_nullexp.c
+++ b/sr_port/op_nullexp.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -10,13 +10,11 @@
  ****************************************************************/
 
 #include "mdef.h"
-
-#include "gtm_string.h"
-
 #include "op.h"
 
-void op_nullexp(mval *v)
+LITREF mval skiparg;
+
+mval *op_nullexp(void)
 {
-	memset(v, 0, SIZEOF(mval));
-	v->str.addr = (char *)v;
+	return (mval *)&skiparg;
 }
diff --git a/sr_port/op_read.c b/sr_port/op_read.c
index 8f7dd80..f013ef9 100644
--- a/sr_port/op_read.c
+++ b/sr_port/op_read.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -66,7 +66,7 @@ int op_read(mval *v, int4 timeout)
 	v->mvtype = MV_STR;
 	v->str.len = 0;
 	stat = (io_curr_device.in->disp_ptr->read)(v, timeout);
-	if (stringpool.free == (unsigned char *)v->str.addr)		/* BYPASSOK */
+	if (IS_AT_END_OF_STRINGPOOL(v->str.addr, 0))
 		stringpool.free += v->str.len;	/* see UNIX iott_readfl */
 	assert(stringpool.free <= stringpool.top);
 #	ifdef KEEP_zOS_EBCDIC
diff --git a/sr_port/op_readfl.c b/sr_port/op_readfl.c
index 3b1dd39..1664b81 100644
--- a/sr_port/op_readfl.c
+++ b/sr_port/op_readfl.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -41,10 +41,10 @@ int op_readfl(mval *v, int4 length, int4 timeout)
 	 */
 	b_length = (!IS_UTF_CHSET(io_curr_device.in->ichset)) ? length : (length * 4);
 	if (0 >= length)
-		rts_error(VARLSTCNT(1) ERR_RDFLTOOSHORT);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_RDFLTOOSHORT);
 	/* This check is more useful in "M" mode. For UTF-8 mode, checks have to be done while reading */
 	if (MAX_STRLEN < length)
-		rts_error(VARLSTCNT(1) ERR_RDFLTOOLONG);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_RDFLTOOLONG);
 	assert(stringpool.free >= stringpool.base);
 	assert(stringpool.free <= stringpool.top);
 	v->mvtype = MV_STR;
@@ -53,7 +53,7 @@ int op_readfl(mval *v, int4 length, int4 timeout)
 	v->str.addr = (char *)stringpool.free;
 	active_device = io_curr_device.in;
 	stat = (io_curr_device.in->disp_ptr->readfl)(v, length, timeout);
-	if (stringpool.free == (unsigned char *)v->str.addr)	/* BYPASSOK */
+	if (IS_AT_END_OF_STRINGPOOL(v->str.addr, 0))
 		stringpool.free += v->str.len;	/* see UNIX iott_readfl */
 	assert((int4)v->str.len <= b_length);
 	assert(stringpool.free <= stringpool.top);
diff --git a/sr_port/op_rhdaddr.c b/sr_port/op_rhdaddr.c
index 4a7b3b6..0f96c43 100644
--- a/sr_port/op_rhdaddr.c
+++ b/sr_port/op_rhdaddr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,35 +25,39 @@ error_def(ERR_ZLMODULE);
 /* For routine name given, return routine header address if rhd not already set */
 rhdtyp	*op_rhdaddr(mval *name, rhdtyp *rhd)
 {
+	if (NULL != rhd)
+		return rhd;
+	else
+		return op_rhdaddr1(name);
+}
+
+/* Find the newest linked version of a routine */
+rhdtyp	*op_rhdaddr1(mval *name)
+{
 	mval		routine;
 	mident_fixed	routname;
 	rhdtyp		*answer;
 
-	if (NULL != rhd)
-		answer = rhd;
-	else
-	{
-		MV_FORCE_STR(name);
-		routine = *name;
-		routine.str.len = (MAX_MIDENT_LEN < routine.str.len ? MAX_MIDENT_LEN : routine.str.len);
-		memcpy(&routname.c[0], routine.str.addr, routine.str.len);
-		routine.str.addr = (char *)&routname.c[0];
-		if ((NULL == rtn_names) || (NULL == (answer = find_rtn_hdr(&routine.str))))	/* Note assignment */
-		{	/* Initial check for rtn_names is so we avoid the call to find_rtn_hdr() if we have just
-			 * unlinked all modules as find_rtn_hdr() does not deal well with an empty rtn table.
-			 */
-			op_zlink(&routine, NULL);
-			answer = find_rtn_hdr(&routine.str);
-			if (NULL == answer)
-				rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr,
-					ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), &zlink_mname);
-#			if defined (__alpha) && defined (__vms)
-			answer = answer->linkage_ptr;
-			if (NULL == answer)
-				rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr,
-					ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), zlink_mname.c);
-#			endif
-		}
+	MV_FORCE_STR(name);
+	routine = *name;
+	routine.str.len = (MAX_MIDENT_LEN < routine.str.len ? MAX_MIDENT_LEN : routine.str.len);
+	memcpy(&routname.c[0], routine.str.addr, routine.str.len);
+	routine.str.addr = (char *)&routname.c[0];
+	if ((NULL == rtn_names) || (NULL == (answer = find_rtn_hdr(&routine.str))))	/* Note assignment */
+	{	/* Initial check for rtn_names is so we avoid the call to find_rtn_hdr() if we have just
+		 * unlinked all modules as find_rtn_hdr() does not deal well with an empty rtn table.
+		 */
+		op_zlink(&routine, NULL);
+		answer = find_rtn_hdr(&routine.str);
+		if (NULL == answer)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr,
+				ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), &zlink_mname);
+#		if defined (__alpha) && defined (__vms)
+		answer = answer->linkage_ptr;
+		if (NULL == answer)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr,
+				ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), zlink_mname.c);
+#		endif
 	}
 	return answer;
 }
diff --git a/sr_port/op_savgvn.c b/sr_port/op_savgvn.c
index ac57ee6..8f928cc 100644
--- a/sr_port/op_savgvn.c
+++ b/sr_port/op_savgvn.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,7 +34,7 @@
 GBLREF	spdesc			stringpool;
 
 /* [Used by SET] Saves a global in the glvn pool and returns its index. */
-void op_savgvn(UNIX_ONLY_COMMA(int argcnt) mval *val_arg, ...)
+void op_savgvn(UNIX_ONLY_COMMA(int argcnt) int hash_code_dummy, mval *val_arg, ...)
 {
 	va_list			var;
 	mval			*m, *key;
@@ -47,6 +47,7 @@ void op_savgvn(UNIX_ONLY_COMMA(int argcnt) mval *val_arg, ...)
 	SETUP_THREADGBL_ACCESS;
 	VAR_START(var, val_arg);
 	VMS_ONLY(va_count(argcnt));
+	--argcnt;	/* remove hash_code_dummy from parameter list before storing */
 	ENSURE_GLVN_POOL_SPACE(argcnt);
 	GET_GLVN_POOL_STATE(slot, m);
 	gvn_info = (gparam_list *)&slot->glvn_info;
diff --git a/sr_port/op_setzbrk.c b/sr_port/op_setzbrk.c
index 3fbfd96..8d8a6c0 100644
--- a/sr_port/op_setzbrk.c
+++ b/sr_port/op_setzbrk.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,7 @@
 #include "iosp.h"
 #include "gtm_text_alloc.h"
 #include "srcline.h"
+#include "compiler.h"
 #ifdef GTM_TRIGGER
 # include "trigger_source_read_andor_verify.h"
 # include "gtm_trigger_trc.h"
@@ -36,7 +37,7 @@
 
 GBLREF z_records		zbrk_recs;
 GBLREF mident_fixed		zlink_mname;
-GBLREF stack_frame		frame_pointer;
+GBLREF stack_frame		*frame_pointer;
 GBLREF unsigned short		proc_act_type;
 
 error_def(ERR_COMMENT);
@@ -84,21 +85,23 @@ void	op_setzbrk(mval *rtn, mval *lab, int offset, mval *act, int cnt)
 		GTMTRIG_ONLY(IS_TRIGGER_RTN(&rtn->str, is_trigger));
 		GTMTRIG_ONLY(if (is_trigger) DBGTRIGR((stderr, "op_setzbrk: Setting/clearing a zbreak in a trigger\n")));
 		flush_pio();
-		if (NULL == (routine = find_rtn_hdr(&rtn->str)))	/* Note assignment */
+		if (WANT_CURRENT_RTN(rtn))
+			routine = CURRENT_RHEAD_ADR(frame_pointer->rvector);
+		else if (NULL == (routine = find_rtn_hdr(&rtn->str)))	/* Note assignment */
 		{
 #			ifdef GTM_TRIGGER
 			if (is_trigger)
 			{
 				sstatus = trigger_source_read_andor_verify(&rtn->str, TRIGGER_COMPILE);
 				if ((0 != sstatus) || (NULL == (routine = find_rtn_hdr(&rtn->str))))	/* Note assignment */
-					rts_error(VARLSTCNT(4) ERR_TRIGNAMENF, 2, rtn->str.len, rtn->str.addr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TRIGNAMENF, 2, rtn->str.len, rtn->str.addr);
 			} else
 #			endif
 			{
 				op_zlink(rtn, NULL);
 				routine = find_rtn_hdr(&rtn->str);
 				if (NULL == routine)
-					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, rtn->str.len, rtn->str.addr,
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZLINKFILE, 2, rtn->str.len, rtn->str.addr,
 						  ERR_ZLMODULE, 2, mid_len(&zlink_mname), &zlink_mname.c[0]);
 			}
 		}
@@ -156,7 +159,7 @@ void	op_setzbrk(mval *rtn, mval *lab, int offset, mval *act, int cnt)
 						lname.len = lab->str.len;
 						lname.addr = lab->str.addr;
 						zbloc_end = rtnlaboff2entryref(zbloc_buff, &rname, &lname, offset);
-						rts_error(VARLSTCNT(4) ERR_ZBREAKFAIL, 2, zbloc_end - zbloc_buff,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZBREAKFAIL, 2, zbloc_end - zbloc_buff,
 								zbloc_buff);
 					}
 				}
@@ -187,9 +190,9 @@ void	op_setzbrk(mval *rtn, mval *lab, int offset, mval *act, int cnt)
 					*addr = (*addr & (zb_code)(~ZB_CODE_MASK)) |
 						((xf_zbstart * SIZEOF(UINTPTR_T)) << ZB_CODE_SHIFT);
 #					endif
-				} else if (((xf_zbstart * SIZEOF(UINTPTR_T)) != tmp_xf_code)
-					&& ((xf_zbfetch * SIZEOF(UINTPTR_T)) != tmp_xf_code))
-					GTMASSERT;
+				} else
+					assertpro( ((xf_zbstart * SIZEOF(UINTPTR_T)) == tmp_xf_code)
+						|| ((xf_zbfetch * SIZEOF(UINTPTR_T)) == tmp_xf_code));
 				z_ptr->rtn = &(CURRENT_RHEAD_ADR(routine))->routine_name;
 				assert(lab_name != NULL);
 				z_ptr->lab = lab_name;
@@ -207,6 +210,6 @@ void	op_setzbrk(mval *rtn, mval *lab, int offset, mval *act, int cnt)
 			z_ptr->action = csp;
 			z_ptr->count = cnt;
 		} else
-			GTMASSERT;
+			assertpro(FALSE && line_offset_addr && cnt);
 	}
 }
diff --git a/sr_port/op_setzextract.c b/sr_port/op_setzextract.c
index 3cce1a1..3fad6d7 100644
--- a/sr_port/op_setzextract.c
+++ b/sr_port/op_setzextract.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -77,7 +77,7 @@ void op_setzextract(mval *src, mval *expr, int schar, int echar, mval *dst)
 	/* Calculate total string len. delim_cnt has needed padding delimiters for null fields */
 	strlen = (size_t)pfxlen + padlen + (size_t)expr->str.len + (size_t)sfxlen;
 	if (MAX_STRLEN < strlen)
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 	ENSURE_STP_FREE_SPACE((int)strlen);
 
 	pfx = (unsigned char *)src->str.addr;
@@ -103,7 +103,7 @@ void op_setzextract(mval *src, mval *expr, int schar, int echar, mval *dst)
 		memcpy(straddr, pfx + sfxoff, sfxlen);
 		straddr += sfxlen;
 	}
-	assert((straddr - stringpool.free) == strlen);
+	assert(IS_AT_END_OF_STRINGPOOL(straddr, -strlen));
 	dst->mvtype = MV_STR;
 	dst->str.len = INTCAST(straddr - stringpool.free);
 	dst->str.addr = (char *)stringpool.free;
diff --git a/sr_port/op_setzp1.c b/sr_port/op_setzp1.c
index 12788eb..5c2b733 100644
--- a/sr_port/op_setzp1.c
+++ b/sr_port/op_setzp1.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -228,7 +228,7 @@ void op_setzp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 	/* Calculate total string len. delim_cnt has needed padding delimiters for null fields */
 	str_len = (size_t)expr->str.len + (size_t)pfx_str_len + delim_cnt + (size_t)sfx_str_len;
 	if (str_len > MAX_STRLEN)
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 	ENSURE_STP_FREE_SPACE((int)str_len);
 	str_addr = stringpool.free;
 	start_pfx = (unsigned char *)src->str.addr;
@@ -253,7 +253,7 @@ void op_setzp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 		memcpy(str_addr, start_pfx + sfx_start_offset, sfx_str_len);
 		str_addr += sfx_str_len;
 	}
-	assert((str_addr - stringpool.free) == (int)str_len);
+	assert(IS_AT_END_OF_STRINGPOOL(str_addr, -str_len));
 	dst->mvtype = MV_STR;
 	dst->str.len = INTCAST(str_addr - stringpool.free);
 	dst->str.addr = (char *)stringpool.free;
diff --git a/sr_port/op_setzpiece.c b/sr_port/op_setzpiece.c
index e2089f6..15893d5 100644
--- a/sr_port/op_setzpiece.c
+++ b/sr_port/op_setzpiece.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -122,7 +122,7 @@ void op_setzpiece(mval *src, mval *del, mval *expr, int4 first, int4 last, mval
 		str_len += (size_t)(src->str.len - second_src_ind);
 	if (MAX_STRLEN < str_len)
 	{
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 		return;
 	}
 	ENSURE_STP_FREE_SPACE((int)str_len);
@@ -150,11 +150,10 @@ void op_setzpiece(mval *src, mval *del, mval *expr, int4 first, int4 last, mval
 		memcpy(str_addr, tmp_str, len);
 		str_addr += len;
 	}
-	assert((str_addr - stringpool.free) == str_len);
+	assert(IS_AT_END_OF_STRINGPOOL(str_addr, -str_len));
 	dst->mvtype = MV_STR;
 	dst->str.len = INTCAST(str_addr - stringpool.free);
 	dst->str.addr = (char *)stringpool.free;
 	stringpool.free = str_addr;
 	return;
 }
-
diff --git a/sr_port/op_svget.c b/sr_port/op_svget.c
index ff84916..15f1544 100644
--- a/sr_port/op_svget.c
+++ b/sr_port/op_svget.c
@@ -293,7 +293,7 @@ void op_svget(int varnum, mval *v)
 		case SV_ZDIR:
 			setzdir(NULL, v);
 			if (v->str.len != dollar_zdir.str.len || 0 != memcmp(v->str.addr, dollar_zdir.str.addr, v->str.len))
-				gtm_putmsg(VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4, v->str.len, v->str.addr,
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4, v->str.len, v->str.addr,
 					   dollar_zdir.str.len, dollar_zdir.str.addr);
 			SKIP_DEVICE_IF_NOT_NEEDED(v);
 			s2pool(&(v->str));
@@ -440,7 +440,7 @@ void op_svget(int varnum, mval *v)
 			}
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTDATA:
 #			ifdef GTM_TRIGGER
@@ -451,7 +451,7 @@ void op_svget(int varnum, mval *v)
 			memcpy(v, (NULL != dollar_ztdata) ? dollar_ztdata : &literal_null, SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTOLDVAL:
 #			ifdef GTM_TRIGGER
@@ -462,7 +462,7 @@ void op_svget(int varnum, mval *v)
 			memcpy(v, (NULL != dollar_ztoldval) ? dollar_ztoldval : &literal_null, SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTRIGGEROP:
 #			ifdef GTM_TRIGGER
@@ -471,7 +471,7 @@ void op_svget(int varnum, mval *v)
 			memcpy(v, (NULL != dollar_ztriggerop) ? dollar_ztriggerop : &literal_null, SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTUPDATE:
 #			ifdef GTM_TRIGGER
@@ -482,7 +482,7 @@ void op_svget(int varnum, mval *v)
 				   : &literal_null), SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTVALUE:
 #			ifdef GTM_TRIGGER
@@ -493,7 +493,7 @@ void op_svget(int varnum, mval *v)
 			memcpy(v, (NULL != dollar_ztvalue) ? dollar_ztvalue : &literal_null, SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTWORMHOLE:
 #			ifdef GTM_TRIGGER
@@ -508,7 +508,7 @@ void op_svget(int varnum, mval *v)
 			ztwormhole_used = TRUE;
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTSLATE:
 #			ifdef GTM_TRIGGER
@@ -519,14 +519,14 @@ void op_svget(int varnum, mval *v)
 			memcpy(v, mvp, SIZEOF(mval));
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTLEVEL:
 #			ifdef GTM_TRIGGER
 			MV_FORCE_MVAL(v, gtm_trigger_depth);
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZONLNRLBK:
 #			ifdef UNIX
@@ -534,9 +534,20 @@ void op_svget(int varnum, mval *v)
 			MV_FORCE_MVAL(v, count);
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
+		case SV_ZCLOSE:
+#			ifdef UNIX
+			count = TREF(dollar_zclose);
+			MV_FORCE_MVAL(v, count);
+			break;
+#			else
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
+#			endif
+		case SV_ZKEY:
+			get_dlr_zkey(v);
+			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE);
 	}
 }
diff --git a/sr_port/op_svput.c b/sr_port/op_svput.c
index 7b29ea4..809a574 100644
--- a/sr_port/op_svput.c
+++ b/sr_port/op_svput.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -52,8 +52,6 @@
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_namehead	*gv_target;
 GBLREF gd_addr		*gd_header;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 GBLREF io_pair		io_curr_device;
 GBLREF mval		dollar_ztrap;
 GBLREF mval		dollar_zstatus;
@@ -138,18 +136,14 @@ void op_svput(int varnum, mval *v)
 		case SV_ZGBLDIR:
 			MV_FORCE_STR(v);
 			if ((dollar_zgbldir.str.len != v->str.len)
-			    || memcmp(dollar_zgbldir.str.addr, v->str.addr, dollar_zgbldir.str.len))
+				|| memcmp(dollar_zgbldir.str.addr, v->str.addr, dollar_zgbldir.str.len))
 			{
 				if (0 == v->str.len)
-				{
-					/* set $zgbldir="" */
-					dpzgbini();
-					gd_header = NULL;
+				{	/* set $zgbldir="" */
+					dpzgbini();	/* sets gd_header to NULL */
 				} else
 				{
 					gd_header = zgbldir(v);
-					/* update the gd_map */
-					SET_GD_MAP;
 					dollar_zgbldir.str.len = v->str.len;
 					dollar_zgbldir.str.addr = v->str.addr;
 					s2pool(&dollar_zgbldir.str);
@@ -186,7 +180,7 @@ void op_svput(int varnum, mval *v)
 		case SV_ZTRAP:
 #			ifdef GTM_TRIGGER
 			if (0 < gtm_trigger_depth)
-				rts_error(VARLSTCNT(1) ERR_NOZTRAPINTRIG);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOZTRAPINTRIG);
 #			endif
 			MV_FORCE_STR(v);
 			if (ztrap_new)
@@ -267,13 +261,13 @@ void op_svput(int varnum, mval *v)
 				if ((state != 1) || (v->str.len < 3))
 				{
 					/* error, ecode = M101 */
-					rts_error(VARLSTCNT(4) ERR_INVECODEVAL, 2, v->str.len, v->str.addr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_INVECODEVAL, 2, v->str.len, v->str.addr);
 				}
 			}
 			if (v->str.len > 0)
 			{
 				ecode_add(&v->str);
-				rts_error(VARLSTCNT(2) ERR_SETECODE, 0);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(2) ERR_SETECODE, 0);
 			} else
 			{
 				NULLIFY_DOLLAR_ECODE;	/* reset $ECODE related variables to correspond to $ECODE = NULL state */
@@ -313,7 +307,7 @@ void op_svput(int varnum, mval *v)
 			break;
 		case SV_SYSTEM:
 			assert(FALSE);
-			rts_error(VARLSTCNT(4) ERR_SYSTEMVALUE, 2, v->str.len, v->str.addr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SYSTEMVALUE, 2, v->str.len, v->str.addr);
 			break;
 		case SV_ZDIR:
 			setzdir(v, NULL); 	/* change directory to v */
@@ -345,9 +339,9 @@ void op_svput(int varnum, mval *v)
 #			ifdef GTM_TRIGGER
 			assert(!dollar_tlevel || (tstart_trigger_depth <= gtm_trigger_depth));
 			if (!dollar_tlevel || (tstart_trigger_depth == gtm_trigger_depth))
-				rts_error(VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
 			if (dollar_ztriggerop != &gvtr_cmd_mval[GVTR_CMDTYPE_SET])
-				rts_error(VARLSTCNT(4) ERR_SETINSETTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SETINSETTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
 			assert(0 < gtm_trigger_depth);
 			memcpy(dollar_ztvalue, v, SIZEOF(mval));
 			dollar_ztvalue->mvtype &= ~MV_ALIASCONT;	/* Make sure to shut off alias container flag on copy */
@@ -355,7 +349,7 @@ void op_svput(int varnum, mval *v)
 			*ztvalue_changed_ptr = TRUE;
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTWORMHOLE:
 #			ifdef GTM_TRIGGER
@@ -363,28 +357,28 @@ void op_svput(int varnum, mval *v)
 			/* See jnl.h for why MAX_ZTWORMHOLE_SIZE should be less than minimum alignsize */
 			assert(MAX_ZTWORMHOLE_SIZE < (JNL_MIN_ALIGNSIZE * DISK_BLOCK_SIZE));
 			if (MAX_ZTWORMHOLE_SIZE < v->str.len)
-				rts_error(VARLSTCNT(4) ERR_ZTWORMHOLE2BIG, 2, v->str.len, MAX_ZTWORMHOLE_SIZE);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZTWORMHOLE2BIG, 2, v->str.len, MAX_ZTWORMHOLE_SIZE);
 			dollar_ztwormhole.mvtype = MV_STR;
 			dollar_ztwormhole.str = v->str;
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		case SV_ZTSLATE:
 #			ifdef GTM_TRIGGER
 			assert(!dollar_tlevel || (tstart_trigger_depth <= gtm_trigger_depth));
 			if (!dollar_tlevel || (tstart_trigger_depth == gtm_trigger_depth))
-				rts_error(VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTSLATE"));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTSLATE"));
 			assert(0 < gtm_trigger_depth);
 			MV_FORCE_DEFINED(v);
 			memcpy((char *)&dollar_ztslate, v, SIZEOF(mval));
 			dollar_ztslate.mvtype &= ~MV_ALIASCONT;	/* Make sure to shut off alias container flag on copy */
 			break;
 #			else
-			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 #			endif
 		default:
-			GTMASSERT;
+			assertpro(FALSE && varnum);
 	}
 	return;
 }
diff --git a/sr_port/op_tcommit.c b/sr_port/op_tcommit.c
index 1b56735..373f70f 100644
--- a/sr_port/op_tcommit.c
+++ b/sr_port/op_tcommit.c
@@ -82,7 +82,6 @@ GBLREF	sgm_info		*first_sgm_info, *sgm_info_ptr;
 GBLREF	char			*update_array, *update_array_ptr;
 GBLREF	unsigned char		rdfail_detail;
 GBLREF	cw_set_element		cw_set[];
-GBLREF	gd_addr			*gd_header;
 GBLREF	boolean_t		tp_kill_bitmaps;
 GBLREF	gv_namehead		*gv_target;
 GBLREF	unsigned char		t_fail_hist[CDB_MAX_TRIES];
diff --git a/sr_port/op_trollback.c b/sr_port/op_trollback.c
index 6587c94..b26500e 100644
--- a/sr_port/op_trollback.c
+++ b/sr_port/op_trollback.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,7 +42,6 @@ GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	void			(*tp_timeout_clear_ptr)(void);
 GBLREF	int			process_exiting;
-GBLREF	gd_binding		*gd_map;
 #ifdef GTM_TRIGGER
 GBLREF	int4			gtm_trigger_depth;
 GBLREF	int4			tstart_trigger_depth;
@@ -85,13 +84,13 @@ void	op_trollback(int rb_levels)		/* rb_levels -> # of transaction levels by whi
 		implicit_trollback = FALSE;
 	}
 	if (!dollar_tlevel)
-		rts_error(VARLSTCNT(1) ERR_TLVLZERO);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TLVLZERO);
 	if (0 > rb_levels)
 	{
 		if (dollar_tlevel < -rb_levels)
-			rts_error(VARLSTCNT(4) ERR_TROLLBK2DEEP, 2, -rb_levels, dollar_tlevel);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TROLLBK2DEEP, 2, -rb_levels, dollar_tlevel);
 	} else if (dollar_tlevel <= rb_levels)
-		rts_error(VARLSTCNT(4) ERR_INVROLLBKLVL, 2, rb_levels, dollar_tlevel);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_INVROLLBKLVL, 2, rb_levels, dollar_tlevel);
 	newlevel = (0 > rb_levels) ? dollar_tlevel + rb_levels : rb_levels;
 	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
 	save_cur_region = gv_cur_region;
@@ -132,10 +131,10 @@ void	op_trollback(int rb_levels)		/* rb_levels -> # of transaction levels by whi
 			assert(tp_pointer <= (tp_frame *)tpstackbase);
 			assert(NULL != gv_currkey);
 			gv_orig_key_ptr = tp_pointer->orig_key;
+			assert(NULL != gv_orig_key_ptr);
 			COPY_KEY(gv_currkey, gv_orig_key_ptr);
 			gv_target = tp_pointer->orig_gv_target;
 			gd_header = tp_pointer->gd_header;
-			gd_map = gd_header->maps;
 			gv_cur_region = tp_pointer->gd_reg;
 			TP_CHANGE_REG(gv_cur_region);
 			reg_reset = TRUE;	/* so we dont restore gv_cur_region again */
diff --git a/sr_port/op_tstart.c b/sr_port/op_tstart.c
index d20568a..17c96a1 100644
--- a/sr_port/op_tstart.c
+++ b/sr_port/op_tstart.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -92,6 +92,7 @@ GBLREF	boolean_t		gtm_utf8_mode;
 GBLREF	uint4			tstartcycle;
 GBLREF	char			*update_array_ptr;
 GBLREF	ua_list			*curr_ua, *first_ua;
+GBLREF	mstr			extnam_str;
 #ifdef GTM_TRIGGER
 GBLREF	mval			dollar_ztwormhole;
 GBLREF	int4			gtm_trigger_depth;
@@ -111,7 +112,8 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 {
 	boolean_t		serial;			/* whether SERIAL keyword was present */
 	int			prescnt,		/* number of names to save, -1 = no restart, -2 = preserve all */
-				pres;
+				pres, len;
+	char			*ptr;
 	lv_val			*lv;
 	mlk_pvtblk		*pre_lock;
 	mlk_tp			*lck_tp;
@@ -165,7 +167,7 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 			for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
 			{
 				if (r_local->open && !r_local->was_open &&
-				    (dba_bg == r_local->dyn.addr->acc_meth || dba_mm == r_local->dyn.addr->acc_meth))
+				    (dba_bg == REG_ACC_METH(r_local) || dba_mm == REG_ACC_METH(r_local)))
 				{	/* Let's initialize those regions but only if it came through gvcst_init_sysops
 					   (being a bg or mm region)
 					*/
@@ -175,9 +177,9 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 		}
 	}
 	if (0 != jnl_fence_ctl.level)
-		rts_error(VARLSTCNT(4) ERR_TPMIXUP, 2, "An M", "a fenced logical");
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TPMIXUP, 2, "An M", "a fenced logical");
 	if (dollar_tlevel + 1 >= TP_MAX_NEST)
-		rts_error(VARLSTCNT(1) ERR_TPTOODEEP);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TPTOODEEP);
 	va_start(varlst, implicit_flag);	/* no argument count first */
 	serial = va_arg(varlst, int);
 	tid = va_arg(varlst, mval *);
@@ -320,9 +322,9 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 			if (msp <= stacktop)
 			{
 				msp = old_sp;
-				rts_error(VARLSTCNT(1) ERR_STACKOFLOW);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_STACKOFLOW);
 			} else
-				rts_error(VARLSTCNT(1) ERR_STACKCRIT);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_STACKCRIT);
 		}
 		memmove(msp, old_sp, top - (unsigned char *)old_sp);	/* Shift stack w/possible overlapping ranges */
 		mv_st_ent = (mv_stent *)(top - shift_size);
@@ -386,7 +388,6 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 	DBGRFCT((stderr, "\n*** op_tstart: *** Entering $TLEVEL = %d\n", dollar_tlevel + 1));
 	tf = (tp_frame *)(tp_sp -= SIZEOF(tp_frame));
 	assert((unsigned char *)tf > tpstacktop);	/* Block should lie entirely within tp stack area */
-	tf->dlr_t = dollar_truth;
 	tf->restart_pc = fp->mpc;
 	tf->restart_ctxt = fp->ctxt;
 	tf->fp = fp;
@@ -394,8 +395,6 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 	tf->trans_id = *tid;
 	tf->restartable = (NORESTART != prescnt);
 	tf->old_locks = (NULL != mlk_pvt_root);
-	tf->orig_gv_target = gv_target;
-	DBG_CHECK_GVTARGET_CSADDRS_IN_SYNC;
 #	ifdef DEBUG
 	if (!jgbl.forw_phase_recovery)
 	{	/* In case of forward phase of journal recovery, gv_currkey is set by caller (mur_forward) only
@@ -404,18 +403,54 @@ void	op_tstart(int implicit_flag, ...) /* value of $T when TSTART */
 		DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
 	}
 #	endif
-	/* If the TP structures have not yet been initialized, do that now. */
-	if (NULL == TREF(gv_tporigkey_ptr))
-	{	/* This need only be set once */
-		TREF(gv_tporigkey_ptr) = (gv_orig_key_array *)malloc(SIZEOF(gv_orig_key_array));
-		memset(TREF(gv_tporigkey_ptr), 0, SIZEOF(gv_orig_key_array));
+	if (!dollar_tlevel)
+	{	/* If the TP structures have not yet been initialized, do that now. */
+		if (NULL == TREF(gv_tporigkey_ptr))
+		{	/* This need only be set once */
+			TREF(gv_tporigkey_ptr) = (gv_orig_key_array *)malloc(SIZEOF(gv_orig_key_array));
+			memset(TREF(gv_tporigkey_ptr), 0, SIZEOF(gv_orig_key_array));
+		}
+		tf->orig_key = (gv_key *)&((TREF(gv_tporigkey_ptr))->gv_orig_key[0]);
+		assert(NULL != gv_currkey);
+		MEMCPY_KEY(tf->orig_key, gv_currkey);
+		tf->gd_header = gd_header;
+		tf->gd_reg = gv_cur_region;
+		tf->orig_gv_target = gv_target;
+		tf->zgbldir = dollar_zgbldir;
+		tf->dlr_t = dollar_truth;
+		len = extnam_str.len;
+		tf->extnam_str.len = len;
+		if (len)
+		{	/* Take a copy of extnam_str */
+			if ((TREF(gv_tporig_extnam_str)).len < len)
+			{
+				if (NULL != (TREF(gv_tporig_extnam_str)).addr)
+					free((TREF(gv_tporig_extnam_str)).addr);
+				(TREF(gv_tporig_extnam_str)).addr = malloc(len);
+				(TREF(gv_tporig_extnam_str)).len = len;	/* this is the allocated buffer size */
+			}
+			ptr = (TREF(gv_tporig_extnam_str)).addr;
+			memcpy(ptr, extnam_str.addr, len);
+			tf->extnam_str.addr = ptr;
+		}
 	}
-	tf->orig_key = (gv_key *)&((TREF(gv_tporigkey_ptr))->gv_orig_key[dollar_tlevel][0]);
-	assert(NULL != gv_currkey);
-	MEMCPY_KEY(tf->orig_key, gv_currkey);
-	tf->gd_header = gd_header;
-	tf->gd_reg = gv_cur_region;
-	tf->zgbldir = dollar_zgbldir;
+#	ifdef DEBUG
+	else
+	{	/* Set up fields in "tf" to impossible values for nested TP frames. These should never be used.
+		 * This will help us get an assert failure or SIG-11 right should any of these get referenced.
+		 */
+		tf->orig_key = NULL;
+		tf->gd_header = NULL;
+		tf->gd_reg = NULL;
+		tf->orig_gv_target = NULL;
+		/* Unfortunately tf->dlr_t has just one bit to store 0 or 1 (valid values) so an impossible value of say -1
+		 * cannot be stored here. We therefore skip initializing this one.
+		 */
+		tf->zgbldir.mvtype = 0;	/* impossible value */
+		tf->extnam_str.len = -1; /* impossible value */
+	}
+#	endif
+	DBG_CHECK_GVTARGET_CSADDRS_IN_SYNC;
 	tf->mvc = mv_st_ent;
 	tf->sym = curr_symval;
 	tf->tp_save_all_flg = FALSE;
diff --git a/sr_port/op_view.c b/sr_port/op_view.c
index c2bda1b..70dbf0b 100644
--- a/sr_port/op_view.c
+++ b/sr_port/op_view.c
@@ -53,6 +53,9 @@
 #include "alias.h"
 #include "fullbool.h"
 #include "anticipatory_freeze.h"
+#include "gvnh_spanreg.h"
+#include "targ_alloc.h"
+#include "gvcst_protos.h"
 #ifdef GTM_TRIGGER
 # include "rtnhdr.h"		/* for rtn_tabent in gv_trigger.h */
 # include "gv_trigger.h"
@@ -61,10 +64,12 @@
 #ifdef UNIX
 # include "wbox_test_init.h"
 # include "mutex.h"
+# include "gtmlink.h"
 # ifdef DEBUG
 #  include "gtmsecshr.h"
 # endif
 #endif
+#include "gtmimagename.h"
 
 STATICFNDCL void view_dbflushop(unsigned char keycode, viewparm *parmblkptr, mval *thirdarg);
 
@@ -99,6 +104,7 @@ error_def(ERR_ACTRANGE);
 error_def(ERR_COLLATIONUNDEF);
 error_def(ERR_COLLDATAEXISTS);
 error_def(ERR_DBFSYNCERR);
+error_def(ERR_GBLNOMAPTOREG);
 error_def(ERR_INVZDIRFORM);
 error_def(ERR_ISOLATIONSTSCHN);
 error_def(ERR_JNLFLUSH);
@@ -140,9 +146,11 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 	mval			*arg, *nextarg, outval;
 	mstr			tmpstr;
 	va_list			var;
-	viewparm		parmblk;
+	viewparm		parmblk, parmblk2;
 	viewtab_entry		*vtp;
 	gd_addr			*addr_ptr;
+	gvnh_reg_t		*gvnh_reg;
+	gvnh_spanreg_t		*gvspan;
 	noisolation_element	*gvnh_entry;
 	int			lct, ncol, nct;
 	collseq			*new_lcl_collseq;
@@ -155,7 +163,7 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 	int			table_size_orig;
 	ht_ent_mname		*table_base_orig;
 	hash_table_mname	*table;
-	boolean_t		dbgdmpenabled, was_crit;
+	boolean_t		dbgdmpenabled, was_crit, was_skip_gtm_putmsg;
 	symval			*lvlsymtab;
 	lv_blk			*lvbp;
 	lv_val			*lvp, *lvp_top;
@@ -174,8 +182,7 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 	VAR_START(var, keyword);
 	VMS_ONLY(va_count(numarg));
 		jnl_status = 0;
-	if (numarg < 1)
-		GTMASSERT;
+	assertpro(1 <= numarg);
 	MV_FORCE_STR(keyword);
 	numarg--;	/* remove keyword from count */
 	if (0 < numarg)
@@ -185,7 +192,7 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 	} else
 		arg = (mval *)NULL;
 	vtp = viewkeys(&keyword->str);
-	view_arg_convert(vtp, arg, &parmblk);
+	view_arg_convert(vtp, (int)vtp->parm, arg, &parmblk, IS_DOLLAR_VIEW_FALSE);
 	switch(vtp->keycode)
 	{
 #		ifdef UNICODE_SUPPORTED
@@ -378,7 +385,7 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 				{
 					if (!reg->open)
 						continue;
-					switch(reg->dyn.addr->acc_meth)
+					switch(REG_ACC_METH(reg))
 					{
 						case dba_mm:
 						case dba_bg:
@@ -389,12 +396,38 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 						case dba_usr:
 							break;
 						default:
-							GTMASSERT;
+							assert(FALSE && REG_ACC_METH(reg));
 							break;
 					}
 				}
 			}
 			break;
+		case VTK_YCHKCOLL:
+			if (arg)
+				lct = MV_FORCE_INT(parmblk.value);
+			else
+			{
+				va_end(var);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REQDVIEWPARM);
+			}
+			if (0 == lct)
+				break;	/* 0 value of collation is always good */
+			if ((lct < MIN_COLLTYPE) || (lct > MAX_COLLTYPE))
+			{
+				va_end(var);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ACTRANGE, 1, lct);
+			}
+			was_skip_gtm_putmsg = TREF(skip_gtm_putmsg);
+			TREF(skip_gtm_putmsg) = TRUE;	/* to avoid ready_collseq from doing gtm_putmsg in case of errors.
+							 * not doing so will cause GDECHECK errors in caller (GDE). */
+			new_lcl_collseq = ready_collseq(lct);
+			TREF(skip_gtm_putmsg) = was_skip_gtm_putmsg;
+			if (0 == new_lcl_collseq)
+			{
+				va_end(var);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, lct);
+			}
+			break;
 		case VTK_YDIRTVAL:
 			/* This is an internal use only call to VIEW which is used to modify directory
 			 * tree entries.  It places a string in in the static array view_ydirt_str.  A subsequent
@@ -424,6 +457,23 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 			 * a YDIRTREE update is performed
 			 */
 			op_gvname(VARLSTCNT(1) parmblk.value);
+			arg = (numarg > 1) ? va_arg(var, mval *) : NULL;
+			if (NULL != arg)
+			{
+				view_arg_convert(vtp, VTP_DBREGION, arg, &parmblk2, IS_DOLLAR_VIEW_FALSE);
+				reg = parmblk2.gv_ptr;
+				/* Determine if "reg" is mapped to by global name. If not issue error */
+				gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set up by op_gvname */
+				gvspan = (NULL == gvnh_reg) ? NULL : gvnh_reg->gvspan;
+				if (((NULL != gvspan) && !gvnh_spanreg_ismapped(gvnh_reg, gd_header, reg))
+					|| ((NULL == gvspan) && (reg != gv_cur_region)))
+				{
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GBLNOMAPTOREG, 4,
+						parmblk.value->str.len, parmblk.value->str.addr, REG_LEN_STR(reg));
+				}
+				if (NULL != gvspan)
+					GV_BIND_SUBSREG(gd_header, reg, gvnh_reg);
+			}
 			assert(INVALID_GV_TARGET == reset_gv_target);
 			reset_gv_target = gv_target;
 			gv_target = cs_addrs->dir_tree;		/* Trick the put program into using the directory tree */
@@ -686,6 +736,11 @@ void	op_view(UNIX_ONLY_COMMA(int numarg) mval *keyword, ...)
 		case VTK_NOLOGTPRESTART:
 			TREF(tprestart_syslog_delta) = 0;
 			break;
+#		ifdef UNIX
+		case VTK_LINK:
+			init_relink_allowed(&parmblk.value->str);
+			break;
+#		endif
 #		ifdef DEBUG_ALIAS
 		case VTK_LVMONOUT:
 			als_lvmon_output();
diff --git a/sr_port/op_zgoto.c b/sr_port/op_zgoto.c
index 165edea..1af75c1 100644
--- a/sr_port/op_zgoto.c
+++ b/sr_port/op_zgoto.c
@@ -51,11 +51,12 @@ error_def(ERR_ZGOTOTOOBIG);
 
 void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
 {
-	stack_frame	*fp, *fpprev, *base_frame;
+	stack_frame	*fp, *fpprev;
 	int4		curlvl;
 	mval		rtnname, lblname;
 	rhdtyp		*rtnhdr;
 	lnr_tabent 	USHBIN_ONLY(*)*lnrptr;
+	void		(*frame_func)();
 	char		rtnname_buff[SIZEOF(mident_fixed)], lblname_buff[SIZEOF(mident_fixed)];
 	DEBUG_ONLY(int4	dlevel;)
 
@@ -156,16 +157,14 @@ void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
 		}
 		/* Full unlink/unwind requested. First unlink everything, then relink our target entryref */
 		gtm_unlink_all();
-		/* Now that everything is unwound except the frame we will rewrite when we start going forward again, we need to
-		 * find the base frame. This frame contains the same rvector pointer that the level 1 stack frame routine has so
-		 * it needs to also be rewritten once we link our new "1st routine". Find the base frame we will be modifying.
+		frame_func = new_stack_frame;
+		/* Now that everything is unwound, frame_pointer is the base frame. This frame contains the same rvector pointer
+		 * that the level 1 stack frame routine has so it needs to also be rewritten once we link our new "1st routine".
 		 */
-		for (base_frame = frame_pointer; ((NULL != base_frame) && (NULL != base_frame->old_frame_pointer));
-		     base_frame = base_frame->old_frame_pointer);
-		assert(NULL != base_frame);
+		assert((NULL != frame_pointer) && (NULL == frame_pointer->old_frame_pointer));
 		rtnhdr = op_rhdaddr(&rtnname, NULL);
 		assert(NULL != rtnhdr);
-		base_frame->rvector = rtnhdr;
+		frame_pointer->rvector = rtnhdr;
 		lnrptr = op_labaddr(rtnhdr, &lblname, offset);
 		assert(NULL != lnrptr);
 	} else
@@ -173,16 +172,19 @@ void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
 	{	/* Unwind to our target level (UNIX if 0 != level  and VMS [all]) */
 		GOLEVEL(level, TRUE);	/* Unwind the trigger base frame if we run into one */
 		assert(level == dollar_zlevel());
+		frame_func = flush_jmp;
 	}
-	/* Convert current stack frame to the frame for the entry ref we want to branch to */
-	USHBIN_ONLY(flush_jmp(rtnhdr, (unsigned char *)LINKAGE_ADR(rtnhdr), LINE_NUMBER_ADDR(rtnhdr, *lnrptr)));
+	/* Convert current stack frame (flush_jmp) to the frame for the entry ref we want to branch to, or create a new level 1
+	 * frame (new_stack_frame) after ZGOTO 0.
+	 */
+	USHBIN_ONLY((* frame_func)(rtnhdr, (unsigned char *)LINKAGE_ADR(rtnhdr), LINE_NUMBER_ADDR(rtnhdr, *lnrptr)));
 	/* on non-shared binary calculate the transfer address to be passed to flush_jmp as follows:
 	 * 	1) get the number stored at lnrptr; this is the offset to the line number entry
 	 *	2) add the said offset to the address of the routine header; this is the address of line number entry
 	 *	3) dereference the said address to get the line number of the actual program
 	 *	4) add the said line number to the address of the routine header
 	 */
-	NON_USHBIN_ONLY(flush_jmp(rtnhdr, (unsigned char *)LINKAGE_ADR(rtnhdr),
+	NON_USHBIN_ONLY((* frame_func)(rtnhdr, (unsigned char *)LINKAGE_ADR(rtnhdr),
 		(unsigned char *)((int)rtnhdr + *(int *)((int)rtnhdr + *lnrptr))));
 	DBGEHND((stderr, "op_zgoto: Resuming at frame 0x"lvaddr" with type 0x%04lx\n", frame_pointer, frame_pointer->type));
 #	ifdef GTM_TRIGGER
diff --git a/sr_port/op_zprevious.c b/sr_port/op_zprevious.c
index a07578c..c6179a4 100644
--- a/sr_port/op_zprevious.c
+++ b/sr_port/op_zprevious.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,6 +11,8 @@
 
 #include "mdef.h"
 
+#include <stddef.h>		/* for offsetof macro in VMS */
+
 #include "gtm_string.h"
 
 #include "gdsroot.h"
@@ -28,14 +30,16 @@
 #include "filestruct.h"
 #include "gdscc.h"
 #include "jnl.h"
+#include "hashtab_mname.h"
+#include "targ_alloc.h"		/* for GV_BIND_SUBSREG macro which needs "targ_alloc" prototype */
+#include "gtmimagename.h"
+#include "collseq.h"		/* for STD_NULL_COLL_FALSE */
+#include "mvalconv.h"
 
 GBLREF gv_namehead	*gv_target;
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_key		*gv_altkey;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_addr		*gd_header;
-GBLREF gd_binding	*gd_map;
-GBLREF gd_binding	*gd_map_top;
 GBLREF sgmnt_addrs	*cs_addrs;
 GBLREF spdesc		stringpool;
 
@@ -44,10 +48,14 @@ GBLREF spdesc		stringpool;
 void op_zprevious(mval *v)
 {
 	int4			n;
-	gd_binding		*map;
-	mstr			name;
+	int			min_reg_index, reg_index, res;
+	mname_entry		gvname;
+	mval			tmpmval, *datamval;
 	enum db_acc_method	acc_meth;
 	boolean_t		found, ok_to_change_currkey;
+	gd_binding		*gd_map_start, *map, *prev_map;
+	gd_addr			*gd_targ;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -58,7 +66,7 @@ void op_zprevious(mval *v)
 		 * is overloaded for DDP now but could be more in the future) it is better to hand over gv_currkey as it is so
 		 * the custom implementation can decide what to do with it.
 		 */
-		acc_meth = gv_cur_region->dyn.addr->acc_meth;
+		acc_meth = REG_ACC_METH(gv_cur_region);
 		ok_to_change_currkey = (dba_usr != acc_meth);
 		if (TREF(gv_last_subsc_null) && ok_to_change_currkey)
 		{	/* Replace the last subscript with the highest possible subscript value i.e. the byte sequence
@@ -81,11 +89,12 @@ void op_zprevious(mval *v)
 		}
 		if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 		{
-			if (!gv_target->root)	/* global does not exist */
-				found = FALSE;
+			gvnh_reg = TREF(gd_targ_gvnh_reg);
+			if (NULL == gvnh_reg)
+				found = (gv_target->root ? gvcst_zprevious() : FALSE);
 			else
-				found = gvcst_zprevious();
-		} else  if (dba_cm == acc_meth)
+				INVOKE_GVCST_SPR_XXX(gvnh_reg, found = gvcst_spr_zprevious());
+		} else if (dba_cm == acc_meth)
 			found = gvcmx_zprevious();
 		else
 			found = gvusr_zprevious();
@@ -130,20 +139,31 @@ void op_zprevious(mval *v)
 	} else
 	{	/* the following section is for $ZPREVIOUS(^gname) */
 		assert(2 <= gv_currkey->end);
-		assert(gv_currkey->end < (MAX_MIDENT_LEN + 3));	/* until names are not in midents */
-		for (map = gd_map_top - 1; (map > (gd_map + 1)) &&
-			(0 >= memcmp(gv_currkey->base, map->name,
-				((MAX_MIDENT_LEN + 2) == gv_currkey->end) ? MAX_MIDENT_LEN : gv_currkey->end - 1)); map--)
-			;
-		for (map++;  map > gd_map;  map--)
+		assert(gv_currkey->end < (MAX_MIDENT_LEN + 2));	/* until names are not in midents */
+		assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end]);
+		assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end - 1]);
+		gd_targ = TREF(gd_targ_addr);
+		gd_map_start = gd_targ->maps;
+		map = gv_srch_map(gd_targ, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+		assert(map > (gd_map_start + 1));
+		/* If ^gname starts at "map" start search from map-1 since $ZPREVIOUS(^gname) is sought */
+		BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_currkey->base, gv_currkey->end - 1, map);
+		found = FALSE;
+		/* The first map entry corresponds to local locks. The second map entry does not contain any globals.
+		 * Therefore, any search for globals needs to only look after these maps. Hence the "gd_map_start + 1" below.
+		 */
+		for ( ; map > gd_map_start + 1; map = prev_map)
 		{
+			prev_map = map - 1;
 			gv_cur_region = map->reg.addr;
 			if (!gv_cur_region->open)
 				gv_init_reg(gv_cur_region);
 			change_reg();
-			acc_meth = gv_cur_region->dyn.addr->acc_meth;
-			for (;  ;)		/* search region, entries in directory tree could be empty */
+			acc_meth = REG_ACC_METH(gv_cur_region);
+			/* search region, entries in directory tree could have empty GVT in which case move on to previous entry */
+			for ( ; ; )
 			{
+				assert(0 == gv_currkey->prev);	/* or else gvcst_zprevious could get confused */
 				if ((dba_bg == acc_meth) || (dba_mm == acc_meth))
 				{
 					gv_target = cs_addrs->dir_tree;
@@ -158,52 +178,77 @@ void op_zprevious(mval *v)
 					break;
 				assert(1 < gv_altkey->end);
 				assert(gv_altkey->end < (MAX_MIDENT_LEN + 2));	/* until names are not in midents */
-				if (memcmp(gv_altkey->base, (map - 1)->name, gv_altkey->end) < 0)
-				{
+				res = memcmp(gv_altkey->base, prev_map->gvkey.addr, gv_altkey->end);
+				assert((0 != res) || (gv_altkey->end <= prev_map->gvkey_len));
+				if (0 > res)
+				{	/* The global name we found is less than the maximum value in the previous map
+					 * so this name is not part of the current map for sure. Move on to previous map.
+					 */
 					found = FALSE;
 					break;
 				}
-				name.addr = (char *)gv_altkey->base;
-				name.len = gv_altkey->end - 1;
+				gvname.var_name.addr = (char *)gv_altkey->base;
+				gvname.var_name.len = gv_altkey->end - 1;
 				if (dba_cm == acc_meth)
 					break;
-				GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &name);
-				if (gv_cur_region != map->reg.addr)
-				{
-					found = FALSE;
-					break;
+				COMPUTE_HASH_MNAME(&gvname);
+				GV_BIND_NAME_AND_ROOT_SEARCH(gd_targ, &gvname, gvnh_reg);	/* updates "gv_currkey" */
+				assert((NULL != gvnh_reg->gvspan) || (gv_cur_region == map->reg.addr));
+				if (NULL != gvnh_reg->gvspan)
+				{	/* gv_target would NOT have been initialized by GV_BIND_NAME in this case.
+					 * So finish that initialization.
+					 */
+					datamval = &tmpmval;
+					/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+					 * 	(e.g. setting gv_cur_region for spanning globals)
+					 */
+					GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_targ, gv_currkey, gvnh_reg->gd_reg);
+					op_gvdata(datamval);
+					if (MV_FORCE_INT(datamval))
+						break;
+				} else
+				{	/* else gv_target->root would have been initialized by GV_BIND_NAME_AND_ROOT_SEARCH */
+					if ((0 != gv_target->root) && (0 != gvcst_data()))
+						break;
 				}
-				if ((gv_target->root) && gvcst_data())
-					break;
 			}
 			if (found)
 				break;
-			else  if ((map - 1) > gd_map)
+			/* If previous map corresponding to a spanning global, then do not update gv_currkey as that would
+			 * effectively cause the spanning global to be skipped. If gvkey_len == gvname_len + 1 it is NOT
+			 * a spanning global map entry.
+			 */
+			assert(prev_map->gvkey_len >= (prev_map->gvname_len + 1));
+			if ((prev_map > (gd_map_start + 1)) && (prev_map->gvkey_len == (prev_map->gvname_len + 1)))
 			{
-				assert(SIZEOF((map - 1)->name) == SIZEOF(mident_fixed));
-				assert(0 == (map - 1)->name[SIZEOF((map - 1)->name) - 1]);
-				gv_currkey->end = mid_len((mident_fixed *)((map - 1)->name));
-				assert(gv_currkey->end <= MAX_MIDENT_LEN);
-				memcpy(gv_currkey->base, (map - 1)->name, gv_currkey->end);
-				gv_currkey->base[gv_currkey->end++] = KEY_DELIMITER;
+				assert(strlen(prev_map->gvkey.addr) == prev_map->gvname_len);
+				gv_currkey->end = prev_map->gvname_len + 1;
+				assert(gv_currkey->end <= (MAX_MIDENT_LEN + 1));
+				memcpy(gv_currkey->base, prev_map->gvkey.addr, gv_currkey->end);
+				assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end - 1]);
 				gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
 				assert(gv_currkey->top > gv_currkey->end);	/* ensure we are within allocated bounds */
 			}
 		}
+		/* Reset gv_currkey as we have potentially skipped one or more regions so we no
+		 * longer can expect gv_currkey/gv_cur_region/gv_target to match each other.
+		 */
 		gv_currkey->end = 0;
 		gv_currkey->base[0] = KEY_DELIMITER;
 		v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied (BYPASSOK)
 				* by this to-be-overwritten mval */
 		if (found)
 		{
-			v->str.len = 0; /* so stp_gcol (if invoked) can free up space currently occupied by this (BYPASSOK)
-					 * to-be-overwritten mval */
-			ENSURE_STP_FREE_SPACE(name.len + 1);
+			if (!IS_STP_SPACE_AVAILABLE(gvname.var_name.len + 1))
+			{
+				v->str.len = 0;	/* so stp_gcol ignores otherwise incompletely setup mval (BYPASSOK) */
+				INVOKE_STP_GCOL(gvname.var_name.len + 1);
+			}
 			v->str.addr = (char *)stringpool.free;
 			*stringpool.free++ = '^';
-			memcpy(stringpool.free, name.addr, name.len);
-			stringpool.free += name.len;
-			v->str.len = name.len + 1;
+			memcpy(stringpool.free, gvname.var_name.addr, gvname.var_name.len);
+			stringpool.free += gvname.var_name.len;
+			v->str.len = gvname.var_name.len + 1;
 			assert(v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
 			assert(v->str.addr + v->str.len <= (char *)stringpool.top &&
 				v->str.addr + v->str.len >= (char *)stringpool.base);
diff --git a/sr_port/op_zshow.c b/sr_port/op_zshow.c
index df347d4..57954f0 100644
--- a/sr_port/op_zshow.c
+++ b/sr_port/op_zshow.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,8 @@
 
 GBLREF gv_key *gv_currkey;
 
+error_def(ERR_ZSHOWBADFUNC);
+
 void op_zshow(mval *func,int type,lv_val *lvn)
 {
 	const char	*ptr;
@@ -39,13 +41,12 @@ void op_zshow(mval *func,int type,lv_val *lvn)
 			done_g = FALSE,
 			done_i = FALSE,
 			done_l = FALSE,
+			done_r = FALSE,
 			done_s = FALSE,
 			done_v = FALSE;
 	int		i;
   	zshow_out	output;
 
-	error_def(ERR_ZSHOWBADFUNC);
-
 	MAXSTR_BUFF_DECL(buff);
 
 	MV_FORCE_STR(func);
@@ -65,6 +66,8 @@ void op_zshow(mval *func,int type,lv_val *lvn)
 			case 'i':
 			case 'L':
 			case 'l':
+			case 'R':
+			case 'r':
 			case 'S':
 			case 's':
 			case 'V':
@@ -74,7 +77,7 @@ void op_zshow(mval *func,int type,lv_val *lvn)
 				do_all = TRUE;
 				break;
 			default:
-				rts_error(VARLSTCNT(1) ERR_ZSHOWBADFUNC);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZSHOWBADFUNC);
 		}
 	}
 	if (do_all)
@@ -153,13 +156,21 @@ void op_zshow(mval *func,int type,lv_val *lvn)
 				output.line_num = 0;	/* L statistics start at 0 for <LUS,LUF> output and not 1 like the others */
 				zshow_locks(&output);
 				break;
+			case 'R':
+			case 'r':
+				if (done_r)
+					break;
+				done_r = TRUE;
+				output.code = 'R';
+				zshow_stack(&output, TRUE);	/* show_checksum = TRUE */
+				break;
 			case 'S':
 			case 's':
 				if (done_s)
 					break;
 				done_s = TRUE;
 				output.code = 'S';
-				zshow_stack(&output);
+				zshow_stack(&output, FALSE);	/* show_checksum = FALSE */
 				break;
 			case 'V':
 			case 'v':
diff --git a/sr_port/opcode_def.h b/sr_port/opcode_def.h
index d652c5e..f2aab23 100644
--- a/sr_port/opcode_def.h
+++ b/sr_port/opcode_def.h
@@ -211,7 +211,7 @@ OPCODE_DEF(OC_ZG1, (OCT_NULL))
 OPCODE_DEF(OC_NEWINTRINSIC, (OCT_NULL))
 OPCODE_DEF(OC_GVZWITHDRAW, (OCT_NULL))
 OPCODE_DEF(OC_LVZWITHDRAW, (OCT_NULL))
-OPCODE_DEF(OC_NULLEXP, (OCT_MVAL))
+OPCODE_DEF(OC_NULLEXP, (OCT_MVADDR | OCT_MVAL | OCT_EXPRLEAF))
 OPCODE_DEF(OC_EXFUNRET, (OCT_NULL))
 OPCODE_DEF(OC_FNLVNAME, (OCT_MVAL | OCT_EXPRLEAF))
 OPCODE_DEF(OC_LKEXTNAME, (OCT_NULL))
diff --git a/sr_port/outofband.h b/sr_port/outofband.h
index bbed753..30779b9 100644
--- a/sr_port/outofband.h
+++ b/sr_port/outofband.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,8 @@ enum outofbands
 	jobinterrupt
 };
 
+#define OUTOFBAND_RESTARTABLE(event)	(jobinterrupt == (event))
+
 /* ------------------------------------------------------------------
  *  Old-style declarations (and uses) of this function abound.
  * Be sure to change all declarations at once!
diff --git a/sr_port/parm_pool.c b/sr_port/parm_pool.c
index d7f81c9..ca73079 100644
--- a/sr_port/parm_pool.c
+++ b/sr_port/parm_pool.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -33,6 +33,8 @@ GBLREF mv_stent		*mv_chain;
 GBLREF unsigned char	*msp, *stackbase, *stackwarn, *stacktop;
 GBLREF symval		*curr_symval;
 
+LITREF mval		skiparg;
+
 error_def(ERR_STACKOFLOW);
 error_def(ERR_STACKCRIT);
 
@@ -166,8 +168,7 @@ void push_parm(UNIX_ONLY_COMMA(unsigned int totalcnt) int truth_value, ...)
 		if (!(mask & 1 << i))
 		{	/* Not a dotted pass-by-reference parm. */
 			actpmv = &actp->v;
-			if ((!MV_DEFINED(actpmv)) && (actpmv->str.addr != (char *)&actp->v))
-				actpmv = underr(actpmv);
+			MV_FORCE_DEFINED_UNLESS_SKIPARG(actpmv);
 			PUSH_MV_STENT(MVST_PVAL);
 			mv_chain->mv_st_cont.mvs_pval.mvs_val = lv_getslot(curr_symval);
 			LVVAL_INIT(mv_chain->mv_st_cont.mvs_pval.mvs_val, curr_symval);
diff --git a/sr_port/patcode.h b/sr_port/patcode.h
index 0894262..9789e27 100644
--- a/sr_port/patcode.h
+++ b/sr_port/patcode.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -81,12 +81,11 @@
 
 #define PAT_MAX_REPEAT		MAX_STRLEN
 #define MAX_PATTERN_ATOMS	50
-#define	MAX_PATOBJ_LENGTH	2048
-#define	MAX_PATTERN_OVERHEAD	((3 * MAX_PATTERN_ATOMS) + 3) * 4/* maximum length (in integers) of compiled pattern code
+#define	MAX_PATOBJ_LENGTH	4096
+#define	MAX_PATTERN_OVERHEAD	((3 * MAX_PATTERN_ATOMS) + 3)	/* maximum length (in integers) of compiled pattern code
 								  * excluding count,tot_min,tot_max and min,max,size arrays
 								  * that come at the tail. 3 * MAX_PATTERN_ATOMS is for
 								  * min, max, size arrays and 3 is for count, tot_min, tot_max
-								  * 4 is to convert the size into bytes.
 								  */
 #define MAX_PATTERN_LENGTH	(MAX_PATOBJ_LENGTH - MAX_PATTERN_OVERHEAD)
 #define PATENTS		256	/* Size of the builtin pattern/typemask table in M mode */
diff --git a/sr_port/patstr.c b/sr_port/patstr.c
index cb73811..24689c5 100644
--- a/sr_port/patstr.c
+++ b/sr_port/patstr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,12 @@ GBLREF	boolean_t	gtm_utf8_mode;
 LITREF	char		ctypetab[NUM_CHARS];
 LITREF	uint4		typemask[PATENTS];
 
+error_def(ERR_PATCLASS);
+error_def(ERR_PATCODE);
+error_def(ERR_PATLIT);
+error_def(ERR_PATMAXLEN);
+error_def(ERR_PATUPPERLIM);
+
 typedef struct
 {
 	unsigned char	*next;
@@ -80,7 +86,7 @@ typedef struct
 int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 {
 	pat_strlit		strlit;
-	boolean_t		infinite, split_atom, done, dfa, fixed_len, prev_fixed_len;
+	boolean_t		dfa, dfa_attempt_failed, done, fixed_len, infinite, prev_fixed_len, split_atom;
 	int4			lower_bound, upper_bound, alloclen;
 	gtm_uint64_t		bound;
 	unsigned char		curchar, symbol, *inchar, *in_top, *buffptr;
@@ -111,7 +117,7 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 	boolean_t		last_infinite;
 	boolean_t		done_free;
 	unsigned char		*let_go;
-	uint4			*fstchar, *outchar, *lastpatptr;
+	uint4			*fstchar, *lastpatptr, *outchar, *topchar;
 	int			any_alt = FALSE;
 	int			altcount, altsimplify;
 	int			low_in, high_in, size_in, jump;
@@ -119,11 +125,6 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 						 * byte in inchar (to be stored in curchar). Therefore from this point onwards,
 						 * "curchar" should never be used in this function. This is also asserted below.
 						 */
-	error_def(ERR_PATCODE);
-	error_def(ERR_PATUPPERLIM);
-	error_def(ERR_PATCLASS);
-	error_def(ERR_PATLIT);
-	error_def(ERR_PATMAXLEN);
 
 	if (0 == instr->len)		/* empty pattern string. Cant do much */
 	{
@@ -140,6 +141,7 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 	for (allmask = 0, chidx = 'A'; chidx <= 'X'; chidx++)
 		allmask |= mapbit[chidx - 'A'];
 	outchar = &obj->buff[PAT_MASK_BEGIN_OFFSET]; /* Note: offset is actually PAT_MASK_BEGIN_OFFSET * SIZEOF (uint4) bytes */
+	topchar = &obj->buff[MAX_PATOBJ_LENGTH];
 	last_leaf_mask = *outchar = 0;
 	patmaskptr = lastpatptr = outchar;
 	infinite = last_infinite = FALSE;
@@ -197,10 +199,12 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 			{
 				if (dfa)
 				{
+					assert(outchar <= topchar);
 					patmaskptr = outchar;
 					cursize = dfa_calc(lv_ptr, leaf_num, exp_ptr, &fstchar, &outchar);
 					if (cursize >= 0)
 					{
+						assert(outchar <= topchar);
 						min[count] = min_dfa;
 						max[count] = PAT_MAX_REPEAT;
 						size[count] = cursize;
@@ -217,9 +221,9 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 							&last_infinite, &fstchar, &outchar, &lastpatptr))
 						{
 							instr->addr = (char *)inchar;
-							assert(FALSE);
 							return ERR_PATMAXLEN;
 						}
+						assert(outchar <= topchar);
 					}
 				}
 				if (outchar == &obj->buff[PAT_MASK_BEGIN_OFFSET])
@@ -229,6 +233,12 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 				}
 				patmaskptr = &obj->buff[0];
 				*patmaskptr++ = fixed_len;
+				assert(outchar <= topchar);
+				if ((outchar + 3 + ((fixed_len ? 2 : 3) * count)) > topchar)
+				{
+					instr->addr = (char *)inchar;
+					return ERR_PATMAXLEN;
+				}
 				*patmaskptr = (uint4)(outchar - patmaskptr); /* unit is SIZEOF(uint4) */
 				*outchar++ = count;
 				*outchar++ = total_min;
@@ -240,6 +250,7 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 						*outchar++ = max[seqcnt];
 				for (seqcnt = 0; seqcnt < count; seqcnt++)
 					*outchar++ = size[seqcnt];
+				assert(outchar <= topchar);
 				obj->len = (int4)(outchar - &obj->buff[0]);
 				assert(!topseen || (inchar == in_top));
 				assert(inchar <= in_top);
@@ -301,10 +312,7 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 			}
 			instr->addr = (char *)inchar;
 			if (count >= MAX_PATTERN_ATOMS)
-			{
-				assert(FALSE);
 				return ERR_PATMAXLEN;
-			}
 		}
 		if (!altend)
 		{
@@ -358,7 +366,6 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 					if (strlit.bytelen >= alloclen)
 					{
 						instr->addr = (char *)inchar;
-						assert(FALSE);
 						return ERR_PATMAXLEN;
 					}
 					do
@@ -381,14 +388,16 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 			{	/* start of 'alternation' */
 				if (dfa)
 				{
+					assert(outchar <= topchar);
 					if (!pat_unwind(&count, lv_ptr, leaf_num, &total_min, &total_max,
 						&min[0], &max[0], &size[0], altmin, altmax,
 						&last_infinite, &fstchar, &outchar, &lastpatptr))
 					{
 						instr->addr = (char *)inchar;
-						assert(FALSE);
 						return ERR_PATMAXLEN;
 					}
+					assert(outchar <= topchar);
+					dfa_attempt_failed = TRUE;
 					dfa = FALSE;
 				}
 				if (inchar >= in_top)
@@ -514,6 +523,10 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 			upper_bound = lower_bound;
 		}
 		done = FALSE;
+		/* If dfa_attempt_failed is set to TRUE, it means we tried DFA for the current pattern match string
+		 * and decided that was not possible. In this case, we should not retry the DFA for this pattern.
+		 */
+		dfa_attempt_failed = FALSE;
 		while (!done)
 		{
 			done = TRUE;
@@ -522,7 +535,8 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 			 * are no character cells to hold the mask and flag bits that the DFA code needs. Also strings with
 			 * non-ASCII UTF-8 byte sequences are currently not processed through the DFA logic.
 			 */
-			if (infinite && !any_alt && !dfa
+			assert(outchar <= topchar);
+			if (infinite && !any_alt && !dfa && !dfa_attempt_failed
 				&& (!(pattern_mask & PATM_STRLIT) || (strlit.charlen && !(strlit.flags & PATM_STRLIT_NONASCII)))
 				&& ((outchar - &obj->buff[0]) <= (MAX_PATTERN_LENGTH / 2)))
 			{
@@ -534,18 +548,20 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 				atom_map = count;
 				memset(expand.num_e, 0, SIZEOF(expand.num_e));
 			}
+			dfa_attempt_failed = FALSE;
 			if (!dfa)
 			{
-				if (count >= MAX_PATTERN_ATOMS ||
-					!add_atom(&count, pattern_mask, &strlit, infinite,
+				assert(outchar <= topchar);
+				if ((MAX_PATTERN_ATOMS <= count)
+					|| !add_atom(&count, pattern_mask, &strlit, infinite,
 						&min[count], &max[count], &size[count],
 						&total_min, &total_max, lower_bound, upper_bound, altmin, altmax,
 						&last_infinite, &fstchar, &outchar, &lastpatptr))
 				{
 					instr->addr = (char *)inchar;
-					assert(FALSE);
 					return ERR_PATMAXLEN;
 				}
+				assert(outchar <= topchar);
 				if (pattern_mask & PATM_ALT)
 				{	/* If the alternation contains only one alternative (altcount == 1) AND
 					 * that alternative contains only one pattern atom, AND that atom is not an
@@ -617,8 +633,14 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 							upper_bound = max[count - 1];
 						}
 						outchar--;
+						if ((outchar + (jump - PAT_MASK_BEGIN_OFFSET + 1)) > topchar)
+						{
+							instr->addr = (char *)inchar;
+							return ERR_PATMAXLEN;
+						}
 						for (seq = PAT_MASK_BEGIN_OFFSET; seq <= jump; seq++)
 							*outchar++ = cur_alt->altpat.buff[seq];
+						assert(outchar <= topchar);
 						pattern_mask = cur_alt->altpat.buff[PAT_MASK_BEGIN_OFFSET];
 						if (pattern_mask & PATM_STRLIT)
 						{
@@ -632,16 +654,28 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 					} else
 					{
 						fixed_len = FALSE;
+						if ((outchar + 3) > topchar)
+						{
+							instr->addr = (char *)inchar;
+							return ERR_PATMAXLEN;
+						}
 						*outchar++ = lower_bound;
 						*outchar++ = upper_bound;
 						for (cur_alt = &init_alt; cur_alt; )
 						{
+							assert(outchar < topchar);
+							if ((outchar + 2 + cur_alt->altpat.len) > topchar)
+							{
+								instr->addr = (char *)inchar;
+								return ERR_PATMAXLEN;
+							}
 							*outchar++ = cur_alt->altpat.len;
 							for (seq = 0; seq < cur_alt->altpat.len; seq++)
 								*outchar++ = cur_alt->altpat.buff[seq];
 							cur_alt = (alternation *)cur_alt->next;
 						}
 						*outchar++ = 0;
+						assert(outchar <= topchar);
 						done_free = TRUE;
 					}
 				}
@@ -661,9 +695,11 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 					|| (charpos > MAX_DFA_STRLEN))
 				{
 					patmaskptr = outchar;
+					assert(outchar <= topchar);
 					cursize = dfa_calc(lv_ptr, leaf_num, exp_ptr, &fstchar, &outchar);
 					if (cursize >= 0)
 					{
+						assert(outchar <= topchar);
 						min[count] = min_dfa;
 						max[count] = PAT_MAX_REPEAT;
 						size[count] = cursize;
@@ -684,9 +720,10 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 							&last_infinite, &fstchar, &outchar, &lastpatptr))
 						{
 							instr->addr = (char *)inchar;
-							assert(FALSE);
 							return ERR_PATMAXLEN;
 						}
+						assert(outchar <= topchar);
+						dfa_attempt_failed = TRUE;
 					}
 					dfa = FALSE;
 					done = FALSE;
@@ -813,9 +850,11 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 				if (sym_num >= MAX_SYM - 1)
 				{
 					patmaskptr = outchar;
+					assert(outchar <= topchar);
 					cursize = dfa_calc(lv_ptr, curr_leaf_num, exp_ptr, &fstchar, &outchar);
 					if (cursize >= 0)
 					{
+						assert(outchar <= topchar);
 						min[count] = curr_min_dfa;
 						max[count] = PAT_MAX_REPEAT;
 						size[count] = cursize;
@@ -836,9 +875,10 @@ int patstr(mstr *instr, ptstr *obj, unsigned char **relay)
 							&last_infinite, &fstchar, &outchar, &lastpatptr))
 						{
 							instr->addr = (char *)inchar;
-							assert(FALSE);
 							return ERR_PATMAXLEN;
 						}
+						assert(outchar <= topchar);
+						dfa_attempt_failed = TRUE;
 					}
 					dfa = FALSE;
 					done = FALSE;
diff --git a/sr_port/preemptive_db_clnup.c b/sr_port/preemptive_db_clnup.c
index 5492f18..a8197ad 100644
--- a/sr_port/preemptive_db_clnup.c
+++ b/sr_port/preemptive_db_clnup.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -87,7 +87,7 @@ void preemptive_db_clnup(int preemptive_severe)
 			/* We know of a few cases in Unix where gv_target and gv_currkey could be out of sync at this point.
 			 *   a) If we are inside trigger code which in turn does an update that does
 			 *	reads of ^#t global and ends up in a restart. This restart would
-			 *	in turn do a rts_error(TPRETRY) which would invoke mdb_condition_handler
+			 *	in turn do a rts_error_csa(TPRETRY) which would invoke mdb_condition_handler
 			 *	that would in turn invoke preemptive_db_clnup which invokes this macro.
 			 *	In this tp restart case though, it is ok for gv_target and gv_currkey
 			 *	to be out of sync because they are going to be reset by tp_clean_up anyways.
@@ -114,11 +114,11 @@ void preemptive_db_clnup(int preemptive_severe)
 			{
 				csa = si->tp_csa;
 				assert(si->tp_csa == si->kip_csa);
-				CAREFUL_DECR_KIP(csa->hdr, csa, si->kip_csa);
+				PROBE_DECR_KIP(csa->hdr, csa, si->kip_csa);
 			}
 		}
 	} else if (NULL != kip_csa && (NULL != kip_csa->hdr) && (NULL != kip_csa->nl))
-		CAREFUL_DECR_KIP(kip_csa->hdr, kip_csa, kip_csa);
+		PROBE_DECR_KIP(kip_csa->hdr, kip_csa, kip_csa);
 	if (IS_DSE_IMAGE)
 	{	/* Release crit on any region that was obtained for the current erroring DSE operation.
 		 * Take care NOT to release crits obtained by a previous CRIT -SEIZE command.
diff --git a/sr_port/print_target.c b/sr_port/print_target.c
index 4cb5f4a..ed5d7fc 100644
--- a/sr_port/print_target.c
+++ b/sr_port/print_target.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,9 +26,6 @@
 #include "gtm_utf8.h"
 #endif
 
-GBLREF gd_region       *gv_cur_region;
-LITDEF char 		spaces[] = "    ";
-
 void print_target(unsigned char *c)
 {
 	unsigned char	ctemp, *p, *ptop, *ptop1, *ptr, *ptr1, *top, *p_next;
@@ -93,7 +90,7 @@ void print_target(unsigned char *c)
 				if (!PRINTABLE(*p))
 					*p = '.';
 		}
-#ifdef UNICODE_SUPPORTED
+#		ifdef UNICODE_SUPPORTED
 		else {
 			for (p = buff;  p < top;  p = p_next)
 			{
@@ -105,7 +102,7 @@ void print_target(unsigned char *c)
 				}
 			}
 		}
-#endif
+#		endif
 		util_out_print("!AD", FALSE, p - buff, buff);
 		if (is_string)
 			util_out_print("\"", FALSE);
diff --git a/sr_port/probe.h b/sr_port/probe.h
index cb8d981..c805b21 100644
--- a/sr_port/probe.h
+++ b/sr_port/probe.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,7 +38,7 @@ boolean_t	probe(uint4 len, sm_uc_ptr_t addr, boolean_t write);
 #define		PROBE_EVEN(X)	(!((UINTPTR_T)(X) & 1))
 #define		PROBE_ODD(X)	(!PROBE_EVEN(X))
 
-#define		CAREFUL_DECR_CNT(X,Y)	if (PROBE_EVEN(X)) DECR_CNT((X),(Y))
-#define		CAREFUL_INCR_CNT(X,Y)	if (PROBE_EVEN(X)) INCR_CNT((X),(Y))
+#define		PROBE_DECR_CNT(X,Y)	if (PROBE_EVEN(X)) DECR_CNT((X),(Y))
+#define		PROBE_INCR_CNT(X,Y)	if (PROBE_EVEN(X)) INCR_CNT((X),(Y))
 
 #endif
diff --git a/sr_port/process_gvt_pending_list.c b/sr_port/process_gvt_pending_list.c
index b22c7db..b11da7e 100644
--- a/sr_port/process_gvt_pending_list.c
+++ b/sr_port/process_gvt_pending_list.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2008, 2010 Fidelity Information Services, Inc.	*
+ *	Copyright 2008, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,65 +20,112 @@
 #include "process_gvt_pending_list.h"
 #include "targ_alloc.h"
 #include "buddy_list.h"
+#include "hashtab_mname.h"
 
 GBLREF	gvt_container	*gvt_pending_list;
 GBLREF	buddy_list	*gvt_pending_buddy_list;
 
-boolean_t	is_gvt_in_pending_list(gv_namehead *gvt)
+gvt_container *is_gvt_in_pending_list(gv_namehead *gvt)
 {
 	gvt_container	*gvtc;
 
 	for (gvtc = gvt_pending_list; NULL != gvtc; gvtc = (gvt_container *)gvtc->next_gvtc)
 	{
-		if (gvtc->gvnh_reg->gvt == gvt)
-			return TRUE;
+		if (*gvtc->gvt_ptr == gvt)
+			return gvtc;
 	}
-	return FALSE;
+	return NULL;
 }
 
-/* Now that "reg" is being opened, process list of gv_targets that were allocated BEFORE reg got opened to see if they
- * need to be re-allocated (due to differences in reg->max_key_size versus csa->hdr->max_key_size.
+/* Now that "reg" is being opened, process list of gv_targets that were allocated BEFORE reg got opened to see
+ * if they need to be re-allocated (due to differences in reg->max_key_size versus csa->hdr->max_key_size).
  */
 void process_gvt_pending_list(gd_region *reg, sgmnt_addrs *csa)
 {
-	gvt_container	*gvtc, *next_gvtc, *prev_gvtc;
-	gv_namehead	*old_gvt, *new_gvt;
-	int4		db_max_key_size;
-	gvnh_reg_t	*gvnh_reg;
+	gvt_container		*gvtc, *next_gvtc, *prev_gvtc;
+	gv_namehead		*old_gvt, *new_gvt, *gvtarg;
+	int4			db_max_key_size;
+	boolean_t		added, first_wasopen;
+	ht_ent_mname		*stayent;
+	hash_table_mname	*gvt_hashtab;
+#	ifdef DEBUG
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
+#	endif
 	for (prev_gvtc = NULL, gvtc = gvt_pending_list; NULL != gvtc; gvtc = next_gvtc)
 	{
 		/* note down next_gvtc first thing before any continues or frees as next iteration relies on this */
 		next_gvtc = (gvt_container *)gvtc->next_gvtc;
-		gvnh_reg = gvtc->gvnh_reg;
-		old_gvt = gvnh_reg->gvt;
+		old_gvt = *gvtc->gvt_ptr;
 		assert(NULL == old_gvt->gd_csa);
-		if (reg != gvnh_reg->gd_reg)
+		if (reg != gvtc->gd_reg)
 		{
 			prev_gvtc = gvtc;
 			continue;
 		}
-		old_gvt->gd_csa = csa;	/* set csa now that we are about to open the region */
+		old_gvt->gd_csa = csa;	/* set csa now that we have just opened the region */
 		db_max_key_size = csa->hdr->max_key_size;
-		if (reg->max_key_size != db_max_key_size)
-		{	/* key sizes are different, so need to reallocate */
-			new_gvt = (gv_namehead *)targ_alloc(db_max_key_size, &old_gvt->gvname, reg);
-			new_gvt->noisolation = old_gvt->noisolation;	/* Copy over noisolation status from old_gvt */
-			assert(!reg->open);
-			/* reg is not yet open but we know csa is already available so set it appropriately */
-			new_gvt->gd_csa = csa;
-			gvnh_reg->gvt = new_gvt;		/* Change hash-table to point to new gvt */
-			old_gvt->regcnt--;
-			targ_free(old_gvt);	/* Reposition pointers & freeup memory associated with old_gvt */
-		}
-		/* Free up the processed gvtc */
+		/* Remove the to-be-processed gvtc from the linked list since TARG_FREE_IF_NEEDED relies on this */
 		if (NULL == prev_gvtc)
-			gvt_pending_list = next_gvtc;	/* freeing up first element in linked list */
+			gvt_pending_list = next_gvtc;	/* removing first element in linked list */
 		else
 		{
-			assert(prev_gvtc->gvnh_reg->gd_reg != reg);
+			assert(prev_gvtc->gd_reg != reg);
 			prev_gvtc->next_gvtc = (struct gvt_container_struct *)next_gvtc;
 		}
+		if (NULL != (gvt_hashtab = csa->gvt_hashtab))
+			added = add_hashtab_mname(gvt_hashtab, &old_gvt->gvname, old_gvt, &stayent);
+		else
+		{
+			added = TRUE;	/* even though there is no hashtable set added so we go through the appropriate codepath */
+			stayent = NULL;
+		}
+		if (added)
+		{	/* Global name not already present in csa->gvt_hashtab. So old_gvt got added into the hashtable.
+			 * But before that, check for differing key sizes between reg and db hdr in which case we need to
+			 * allocate a new_gvt (with the bigger key size) and add new_gvt instead into csa->gvt_hashtab.
+			 */
+			if (reg->max_key_size != db_max_key_size)
+			{	/* key sizes are different, need to reallocate */
+				assert((dba_bg == REG_ACC_METH(reg)) || (dba_mm == REG_ACC_METH(reg)));
+				new_gvt = (gv_namehead *)targ_alloc(db_max_key_size, &old_gvt->gvname, reg);
+				new_gvt->noisolation = old_gvt->noisolation;	/* Copy over noisolation status from old_gvt */
+				new_gvt->act = old_gvt->act; /* copy over act,nct,ver from old_gvt (actually from the gld file) */
+				new_gvt->nct = old_gvt->nct;
+				new_gvt->ver = old_gvt->ver;
+				assert(!reg->open);
+				/* reg is not yet open but we know csa is already available so set it appropriately */
+				new_gvt->gd_csa = csa;
+				if (NULL != stayent)
+					stayent->value = new_gvt;
+			} else
+				new_gvt = NULL; /* No change to any gvt. Reset new_gvt to prevent allocation/free done later. */
+		} else
+		{	/* Global name already present in csa->gvt_hashtab. No need to allocate new_gvt.
+			 * Only need to free up old_gvt. Also increment gvt->regcnt.
+			 * If NOISOLATION status differs between the two, choose the more pessimistic one.
+			 */
+			new_gvt = (gv_namehead *)stayent->value;
+			assert(new_gvt != old_gvt);
+			if (FALSE == old_gvt->noisolation)
+				new_gvt->noisolation = FALSE;
+			assert(1 <= new_gvt->regcnt);
+			new_gvt->regcnt++;
+		}
+		if (NULL != new_gvt)
+		{
+			*gvtc->gvt_ptr = new_gvt;	/* change hash-table to eventually point to new gvt */
+			if (NULL != gvtc->gvt_ptr2)
+			{	/* this is true only for spanning globals. Update one more location to point to new gvt */
+				assert(TREF(spangbl_seen));
+				assert(old_gvt == *gvtc->gvt_ptr2);
+				*gvtc->gvt_ptr2 = new_gvt;
+			}
+			assert(1 == old_gvt->regcnt); /* assert that TARG_FREE will happen below */
+			TARG_FREE_IF_NEEDED(old_gvt);
+		}
+		/* else: new_gvt is NULL which means old_gvt stays as is */
 		free_element(gvt_pending_buddy_list, (char *)gvtc);
 	}
 }
diff --git a/sr_port/process_gvt_pending_list.h b/sr_port/process_gvt_pending_list.h
index 873933c..4870ee9 100644
--- a/sr_port/process_gvt_pending_list.h
+++ b/sr_port/process_gvt_pending_list.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2008, 2010 Fidelity Information Services, Inc.	*
+ *	Copyright 2008, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -13,7 +13,7 @@
 
 /* Declare parms for process_gvt_pending_list.c */
 
-boolean_t	is_gvt_in_pending_list(gv_namehead *gvt);
+gvt_container	*is_gvt_in_pending_list(gv_namehead *gvt);
 void 		process_gvt_pending_list(gd_region *reg, sgmnt_addrs *csa);
 
 #define PROCESS_GVT_PENDING_LIST_DEFINED
diff --git a/sr_port/region_init_ch.c b/sr_port/region_init_ch.c
index 3d04b1a..5884835 100644
--- a/sr_port/region_init_ch.c
+++ b/sr_port/region_init_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,7 +26,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(region_init_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (!(IS_GTM_ERROR(SIGNAL)) || DUMPABLE)
 		NEXTCH;
      	PRN_ERROR;
diff --git a/sr_port/repl_comm.c b/sr_port/repl_comm.c
index a9cacd1..5cf824c 100644
--- a/sr_port/repl_comm.c
+++ b/sr_port/repl_comm.c
@@ -22,9 +22,13 @@
 #include "gtm_string.h"
 #include "gtm_socket.h"
 #include "gtm_inet.h"
+#include "gtm_netdb.h"
 #include "gtm_fcntl.h"
 #include "gtm_unistd.h"
 #include "gtm_stat.h"
+#include "gtm_select.h"
+#include "gtm_time.h"
+#include "eintr_wrappers.h"
 
 #include "gtmio.h"
 #include "repl_msg.h"
@@ -36,9 +40,19 @@
 #include "min_max.h"
 #include "rel_quant.h"
 #include "repl_log.h"
-#include "iotcpdef.h"
 #include "gtmmsg.h"
 #include "gt_timer.h"
+#include "have_crit.h"
+#ifdef GTM_TLS
+#include "error.h"	/* For MAKE_MSG_WARNING macro. */
+#include "lv_val.h"
+#include "fgncalsp.h"
+#include "gtm_tls.h"
+#include "gtm_repl.h"
+#endif
+#ifdef DEBUG
+#include "wbox_test_init.h"
+#endif
 
 /* These statistics are useful and should perhaps be collected - Vinaya 2003/08/18
  *
@@ -74,6 +88,11 @@
  */
 
 GBLDEF	int			repl_max_send_buffsize, repl_max_recv_buffsize;
+#ifdef GTM_TLS
+GBLREF	gtm_tls_ctx_t		*tls_ctx;
+GBLREF	char			dl_err[MAX_ERRSTR_LEN];
+#endif
+
 #if defined(__hppa) || defined(__vms)
 #define REPL_SEND_TRACE_BUFF_SIZE 65536
 #define REPL_RECV_TRACE_BUFF_SIZE 65536
@@ -96,6 +115,11 @@ error_def(ERR_GETADDRINFO);
 error_def(ERR_GETNAMEINFO);
 error_def(ERR_GETSOCKNAMERR);
 error_def(ERR_TEXT);
+error_def(ERR_TLSCLOSE);
+error_def(ERR_TLSDLLNOOPEN);
+error_def(ERR_TLSINIT);
+error_def(ERR_TLSIOERROR);
+error_def(ERR_TLSCONNINFO);
 
 #define REPL_TRACE_BUFF(TRACE_BUFF, TRACE_BUFF_POS, IO_BUFF, IO_SIZE, MAX_TRACE_SIZE)			\
 {													\
@@ -116,7 +140,7 @@ error_def(ERR_TEXT);
 	}												\
 }
 
-int fd_ioready(int sock_fd, boolean_t pollin, int timeout)
+int fd_ioready(int sock_fd, int poll_direction, int timeout)
 {
 	int		save_errno, status, EAGAIN_cnt = 0;
 #	ifdef USE_POLL
@@ -131,15 +155,16 @@ int fd_ioready(int sock_fd, boolean_t pollin, int timeout)
 	assert((timeout >= 0) && (timeout < POLL_ONLY(MILLISECS_IN_SEC) SELECT_ONLY(MICROSEC_IN_SEC)));
 #	ifdef USE_POLL
 	fds.fd = sock_fd;
-	fds.events = pollin ? POLLIN : POLLOUT;
+	fds.events = (REPL_POLLIN == poll_direction) ? POLLIN : POLLOUT;
 #	else
 	readfds = writefds = NULL;
 	timeout_spec.tv_sec = 0;
 	timeout_spec.tv_usec = timeout;
+	assertpro(FD_SETSIZE > sock_fd);
 	FD_ZERO(&fds);
 	FD_SET(sock_fd, &fds);
-	writefds = !pollin ? &fds : NULL;
-	readfds = pollin ? &fds : NULL;
+	writefds = (REPL_POLLOUT == poll_direction) ? &fds : NULL;
+	readfds = (REPL_POLLIN == poll_direction) ? &fds : NULL;
 #	endif
 	POLL_ONLY(while (-1 == (status = poll(&fds, 1, timeout))))
 	SELECT_ONLY(while (-1 == (status = select(sock_fd + 1, readfds, writefds, NULL, &timeout_spec))))
@@ -170,9 +195,9 @@ int fd_ioready(int sock_fd, boolean_t pollin, int timeout)
 	return status;
 }
 
-int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout)
+int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout GTMTLS_ONLY_COMMA(int *poll_direction))
 {
-	int		send_size, status, eintr_cnt, ewouldblock_cnt = 0, emsgsize_cnt = 0, io_ready, save_errno;
+	int		send_size, status, io_ready, save_errno, EMSGSIZE_cnt = 0, EWOULDBLOCK_cnt = 0;
   	ssize_t		bytes_sent;
 
 	if (!repl_send_trace_buff)
@@ -188,7 +213,21 @@ int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout)
 	 */
 	VMS_ONLY(send_size = MIN(send_size, VMS_MAX_TCP_SEND_SIZE));
 	*send_len = 0;
-	if (0 < (io_ready = fd_ioready(sock_fd, FALSE, timeout)))
+#	ifdef GTM_TLS
+	if (repl_tls.enabled && (REPL_INVALID_POLL_DIRECTION != *poll_direction))
+	{
+		if (0 >= (io_ready = fd_ioready(sock_fd, *poll_direction, timeout)))
+		{
+			if (!io_ready)
+				return SS_NORMAL;
+			save_errno = ERRNO;
+			repl_errno = EREPL_SELECT;
+			return save_errno;
+		}
+		/* Fall-through */
+	}
+#	endif
+	if (0 < (io_ready = fd_ioready(sock_fd, REPL_POLLOUT, timeout)))
 	{
 		/* Trace last REPL_SEND_SIZE_TRACE_SIZE sizes of what was sent */
 		repl_send_size_trace[repl_send_size_trace_pos++] = send_size;
@@ -199,14 +238,43 @@ int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout)
 		/* The check for EINTR below is valid and should not be converted to an EINTR wrapper macro, because other errno
 		 * values are being checked.
 		 */
-		while (0 > (bytes_sent = send(sock_fd, (char *)buff, send_size, 0)))
+		while (TRUE)
 		{
+			bytes_sent = GTMTLS_ONLY(repl_tls.enabled ? gtm_tls_send(repl_tls.sock, (char *)buff, send_size)
+							: ) send(sock_fd, (char *)buff, send_size, 0);	/* BYPASSOK(send) */
+			if (0 <= bytes_sent)
+			{
+				assert(0 < bytes_sent);
+				*send_len = (int)bytes_sent;
+				REPL_DPRINT2("repl_send: returning with send_len %ld\n", bytes_sent);
+				return SS_NORMAL;
+			}
+#			ifdef GTM_TLS
+			if (repl_tls.enabled && ((GTMTLS_WANT_READ == bytes_sent) || (GTMTLS_WANT_WRITE == bytes_sent)))
+			{	/* TLS/SSL implementation couldn't complete the send() without reading or writing more data. Treat
+				 * as if nothing was sent. But, mark the poll direction so that then next call to repl_recv waits
+				 * for the TCP/IP pipe to be ready for an I/O.
+				 */
+				*poll_direction = (GTMTLS_WANT_READ == bytes_sent) ? REPL_POLLIN : REPL_POLLOUT;
+				return SS_NORMAL;
+			}
+			/* handle error */
+			save_errno = repl_tls.enabled ? gtm_tls_errno() : ERRNO;
+			if (-1 == save_errno)
+			{	/* This indicates an error from TLS/SSL layer and not from a system call. */
+				assert(repl_tls.enabled);
+				assert(FALSE);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT("send"), ERR_TEXT, 2,
+						LEN_AND_STR(gtm_tls_get_error()));
+			}
+#			else
 			save_errno = ERRNO;
+#			endif
 			assert((EMSGSIZE != save_errno) && (EWOULDBLOCK != save_errno));
 			if (EINTR == save_errno)
 				continue;
 			if (EMSGSIZE == save_errno)
-			{	/* Reduce the send size if possible */
+			{
 				if (send_size > REPL_COMM_MIN_SEND_SIZE)
 				{
 					if ((send_size >> 1) <= REPL_COMM_MIN_SEND_SIZE)
@@ -214,28 +282,22 @@ int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout)
 					else
 						send_size >>= 1;
 				}
-				if (0 == ++emsgsize_cnt % REPL_COMM_LOG_EMSGSIZE_INTERVAL)
+				if (0 == ++EMSGSIZE_cnt % REPL_COMM_LOG_EMSGSIZE_INTERVAL)
 				{
 					repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: System appears to be "
-							"clogged; EMSGSIZE returned from send %d times\n", emsgsize_cnt);
+							"clogged; EMSGSIZE returned from send %d times\n", EMSGSIZE_cnt);
 				}
 			} else if (EWOULDBLOCK == save_errno)
 			{
-				if (0 == ++ewouldblock_cnt % REPL_COMM_LOG_EWDBLCK_INTERVAL)
+				if (0 == ++EWOULDBLOCK_cnt % REPL_COMM_LOG_EWDBLCK_INTERVAL)
 				{
 					repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: System appears to be "
-							"running slow; EWOULDBLOCK returned from send %d times\n", ewouldblock_cnt);
+							"running slow; EWOULDBLOCK returned from send %d times\n", EWOULDBLOCK_cnt);
 				}
 				rel_quant(); /* Relinquish our quanta in the hope that things get cleared next time around */
 			} else
 				break;
 		}
-		if (0 <= bytes_sent)
-		{
-			*send_len = (int)bytes_sent;
-			REPL_DPRINT2("repl_send: returning with send_len %ld\n", bytes_sent);
-			return SS_NORMAL;
-		}
 		repl_errno = EREPL_SEND;
 		return save_errno;
 	} else if (!io_ready)
@@ -245,9 +307,9 @@ int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout)
 	return save_errno;
 }
 
-int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout)
+int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout GTMTLS_ONLY_COMMA(int *poll_direction))
 {
-	int		status, max_recv_len, eintr_cnt, eagain_cnt, io_ready, save_errno;
+	int		status, max_recv_len, io_ready, save_errno;
 	ssize_t		bytes_recvd;
 
 	if (!repl_recv_trace_buff)
@@ -263,38 +325,79 @@ int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout)
 	 */
 	VMS_ONLY(max_recv_len = MIN(max_recv_len, VMS_MAX_TCP_RECV_SIZE));
 	*recv_len = 0;
-	if (0 < (io_ready = fd_ioready(sock_fd, TRUE, timeout)))
+#	ifdef GTM_TLS
+	if (repl_tls.enabled && (REPL_INVALID_POLL_DIRECTION != *poll_direction))
 	{
-		while (0 > (bytes_recvd = recv(sock_fd, (char *)buff, max_recv_len, 0)) && EINTR == ERRNO)
-			;
-		if (0 < bytes_recvd)
+		if (0 >= (io_ready = fd_ioready(sock_fd, *poll_direction, timeout)))
 		{
-			*recv_len = (int)bytes_recvd;
-			REPL_DPRINT2("repl_recv: returning with recv_len %ld\n", bytes_recvd);
-			/* Trace last REPL_RECV_SIZE_TRACE_SIZE sizes of what was received */
-			repl_recv_size_trace[repl_recv_size_trace_pos++] = bytes_recvd;
-			repl_recv_size_trace_pos %= ARRAYSIZE(repl_recv_size_trace);
-			/* Trace last REPL_RECV_TRACE_BUFF_SIZE bytes received. */
-			REPL_TRACE_BUFF(repl_recv_trace_buff, repl_recv_trace_buff_pos, buff, bytes_recvd,
-						REPL_RECV_TRACE_BUFF_SIZE);
-			return (SS_NORMAL); /* always process the received buffer before dealing with any errno */
+			if (!io_ready)
+				return SS_NORMAL;
+			save_errno = ERRNO;
+			repl_errno = EREPL_SELECT;
+			return save_errno;
 		}
-		save_errno = ERRNO;
-		if (0 == bytes_recvd) /* Connection reset */
-			save_errno = errno = ECONNRESET;
-		else if (ETIMEDOUT == save_errno)
+		/* Fall-through */
+	}
+#	endif
+	if ((0 < (io_ready = fd_ioready(sock_fd, REPL_POLLIN, timeout)))
+		GTMTLS_ONLY( || (repl_tls.enabled && gtm_tls_cachedbytes(repl_tls.sock))))
+	{
+		while (TRUE)
 		{
-			repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: network may be down;"
-						" socket recv() returned ETIMEDOUT\n");
-		} else if (EWOULDBLOCK == save_errno)
-		{	/* NOTE: Although we use blocking sockets, it is possible to get EWOULDBLOCK error status if receive timeout
-		   	 * has been set and the timeout expired before data was received (from man recv on RH 8 Linux). Some systems
-		   	 * return ETIMEDOUT for the timeout condition.
-			 */
-			assert(EWOULDBLOCK != save_errno);
-			repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: network I/O failed to complete; "
-					"socket recv() returned EWOULDBLOCK\n");
-			save_errno = errno = ETIMEDOUT; /* will be treated as a bad connection and the connection closed */
+			bytes_recvd = GTMTLS_ONLY(repl_tls.enabled ? gtm_tls_recv(repl_tls.sock, (char *)buff, max_recv_len)
+							 : ) recv(sock_fd, (char *)buff, max_recv_len, 0);	/* BYPASSOK */
+			if (0 < bytes_recvd)
+			{
+				*recv_len = (int)bytes_recvd;
+				REPL_DPRINT2("repl_recv: returning with recv_len %ld\n", bytes_recvd);
+				/* Trace last REPL_RECV_SIZE_TRACE_SIZE sizes of what was received */
+				repl_recv_size_trace[repl_recv_size_trace_pos++] = bytes_recvd;
+				repl_recv_size_trace_pos %= ARRAYSIZE(repl_recv_size_trace);
+				/* Trace last REPL_RECV_TRACE_BUFF_SIZE bytes received. */
+				REPL_TRACE_BUFF(repl_recv_trace_buff, repl_recv_trace_buff_pos, buff, bytes_recvd,
+							REPL_RECV_TRACE_BUFF_SIZE);
+				return (SS_NORMAL); /* always process the received buffer before dealing with any errno */
+			}
+#			ifdef GTM_TLS
+			if (repl_tls.enabled && ((GTMTLS_WANT_READ == bytes_recvd) || (GTMTLS_WANT_WRITE == bytes_recvd)))
+			{	/* TLS/SSL implementation couldn't complete the recv() without reading or writing more data. Treat
+				 * as if nothing was read. But, mark the poll direction so that then next call to repl_recv waits
+				 * for the TCP/IP pipe to be ready for an I/O.
+				 */
+				*poll_direction = (GTMTLS_WANT_READ == bytes_recvd) ? REPL_POLLIN : REPL_POLLOUT;
+				return SS_NORMAL;
+			}
+			/* handle error */
+			save_errno = repl_tls.enabled ? gtm_tls_errno() : ERRNO;
+			if (-1 == save_errno)
+			{
+				assert(repl_tls.enabled);
+				assert(FALSE);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT("recv"), ERR_TEXT, 2,
+						LEN_AND_STR(gtm_tls_get_error()));
+			}
+#			else
+			save_errno = ERRNO;
+#			endif
+			if (0 == bytes_recvd)
+				save_errno = ECONNRESET;
+			if (EINTR == save_errno)
+				continue;
+			else if (ETIMEDOUT == save_errno)
+			{
+				repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: network may be down;"
+								" socket recv() returned ETIMEDOUT\n");		/* BYPASSOK(recv) */
+			} else if (EWOULDBLOCK == save_errno)
+			{	/* NOTE: Although we use blocking sockets, it is possible to get EWOULDBLOCK error status if
+				 * receive timeout has been set and the timeout expired before data was received (from man recv on
+				 * RH 8 Linux). Some systems return ETIMEDOUT for the timeout condition.
+				 */
+				assert(EWOULDBLOCK != save_errno);
+				repl_log(stderr, TRUE, TRUE, "Communication subsystem warning: network I/O failed to complete; "
+								" Socket recv() returned EWOULDBLOCK\n");	/* BYPASSOK(recv) */
+				save_errno = errno = ETIMEDOUT; /* will be treated as a bad connection and the connection closed */
+			}
+			break;
 		}
 		repl_errno = EREPL_RECV;
 		return save_errno;
@@ -307,8 +410,21 @@ int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout)
 
 int repl_close(int *sock_fd)
 {
-	int	status = 0;
+	int		status = 0;
+	boolean_t	close_tls;
 
+	/* Before closing the underlying transport, close the TLS/SSL connection */
+#	ifdef GTM_TLS
+	close_tls = (NULL != repl_tls.sock) && (NULL != repl_tls.sock->ssl);
+	if (close_tls)
+	{
+		assert(REPL_TLS_REQUESTED);
+		gtm_tls_socket_close(repl_tls.sock);
+		assert(NULL == repl_tls.sock->ssl);
+	}
+	CLEAR_REPL_TLS_ENABLED;
+	repl_tls.renegotiate_state = REPLTLS_RENEG_STATE_NONE;
+#	endif
 	if (FD_INVALID != *sock_fd)
 		CLOSEFILE_RESET(*sock_fd, status);	/* resets "*sock_fd" to FD_INVALID */
 	return (0 == status ? 0 : ERRNO);
@@ -316,8 +432,8 @@ int repl_close(int *sock_fd)
 
 static int get_sock_buff_size(int sockfd, int *buffsize, int which_buf)
 {
-	int	status;
-	GTM_SOCKLEN_TYPE optlen;
+	int			status;
+	GTM_SOCKLEN_TYPE 	optlen;
 
 	optlen = SIZEOF(*buffsize);
         status = getsockopt(sockfd, SOL_SOCKET, which_buf, (void *)buffsize, (GTM_SOCKLEN_TYPE *)&optlen);
@@ -411,3 +527,118 @@ void repl_log_conn_info(int sock_fd, FILE *log_fp)
 			remote_ip, remote_port_buffer);
 	return;
 }
+
+#ifdef GTM_TLS
+void repl_log_tls_info(FILE *logfp, gtm_tls_socket_t *socket)
+{
+	char			*expiry;
+	struct tm		*localtm;
+	gtm_tls_conn_info	conn_info;
+
+	if (0 != gtm_tls_get_conn_info(repl_tls.sock, &conn_info))
+	{
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSCONNINFO, 0, ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+		return;
+	}
+	repl_log(logfp, FALSE, TRUE, "TLS/SSL Session:\n");
+	repl_log(logfp, FALSE, TRUE, "  Protocol Version: %s\n", conn_info.protocol);
+	repl_log(logfp, FALSE, TRUE, "  Session Algorithm: %s\n", conn_info.session_algo);
+	repl_log(logfp, FALSE, TRUE, "  Compression: %s\n", conn_info.compression);
+	repl_log(logfp, FALSE, TRUE, "  Session Reused: %s\n", conn_info.reused ? "YES" : "NO");
+	if ('\0' != conn_info.session_id[0])
+		repl_log(logfp, FALSE, TRUE, "  Session-ID: %s\n", conn_info.session_id);
+	if (-1 == conn_info.session_expiry_timeout)
+		expiry = "NEVER\n";	/* '\n' is added because asctime always appends a '\n' at the end. */
+	else
+	{
+		GTM_LOCALTIME(localtm, (time_t *)&conn_info.session_expiry_timeout);
+		expiry = asctime(localtm);
+	}
+	repl_log(logfp, FALSE, TRUE, "  Session Expiry: %s", expiry);
+	repl_log(logfp, FALSE, TRUE, "  Secure Renegotiation %s supported\n", conn_info.secure_renegotiation ? "IS" : "IS NOT");
+	repl_log(logfp, FALSE, TRUE, "Peer Certificate Information:\n");
+	repl_log(logfp, FALSE, TRUE, "  Asymmetric Algorithm: %s (%d bit)\n", conn_info.cert_algo, conn_info.cert_nbits);
+	repl_log(logfp, FALSE, TRUE, "  Subject: %s\n", conn_info.subject);
+	repl_log(logfp, FALSE, TRUE, "  Issuer: %s\n", conn_info.issuer);
+	repl_log(logfp, FALSE, TRUE, "  Validity:\n");
+	repl_log(logfp, FALSE, TRUE, "    Not Before: %s\n", conn_info.not_before);
+	repl_log(logfp, FALSE, TRUE, "    Not After: %s\n", conn_info.not_after);
+}
+
+void repl_do_tls_init(FILE *logfp)
+{
+	boolean_t	issue_fallback_warning, status;
+
+	assert(REPL_TLS_REQUESTED);
+	assert(NULL == tls_ctx);
+	assert(!repl_tls.enabled);
+	issue_fallback_warning = FALSE;
+	if (SS_NORMAL != (status = gtm_tls_loadlibrary()))
+	{
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0, ERR_TEXT, 2, LEN_AND_STR(dl_err));
+		else
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSDLLNOOPEN), 0, ERR_TEXT, 2,
+					LEN_AND_STR(dl_err));
+		issue_fallback_warning = TRUE;
+	} else if (NULL == (tls_ctx = gtm_tls_init(GTM_TLS_API_VERSION, 0)))
+	{
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0, ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+		else
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSINIT), 0, ERR_TEXT, 2,
+					LEN_AND_STR(gtm_tls_get_error()));
+		issue_fallback_warning = TRUE;
+	}
+	if (issue_fallback_warning)
+	{
+		repl_log(logfp, TRUE, TRUE, "Plaintext fallback enabled. TLS/SSL communication will not be attempted again.\n");
+		CLEAR_REPL_TLS_REQUESTED;	/* As if -tlsid qualifier was never specified. */
+	} else
+	{
+		assert(NULL != tls_ctx);
+		repl_log(logfp, TRUE, FALSE, "TLS/SSL library for secure communication successfully loaded. ");
+		repl_log(logfp, FALSE, TRUE, "Runtime library version: 0x%08x; FIPS Mode: %s\n",
+				GTMTLS_RUNTIME_LIB_VERSION(tls_ctx),  GTMTLS_IS_FIPS_MODE(tls_ctx) ? "ON" : "OFF");
+	}
+}
+
+int repl_do_tls_handshake(FILE *logfp, int sock_fd, boolean_t do_accept, int *poll_direction)
+{
+	int			io_ready, save_errno, status;
+
+	assert(REPL_TLS_REQUESTED);
+	assert(NULL != tls_ctx);
+	assert(NULL != repl_tls.sock);
+	assert(!repl_tls.enabled);
+	if (REPL_INVALID_POLL_DIRECTION != *poll_direction)
+	{
+		if (0 >= (io_ready = fd_ioready(sock_fd, *poll_direction, REPL_POLL_WAIT)))
+		{
+			if (!io_ready)
+				return REPL_POLLIN == *poll_direction ? GTMTLS_WANT_READ : GTMTLS_WANT_WRITE;
+			save_errno = errno;
+			repl_errno = EREPL_SELECT;
+			return save_errno;
+		}
+		/* Fall-through */
+	}
+	/* Do the TLS/SSL handshake */
+	save_errno = SS_NORMAL;
+	if (-1 == (status = do_accept ? gtm_tls_accept(repl_tls.sock) : gtm_tls_connect(repl_tls.sock)))
+		save_errno = gtm_tls_errno();
+	else if ((GTMTLS_WANT_READ == status) || (GTMTLS_WANT_WRITE == status))
+	{
+		*poll_direction = GTMTLS_WANT_READ ? REPL_POLLIN : REPL_POLLOUT;
+		return status;
+	} else
+	{	/* TLS/SSL handshake succeeded. Log information about the peer's certificate and the TLS/SSL connection. */
+		repl_log(logfp, TRUE, TRUE, "Secure communication enabled using TLS/SSL protocol\n");
+		repl_log_tls_info(logfp, repl_tls.sock);
+		return SS_NORMAL;
+	}
+	assert(SS_NORMAL != save_errno);
+	repl_errno = do_accept ? EREPL_RECV : EREPL_SEND;
+	return save_errno;
+}
+#endif
diff --git a/sr_port/repl_comm.h b/sr_port/repl_comm.h
index ec8bc54..312a964 100644
--- a/sr_port/repl_comm.h
+++ b/sr_port/repl_comm.h
@@ -20,6 +20,7 @@
  *	int		sent_len;
  *	int		sent_this_iter;
  *	int		status;
+ *	int		poll_dir;
  * On completion of an iteration, sent_len contains the number of bytes sent upto now, tosend_len contains the number of bytes
  * yet to be sent. Users of this macro must NOT count on msg_ptr pointing to BUFF + LEN. sent_this_iter is used as a
  * temporary, and users must NOT count on its value. The loop is terminated when
@@ -27,11 +28,11 @@
  * b. when repl_send() fails, in which case sent_len contains the number of bytes successfully sent, and tosend_len is the
  *    length that we failed to send.
  */
-#define REPL_SEND_LOOP(SOCK_FD, BUFF, LEN, TIMEOUT) 							\
-assert(LEN > 0);											\
-for (msg_ptr = (unsigned char *)(BUFF), sent_len = 0, sent_this_iter = tosend_len = (LEN); 		\
-     SS_NORMAL == (status = repl_send(SOCK_FD, msg_ptr, &sent_this_iter, TIMEOUT)) 			\
-     && ((sent_len += sent_this_iter), (tosend_len -= sent_this_iter), (tosend_len > 0)); 		\
+#define REPL_SEND_LOOP(SOCK_FD, BUFF, LEN, TIMEOUT)										\
+assert(LEN > 0);														\
+for (msg_ptr = (unsigned char *)(BUFF), sent_len = 0, sent_this_iter = tosend_len = (LEN) GTMTLS_ONLY_COMMA(poll_dir = -1);	\
+     (SS_NORMAL == (status = repl_send(SOCK_FD, msg_ptr, &sent_this_iter, TIMEOUT GTMTLS_ONLY_COMMA(&poll_dir))))		\
+     && ((sent_len += sent_this_iter), (tosend_len -= sent_this_iter), (tosend_len > 0));					\
      msg_ptr += sent_this_iter, sent_this_iter = tosend_len)
 
 /* Use REPL_RECV_LOOP when the length of the msg to be recieved is already known
@@ -41,6 +42,7 @@ for (msg_ptr = (unsigned char *)(BUFF), sent_len = 0, sent_this_iter = tosend_le
  *	int		recvd_len;
  *	int		recvd_this_iter;
  *	int		status;
+ *	int		poll_dir;
  * On completion of an iteration, recvd_len contains the number of bytes received upto now, torecv_len contains the number of bytes
  * yet to be received. Users of this macro must NOT count on msg_ptr pointing to BUFF + LEN. recvd_this_iter is used as a
  * temporary, and users must NOT count on its value. The loop is terminated when
@@ -48,10 +50,10 @@ for (msg_ptr = (unsigned char *)(BUFF), sent_len = 0, sent_this_iter = tosend_le
  * b. when repl_recv() fails, in which case recvd_len contains the number of bytes successfully received, and torecv_len is the
  *    length that we failed to receive.
  */
-#define REPL_RECV_LOOP(SOCK_FD, BUFF, LEN, TIMEOUT) 							\
-for (msg_ptr = (unsigned char *)(BUFF), recvd_len = 0, recvd_this_iter = torecv_len = (LEN); 		\
-     (SS_NORMAL == (status = repl_recv(SOCK_FD, msg_ptr, &recvd_this_iter, TIMEOUT))) 			\
-     && ((recvd_len += recvd_this_iter), (torecv_len -= recvd_this_iter), (torecv_len > 0)); 		\
+#define REPL_RECV_LOOP(SOCK_FD, BUFF, LEN, TIMEOUT)										\
+for (msg_ptr = (unsigned char *)(BUFF), recvd_len = 0, recvd_this_iter = torecv_len = (LEN) GTMTLS_ONLY_COMMA(poll_dir = -1);	\
+     (SS_NORMAL == (status = repl_recv(SOCK_FD, msg_ptr, &recvd_this_iter, TIMEOUT GTMTLS_ONLY_COMMA(&poll_dir))))		\
+     && ((recvd_len += recvd_this_iter), (torecv_len -= recvd_this_iter), (torecv_len > 0));					\
      msg_ptr += recvd_this_iter, recvd_this_iter = torecv_len)
 
 #define REPL_COMM_MAX_INTR_CNT	3	/* # of iterations we'll let select() be interrupted before we give up and assume timeout */
@@ -70,11 +72,14 @@ for (msg_ptr = (unsigned char *)(BUFF), recvd_len = 0, recvd_this_iter = torecv_
 #define GTMSOURCE_IDLE_POLL_WAIT	100			/* 100ms sleep in case nothing sent to the other side */
 #define REPL_POLL_WAIT			(MILLISECS_IN_SEC - 1)	/* Maximum time (in ms) for select()/poll() to timeout */
 #define REPL_POLL_NOWAIT		0			/* Forces poll()/select() to return immediately */
+#define REPL_INVALID_POLL_DIRECTION	-1
+#define REPL_POLLIN			1
+#define REPL_POLLOUT			2
 
 /* Replication communcation subsystem function prototypes */
-int fd_ioready(int sock_fd, boolean_t pollin, int timeout);
-int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout);
-int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout);
+int fd_ioready(int sock_fd, int poll_direction, int timeout);
+int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout GTMTLS_ONLY_COMMA(int *poll_direction));
+int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout GTMTLS_ONLY_COMMA(int *poll_direction));
 int repl_close(int *sock_fd);
 int get_send_sock_buff_size(int sockfd, int *buflen);
 int get_recv_sock_buff_size(int sockfd, int *buflen);
diff --git a/sr_port/repl_errno.h b/sr_port/repl_errno.h
index 4d0a764..e3a4aaa 100644
--- a/sr_port/repl_errno.h
+++ b/sr_port/repl_errno.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -51,7 +51,8 @@ enum
 	EREPL_FILTERNOSPC,			/* 288 */
 	EREPL_INTLFILTER_SECNODZTRIGINTP,	/* 289 */
 	EREPL_INTLFILTER_MULTILINEXECUTE,	/* 290 */
-	EREPL_MAXERRNO				/* 291 */
+	EREPL_FILTERTIMEDOUT,			/* 291 */
+	EREPL_MAXERRNO				/* 292 */
 };
 
 #endif
diff --git a/sr_port/repl_filter.c b/sr_port/repl_filter.c
index c91897d..34ab1cd 100644
--- a/sr_port/repl_filter.c
+++ b/sr_port/repl_filter.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,6 +16,7 @@
 #include "gtm_unistd.h"
 #include "gtm_string.h"
 #include "gtm_stdio.h"
+#include "gtm_select.h"
 #ifdef UNIX
 #include "gtm_ipc.h"
 #endif
@@ -30,7 +31,6 @@
 #include <errno.h>
 #include <sys/wait.h>
 
-#include "iotcp_select.h"
 #include "gdsroot.h"
 #include "gdsblk.h"
 #include "gtm_facility.h"
@@ -56,6 +56,10 @@
 #include "jnl_typedef.h"
 #include "gv_trigger_common.h" /* for HASHT* macros */
 #include "replgbl.h"
+#ifdef UNIX
+#include "heartbeat_timer.h"
+#include "gtm_c_stack_trace.h"
+#endif
 #ifdef GTM_USE_POLL_FOR_SUBSECOND_SELECT
 #include <sys/poll.h>
 #endif
@@ -71,6 +75,7 @@
 	{									\
 		assert(SIZEOF(jnl_str_len_t) == SIZEOF(uint4));			\
 		keylen = *((jnl_str_len_t *)(PTR));				\
+		keylen &= 0xFFFFFF;	/* to remove 8-bit nodeflags if any */	\
 		lclptr = PTR + SIZEOF(jnl_str_len_t);				\
 		if (STDNULL_TO_GTMNULL_COLL == REMOTE_NULL_SUBS_XFORM)		\
 		{								\
@@ -194,7 +199,7 @@
 	nodelen = *((uint4 *)jb);										\
 	assert(tail_minus_suffix_len >= (SIZEOF(jnl_str_len_t) + nodelen));					\
 	memcpy(cb, jb, tail_minus_suffix_len);									\
-	NULLSUBSC_TRANSFORM_IF_NEEDED(cb + SIZEOF(jnl_str_len_t));						\
+	NULLSUBSC_TRANSFORM_IF_NEEDED(cb);									\
 	jb += tail_minus_suffix_len;										\
 	cb += tail_minus_suffix_len;										\
 }
@@ -264,7 +269,7 @@
 	 */													\
 	((jnl_string *)cb)->nodeflags = 0;									\
 	GET_JREC_UPD_TYPE(jb, trigupd_type);									\
-	NULLSUBSC_TRANSFORM_IF_NEEDED(cb + SIZEOF(jnl_str_len_t));						\
+	NULLSUBSC_TRANSFORM_IF_NEEDED(cb);									\
 	jb += tail_minus_suffix_len;										\
 	cb += tail_minus_suffix_len;										\
 }
@@ -379,6 +384,9 @@
 #define MORE_TO_TRANSFER -99
 #define DUMMY_TCOMMIT_LENGTH 3	/* A dummy commit is 09\n */
 
+#define FILTER_HALF_TIMEOUT	4			/* 4 heartbeats : 32 seconds. */
+#define FILTER_FULL_TIMEOUT	8			/* 4 heartbeats : 64 seconds. */
+
 /* repl_filter_recv receive state */
 
 enum
@@ -430,7 +438,9 @@ GBLREF	int			repl_filter_bufsiz;
 GBLREF	boolean_t		is_src_server, is_rcvr_server;
 #ifdef UNIX
 GBLREF	repl_conn_info_t	*this_side, *remote_side;
+GBLREF	volatile uint4		heartbeat_counter;
 #endif
+GBLREF	uint4			process_id;
 
 error_def(ERR_FILTERBADCONV);
 error_def(ERR_FILTERCOMM);
@@ -439,6 +449,7 @@ error_def(ERR_REPLFILTER);
 error_def(ERR_REPLNOXENDIAN);
 error_def(ERR_TEXT);
 error_def(ERR_UNIMPLOP);
+error_def(ERR_FILTERTIMEDOUT);
 
 static	pid_t	repl_filter_pid = -1;
 static	int	repl_srv_filter_fd[2] = {FD_INVALID, FD_INVALID};
@@ -462,8 +473,8 @@ void jnl_extr_init(void)
 
 	SETUP_THREADGBL_ACCESS;
 	/* Should be a non-filter related function. But for now,... Needs GBLREFs gv_currkey and transform */
-	TREF(transform) = FALSE;      /* to avoid the assert in mval2subsc() */
-	GVKEYSIZE_INCREASE_IF_NEEDED(DBKEYSIZE(MAX_KEY_SZ));
+	TREF(transform) = FALSE;      /* to avoid SIG-11 in "mval2subsc" as it expects gv_target to be set up and we dont set it */
+	GVKEYSIZE_INIT_IF_NEEDED;
 }
 
 static void repl_filter_close_all_pipes(void)
@@ -495,7 +506,7 @@ int repl_filter_init(char *filter_cmd)
 	if (0 > status)
 	{
 		repl_filter_close_all_pipes();
-		gtm_putmsg(VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
 				RTS_ERROR_LITERAL("Could not create pipe for Server->Filter I/O"), ERRNO);
 		repl_errno = EREPL_FILTERSTART_PIPE;
 		return(FILTERSTART_ERR);
@@ -505,7 +516,7 @@ int repl_filter_init(char *filter_cmd)
 	if (0 > status)
 	{
 		repl_filter_close_all_pipes();
-		gtm_putmsg(VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
 				RTS_ERROR_LITERAL("Could not create pipe for Server->Filter I/O"), ERRNO);
 		repl_errno = EREPL_FILTERSTART_PIPE;
 		return(FILTERSTART_ERR);
@@ -516,7 +527,8 @@ int repl_filter_init(char *filter_cmd)
 	if (NULL == (arg_ptr = strtok(cmd, FILTER_CMD_ARG_DELIM_TOKENS)))
 	{
 		repl_filter_close_all_pipes();
-		gtm_putmsg(VARLSTCNT(6) ERR_REPLFILTER, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Null filter command specified"));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLFILTER, 0, ERR_TEXT, 2,
+				RTS_ERROR_LITERAL("Null filter command specified"));
 		repl_errno = EREPL_FILTERSTART_NULLCMD;
 		return(FILTERSTART_ERR);
 	}
@@ -566,12 +578,10 @@ int repl_filter_init(char *filter_cmd)
 								* also resets "repl_srv_filter_fd[READ_END]" to FD_INVALID */
 			/* Make the server->filter pipe stdin for filter */
 			DUP2(repl_srv_filter_fd[READ_END], 0, status);
-			if (0 > status)
-				GTMASSERT;
+			assertpro(0 <= status);
 			/* Make the filter->server pipe stdout for filter */
 			DUP2(repl_filter_srv_fd[WRITE_END], 1, status);
-			if (0 > status)
-				GTMASSERT;
+			assertpro(0 <= status);
 		)
 		VMS_ONLY(decc$set_child_standard_streams(repl_srv_filter_fd[READ_END], repl_filter_srv_fd[WRITE_END], -1));
 		/* Start the filter */
@@ -585,13 +595,15 @@ int repl_filter_init(char *filter_cmd)
 				F_CLOSE(repl_filter_srv_fd[READ_END], close_res);
 					/* resets "repl_filter_srv_fd[READ_END]" to FD_INVALID */
 			)
-			gtm_putmsg(VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not exec filter"), ERRNO);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
+					RTS_ERROR_LITERAL("Could not exec filter"), ERRNO);
 			repl_errno = EREPL_FILTERSTART_EXEC;
 			return(FILTERSTART_ERR);
 		}
 	} else
 	{	/* Error in fork */
-		gtm_putmsg(VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not fork filter"), ERRNO);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLFILTER, 0, ERR_TEXT, 2,
+				RTS_ERROR_LITERAL("Could not fork filter"), ERRNO);
 		repl_errno = EREPL_FILTERSTART_FORK;
 		return(FILTERSTART_ERR);
 	}
@@ -615,8 +627,8 @@ static int repl_filter_send(seq_num tr_num, unsigned char *tr, int tr_len, boole
 			is_null = (JRT_NULL == first_rectype);
 			save_jnl_seqno = GET_JNL_SEQNO(tr);
 			save_strm_seqno = GET_STRM_SEQNO(tr);
-			if (NULL == (extr_end = jnl2extcvt((jnl_record *)tr, tr_len, extract_buff)))
-				GTMASSERT;
+			extr_end = jnl2extcvt((jnl_record *)tr, tr_len, extract_buff);
+			assertpro(NULL != extr_end);
 			extr_len = extr_end - extract_buff;
 			extract_buff[extr_len] = '\0';
 		} else
@@ -656,7 +668,7 @@ static int repl_filter_send(seq_num tr_num, unsigned char *tr, int tr_len, boole
 static int repl_filter_recv_line(char *line, int *line_len, int max_line_len, boolean_t send_done)
 { /* buffer input read from repl_filter_srv_fd[READ_END], return one line at a time; line separator is '\n' */
 
-	int		save_errno;
+	int		save_errno, orig_heartbeat;
 	int		status;
 	ssize_t		l_len, r_len, buff_remaining ;
 	muextract_type	exttype;
@@ -667,6 +679,7 @@ static int repl_filter_recv_line(char *line, int *line_len, int max_line_len, bo
 	struct pollfd	poll_fdlist[1];
 #endif
 	struct timeval	repl_filter_poll_interval;
+	boolean_t	half_timeout_done;
 
 	for (; ;)
 	{
@@ -711,6 +724,7 @@ static int repl_filter_recv_line(char *line, int *line_len, int max_line_len, bo
 					repl_filter_poll_interval.tv_sec = 0;
 					repl_filter_poll_interval.tv_usec = 1000;
 #ifndef GTM_USE_POLL_FOR_SUBSECOND_SELECT
+					assertpro(FD_SETSIZE > repl_filter_srv_fd[READ_END]);
 					FD_ZERO(&input_fds);
 					FD_SET(repl_filter_srv_fd[READ_END], &input_fds);
 #else
@@ -742,9 +756,46 @@ static int repl_filter_recv_line(char *line, int *line_len, int max_line_len, bo
 					break;
 				}
 			}
-			while (-1 == (r_len = read(repl_filter_srv_fd[READ_END], srv_read_end, buff_remaining)) &&
-					(EINTR == errno || ENOMEM == errno))
+#			ifdef UNIX
+			/* Before starting the `read', note down the current heartbeat counter. This is used to break from the
+			 * read if the filter program takes too long to send records back to us. Do it only if send_done is TRUE
+			 * which indicates the end of a mini-transaction or a commit record for an actual transaction.
+			 */
+			assert(-1 != repl_filter_pid);
+			assert(heartbeat_started);
+			half_timeout_done = FALSE;
+			if (send_done)
+				orig_heartbeat = heartbeat_counter;
+			do
+			{
+				r_len = read(repl_filter_srv_fd[READ_END], srv_read_end, buff_remaining);
+				if (0 < r_len)
+					break;
+				save_errno = errno;
+				if ((ENOMEM != save_errno) && (EINTR != save_errno))
+					break;
+				/* EINTR/ENOMEM -- check if it's time to take the stack trace. */
+				if (send_done)
+				{
+					if (!half_timeout_done && ((heartbeat_counter - orig_heartbeat) >= FILTER_HALF_TIMEOUT))
+					{
+						/* Half-timeout : take C-stack of the filter program. */
+						half_timeout_done = TRUE;
+						GET_C_STACK_FROM_SCRIPT("FILTERTIMEDOUT_HALF_TIME", process_id, repl_filter_pid, 0);
+					} else if ((heartbeat_counter - orig_heartbeat) >= FILTER_FULL_TIMEOUT)
+					{
+						/* Full-timeout : take C-stack of the filter program. */
+						GET_C_STACK_FROM_SCRIPT("FILTERTIMEDOUT_FULL_TIME", process_id, repl_filter_pid, 1);
+						return (repl_errno = EREPL_FILTERTIMEDOUT);
+					}
+					continue;
+				}
+			} while (TRUE);
+#			else
+			while (-1 == (r_len = read(repl_filter_srv_fd[READ_END], srv_read_end, buff_remaining))
+					&& (EINTR == errno || ENOMEM == errno))
 				;
+#			endif
 			if (0 < r_len) /* successful read */
 			{
 				/* if send is not done then need to do select/poll if we try read again */
@@ -787,8 +838,7 @@ static int repl_filter_recv(seq_num tr_num, unsigned char *tr, int *tr_len, bool
 		if (SS_NORMAL != (status = repl_filter_recv_line(extr_rec, &firstrec_len, ZWR_EXP_RATIO(MAX_LOGI_JNL_REC_SIZE),
 								 send_done)))
 		{
-			if (EREPL_FILTERNOSPC == repl_errno)
-				GTMASSERT; /* why didn't we pre-allocate enough memory? */
+			assertpro(EREPL_FILTERNOSPC != repl_errno);	/* why didn't we pre-allocate enough memory? */
 			return status;
 		}
 		/* if send not done make sure we do a select before reading any more */
@@ -822,8 +872,7 @@ static int repl_filter_recv(seq_num tr_num, unsigned char *tr, int *tr_len, bool
 			if (SS_NORMAL != (status = repl_filter_recv_line(extr_rec, &extr_reclen,
 									 ZWR_EXP_RATIO(MAX_LOGI_JNL_REC_SIZE), send_done)))
 			{
-				if (EREPL_FILTERNOSPC == repl_errno)
-					GTMASSERT; /* why didn't we pre-allocate enough memory? */
+				assertpro(EREPL_FILTERNOSPC != repl_errno);	/* why didn't we pre-allocate enough memory? */
 				return status;
 			}
 			/* We don't want a null transaction inside a tp so get rid of it */
@@ -921,6 +970,7 @@ int repl_filter(seq_num tr_num, unsigned char *tr, int *tr_len, int bufsize)
 				repl_filter_poll_interval.tv_sec = 0;
 				repl_filter_poll_interval.tv_usec = 1000;
 #ifndef GTM_USE_POLL_FOR_SUBSECOND_SELECT
+				assertpro(FD_SETSIZE > repl_srv_filter_fd[WRITE_END]);
 				FD_ZERO(&output_fds);
 				FD_SET(repl_srv_filter_fd[WRITE_END], &output_fds);
 #else
@@ -975,6 +1025,7 @@ int repl_filter(seq_num tr_num, unsigned char *tr, int *tr_len, int bufsize)
 				repl_filter_poll_interval.tv_sec = 0;
 				repl_filter_poll_interval.tv_usec = 1000;
 #ifndef GTM_USE_POLL_FOR_SUBSECOND_SELECT
+				assertpro(FD_SETSIZE > repl_filter_srv_fd[READ_END]);
 				FD_ZERO(&input_fds);
 				FD_SET(repl_filter_srv_fd[READ_END], &input_fds);
 #else
@@ -1051,19 +1102,22 @@ void repl_filter_error(seq_num filter_seqno, int why)
 	switch (repl_errno)
 	{
 		case EREPL_FILTERNOTALIVE :
-			rts_error(VARLSTCNT(3) ERR_FILTERNOTALIVE, 1, &filter_seqno);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_FILTERNOTALIVE, 1, &filter_seqno);
 			break;
 		case EREPL_FILTERSEND :
-			rts_error(VARLSTCNT(4) ERR_FILTERCOMM, 1, &filter_seqno, why);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FILTERCOMM, 1, &filter_seqno, why);
 			break;
 		case EREPL_FILTERBADCONV :
-			rts_error(VARLSTCNT(3) ERR_FILTERBADCONV, 1, &filter_seqno);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_FILTERBADCONV, 1, &filter_seqno);
 			break;
 		case EREPL_FILTERRECV :
-			rts_error(VARLSTCNT(4) ERR_FILTERCOMM, 1, &filter_seqno, why);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FILTERCOMM, 1, &filter_seqno, why);
+			break;
+		case EREPL_FILTERTIMEDOUT :
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_FILTERTIMEDOUT, 1, &filter_seqno);
 			break;
 		default :
-			GTMASSERT;
+			assertpro(repl_errno != repl_errno);
 	}
 	return;
 }
@@ -1081,7 +1135,7 @@ void repl_check_jnlver_compat(UNIX_ONLY(boolean_t same_endianness))
 	assert(is_src_server || is_rcvr_server);
 	assert(JNL_VER_EARLIEST_REPL <= REMOTE_JNL_VER);
 	if (JNL_VER_EARLIEST_REPL > REMOTE_JNL_VER)
-		rts_error(VARLSTCNT(6) ERR_UNIMPLOP, 0, ERR_TEXT, 2,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_UNIMPLOP, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Dual/Multi site replication not supported between these two GT.M versions"));
 #	ifdef UNIX
 	else if ((V18_JNL_VER > REMOTE_JNL_VER) && !same_endianness)
@@ -1091,8 +1145,9 @@ void repl_check_jnlver_compat(UNIX_ONLY(boolean_t same_endianness))
 		else if (is_rcvr_server)
 			other_side = "Originating";
 		else
-			GTMASSERT; /* repl_check_jnlver_compat is called only from source server and receiver server */
-		rts_error(VARLSTCNT(6) ERR_REPLNOXENDIAN, 4, LEN_AND_STR(other_side), LEN_AND_STR(other_side));
+			/* repl_check_jnlver_compat is called only from source server and receiver server */
+			assertpro(is_src_server || is_rcvr_server);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLNOXENDIAN, 4, LEN_AND_STR(other_side), LEN_AND_STR(other_side));
 	}
 #	endif
 }
@@ -2380,7 +2435,7 @@ int jnl_v22TOv22(uchar_ptr_t jnl_buff, uint4 *jnl_len, uchar_ptr_t conv_buff, ui
 				mumps_node_ptr = cb + FIXED_UPD_RECLEN;
 				if (!remote_supports_triggers)
 					((jnl_string *)mumps_node_ptr)->nodeflags = 0;
-				NULLSUBSC_TRANSFORM_IF_NEEDED(mumps_node_ptr + SIZEOF(jnl_str_len_t));
+				NULLSUBSC_TRANSFORM_IF_NEEDED(mumps_node_ptr);
 				if (IS_TUPD(rectype))
 					tupd_num++;
 				else if (IS_UUPD(rectype) && promote_uupd_to_tupd)
diff --git a/sr_port/replic_gbldefs.c b/sr_port/replic_gbldefs.c
index 8f97323..d2d0472 100644
--- a/sr_port/replic_gbldefs.c
+++ b/sr_port/replic_gbldefs.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2003, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2003, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -37,22 +37,28 @@
 #include "gtmsource.h"
 #include "gtmrecv.h"
 #include "read_db_files_from_gld.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
-GBLDEF	unsigned char	*gtmsource_tcombuff_start = NULL;
-GBLDEF	unsigned char	*repl_filter_buff = NULL;
-GBLDEF	int		repl_filter_bufsiz = 0;
-GBLDEF	unsigned int	jnl_source_datalen, jnl_dest_maxdatalen;
-GBLDEF	unsigned char	jnl_source_rectype, jnl_dest_maxrectype;
-GBLDEF	char		*ext_stop;
-GBLDEF	char		*jb_stop;
-GBLDEF	seq_num		lastlog_seqno;
-GBLDEF	qw_num		trans_sent_cnt, last_log_tr_sent_cnt, trans_recvd_cnt, last_log_tr_recvd_cnt;
+GBLDEF	unsigned char		*gtmsource_tcombuff_start = NULL;
+GBLDEF	unsigned char		*repl_filter_buff = NULL;
+GBLDEF	int			repl_filter_bufsiz = 0;
+GBLDEF	unsigned int		jnl_source_datalen, jnl_dest_maxdatalen;
+GBLDEF	unsigned char		jnl_source_rectype, jnl_dest_maxrectype;
+GBLDEF	char			*ext_stop;
+GBLDEF	char			*jb_stop;
+GBLDEF	seq_num			lastlog_seqno;
+GBLDEF	qw_num			trans_sent_cnt, last_log_tr_sent_cnt, trans_recvd_cnt, last_log_tr_recvd_cnt;
 GBLDEF	upd_helper_entry_ptr_t	helper_entry;
+#ifdef GTM_TLS
+GBLDEF	repl_tls_info_t		repl_tls;
+#endif
 
 #ifdef VMS
-GBLDEF	unsigned char	jnl_ver, remote_jnl_ver;
-GBLDEF	boolean_t	primary_side_std_null_coll;
-GBLDEF	boolean_t	primary_side_trigger_support;
-GBLDEF	boolean_t	secondary_side_std_null_coll;
-GBLDEF	boolean_t	secondary_side_trigger_support;
+GBLDEF	unsigned char		jnl_ver, remote_jnl_ver;
+GBLDEF	boolean_t		primary_side_std_null_coll;
+GBLDEF	boolean_t		primary_side_trigger_support;
+GBLDEF	boolean_t		secondary_side_std_null_coll;
+GBLDEF	boolean_t		secondary_side_trigger_support;
 #endif
diff --git a/sr_port/replication_ch.c b/sr_port/replication_ch.c
index e758c1f..c0adfc4 100644
--- a/sr_port/replication_ch.c
+++ b/sr_port/replication_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -22,7 +22,7 @@ GBLREF	bool gv_replication_error;
 
 CONDITION_HANDLER(replication_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	gv_replication_error = TRUE;
 	if (SEVERITY == SEVERE)
 	{
diff --git a/sr_port/rtn_src_chksum.c b/sr_port/rtn_src_chksum.c
new file mode 100644
index 0000000..599b4ec
--- /dev/null
+++ b/sr_port/rtn_src_chksum.c
@@ -0,0 +1,174 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include <sys/mman.h>
+
+#include "copy.h"
+#include "eintr_wrappers.h"
+#include "gtm_string.h"
+#include "io.h"
+#include "gtmio.h"
+#include <rtnhdr.h>
+#include "rtn_src_chksum.h"
+
+error_def(ERR_FILENOTFND);
+
+/****************************************************************/
+
+/*
+ * Initialize MD5 checksum context structure
+ */
+
+void rtn_src_chksum_init(gtm_rtn_src_chksum_ctx *ctx)
+{
+	cvs_MD5Init(&ctx->md5ctx);
+}
+
+/*
+ * Add a data chunk of length len bytes to our checksum.
+ */
+
+void rtn_src_chksum_line(gtm_rtn_src_chksum_ctx *ctx, const void *data, uint4 len)
+{
+	cvs_MD5Update(&ctx->md5ctx, data, len);
+}
+
+/*
+ * Finished computing checksum. Fill in digest[] array from MD5 context.
+ */
+
+void rtn_src_chksum_digest(gtm_rtn_src_chksum_ctx *ctx)
+{
+	cvs_MD5Final(ctx->digest, &ctx->md5ctx);
+#	ifndef GTM_USE_128BIT_SRC_CHKSUM
+	GET_ULONG(ctx->checksum, &ctx->digest[0]);
+#	endif
+}
+
+/*
+ * Copy source code checksum from MD5 context into routine header structure.
+ */
+
+void set_rtnhdr_checksum(rhdtyp *hdr, gtm_rtn_src_chksum_ctx *ctx)
+{
+#	ifdef GTM_USE_128BIT_SRC_CHKSUM
+	memcpy(&hdr->checksum_md5[0], &ctx->digest[0], MD5_DIGEST_LENGTH);
+#	else
+	hdr->checksum = ctx->checksum;
+#	endif
+}
+
+/*
+ * Compute and digest checksum of a single data chunk, specifically a source file.
+ */
+
+void rtn_src_chksum_buffer(gtm_rtn_src_chksum_ctx *ctx, const void *data, uint4 len)
+{
+	rtn_src_chksum_init(ctx);
+	rtn_src_chksum_line(ctx, data, len);
+	rtn_src_chksum_digest(ctx);
+}
+
+/****************************************************************/
+
+#ifdef GTM_USE_128BIT_SRC_CHKSUM
+
+/*
+ * Return start of checksum digest[] array within a routine header structure.
+ */
+
+unsigned char *get_rtnhdr_checksum(rhdtyp *hdr)
+{
+	return &hdr->checksum_md5[0];
+}
+
+/*
+ * Return start of checksum digest[] array within a gtm_rtn_src_chksum_ctx structure.
+ */
+
+unsigned char *get_ctx_checksum(gtm_rtn_src_chksum_ctx *ctx)
+{
+	return &ctx->digest[0];
+}
+
+/*
+ * Are two checksum digests equal?
+ */
+
+boolean_t rtn_src_chksum_match(unsigned char *digest1, unsigned char *digest2)
+{
+	return (0 == memcmp(digest1, digest2, MD5_DIGEST_LENGTH));
+}
+
+#else /* VMS uses 32-bit checksum (... to avoid messing with routine header format). Use first 4 bytes of MD5 checksum */
+
+/*
+ * Return 4-byte checksum within a routine header structure.
+ */
+
+uint4 get_rtnhdr_checksum(rhdtyp *hdr)
+{
+	return hdr->checksum;
+}
+
+/*
+ * Return 4-byte checksum within a gtm_rtn_src_chksum_ctx structure.
+ */
+
+uint4 get_ctx_checksum(gtm_rtn_src_chksum_ctx *ctx)
+{
+	return ctx->checksum;
+}
+
+/*
+ * Are two 4-byte checksums equal?
+ */
+
+boolean_t rtn_src_chksum_match(uint4 checksum1, uint4 checksum2)
+{
+	return (checksum1 == checksum2);
+}
+
+#endif /* GTM_USE_128BIT_SRC_CHKSUM */
+
+/****************************************************************/
+
+/*
+ * Extract checksum from a given routine header, and convert to printable hex form.
+ * Returns length of valid output copied into 'out' buffer.
+ */
+
+int append_checksum(unsigned char *out, rhdtyp *routine)
+{
+	char		buf[MAX_ROUTINE_CHECKSUM_DIGITS];
+	unsigned char	*cptr, *bptr;
+	int		i, len, tlen;
+	rhdtyp		*hdr;
+
+	hdr = CURRENT_RHEAD_ADR(routine);
+#	ifdef GTM_USE_128BIT_SRC_CHKSUM
+	cptr = (unsigned char *)get_rtnhdr_checksum(hdr);
+	bptr = (unsigned char *)buf;
+	len = 0;
+	for (i = 0; i < MD5_DIGEST_LENGTH; i++)
+	{
+		tlen = SPRINTF((char *)bptr, "%02x", cptr[i]);
+		bptr += tlen;
+		len += tlen;
+	}
+#	else
+	len = SPRINTF(buf, "%04x", (uint4)get_rtnhdr_checksum(hdr));
+#	endif
+	memcpy(out, (unsigned char *)buf, len);
+	return len;
+}
diff --git a/sr_port/rtn_src_chksum.h b/sr_port/rtn_src_chksum.h
new file mode 100644
index 0000000..ff02d43
--- /dev/null
+++ b/sr_port/rtn_src_chksum.h
@@ -0,0 +1,61 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#ifndef RTN_SRC_CHKSUM_H_INCLUDED
+#define RTN_SRC_CHKSUM_H_INCLUDED
+
+/*
+ * MD5 checksum context structures differ depending on whether openssl or libgcrypt is used.
+ * If this is not an encryption-enabled platform, we default to a simple four-byte checksum.
+ */
+
+#include "md5hash.h"
+
+#ifdef UNIX
+# define GTM_USE_128BIT_SRC_CHKSUM
+#endif
+
+typedef struct
+{
+	cvs_MD5_CTX	md5ctx;
+	unsigned char	digest[MD5_DIGEST_LENGTH];
+#	ifndef GTM_USE_128BIT_SRC_CHKSUM
+	uint4		checksum;	/* 32-bit checksum, equals first 4 bytes of digest */
+#	endif
+} gtm_rtn_src_chksum_ctx;
+
+#define MAX_ROUTINE_CHECKSUM_DIGITS	33
+
+/*
+ * The following functions compute a running checksum of a routine, one line at a time.
+ */
+
+void rtn_src_chksum_init(gtm_rtn_src_chksum_ctx *ctx);
+void rtn_src_chksum_line(gtm_rtn_src_chksum_ctx *ctx, const void *data, uint4 len);
+void rtn_src_chksum_digest(gtm_rtn_src_chksum_ctx *ctx);
+
+void set_rtnhdr_checksum(rhdtyp *hdr, gtm_rtn_src_chksum_ctx *ctx);
+
+#ifdef GTM_USE_128BIT_SRC_CHKSUM
+unsigned char *get_rtnhdr_checksum(rhdtyp *hdr);
+unsigned char *get_ctx_checksum(gtm_rtn_src_chksum_ctx *ctx);
+boolean_t rtn_src_chksum_match(unsigned char *digest1, unsigned char *digest2);
+#else
+uint4 get_rtnhdr_checksum(rhdtyp *hdr);
+uint4 get_ctx_checksum(gtm_rtn_src_chksum_ctx *ctx);
+boolean_t rtn_src_chksum_match(uint4 checksum1, uint4 checksum2);
+#endif
+
+int append_checksum(unsigned char *out, rhdtyp *routine);
+
+void rtn_src_chksum_buffer(gtm_rtn_src_chksum_ctx *ctx, const void *data, uint4 len);
+
+#endif /* RTN_SRC_CHKSUM_H_INCLUDED */
diff --git a/sr_port/s2n.c b/sr_port/s2n.c
index 688d7e9..21d43ed 100644
--- a/sr_port/s2n.c
+++ b/sr_port/s2n.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,8 +31,7 @@ char *s2n (mval *u)
 
 	SETUP_THREADGBL_ACCESS;
 	i = 0;
-	if (!MV_DEFINED(u))
-		GTMASSERT;
+	assertpro(MV_DEFINED(u));
 	c = u->str.addr;
 	if (0 == u->str.len)
 	{	/* Substitute pre-converted NULL/0 value */
@@ -119,10 +118,12 @@ char *s2n (mval *u)
 	exp = ('E' == *c) && digit;
 	if (exp && ((c + 1) < eos))
 	{
+		w = c;	/* save pointer to return in case expression following E is not a valid exponent */
 		c++;
 		exneg = ('-' == *c);
 		if (exneg || ('+' == *c))
 			c++;
+		d = c;	/* save pointer to see if any progress occurs in the below for loop */
 		for (; (c < eos) && ('0' == *c); c++)
 			;	/* Do not count leading 0s towards MAX_DIGITS_IN_EXP */
 		for (expdigits = 0; (c < eos) && DIGIT(*c); c++)
@@ -133,7 +134,11 @@ char *s2n (mval *u)
 				expdigits++;
 			}
 		}
-		if (exneg)
+		if (!expdigits && (d == c))
+		{
+			c = w;	/* if we did not see any digit following the E (and optional + or -) reset parse to E */
+			assert(0 == x);
+		} else if (exneg)
 			x = -x;
 	}
 	TREF(s2n_intlit) = (0 != sign) || dot || exp;
@@ -162,7 +167,7 @@ char *s2n (mval *u)
 			{
 				u->mvtype &= ~NUM_MASK;
 				if (!TREF(compile_time))
-					rts_error(VARLSTCNT(1) ERR_NUMOFLOW);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NUMOFLOW);
 			} else
 			{
 				u->e = x;
diff --git a/sr_port/s2pool_concat.c b/sr_port/s2pool_concat.c
new file mode 100644
index 0000000..7cbd287
--- /dev/null
+++ b/sr_port/s2pool_concat.c
@@ -0,0 +1,47 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gtm_string.h"
+
+#include "stringpool.h"
+
+void s2pool_concat(mval *dst, mstr *a)
+{
+	int	alen, dstlen;
+	char	*dstaddr;
+
+	if ((alen = a->len) == 0)
+		return;
+	assert(MV_STR == dst->mvtype);
+	dstaddr = dst->str.addr;
+	dstlen = dst->str.len;
+	assert(IS_IN_STRINGPOOL(dstaddr, dstlen));
+	assert(stringpool.free >= stringpool.base);
+	assert(stringpool.free <= stringpool.top);
+	if (IS_AT_END_OF_STRINGPOOL(dstaddr, dstlen))
+	{
+		ENSURE_STP_FREE_SPACE(alen);
+		memcpy(stringpool.free, a->addr, alen);
+		stringpool.free += alen;
+	} else
+	{
+		ENSURE_STP_FREE_SPACE(dstlen + alen);
+		memcpy(stringpool.free, dstaddr, dstlen);
+		memcpy(stringpool.free + dstlen, a->addr, alen);
+		dst->str.addr = (char *)stringpool.free;
+		stringpool.free += dstlen + alen;
+	}
+	dst->str.len += alen;
+	assert(stringpool.free >= stringpool.base);
+	assert(stringpool.free <= stringpool.top);
+}
diff --git a/sr_port/secshr_db_clnup.c b/sr_port/secshr_db_clnup.c
index b1bbf68..ae1613b 100644
--- a/sr_port/secshr_db_clnup.c
+++ b/sr_port/secshr_db_clnup.c
@@ -471,7 +471,7 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					if (csa->timer)
 					{
 						if (-1 < cnl->wcs_timers) /* private flag is optimistic: dont overdo */
-							CAREFUL_DECR_CNT(&cnl->wcs_timers, &cnl->wc_var_lock);
+							PROBE_DECR_CNT(&cnl->wcs_timers, &cnl->wc_var_lock);
 						csa->timer = FALSE;
 					}
 					if (csa->read_write && csa->ref_cnt)
@@ -479,15 +479,15 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 						assert(0 < cnl->ref_cnt);
 						csa->ref_cnt--;
 						assert(!csa->ref_cnt);
-						CAREFUL_DECR_CNT(&cnl->ref_cnt, &cnl->wc_var_lock);
+						PROBE_DECR_CNT(&cnl->ref_cnt, &cnl->wc_var_lock);
 					}
 				}
 				if ((csa->in_wtstart) && (0 < cnl->in_wtstart))
 				{
-					CAREFUL_DECR_CNT(&cnl->in_wtstart, &cnl->wc_var_lock);
+					PROBE_DECR_CNT(&cnl->in_wtstart, &cnl->wc_var_lock);
 					assert(0 < cnl->intent_wtstart);
 					if (0 < cnl->intent_wtstart)
-						CAREFUL_DECR_CNT(&cnl->intent_wtstart, &cnl->wc_var_lock);
+						PROBE_DECR_CNT(&cnl->intent_wtstart, &cnl->wc_var_lock);
 				}
 				csa->in_wtstart = FALSE;	/* Let wcs_wtstart run for exit processing */
 				if (cnl->wcsflu_pid == rundown_process_id)
@@ -669,8 +669,8 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 				assert((T_COMMIT_CRIT_PHASE2 == csa->t_commit_crit) || csa->now_crit);
 				if (T_COMMIT_CRIT_PHASE1 == csa->t_commit_crit)
 				{	/* in PHASE1 so hold crit AND have noted down valid value in csa->prev_free_blks */
-					assert(NORMAL_TERMINATION != secshr_state); /* for normal termination we should not
-										     * have been in the midst of commit */
+					/* for normal termination we should not have been in the midst of commit */
+					assert((NORMAL_TERMINATION != secshr_state) || WBTEST_ENABLED(WBTEST_SLEEP_IN_WCS_WTSTART));
 					assert(csa->now_crit);
 					csd->trans_hist.free_blocks = csa->prev_free_blks;
 				}
@@ -911,8 +911,8 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					 * holding crit at this point.
 					 */
 					set_wc_blocked = TRUE;
-					assert(NORMAL_TERMINATION != secshr_state); /* for normal termination we should not
-										     * have been in the midst of commit */
+					/* for normal termination we should not have been in the midst of commit */
+					assert((NORMAL_TERMINATION != secshr_state) || WBTEST_ENABLED(WBTEST_SLEEP_IN_WCS_WTSTART));
 					if (tp_update_underway)
 					{	/* Since the current cse has not been committed, this is a partial
 						 * GT.M commit in this region even if we have already seen committed cses.
@@ -1543,7 +1543,7 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 						|| (REG_COMMIT_PARTIAL == this_reg_commit_type)
 						|| (REG_COMMIT_UNSTARTED == this_reg_commit_type));
 					/* We have already checked that "si" is READABLE. Check that it is WRITABLE since
-					 * we might need to set "si->kip_csa" in the CAREFUL_INCR_KIP macro.
+					 * we might need to set "si->kip_csa" in the PROBE_INCR_KIP macro.
 					 */
 					if (GTM_PROBE(SIZEOF(sgm_info), si, WRITE))
 					{
@@ -1558,7 +1558,7 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					if (REG_COMMIT_COMPLETE != this_reg_commit_type)
 					{
 						if (kip_csa_usable && (NULL != si->kill_set_head) && (NULL == si->kip_csa))
-							CAREFUL_INCR_KIP(csd, csa, si->kip_csa);
+							PROBE_INCR_KIP(csd, csa, si->kip_csa);
 					} else
 						assert((NULL == si->kill_set_head) || (NULL != si->kip_csa));
 					assert((NULL == si->kill_set_head) || (NULL != si->kip_csa));
@@ -1582,7 +1582,7 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					}
 					if (needkipincr && kip_csa_usable && (NULL == *kip_csa_addrs))
 					{
-						CAREFUL_INCR_KIP(csd, csa, *kip_csa_addrs);
+						PROBE_INCR_KIP(csd, csa, *kip_csa_addrs);
 						*need_kip_incr_addrs = FALSE;
 					}
 #					ifdef UNIX
@@ -1625,8 +1625,8 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					if (kip_csa_usable && (NULL != si->kill_set_head) && (NULL != si->kip_csa))
 					{
 						assert(csa == si->kip_csa);
-						CAREFUL_DECR_KIP(csd, csa, si->kip_csa);
-						CAREFUL_INCR_ABANDONED_KILLS(csd, csa);
+						PROBE_DECR_KIP(csd, csa, si->kip_csa);
+						PROBE_INCR_ABANDONED_KILLS(csd, csa);
 					} else
 						assert((NULL == si->kill_set_head) || (NULL == si->kip_csa));
 				} else if (!dlr_tlevel)
@@ -1638,8 +1638,8 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 					if (kip_csa_usable && (NULL != *kip_csa_addrs) && (csa == *kip_csa_addrs))
 					{
 						assert(0 < (*kip_csa_addrs)->hdr->kill_in_prog);
-						CAREFUL_DECR_KIP(csd, csa, *kip_csa_addrs);
-						CAREFUL_INCR_ABANDONED_KILLS(csd, csa);
+						PROBE_DECR_KIP(csd, csa, *kip_csa_addrs);
+						PROBE_INCR_ABANDONED_KILLS(csd, csa);
 					}
 				}
 			}
@@ -1724,20 +1724,20 @@ void secshr_db_clnup(enum secshr_db_state secshr_state)
 				}
 				UNIX_ONLY(
 					/* cannot send oplog message in VMS as privileged routines cannot do I/O */
-					send_msg(VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_STR(wcblocked_ptr),
+					send_msg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_STR(wcblocked_ptr),
 						rundown_process_id, &csd->trans_hist.curr_tn, DB_LEN_STR(reg));
 				)
 			}
 			csa->wbuf_dqd = 0;		/* We can clear the flag now */
 			if (csa->wcs_pidcnt_incremented)
-				CAREFUL_DECR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl);
+				PROBE_DECR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl);
 			if (csa->now_crit)
 			{
 				if (csd->trans_hist.curr_tn == csd->trans_hist.early_tn - 1)
 				{	/* there can be at most one region in non-TP with different curr_tn and early_tn */
 					assert(!non_tp_update_underway || first_time);
-					assert(NORMAL_TERMINATION != secshr_state); /* for normal termination we should not
-										     * have been in the midst of commit */
+					/* for normal termination we should not have been in the midst of commit */
+					assert((NORMAL_TERMINATION != secshr_state) || WBTEST_ENABLED(WBTEST_SLEEP_IN_WCS_WTSTART));
 					DEBUG_ONLY(first_time = FALSE;)
 					if (update_underway)
 					{
diff --git a/sr_port/sorts_after.c b/sr_port/sorts_after.c
index 962ce9d..6992461 100644
--- a/sr_port/sorts_after.c
+++ b/sr_port/sorts_after.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -45,6 +45,8 @@ long	sorts_after (mval *lhs, mval *rhs)
 	SETUP_THREADGBL_ACCESS;
 	if (!TREF(local_coll_nums_as_strings))
 	{	/* If numbers collate normally (ahead of strings), check if either of the operands is a number */
+		MV_FORCE_DEFINED(lhs);
+		MV_FORCE_DEFINED(rhs);
 		if (MV_IS_CANONICAL(lhs))
 		{	/* lhs is a number */
 			if (MV_IS_CANONICAL(rhs))
diff --git a/sr_port/spec_type.h b/sr_port/spec_type.h
index d6beb17..d58098f 100644
--- a/sr_port/spec_type.h
+++ b/sr_port/spec_type.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,7 +12,8 @@
 #define MAX_SPEC_TYPE_LEN	10
 #define LAST_TYPE_DEFINED	2
 
-#define COLL_SPEC		1
-#define COLL_NCT_OFFSET		1
-#define	COLL_ACT_OFFSET		2
-#define	COLL_VER_OFFSET		3
+#define COLL_SPEC_LEN		4	/* length of the collation record stored in the directory tree per global name */
+#define COLL_SPEC		1	/* first byte of collation record : hardcoded type of 1 */
+#define COLL_NCT_OFFSET		1	/* second byte of collation record : numeric collation for this global name */
+#define	COLL_ACT_OFFSET		2	/* third  byte of collation record : alternative collation for this global name */
+#define	COLL_VER_OFFSET		3	/* fourth byte of collation record : collation library version for this global name */
diff --git a/sr_port/stack_frame.h b/sr_port/stack_frame.h
index 116d226..55c2672 100644
--- a/sr_port/stack_frame.h
+++ b/sr_port/stack_frame.h
@@ -133,6 +133,15 @@ typedef struct stack_frame_struct	/* contents of the GT.M MUMPS stack frame */
 	}							\
 }
 
+/*
+ * Skip past trigger base frames
+ */
+#ifdef GTM_TRIGGER
+# define SKIP_BASE_FRAME(FP) (((NULL != (FP)) && (SFT_TRIGR & (FP)->type)) ? *(stack_frame **)((FP) + 1) : (FP))
+#else
+# define SKIP_BASE_FRAME(FP) (FP)
+#endif
+
 void new_stack_frame(rhdtyp *rtn_base, unsigned char *context, unsigned char *transfer_addr);
 void new_stack_frame_sp(rhdtyp *rtn_base, unsigned char *context, unsigned char *transfer_addr);
 int4 symbinit(void);
diff --git a/sr_port/stp_gcol_ch.c b/sr_port/stp_gcol_ch.c
index 77f931d..539d040 100644
--- a/sr_port/stp_gcol_ch.c
+++ b/sr_port/stp_gcol_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2002, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2002, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -15,14 +15,14 @@
 
 GBLREF boolean_t	expansion_failed, retry_if_expansion_fails;
 
+error_def(ERR_MEMORY);
+error_def(ERR_VMSMEMORY);
+error_def(ERR_MEMORYRECURSIVE);
+
 CONDITION_HANDLER(stp_gcol_ch)
 {
 	/* If we cannot alloc memory while doing a forced expansion, disable all cases of forced expansion henceforth */
-	error_def(ERR_MEMORY);
-	error_def(ERR_VMSMEMORY);
-	error_def(ERR_MEMORYRECURSIVE);
-
-	START_CH;
+	START_CH(TRUE);
 
 	if ((ERR_MEMORY == SIGNAL || ERR_VMSMEMORY == SIGNAL || ERR_MEMORYRECURSIVE == SIGNAL) && retry_if_expansion_fails)
 	{
diff --git a/sr_port/stp_gcol_src.h b/sr_port/stp_gcol_src.h
index c0e817a..b30e47b 100644
--- a/sr_port/stp_gcol_src.h
+++ b/sr_port/stp_gcol_src.h
@@ -538,9 +538,7 @@ void stp_gcol(int space_asked)	/* BYPASSOK */
 		low_reclaim_passes = &indr_stp_low_reclaim_passes;
 		incr_factor = &indr_stp_incr_factor;
 	} else
-	{
-		GTMASSERT; /* neither rts_stringpool, nor indr_stringpool */
-	}
+		assertpro(FALSE && stringpool.base);	/* neither rts_stringpool, nor indr_stringpool */
 	if (NULL == stp_array)
 		stp_array = (mstr **)malloc((stp_array_size = STP_MAXITEMS) * SIZEOF(mstr *));
 	topstr = array = stp_array;
@@ -626,6 +624,7 @@ void stp_gcol(int space_asked)	/* BYPASSOK */
 			for (xnewvar = symtab->xnew_var_list; xnewvar; xnewvar = xnewvar->next)
 				MSTR_STPG_ADD(&xnewvar->key.var_name);
 		}
+#		ifdef VMS
 		if (NULL != (TREF(rt_name_tbl)).base)
 		{	/* Keys for $TEXT source hash table can live in stringpool */
 			for (tabent_mname = (TREF(rt_name_tbl)).base, topent_mname = (TREF(rt_name_tbl)).top;
@@ -633,6 +632,7 @@ void stp_gcol(int space_asked)	/* BYPASSOK */
 				if (HTENT_VALID_MNAME(tabent_mname, routine_source, rsptr))
 					MSTR_STPG_ADD(&tabent_mname->key.var_name);
 		}
+#		endif
 		if (x = comline_base)
 			for (index = MAX_RECALL; index > 0 && x->len; index--, x++)
 			{	/* These strings are guaranteed to be in the stringpool so use MSTR_STPG_PUT macro directly
@@ -776,7 +776,7 @@ void stp_gcol(int space_asked)	/* BYPASSOK */
 					ZWRHTAB_GC(mvs->mv_st_cont.mvs_mrgzwrsv.save_zwrhtab);
 					continue;
 				default:
-					GTMASSERT;
+					assertpro(FALSE && mvs->mv_st_type);
 			}
 			MVAL_STPG_ADD(m);
 		}
diff --git a/sr_port/str2gvkey_nogvfunc.c b/sr_port/str2gvkey_nogvfunc.c
index 5d0cdab..cbcc6b6 100644
--- a/sr_port/str2gvkey_nogvfunc.c
+++ b/sr_port/str2gvkey_nogvfunc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2002 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2002, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,6 +21,15 @@
 #include "subscript.h"
 #include "str2gvargs.h"
 #include "str2gvkey.h"
+#include "collseq.h"
+
+#ifdef UNIX
+GBLREF  repl_conn_info_t        *this_side;
+#endif
+
+#ifdef VMS
+GBLREF	gd_region	*gv_cur_region;
+#endif
 
 void str2gvkey_nogvfunc(char *cp, int len, gv_key *key)
 { /* We have two functions str2gvkey_gvfunc and str2gvkey_nogvfunc instead of passing a boolean argument to say a common  */
@@ -32,14 +41,18 @@ void str2gvkey_nogvfunc(char *cp, int len, gv_key *key)
 	int		subsc;
 
 	naked = str2gvargs(cp, len, &op_gvargs);
-	if (naked)
-		GTMASSERT; /* 'cos this function does not handle nakeds correctly */
+	assertpro(!naked);	/* because this function does not handle nakeds correctly */
 	key->end = op_gvargs.args[0]->str.len;
 	memcpy(key->base, op_gvargs.args[0]->str.addr, key->end);
 	key->base[key->end] = 0;
 	key->end++;
 	key->prev = 0;
+	/* Since this function is called from the source and/or receiver server for now and since both of them ensure
+	 * all regions have the same std_null_coll value and since "this_side" holds this information (for Unix) we
+	 * use this to determine the std_null_coll setting to use for mval2subsc. In VMS, we use a hardcoded value.
+	 */
 	for (subsc = 1; subsc < op_gvargs.count; subsc++)
-		mval2subsc(op_gvargs.args[subsc], key);
+		mval2subsc(op_gvargs.args[subsc], key, UNIX_ONLY(this_side->is_std_null_coll)
+				VMS_ONLY((NULL != gv_cur_region ? gv_cur_region->std_null_coll : STD_NULL_COLL_FALSE)));
 	return;
 }
diff --git a/sr_port/stringpool.h b/sr_port/stringpool.h
index 7c8456d..bf2361d 100644
--- a/sr_port/stringpool.h
+++ b/sr_port/stringpool.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,6 +20,7 @@ void	stp_move(char *from, char *to);
 void	stp_init(unsigned int size);
 void	s2pool(mstr *a);
 void	s2pool_align(mstr *string);
+void	s2pool_concat(mval *dst, mstr *a);	/* concatenates strings "dst->str" + "a" and stores result in "dst->str" */
 
 #ifdef DEBUG
 void		stp_vfy_mval(void);
@@ -37,6 +38,7 @@ GBLREF	spdesc		stringpool;
 #define	IS_STP_SPACE_AVAILABLE_PRO(SPC)	((stringpool.free + SPC) <= stringpool.top)
 #define	IS_IN_STRINGPOOL(PTR, LEN)		\
 		((((unsigned char *)PTR + (int)(LEN)) <= stringpool.top) && ((unsigned char *)PTR >= stringpool.base))
+#define	IS_AT_END_OF_STRINGPOOL(PTR, LEN)		(((unsigned char *)PTR + (int)(LEN)) == stringpool.free)
 #define	INVOKE_STP_GCOL(SPC)		stp_gcol(SPC);								/* BYPASSOK */
 
 #ifdef DEBUG
diff --git a/sr_port/svnames.h b/sr_port/svnames.h
index b72d179..0cf5e56 100644
--- a/sr_port/svnames.h
+++ b/sr_port/svnames.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -79,6 +79,8 @@ enum
 	SV_ZTSLATE,		/* 65 */
 	SV_ZTNAME,		/* 66 */
 	SV_ZONLNRLBK,		/* 67 */
+	SV_ZCLOSE,		/* 68 */
+	SV_ZKEY,		/* 69 */
 	SV_NUM_SV,		/* count - should be next to last SV entry just prior to dummy entry below */
 	SV_DUMMY_TO_FORCE_INT = 0x0FFFFFFF	/* to ensure an int on S390 */
 };
diff --git a/sr_port/t_ch.c b/sr_port/t_ch.c
index fccc06d..88cd928 100644
--- a/sr_port/t_ch.c
+++ b/sr_port/t_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -47,14 +47,22 @@ CONDITION_HANDLER(t_ch)
 {
 	boolean_t	retvalue;
 
-	START_CH;
+	/* We dont know how it is possible to have a success or info type severity message show up while we are in
+	 * the middle of a transaction commit. In any case, return right away instead of invoking t_commit_cleanup.
+	 * The issue with invoking that is that it would complete the transaction and release crit but the NEXTCH
+	 * call at the end of this condition handler would invoke the next level condition handler which could
+	 * decide the message is innocuous and therefore decide to return control to where the error was signalled
+	 * in the first place (in the midst of database commit) which can cause database damage since we no longer
+	 * hold crit.
+	 */
+	START_CH(TRUE);
 	UNIX_ONLY(
 		/* To get as virgin a state as possible in the core, take the core now if we
 		 * would be doing so anyway. This will set created_core so it doesn't happen again.
 		 */
 		if (DUMPABLE)
 		{	/* this is most likely a fatal error, therefore print the error right here as we do not know if
-			 * the send_msg() call in t_commit_cleanup() done below might overlay this primary fatal error.
+			 * the send_msg_csa() call in t_commit_cleanup() done below might overlay this primary fatal error.
 			 */
 			PRN_ERROR;
 			if (!SUPPRESS_DUMP)
@@ -64,18 +72,14 @@ CONDITION_HANDLER(t_ch)
 			}
 		}
 	)
-	if ((SUCCESS == SEVERITY) || (INFO == SEVERITY))
-	{	/* We dont know how it is possible to have a success or info type severity message show up while we are in
-		 * the middle of a transaction commit. In any case, return right away instead of invoking t_commit_cleanup.
-		 * The issue with invoking that is that it would complete the transaction and release crit but the NEXTCH
-		 * call at the end of this condition handler would invoke the next level condition handler which could
-		 * decide the message is innocuous and therefore decide to return control to where the error was signalled
-		 * in the first place (in the midst of database commit) which can cause database damage since we no longer
-		 * hold crit.
-		 */
-		assert(FALSE);
-		CONTINUE;
-	}
+	VMS_ONLY (
+		if ((SUCCESS == SEVERITY) || (INFO == SEVERITY))
+		{
+			assert(FALSE);
+			CONTINUE;
+		}
+	)
+	ENABLE_AST;
 	ENABLE_AST;
 	/* Reset jgbl.dont_reset_gbl_jrec_time to FALSE if already set by tp_tend and we come here due to an rts_error in wcs_flu.
 	 * However, if it was forward recovery that ended up invoking tp_tend, then we should not reset the variable to FALSE as
diff --git a/sr_port/t_end.c b/sr_port/t_end.c
index abc5b51..874e349 100644
--- a/sr_port/t_end.c
+++ b/sr_port/t_end.c
@@ -168,21 +168,7 @@ error_def(ERR_TEXT);
 	}												\
 }
 
-/* This macro isn't enclosed in parantheses to allow for optimizations */
-#define VALIDATE_CYCLE(is_mm, history)					\
-if (history)								\
-{									\
-	for (t1 = history->h;  t1->blk_num;  t1++)			\
-	{								\
-		if (!is_mm && (t1->cr->cycle != t1->cycle))		\
-		{	/* cache slot has been stolen */		\
-			assert(!csa->now_crit || csa->hold_onto_crit);	\
-			status = cdb_sc_cyclefail;			\
-			goto failed_skip_revert;			\
-		}							\
-		n_blks_validated++;					\
-	}								\
-}
+#define EACH_HIST(HIST, HIST1, HIST2)	(HIST = HIST1;  (NULL != HIST);  HIST = (HIST == HIST1) ? HIST2 : NULL)
 
 #define	BUSY2FREE	0x00000001
 #define	RECYCLED2FREE	0x00000002
@@ -247,6 +233,7 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 	int			n_blks_validated;
 	boolean_t		before_image_needed, lcl_ss_in_prog = FALSE, reorg_ss_in_prog = FALSE;
 	boolean_t		ss_need_to_restart, new_bkup_started;
+	boolean_t		same_db_state;
 	gv_namehead		*gvnh;
 #	ifdef GTM_TRIGGER
 	uint4			cycle;
@@ -301,63 +288,95 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 	assert(0 == cr_array_index);
 	assert(!gv_cur_region->read_only || !update_trans);
 	cr_array_index = 0;	/* be safe and reset it in PRO even if it is not zero */
+	/* If inctn_opcode has a valid value, then we better be doing an update. The only exception to this rule is if we are
+	 * in MUPIP REORG UPGRADE/DOWNGRADE (mu_reorg_upgrd_dwngrd.c) where update_trans is explicitly set to 0 in some cases.
+	 */
+	assert((inctn_invalid_op == inctn_opcode) || mu_reorg_upgrd_dwngrd_in_prog || update_trans);
+	assert(!need_kip_incr || update_trans UNIX_ONLY(|| TREF(in_gvcst_redo_root_search)));
 	if (cnl->wc_blocked || (is_mm && (csa->total_blks != csa->ti->total_blks)))
 	{	/* If blocked, or we have MM and file has been extended, force repair */
 		status = cdb_sc_helpedout;	/* force retry with special status so philanthropy isn't punished */
 		assert((CDB_STAGNATE > t_tries) || !is_mm || (csa->total_blks == csa->ti->total_blks));
 		goto failed_skip_revert;
-	} else
-	{
-		/* See if we can take a fast path for read transactions based on the following conditions :
-		 * 1. If the transaction number hasn't changed since we read the blocks from the disk or cache
-		 * 2. If NO concurrent online rollback is running. This is needed because we don't want read transactions
-		 *    to succeed. The issue with this check is that for a rollback that was killed, the PID will be non-zero.
-		 *    In that case, we might skip the fast path and go ahead and do the validation. The validation logic
-		 *    gets crit anyways and so will salvage the lock and do the necessary recovery and issue DBFLCORRP if
-		 *    it notices that csd->file_corrupt is TRUE.
+	}
+	if (!update_trans)
+	{	/* Take a fast path for read transactions. We do not need crit; we simply need to verify our blocks have not been
+		 * modified since we read them. The read is valid if neither the cycles nor the tns have changed. Otherwise restart.
+		 * Note: if, as with updates, we validated via bt_get/db_csh_get, we would restart under the same conditions.
 		 */
-		if (!update_trans && (start_tn == csa->ti->early_tn) UNIX_ONLY(&& (0 == csa->nl->onln_rlbk_pid)))
-		{	/* read with no change to the transaction history */
-			n_blks_validated = 0;
-			VALIDATE_CYCLE(is_mm, hist1);	/* updates n_blks_validated */
-			VALIDATE_CYCLE(is_mm, hist2);	/* updates n_blks_validated */
-			assert(cdb_sc_normal == status);
-#			ifdef UNIX
-			if (MISMATCH_ROOT_CYCLES(csa, cnl))
-			{	/* If a root block has moved, we might have started the read from the wrong root block, in which
-				 * case we cannot trust the entire search. Need to redo root search.
-				 */
-				was_crit = csa->now_crit;
-				if (!was_crit)
-					grab_crit(gv_cur_region);
-				status = cdb_sc_gvtrootmod2;
-				if (MISMATCH_ONLN_RLBK_CYCLES(csa, cnl))
-				{
-					assert(!mupip_jnl_recover);
-					status = ONLN_RLBK_STATUS(csa, cnl);
-					SYNC_ONLN_RLBK_CYCLES;
-					SYNC_ROOT_CYCLES(NULL);
-				} else
-					SYNC_ROOT_CYCLES(csa);
-				if (!was_crit && !csa->hold_onto_crit)
-					rel_crit(gv_cur_region);
-				goto failed_skip_revert;
+		SHM_READ_MEMORY_BARRIER;
+		same_db_state = (start_tn == csa->ti->early_tn);
+		n_blks_validated = 0;
+		for EACH_HIST(hist, hist1, hist2)
+		{
+			for (t1 = hist->h;  t1->blk_num;  t1++)
+			{	/* Validate block tn */
+				if (!same_db_state && TP_IS_CDB_SC_BLKMOD(t1->cr, t1))
+				{	/* block has been modified */
+					status = cdb_sc_blkmod;
+					goto failed_skip_revert;
+				}
+				/* Validate buffer cycle */
+				if (!is_mm && (t1->cr->cycle != t1->cycle))
+				{	/* cache slot has been stolen */
+					assert(!csa->now_crit);
+					status = cdb_sc_cyclefail;
+					goto failed_skip_revert;
+				}
+				n_blks_validated++; /* update n_blks_validated */
 			}
-#			endif
-			/* Assert that if gtm_gvundef_fatal is non-zero, then we better not be about to signal a GVUNDEF */
-			assert(!TREF(gtm_gvundef_fatal) || !ready2signal_gvundef_lcl);
-			if (csa->now_crit && !csa->hold_onto_crit)
+		}
+		assert(cdb_sc_normal == status);
+#		ifdef UNIX
+		if ((0 != csa->nl->onln_rlbk_pid) && (process_id != csa->nl->onln_rlbk_pid))
+		{	/* We don't want read transactions to succeed if a concurrent online rollback is running. Following
+			 * grab_crit, we know none is running because grab_crit either waits for online rollback to complete, or
+			 * salvages crit from a KILL -9'd online rollback. In the former case, we restart because of
+			 * MISMATCH_ONLN_RLBK_CYCLES. In the latter case, grab_crit does the necessary recovery and issues
+			 * DBFLCORRP if it notices that csd->file_corrupt is TRUE. Otherwise online rollback did not take the
+			 * database to a state back in time, and we can complete the read.
+			 */
+			assert(!csa->now_crit);
+			grab_crit(gv_cur_region);
+			rel_crit(gv_cur_region);
+		}
+		if (MISMATCH_ROOT_CYCLES(csa, cnl))
+		{	/* If a root block has moved, we might have started the read from the wrong root block, in which
+			 * case we cannot trust the entire search. Need to redo root search.
+			 * If an online rollback concurrently finished, we will come into this "if" block and restart.
+			 */
+			was_crit = csa->now_crit;
+			if (!was_crit)
+				grab_crit(gv_cur_region);
+			status = cdb_sc_gvtrootmod2;
+			if (MISMATCH_ONLN_RLBK_CYCLES(csa, cnl))
+			{
+				assert(!mupip_jnl_recover);
+				status = ONLN_RLBK_STATUS(csa, cnl);
+				SYNC_ONLN_RLBK_CYCLES;
+				SYNC_ROOT_CYCLES(NULL);
+			} else
+				SYNC_ROOT_CYCLES(csa);
+			if (!was_crit)
 				rel_crit(gv_cur_region);
-			if (unhandled_stale_timer_pop)
-				process_deferred_stale();
-			CWS_RESET;
-			assert(!csa->now_crit || csa->hold_onto_crit); /* shouldn't hold crit unless asked to */
-			t_tries = 0;	/* commit was successful so reset t_tries */
-			INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_readonly, 1);
-			INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkread, n_blks_validated);
-			return csa->ti->curr_tn;
+			goto failed_skip_revert;
 		}
+#		endif
+		/* Assert that if gtm_gvundef_fatal is non-zero, then we better not be about to signal a GVUNDEF */
+		assert(!TREF(gtm_gvundef_fatal) || !ready2signal_gvundef_lcl);
+		assert(!TREF(donot_commit));    /* We should never commit a transaction that was determined restartable */
+		if (csa->now_crit && !csa->hold_onto_crit)
+			rel_crit(gv_cur_region);
+		if (unhandled_stale_timer_pop)
+			process_deferred_stale();
+		CWS_RESET;
+		assert(!csa->now_crit || csa->hold_onto_crit); /* shouldn't hold crit unless asked to */
+		t_tries = 0;	/* commit was successful so reset t_tries */
+		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_readonly, 1);
+		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkread, n_blks_validated);
+		return csa->ti->curr_tn;
 	}
+	assert(update_trans);
 	assert((gds_t_committed < gds_t_busy2free)	&& (n_gds_t_op > gds_t_busy2free));
 	assert((gds_t_committed < gds_t_recycled2free)	&& (n_gds_t_op > gds_t_recycled2free));
 	assert((gds_t_committed < gds_t_write_root)	&& (n_gds_t_op > gds_t_write_root));
@@ -392,7 +411,7 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 		}
 	}
 #	ifdef GTM_SNAPSHOT
-	if (update_trans && SNAPSHOTS_IN_PROG(cnl))
+	if (SNAPSHOTS_IN_PROG(cnl))
 	{
 		/* If snapshot context is not already created, then create one now to be used by this transaction. If context
 		 * creation failed (for instance, on snapshot file open fail), then SS_INIT_IF_NEEDED sets csa->snapshot_in_prog
@@ -412,7 +431,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 									  * REORG are in progress */
 #		endif
 		assert(SIZEOF(bsiz) == SIZEOF(old_block->bsiz));
-		assert(update_trans);
 		csa->backup_in_prog = (BACKUP_NOT_IN_PROGRESS != cnl->nbb);
 		jbbp = (JNL_ENABLED(csa) && csa->jnl_before_image) ? csa->jnl->jnl_buff : NULL;
 		read_before_image = ((NULL != jbbp) || csa->backup_in_prog || lcl_ss_in_prog);
@@ -448,7 +466,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 					}
 					goto failed_skip_revert;
 				}
-				assert(!is_mm || (cs->blk < csa->total_blks));
 				assert((CDB_STAGNATE > t_tries) || (cs->blk < csa->ti->total_blks));
 				blk_used ? BIT_SET_RECYCLED_AND_CLEAR_FREE(cs->blk_prior_state)
 					 : BIT_CLEAR_RECYCLED_AND_SET_FREE(cs->blk_prior_state);
@@ -518,7 +535,7 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 			}
 		}
 	}
-	if (update_trans && JNL_ENABLED(csa))
+	if (JNL_ENABLED(csa))
 	{	/* compute the total journal record size requirements before grab_crit.
 		 * there is code later that will check for state changes from now to then and if so do a recomputation
 		 */
@@ -550,27 +567,24 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 	assert(!csa->hold_onto_crit || csa->now_crit);
 	if (!csa->now_crit)
 	{
-		if (update_trans)
-		{	/* Get more space if needed. This is done outside crit so that
-			 * any necessary IO has a chance of occurring outside crit.
-			 * The available space must be double-checked inside crit. */
-			if (!is_mm && !WCS_GET_SPACE(gv_cur_region, cw_set_depth + 1, NULL))
-				assert(FALSE);	/* wcs_get_space should have returned TRUE unconditionally in this case */
-			for (;;)
-			{
-				grab_crit(gv_cur_region);
-				if (FALSE == csd->freeze)
-					break;
-				rel_crit(gv_cur_region);
-				/* We are about to wait for freeze. Assert that we are not in phase2 of a bitmap free operation
-				 * (part of an M-kill or REORG operation). The freeze must have waited for the phase2 to complete.
-				 */
-				assert((inctn_bmp_mark_free_gtm != inctn_opcode) && (inctn_bmp_mark_free_mu_reorg != inctn_opcode));
-				while (csd->freeze)
-					hiber_start(1000);
-			}
-		} else
+		/* Get more space if needed. This is done outside crit so that
+		 * any necessary IO has a chance of occurring outside crit.
+		 * The available space must be double-checked inside crit. */
+		if (!is_mm && !WCS_GET_SPACE(gv_cur_region, cw_set_depth + 1, NULL))
+			assert(FALSE);	/* wcs_get_space should have returned TRUE unconditionally in this case */
+		for (;;)
+		{
 			grab_crit(gv_cur_region);
+			if (FALSE == csd->freeze)
+				break;
+			rel_crit(gv_cur_region);
+			/* We are about to wait for freeze. Assert that we are not in phase2 of a bitmap free operation
+			 * (part of an M-kill or REORG operation). The freeze must have waited for the phase2 to complete.
+			 */
+			assert((inctn_bmp_mark_free_gtm != inctn_opcode) && (inctn_bmp_mark_free_mu_reorg != inctn_opcode));
+			while (csd->freeze)
+				hiber_start(1000);
+		}
 	} else
 	{	/* We expect the process to be in its final retry as it is holding crit. The only exception is if hold_onto_crit
 		 * is TRUE but in that case we dont expect csd->freeze to be TRUE so we dont care much about that case. The other
@@ -578,7 +592,7 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 		 * about whether we are about to update a frozen db. DSE is the only utility allowed to update frozen databases.
 		 */
 		assert((CDB_STAGNATE == t_tries) || csa->hold_onto_crit || IS_DSE_IMAGE);
-		if (csd->freeze && update_trans && !IS_DSE_IMAGE)
+		if (csd->freeze && !IS_DSE_IMAGE)
 		{	/* We are about to update a frozen database. This is possible in rare cases even though
 			 * we waited for the freeze to be lifted in t_retry (see GTM-7004). Restart in this case.
 			 */
@@ -588,7 +602,7 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 	}
 	com_csum = 0;
 	/* We should never proceed to update a frozen database. Only exception is DSE */
-	assert(!update_trans || !csd->freeze || IS_DSE_IMAGE);
+	assert(!csd->freeze || IS_DSE_IMAGE);
 #	ifdef UNIX
 	/* We never expect to come here with file_corrupt set to TRUE (in case of an online rollback) because
 	 * grab_crit done above will make sure of that. The only exception is RECOVER/ROLLBACK itself coming
@@ -624,7 +638,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
                 status = cdb_sc_helpedout;      /* force retry with special status so philanthropy isn't punished */
                 goto failed;
         }
-	assert(!cw_depth || update_trans);
 #	ifdef GTM_TRIGGER
 	if (!skip_dbtriggers)
 	{
@@ -650,116 +663,104 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 		}
 	}
 #	endif
-	/* If inctn_opcode has a valid value, then we better be doing an update. The only exception to this rule is if we are
-	 * in MUPIP REORG UPGRADE/DOWNGRADE (mu_reorg_upgrd_dwngrd.c) where update_trans is explicitly set to 0 in some cases.
-	 */
-	assert((inctn_invalid_op == inctn_opcode) || mu_reorg_upgrd_dwngrd_in_prog || update_trans);
-	if (update_trans)
+	if (JNL_ALLOWED(csa))
 	{
-		if (JNL_ALLOWED(csa))
-		{
-			if ((csa->jnl_state != csd->jnl_state) || (csa->jnl_before_image != csd->jnl_before_image))
-			{ 	/* csd->jnl_state or csd->jnl_before_image changed since last time
-				 * 	csa->jnl_before_image and csa->jnl_state got set */
-				csa->jnl_before_image = csd->jnl_before_image;
-				csa->jnl_state = csd->jnl_state;
-				/* jnl_file_lost causes a jnl_state transition from jnl_open to jnl_closed
-				 * and additionally causes a repl_state transition from repl_open to repl_closed
-				 * all without standalone access. This means that csa->repl_state might be repl_open
-				 * while csd->repl_state might be repl_closed. update csa->repl_state in this case
-				 * as otherwise the rest of the code might look at csa->repl_state and incorrectly
-				 * conclude replication is on and generate sequence numbers when actually no journal
-				 * records are being generated. [C9D01-002219]
-				 */
-				csa->repl_state = csd->repl_state;
-				status = cdb_sc_jnlstatemod;
-				goto failed;
-			}
-		}
-		/* Flag retry, if other mupip activities like BACKUP, INTEG or FREEZE are in progress.
-		 * If in final retry, go ahead with kill. BACKUP/INTEG/FREEZE will wait for us to be done.
-		 */
-		if (need_kip_incr && (0 < cnl->inhibit_kills) && (CDB_STAGNATE > t_tries))
-		{
-			status = cdb_sc_inhibitkills;
+		if ((csa->jnl_state != csd->jnl_state) || (csa->jnl_before_image != csd->jnl_before_image))
+		{ 	/* csd->jnl_state or csd->jnl_before_image changed since last time
+			 * 	csa->jnl_before_image and csa->jnl_state got set */
+			csa->jnl_before_image = csd->jnl_before_image;
+			csa->jnl_state = csd->jnl_state;
+			/* jnl_file_lost causes a jnl_state transition from jnl_open to jnl_closed
+			 * and additionally causes a repl_state transition from repl_open to repl_closed
+			 * all without standalone access. This means that csa->repl_state might be repl_open
+			 * while csd->repl_state might be repl_closed. update csa->repl_state in this case
+			 * as otherwise the rest of the code might look at csa->repl_state and incorrectly
+			 * conclude replication is on and generate sequence numbers when actually no journal
+			 * records are being generated. [C9D01-002219]
+			 */
+			csa->repl_state = csd->repl_state;
+			status = cdb_sc_jnlstatemod;
 			goto failed;
 		}
-		ss_need_to_restart = new_bkup_started = FALSE;
-		GTM_SNAPSHOT_ONLY(
-			if (update_trans)
-				CHK_AND_UPDATE_SNAPSHOT_STATE_IF_NEEDED(csa, cnl, ss_need_to_restart);
-		)
-		if (cw_depth)
+	}
+	/* Flag retry, if other mupip activities like BACKUP, INTEG or FREEZE are in progress.
+	 * If in final retry, go ahead with kill. BACKUP/INTEG/FREEZE will wait for us to be done.
+	 */
+	if (need_kip_incr && (0 < cnl->inhibit_kills) && (CDB_STAGNATE > t_tries))
+	{
+		status = cdb_sc_inhibitkills;
+		goto failed;
+	}
+	ss_need_to_restart = new_bkup_started = FALSE;
+	GTM_SNAPSHOT_ONLY(CHK_AND_UPDATE_SNAPSHOT_STATE_IF_NEEDED(csa, cnl, ss_need_to_restart));
+	if (cw_depth)
+	{
+		CHK_AND_UPDATE_BKUP_STATE_IF_NEEDED(cnl, csa, new_bkup_started);
+		/* recalculate based on the new values of snapshot_in_prog and backup_in_prog. Since read_before_image used
+		 * only in the context of acquired blocks, recalculation should happen only for non-zero cw_depth
+		 */
+		read_before_image = ((JNL_ENABLED(csa) && csa->jnl_before_image)
+				     || csa->backup_in_prog
+				     || SNAPSHOTS_IN_PROG(csa));
+	}
+	if ((cw_depth && new_bkup_started) || ss_need_to_restart)
+	{
+		if (ss_need_to_restart || (new_bkup_started && !(JNL_ENABLED(csa) && csa->jnl_before_image)))
 		{
-			assert(update_trans);
-			CHK_AND_UPDATE_BKUP_STATE_IF_NEEDED(cnl, csa, new_bkup_started);
-			/* recalculate based on the new values of snapshot_in_prog and backup_in_prog. Since read_before_image used
-			 * only in the context of acquired blocks, recalculation should happen only for non-zero cw_depth
+			/* If online backup is in progress now and before-image journaling is not enabled,
+			 * we would not have read before-images for created blocks. Although it is possible
+			 * that this transaction might not have blocks with gds_t_create at all, we expect
+			 * this backup_in_prog state change to be so rare that it is ok to restart.
 			 */
-			read_before_image = ((JNL_ENABLED(csa) && csa->jnl_before_image)
-					     || csa->backup_in_prog
-					     || SNAPSHOTS_IN_PROG(csa));
-		}
-		if ((cw_depth && new_bkup_started) || (update_trans && ss_need_to_restart))
-		{
-			if (ss_need_to_restart || (new_bkup_started && !(JNL_ENABLED(csa) && csa->jnl_before_image)))
-			{
-				/* If online backup is in progress now and before-image journaling is not enabled,
-				 * we would not have read before-images for created blocks. Although it is possible
-				 * that this transaction might not have blocks with gds_t_create at all, we expect
-				 * this backup_in_prog state change to be so rare that it is ok to restart.
-				 */
-				status = cdb_sc_bkupss_statemod;
-				goto failed;
-			}
-		}
-		/* in crit, ensure cache-space is available. the out-of-crit check done above might not have been enough */
-		if (!is_mm && !WCS_GET_SPACE(gv_cur_region, cw_set_depth + 1, NULL))
-		{
-			assert(cnl->wc_blocked);	/* only reason we currently know why wcs_get_space could fail */
-			assert(gtm_white_box_test_case_enabled);
-			SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
-			BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_hist);
-			SET_CACHE_FAIL_STATUS(status, csd);
+			status = cdb_sc_bkupss_statemod;
 			goto failed;
 		}
-		if (inctn_invalid_op != inctn_opcode)
-		{
-			assert(cw_set_depth || mu_reorg_process);
-			write_inctn = TRUE;	/* mupip reorg or gvcst_bmp_mark_free or extra block split in gvcstput */
-			decremented_currtn = FALSE;
-			if (jgbl.forw_phase_recovery && !JNL_ENABLED(csa))
-			{	/* forward recovery (deduced above from the fact that journaling is not enabled) is supposed
-				 * to accurately simulate GT.M runtime activity for every transaction number. The way it does
-				 * this is by incrementing transaction numbers for all inctn records that GT.M wrote and not
-				 * incrementing transaction number for any inctn activity that forward recovery internally needs
-				 * to do. all inctn activity done outside of t_end has already been protected against incrementing
-				 * transaction number in case of forward recovery. t_end is a little bit tricky since in this case
-				 * a few database blocks get modified with the current transaction number and not incrementing the
-				 * transaction number might result in the database transaction number being lesser than the block
-				 * transaction number. we work around this problem by decrementing the database transaction number
-				 * just before the commit so the database block updates for the inctn transaction get the
-				 * transaction number of the previous transaction effectively merging the inctn transaction with
-				 * the previous transaction.
-				 */
-				/* cw_set_depth is 1 for all INCTN operations except for block free operations when it can be 2 */
-				assert((inctn_gvcstput_extra_blk_split == inctn_opcode)
-					|| (inctn_bmp_mark_free_gtm == inctn_opcode)
-					|| (inctn_bmp_mark_free_mu_reorg == inctn_opcode) || (1 == cw_set_depth));
-				csa->ti->curr_tn--;
-				csa->ti->early_tn--;
-				decremented_currtn = TRUE;
-			}
+	}
+	/* in crit, ensure cache-space is available. the out-of-crit check done above might not have been enough */
+	if (!is_mm && !WCS_GET_SPACE(gv_cur_region, cw_set_depth + 1, NULL))
+	{
+		assert(cnl->wc_blocked);	/* only reason we currently know why wcs_get_space could fail */
+		assert(gtm_white_box_test_case_enabled);
+		SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
+		BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_hist);
+		SET_CACHE_FAIL_STATUS(status, csd);
+		goto failed;
+	}
+	if (inctn_invalid_op != inctn_opcode)
+	{
+		assert(cw_set_depth || mu_reorg_process);
+		write_inctn = TRUE;	/* mupip reorg or gvcst_bmp_mark_free or extra block split in gvcstput */
+		decremented_currtn = FALSE;
+		if (jgbl.forw_phase_recovery && !JNL_ENABLED(csa))
+		{	/* forward recovery (deduced above from the fact that journaling is not enabled) is supposed
+			 * to accurately simulate GT.M runtime activity for every transaction number. The way it does
+			 * this is by incrementing transaction numbers for all inctn records that GT.M wrote and not
+			 * incrementing transaction number for any inctn activity that forward recovery internally needs
+			 * to do. all inctn activity done outside of t_end has already been protected against incrementing
+			 * transaction number in case of forward recovery. t_end is a little bit tricky since in this case
+			 * a few database blocks get modified with the current transaction number and not incrementing the
+			 * transaction number might result in the database transaction number being lesser than the block
+			 * transaction number. we work around this problem by decrementing the database transaction number
+			 * just before the commit so the database block updates for the inctn transaction get the
+			 * transaction number of the previous transaction effectively merging the inctn transaction with
+			 * the previous transaction.
+			 */
+			/* cw_set_depth is 1 for all INCTN operations except for block free operations when it can be 2 */
+			assert((inctn_gvcstput_extra_blk_split == inctn_opcode)
+				|| (inctn_bmp_mark_free_gtm == inctn_opcode)
+				|| (inctn_bmp_mark_free_mu_reorg == inctn_opcode) || (1 == cw_set_depth));
+			csa->ti->curr_tn--;
+			csa->ti->early_tn--;
+			decremented_currtn = TRUE;
 		}
 	}
 	assert(csd == csa->hdr);
 	valid_thru = dbtn = csa->ti->curr_tn;
 	if (!is_mm)
 		oldest_hist_tn = OLDEST_HIST_TN(csa);
-	if (update_trans)
-		valid_thru++;
+	valid_thru++;
 	n_blks_validated = 0;
-	for (hist = hist1;  (NULL != hist);  hist = (hist == hist1) ? hist2 : NULL)
+	for EACH_HIST(hist, hist1, hist2)
 	{
 		for (t1 = hist->h;  t1->blk_num;  t1++)
 		{
@@ -873,7 +874,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 				{
 					if (n_gds_t_op > cs->mode)
 					{
-						assert(update_trans);
 						PIN_CACHE_RECORD(cr, cr_array, cr_array_index);
 						/* If cs->mode is gds_t_busy2free, then the corresponding cache-record needs
 						 * to be pinned to write the before-image right away but this cse is not going
@@ -1013,631 +1013,626 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 		}
 	}
 	assert(csd == csa->hdr);
-	assert(!need_kip_incr || update_trans UNIX_ONLY(|| TREF(in_gvcst_redo_root_search)));
-	/* At this point if the transaction has no updates, we are done with validation (all possibilities of "goto failed")
-	 * and so we need to assert that donot_commit better be set to FALSE at this point. For transaction with updates,
-	 * there are a few more "goto failed" usages below so we will do this check separately after those usages.
-	 */
-	assert(update_trans || !TREF(donot_commit));	/* We should never commit a transaction that was determined restartable */
-	if (update_trans)
+	if (cw_depth && read_before_image && !is_mm)
 	{
-		if (cw_depth && read_before_image && !is_mm)
-		{
-			assert(!(JNL_ENABLED(csa) && csa->jnl_before_image) || jbbp == csa->jnl->jnl_buff);
-			assert((JNL_ENABLED(csa) && csa->jnl_before_image) || (NULL == jbbp));
-			for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
-			{	/* have already read old block for creates before we got crit, make sure
-				 * cache record still has correct block. if not, reset "cse" fields to
-				 * point to correct cache-record. this is ok to do since we only need the
-				 * prior content of the block (for online backup or before-image journaling
-				 * or online integ) and did not rely on it for constructing the transaction.
-				 * Restart if block is not present in cache now or is being read in currently.
+		assert(!(JNL_ENABLED(csa) && csa->jnl_before_image) || jbbp == csa->jnl->jnl_buff);
+		assert((JNL_ENABLED(csa) && csa->jnl_before_image) || (NULL == jbbp));
+		for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
+		{	/* have already read old block for creates before we got crit, make sure
+			 * cache record still has correct block. if not, reset "cse" fields to
+			 * point to correct cache-record. this is ok to do since we only need the
+			 * prior content of the block (for online backup or before-image journaling
+			 * or online integ) and did not rely on it for constructing the transaction.
+			 * Restart if block is not present in cache now or is being read in currently.
+			 */
+			assert((gds_t_busy2free != cs->mode) && (gds_t_recycled2free != cs->mode));
+			if ((gds_t_acquired == cs->mode) && (NULL != cs->old_block))
+			{
+				assert(read_before_image == ((JNL_ENABLED(csa) && csa->jnl_before_image)
+							     || csa->backup_in_prog
+							     || SNAPSHOTS_IN_PROG(csa)));
+				cr = db_csh_get(cs->blk);
+				if ((cache_rec_ptr_t)CR_NOTVALID == cr)
+				{
+					SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
+					BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_jnl_cwset);
+					SET_CACHE_FAIL_STATUS(status, csd);
+					goto failed;
+				}
+				/* It is possible that cr->in_cw_set is non-zero in case a concurrent MUPIP REORG
+				 * UPGRADE/DOWNGRADE is in PHASE2 touching this very same block. In that case,
+				 * we cannot reuse this block so we restart. We could try finding a different block
+				 * to acquire instead and avoid a restart (tracked as part of C9E11-002651).
+				 * Note that in_cw_set is set to 0 ahead of in_tend in bg_update_phase2. Therefore
+				 * it is possible that we see in_cw_set 0 but in_tend is still non-zero. In that case,
+				 * we cannot proceed with pinning this cache-record as the cr is still locked by
+				 * the other process. We can choose to wait here but instead decide to restart.
 				 */
-				assert((gds_t_busy2free != cs->mode) && (gds_t_recycled2free != cs->mode));
-				if ((gds_t_acquired == cs->mode) && (NULL != cs->old_block))
+				if ((NULL == cr) || (0 <= cr->read_in_progress)
+					|| (0 != cr->in_cw_set) || (0 != cr->in_tend))
 				{
-					assert(read_before_image == ((JNL_ENABLED(csa) && csa->jnl_before_image)
-								     || csa->backup_in_prog
-								     || SNAPSHOTS_IN_PROG(csa)));
-					cr = db_csh_get(cs->blk);
-					if ((cache_rec_ptr_t)CR_NOTVALID == cr)
-					{
-						SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
-						BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_jnl_cwset);
-						SET_CACHE_FAIL_STATUS(status, csd);
-						goto failed;
-					}
-					/* It is possible that cr->in_cw_set is non-zero in case a concurrent MUPIP REORG
-					 * UPGRADE/DOWNGRADE is in PHASE2 touching this very same block. In that case,
-					 * we cannot reuse this block so we restart. We could try finding a different block
-					 * to acquire instead and avoid a restart (tracked as part of C9E11-002651).
-					 * Note that in_cw_set is set to 0 ahead of in_tend in bg_update_phase2. Therefore
-					 * it is possible that we see in_cw_set 0 but in_tend is still non-zero. In that case,
-					 * we cannot proceed with pinning this cache-record as the cr is still locked by
-					 * the other process. We can choose to wait here but instead decide to restart.
+					assert(CDB_STAGNATE > t_tries);
+					status = cdb_sc_lostbefor;
+					goto failed;
+				}
+				PIN_CACHE_RECORD(cr, cr_array, cr_array_index);
+				cs->ondsk_blkver = cr->ondsk_blkver;
+				old_block = (blk_hdr_ptr_t)GDS_REL2ABS(cr->buffaddr);
+				assert((cs->cr != cr) || (cs->old_block == (sm_uc_ptr_t)old_block));
+				old_block_tn = old_block->tn;
+				/* Need checksums if before imaging and if a PBLK record is going to be written. However,
+				 * while doing the bm_getfree, if we got a free block, then no need to compute checksum
+				 * as we would NOT be writing before images of free blocks to journal files
+				 */
+				cksum_needed = (!WAS_FREE(cs->blk_prior_state) && (NULL != jbbp)
+							&& (old_block_tn < jbbp->epoch_tn));
+				if ((cs->cr != cr) || (cs->cycle != cr->cycle))
+				{	/* Block has relocated in the cache. Adjust pointers to new location. */
+					cs->cr = cr;
+					cs->cycle = cr->cycle;
+					cs->old_block = (sm_uc_ptr_t)old_block;
+					/* PBLK checksum was computed outside-of-crit when block was read but
+					 * block has relocated in the cache since then so recompute the checksum
+					 * if this block needs a checksum in the first place (cksum_needed is TRUE).
 					 */
-					if ((NULL == cr) || (0 <= cr->read_in_progress)
-						|| (0 != cr->in_cw_set) || (0 != cr->in_tend))
-					{
-						assert(CDB_STAGNATE > t_tries);
-						status = cdb_sc_lostbefor;
-						goto failed;
-					}
-					PIN_CACHE_RECORD(cr, cr_array, cr_array_index);
-					cs->ondsk_blkver = cr->ondsk_blkver;
-					old_block = (blk_hdr_ptr_t)GDS_REL2ABS(cr->buffaddr);
-					assert((cs->cr != cr) || (cs->old_block == (sm_uc_ptr_t)old_block));
-					old_block_tn = old_block->tn;
-					/* Need checksums if before imaging and if a PBLK record is going to be written. However,
-					 * while doing the bm_getfree, if we got a free block, then no need to compute checksum
-					 * as we would NOT be writing before images of free blocks to journal files
+					recompute_cksum = cksum_needed;
+				} else if (cksum_needed)
+				{	/* We have determined that a checksum is needed for this block. If we have not
+					 * previously computed one outside crit OR if the block contents have changed
+					 * since the checksum was previously computed, we need to recompute it.
+					 * Otherwise, the out-of-crit computed value can be safely used.
+					 * Note that cs->tn is valid only if a checksum was computed outside of crit.
+					 * So make sure it is used only if checksum is non-zero. There is a rare chance
+					 * that the computed checksum could be zero in which case we will recompute
+					 * unnecessarily. Since that is expected to be very rare, it is considered ok.
 					 */
-					cksum_needed = (!WAS_FREE(cs->blk_prior_state) && (NULL != jbbp)
-								&& (old_block_tn < jbbp->epoch_tn));
-					if ((cs->cr != cr) || (cs->cycle != cr->cycle))
-					{	/* Block has relocated in the cache. Adjust pointers to new location. */
-						cs->cr = cr;
-						cs->cycle = cr->cycle;
-						cs->old_block = (sm_uc_ptr_t)old_block;
-						/* PBLK checksum was computed outside-of-crit when block was read but
-						 * block has relocated in the cache since then so recompute the checksum
-						 * if this block needs a checksum in the first place (cksum_needed is TRUE).
-						 */
-						recompute_cksum = cksum_needed;
-					} else if (cksum_needed)
-					{	/* We have determined that a checksum is needed for this block. If we have not
-						 * previously computed one outside crit OR if the block contents have changed
-						 * since the checksum was previously computed, we need to recompute it.
-						 * Otherwise, the out-of-crit computed value can be safely used.
-						 * Note that cs->tn is valid only if a checksum was computed outside of crit.
-						 * So make sure it is used only if checksum is non-zero. There is a rare chance
-						 * that the computed checksum could be zero in which case we will recompute
-						 * unnecessarily. Since that is expected to be very rare, it is considered ok.
-						 */
-						recompute_cksum = (!cs->blk_checksum || (cs->tn <= old_block_tn));
-					}
-					if (!cksum_needed)
-						cs->blk_checksum = 0;	/* zero any out-of-crit computed checksum */
-					else if (recompute_cksum)
-					{	/* We hold crit at this point so we are guaranteed valid bsiz field.
-						 * Hence we do not need to take MIN(bsiz, csd->blk_size) like we did
-						 * in the earlier call to jnl_get_checksum.
-						 */
-						assert(NULL != jbbp);
-						assert(SIZEOF(bsiz) == SIZEOF(old_block->bsiz));
-						bsiz = old_block->bsiz;
-						assert(bsiz <= csd->blk_size);
-						cs->blk_checksum = jnl_get_checksum((uint4*)old_block, csa, bsiz);
-					}
-					DEBUG_ONLY(
-					else
-						assert(cs->blk_checksum == jnl_get_checksum((uint4 *)old_block,
-												csa, old_block->bsiz));
-					)
-					assert(cs->cr->blk == cs->blk);
+					recompute_cksum = (!cs->blk_checksum || (cs->tn <= old_block_tn));
+				}
+				if (!cksum_needed)
+					cs->blk_checksum = 0;	/* zero any out-of-crit computed checksum */
+				else if (recompute_cksum)
+				{	/* We hold crit at this point so we are guaranteed valid bsiz field.
+					 * Hence we do not need to take MIN(bsiz, csd->blk_size) like we did
+					 * in the earlier call to jnl_get_checksum.
+					 */
+					assert(NULL != jbbp);
+					assert(SIZEOF(bsiz) == SIZEOF(old_block->bsiz));
+					bsiz = old_block->bsiz;
+					assert(bsiz <= csd->blk_size);
+					cs->blk_checksum = jnl_get_checksum((uint4*)old_block, csa, bsiz);
 				}
+				DEBUG_ONLY(
+				else
+					assert(cs->blk_checksum == jnl_get_checksum((uint4 *)old_block,
+											csa, old_block->bsiz));
+				)
+				assert(cs->cr->blk == cs->blk);
 			}
 		}
-		/* if we are not writing an INCTN record, we better have a non-zero cw_depth.
-		 * the only known exceptions are
-		 * 	a) if we were being called from gvcst_put for a duplicate SET
-		 * 	b) if we were being called from gvcst_kill for a duplicate KILL
-		 * 	c) if we were called from DSE MAPS
-		 * 	d) if we were being called from gvcst_jrt_null.
-		 * in case (a) and (b), we want to write logical SET or KILL journal records and replicate them.
-		 * in case (c), we do not want to replicate them. we want to assert that is_replicator is FALSE in this case.
-		 * the following assert achieves that purpose.
-		 */
-		assert((inctn_invalid_op != inctn_opcode) || cw_depth
-				|| !is_replicator						/* exception case (c) */
-				|| (ERR_GVPUTFAIL == t_err) && gvdupsetnoop			/* exception case (a) */
-				|| (ERR_JRTNULLFAIL == t_err)					/* exception case (d) */
-				|| (ERR_GVKILLFAIL == t_err) && gv_play_duplicate_kills);	/* exception case (b) */
-		if (REPL_ALLOWED(csa) && (NULL != jnlpool_ctl))
+	}
+	/* if we are not writing an INCTN record, we better have a non-zero cw_depth.
+	 * the only known exceptions are
+	 * 	a) if we were being called from gvcst_put for a duplicate SET
+	 * 	b) if we were being called from gvcst_kill for a duplicate KILL
+	 * 	c) if we were called from DSE MAPS
+	 * 	d) if we were being called from gvcst_jrt_null.
+	 * in case (a) and (b), we want to write logical SET or KILL journal records and replicate them.
+	 * in case (c), we do not want to replicate them. we want to assert that is_replicator is FALSE in this case.
+	 * the following assert achieves that purpose.
+	 */
+	assert((inctn_invalid_op != inctn_opcode) || cw_depth
+			|| !is_replicator						/* exception case (c) */
+			|| (ERR_GVPUTFAIL == t_err) && gvdupsetnoop			/* exception case (a) */
+			|| (ERR_JRTNULLFAIL == t_err)					/* exception case (d) */
+			|| (ERR_GVKILLFAIL == t_err) && gv_play_duplicate_kills);	/* exception case (b) */
+	if (REPL_ALLOWED(csa) && (NULL != jnlpool_ctl))
+	{
+		repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;
+		if (!repl_csa->hold_onto_crit)
+			grab_lock(jnlpool.jnlpool_dummy_reg, TRUE, ASSERT_NO_ONLINE_ROLLBACK);
+		assert(repl_csa->now_crit);
+		jnlpool_crit_acquired = TRUE;
+#		ifdef UNIX
+		/* With jnlpool lock held, check instance freeze, and retry if set. */
+		if (jnlpool.jnlpool_ctl->freeze)
 		{
-			repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;
-			if (!repl_csa->hold_onto_crit)
-				grab_lock(jnlpool.jnlpool_dummy_reg, TRUE, ASSERT_NO_ONLINE_ROLLBACK);
-			assert(repl_csa->now_crit);
-			jnlpool_crit_acquired = TRUE;
+			status = cdb_sc_instancefreeze;
+			goto failed;
+		}
+#		endif
+		if (is_replicator && (inctn_invalid_op == inctn_opcode))
+		{
+			jpl = jnlpool_ctl;
+			tjpl = temp_jnlpool_ctl;
+			replication = TRUE;
+			tjpl->write_addr = jpl->write_addr;
+			tjpl->write = jpl->write;
+			tjpl->jnl_seqno = jpl->jnl_seqno;
 #			ifdef UNIX
-			/* With jnlpool lock held, check instance freeze, and retry if set. */
-			if (jnlpool.jnlpool_ctl->freeze)
-			{
-				status = cdb_sc_instancefreeze;
-				goto failed;
-			}
+			if (INVALID_SUPPL_STRM != strm_index)
+			{	/* Need to also update supplementary stream seqno */
+				supplementary = TRUE;
+				assert(0 <= strm_index);
+				/* assert(strm_index < ARRAYSIZE(tjpl->strm_seqno)); */
+				strm_seqno = jpl->strm_seqno[strm_index];
+				ASSERT_INST_FILE_HDR_HAS_HISTREC_FOR_STRM(strm_index);
+			} else
+				supplementary = FALSE;
 #			endif
-			if (is_replicator && (inctn_invalid_op == inctn_opcode))
+			INT8_ONLY(assert(tjpl->write == tjpl->write_addr % tjpl->jnlpool_size));
+			assert(jgbl.cumul_jnl_rec_len);
+			tmp_cumul_jnl_rec_len = (uint4)(jgbl.cumul_jnl_rec_len + SIZEOF(jnldata_hdr_struct));
+			tjpl->write += SIZEOF(jnldata_hdr_struct);
+			if (tjpl->write >= tjpl->jnlpool_size)
 			{
-				jpl = jnlpool_ctl;
-				tjpl = temp_jnlpool_ctl;
-				replication = TRUE;
-				tjpl->write_addr = jpl->write_addr;
-				tjpl->write = jpl->write;
-				tjpl->jnl_seqno = jpl->jnl_seqno;
-#				ifdef UNIX
-				if (INVALID_SUPPL_STRM != strm_index)
-				{	/* Need to also update supplementary stream seqno */
-					supplementary = TRUE;
-					assert(0 <= strm_index);
-					/* assert(strm_index < ARRAYSIZE(tjpl->strm_seqno)); */
-					strm_seqno = jpl->strm_seqno[strm_index];
-					ASSERT_INST_FILE_HDR_HAS_HISTREC_FOR_STRM(strm_index);
-				} else
-					supplementary = FALSE;
-#				endif
-				INT8_ONLY(assert(tjpl->write == tjpl->write_addr % tjpl->jnlpool_size));
-				assert(jgbl.cumul_jnl_rec_len);
-				tmp_cumul_jnl_rec_len = (uint4)(jgbl.cumul_jnl_rec_len + SIZEOF(jnldata_hdr_struct));
-				tjpl->write += SIZEOF(jnldata_hdr_struct);
-				if (tjpl->write >= tjpl->jnlpool_size)
-				{
-					assert(tjpl->write == tjpl->jnlpool_size);
-					tjpl->write = 0;
-				}
-				assert(jpl->early_write_addr == jpl->write_addr);
-				jpl->early_write_addr = jpl->write_addr + tmp_cumul_jnl_rec_len;
-				/* Source server does not read in crit. It relies on early_write_addr, the transaction
-				 * data, lastwrite_len, write_addr being updated in that order. To ensure this order,
-				 * we have to force out early_write_addr to its coherency point now. If not, the source
-				 * server may read data that is overwritten (or stale). This is true only on
-				 * architectures and OSes that allow unordered memory access
-				 */
-				SHM_WRITE_MEMORY_BARRIER;
+				assert(tjpl->write == tjpl->jnlpool_size);
+				tjpl->write = 0;
 			}
+			assert(jpl->early_write_addr == jpl->write_addr);
+			jpl->early_write_addr = jpl->write_addr + tmp_cumul_jnl_rec_len;
+			/* Source server does not read in crit. It relies on early_write_addr, the transaction
+			 * data, lastwrite_len, write_addr being updated in that order. To ensure this order,
+			 * we have to force out early_write_addr to its coherency point now. If not, the source
+			 * server may read data that is overwritten (or stale). This is true only on
+			 * architectures and OSes that allow unordered memory access
+			 */
+			SHM_WRITE_MEMORY_BARRIER;
 		}
-		assert(cw_set_depth < CDB_CW_SET_SIZE);
-		ASSERT_CURR_TN_EQUALS_EARLY_TN(csa, dbtn);
-		CHECK_TN(csa, csd, dbtn);	/* can issue rts_error TNTOOLARGE */
-		if (JNL_ENABLED(csa))
-		{	/* Since we got the system time (jgbl.gbl_jrec_time) outside of crit, it is possible that
-			 * journal records were written concurrently to this file with a timestamp that is future
-			 * relative to what we recorded. In that case, adjust our recorded time to match this.
-			 * This is necessary to ensure that timestamps of successive journal records for each
-			 * database file are in non-decreasing order. A side-effect of this is that our recorded
-			 * time might not accurately reflect the current system time but that is considered not
-			 * an issue since we dont expect to be off by more than a second or two if at all.
-			 * Another side effect is that even if the system time went back, we will never write
-			 * out-of-order timestamped journal records in the lifetime of this database shared memory.
+	}
+	assert(cw_set_depth < CDB_CW_SET_SIZE);
+	ASSERT_CURR_TN_EQUALS_EARLY_TN(csa, dbtn);
+	CHECK_TN(csa, csd, dbtn);	/* can issue rts_error TNTOOLARGE */
+	if (JNL_ENABLED(csa))
+	{	/* Since we got the system time (jgbl.gbl_jrec_time) outside of crit, it is possible that
+		 * journal records were written concurrently to this file with a timestamp that is future
+		 * relative to what we recorded. In that case, adjust our recorded time to match this.
+		 * This is necessary to ensure that timestamps of successive journal records for each
+		 * database file are in non-decreasing order. A side-effect of this is that our recorded
+		 * time might not accurately reflect the current system time but that is considered not
+		 * an issue since we dont expect to be off by more than a second or two if at all.
+		 * Another side effect is that even if the system time went back, we will never write
+		 * out-of-order timestamped journal records in the lifetime of this database shared memory.
+		 */
+		jpc = csa->jnl;
+		jbp = jpc->jnl_buff;
+		/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order of jnl
+		 * records. This needs to be done BEFORE the jnl_ensure_open as that could write journal records
+		 * (if it decides to switch to a new journal file)
+		 */
+		ADJUST_GBL_JREC_TIME(jgbl, jbp);
+		if (replication)
+		{	/* Make sure timestamp of this seqno is >= timestamp of previous seqno. Note: The below macro
+			 * invocation should be done AFTER the ADJUST_GBL_JREC_TIME call as the below resets
+			 * jpl->prev_jnlseqno_time. Doing it the other way around would mean the reset will happen
+			 * with a potentially lower value than the final adjusted time written in the jnl record.
 			 */
-			jpc = csa->jnl;
-			jbp = jpc->jnl_buff;
-			/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order of jnl
-			 * records. This needs to be done BEFORE the jnl_ensure_open as that could write journal records
-			 * (if it decides to switch to a new journal file)
+			ADJUST_GBL_JREC_TIME_JNLPOOL(jgbl, jpl);
+		}
+		/* Note that jnl_ensure_open can call cre_jnl_file which
+		 * in turn assumes jgbl.gbl_jrec_time is set. Also jnl_file_extend can call
+		 * jnl_write_epoch_rec which in turn assumes jgbl.gbl_jrec_time is set.
+		 * In case of forw-phase-recovery, mur_output_record would have already set this.
+		 */
+		assert(jgbl.gbl_jrec_time);
+		jnl_status = jnl_ensure_open();
+		GTM_WHITE_BOX_TEST(WBTEST_T_END_JNLFILOPN, jnl_status, ERR_JNLFILOPN);
+		if (jnl_status == 0)
+		{	/* tmp_cw_set_depth was used to do TOTAL_NONTPJNL_REC_SIZE calculation earlier in this function.
+			 * It is now though that the actual jnl record write occurs. Ensure that the current value of
+			 * cw_set_depth does not entail any change in journal record size than was calculated.
+			 * Same case with csa->jnl_before_images & jbp->before_images.
+			 * The only exception is that in case of mu_reorg_upgrd_dwngrd_in_prog cw_set_depth will be
+			 * LESSER than tmp_cw_set_depth (this is still fine as there is more size allocated than used).
 			 */
-			ADJUST_GBL_JREC_TIME(jgbl, jbp);
-			if (replication)
-			{	/* Make sure timestamp of this seqno is >= timestamp of previous seqno. Note: The below macro
-				 * invocation should be done AFTER the ADJUST_GBL_JREC_TIME call as the below resets
-				 * jpl->prev_jnlseqno_time. Doing it the other way around would mean the reset will happen
-				 * with a potentially lower value than the final adjusted time written in the jnl record.
-				 */
-				ADJUST_GBL_JREC_TIME_JNLPOOL(jgbl, jpl);
+			assert(cw_set_depth == tmp_cw_set_depth
+				|| mu_reorg_upgrd_dwngrd_in_prog && cw_map_depth && cw_set_depth < tmp_cw_set_depth);
+			assert(jbp->before_images == csa->jnl_before_image);
+			assert((csa->jnl_state == csd->jnl_state) && (csa->jnl_before_image == csd->jnl_before_image));
+			if (DISK_BLOCKS_SUM(jbp->freeaddr, total_jnl_rec_size) > jbp->filesize)
+			{	/* Moved as part of change to prevent journal records splitting
+				 * across multiple generation journal files. */
+				if (SS_NORMAL != (jnl_status = jnl_flush(jpc->region)))
+				{
+					send_msg_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(csd),
+						ERR_TEXT, 2, RTS_ERROR_TEXT("Error with journal flush during t_end"),
+						jnl_status);
+					assert((!JNL_ENABLED(csd)) && (JNL_ENABLED(csa)));
+					status = cdb_sc_jnlclose;
+					goto failed;
+				} else if (EXIT_ERR == jnl_file_extend(jpc, total_jnl_rec_size))
+				{
+					assert(csd == csa->hdr);	/* jnl_file_extend() shouldn't reset csd in MM */
+					assert((!JNL_ENABLED(csd)) && (JNL_ENABLED(csa)));
+					status = cdb_sc_jnlclose;
+					goto failed;
+				}
+				assert(csd == csa->hdr);	/* If MM, csd shouldn't have been reset */
 			}
-			/* Note that jnl_ensure_open can call cre_jnl_file which
-			 * in turn assumes jgbl.gbl_jrec_time is set. Also jnl_file_extend can call
-			 * jnl_write_epoch_rec which in turn assumes jgbl.gbl_jrec_time is set.
-			 * In case of forw-phase-recovery, mur_output_record would have already set this.
-			 */
-			assert(jgbl.gbl_jrec_time);
-			jnl_status = jnl_ensure_open();
-			GTM_WHITE_BOX_TEST(WBTEST_T_END_JNLFILOPN, jnl_status, ERR_JNLFILOPN);
-			if (jnl_status == 0)
-			{	/* tmp_cw_set_depth was used to do TOTAL_NONTPJNL_REC_SIZE calculation earlier in this function.
-				 * It is now though that the actual jnl record write occurs. Ensure that the current value of
-				 * cw_set_depth does not entail any change in journal record size than was calculated.
-				 * Same case with csa->jnl_before_images & jbp->before_images.
-				 * The only exception is that in case of mu_reorg_upgrd_dwngrd_in_prog cw_set_depth will be
-				 * LESSER than tmp_cw_set_depth (this is still fine as there is more size allocated than used).
-				 */
-				assert(cw_set_depth == tmp_cw_set_depth
-					|| mu_reorg_upgrd_dwngrd_in_prog && cw_map_depth && cw_set_depth < tmp_cw_set_depth);
-				assert(jbp->before_images == csa->jnl_before_image);
-				assert((csa->jnl_state == csd->jnl_state) && (csa->jnl_before_image == csd->jnl_before_image));
-				if (DISK_BLOCKS_SUM(jbp->freeaddr, total_jnl_rec_size) > jbp->filesize)
-				{	/* Moved as part of change to prevent journal records splitting
-					 * across multiple generation journal files. */
-					if (SS_NORMAL != (jnl_status = jnl_flush(jpc->region)))
-					{
-						send_msg_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(csd),
-							ERR_TEXT, 2, RTS_ERROR_TEXT("Error with journal flush during t_end"),
-							jnl_status);
-						assert((!JNL_ENABLED(csd)) && (JNL_ENABLED(csa)));
-						status = cdb_sc_jnlclose;
-						goto failed;
-					} else if (EXIT_ERR == jnl_file_extend(jpc, total_jnl_rec_size))
+			assert(jgbl.gbl_jrec_time >= jbp->prev_jrec_time);
+			if (0 == jpc->pini_addr)
+				jnl_put_jrt_pini(csa);
+			if (JNL_HAS_EPOCH(jbp))
+			{
+				if ((jbp->next_epoch_time <= jgbl.gbl_jrec_time) UNCONDITIONAL_EPOCH_ONLY(|| TRUE))
+				{	/* Flush the cache. Since we are in crit, defer syncing epoch */
+					if (!wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_IN_COMMIT
+											| WCSFLU_SPEEDUP_NOBEFORE))
 					{
-						assert(csd == csa->hdr);	/* jnl_file_extend() shouldn't reset csd in MM */
-						assert((!JNL_ENABLED(csd)) && (JNL_ENABLED(csa)));
-						status = cdb_sc_jnlclose;
+						SET_WCS_FLU_FAIL_STATUS(status, csd);
+						SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
+						BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_jnl_wcsflu);
 						goto failed;
 					}
-					assert(csd == csa->hdr);	/* If MM, csd shouldn't have been reset */
-				}
-				assert(jgbl.gbl_jrec_time >= jbp->prev_jrec_time);
-				if (0 == jpc->pini_addr)
-					jnl_put_jrt_pini(csa);
-				if (JNL_HAS_EPOCH(jbp))
-				{
-					if ((jbp->next_epoch_time <= jgbl.gbl_jrec_time) UNCONDITIONAL_EPOCH_ONLY(|| TRUE))
-					{	/* Flush the cache. Since we are in crit, defer syncing epoch */
-						if (!wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_IN_COMMIT
-												| WCSFLU_SPEEDUP_NOBEFORE))
+					assert(csd == csa->hdr);
+					VMS_ONLY(
+						if (csd->clustered  &&
+							!CCP_SEGMENT_STATE(cnl, CCST_MASK_HAVE_DIRTY_BUFFERS))
 						{
-							SET_WCS_FLU_FAIL_STATUS(status, csd);
-							SET_TRACEABLE_VAR(cnl->wc_blocked, TRUE);
-							BG_TRACE_PRO_ANY(csa, wc_blocked_t_end_jnl_wcsflu);
-							goto failed;
+							CCP_FID_MSG(gv_cur_region, CCTR_FLUSHLK);
+							ccp_userwait(gv_cur_region,
+								CCST_MASK_HAVE_DIRTY_BUFFERS, 0, cnl->ccp_cycle);
 						}
-						assert(csd == csa->hdr);
-						VMS_ONLY(
-							if (csd->clustered  &&
-								!CCP_SEGMENT_STATE(cnl, CCST_MASK_HAVE_DIRTY_BUFFERS))
-							{
-								CCP_FID_MSG(gv_cur_region, CCTR_FLUSHLK);
-								ccp_userwait(gv_cur_region,
-									CCST_MASK_HAVE_DIRTY_BUFFERS, 0, cnl->ccp_cycle);
-							}
-						)
-					}
+					)
 				}
-			} else
-			{
-				if (SS_NORMAL != jpc->status)
-					rts_error_csa(CSA_ARG(csa) VARLSTCNT(7) jnl_status, 4, JNL_LEN_STR(csd),
-							DB_LEN_STR(gv_cur_region), jpc->status);
-				else
-					rts_error_csa(CSA_ARG(csa) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd),
-							DB_LEN_STR(gv_cur_region));
 			}
+		} else
+		{
+			if (SS_NORMAL != jpc->status)
+				rts_error_csa(CSA_ARG(csa) VARLSTCNT(7) jnl_status, 4, JNL_LEN_STR(csd),
+						DB_LEN_STR(gv_cur_region), jpc->status);
+			else
+				rts_error_csa(CSA_ARG(csa) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd),
+						DB_LEN_STR(gv_cur_region));
 		}
-		assert(!TREF(donot_commit));	/* We should never commit a transaction that was determined restartable */
-		assert(TN_NOT_SPECIFIED > MAX_TN_V6); /* Ensure TN_NOT_SPECIFIED isn't a valid TN number */
-		blktn = (TN_NOT_SPECIFIED == ctn) ? dbtn : ctn;
-		csa->ti->early_tn = dbtn + 1;
-		if (JNL_ENABLED(csa))
+	}
+	assert(!TREF(donot_commit));	/* We should never commit a transaction that was determined restartable */
+	assert(TN_NOT_SPECIFIED > MAX_TN_V6); /* Ensure TN_NOT_SPECIFIED isn't a valid TN number */
+	blktn = (TN_NOT_SPECIFIED == ctn) ? dbtn : ctn;
+	csa->ti->early_tn = dbtn + 1;
+	if (JNL_ENABLED(csa))
+	{
+		/* At this point we know tn,pini_addr and jrec_time; so calculate the checksum for the transaction once
+		   reuse it for all the updates
+		*/
+		if(!com_csum)
 		{
-			/* At this point we know tn,pini_addr and jrec_time; so calculate the checksum for the transaction once
-			   reuse it for all the updates
-			*/
-			if(!com_csum)
+			ADJUST_CHECKSUM_TN(INIT_CHECKSUM_SEED, &dbtn, com_csum);
+			ADJUST_CHECKSUM(com_csum, csa->jnl->pini_addr, com_csum);
+			ADJUST_CHECKSUM(com_csum, jgbl.gbl_jrec_time, com_csum);
+		}
+		DEBUG_ONLY(save_gbl_jrec_time = jgbl.gbl_jrec_time;)
+		if (jbp->before_images)
+		{	/* do not write PBLKs if MUPIP REORG UPGRADE/DOWNGRADE with -NOSAFEJNL */
+			if (!mu_reorg_upgrd_dwngrd_in_prog || !mu_reorg_nosafejnl)
 			{
-				ADJUST_CHECKSUM_TN(INIT_CHECKSUM_SEED, &dbtn, com_csum);
-				ADJUST_CHECKSUM(com_csum, csa->jnl->pini_addr, com_csum);
-				ADJUST_CHECKSUM(com_csum, jgbl.gbl_jrec_time, com_csum);
-			}
-			DEBUG_ONLY(save_gbl_jrec_time = jgbl.gbl_jrec_time;)
-			if (jbp->before_images)
-			{	/* do not write PBLKs if MUPIP REORG UPGRADE/DOWNGRADE with -NOSAFEJNL */
-				if (!mu_reorg_upgrd_dwngrd_in_prog || !mu_reorg_nosafejnl)
+				epoch_tn = jbp->epoch_tn; /* store in a local as it is used in a loop below */
+				for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
 				{
-					epoch_tn = jbp->epoch_tn; /* store in a local as it is used in a loop below */
-					for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
-					{
-						/* PBLK computations for FREE blocks are not needed */
-						if (WAS_FREE(cs->blk_prior_state))
+					/* PBLK computations for FREE blocks are not needed */
+					if (WAS_FREE(cs->blk_prior_state))
+						continue;
+					/* write out before-update journal image records */
+					mode = cs->mode;
+					if (gds_t_committed < mode)
+					{	/* There are three possibilities at this point.
+						 * a) gds_t_write_root : In this case no need to write PBLK.
+						 * b) gds_t_busy2free : This is set by gvcst_bmp_mark_free to indicate
+						 *	that a block has to be freed right away instead of taking it
+						 *	through the RECYCLED state. This should be done only if
+						 *	csd->db_got_to_v5_once has not yet become TRUE. Once it is
+						 *	TRUE, block frees will write PBLK only when the block is reused.
+						 *      An exception is when the block is a level-0 block in directory
+						 * 	tree, we always write PBLK immediately.
+						 * c) gds_t_recycled2free: Need to write PBLK
+						 */
+						assert((gds_t_write_root == mode) || (gds_t_busy2free == mode)
+							|| (gds_t_recycled2free == mode));
+						if (!SAVE_2FREE_IMAGE(mode, free_seen, csd))
 							continue;
-						/* write out before-update journal image records */
-						mode = cs->mode;
-						if (gds_t_committed < mode)
-						{	/* There are three possibilities at this point.
-							 * a) gds_t_write_root : In this case no need to write PBLK.
-							 * b) gds_t_busy2free : This is set by gvcst_bmp_mark_free to indicate
-							 *	that a block has to be freed right away instead of taking it
-							 *	through the RECYCLED state. This should be done only if
-							 *	csd->db_got_to_v5_once has not yet become TRUE. Once it is
-							 *	TRUE, block frees will write PBLK only when the block is reused.
-							 *      An exception is when the block is a level-0 block in directory
-							 * 	tree, we always write PBLK immediately.
-							 * c) gds_t_recycled2free: Need to write PBLK
-							 */
-							assert((gds_t_write_root == mode) || (gds_t_busy2free == mode)
-								|| (gds_t_recycled2free == mode));
-							if (!SAVE_2FREE_IMAGE(mode, free_seen, csd))
-								continue;
-						}
-						old_block = (blk_hdr_ptr_t)cs->old_block;
-						ASSERT_IS_WITHIN_SHM_BOUNDS((sm_uc_ptr_t)old_block, csa);
-						DBG_ENSURE_OLD_BLOCK_IS_VALID(cs, is_mm, csa, csd);
-						if ((NULL != old_block) && (old_block->tn < epoch_tn))
+					}
+					old_block = (blk_hdr_ptr_t)cs->old_block;
+					ASSERT_IS_WITHIN_SHM_BOUNDS((sm_uc_ptr_t)old_block, csa);
+					DBG_ENSURE_OLD_BLOCK_IS_VALID(cs, is_mm, csa, csd);
+					if ((NULL != old_block) && (old_block->tn < epoch_tn))
+					{
+						bsiz = old_block->bsiz;
+						assert((bsiz <= csd->blk_size) || IS_DSE_IMAGE);
+						assert(bsiz >= SIZEOF(blk_hdr) || IS_DSE_IMAGE);
+						/* For acquired or gds_t_busy2free blocks, we should have computed
+						 * checksum already. The only exception is if we found no need to
+						 * compute checksum outside of crit but before we got crit, an
+						 * EPOCH got written concurrently so we have to write a PBLK (and
+						 * hence compute the checksum as well) when earlier we thought none
+						 * was necessary. An easy way to check this is that an EPOCH was
+						 * written AFTER we started this transaction.
+						 */
+						assert((gds_t_acquired != cs->mode) || (gds_t_busy2free != cs->mode)
+							|| cs->blk_checksum || (epoch_tn >= start_tn));
+						/* It is possible that the block has a bad block-size.
+						 * Before computing checksum ensure bsiz passed is safe.
+						 * The checks done here for "bsiz" assignment are
+						 * similar to those done in jnl_write_pblk/jnl_write_aimg.
+						 */
+						if (IS_DSE_IMAGE)
+							bsiz = MIN(bsiz, csd->blk_size);
+						assert(!cs->blk_checksum ||
+							(cs->blk_checksum == jnl_get_checksum((uint4 *)old_block,
+												csa,
+												bsiz)));
+						if (!cs->blk_checksum)
+							cs->blk_checksum = jnl_get_checksum((uint4 *)old_block,
+												csa,
+												bsiz);
+#						ifdef GTM_CRYPT
+						if (csd->is_encrypted)
 						{
-							bsiz = old_block->bsiz;
-							assert((bsiz <= csd->blk_size) || IS_DSE_IMAGE);
-							assert(bsiz >= SIZEOF(blk_hdr) || IS_DSE_IMAGE);
-							/* For acquired or gds_t_busy2free blocks, we should have computed
-							 * checksum already. The only exception is if we found no need to
-							 * compute checksum outside of crit but before we got crit, an
-							 * EPOCH got written concurrently so we have to write a PBLK (and
-							 * hence compute the checksum as well) when earlier we thought none
-							 * was necessary. An easy way to check this is that an EPOCH was
-							 * written AFTER we started this transaction.
+							DBG_ENSURE_PTR_IS_VALID_GLOBUFF(csa, csd, (sm_uc_ptr_t)old_block);
+							DEBUG_ONLY(save_old_block = old_block;)
+							old_block = (blk_hdr_ptr_t)GDS_ANY_ENCRYPTGLOBUF(old_block,
+													      csa);
+							/* Ensure that the unencrypted block and it's twin counterpart are
+							 * in sync.
 							 */
-							assert((gds_t_acquired != cs->mode) || (gds_t_busy2free != cs->mode)
-								|| cs->blk_checksum || (epoch_tn >= start_tn));
-							/* It is possible that the block has a bad block-size.
-							 * Before computing checksum ensure bsiz passed is safe.
-							 * The checks done here for "bsiz" assignment are
-							 * similar to those done in jnl_write_pblk/jnl_write_aimg.
-							 */
-							if (IS_DSE_IMAGE)
-								bsiz = MIN(bsiz, csd->blk_size);
-							assert(!cs->blk_checksum ||
-								(cs->blk_checksum == jnl_get_checksum((uint4 *)old_block,
-													csa,
-													bsiz)));
-							if (!cs->blk_checksum)
-								cs->blk_checksum = jnl_get_checksum((uint4 *)old_block,
-													csa,
-													bsiz);
-#							ifdef GTM_CRYPT
-							if (csd->is_encrypted)
-							{
-								DBG_ENSURE_PTR_IS_VALID_GLOBUFF(csa, csd, (sm_uc_ptr_t)old_block);
-								DEBUG_ONLY(save_old_block = old_block;)
-								old_block = (blk_hdr_ptr_t)GDS_ANY_ENCRYPTGLOBUF(old_block,
-														      csa);
-								/* Ensure that the unencrypted block and it's twin counterpart are
-								 * in sync.
-								 */
-								assert(save_old_block->tn == old_block->tn);
-								assert(save_old_block->bsiz == old_block->bsiz);
-								assert(save_old_block->levl == old_block->levl);
-								DBG_ENSURE_PTR_IS_VALID_ENCTWINGLOBUFF(csa,
-												       csd,
-												       (sm_uc_ptr_t)old_block);
-							}
-#							endif
-							jnl_write_pblk(csa, cs, old_block, com_csum);
-							cs->jnl_freeaddr = jbp->freeaddr;
+							assert(save_old_block->tn == old_block->tn);
+							assert(save_old_block->bsiz == old_block->bsiz);
+							assert(save_old_block->levl == old_block->levl);
+							DBG_ENSURE_PTR_IS_VALID_ENCTWINGLOBUFF(csa,
+											       csd,
+											       (sm_uc_ptr_t)old_block);
 						}
-						DEBUG_ONLY(
-						else
-							assert(0 == cs->jnl_freeaddr);
-						)
+#						endif
+						jnl_write_pblk(csa, cs, old_block, com_csum);
+						cs->jnl_freeaddr = jbp->freeaddr;
 					}
+					DEBUG_ONLY(
+					else
+						assert(0 == cs->jnl_freeaddr);
+					)
 				}
 			}
-			if (write_after_image)
-			{	/* either DSE or MUPIP RECOVER playing an AIMG record */
-				assert(1 == cw_set_depth); /* only one block at a time */
-				assert(!replication);
-				cs = cw_set;
-				jnl_write_aimg_rec(csa, cs, com_csum);
-			} else if (write_inctn)
+		}
+		if (write_after_image)
+		{	/* either DSE or MUPIP RECOVER playing an AIMG record */
+			assert(1 == cw_set_depth); /* only one block at a time */
+			assert(!replication);
+			cs = cw_set;
+			jnl_write_aimg_rec(csa, cs, com_csum);
+		} else if (write_inctn)
+		{
+			assert(!replication);
+			if ((inctn_blkupgrd == inctn_opcode) || (inctn_blkdwngrd == inctn_opcode))
 			{
-				assert(!replication);
-				if ((inctn_blkupgrd == inctn_opcode) || (inctn_blkdwngrd == inctn_opcode))
+				assert(1 == cw_set_depth); /* upgrade/downgrade one block at a time */
+				cs = cw_set;
+				assert(inctn_detail.blknum_struct.blknum == cs->blk);
+				assert(mu_reorg_upgrd_dwngrd_blktn < dbtn);
+				if (mu_reorg_nosafejnl)
 				{
-					assert(1 == cw_set_depth); /* upgrade/downgrade one block at a time */
-					cs = cw_set;
-					assert(inctn_detail.blknum_struct.blknum == cs->blk);
-					assert(mu_reorg_upgrd_dwngrd_blktn < dbtn);
-					if (mu_reorg_nosafejnl)
-					{
-						blktn = mu_reorg_upgrd_dwngrd_blktn;
-						/* if NOSAFEJNL and there is going to be a block format change
-						 * as a result of this update, note it down in the inctn opcode
-						 * (for recovery) as there is no PBLK record for it to rely on.
-						 */
-						if (cs->ondsk_blkver != csd->desired_db_format)
-							inctn_opcode = (inctn_opcode == inctn_blkupgrd)
-									? inctn_blkupgrd_fmtchng : inctn_blkdwngrd_fmtchng;
-					}
+					blktn = mu_reorg_upgrd_dwngrd_blktn;
+					/* if NOSAFEJNL and there is going to be a block format change
+					 * as a result of this update, note it down in the inctn opcode
+					 * (for recovery) as there is no PBLK record for it to rely on.
+					 */
+					if (cs->ondsk_blkver != csd->desired_db_format)
+						inctn_opcode = (inctn_opcode == inctn_blkupgrd)
+								? inctn_blkupgrd_fmtchng : inctn_blkdwngrd_fmtchng;
 				}
-				jnl_write_inctn_rec(csa);
-			} else if (0 == jnl_fence_ctl.level)
-			{
-				assert(!replication || !jgbl.forw_phase_recovery);
-				if (replication)
-				{
-					jnl_fence_ctl.token = tjpl->jnl_seqno;
-					UNIX_ONLY(
-						if (supplementary)
-							jnl_fence_ctl.strm_seqno = SET_STRM_INDEX(strm_seqno, strm_index);
-					)
-				} else if (!jgbl.forw_phase_recovery)
-					jnl_fence_ctl.token = seq_num_zero;
-				/* In case of forw-phase of recovery, token would have been set by mur_output_record */
-				jnl_write_logical(csa, non_tp_jfb_ptr, com_csum);
-			} else
-				jnl_write_ztp_logical(csa, non_tp_jfb_ptr, com_csum);
-			/* Ensure jgbl.gbl_jrec_time did not get reset by any of the jnl writing functions */
-			assert(save_gbl_jrec_time == jgbl.gbl_jrec_time);
-		} else if (replication)
-		{	/* Case where JNL_ENABLED(csa) is FALSE but REPL_WAS_ENABLED(csa) is TRUE and therefore we need to
-			 * write logical jnl records in the journal pool (no need to write in journal buffer or journal file).
-			 */
-			assert(!JNL_ENABLED(csa) && REPL_WAS_ENABLED(csa));
-			if (0 == jnl_fence_ctl.level)
+			}
+			jnl_write_inctn_rec(csa);
+		} else if (0 == jnl_fence_ctl.level)
+		{
+			assert(!replication || !jgbl.forw_phase_recovery);
+			if (replication)
 			{
 				jnl_fence_ctl.token = tjpl->jnl_seqno;
 				UNIX_ONLY(
 					if (supplementary)
 						jnl_fence_ctl.strm_seqno = SET_STRM_INDEX(strm_seqno, strm_index);
 				)
-				jnl_write_logical(csa, non_tp_jfb_ptr, com_csum);
-			} else
-				jnl_write_ztp_logical(csa, non_tp_jfb_ptr, com_csum);
-		}
-		if (free_seen)
-		{	/* Write to snapshot and backup file for busy2free and recycled2free mode. These modes only appear in
-			 * mupip reorg -truncate or v4-v5 upgrade, neither of which can occur with MM.
-			 */
-			assert(!is_mm);
-			cs = &cw_set[0];
-			if (SAVE_2FREE_IMAGE(cs->mode, free_seen, csd))
-			{
-				blkid = cs->blk;
-				assert(!IS_BITMAP_BLK(blkid) && (blkid == cr_array[0]->blk));
-				csa->backup_in_prog = (BACKUP_NOT_IN_PROGRESS != cnl->nbb);
-				cr = cr_array[0];
-				backup_cr = cr;
-				blk_ptr = (sm_uc_ptr_t)GDS_REL2ABS(cr->buffaddr);
-				backup_blk_ptr = blk_ptr;
-				BG_BACKUP_BLOCK(csa, csd, cnl, cr, cs, blkid, backup_cr, backup_blk_ptr, block_saved,
-						 dummysi->backup_block_saved);
-#				ifdef GTM_SNAPSHOT
-				if (SNAPSHOTS_IN_PROG(csa))
-				{	/* we write the before-image to snapshot file only for FAST_INTEG and not for
-					 * regular integ because the block is going to be marked free at this point
-					 * and in case of a regular integ a before image will be written to the snapshot
-					 * file eventually when the free block gets reused. So the before-image writing
-					 * effectively gets deferred but does happen.
-					 */
-					lcl_ss_ctx = SS_CTX_CAST(cs_addrs->ss_ctx);
-					if (lcl_ss_ctx && FASTINTEG_IN_PROG(lcl_ss_ctx))
-						WRITE_SNAPSHOT_BLOCK(cs_addrs, cr, NULL, blkid, lcl_ss_ctx);
-				}
-#				endif
-			}
-		}
-		if (replication)
+			} else if (!jgbl.forw_phase_recovery)
+				jnl_fence_ctl.token = seq_num_zero;
+			/* In case of forw-phase of recovery, token would have been set by mur_output_record */
+			jnl_write_logical(csa, non_tp_jfb_ptr, com_csum);
+		} else
+			jnl_write_ztp_logical(csa, non_tp_jfb_ptr, com_csum);
+		/* Ensure jgbl.gbl_jrec_time did not get reset by any of the jnl writing functions */
+		assert(save_gbl_jrec_time == jgbl.gbl_jrec_time);
+	} else if (replication)
+	{	/* Case where JNL_ENABLED(csa) is FALSE but REPL_WAS_ENABLED(csa) is TRUE and therefore we need to
+		 * write logical jnl records in the journal pool (no need to write in journal buffer or journal file).
+		 */
+		assert(!JNL_ENABLED(csa) && REPL_WAS_ENABLED(csa));
+		if (0 == jnl_fence_ctl.level)
 		{
-			tjpl->jnl_seqno++;
-			assert(csa->hdr->reg_seqno < tjpl->jnl_seqno);
-			csa->hdr->reg_seqno = tjpl->jnl_seqno;
+			jnl_fence_ctl.token = tjpl->jnl_seqno;
 			UNIX_ONLY(
 				if (supplementary)
-				{
-					next_strm_seqno = strm_seqno + 1;
-					/* tjpl->strm_seqno[strm_index] = next_strm_seqno; */
-					csa->hdr->strm_reg_seqno[strm_index] = next_strm_seqno;
-				}
+					jnl_fence_ctl.strm_seqno = SET_STRM_INDEX(strm_seqno, strm_index);
 			)
-			VMS_ONLY(
-				if (is_updproc)
-				{
-					jgbl.max_resync_seqno++;
-					csa->hdr->resync_seqno = jgbl.max_resync_seqno;
-				}
-			)
-		}
-		csa->prev_free_blks = csa->ti->free_blocks;
-		csa->t_commit_crit = T_COMMIT_CRIT_PHASE1;
-		if (cw_set_depth)
+			jnl_write_logical(csa, non_tp_jfb_ptr, com_csum);
+		} else
+			jnl_write_ztp_logical(csa, non_tp_jfb_ptr, com_csum);
+	}
+	if (free_seen)
+	{	/* Write to snapshot and backup file for busy2free and recycled2free mode. These modes only appear in
+		 * mupip reorg -truncate or v4-v5 upgrade, neither of which can occur with MM.
+		 */
+		assert(!is_mm);
+		cs = &cw_set[0];
+		if (SAVE_2FREE_IMAGE(cs->mode, free_seen, csd))
 		{
-			if (!is_mm)	/* increment counter of # of processes that are actively doing two-phase commit */
-				INCR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl);
-#			ifdef DEBUG
-			/* Assert that cs->old_mode if uninitialized, never contains a negative value (relied by secshr_db_clnup) */
-			for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
-				assert(0 <= cs->old_mode);
+			blkid = cs->blk;
+			assert(!IS_BITMAP_BLK(blkid) && (blkid == cr_array[0]->blk));
+			csa->backup_in_prog = (BACKUP_NOT_IN_PROGRESS != cnl->nbb);
+			cr = cr_array[0];
+			backup_cr = cr;
+			blk_ptr = (sm_uc_ptr_t)GDS_REL2ABS(cr->buffaddr);
+			backup_blk_ptr = blk_ptr;
+			BG_BACKUP_BLOCK(csa, csd, cnl, cr, cs, blkid, backup_cr, backup_blk_ptr, block_saved,
+					 dummysi->backup_block_saved);
+#			ifdef GTM_SNAPSHOT
+			if (SNAPSHOTS_IN_PROG(csa))
+			{	/* we write the before-image to snapshot file only for FAST_INTEG and not for
+				 * regular integ because the block is going to be marked free at this point
+				 * and in case of a regular integ a before image will be written to the snapshot
+				 * file eventually when the free block gets reused. So the before-image writing
+				 * effectively gets deferred but does happen.
+				 */
+				lcl_ss_ctx = SS_CTX_CAST(cs_addrs->ss_ctx);
+				if (lcl_ss_ctx && FASTINTEG_IN_PROG(lcl_ss_ctx))
+					WRITE_SNAPSHOT_BLOCK(cs_addrs, cr, NULL, blkid, lcl_ss_ctx);
+			}
 #			endif
-			for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
+		}
+	}
+	if (replication)
+	{
+		tjpl->jnl_seqno++;
+		assert(csa->hdr->reg_seqno < tjpl->jnl_seqno);
+		csa->hdr->reg_seqno = tjpl->jnl_seqno;
+		UNIX_ONLY(
+			if (supplementary)
+			{
+				next_strm_seqno = strm_seqno + 1;
+				/* tjpl->strm_seqno[strm_index] = next_strm_seqno; */
+				csa->hdr->strm_reg_seqno[strm_index] = next_strm_seqno;
+			}
+		)
+		VMS_ONLY(
+			if (is_updproc)
+			{
+				jgbl.max_resync_seqno++;
+				csa->hdr->resync_seqno = jgbl.max_resync_seqno;
+			}
+		)
+	}
+	csa->prev_free_blks = csa->ti->free_blocks;
+	csa->t_commit_crit = T_COMMIT_CRIT_PHASE1;
+	if (cw_set_depth)
+	{
+		if (!is_mm)	/* increment counter of # of processes that are actively doing two-phase commit */
+			INCR_WCS_PHASE2_COMMIT_PIDCNT(csa, cnl);
+#		ifdef DEBUG
+		/* Assert that cs->old_mode if uninitialized, never contains a negative value (relied by secshr_db_clnup) */
+		for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
+			assert(0 <= cs->old_mode);
+#		endif
+		for (cs = cw_set, cs_top = cs + cw_set_depth;  cs < cs_top;  ++cs)
+		{
+			mode = cs->mode;
+			assert((gds_t_write_root != mode) || ((cs - cw_set) + 1 == cw_depth));
+			assert((gds_t_committed > mode) ||
+				(gds_t_busy2free == mode) || (gds_t_recycled2free == mode) || (gds_t_write_root == mode));
+			cs->old_mode = (int4)mode;	/* note down before being reset to gds_t_committed */
+			if (gds_t_committed > mode)
 			{
-				mode = cs->mode;
-				assert((gds_t_write_root != mode) || ((cs - cw_set) + 1 == cw_depth));
-				assert((gds_t_committed > mode) ||
-					(gds_t_busy2free == mode) || (gds_t_recycled2free == mode) || (gds_t_write_root == mode));
-				cs->old_mode = (int4)mode;	/* note down before being reset to gds_t_committed */
-				if (gds_t_committed > mode)
+				DEBUG_ONLY(
+					/* Check bitmap status of block we are about to modify.
+					 * Two exceptions are
+					 *	a) DSE which can modify bitmaps at will.
+					 *	b) MUPIP RECOVER writing an AIMG. In this case it is playing
+					 *		forward a DSE action so is effectively like DSE doing it.
+					 */
+					if (!IS_DSE_IMAGE && !write_after_image)
+						bml_status_check(cs);
+				)
+				if (is_mm)
+					status = mm_update(cs, dbtn, blktn, dummysi);
+				else
 				{
-					DEBUG_ONLY(
-						/* Check bitmap status of block we are about to modify.
-						 * Two exceptions are
-						 *	a) DSE which can modify bitmaps at will.
-						 *	b) MUPIP RECOVER writing an AIMG. In this case it is playing
-						 *		forward a DSE action so is effectively like DSE doing it.
-						 */
-						if (!IS_DSE_IMAGE && !write_after_image)
-							bml_status_check(cs);
-					)
-					if (is_mm)
-						status = mm_update(cs, dbtn, blktn, dummysi);
-					else
+					if (csd->dsid)
 					{
-						if (csd->dsid)
+						if (ERR_GVKILLFAIL == t_err)
 						{
-							if (ERR_GVKILLFAIL == t_err)
+							if (cs == cw_set)
 							{
-								if (cs == cw_set)
-								{
-									if ((gds_t_acquired == mode) ||
-									    ((cw_set_depth > 1) && (0 == cw_set[1].level)))
-										rc_cpt_inval();
-									else
-										rc_cpt_entry(cs->blk);
-								}
-							} else	if (0 == cs->level)
-								rc_cpt_entry(cs->blk);
-						}
-						/* Do phase1 of bg_update while holding crit on the database.
-						 * This will lock the buffers that need to be changed.
-						 * Once crit is released, invoke phase2 which will update those locked buffers.
-						 * The exception is if it is a bitmap block. In that case we also do phase2
-						 * while holding crit so the next process to use this bitmap will see a
-						 * consistent copy of this bitmap when it gets crit for commit. This avoids
-						 * the reallocate_bitmap routine from restarting or having to wait for a
-						 * concurrent phase2 construction to finish. When the change request C9E11-002651
-						 * (to reduce restarts due to bitmap collisions) is addressed, we can reexamine
-						 * whether it makes sense to move bitmap block builds back to phase2.
-						 */
-						status = bg_update_phase1(cs, dbtn, dummysi);
-						if ((cdb_sc_normal == status) && (gds_t_writemap == mode))
-						{
-							status = bg_update_phase2(cs, dbtn, blktn, dummysi);
-							if (cdb_sc_normal == status)
-								cs->mode = gds_t_committed;
-						}
+								if ((gds_t_acquired == mode) ||
+								    ((cw_set_depth > 1) && (0 == cw_set[1].level)))
+									rc_cpt_inval();
+								else
+									rc_cpt_entry(cs->blk);
+							}
+						} else	if (0 == cs->level)
+							rc_cpt_entry(cs->blk);
 					}
-					if (cdb_sc_normal != status)
-					{	/* the database is probably in trouble */
-						INVOKE_T_COMMIT_CLEANUP(status, csa);
-						assert(cdb_sc_normal == status);
-						/* At this time "cr_array_index" could be non-zero and a few cache-records might
-						 * have their "in_cw_set" field set to TRUE. We should not reset "in_cw_set" as we
-						 * don't hold crit at this point and also because we might still need those buffers
-						 * pinned until their before-images are backed up in wcs_recover (in case an
-						 * online backup was running while secshr_db_clnup did its job). Reset the
-						 * local variable "cr_array_index" though so we do not accidentally reset the
-						 * "in_cw_set" fields ourselves before the wcs_recover.
-						 */
-						cr_array_index = 0;
-						goto skip_cr_array;	/* hence skip until past "cr_array_index" processing */
+					/* Do phase1 of bg_update while holding crit on the database.
+					 * This will lock the buffers that need to be changed.
+					 * Once crit is released, invoke phase2 which will update those locked buffers.
+					 * The exception is if it is a bitmap block. In that case we also do phase2
+					 * while holding crit so the next process to use this bitmap will see a
+					 * consistent copy of this bitmap when it gets crit for commit. This avoids
+					 * the reallocate_bitmap routine from restarting or having to wait for a
+					 * concurrent phase2 construction to finish. When the change request C9E11-002651
+					 * (to reduce restarts due to bitmap collisions) is addressed, we can reexamine
+					 * whether it makes sense to move bitmap block builds back to phase2.
+					 */
+					status = bg_update_phase1(cs, dbtn, dummysi);
+					if ((cdb_sc_normal == status) && (gds_t_writemap == mode))
+					{
+						status = bg_update_phase2(cs, dbtn, blktn, dummysi);
+						if (cdb_sc_normal == status)
+							cs->mode = gds_t_committed;
 					}
 				}
+				if (cdb_sc_normal != status)
+				{	/* the database is probably in trouble */
+					INVOKE_T_COMMIT_CLEANUP(status, csa);
+					assert(cdb_sc_normal == status);
+					/* At this time "cr_array_index" could be non-zero and a few cache-records might
+					 * have their "in_cw_set" field set to TRUE. We should not reset "in_cw_set" as we
+					 * don't hold crit at this point and also because we might still need those buffers
+					 * pinned until their before-images are backed up in wcs_recover (in case an
+					 * online backup was running while secshr_db_clnup did its job). Reset the
+					 * local variable "cr_array_index" though so we do not accidentally reset the
+					 * "in_cw_set" fields ourselves before the wcs_recover.
+					 */
+					cr_array_index = 0;
+					goto skip_cr_array;	/* hence skip until past "cr_array_index" processing */
+				}
 			}
 		}
-		/* signal secshr_db_clnup/t_commit_cleanup, roll-back is no longer possible */
-		update_trans |= UPDTRNS_TCOMMIT_STARTED_MASK;
-		assert(cdb_sc_normal == status);
-		/* should never increment curr_tn on a frozen database except if DSE */
-		assert(!(csd->freeze UNIX_ONLY(|| (replication && jnlpool.jnlpool_ctl->freeze))) || IS_DSE_IMAGE);
-		INCREMENT_CURR_TN(csd);
-		csa->t_commit_crit = T_COMMIT_CRIT_PHASE2;	/* set this BEFORE releasing crit but AFTER incrementing curr_tn */
-		/* If db is journaled, then db header is flushed periodically when writing the EPOCH record,
-		 * otherwise do it here every HEADER_UPDATE_COUNT transactions.
-		 */
-		assert(!JNL_ENABLED(csa) || (jbp == csa->jnl->jnl_buff));
-		if ((!JNL_ENABLED(csa) || !JNL_HAS_EPOCH(jbp)) && !(csd->trans_hist.curr_tn & (HEADER_UPDATE_COUNT - 1)))
-			fileheader_sync(gv_cur_region);
-		UNIX_ONLY(assert((MUSWP_INCR_ROOT_CYCLE != TREF(in_mu_swap_root_state)) || need_kip_incr));
-		if (need_kip_incr)		/* increment kill_in_prog */
-		{
-			INCR_KIP(csd, csa, kip_csa);
-			need_kip_incr = FALSE;
-#			ifdef UNIX
-			if (MUSWP_INCR_ROOT_CYCLE == TREF(in_mu_swap_root_state))
-			{	/* Increment root_search_cycle to let other processes know that they should redo_root_search. */
-				assert((0 != cw_map_depth) && !TREF(in_gvcst_redo_root_search));
-				csa->nl->root_search_cycle++;
-			}
-#			endif
-		}
-		start_tn = dbtn; /* start_tn temporarily used to store currtn (for bg_update_phase2) before releasing crit */
-		if (free_seen)
-		{	/* need to do below BEFORE releasing crit as we have no other lock on this buffer */
-			VMS_ONLY(assert((BUSY2FREE == free_seen) && (2 <= cr_array_index) && (cr_array_index <= 3)));
-			UNIX_ONLY(assert(2 == cr_array_index));	/* Unlike VMS, no chance to pin a twin for bitmap update */
-			assert((2 == cw_set_depth) && (process_id == cr_array[0]->in_cw_set));
-			UNPIN_CACHE_RECORD(cr_array[0]);
+	}
+	/* signal secshr_db_clnup/t_commit_cleanup, roll-back is no longer possible */
+	update_trans |= UPDTRNS_TCOMMIT_STARTED_MASK;
+	assert(cdb_sc_normal == status);
+	/* should never increment curr_tn on a frozen database except if DSE */
+	assert(!(csd->freeze UNIX_ONLY(|| (replication && jnlpool.jnlpool_ctl->freeze))) || IS_DSE_IMAGE);
+	/* To avoid confusing concurrent processes, MM requires a barrier before incrementing db TN. For BG, cr->in_tend
+	 * serves this purpose so no barrier is needed. See comment in tp_tend.
+	 */
+	if (is_mm)
+		MM_WRITE_MEMORY_BARRIER;
+	INCREMENT_CURR_TN(csd);
+	csa->t_commit_crit = T_COMMIT_CRIT_PHASE2;	/* set this BEFORE releasing crit but AFTER incrementing curr_tn */
+	/* If db is journaled, then db header is flushed periodically when writing the EPOCH record,
+	 * otherwise do it here every HEADER_UPDATE_COUNT transactions.
+	 */
+	assert(!JNL_ENABLED(csa) || (jbp == csa->jnl->jnl_buff));
+	if ((!JNL_ENABLED(csa) || !JNL_HAS_EPOCH(jbp)) && !(csd->trans_hist.curr_tn & (HEADER_UPDATE_COUNT - 1)))
+		fileheader_sync(gv_cur_region);
+	UNIX_ONLY(assert((MUSWP_INCR_ROOT_CYCLE != TREF(in_mu_swap_root_state)) || need_kip_incr));
+	if (need_kip_incr)		/* increment kill_in_prog */
+	{
+		INCR_KIP(csd, csa, kip_csa);
+		need_kip_incr = FALSE;
+#		ifdef UNIX
+		if (MUSWP_INCR_ROOT_CYCLE == TREF(in_mu_swap_root_state))
+		{	/* Increment root_search_cycle to let other processes know that they should redo_root_search. */
+			assert((0 != cw_map_depth) && !TREF(in_gvcst_redo_root_search));
+			csa->nl->root_search_cycle++;
 		}
+#		endif
+	}
+	start_tn = dbtn; /* start_tn temporarily used to store currtn (for bg_update_phase2) before releasing crit */
+	if (free_seen)
+	{	/* need to do below BEFORE releasing crit as we have no other lock on this buffer */
+		VMS_ONLY(assert((BUSY2FREE == free_seen) && (2 <= cr_array_index) && (cr_array_index <= 3)));
+		UNIX_ONLY(assert(2 == cr_array_index));	/* Unlike VMS, no chance to pin a twin for bitmap update */
+		assert((2 == cw_set_depth) && (process_id == cr_array[0]->in_cw_set));
+		UNPIN_CACHE_RECORD(cr_array[0]);
 	}
 	if (!csa->hold_onto_crit)
 		rel_crit(gv_cur_region);
-	assert(!replication || update_trans);
 	if (replication)
 	{
 		assert(jpl->early_write_addr > jpl->write_addr);
@@ -1728,7 +1723,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
 	 */
 	if (SNAPSHOTS_IN_PROG(csa))
 	{
-		assert(update_trans);
 		SS_RELEASE_IF_NEEDED(csa, cnl);
 	}
 
@@ -1741,23 +1735,17 @@ skip_cr_array:
 		backup_buffer_flush(gv_cur_region);
 	if (unhandled_stale_timer_pop)
 		process_deferred_stale();
-	if (update_trans)
+	assert(update_trans);
+	wcs_timer_start(gv_cur_region, TRUE);
+	if (REPL_ALLOWED(csa) && IS_DSE_IMAGE)
 	{
-		wcs_timer_start(gv_cur_region, TRUE);
-		if (REPL_ALLOWED(csa) && IS_DSE_IMAGE)
-		{
-			temp_tn = dbtn + 1;
-			send_msg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_NOTREPLICATED, 4, &temp_tn, LEN_AND_LIT("DSE"), process_id);
-		}
-		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_readwrite, 1);
-		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkread, n_blks_validated);
-		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkwrite, cw_set_depth);
-		GVSTATS_SET_CSA_STATISTIC(csa, db_curr_tn, dbtn);
-	} else
-	{
-		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_readonly, 1);
-		INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkread, n_blks_validated);
+		temp_tn = dbtn + 1;
+		send_msg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_NOTREPLICATED, 4, &temp_tn, LEN_AND_LIT("DSE"), process_id);
 	}
+	INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_readwrite, 1);
+	INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkread, n_blks_validated);
+	INCR_GVSTATS_COUNTER(csa, cnl, n_nontp_blkwrite, cw_set_depth);
+	GVSTATS_SET_CSA_STATISTIC(csa, db_curr_tn, dbtn);
 	/* "secshr_db_clnup/t_commit_cleanup" assume an active non-TP transaction if cw_set_depth is non-zero
 	 * or if update_trans is set to T_COMMIT_STARTED. Now that the transaction is complete, reset these fields.
 	 */
diff --git a/sr_port/tab_gvstats_rec.h b/sr_port/tab_gvstats_rec.h
index 4d9df6f..1c58456 100644
--- a/sr_port/tab_gvstats_rec.h
+++ b/sr_port/tab_gvstats_rec.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2008, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2008, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
diff --git a/sr_port/targ_alloc.c b/sr_port/targ_alloc.c
index ff166fe..72cd6f9 100644
--- a/sr_port/targ_alloc.c
+++ b/sr_port/targ_alloc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,36 +24,55 @@
 #include "min_max.h"
 #include "hashtab_mname.h"
 #include "gtmimagename.h"
+#include "dpgbldir.h"
 
 GBLREF	gv_namehead		*gv_target_list;
 GBLREF	gv_namehead		*gv_target;
 GBLREF	boolean_t		mupip_jnl_recover;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	int			process_exiting;
+GBLREF	gvt_container		*gvt_pending_list;
 
 gv_namehead *targ_alloc(int keysize, mname_entry *gvent, gd_region *reg)
 {
-	gv_namehead	*gvt, *gvt1;
-	int4		index;
-	int4		partial_size;
-	int4		gvn_size;
-	sgmnt_addrs	*csa;
-	ht_ent_mname	*tabent;
-	boolean_t	gvt_hashtab_present, added;
-#ifdef DEBUG
-	ssize_t		first_rec_size, last_rec_size, clue_size;
-#endif
+	gv_namehead		*gvt, *gvt1;
+	int4			index;
+	int4			partial_size;
+	int4			gvn_size;
+	sgmnt_addrs		*csa;
+	ht_ent_mname		*tabent;
+	boolean_t		gvt_hashtab_present, added;
+	enum db_acc_method	acc_meth;
+#	ifdef DEBUG
+	ssize_t			first_rec_size, last_rec_size, clue_size;
+#	endif
 
+	acc_meth = (NULL != reg) ? REG_ACC_METH(reg) : dba_bg;
+	if ((dba_cm == acc_meth) || (dba_usr == acc_meth))
+	{
+		gvt = malloc(SIZEOF(gv_namehead) + gvent->var_name.len);
+		memset(gvt, 0, SIZEOF(gv_namehead) + gvent->var_name.len);
+		gvt->gvname.var_name.addr = (char *)gvt + SIZEOF(gv_namehead);
+		gvt->nct = 0;
+		gvt->collseq = NULL;
+		gvt->regcnt = 1;
+		memcpy(gvt->gvname.var_name.addr, gvent->var_name.addr, gvent->var_name.len);
+		gvt->gvname.var_name.len = gvent->var_name.len;
+		gvt->gvname.hash_code = gvent->hash_code;
+		return gvt;
+	}
+	assert((NULL == reg) || dba_mm == REG_ACC_METH(reg) || (dba_bg == REG_ACC_METH(reg)));
+	assert((NULL == reg) || (reg->max_key_size <= MAX_KEY_SZ));
 	/* Ensure there are no additional compiler introduced filler bytes. This is a safety since a few elements in the
 	 * gv_namehead structure are defined using MAX_BT_DEPTH macros and we want to guard against changes to this macro
 	 * that cause unintended changes to the layout/size of the gv_namehead structure.
 	 */
-	assert(OFFSETOF(gv_namehead, filler_8byte_align1[0]) + SIZEOF(gvt->filler_8byte_align1)
+	assert(OFFSETOF(gv_namehead, filler_8byte_align2[0]) + SIZEOF(gvt->filler_8byte_align2)
 			== OFFSETOF(gv_namehead, last_split_blk_num[0]));
 #	ifdef GTM_TRIGGER
 	assert(OFFSETOF(gv_namehead, last_split_blk_num[0]) + SIZEOF(gvt->last_split_blk_num)
 			== OFFSETOF(gv_namehead, gvt_trigger));
-	GTM64_ONLY(assert(OFFSETOF(gv_namehead, filler_8byte_align2) + SIZEOF(gvt->filler_8byte_align2)
+	GTM64_ONLY(assert(OFFSETOF(gv_namehead, filler_8byte_align3) + SIZEOF(gvt->filler_8byte_align3)
 			== OFFSETOF(gv_namehead, clue));)
 	NON_GTM64_ONLY(assert(OFFSETOF(gv_namehead, trig_mismatch_test_done) + SIZEOF(gvt->trig_mismatch_test_done)
 			== OFFSETOF(gv_namehead, clue));)
@@ -110,8 +129,11 @@ gv_namehead *targ_alloc(int keysize, mname_entry *gvent, gd_region *reg)
 	assert(clue_size == first_rec_size);
 	assert(clue_size == last_rec_size);
 	assert(clue_size == (SIZEOF(gv_key) + keysize));
-	gvt->clue.top = gvt->last_rec->top = gvt->first_rec->top = keysize;
-	gvt->clue.prev = gvt->clue.end = 0;
+	gvt->first_rec->top = keysize;
+	gvt->last_rec->top =keysize;
+	gvt->clue.top = keysize;
+	/* No need to initialize gvt->clue.prev as it is not currently used */
+	gvt->clue.end = 0;
 	/* If "reg" is non-NULL, but "gvent" is NULL, then it means the targ_alloc is being done for the directory tree.
 	 * In that case, set gvt->root appropriately to DIR_ROOT. Else set it to 0. Also assert that the region is
 	 * open in this case with the only exception being if called from mur_forward for non-invasive operations (e.g. EXTRACT).
@@ -119,7 +141,9 @@ gv_namehead *targ_alloc(int keysize, mname_entry *gvent, gd_region *reg)
 	assert((NULL != gvent) || (NULL == reg) || reg->open || (IS_MUPIP_IMAGE && !mupip_jnl_recover));
 	gvt->root = ((NULL != reg) && (NULL == gvent) ? DIR_ROOT : 0);
 	gvt->nct = 0;
+	gvt->nct_must_be_zero = FALSE;
 	gvt->act = 0;
+	gvt->act_specified_in_gld = FALSE;
 	gvt->ver = 0;
 	gvt->regcnt = 1;
 	gvt->collseq = NULL;
@@ -169,7 +193,18 @@ gv_namehead *targ_alloc(int keysize, mname_entry *gvent, gd_region *reg)
 void	targ_free(gv_namehead *gvt)
 {
 	gv_namehead	*prev_gvnh, *next_gvnh;
+#	ifdef DEBUG
+	gvt_container	*gvtc;
+#	endif
 
+#	ifdef DEBUG
+	/* Assert that no container points to the gvt we are about to free up */
+	for (gvtc = gvt_pending_list; NULL != gvtc; gvtc = (gvt_container *)gvtc->next_gvtc)
+	{
+		prev_gvnh = *gvtc->gvt_ptr;
+		assert(prev_gvnh != gvt);
+	}
+#	endif
 	assert(0 == gvt->regcnt);
 	if (gvt == gv_target)
 	{	/* Should not be freeing an actively used global variable. Exceptions are
diff --git a/sr_port/tcp_open.c b/sr_port/tcp_open.c
index 7cf6e49..a6a2c7b 100644
--- a/sr_port/tcp_open.c
+++ b/sr_port/tcp_open.c
@@ -38,14 +38,13 @@
 #include "gtm_string.h"
 #include "gtm_ctype.h"
 #include "gtm_stdio.h"
+#include "gtm_select.h"
+#include "eintr_wrappers.h"
 
 #include "copy.h"
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
-#include "iotcp_select.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "io_params.h"
 #include "util.h"
 #include "gtmmsg.h"
@@ -61,12 +60,9 @@
 const char *hstrerror(int err);
 #endif
 
-GBLREF tcp_library_struct       tcp_routines;
-
 error_def(ERR_GETADDRINFO);
 error_def(ERR_GETNAMEINFO);
 error_def(ERR_INVADDRSPEC);
-error_def(ERR_IPADDRREQ);
 error_def(ERR_SETSOCKOPTERR);
 error_def(ERR_SOCKACPT);
 error_def(ERR_SOCKINIT);
@@ -148,11 +144,11 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 		int 		lsock;
 
 		af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
-		lsock = tcp_routines.aa_socket(af, SOCK_STREAM, IPPROTO_TCP);
+		lsock = socket(af, SOCK_STREAM, IPPROTO_TCP);
 		if (-1 == lsock)
 		{
 			af = AF_INET;
-			if (-1 == (lsock = tcp_routines.aa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
+			if (-1 == (lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
 			{
 				save_errno = errno;
 				errptr = (char *)STRERROR(save_errno);
@@ -174,10 +170,10 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 
 		}
 		/* allow multiple connections to the same IP address */
-		if (-1 == tcp_routines.aa_setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)))
+		if (-1 == setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)))
 		{
 			save_errno = errno;
-			(void)tcp_routines.aa_close(lsock);
+			(void)close(lsock);
 			errptr = (char *)STRERROR(save_errno);
          		errlen = STRLEN(errptr);
                 	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
@@ -185,20 +181,20 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 			assert(FALSE);
 			return -1;
 		}
-		if (-1 == tcp_routines.aa_bind(lsock, ai_ptr->ai_addr, ai_ptr->ai_addrlen))
+		if (-1 == bind(lsock, ai_ptr->ai_addr, ai_ptr->ai_addrlen))
 		{
 			save_errno = errno;
-			(void)tcp_routines.aa_close(lsock);
+			(void)close(lsock);
 			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 				   LEN_AND_LIT("bind()"), CALLFROM, save_errno);
 			return -1;
 		}
 		freeaddrinfo(ai_ptr);
 		/* establish a queue of length MAX_CONN_PENDING for incoming connections */
-		if (-1 == tcp_routines.aa_listen(lsock, MAX_CONN_PENDING))
+		if (-1 == listen(lsock, MAX_CONN_PENDING))
 		{
 			save_errno = errno;
-			(void)tcp_routines.aa_close(lsock);
+			(void)close(lsock);
 			errptr = (char *)STRERROR(save_errno);
 			errlen = STRLEN(errptr);
 			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKLISTEN, 0, ERR_TEXT, 2, errlen, errptr);
@@ -213,6 +209,7 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 			utimeout.tv_sec = timeout;
 			utimeout.tv_usec = 0;
 		}
+		assertpro(FD_SETSIZE > lsock);
 		FD_ZERO(&tcp_fd);
 		while (TRUE)
 		{
@@ -223,7 +220,7 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 				 */
 				FD_SET(lsock, &tcp_fd);
                                 save_utimeout = utimeout;
-				rv = tcp_routines.aa_select(lsock + 1, (void *)&tcp_fd, (void *)0, (void *)0,
+				rv = select(lsock + 1, (void *)&tcp_fd, (void *)0, (void *)0,
 					(NO_M_TIMEOUT == timeout) ? (struct timeval *)0 : &utimeout);
 				save_errno = errno;
                                 utimeout = save_utimeout;
@@ -242,20 +239,20 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 			}
 			if (0 == rv)
 			{
-				(void)tcp_routines.aa_close(lsock);
+				(void)close(lsock);
 				util_out_print("Listening timed out.\n", TRUE);
 				assert(FALSE);
 				return -1;
 			} else  if (0 > rv)
 			{
-				(void)tcp_routines.aa_close(lsock);
+				(void)close(lsock);
 				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 					   LEN_AND_LIT("select()"), CALLFROM, save_errno);
 				assert(FALSE);
 				return -1;
 			}
 			size = SIZEOF(struct sockaddr_storage);
-			sock = tcp_routines.aa_accept(lsock, (struct sockaddr*)(&peer), &size);
+			ACCEPT_SOCKET(lsock, (struct sockaddr*)(&peer), &size, sock);
 			if (FD_INVALID == sock)
 			{
 				save_errno = errno;
@@ -263,7 +260,7 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 				if (ENOBUFS == save_errno)
 					continue;
 #				endif
-				(void)tcp_routines.aa_close(lsock);
+				(void)close(lsock);
 				errptr = (char *)STRERROR(save_errno);
 				errlen = STRLEN(errptr);
 				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_SOCKACPT, 0, ERR_TEXT, 2, errlen, errptr);
@@ -286,7 +283,7 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 			 * temp_addr(remote address), so the entire check should be removed
 			 */
 		}
-		(void)tcp_routines.aa_close(lsock);
+		(void)close(lsock);
 	} else
 	{	/* client side (connection side) */
 		if (NO_M_TIMEOUT != timeout)
@@ -300,11 +297,11 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 		do
 		{
 			if (1 != temp_1)
-				tcp_routines.aa_close(sock);
+				close(sock);
 			assert(NULL != remote_ai_head);
 			for (remote_ai_ptr = remote_ai_head; NULL != remote_ai_ptr; remote_ai_ptr = remote_ai_ptr->ai_next)
 			{
-				sock = tcp_routines.aa_socket(remote_ai_ptr->ai_family, remote_ai_ptr->ai_socktype,
+				sock = socket(remote_ai_ptr->ai_family, remote_ai_ptr->ai_socktype,
 							      remote_ai_ptr->ai_protocol);
 				if (FD_INVALID != sock)
 					break;
@@ -319,10 +316,10 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 				return -1;
 			}
 			/* Allow multiple connections to the same IP address */
-			if (-1 == tcp_routines.aa_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)))
+			if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, SIZEOF(on)))
 			{
 				save_errno = errno;
-				(void)tcp_routines.aa_close(sock);
+				(void)close(sock);
 				errptr = (char *)STRERROR(save_errno);
 				errlen = STRLEN(errptr);
 				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_SETSOCKOPTERR, 5,
@@ -330,13 +327,13 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 				assert(FALSE);
 				return -1;
 			}
-			temp_1 = tcp_routines.aa_connect(sock, remote_ai_ptr->ai_addr, remote_ai_ptr->ai_addrlen);
+			CONNECT_SOCKET(sock, remote_ai_ptr->ai_addr, remote_ai_ptr->ai_addrlen, temp_1);
 			save_errno = errno;
-			/* tcp_routines.aa_connect == gtm_connect should have handled EINTR. Assert that */
+			/* CONNECT_SOCKET should have handled EINTR. Assert that */
 			assert((0 <= temp_1) || (EINTR != save_errno));
 			if ((0 > temp_1) && (ECONNREFUSED != save_errno))
 			{
-				(void)tcp_routines.aa_close(sock);
+				(void)close(sock);
 				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 					   LEN_AND_LIT("connect()"), CALLFROM, save_errno);
 				assert(FALSE);
@@ -355,7 +352,7 @@ int tcp_open(char *host, unsigned short port, int4 timeout, boolean_t passive) /
 		freeaddrinfo(remote_ai_head);
 		if (0 > temp_1) /* out of time */
 		{
-			tcp_routines.aa_close(sock);
+			close(sock);
 			util_out_print("Connection timed out.", TRUE);
 			assert(FALSE);
 			return -1;
diff --git a/sr_port/tp.h b/sr_port/tp.h
index d0681f4..5aca7a5 100644
--- a/sr_port/tp.h
+++ b/sr_port/tp.h
@@ -358,13 +358,16 @@ typedef struct ua_list_struct
 
 #define TP_MAX_NEST	127
 
-/* Note gv_orig_key[i] is assigned to tp_pointer->orig_key which then tries to dereference the "begin", "end", "prev", "top"
+/* Note gv_orig_key is assigned to tp_pointer->orig_key which then tries to dereference the "begin", "end", "prev", "top"
  * 	fields like it were a gv_currkey pointer. Since these members are 2-byte fields, we need atleast 2 byte alignment.
- * We want to be safer and hence give 4-byte alignment by declaring the array as an array of integers.
+ * We want to be safer and hence give 4-byte alignment by declaring it as an array of integers.
+ * Note that the array stores only ONE key since we need to store gv_currkey at the outermost TSTART only since this needs
+ *	to be restored only in case of a TRESTART or TROLLBACK where the objective is to restore it to what the state was
+ *	at the outermost TSTART.
  */
 typedef struct gv_orig_key_struct
 {
-	int4	gv_orig_key[TP_MAX_NEST + 1][DIVIDE_ROUND_UP((SIZEOF(gv_key) + MAX_KEY_SZ + 1), SIZEOF(int4))];
+	int4	gv_orig_key[DIVIDE_ROUND_UP((SIZEOF(gv_key) + MAX_KEY_SZ + 1), SIZEOF(int4))];
 }gv_orig_key_array;
 
 GBLREF	block_id	t_fail_hist_blk[];
diff --git a/sr_port/tp_frame.h b/sr_port/tp_frame.h
index 3d43663..4425643 100644
--- a/sr_port/tp_frame.h
+++ b/sr_port/tp_frame.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -59,7 +59,7 @@ typedef struct tp_frame_struct
 	unsigned int			serial : 1;
 	unsigned int			restartable : 1;
 	unsigned int			old_locks : 1;
-	unsigned int			dlr_t : 1;
+	unsigned int			dlr_t : 1;		/* saved/restored only for OUTERMOST tstart */
 	unsigned int			tp_save_all_flg : 1;
 	unsigned int			implicit_tstart : 1;	/* TRUE if op_tstart was invoked by gvcst_put/gvcst_kill as part of
 								 * trigger processing. Field is inherited across nested op_tstarts
@@ -80,14 +80,15 @@ typedef struct tp_frame_struct
 	unsigned char 			*restart_pc;
 	struct stack_frame_struct	*fp;
 	struct mv_stent_struct		*mvc;
-	struct gv_namehead_struct	*orig_gv_target;
-	struct gv_key_struct		*orig_key;
-	struct gd_addr_struct		*gd_header;
-	struct gd_region_struct		*gd_reg;
+	struct gv_namehead_struct	*orig_gv_target; /* saved/restored only for OUTERMOST tstart */
+	struct gv_key_struct		*orig_key;	/* saved/restored only for OUTERMOST tstart */
+	struct gd_addr_struct		*gd_header;	/* saved/restored only for OUTERMOST tstart */
+	struct gd_region_struct		*gd_reg;	/* saved/restored only for OUTERMOST tstart */
 	struct symval_struct		*sym;
 	struct tp_var_struct		*vars;
-	mval				zgbldir;
+	mval				zgbldir;	/* saved/restored only for OUTERMOST tstart */
 	mval				trans_id;
+	mstr				extnam_str;	/* saved/restored only for OUTERMOST tstart */
 	struct tp_frame_struct 		*old_tp_frame;
 	unsigned char			*restart_ctxt;
 } tp_frame;
diff --git a/sr_port/tp_restart.c b/sr_port/tp_restart.c
index 140aad3..ff2f179 100644
--- a/sr_port/tp_restart.c
+++ b/sr_port/tp_restart.c
@@ -97,6 +97,7 @@ GBLREF	sgmnt_data		*cs_data;
 GBLREF	symval			*curr_symval;
 GBLREF	trans_num		tstart_local_tn;	/* copy of global variable "local_tn" at op_tstart time */
 GBLREF	boolean_t		mupip_jnl_recover;
+GBLREF	mstr			extnam_str;
 #ifdef VMS
 GBLREF	struct chf$signal_array	*tp_restart_fail_sig;
 GBLREF	boolean_t		tp_restart_fail_sig_used;
@@ -130,7 +131,7 @@ static readonly int4		gvname_unknown_len = STR_LIT_LEN(GVNAME_UNKNOWN);
 
 CONDITION_HANDLER(tp_restart_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	/* On Unix, there is only one set of the signal info and this error will handily replace it. For VMS,
 	 * far more subterfuge is required. We will save the signal information and paramters and overlay the
 	 * TPRETRY signal information with it so that the signal will be handled properly. Note also that since
@@ -167,7 +168,7 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 	boolean_t		reset_clues_done = FALSE;
 	mstr			gvname_mstr, reg_mstr;
 	gd_region		*restart_reg, *reg;
-	int			tprestart_rc;
+	int			tprestart_rc, len;
 	enum cdb_sc		status;
 	DCL_THREADGBL_ACCESS;
 
@@ -199,7 +200,7 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 	assert(1 == newlevel);
 	if (!dollar_tlevel)
 	{
-		rts_error(VARLSTCNT(1) ERR_TLVLZERO);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TLVLZERO);
 		return 0; /* for the compiler only -- never executed */
 	}
 #	ifdef GTM_TRIGGER
@@ -272,14 +273,14 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 			}
 			if (cdb_sc_blkmod != status)
 			{
-				send_msg(VARLSTCNT(16) ERR_TPRESTART, 14, reg_mstr.len, reg_mstr.addr,
+				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(16) ERR_TPRESTART, 14, reg_mstr.len, reg_mstr.addr,
 					 t_tries + 1, t_fail_hist, t_fail_hist_blk[t_tries], gvname_mstr.len, gvname_mstr.addr,
 					 0, 0, 0, tp_blkmod_nomod,
 					 (NULL != sgm_info_ptr) ? sgm_info_ptr->num_of_blks : 0,
 					 (NULL != sgm_info_ptr) ? sgm_info_ptr->cw_set_depth : 0, &local_tn);
 			} else
 			{
-				send_msg(VARLSTCNT(16) ERR_TPRESTART, 14, reg_mstr.len, reg_mstr.addr,
+				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(16) ERR_TPRESTART, 14, reg_mstr.len, reg_mstr.addr,
 					 t_tries + 1, t_fail_hist, t_fail_hist_blk[t_tries], gvname_mstr.len, gvname_mstr.addr,
 					 n_pvtmods, n_blkmods, tp_fail_level, tp_fail_n,
 					 sgm_info_ptr->num_of_blks,
@@ -423,7 +424,8 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 					assert(gtm_white_box_test_case_enabled
 					    && (WBTEST_TP_HIST_CDB_SC_BLKMOD == gtm_white_box_test_case_number));
 #					ifdef UNIX
-					send_msg(VARLSTCNT(5) ERR_TPFAIL, 2, hist_index, t_fail_hist, ERR_GVFAILCORE);
+					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_TPFAIL, 2, hist_index, t_fail_hist,
+							ERR_GVFAILCORE);
 					/* Generate core only if not triggering this codepath using white-box tests */
 					DEBUG_ONLY(
 						if (!gtm_white_box_test_case_enabled
@@ -431,8 +433,8 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 					)
 							gtm_fork_n_core();
 #					endif
-					VMS_ONLY(send_msg(VARLSTCNT(4) ERR_TPFAIL, 2, hist_index, t_fail_hist));
-					rts_error(VARLSTCNT(4) ERR_TPFAIL, 2, hist_index, t_fail_hist);
+					VMS_ONLY(send_msg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TPFAIL, 2, hist_index, t_fail_hist));
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TPFAIL, 2, hist_index, t_fail_hist);
 					return 0; /* for the compiler only -- never executed */
 				} else
 				{
@@ -510,7 +512,7 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 			for (tr = tp_reg_list; NULL != tr; tr = tr->fPtr)
 			{
 				reg = tr->reg;
-				if (dba_mm == reg->dyn.addr->acc_meth)
+				if (dba_mm == REG_ACC_METH(reg))
 				{
 					TP_CHANGE_REG_IF_NEEDED(reg);
 					MM_DBFILEXT_REMAP_IF_NEEDED(cs_addrs, gv_cur_region);
@@ -534,7 +536,7 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 	 * stack. If ever other sized blocks are pushed on, a different method will need to be found.
 	 */
 	assert(0 == ((tpstackbase - (unsigned char *)tp_pointer) % SIZEOF(tp_frame))); /* Simple check for above condition */
-	tf = (tp_frame *)(tpstackbase - (newlevel * SIZEOF(tp_frame)));
+	tf = (tp_frame *)(tpstackbase - SIZEOF(tp_frame));
 	assert(NULL != tf);
 	assert(tpstacktop < (unsigned char *)tf);
 #	ifdef GTM_TRIGGER
@@ -584,12 +586,22 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 		tp_unwind(newlevel, RESTART_INVOCATION, &tprestart_rc);
 		assert(dollar_tlevel == newlevel);	/* tp_unwind would have set this */
 		assert(tf == tp_pointer);	/* Needs to be true for now. Revisit when can restart to other than newlevel == 1 */
-		gd_header = tp_pointer->gd_header;
-		gv_target = tp_pointer->orig_gv_target;
-		gv_cur_region = tp_pointer->gd_reg;
+		assert(NULL == tf->old_tp_frame);	/* this is indeed the outermost TSTART */
+		gd_header = tf->gd_header;
+		gv_target = tf->orig_gv_target;
+		gv_cur_region = tf->gd_reg;
 		TP_CHANGE_REG(gv_cur_region);
-		COPY_KEY(gv_currkey, tp_pointer->orig_key);
+		assert(NULL != tf->orig_key);
+		COPY_KEY(gv_currkey, tf->orig_key);
 		DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+		assert(-1 != tf->extnam_str.len);
+		len = tf->extnam_str.len;
+		if (len)
+		{
+			assert(TREF(gv_extname_size) >= len);
+			memcpy(extnam_str.addr, (TREF(gv_tporig_extnam_str)).addr, len);
+		}
+		extnam_str.len = len;
 #		ifdef GTM_TRIGGER
 		/* Maintenance of SFF_IMPLTSTART_CALLD stack frame flag:
 		 * - Set by gtm_trigger when trigger base frame is created. Purpose to prevent MUM_TSTART from restarting
@@ -601,20 +613,20 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 		 * - For TSTARTs done implcitly by triggers, MUM_TSTART would break things so we do not turn off the flag
 		 *   for that type.
 		 */
-		if (!tp_pointer->implicit_tstart)
+		if (!tf->implicit_tstart)
 		{	/* SFF_IMPLTSTART_CALLD validation:
 			 * - This is not a trigger-initiated implicit TSTART.
 			 * - If the flag is is not on, no further checks. Turning off flag is unconditional for best performance.
 			 * - If flag is on, verify the address in the stack frame is in fact being modified so it points to
 			 *   a TSTART instead of the (currently) trigger call point.
 			 */
-			assert(!(tp_pointer->fp->flags & SFF_IMPLTSTART_CALLD) || (tp_pointer->fp->mpc != tp_pointer->restart_pc));
-			tp_pointer->fp->flags &= SFF_IMPLTSTART_CALLD_OFF;
-			DBGTRIGR((stderr, "tp_restart: Removing SFF_IMPLTSTART_CALLD in frame 0x"lvaddr"\n", tp_pointer->fp));
+			assert(!(tf->fp->flags & SFF_IMPLTSTART_CALLD) || (tf->fp->mpc != tf->restart_pc));
+			tf->fp->flags &= SFF_IMPLTSTART_CALLD_OFF;
+			DBGTRIGR((stderr, "tp_restart: Removing SFF_IMPLTSTART_CALLD in frame 0x"lvaddr"\n", tf->fp));
 		}
 #		endif
-		tp_pointer->fp->mpc = tp_pointer->restart_pc;
-		tp_pointer->fp->ctxt = tp_pointer->restart_ctxt;
+		tf->fp->mpc = tf->restart_pc;
+		tf->fp->ctxt = tf->restart_ctxt;
 #		ifdef GTM_TRIGGER
 	} else
 		assert(TPRESTART_STATE_MSTKUNW == tprestart_state);
@@ -681,8 +693,8 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 			 * this frame, op_xnew creates a NEW symtab just for this frame. But when this code
 			 * unwound back to the TSTART, we also unwound the l_symtab this frame was using. So here
 			 * we verify this frame is a simple call frame from the previous and restore the use of its
-			 * l_symtab if so. If not, assertpro/GTMASSERT2. Note the outer SFF_UWN_SYMVAL check keeps
-			 * us from having non-existant l_symtab issues which is possible when we are MUPIP.
+			 * l_symtab if so. If not, assertpro. Note the outer SFF_UWN_SYMVAL check keeps  us from
+			 * having non-existant l_symtab issues which is possible when we are MUPIP.
 			 */
 			if ((frame_pointer->rvector == frame_pointer->old_frame_pointer->rvector)
 			    && (frame_pointer->vartab_ptr == frame_pointer->old_frame_pointer->vartab_ptr))
@@ -697,8 +709,11 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 			frame_pointer->flags &= SFF_UNW_SYMVAL_OFF;
 		}
 	}
-	dollar_truth = tp_pointer->dlr_t;
-	dollar_zgbldir = tp_pointer->zgbldir;
+	assert(tf == tp_pointer);
+	assert(NULL == tf->old_tp_frame);
+	dollar_truth = tf->dlr_t;
+	dollar_zgbldir = tf->zgbldir;
+	assert(0 != dollar_zgbldir.mvtype);
 	GTMTRIG_ONLY(tprestart_state = TPRESTART_STATE_NORMAL);
 	if (FALSE == tf->restartable)
 	{	/* Transation is not restartable. Be sure to leave things in a state that the transaction could
@@ -708,13 +723,14 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 		if (IS_MCODE_RUNNING)
 		{
 			getzposition(&beganHere);
-			send_msg(VARLSTCNT(1) ERR_TRESTNOT);		/* Separate msgs so we get both */
-			send_msg(VARLSTCNT(6) ERR_TRESTLOC, 4, beganHere.str.len, beganHere.str.addr,
-				(TREF(tp_restart_entryref)).str.len, (TREF(tp_restart_entryref)).str.addr);
-			rts_error(VARLSTCNT(8) ERR_TRESTNOT, 0, ERR_TRESTLOC, 4, beganHere.str.len, beganHere.str.addr,
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TRESTNOT);		/* Separate msgs so we get both */
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TRESTLOC, 4, beganHere.str.len, beganHere.str.addr,
 				(TREF(tp_restart_entryref)).str.len, (TREF(tp_restart_entryref)).str.addr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TRESTNOT, 0, ERR_TRESTLOC, 4,
+					beganHere.str.len, beganHere.str.addr,
+					(TREF(tp_restart_entryref)).str.len, (TREF(tp_restart_entryref)).str.addr);
 		} else
-			rts_error(VARLSTCNT(1) ERR_TRESTNOT);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TRESTNOT);
 		return 0; /* for the compiler only -- never executed */
 	}
 	++dollar_trestart;
@@ -736,7 +752,7 @@ int tp_restart(int newlevel, boolean_t handle_errors_internally)
 		 */
 		assert(cdb_sc_normal != status);
 		if (is_updproc && ((cdb_sc_onln_rlbk1 == status) || (cdb_sc_onln_rlbk2 == status)))
-			rts_error(VARLSTCNT(1) ERR_REPLONLNRLBK);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REPLONLNRLBK);
 	)
 	if (handle_errors_internally)
 		REVERT;
diff --git a/sr_port/tp_tend.c b/sr_port/tp_tend.c
index 99182d8..e49d443 100644
--- a/sr_port/tp_tend.c
+++ b/sr_port/tp_tend.c
@@ -1701,6 +1701,16 @@ boolean_t	tp_tend()
 			csa->t_commit_crit = T_COMMIT_CRIT_PHASE2;	/* set this BEFORE releasing crit */
 			/* should never increment curr_tn on a frozen database */
 			assert(!(csd->freeze UNIX_ONLY(|| (replication && IS_REPL_INST_FROZEN))));
+			/* For MM, barrier ensures blocks updates complete before incrementing db TN. Otherwise concurrent
+			 * processes could note a premature db TN value in gvcst_search and later fail to detect a block
+			 * modification.
+			 * For BG, no barrier is needed. We increment db TN only after pinning the relevant buffers.
+			 * Concurrent processes wait for the buffer to be unpinned before accessing it and so never mistake
+			 * the old contents for the new contents. The acts of pinning and unpinning use compswap which does the
+			 * needed memory barriers.
+			 */
+			if (is_mm)
+				MM_WRITE_MEMORY_BARRIER;
 			INCREMENT_CURR_TN(csd);
 #			ifdef GTM_TRIGGER
 			if (csa->incr_db_trigger_cycle)
@@ -2110,8 +2120,7 @@ enum cdb_sc	recompute_upd_array(srch_blk_status *bh, cw_set_element *cse)
 			segment_update_array_size = UA_NON_BM_SIZE(cs_data);
 			ENSURE_UPDATE_ARRAY_SPACE(segment_update_array_size);
 			BLK_INIT(bs_ptr, bs1);
-			if (0 != rc_set_fragment)
-				GTMASSERT;
+			assertpro(0 == rc_set_fragment);
 			BLK_SEG(bs_ptr, buffaddr + SIZEOF(blk_hdr), bh->curr_rec.offset - SIZEOF(blk_hdr));
 			BLK_ADDR(curr_rec_hdr, SIZEOF(rec_hdr), rec_hdr);
 			curr_rec_hdr->rsiz = new_rec_size;
@@ -2256,11 +2265,28 @@ boolean_t	reallocate_bitmap(sgm_info *si, cw_set_element *bml_cse)
 		if ((gds_t_acquired != cse->mode) || (ROUND_DOWN2(cse->blk, BLKS_PER_LMAP) != bml))
 			continue;
 		assert(*b_ptr == (cse->blk - bml));
+		/* If bm_find_blk is passed a hint (first arg) it assumes it is less than map_size and gives invalid results (for
+		 * values >= map_size). Instead of changing bm_find_blk we do the check here and assert that "hint" < "map_size" in
+		 * bm_find_blk.
+		 */
+		if (offset >= map_size)
+		{	/* We have a block that needs to be reallocated but there are no free blocks left in this local bitmap.
+			 * Note: It's possible for `offset' to be greater than `map_size' if the cache record holding the bitmap
+			 * gets reused for a non-bitmap block in which case donot_commit should be set (and hence asserted here).
+			 * In such a case, we return FALSE causing the caller to restart the transaction with a cdb_sc_bmlmod
+			 * even though it's a case of cdb_sc_lostbmlcr.
+			 */
+			assert((offset == map_size) || (TREF(donot_commit) & DONOTCOMMIT_REALLOCATE_BITMAP_BMLMOD));
+			return FALSE;
+		}
 		free_bit = bm_find_blk(offset, (sm_uc_ptr_t)bml_cse->old_block + SIZEOF(blk_hdr), map_size, &blk_used);
 		if (MAP_RD_FAIL == free_bit || NO_FREE_SPACE == free_bit)
 			return FALSE;
 		cse->blk = bml + free_bit;
-		assert(cse->blk < total_blks);
+#		ifdef DEBUG
+		if (cse->blk >= total_blks)
+			TREF(donot_commit) |= DONOTCOMMIT_REALLOCATE_BITMAP_BMLMOD;
+#		endif
 		blk_used ? BIT_SET_RECYCLED_AND_CLEAR_FREE(cse->blk_prior_state)
 			 : BIT_CLEAR_RECYCLED_AND_SET_FREE(cse->blk_prior_state);
 		/* re-point before-images into cse->old_block if necessary; if not available restart by returning FALSE */
@@ -2313,14 +2339,6 @@ boolean_t	reallocate_bitmap(sgm_info *si, cw_set_element *bml_cse)
 		}
 		*b_ptr++ = free_bit;
 		offset = free_bit + 1;
-		if (offset >= map_size)
-		{	/* If bm_find_blk is passed a hint (first arg) it assumes it is less than map_size
-			 * and gives invalid results (like values >= map_size). Instead of changing bm_find_blk
-			 * we do the check here and assert that "hint" < "map_size" in bm_find_blk.
-			 */
-			assert(offset == map_size);
-			return FALSE;
-		}
 	}
 	if (cse == bmp_begin_cse)
 	{
diff --git a/sr_port/trans_code.c b/sr_port/trans_code.c
index fc8ae78..17d3367 100644
--- a/sr_port/trans_code.c
+++ b/sr_port/trans_code.c
@@ -84,7 +84,7 @@ void trans_code(void);
 
 CONDITION_HANDLER(zyerr_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (indr_stringpool.base == stringpool.base)
 	{ /* switch to run time stringpool */
 		indr_stringpool = stringpool;
@@ -129,7 +129,7 @@ CONDITION_HANDLER(trans_code_ch)
 	mval		dummy;
 	int		level2go;
 
-	START_CH;
+	START_CH(TRUE);
 	/* Treat $ZTRAP (and DEVICE exception action) as the target entryref for an implicit GOTO */
 	if (DUMPABLE 				/* fatal error; we test for STACKOFLOW as part of DUMPABLE test */
 	    || (int)ERR_STACKCRIT == SIGNAL 	/* Successfully compiled ${Z,E}TRAP code but encountered STACK error while
diff --git a/sr_port/unw_mv_ent.c b/sr_port/unw_mv_ent.c
index 5a5b474..7f84895 100644
--- a/sr_port/unw_mv_ent.c
+++ b/sr_port/unw_mv_ent.c
@@ -16,6 +16,7 @@
 #endif
 
 #include "gtm_string.h"
+#include "gtm_unistd.h"
 
 #include "lv_val.h"
 #include <rtnhdr.h>
@@ -42,8 +43,6 @@
 #include "dpgbldir_sysops.h"
 #include "error_trap.h"		/* for STACK_ZTRAP_EXPLICIT_NULL macro */
 #include "op.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #ifdef UNIX
@@ -64,8 +63,6 @@ GBLREF lv_val			*active_lv;
 GBLREF gv_key			*gv_currkey;
 GBLREF gv_namehead		*gv_target;
 GBLREF gd_addr			*gd_header;
-GBLREF gd_binding		*gd_map;
-GBLREF gd_binding		*gd_map_top;
 GBLREF dollar_ecode_type	dollar_ecode;
 GBLREF dollar_stack_type	dollar_stack;
 GBLREF mval			dollar_etrap;
@@ -96,7 +93,6 @@ GBLREF ch_ret_type		(*ch_at_trigger_init)();
 #endif
 GBLREF unsigned char		*restart_pc, *restart_ctxt;
 GBLREF mval			*alias_retarg;
-GBLREF tcp_library_struct	tcp_routines;
 GBLREF int			merge_args;
 GBLREF uint4			zwrtacindx;
 GBLREF merge_glvn_ptr		mglvnp;
@@ -153,17 +149,14 @@ void unw_mv_ent(mv_stent *mv_st_ent)
 			} else if (mv_st_ent->mv_st_cont.mvs_msav.addr == &dollar_zgbldir)
 			{
 				if (0 != dollar_zgbldir.str.len)
-				{
 					gd_header = zgbldir(&dollar_zgbldir);
-					/* update the gd_map */
-					SET_GD_MAP;
-				} else
-				{
-					dpzgbini();
-					gd_header = NULL;
-				}
+				else
+					dpzgbini();	/* sets gd_header to NULL */
 				if (gv_currkey)
+				{
 					gv_currkey->base[0] = 0;
+					gv_currkey->prev = gv_currkey->end = 0;
+				}
 				if (gv_target)
 					gv_target->clue.end = 0;
 			}
@@ -385,8 +378,10 @@ void unw_mv_ent(mv_stent *mv_st_ent)
 						{	/* clean up socketptr structure */
 							socketptr = (socket_struct *)mv_st_ent->mv_st_cont.mvs_zintdev.socketptr;
 							if (socket_connect_inprogress == socketptr->state
-								&& (FD_INVALID != socketptr->sd))
-								tcp_routines.aa_close(socketptr->sd);
+									&& (FD_INVALID != socketptr->sd))
+								close(socketptr->sd);
+							if (NULL != socketptr->remote.ai_head)
+								freeaddrinfo(socketptr->remote.ai_head);
 							if (NULL != socketptr->zff.addr)
 								free(socketptr->zff.addr);
 							if (NULL != socketptr->buffer)
@@ -400,7 +395,7 @@ void unw_mv_ent(mv_stent *mv_st_ent)
 					mv_st_ent->mv_st_cont.mvs_zintdev.io_ptr = NULL;
 					return;
 				default:
-					GTMASSERT;	/* No other device should be here */
+					assertpro(FALSE);	/* No other device should be here */
 			}
 			break;
 		case MVST_ZINTCMD:
@@ -535,7 +530,7 @@ void unw_mv_ent(mv_stent *mv_st_ent)
 			zwrhtab = mv_st_ent->mv_st_cont.mvs_mrgzwrsv.save_zwrhtab;
 			return;
 		default:
-			GTMASSERT;
+			assertpro(mv_st_ent->mv_st_type != mv_st_ent->mv_st_type);
 			break;
 	}
 	return; /* This should never get executed, added to make compiler happy */
diff --git a/sr_port/updhelper_reader.c b/sr_port/updhelper_reader.c
index 977cf5c..ad4102e 100644
--- a/sr_port/updhelper_reader.c
+++ b/sr_port/updhelper_reader.c
@@ -120,8 +120,7 @@ int updhelper_reader(void)
 	call_on_signal = updhelper_reader_sigstop;
 	updhelper_init(UPD_HELPER_READER);
 	repl_log(updhelper_log_fp, TRUE, TRUE, "Helper reader started. PID %d [0x%X]\n", process_id, process_id);
-	GVKEY_INIT(gv_currkey, gv_keysize);
-	GVKEY_INIT(gv_altkey, gv_keysize);
+	GVKEYSIZE_INIT_IF_NEEDED;       /* sets "gv_keysize", "gv_currkey" and "gv_altkey" (if not already done) */
 	last_pre_read_offset = 0;
 	continue_reading = TRUE;
 	do
@@ -148,7 +147,7 @@ boolean_t updproc_preread(void)
 	int			rec_len, cnt, retries, spins, maxspins, key_len;
 	enum jnl_record_type	rectype;
 	mstr_len_t		val_len;
-	mstr			mname;
+	mname_entry		gvname;
 	sm_uc_ptr_t		readaddrs;	/* start of current rec in pool */
 	sm_uc_ptr_t		limit_readaddrs;
 	jnl_record		*rec;
@@ -167,6 +166,7 @@ boolean_t updproc_preread(void)
 	upd_proc_local_ptr_t	upd_proc_local;
 	gtmrecv_local_ptr_t	gtmrecv_local;
 	upd_helper_ctl_ptr_t	upd_helper_ctl;
+	gvnh_reg_t		*gvnh_reg;
 #ifdef REPL_DEBUG
 	unsigned char 		buff[MAX_ZWR_KEY_SZ], *end;
 	uint4			write, write_wrap;
@@ -335,32 +335,47 @@ boolean_t updproc_preread(void)
 					 */
 					memcpy(lcl_key, keystr->text, key_len);
 					if ((0 < key_len) && (0 == lcl_key[key_len - 1])
-						&& (upd_good_record == updproc_get_gblname(lcl_key, key_len, gv_mname, &mname))
+						&& (upd_good_record == updproc_get_gblname(lcl_key, key_len, gv_mname, &gvname))
 						&& (key_len == keystr->length))	/* If the shared copy changed underneath us, what
 										   we copied over is potentially a bad record */
 					{
 						TREF(tqread_nowait) = FALSE;	/* don't screw up gvcst_root_search */
-						UPD_GV_BIND_NAME_APPROPRIATE(gd_header, mname, lcl_key, key_len); /* if ^#t do
-													       special processing */
+						UPD_GV_BIND_NAME_APPROPRIATE(gd_header, gvname, lcl_key, key_len, gvnh_reg);
+							/* if ^#t do special processing */
+						memcpy(gv_currkey->base, lcl_key, key_len);
+						gv_currkey->end = key_len;
+						gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
+						/* If gvname is "^#t", then gvnh_reg is NULL. This global for sure does NOT
+						 * span multiple regions. So treat it accordingly.
+						 */
+						if (NULL != gvnh_reg)
+						{	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+							 * (e.g. setting gv_cur_region for spanning globals).
+							 */
+							GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header,
+													gv_currkey, reg);
+									/* "reg" is a dummy argument above */
+						}
 						/* the above would have set gv_target and gv_cur_region appropriately */
+						DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
 						if (!gv_target->root)
 							continue;
-						csa = &FILE_INFO(gv_cur_region)->s_addrs;/* we modify n_pre_read for the region we
-											    read on our last try. This is done for
-											    performance reasons so that n_pre_read
-											    doesn't have to be an atomic counter */
-						memcpy(gv_currkey->base, lcl_key, key_len);
 						if ((readaddrs + rec_len > recvpool.recvdata_base + upd_proc_local->read
 						     && !(was_wrapped && !recvpool_ctl->wrapped))
 						    && (0 != gv_currkey->base[0]
 							&&  0 == gv_currkey->base[key_len - 1]
-							&&  0 == gv_currkey->base[mname.len]))
+							&&  0 == gv_currkey->base[gvname.var_name.len]))
 						{
 							gv_currkey->base[key_len] = 0; 	/* second null of a key terminator */
 							gv_currkey->end = key_len;
 							disk_blk_read = FALSE;
 							DEBUG_ONLY(num_helped++);
 							TREF(tqread_nowait) = TRUE;
+							/* we modify n_pre_read for the region we read on our last try.
+							 * This is done for performance reasons so that n_pre_read
+							 * doesn't have to be an atomic counter.
+							 */
+							csa = &FILE_INFO(gv_cur_region)->s_addrs;
 							assert(!csa->now_crit);
 							status = gvcst_search(gv_currkey, NULL);
 							assert(!csa->now_crit);
diff --git a/sr_port/updproc.c b/sr_port/updproc.c
index da2456c..1781596 100644
--- a/sr_port/updproc.c
+++ b/sr_port/updproc.c
@@ -260,7 +260,7 @@ CONDITION_HANDLER(updproc_ch)
 	unsigned char	seq_num_str[32], *seq_num_ptr;
 	unsigned char	seq_num_strx[32], *seq_num_ptrx;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 #		if defined(DEBUG) && defined(DEBUG_UPDPROC_TPRETRY)
@@ -270,7 +270,7 @@ CONDITION_HANDLER(updproc_ch)
 			INT8_PRINT(recvpool.upd_proc_local->read_jnl_seqno),
 			INT8_PRINTX(recvpool.upd_proc_local->read_jnl_seqno));
 		/* This is a kludge. We can come here from 2 places.
-		 *	( i) From a call to t_retry which does a rts_error(ERR_TPRETRY)
+		 *	( i) From a call to t_retry which does a rts_error_csa(ERR_TPRETRY)
 		 *	(ii) From updproc_actions() where immediately after op_tcommit we detect that dollar_tlevel is non-zero.
 		 * In the first case, we need to do a tp_restart. In the second, op_tcommit would have already done it for us.
 		 * The way we detect the second case is from the value of first_sgm_info since it is NULLified in tp_restart.
@@ -284,7 +284,7 @@ CONDITION_HANDLER(updproc_ch)
 			NON_GTMTRIG_ONLY(assert(INVALID_GV_TARGET == reset_gv_target);)
 			reset_gv_target = INVALID_GV_TARGET; /* see "trigger_item_tpwrap_ch" similar code for why this is needed */
 #			ifdef UNIX
-			if (ERR_REPLONLNRLBK == SIGNAL) /* tp_restart did rts_error(ERR_REPLONLNRLBK) */
+			if (ERR_REPLONLNRLBK == SIGNAL) /* tp_restart did rts_error_csa(ERR_REPLONLNRLBK) */
 				set_onln_rlbk_flg = TRUE;
 			if ((ERR_TPRETRY == SIGNAL) || (ERR_REPLONLNRLBK == SIGNAL))
 #			elif defined VMS
@@ -532,7 +532,7 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 	seq_num			jnlpool_ctl_seqno, rec_strm_seqno, strm_seqno;
 	char			*val_ptr;
 	jnl_string		*keystr;
-	mstr			mname;
+	mname_entry		gvname;
 	char			*key, *keytop;
 	gv_key			*gv_failed_key = NULL, *gv_failed_key_ptr;
 	unsigned char		*endBuff, fmtBuff[MAX_ZWR_KEY_SZ];
@@ -555,13 +555,14 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 #	endif
 	jnl_private_control	*jpc;
 	gld_dbname_list		*curr;
-	gd_region		*save_reg;
+	gd_region		*save_reg, *dummy_reg;
 	uint4			write_wrap, cntr, last_nullsubs, last_subs, keyend;
 #	ifdef GTM_TRIGGER
 	uint4			nodeflags;
 	boolean_t		primary_has_trigdef, secondary_has_trigdef;
 	const char		*trigdef_inst = NULL, *no_trigdef_inst = NULL;
 #	endif
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -603,6 +604,10 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 		suppl_propagate_primary = FALSE;
 	}
 #	endif
+	/* Since update process does not invoke op_gvname but directly invokes op_gvput/kill etc. we set TREF(gd_targ_addr)
+	 * here (this is normally set by op_gvname in mumps).
+	 */
+	TREF(gd_targ_addr) = gd_header;
 	while (TRUE)
 	{
 		incr_seqno = FALSE;
@@ -696,8 +701,8 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 		if (temp_read >= write_wrap)
 		{
 			assert(temp_read == write_wrap);
-			if (0 < tupd_num)	/* receive pool cannot wrap in the middle of TP */
-				GTMASSERT;	/* see process_tr_buff in gtmrecv_process for why */
+			/* receive pool cannot wrap in the middle of TP; See process_tr_buff in gtmrecv_process for why */
+			assertpro(0 == tupd_num);
 			if (FALSE == recvpool.recvpool_ctl->wrapped)
 			{ 	/* Update process in keeping up with receiver server, notices that there was a wrap
 				 * (thru write and write_wrap). It has to wait till receiver sets wrapped.
@@ -929,7 +934,7 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 				)
 				key_len = keystr->length;	/* local copy of shared recvpool key */
 				if ((MAX_KEY_SZ >= key_len && 0 < key_len && 0 == keystr->text[key_len - 1]) &&
-					(upd_good_record == updproc_get_gblname(keystr->text, key_len, gv_mname, &mname)))
+					(upd_good_record == updproc_get_gblname(keystr->text, key_len, gv_mname, &gvname)))
 				{
 					if (IS_SET(rectype))
 					{
@@ -1081,8 +1086,22 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 			} else if (IS_SET_KILL_ZKILL_ZTRIG(rectype))
 			{
 				key = keystr->text;
-				UPD_GV_BIND_NAME_APPROPRIATE(gd_header, mname, key, key_len);	/* if ^#t do special processing */
+				UPD_GV_BIND_NAME_APPROPRIATE(gd_header, gvname, key, key_len, gvnh_reg);
+					/* if ^#t do special processing */
+				memcpy(gv_currkey->base, keystr->text, keystr->length);
+				gv_currkey->end = keystr->length;
+				gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
+				/* If gvname is "^#t", then gvnh_reg is NULL. This global for sure does NOT
+				 * span multiple regions. So treat it accordingly.
+				 */
+				if (NULL != gvnh_reg)
+				{	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+					 * (e.g. setting gv_cur_region for spanning globals).
+					 */
+					GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey, dummy_reg);
+				}
 				/* the above would have set gv_target and gv_cur_region appropriately */
+				DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
 				csa = &FILE_INFO(gv_cur_region)->s_addrs;
 				if (!REPL_ALLOWED(csa))
 				{	/* Replication/Journaling is NOT enabled on the database file that the current
@@ -1092,12 +1111,11 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 					 * the primary database.
 					 */
 					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_UPDREPLSTATEOFF, 4,
-						mname.len, mname.addr, DB_LEN_STR(gv_cur_region));
+						gvname.var_name.len, gvname.var_name.addr, DB_LEN_STR(gv_cur_region));
 					/* Shut down the update process normally */
 					upd_proc_local->upd_proc_shutdown = SHUTDOWN;
 					break;
 				}
-				memcpy(gv_currkey->base, keystr->text, keystr->length);
 				gv_currkey->base[keystr->length] = 0; 	/* second null of a key terminator */
 				gv_currkey->end = keystr->length;
 				if (gv_currkey->end + 1 > gv_cur_region->max_key_size)
@@ -1214,8 +1232,9 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 								no_trigdef_inst = "originating";
 							}
 							send_msg_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_TRIGDEFNOSYNC, 7,
-									mname.len, mname.addr, LEN_AND_STR(trigdef_inst),
-									LEN_AND_STR(no_trigdef_inst), &jnl_seqno);
+								gvname.var_name.len, gvname.var_name.addr,
+								LEN_AND_STR(trigdef_inst), LEN_AND_STR(no_trigdef_inst),
+								&jnl_seqno);
 						}
 					}
 #					endif
@@ -1279,8 +1298,8 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 			temp_write = 0;
 			upd_rec_seqno = tupd_num = tcom_num = 0;
 			/* KEY2BIG and REC2BIG are cases for which we need to make sure it is not a transmission hiccup before we
-			 * go ahead and do the rts_error(GVSUBOFLOW) or rts_error(REC2BIG). That is the reason we give those two
-			 * errors a second chance. Other errors are handled by either throwing an rts_error or asking for an
+			 * go ahead and do the rts_error_csa(GVSUBOFLOW) or rts_error_csa(REC2BIG). That is the reason we give those
+			 * two errors a second chance. Other errors are handled by either throwing an rts_error or asking for an
 			 * unconditional re-transmission (as opposed to only two attempts for GVSUBOFLOW and REC2BIG). By asking for
 			 * a re-transmission we increase our confidence level that this is a configuration issue (with smaller
 			 * keysize on the secondary) and proceed with an rts_error if we see the same symptom. It is possible we
@@ -1371,7 +1390,7 @@ void updproc_actions(gld_dbname_list *gld_db_files)
 					repl_log(updproc_log_fp, TRUE, TRUE,
 						"JNLSEQNO of last transaction written to journal pool = "INT8_FMT" "INT8_FMTX"\n",
 						INT8_PRINT(jnlpool_ctl_seqno), INT8_PRINTX(jnlpool_ctl_seqno));
-					GTMASSERT;
+					assertpro(FALSE && (upd_proc_local->read_jnl_seqno == jnlpool_ctl_seqno));
 				}
 			}
 		}
diff --git a/sr_port/updproc.h b/sr_port/updproc.h
index 163cd40..6134e84 100644
--- a/sr_port/updproc.h
+++ b/sr_port/updproc.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -33,19 +33,19 @@ enum upd_bad_trans_type
 	upd_bad_key
 };
 
-#define	UPD_GV_BIND_NAME(GD_HEADER, MNAME)	GV_BIND_NAME_AND_ROOT_SEARCH(GD_HEADER, &MNAME)
+#define	UPD_GV_BIND_NAME(GD_HEADER, GVNAME, GVNH_REG)	GV_BIND_NAME_AND_ROOT_SEARCH(GD_HEADER, &GVNAME, GVNH_REG)
 
 #ifdef GTM_TRIGGER
-#define UPD_GV_BIND_NAME_APPROPRIATE(GD_HEADER, MNAME, KEY, KEYLEN)					\
+#define UPD_GV_BIND_NAME_APPROPRIATE(GD_HEADER, GVNAME, KEY, KEYLEN, GVNH_REG)				\
 {													\
 	char			*tr_ptr;								\
-	gv_namehead		*hasht_tree;								\
-	mstr			gbl_name;								\
+	mname_entry		gvname1;								\
 	int			tr_len;									\
-	mname_entry		gvent;									\
+	sgmnt_addrs		*csa;									\
+													\
 	GBLREF boolean_t	dollar_ztrigger_invoked;						\
 													\
-	if (IS_MNAME_HASHT_GBLNAME(MNAME))								\
+	if (IS_MNAME_HASHT_GBLNAME(GVNAME.var_name))							\
 	{	/* gbl is ^#t. In this case, do special processing. Look at the first subscript and	\
 		 * bind to the region mapped to by that global name (not ^#t).				\
 		 */											\
@@ -58,12 +58,12 @@ enum upd_bad_trans_type
 		assert((HASHT_GBL_CHAR1 == *tr_ptr) || ('%' == *tr_ptr) || (ISALPHA_ASCII(*tr_ptr)));	\
 		if (HASHT_GBL_CHAR1 != *tr_ptr)								\
 		{											\
-			gbl_name.addr = tr_ptr;								\
-			gbl_name.len = STRLEN(tr_ptr);							\
-			GV_BIND_NAME_ONLY(GD_HEADER, &gbl_name);					\
+			gvname1.var_name.addr = tr_ptr;							\
+			gvname1.var_name.len = STRLEN(tr_ptr);						\
+			COMPUTE_HASH_MNAME(&gvname1);							\
+			GV_BIND_NAME_ONLY(GD_HEADER, &gvname1, GVNH_REG);				\
 			csa = cs_addrs;									\
-			SETUP_TRIGGER_GLOBAL;								\
-			gv_target = hasht_tree;								\
+			SET_GVTARGET_TO_HASHT_GBL(csa);							\
 			if (!dollar_ztrigger_invoked)							\
 				dollar_ztrigger_invoked = TRUE;						\
 			csa->incr_db_trigger_cycle = TRUE;						\
@@ -71,13 +71,15 @@ enum upd_bad_trans_type
 		} else											\
 		{											\
 			SWITCH_TO_DEFAULT_REGION;							\
+			/* Special case for ^#t. Set GVNH_REG to NULL. Caller needs to check this */	\
+			GVNH_REG = NULL;								\
 		}											\
 		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;							\
 	} else												\
-		UPD_GV_BIND_NAME(GD_HEADER, MNAME);							\
+		UPD_GV_BIND_NAME(GD_HEADER, GVNAME, GVNH_REG);						\
 }
 #else
-#define UPD_GV_BIND_NAME_APPROPRIATE(GD_HEADER, MNAME, KEY, KEYLEN)	UPD_GV_BIND_NAME(GD_HEADER, MNAME)
+#define UPD_GV_BIND_NAME_APPROPRIATE(GD_HEADER, GVNAME, KEY, KEYLEN, GVNH_REG)	UPD_GV_BIND_NAME(GD_HEADER, GVNAME, GVNH_REG)
 #endif
 
 int		updproc(void);
diff --git a/sr_port/updproc_get_gblname.c b/sr_port/updproc_get_gblname.c
index f3e8bf5..b75cab0 100644
--- a/sr_port/updproc_get_gblname.c
+++ b/sr_port/updproc_get_gblname.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2005, 2007 Fidelity Information Services, Inc	*
+ *	Copyright 2005, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,13 +31,12 @@
 #include "updproc.h"
 #include "updproc_get_gblname.h"
 #include "min_max.h"
+#include "hashtab_mname.h"
 
-/*
- * This rourine validates the key from journal record copying to memory pointed updproc_get_gblname
- * The mname is an mstr for the global name (to be used for gv_bind_name) is set here.
+/* This routine validates the key from journal record copying to memory pointed updproc_get_gblname
+ * "gvname" is an mname_entry pointing to the global name (to be used for gv_bind_name) is set here.
  */
-
-enum upd_bad_trans_type updproc_get_gblname(char *src_ptr, int key_len, char *gv_mname, mstr *mname)
+enum upd_bad_trans_type updproc_get_gblname(char *src_ptr, int key_len, char *gv_mname, mname_entry *gvname)
 {
 	char			*dest_ptr;
 	int			cplen;
@@ -52,7 +51,8 @@ enum upd_bad_trans_type updproc_get_gblname(char *src_ptr, int key_len, char *gv
 	} while (cplen);
 	if (0 != (*(dest_ptr - 1)) || (0 >= dest_ptr - 1 - gv_mname))
 		return upd_bad_mname_size;
-	mname->addr = (char *)gv_mname;
-	mname->len = INTCAST(dest_ptr - 1 - (char *)gv_mname);
+	gvname->var_name.addr = (char *)gv_mname;
+	gvname->var_name.len = INTCAST(dest_ptr - 1 - (char *)gv_mname);
+	COMPUTE_HASH_MNAME(gvname);
 	return upd_good_record;
 }
diff --git a/sr_port/updproc_get_gblname.h b/sr_port/updproc_get_gblname.h
index 80cd563..8967d8d 100644
--- a/sr_port/updproc_get_gblname.h
+++ b/sr_port/updproc_get_gblname.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2005 Fidelity Information Services, Inc	*
+ *	Copyright 2005, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,6 +12,6 @@
 #ifndef UPDPROC_GET_GBLNAME_INCLUDED
 #define UPDPROC_GET_GBLNAME_INCLUDED
 
-enum upd_bad_trans_type updproc_get_gblname(char *src_ptr, int key_len, char *gv_mname, mstr *mname);
+enum upd_bad_trans_type updproc_get_gblname(char *src_ptr, int key_len, char *gv_mname, mname_entry *gvname);
 
 #endif /* UPDPROC_GET_GBLNAME_INCLUDED */
diff --git a/sr_port/updproc_init.c b/sr_port/updproc_init.c
index eecd1d0..da1d842 100644
--- a/sr_port/updproc_init.c
+++ b/sr_port/updproc_init.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,6 +42,9 @@
 #include "read_db_files_from_gld.h"
 #include "updproc.h"
 #include "repl_dbg.h"
+#ifdef VMS
+#include "dpgbldir_sysops.h"	/* for dpzgbini prototype */
+#endif
 
 GBLREF	boolean_t	pool_init;
 GBLREF	gd_addr		*gd_header;
@@ -80,7 +83,7 @@ int updproc_init(gld_dbname_list **gld_db_files , seq_num *start_jnl_seqno)
 		if (REPL_SEM_NOT_GRABBED)
 			return UPDPROC_EXISTS;
 		else
-			rts_error(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
 				RTS_ERROR_LITERAL("Receive pool semop error"), UNIX_ONLY(save_errno) VMS_ONLY(REPL_SEM_ERRNO));
 	}
 	jnlpool_init((jnlpool_user)GTMPROC, (boolean_t)FALSE, (boolean_t *)NULL);
@@ -90,7 +93,12 @@ int updproc_init(gld_dbname_list **gld_db_files , seq_num *start_jnl_seqno)
 	repl_log(updproc_log_fp, TRUE, TRUE, "Attached to existing recvpool with shmid = [%d] and semid = [%d]\n",
 			jnlpool.repl_inst_filehdr->recvpool_shmid, jnlpool.repl_inst_filehdr->recvpool_semid);
 #	endif
-	gvinit();	/* get the desired global directory and update the gd_map */
+	/* In case of Unix dpzgbini() is called as part of gtm_startup which in turn is invoked by init_gtm.
+	 * In VMS though, this is not the case. But the update process needs to initialize dollar_zgbldir as
+	 * tp_restart relies on this (fails an assert otherwise). So do this initialization now for VMS.
+	 */
+	VMS_ONLY(dpzgbini();)
+	gvinit();	/* get the desired global directory */
 	*gld_db_files = read_db_files_from_gld(gd_header);/* read all the database files to be opened in this global directory */
 	if (!updproc_open_files(gld_db_files, start_jnl_seqno)) /* open and initialize all regions */
 		mupip_exit(ERR_UPDATEFILEOPEN);
diff --git a/sr_port/updproc_open_files.c b/sr_port/updproc_open_files.c
index 2cea8ed..00126c0 100644
--- a/sr_port/updproc_open_files.c
+++ b/sr_port/updproc_open_files.c
@@ -113,10 +113,9 @@ boolean_t updproc_open_files(gld_dbname_list **gld_db_files, seq_num *start_jnl_
 			if (-1 == this_side_std_null_coll)
 				this_side_std_null_coll = csd->std_null_coll;
 			else
-				rts_error(VARLSTCNT(1) ERR_NULLCOLLDIFF);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NULLCOLLDIFF);
 		}
-		if (DBKEYSIZE(csd->max_key_size) > gv_keysize)
-			gv_keysize = DBKEYSIZE(csd->max_key_size);
+		assert(DBKEYSIZE(csd->max_key_size) <= gv_keysize);
 		SET_CSA_DIR_TREE(csa, reg->max_key_size, reg);
 		assert(!csa->now_crit);
 		if (reg->was_open)	/* Should never happen as only open one at a time, but handle for safety */
@@ -131,8 +130,8 @@ boolean_t updproc_open_files(gld_dbname_list **gld_db_files, seq_num *start_jnl_
 		{
 			curr = curr->next;
 			continue;
-		} else if (REPL_ENABLED(csd) && !JNL_ENABLED(csd))
-			GTMASSERT;
+		} else
+			assertpro(!REPL_ENABLED(csd) || JNL_ENABLED(csd));
 #		ifdef VMS
 		if (recvpool.upd_proc_local->updateresync)
 		{
@@ -156,7 +155,7 @@ boolean_t updproc_open_files(gld_dbname_list **gld_db_files, seq_num *start_jnl_
 		/* Unix and VMS have different field names */
 		UNIX_ONLY(gld_fn = (sm_uc_ptr_t)recvpool.recvpool_ctl->recvpool_id.instfilename;)
 		VMS_ONLY(gld_fn = (sm_uc_ptr_t)recvpool.recvpool_ctl->recvpool_id.gtmgbldir;)
-		rts_error(VARLSTCNT(5) ERR_NOREPLCTDREG, 3,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_NOREPLCTDREG, 3,
 			   LEN_AND_LIT(UNIX_ONLY("instance file") VMS_ONLY("global directory")), gld_fn);
 	}
 	/* Now that all the databases are opened, compute the MAX region sequence number across all regions */
diff --git a/sr_port/util_base_ch.c b/sr_port/util_base_ch.c
index b7ef1db..14499f8 100644
--- a/sr_port/util_base_ch.c
+++ b/sr_port/util_base_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -63,65 +63,65 @@ CONDITION_HANDLER(util_base_ch)
 		$DESCRIPTOR(msgbuf, msg_buff);
 	)
 
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
-	if (SUCCESS == SEVERITY || INFO == SEVERITY)
-	{
-		CONTINUE;
-	} else
+	VMS_ONLY (
+		if (SUCCESS == SEVERITY || INFO == SEVERITY)
+		{
+			CONTINUE;
+		}
+	)
+	for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
 	{
-		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
+		for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
 		{
-			for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
+			if (r_local->open && !r_local->was_open)
 			{
-				if (r_local->open && !r_local->was_open)
-				{
-					csa = &FILE_INFO(r_local)->s_addrs;
-					if (!csa->persistent_freeze)
-						region_freeze(r_local, FALSE, FALSE, FALSE);
-				}
+				csa = &FILE_INFO(r_local)->s_addrs;
+				if (!csa->persistent_freeze)
+					region_freeze(r_local, FALSE, FALSE, FALSE);
 			}
 		}
-		if (IS_MUPIP_IMAGE)
-			preemptive_db_clnup(SEVERITY);	/* for other utilities, preemptive_db_clnup() is called from util_ch() */
-		UNIX_ONLY(
-			if ((DUMPABLE) && !SUPPRESS_DUMP)
-			{
-				need_core = TRUE;
-				gtm_fork_n_core();
-			}
-			/* rts_error sets error_condition, and util_base_ch is called only if
-			 * exiting thru rts_error. Setup exi_condition to reflect error
-			 * exit status. Note, if the last eight bits (the only relevant bits
-			 * for Unix exit status) of error_condition is non-zero in case of
-			 * errors, we make sure that an error exit status (non-zero value -1)
-			 * is setup. This is a hack.
-			 */
-			if (0 == exi_condition)
-				exi_condition = (((error_condition & UNIX_EXIT_STATUS_MASK) != 0) ? error_condition : -1);
-		)
-		VMS_ONLY(
-			if ((DUMPABLE) && !SUPPRESS_DUMP)
-			{
-				gtm_dump();
-				TERMINATE;
-			}
-			exi_condition = SIGNAL;
-			/* following is a hack to avoid FAO directives getting printed without expanding
-			 * in the error message during EXIT()
-			 */
-			if (IS_GTM_ERROR(SIGNAL))
+	}
+	if (IS_MUPIP_IMAGE)
+		preemptive_db_clnup(SEVERITY);	/* for other utilities, preemptive_db_clnup() is called from util_ch() */
+	UNIX_ONLY(
+		if ((DUMPABLE) && !SUPPRESS_DUMP)
+		{
+			need_core = TRUE;
+			gtm_fork_n_core();
+		}
+		/* rts_error sets error_condition, and util_base_ch is called only if
+		 * exiting thru rts_error. Setup exi_condition to reflect error
+		 * exit status. Note, if the last eight bits (the only relevant bits
+		 * for Unix exit status) of error_condition is non-zero in case of
+		 * errors, we make sure that an error exit status (non-zero value -1)
+		 * is setup. This is a hack.
+		 */
+		if (0 == exi_condition)
+			exi_condition = (((error_condition & UNIX_EXIT_STATUS_MASK) != 0) ? error_condition : -1);
+	)
+	VMS_ONLY(
+		if ((DUMPABLE) && !SUPPRESS_DUMP)
+		{
+			gtm_dump();
+			TERMINATE;
+		}
+		exi_condition = SIGNAL;
+		/* following is a hack to avoid FAO directives getting printed without expanding
+		 * in the error message during EXIT()
+		 */
+		if (IS_GTM_ERROR(SIGNAL))
+		{
+			status = sys$getmsg(SIGNAL, &msglen, &msgbuf, 0, msginfo);
+			if (status & 1)
 			{
-				status = sys$getmsg(SIGNAL, &msglen, &msgbuf, 0, msginfo);
-				if (status & 1)
-				{
-					if (0 < msginfo[1])
-						exi_condition = (IS_MUPIP_IMAGE ? ERR_MUNOFINISH :
-								(IS_DSE_IMAGE ? ERR_DSENOFINISH : ERR_LKENOFINISH));
-				}
+				if (0 < msginfo[1])
+					exi_condition = (IS_MUPIP_IMAGE ? ERR_MUNOFINISH :
+							(IS_DSE_IMAGE ? ERR_DSENOFINISH : ERR_LKENOFINISH));
 			}
-		)
-		UNSUPPORTED_PLATFORM_CHECK;
-		EXIT(exi_condition);
-	}
+		}
+	)
+	UNSUPPORTED_PLATFORM_CHECK;
+	EXIT(exi_condition);
 }
diff --git a/sr_port/util_ch.c b/sr_port/util_ch.c
index 062f119..1064eec 100644
--- a/sr_port/util_ch.c
+++ b/sr_port/util_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,7 +30,8 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(util_ch)
 {
-	START_CH;
+	START_CH(SIGNAL != ERR_CTRLC);
+
 	if (DUMPABLE)
        		NEXTCH;
 	PRN_ERROR;
@@ -40,10 +41,12 @@ CONDITION_HANDLER(util_ch)
 		assert(util_interrupt);
 		util_interrupt = 0;
 		UNWIND(NULL, NULL);
-	} else  if (SUCCESS == SEVERITY || INFO == SEVERITY)
+	} VMS_ONLY (
+	else  if (SUCCESS == SEVERITY || INFO == SEVERITY)
 	{
 		CONTINUE;
-	} else
+	}
+	) else
 	{
 		preemptive_db_clnup(SEVERITY);
 		UNWIND(NULL, NULL);
diff --git a/sr_port/view.h b/sr_port/view.h
index 4749487..1e6f2bf 100644
--- a/sr_port/view.h
+++ b/sr_port/view.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,6 +9,9 @@
  *								*
  ****************************************************************/
 
+#ifndef VIEW_INCLUDED
+#define VIEW_INCLUDED
+
 typedef struct
 {
 	unsigned char keyword[16];
@@ -44,6 +47,7 @@ typedef union
 	mval			*value;
 	struct gd_region_struct *gv_ptr;
 	noisolation_list	ni_list;
+	mstr			str;
 } viewparm;
 
 #define VTP_NULL 1
@@ -56,12 +60,18 @@ typedef union
 
 #define VIEWTAB(A,B,C,D) C
 
+#define	IS_DOLLAR_VIEW_FALSE	FALSE
+#define	IS_DOLLAR_VIEW_TRUE	TRUE
+
 enum viewtab_keycode {
 #include "viewtab.h"
 };
 
 viewtab_entry *viewkeys(mstr *v);
-void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk);
+void view_arg_convert(viewtab_entry *vtp, int vtp_parm, mval *parm, viewparm *parmblk, boolean_t is_dollar_view);
 void view_routines(mval *dst, mident_fixed *name);
+void view_routines_checksum(mval *dst, mident_fixed *name);
 
 #undef VIEWTAB
+
+#endif /* VIEW_INCLUDED */
diff --git a/sr_port/view_arg_convert.c b/sr_port/view_arg_convert.c
index bf2fe3f..dc5cc8b 100644
--- a/sr_port/view_arg_convert.c
+++ b/sr_port/view_arg_convert.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,43 +25,49 @@
 #include "dpgbldir.h"
 #include "lv_val.h"	/* needed for "symval" structure */
 #include "min_max.h"
+#include "gvnh_spanreg.h"
+#include "process_gvt_pending_list.h"	/* for "is_gvt_in_pending_list" prototype used in ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN */
+#include "gtmimagename.h"
+#include "gv_trigger_common.h"	/* for *HASHT* macros used inside GVNH_REG_INIT macro */
+#include "filestruct.h"		/* needed for "jnl.h" */
+#include "jnl.h"		/* needed for "jgbl" */
 
 LITREF mval 		literal_one;
 
 GBLREF	gd_addr 	*gd_header;
-GBLREF	gvt_container	*gvt_pending_list;
 GBLREF	buddy_list	*gvt_pending_buddy_list;
 GBLREF	symval		*curr_symval;
+GBLREF	buddy_list	*noisolation_buddy_list;	/* a buddy_list for maintaining the globals that are noisolated */
 
-static	buddy_list	*noisolation_buddy_list;	/* a buddy_list for maintaining the globals that are noisolated */
+error_def(ERR_NOREGION);
+error_def(ERR_NOTGBL);
+error_def(ERR_VIEWARGCNT);
+error_def(ERR_VIEWGVN);
+error_def(ERR_VIEWLVN);
 
-void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
+void view_arg_convert(viewtab_entry *vtp, int vtp_parm, mval *parm, viewparm *parmblk, boolean_t is_dollar_view)
 {
 	static	int4		first_time = TRUE;
-	int			n, res;
+	int			n, reg_index;
 	ht_ent_mname		*tabent;
 	mstr			tmpstr, namestr;
-	gd_region		*r_top, *r_ptr;
+	gd_region		*r_top, *r_ptr, *gd_reg_start;
 	mname_entry		gvent, lvent;
 	mident_fixed		lcl_buff;
 	unsigned char		global_names[1024], stashed;
-	noisolation_element	*gvnh_entry;
 	unsigned char 		*src, *nextsrc, *src_top, *dst, *dst_top, y;
-	gd_binding		*temp_gd_map, *temp_gd_map_top;
-	gv_namehead		*temp_gv_target;
-	gvt_container		*gvtc;
+	unsigned char		*c, *c_top;
+	gd_binding		*gd_map;
+	gv_namehead		*tmp_gvt;
 	gvnh_reg_t		*gvnh_reg;
+	gvnh_spanreg_t		*gvspan;
 
-	error_def(ERR_VIEWARGCNT);
-	error_def(ERR_NOREGION);
-	error_def(ERR_VIEWGVN);
-	error_def(ERR_VIEWLVN);
-
-	switch(vtp->parm)
+	switch (vtp_parm)
 	{
 		case VTP_NULL:
 			if (parm != 0)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			break;
 		case (VTP_NULL | VTP_VALUE):
 			if (NULL == parm)
@@ -72,7 +78,8 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 			/* caution:  fall through */
 		case VTP_VALUE:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			parmblk->value = parm;
 			break;
 		case (VTP_NULL | VTP_DBREGION):
@@ -84,7 +91,8 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 			/* caution:  fall through */
 		case VTP_DBREGION:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			if (!gd_header)		/* IF GD_HEADER ==0 THEN OPEN GBLDIR */
 				gvinit();
 			r_ptr = gd_header->regions;
@@ -95,7 +103,8 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 				for (r_top = r_ptr + gd_header->n_regions; ; r_ptr++)
 				{
 					if (r_ptr >= r_top)
-						rts_error(VARLSTCNT(4) ERR_NOREGION,2, parm->str.len, parm->str.addr);
+						rts_error_csa(CSA_ARG(NULL)
+							VARLSTCNT(4) ERR_NOREGION,2, parm->str.len, parm->str.addr);
 					tmpstr.len = r_ptr->rname_len;
 					tmpstr.addr = (char *) r_ptr->rname;
 					MSTR_CMP(tmpstr, parm->str, n);
@@ -107,26 +116,28 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 			break;
 		case VTP_DBKEY:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			if (!gd_header)		/* IF GD_HEADER ==0 THEN OPEN GBLDIR */
 				gvinit();
-			memset(&parmblk->ident.c[0], 0, SIZEOF(parmblk->ident));
-			if (parm->str.len >= 2 && *parm->str.addr == '^')
-			{
-				namestr.addr = parm->str.addr + 1;	/* skip initial '^' */
-				namestr.len = parm->str.len - 1;
-				if (namestr.len > MAX_MIDENT_LEN)
-					namestr.len = MAX_MIDENT_LEN;
-				if (valid_mname(&namestr))
-					memcpy(&parmblk->ident.c[0], namestr.addr, namestr.len);
-				else
-					rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, parm->str.len, parm->str.addr);
-			} else
-				rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, parm->str.len, parm->str.addr);
+			c = (unsigned char *)parm->str.addr;
+			if ('^' != *c)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_NOTGBL, 2, parm->str.len, c);
+			c_top = c + parm->str.len;
+			c++;				/* skip initial '^' */
+			parmblk->str.addr = (char *)c;
+			for ( ; (c < c_top) && ('(' != *c); c++)
+				;
+			parmblk->str.len = (char *)c - parmblk->str.addr;
+			if (MAX_MIDENT_LEN < parmblk->str.len)
+				parmblk->str.len = MAX_MIDENT_LEN;
+			if (!valid_mname(&parmblk->str))
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWGVN, 2, parmblk->str.len, parmblk->str.addr);
 			break;
 		case VTP_RTNAME:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			memset(&parmblk->ident.c[0], 0, SIZEOF(parmblk->ident));
 			if (parm->str.len > 0)
 				memcpy(&parmblk->ident.c[0], parm->str.addr,
@@ -142,7 +153,8 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 			/* caution : explicit fall through */
 		case VTP_DBKEYLIST:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			if (!gd_header)
 				gvinit();
 			if (first_time)
@@ -153,8 +165,7 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 				initialize_list(gvt_pending_buddy_list, SIZEOF(gvt_container), NOISOLATION_INIT_ALLOC);
 				first_time = FALSE;
 			}
-			if (SIZEOF(global_names) <= parm->str.len)
-				GTMASSERT;
+			assertpro(SIZEOF(global_names) > parm->str.len);
 			tmpstr.len = parm->str.len;	/* we need to change len and should not change parm->str, so take a copy */
 			tmpstr.addr = parm->str.addr;
 			if (0 != tmpstr.len)
@@ -196,70 +207,65 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 							memcpy(&lcl_buff.c[0], namestr.addr, namestr.len);
 							gvent.var_name.len = namestr.len;
 						} else
-							rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
+							rts_error_csa(CSA_ARG(NULL)
+								VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
 					} else
-						rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
-					temp_gv_target = NULL;
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
+					tmp_gvt = NULL;
 					gvent.var_name.addr = &lcl_buff.c[0];
 					COMPUTE_HASH_MNAME(&gvent);
-					if (NULL == (tabent = lookup_hashtab_mname(gd_header->tab_ptr, &gvent))
-					    || (NULL == (gvnh_reg = (gvnh_reg_t *)tabent->value)))
+					if (NULL != (tabent = lookup_hashtab_mname(gd_header->tab_ptr, &gvent)))
 					{
-						temp_gd_map = gd_header->maps;
-						temp_gd_map_top = temp_gd_map + gd_header->n_maps;
-						temp_gd_map++;	/* get past local locks */
-						for (; (res = memcmp(gvent.var_name.addr, &(temp_gd_map->name[0]),
-								     gvent.var_name.len)) >= 0; temp_gd_map++)
+						gvnh_reg = (gvnh_reg_t *)tabent->value;
+						assert(NULL != gvnh_reg);
+						tmp_gvt = gvnh_reg->gvt;
+					} else
+					{
+						gd_map = gv_srch_map(gd_header, gvent.var_name.addr, gvent.var_name.len);
+						r_ptr = gd_map->reg.addr;
+						tmp_gvt = (gv_namehead *)targ_alloc(r_ptr->max_key_size, &gvent, r_ptr);
+						GVNH_REG_INIT(gd_header, gd_header->tab_ptr, gd_map, tmp_gvt,
+											r_ptr, gvnh_reg, tabent);
+						/* In case of a global spanning multiple regions, the gvt pointer corresponding to
+						 * the region where the unsubscripted global reference maps to is stored in TWO
+						 * locations (one in gvnh_reg->gvspan->gvt_array[index] and one in gvnh_reg->gvt.
+						 * So pass in both these pointer addresses to be stored in the pending list in
+						 * case this gvt gets reallocated (due to different keysizes between gld and db).
+						 */
+						if (NULL == (gvspan = gvnh_reg->gvspan))
 						{
-							assert (temp_gd_map < temp_gd_map_top);
-							if (0 == res && 0 != temp_gd_map->name[gvent.var_name.len])
-								break;
-						}
-						r_ptr = temp_gd_map->reg.addr;
-						assert(r_ptr->max_key_size <= MAX_KEY_SZ);
-						temp_gv_target = (gv_namehead *)targ_alloc(r_ptr->max_key_size, &gvent, r_ptr);
-						gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
-						gvnh_reg->gvt = temp_gv_target;
-						gvnh_reg->gd_reg = r_ptr;
-						if (NULL != tabent)
-						{	/* Since the global name was found but gv_target was null and
-							 * now we created a new gv_target, the hash table key must point
-							 * to the newly created gv_target->gvname. */
-							tabent->key = temp_gv_target->gvname;
-							tabent->value = (char *)gvnh_reg;
+							ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN(r_ptr, &gvnh_reg->gvt, NULL);
 						} else
 						{
-							if (!add_hashtab_mname((hash_table_mname *)gd_header->tab_ptr,
-									       &temp_gv_target->gvname, gvnh_reg, &tabent))
-								GTMASSERT;
+							gd_reg_start = &gd_header->regions[0];
+							GET_REG_INDEX(gd_header, gd_reg_start, r_ptr, reg_index);
+								/* the above sets "reg_index" */
+							assert(reg_index >= gvspan->min_reg_index);
+							assert(reg_index <= gvspan->max_reg_index);
+							reg_index -= gvspan->min_reg_index;
+							ADD_TO_GVT_PENDING_LIST_IF_REG_NOT_OPEN(r_ptr,
+								&gvspan->gvt_array[reg_index], &gvnh_reg->gvt);
 						}
-						if (!r_ptr->open)
-						{	/* Record list of all gv_targets that have been allocated BEFORE the
-							 * region has been opened. Once the region gets opened, we will re-examine
-							 * this list and reallocate them (if needed) since they have now been
-							 * allocated using the region's max_key_size value which could potentially
-							 * be different from the max_key_size value in the corresponding database
-							 * file header.
-							 */
-							gvtc = (gvt_container *)get_new_free_element(gvt_pending_buddy_list);
-							gvtc->gvnh_reg = gvnh_reg;
-							assert(!gvtc->gvnh_reg->gd_reg->open);
-							gvtc->next_gvtc = (struct gvt_container_struct *)gvt_pending_list;
-							gvt_pending_list = gvtc;
-						}
-					} else
-						temp_gv_target = gvnh_reg->gvt;
-					gvnh_entry = (noisolation_element *)get_new_element(noisolation_buddy_list, 1);
-					gvnh_entry->gvnh = temp_gv_target;
-					gvnh_entry->next = parmblk->ni_list.gvnh_list;
-					parmblk->ni_list.gvnh_list = gvnh_entry;
+					}
+					ADD_GVT_TO_VIEW_NOISOLATION_LIST(tmp_gvt, parmblk);
+					if (!is_dollar_view && (NULL != gvnh_reg->gvspan))
+					{	/* Global spans multiple regions. Make sure gv_targets corresponding to ALL
+						 * spanned regions are allocated so NOISOLATION status can be set in all of
+						 * them even if the corresponding regions are not open yet. Do this only for
+						 * VIEW "NOISOLATION" commands which change the noisolation characteristic.
+						 * $VIEW("NOISOLATION") only examines the characteristics and so no need to
+						 * allocate all the gv-targets in that case. Just one is enough.
+						 */
+						gvnh_spanreg_subs_gvt_init(gvnh_reg, gd_header, parmblk);
+					}
 				}
 			} else
-				rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, tmpstr.len, tmpstr.addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWGVN, 2, tmpstr.len, tmpstr.addr);
 			break;
 		case VTP_LVN:
 			if (NULL == parm)
-				rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
 			if (0 < parm->str.len)
 			{
 				lvent.var_name.addr = parm->str.addr;
@@ -267,17 +273,17 @@ void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
 				if (lvent.var_name.len > MAX_MIDENT_LEN)
 					lvent.var_name.len = MAX_MIDENT_LEN;
 				if (!valid_mname(&lvent.var_name))
-					rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
 			} else
-				rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
 			/* Now look up the name.. */
 			COMPUTE_HASH_MNAME(&lvent);
 			if ((tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &lvent)) && (NULL != tabent->value))
 				parmblk->value = (mval *)tabent->value;	/* Return lv_val ptr */
 			else
-				rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && vtp_parm);
 	}
 }
diff --git a/sr_port/view_routines.c b/sr_port/view_routines.c
index 3f9d6aa..a9e248c 100644
--- a/sr_port/view_routines.c
+++ b/sr_port/view_routines.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,100 +18,63 @@
 #include "gtm_caseconv.h"
 #include "stringpool.h"
 #include "view.h"
-#include "min_max.h"	/* MIDENT_CMP needs MIN */
-
-#define S_CUTOFF 7
+#include "rtn_src_chksum.h"
 
 GBLREF rtn_tabent	*rtn_names, *rtn_names_end;
-GBLREF stack_frame 	*frame_pointer;
+
+/*
+ * Returns name of next (alphabetical) routine currently ZLINK'd.
+ * If no such routine, returns null string.
+ */
 
 void view_routines(mval *dst, mident_fixed *name)
 {
-	mident		temp;
-	char		temp_buff[SIZEOF(mident_fixed)];
-	rtn_tabent	*bot, *top, *mid;
-	int4		comp;
-
-	temp.len = INTCAST(mid_len(name));
-#ifdef UNIX
-	temp.addr = &name->c[0];
-#else
-	lower_to_upper(&temp_buff[0], &name->c[0], temp.len);
-	temp.addr = &temp_buff[0];
-#endif
+	mident		rname;
+	rtn_tabent	*mid;
+	boolean_t	found;
 
-	bot = rtn_names;
-	top = rtn_names_end;
+	rname.len = INTCAST(mid_len(name));	/* convert from mident_fixed to mident */
+	rname.addr = &name->c[0];
+	found = find_rtn_tabent(&mid, &rname);
+	if (found)
+		mid++;	/* want the *next* routine */
 	/* Skip over all routines that are not created by the user. These routines include
 	 * the dummy null routine, $FGNXEC (created for DALs) and $FGNFNC (created for Call-ins)
 	 * which are guaranteed to sort before any valid M routine */
-	while (bot < top && (0 == bot->rt_name.len || '%' > bot->rt_name.addr[0]))
-		bot++;
-	assert(bot <= top);
-	if (!temp.len)
-	{	dst->str.addr = bot->rt_name.addr;
-		dst->str.len = bot->rt_name.len;
+	while ((mid <= rtn_names_end) && ((0 == mid->rt_name.len) || ('%' > mid->rt_name.addr[0])))
+		mid++;
+	if (mid > rtn_names_end)
+		dst->str.len = 0;
+	else
+	{
+		dst->str.addr = mid->rt_name.addr;
+		dst->str.len = mid->rt_name.len;
 		s2pool(&dst->str);
-		return;
 	}
+}
 
-	for (;;)
+/*
+ * Returns checksum of routine <name>.
+ * If name is not ZLINK'd, returns null string.
+ */
+
+void view_routines_checksum(mval *dst, mident_fixed *name)
+{
+	mident		rname;
+	rtn_tabent	*mid;
+	boolean_t	found;
+	char		buf[MAX_ROUTINE_CHECKSUM_DIGITS];
+
+	rname.len = INTCAST(mid_len(name));	/* convert from mident_fixed to mident */
+	rname.addr = &name->c[0];
+	found = find_rtn_tabent(&mid, &rname);
+	/* Ignore the dummy null routine, $FGNXEC (created for DALs) and $FGNFNC (created for Call-ins) */
+	if (!found || ((0 == mid->rt_name.len) || ('%' > mid->rt_name.addr[0])))
+		dst->str.len = 0;
+	else
 	{
-		if ((top - bot) < S_CUTOFF)
-		{
-			comp = -1;
-			for (mid = bot; comp < 0 && mid <= top ;mid++)
-			{
-				MIDENT_CMP(&mid->rt_name, &temp, comp);
-				if (!comp)
-				{
-					if (mid != rtn_names_end)
-					{
-						mid++;
-						dst->str.addr = mid->rt_name.addr;
-						dst->str.len = mid->rt_name.len;
-						s2pool(&dst->str);
-					}
-					else
-						dst->str.len = 0;
-					return;
-				}
-				else if (comp < 0)
-					continue;
-				else
-				{	dst->str.addr = mid->rt_name.addr;
-					dst->str.len = mid->rt_name.len;
-					s2pool(&dst->str);
-					return;
-				}
-			}
-			dst->str.len = 0;
-			return;
-		}
-		else
-		{
-			mid = bot + (top - bot)/2;
-			MIDENT_CMP(&mid->rt_name, &temp, comp);
-			if (!comp)
-			{	if (mid != rtn_names_end)
-				{
-					mid++;
-					dst->str.addr = mid->rt_name.addr;
-					dst->str.len = mid->rt_name.len;
-					s2pool(&dst->str);
-				}
-				else
-					dst->str.len = 0;
-				return;
-			}
-			else if (comp < 0)
-			{	bot = mid + 1;
-				continue;
-			}
-			else
-			{	top = mid;
-				continue;
-			}
-		}
+		dst->str.addr = &buf[0];
+		dst->str.len = append_checksum((unsigned char *)&buf[0], mid->rt_adr);
+		s2pool(&dst->str);
 	}
 }
diff --git a/sr_port/viewtab.h b/sr_port/viewtab.h
index 14a5665..14e6571 100644
--- a/sr_port/viewtab.h
+++ b/sr_port/viewtab.h
@@ -12,94 +12,116 @@
 /* a few of the following VIEWTAB entries (be it VIEW command related or $VIEW function related) are not documented
  * in the programmer's guide. the reason behind the non-documentation is indicated across each such entry with a "nodoc :" prefix.
  */
-VIEWTAB("0",		VTP_NULL,		VTK_GDSCERT0,	MV_STR),
-VIEWTAB("1",		VTP_NULL,		VTK_GDSCERT1,	MV_STR),
-VIEWTAB("BADCHAR",	VTP_NULL,		VTK_BADCHAR,	MV_NM),
-VIEWTAB("BREAKMSG",	VTP_NULL | VTP_VALUE,	VTK_BREAKMSG,	MV_NM),
-VIEWTAB("DBFLUSH",	VTP_DBREGION | VTP_NULL, VTK_DBFLUSH,	MV_STR),
-VIEWTAB("DBSYNC",	VTP_DBREGION | VTP_NULL, VTK_DBSYNC,	MV_STR),
-VIEWTAB("DEBUG1",	VTP_VALUE | VTP_NULL,	VTK_DEBUG1,	MV_STR),
-VIEWTAB("DEBUG2",	VTP_VALUE | VTP_NULL,	VTK_DEBUG2,	MV_STR),
-VIEWTAB("DEBUG3",	VTP_VALUE | VTP_NULL,	VTK_DEBUG3,	MV_STR),
-VIEWTAB("DEBUG4",	VTP_VALUE | VTP_NULL,	VTK_DEBUG4,	MV_STR),
-VIEWTAB("EPOCH",	VTP_DBREGION | VTP_NULL, VTK_EPOCH,	MV_STR),
-VIEWTAB("FILL_FACTOR",	VTP_VALUE | VTP_NULL,	VTK_FILLFACTOR, MV_NM),
-VIEWTAB("FLUSH",	VTP_DBREGION | VTP_NULL, VTK_FLUSH,	MV_STR),
-VIEWTAB("FREEBLOCKS",	VTP_DBREGION,		VTK_BLFREE,	MV_NM),
-VIEWTAB("FREEZE",	VTP_DBREGION,		VTK_FREEZE,	MV_NM),
-VIEWTAB("FULL_BOOLEAN",	VTP_NULL,		VTK_FULLBOOL,	MV_STR),
-VIEWTAB("FULL_BOOLWARN", VTP_NULL,		VTK_FULLBOOLWARN, MV_STR),
-VIEWTAB("GDSCERT",	VTP_NULL | VTP_VALUE,	VTK_GDSCERT,	MV_STR),
-VIEWTAB("GVACCESS_METHOD", VTP_DBREGION,	VTK_GVACC_METH, MV_STR),
-VIEWTAB("GVDUPSETNOOP", VTP_NULL | VTP_VALUE,	VTK_GVDUPSETNOOP, MV_STR),
-VIEWTAB("GVFILE",	VTP_DBREGION,		VTK_GVFILE,	MV_STR),
-VIEWTAB("GVFIRST",	VTP_NULL,		VTK_GVFIRST,	MV_STR), /* nodoc : archaic and deprecated. use GVNEXT instead */
-VIEWTAB("GVNEXT",	VTP_DBREGION,		VTK_GVNEXT,	MV_STR),
-VIEWTAB("GVSTATS",	VTP_DBREGION,		VTK_GVSTATS,	MV_STR),
-VIEWTAB("ICHITS",	VTP_NULL,		VTK_ICHITS,	MV_NM),
-VIEWTAB("ICMISS",	VTP_NULL,		VTK_ICMISS,	MV_NM),
-VIEWTAB("ICSIZE",	VTP_NULL,		VTK_ICSIZE,	MV_NM),
-VIEWTAB("IMAGENAME", 	VTP_NULL,		VTK_IMAGENAME,	MV_STR), /* nodoc : test system use returns running executable */
-VIEWTAB("JNLACTIVE",	VTP_DBREGION,		VTK_JNLACTIVE,	MV_NM),
+/*      KEYWORD			PARAMETER-TYPE			KEYCODE		RESULT-TYPE */
+VIEWTAB("0",			VTP_NULL,			VTK_GDSCERT0,		MV_STR),
+VIEWTAB("1",			VTP_NULL,			VTK_GDSCERT1,		MV_STR),
+VIEWTAB("BADCHAR",		VTP_NULL,			VTK_BADCHAR,		MV_NM),
+VIEWTAB("BREAKMSG",		VTP_NULL | VTP_VALUE,		VTK_BREAKMSG,		MV_NM),
+VIEWTAB("DEBUG1",		VTP_VALUE | VTP_NULL,		VTK_DEBUG1,		MV_STR),
+VIEWTAB("DEBUG2",		VTP_VALUE | VTP_NULL,		VTK_DEBUG2,		MV_STR),
+VIEWTAB("DEBUG3",		VTP_VALUE | VTP_NULL,		VTK_DEBUG3,		MV_STR),
+VIEWTAB("DEBUG4",		VTP_VALUE | VTP_NULL,		VTK_DEBUG4,		MV_STR),
+VIEWTAB("DBFLUSH",		VTP_DBREGION | VTP_NULL,	VTK_DBFLUSH,		MV_STR),
+VIEWTAB("DBSYNC",		VTP_DBREGION | VTP_NULL,	VTK_DBSYNC,		MV_STR),
+VIEWTAB("EPOCH",		VTP_DBREGION | VTP_NULL,	VTK_EPOCH,		MV_STR),
+VIEWTAB("FILL_FACTOR",		VTP_VALUE | VTP_NULL,		VTK_FILLFACTOR,		MV_NM),
+VIEWTAB("FLUSH",		VTP_DBREGION | VTP_NULL,	VTK_FLUSH,		MV_STR),
+VIEWTAB("FREEBLOCKS",		VTP_DBREGION,			VTK_BLFREE,		MV_NM),
+VIEWTAB("FREEZE",		VTP_DBREGION,			VTK_FREEZE,		MV_NM),
+VIEWTAB("FULL_BOOLEAN",		VTP_NULL,			VTK_FULLBOOL,		MV_STR),
+VIEWTAB("FULL_BOOLWARN",	VTP_NULL,			VTK_FULLBOOLWARN,	MV_STR),
+VIEWTAB("GDSCERT",		VTP_NULL | VTP_VALUE,		VTK_GDSCERT,		MV_STR),
+VIEWTAB("GVACCESS_METHOD",	VTP_DBREGION,			VTK_GVACC_METH,		MV_STR),
+VIEWTAB("GVDUPSETNOOP",		VTP_NULL | VTP_VALUE,		VTK_GVDUPSETNOOP,	MV_STR),
+VIEWTAB("GVFILE",		VTP_DBREGION,			VTK_GVFILE,		MV_STR),
+VIEWTAB("GVFIRST",		VTP_NULL,			VTK_GVFIRST,		MV_STR), /* nodoc : archaic and deprecated.
+												  * use GVNEXT instead */
+VIEWTAB("GVNEXT",		VTP_DBREGION,			VTK_GVNEXT,		MV_STR),
+VIEWTAB("GVSTATS",		VTP_DBREGION,			VTK_GVSTATS,		MV_STR),
+VIEWTAB("ICHITS",		VTP_NULL,			VTK_ICHITS,		MV_NM),
+VIEWTAB("ICMISS",		VTP_NULL,			VTK_ICMISS,		MV_NM),
+VIEWTAB("ICSIZE",		VTP_NULL,			VTK_ICSIZE,		MV_NM),
+VIEWTAB("IMAGENAME",		VTP_NULL,			VTK_IMAGENAME,		MV_STR), /* nodoc : test system use returns
+												  * running executable */
+VIEWTAB("JNLACTIVE",		VTP_DBREGION,			VTK_JNLACTIVE,		MV_NM),
 #ifndef VMS
-VIEWTAB("JNLERROR",	VTP_VALUE | VTP_NULL,	VTK_JNLERROR,	MV_NM),
+VIEWTAB("JNLERROR",		VTP_VALUE | VTP_NULL,		VTK_JNLERROR,		MV_NM),
 #endif
-VIEWTAB("JNLFILE",	VTP_DBREGION,		VTK_JNLFILE,	MV_STR),
-VIEWTAB("JNLFLUSH",	VTP_DBREGION | VTP_NULL, VTK_JNLFLUSH,	MV_STR),
-VIEWTAB("JNLTRANSACTION", VTP_NULL,		VTK_JNLTRANSACTION, MV_NM),
-VIEWTAB("JNLWAIT",	VTP_NULL,		VTK_JNLWAIT,	MV_STR),
-VIEWTAB("JOBPID",	VTP_VALUE | VTP_NULL,	VTK_JOBPID,	MV_STR),
-VIEWTAB("LABELS",	VTP_VALUE | VTP_NULL,	VTK_LABELS,	MV_NM),
-VIEWTAB("LOGTPRESTART",	VTP_VALUE | VTP_NULL, 	VTK_LOGTPRESTART,	MV_NM),
+VIEWTAB("JNLFILE",		VTP_DBREGION,			VTK_JNLFILE,		MV_STR),
+VIEWTAB("JNLFLUSH",		VTP_DBREGION | VTP_NULL,	VTK_JNLFLUSH,		MV_STR),
+VIEWTAB("JNLTRANSACTION",	VTP_NULL,			VTK_JNLTRANSACTION,	MV_NM),
+VIEWTAB("JNLWAIT",		VTP_NULL,			VTK_JNLWAIT,		MV_STR),
+VIEWTAB("JOBPID",		VTP_VALUE | VTP_NULL,		VTK_JOBPID,		MV_STR),
+VIEWTAB("LABELS",		VTP_VALUE | VTP_NULL,		VTK_LABELS,		MV_NM),
+VIEWTAB("LINK",			VTP_VALUE | VTP_NULL,		VTK_LINK,		MV_STR),
+VIEWTAB("LOGTPRESTART",		VTP_VALUE | VTP_NULL,		VTK_LOGTPRESTART,	MV_NM),
 #ifdef DEBUG
-VIEWTAB("LVDMP",	VTP_LVN,		VTK_LVDMP,	MV_NM),
+VIEWTAB("LVDMP",		VTP_LVN,			VTK_LVDMP,		MV_NM),
 #endif
-VIEWTAB("LVDUPCHECK",	VTP_NULL | VTP_VALUE,	VTK_LVDUPCHECK, MV_STR), /* nodoc : felt unnecessary in all known cases */
+VIEWTAB("LVDUPCHECK",		VTP_NULL | VTP_VALUE,		VTK_LVDUPCHECK,		MV_STR), /* nodoc : felt unnecessary in
+												  * all known cases */
 #ifdef DEBUG_ALIAS
-VIEWTAB("LVMONOUT",	VTP_NULL,		VTK_LVMONOUT,	MV_NM),	/* nodoc : code debugging feature */
-VIEWTAB("LVMONSTART",	VTP_NULL,		VTK_LVMONSTART,	MV_NM),	/* nodoc : code debugging feature */
-VIEWTAB("LVMONSTOP",	VTP_NULL,		VTK_LVMONSTOP,	MV_NM),	/* nodoc : code debugging feature */
+VIEWTAB("LVMONOUT",		VTP_NULL,			VTK_LVMONOUT,		MV_NM), /* nodoc : code debugging feature */
+VIEWTAB("LVMONSTART",		VTP_NULL,			VTK_LVMONSTART,		MV_NM), /* nodoc : code debugging feature */
+VIEWTAB("LVMONSTOP",		VTP_NULL,			VTK_LVMONSTOP,		MV_NM), /* nodoc : code debugging feature */
 #endif
-VIEWTAB("LVNULLSUBS",	VTP_NULL,		VTK_LVNULLSUBS, MV_NM),
-VIEWTAB("LV_CREF",	VTP_LVN,		VTK_LVCREF,	MV_NM),
-VIEWTAB("LV_GCOL",	VTP_NULL,		VTK_LVGCOL,	MV_NM),
-VIEWTAB("LV_REF",	VTP_LVN,		VTK_LVREF,	MV_NM),
-VIEWTAB("LV_REHASH",	VTP_NULL,		VTK_LVREHASH,	MV_NM),
-VIEWTAB("MAX_SOCKETS",	VTP_NULL,		VTK_MAXSOCKETS, MV_NM),
-VIEWTAB("NEVERLVNULLSUBS", VTP_NULL,		VTK_NEVERLVNULLSUBS, MV_NM),
-VIEWTAB("NOBADCHAR",	VTP_NULL,		VTK_NOBADCHAR,	MV_NM),
-VIEWTAB("NOFULL_BOOLEAN",	VTP_NULL,	VTK_NOFULLBOOL,	MV_STR),
-VIEWTAB("NOISOLATION",	VTP_NULL | VTP_DBKEYLIST, VTK_NOISOLATION, MV_NM),
-VIEWTAB("NOLOGTPRESTART", VTP_NULL, 		VTK_NOLOGTPRESTART,	MV_NM),
-VIEWTAB("NOLVNULLSUBS", VTP_NULL,		VTK_NOLVNULLSUBS, MV_NM),
-VIEWTAB("NOUNDEF",	VTP_NULL,		VTK_NOUNDEF,	MV_NM),
-VIEWTAB("PATCODE",	VTP_VALUE | VTP_NULL,	VTK_PATCODE,	MV_STR),
-VIEWTAB("PATLOAD",	VTP_VALUE,		VTK_PATLOAD,	MV_NM),
+VIEWTAB("LVNULLSUBS",		VTP_NULL,			VTK_LVNULLSUBS,		MV_NM),
+VIEWTAB("LV_CREF",		VTP_LVN,			VTK_LVCREF,		MV_NM),
+VIEWTAB("LV_GCOL",		VTP_NULL,			VTK_LVGCOL,		MV_NM),
+VIEWTAB("LV_REF",		VTP_LVN,			VTK_LVREF,		MV_NM),
+VIEWTAB("LV_REHASH",		VTP_NULL,			VTK_LVREHASH,		MV_NM),
+VIEWTAB("MAX_SOCKETS",		VTP_NULL,			VTK_MAXSOCKETS,		MV_NM),
+VIEWTAB("NEVERLVNULLSUBS",	VTP_NULL,			VTK_NEVERLVNULLSUBS,	MV_NM),
+VIEWTAB("NOBADCHAR",		VTP_NULL,			VTK_NOBADCHAR,		MV_NM),
+VIEWTAB("NOFULL_BOOLEAN",	VTP_NULL,			VTK_NOFULLBOOL,		MV_STR),
+VIEWTAB("NOISOLATION",		VTP_NULL | VTP_DBKEYLIST,	VTK_NOISOLATION,	MV_NM),
+VIEWTAB("NOLOGTPRESTART",	VTP_NULL,			VTK_NOLOGTPRESTART,	MV_NM),
+VIEWTAB("NOLVNULLSUBS",		VTP_NULL,			VTK_NOLVNULLSUBS,	MV_NM),
+VIEWTAB("NOUNDEF",		VTP_NULL,			VTK_NOUNDEF,		MV_NM),
+VIEWTAB("PATCODE",		VTP_VALUE | VTP_NULL,		VTK_PATCODE,		MV_STR),
+VIEWTAB("PATLOAD",		VTP_VALUE,			VTK_PATLOAD,		MV_NM),
 #ifdef DEBUG
-VIEWTAB("PROBECRIT",	VTP_DBREGION,		VTK_PROBECRIT,	MV_NM),
+VIEWTAB("PROBECRIT",		VTP_DBREGION,			VTK_PROBECRIT,		MV_NM),
 #endif
-VIEWTAB("RCHITS",	VTP_NULL,		VTK_RCHITS,	MV_NM),
-VIEWTAB("RCMISSES",	VTP_NULL,		VTK_RCMISSES,	MV_NM),
-VIEWTAB("RCSIZE",	VTP_NULL,		VTK_RCSIZE,	MV_NM),
-VIEWTAB("REGION",	VTP_DBKEY,		VTK_REGION,	MV_STR),
-VIEWTAB("RESETGVSTATS", VTP_NULL,		VTK_RESETGVSTATS, MV_STR),
-VIEWTAB("RTNNEXT",	VTP_RTNAME,		VTK_RTNEXT,	MV_STR),
-VIEWTAB("SPSIZE",	VTP_NULL,		VTK_SPSIZE,	MV_NM),
-VIEWTAB("STKSIZ",	VTP_NULL,		VTK_STKSIZ,	MV_NM),
-VIEWTAB("STORDUMP",	VTP_NULL,		VTK_STORDUMP,	MV_NM),	/* nodoc : code debugging feature */
-VIEWTAB("STP_GCOL",	VTP_NULL,		VTK_STPGCOL,	MV_NM),
-VIEWTAB("TESTPOINT",	VTP_VALUE,		VTK_TESTPOINT,	MV_NM),
-VIEWTAB("TOTALBLOCKS",	VTP_DBREGION,		VTK_BLTOTAL,	MV_NM),
-VIEWTAB("TRACE",	VTP_VALUE,		VTK_TRACE,	MV_NM),
-VIEWTAB("TRANSACTIONID", VTP_VALUE | VTP_NULL,	VTK_TID,	MV_STR),
-VIEWTAB("UNDEF",	VTP_NULL,		VTK_UNDEF,	MV_NM),
-VIEWTAB("YCOLLATE",	VTP_VALUE,		VTK_YCOLLATE,	MV_NM),	 /* nodoc : collation related undocumented feature */
-VIEWTAB("YDIRTREE",	VTP_VALUE,		VTK_YDIRTREE,	MV_STR), /* nodoc : collation related undocumented feature */
-VIEWTAB("YDIRTVAL",	VTP_VALUE,		VTK_YDIRTVAL,	MV_STR), /* nodoc : collation related undocumented feature */
-VIEWTAB("YLCT",		VTP_NULL | VTP_VALUE,	VTK_YLCT,	MV_NM),	 /* nodoc : collation related undocumented feature */
-VIEWTAB("ZDEFBUFFER",	VTP_DBREGION,		VTK_ZDEFBUFF,	MV_NM), /* nodoc : seems to be an archaic feature of GT.CM GNP */
-VIEWTAB("ZDEFCOUNT",	VTP_DBREGION,		VTK_ZDEFCNT,	MV_NM), /* nodoc : seems to be an archaic feature of GT.CM GNP */
-VIEWTAB("ZDEFER",	VTP_NULL | VTP_VALUE,	VTK_ZDEFER,	MV_NM), /* nodoc : seems to be an archaic feature of GT.CM GNP */
-VIEWTAB("ZDEFSIZE",	VTP_DBREGION,		VTK_ZDEFSIZE,	MV_NM), /* nodoc : seems to be an archaic feature of GT.CM GNP */
-VIEWTAB("ZDIR_FORM",	VTP_NULL | VTP_VALUE,	VTK_ZDIR_FORM,	MV_NM),
-VIEWTAB("ZFLUSH",	VTP_NULL,		VTK_ZFLUSH,	MV_NM)
+VIEWTAB("RCHITS",		VTP_NULL,			VTK_RCHITS,		MV_NM),
+VIEWTAB("RCMISSES",		VTP_NULL,			VTK_RCMISSES,		MV_NM),
+VIEWTAB("RCSIZE",		VTP_NULL,			VTK_RCSIZE,		MV_NM),
+VIEWTAB("REGION",		VTP_DBKEY,			VTK_REGION,		MV_STR),
+VIEWTAB("RESETGVSTATS",		VTP_NULL,			VTK_RESETGVSTATS,	MV_STR),
+VIEWTAB("RTNCHECKSUM",		VTP_RTNAME,			VTK_RTNCHECKSUM,	MV_STR),
+VIEWTAB("RTNNEXT",		VTP_RTNAME,			VTK_RTNEXT,		MV_STR),
+VIEWTAB("SPSIZE",		VTP_NULL,			VTK_SPSIZE,		MV_NM),
+VIEWTAB("STKSIZ",		VTP_NULL,			VTK_STKSIZ,		MV_NM),
+VIEWTAB("STORDUMP",		VTP_NULL,			VTK_STORDUMP,		MV_NM), /* nodoc : code debugging feature */
+VIEWTAB("STP_GCOL",		VTP_NULL,			VTK_STPGCOL,		MV_NM),
+VIEWTAB("TESTPOINT",		VTP_VALUE,			VTK_TESTPOINT,		MV_NM),
+VIEWTAB("TOTALBLOCKS",		VTP_DBREGION,			VTK_BLTOTAL,		MV_NM),
+VIEWTAB("TRACE",		VTP_VALUE,			VTK_TRACE,		MV_NM),
+VIEWTAB("TRANSACTIONID",	VTP_VALUE | VTP_NULL,		VTK_TID,		MV_STR),
+VIEWTAB("UNDEF",		VTP_NULL,			VTK_UNDEF,		MV_NM),
+VIEWTAB("YCHKCOLL",		VTP_NULL | VTP_VALUE,		VTK_YCHKCOLL,		MV_NM), /* nodoc : GDE related
+												 * undocumented feature */
+VIEWTAB("YCOLLATE",		VTP_VALUE,			VTK_YCOLLATE,		MV_NM), /* nodoc : collation related
+												 * undocumented feature */
+VIEWTAB("YDIRTREE",		VTP_VALUE,			VTK_YDIRTREE,		MV_STR), /* nodoc : collation related
+												  * undocumented feature */
+VIEWTAB("YDIRTVAL",		VTP_VALUE,			VTK_YDIRTVAL,		MV_STR), /* nodoc : collation related
+												  * undocumented feature */
+VIEWTAB("YGDS2GVN",		VTP_VALUE,			VTK_YGDS2GVN,		MV_STR), /* nodoc : GDE related
+												  * undocumented feature */
+VIEWTAB("YGLDCOLL",		VTP_DBKEY,			VTK_YGLDCOLL,		MV_STR), /* nodoc : collation related
+												  * undocumented feature */
+VIEWTAB("YGVN2GDS",		VTP_VALUE,			VTK_YGVN2GDS,		MV_STR), /* nodoc : GDE related
+												  * undocumented feature */
+VIEWTAB("YLCT",			VTP_NULL | VTP_VALUE,		VTK_YLCT,		MV_NM), /* nodoc : collation related
+												 * undocumented feature */
+VIEWTAB("ZDEFBUFFER",		VTP_DBREGION,			VTK_ZDEFBUFF,		MV_NM), /* nodoc : seems to be an archaic
+												 * feature of GT.CM GNP */
+VIEWTAB("ZDEFCOUNT",		VTP_DBREGION,			VTK_ZDEFCNT,		MV_NM), /* nodoc : seems to be an archaic
+												 * feature of GT.CM GNP */
+VIEWTAB("ZDEFER",		VTP_NULL | VTP_VALUE,		VTK_ZDEFER,		MV_NM), /* nodoc : seems to be an archaic
+												 * feature of GT.CM GNP */
+VIEWTAB("ZDEFSIZE",		VTP_DBREGION,			VTK_ZDEFSIZE,		MV_NM), /* nodoc : seems to be an archaic
+												 * feature of GT.CM GNP */
+VIEWTAB("ZDIR_FORM",		VTP_NULL | VTP_VALUE,		VTK_ZDIR_FORM,		MV_NM),
+VIEWTAB("ZFLUSH",		VTP_NULL,			VTK_ZFLUSH,		MV_NM)
diff --git a/sr_port/wbox_test_init.h b/sr_port/wbox_test_init.h
index 4e8b996..c95a165 100644
--- a/sr_port/wbox_test_init.h
+++ b/sr_port/wbox_test_init.h
@@ -126,14 +126,16 @@ typedef enum {
 	WBTEST_FSYNC_SYSCALL_FAIL,		/* 88 : Force error from fsync() */
 	WBTEST_HUGE_ALLOC,			/* 89 : Force ZALLOCSTOR, ZREALSTOR, and ZUSEDSTOR to be values exceeding
 						 *	the capacity of four-byte ints */
-	WBTEST_MMAP_SYSCALL_FAIL,		/* 90 : Force mmap() to return an error */
+	WBTEST_MEM_MAP_SYSCALL_FAIL,		/* 90 : Force shmat() on AIX and mmap() on other platforms to return an error */
 	WBTEST_TAMPER_HOSTNAME,			/* 91 : Change host name in db_init to call condition handler */
 	WBTEST_RECOVER_ENOSPC,			/* 92 : Cause ENOSPC error on Xth write to test return status on error */
 	WBTEST_WCS_FLU_FAIL,			/* 93 : Simulates a failure in wcs_flu */
 	WBTEST_PREAD_SYSCALL_FAIL,		/* 94 : Simulate pread() error in dsk_read */
 	WBTEST_HOLD_CRIT_ENABLED,		/* 95 : Enable $view("PROBECRIT","REGION") command to cold crit */
-	WBTEST_HOLD_FTOK_UNTIL_BYPASS		/* 96 : Hold the ftok semaphore until another process comes and bypasses
-						 *      it*/
+	WBTEST_HOLD_FTOK_UNTIL_BYPASS,		/* 96 : Hold the ftok semaphore until another process comes and bypasses it */
+	WBTEST_SLEEP_IN_WCS_WTSTART,		/* 97 : Sleep in one of the predetermined places inside wcs_wtstart.c */
+	WBTEST_SETITIMER_ERROR,			/* 98 : Simulate an error return from setitimer in gt_timers.c */
+	WBTEST_HOLD_GTMSOURCE_SRV_LATCH		/* 99 : Hold the source server latch until rollback process issues a SIGCONT */
 	/* Note 1: when adding new white box test cases, please make use of WBTEST_ENABLED and WBTEST_ASSIGN_ONLY (defined below)
 	 * whenever applicable
 	 * Note 2: when adding a new white box test case, see if an existing WBTEST_UNUSED* slot can be levereged.
diff --git a/sr_port/wcs_phase2_commit_wait.c b/sr_port/wcs_phase2_commit_wait.c
index c722f12..4ce76bc 100644
--- a/sr_port/wcs_phase2_commit_wait.c
+++ b/sr_port/wcs_phase2_commit_wait.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2008, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2008, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,16 +34,17 @@
 error_def(ERR_COMMITWAITPID);
 error_def(ERR_COMMITWAITSTUCK);
 
-#define	SEND_COMMITWAITPID_GET_STACK_IF_NEEDED(BLOCKING_PID, STUCK_CNT, CR, CSA)						\
-{																\
-	GBLREF	uint4	process_id;												\
-																\
-	if (BLOCKING_PID)													\
-	{															\
-		STUCK_CNT++;													\
-		GET_C_STACK_FROM_SCRIPT("COMMITWAITPID", process_id, BLOCKING_PID, STUCK_CNT);					\
-		send_msg(VARLSTCNT(8) ERR_COMMITWAITPID, 6, process_id, 1, BLOCKING_PID, CR->blk, DB_LEN_STR(CSA->region));	\
-	}															\
+#define	SEND_COMMITWAITPID_GET_STACK_IF_NEEDED(BLOCKING_PID, STUCK_CNT, CR, CSA)				\
+{														\
+	GBLREF	uint4	process_id;										\
+														\
+	if (BLOCKING_PID)											\
+	{													\
+		STUCK_CNT++;											\
+		GET_C_STACK_FROM_SCRIPT("COMMITWAITPID", process_id, BLOCKING_PID, STUCK_CNT);			\
+		send_msg_csa(CSA_ARG(CSA) VARLSTCNT(8) ERR_COMMITWAITPID, 6,					\
+			process_id, 1, BLOCKING_PID, CR->blk, DB_LEN_STR(CSA->region));				\
+	}													\
 }
 
 /* take C-stack trace of the process doing the phase2 commits at half the entire wait. We do this only while waiting
@@ -110,15 +111,12 @@ boolean_t	wcs_phase2_commit_wait(sgmnt_addrs *csa, cache_rec_ptr_t cr)
 	assert(!in_mu_rndwn_file);
 	csd = csa->hdr;
 	/* To avoid unnecessary time spent waiting, we would like to do rel_quants instead of wcs_sleep. But this means
-	 * we need to have some other scheme for limiting the total time slept. We use the heartbeat scheme which currently
-	 * is available only in Unix. Every 8 seconds or so, the heartbeat timer increments a counter. But there are two
-	 * cases where heartbeat_timer will not pop:
-	 * (a) if we are in the process of exiting (through a call to cancel_timer(0) which cancels all active timers)
-	 * (b) if we are are already in timer_handler. This is possible if the flush timer pops and we end up invoking
-	 *     wcs_clean_dbsync->wcs_flu->wcs_phase2_commit_wait. But since the heartbeat timer cannot pop as long as
-	 *     timer_in_handler is TRUE (which it will be until at least we exit this function), we cannot use the heartbeat
-	 *     scheme in this case as well.
-	 * Therefore, if heartbeat timer is available and currently active, then use rel_quants. If not, use wcs_sleep.
+	 * we need to have some other scheme for limiting the total time slept. We use the heartbeat scheme which currently is
+	 * available only in Unix. Every 8 seconds or so, the heartbeat timer increments a counter. But the heartbeat_timer
+	 * will not pop if we are are already in timer_handler. This is possible if the flush timer pops and we end up invoking
+	 * wcs_clean_dbsync->wcs_flu->wcs_phase2_commit_wait. But since the heartbeat timer cannot pop as long as
+	 * timer_in_handler is TRUE (which it will be until at least we exit this function), we cannot use the heartbeat scheme
+	 * and so fall back on rel_quants. If not, use wcs_sleep.
 	 * We have found that doing rel_quants (instead of sleeps) causes huge CPU usage in Tru64 even if the default spincnt is
 	 * set to 0 and ALL processes are only waiting for one process to finish its phase2 commit. Therefore we choose
 	 * the sleep approach for Tru64. Choosing a spincnt of 0 would choose the sleep approach (versus rel_quant).
@@ -163,8 +161,7 @@ boolean_t	wcs_phase2_commit_wait(sgmnt_addrs *csa, cache_rec_ptr_t cr)
 			assert(gtm_white_box_test_case_enabled);
 			return TRUE;
 		}
-		if (process_id == start_in_tend)
-			GTMASSERT;	/* should not deadlock on our self */
+		assertpro(process_id != start_in_tend);	/* should not deadlock on our self */
 		if (!start_in_tend)
 			return TRUE;
 	} else
@@ -194,10 +191,10 @@ boolean_t	wcs_phase2_commit_wait(sgmnt_addrs *csa, cache_rec_ptr_t cr)
 			 * an update to the 8-byte transaction number is not necessarily atomic AND because the block's tn
 			 * that we read could be a mish-mash of low-order and high-order bytes taken from BEFORE and AFTER
 			 * an update. Doing less than checks with these bad values is considered risky as a false return
-			 * means a GTMASSERT in "t_end" or "tp_tend" in the PIN_CACHE_RECORD macro. Since this situation is
-			 * almost an impossibility in practice, we handle this by returning FALSE after timing out and
-			 * requiring the caller (t_qread) to restart. Eventually we will get crit (in the final retry) where
-			 * we are guaranteed not to end up in this situation.
+			 * means a GTMASSERT (BYPASSOK) in "t_end" or "tp_tend" in the PIN_CACHE_RECORD macro. Since this
+			 * situation is almost an impossibility in practice, we handle this by returning FALSE after timing
+			 * out and requiring the caller (t_qread) to restart. Eventually we will get crit (in the final retry)
+			 * where we are guaranteed not to end up in this situation.
 			 */
 			value = cr->in_tend;
 			if (value != start_in_tend)
@@ -320,7 +317,8 @@ boolean_t	wcs_phase2_commit_wait(sgmnt_addrs *csa, cache_rec_ptr_t cr)
 		SEND_COMMITWAITPID_GET_STACK_IF_NEEDED(blocking_pid, stuck_cnt, cr, csa);
 	}
 	DEBUG_ONLY(incrit_pid = cnl->in_crit;)
-	send_msg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1, cnl->wcs_phase2_commit_pidcnt, DB_LEN_STR(csa->region));
+	send_msg_csa(CSA_ARG(csa) VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id,
+		1, cnl->wcs_phase2_commit_pidcnt, DB_LEN_STR(csa->region));
 	BG_TRACE_PRO_ANY(csa, wcb_phase2_commit_wait);
 	/* If called from wcs_recover(), we dont want to assert(FALSE) as it is possible (in case of STOP/IDs) that
 	 * cnl->wcs_phase2_commit_pidcnt is non-zero even though there is no process in phase2 of commit. In this case
diff --git a/sr_port/wcs_recover.c b/sr_port/wcs_recover.c
index e922f62..671f698 100644
--- a/sr_port/wcs_recover.c
+++ b/sr_port/wcs_recover.c
@@ -17,6 +17,9 @@
 
 #ifdef UNIX
 #  include <sys/mman.h>
+# ifdef _AIX
+# include <sys/shm.h>
+# endif
 #  include "gtm_stat.h"
 #  include <errno.h>
 #  include <signal.h>
@@ -385,8 +388,7 @@ void wcs_recover(gd_region *reg)
 					 * this as corruption and fixup up this cr and proceed to the next cr.
 					 */
 					assert(FALSE || (WBTEST_CRASH_SHUTDOWN_EXPECTED == gtm_white_box_test_case_number));
-					if ((0 != r_epid) && (epid != r_epid))
-						GTMASSERT;
+					assertpro((0 == r_epid) || (epid == r_epid));
 					/* process still active but not playing fair or cache is corrupted */
 					GET_C_STACK_FROM_SCRIPT("BUFRDTIMEOUT", process_id, r_epid, TWICE);
 					send_msg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_BUFRDTIMEOUT, 6, process_id, cr->blk, cr, r_epid,
@@ -424,8 +426,7 @@ void wcs_recover(gd_region *reg)
 						epid = cr->epid;
 					else  if (BUF_OWNER_STUCK < lcnt)
 					{
-						if ((0 != cr->epid) && (epid != cr->epid))
-							GTMASSERT;
+						assertpro((0 == cr->epid) || (epid == cr->epid));
 						if (0 != epid)
 						{	/* process still active, but not playing fair */
 							send_msg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_STOPTIMEOUT, 3, epid,
@@ -493,10 +494,12 @@ void wcs_recover(gd_region *reg)
 				}
 			}	/* end of bitmap processing */
 			if (certify_all_blocks)
-				cert_blk(reg, cr->blk, (blk_hdr_ptr_t)GDS_REL2ABS(cr->buffaddr), 0, TRUE); /* GTMASSERT on error */
+				cert_blk(reg, cr->blk, (blk_hdr_ptr_t)GDS_REL2ABS(cr->buffaddr), 0, TRUE);/* assertpro() on error */
 			bt = bt_put(reg, cr->blk);
-			if (NULL == bt)		/* NULL value is only possible if wcs_get_space in bt_put fails */
-				GTMASSERT;	/* That is impossible here since we have called bt_refresh above */
+			/* NULL value for 'bt' is only possible if wcs_get_space in bt_put fails which is impossible here since we
+			 * have called bt_refresh above. Confrim this in the below assertpro().
+			 */
+			assertpro(NULL != bt);
 			bt->killtn = csd->trans_hist.curr_tn;	/* be safe; don't know when was last kill after recover */
 			if (CR_NOTVALID != bt->cache_index)
 			{	/* the bt already identifies another cache entry with this block */
@@ -630,8 +633,7 @@ void wcs_recover(gd_region *reg)
 				hq = (cache_que_head_ptr_t)(hash_hdr + (cr->blk % bt_buckets));
 				WRITE_LATCH_VAL(cr) = LATCH_SET;
 				bt = bt_put(reg, cr->blk);
-				if (NULL == bt)		/* NULL value is only possible if wcs_get_space in bt_put fails */
-					GTMASSERT;	/* That is impossible here since we have called bt_refresh above */
+				assertpro(NULL != bt);		/* NULL value is only possible if wcs_get_space in bt_put fails */
 				bt->killtn = csd->trans_hist.curr_tn;	/* be safe; don't know when was last kill after recover */
 				if (CR_NOTVALID == bt->cache_index)
 				{	/* no previous entry for this block; more recent cache record will twin when processed */
@@ -674,8 +676,7 @@ void wcs_recover(gd_region *reg)
 		if ((LATCH_SET > WRITE_LATCH_VAL(cr)) VMS_ONLY(|| (WRT_STRT_PNDNG == cr->iosb.cond)))
 		{	/* no process has an interest */
 			bt = bt_put(reg, cr->blk);
-			if (NULL == bt)		/* NULL value is only possible if wcs_get_space in bt_put fails */
-				GTMASSERT;	/* That is impossible here since we have called bt_refresh above */
+			assertpro(NULL != bt);		/* NULL value is only possible if wcs_get_space in bt_put fails */
 			bt->killtn = csd->trans_hist.curr_tn;	/* be safe; don't know when was last kill after recover */
 			if (CR_NOTVALID == bt->cache_index)
 			{	/* no previous entry for this block */
@@ -736,8 +737,7 @@ void wcs_recover(gd_region *reg)
 		UNIX_ONLY(WRITE_LATCH_VAL(cr) = LATCH_CLEAR;)
 		hq = (cache_que_head_ptr_t)(hash_hdr + (cr->blk % bt_buckets));
 		bt = bt_put(reg, cr->blk);
-		if (NULL == bt)		/* NULL value is only possible if wcs_get_space in bt_put fails */
-			GTMASSERT;	/* That is impossible here since we have called bt_refresh above */
+		assertpro(NULL != bt);		/* NULL value is only possible if wcs_get_space in bt_put fails */
 		bt->killtn = csd->trans_hist.curr_tn;	/* be safe; don't know when was last kill after recover */
 		if (CR_NOTVALID == bt->cache_index)
 		{	/* no previous entry for this block */
@@ -773,8 +773,7 @@ void wcs_recover(gd_region *reg)
 		if (!reg->read_only)
 			fileheader_sync(reg);
 	}
-	if (FALSE == wcs_verify(reg, FALSE, TRUE))	/* expect_damage is FALSE, in_wcs_recover is TRUE */
-		GTMASSERT;
+	assertpro(wcs_verify(reg, FALSE, TRUE));	/* expect_damage is FALSE, in_wcs_recover is TRUE */
 	/* skip INCTN processing in case called from mu_rndwn_file().
 	 * if called from mu_rndwn_file(), we have standalone access to shared memory so no need to increment db curr_tn
 	 * or write inctn (since no concurrent GT.M process is present in order to restart because of this curr_tn change)
@@ -838,7 +837,7 @@ void	wcs_mm_recover(gd_region *reg)
 	sm_uc_ptr_t		old_db_addrs[2], mmap_retaddr;
 	boolean_t       	was_crit, read_only;
 	unix_db_info		*udi;
-	const char		*syscall = "munmap()";
+	const char		*syscall;
 
 	VMS_ONLY(assert(FALSE));
 	assert(&FILE_INFO(reg)->s_addrs == cs_addrs);
@@ -860,7 +859,12 @@ void	wcs_mm_recover(gd_region *reg)
 	old_db_addrs[0] = cs_addrs->db_addrs[0];
 	old_db_addrs[1] = cs_addrs->db_addrs[1];
 	cs_addrs->db_addrs[0] = NULL;
+	syscall = MEM_UNMAP_SYSCALL;
+#	ifdef _AIX
+	status = shmdt(old_db_addrs[0] - BLK_ZERO_OFF(cs_data));
+#	else
 	status = (INTPTR_T)munmap((caddr_t)old_db_addrs[0], (size_t)(old_db_addrs[1] - old_db_addrs[0]));
+#	endif
 	if (-1 != status)
 	{
 		udi = FILE_INFO(gv_cur_region);
@@ -868,20 +872,28 @@ void	wcs_mm_recover(gd_region *reg)
 		mmap_sz = stat_buf.st_size - BLK_ZERO_OFF(cs_data);
 		CHECK_LARGEFILE_MMAP(gv_cur_region, mmap_sz); /* can issue rts_error MMFILETOOLARGE */
 		read_only = gv_cur_region->read_only;
-		syscall = "mmap()";
+		syscall = MEM_MAP_SYSCALL;
+#		ifdef _AIX
+		status = (sm_long_t)(mmap_retaddr = (sm_uc_ptr_t)shmat(udi->fd, (void *)NULL,
+								(read_only ? (SHM_MAP|SHM_RDONLY) : SHM_MAP)));
+		#else
 		status = (sm_long_t)(mmap_retaddr = (sm_uc_ptr_t)MMAP_FD(udi->fd, mmap_sz, BLK_ZERO_OFF(cs_data), read_only));
-		GTM_WHITE_BOX_TEST(WBTEST_MMAP_SYSCALL_FAIL, status, -1);
+#		endif
+		GTM_WHITE_BOX_TEST(WBTEST_MEM_MAP_SYSCALL_FAIL, status, -1);
 	}
 	if (-1 == status)
 	{
 		save_errno = errno;
-		WBTEST_ASSIGN_ONLY(WBTEST_MMAP_SYSCALL_FAIL, save_errno, ENOMEM);
+		WBTEST_ASSIGN_ONLY(WBTEST_MEM_MAP_SYSCALL_FAIL, save_errno, ENOMEM);
 		if (!was_crit)
 			rel_crit(gv_cur_region);
-		assert(WBTEST_ENABLED(WBTEST_MMAP_SYSCALL_FAIL));
+		assert(WBTEST_ENABLED(WBTEST_MEM_MAP_SYSCALL_FAIL));
 		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_SYSCALL, 5,
 				LEN_AND_STR(syscall), CALLFROM, save_errno);
 	}
+#	if defined(_AIX)
+	mmap_retaddr = (sm_uc_ptr_t)mmap_retaddr + BLK_ZERO_OFF(cs_data);
+#	endif
 	gds_map_moved(mmap_retaddr, old_db_addrs[0], old_db_addrs[1], mmap_sz); /* updates cs_addrs->db_addrs[1] */
 	cs_addrs->db_addrs[0] = mmap_retaddr;
         cs_addrs->total_blks = cs_addrs->ti->total_blks;
diff --git a/sr_port/xfer.h b/sr_port/xfer.h
index 0ec34f6..7471c41 100644
--- a/sr_port/xfer.h
+++ b/sr_port/xfer.h
@@ -29,11 +29,11 @@ XFER(xf_kill, op_kill),
 XFER(xf_add, op_add),
 XFER(xf_getindx, op_getindx),
 XFER(xf_putindx, op_putindx),
-XFER(xf_gvnaked, op_gvnaked),
+XFER(xf_gvnaked, op_gvnaked_fast),
 XFER(xf_ret, opp_ret),
 XFER(xf_numcmp, op_numcmp),
 XFER(xf_fnextract, op_fnextract),
-XFER(xf_gvname, op_gvname),
+XFER(xf_gvname, op_gvname_fast),
 XFER(xf_mval2mint, mval2mint),
 XFER(xf_contain, op_contain),
 XFER(xf_wteol, op_wteol),
@@ -149,7 +149,7 @@ XFER(xf_lkinit, op_lkinit),
 XFER(xf_zattach, op_zattach),
 XFER(xf_zedit, op_zedit),
 XFER(xf_restartpc, op_restartpc),
-XFER(xf_gvextnam, op_gvextnam),
+XFER(xf_gvextnam, op_gvextnam_fast),
 XFER(xf_fnzcall, op_fnzcall),
 XFER(xf_fnview, op_fnview),
 XFER(xf_zdeallocate, op_zdeallocate),
diff --git a/sr_port/zlput_rname.c b/sr_port/zlput_rname.c
index 3a84593..cba8f6b 100644
--- a/sr_port/zlput_rname.c
+++ b/sr_port/zlput_rname.c
@@ -25,7 +25,12 @@
 #include "gtm_text_alloc.h"
 #ifdef UNIX
 #include "srcline.h"
+#include "gtmlink.h"
 #endif
+#include "mmemory.h"
+
+STATICFNDCL boolean_t handle_active_old_versions(rhdtyp *old_rhead, rhdtyp *hdr);
+void zr_release(rhdtyp *old_rhead);
 
 #define S_CUTOFF 		7
 #define FREE_RTNTBL_SPACE 	17
@@ -37,59 +42,18 @@ GBLREF stack_frame	*frame_pointer;
 
 bool zlput_rname (rhdtyp *hdr)
 {
-	rhdtyp		*old_rhead, *rhead;
-	rtn_tabent	*rbot, *mid, *rtop;
-	stack_frame	*fp, *fpprev;
+	rhdtyp		*old_rhead, *rhead, *prev_active;
+	rtn_tabent	*mid;
 	char		*src, *new, *old_table;
-	int		comp;
-	ht_ent_mname    *tabent;
-	mname_entry	key;
-	uint4		entries;
-	mstr		*curline;
 	mident		*rtn_name;
 	size_t		size, src_len;
-#	ifdef VMS
-	uint4		*src_tbl;
-#	else
-	routine_source	*src_tbl;
-#	endif
+	boolean_t	found;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
 	rtn_name = &hdr->routine_name;
-	rbot = rtn_names;
-	rtop = rtn_names_end;
-	for (;;)
-	{	/* See if routine exists in list via a binary search which reverts to serial
-		   search when # of items drops below the threshold S_CUTOFF.
-		*/
-		if ((rtop - rbot) < S_CUTOFF)
-		{
-			comp = -1;
-			for (mid = rbot; mid <= rtop ; mid++)
-			{
-				MIDENT_CMP(&mid->rt_name, rtn_name, comp);
-				if (0 <= comp)
-					break;
-			}
-			break;
-		} else
-		{	mid = rbot + (rtop - rbot)/2;
-			MIDENT_CMP(&mid->rt_name, rtn_name, comp);
-			if (0 == comp)
-				break;
-			else if (0 > comp)
-			{
-				rbot = mid + 1;
-				continue;
-			} else
-			{
-				rtop = mid - 1;
-				continue;
-			}
-		}
-	}
-	if (comp)
+	found = find_rtn_tabent(&mid, rtn_name);
+	if (!found)
 	{	/* Entry was not found. Add in a new one */
 		old_table = NULL;
 		src = (char *)mid;
@@ -111,7 +75,6 @@ bool zlput_rname (rhdtyp *hdr)
 			memset(rtn_names_end + 1, 0, size - ((char *)(rtn_names_end + 1) - new));
 		}
 		memmove(mid + 1, src, src_len);
-		mid->rt_name = *rtn_name;
 		rtn_names_end++;
 		if (old_table && old_table != (char *)rtn_fst_table)
 			free(old_table);		/* original table can't be freed */
@@ -119,117 +82,116 @@ bool zlput_rname (rhdtyp *hdr)
 	} else
 	{	/* Entry exists. Update it */
 		old_rhead = (rhdtyp *)mid->rt_adr;
-		/* Verify routine is not currently active. If it is, we cannot replace it */
-		for (fp = frame_pointer; fp ; fp = fpprev)
-		{
-			fpprev = fp->old_frame_pointer;
-#			ifdef GTM_TRIGGER
-			if (NULL != fpprev && SFT_TRIGR & fpprev->type)
-				fpprev = *(stack_frame **)(fpprev + 1);
-#			endif
-			/* Check all possible versions of each routine header */
-			for (rhead = CURRENT_RHEAD_ADR(old_rhead); rhead;
-			     rhead = (rhdtyp *)NON_USHBIN_ONLY(rhead->old_rhead_ptr)USHBIN_ONLY(rhead->old_rhead_adr))
-				if (fp->rvector == rhead)
-					return FALSE;
-		}
-		zr_remove(old_rhead, NOBREAKMSG); /* get rid of the inactive breakpoints and release private code section */
-
-		/* If source has been read in for old routine, free space. Since routine name is the key, do this before
-		   (in USHBIN builds) we release the literal text section as part of the releasable read-only section.
-		*/
-		tabent = NULL;
-		if (NULL != (TREF(rt_name_tbl)).base)
-		{
-			key.var_name = mid->rt_name;
-			COMPUTE_HASH_MNAME(&key);
-			if (NULL != (tabent = lookup_hashtab_mname(TADR(rt_name_tbl), &key)) && tabent->value)
-			{
-#				ifdef VMS
-				src_tbl = (uint4 *)tabent->value;
-				/* Must delete the entries piece-meal */
-				entries = *(src_tbl + 1);
-				if (0 != entries)
-					/* Don't count line 0 which we bypass */
-					entries--;
-				/* curline start is 2 uint4s into src_tbl and then space past line 0 or
-				   we end up freeing the storage for line 0/1 twice since they have the
-				   same pointers.
-				*/
-				for (curline = RECAST(mstr *)(src_tbl + 2) + 1; 0 != entries; --entries, ++curline)
-				{
-					assert(curline->len);
-					free(curline->addr);
-				}
-				free(tabent->value);
-#				elif defined(UNIX)
-				/* Entries and source are malloc'd in two blocks on UNIX */
-				src_tbl = (routine_source *)tabent->value;
-				if (NULL != src_tbl->srcbuff)
-					free(src_tbl->srcbuff);
-				free(src_tbl);
-#				else
-#				  error "unsupported platform"
-#				endif
-				/* Note that there are two possible ways to proceed here to clear this entry:
-				 *   1. Just clear the value as we do below.
-				 *   2. Use the DELETE_HTENT() macro to remove the entry entirely from the hash table.
-				 *
-				 * We choose #1 since a routine that had had its source loaded is likely to have it reloaded
-				 * and if the source load rtn has to re-add the key, it won't reuse the deleted key (if it
-				 * remained a deleted key) until all other hashtable slots have been used up (creating a long
-				 * collision chain). A deleted key may not remain a deleted key if it was reached with no
-				 * collisions but will instead be turned into an unused key and be immediately reusable.
-				 * But since it is likely to be reused, we just zero the entry but this creates a necessity
-				 * that the key be maintained. If this is a non-USBHIN platform, everything stays around
-				 * anyway so that's not an issue. However, in a USHBIN platform, the literal storage the key
-				 * is pointing to gets released. For that reason, in the USHBIN processing section below, we
-				 * update the key to point to the newly loaded module's routine name.
-				 */
-				tabent->value = NULL;
-			}
+		/* Verify routine is not currently active. If it is, we cannot replace it -- wrong */
+		USHBIN_ONLY(prev_active = old_rhead->active_rhead_adr);
+		if (!handle_active_old_versions(old_rhead, hdr))
+			return FALSE;
+		USHBIN_ONLY( if (prev_active == old_rhead->active_rhead_adr))
+		{	/* old version not in use. free it */
+			zr_remove(old_rhead, NOBREAKMSG); /* remove breakpoints (now inactive) */
+			/* If source has been read in for old routine, free space. On VMS, source is associated with a routine name
+			 * table entry. On UNIX, source is associated with a routine header, and we may have different sources for
+			 * different linked versions of the same routine name.
+			 */
+			free_src_tbl(old_rhead);
+			zr_release(old_rhead); /* release private code section */
 		}
 #		ifndef USHBIN_SUPPORTED
 		hdr->old_rhead_ptr = (int4)old_rhead;
-		if (!old_rhead->old_rhead_ptr)
-		{
-		        fix_pages((unsigned char *)old_rhead, (unsigned char *)LNRTAB_ADR(old_rhead)
-				  + (SIZEOF(lnr_tabent) * old_rhead->lnrtab_len));
-		}
 #		else /* USHBIN_SUPPORTED */
-		if (!old_rhead->shlib_handle)
-	        { 	/* Migrate text literals pointing into text area we are about to throw away into the stringpool.
-			   We also can release the read-only releasable segment as it is no longer needed.
-			*/
-			stp_move((char *)old_rhead->literal_text_adr,
-				 (char *)(old_rhead->literal_text_adr + old_rhead->literal_text_len));
-			if (tabent)
-			{	/* There was (at one time) a $TEXT source section for this routine. We may have just
-				   released it but whether the source was for the routine just replaced or for an earlier
-				   replacement, the key for that segment is pointing into the readonly storage we
-				   are just about to release. Replace the key with the current one for this routine.
-				*/
-				assert(MSTR_EQ(&tabent->key.var_name, rtn_name));
-				tabent->key.var_name = *rtn_name;	/* Update key with newly saved mident */
-			}
-			zlmov_lnames(old_rhead); /* copy the label names from literal pool to malloc'd area */
-			GTM_TEXT_FREE(old_rhead->ptext_adr);
-			/* Reset the routine header pointers to the sections we just freed up.
-			 * NOTE: literal_text_adr shouldn't be reset as it points to the label area malloc'd
-			 * in zlmov_lnames() */
-			old_rhead->ptext_adr = old_rhead->ptext_end_adr = NULL;
-			old_rhead->lnrtab_adr = NULL;
-		}
-		urx_remove(old_rhead);
-		free(RW_REL_START_ADR(old_rhead));	/* Release the read-write releasable segments */
-		old_rhead->literal_adr = NULL;
-		old_rhead->vartab_adr = NULL;
-		free(old_rhead->linkage_adr);		/* Release the old linkage section */
-		old_rhead->linkage_adr = NULL;
 		hdr->old_rhead_adr = old_rhead;
 #		endif
-		mid->rt_name = *rtn_name;
 	}
-	mid->rt_adr= hdr;
+	mid->rt_name = *rtn_name;
+	mid->rt_adr = hdr;
+	UNIX_ONLY(hdr->source_code = NULL);
 	return TRUE;
 }
+
+STATICFNDEF boolean_t handle_active_old_versions(rhdtyp *old_rhead, rhdtyp *hdr)
+{
+	stack_frame	*fp;
+	rhdtyp 		*rhead, *new_rhead;
+	boolean_t	need_duplicate, on_stack;
+	ssize_t		sect_rw_nonrel_size;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	assert(old_rhead == CURRENT_RHEAD_ADR(old_rhead));
+	on_stack = FALSE;
+	need_duplicate = FALSE;
+	for (fp = frame_pointer; NULL != fp; fp = SKIP_BASE_FRAME(fp->old_frame_pointer))
+	{
+		if (MSTR_EQ(&fp->rvector->routine_name, &old_rhead->routine_name))
+		{
+			on_stack = TRUE;
+			if (CURRENT_RHEAD_ADR(fp->rvector) == old_rhead)
+				need_duplicate = TRUE;
+		}
+	}
+	if (on_stack)
+	{
+#		ifdef USHBIN_SUPPORTED
+		if (LINK_NORECURSIVE == TREF(relink_allowed))
+#		endif
+			return FALSE;
+	}
+#	ifdef USHBIN_SUPPORTED
+	if (need_duplicate)
+	{
+		new_rhead = (rhdtyp *)malloc(SIZEOF(rhdtyp));
+		*new_rhead = *old_rhead;
+		new_rhead->current_rhead_adr = new_rhead;
+		old_rhead->active_rhead_adr = new_rhead; /* reserve previous version on active chain */
+		for (fp = frame_pointer; NULL != fp; fp = SKIP_BASE_FRAME(fp->old_frame_pointer))
+			if (CURRENT_RHEAD_ADR(fp->rvector) == old_rhead)
+				fp->rvector = new_rhead; /* point frame's code vector at reserved copy of old routine version */
+		/* any field (e.g. the label table) that is currently shared by old_rhead needs to be copied to a separate area
+		 * other fields (e.g. literal mvals) will be redirected for old_rhead, so we just need to keep the older version
+		 * around (don't free it).
+		 */
+		sect_rw_nonrel_size = old_rhead->labtab_len * SIZEOF(lab_tabent);
+		new_rhead->labtab_adr = (lab_tabent *)malloc(sect_rw_nonrel_size);
+		memcpy(new_rhead->labtab_adr, old_rhead->labtab_adr, sect_rw_nonrel_size);
+		/* make sure to: skip urx_remove, do not free code section, etc. */
+		/* ALSO: we need to go through resolve linkage table entries corresponding to this the old version, and re-resolve
+		 * them to point into the new version */
+	}
+#	endif /* USHBIN_SUPPORTED */
+	return TRUE;
+}
+
+#ifdef USHBIN_SUPPORTED
+void zr_release(rhdtyp *old_rhead)
+{
+	if (!old_rhead->shlib_handle)
+        { 	/* Migrate text literals pointing into text area we are about to throw away into the stringpool.
+		   We also can release the read-only releasable segment as it is no longer needed.
+		*/
+		stp_move((char *)old_rhead->literal_text_adr,
+			 (char *)(old_rhead->literal_text_adr + old_rhead->literal_text_len));
+		zlmov_lnames(old_rhead); /* copy the label names from literal pool to malloc'd area */
+		GTM_TEXT_FREE(old_rhead->ptext_adr);
+		/* Reset the routine header pointers to the sections we just freed up.
+		 * NOTE: literal_text_adr shouldn't be reset as it points to the label area malloc'd
+		 * in zlmov_lnames() */
+		old_rhead->ptext_adr = old_rhead->ptext_end_adr = NULL;
+		old_rhead->lnrtab_adr = NULL;
+	}
+	urx_remove(old_rhead);
+	free(RW_REL_START_ADR(old_rhead));	/* Release the read-write releasable segments */
+	old_rhead->literal_adr = NULL;
+	old_rhead->vartab_adr = NULL;
+	free(old_rhead->linkage_adr);		/* Release the old linkage section */
+	old_rhead->linkage_adr = NULL;
+}
+#else /* non-USHBIN_SUPPORTED platforms */
+void zr_release(rhdtyp *old_rhead)
+{
+	if (!old_rhead->old_rhead_ptr)
+	{
+	        fix_pages((unsigned char *)old_rhead, (unsigned char *)LNRTAB_ADR(old_rhead)
+			  + (SIZEOF(lnr_tabent) * old_rhead->lnrtab_len));
+	}
+}
+#endif
diff --git a/sr_port/zshow.h b/sr_port/zshow.h
index a98bbc8..ca5893f 100644
--- a/sr_port/zshow.h
+++ b/sr_port/zshow.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -17,7 +17,12 @@
 #define ZSHOW_LOCAL		3
 #define ZSHOW_BUFF_ONLY 	4
 #define ZSHOW_NOPARM		-1
-#define ZSHOW_ALL		"IVBDLGSC"
+
+#ifdef UNIX
+# define ZSHOW_ALL		"IVBDLGRC"
+#else
+# define ZSHOW_ALL		"IVBDLGSC"
+#endif
 
 #define CLEANUP_ZSHOW_BUFF				\
 {							\
@@ -80,7 +85,7 @@ typedef struct zshow_out_struct
 #define QUOTE_DZCH 		"\"_$ZCH("
 #define CLOSE_PAREN_DOLLARZCH 	")_$ZCH("
 
-void		zshow_stack(zshow_out *output);
+void		zshow_stack(zshow_out *output, boolean_t show_checksum);
 void		zshow_devices(zshow_out *output);
 void		zshow_format_lock(zshow_out *output, mlk_pvtblk *temp);
 void		zshow_locks(zshow_out *output);
diff --git a/sr_port/zshow_ch.c b/sr_port/zshow_ch.c
index a61562f..21c4ef7 100644
--- a/sr_port/zshow_ch.c
+++ b/sr_port/zshow_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2003 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,7 @@
 
 CONDITION_HANDLER(zshow_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	CLEANUP_ZSHOW_BUFF;
 	NEXTCH;
 }
diff --git a/sr_port/zshow_output.c b/sr_port/zshow_output.c
index 02f4a62..210e05f 100644
--- a/sr_port/zshow_output.c
+++ b/sr_port/zshow_output.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -36,6 +36,7 @@
 #ifdef UNICODE_SUPPORTED
 #include "gtm_utf8.h"
 #endif
+#include "gtmimagename.h"
 
 #define F_SUBSC_LEN		 3
 #define N_SUBSC_LEN		 5
@@ -65,10 +66,14 @@ void zshow_output(zshow_out *out, const mstr *str)
 	int		buff_len;
 	int		device_width, inchar_width, cumul_width;
 	boolean_t	is_base_var, lvundef, utf8_active;
+	gd_addr		*gbl_gd_addr;
+	gvnh_reg_t	*gvnh_reg;
 #ifdef UNICODE_SUPPORTED
 	wint_t		codepoint;
 #endif
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	if (NULL != str)
 	{
 		buff_len = (int)(out->ptr - out->buff);
@@ -200,7 +205,7 @@ void zshow_output(zshow_out *out, const mstr *str)
 				is_base_var = LV_IS_BASE_VAR(lv);
 				LV_SBS_DEPTH(lv, is_base_var, sbs_depth);
 				if (MAX_LVSUBSCRIPTS <= (sbs_depth + 2))
-					rts_error(VARLSTCNT(1) ERR_MAXNRSUBSCRIPTS);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXNRSUBSCRIPTS);
 				out->out_var.lv.child = op_putindx(VARLSTCNT(2) lv, mv);
 				DEBUG_ONLY(LV_SBS_DEPTH(out->out_var.lv.child, FALSE, dbg_sbs_depth);)
 				assert(MAX_LVSUBSCRIPTS > (dbg_sbs_depth + 1));
@@ -286,8 +291,10 @@ void zshow_output(zshow_out *out, const mstr *str)
 			key_ovrhd = gv_currkey->end + 1 + F_SUBSC_LEN + N_SUBSC_LEN;
 			out->len = (int)(gv_cur_region->max_rec_size - key_ovrhd - SIZEOF(rec_hdr));
 			if (out->len < MIN_DATASIZE)
-				rts_error(VARLSTCNT(1) ERR_ZSHOWGLOSMALL);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZSHOWGLOSMALL);
 		}
+		gbl_gd_addr = TREF(gd_targ_addr);	/* set by op_gvname/op_gvextnam/op_gvnaked at start of ZSHOW cmd */
+		gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname/op_gvextnam/op_gvnaked at start of ZSHOW cmd */
 		if (out->code && out->code != out->curr_code)
 		{
 			gv_currkey->end = out->out_var.gv.end;
@@ -297,9 +304,13 @@ void zshow_output(zshow_out *out, const mstr *str)
 			mv->str.len = 1;
 			mv->str.addr = &buff;
 			*mv->str.addr = out->code;
-			mval2subsc(mv, gv_currkey);
+			mval2subsc(mv, gv_currkey, gv_cur_region->std_null_coll);
+			/* If gvnh_reg corresponds to a spanning global, then determine
+			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+			 */
+			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gbl_gd_addr, gv_currkey);
 			if (gv_currkey->end >= gv_cur_region->max_key_size)
-				ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
+				ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
 			op_gvkill();
 		}
 		if (str)
@@ -334,9 +345,13 @@ void zshow_output(zshow_out *out, const mstr *str)
 					op_gvnaked(VARLSTCNT(1) mv);
 				else
 				{
-					mval2subsc(mv, gv_currkey);
+					mval2subsc(mv, gv_currkey, gv_cur_region->std_null_coll);
+					/* If gvnh_reg corresponds to a spanning global, then determine
+					 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+					 */
+					GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gbl_gd_addr, gv_currkey);
 					if (gv_currkey->end >= gv_cur_region->max_key_size)
-						ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
+						ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
 				}
 				ENSURE_STP_FREE_SPACE((int)(out->ptr - out->buff));
 				mv->str.addr = (char *)stringpool.free;
@@ -362,9 +377,13 @@ void zshow_output(zshow_out *out, const mstr *str)
 				op_gvnaked(VARLSTCNT(1) mv);
 			else
 			{
-				mval2subsc(mv, gv_currkey);
+				mval2subsc(mv, gv_currkey, gv_cur_region->std_null_coll);
+				/* If gvnh_reg corresponds to a spanning global, then determine
+				 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
+				 */
+				GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, gbl_gd_addr, gv_currkey);
 				if (gv_currkey->end >= gv_cur_region->max_key_size)
-					ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
+					ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
 			}
 			ENSURE_STP_FREE_SPACE((int)(out->ptr - out->buff));
 			mv->str.addr = (char *)stringpool.free;
@@ -390,13 +409,11 @@ void zshow_output(zshow_out *out, const mstr *str)
 		}
 		break;
 	default:
-		GTMASSERT;
+		assertpro(FALSE && out->type);
 		break;
 	}
 	if (!process_exiting)
-	{
 		POP_MV_STENT();
-	}
 	out->curr_code = out->code;
 	out->flush = 0;
 }
diff --git a/sr_port/zshow_stack.c b/sr_port/zshow_stack.c
index ad81d17..6a883e5 100644
--- a/sr_port/zshow_stack.c
+++ b/sr_port/zshow_stack.c
@@ -18,6 +18,8 @@
 #include "mlkdef.h"
 #include "zshow.h"
 #include "io.h"
+#include "copy.h"
+#include "rtn_src_chksum.h"
 
 #define ZTRAP_FRAME		"    ($ZTRAP)"
 #define ZBRK_FRAME		"    (ZBREAK)"
@@ -35,14 +37,14 @@
 
 GBLREF stack_frame *frame_pointer;
 
-void zshow_stack(zshow_out *output)
+void zshow_stack(zshow_out *output, boolean_t show_checksum)
 {
 	boolean_t	line_reset;
 	unsigned char	*addr;
 	unsigned short	nocount_frames[MAX_INDR_PER_COUNTED], *nfp;
 	stack_frame	*fp;
 	mstr 		v;
-	unsigned char	buff[MAX_ENTRYREF_LEN + SIZEOF(INDR_OVERFLOW)];
+	unsigned char	buff[MAX_ENTRYREF_LEN + MAX_ROUTINE_CHECKSUM_DIGITS + SIZEOF(INDR_OVERFLOW)];
 
 	v.addr = (char *)&buff[0];
 	flush_pio();
@@ -50,16 +52,9 @@ void zshow_stack(zshow_out *output)
 	line_reset = FALSE;
 	for (fp = frame_pointer; ; fp = fp->old_frame_pointer)
 	{
+		fp = SKIP_BASE_FRAME(fp);
 		if (NULL == fp->old_frame_pointer)
-		{	/* This frame is a base frame - endpoint or jump it? */
-#		ifdef GTM_TRIGGER
-			if (fp->type & SFT_TRIGR)
-				/* Have a trigger baseframe, pick up stack continuation frame_pointer stored by base_frame() */
-				fp = *(stack_frame **)(fp + 1);
-			else
-#		endif
-				break;	/* Endpoint.. */
-		}
+			break; /* Endpoint.. */
 		if (!(fp->type & SFT_COUNT) || ((fp->type & SFT_ZINTR) && (fp->flags & SFF_INDCE)))
 		{	/* SFT_ZINTR is normally indirect but if the frame has been replaced by non-indirect frame via ZGOTO or GOTO
 			 * then do not include it in the indirect list here.
@@ -89,7 +84,11 @@ void zshow_stack(zshow_out *output)
 			{
 				MEMCPY_LIT(&buff[0], UNK_LOC_MESS);
 				v.len = SIZEOF(UNK_LOC_MESS) - 1;
-			}
+			} /*else if (show_checksum && !(fp->type & SFT_DM)) Don't print noisy 000...000 checksum for GTM$DMOD */
+			/* {
+				v.len += SPRINTF(&buff[v.len], ":");
+				v.len += append_checksum(&buff[v.len], fp->rvector);
+			}*/
 			if (nfp != &nocount_frames[0])
 			{
 				for (--nfp; nfp >= &nocount_frames[0]; nfp--)
@@ -130,6 +129,14 @@ void zshow_stack(zshow_out *output)
 				nfp = &nocount_frames[0];
 			} else
 			{
+				if ((0 < v.len) && show_checksum)
+				{	/* Note: we don't print a noisy 000...000 checksum for GTM$DMOD, because that logic
+					 * goes through the if-block above. Instead we only print checksums for "real" routines,
+					 * where it is meaningful.
+					 */
+					buff[v.len++] = ':';
+					v.len += append_checksum(&buff[v.len], fp->rvector);
+				}
 				output->flush = TRUE;
 				zshow_output(output, &v);
 			}
diff --git a/sr_port/zshow_svn.c b/sr_port/zshow_svn.c
index 9096fd2..a79c62c 100644
--- a/sr_port/zshow_svn.c
+++ b/sr_port/zshow_svn.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -127,6 +127,8 @@ static readonly char zusedstor_text[] = "$ZUSEDSTOR";
 static readonly char zversion_text[] = "$ZVERSION";
 static readonly char zyerror_text[] = "$ZYERROR";
 static readonly char zonlnrlbk_text[] = "$ZONLNRLBK";
+static readonly char zclose_text[] = "$ZCLOSE";
+static readonly char zkey_text[] = "$ZKEY";
 static readonly char arrow_text[] = "->";
 
 GBLREF mval		dollar_zdir;
@@ -400,6 +402,16 @@ void zshow_svn(zshow_out *output, int one_sv)
 			if (SV_ALL != one_sv)
 				break;
 		/* CAUTION: fall through */
+#		ifdef UNIX
+		case SV_ZCLOSE:
+			count = (int)(TREF(dollar_zclose));
+			MV_FORCE_MVAL(&var, count);
+			ZS_VAR_EQU(&x, zclose_text);
+			mval_write(output, &var, TRUE);
+			if (SV_ALL != one_sv)
+				break;
+#		endif
+		/* CAUTION: fall through */
 		case SV_ZCMDLINE:
 			get_command_line(&var, TRUE);	/* TRUE indicates $ZCMDLINE (i.e. processed not actual command line) */
 			ZS_VAR_EQU(&x, zcmdline_text);
@@ -517,6 +529,13 @@ void zshow_svn(zshow_out *output, int one_sv)
 			if (SV_ALL != one_sv)
 				break;
 		/* CAUTION: fall through */
+		case SV_ZKEY:
+			get_dlr_zkey(&var);
+			ZS_VAR_EQU(&x, zkey_text);
+			mval_write(output, &var, TRUE);
+			if (SV_ALL != one_sv)
+				break;
+		/* CAUTION: fall through */
 		case SV_ZLEVEL:
 			save_dollar_zlevel = dollar_zlevel();
 			MV_FORCE_MVAL(&var, save_dollar_zlevel);
@@ -771,7 +790,7 @@ void zshow_svn(zshow_out *output, int one_sv)
 			mval_write(output, &var, TRUE);
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE);
 
 	}
 }
diff --git a/sr_port/zwrite.h b/sr_port/zwrite.h
index 4098ca9..167f0c3 100644
--- a/sr_port/zwrite.h
+++ b/sr_port/zwrite.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -95,8 +95,6 @@ typedef struct gvzwrite_datablk_struct
 	unsigned char			*old_key;
 	unsigned char			*old_targ;
 	zwr_sub_lst			*sub;
-	gd_binding			*old_map;
-	gd_binding			*old_map_top;
 	gd_region			*gd_reg;
 	boolean_t			gv_last_subsc_null;
 	boolean_t			gv_some_subsc_null;
diff --git a/sr_port_cm/gtcm_bind_name.c b/sr_port_cm/gtcm_bind_name.c
index 14b2f1f..a40452b 100644
--- a/sr_port_cm/gtcm_bind_name.c
+++ b/sr_port_cm/gtcm_bind_name.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -17,7 +17,7 @@
 #include "fileinfo.h"
 #include "gdsbt.h"
 #include "gdsfhead.h"
-#include "filestruct.h"
+#include "filestruct.h"		/* needed for "jnl.h" and others */
 #include "cmidef.h"
 #include "hashtab_mname.h"
 #include "cmmdef.h"
@@ -25,6 +25,10 @@
 #include "gv_xform_key.h"
 #include "targ_alloc.h"
 #include "gvcst_protos.h"	/* for gvcst_root_search prototype */
+#include "gvnh_spanreg.h"
+#include "gtmimagename.h"
+#include "gv_trigger_common.h"	/* for *HASHT* macros used inside GVNH_REG_INIT macro */
+#include "jnl.h"		/* needed for "jgbl" */
 
 #define DIR_ROOT 1
 
@@ -36,31 +40,23 @@ void gtcm_bind_name(cm_region_head *rh, boolean_t xform)
 {
 	ht_ent_mname	*tabent;
 	mname_entry	 gvent;
-	boolean_t	added;
 	gvnh_reg_t	*gvnh_reg;
 
 	GTCM_CHANGE_REG(rh);	/* sets the global variables gv_cur_region/cs_addrs/cs_data appropriately */
 	gvent.var_name.addr = (char *)gv_currkey->base;
 	gvent.var_name.len = STRLEN((char *)gv_currkey->base);
 	COMPUTE_HASH_MNAME(&gvent);
-	if (NULL == (tabent = lookup_hashtab_mname(rh->reg_hash, &gvent)) || NULL == (gvnh_reg = (gvnh_reg_t *)tabent->value))
+	if (NULL != (tabent = lookup_hashtab_mname(rh->reg_hash, &gvent)))	/* WARNING ASSIGNMENT */
 	{
-		gv_target = targ_alloc(cs_data->max_key_size, &gvent, rh->reg);
-		gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
-		gvnh_reg->gvt = gv_target;
-		gvnh_reg->gd_reg = rh->reg;
-		if (NULL != tabent)
-		{ 	/* Since the global name was found but gv_target was null and now we created a new gv_target,
-			 * the hash table key must point to the newly created gv_target->gvname. */
-			tabent->key = gv_target->gvname;
-			tabent->value = (char *)gvnh_reg;
-		} else
-		{
-			added = add_hashtab_mname((hash_table_mname *)rh->reg_hash, &gv_target->gvname, gvnh_reg, &tabent);
-			assert(added);
-		}
-	} else
+		gvnh_reg = (gvnh_reg_t *)tabent->value;
+		assert(NULL != gvnh_reg);
 		gv_target = gvnh_reg->gvt;
+	} else
+	{
+		assert((dba_bg == REG_ACC_METH(rh->reg)) || (dba_mm == REG_ACC_METH(rh->reg)));
+		gv_target = targ_alloc(cs_data->max_key_size, &gvent, rh->reg);
+		GVNH_REG_INIT(NULL, rh->reg_hash, NULL, gv_target, rh->reg, gvnh_reg, tabent);
+	}
 	GVCST_ROOT_SEARCH;
 	if ((gv_target->collseq || gv_target->nct) && xform)
 		gv_xform_key(gv_currkey, FALSE);
diff --git a/sr_port_cm/gtcmtr_order.c b/sr_port_cm/gtcmtr_order.c
index c5ce458..8389396 100644
--- a/sr_port_cm/gtcmtr_order.c
+++ b/sr_port_cm/gtcmtr_order.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -39,6 +39,9 @@ GBLREF gv_key			*gv_altkey;
 GBLREF sgmnt_addrs		*cs_addrs;
 GBLREF gd_region		*gv_cur_region;
 
+error_def(ERR_TEXT);
+error_def(ERR_UNIMPLOP);
+
 bool gtcmtr_order(void)
 {
 	boolean_t		found;
@@ -49,9 +52,6 @@ bool gtcmtr_order(void)
 	boolean_t		last_subsc_is_null;
 	cm_region_head		*cm_reg_head;
 
-	error_def(ERR_UNIMPLOP);
-	error_def(ERR_TEXT);
-
 	ptr = curr_entry->clb_ptr->mbf;
 	assert(CMMS_Q_ORDER == *ptr);
 	ptr++;
@@ -106,9 +106,7 @@ bool gtcmtr_order(void)
 					&& (STR_SUB_PREFIX == gv_currkey->base[gv_currkey->end - 2])));
 			if (!last_subsc_is_null)
 			{	/* last subscript is not null */
-				gv_currkey->base[gv_currkey->end - 1] = 1;
-				gv_currkey->base[gv_currkey->end + 1] = KEY_DELIMITER;
-				gv_currkey->end++;
+				GVKEY_INCREMENT_ORDER(gv_currkey);
 			} else
 				gv_currkey->base[gv_currkey->prev] = 1;
 		}
@@ -133,8 +131,8 @@ bool gtcmtr_order(void)
 									 * and two <NUL> delimiters */
 			if ((PRE_V5_MAX_MIDENT_LEN < strlen((char *)gv_altkey->base)) && !curr_entry->client_supports_long_names)
 			{
-				rts_error(VARLSTCNT(6) ERR_UNIMPLOP, 0,
-					ERR_TEXT, 2,
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(6) ERR_UNIMPLOP, 0, ERR_TEXT, 2,
 					LEN_AND_LIT("GT.CM client does not support global names longer than 8 characters"));
 			}
 			save_key = gv_currkey;
@@ -149,10 +147,7 @@ bool gtcmtr_order(void)
 				gv_altkey = save_key;
 				break;
 			}
-			gv_currkey->base[gv_currkey->end - 1] = 1;
-			gv_currkey->base[gv_currkey->end + 1] = 0;
-			gv_currkey->end += 1;
-
+			GVKEY_INCREMENT_ORDER(gv_currkey);
 		}
 	}
 	if (!found)
diff --git a/sr_port_cm/gtcmtr_query.c b/sr_port_cm/gtcmtr_query.c
index 7ccd0fe..815f10e 100644
--- a/sr_port_cm/gtcmtr_query.c
+++ b/sr_port_cm/gtcmtr_query.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -86,19 +86,13 @@ bool gtcmtr_query(void)
 				 	SUBSCRIPT_STDCOL_NULL))
 		{
 			assert(!was_null); /* null to non null transformation not allowed */
-			gv_currkey->base[gv_currkey->end++] = 1;
-			gv_currkey->base[gv_currkey->end++] = 0;
-			gv_currkey->base[gv_currkey->end] = 0;
+			GVKEY_INCREMENT_QUERY(gv_currkey);
 		} else
 		{
 			if (0 == gv_cur_region->std_null_coll)
 				gv_currkey->base[gv_currkey->prev] = 1;
 			else
-			{
-				gv_currkey->base[gv_currkey->end++]= 1;
-				gv_currkey->base[gv_currkey->end++] = 0;
-				gv_currkey->base[gv_currkey->end] = 0;
-			}
+				GVKEY_INCREMENT_QUERY(gv_currkey);
 		}
 	}
 	found = (0 != gv_target->root) ? (curr_entry->query_is_queryget ? gvcst_queryget(&val) : gvcst_query()) : FALSE;
diff --git a/sr_port_cm/gvcmy_open.c b/sr_port_cm/gvcmy_open.c
index d686ed9..97ef98e 100644
--- a/sr_port_cm/gvcmy_open.c
+++ b/sr_port_cm/gvcmy_open.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -47,9 +47,9 @@ error_def(ERR_BADSRVRNETMSG);
 error_def(ERR_INVNETFILNM);
 error_def(ERR_LOGTOOLONG);
 error_def(ERR_NETDBOPNERR);
+error_def(ERR_REMOTEDBNOSPGBL);
 error_def(ERR_SYSCALL);
 
-
 #define GTCM_ENVVAR_PFX "GTCM_"
 #define GTCM_ENVVAR_PFXLEN (SIZEOF(GTCM_ENVVAR_PFX) - 1)
 
@@ -74,9 +74,11 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 	UNIX_ONLY(MSTR_DEF(task, 0, NULL);)
 
 	ESTABLISH(gvcmy_open_ch);
+	if (reg->is_spanned)
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REMOTEDBNOSPGBL, 2, REG_LEN_STR(reg));
 #ifdef VMS
 	if (!nb->nam$b_node)
-		rts_error(VARLSTCNT(1) ERR_INVNETFILNM);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVNETFILNM);
 	top = nb->nam$l_esa + nb->nam$b_esl;
 	fn = nb->nam$l_node + nb->nam$b_node;
 	node.dsc$b_dtype = task.dsc$b_dtype = 14;
@@ -88,7 +90,7 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 	status = TRANS_LOG_NAME(&task1, &task2, (char *)buff, SIZEOF(buff), dont_sendmsg_on_log2long);
 #elif defined(UNIX)
 	if (!pb->b_node)
-		rts_error(VARLSTCNT(1) ERR_INVNETFILNM);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVNETFILNM);
 	fn = (unsigned char *)pb->l_dir;
 	top = fn + pb->b_esl - pb->b_node; 	/* total length except node gives end of string */
 	/*
@@ -122,10 +124,11 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 		{
 #			ifdef UNIX
 			if (SS_LOG2LONG == status)
-				rts_error(VARLSTCNT(5) ERR_LOGTOOLONG, 3, task1.len, task1.addr, SIZEOF(buff) - 1);
+				rts_error_csa(CSA_ARG(NULL)
+					VARLSTCNT(5) ERR_LOGTOOLONG, 3, task1.len, task1.addr, SIZEOF(buff) - 1);
 			else
 #			endif
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 		}
 		VMS_ONLY(
 			task.dsc$a_pointer = buff;
@@ -164,14 +167,14 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 	{
 		if (new)
 			gvcmy_close(clb_ptr);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
 	}
 	status = cmi_read(clb_ptr);
 	if (CMI_ERROR(status))
 	{
 		if (new)
 			gvcmy_close(clb_ptr);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
 	}
 	if (CMMS_T_REGNUM != *clb_ptr->mbf)
 	{
@@ -179,7 +182,7 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 		{
 			if (new)
 				gvcmy_close(clb_ptr);
-			rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
 		}
 		gvcmz_errmsg(clb_ptr, new);
 	}
@@ -209,7 +212,7 @@ void gvcmy_open(gd_region *reg, parse_blk *pb)
 	reg->std_null_coll = (li->server_supports_std_null_coll) ? *ptr++ : 0;
 		/* From level 210 (GT.M V5), server will send null subscript collation info into CMMS_S_INITREG message */
 	reg->dyn.addr->cm_blk = clb_ptr;
-	reg->dyn.addr->acc_meth = dba_cm;
+	REG_ACC_METH(reg) = dba_cm;
 	SET_REGION_OPEN_TRUE(reg, WAS_OPEN_FALSE);
 	clb_ptr->mbl = li->buffer_size;
 	if (clb_ptr->mbl < CM_MINBUFSIZE)
diff --git a/sr_port_cm/gvcmy_open_ch.c b/sr_port_cm/gvcmy_open_ch.c
index 53a23ab..b32ef62 100644
--- a/sr_port_cm/gvcmy_open_ch.c
+++ b/sr_port_cm/gvcmy_open_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,12 +34,12 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(gvcmy_open_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (DUMPABLE)
 	{ /* don't disturb state so that the core reflects the "bad" state */
 		NEXTCH;
 	}
-	if (WARNING == SEVERITY || INFO == SEVERITY)
+	if (WARNING == SEVERITY)
 	{
 		PRN_ERROR;
 		CONTINUE;
diff --git a/sr_port_cm/gvcmz_netopen.c b/sr_port_cm/gvcmz_netopen.c
index 16cfaf1..0995e98 100644
--- a/sr_port_cm/gvcmz_netopen.c
+++ b/sr_port_cm/gvcmz_netopen.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -43,6 +43,11 @@ GBLREF jnl_process_vector	*prc_vec;
 GBLREF spdesc			stringpool;
 GBLREF struct NTD		*ntd_root;
 
+error_def(CMERR_INVPROT);
+error_def(ERR_BADSRVRNETMSG);
+error_def(ERR_NETDBOPNERR);
+error_def(ERR_TEXT);
+
 static volatile boolean_t	second_attempt = FALSE;
 static protocol_msg		myproto;
 static struct CLB		*clb;
@@ -52,9 +57,9 @@ void		v010_jnl_prc_vector(void *);
 
 CONDITION_HANDLER(gvcmz_netopen_ch)
 {
-	error_def(CMERR_INVPROT);
-
-	START_CH;
+	/* This condition handler is established only for VMS. In VMS, we do not do CONTINUE for INFO/SUCCESS severity.
+	 * FALSE input to START_CH achieves the same thing. */
+	START_CH(FALSE);
 	if (SIGNAL != CMERR_INVPROT || second_attempt)
 	{
 		second_attempt = FALSE;
@@ -75,9 +80,6 @@ void gvcmz_netopen_attempt(struct CLB *c)
 	jnl_process_vector	temp_vect;
 #endif
 
-	error_def(ERR_BADSRVRNETMSG);
-	error_def(ERR_NETDBOPNERR);
-
 	VMS_ONLY(
 		ESTABLISH(gvcmz_netopen_ch); /* our old servers run only on VMS; no need for retry on other OSs */
 		clb = c; /* need this assignment since we can't pass c to gvcmz_netopen_ch */
@@ -128,20 +130,20 @@ void gvcmz_netopen_attempt(struct CLB *c)
 	if (CMI_ERROR(status))
 	{
 		gvcmy_close(c);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
 	}
 	status = cmi_read(c);	/* return message should be same size */
 	if (CMI_ERROR(status))
 	{
 		gvcmy_close(c);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
 	}
 	if (CMMS_T_INITPROC != *c->mbf)
 	{
 		if (CMMS_E_ERROR != *c->mbf)
 		{
 			gvcmy_close(c);
-			rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
 		}
 		gvcmz_errmsg(c, FALSE);
 	}
@@ -162,11 +164,6 @@ struct CLB *gvcmz_netopen(struct CLB *c, cmi_descriptor *node, cmi_descriptor *t
 	uint4			status;
 	protocol_msg		*server_proto;
 
-	error_def(ERR_BADSRVRNETMSG);
-	error_def(ERR_NETDBOPNERR);
-	error_def(ERR_TEXT);
-	error_def(CMERR_INVPROT);
-
 	c = UNIX_ONLY(cmi_alloc_clb())VMS_ONLY(cmu_makclb());
 	c->usr = malloc(SIZEOF(link_info));
 	li = c->usr;
@@ -206,7 +203,7 @@ struct CLB *gvcmz_netopen(struct CLB *c, cmi_descriptor *node, cmi_descriptor *t
 		free(VMS_ONLY(c->tnd.dsc$a_pointer) UNIX_ONLY(c->tnd.addr));
 		VMS_ONLY(lib$free_vm(&SIZEOF(*c), &c, 0);)
 		UNIX_ONLY(cmi_free_clb(c));
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
 	}
 	if (0 == ntd_root)
 		ntd_root = cmu_ntdroot();
@@ -220,13 +217,13 @@ struct CLB *gvcmz_netopen(struct CLB *c, cmi_descriptor *node, cmi_descriptor *t
 	if (S_HDRSIZE + S_PROTSIZE + 2 != c->cbl)
 	{
 		gvcmy_close(c);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
 	}
 	server_proto = (protocol_msg *)(c->mbf + 1);
 	if (!gtcm_protocol_match(server_proto, &myproto))
 	{
 		gvcmy_close(c);
-		rts_error(VARLSTCNT(3) ERR_NETDBOPNERR, 0, CMERR_INVPROT);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, CMERR_INVPROT);
 	}
 	li->convert_byteorder = (gtcm_is_big_endian(&myproto) != gtcm_is_big_endian(server_proto));
 	li->query_is_queryget = gtcm_is_query_queryget(server_proto, &myproto);
@@ -236,7 +233,7 @@ struct CLB *gvcmz_netopen(struct CLB *c, cmi_descriptor *node, cmi_descriptor *t
 	if (!(li->err_compat = gtcm_err_compat((protocol_msg *)(c->mbf + 1), &myproto)))
 	{
 		gvcmy_close(c);
-		rts_error(VARLSTCNT(6) ERR_NETDBOPNERR, 0, ERR_TEXT, 2,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_NETDBOPNERR, 0, ERR_TEXT, 2,
 				LEN_AND_LIT("GTCM functionality not implemented between UNIX and VMS yet"));
 	}
 	gtcm_connection = TRUE;
diff --git a/sr_unix/CMakeLists.txt b/sr_unix/CMakeLists.txt
index 9f3b229..cca42e8 100644
--- a/sr_unix/CMakeLists.txt
+++ b/sr_unix/CMakeLists.txt
@@ -57,7 +57,8 @@ set(gtm_osarch_libs "")
 set(gt_src_list)
 set(sources_used "")
 set(extralibs "")
-set(is_encryption_supported 1)
+# Disable encryption for the time being. Need to change this to invoke the gtmcrypt Makefile AS 2013.12.18
+set(is_encryption_supported 0)
 set(libmumpsrestoreregex "")
 message("--> OS = ${CMAKE_SYSTEM_NAME} / ARCH = ${CMAKE_SYSTEM_PROCESSOR}")
 # Establish platform
@@ -220,10 +221,12 @@ set_source_list(gtcm_server      gtcm_main omi_srvc_xct)
 set_source_list(gtcm_shmclean    gtcm_shmclean)
 set_source_list(gtmsecshr        gtmsecshr_wrapper)
 set_source_list(gtmsecshr_real   gtmsecshr)
-set_source_list(libgtmcrypt      gtmcrypt_ref gtmcrypt_pk_ref gtmcrypt_dbk_ref)
+set_source_list(libgtmcrypt      gtmcrypt_ref gtmcrypt_pk_ref gtmcrypt_dbk_ref gtmcrypt_sym_ref)
+set_source_list(libgtmtls        gtm_tls_impl)
+set_source_list(libgtmcryptutil  gtmcrypt_util)
 set_source_list(libgtmshr        gtm_main)
 set_source_list(lke              lke lke_cmd)
-set_source_list(maskpass         maskpass)
+set_source_list(maskpass         maskpass gtmcrypt_util)
 set_source_list(mumps            gtm)
 set_source_list(mupip            mupip mupip_cmd)
 set_source_list(semstat2         semstat2)
@@ -472,6 +475,14 @@ if(is_encryption_supported)
     set(GPG_LIBRARIES ${GPG_LIBRARIES} ${GPGLIB_${gpglib}})
   endforeach()
 
+  # Iterate over the list of SSL related libraries
+  foreach(ssl)
+    # For each library, we need a new CMake variable, hence TLSLIB_${tlslib}
+    find_library(TLSLIB_${tlslib} NAME ${tlslib} PATHS ${CMAKE_LIBRARY_PATH})
+    # Append the found library to the list
+    set(TLS_LIBRARIES ${TLS_LIBRARIES} ${TLSLIB_${tlslib}})
+  endforeach()
+
   add_library(libgtmcrypt MODULE ${libgtmcrypt_SOURCES})
   set_target_properties(libgtmcrypt PROPERTIES
     OUTPUT_NAME gtmcrypt
@@ -481,57 +492,76 @@ if(is_encryption_supported)
   target_link_libraries(libgtmcrypt ${GPG_LIBRARIES})
   install(TARGETS libgtmcrypt DESTINATION ${GTM_INSTALL_DIR}/plugin)
 
+  add_library(libgtmtls MODULE ${libgtmtls_SOURCES})
+  set_target_properties(libgtmtls PROPERTIES
+    OUTPUT_NAME gtmtls
+    LIBRARY_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin
+    )
+  target_link_libraries(libgtmtls ${TLS_LIBRARIES})
+  install(TARGETS libgtmtls DESTINATION ${GTM_INSTALL_DIR}/plugin)
+
+  add_library(libgtmcryptutil MODULE ${libgtmcryptutil_SOURCES})
+  set_target_properties(libgtmcryptutil PROPERTIES
+    OUTPUT_NAME gtmcryptutil
+    COMPILE_DEFINITIONS "USE_GCRYPT -DUSE_AES256CFB"
+    LIBRARY_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin
+    )
+  target_link_libraries(libgtmcryptutil ${GPG_LIBRARIES})
+  install(TARGETS libgtmcryptutil DESTINATION ${GTM_INSTALL_DIR}/plugin)
+
   add_executable(maskpass ${maskpass_SOURCES})
   target_link_libraries(maskpass ${GPG_LIBRARIES})
   set_target_properties(maskpass PROPERTIES
-    COMPILE_DEFINITIONS USE_GCRYPT
+    COMPILE_DEFINITIONS "USE_GCRYPT -DUSE_SYSLIB_FUNCS"
     RUNTIME_OUTPUT_DIRECTORY ${GTM_BINARY_DIR}/plugin/gtmcrypt
     )
   install(TARGETS maskpass DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt)
+endif()
 
-  foreach(f
+# Always copy files into the plugin directory
+foreach(f
+      Makefile.mk
       add_db_key.sh
-      build.sh
       encrypt_sign_db_key.sh
       gen_keypair.sh
       gen_sym_hash.sh
       gen_sym_key.sh
-      gtmcrypt.tab
+      gtm_tls_impl.c
+      gtm_tls_impl.h
+      gtm_tls_interface.h
       gtmcrypt_dbk_ref.c
       gtmcrypt_dbk_ref.h
       gtmcrypt_interface.h
       gtmcrypt_pk_ref.c
       gtmcrypt_pk_ref.h
-      gtmcrypt_dbk_ref.c
-      gtmcrypt_dbk_ref.h
       gtmcrypt_ref.c
       gtmcrypt_ref.h
+      gtmcrypt_sym_ref.c
       gtmcrypt_sym_ref.h
-      gtmxc_types.h
+      gtmcrypt_util.c
+      gtmcrypt_util.h
       import_and_sign_key.sh
-      install.sh
       maskpass.c
       pinentry-gtm.sh
       pinentry.m
-      pinentry.m
       show_install_config.sh
-      )
-    set(f_in "${GTM_SOURCE_DIR}/sr_unix/${f}")
-    set(f_out "${GTM_BINARY_DIR}/plugin/gtmcrypt/${f}")
-    add_custom_command(
-      OUTPUT "${f_out}"
-      DEPENDS "${f_in}"
-      COMMAND ${CMAKE_COMMAND} -E copy "${f_in}" "${f_out}"
-      )
-    if("${f}" MATCHES "\\.sh$")
-      set(permissions PERMISSIONS ${install_permissions_script})
-    else()
-      set(permissions "")
-    endif()
-    install(FILES "${f_out}" DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt ${permissions})
-    list(APPEND files_to_place "${f_out}")
-  endforeach()
-endif()
+    )
+  set(f_in "${GTM_SOURCE_DIR}/sr_unix/${f}")
+  string(REGEX REPLACE ".mk$" "" f_mod "${f}")
+  set(f_out "${GTM_BINARY_DIR}/plugin/gtmcrypt/${f_mod}")
+  add_custom_command(
+    OUTPUT "${f_out}"
+    DEPENDS "${f_in}"
+    COMMAND ${CMAKE_COMMAND} -E copy "${f_in}" "${f_out}"
+    )
+  if("${f}" MATCHES "\\.sh$")
+    set(permissions PERMISSIONS ${install_permissions_script})
+  else()
+    set(permissions "")
+  endif()
+  install(FILES "${f_out}" DESTINATION ${GTM_INSTALL_DIR}/plugin/gtmcrypt ${permissions})
+  list(APPEND files_to_place "${f_out}")
+endforeach()
 
 install(TARGETS
   mumps
@@ -623,6 +653,7 @@ endforeach()
 
 set(files)
 foreach(f
+  gtm_common_defs.h
   gtm_descript.h
   gtm_limits.h
   gtm_sizeof.h
@@ -759,6 +790,7 @@ Halt")
     )
   list(APPEND files_to_place ${help}help.dat)
   install(FILES ${GTM_BINARY_DIR}/${help}help.dat DESTINATION ${GTM_INSTALL_DIR})
+  install(FILES ${GTM_BINARY_DIR}/${help}help.gld DESTINATION ${GTM_INSTALL_DIR})
 endforeach()
 #-----------------------------------------------------------------------------
 
diff --git a/sr_unix/Makefile.mk b/sr_unix/Makefile.mk
new file mode 100644
index 0000000..959b991
--- /dev/null
+++ b/sr_unix/Makefile.mk
@@ -0,0 +1,223 @@
+#################################################################
+#								#
+#	Copyright 2013 Fidelity Information Services, Inc	#
+#								#
+#	This source code contains the intellectual property	#
+#	of its copyright holder(s), and is made available	#
+#	under a license.  If you do not know the terms of	#
+#	the license, please stop and do not read further.	#
+#								#
+#################################################################
+
+# Default configuration parameters. These values can be overridden by passing different values to build different build targets. For
+# the list of available build targets, see below.
+image = DEBUG
+thirdparty = gcrypt
+algo = AES256CFB
+# If the machine has a libgcrypt version <= 1.4.1, then FIPS mode cannot be turned on.
+gcrypt_nofips = 0
+# Default HP-UX OpenSSL include/lib base directory.
+HPUX_OPENSSL_ROOT = /opt/openssl/1.0.1e/
+
+# Verify that $gtm_dist is defined
+ifndef gtm_dist
+$(error $$gtm_dist not defined!)
+endif
+
+DISTDIR = $(gtm_dist)
+PLUGINDIR = $(DISTDIR)/plugin
+CURDIR = `pwd`
+
+# Determine machine and OS type.
+UNAMESTR = $(shell uname -a)
+MACHTYPE = $(shell uname -m)
+
+ifneq (,$(findstring Linux,$(UNAMESTR)))
+	FILEFLAG = -L
+endif
+# 64 bit system? 0 for yes!
+BIT64 = $(shell file $(FILEFLAG) $(DISTDIR)/mumps | grep -q -E '64-bit|ELF-64'; echo $$?)
+
+# Default installation target. This allows for the build system to randomize `thirdparty' and `algo' thereby changing the default
+# gtmcrypt install link.
+install_targ = libgtmcrypt_$(thirdparty)_$(algo).so
+
+# Setup build type -- debug or production.
+ifneq ($(image),DEBUG)
+	debug_flag =
+	optimize = -O2
+else
+	debug_flag = -g -DDEBUG
+	optimize =
+endif
+
+CC = cc
+LD = $(CC)
+
+# Setup common compiler flags
+CFLAGS = -c $(debug_flag) $(optimize) -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D_LARGEFILE64_SOURCE=1
+
+ifneq ($(gcrypt_nofips),0)
+	gcrypt_nofips_flag = -DGCRYPT_NO_FIPS
+else
+	gcrypt_nofips_flag =
+endif
+
+# Set default extra CFLAGS and LDFLAGS for building maskpass and libgtmcryptutil.so. Both of these use SHA512 for password
+# obfuscation which must come from either OpenSSL or Libgcrypt. Historically, on AIX we have always made OpenSSL the default
+# library and on non-AIX platforms, it has been libgcrypt.
+default_thirdparty_CFLAGS = -DUSE_GCRYPT
+default_thirdparty_LDFLAGS = -lgcrypt -lgpg-error
+
+# Platform specific compiler and linker flags
+# Linux
+LIBFLAGS =
+IFLAGS =
+ifneq (,$(findstring Linux,$(UNAMESTR)))
+	# -fPIC for Position Independent Code.
+	CFLAGS += -fPIC
+	LDFLAGS =
+	# So that dependent libraries are loaded from the parent library's load path at runtime
+	RPATHFLAGS = -Wl,-rpath,'$$ORIGIN'
+	# So that we can build shared library.
+	LDSHR = -shared
+endif
+
+# Solaris
+ifneq (,$(findstring Solaris,$(UNAMESTR)))
+	# -fPIC for Position Independent Code; -m64 for 64-bit
+	CFLAGS += -fPIC -m64
+	LDFLAGS = -Wl,-64 -m64
+	# So that dependent libraries are loaded from the parent library's load path at runtime
+	RPATHFLAGS = -Wl,-R,'$$ORIGIN'
+	LDSHR = -G
+endif
+
+# HP-UX
+ifneq (,$(findstring HP-UX,$(UNAMESTR)))
+	# +Z is for Position Independent Code; -Ae for Extended ANSI mode and +DD64 for 64-bit
+	CFLAGS += +Z -Ae  +DD64
+	LDFLAGS = +DD64
+	# So that dependent libraries are loaded from the parent library's load path at runtime
+	RPATHFLAGS = -Wl,+b,\$$ORIGIN
+	# -b for shared library and -B,symbolic for assigning protected export calls to symbols.
+	LDSHR = -Wl,-b,-B,symbolic
+	LIBFLAGS = -L $(HPUX_OPENSSL_ROOT)/lib
+	IFLAGS = -I $(HPUX_OPENSSL_ROOT)/include
+endif
+
+# AIX
+ifneq (,$(findstring AIX,$(UNAMESTR)))
+	# -qchars=signed forces `char' type to be treated as signed chars.
+	# -qsrcmsg enhances error reporting.
+	# -qmaxmem limits the amount of memory used for local tables of specific, memory-intensive operations (in kilobytes).
+	CFLAGS += -qchars=signed -qsrcmsg -qmaxmem=8192 -D_TPARM_COMPAT
+
+	# -qro places string literals in read-only storage.
+	# -qroconst places constants in read-only storage.
+	# -q64 forces 64-bit object generation
+	CFLAGS += -qro -qroconst -q64
+	# -q64 for 64-bit object generation
+	# -brtl for allowing both '.a' and '.so' to be searched at runtime.
+	LDFLAGS = -q64 -brtl
+	RPATHFLAGS =
+	# -G so that we can build shared library
+	# -bexpall exports all symbols from the shared library.
+	# -bnoentry to tell the linker that shared library has no entry point.
+	LDSHR = -Wl,-G -bexpall -bnoentry
+	# On AIX, build maskpass and libgtmcryptutil.so with OpenSSL's libcrypto instead of libgcrypt.
+	default_thirdparty_CFLAGS = -DUSE_OPENSSL
+	default_thirdparty_LDFLAGS = -lcrypto
+endif
+
+# Common header and library paths
+IFLAGS += -I /usr/local/ssl/include -I /usr/local/include -I /usr/include -I $(gtm_dist) -I $(CURDIR)
+ifeq ($(BIT64),0)
+	LIBFLAGS += -L /usr/local/ssl/lib -L /usr/local/lib64 -L /usr/local/lib -L /usr/lib64 -L /usr/lib -L /lib64 -L /lib -L `pwd`
+else
+	LIBFLAGS += -L /usr/local/ssl/lib -L /usr/local/lib32 -L /usr/local/lib -L /usr/lib32 -L /usr/lib -L /lib32 -L /lib -L `pwd`
+endif
+
+CFLAGS += $(IFLAGS)
+LDFLAGS += $(LIBFLAGS) -o
+
+COMMON_LIBS = -lgtmcryptutil -lconfig
+
+# List of all files needed for building the encryption plugin.
+crypt_srcfiles = gtmcrypt_ref.c gtmcrypt_pk_ref.c gtmcrypt_dbk_ref.c gtmcrypt_sym_ref.c
+crypt_objfiles = gtmcrypt_ref.o gtmcrypt_pk_ref.o gtmcrypt_dbk_ref.o gtmcrypt_sym_ref.o
+all_crypt_objfiles = $(crypt_objfiles)
+
+tls_srcfiles = gtm_tls_impl.c gtm_tls_impl.h gtm_tls_interface.h
+tls_objfiles = gtm_tls_impl.o
+
+all_objfiles = $(all_crypt_objfiles) $(tls_objfiles) maskpass.o gtmcrypt_util.o gtmcrypt_util_syslib.o
+
+all: libgtmcryptutil.so maskpass gcrypt openssl gtmtls
+	rm -f $(crypt_objfiles) maskpass.o
+
+gtmcrypt_util.o: gtmcrypt_util.c
+	$(CC) $(CFLAGS) $(default_thirdparty_CFLAGS) $^
+
+# Rules for building libgtmcryptutil.so
+libgtmcryptutil.so: gtmcrypt_util.o
+	$(LD) $^ $(LDSHR) $(LDFLAGS) $@ $(default_thirdparty_LDFLAGS)
+
+# Rules for building maskpass
+maskpass.o: maskpass.c
+	$(CC) $(CFLAGS) $^
+
+# Since maskpass is a standalone utility and doesn't depend on functions like `gtm_malloc' and `gtm_free' for memory allocation,
+# build gtmcrypt_util.c with -DUSE_SYSLIB_FUNCS.
+gtmcrypt_util_syslib.o: gtmcrypt_util.c
+	$(CC) $(CFLAGS) -DUSE_SYSLIB_FUNCS $(default_thirdparty_CFLAGS) -o $@ $^
+
+# Since maskpass is a standalone utility, link it with gtmcrypt_utils_syslib.o instead of libgtmcryptutil.so. This allows maskpass
+# to be run without the need for the user setting LD_LIBRARY_PATH/LIBPATH to load libgtmcryptutil.so.
+maskpass: maskpass.o gtmcrypt_util_syslib.o
+	$(LD) $(LDFLAGS) maskpass $^ $(default_thirdparty_LDFLAGS)
+
+# Rules for building libgtmtls.so
+gtm_tls_impl.o: gtm_tls_impl.c
+	$(CC) $(CFLAGS) $<
+
+gtmtls: gtm_tls_impl.o libgtmcryptutil.so
+	$(LD) $< $(LDSHR) $(RPATHFLAGS) $(LDFLAGS) lib$@.so -lssl $(COMMON_LIBS)
+
+# Rules for building all supported variations of encryption libraries. These again point to the specific ones.
+gcrypt: gcrypt_AES256CFB
+
+openssl: openssl_AES256CFB openssl_BLOWFISHCFB
+
+# Rules for building specific encryption libraries.
+gcrypt_AES256CFB: $(crypt_srcfiles) libgtmcryptutil.so
+	$(CC) $(CFLAGS) -DUSE_GCRYPT -DUSE_AES256CFB $(gcrypt_nofips_flag) $(crypt_srcfiles)
+	$(LD) $(crypt_objfiles) $(LDSHR) $(RPATHFLAGS) $(LDFLAGS) libgtmcrypt_$@.so -lgcrypt -lgpgme -lgpg-error $(COMMON_LIBS)
+
+openssl_AES256CFB: $(crypt_srcfiles) libgtmcryptutil.so
+	$(CC) $(CFLAGS) -DUSE_OPENSSL -DUSE_AES256CFB $(crypt_srcfiles)
+	$(LD) $(crypt_objfiles) $(LDSHR) $(RPATHFLAGS) $(LDFLAGS) libgtmcrypt_$@.so -lcrypto -lgpgme -lgpg-error $(COMMON_LIBS)
+
+openssl_BLOWFISHCFB: $(crypt_srcfiles) libgtmcryptutil.so
+	$(CC) $(CFLAGS) -DUSE_OPENSSL -DUSE_BLOWFISHCFB $(crypt_srcfiles)
+	$(LD) $(crypt_objfiles) $(LDSHR) $(RPATHFLAGS) $(LDFLAGS) libgtmcrypt_$@.so -lcrypto -lgpgme -lgpg-error $(COMMON_LIBS)
+
+# The below rule is useful when the user wants to [re]build a specific target (one of gcrypt_AES256CFB, openssl_AES256CFB or
+# openssl_BLOWFISHCFB).
+gtmcrypt: $(thirdparty)_$(algo)
+
+
+# install, uninstall and cleanup rules.
+install:
+	rm -f $(all_objfiles)
+	mv *.so $(PLUGINDIR)
+	ln -s ./$(install_targ) $(PLUGINDIR)/libgtmcrypt.so
+
+uninstall:
+	rm -f $(PLUGINDIR)/*.so
+	rm -f $(PLUGINDIR)/gtmcrypt/maskpass
+
+clean:
+	rm -f $(all_objfiles)
+	rm -f *.so
+	rm -f maskpass
diff --git a/sr_unix/bdelete.txt b/sr_unix/bdelete.txt
index 20fd7ac..d14d772 100644
--- a/sr_unix/bdelete.txt
+++ b/sr_unix/bdelete.txt
@@ -43,22 +43,16 @@ obj
 pro/gtmsecshrdir:
 
 pro/plugin/gtmcrypt:
-build.sh
+Makefile
 gpgagent.tab
+gtm_tls_impl.h
+gtm_tls_interface.h
 gtmcrypt_dbk_ref.h
 gtmcrypt_interface.h
 gtmcrypt_pk_ref.h
 gtmcrypt_ref.h
 gtmcrypt_sym_ref.h
-install.sh
-ld_verbose.out
-libgtmcrypt.dll
-libgtmcrypt.dll.map
-libgtmcrypt.so
-libgtmcrypt.so.map
-libgtmcrypt.x
-maskpass.map
-maskpass.x
+gtmcrypt_util.h
 
 pro/utf8:
 CHK2LEV.o
diff --git a/sr_unix/bin_load.c b/sr_unix/bin_load.c
index 9e8af6b..5bb2c2b 100644
--- a/sr_unix/bin_load.c
+++ b/sr_unix/bin_load.c
@@ -47,6 +47,8 @@
 #include "gvcst_protos.h"	/* for gvcst_root_search in GV_BIND_NAME_AND_ROOT_SEARCH macro */
 #include "format_targ_key.h"
 #include "zshow.h"
+#include "hashtab_mname.h"
+#include "min_max.h"
 
 GBLREF bool		mupip_DB_full;
 GBLREF bool		mu_ctrly_occurred;
@@ -58,7 +60,6 @@ GBLREF gv_key		*gv_altkey;
 GBLREF gv_key		*gv_currkey;
 GBLREF gv_namehead	*gv_target;
 GBLREF int4		gv_keysize;
-GBLREF gd_region	*gv_cur_region;
 GBLREF sgmnt_addrs	*cs_addrs;
 #ifdef GTM_CRYPT
 GBLREF io_pair		io_curr_device;
@@ -108,16 +109,22 @@ error_def(ERR_LDSPANGLOINCMP);
 
 #define	DEFAULT_SN_HOLD_BUFF_SIZE MAX_IO_BLOCK_SIZE
 
-#define KILL_INCMP_SN_IF_NEEDED													\
-{																\
-	if (!sn_incmp_gbl_already_killed)											\
-	{															\
-		COPY_KEY(sn_savekey,  gv_currkey);										\
-		COPY_KEY(gv_currkey, sn_gvkey);											\
-		bin_call_db(BIN_KILL, 0, 0);											\
-		COPY_KEY(gv_currkey, sn_savekey);										\
-		sn_incmp_gbl_already_killed = TRUE;										\
-	}															\
+#define KILL_INCMP_SN_IF_NEEDED(GVNH_REG)									\
+{														\
+	gd_region	*dummy_reg;										\
+														\
+	if (!sn_incmp_gbl_already_killed)									\
+	{													\
+		COPY_KEY(sn_savekey, gv_currkey);								\
+		COPY_KEY(gv_currkey, sn_gvkey);									\
+		/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH				\
+		 * (e.g. setting gv_cur_region for spanning globals).						\
+		 */												\
+		GV_BIND_SUBSNAME_IF_GVSPAN(GVNH_REG, gd_header, gv_currkey, dummy_reg);		\
+		bin_call_db(BIN_KILL, 0, 0);									\
+		COPY_KEY(gv_currkey, sn_savekey);								\
+		sn_incmp_gbl_already_killed = TRUE;								\
+	}													\
 }
 
 #define DISPLAY_INCMP_SN_MSG													\
@@ -175,7 +182,7 @@ error_def(ERR_LDSPANGLOINCMP);
  * that its size is 4 bytes and no valid data record can have length 4.
  */
 
-void		bin_call_db(int, INTPTR_T, INTPTR_T);
+gvnh_reg_t	*bin_call_db(int, INTPTR_T, INTPTR_T);
 void 		zwr_out_print(char * buff, int len);
 
 #define ZWR_BASE_STRIDE 1024
@@ -227,6 +234,7 @@ void bin_load(uint4 begin, uint4 end)
 	boolean_t		is_hidden_subscript, ok_to_put = TRUE, putting_a_sn = FALSE, sn_incmp_gbl_already_killed = FALSE;
 	rec_hdr			*rp, *next_rp;
 	mval			v, tmp_mval;
+	mname_entry		gvname;
 	mstr			mstr_src, mstr_dest;
 	collseq			*extr_collseq, *db_collseq, *save_gv_target_collseq;
 	coll_hdr		extr_collhdr, db_collhdr;
@@ -235,12 +243,13 @@ void bin_load(uint4 begin, uint4 end)
 	gv_key			*sn_savekey = NULL; /* null-initialize at start, will be malloced later */
 	char			std_null_coll[BIN_HEADER_NUMSZ + 1], *sn_hold_buff = NULL, *sn_hold_buff_temp = NULL;
 #	ifdef GTM_CRYPT
-	gtmcrypt_key_t		*encr_key_handles;
-	char			*inbuf;
+	int			in_len, gtmcrypt_errno, n_index, encrypted_hash_array_len;
+	char			*inbuf, *encrypted_hash_array_ptr, *curr_hash_ptr;
 	int4			index;
-	int			in_len, gtmcrypt_errno;
-	muext_hash_hdr_ptr_t	hash_array = NULL;
+	gtmcrypt_key_t		*encr_key_handles;
 #	endif
+	gvnh_reg_t		*gvnh_reg;
+	gd_region		*dummy_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -311,20 +320,19 @@ void bin_load(uint4 begin, uint4 end)
 #	ifdef GTM_CRYPT
 	if ('7' <= hdr_lvl)
 	{
-		int	i, num_indexes;
-		len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base);
-		hash_array = (muext_hash_hdr *)malloc(len);
-		/* store hashes of all the files used during extract into muext_hash_hdr structure */
-		memcpy((char *)hash_array, ptr, len);
-		num_indexes = len / GTMCRYPT_HASH_LEN;
-		encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes);
+		encrypted_hash_array_len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base);
+		encrypted_hash_array_ptr = malloc(encrypted_hash_array_len);
+		memcpy(encrypted_hash_array_ptr, ptr, encrypted_hash_array_len);
+		n_index = encrypted_hash_array_len / GTMCRYPT_HASH_LEN;
+		encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * n_index);
 		INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno);
 		GC_BIN_LOAD_ERR(gtmcrypt_errno);
-		for (index = 0; index < num_indexes; index++)
+		for (index = 0; index < n_index; index++)
 		{
-			if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN))
+			curr_hash_ptr = encrypted_hash_array_ptr + index * GTMCRYPT_HASH_LEN;
+			if (0 == memcmp(curr_hash_ptr, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN))
 				continue;
-			GTMCRYPT_GETKEY(NULL, hash_array[index].gtmcrypt_hash, encr_key_handles[index], gtmcrypt_errno);
+			GTMCRYPT_GETKEY(NULL, curr_hash_ptr, encr_key_handles[index], gtmcrypt_errno);
 			GC_BIN_LOAD_ERR(gtmcrypt_errno);
 		}
 	}
@@ -373,7 +381,8 @@ void bin_load(uint4 begin, uint4 end)
 	GVKEY_INIT(sn_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* sn_gvkey will point to malloced memory after this */
 	assert(NULL == sn_savekey);	/* GVKEY_INIT macro relies on this */
 	GVKEY_INIT(sn_savekey, DBKEYSIZE(MAX_KEY_SZ));	/* sn_gvkey will point to malloced memory after this */
-	for (; !mupip_DB_full ;)
+	gvnh_reg = NULL;
+	for ( ; !mupip_DB_full; )
 	{
 		if (++rec_count > end)
 			break;
@@ -417,22 +426,29 @@ void bin_load(uint4 begin, uint4 end)
 #		endif
 		btop = ptr + len;
 		cp1 = (unsigned char*)(rp + 1);
-		v.str.addr = (char*)cp1;
+		gvname.var_name.addr = (char*)cp1;
 		while (*cp1++)
 			;
-		v.str.len =INTCAST((char*)cp1 - v.str.addr - 1);
+		gvname.var_name.len =INTCAST((char*)cp1 - gvname.var_name.addr - 1);
 		if (('2' >= hdr_lvl) || new_gvn)
 		{
-			if ((HASHT_GBLNAME_LEN == v.str.len) &&	(0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN)))
+			if ((HASHT_GBLNAME_LEN == gvname.var_name.len)
+					&& (0 == memcmp(gvname.var_name.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN)))
 				continue;
-			bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str);
-			max_key = gv_cur_region->max_key_size;
+			gvname.var_name.len = MIN(gvname.var_name.len, MAX_MIDENT_LEN);
+			COMPUTE_HASH_MNAME(&gvname);
+			gvnh_reg = bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&gvname);
+			/* "gv_cur_region" will be set at this point in case the global does NOT span regions.
+			 * For globals that do span regions, "gv_cur_region" will be set just before the call to op_gvput.
+			 * This value of "gvnh_reg" will be in effect until all records of this global are processed.
+			 */
+			max_key = gvnh_reg->gd_reg->max_key_size;
 			db_collhdr.act = gv_target->act;
 			db_collhdr.ver = gv_target->ver;
 			db_collhdr.nct = gv_target->nct;
 		}
 		GET_USHORT(rec_len, &rp->rsiz);
-		if (EVAL_CMPC(rp) != 0 || v.str.len > rec_len || mupip_error_occurred)
+		if ((0 != EVAL_CMPC(rp)) || (gvname.var_name.len > rec_len) || mupip_error_occurred)
 		{
 			bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
 			mu_gvis();
@@ -442,9 +458,8 @@ void bin_load(uint4 begin, uint4 end)
 		if (new_gvn)
 		{
 			global_key_count = 1;
-			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver
-				|| db_collhdr.nct != extr_collhdr.nct
-				|| gv_cur_region->std_null_coll != extr_std_null_coll))
+			if ((db_collhdr.act != extr_collhdr.act) || (db_collhdr.ver != extr_collhdr.ver)
+				|| (db_collhdr.nct != extr_collhdr.nct) || (gvnh_reg->gd_reg->std_null_coll != extr_std_null_coll))
 			{
 				if (extr_collhdr.act)
 				{
@@ -487,7 +502,7 @@ void bin_load(uint4 begin, uint4 end)
 				need_xlation = FALSE;
 		}
 		new_gvn = FALSE;
-		for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
+		for ( ; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
 		{
 			GET_USHORT(rec_len, &rp->rsiz);
 			if (rec_len + (unsigned char *)rp > btop)
@@ -500,7 +515,7 @@ void bin_load(uint4 begin, uint4 end)
 			cp1 =  (unsigned char*)(rp + 1);
 			cp2 = gv_currkey->base + EVAL_CMPC(rp);
 			current = 1;
-			for (;;)
+			for ( ; ; )
 			{
 				last = current;
 				current = *cp2++ = *cp1++;
@@ -524,8 +539,8 @@ void bin_load(uint4 begin, uint4 end)
 			if (need_xlation)
 			{
 				assert(hdr_lvl >= '3');
-				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
-				 	extr_std_null_coll != gv_cur_region->std_null_coll);
+				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct
+						|| (extr_std_null_coll != gvnh_reg->gd_reg->std_null_coll));
 							/* gv_currkey would have been modified/translated in the earlier put */
 				memcpy(gv_currkey->base, cmpc_str, next_cmpc);
 				next_rp = (rec_hdr *)((unsigned char*)rp + rec_len);
@@ -573,7 +588,7 @@ void bin_load(uint4 begin, uint4 end)
 					tmp_gvkey->end = 0;
 					if (extr_collseq)
 						gv_target->collseq = save_gv_target_collseq;
-					mval2subsc(&tmp_mval, tmp_gvkey);
+					mval2subsc(&tmp_mval, tmp_gvkey, gvnh_reg->gd_reg->std_null_coll);
 						/* we now have the correctly transformed subscript */
 					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
 					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
@@ -581,16 +596,6 @@ void bin_load(uint4 begin, uint4 end)
 					gv_currkey->end += tmp_gvkey->end;
 					gvkey_char_ptr++;
 				}
-				if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev)
-				{
-					if (extr_std_null_coll == 0)
-					{
-						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
-					} else
-					{
-						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
-					}
-				}
 			}
 			if (gv_currkey->end >= max_key)
 			{
@@ -635,7 +640,7 @@ void bin_load(uint4 begin, uint4 end)
 						expected_sn_chunk_number + 1);
 				if (sn_hold_buff_pos)
 					DISPLAY_PARTIAL_SN_HOLD_BUFF;
-				KILL_INCMP_SN_IF_NEEDED;
+				KILL_INCMP_SN_IF_NEEDED(gvnh_reg);
 				sn_hold_buff_pos = 0;
 				expected_sn_chunk_number = 0;
 				ok_to_put = TRUE;
@@ -663,7 +668,7 @@ void bin_load(uint4 begin, uint4 end)
 								expected_sn_chunk_number + 1, sn_chunk_number + 1);
 						if (sn_hold_buff_pos)
 							DISPLAY_PARTIAL_SN_HOLD_BUFF;
-						KILL_INCMP_SN_IF_NEEDED;
+						KILL_INCMP_SN_IF_NEEDED(gvnh_reg);
 					}
 					/* start building a new spanning node */
 					sn_gvkey->end = gv_currkey->end - (SPAN_SUBS_LEN + 1);
@@ -703,27 +708,26 @@ void bin_load(uint4 begin, uint4 end)
 						{
 							if (sn_hold_buff_pos != gblsize)
 							{	/* we don't have the expected size even though 	*/
-								/* we have all the expected chunks.		 		*/
+								/* we have all the expected chunks. 		*/
 								DISPLAY_INCMP_SN_MSG;
 								util_out_print("!_!_Expected size : !UL actual size : !UL", TRUE,
 										gblsize, sn_hold_buff_pos);
 								if (sn_hold_buff_pos)
 									DISPLAY_PARTIAL_SN_HOLD_BUFF;
-								KILL_INCMP_SN_IF_NEEDED;
+								KILL_INCMP_SN_IF_NEEDED(gvnh_reg);
 								expected_sn_chunk_number = 0;
 								ok_to_put = FALSE;
 								sn_hold_buff_pos = 0;
-							}
-							else
+							} else
 							{
 								expected_sn_chunk_number = 0;
 								ok_to_put = TRUE;
 								putting_a_sn = TRUE;
 							}
 
-						}else
+						} else
 							expected_sn_chunk_number++;
-					}else
+					} else
 					{
 						DISPLAY_INCMP_SN_MSG;
 						if ((sn_hold_buff_pos + v.str.len) <= gblsize)
@@ -736,7 +740,7 @@ void bin_load(uint4 begin, uint4 end)
 							DISPLAY_PARTIAL_SN_HOLD_BUFF;
 						if (v.str.len)
 							DISPLAY_VALUE("!_!_Errant Chunk :");
-						KILL_INCMP_SN_IF_NEEDED;
+						KILL_INCMP_SN_IF_NEEDED(gvnh_reg);
 						sn_hold_buff_pos = 0;
 						expected_sn_chunk_number = 0;
 					}
@@ -745,42 +749,49 @@ void bin_load(uint4 begin, uint4 end)
 				ok_to_put = TRUE;
 			if (ok_to_put)
 			{
-					if (putting_a_sn)
-					{
-						gv_currkey->base[gv_currkey->end - (SPAN_SUBS_LEN + 1)] = 0;
-						gv_currkey->end -= (SPAN_SUBS_LEN + 1);
-						v.str.addr = sn_hold_buff;
-						v.str.len = sn_hold_buff_pos;
-					}
-					if (max_data_len < v.str.len)
-						max_data_len = v.str.len;
-					bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
-					if (mupip_error_occurred)
-					{
-						if (!mupip_DB_full)
-						{
-							bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
-							file_offset = file_offset_base + ((unsigned char *)rp - ptr_base);
-							util_out_print("!_!_at File offset : [0x!XL]", TRUE, file_offset);
-							DISPLAY_CURRKEY;
-							DISPLAY_VALUE("!_!_Value :");
-						}
-						break;
-					}
-					if (putting_a_sn)
-						putting_a_sn = FALSE;
-					else
+				if (putting_a_sn)
+				{
+					gv_currkey->base[gv_currkey->end - (SPAN_SUBS_LEN + 1)] = 0;
+					gv_currkey->end -= (SPAN_SUBS_LEN + 1);
+					v.str.addr = sn_hold_buff;
+					v.str.len = sn_hold_buff_pos;
+				}
+				if (max_data_len < v.str.len)
+					max_data_len = v.str.len;
+				/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+				 * (e.g. setting gv_cur_region for spanning globals).
+				 */
+				GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey, dummy_reg);
+				bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
+				if (mupip_error_occurred)
+				{
+					if (!mupip_DB_full)
 					{
-						key_count++;
-						global_key_count++;
+						bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
+						file_offset = file_offset_base + ((unsigned char *)rp - ptr_base);
+						util_out_print("!_!_at File offset : [0x!XL]", TRUE, file_offset);
+						DISPLAY_CURRKEY;
+						DISPLAY_VALUE("!_!_Value :");
 					}
+					break;
+				}
+				if (putting_a_sn)
+					putting_a_sn = FALSE;
+				else
+				{
+					key_count++;
+					global_key_count++;
+				}
 			}
 		}
 	}
-	GTMCRYPT_ONLY(
-		if (NULL != hash_array)
-			free(hash_array);
-	)
+#	ifdef GTM_CRYPT
+	if ('7' <= hdr_lvl)
+	{
+		assert(NULL != encrypted_hash_array_ptr);
+		free(encrypted_hash_array_ptr);
+	}
+#	endif
 	free(tmp_gvkey);
 	free(sn_gvkey);
 	if (NULL != sn_hold_buff)
@@ -796,20 +807,22 @@ void bin_load(uint4 begin, uint4 end)
 	}
 }
 
-void bin_call_db(int routine, INTPTR_T parm1, INTPTR_T parm2)
+gvnh_reg_t *bin_call_db(int routine, INTPTR_T parm1, INTPTR_T parm2)
 {	/* In order to duplicate the VMS functionality, which is to trap all errors in mupip_load_ch and
 	 * continue in bin_load after they occur, it is necessary to call these routines from a
 	 * subroutine due to the limitations of condition handlers and unwinding on UNIX
 	 */
+	gvnh_reg_t	*gvnh_reg;
 
-	ESTABLISH(mupip_load_ch);
+	gvnh_reg = NULL;
+	ESTABLISH_RET(mupip_load_ch, gvnh_reg);
 	switch(routine)
 	{
 		case BIN_PUT:
 			op_gvput((mval *)parm1);
 			break;
 		case BIN_BIND:
-			GV_BIND_NAME_AND_ROOT_SEARCH((gd_addr *)parm1, (mstr *)parm2);
+			GV_BIND_NAME_AND_ROOT_SEARCH((gd_addr *)parm1, (mname_entry *)parm2, gvnh_reg);
 			break;
 		case ERR_COR:
 			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_CORRUPT, 2, parm1, parm2);
@@ -818,4 +831,5 @@ void bin_call_db(int routine, INTPTR_T parm1, INTPTR_T parm2)
 			break;
 	}
 	REVERT;
+	return gvnh_reg;
 }
diff --git a/sr_unix/build.sh b/sr_unix/build.sh
deleted file mode 100644
index e4ed958..0000000
--- a/sr_unix/build.sh
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/bin/sh
-#################################################################
-#								#
-#	Copyright 2009, 2013 Fidelity Information Services, Inc #
-#								#
-#	This source code contains the intellectual property	#
-#	of its copyright holder(s), and is made available	#
-#	under a license.  If you do not know the terms of	#
-#	the license, please stop and do not read further.	#
-#								#
-#################################################################
-
-if [ $# -lt 2 ]; then
-	echo "Usage: $0 ENCRYPTION_LIB BUILD_TYPE [ALGORITHM]"
-	echo "ENCRYPTION_LIB is either gcrypt or openssl"
-	echo "	gcrypt : Build the plugin with libgcrypt"
-	echo "	openssl: Build the plugin with OpenSSL"
-	echo "BUILD_TYPE is either [p|P] or [d|D]"
-	echo "	d|D : Build the plugin with debug information"
-	echo "	p|P : Build the plugin without debug information"
-	echo "ALGORITHM is either AES256CFB (default) or BLOWFISHCFB"
-	echo "  AES256CFB   : Build the plugin with AES (CFB mode) with 256-bit encryption"
-	echo "  BLOWFISHCFB : Build the plugin with BLOWFISH (CFB mode) with 256-bit encryption"
-	exit 1
-fi
-
-if [ -z "$gtm_dist" ]; then
-	echo "Environment variable gtm_dist undefined. Exiting"
-	exit 1
-fi
-
-encryption_lib=$1
-build_type=$2
-if [ $# -eq 3 ]; then
-	algorithm="$3"
-else
-	algorithm="AES256CFB"	# default
-fi
-algorithm_option="-DUSE_$algorithm"
-# Clean up existing artifacts
-\rm -f *.o 2>/dev/null
-
-hostos=`uname -s`
-machtype=`uname -m`
-
-# There are two cases where we might be running 32 bit GT.M
-# (a) On Linux i686
-# (b) On Linux x86_64, but running 32 bit GT.M
-# All the non-Linux platforms that supports encryption runs 64 bit GT.M
-if [ "Linux" = "$hostos" ] ; then
-	is64bit_gtm=`file $gtm_dist/mumps | grep "64" | wc -l`
-else
-	is64bit_gtm=1
-fi
-
-builddir=`pwd`
-bld_status=0
-ext=".so"
-
-# Set debug/optimization options if needed.
-if [ "d" = $build_type -o "D" = $build_type ]; then
-	dbg_enable="1"
-	options_optimize="-DDEBUG -g"
-else
-	options_optimize="-O"
-fi
-
-cc="cc"
-ld="$cc"
-
-# Set library and include search path for compiler and linker to find the dependencies based on whether the
-# platform is running 32 bit GT.M.
-if [ $is64bit_gtm -eq 1 ] ; then
-	options_libpath="-L /usr/local/lib64 -L /usr/local/lib -L /usr/lib64 -L /usr/lib -L /lib64 -L /lib"
-else
-	options_libpath="-L /usr/local/lib32 -L /usr/local/lib -L /usr/lib32 -L /usr/lib -L /lib32 -L /lib"
-fi
-# -I $gtm_dist needed for main_pragma.h, gtmxc_types.h and gtm_common_defs.h
-options_incpath="-I /usr/local/include/ -I /usr/include -I $builddir -I $gtm_dist"
-
-base_libname="libgtmcrypt"
-# Common CC options for various platforms
-if [ "AIX" = "$hostos" ] ; then
-	cc_common="-c -qchars=signed -qsrcmsg -qmaxmem=8192 -D_BSD=43 -D_LARGE_FILES -D_TPARM_COMPAT -D_AIO_AIX_SOURCE"
-	cc_common="$cc_common -qro -qroconst -D_USE_IRS -q64"
-	ld_common="-q64 -brtl"
-	aix_loadmap_option="-bcalls:$builddir/$base_libname.so.map -bmap:$builddir/$base_libname.so.map"
-	aix_loadmap_option="$aix_loadmap_option -bxref:$builddir/$base_libname.so.map"
-	ld_shl_options="-q64 -Wl,-G -bexpall -bnoentry -bh:4 $aix_loadmap_option"
-	# Reference implementation on AIX requires OpenSSL. Adjust library and include paths accordingly.
-	options_libpath="-L /usr/local/ssl/lib $options_libpath"
-	options_incpath="-I /usr/local/ssl/include $options_incpath"
-elif [ "HP-UX" = "$hostos" -a "ia64" = "$machtype" ] ; then
-	cc_common="+Z -DGTM_PIC -c -D__STDC_EXT__ -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE_EXTENDED  -Ae  +DD64"
-	cc_common="$cc_common -D_LARGEFILE64_SOURCE +W2550"
-	ld_common="-Wl,-m +DD64"
-	ld_shl_options="+DD64 -Wl,-b,-B,symbolic"
-	options_libpath="-L /opt/openssl/lib/hpux64 $options_libpath"
-	options_incpath="-L /opt/openssl/include $options_incpath"
-	# Additional DEBUG-ONLY options on HP-UX
-	if  [ ! -z "$dbg_enable" ] ; then options_optimize="$options_optimize +ESdbgasm" ; fi
-elif [ "SunOS" = "$hostos" ] ; then
-	cc_common="-KPIC -c -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DSUNOS -DSHADOWPW -m64"
-	ld_common="-Wl,-m,-64 -m64 -xarch=generic"
-	ld_shl_options="-m64 -xarch=generic -G -z combreloc"
-	options_libpath="-L /usr/lib/sparcv9 -L /usr/local/ssl/lib $options_libpath"
-	options_incpath="-I /usr/local/ssl/include $options_incpath"
-elif [ "Linux" = "$hostos" ] ; then
-	cc_common="-c -ansi  -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64  -D_XOPEN_SOURCE=600 -fsigned-char -fPIC"
-	ld_common="-Wl,-M"
-	if [ "ia64" != "$machtype" ] ; then
-		cc_common="$cc_common -Wmissing-prototypes -D_LARGEFILE64_SOURCE"
-		# PRO options on Linux x86_64 and i686
-		if  [ -z "$dbg_enable" ] ; then
-			options_optimize="-O2 -fno-defer-pop -fno-strict-aliasing -ffloat-store"
-			if [ "i686" = "$machtype" ] ; then options_optimize="$options_optimize -march=i686" ; fi
-		fi
-	fi
-	if [ "x86_64" = "$machtype" -a "32" = "$OBJECT_MODE" ] ; then
-		cc_common="$cc_common -m32"
-		ld_common="$ld_common -m32"
-	fi
-	ld_shl_options="-shared"
-elif [ "OS/390" = "$hostos" ] ; then
-	cc="xlc"
-	ld="xlc"
-	cc_common="-c -q64 -qWARN64 -qchars=signed -qenum=int -qascii -D_ENHANCED_ASCII_EXT=0xFFFFFFFF -D_VARARG_EXT_"
-	cc_common="$cc_common -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE_NO_THREADS -D_ISOC99_SOURCE -D_UNIX03_SOURCE"
-	cc_common="$cc_common -D_IEEEV1_COMPATIBILITY -D_POSIX_C_SOURCE=200112L"
-	cc_common="$cc_common -W c,DLL,XPLINK,EXPORTALL,RENT,NOANSIALIAS,LANGLVL(EXTENDED),ARCH(7)"
-	cc_common="$cc_common -W l,DLL,XPLINK"
-	ld_common="-q64 -W l,DLL,XPLINK,MAP,XREF,REUS=RENT"
-	ld_shl_options="-q64 -W l,DLL,XPLINK"
-	ext=".dll"
-fi
-generic_libname=$base_libname$ext
-specific_libname=${base_libname}_${encryption_lib}_${algorithm}${ext}
-if [ -f $builddir/$specific_libname ]; then \rm -f $specific_libname ; fi
-# Needed shared libraries for building encryption plugin
-crypto_libs="-lgpgme -lgpg-error"
-if [ "openssl" = "$encryption_lib" ] ; then
-	crypto_libs="$crypto_libs -lcrypto"
-	cc_options="$cc_common $options_optimize $options_incpath -DUSE_OPENSSL $algorithm_option"
-elif [ "gcrypt" = "$encryption_lib" ] ; then
-	crypto_libs="$crypto_libs -lgcrypt"
-	cc_options="$cc_common $options_optimize $options_incpath -DUSE_GCRYPT $algorithm_option"
-else
-	echo "Unsupported encryption library : $encryption_lib"
-	exit 1
-fi
-
-$cc $cc_options $builddir/gtmcrypt_ref.c
-bld_status=`expr $bld_status + $?`
-$cc $cc_options $builddir/gtmcrypt_pk_ref.c
-bld_status=`expr $bld_status + $?`
-$cc $cc_options $builddir/gtmcrypt_dbk_ref.c
-bld_status=`expr $bld_status + $?`
-
-$ld $ld_common $ld_shl_options -o $builddir/$specific_libname $builddir/gtmcrypt_ref.o $builddir/gtmcrypt_pk_ref.o \
-	$builddir/gtmcrypt_dbk_ref.o $options_libpath $crypto_libs > $builddir/$generic_libname.map
-bld_status=`expr $bld_status + $?`
-
-# Compile maskpass.c
-$cc $cc_options $builddir/maskpass.c
-$ld $ld_common -o $builddir/maskpass $builddir/maskpass.o $options_libpath $crypto_libs > $builddir/maskpass.map
-bld_status=`expr $bld_status + $?`
-
-# Remove *.o files left over from the compilations above
-\rm -f *.o
-if [ 0 = $bld_status ] ; then
-	echo "Encryption plugin built successfully."
-else
-	echo "Encryption plugin build failed. Please use verbose option for more details."
-fi
-
-exit $bld_status
diff --git a/sr_unix/buildaux.csh b/sr_unix/buildaux.csh
index 511f172..aa09c17 100644
--- a/sr_unix/buildaux.csh
+++ b/sr_unix/buildaux.csh
@@ -153,7 +153,7 @@ if ( $buildaux_gde == 1 ) then
 		chmod 664 *.m *.o
 
 		\rm -f *.m *.o	# use \rm to avoid rm from asking for confirmation (in case it has been aliased so)
-		cp $gtm_pct/*.m .
+		cp -p $gtm_pct/*.m .
 		switch ($gt_image)  # potentially all 3 versions could be in $gtm_pct .. we only need one, delete the others
 		    case "pro":
 			rm -f GTMDefinedTypesInitBta.m >& /dev/null
@@ -189,7 +189,7 @@ if ( $buildaux_gde == 1 ) then
 		if (0 != $status) @ buildaux_status = $status
 		if ($buildaux_status != 0) then
 			echo "buildaux-E-compile_M, Failed to compile .m programs in M mode" \
-				>> $gtm_log/error.`basename $gtm_exe`.log
+				>> $gtm_log/error.${gtm_exe:t}.log
 		endif
 
 		source $gtm_tools/set_library_path.csh
@@ -213,7 +213,7 @@ if ( $buildaux_gde == 1 ) then
 			if (0 != $status) @ buildaux_status = $status
 			if ($buildaux_status != 0) then
 				echo "buildaux-E-compile_UTF8, Failed to compile .m programs in UTF-8 mode" \
-					>> $gtm_log/error.`basename $gtm_exe`.log
+					>> $gtm_log/error.${gtm_exe:t}.log
 			endif
 			cd ..
 			setenv LC_CTYPE C
@@ -241,7 +241,7 @@ if ( $buildaux_dse == 1 ) then
 	if ( $status != 0  ||  ! -x $3/dse ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkdse, Failed to link dse (see ${dollar_sign}gtm_map/dse.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/dse
@@ -263,7 +263,7 @@ if ( $buildaux_geteuid == 1 ) then
 	if ( $status != 0  ||  ! -x $3/geteuid ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgeteuid, Failed to link geteuid (see ${dollar_sign}gtm_map/geteuid.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable $3/geteuid
@@ -286,7 +286,7 @@ if ( $buildaux_gtmsecshr == 1 ) then
 		if ( $status != 0  ||  ! -x $3/${file} ) then
 			set buildaux_status = `expr $buildaux_status + 1`
 			echo "buildaux-E-link${file}, Failed to link ${file} (see ${dollar_sign}gtm_map/${file}.map)" \
-				>> $gtm_log/error.`basename $gtm_exe`.log
+				>> $gtm_log/error.${gtm_exe:t}.log
 		else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 			if ( "dbg" == $gt_image ) then
 				chatr +dbg enable +as mpas $3/${file}
@@ -318,7 +318,7 @@ if ( $buildaux_lke == 1 ) then
 	if ( $status != 0  ||  ! -x $3/lke ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linklke, Failed to link lke (see ${dollar_sign}gtm_map/lke.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/lke
@@ -339,7 +339,7 @@ if ( $buildaux_mupip == 1 ) then
 	if ( $status != 0  ||  ! -x $3/mupip ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkmupip, Failed to link mupip (see ${dollar_sign}gtm_map/mupip.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/mupip
@@ -362,7 +362,7 @@ if ( $buildaux_gtcm_server == 1 ) then
 	if ( $status != 0  ||  ! -x $3/gtcm_server) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgtcm_server, Failed to link gtcm_server (see ${dollar_sign}gtm_map/gtcm_server.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/gtcm_server
@@ -386,7 +386,7 @@ if ( $buildaux_gtcm_gnp_server == 1 ) then
 	if ( $status != 0  ||  ! -x $3/gtcm_gnp_server) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgtcm_gnp_server, Failed to link gtcm_gnp_server" \
-			"(see ${dollar_sign}gtm_map/gtcm_gnp_server.map)" >> $gtm_log/error.`basename $gtm_exe`.log
+			"(see ${dollar_sign}gtm_map/gtcm_gnp_server.map)" >> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/gtcm_gnp_server
@@ -410,7 +410,7 @@ if ( $buildaux_gtcm_play == 1 ) then
 	if ( $status != 0  ||  ! -x $3/gtcm_play) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgtcm_play, Failed to link gtcm_play (see ${dollar_sign}gtm_map/gtcm_play.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/gtcm_play
@@ -433,7 +433,7 @@ if ( $buildaux_gtcm_pkdisp == 1 ) then
 	if ( $status != 0  ||  ! -x $3/gtcm_pkdisp) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgtcm_pkdisp, Failed to link gtcm_pkdisp (see ${dollar_sign}gtm_map/gtcm_pkdisp.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable $3/gtcm_pkdisp
@@ -454,7 +454,7 @@ if ( $buildaux_gtcm_shmclean == 1 ) then
 	if ( $status != 0  ||  ! -x $3/gtcm_shmclean) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkgtcm_shmclean, Failed to link gtcm_shmclean (see ${dollar_sign}gtm_map/gtcm_shmclean.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable $3/gtcm_shmclean
@@ -474,7 +474,7 @@ if ( $buildaux_semstat2 == 1 ) then
 	if ( $status != 0  ||  ! -x $3/semstat2 ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linksemstat2, Failed to link semstat2 (see ${dollar_sign}gtm_map/semstat2.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable $3/semstat2
@@ -492,7 +492,7 @@ if ( $buildaux_ftok == 1 ) then
 	if ( $status != 0  ||  ! -x $3/ftok ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkftok, Failed to link ftok (see ${dollar_sign}gtm_map/ftok.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable $3/ftok
@@ -513,7 +513,7 @@ if ( $buildaux_dbcertify == 1 ) then
 	if ( $status != 0  ||  ! -x $3/dbcertify ) then
 		set buildaux_status = `expr $buildaux_status + 1`
 		echo "buildaux-E-linkdbcertify, Failed to link dbcertify (see ${dollar_sign}gtm_map/dbcertify.map)" \
-			>> $gtm_log/error.`basename $gtm_exe`.log
+			>> $gtm_log/error.${gtm_exe:t}.log
 	else if ( "ia64" == $mach_type && "hpux" == $platform_name ) then
 		if ( "dbg" == $gt_image ) then
 			chatr +dbg enable +as mpas $3/dbcertify
@@ -530,51 +530,84 @@ if ($buildaux_gtmcrypt == 1) then
 		set plugin_build_type=""
 		switch ($2)
 			case "[bB]*":
-				set plugin_build_type="p"
+				set plugin_build_type="PRO"
 				breaksw
 			case "[pP]*":
-				set plugin_build_type="p"
+				set plugin_build_type="PRO"
 				breaksw
 			default:
-				set plugin_build_type="d"
+				set plugin_build_type="DEBUG"
 				breaksw
 		endsw
-		rm -rf $gtm_dist/plugin/gtmcrypt
-		rm -rf $gtm_dist/plugin/
-		mkdir -p $gtm_dist/plugin/gtmcrypt >&! /dev/null
-		setenv gtm_dist_plugin $gtm_dist/plugin/gtmcrypt
-		cp -pf $gtm_src/gtmcrypt_*ref.c $gtm_src/maskpass.c $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_inc/gtmcrypt_*ref.h $gtm_inc/gtmcrypt_interface.h $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_tools/build.sh $gtm_tools/install.sh $gtm_tools/add_db_key.sh $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_tools/encrypt_sign_db_key.sh $gtm_tools/gen_keypair.sh $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_tools/gen_sym_hash.sh $gtm_tools/gen_sym_key.sh $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_tools/import_and_sign_key.sh $gtm_tools/pinentry-gtm.sh $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_tools/show_install_config.sh $gtm_dist_plugin >&! /dev/null
-		cp -pf $gtm_pct/pinentry.m $gtm_dist_plugin >&! /dev/null
-		chmod +x $gtm_dist_plugin/*.sh
-		pushd $gtm_dist_plugin >&! /dev/null
-		# For, non-AIX platforms, move the libgcrypt entry to the end of $supported_list. This way, build.sh will always
-		# build maskpass with libgcrypt dependency rather than libcrypto dependency on non-AIX platforms.
-		if ($HOSTOS != "AIX") then
-			set supported_list_reorder = `echo $supported_list | sed 's/gcrypt//;s/$/ gcrypt/'`
-			set supported_list = `echo $supported_list_reorder`
+		# First copy all the necessary source and script files to $gtm_dist/plugin/gtmcrypt
+		set helpers = "add_db_key,encrypt_sign_db_key,gen_keypair,gen_sym_hash,gen_sym_key,import_and_sign_key"
+		set helpers = "$helpers,pinentry-gtm,show_install_config"
+
+		set srcfiles = "gtmcrypt_dbk_ref.c gtmcrypt_pk_ref.c gtmcrypt_sym_ref.c gtmcrypt_ref.c gtm_tls_impl.c maskpass.c"
+		set srcfiles = "$srcfiles gtmcrypt_util.c"
+
+		set incfiles = "gtmcrypt_interface.h gtmcrypt_dbk_ref.h gtmcrypt_sym_ref.h gtmcrypt_pk_ref.h gtmcrypt_ref.h"
+		set incfiles = "$incfiles gtmcrypt_util.h gtm_tls_impl.h gtm_tls_interface.h"
+
+		set gtm_dist_plugin = $gtm_dist/plugin
+		rm -rf $gtm_dist_plugin
+		mkdir -p $gtm_dist_plugin/gtmcrypt
+		set srcfile_list = ($srcfiles)
+		eval cp -pf '${srcfile_list:gs||'$gtm_src'/|} $gtm_dist_plugin/gtmcrypt'
+
+		set incfile_list = ($incfiles)
+		eval cp -pf '${incfile_list:gs||'$gtm_inc'/|} $gtm_dist_plugin/gtmcrypt'
+
+		cp -pf $gtm_tools/{$helpers}.sh $gtm_dist_plugin/gtmcrypt
+		cp -pf $gtm_pct/pinentry.m $gtm_dist_plugin/gtmcrypt
+		cp -pf $gtm_tools/Makefile.mk $gtm_dist_plugin/gtmcrypt/Makefile
+		chmod +x $gtm_dist_plugin/gtmcrypt/*.sh
+		#
+		pushd $gtm_dist_plugin/gtmcrypt
+		if ("HP-UX" == "$HOSTOS") then
+			set make = "gmake"
+		else
+			set make = "make"
+		endif
+		# libssl.so isn't available on pfloyd. Skip building SSL/TLS reference implementation library on pfloyd. This is
+		# okay since pfloyd is AIX 5.3 which isn't a supported AIX version anyways.
+		set host=$HOST:r:r:r
+		if ($host !~ pfloyd) then
+			$make gtmtls
+			if (0 != $status) then
+				set buildaux_status = `expr $buildaux_status + 1`
+				echo "buildaux-E-tls, failed to build libgtmtls.so." >> $gtm_log/error.${gtm_exe:t}.log
+			endif
+		endif
+		# On tuatara, atlhxit1 and atlhxit2 Libgcrypt version is too low to support FIPS mode. Add necessary flags to
+		# Makefile to tell the plugin to build without FIPS support.
+		if ($host =~ {tuatara,atlhxit1,atlhxit2}) then
+			set fips_flag = "gcrypt_nofips=1"
+		else
+			set fips_flag = ""
 		endif
 		# Build all possible encryption libraries based on what encryption libraries are supported in this platform.
 		foreach supported_lib ($supported_list)
 			foreach algorithm ("AES256CFB" "BLOWFISHCFB")
 				if ("gcrypt" == "$supported_lib" && "BLOWFISHCFB" == "$algorithm") continue
 				echo "####### Building encryption plugin using $supported_lib with $algorithm algorithm #########"
-				sh -x $gtm_dist_plugin/build.sh $supported_lib $plugin_build_type $algorithm
+				$make gtmcrypt image=$plugin_build_type thirdparty=$supported_lib algo=$algorithm $fips_flag
 				set bstat = $status
 				echo ""
 				if (0 != $bstat) then
 					set buildaux_status = `expr $buildaux_status + 1`
-					echo "buildaux-E-libgtmcrypt, failed to build gtmcrypt and/or helper scripts. See 'map'	\
-						files in ${dollar_sign}gtm_dist/plugin/gtmcrypt for more details" 		\
-									>> $gtm_log/error.`basename $gtm_exe`.log
+					echo "buildaux-E-libgtmcrypt, failed to build gtmcrypt and/or helper scripts."	\
+									>> $gtm_log/error.${gtm_exe:t}.log
 				endif
 			end
 		end
+		# Now that the individual libraries are built, go ahead and build the maskpass
+		$make maskpass
+		if (0 != $status) then
+			set buildaux_status = `expr $buildaux_status + 1`
+			echo "buildaux-E-maskpass, failed to build maskpass." >> $gtm_log/error.${gtm_exe:t}.log
+		endif
+		#
 		if ($gtm_verno =~ V[4-8]*) then
 			# For production builds don't do any randomizations.
 			set algorithm = "AES256CFB"
@@ -599,12 +632,17 @@ if ($buildaux_gtmcrypt == 1) then
 				set algorithm = $algorithms[$rand]
 			endif
 		endif
-		$gtm_dist_plugin/install.sh $encryption_lib $algorithm
+		$make install thirdparty=$encryption_lib algo=$algorithm
 		if (0 != $status) then
 			set buildaux_status = `expr $buildaux_status + 1`
 			echo "buildaux-E-libgtmcrypt, failed to install libgtmcrypt and/or helper scripts"		\
-						>> $gtm_log/error.`basename $gtm_exe`.log
+						>> $gtm_log/error.${gtm_exe:t}.log
 		endif
+		# Create the one time gpgagent.tab file.
+		echo "$gtm_dist_plugin/libgtmcryptutil.so" >&! $gtm_dist_plugin/gpgagent.tab
+		echo "unmaskpwd: gtm_status_t gc_mask_unmask_passwd(I:gtm_string_t*,O:gtm_string_t*[512])"	\
+							>>&! $gtm_dist_plugin/gpgagent.tab
+		#
 		popd >&! /dev/null
 	endif
 endif
diff --git a/sr_unix/ch_overrun.c b/sr_unix/ch_overrun.c
index fabb280..2ea0b37 100644
--- a/sr_unix/ch_overrun.c
+++ b/sr_unix/ch_overrun.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,12 +21,13 @@
 GBLREF int		mumps_status;
 GBLREF boolean_t	exit_handler_active;
 
+error_def(ERR_NOCHLEFT);
+
 void ch_overrun(void)
 {
-	error_def(ERR_NOCHLEFT);
-
-	gtm_putmsg(VARLSTCNT(1) ERR_NOCHLEFT);
-	send_msg(VARLSTCNT(1) ERR_NOCHLEFT);
+	PRN_ERROR;
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOCHLEFT);
+	send_msg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOCHLEFT);
 
 	/* If exit handler is already active, we will just core and die */
 	if (exit_handler_active)
diff --git a/sr_unix/check_encrypt_support.sh b/sr_unix/check_encrypt_support.sh
index 2edf663..20b833e 100644
--- a/sr_unix/check_encrypt_support.sh
+++ b/sr_unix/check_encrypt_support.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 #################################################################
 #								#
-#	Copyright 2009, 2012 Fidelity Information Services, Inc #
+#	Copyright 2009, 2013 Fidelity Information Services, Inc #
 #								#
 #	This source code contains the intellectual property	#
 #	of its copyright holder(s), and is made available	#
@@ -109,8 +109,8 @@ mandate_libs="libgpg-error libgpgme"
 mandate_bins="gpg"
 gcrypt_headers="gcrypt.h gcrypt-module.h"
 gcrypt_libs="libgcrypt"
-openssl_headers="openssl/evp.h openssl/sha.h openssl/blowfish.h"
-openssl_libs="libcrypto"
+openssl_headers="openssl/evp.h openssl/sha.h openssl/blowfish.h openssl/ssl.h openssl/err.h"
+openssl_libs="libcrypto libssl"
 lib_ext=".so"
 if [ "AIX" = "$hostos" ]; then
 	lib_ext="$lib_ext .a"
diff --git a/sr_unix/comlist.csh b/sr_unix/comlist.csh
index 1dbd4c3..bbf7fcf 100644
--- a/sr_unix/comlist.csh
+++ b/sr_unix/comlist.csh
@@ -449,11 +449,23 @@ echo ""
 echo "Start of C Compilation"	# Do not change this string. $gtm_tools/buildwarn.awk relies on this to detect warnings.
 echo ""
 
-#Do not compile gtmcrypt_ref.c, maskpass.c, gtm_threadgbl_deftypes.c
-#$gtm_tools/buildplugin.csh will take care of compilation and building of the reference plugin and the supporting files.
-find $gs[1] \( -name 'gtmcrypt*_ref.c' -o -name 'maskpass.c' -o -name 'omi_sx_play.c' -o \
-	-name 'gtm_threadgbl_deftypes.c' \) -prune -o -name '*.c' -print | \
-	sort | xargs -n25 $shell $gtm_tools/gt_cc.csh
+# List of files that should be excluded from the compilation as they are dealt with separately
+set TMP_DIR_PREFIX = "/tmp/__${user}__comlist"
+set TMP_DIR = "${TMP_DIR_PREFIX}__`date +"%y%m%d_%H_%M_%S"`_$$"
+\mkdir -p ${TMP_DIR}
+cat << EOF >&! ${TMP_DIR}/exclude.lst
+omi_sx_play.c
+gtm_threadgbl_deftypes.c
+gtmcrypt_pk_ref.c
+gtmcrypt_dbk_ref.c
+gtmcrypt_sym_ref.c
+gtmcrypt_ref.c
+gtmcrypt_util.c
+maskpass.c
+gtm_tls_impl.c
+EOF
+find $gs[1] -name '*.c' | grep -v -f ${TMP_DIR}/exclude.lst | sort | xargs -n25 $shell $gtm_tools/gt_cc.csh
+\rm -rf ${TMP_DIR}
 
 # Special compilation for omi_sx_play.c
 set comlist_gt_cc_bak = "$comlist_gt_cc"
diff --git a/sr_unix/configure.gtc b/sr_unix/configure.gtc
index 6409351..f79f876 100644
--- a/sr_unix/configure.gtc
+++ b/sr_unix/configure.gtc
@@ -405,7 +405,7 @@ fi
 # copy debug files if necessary
 if [ $arch = "zos" ] ; then
 	for i in `ls *.mdbg 2> /dev/null` ; do
-		cp $i $gtmdist
+		cp -p $i $gtmdist
 		rm -f $i
 	done
 fi
@@ -413,7 +413,7 @@ fi
 # Install COPYING if it is applicable
 file=COPYING
 if [ -f $file ]; then
-	cp $file $gtmdist
+	cp -p $file $gtmdist
 	if [ "$doutf8" -ne 0 ]; then
 		ln -s ../$file $gtmdist/utf8/$file
 	fi
@@ -422,7 +422,7 @@ fi
 # Install README.txt if it is applicable
 file=README.txt
 if [ -f $file ]; then
-	cp $file $gtmdist
+	cp -p $file $gtmdist
 	if [ "$doutf8" -ne 0 ]; then
 		ln -s ../$file $gtmdist/utf8/$file
 	fi
@@ -431,13 +431,13 @@ fi
 # Install custom_errors_sample.txt if it is applicable
 file=custom_errors_sample.txt
 if [ -f $file ]; then
-	cp $file $gtmdist
+	cp -p $file $gtmdist
 	if [ "$doutf8" -ne 0 ]; then
 		ln -s ../$file $gtmdist/utf8/$file
 	fi
 fi
 # Install the .cshrc and .profile files
-cp gdedefaults gtmprofile gtmprofile_preV54000 gtm gtmcshrc $gtmdist
+cp -p gdedefaults gtmprofile gtmprofile_preV54000 gtm gtmcshrc $gtmdist
 chmod 0444 $gtmdist/gdedefaults
 chown $owner $gtmdist/gdedefaults
 chmod 0755 $gtmdist/gtmprofile
@@ -452,7 +452,7 @@ chown $owner $gtmdist/gtmcshrc
 # Install the normal scripts
 for i in $nscripts
 do
-	cp $i $gtmdist
+	cp -p $i $gtmdist
 	chmod 0755 $gtmdist/$i
 	chown $owner $gtmdist/$i
 done
@@ -460,7 +460,7 @@ done
 # Install the root scripts
 for i in $rscripts
 do
-	cp $i $gtmdist
+	cp -p $i $gtmdist
 	chmod 0744 $gtmdist/$i
 	chown $rootuser $gtmdist/$i
 done
@@ -475,7 +475,7 @@ do
 	elif [ -x /usr/sbin/install ]; then
 		/usr/sbin/install -f $gtmdist -m 644 -u $owner -g $bingroup $i $gtmdist
 	elif [ $arch = "zos" ]; then
-		cp $i $gtmdist/
+		cp -p $i $gtmdist/
 		chmod 644 $gtmdist/$i
 		chown $user:$bingroup $gtmdist/$i
 	else
@@ -487,7 +487,7 @@ done
 # Install other individual files
 for i in  $ofiles
 do
-	cp $i $gtmdist
+	cp -p $i $gtmdist
 	chown $owner $gtmdist/$i
 done
 if [ $arch = "sun" ]; then
@@ -508,7 +508,7 @@ plugin="plugin"
 plugin_gtmcrypt="$plugin/gtmcrypt"
 
 # Gtmcrypt files used to build (and install)
-gtmcryptbldfiles="install.sh build.sh"
+gtmcryptbldfiles="Makefile"
 
 # Gtmcrypt Binaries
 gtmcryptbinaries="maskpass"
@@ -516,6 +516,7 @@ gtmcryptbinaries="maskpass"
 # Gtmcrypt shared library
 gtmcryptsharedlibs="libgtmcrypt_openssl_BLOWFISHCFB$ext libgtmcrypt_openssl_AES256CFB$ext"
 gtmcryptsharedlibs="$gtmcryptsharedlibs libgtmcrypt_gcrypt_AES256CFB$ext libgtmcrypt$ext"
+gtmcryptsharedlibs="$gtmcryptsharedlibs libgtmtls$ext libgtmcryptutil$ext"
 
 # Gtmcrypt scripts
 gtmcryptscripts="add_db_key.sh gen_sym_key.sh encrypt_sign_db_key.sh gen_keypair.sh pinentry-gtm.sh"
@@ -527,10 +528,8 @@ gtmcryptmfile="pinentry.m"
 # Gtmcrypt source files
 gtmcryptsrcfiles="gtmcrypt_ref.c gtmcrypt_ref.h gtmcrypt_interface.h maskpass.c"
 gtmcryptsrcfiles="$gtmcryptsrcfiles gtmcrypt_dbk_ref.c gtmcrypt_dbk_ref.h gtmcrypt_pk_ref.c gtmcrypt_pk_ref.h"
-gtmcryptsrcfiles="$gtmcryptsrcfiles gtmcrypt_sym_ref.h $gtmcryptbldfiles $gtmcryptmfile"
-
-# Other Gtmcrypt related files
-gtmcryptofiles="gtmcrypt.tab"
+gtmcryptsrcfiles="$gtmcryptsrcfiles gtmcrypt_sym_ref.h gtmcrypt_sym_ref.c gtm_tls_interface.h gtm_tls_impl.h"
+gtmcryptsrcfiles="$gtmcryptsrcfiles gtm_tls_impl.c gtmcrypt_util.c gtmcrypt_util.h $gtmcryptbldfiles $gtmcryptmfile"
 
 dogtmcrypt=0
 if [ -d "$plugin_gtmcrypt" ]; then
@@ -548,7 +547,7 @@ if [ -d "$plugin_gtmcrypt" ]; then
 	#Install the plugin related scripts
 	for i in $gtmcryptscripts
 	do
-		cp $plugin_gtmcrypt/$i $gtmdist/$plugin_gtmcrypt/$i
+		cp -p $plugin_gtmcrypt/$i $gtmdist/$plugin_gtmcrypt/$i
 		chmod 0755 $gtmdist/$plugin_gtmcrypt/$i
 		chown $owner $gtmdist/$plugin_gtmcrypt/$i
 		chgrp $bingroup $gtmdist/$plugin_gtmcrypt/$i
@@ -562,7 +561,7 @@ if [ -d "$plugin_gtmcrypt" ]; then
 		elif [ $arch = "ibm" ]; then
 			/usr/bin/install -f $gtmdist/$plugin_gtmcrypt -M 755 -O $owner -G $bingroup $plugin_gtmcrypt/$i
 		elif [ $arch = "zos" ]; then
-			cp $plugin_gtmcrypt/$i $gtmdist/$plugin_gtmcrypt
+			cp -p $plugin_gtmcrypt/$i $gtmdist/$plugin_gtmcrypt
 			chmod 755 $gtmdist/$plugin_gtmcrypt/$i
 			chown $user:$bingroup $gtmdist/$plugin_gtmcrypt/$i
 		elif [ -x /usr/sbin/install ]; then
@@ -586,7 +585,7 @@ if [ -d "$plugin_gtmcrypt" ]; then
 		elif [ $arch = "ibm" ]; then
 			/usr/bin/install -f $gtmdist/$plugin -M 755 -O $owner -G $bingroup $plugin/$i
 		elif [ $arch = "zos" ]; then
-			cp $plugin/$i $gtmdist/$plugin
+			cp -p $plugin/$i $gtmdist/$plugin
 			chmod 755 $gtmdist/$plugin/$i
 			chown $user:$bingroup $gtmdist/$plugin/$i
 		elif [ -x /usr/sbin/install ]; then
@@ -603,23 +602,14 @@ if [ -d "$plugin_gtmcrypt" ]; then
 	fi
 
 	# Install the plugin related M file
-	cp $plugin_gtmcrypt/$gtmcryptmfile $gtmdist/$plugin_gtmcrypt/$gtmcryptmfile
+	cp -p $plugin_gtmcrypt/$gtmcryptmfile $gtmdist/$plugin_gtmcrypt/$gtmcryptmfile
 	chmod 0644 $gtmdist/$plugin_gtmcrypt/$gtmcryptmfile
 	chown $owner $gtmdist/$plugin_gtmcrypt/$gtmcryptmfile
 	chgrp $bingroup $gtmdist/$plugin_gtmcrypt/$gtmcryptmfile
 
-	# Install other plugin files
-	for i in $gtmcryptofiles
-	do
-		cp $plugin_gtmcrypt/$i $gtmdist/$plugin_gtmcrypt
-		chmod 0644 $gtmdist/$plugin_gtmcrypt/$i
-		chown $owner $gtmdist/$plugin_gtmcrypt/$i
-		chgrp $bingroup $gtmdist/$plugin_gtmcrypt/$i
-	done
-
 	# Install gpgagent.tab
 	# This is an external call table so the path to the shared library has to be adjusted
-	echo "$gtmdist/plugin/libgtmcrypt.so" > $gtmdist/$plugin/gpgagent.tab
+	echo "$gtmdist/plugin/libgtmcryptutil$ext" > $gtmdist/$plugin/gpgagent.tab
 	cat $plugin/gpgagent.tab | sed 1d >> $gtmdist/$plugin/gpgagent.tab
 
 	# Tar the source files
@@ -630,7 +620,7 @@ if [ -d "$plugin_gtmcrypt" ]; then
 fi
 
 # Install GDE, GTMHELP, and all the percent routines
-cp *.o *.m $gtmdist
+cp -p *.o *.m $gtmdist
 
 # Install a mirror image (using soft links) of $gtmdist under $gtmdist/utf8 if this platform can support "UTF-8" mode.
 if [ "$doutf8" -ne 0 ]; then
@@ -648,7 +638,7 @@ if [ "$doutf8" -ne 0 ]; then
 		# Install .o files
 		base="`basename $file .o`"
 		if [ "$base" != "$file" ]; then
-			cp $file $gtmdist/utf8
+			cp -p $file $gtmdist/utf8
 		else
 			# Soft link everything else
 			if [ -f $gtmdist/utf8/$file ]; then
@@ -851,8 +841,8 @@ elif [ -x /usr/sbin/install ]; then
 	/usr/sbin/install -f $gtmdist -m 4555 -u root -g $bingroup gtmsecshr $gtmdist
 	/usr/sbin/install -f $tgtmsecshrdir -m 4500 -u root -g $bingroup gtmsecshrdir/gtmsecshr $tgtmsecshrdir
 elif [ $arch = "zos" ]; then
-	cp gtmsecshr $gtmdist/gtmsecshr
-	cp gtmsecshrdir/gtmsecshr $tgtmsecshrdir/gtmsecshr
+	cp -p gtmsecshr $gtmdist/gtmsecshr
+	cp -p gtmsecshrdir/gtmsecshr $tgtmsecshrdir/gtmsecshr
 	chown $rootuser:$bingroup $gtmdist/gtmsecshr $tgtmsecshrdir/gtmsecshr
 	chmod 4555 $gtmdist/gtmsecshr
 	chmod 4500 $tgtmsecshrdir/gtmsecshr
diff --git a/sr_unix/continue_proc.c b/sr_unix/continue_proc.c
index 29214f1..8c58d66 100644
--- a/sr_unix/continue_proc.c
+++ b/sr_unix/continue_proc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -19,6 +19,8 @@
 #include "gtmsecshr.h"
 #include "secshr_client.h"
 #include "send_msg.h"
+#include "is_proc_alive.h"
+#include "wbox_test_init.h"
 
 error_def(ERR_NOSUCHPROC);
 
@@ -29,11 +31,19 @@ int continue_proc(pid_t pid)
 	SETUP_THREADGBL_ACCESS;
 	DEBUG_ONLY(if (!TREF(gtm_usesecshr)))	/* Cause debug builds to talk to gtmsecshr more often */
 	{
-		if (0 == kill(pid, SIGCONT))
+		if (WBTEST_ENABLED(WBTEST_HOLD_GTMSOURCE_SRV_LATCH))
+		{
+			/* Simulate the kill below, but ignore its return status so that we end up invoking gtmsecshr */
+			kill(pid, SIGCONT);
+			/* Wait until the target quits so that kill() call by gtmsecshr fails with ESRCH */
+			while (is_proc_alive(pid, 0))
+				LONG_SLEEP(1);
+		}
+		else if (0 == kill(pid, SIGCONT))
 			return 0;
 		else if (ESRCH == errno)
 		{
-			send_msg(VARLSTCNT(5) ERR_NOSUCHPROC, 3, pid, RTS_ERROR_LITERAL("continue"));
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_NOSUCHPROC, 3, pid, RTS_ERROR_LITERAL("continue"));
 			return ESRCH;
 		} else
 			assert(EINVAL != errno);
diff --git a/sr_unix/daemon_ch.c b/sr_unix/daemon_ch.c
deleted file mode 100644
index dd38f46..0000000
--- a/sr_unix/daemon_ch.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-void	daemon_ch(void);	/* prototype to avoid warning */
-
-void	daemon_ch(void)
-{
-	return; /* No longer used */
-}
diff --git a/sr_unix/dbinit_ch.c b/sr_unix/dbinit_ch.c
index f2a2f53..f83b52e 100644
--- a/sr_unix/dbinit_ch.c
+++ b/sr_unix/dbinit_ch.c
@@ -40,12 +40,7 @@ GBLREF gd_region		*db_init_region;
 
 CONDITION_HANDLER(dbinit_ch)
 {
-	START_CH;
-	if (SUCCESS == SEVERITY || INFO == SEVERITY)
-	{
-		PRN_ERROR;
-		CONTINUE;
-	}
+	START_CH(TRUE);
 	db_init_err_cleanup(FALSE);
 	NEXTCH
 }
@@ -68,18 +63,13 @@ void db_init_err_cleanup(boolean_t retry_dbinit)
 			CLOSEFILE_RESET(udi->fd, rc);	/* resets "udi->fd" to FD_INVALID */
 		assert(FD_INVALID == udi->fd || retry_dbinit);
 		csa = &udi->s_addrs;
-#		ifdef GTM_CRYPT
-		if (NULL != csa->encrypted_blk_contents)
-		{
-			free(csa->encrypted_blk_contents);
-			csa->encrypted_blk_contents = NULL;
-		}
-#		endif
+#		ifdef _AIX
 		if ((NULL != csa->hdr) && (dba_mm == db_init_region->dyn.addr->acc_meth))
 		{
 			assert((NULL != csa->db_addrs[1]) && (csa->db_addrs[1] > csa->db_addrs[0]));
 			munmap((caddr_t)csa->db_addrs[0], (size_t)(csa->db_addrs[1] - csa->db_addrs[0]));
 		}
+#		endif
 		if (NULL != csa->jnl)
 		{
 			free(csa->jnl);
diff --git a/sr_unix/dm_read.c b/sr_unix/dm_read.c
index 7a3a4e9..30aab2e 100644
--- a/sr_unix/dm_read.c
+++ b/sr_unix/dm_read.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -19,7 +19,7 @@
 #include <signal.h>
 #include "gtm_unistd.h"
 #include "gtm_stdlib.h"
-#include "iotcp_select.h"
+#include "gtm_select.h"
 #include "io.h"
 #include "trmdef.h"
 #include "iottdef.h"
@@ -205,17 +205,15 @@ void	dm_read (mval *v)
 	if (tt_ptr->mupintr)
 	{	/* restore state to before job interrupt */
 		tt_state = &tt_ptr->tt_state_save;
-		if (ttwhichinvalid == tt_state->who_saved)
-			GTMASSERT;
+		assertpro(ttwhichinvalid != tt_state->who_saved);
 		if (dollar_zininterrupt)
 		{
 			tt_ptr->mupintr = FALSE;
 			tt_state->who_saved = ttwhichinvalid;
-			rts_error(VARLSTCNT(1) ERR_ZINTDIRECT);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTDIRECT);
 		}
 		assert(length == tt_state->length);
-		if (dmread != tt_state->who_saved)
-			GTMASSERT;	/* ZINTRECURSEIO should have caught */
+		assertpro(dmread == tt_state->who_saved);	/* ZINTRECURSEIO should have caught */
 		mv_zintdev = io_find_mvstent(io_ptr, FALSE);
 		if (mv_zintdev && mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid)
 		{
@@ -313,7 +311,7 @@ void	dm_read (mval *v)
 					tt_state->more_ptr = more_ptr;
 					memcpy(tt_state->more_buf, more_buf, SIZEOF(more_buf));
 				}
-				if (buffer_start == stringpool.free)	/* BYPASSOK */
+				if (IS_AT_END_OF_STRINGPOOL(buffer_start, 0))
 					stringpool.free += exp_length;	/* reserve space */
 				tt_state->instr = instr;
 				tt_state->outlen = outlen;
@@ -332,6 +330,7 @@ void	dm_read (mval *v)
 			outofband_action(FALSE);
 			break;
 		}
+		assertpro(FD_SETSIZE > tt_ptr->fildes);
 		FD_ZERO(&input_fd);
 		FD_SET(tt_ptr->fildes, &input_fd);
 		assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd));
@@ -346,7 +345,7 @@ void	dm_read (mval *v)
 		selstat = select(tt_ptr->fildes + 1, (void *)&input_fd, (void *)NULL, (void *)NULL, &input_timeval);
 		if (0 > selstat)
 			if (EINTR != errno)
-				rts_error(VARLSTCNT(1) errno);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 			else
 				continue;
 		else if (0 == selstat)
@@ -358,7 +357,7 @@ void	dm_read (mval *v)
 			{	/* If error was EINTR, go to the top of the loop to check for outofband. */
 				tt_ptr->discard_lf = FALSE;
 				io_ptr->dollar.za = 9;
-				rts_error(VARLSTCNT(1) errno);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 			} else
 				continue;
 		} else if (0 == status)
@@ -371,7 +370,7 @@ void	dm_read (mval *v)
 					exit(errno);
 			}
 			tt_ptr->discard_lf = FALSE;
-			rts_error(VARLSTCNT(1) ERR_IOEOF);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IOEOF);
 		}
 		else if (0 < status)
 		{	/* select() says it's ready to read and read() found some data */
@@ -919,7 +918,7 @@ void	dm_read (mval *v)
 			if (MAX_RECALL != recall_num)
 				recall_num ++;
 		}
-		if (buffer_start == stringpool.free)	/* BYPASSOK */
+		if (IS_AT_END_OF_STRINGPOOL(buffer_start, 0))
 			stringpool.free += v->str.len;	/* otherwise using space from before interrupt */
 	}
 	if (!(mask & TRM_NOECHO))
diff --git a/sr_unix/dpgbldir_sysops.c b/sr_unix/dpgbldir_sysops.c
index aafa9db..dadf1f2 100644
--- a/sr_unix/dpgbldir_sysops.c
+++ b/sr_unix/dpgbldir_sysops.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,7 +42,8 @@ char LITDEF gde_labels[GDE_LABEL_NUM][GDE_LABEL_SIZE] =
 	GDE_LABEL_LITERAL
 };
 
-GBLREF mval dollar_zgbldir;
+GBLREF mval 	dollar_zgbldir;
+GBLREF gd_addr	*gd_header;
 
 error_def(ERR_ZGBLDIRACC);
 error_def(ERR_IOEOF);
@@ -66,7 +67,8 @@ mstr *get_name(mstr *ms)
 	pblk.def1_size = SIZEOF(DEF_GDR_EXT) - 1;
 	status = parse_file(ms,&pblk);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, ms->len, ms->addr, LEN_AND_LIT(""), LEN_AND_LIT(""), status);
+		rts_error_csa(CSA_ARG(NULL)
+			VARLSTCNT(9) ERR_ZGBLDIRACC, 6, ms->len, ms->addr, LEN_AND_LIT(""), LEN_AND_LIT(""), status);
 	new = (mstr *)malloc(SIZEOF(mstr));
 	new->len = pblk.b_esl;
 	new->addr = (char *)malloc(pblk.b_esl);
@@ -90,11 +92,11 @@ void *open_gd_file(mstr *v)
 		if (!dollar_zgbldir.str.len || ((dollar_zgbldir.str.len == fp->v.len)
 							&& !memcmp(dollar_zgbldir.str.addr, fp->v.addr, fp->v.len)))
 		{
-			rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, fp->v.len, fp->v.addr,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, fp->v.len, fp->v.addr,
 				LEN_AND_LIT(".  Cannot continue"), LEN_AND_LIT(""), errno);
 			assert(FALSE);
 		}
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, fp->v.len, fp->v.addr, LEN_AND_LIT(".  Retaining "),
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, fp->v.len, fp->v.addr, LEN_AND_LIT(".  Retaining "),
 			dollar_zgbldir.str.len, dollar_zgbldir.str.addr, errno);
 	}
 #ifdef __MVS__
@@ -111,7 +113,7 @@ bool comp_gd_addr(gd_addr *gd_ptr, file_pointer *file_ptr)
 
 	FSTAT_FILE(file_ptr->fd, &buf, fstat_res);
 	if (-1 == fstat_res)
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
 			LEN_AND_LIT(""), LEN_AND_LIT(""), errno);
 	return is_gdid_stat_identical(gd_ptr->id, &buf);
 }
@@ -121,10 +123,10 @@ void fill_gd_addr_id(gd_addr *gd_ptr, file_pointer *file_ptr)
 	int fstat_res;
 	struct stat buf;
 
-	gd_ptr->id = (gd_id *) malloc(SIZEOF(gd_id));	/* Need to convert to gd_id_ptr_t during the 64-bit port */
+	gd_ptr->id = (gd_id *)malloc(SIZEOF(gd_id));
 	FSTAT_FILE(file_ptr->fd, &buf, fstat_res);
 	if (-1 == fstat_res)
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
 			LEN_AND_LIT(""), LEN_AND_LIT(""), errno);
 	set_gdid_from_stat(gd_ptr->id, &buf);
 	return;
@@ -146,19 +148,19 @@ void file_read(file_pointer *file_ptr, int4 size, uchar_ptr_t buff, int4 pos)
 	LSEEKREAD(file_ptr->fd, (off_t)(pos - 1 ) * DISK_BLOCK_SIZE, buff, size, save_errno);
 	if (0 != save_errno)
 		if (-1 == save_errno)
-			rts_error(VARLSTCNT(1) ERR_IOEOF);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IOEOF);
 		else
-			rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->v.len, file_ptr->v.addr,
 				LEN_AND_LIT(""), LEN_AND_LIT(""), save_errno);
 	return;
 }
 
 void dpzgbini(void)
 {
-	mstr	temp_mstr;
-	char	temp_buff[MAX_FBUFF + 1];
-	uint4 status;
-	parse_blk pblk;
+	mstr		temp_mstr;
+	char		temp_buff[MAX_FBUFF + 1];
+	uint4		status;
+	parse_blk	pblk;
 
 	temp_mstr.addr = GTM_GBLDIR;
 	temp_mstr.len = SIZEOF(GTM_GBLDIR) - 1;
@@ -178,4 +180,5 @@ void dpzgbini(void)
 		dollar_zgbldir.str.addr = pblk.buffer;
 	}
 	s2pool(&dollar_zgbldir.str);
+	gd_header = NULL;
 }
diff --git a/sr_unix/dse.c b/sr_unix/dse.c
index 7ba0a4a..aad0502 100644
--- a/sr_unix/dse.c
+++ b/sr_unix/dse.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -22,8 +22,6 @@
 #include "gtm_string.h"
 #include "stp_parms.h"
 #include "error.h"
-#include "min_max.h"
-#include "init_root_gv.h"
 #include "interlock.h"
 #include "gtmimagename.h"
 #include "stringpool.h"
@@ -80,14 +78,11 @@ GBLREF	u_casemap_t 		gtm_strToTitle_ptr;		/* Function pointer for gtm_strToTitle
 #endif
 
 GBLREF gd_region		*gv_cur_region;
-GBLREF gd_binding		*gd_map;
-GBLREF gd_binding		*gd_map_top;
 GBLREF gd_addr			*gd_header;
 GBLREF gd_addr			*original_header;
 GBLREF bool			licensed;
 GBLREF void			(*func)(void);
 GBLREF gv_namehead		*gv_target;
-GBLREF mval			curr_gbl_root;
 GBLREF int			(*op_open_ptr)(mval *v, mval *p, int t, mval *mspace);
 GBLREF boolean_t		dse_running;
 GBLREF spdesc			rts_stringpool, stringpool;
@@ -116,6 +111,7 @@ int main(int argc, char *argv[])
 	gtm_env_init();	/* read in all environment variables */
 	licensed = TRUE;
 	TREF(transform) = TRUE;
+	TREF(no_spangbls) = TRUE;	/* dse operates on a per-region basis irrespective of global mapping in gld */
 	op_open_ptr = op_open;
 	patch_curr_blk = get_dir_root();
 	err_init(util_base_ch);
@@ -136,12 +132,13 @@ int main(int argc, char *argv[])
 	initialize_pattern_table();
 	gvinit();
 	region_init(FALSE);
-	INIT_GBL_ROOT(); /* Needed for GVT initialization */
 	getjobnum();
 	util_out_print("!/File  !_!AD", TRUE, DB_LEN_STR(gv_cur_region));
 	util_out_print("Region!_!AD!/", TRUE, REG_LEN_STR(gv_cur_region));
 	cli_lex_setup(argc, argv);
-	CREATE_DUMMY_GBLDIR(gd_header, original_header, gv_cur_region, gd_map, gd_map_top);
+	/* Since DSE operates on a region-by-region basis (for the most part), do not use a global directory at all from now on */
+	original_header = gd_header;
+	gd_header = NULL;
 	OPERATOR_LOG_MSG;
 #	ifdef DEBUG
 	if ((gtm_white_box_test_case_enabled && (WBTEST_SEMTOOLONG_STACK_TRACE == gtm_white_box_test_case_number) ))
@@ -188,7 +185,7 @@ static bool	dse_process(int argc)
 	{
 		if (util_interrupt)
 		{
-			rts_error(VARLSTCNT(1) ERR_CTRLC);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CTRLC);
 			REVERT;
 			return TRUE;
 		} else
@@ -206,9 +203,9 @@ static bool	dse_process(int argc)
 			 * prompt, but UNIX exits
 			 */
 			REVERT;
-			rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
 		} else
-			gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
 	}
 	if (func)
 		func();
diff --git a/sr_unix/dse_cmd.c b/sr_unix/dse_cmd.c
index 2c2a81d..48d66f1 100644
--- a/sr_unix/dse_cmd.c
+++ b/sr_unix/dse_cmd.c
@@ -191,15 +191,15 @@ static readonly CLI_ENTRY dse_cfhead_qual[] = {
 };
 
 static readonly CLI_ENTRY dse_change_qual[] = {
-{ "BLOCK",      0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "BSIZ",       0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "CMPC",       dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "FILEHEADER", dse_chng_fhead, dse_cfhead_qual, 0, 0, cli_disallow_dse_chng_fhead, 0, VAL_DISALLOWED, 0, 0,       0,       0       },
-{ "LEVEL",      0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "OFFSET",     dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "RECORD",     dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "RSIZ",       dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
-{ "TN",         0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },
+{ "BLOCK",      0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "BSIZ",       0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "CMPC",       dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "FILEHEADER", dse_chng_fhead, dse_cfhead_qual, 0, 0, cli_disallow_dse_chng_fhead, 0, VAL_DISALLOWED, 0, 0,       0,       0       },	/* BYPASSOK */
+{ "LEVEL",      0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "OFFSET",     dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "RECORD",     dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "RSIZ",       dse_chng_rhead, 0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
+{ "TN",         0,              0,               0, 0, 0,                           0, VAL_REQ,        0, NON_NEG, VAL_NUM, VAL_HEX },	/* BYPASSOK */
 { 0 }
 };
 
@@ -274,6 +274,7 @@ static readonly CLI_ENTRY dse_find_qual[] = {
 { "CRIT",       0,          0, 0,                    0, 0, 0, VAL_N_A,     0, NEG,     0,       0       },
 { "EXHAUSTIVE", 0,          0, 0,                    0, 0, 0, VAL_N_A,     0, NON_NEG, 0,       0       },
 { "FREEBLOCK",  dse_f_free, 0, 0,                    0, 0, 0, VAL_N_A,     0, NON_NEG, 0,       0       },
+{ "GBLDIR",     0,          0, 0,                    0, 0, 0, VAL_N_A,     0, NEG,     0,       0       },
 { "HINT",       0,          0, 0,                    0, 0, 0, VAL_REQ,     0, NON_NEG, VAL_NUM, VAL_HEX },
 { "KEY",        dse_f_key,  0, 0,                    0, 0, 0, VAL_REQ,     0, NON_NEG, VAL_STR, 0       },
 { "REGION",     dse_f_reg,  0, dse_freg_parm_values, 0, 0, 0, VAL_NOT_REQ, 0, NON_NEG, VAL_STR, 0       },
diff --git a/sr_unix/dsk_write_nocache.c b/sr_unix/dsk_write_nocache.c
index 6de961f..552778c 100644
--- a/sr_unix/dsk_write_nocache.c
+++ b/sr_unix/dsk_write_nocache.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2005, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2005, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -54,7 +54,7 @@ int	dsk_write_nocache(gd_region *reg, block_id blk, sm_uc_ptr_t buff, enum db_ve
 	sm_uc_ptr_t		save_buff;
 #	ifdef GTM_CRYPT
 	int			in_len, this_blk_size, gtmcrypt_errno;
-	char			*in, *out;
+	char			*in;
 	gd_segment		*seg;
 #	endif
 
@@ -93,7 +93,10 @@ int	dsk_write_nocache(gd_region *reg, block_id blk, sm_uc_ptr_t buff, enum db_ve
 		assert(SIZEOF(blk_hdr) <= size);
 		/* no adjustment to blks_to_upgrd counter is needed since the format we are going to write is GDSVCURR */
 	}
-	DEBUG_ONLY(else GTMASSERT);
+#	ifdef DEBUG
+	else
+		assert(GDSV6 == ondsk_blkver);
+#	endif
 	if (csa->do_fullblockwrites)
 		size =(int)ROUND_UP(size, csa->fullblockwrite_len); /* round size up to next full logical filesys block. */
 	assert(size <= csd->blk_size);
@@ -102,7 +105,6 @@ int	dsk_write_nocache(gd_region *reg, block_id blk, sm_uc_ptr_t buff, enum db_ve
 	assert(size <= csd->blk_size);
 	if (udi->raw)
 		size = ROUND_UP(size, DISK_BLOCK_SIZE);	/* raw I/O must be a multiple of DISK_BLOCK_SIZE */
-
 #	ifdef GTM_CRYPT
 	/* Make sure we don't end up encrypting a zero length'ed record */
 	if (csd->is_encrypted)
@@ -113,17 +115,13 @@ int	dsk_write_nocache(gd_region *reg, block_id blk, sm_uc_ptr_t buff, enum db_ve
 		if (BLK_NEEDS_ENCRYPTION(((blk_hdr_ptr_t)buff)->levl, in_len))
 		{
 			ASSERT_ENCRYPTION_INITIALIZED;
-			assert(csa->encrypted_blk_contents);
-			memcpy(csa->encrypted_blk_contents, buff, SIZEOF(blk_hdr));
-			out = csa->encrypted_blk_contents + SIZEOF(blk_hdr);
 			in = (char *)(buff + SIZEOF(blk_hdr));
-			GTMCRYPT_ENCRYPT(csa, csa->encr_key_handle, in, in_len, out, gtmcrypt_errno);
+			GTMCRYPT_ENCRYPT(csa, csa->encr_key_handle, in, in_len, NULL, gtmcrypt_errno);
 			if (0 != gtmcrypt_errno)
 			{
 				seg = reg->dyn.addr;
-				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, seg->fname_len, seg->fname);
+				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, seg->fname_len, seg->fname);
 			}
-			buff = (unsigned char *)csa->encrypted_blk_contents;
 		}
 	}
 #	endif
diff --git a/sr_unix/dtgbldir.c b/sr_unix/dtgbldir.c
index bdfbae5..7e1c822 100644
--- a/sr_unix/dtgbldir.c
+++ b/sr_unix/dtgbldir.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -48,29 +48,14 @@
 #	define  SECOND_ONE	0xFFFFFF25
 #endif
 
-#ifdef GTM64
-#define SAVE_ADDR_REGION                   \
-{ \
-	int4 *tmp = (int *)&(addr->regions); \
-	*int4_ptr++ = *(tmp + lsb_index); \
-	int4_ptr++;       \
-}
-#else /* GTM64 */
-#define SAVE_ADDR_REGION                   \
-	*int4_ptr++ = (int4)addr->regions;
-#endif /* GTM64 */
-
-
 int main(int argc, char **argv)
 {
 	int		fd;
 	header_struct	*header;
 	gd_addr		*addr;
 	gd_region	*region;
-	gd_region	*region_top;
 	gd_segment	*segment;
-	int4		*int4_ptr;
-	uint4		t_offset, size;
+	uint4		size;
 	int		i, alloc, extend, block, global, key, lock, record;
 	ZOS_ONLY(int	realfiletag;)
 
@@ -192,64 +177,9 @@ int main(int argc, char **argv)
 	if (-1 == gtm_zos_set_tag(fd, TAG_BINARY, TAG_NOTTEXT, TAG_FORCE, &realfiletag))
 		PERROR("Error tagging file with TAG_BINARY");
 #endif
-	size = SIZEOF(header_struct) + SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding) + 1 * SIZEOF(gd_region) + 1 * SIZEOF(gd_segment);
-	header = (header_struct *)malloc(ROUND_UP(size, DISK_BLOCK_SIZE));
-	memset(header, 0, ROUND_UP(size, DISK_BLOCK_SIZE));
-	header->filesize = size;
-	size = ROUND_UP(size, DISK_BLOCK_SIZE);
-	MEMCPY_LIT(header->label, GDE_LABEL_LITERAL);
-	addr = (gd_addr *)((char *)header + SIZEOF(header_struct));
-	addr->max_rec_size = 256;
-	addr->maps = (gd_binding*)(SIZEOF(gd_addr));
-	addr->n_maps = 3;
-	addr->regions = (gd_region *)((INTPTR_T)(addr->maps) + 3 * SIZEOF(gd_binding));
-	addr->n_regions = 1;
-	addr->segments = (gd_segment *)((INTPTR_T)(addr->regions) + SIZEOF(gd_region));
-	addr->n_segments = 1;
-	addr->link = 0;
-	addr->tab_ptr = 0;
-	addr->id = 0;
-	addr->local_locks = 0;
-	addr->end = (INTPTR_T)((char *)addr->segments + 1 * SIZEOF(gd_segment));
-	int4_ptr = (int4*)((char *)addr + (INTPTR_T)(addr->maps));
-	*int4_ptr++ = FIRST_ONE;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	*int4_ptr++ = SECOND_ONE;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-	*int4_ptr++ = 0xFFFFFFFF;
-        SAVE_ADDR_REGION
-	region = (gd_region*)((char *)addr + (INTPTR_T)(addr->regions));
-	segment = (gd_segment*)((char *)addr + (INTPTR_T)(addr->segments));
-	region->rname_len = 7;
-	memcpy(region->rname,"DEFAULT",7);
-
-	for (region_top = region + addr->n_regions; region < region_top ; region++)
-	{	t_offset = region->dyn.offset;
-		region->dyn.addr = (gd_segment *)(INTPTR_T)t_offset;
-	}
 
-	region = (gd_region*)((char *)addr + (INTPTR_T)(addr->regions));
+	DUMMY_GLD_INIT(header, addr, region, segment, size, RELATIVE_OFFSET_TRUE);
+	/* the above macro invocation initializes "header", "addr", "region", "segment" and "size" */
 	region->dyn.offset = (int4)(INTPTR_T)addr->segments;
 	region->max_rec_size = record;
 	region->max_key_size = key;
diff --git a/sr_unix/errorsp.h b/sr_unix/errorsp.h
index a9f0cbd..10d1bc5 100644
--- a/sr_unix/errorsp.h
+++ b/sr_unix/errorsp.h
@@ -260,6 +260,7 @@ void ch_trace_point() {return;}
 						 */							\
 						stop_image_ch();					\
 					}								\
+					assert((SUCCESS == SEVERITY) || (INFO == SEVERITY));		\
                                 }
 
 #define NEXTCH			{									\
@@ -300,7 +301,7 @@ void ch_trace_point() {return;}
 					longjmp(active_ch->jmp, -1);								\
 				}
 
-#define START_CH		int current_ch;										\
+#define START_CH(flag_assert)	int current_ch;										\
 				DCL_THREADGBL_ACCESS;									\
 															\
 				SETUP_THREADGBL_ACCESS;									\
@@ -310,7 +311,12 @@ void ch_trace_point() {return;}
 				active_ch--;										\
 				CHECKLOWBOUND(active_ch);								\
 				DBGEHND((stderr, "%s: Condition handler entered at line %d - arg: %d  SIGNAL: %d\n",	\
-				         __FILE__, __LINE__, arg, SIGNAL));
+				         __FILE__, __LINE__, arg, SIGNAL));						\
+				if ((flag_assert) && ((SUCCESS == SEVERITY) || (INFO == SEVERITY)))			\
+				{											\
+					PRN_ERROR;									\
+					CONTINUE;									\
+				}
 
 #define MDB_START
 
@@ -416,6 +422,14 @@ CONDITION_HANDLER(gvcst_put_ch);
 CONDITION_HANDLER(gvcst_query_ch);
 CONDITION_HANDLER(gvcst_queryget_ch);
 CONDITION_HANDLER(gvcst_zprevious_ch);
+
+CONDITION_HANDLER(gvcst_spr_data_ch);
+CONDITION_HANDLER(gvcst_spr_kill_ch);
+CONDITION_HANDLER(gvcst_spr_order_ch);
+CONDITION_HANDLER(gvcst_spr_zprevious_ch);
+CONDITION_HANDLER(gvcst_spr_query_ch);
+CONDITION_HANDLER(gvcst_spr_queryget_ch);
+
 CONDITION_HANDLER(op_fnzpeek_ch);
 CONDITION_HANDLER(op_fnzpeek_getpool_ch);
 
diff --git a/sr_unix/f_piece.c b/sr_unix/f_piece.c
index 190868d..dc87ea9 100644
--- a/sr_unix/f_piece.c
+++ b/sr_unix/f_piece.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -59,8 +59,8 @@ int f_piece(oprtype *a, opctype op)
 	}
 	assert(TRIP_REF == x.oprclass);
 	if ((TK_COMMA != TREF(window_token)) && (OC_LIT == x.oprval.tref->opcode)
-		 && (1 == ((gtm_utf8_mode && (OC_FNZPIECE != op))  ?   MV_FORCE_LEN(&x.oprval.tref->operand[0].oprval.mlit->v)
-								   : x.oprval.tref->operand[0].oprval.mlit->v.str.len)))
+	    && (1 == ((gtm_utf8_mode && (OC_FNZPIECE != op)) ? MV_FORCE_LEN_DEC(&x.oprval.tref->operand[0].oprval.mlit->v)
+		      : x.oprval.tref->operand[0].oprval.mlit->v.str.len)))
 	{	/* Potential shortcut to op_fnzp1 or op_fnp1. Make some further checks */
 		delim_mval = &x.oprval.tref->operand[0].oprval.mlit->v;
 		/* Both valid chars of char_len 1 and invalid chars of byte length 1 get the fast path */
diff --git a/sr_unix/file_input.c b/sr_unix/file_input.c
index 487996f..8272566 100644
--- a/sr_unix/file_input.c
+++ b/sr_unix/file_input.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -36,6 +36,7 @@ GBLREF	uint4		dollar_tlevel;
 GBLREF io_pair		io_curr_device;
 
 error_def(ERR_LOADFILERR);
+error_def(ERR_FILEOPENFAIL);
 error_def(ERR_PREMATEOF);
 
 static char		buff1[BUFF_SIZE];
@@ -74,6 +75,8 @@ void file_input_init(char *fn, short fn_len)
 	val.str.addr = (char *)fn;
 	/* The mode will be set to M for reads */
 	status = (*op_open_ptr)(&val, &pars, 0, 0);
+	if (!status)
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_FILEOPENFAIL, 2, fn_len, fn);
 	pars.str.len = SIZEOF(iop_eol);
 	pars.str.addr = (char *)&no_param;
 	op_use(&val, &pars);
@@ -111,9 +114,9 @@ int	file_input_bin_get(char **in_ptr, ssize_t *file_offset, char **buff_base)
 		if (0 >= (rd_len = file_input_bin_read()))	/* NOTE assignment */
 		{
 			if (buff1_end != buff1_ptr)
-				rts_error(VARLSTCNT(1) ERR_PREMATEOF);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PREMATEOF);
 			else  if (-1 == rd_len)
-				rts_error(VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr);
 			else
 			{
 				REVERT;
@@ -134,8 +137,8 @@ int	file_input_bin_get(char **in_ptr, ssize_t *file_offset, char **buff_base)
 		if ((rd_len + buff1_end - buff1_ptr) < s1)
 		{
 			if (-1 == rd_len)
-				rts_error(VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr);
-			rts_error(VARLSTCNT(1) ERR_PREMATEOF);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PREMATEOF);
 		}
 		buff1_end += rd_len;
 	}
@@ -166,7 +169,7 @@ int file_input_bin_read(void)
 #	ifdef DEBUG_FO_BIN
 	PRINTF("int file_input_bin_read:\t\tread(%d, %x, %d) = %d\n", d_rm->fildes, buff1,  BUFF_SIZE, s1);
 	if (BUFF_SIZE - s1 > rdlen)
-		rts_error(VARLSTCNT(1) errno);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 #	endif
 	return rdlen;
 }
@@ -190,7 +193,7 @@ int file_input_get(char **in_ptr)
 		{
 			REVERT;
 			if (io_curr_device.in->dollar.x)
-				rts_error(VARLSTCNT(1) ERR_PREMATEOF);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PREMATEOF);
 			return -1;
 		}
 		if (mbuff_len < ret_len + rd_len)
diff --git a/sr_unix/ftok_sems.c b/sr_unix/ftok_sems.c
index 3e4b050..df5d10c 100644
--- a/sr_unix/ftok_sems.c
+++ b/sr_unix/ftok_sems.c
@@ -85,11 +85,11 @@ error_def(ERR_TEXT);
 
 #define	OLD_VERSION_SEM_PER_SET 2
 
-#define ISSUE_CRITSEMFAIL_AND_RETURN(REG, FAILED_OP, ERRNO)								\
-{															\
-	gtm_putmsg(VARLSTCNT(4) ERR_CRITSEMFAIL, 2, DB_LEN_STR(REG));							\
-	gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL(FAILED_OP), CALLFROM, ERRNO);				\
-	return FALSE;													\
+#define ISSUE_CRITSEMFAIL_AND_RETURN(REG, FAILED_OP, ERRNO)									\
+{																\
+	gtm_putmsg_csa(CSA_ARG(REG2CSA(REG)) VARLSTCNT(4) ERR_CRITSEMFAIL, 2, DB_LEN_STR(REG));					\
+	gtm_putmsg_csa(CSA_ARG(REG2CSA(REG)) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL(FAILED_OP), CALLFROM, ERRNO);	\
+	return FALSE;														\
 }
 
 #define CANCEL_TIMER_AND_RETURN_SUCCESS(REG)										\
@@ -222,7 +222,7 @@ boolean_t ftok_sem_get(gd_region *reg, boolean_t incr_cnt, int project_id, boole
 	assert(NULL == ftok_sem_reg);
 	if (-1 == (udi->key = FTOK(udi->fn, project_id)))
 	{
-		gtm_putmsg(VARLSTCNT(5) ERR_FTOKERR, 2, DB_LEN_STR(reg), errno);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_FTOKERR, 2, DB_LEN_STR(reg), errno);
 		return FALSE;
 	}
 	/* The following loop deals with the possibility that the semaphores can be deleted by someone else AFTER a successful
@@ -238,25 +238,29 @@ boolean_t ftok_sem_get(gd_region *reg, boolean_t incr_cnt, int project_id, boole
 			{
 				/* Possibly the key is in use by older GTM version */
 				if (-1 != semget(udi->key, OLD_VERSION_SEM_PER_SET, RALL))
-					gtm_putmsg(VARLSTCNT(4) ERR_SEMKEYINUSE, 1, udi->key, errno);
+					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_SEMKEYINUSE, 1, udi->key, errno);
 			}
 			ISSUE_CRITSEMFAIL_AND_RETURN(reg, "semget()", save_errno);
 		}
 		SET_GTM_ID_SEM(udi->ftok_semid, status); /* sets 3rd semaphore's value to GTM_ID = 43 */
-		if (-1 == status)
-		{
-			save_errno = errno;
-			ISSUE_CRITSEMFAIL_AND_RETURN(reg, "semctl()", save_errno);
-		}
-		SET_GTM_SOP_ARRAY(ftok_sop, ftok_sopcnt, incr_cnt, (SEM_UNDO | IPC_NOWAIT));
-		assert(mupip_jnl_recover || incr_cnt);
-		/* First try is always non-blocking */
-		SEMOP(udi->ftok_semid, ftok_sop, ftok_sopcnt, status, NO_WAIT);
 		if (-1 != status)
 		{
-			SENDMSG_SEMOP_SUCCESS_IF_NEEDED(stacktrace_issued, gtm_ftok_sem);
-			udi->counter_ftok_incremented = incr_cnt;
-			RETURN_SUCCESS(reg);
+			SET_GTM_SOP_ARRAY(ftok_sop, ftok_sopcnt, incr_cnt, (SEM_UNDO | IPC_NOWAIT));
+			assert(mupip_jnl_recover || incr_cnt);
+			/* First try is always non-blocking */
+			SEMOP(udi->ftok_semid, ftok_sop, ftok_sopcnt, status, NO_WAIT);
+			if (-1 != status)
+			{
+				SENDMSG_SEMOP_SUCCESS_IF_NEEDED(stacktrace_issued, gtm_ftok_sem);
+				udi->counter_ftok_incremented = incr_cnt;
+				RETURN_SUCCESS(reg);
+			}
+		} else
+		{
+			save_errno = errno;
+			if (immediate || !SEM_REMOVED(save_errno))
+				ISSUE_CRITSEMFAIL_AND_RETURN(reg, "semctl()", save_errno);
+			continue;
 		}
 		save_errno = errno;
 		if (immediate)
@@ -309,8 +313,8 @@ boolean_t ftok_sem_get(gd_region *reg, boolean_t incr_cnt, int project_id, boole
 				{	/* we exhausted maximum attempts to do blocking semop. Issue SEMWT2LONG error and return */
 					assert(-1 != sem_pid);
 					tot_wait_time = (semop_wait_time * max_semop_trycnt) / MILLISECS_IN_SEC;
-					gtm_putmsg(VARLSTCNT(9) ERR_SEMWT2LONG, 7, process_id, tot_wait_time, LEN_AND_LIT("ftok"),
-							DB_LEN_STR(reg), sem_pid);
+					gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_SEMWT2LONG, 7, process_id, tot_wait_time,
+						       LEN_AND_LIT("ftok"), DB_LEN_STR(reg), sem_pid);
 					return FALSE;
 				}
 				/* fall-through */
@@ -326,7 +330,7 @@ boolean_t ftok_sem_get(gd_region *reg, boolean_t incr_cnt, int project_id, boole
 	assert(-1 == status);
 	assert(MAX_SEMGET_RETRIES < lcnt);
 	assert(FALSE);
-	gtm_putmsg(VARLSTCNT(8) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
+	gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
 			ERR_TEXT, 2, RTS_ERROR_LITERAL("failed to obtain ftok semaphore after maximum retries"));
 	return FALSE;
 }
diff --git a/sr_unix/gbldirnam.h b/sr_unix/gbldirnam.h
index f34b3de..b9af636 100644
--- a/sr_unix/gbldirnam.h
+++ b/sr_unix/gbldirnam.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,5 +12,5 @@
 #define GDE_LABEL_SIZE 13
 #define GDE_LABEL_NUM 1
 /* Note, GDE_LABEL_LITERAL must be maintained in gdeinit.m if changes are made here */
-#define GDE_LABEL_LITERAL GTM64_ONLY("GTCGBDUNX108") NON_GTM64_ONLY("GTCGBDUNX008")
+#define GDE_LABEL_LITERAL GTM64_ONLY("GTCGBDUNX109") NON_GTM64_ONLY("GTCGBDUNX009")
 #define DEF_GDR_EXT "*.gld"
diff --git a/sr_unix/gdeget.m b/sr_unix/gdeget.m
index 14ccbf8..b9887c6 100644
--- a/sr_unix/gdeget.m
+++ b/sr_unix/gdeget.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,9 +10,9 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gdeget:	;read in an existing GD or create a default
 LOAD
-	n abs,contents,rel,xregs,xsegs,reglist,map,$et
+	n abs,contents,rel,xregs,xsegs,reglist,map,$et,ptrsize
 	i debug s $et="b"
-	e  s $et="g ABORT^GDE:($p($p($zs,"","",3),""-"")'=""%GDE"") u io w !,$p($zs,"","",3,999),! h"
+	e  s $et="g ABORT^GDE:($p($p($zs,"","",3),""-"")'=""%GDE"") u io w !,$p($zs,"","",3,999),! d GETOUT^GDEEXIT h"
 	; if zchset is UTF-8 open in raw mode to avoid BADCHAR errors
 	; For OS390 aka z/OS, use BINARY mode
 	s abs=1,update=0,chset=$SELECT($ZV["OS390":"BINARY",$ZV["VMS":"",$ZCHSET="UTF-8":"M",1:"")
@@ -23,68 +23,71 @@ LOAD
 	s label=$ze(rec,1,12)
 	s olabel=label
 	s mach=$p($zver," ",4)
+	n gldfmt
+	i ($ze(label,1,9)'="GTCGBDUNX") zm gdeerr("GDUNKNFMT"):file,gdeerr("INPINTEG")
+	s gldfmt=+$ze(label,11,12)	; 10th byte could be 1 indicating 64-bit platform so ignore that for format check
 	s seghasencrflag=FALSE
-	if ($e(label,0,9)="GTCGBDUNX"),$e(label,$l(label)-1,99)>5 s seghasencrflag=TRUE
+	i gldfmt>5 s seghasencrflag=TRUE
 	s reghasv550fields=FALSE
-	if ($e(label,0,9)="GTCGBDUNX"),$e(label,$l(label)-1,99)>6 s reghasv550fields=TRUE
+	i gldfmt>6 s reghasv550fields=TRUE
 	s reghasv600fields=FALSE
-	if ($e(label,0,9)="GTCGBDUNX"),$e(label,$l(label)-1,99)>7 s reghasv600fields=TRUE
-	set v550=0
+	i gldfmt>7 s reghasv600fields=TRUE
+	s v600=0
+	i (label="GTCGBDUNX008")!(label="GTCGBDUNX108") s label=hdrlab,v600=1,update=1	;autoconvert
+	i (v600=1) n SIZEOF d v600init
+	s v550=0
 	i (label="GTCGBDUNX007")!(label="GTCGBDUNX107") s label=hdrlab,v550=1,update=1	;autoconvert
 	i (v550=1) n SIZEOF d v550init
-	set v542=0
+	s v542=0
 	i (label="GTCGBLDIR009")!(label="GTCGBDUNX006")!(label="GTCGBDUNX106") s label=hdrlab,v542=1,update=1	;autoconvert
 	i (v542=1) n SIZEOF d v542init
-	set v534=0
+	s v534=0
 	i (label="GTCGBDUNX105")!((label="GTCGBDUNX005")&(mach="IA64")) s label=hdrlab,v534=1,update=1   ;autoconvert
 	i (v534=1) n SIZEOF d v534init
-	set v533=0
+	s v533=0
 	i (gtm64=TRUE),(label="GTCGBDUNX006") s label=hdrlab,v533=1,update=1   ;autoconvert
 	i (v533=1) n SIZEOF d v533init
-	set v532=0
+	s v532=0
 	i (label="GTCGBLDIR008")!(label="GTCGBDUNX005") s label=hdrlab,v532=1,update=1	;autoconvert
 	i (v532=1),(mach'="IA64") n gtm64 s gtm64=FALSE
 	i (v532=1),(mach'="IA64") n SIZEOF d v532init
-	set v5ft1=0
+	s v5ft1=0
 	i (label="GTCGBLDIR008")!(label="GTCGBDUNX004") s label=hdrlab,v5ft1=1,update=1 ;autoconvert
 	i v5ft1=1 n gtm64 s gtm64=FALSE
 	i v5ft1=1 n SIZEOF d v5ft1init
-	set v44=0
+	s v44=0
 	i (label="GTCGBLDIR007")!(label="GTCGBDUNX003") s label=hdrlab,v44=1,update=1	;autoconvert
 	i v44=1 n gtm64 s gtm64=FALSE
 	i v44=1 n MAXNAMLN,MAXSEGLN,MAXREGLN,SIZEOF d v44init
 	s v30=0
 	i (label="GTCGBLDIR006")!(label="GTCGBDUNX002") s label=hdrlab,v30=4,update=1 ;autoconvert
 	i v30=4 n gtm64 s gtm64=FALSE
-	i label'=hdrlab d cretmps,CONVERT^GDEOGET,verify s encryptsupported=FALSE,update=1 q ;autoconvert
+	i label'=hdrlab zm gdeerr("GDUNKNFMT"):file,gdeerr("INPINTEG")
 	s filesize=$$bin2num($ze(rec,13,16))
 	s abs=abs+SIZEOF("gd_header")
 ; contents
-	i (gtm64=TRUE) d
-	. i $ze(rec,abs,abs+7)'=$c(0,0,0,0,0,0,0,0) zm gdeerr("INPINTEG")						; filler
-	. s abs=abs+8
-	e  d
-	. i $ze(rec,abs,abs+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; filler
-	. s abs=abs+4
+	s ptrsize=$s((gtm64=TRUE):8,1:4)
+	i $ze(rec,abs,abs+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")	; gd_addr.local_locks
+	s abs=abs+ptrsize
 	s contents("maxrecsize")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("mapcnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("regioncnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("segmentcnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	i $ze(rec,abs,abs+1)'=$tr($j("",2)," ",ZERO) zm gdeerr("INPINTEG")				; filler
-	i (gtm64=TRUE) d
-	. s abs=abs+6											; including padding
-	. s contents("maps")=$$bin2num($ze(rec,abs,abs+7)),abs=abs+8
-	. s contents("regions")=$$bin2num($ze(rec,abs,abs+7)),abs=abs+8
-	. s contents("segments")=$$bin2num($ze(rec,abs,abs+7)),abs=abs+8
-	. s abs=abs+24								;skip link, tab_ptr and id pointers
-	. s contents("end")=$$bin2num($ze(rec,abs,abs+7)),abs=abs+8
+	n cntsize  s cntsize=$s((gldfmt>8):4,1:2)				; counters are 4-bytes since V6.1
+	s contents("mapcnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("regioncnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("segmentcnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	i '(gldfmt>8) d
+	. i $ze(rec,abs,abs+cntsize-1)'=$tr($j("",cntsize)," ",ZERO) zm gdeerr("INPINTEG") ; filler
+	. s abs=abs+cntsize
+	. i gtm64=TRUE s abs=abs+4						; including 4-byte padding
 	e  d
-	. s abs=abs+2
-	. s contents("maps")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	. s contents("regions")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	. s contents("segments")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	. s abs=abs+12								;skip link, tab_ptr and id pointers
-	. s contents("end")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	. s contents("gblnamecnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	. s contents("varmapslen")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("maps")=$$bin2num($ze(rec,abs,abs+ptrsize-1)),abs=abs+ptrsize
+	s contents("regions")=$$bin2num($ze(rec,abs,abs+ptrsize-1)),abs=abs+ptrsize
+	s contents("segments")=$$bin2num($ze(rec,abs,abs+ptrsize-1)),abs=abs+ptrsize
+	i (gldfmt>8) s contents("gblnames")=$$bin2num($ze(rec,abs,abs+ptrsize-1)),abs=abs+ptrsize
+	s abs=abs+(3*ptrsize)							;skip link, tab_ptr and id pointers
+	s contents("end")=$$bin2num($ze(rec,abs,abs+ptrsize-1)),abs=abs+ptrsize
+	i (gldfmt>8) s abs=abs+16	; reserved for runtime fillers
 	i contents("regioncnt")'=contents("segmentcnt") zm gdeerr("INPINTEG")
 	i contents("regioncnt")-1>contents("mapcnt") zm gdeerr("INPINTEG")
 ; verify offsets
@@ -92,19 +95,33 @@ LOAD
 	s x=contents("maps")
 	i x+1'=(abs-SIZEOF("gd_header")) zm gdeerr("INPINTEG")
 	s x=x+(contents("mapcnt")*SIZEOF("gd_map"))
+	i (gldfmt>8)  s x=x+contents("varmapslen")		; add variable maps section too if available
 	i x'=contents("regions") zm gdeerr("INPINTEG")
 	s x=x+(contents("regioncnt")*SIZEOF("gd_region"))
 	i x'=contents("segments") zm gdeerr("INPINTEG")
 	s x=x+(contents("segmentcnt")*(SIZEOF("gd_segment")-v30))
+	i (gldfmt>8) d
+	. i x'=contents("gblnames") zm gdeerr("INPINTEG")
+	. s x=x+(contents("gblnamecnt")*(SIZEOF("gd_gblname")))
 	i x'=contents("end") zm gdeerr("INPINTEG")
 	s rel=abs
 ; maps - verify that mapped regions and regions are 1-to-1
 	k reglist
-	f i=1:1:contents("mapcnt") d map
-	zm:'$$MAP2NAM^GDEMAP(.map) gdeerr("INPINTEG")
+	i '(gldfmt>8) d
+	. f i=1:1:contents("mapcnt") d mapPreV61
+	e  d
+	. n maparray,tmpabs,newabs
+	. f i=1:1:contents("mapcnt") d mapfixed(i)	; read through fixed    section of MAPS
+	. s tmpabs=abs
+	. f i=1:1:contents("mapcnt") d mapvariable(i)	; read through variable section of MAPS
+	. s newabs=(((abs-1)+(ptrsize-1))\ptrsize*ptrsize)+1 ; make "abs" 8-byte aligned for 64bit platforms (and 4-byte for 32-bit)
+	. s rel=rel+(newabs-abs)			; adjust "rel" to take "abs"-alignment-adjustment into account
+	. s abs=newabs
+	. i (abs-tmpabs)'=contents("varmapslen") zm gdeerr("INPINTEG")
 	s s=""
 	f i=1:1:contents("regioncnt") s s=$o(reglist(s))
-	i $l($o(reglist(s))) zm gdeerr("INPINTEG")
+	i $zl($o(reglist(s))) zm gdeerr("INPINTEG")
+	i i'=contents("regioncnt") zm gdeerr("INPINTEG")
 ; regions
 	k regs,xregs s regs=0
 	f i=1:1:contents("regioncnt") d region
@@ -113,6 +130,13 @@ LOAD
 	k segs,xsegs s segs=0
 	f i=1:1:contents("segmentcnt") d segment
 	i segs'=contents("segmentcnt") zm gdeerr("INPINTEG")
+; gblnames
+	i (gldfmt>8) d
+	. k gnams s gnams=0
+	. f i=1:1:contents("gblnamecnt") d gblname(i)
+	e  s gnams=0
+	; wait until "gnams" is setup before checking maps, as "gnams" is used in case of subscripted gvns in map entries
+	zm:'$$MAP2NAM^GDEMAP(.map) gdeerr("INPINTEG")
 ; template access method
 	s tmpacc=$$gderead(4)
 	i accmeth'[("\"_tmpacc) zm gdeerr("INPINTEG")
@@ -130,7 +154,7 @@ LOAD
 	i (reghasv600fields=TRUE) d tmpreg("INST_FREEZE_ON_ERROR")
 	f s="JOURNAL","KEY_SIZE","NULL_SUBSCRIPTS" d tmpreg(s)
 	i (reghasv600fields=TRUE) d tmpreg("QDBRUNDOWN")
-	f s="RECORD_SIZE" d tmpreg(s) ;,"STOP_ENABLE"
+	f s="RECORD_SIZE" d tmpreg(s)
 	; need to handle versioning
 	i 'v44&'v30 d tmpreg("STDNULLCOLL")
 	i (reghasv550fields=TRUE) d tmpreg("SYNC_IO")
@@ -141,24 +165,25 @@ LOAD
 	i (reghasv550fields=TRUE) i tmpreg("ALIGNSIZE")<minreg("ALIGNSIZE")  s tmpreg("ALIGNSIZE")=minreg("ALIGNSIZE"),update=1
 	i (reghasv550fields=TRUE) i tmpreg("AUTOSWITCHLIMIT")<minreg("AUTOSWITCHLIMIT")  d
 	. s tmpreg("AUTOSWITCHLIMIT")=minreg("AUTOSWITCHLIMIT"),update=1
-	f i=2:1:$l(accmeth,"\") s am=$p(accmeth,"\",i) d
-	. i am="MM" d:$zl(rec)-(rel-1)<3 nextrec i +$ze(rec,rel,rel+2)'=2 d tmpmm q
+	f i=2:1:$zl(accmeth,"\") s am=$p(accmeth,"\",i) d
+	. i am="MM" d:$zl(rec)-(rel-1)<3 nextrec i +$ze(rec,rel,rel+2)'=2 n tmpsegcommon d tmpmm q
 	. f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","BUCKET_SIZE","DEFER" d tmpseg(am,s)
 	. i (seghasencrflag=TRUE) d tmpseg(am,"ENCRYPTION_FLAG")
 	. f s="EXTENSION_COUNT","FILE_TYPE","GLOBAL_BUFFER_COUNT","LOCK_SPACE" d tmpseg(am,s)
+	. i (gldfmt>8) d tmpseg(am,"MUTEX_SLOTS")
 	. i 'v30 d tmpseg(am,"RESERVED_BYTES")					;autoconvert, can be condensed someday
 	. d tmpseg(am,"WINDOW_SIZE")
 	.
 	c file
 ; resolve
 	s s=""
-	f  s s=$o(nams(s)) q:'$l(s)  zm:'$d(xregs(nams(s))) gdeerr("INPINTEG") s nams(s)=xregs(nams(s))
-	f  s s=$o(regs(s)) q:'$l(s)  zm:'$d(xsegs(regs(s,"DYNAMIC_SEGMENT"))) gdeerr("INPINTEG") d
+	f  s s=$o(nams(s)) q:'$zl(s)  zm:'$d(xregs(nams(s))) gdeerr("INPINTEG") s nams(s)=xregs(nams(s))
+	f  s s=$o(regs(s)) q:'$zl(s)  zm:'$d(xsegs(regs(s,"DYNAMIC_SEGMENT"))) gdeerr("INPINTEG") d
 	. s regs(s,"DYNAMIC_SEGMENT")=xsegs(regs(s,"DYNAMIC_SEGMENT"))
-	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD") d
+	f  s s=$o(segs(s)) q:'$zl(s)  s am=segs(s,"ACCESS_METHOD") d
 	. s x=""
 	. f  s x=$o(segs(s,x)) q:x=""  d
-	. . i x'="FILE_NAME",'$l(tmpseg(am,x)) zm:segs(s,x) gdeerr("INPINTEG") s segs(s,x)=""
+	. . i x'="FILE_NAME",'$zl(tmpseg(am,x)) zm:segs(s,x) gdeerr("INPINTEG") s segs(s,x)=""
 	; fall through !
 verify:	s x=$$ALL^GDEVERIF
 	i 'x zm gdeerr("INPINTEG")
@@ -168,6 +193,7 @@ verify:	s x=$$ALL^GDEVERIF
 
 badfile ;file access failed
 	s:'debug $et="" u file:exc="" s abortzs=$zs zm gdeerr("GDREADERR"):file,+abortzs
+	d GETOUT^GDEEXIT
 	h
 	;
 bin2num:(bin)	; binary number -> number
@@ -179,19 +205,57 @@ bin2num:(bin)	; binary number -> number
 	;
 
 ;----------------------------------------------------------------------------------------------------------------------------------
-map:
+regoffchk:(x)	; check region offset
+	s reglist(x)="",x=x-contents("regions")
+	i x#SIZEOF("gd_region") zm gdeerr("INPINTEG")
+	i x\SIZEOF("gd_region")'<contents("regioncnt") zm gdeerr("INPINTEG")
+	q
+
+mapPreV61:
 	i $zl(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
 	s s=$ze(rec,rel,rel+SIZEOF("mident")-1),rel=rel+SIZEOF("mident")
-	s x=$zf(s,$c(0))-2 i x=-2 s x=SIZEOF("mident")
+	s x=$zf(s,ZERO)-2 i x=-2 s x=SIZEOF("mident")
 	s s=$ze(s,1,x)
-	i (gtm64=TRUE) s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+8 ; read 4 bytes, but skip 8 bytes
-	e  s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+ptrsize ; read 4 bytes, but skip 8 bytes if gtm64
 	s map(s)=x
-	s reglist(x)="",x=x-contents("regions")
-	i x#SIZEOF("gd_region") zm gdeerr("INPINTEG")
-	i x\SIZEOF("gd_region")'<contents("regioncnt") zm gdeerr("INPINTEG")
+	d regoffchk(x)
 	s abs=abs+SIZEOF("gd_map")
 	q
+
+mapfixed:(i)
+	n regoffset,keyoffset,gvnamelen,gvkeylen
+	i $zl(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
+	s keyoffset=$$bin2num($ze(rec,rel,rel+3)),rel=rel+ptrsize ; read 4 bytes, but skip 8 bytes if gtm64
+	s regoffset=$$bin2num($ze(rec,rel,rel+3)),rel=rel+ptrsize ; read 4 bytes, but skip 8 bytes if gtm64
+	s gvnamelen=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s gvkeylen=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s maparray(i,1)=keyoffset
+	s maparray(i,2)=regoffset
+	s maparray(i,3)=gvnamelen
+	s maparray(i,4)=gvkeylen+1	; include second null byte as well
+	d regoffchk(regoffset)
+	s abs=abs+SIZEOF("gd_map")
+	q
+
+mapvariable:(i)
+	n keyoffset,regoffset,gvnamelen,gvkeylen,s
+	s keyoffset=maparray(i,1)
+	s regoffset=maparray(i,2)
+	s gvnamelen=maparray(i,3)
+	s gvkeylen=maparray(i,4)
+	i (keyoffset+1+SIZEOF("gd_header"))'=abs zm gdeerr("INPINTEG")
+	i (keyoffset+gvkeylen)>contents("regions") zm gdeerr("INPINTEG")
+	f  q:(($zl(rec)-(rel-1))'<gvkeylen)  d nextrec
+	s s=$ze(rec,rel,rel+gvkeylen-1)
+	i $ze(s,gvnamelen+1)'=ZERO zm gdeerr("INPINTEG")
+	i $ze(s,gvkeylen-1)'=ZERO zm gdeerr("INPINTEG")
+	i $ze(s,gvkeylen)'=ZERO zm gdeerr("INPINTEG")
+	s s=$ze(s,1,gvkeylen-2)
+	s map(s)=regoffset
+	s rel=rel+gvkeylen
+	s abs=abs+gvkeylen
+	q
+
 region:
 	i $zl(rec)-(rel-1)<SIZEOF("gd_region") d nextrec
 	s regs=regs+1
@@ -199,17 +263,12 @@ region:
 	s s=$ze(rec,rel,rel+l-1),rel=rel+MAXREGLN,xregs(abs-1-SIZEOF("gd_header"))=s
 	s regs(s,"KEY_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
 	s regs(s,"RECORD_SIZE")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	i (gtm64=TRUE) s regs(s,"DYNAMIC_SEGMENT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+8  ; read 4 bytes, but skip 8
-	e  s regs(s,"DYNAMIC_SEGMENT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s regs(s,"DYNAMIC_SEGMENT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+ptrsize
 	s x=regs(s,"DYNAMIC_SEGMENT")-contents("segments")
 	i x#(SIZEOF("gd_segment")-v30) zm gdeerr("INPINTEG")						; autoconvert
 	i x\(SIZEOF("gd_segment")-v30)'<contents("segmentcnt") zm gdeerr("INPINTEG")			; autoconvert
-	i (gtm64=TRUE) d
-	. i $ze(rec,rel,rel+7)'=$c(0,0,0,0,0,0,0,0) zm gdeerr("INPINTEG")				; static segment
-	. s rel=rel+8
-	e  d
-	. i $ze(rec,rel,rel+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")					; static segment
-	. s rel=rel+4
+	i $ze(rec,rel,rel+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")		; static segment
+	s rel=rel+ptrsize
 	i $ze(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; OPEN state
 	s rel=rel+1
 	i $ze(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; lock_write
@@ -256,9 +315,10 @@ region:
 	. s regs(s,"QDBRUNDOWN")=0
 	s l=$$bin2num($ze(rec,rel)),rel=rel+1 ;jnl_file_len
 	s regs(s,"FILE_NAME")=$ze(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
-	s rel=rel+SIZEOF("gd_region_padding")								; padding
 	i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")				; reserved
 	s rel=rel+8											; reserved
+	i (gldfmt>8) s rel=rel+16	; reserved for runtime fillers
+	s rel=rel+SIZEOF("gd_region_padding")								; padding
 	s abs=abs+SIZEOF("gd_region")
 	q
 segment:
@@ -275,12 +335,8 @@ segment:
 	s segs(s,"BLOCK_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
 	s segs(s,"EXTENSION_COUNT")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
 	s segs(s,"ALLOCATION")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	i (gtm64=TRUE) d
-	. i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
-	. s rel=rel+12						; padding
-	e  d
-	. i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
-	. s rel=rel+4
+	i $ze(rec,rel,rel+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")	; reserved for clb
+	s rel=rel+$s((gtm64=TRUE):12,1:4)							; padding
 	i $ze(rec,rel,rel+3)'=".DAT" zm gdeerr("INPINTEG")
 	s rel=rel+4
 	s segs(s,"DEFER")=$$bin2num($ze(rec,rel))
@@ -294,27 +350,41 @@ segment:
 	s rel=rel+1
 	s segs(s,"LOCK_SPACE")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
 	s segs(s,"GLOBAL_BUFFER_COUNT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	i 'v30 s segs(s,"RESERVED_BYTES")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4		;autoconvert
+	i 'v30 d
+	. s segs(s,"RESERVED_BYTES")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4		;autoconvert
 	e  s segs(s,"RESERVED_BYTES")=0
+	i (gldfmt>8) s segs(s,"MUTEX_SLOTS")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	e  s segs(s,"MUTEX_SLOTS")=defseg("MUTEX_SLOTS")
 	s rel=rel+4										; access method already processed
-	i (gtm64=TRUE) d
-	. i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")			; file_cntl pointer
-	. s rel=rel+8
-	. i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")			; repl_list pointer
-	. s rel=rel+8
-	e  d
-	. i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; file_cntl pointer
-	. s rel=rel+4
-	. i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; repl_list pointer
-	. s rel=rel+4
+	i (gldfmt>8)&(gtm64=TRUE) s rel=rel+4 							; 4-byte filler
+	i $ze(rec,rel,rel+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")	; file_cntl pointer
+	s rel=rel+ptrsize
+	i $ze(rec,rel,rel+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")	; repl_list pointer
+	s rel=rel+ptrsize
 	; If the gld file has the encrytion flag, read it. Also read only if
 	; the current platform is encrpytion enabled. Otherwise default to 0
 	s segs(s,"ENCRYPTION_FLAG")=$S(((encsupportedplat=TRUE)&(seghasencrflag=TRUE)):$$bin2num($ze(rec,rel,rel+3)),1:0)
 	i (seghasencrflag=TRUE) d
 	. s rel=rel+4
         . if (gtm64=TRUE) s rel=rel+4 ; Padding bytes for 64 bit platforms
+	i (gldfmt>8) s rel=rel+16	; reserved for runtime fillers
 	s abs=abs+SIZEOF("gd_segment")-v30
 	q
+gblname(i);
+	n x,y
+	i $zl(rec)-(rel-1)<SIZEOF("gd_gblname") d nextrec
+	s gnams=gnams+1
+	s s=$ze(rec,rel,rel+SIZEOF("mident")-1),rel=rel+SIZEOF("mident")
+	s x=$zf(s,ZERO)-2 i x=-2 zm gdeerr("INPINTEG")	; it better be null terminated
+	s s=$ze(s,1,x)
+	s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4 	; read 4 bytes
+	i x>maxgnam("COLLATION") zm gdeerr("INPINTEG")	; collation # should be <= 255
+	s y=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4 	; read 4 bytes
+	d chkcoll^GDEPARSE(x,s,y)
+	s gnams(s,"COLLATION")=x
+	s gnams(s,"COLLVER")=y
+	s abs=abs+SIZEOF("gd_gblname")
+	q
 gderead:(max)
 	n s
 	i $zl(rec)-(rel-1)<3 d nextrec
@@ -334,7 +404,7 @@ tmpseg:(a,s)
 	i $zl(rec)-(rel-1)<3 d nextrec
 	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
 	i $zl(rec)-(rel-1)<l d nextrec
-	s tmpseg(a,s)=$s($l(tmpseg(a,s)):$ze(rec,rel,rel+l-1),1:"") s rel=rel+l,abs=abs+l
+	s tmpseg(a,s)=$s($zl(tmpseg(a,s)):$ze(rec,rel,rel+l-1),1:"") s rel=rel+l,abs=abs+l
 	q
 nextrec:
 	n nextrec
@@ -345,14 +415,15 @@ nextrec:
 ;----------------------------------------------------------------------------------------------------------------------------------
 
 CREATE
-	k contents,nams,regs,segs,tmpreg,tmpseg
+	k contents,nams,regs,segs,tmpreg,tmpseg,gnams
 	s update=1
 	s header=$tr($j("",SIZEOF("gd_header")-16)," ",ZERO)
 	s nams=2,(nams("*"),nams("#"))=defreg
 	s regs=1,regs(defreg,"DYNAMIC_SEGMENT")=defseg,reg="regs(defreg)"
+	s gnams=0
 	d cretmps
 	s x=""
-	f  s x=$o(tmpreg(x)) q:'$l(x)  s @reg@(x)=tmpreg(x)
+	f  s x=$o(tmpreg(x)) q:'$zl(x)  s @reg@(x)=tmpreg(x)
 	s segs=1
 	s am=tmpacc d maktseg
 	q
@@ -375,50 +446,32 @@ cretmps:
 	s tmpreg("STDNULLCOLL")=0
 	s tmpreg("SYNC_IO")=0
 	s tmpreg("YIELD_LIMIT")=8
-	;s tmpreg("STOP_ENABLED")=1
+	n tmpsegcommon
+	; First define segment characteristics that are identical to BG and MM access methods (done inside "tmpmm")
+	; Then define overrides specific to BG and MM
+	d tmpmm
+	m tmpseg("BG")=tmpsegcommon	; copy over all common templates into BG access method first
+	; now add BG specific overrides
 	s tmpseg("BG","ACCESS_METHOD")="BG"
-	s tmpseg("BG","ALLOCATION")=100
-	s tmpseg("BG","BLOCK_SIZE")=1024
-	s tmpseg("BG","BUCKET_SIZE")=""
 	s tmpseg("BG","DEFER")=""
-	s tmpseg("BG","EXTENSION_COUNT")=100
-	s tmpseg("BG","FILE_TYPE")="DYNAMIC"
 	s tmpseg("BG","GLOBAL_BUFFER_COUNT")=defglo
-	s tmpseg("BG","RESERVED_BYTES")=0
-	s tmpseg("BG","LOCK_SPACE")=40
-	s tmpseg("BG","WINDOW_SIZE")=""
-	s tmpseg("BG","ENCRYPTION_FLAG")=0
-	d tmpmm
-	s tmpseg("USER","ACCESS_METHOD")="USER"
-	s tmpseg("USER","ALLOCATION")=""
-	s tmpseg("USER","BLOCK_SIZE")=""
-	s tmpseg("USER","BUCKET_SIZE")=""
-	s tmpseg("USER","DEFER")=""
-	s tmpseg("USER","EXTENSION_COUNT")=""
-	s tmpseg("USER","FILE_TYPE")="DYNAMIC"
-	s tmpseg("USER","GLOBAL_BUFFER_COUNT")=""
-	s tmpseg("USER","RESERVED_BYTES")=0
-	s tmpseg("USER","LOCK_SPACE")=""
-	s tmpseg("USER","WINDOW_SIZE")=""
-	s tmpseg("USER","ENCRYPTION_FLAG")=0
-	s tmpacc="BG"
+	s tmpacc="BG"	; set default access method to BG
 	q
-tmpmm:	s tmpseg("MM","ACCESS_METHOD")="MM"
-	s tmpseg("MM","ALLOCATION")=100
-	s tmpseg("MM","BLOCK_SIZE")=1024
-	s tmpseg("MM","BUCKET_SIZE")=""
+tmpmm:	;
+	d tmpsegcommon
+	m tmpseg("MM")=tmpsegcommon	; copy over all common stuff into MM access method first
+	; now add MM specific overrides
+	s tmpseg("MM","ACCESS_METHOD")="MM"
 	s tmpseg("MM","DEFER")=1
-	s tmpseg("MM","EXTENSION_COUNT")=100
-	s tmpseg("MM","FILE_TYPE")="DYNAMIC"
 	s tmpseg("MM","GLOBAL_BUFFER_COUNT")=1024
-	s tmpseg("MM","RESERVED_BYTES")=0
-	s tmpseg("MM","LOCK_SPACE")=40
-	s tmpseg("MM","WINDOW_SIZE")=""
-	s tmpseg("MM","ENCRYPTION_FLAG")=0
 	q
-maktseg:	s segs(defseg,"FILE_NAME")=defdb
+tmpsegcommon:
+	m tmpsegcommon=defseg
+	q
+	;
+maktseg: s segs(defseg,"FILE_NAME")=defdb
 	s seg="segs(defseg)",x=""
-	f  s x=$o(tmpseg(am,x)) q:'$l(x)  s @seg@(x)=tmpseg(am,x)
+	f  s x=$o(tmpseg(am,x)) q:'$zl(x)  s @seg@(x)=tmpseg(am,x)
 	q
 v44init:
 	s SIZEOF("am_offset")=308
@@ -571,3 +624,31 @@ v550init:
 	s MAXNAMLN=SIZEOF("mident")-1,MAXREGLN=32,MAXSEGLN=32	; maximum name length allowed is 31 characters
 	s PARNAMLN=31,PARREGLN=31,PARSEGLN=31
 	q
+v600init:
+	i (olabel="GTCGBDUNX008") d
+	. s SIZEOF("am_offset")=324
+	. s SIZEOF("file_spec")=256
+	. s SIZEOF("gd_header")=16
+	. s SIZEOF("gd_contents")=44
+	. s SIZEOF("gd_map")=36
+	. s SIZEOF("gd_region")=356
+	. s SIZEOF("gd_region_padding")=0
+	. s SIZEOF("gd_segment")=340
+	e  d
+	. s SIZEOF("am_offset")=332
+	. s SIZEOF("file_spec")=256
+	. s SIZEOF("gd_header")=16
+	. s SIZEOF("gd_contents")=80
+	. s SIZEOF("gd_map")=40
+	. s SIZEOF("gd_region")=368
+	. s SIZEOF("gd_region_padding")=4
+	. s SIZEOF("gd_segment")=360
+	s SIZEOF("mident")=32
+	s SIZEOF("blk_hdr")=16
+	s SIZEOF("rec_hdr")=4
+	s SIZEOF("dsk_blk")=512
+	s SIZEOF("max_str")=1048576
+	s SIZEOF("reg_jnl_deq")=4
+	s MAXNAMLN=SIZEOF("mident")-1,MAXREGLN=32,MAXSEGLN=32	; maximum name length allowed is 31 characters
+	s PARNAMLN=31,PARREGLN=31,PARSEGLN=31
+	q
diff --git a/sr_unix/gdeoget.m b/sr_unix/gdeoget.m
deleted file mode 100644
index cdc95c8..0000000
--- a/sr_unix/gdeoget.m
+++ /dev/null
@@ -1,436 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;								;
-;	Copyright 2006 Fidelity Information Services, Inc	;
-;								;
-;	This source code contains the intellectual property	;
-;	of its copyright holder(s), and is made available	;
-;	under a license.  If you do not know the terms of	;
-;	the license, please stop and do not read further.	;
-;								;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-gdeget:	;read in an existing GD or create a default
-CONVERT	n accmeth,hdrlab,MAXSEGLN,MAXREGLN,SIZEOF,RMS,csegs,cregs,contents d gdeinit
-	;s label=$e(rec,1,12)
-	s (v23,v24,v25)=0 										; to allow autoconvert
-	i label="GTCGBLDIR001" s label=hdrlab,(v23,v24)=1,update=1					; to allow autoconvert
-	i label="GTCGBLDIR002" s label=hdrlab,v24=1,update=1						; to allow autoconvert
-	i label="GTCGBLDIR003" s label=hdrlab,v25=1,update=1						; to allow autoconvert
-	i label'=hdrlab zm gdeerr("GDUNKNFMT"):file,gdeerr("INPINTEG")
-	s filesize=$$bin2num($ze(rec,13,16))
-	s header=$ze(rec,17,SIZEOF("gd_header")),abs=abs+SIZEOF("gd_header")
-; contents
-	i $ze(rec,abs,abs+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; filler
-	s abs=abs+4
-	s contents("maxrecsize")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("mapcnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("maps")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("regioncnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("regions")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("segmentcnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("segments")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("gdscnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("gdsfiledata")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("rmscnt")=$$bin2num($ze(rec,abs,abs+1)),abs=abs+2
-	s contents("rmsfiledata")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s contents("end")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
-	s abs=abs+22
-	i contents("regioncnt")'=contents("segmentcnt") zm gdeerr("INPINTEG")
-	i contents("regioncnt")-1>contents("mapcnt") zm gdeerr("INPINTEG")
-; verify offsets
-	i abs'=(SIZEOF("gd_header")+SIZEOF("gd_contents")+1) zm gdeerr("INPINTEG")
-	s x=contents("maps")
-	i x+1'=(abs-SIZEOF("gd_header")) zm gdeerr("INPINTEG")
-	s x=x+(contents("mapcnt")*SIZEOF("gd_map"))
-	i x'=contents("regions") zm gdeerr("INPINTEG")
-	s x=x+(contents("regioncnt")*SIZEOF("gd_region"))
-	i x'=contents("segments") zm gdeerr("INPINTEG")
-	s x=x+(contents("segmentcnt")*SIZEOF("gd_segment"))
-	i x'=contents("gdsfiledata") zm gdeerr("INPINTEG")
-	s x=x+(contents("gdscnt")*SIZEOF("gds_filedata"))
-	i x'=contents("rmsfiledata") zm gdeerr("INPINTEG")
-	s x=x+(contents("rmscnt")*SIZEOF("rms_filedata"))
-	i x'=contents("end") zm gdeerr("INPINTEG")
-	s rel=abs
-; maps - verify that mapped regions and regions are 1-to-1
-	k reglist
-	f i=1:1:contents("mapcnt") d map
-	s s=""
-	f i=1:1:contents("regioncnt") s s=$o(reglist(s))
-	i $l($o(reglist(s))) zm gdeerr("INPINTEG")
-; regions
-	k cregs,xregs s cregs=0
-	f i=1:1:contents("regioncnt") d region
-	i cregs'=contents("regioncnt") zm gdeerr("INPINTEG")
-; segments
-	k csegs,xsegs s csegs=0
-	f i=1:1:contents("segmentcnt") d segment
-	i csegs'=contents("segmentcnt") zm gdeerr("INPINTEG")
-; gdsfiledata
-	f i=1:1:contents("gdscnt") d fabdata(SIZEOF("gds_filedata"),0)
-; rmsfiledata
-	f i=1:1:contents("rmscnt") d fabdata(SIZEOF("rms_filedata"),SIZEOF("struct RAB"))
-; names
-	k nams s nams=0
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s nams=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	f i=1:1:nams d name
-; regions
-	k regs s regs=0
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s regs=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i regs<contents("regioncnt") zm gdeerr("INPINTEG")
-	f i=1:1:regs d gdereg
-; template access method
-	s tmpacc=$$gderead(4)
-	i accmeth'[("\"_tmpacc) zm gdeerr("INPINTEG")
-; segments
-	k segs s segs=0
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s segs=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i segs<contents("segmentcnt") zm gdeerr("INPINTEG")
-	f i=1:1:segs d gdeseg
-; templates
-	;k tmpreg,tmpseg
-	f s="ALLOCATION","BEFORE_IMAGE","BUFFER_SIZE","EXTENSION","FILE_NAME" d tmpreg(s)
-	i v24 d tmpreg(s) s tmpreg("ALLOCATION")=100,tmpreg("BEFORE_IMAGE")=1			; to allow autoconvert
-	i v24 s tmpreg("BUFFER_SIZE")=128,tmpreg("EXTENSION")=100,tmpreg("FILE_NAME")=""	; to allow autoconvert
-	;											; ,tmpreg("STOP_ENABLE")=0
-	f s="JOURNAL","KEY_SIZE","LOCK_WRITE","NULL_SUBSCRIPTS","RECORD_SIZE" d tmpreg(s) 	;,"STOP_ENABLE"
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE" d tmpseg("BG",s)
-	f s="EXTENSION_COUNT","FILE_TYPE","GLOBAL_BUFFER_COUNT" d tmpseg("BG",s)
-	i v23 s tmpseg("BG","LOCK_SPACE")=20							; to allow autoconvert
-	e  s s="LOCK_SPACE" d tmpseg("BG",s)							; remove else
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","DEFER","EXTENSION_COUNT","FILE_TYPE" d tmpseg("MM",s)
-	i v23 s tmpseg("MM","LOCK_SPACE")=20							; to allow autoconvert
-	e  s s="LOCK_SPACE" d tmpseg("MM",s)							; remove else
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","BUCKET_SIZE","EXTENSION_COUNT" d tmpseg("RMS",s)
-	f s="FILE_TYPE","GLOBAL_BUFFER_COUNT","WINDOW_SIZE" d tmpseg("RMS",s)
-	i v25 s tmpseg("USER","ACCESS_METHOD")="USER",tmpseg("USER","FILE_TYPE")="DYNAMIC"	; to allow autoconvert
-	e  f s="ACCESS_METHOD","FILE_TYPE" d tmpseg("USER",s)					; remove else
-; resolve
-	s s=""
-	f  s s=$o(cregs(s)) q:'$l(s)  i '$d(regs(s)) zm gdeerr("INPINTEG")
-	f  s s=$o(csegs(s)) q:'$l(s)  i '$d(segs(s)) zm gdeerr("INPINTEG")
-	f  s s=$o(cregs(s)) q:'$l(s)  i '$d(xsegs(cregs(s,"DYNAMIC_SEGMENT"))) zm gdeerr("INPINTEG")
-	f  s s=$o(regs(s)) q:'$l(s)  i '$d(segs(regs(s,"DYNAMIC_SEGMENT"))) zm gdeerr("INPINTEG")
-	c file
-	d tmpres
-	f  s s=$o(regs(s)) q:'$l(s)  k regs(s,"LOCK_WRITE") d regres f x=$o(regs(s,x)) q:'$l(x)  d
-	. s:$d(minreg(x))&(regs(s,x)<minreg(x)) regs(s,x)=minreg(x)
-	. s:$d(maxreg(x))&(regs(s,x)>maxreg(x)) regs(s,x)=maxreg(x)
-	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD"),x="" s:am="RMS" am="BG" d
-	. d segres f  s x=$o(segs(s,am,x)) q:x=""  s segs(s,x)=segs(s,am,x) k segs(s,am,x) d
-	. . s:$d(minseg(am,x))&(segs(s,x)<minseg(am,x)) segs(s,x)=minseg(am,x)
-	. . s:$d(maxseg(am,x))&(segs(s,x)>maxseg(am,x)) segs(s,x)=maxseg(am,x)
-	. f i=1:1:$l(accmeth,"\") s x=$p(accmeth,"\",i) i am'=x k segs(s,x)
-	k minseg("RMS"),maxseg("RMS"),tmpseg("RMS")
-	i tmpacc="RMS" s tmpacc="BG"
-	q
-
-tmpres:	k tmpreg("LOCK_WRITE")
-	s x="" s x=$o(tmpreg(x)) q:x=""  d
-	. s:$d(minreg(x))&(tmpreg(x)<minreg(x)) tmpreg(x)=minreg(x)
-	. s:$d(maxreg(x))&(tmpreg(x)>maxreg(x)) tmpreg(x)=maxreg(x)
-	s am="" f  s am=$o(tmpseq(am)) q:am=""  s x="" f  s x=$o(tmpseq(am,x)) q:x=""  d
-	. s:$d(minseg(am,x))&(tmpseg(am,x)<minseg(am,x)) tmpseg(am,x)=minseg(am,x)
-	. s:$d(maxseg(am,x))&(tmpseg(am,x)>maxseg(am,x)) tmpseg(am,x)=maxseg(am,x)
-	q
-
-regres:	s x="" f  s x=$o(tmpreg(x)) q:x=""  s:'$d(regs(s,x)) regs(s,x)=tmpreg(x)
-	q
-
-segres:	s x="" f  s x=$o(tmpseg(am,x)) q:x=""  s:'$d(segs(s,am,x)) segs(s,am,x)=tmpseg(am,x)
-	q
-
-; verify
-	s x=$$ALL^GDEVERIF
-	i 'x zm gdeerr("INPINTEG")
-	q
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-badfile ;file access failed
-	s:'debug $et="" s abortzs=$zs zm gdeerr("GDREADERR"):file,+abortzs
-	h
-	;
-bin2num:(bin)	; binary number -> number
-	n num,i
-	s num=0
-	f i=1:1:$zl(bin) s num=$za(bin,i)*HEX(i-1*2)+num
-	q num
-	;
-str2hex:(in)
-	n i,j,out
-	s out=""
-	f i=1:1 s j=$a(in,i) q:j=-1  f k=j\16,j#16 s out=out_$s(k<10:k,1:$c(k+55))
-	q out
-	;
-num2long:(num)
-	i num<0 zm gdeerr("INPINTEG")
-	i num'<TWO(32) zm gdeerr("INPINTEG")
-	q $c(num/TWO(24),num/TWO(16)#256,num/256#256,num#256)
-	;
-num2shrt:(num)
-	i num<0 zm gdeerr("INPINTEG")
-	i num'<TWO(16) zm gdeerr("INPINTEG")
-	q $c(num\256,num#256)
-	;
-dec2hex:(in)
-	q $$str2hex($$num2long(in))
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-map:
-	i $zl(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
-	s x=$$bin2num($ze(rec,rel+SIZEOF("mident"),rel+SIZEOF("gd_map")-1))
-	s reglist(x)="",x=x-contents("regions")
-	i x#SIZEOF("gd_region") zm gdeerr("INPINTEG")
-	i x\SIZEOF("gd_region")'<contents("regioncnt") zm gdeerr("INPINTEG")
-	s rel=rel+SIZEOF("gd_map")
-	s abs=abs+SIZEOF("gd_map")
-	q
-region:
-	i $zl(rec)-(rel-1)<SIZEOF("gd_region") d nextrec
-	s cregs=cregs+1
-	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	s s=$ze(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xregs(abs-1-SIZEOF("gd_header"))=s
-	s cregs(s,"DYNAMIC_SEGMENT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	s x=cregs(s,"DYNAMIC_SEGMENT")-contents("segments")
-	i x#SIZEOF("gd_segment") zm gdeerr("INPINTEG")
-	i x\SIZEOF("gd_segment")'<contents("segmentcnt") zm gdeerr("INPINTEG")
-	i $ze(rec,rel,rel+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; static segment
-	s rel=rel+4
-	s cregs(s,"RECORD_SIZE")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	s cregs(s,"KEY_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	i $ze(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; OPEN state
-	s rel=rel+1
-	s cregs(s,"LOCK_WRITE")=$$bin2num($ze(rec,rel)),rel=rel+1
-	s cregs(s,"NULL_SUBSCRIPTS")=$$bin2num($ze(rec,rel)),rel=rel+1
-	s cregs(s,"JOURNAL")=$$bin2num($ze(rec,rel)),rel=rel+1
-	i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")				; gbl_lk_root, lcl_lk_root
-	s rel=rel+8
-	s cregs(s,"ALLOCATION")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4					; journal options
-	s cregs(s,"EXTENSION")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	s cregs(s,"BUFFER_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	s cregs(s,"BEFORE_IMAGE")=$$bin2num($ze(rec,rel)),rel=rel+1
-	i 'v23,'v24,$ze(rec,rel,rel+10)'=$tr($j("",11)," ",ZERO) zm gdeerr("INPINTEG")			; 7 filler + 4 for jnllsb
-	s rel=rel+11
-	s l=$$bin2num($ze(rec,rel)),rel=rel+1
-	s cregs(s,"FILE_NAME")=$ze(rec,rel,rel+l-1),rel=rel+SIZEOF("jnl_filename")
-	i $ze(rec,rel,rel+46)'=$tr($j("",47)," ",ZERO) zm gdeerr("INPINTEG")				; reserved
-	s rel=rel+47
-	s abs=abs+SIZEOF("gd_region")
-	q
-segment:
-	i $zl(rec)-(rel-1)<SIZEOF("gd_segment") d nextrec
-	s csegs=csegs+1
-	s x=$$bin2num($ze(rec,rel+SIZEOF("am_offset"),rel+SIZEOF("am_offset")+3))
-	s am=$s(x=0:"RMS",x=1:"BG",x=2:"MM",x=4:"USER",1:"ERROR")
-	i am="ERROR" zm gdeerr("INPINTEG")
-	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	s s=$ze(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xsegs(abs-1-SIZEOF("gd_header"))=s
-	s (csegs(s,"ACCESS_METHOD"),csegs(s,am,"ACCESS_METHOD"))=am
-	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	s csegs(s,am,"FILE_NAME")=$ze(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
-	s x=$$bin2num($ze(rec,rel)),rel=rel+1
-	s csegs(s,am,"FILE_TYPE")=$s(x=0:"DYNAMIC",1:"ERROR")
-	i csegs(s,am,"FILE_TYPE")="ERROR" zm gdeerr("INPINTEG")
-	i "USER"=am s rel=rel+8
-	e  s csegs(s,am,"BLOCK_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	e  s csegs(s,am,"ALLOCATION")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	e  s csegs(s,am,"EXTENSION_COUNT")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
-	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
-	s rel=rel+4
-	i "BG|MM"[am s csegs(s,am,"LOCK_SPACE")=$s(v23:20,1:$$bin2num($ze(rec,rel)))		; allow autoconv
-	s rel=rel+1
-	i 'v24 i $ze(rec,rel,rel+3)'=".DAT" zm gdeerr("INPINTEG")				; if to allow autoconv
-	s rel=rel+4
-	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; filler
-	s rel=rel+4
-	s rel=rel+4									; access method already processed
-	s xfile(s)=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
-	i "MM"=am s csegs(s,am,"DEFER")=$$bin2num($ze(rec,rel+36))
-	s rel=rel+96
-	s abs=abs+SIZEOF("gd_segment")
-	q
-fabdata:(datasize,offset)
-	n fna,x,y
-	i $zl(rec)-(rel-1)<datasize d nextrec
-	s x=$ze(rec,rel+1+offset,rel+datasize-1)
-	s fna=$$bin2num($e(x,RMS("FAB$L_FNA"),RMS("FAB$L_FNA")+3))
-	s y=fna-contents("segments")
-	i y#SIZEOF("gd_segment")'=SIZEOF("fna_offset") zm gdeerr("INPINTEG")
-	i y\SIZEOF("gd_segment")'<contents("segmentcnt") zm gdeerr("INPINTEG")
-	s y=fna-SIZEOF("fna_offset")
-	i '$d(xsegs(y)) zm gdeerr("INPINTEG")
-	s s=xsegs(y)
-	i '$d(csegs(s,"ACCESS_METHOD")) zm gdeerr("INPINTEG")
-	s am=csegs(s,"ACCESS_METHOD")
-	i csegs(s,am,"ALLOCATION")'=$$bin2num($e(x,RMS("FAB$L_ALQ"),RMS("FAB$L_ALQ")+3)) zm gdeerr("INPINTEG")
-	i csegs(s,am,"EXTENSION_COUNT")'=$$bin2num($e(x,RMS("FAB$W_DEQ"),RMS("FAB$W_DEQ")+1)) zm gdeerr("INPINTEG")
-	i "RMS"=am s csegs(s,am,"WINDOW_SIZE")=$$bin2num($e(x,RMS("FAB$B_RTV")))
-	s y=$$bin2num($e(x,RMS("FAB$L_DNA"),RMS("FAB$L_DNA")+3))-contents("segments")
-	i 'v24 i y#SIZEOF("gd_segment")'=SIZEOF("dna_offset") zm gde("INPINTEG")		; if to allow autoconvert
-	i $l(csegs(s,am,"FILE_NAME"))'=$$bin2num($e(x,RMS("FAB$B_FNS"))) zm gdeerr("INPINTEG")
-	i 'v24 i $$bin2num($e(x,RMS("FAB$B_DNS")))'=4						; if to allow autoconvert
-	i csegs(s,am,"BLOCK_SIZE")'=$$bin2num($e(x,RMS("FAB$W_BLS"),RMS("FAB$W_BLS")+1)) zm gdeerr("INPINTEG")
-	i "RMS"=am s csegs(s,am,"BUCKET_SIZE")=$$bin2num($e(x,RMS("FAB$B_BKS")))
-	i "BG|RMS"[am s csegs(s,am,"GLOBAL_BUFFER_COUNT")=$$bin2num($e(x,RMS("FAB$W_GBC"),RMS("FAB$W_GBC")+1))
-	s rel=rel+datasize,abs=abs+datasize
-	q
-name:
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>SIZEOF("mident") zm gdeerr("INPINTEG")
-	i $zl(rec)-(rel-1)<l d nextrec
-	s s=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>MAXREGLN zm gdeerr("INPINTEG")
-	i $zl(rec)-(rel-1)<l d nextrec
-	s nams(s)=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-gdereg:
-	s s=$$gderead(MAXREGLN)
-	s regs(s,"DYNAMIC_SEGMENT")=$$gderead(MAXSEGLN)
-	s regs(s,"ALLOCATION")=$$gderead(10)
-	s regs(s,"EXTENSION")=$$gderead($l(maxreg("EXTENSION")))
-	s regs(s,"FILE_NAME")=$$gderead(SIZEOF("jnl_filename"))
-	s regs(s,"BUFFER_SIZE")=$$gderead(5)
-	i v24 s regs(s,"ALLOCATION")=100,regs(s,"EXTENSION")=100,regs(s,"FILE_NAME")=""		; to allow autoconvert
-	i  s regs(s,"BUFFER_SIZE")=128,regs(s,"BEFORE_IMAGE")=1	;,regs(s,"STOP_ENABLE")=0	; to allow autoconvert
-	i  s x=$$gderead(5),x=$$gderead(5)							; to allow autoconvert
-	e  s regs(s,"BEFORE_IMAGE")=$$gderead(1) ;s regs(s,""STOP_ENABLE")=$$gderead(1)		; remove else
-	s regs(s,"JOURNAL")=$$gderead(1)
-	s regs(s,"KEY_SIZE")=$$gderead(5)
-	s regs(s,"LOCK_WRITE")=$$gderead(1)
-	s regs(s,"NULL_SUBSCRIPTS")=$$gderead(1)
-	s regs(s,"RECORD_SIZE")=$$gderead(5)
-	q
-gdeseg:
-	s s=$$gderead(MAXSEGLN)
-	s segs(s,"ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"BG","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"BG","ALLOCATION")=$$gderead(10)
-	s segs(s,"BG","BLOCK_SIZE")=$$gderead($l(maxseg("BG","BLOCK_SIZE")))
-	s segs(s,"BG","EXTENSION_COUNT")=$$gderead($l(maxseg("BG","EXTENSION_COUNT")))
-	s segs(s,"BG","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"BG","FILE_TYPE")=$$gderead(7)
-	s segs(s,"BG","GLOBAL_BUFFER_COUNT")=$$gderead(5)
-	s segs(s,"BG","LOCK_SPACE")=$s(v23:20,1:$$gderead(3))				; to allow autoconvert
-	s segs(s,"MM","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"MM","ALLOCATION")=$$gderead(10)
-	s segs(s,"MM","BLOCK_SIZE")=$$gderead($l(maxseg("MM","BLOCK_SIZE")))
-	s segs(s,"MM","DEFER")=$$gderead(1)
-	s segs(s,"MM","EXTENSION_COUNT")=$$gderead($l(maxseg("MM","EXTENSION_COUNT")))
-	s segs(s,"MM","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"MM","FILE_TYPE")=$$gderead(7)
-	s segs(s,"MM","LOCK_SPACE")=$s(v23:20,1:$$gderead(3))				; to allow autoconvert
-	s segs(s,"RMS","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"RMS","ALLOCATION")=$$gderead(10)
-	s segs(s,"RMS","BLOCK_SIZE")=$$gderead(5)
-	s segs(s,"RMS","BUCKET_SIZE")=$$gderead(5)
-	s segs(s,"RMS","EXTENSION_COUNT")=$$gderead($l(maxseg("RMS","EXTENSION_COUNT")))
-	s segs(s,"RMS","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"RMS","FILE_TYPE")=$$gderead(7)
-	s segs(s,"RMS","GLOBAL_BUFFER_COUNT")=$$gderead(5)
-	s segs(s,"RMS","WINDOW_SIZE")=$$gderead(5)
-	s segs(s,"USER","ACCESS_METHOD")=$s(v25:"USER",1:$$gderead(4))				; to allow autoconvert
-	s segs(s,"USER","FILE_NAME")=$s(v25:"MUMPS",1:$$gderead(SIZEOF("file_spec")))		; to allow autoconvert
-	s segs(s,"USER","FILE_TYPE")=$s(v25:"DYNAMIC",1:$$gderead(7))				; to allow autoconvert
-	q
-gderead:(max)
-	n s
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>max zm gdeerr("INPINTEG")
-	i $zl(rec)-(rel-1)<l d nextrec
-	s s=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q s
-	;
-tmpreg:(s)
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $zl(rec)-(rel-1)<l d nextrec
-	s tmpreg(s)=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-tmpseg:(a,s)
-	i $zl(rec)-(rel-1)<3 d nextrec
-	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $zl(rec)-(rel-1)<l d nextrec
-	s tmpseg(a,s)=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-nextrec:
-	n nextrec
-	u file r nextrec
-	i debug u @useio
-	s rec=$ze(rec,rel,$zl(rec))_nextrec,rel=1
-	q
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-gdeinit:
-	s accmeth="\BG\MM\RMS\USER"
-	s hdrlab="GTCGBLDIR004"
-	s SIZEOF("am_offset")=296
-	s SIZEOF("blk_hdr")=7
-	s SIZEOF("dna_offset")=288
-	s SIZEOF("file_spec")=255
-	s SIZEOF("fna_offset")=19
-	s SIZEOF("gd_header")=288
-	s SIZEOF("gd_contents")=64
-	s SIZEOF("gd_map")=12
-	s SIZEOF("gd_region")=160
-	s SIZEOF("gd_segment")=400
-	s SIZEOF("gds_filedata")=80
-	s SIZEOF("jnl_filename")=49
-	s SIZEOF("mident")=8
-	s SIZEOF("rec_hdr")=3
-	s SIZEOF("dsk_blk")=512
-	s SIZEOF("rms_filedata")=224
-	s SIZEOF("struct FAB")=80,SIZEOF("struct RAB")=68
-;
-	s MAXNAMLN=SIZEOF("mident"),MAXREGLN=15,MAXSEGLN=15
-;define offsets into rms structures
-	;fab
-	;s RMS("FAB$B_BID")=0
-	s RMS("FAB$B_BLN")=1
-	;s RMS("FAB$W_IFI")=2
-	s RMS("FAB$L_FOP")=4
-	;s RMS("FAB$L_STS")=8
-	s RMS("FAB$L_STV")=12
-	s RMS("FAB$L_ALQ")=16
-	s RMS("FAB$W_DEQ")=20
-	s RMS("FAB$B_FAC")=22
-	;s RMS("FAB$B_SHR")=23
-	;s RMS("FAB$L_CTX")=24
-	s RMS("FAB$B_RTV")=28
-	;s RMS("FAB$B_ORG")=29
-	;s RMS("FAB$B_RAT")=30
-	;s RMS("FAB$B_RFM")=31
-	;s RMS("FAB$L_JNL")=32
-	s RMS("FAB$L_XAB")=36
-	;s RMS("FAB$L_NAM")=40
-	s RMS("FAB$L_FNA")=44
-	s RMS("FAB$L_DNA")=48
-	s RMS("FAB$B_FNS")=52
-	s RMS("FAB$B_DNS")=53
-	;s RMS("FAB$W_MRS")=54
-	;s RMS("FAB$L_MRN")=56
-	s RMS("FAB$W_BLS")=60
-	s RMS("FAB$B_BKS")=62
-	s RMS("FAB$B_FSZ")=63
-	;s RMS("FAB$L_DEV")=64
-	;s RMS("FAB$L_SDC")=68
-	s RMS("FAB$W_GBC")=72
-	;s RMS("FAB$B_ACMODES")=74
-	;s RMS("FAB$B_RCF")=75
-	;rab
-	s RMS("RAB$L_FAB")=60
-	s RMS("RAB$L_XAB")=64
-; rms
-	s minseg("RMS","ALLOCATION")=10,minseg("RMS","BLOCK_SIZE")=SIZEOF("dsk_blk"),minseg("RMS","BUCKET_SIZE")=0
-	s minseg("RMS","EXTENSION_COUNT")=0,minseg("RMS","GLOBAL_BUFFER_COUNT")=0,minseg("RMS","WINDOW_SIZE")=0
-	s maxseg("RMS","ALLOCATION")=TWO(24),maxseg("RMS","BLOCK_SIZE")=HEX(4)-SIZEOF("dsk_blk"),maxseg("RMS","BUCKET_SIZE")=63
-	s maxseg("RMS","EXTENSION_COUNT")=HEX(4)-1,maxseg("RMS","GLOBAL_BUFFER_COUNT")=32767,maxseg("RMS","WINDOW_SIZE")=255
-	q
diff --git a/sr_unix/gdeput.m b/sr_unix/gdeput.m
index 92c0af4..e63de4e 100644
--- a/sr_unix/gdeput.m
+++ b/sr_unix/gdeput.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,44 +10,55 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gdeput:	;output the result of the session to the global directory file
 GDEPUT()
-	n rec,gds,cregs,csegs,cregcnt,csegcnt,maxrecsize,mapcnt,map
-	d PUTMAKE^GDEMAP
-	s s="",gdeputzs=""
-	f mapcnt=0:1 s s=$o(map(s)) q:'$zl(s)  s cregs(map(s))=""
+	n rec,gds,cregs,csegs,cregcnt,csegcnt,maxrecsize,mapcnt,map,hasSpanGbls,isSpanned,curMapSpanning,prevMapSpanning
+	n varmapslen,vargblnamelen,tmplen,ptrsize,varmapoff,gnamcnt,gblnamelen,filler16byte,filler12byte
+	d CREATEGLDMAP^GDEMAP
+	s ptrsize=$s((gtm64=TRUE):8,1:4)
+	s s="",gdeputzs="",varmapslen=0,mapcnt=0,hasSpanGbls=0
+	f  s s=$o(map(s)),tmplen=$zl(s) q:'tmplen  d
+	. s cregs(map(s))=""
+	. s varmapslen=(varmapslen+tmplen+2) ; varmapslen needs to account 2 null terminating bytes
+	. s varmapslen($incr(mapcnt))=tmplen
+	. s gblnamelen=$zf(s,ZERO)
+	. i gblnamelen'=0 s hasSpanGbls=1
+	. s gblnamelen=$s(gblnamelen=0:tmplen,1:gblnamelen-2)
+	. s vargblnamelen(mapcnt)=gblnamelen
+	s varmapslen=(varmapslen+ptrsize-1)\ptrsize*ptrsize	; do 8-byte or 4-byte rounding up as appropriate
 	s maxrecsize=0
 	f cregcnt=0:1 s s=$o(cregs(s)) q:'$l(s)  d
 	. s csegs(regs(s,"DYNAMIC_SEGMENT"))=s i maxrecsize<regs(s,"RECORD_SIZE") s maxrecsize=regs(s,"RECORD_SIZE")
+	. s isSpanned(s)=0
 	f csegcnt=0:1 s s=$o(csegs(s)) q:'$l(s)  d fdatum
 	i cregcnt'=csegcnt d error1
-	s x=SIZEOF("gd_contents")+(mapcnt*SIZEOF("gd_map")),s=""
+	s x=SIZEOF("gd_contents")+(mapcnt*SIZEOF("gd_map"))+varmapslen,s=""
 	f i=0:1 s s=$o(cregs(s)) q:'$l(s)  s cregs(s,"offset")=i*SIZEOF("gd_region")+x
 	s x=x+(cregcnt*SIZEOF("gd_region"))
 	f i=0:1 s s=$o(csegs(s)) q:'$l(s)  s csegs(s,"offset")=i*SIZEOF("gd_segment")+x
 	s x=x+(csegcnt*SIZEOF("gd_segment"))
+	s gnamcnt=gnams
 	s rec=""
+	s $p(filler12byte,ZERO,12)=ZERO
+	s $p(filler16byte,ZERO,16)=ZERO
 ; contents
-	i (gtm64=TRUE) s rec=rec_$c(0,0,0,0,0,0,0,0)				       		; not used
-	e  s rec=rec_$c(0,0,0,0)								; not used
-	s rec=rec_$$num2bin(4,maxrecsize)							; max rec size
+	s rec=rec_$tr($j("",ptrsize)," ",ZERO)			; not used (gd_addr.local_locks)
+	s rec=rec_$$num2bin(4,maxrecsize)			; max rec size
 	s filesize=SIZEOF("gd_contents")
-	s rec=rec_$$num2bin(2,mapcnt)_$$num2bin(2,cregcnt)_$$num2bin(2,csegcnt)_$$num2bin(2,0)	; maps,regs,segs,filler
-	i (gtm64=TRUE) d
-	. s rec=rec_$$num2bin(4,0) 								; padding
-	. s rec=rec_$$num2bin(8,filesize)							; mapptr
-	e  s rec=rec_$$num2bin(4,filesize)							; mapptr
-	s filesize=filesize+(mapcnt*SIZEOF("gd_map"))
-	i (gtm64=TRUE) s rec=rec_$$num2bin(8,filesize)						; regionptr
-	e  s rec=rec_$$num2bin(4,filesize)							; regionptr
+	s rec=rec_$$num2bin(4,mapcnt)_$$num2bin(4,cregcnt)	; maps,regs
+	s rec=rec_$$num2bin(4,csegcnt)_$$num2bin(4,gnamcnt) 	; segs,gblnames
+	s rec=rec_$$num2bin(4,varmapslen)			; varmapslen
+	s rec=rec_$$num2bin(ptrsize,filesize)			; mapptr
+	s varmapoff=filesize+(mapcnt*SIZEOF("gd_map"))     	; offset of variable length map section
+	s filesize=varmapoff+varmapslen
+	s rec=rec_$$num2bin(ptrsize,filesize)			; regionptr
 	s filesize=filesize+(cregcnt*SIZEOF("gd_region"))
-	i (gtm64=TRUE) s rec=rec_$$num2bin(8,filesize)					; segmentptr
-	e  s rec=rec_$$num2bin(4,filesize)							; segmentptr
-	s filesize=filesize+(csegcnt*SIZEOF("gd_segment")),base=filesize
-	i (gtm64=TRUE) d
-	. s rec=rec_$tr($j("",24)," ",ZERO)							; reserved
-	. s rec=rec_$$num2bin(8,filesize)							; end
-	e  d
-	. s rec=rec_$tr($j("",12)," ",ZERO)							; reserved
-	. s rec=rec_$$num2bin(4,filesize)							; end
+	s rec=rec_$$num2bin(ptrsize,filesize)			; segmentptr
+	s filesize=filesize+(csegcnt*SIZEOF("gd_segment"))
+	s rec=rec_$$num2bin(ptrsize,filesize)			; gblnameptr
+	s filesize=filesize+(gnamcnt*SIZEOF("gd_gblname"))
+	s rec=rec_$tr($j("",(3*ptrsize))," ",ZERO)		; reserved
+	s rec=rec_$$num2bin(ptrsize,filesize)			; end
+	s rec=rec_$$num2bin(4,hasSpanGbls)			; has_span_gbls
+	s rec=rec_filler12byte					; for runtime filler
 	s rec=hdrlab_$$num2bin(4,$l(hdrlab)+4+filesize)_rec
 	i create zm gdeerr("GDCREATE"):file
 	e  s:$ZVersion["VMS" $p(file,";",2)=$p(file,";",2)+1  zm gdeerr("GDUPDATE"):file
@@ -59,12 +70,21 @@ GDEPUT()
 	s chset=$SELECT($ZV["OS390":"BINARY",$ZV["VMS":"",$ZCHSET="UTF-8":"M",1:"")
 	o tempfile:(rewind:noreadonly:newversion:recordsize=512:fixed:blocksize=512:exception=gdexcept:ochset=chset)
 ; maps
+	s s="",curMapSpanning=0,prevMapSpanning=0
+	f i=1:1 s s=$o(map(s)) q:'$zl(s)  d mapfixed(i,s)
 	s s=""
-	f  s s=$o(map(s)) q:'$zl(s)  d map
+	f i=1:1 s s=$o(map(s)) q:'$zl(s)  d mapvariable(i,s)
+	; write padding if not 8-byte (on 64-bit) or 4-byte (on 32-bit platform) aligned after variable maps section
+	s tmplen=varmapoff#ptrsize
+	i tmplen d
+	. s tmplen=ptrsize-tmplen
+	. s rec=rec_$tr($j("",tmplen)," ",ZERO)
 ; cregs
 	f  s s=$o(cregs(s)) q:'$l(s)  d cregion
 ; csegs
 	f  s s=$o(csegs(s)) q:'$l(s)  d csegment
+; cgnams
+	f  s s=$o(gnams(s)) q:'$l(s)  d cgblname(s)
 ; template access method
 	i accmeth'[("\"_tmpacc) d error1
 	s rec=rec_$tr($j($l(tmpacc),3)," ",0)
@@ -74,7 +94,7 @@ GDEPUT()
 	f i=2:1:$l(accmeth,"\") s am=$p(accmeth,"\",i) s s="" d
 	. f  s s=$o(tmpseg(am,s)) q:'$l(s)  s rec=rec_$tr($j($l(tmpseg(am,s)),3)," ",0),rec=rec_tmpseg(am,s)
 	u tempfile
-	f  s record=$ze(rec,1,512),rec=$ze(rec,513,9999) q:'$zl(record)  w record,!
+	f  s record=$ze(rec,1,512),rec=$ze(rec,513,MAXSTRLEN) q:'$zl(record)  w record,!
 	u @useio
 	i $ZV'["VMS" o file:chset="M" c file:delete
 	c tempfile:rename=file
@@ -87,11 +107,26 @@ fdatum:
 	s filetype=$s((x="BG")!(x="MM"):"GDS",x="USER":"USER",1:"ERROR")
 	i filetype="ERROR" d error1
 	q
-map:
+mapfixed:(i,key)
+	n tmpmaplen,tmpnamelen,reg
 	d writerec
-	i $zl(s)'=SIZEOF("mident") d error1
-	i (gtm64=TRUE) s rec=rec_s_$$num2bin(4,cregs(map(s),"offset"))_$$num2bin(4,0) ; add padding
-	e  s rec=rec_s_$$num2bin(4,cregs(map(s),"offset"))
+	s tmpmaplen=varmapslen(i)
+	s rec=rec_$$num2bin(4,varmapoff)		; gvkey.offset
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0) 	; add padding
+	s reg=map(key)
+	s rec=rec_$$num2bin(4,cregs(reg,"offset"))	; reg.offset
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0)		; add padding
+	s tmpnamelen=vargblnamelen(i)
+	s rec=rec_$$num2bin(4,tmpnamelen)		; gvname_len
+	s rec=rec_$$num2bin(4,tmpmaplen+1)		; gvkey_len
+	s varmapoff=varmapoff+tmpmaplen+2
+	s curMapSpanning=(tmpnamelen'=tmpmaplen)
+	i (curMapSpanning!prevMapSpanning) s isSpanned(reg)=1
+	s prevMapSpanning=curMapSpanning
+	q
+mapvariable:(i,key)
+	d writerec
+	s rec=rec_key_ZERO_ZERO
 	q
 cregion:
 	d writerec
@@ -99,14 +134,11 @@ cregion:
 	s rec=rec_s_$tr($j("",MAXREGLN-$l(s))," ",ZERO)
 	s rec=rec_$$num2bin(2,regs(s,"KEY_SIZE"))
 	s rec=rec_$$num2bin(4,regs(s,"RECORD_SIZE"))
-	i (gtm64=TRUE) d
-	. s rec=rec_$$num2bin(4,csegs(regs(s,"DYNAMIC_SEGMENT"),"offset"))_$$num2bin(4,0) ; padding
-	. s rec=rec_$$num2bin(8,0)
-	e  d
-	. s rec=rec_$$num2bin(4,csegs(regs(s,"DYNAMIC_SEGMENT"),"offset"))
-	. s rec=rec_$$num2bin(4,0)
-	s rec=rec_ZERO										; OPEN state
-	s rec=rec_ZERO										; LOCK_WRITE
+	s rec=rec_$$num2bin(4,csegs(regs(s,"DYNAMIC_SEGMENT"),"offset"))
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0) ; padding
+	s rec=rec_$$num2bin(ptrsize,0)
+	s rec=rec_ZERO						; OPEN state
+	s rec=rec_ZERO						; LOCK_WRITE
 	s rec=rec_$c(regs(s,"NULL_SUBSCRIPTS"))
 	s rec=rec_$c(regs(s,"JOURNAL"))
 	s rec=rec_$$num2bin(4,regs(s,"ALLOCATION"))
@@ -125,8 +157,10 @@ cregion:
 	i $ZVersion'["VMS" s rec=rec_$$num2bin(1,regs(s,"QDBRUNDOWN"))
 	s rec=rec_$$num2bin(1,$zl(regs(s,"FILE_NAME")))
 	s rec=rec_regs(s,"FILE_NAME")_$tr($j("",SIZEOF("file_spec")-$zl(regs(s,"FILE_NAME")))," ",ZERO)
-	s rec=rec_$tr($j("",SIZEOF("gd_region_padding"))," ",ZERO)				; padding
 	s rec=rec_$tr($j("",8)," ",ZERO)							; reserved
+	s rec=rec_$$num2bin(4,isSpanned(s))							; is_spanned
+	s rec=rec_filler12byte									; runtime filler
+	s rec=rec_$tr($j("",SIZEOF("gd_region_padding"))," ",ZERO)				; padding
 	q
 csegment:
 	d writerec
@@ -149,27 +183,36 @@ csegment:
 	s rec=rec_$$num2bin(4,segs(s,"LOCK_SPACE"))
 	s rec=rec_$$num2bin(4,segs(s,"GLOBAL_BUFFER_COUNT"))
 	s rec=rec_$$num2bin(4,segs(s,"RESERVED_BYTES"))
+	s rec=rec_$$num2bin(4,segs(s,"MUTEX_SLOTS"))
 	s x=$s(am="BG":1,am="MM":2,am="USER":4,1:-1)
 	i x=-1 d error1
 	s rec=rec_$$num2bin(4,x)
-	i (gtm64=TRUE) d
-	. s rec=rec_$$num2bin(8,0)		; file_cntl ptr
-	. s rec=rec_$$num2bin(8,0)		; repl_list ptr
-	e  d
-	. s rec=rec_$$num2bin(4,0)		; file_cntl ptr
-	. s rec=rec_$$num2bin(4,0)		; repl_list ptr
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0) ; 4-byte filler
+	s rec=rec_$$num2bin(ptrsize,0)		; file_cntl ptr
+	s rec=rec_$$num2bin(ptrsize,0)		; repl_list ptr
 	; Only for platforms that support encryption, we write this value. Others it will
 	; always be 0 (ie encryption is off)
 	i (encsupportedplat=TRUE) s rec=rec_$$num2bin(4,segs(s,"ENCRYPTION_FLAG"))
 	e  s rec=rec_$$num2bin(4,0)
+	s rec=rec_filler16byte			; runtime filler
 	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0)
 	q
+cgblname:(s)
+	n len,coll,ver
+	d writerec
+	s len=$zl(s)
+	s rec=rec_s_$tr($j("",SIZEOF("mident")-len)," ",ZERO)
+	s coll=gnams(s,"COLLATION")
+	s rec=rec_$$num2bin(4,coll)
+	s ver=$view("YCOLLATE",coll)
+	s rec=rec_$$num2bin(4,ver)
+	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
 
 num2bin:(l,n)
 	i (gtm64=TRUE) q $s(l=1:$$num2tiny(+n),l=2:$$num2shrt(+n),l=4:$$num2int(+n),l=8:$$num2long(+n),1:$$num2error)
-	e  q $s(l=1:$$num2tiny(+n),l=2:$$num2shrt(+n),l=4:$$num2int(+n),1:$$num2error)
+	q $s(l=1:$$num2tiny(+n),l=2:$$num2shrt(+n),l=4:$$num2int(+n),1:$$num2error)
 	;
 num2tiny:(num)
 	i (num<0)!(num'<256) d error1
@@ -178,19 +221,19 @@ num2tiny:(num)
 num2shrt:(num)
 	i (num<0)!(num'<TWO(16)) d error1
 	i endian=TRUE q $zch(num\256,num#256)
-	e  q $zch(num#256,num\256)
+	q $zch(num#256,num\256)
 	;
 num2int:(num)
 	i (num<0)!(num'<TWO(32)) d error1
 	i endian=TRUE q $zch(num\TWO(24),num\TWO(16)#256,num\TWO(8)#256,num#256)
-	e  q $zch(num#256,num\TWO(8)#256,num\TWO(16)#256,num\TWO(24))
+	q $zch(num#256,num\TWO(8)#256,num\TWO(16)#256,num\TWO(24))
 	;
 num2long:(num)
 	n t8,t16,t24,t32,t40,t48,t56
 	s t8=TWO(8),t16=TWO(16),t24=TWO(24),t32=TWO(32),t40=TWO(40),t48=TWO(48),t56=TWO(56)
 	i (num<0)!(num'<TWO(64)) d error1
 	i endian=TRUE q $zch(num\t56,num\t48#256,num\t40#256,num\t32#256,num\t24#256,num\t16#256,num\t8#256,num#256)
-	e  q $zch(num#256,num\t8#256,num\t16#256,num\t24#256,num\t32#256,num\t40#256,num\t48#256,num\t56)
+	q $zch(num#256,num\t8#256,num\t16#256,num\t24#256,num\t32#256,num\t40#256,num\t48#256,num\t56)
 	;
 num2error:()
 	d error1
@@ -207,8 +250,12 @@ error1:
 	zm $$fatal(gdeerr("VERIFY")):"FAILED"
 	;
 writerec:
-	i $zl(rec)<512 q
-	s record=$ze(rec,1,512),rec=$ze(rec,513,9999)
+	n len
+	s len=$zl(rec)
+	i len<512 q
+	s len=len\512*512
+	s record=$ze(rec,1,len),rec=$ze(rec,len+1,MAXSTRLEN)
+	; At this point, "rec" is guaranteed to be less than 512 bytes.
 	u tempfile w record,! u @useio
 	q
 	;
diff --git a/sr_unix/gdeverif.m b/sr_unix/gdeverif.m
index ccc291c..f47567b 100644
--- a/sr_unix/gdeverif.m
+++ b/sr_unix/gdeverif.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -12,6 +12,7 @@ verify:	;implement the verb: VERIFY, also invoked from show and GDEGET
 ALL()	;external
 	n verified,gqual s verified=1
 	s gqual="NAME" d ALLNAM
+	s gqual="GBLNAME" d ALLGBL
 	s gqual="REGION" d ALLREG,usereg
 	s gqual="SEGMENT" d ALLSEG,useseg
 	d ALLTEM
@@ -22,8 +23,34 @@ ALL()	;external
 ; called from GDEPARSE.M
 
 ALLNAM
-	n NAME s NAME=""
-	f  s NAME=$o(nams(NAME)) q:'$l(NAME)  d name1
+	n NAME,hassubs s NAME="",hassubs=0
+	f  s NAME=$o(nams(NAME)) q:'$zl(NAME)  d name1  i +$g(nams(NAME,"NSUBS")) s hassubs=1
+	; if using subscripted names, check that all regions where a globals spans has STDNULLCOLL set to TRUE
+	i hassubs d
+	. n map,currMap,nextMap,nextMapHasSubs,reg,gblname,mapreg
+	. d NAM2MAP^GDEMAP
+	. s currMap="",nextMap="",nextMapHasSubs=0
+	. f  s currMap=$o(map(currMap),-1) q:currMap="#)"  d
+	. . s hassubs=$zf(currMap,ZERO)
+	. . ; Check if current map entry has subscripts. If so this map entry should have STDNULLCOLL set.
+	. . ; Also check if next map entry had subscripts. If so this map entry should have STDNULLCOLL set
+	. . ; 	That is because a portion of the global in the next map entry lies in the current map entry region.
+	. . i (hassubs!nextMapHasSubs) d
+	. . . ; check if region has STDNULLCOLL defined to true
+	. . . s reg=map(currMap)
+	. . . i '+$g(regs(reg,"STDNULLCOLL")) d
+	. . . . s verified=0
+	. . . . i nextMapHasSubs d
+	. . . . . s gblname=$ze(nextMap,1,nextMapHasSubs-2)
+	. . . . . i '$d(mapreg(reg,gblname)) zm gdeerr("STDNULLCOLLREQ"):reg:"^"_gblname s mapreg(reg,gblname)=""
+	. . . . i hassubs d
+	. . . . . s gblname=$ze(currMap,1,hassubs-2)
+	. . . . . i '$d(mapreg(reg,gblname)) zm gdeerr("STDNULLCOLLREQ"):reg:"^"_gblname s mapreg(reg,gblname)=""
+	. . s nextMapHasSubs=hassubs,nextMap=currMap
+	q
+ALLGBL
+	n GBLNAME s GBLNAME=""
+	f  s GBLNAME=$o(gnams(GBLNAME)) q:""=GBLNAME  d gblname1
 	q
 ALLREG
 	n REGION s REGION=""
@@ -40,8 +67,29 @@ ALLSEG
 	f  s s=$o(segs(s)) q:'$l(s)  d:$d(reffils(segs(s,"FILE_NAME"))) dupfile s reffils(segs(s,"FILE_NAME"),s)=""
 	q
 NAME
-	i '$d(nams(NAME)) k verified zm $$info(gdeerr("OBJNOTFND")):"Name":$s(NAME'="#":NAME,1:"Local Locks") q
-name1:	i '$d(regs(nams(NAME))) s verified=0 zm gdeerr("MAPBAD"):"Region":nams(NAME):"Name":$s(NAME'="#":NAME,1:"Local Locks")
+	i '$d(nams(NAME)) k verified d  q
+	. zm $$info(gdeerr("OBJNOTFND")):"Name":$s(NAME'="#":$$namedisp^GDESHOW(NAME,0),1:"Local Locks")
+name1:	i '$d(regs(nams(NAME))) d
+	. s verified=0
+	. zm gdeerr("MAPBAD"):"Region":nams(NAME):"Name":$s(NAME'="#":$$namedisp^GDESHOW(NAME,0),1:"Local Locks")
+	q
+GBLNAME
+	i '$d(gnams(GBLNAME)) k verified zm $$info(gdeerr("OBJNOTFND")):"Global Name":GBLNAME q
+gblname1:
+	n s,sval,errissued s s=""
+	f  s s=$o(gnams(GBLNAME,s)) q:""=s  s sval=gnams(GBLNAME,s) d
+	. s errissued=0
+	. i $d(mingnam(s)),mingnam(s)>sval s errissued=1 zm gdeerr("VALTOOSMALL"):sval:mingnam(s):s
+	. i $d(maxgnam(s)),maxgnam(s)<sval s errissued=1 zm gdeerr("VALTOOBIG"):sval:maxgnam(s):s
+	. i errissued s verified=0 zm gdeerr("GBLNAMEIS"):GBLNAME
+	. i (s="COLLATION") d
+	. . i $d(gnams(GBLNAME,"COLLVER")) d
+	. . . d chkcoll^GDEPARSE(sval,GBLNAME,gnams(GBLNAME,"COLLVER"))
+	. . e  d chkcoll^GDEPARSE(sval,GBLNAME)
+	; now that all gblnames and names have been read, do some checks between them
+	; ASSERT : i $d(namrangeoverlap)  zsh "*"  h
+	d gblnameeditchecks^GDEPARSE("*",0)	; check all name specifications are good given the gblname collation settings
+	; ASSERT : i $d(namrangeoverlap)  zsh "*"  h
 	q
 REGION
 	i '$d(regs(REGION)) k verified zm $$info(gdeerr("OBJNOTFND")):"Region":REGION q
@@ -68,8 +116,8 @@ usereg:	n REGION,NAME s REGION=""
 	f  s REGION=$o(regs(REGION)) q:'$l(REGION)  d usereg1
 	q
 usereg1:	s NAME=""
-	f  s NAME=$o(nams(NAME)) q:$g(nams(NAME))=REGION!'$l(NAME)
-	i '$l(NAME) s verified=0 zm gdeerr("MAPBAD"):"A":"NAME":"REGION":REGION
+	f  s NAME=$o(nams(NAME)) q:$g(nams(NAME))=REGION!'$zl(NAME)
+	i '$zl(NAME) s verified=0 zm gdeerr("MAPBAD"):"A":"NAME":"REGION":REGION
 	q
 useseg:	n SEGMENT,REGION s SEGMENT=""
 	f  s SEGMENT=$o(segs(SEGMENT)) q:'$l(SEGMENT)  d useseg1
@@ -110,11 +158,14 @@ segelm:	i s'="FILE_NAME",'$l(tmpseg(am,s)) zm $$info(gdeerr("QUALBAD")):s
 	e  i $d(maxseg(am,s)),maxseg(am,s)<squals(s) zm gdeerr("VALTOOBIG"):squals(s):maxseg(am,s):s
 	i  s verified=0 zm gdeerr("SEGIS"):am:SEGMENT
 	q
-key2blk:	;bs:block size, y:supportable max key size, f:size of reserved bytes, ks:key size
-	s y=bs-f-SIZEOF("blk_hdr")-len("min_val")-SIZEOF("rec_hdr")-len("bstar_rec")-len("hide_subs")
-	i ks>y s verified=0 zm gdeerr("KEYSIZIS"):ks,gdeerr("KEYFORBLK"):bs:y,gdeerr("REGIS"):REGION
+key2blk:
+	; the computation below allows for at least 1 max-key record in a data OR index block.
+	; since an index block always contains a *-key, we need to account for that too.
+	; bs:block size, y:supportable max key size, f:size of reserved bytes, ks:key size
+	s y=bs-f-SIZEOF("blk_hdr")-len("min_val")-SIZEOF("rec_hdr")-len("hide_subs")-len("bstar_rec")
+	i ks>y s verified=0 zm gdeerr("KEYSIZIS"):ks,gdeerr("KEYFORBLK"):bs:f:y,gdeerr("REGIS"):REGION
 	q
-buf2blk:	i REGION="TEMPLATE","USER"[am,am'=tmpacc q
+buf2blk:	i REGION="TEMPLATE" q
 	i "USER"[am s verified=0 zm gdeerr("NOJNL"):am,gdeerr("REGIS"):REGION,gdeerr("SEGIS"):am:SEGMENT
 	q
 mmbichk:	i REGION="TEMPLATE",am="MM",tmpacc'="MM" q
@@ -125,17 +176,11 @@ allocchk(rquals)
 	s qn="EXTENSION",ext=$s($d(rquals(qn)):rquals(qn),$d(regs(REGION,qn)):regs(REGION,qn),1:tmpreg(qn))
 	s qn="ALLOCATION",alloc=$s($d(rquals(qn)):rquals(qn),$d(regs(REGION,qn)):regs(REGION,qn),1:tmpreg(qn))
 	s qn="AUTOSWITCHLIMIT",asl=$s($d(rquals(qn)):rquals(qn),$d(regs(REGION,qn)):regs(REGION,qn),1:tmpreg(qn))
-	i $d(alloc),$d(asl),alloc>asl s verified=0 zm gdeerr("VALTOOBIG"):alloc:asl_" (AUTOSWITCHLIMIT)":"ALLOCATION" q
-	i $d(ext),$d(alloc),$d(asl),alloc'=asl,ext+alloc>asl d
+	i alloc>asl s verified=0 zm gdeerr("VALTOOBIG"):alloc:asl_" (AUTOSWITCHLIMIT)":"ALLOCATION" q
+	i alloc'=asl,ext+alloc>asl d
 	. s rquals("ALLOCATION")=asl
 	. zm gdeerr("JNLALLOCGROW"):alloc:asl:"region":REGION
 	q
-prefix(str1,str2)  ;check whether str1 is a prefix of str2
-	n len1,len2
-	s len1=$l(str1),len2=$l(str2)
-	q:(len1>len2)!'len1 0
-	i ($e(str2,1,len1)=str1) q 1
-	q 0
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
 ; called from GDEADD.M and GDECHANG.M
@@ -153,6 +198,8 @@ RQUALS(rquals)
 	s x="RECORD_SIZE",x=$s($d(rquals(x)):rquals(x),$d(regs(REGION,x)):regs(REGION,x),1:tmpreg(x))
 	d allocchk(.rquals)
 	i REGION="TEMPLATE" s bs=tmpseg(tmpacc,"BLOCK_SIZE"),f=tmpseg(tmpacc,"RESERVED_BYTES")
+	; note "else" used in two consecutive lines intentionally (instead of using a do block inside one else).
+	; this is because we want the QUIT to quit out of RQUALS and the NEW of SEGMENT,am to happen at the RQUALS level.
 	e  s s="DYNAMIC_SEGMENT",s=$s($d(rquals(s)):rquals(s),$d(regs(REGION,s)):regs(REGION,s),1:0)
 	e  q:'$d(segs(s)) verified n SEGMENT,am d
 	. s SEGMENT=s,am=segs(s,"ACCESS_METHOD"),bs=$g(segs(s,"BLOCK_SIZE")),f=$g(segs(s,"RESERVED_BYTES"))
@@ -177,7 +224,8 @@ SQUALS(am,squals)
 	s s="WINDOW_SIZE"
 	i SEGMENT="TEMPLATE" s x=tmpreg("RECORD_SIZE") d segreg q verified
 	n REGION s REGION=""
-   f  s REGION=$o(regs(REGION)) q:'$l(REGION)  i regs(REGION,"DYNAMIC_SEGMENT")=SEGMENT s bs=regs(REGION,"RECORD_SIZE") d segreg
+	f  s REGION=$o(regs(REGION)) q:'$l(REGION)  d
+	. i regs(REGION,"DYNAMIC_SEGMENT")=SEGMENT s bs=regs(REGION,"RECORD_SIZE") d segreg
 	q verified
 segreg:
 	i am'="USER" d
@@ -186,9 +234,9 @@ segreg:
 	. s x="RECORD_SIZE",x=$s($d(regs(REGION,x)):regs(REGION,x),1:tmpreg(x))
 	. s ks="KEY_SIZE",ks=$s($d(regs(REGION,ks)):regs(REGION,ks),1:tmpreg(ks))
 	. d key2blk ;GTM-6941
-	i '$s(SEGMENT="TEMPLATE":tmpreg("JOURNAL"),1:regs(REGION,"JOURNAL")) q
+	i '$s(SEGMENT="TEMPLATE":0,1:regs(REGION,"JOURNAL")) q
 	s x=$s(SEGMENT="TEMPLATE":tmpreg("BUFFER_SIZE"),1:regs(REGION,"BUFFER_SIZE")) d buf2blk
-	i nommbi,$s(SEGMENT="TEMPLATE":tmpreg("BEFORE_IMAGE"),1:regs(REGION,"BEFORE_IMAGE")) d mmbichk
+	i nommbi,$s(SEGMENT="TEMPLATE":0,1:regs(REGION,"BEFORE_IMAGE")) d mmbichk
 	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
@@ -202,14 +250,3 @@ TSQUALS(am,squals)
 	n REGION,SEGMENT s (REGION,SEGMENT)="TEMPLATE"
 	q $$SQUALS(am,.squals)
 
-;-----------------------------------------------------------------------------------------------------------------------------------
-; called from GDEADD.M, GDECHANG.M and GDETEMPL.M, [GTM-7184]
-NQUALS(rquals)
-	n nullsub s nullsub=rquals("NULL_SUBSCRIPTS")
-	i ($$prefix(nullsub,"NEVER")!$$prefix(nullsub,"FALSE")) s rquals("NULL_SUBSCRIPTS")=0
-	e  d
-	. i ($$prefix(nullsub,"ALWAYS")!$$prefix(nullsub,"TRUE")) s rquals("NULL_SUBSCRIPTS")=1
-	. e  d
-	. . i ($$prefix(nullsub,"EXISTING")) s rquals("NULL_SUBSCRIPTS")=2
-	q
-
diff --git a/sr_unix/gds_rundown.c b/sr_unix/gds_rundown.c
index 8db5389..cafd7d9 100644
--- a/sr_unix/gds_rundown.c
+++ b/sr_unix/gds_rundown.c
@@ -580,10 +580,15 @@ int4 gds_rundown(void)
 			} else
 			{	/* Now do final MM file sync before exit */
 				assert(csa->ti->total_blks == csa->total_blks);
+				#ifdef _AIX
+				GTM_DB_FSYNC(csa, udi->fd, rc);
+				if (-1 == rc)
+				#else
 				if (-1 == MSYNC((caddr_t)csa->db_addrs[0], (caddr_t)csa->db_addrs[1]))
+				#endif
 				{
 					rts_error_csa(CSA_ARG(csa) VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
-						  ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file msync at close"), errno);
+						  ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file sync at close"), errno);
 				}
 			}
                 }
@@ -615,6 +620,7 @@ int4 gds_rundown(void)
 			  ERR_TEXT, 2, LEN_AND_LIT("Error during file close"), errno);
 	}
 	/* Unmap storage if mm mode but only the part that is not the fileheader (so shows up in dumps) */
+#	if !defined(_AIX)
 	if (is_mm && (NULL != csa->db_addrs[0]))
 	{
 		assert(csa->db_addrs[1] > csa->db_addrs[0]);
@@ -622,6 +628,7 @@ int4 gds_rundown(void)
 		if (0 < munmap_len)
 			munmap((caddr_t)(csa->db_addrs[0]), (size_t)(munmap_len));
 	}
+#	endif
 	/* Detach our shared memory while still under lock so reference counts will be correct for the next process to run down
 	 * this region. In the process also get the remove_shm status from node_local before detaching.
 	 * If csa->nl->donotflush_dbjnl is TRUE, it means we can safely remove shared memory without compromising data
@@ -664,23 +671,23 @@ int4 gds_rundown(void)
 			if (0 != shm_rmid(udi->shmid))
 				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
 					ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove shared memory"));
+			/* mupip recover/rollback don't release the semaphore here, but do it later in db_ipcs_reset (invoked from
+			 * mur_close_files())
+			 */
+			if (!have_standalone_access)
+			{
+				if (0 != sem_rmid(udi->semid))
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
+						      ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove semaphore"));
+				udi->grabbed_access_sem = FALSE;
+				udi->counter_acc_incremented = FALSE;
+			}
 		} else if (is_src_server || is_updproc)
 		{
 			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
 			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
 		} else
 			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
-		/* mupip recover/rollback don't release the semaphore here, but do it later in db_ipcs_reset (invoked from
-		 * mur_close_files())
-		 */
-		if (!have_standalone_access)
-		{
-			if (0 != sem_rmid(udi->semid))
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
-					ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove semaphore"));
-			udi->grabbed_access_sem = FALSE;
-			udi->counter_acc_incremented = FALSE;
-		}
 	} else
 	{
 		assert(!have_standalone_access || jgbl.onlnrlbk || safe_mode);
diff --git a/sr_unix/gds_rundown_ch.c b/sr_unix/gds_rundown_ch.c
index 4106189..d05f2c9 100644
--- a/sr_unix/gds_rundown_ch.c
+++ b/sr_unix/gds_rundown_ch.c
@@ -20,7 +20,7 @@ GBLREF	boolean_t	ok_to_UNWIND_in_exit_handling;
 
 CONDITION_HANDLER(gds_rundown_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	/* To get as virgin a state as possible in the core, take the core now if we
 	 * would be doing so anyway. This will set created_core so it doesn't happen again.
 	 */
diff --git a/sr_unix/gdsfilext.c b/sr_unix/gdsfilext.c
index 29e9192..59386f3 100644
--- a/sr_unix/gdsfilext.c
+++ b/sr_unix/gdsfilext.c
@@ -14,6 +14,9 @@
 #include "gtm_string.h"
 #include "gtm_time.h"
 #include <sys/mman.h>
+#ifdef _AIX
+#include <sys/shm.h>
+#endif
 #include <errno.h>
 #include "gtm_unistd.h"
 #include <signal.h>
@@ -172,7 +175,7 @@ uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
 				if (blocks > (uint4)avail_blocks)
 				{
 					SETUP_THREADGBL_ACCESS;
-					if (!ANTICIPATORY_FREEZE_ENABLED(cs_addrs))
+					if (!INST_FREEZE_ON_NOSPC_ENABLED(cs_addrs))
 						return (uint4)(NO_FREE_SPACE);
 					else
 						send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_NOSPACEEXT), 4,
@@ -219,13 +222,19 @@ uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
 			while (cs_data->freeze || IS_REPL_INST_FROZEN)
 				hiber_start(1000);
 		}
-	} else if ((cs_data->freeze || IS_REPL_INST_FROZEN) && dollar_tlevel)
+	} else if (cs_data->freeze && dollar_tlevel)
 	{	/* We don't want to continue with file extension as explained above. Hence return with an error code which
-		 * op_tcommit will recognize (as a cdb_sc_needcrit type of restart) and restart accordingly.
+		 * op_tcommit will recognize (as a cdb_sc_needcrit/cdb_sc_instancefreeze type of restart) and restart accordingly.
 		 */
 		assert(CDB_STAGNATE <= t_tries);
 		GDSFILEXT_CLNUP;
-		return (uint4)(FINAL_RETRY_FREEZE_PROG);
+		return (uint4)FINAL_RETRY_FREEZE_PROG;
+	}
+	if (IS_REPL_INST_FROZEN && trans_in_prog)
+	{
+		assert(CDB_STAGNATE <= t_tries);
+		GDSFILEXT_CLNUP;
+		return (uint4)FINAL_RETRY_INST_FREEZE;
 	}
 	assert(cs_addrs->ti->total_blks == cs_data->trans_hist.total_blks);
 	old_total = cs_data->trans_hist.total_blks;
@@ -278,13 +287,17 @@ uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
 		old_base[0] = cs_addrs->db_addrs[0];
 		old_base[1] = cs_addrs->db_addrs[1];
 		cs_addrs->db_addrs[0] = NULL; /* don't rely on it until the mmap below */
+#		ifdef _AIX
+		status = shmdt(old_base[0] - BLK_ZERO_OFF(cs_data));
+#		else
 		status = munmap((caddr_t)old_base[0], (size_t)(old_base[1] - old_base[0]));
+#		endif
 		if (0 != status)
 		{
 			save_errno = errno;
 			GDSFILEXT_CLNUP;
 			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region),
-					ERR_SYSCALL, 5, LEN_AND_LIT("munmap()"), CALLFROM, save_errno);
+					ERR_SYSCALL, 5, LEN_AND_STR(MEM_UNMAP_SYSCALL), CALLFROM, save_errno);
 			return (uint4)(NO_FREE_SPACE);
 		}
 	} else
@@ -453,18 +466,25 @@ uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
 		assert((NULL != old_base[0]) && (NULL != old_base[1]));
 		mmap_sz = new_eof - BLK_ZERO_OFF(cs_data);	/* Don't mmap the file header and master map */
 		CHECK_LARGEFILE_MMAP(gv_cur_region, mmap_sz);   /* can issue rts_error MMFILETOOLARGE */
+#		ifdef _AIX
+		status = (sm_long_t)(mmap_retaddr = (sm_uc_ptr_t)shmat(udi->fd, (void *)NULL,SHM_MAP));
+#		else
 		status = (sm_long_t)(mmap_retaddr = (sm_uc_ptr_t)MMAP_FD(udi->fd, mmap_sz, BLK_ZERO_OFF(cs_data), FALSE));
-		GTM_WHITE_BOX_TEST(WBTEST_MMAP_SYSCALL_FAIL, status, -1);
+#		endif
+		GTM_WHITE_BOX_TEST(WBTEST_MEM_MAP_SYSCALL_FAIL, status, -1);
 		if (-1 == status)
 		{
 			save_errno = errno;
-			WBTEST_ASSIGN_ONLY(WBTEST_MMAP_SYSCALL_FAIL, save_errno, ENOMEM);
+			WBTEST_ASSIGN_ONLY(WBTEST_MEM_MAP_SYSCALL_FAIL, save_errno, ENOMEM);
 			GDSFILEXT_CLNUP;
 			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region),
-					ERR_SYSCALL, 5, LEN_AND_LIT("mmap()"), CALLFROM, save_errno);
+					ERR_SYSCALL, 5, LEN_AND_STR(MEM_MAP_SYSCALL), CALLFROM, save_errno);
 			return (uint4)(NO_FREE_SPACE);
 		}
 		/* In addition to updating the internal map values, gds_map_moved sets cs_data to point to the remapped file */
+#		if defined(_AIX)
+		mmap_retaddr = (sm_uc_ptr_t)mmap_retaddr + BLK_ZERO_OFF(cs_data);
+#		endif
 		gds_map_moved(mmap_retaddr, old_base[0], old_base[1], mmap_sz); /* updates cs_addrs->db_addrs[1] */
 		cs_addrs->db_addrs[0] = mmap_retaddr;
 		assert(cs_addrs->db_addrs[0] < cs_addrs->db_addrs[1]);
diff --git a/sr_unix/generic_signal_handler.c b/sr_unix/generic_signal_handler.c
index 9fbb3ed..a5266cf 100644
--- a/sr_unix/generic_signal_handler.c
+++ b/sr_unix/generic_signal_handler.c
@@ -73,6 +73,7 @@ GBLREF	boolean_t		exit_handler_active;
 GBLREF	void			(*call_on_signal)();
 GBLREF	boolean_t		gtm_quiet_halt;
 GBLREF	volatile int4           gtmMallocDepth;         /* Recursion indicator */
+GBLREF	volatile boolean_t	timer_active;
 
 LITREF	gtmImageName		gtmImageNames[];
 
@@ -303,7 +304,8 @@ void generic_signal_handler(int sig, siginfo_t *info, void *context)
 	/* Stop the timers but do not cancel them. This allows the timer structures to appear in the core where gtmpcat can
 	 * extract them allowing us to see what was going on.
 	 */
-	sys_canc_timer();
+	if (timer_active)
+		sys_canc_timer();
 	FFLUSH(stdout);
 	if (!dont_want_core)
 	{
diff --git a/sr_unix/get_command_line.c b/sr_unix/get_command_line.c
index 1d29b1f..8c14ad0 100644
--- a/sr_unix/get_command_line.c
+++ b/sr_unix/get_command_line.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -36,7 +36,7 @@ void get_command_line(mval *result, boolean_t zcmd_line)
 	int		first_item, len, word_cnt;
 	unsigned char	*cp;
 
-	result->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by this to-be-overwritten mval */
+	result->mvtype = 0; /* so stp_gcol, if invoked below, can free up space currently occupied by this to-be-overwritten mval */
 	len = -1;							/* to compensate for no space at the end */
 	if (cmd_cnt > 1)
 	{
@@ -74,6 +74,6 @@ void get_command_line(mval *result, boolean_t zcmd_line)
 			break;
 		cp += len;
 	}
-	assert(cp + len == stringpool.free);
+	assert(IS_AT_END_OF_STRINGPOOL(cp, len));
 	return;
 }
diff --git a/sr_unix/get_src_line.c b/sr_unix/get_src_line.c
index 2527914..4be5245 100644
--- a/sr_unix/get_src_line.c
+++ b/sr_unix/get_src_line.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -39,11 +39,14 @@
 # include "t_retry.h"
 # include "trigger_source_read_andor_verify.h"
 #endif
+#include "stack_frame.h"
+#include "rtn_src_chksum.h"
 
 #define RT_TBL_SZ 20
 
 GBLREF uint4		dollar_tlevel;
 GBLREF unsigned int	t_tries;
+GBLREF stack_frame	*frame_pointer;
 
 LITDEF char		litconst_space = ' ';
 
@@ -52,24 +55,22 @@ error_def(ERR_SYSCALL);
 
 int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig)
 {
-	int		srcrecs, *lt_ptr, size, line_indx, srcfilnamlen;
-	uint4		checksum;
-	boolean_t	found, added, eof_seen, srcstat;
-	mstr		src;
-	rhdtyp		*rtn_vector;
-	zro_ent		*srcdir;
-	mstr		*base, *current, *top;
-	char		buff[MAX_SRCLINE], *cptr, *srcfile_name;
-	char		srcnamebuf[SIZEOF(mident_fixed) + STR_LIT_LEN(DOTM)];
-	ht_ent_mname	*tabent;
-	var_tabent	rtnent;
-	routine_source	*src_tbl;
-	int		rc, fclose_res;
-	char		*fgets_rc;
-	FILE		*fp;
-	struct stat	srcfile_stat;
-	off_t		srcsize;
-	unsigned char	*srcptr, *srcptr_max, *srcstart;
+	int			srcrecs, *lt_ptr, size, line_indx, srcfilnamlen;
+	boolean_t		found, added, eof_seen, srcstat;
+	mstr			src;
+	rhdtyp			*rtn_vector;
+	zro_ent			*srcdir;
+	mstr			*base, *current, *top;
+	char			buff[MAX_SRCLINE], *cptr, *srcfile_name;
+	char			srcnamebuf[SIZEOF(mident_fixed) + STR_LIT_LEN(DOTM)];
+	routine_source		*src_tbl;
+	int			rc, fclose_res;
+	char			*fgets_rc;
+	FILE			*fp;
+	struct stat		srcfile_stat;
+	off_t			srcsize;
+	unsigned char		*srcptr, *srcptr_max, *srcstart, *eol_srcstart, *prev_srcptr;
+	gtm_rtn_src_chksum_ctx	checksum_ctx;
 #	ifdef GTM_TRIGGER
 	boolean_t	is_trigger;
 #	endif
@@ -78,8 +79,6 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 	SETUP_THREADGBL_ACCESS;
 	srcstat = 0;
 	*srcret = NULL;
-	if (NULL == (TREF(rt_name_tbl)).base)
-		init_hashtab_mname(TADR(rt_name_tbl), RT_TBL_SZ, HASHTAB_COMPACT, HASHTAB_SPARE_TABLE);
 	assert (routine->mvtype & MV_STR);
 
 	/* The source to be loaded can be of two types:
@@ -90,12 +89,15 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 	 * Determine which source we need.
 	 */
 	GTMTRIG_ONLY(IS_TRIGGER_RTN(&routine->str, is_trigger));
-	/* Need source on a trigger. Get trigger source loaded and/or verified which may involve
-	 * creating a TP fence and dealing with TP restarts.
-	 */
+	if (WANT_CURRENT_RTN(routine))
+	{	/* we want $TEXT for the routine currently executing. */
+		rtn_vector = CURRENT_RHEAD_ADR(frame_pointer->rvector);
+	} else
 #	ifdef GTM_TRIGGER
 	if (is_trigger)
-	{	/* ZPRINT wants a consistent view of triggers across multiple calls so it bypasses verification
+	{	/* Need source on a trigger. Get trigger source loaded and/or verified which may involve
+		 * creating a TP fence and dealing with TP restarts.
+		 * ZPRINT wants a consistent view of triggers across multiple calls so it bypasses verification
 		 * after the first call. In this case, the trigger had better be found since the first call found it.
 		 */
 		if (verifytrig)
@@ -123,13 +125,9 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 	}
 	if (!rtn_vector->src_full_name.len)
 		return SRCNOTAVAIL;
-	rtnent.var_name = rtn_vector->routine_name;
-	COMPUTE_HASH_MNAME(&rtnent);
-	added = add_hashtab_mname(TADR(rt_name_tbl), &rtnent, NULL, &tabent);
-	src_tbl = (routine_source *)tabent->value;
-	if (added || (NULL == tabent->value))
+	src_tbl = rtn_vector->source_code;
+	if (NULL == src_tbl)
 	{
-		checksum = 0;
 #		ifdef GTM_TRIGGER
 		if (is_trigger)
 		{
@@ -137,6 +135,19 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 			srcsize = ((gv_trigger_t *)rtn_vector->trigr_handle)->xecute_str.str.len;
 			assert(0 < srcsize);
 			assert(NULL != srcstart);
+			/* Calculate source checksum */
+			if (NULL == memchr(srcstart, '\n', srcsize))
+			{	/* In this case, gtm_trigger_complink() would have written an extra newline character to the
+				 * source file. Since we want to take the checksum of the same data, we append a newline character
+				 * here as well.
+				 */
+				eol_srcstart = (unsigned char *)malloc(srcsize + 1);
+				memcpy(eol_srcstart, srcstart, srcsize);
+				eol_srcstart[srcsize] = '\n';
+				rtn_src_chksum_buffer(&checksum_ctx, eol_srcstart, srcsize + 1);
+				free(eol_srcstart);
+			} else
+				rtn_src_chksum_buffer(&checksum_ctx, srcstart, srcsize);
 			srcrecs = (int)rtn_vector->lnrtab_len;
 			/* Allocate the array to hold the mstr array pointing to the src lines. */
 			src_tbl = (routine_source *)malloc(SIZEOF(routine_source) + ((srcrecs - 1) * SIZEOF(mstr)));
@@ -155,9 +166,9 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 				/* Find end of this record */
 				for (; (srcptr < srcptr_max) && ('\n' != *srcptr); srcptr++)
 					;
-				if (0 != (size = (srcptr - (unsigned char *)current->addr)))	/* note assignment */
-				{	/* Do checksum computation plus set length */
-					RTN_SRC_CHKSUM((char *)srcstart, size, checksum);
+				size = (srcptr - (unsigned char *)current->addr);
+				if (0 != size)
+				{	/* Set line length */
 					current->len = size;
 				} else
 				{	/* Null record -  point to a single space for the record */
@@ -167,16 +178,13 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 				srcptr++;	/* Skip line end char */
 				srcstart = srcptr;
 			}
-			if (checksum != rtn_vector->checksum)
+			if (!rtn_src_chksum_match(get_ctx_checksum(&checksum_ctx), get_rtnhdr_checksum(rtn_vector)))
 			{	/* Should never happen with a trigger unless it ran into some restartable concurrency
 				 * issues. Assert we can restart and do it.
 				 */
-				if (0 < dollar_tlevel)
-				{
-					assert(CDB_STAGNATE > t_tries);
-					t_retry(cdb_sc_triggermod);
-				} else
-					GTMASSERT;
+				assertpro(0 < dollar_tlevel);
+				assert(CDB_STAGNATE > t_tries);
+				t_retry(cdb_sc_triggermod);
 			}
 		} else
 #		endif
@@ -213,7 +221,7 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 					fp = Fopen(srcfile_name, "r");
 					if (NULL == fp)
 					{
-						rts_error(VARLSTCNT(1) errno);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 						assert(FALSE);
 					}
 					found = TRUE;
@@ -237,7 +245,8 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 					if (0 != rc)
 					{
 						free(srcfile_name);
-						rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("stat"), CALLFROM, rc);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL,
+								5, LEN_AND_LIT("stat"), CALLFROM, rc);
 					}
 					srcsize = srcfile_stat.st_size;
 				} else
@@ -270,7 +279,7 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 						{
 							FCLOSE(fp, fclose_res);
 							assert(!fclose_res);
-							rts_error(VARLSTCNT(3) ERR_TXTSRCFMT, 0, errno);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_TXTSRCFMT, 0, errno);
 							assert(FALSE);
 						} else
 						{
@@ -281,6 +290,9 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 					} else
 					{
 						size = (int)STRLEN(buff);
+						prev_srcptr = srcptr;
+						memcpy(srcptr, buff, size);
+						srcptr += size;
 						/* Strip trailing '\n' if any (if at least one byte was read in) */
 						if (size && ('\n' == buff[size - 1]))
 							size--;
@@ -288,14 +300,10 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 				} else	/* eof seen; nothing more to read in file */
 					size = 0;
 				if (size)
-				{	/* Calculate checksum to verify with loaded routine */
-					RTN_SRC_CHKSUM(buff, size, checksum);
-					assert(NULL != srcptr);
-					assert((srcptr + size) <= srcptr_max);
+				{
+					assert((prev_srcptr + size) <= srcptr_max);
 					current->len = size;
-					current->addr = (char *)srcptr;
-					memcpy(srcptr, buff, size);
-					srcptr += size;
+					current->addr = (char *)prev_srcptr;
 				} else
 				{
 					current->addr = (char *)&litconst_space;
@@ -319,14 +327,16 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 						assert(feof(fp));
 					}
 				}
-				if (!eof_seen || (checksum != rtn_vector->checksum))
+				rtn_src_chksum_buffer(&checksum_ctx, src_tbl->srcbuff, srcsize);
+				if (!eof_seen
+					|| !rtn_src_chksum_match(get_ctx_checksum(&checksum_ctx), get_rtnhdr_checksum(rtn_vector)))
 					srcstat |= CHECKSUMFAIL;
 				FCLOSE(fp, fclose_res);
 				assert(!fclose_res);
 			}
 		}
 		src_tbl->srcstat = srcstat;
-		tabent->value = (char *)src_tbl;
+		rtn_vector->source_code = src_tbl;
 	} else
 		srcstat |= src_tbl->srcstat;
 	lt_ptr = (int *)find_line_addr(rtn_vector, &label->str, 0, NULL);
@@ -350,3 +360,17 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 	}
 	return srcstat;
 }
+
+void free_src_tbl(rhdtyp *rtn_vector)
+{
+	routine_source		*src_tbl;
+
+	src_tbl = rtn_vector->source_code;
+	if (NULL != src_tbl)
+	{	/* Release the source. Entries and source are malloc'd in two blocks on UNIX */
+		if (NULL != src_tbl->srcbuff)
+			free(src_tbl->srcbuff);
+		free(src_tbl);
+		rtn_vector->source_code = NULL;
+	}
+}
diff --git a/sr_unix/getpass.m b/sr_unix/getpass.m
deleted file mode 100644
index b4553c4..0000000
--- a/sr_unix/getpass.m
+++ /dev/null
@@ -1,22 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;								;
-;	Copyright 2009 Fidelity Information Services, Inc	;
-;								;
-;	This source code contains the intellectual property	;
-;	of its copyright holder(s), and is made available	;
-;	under a license.  If you do not know the terms of	;
-;	the license, please stop and do not read further.	;
-;								;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-getpass(passlen)
-	new isave,zsd,i,pass
-	if $IO'=$P set isave=$IO use $P
-	zshow "D":zsd
-	set i=""
-	for  set i=$order(zsd("D",i)) q:i=""  if $P=$piece(zsd("D",i)," ",1) set zsd=$find(zsd("D",i),"NOECHO",$length($p))
-	use $P:(NOECHO)
-	read !,"Enter Passphrase: ",pass#passlen,!
-	if 'zsd use $P:ECHO
-	if $d(isave) use isave
-	quit pass
diff --git a/sr_unix/gt_timer.h b/sr_unix/gt_timer.h
index 29bb4ee..002552a 100644
--- a/sr_unix/gt_timer.h
+++ b/sr_unix/gt_timer.h
@@ -93,9 +93,12 @@ typedef struct st_timer_alloc
  */
 #define SLACKTIME		10
 
+#define CANCEL_TIMERS		cancel_unsafe_timers()
+
 int4		abs_time_comp(ABS_TIME *atp1, ABS_TIME *atp2);
 void		add_int_to_abs_time(ABS_TIME *atps, int4 ival, ABS_TIME *atpd);
 void		cancel_timer(TID tid);
+void		cancel_unsafe_timers(void);
 void		clear_timers(void);
 void		hiber_start(uint4 hiber);
 void		hiber_start_wait_any(uint4 hiber);
@@ -122,8 +125,6 @@ STATICFNDCL GT_TIMER	*find_timer(TID tid, GT_TIMER **tprev);
 STATICFNDCL void	add_timer(ABS_TIME *atp, TID tid, int4 time_to_expir, void (*handler)(), int4 hdata_len,
 	void *hdata, boolean_t safe_timer);
 STATICFNDCL void	remove_timer(TID tid);
-STATICFNDCL void 	uninit_all_timers(void);
-STATICFNDCL void	cancel_all_timers(void);
 STATICFNDCL void	init_timers(void);
 
 #endif
diff --git a/sr_unix/gt_timers.c b/sr_unix/gt_timers.c
index 123e9d7..9092985 100644
--- a/sr_unix/gt_timers.c
+++ b/sr_unix/gt_timers.c
@@ -76,6 +76,7 @@
 #include "have_crit.h"
 #include "util.h"
 #include "sleep.h"
+#include "error.h"
 #if defined(__osf__)
 # define HZ	CLK_TCK
 #elif defined(__MVS__)
@@ -98,17 +99,39 @@ int4	time();
 #define GT_TIMER_INIT_DATA_LEN	8
 #define MAX_TIMER_POP_TRACE_SZ	32
 
-#define ADD_SAFE_HNDLR(HNDLR)						\
-{									\
-	assert((ARRAYSIZE(safe_handlers) - 1) > safe_handlers_cnt);	\
-	safe_handlers[safe_handlers_cnt++] = HNDLR;			\
+#define ADD_SAFE_HNDLR(HNDLR)									\
+{												\
+	assert((ARRAYSIZE(safe_handlers) - 1) > safe_handlers_cnt);				\
+	safe_handlers[safe_handlers_cnt++] = HNDLR;						\
 }
 
 #ifdef BSD_TIMER
-STATICDEF struct itimerval sys_timer, old_sys_timer;
+#  define REPORT_SETITIMER_ERROR(TIMER_TYPE, SYS_TIMER, FATAL, ERRNO)				\
+{												\
+	char s[512];										\
+												\
+	SNPRINTF(s, 512, "Timer: %s; timer_active: %d; "					\
+		"sys_timer.it_value: [tv_sec: %ld; tv_usec: %ld]; "				\
+		"sys_timer.it_interval: [tv_sec: %ld; tv_usec: %ld]",				\
+		TIMER_TYPE, timer_active,							\
+		SYS_TIMER.it_value.tv_sec, SYS_TIMER.it_value.tv_usec,				\
+		SYS_TIMER.it_interval.tv_sec, SYS_TIMER.it_interval.tv_usec);			\
+	if (FATAL)										\
+	{											\
+		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7)						\
+			ERR_SETITIMERFAILED, 1, ERRNO, ERR_TEXT, 2, LEN_AND_STR(s));		\
+		in_setitimer_error = TRUE;							\
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SETITIMERFAILED, 1, ERRNO);	\
+	} else											\
+		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7)	MAKE_MSG_WARNING(ERR_SETITIMERFAILED),	\
+			1, ERRNO, ERR_TEXT, 2, LEN_AND_STR(s));					\
+}
+
+STATICDEF struct itimerval	sys_timer, old_sys_timer;
+STATICDEF boolean_t		in_setitimer_error;
 #endif
 
-#define DUMMY_SIG_NUM 0			/* following can be used to see why timer_handler was called */
+#define DUMMY_SIG_NUM		0	/* following can be used to see why timer_handler was called */
 
 STATICDEF volatile GT_TIMER *timeroot = NULL;	/* chain of pending timer requests in time order */
 STATICDEF boolean_t first_timeset = TRUE;
@@ -162,6 +185,8 @@ GBLREF	int4		error_condition;
 GBLREF	int4		outofband;
 GBLREF	int		process_exiting;
 
+error_def(ERR_SETITIMERFAILED);
+error_def(ERR_TEXT);
 error_def(ERR_TIMERHANDLER);
 
 /* Called when a hiber_start timer pops. Set flag so a given timer will wake up (not go back to sleep). */
@@ -264,7 +289,7 @@ void prealloc_gt_timers(void)
 	 */
 	ADD_SAFE_HNDLR(&hiber_wake);		/* Resident in this module */
 	ADD_SAFE_HNDLR(&hiber_start_wait_any);	/* Resident in this module */
-	ADD_SAFE_HNDLR(&wake_alarm);		/* Standalone module containing on one global reference */
+	ADD_SAFE_HNDLR(&wake_alarm);		/* Standalone module containing only one global reference */
 }
 
 /* Get current clock time. Fill-in the structure with the absolute time of system clock.
@@ -294,7 +319,6 @@ void hiber_start(uint4 hiber)
 	TID		tid;
 	sigset_t	savemask;
 
-	assertpro(1 > timer_stack_count);		/* timer services are unavailable from within a timer handler */
 	sigprocmask(SIG_BLOCK, &blockalrm, &savemask);	/* block SIGALRM signal */
 	/* sigsuspend() sets the signal mask to 'savemask' and waits for an ALARM signal. If the SIGALRM is a member of savemask,
 	 * this process will never receive SIGALRM, and it will hang indefinitely. One such scenario would be if we interrupted a
@@ -303,10 +327,13 @@ void hiber_start(uint4 hiber)
 	 * than GT.M timers.
 	 */
 	if (sigismember(&savemask, SIGALRM))
-	{
+	{	/* normally, if SIGALRMs are blocked, we must already be inside a timer handler, but someone can actually disable
+		 * SIGALRMs, in which case we do not want this assert to trip in pro */
+		assert(1 <= timer_stack_count);
 		NANOSLEEP(hiber);
 	} else
 	{
+		assertpro(1 > timer_stack_count);	/* if SIGALRMs are not blocked, we cannot be inside a timer handler */
 		waitover = FALSE;			/* when OUR timer pops, it will set this flag */
 		waitover_addr = &waitover;
 		tid = (TID)waitover_addr;		/* unique id of this timer */
@@ -321,7 +348,7 @@ void hiber_start(uint4 hiber)
 				cancel_timer(tid);
 				break;
 			}
-		} while(FALSE == waitover);
+		} while (FALSE == waitover);
 	}
 	sigprocmask(SIG_SETMASK, &savemask, NULL);	/* reset signal handlers */
 }
@@ -395,21 +422,30 @@ void start_timer(TID tid,
 	{
 		safe_to_add = TRUE;
 		safe_timer = TRUE;
-	} else if ((wcs_clean_dbsync_fptr == handler) || (wcs_stale_fptr == handler))
+	} else if (wcs_clean_dbsync_fptr == handler)
+	{	/* Account for known instances of the above function being called from within a deferred zone. */
+		assert((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) || (INTRPT_IN_WCS_WTSTART == intrpt_ok_state)
+			|| (INTRPT_IN_DB_CSH_GETN == intrpt_ok_state));
 		safe_to_add = TRUE;
-	else
+	} else if (wcs_stale_fptr == handler)
+	{	/* Account for known instances of the above function being called from within a deferred zone. */
+		assert((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) || (INTRPT_IN_DB_CSH_GETN == intrpt_ok_state));
+		safe_to_add = TRUE;
+	} else
 	{
                 for (i = 0; NULL != safe_handlers[i]; i++)
+		{
                         if (safe_handlers[i] == handler)
                         {
 				safe_to_add = TRUE;
 				safe_timer = TRUE;
                                 break;
                         }
+		}
 	}
 	if (!safe_to_add && (process_exiting || (INTRPT_OK_TO_INTERRUPT != intrpt_ok_state)))
 	{
-		assert(WBTEST_ENABLED(WBTEST_RECOVER_ENOSPC));
+		assert(FALSE);
 		return;
 	}
 	sigprocmask(SIG_BLOCK, &blockalrm, &savemask);	/* block SIGALRM signal */
@@ -436,8 +472,6 @@ STATICFNDEF void start_timer_int(TID tid, int4 time_to_expir, void (*handler)(),
 	 * If a few years pass without the assert failing, it might be safe then to remove the PRO_ONLY code below.
 	 */
 #	ifndef DEBUG
-	if (timeroot && (timeroot->tid == tid))
-		sys_canc_timer();
 	remove_timer(tid); /* Remove timer from chain */
 #	endif
 	/* Check if # of free timer slots is less than minimum threshold. If so, allocate more of those while it is safe to do so */
@@ -448,55 +482,26 @@ STATICFNDEF void start_timer_int(TID tid, int4 time_to_expir, void (*handler)(),
 		start_first_timer(&at);
 }
 
-/* Uninitialize all timers, since we will not be needing them anymore. */
-STATICFNDEF void uninit_all_timers(void)
-{
-	st_timer_alloc	*next_timeblk;
-
-	sys_canc_timer();
-	first_timeset = TRUE;
-	for (; timer_allocs;  timer_allocs = next_timeblk)	/* loop over timer_allocs entries and deallocate them */
-	{
-		next_timeblk = timer_allocs->next;
-		free(timer_allocs->addr);			/* free the timeblk */
-		free((st_timer_alloc *)timer_allocs); 		/* free the container */
-	}
-	/* after all timers are removed, we need to set the below pointers to NULL */
-	timeroot = NULL;
-	timefree = NULL;
-	num_timers_free = 0;
-	/* empty the blockalrm and sigsent entries */
-	sigemptyset(&blockalrm);
-	sigemptyset(&block_sigsent);
-	sigaction(SIGALRM, &prev_alrm_handler, NULL);
-	timer_active = FALSE;
-}
-
 /* Cancel timer.
  * Arguments:	tid - timer id
  */
 void cancel_timer(TID tid)
 {
-        ABS_TIME at;
-	sigset_t savemask;
+        ABS_TIME	at;
+	sigset_t	savemask;
+	boolean_t	first_timer;
 
 	sigprocmask(SIG_BLOCK, &blockalrm, &savemask);	/* block SIGALRM signal */
 	sys_get_curr_time(&at);
-	if (tid == 0)
+	first_timer = (timeroot && (timeroot->tid == tid));
+	remove_timer(tid);		/* remove it from the chain */
+	if (first_timer)
 	{
-		assert(process_exiting || IS_GTMSECSHR_IMAGE); /* wcs_phase2_commit_wait relies on this flag being set BEFORE
-								* cancelling all timers. But secshr doesn't have it.
-								*/
-		cancel_all_timers();
-		uninit_all_timers();
-		timer_stack_count = 0;
-		sigprocmask(SIG_SETMASK, &savemask, NULL);
-		return;
+		if (timeroot)
+			start_first_timer(&at);		/* start the first timer in the chain */
+		else if (timer_active)
+			sys_canc_timer();
 	}
-	if (timeroot && (timeroot->tid == tid))		/* if this is the first timer in the chain, stop it */
-		sys_canc_timer();
-	remove_timer(tid);		/* remove it from the chain */
-	start_first_timer(&at);		/* start the first timer in the chain */
 	sigprocmask(SIG_SETMASK, &savemask, NULL);
 }
 
@@ -520,9 +525,11 @@ void clear_timers(void)
  *		time_to_expir	- time to expiration
  *		handler		- address of handler routine
  */
-STATICFNDEF void sys_settimer (TID tid, ABS_TIME *time_to_expir, void (*handler)())
+STATICFNDEF void sys_settimer(TID tid, ABS_TIME *time_to_expir, void (*handler)())
 {
 #	ifdef BSD_TIMER
+	if (in_setitimer_error)
+		return;
 	if ((time_to_expir->at_sec == 0) && (time_to_expir->at_usec < (1000000 / HZ)))
 	{
 		sys_timer.it_value.tv_sec = 0;
@@ -533,7 +540,11 @@ STATICFNDEF void sys_settimer (TID tid, ABS_TIME *time_to_expir, void (*handler)
 		sys_timer.it_value.tv_usec = (gtm_tv_usec_t)time_to_expir->at_usec;
 	}
 	sys_timer.it_interval.tv_sec = sys_timer.it_interval.tv_usec = 0;
-	setitimer(ITIMER_REAL, &sys_timer, &old_sys_timer);
+	assert(1000000 > sys_timer.it_value.tv_usec);
+	if ((-1 == setitimer(ITIMER_REAL, &sys_timer, &old_sys_timer)) || WBTEST_ENABLED(WBTEST_SETITIMER_ERROR))
+	{
+		REPORT_SETITIMER_ERROR("ITIMER_REAL", sys_timer, TRUE, errno);
+	}
 #	else
 	if (time_to_expir->at_sec == 0)
 		alarm((unsigned)1);
@@ -736,9 +747,9 @@ STATICFNDEF void timer_handler(int why)
 		start_first_timer(&at);
 	else if ((NULL != timeroot) || (0 < timer_defer_cnt))
 		deferred_timers_check_needed = TRUE;
-	/* Restore mainline error_condition global variable. This way any gtm_putmsg or rts_errors that occurred inside
-	 * interrupt code do not affect the error_condition global variable that mainline code was relying on.
-	 * For example, not doing this restore caused the update process (in updproc_ch) to issue a GTMASSERT (GTM-7526).
+	/* Restore mainline error_condition global variable. This way any gtm_putmsg or rts_errors that occurred inside interrupt
+	 * code do not affect the error_condition global variable that mainline code was relying on. For example, not doing this
+	 * restore caused the update process (in updproc_ch) to issue a GTMASSERT (GTM-7526). BYPASSOK.
 	 */
 	error_condition = save_error_condition;
 	errno = save_errno;		/* restore mainline errno by similar reasoning as mainline error_condition */
@@ -887,43 +898,70 @@ void sys_canc_timer()
 	struct itimerval zero;
 
 	memset(&zero, 0, SIZEOF(struct itimerval));
-	setitimer(ITIMER_REAL, &zero, &old_sys_timer);
+	assert(timer_active);
+	/* In case of canceling the system timer, we do not care if we succeed. Consider the two scenarios:
+	 *   1) The process is exiting, so all timers must have been removed anyway, and regardless of whether the system
+	 *      timer got unset or not, no handlers would be processed (even in the event of a pop).
+	 *   2) Some timer is being canceled as part of the runtime logic. If the system is experiencing problems, then the
+	 *      following attempt to schedule a new timer (remember that we at the very least have the heartbeat timer once
+	 *      database access has been established) would fail; if no other timer is scheduled, then the canceled entry
+	 *      must have been removed off the queue anyway, so no processing would occur on a pop.
+	 */
+	if (-1 == setitimer(ITIMER_REAL, &zero, &old_sys_timer))
+	{
+		REPORT_SETITIMER_ERROR("ITIMER_REAL", zero, FALSE, errno);
+	}
 #	else
 	alarm(0);
 #	endif
 	timer_active = FALSE;		/* no timer is active now */
 }
 
-/* Cancel all timers.
- * Note: The timer signal must be blocked prior to entry
+/* Cancel all unsafe timers.
  */
-STATICFNDEF void cancel_all_timers(void)
+void cancel_unsafe_timers(void)
 {
+        ABS_TIME	at;
+	sigset_t	savemask;
+	GT_TIMER	*active, *curr, *next;
 	DEBUG_ONLY(int4 cnt = 0;)
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	if (timeroot)
-		sys_canc_timer();
-	while (timeroot)
-	{	/* remove timer from the chain */
-		remove_timer(timeroot->tid);
+	sigprocmask(SIG_BLOCK, &blockalrm, &savemask);	/* block SIGALRM signal */
+	active = curr = (GT_TIMER *)timeroot;
+	while (curr)
+	{	/* If the timer is unsafe, remove it from the chain. */
+		next = curr->next;
+		if (!curr->safe)
+			remove_timer(curr->tid);
+		curr = next;
 		DEBUG_ONLY(cnt++;)
 	}
-	safe_timer_cnt = 0;
-	if (!timeroot)
+	assert((NULL == timeroot) || (0 < safe_timer_cnt));
+	if (timeroot)
+	{	/* If the head of the queue has changed, start the current first timer. */
+		if (timeroot != active)
+		{
+			sys_get_curr_time(&at);
+			start_first_timer(&at);
+		}
+	} else
 	{
 		deferred_timers_check_needed = FALSE;
+		/* There are no timers left, but the system timer was active, so cancel it. */
+		if (timer_active)
+			sys_canc_timer();
 	}
 #	ifdef DEBUG
-	if (gtm_white_box_test_case_enabled
-		&& WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number)
+	if (WBTEST_ENABLED(WBTEST_DEFERRED_TIMERS))
 	{
 		DBGFPF((stderr, "CANCEL_ALL_TIMERS:\n"));
 		DBGFPF((stderr, " Timer pops handled: %d\n", timer_pop_cnt));
 		DBGFPF((stderr, " Timers canceled: %d\n", cnt));
 	}
 #	endif
+	sigprocmask(SIG_SETMASK, &savemask, NULL);
 }
 
 /* Initialize timers. */
diff --git a/sr_unix/gt_timers_add_safe_hndlrs.c b/sr_unix/gt_timers_add_safe_hndlrs.c
index 736b668..475c629 100644
--- a/sr_unix/gt_timers_add_safe_hndlrs.c
+++ b/sr_unix/gt_timers_add_safe_hndlrs.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,6 +16,7 @@
 #include "heartbeat_timer.h"
 #include "semwt2long_handler.h"
 #include "secshr_client.h"
+#include "dskspace_msg_timer.h"
 
 /* This optional routine adds entries to the safe_handlers[] array. It is separate because while most executables need
  * these timers listed, there is one executable (gtmsecshr) that decidedly does not - gtmsecshr. If these routines are
@@ -25,5 +26,5 @@
 
 void gt_timers_add_safe_hndlrs(void)
 {
-	add_safe_timer_handler(3, semwt2long_handler, client_timer_handler, heartbeat_timer);
+	add_safe_timer_handler(4, semwt2long_handler, client_timer_handler, heartbeat_timer, dskspace_msg_timer);
 }
diff --git a/sr_unix/gtm_env_init_sp.c b/sr_unix/gtm_env_init_sp.c
index 145d5e8..68bae0e 100644
--- a/sr_unix/gtm_env_init_sp.c
+++ b/sr_unix/gtm_env_init_sp.c
@@ -46,6 +46,7 @@
 #include "jnl.h"
 #include "replgbl.h"
 #include "gtm_semutils.h"
+#include "gtmlink.h"
 #ifdef __linux__
 #include "hugetlbfs_overrides.h"
 #endif
@@ -91,6 +92,7 @@ GTMTRIG_ONLY(GBLREF	mval	gtm_trigger_etrap;)
 LITDEF mval default_mupip_trigger_etrap = DEFINE_MVAL_LITERAL(MV_STR, 0 , 0 , (SIZEOF(DEFAULT_MUPIP_TRIGGER_ETRAP) - 1),
 							      DEFAULT_MUPIP_TRIGGER_ETRAP , 0 , 0 );
 #endif
+LITREF mstr relink_allowed_mstr[];
 
 static readonly nametabent editing_params[] =
 {
@@ -116,7 +118,7 @@ void	gtm_env_init_sp(void)
 	size_t		cwdlen;
 	boolean_t	ret, is_defined;
 	char		buf[MAX_TRANS_NAME_LEN], *token, cwd[GTM_PATH_MAX];
-	char		*cwdptr, *trigger_etrap;
+	char		*cwdptr, *trigger_etrap, *c, *end;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -326,6 +328,16 @@ void	gtm_env_init_sp(void)
 		dollar_ztrap.str.len = SIZEOF(init_break);
 		dollar_ztrap.str.addr = (char *)init_break;
 	}
+	/* See if gtm_link is set */
+	val.addr = GTM_LINK;
+	val.len = SIZEOF(GTM_LINK) - 1;
+	TREF(relink_allowed) = LINK_NORECURSIVE; /* default */
+	if (SS_NORMAL == (status = TRANS_LOG_NAME(&val, &trans, buf, SIZEOF(buf), do_sendmsg_on_log2long)))
+	{
+		init_relink_allowed(&trans); /* set TREF(relink_allowed) */
+		/*for (c = trans.addr, end = c + trans.len; c < end; c++)
+			*c = TOUPPER(*c);*/ /* convert trans (an mstr) to all caps */
+	}
 #	ifdef DEBUG
 	/* DEBUG-only option to bypass 'easy' methods of things and always use gtmsecshr for IPC cleanups, wakeups, file removal,
 	 * etc. Basically use gtmsecshr for anything where it is an option - helps with testing gtmsecshr for proper operation.
diff --git a/sr_unix/gtm_exit_handler.c b/sr_unix/gtm_exit_handler.c
index 477a11b..8cd9f73 100644
--- a/sr_unix/gtm_exit_handler.c
+++ b/sr_unix/gtm_exit_handler.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -76,7 +76,7 @@ void gtm_exit_handler(void)
 		turn_tracing_off(NULL);
 	exit_handler_active = TRUE;
 	SET_PROCESS_EXITING_TRUE;
-	cancel_timer(0);		/* Cancel all timers - No unpleasant surprises */
+	CANCEL_TIMERS;			/* Cancel all unsafe timers - No unpleasant surprises */
 	ESTABLISH(lastchance1);
 	secshr_db_clnup(NORMAL_TERMINATION);
 	if (dollar_tlevel)
diff --git a/sr_unix/gtm_fork_n_core.c b/sr_unix/gtm_fork_n_core.c
index 31b0911..268632e 100644
--- a/sr_unix/gtm_fork_n_core.c
+++ b/sr_unix/gtm_fork_n_core.c
@@ -76,24 +76,23 @@ void gtm_fork_n_core(void)
 	sgmnt_addrs		*csa;
 	sgmnt_data_ptr_t	csd, tmp_csd;
 	gd_region		*reg, *r_top;
-	gd_addr			*addr_ptr;
-DEBUG_ONLY( struct rlimit rlim;)
+	DEBUG_ONLY(struct rlimit rlim;)
 
 	DEBUG_ONLY(
-	getrlimit(RLIMIT_CORE, &rlim);
-	if ( rlim.rlim_cur != rlim.rlim_max)
-	{
-		if (RLIM_INFINITY == rlim.rlim_max)
-			rlim.rlim_cur = RLIM_INFINITY;
-		else
+		getrlimit(RLIMIT_CORE, &rlim);
+		if ( rlim.rlim_cur != rlim.rlim_max)
 		{
-			if (rlim.rlim_cur < rlim.rlim_max)
+			if (RLIM_INFINITY == rlim.rlim_max)
+				rlim.rlim_cur = RLIM_INFINITY;
+			else
 			{
-				rlim.rlim_cur = rlim.rlim_max;
+				if (rlim.rlim_cur < rlim.rlim_max)
+				{
+					rlim.rlim_cur = rlim.rlim_max;
+				}
 			}
+			setrlimit(RLIMIT_CORE, &rlim);
 		}
-		setrlimit(RLIMIT_CORE, &rlim);
-	}
 	)
 
 #ifdef AIX_SYSTRACE_ENABLE
diff --git a/sr_unix/gtm_icu.c b/sr_unix/gtm_icu.c
index 5847bd9..dea46d1 100644
--- a/sr_unix/gtm_icu.c
+++ b/sr_unix/gtm_icu.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -163,7 +163,7 @@ static boolean_t parse_gtm_icu_version(char *icu_ver_buf, int len, char **major_
 	{
 		/* Construct the first part of the ICUVERLT36 error message. */
 		SPRINTF(tmp_errstr, "%s%s", GTM_ICU_VERSION, GTM_ICU_VERSION_SUFFIX);
-		rts_error(VARLSTCNT(6) ERR_ICUVERLT36, 4, LEN_AND_STR(tmp_errstr), major_ver, minor_ver);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ICUVERLT36, 4, LEN_AND_STR(tmp_errstr), major_ver, minor_ver);
 	}
 	return TRUE;
 }
@@ -201,7 +201,7 @@ void gtm_icu_init(void)
 	locale = setlocale(LC_CTYPE, "");
 	chset = nl_langinfo(CODESET);
 	if ((NULL == locale) || (NULL == chset) || ((0 != strcasecmp(chset, "utf-8")) && (0 != strcasecmp(chset, "utf8"))))
-		rts_error(VARLSTCNT(4) ERR_NONUTF8LOCALE, 2, LEN_AND_STR(chset));
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_NONUTF8LOCALE, 2, LEN_AND_STR(chset));
 	/* By default, GT.M will henceforth expect that ICU has been built with symbol renaming disabled. If that is not the case,
 	 * GT.M can be notified of this through an environment variable (macro GTM_ICU_VERSION).  The variable should contain the
 	 * icu version number formatted as "<major-ver>.<minor-ver>". Example would be "3.6" to indicate ICU 3.6.
@@ -266,8 +266,8 @@ void gtm_icu_init(void)
 	search_path_ptr = search_paths;
 	while(-1 == loadquery(L_GETLIBPATH, search_path_ptr, prev_dyn_size))
 	{
-		if (ENOMEM != errno)
-			GTMASSERT;	/* We don't expect loadquery to fail for reason other than ENOMEM */
+		/* We don't expect loadquery to fail for reason other than ENOMEM */
+		assertpro(ENOMEM == errno);
 		/* If the previous call to loadquery fails and if it's because the input buffer's length was not
 		 * enough for loadquery to fill the library search paths, then do a malloc equal to double the previous
 		 * size and call loadquery again. It's relatively unlikely that this condition would be reached
@@ -308,7 +308,8 @@ void gtm_icu_init(void)
 		free(dyn_search_paths);
 	/* If each_libpath is NULL then we were not able to look for libicuio.a in the loader search path */
 	if (NULL == each_libpath)
-		rts_error(VARLSTCNT(8) ERR_DLLNOOPEN, 2, LEN_AND_STR(libname), ERR_TEXT, 2, LEN_AND_LIT(ICU_NOT_FOUND_ERR));
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DLLNOOPEN, 2, LEN_AND_STR(libname),
+				ERR_TEXT, 2, LEN_AND_LIT(ICU_NOT_FOUND_ERR));
 	libname = buf;
 	handle = dlopen(libname, ICU_LIBFLAGS | RTLD_MEMBER);
 #else
@@ -322,14 +323,15 @@ void gtm_icu_init(void)
 		 * instead of libicuio36.0.so. Try dlopen with this new naming scheme as well.
 		 * Below SNPRINTF converts /usr/local/lib64/libicuio36.0.a to /usr/local/lib64/libicuio36.0.a(libicuio.so)
 		 */
-		SNPRINTF(buf, ICU_LIBNAME_LEN, "%s(%s.so)", real_path, ICU_LIBNAME_ROOT);
-		libname = buf;
+		SNPRINTF(temp_path, ICU_LIBNAME_LEN, "%s(%s.so)", real_path, ICU_LIBNAME_ROOT);
+		libname = temp_path;
 		handle = dlopen(libname, ICU_LIBFLAGS | RTLD_MEMBER);
 		if (NULL == handle)
 		{
-			COPY_DLLERR_MSG(err_str, err_msg); /* overwrites the previous error */
+			libname = buf;
 #		endif
-			rts_error(VARLSTCNT(8) ERR_DLLNOOPEN, 2, LEN_AND_STR(libname), ERR_TEXT, 2, LEN_AND_STR(err_msg));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DLLNOOPEN, 2, LEN_AND_STR(libname),
+					ERR_TEXT, 2, LEN_AND_STR(err_msg));
 #		ifdef _AIX
 		}
 #		endif
@@ -340,8 +342,7 @@ void gtm_icu_init(void)
 	 * where all symbols would have been brought in by previous dlopen() with the RTLD_GLOBAL flag.
 	 */
 	handle = dlopen(NULL, ICU_LIBFLAGS);
-	if (NULL == handle)
-		GTMASSERT;
+	assertpro(handle);
 #	endif
 	assert(((-1 != major_ver_len) && (-1 != minor_ver_len)) || !gtm_icu_ver_defined);
 	DEBUG_ONLY(symbols_renamed = -1;)
@@ -389,7 +390,7 @@ void gtm_icu_init(void)
 			if (NULL == fptr)
 			{
 				COPY_DLLERR_MSG(err_str, err_msg);
-				rts_error(VARLSTCNT(8) ERR_ICUSYMNOTFOUND, 2, LEN_AND_STR(cur_icu_fname),
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ICUSYMNOTFOUND, 2, LEN_AND_STR(cur_icu_fname),
 					ERR_TEXT, 2, LEN_AND_STR(err_msg));
 			}
 			if (0 == findx)	/* record the fact that the symbols ARE renamed */
@@ -415,7 +416,8 @@ void gtm_icu_init(void)
 			{
 				/* Construct the first part of the ICUVERLT36 error message. */
 				SPRINTF(tmp_errstr, "%s%s", ICU_LIBNAME, ICU_LIBNAME_SUFFIX);
-				rts_error(VARLSTCNT(6) ERR_ICUVERLT36, 4, LEN_AND_STR(tmp_errstr), icu_version[0], icu_version[1]);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ICUVERLT36, 4,
+						LEN_AND_STR(tmp_errstr), icu_version[0], icu_version[1]);
 			}
 		}
 	}
diff --git a/sr_unix/gtm_ipc.h b/sr_unix/gtm_ipc.h
index 87c26f6..a76c82d 100644
--- a/sr_unix/gtm_ipc.h
+++ b/sr_unix/gtm_ipc.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Serivces, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Serivces, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,12 +25,15 @@
 
 #define JNLPOOL_SHMDT(RC, SAVE_ERRNO)				\
 {								\
+	jnlpool_ctl_ptr_t save_jnlpool_ctl;			\
+								\
 	SAVE_ERRNO = 0; /* clear any left-over value */		\
 	assert(NULL != jnlpool_ctl);				\
 	DEFER_INTERRUPTS(INTRPT_IN_SHMDT);			\
-	RC = SHMDT(jnlpool.jnlpool_ctl);			\
-	SAVE_ERRNO = errno;					\
+	save_jnlpool_ctl = jnlpool.jnlpool_ctl;			\
 	jnlpool_ctl = jnlpool.jnlpool_ctl = NULL;		\
+	RC = SHMDT(save_jnlpool_ctl);				\
+	SAVE_ERRNO = errno;					\
 	ENABLE_INTERRUPTS(INTRPT_IN_SHMDT);			\
 }
 
diff --git a/sr_unix/gtm_logicals.h b/sr_unix/gtm_logicals.h
index 94a8a01..830476e 100644
--- a/sr_unix/gtm_logicals.h
+++ b/sr_unix/gtm_logicals.h
@@ -29,7 +29,9 @@
 #define	GTM_TPRESTART_LOG_DELTA		"$gtm_tprestart_log_delta"
 #define	GTM_TPRESTART_LOG_LIMIT		"$gtm_tprestart_log_first"
 #define	GTM_ZMAXTPTIME			"$gtm_zmaxtptime"
-
+/* 	GTM_DIRTREE_COLLHDR_ALWAYS	"$gtm_dirtree_collhdr_always"	dbg-only use in gvcst_put hence no #define for it or
+									else the D9I10002703 subtest will need changes for this.
+									*/
 /* White-box testing */
 #define	GTM_WHITE_BOX_TEST_CASE_COUNT	"$gtm_white_box_test_case_count"
 #define	GTM_WHITE_BOX_TEST_CASE_ENABLE	"$gtm_white_box_test_case_enable"
@@ -111,6 +113,7 @@
 /* Miscellaneous */
 #define GTM_ERROR_ON_JNL_FILE_LOST	"$gtm_error_on_jnl_file_lost"
 #define GTM_ETRAP			"$gtm_etrap"
+#define	GTM_LINK			"$gtm_link"
 #define	GTM_LOG_ENV			"$gtm_log"
 #define	GTM_LVNULLSUBS			"$gtm_lvnullsubs"
 #define	GTM_NOCENABLE			"$gtm_nocenable"
diff --git a/sr_unix/gtm_main.c b/sr_unix/gtm_main.c
index f91086f..0feca08 100644
--- a/sr_unix/gtm_main.c
+++ b/sr_unix/gtm_main.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -46,52 +46,63 @@
 #include "gtm_conv.h"
 #endif
 #ifdef GTM_CRYPT
-#include "gtmci.h"
 #include "gtmcrypt.h"
-#define GTM_PASSWD "gtm_passwd"
+#endif
+#ifdef GTM_TLS
+#include "gtm_tls.h"
 #endif
 
 GBLREF	IN_PARMS			*cli_lex_in_ptr;
 GBLREF	char				cli_token_buf[];
 GBLREF	char				cli_err_str[];
 GBLREF	CLI_ENTRY			mumps_cmd_ary[];
-GTMTRIG_DBG_ONLY(GBLREF	ch_ret_type	(*ch_at_trigger_init)();)
+GBLREF	boolean_t			skip_dbtriggers;
+#if defined (GTM_TRIGGER) && (DEBUG)
+GBLREF	ch_ret_type			(*ch_at_trigger_init)();
+#endif
 #ifdef UNICODE_SUPPORTED
 GBLREF	u_casemap_t 			gtm_strToTitle_ptr;		/* Function pointer for gtm_strToTitle */
 #endif
 
 GBLDEF	CLI_ENTRY			*cmd_ary = &mumps_cmd_ary[0]; /* Define cmd_ary to be the MUMPS specific cmd table */
-GBLREF	boolean_t			skip_dbtriggers;
+
+#define GTMCRYPT_ERRLIT			"during GT.M startup"
 
 #ifdef __osf__
-	/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
-	 * specify compiler and link editor options in order to use (and allocate) 32-bit pointers.  However, since C is
-	 * the only exception and, in particular because the operating system does not support such an exception, the argv
-	 * array passed to the main program is an array of 64-bit pointers.  Thus the C program needs to declare argv[]
-	 * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
-	 */
+ /* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
+  * specify compiler and link editor options in order to use (and allocate) 32-bit pointers.  However, since C is
+  * the only exception and, in particular because the operating system does not support such an exception, the argv
+  * array passed to the main program is an array of 64-bit pointers.  Thus the C program needs to declare argv[]
+  * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
+  */
 # pragma pointer_size (save)
 # pragma pointer_size (long)
 #endif
-GBLDEF char 		**gtmenvp;
-#ifdef GTM_CRYPT
+
+GBLDEF	char 				**gtmenvp;
+
 error_def(ERR_CRYPTDLNOOPEN);
 error_def(ERR_CRYPTDLNOOPEN2);
 error_def(ERR_CRYPTINIT);
 error_def(ERR_CRYPTINIT2);
-#endif
+error_def(ERR_TEXT);
+error_def(ERR_TLSDLLNOOPEN);
+error_def(ERR_TLSINIT);
+
 int gtm_main (int argc, char **argv, char **envp)
 #ifdef __osf__
 # pragma pointer_size (restore)
 #endif
 {
-	char			*ptr;
+	char			*ptr, *eq, **p;
 	int             	eof, parse_ret;
 #	ifdef GTM_CRYPT
-	char			*gtm_passwd;
-	const char		*gtmcrypt_errlit = "during GT.M startup";
 	int			gtmcrypt_errno;
 #	endif
+#	ifdef GTM_SOCKET_SSL_SUPPORT
+	int			status;
+	char			tlsid_env_name[MAX_TLSID_LEN * 2];
+#	endif
 	DCL_THREADGBL_ACCESS;
 
 	GTM_THREADGBL_INIT;
@@ -133,7 +144,7 @@ int gtm_main (int argc, char **argv, char **envp)
 	cli_lex_in_ptr->tp = cli_lex_in_ptr->in_str;
 	parse_ret = parse_cmd();
 	if (parse_ret && (EOF != parse_ret))
-		rts_error(VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));
 	if (cli_present("DIRECT_MODE"))
 		invocation_mode = MUMPS_DIRECT;
 	else if (cli_present("RUN"))
@@ -141,24 +152,67 @@ int gtm_main (int argc, char **argv, char **envp)
 	gtm_chk_dist(argv[0]);
 	/* this should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup   */
 	init_gtm();
-#	ifdef GTM_CRYPT
-	if (MUMPS_COMPILE != invocation_mode
-	    && (NULL != (gtm_passwd = (char *)getenv(GTM_PASSWD)))
-	    && (0 == strlen(gtm_passwd)))
+#	if defined(GTM_CRYPT) || defined(GTM_TLS)
+	if (MUMPS_COMPILE != invocation_mode)
 	{
-		INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno);
-		if (0 != gtmcrypt_errno)
+		if ((NULL != (ptr = (char *)getenv(GTM_PASSWD_ENV))) && (0 == strlen(ptr)))
 		{
-			CLEAR_CRYPTERR_MASK(gtmcrypt_errno);
-			assert(!IS_REPEAT_MSG_MASK(gtmcrypt_errno));
-			assert((ERR_CRYPTDLNOOPEN == gtmcrypt_errno) || (ERR_CRYPTINIT == gtmcrypt_errno));
-			if (ERR_CRYPTDLNOOPEN == gtmcrypt_errno)
-				gtmcrypt_errno = ERR_CRYPTDLNOOPEN2;
-			else if (ERR_CRYPTINIT == gtmcrypt_errno)
-				gtmcrypt_errno = ERR_CRYPTINIT2;
-			gtmcrypt_errno = SET_CRYPTERR_MASK(gtmcrypt_errno);
-			GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, STRLEN(gtmcrypt_errlit), gtmcrypt_errlit);
+			INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno);
+			if (0 != gtmcrypt_errno)
+			{
+				CLEAR_CRYPTERR_MASK(gtmcrypt_errno);
+				assert(!IS_REPEAT_MSG_MASK(gtmcrypt_errno));
+				assert((ERR_CRYPTDLNOOPEN == gtmcrypt_errno) || (ERR_CRYPTINIT == gtmcrypt_errno));
+				if (ERR_CRYPTDLNOOPEN == gtmcrypt_errno)
+					gtmcrypt_errno = ERR_CRYPTDLNOOPEN2;
+				else if (ERR_CRYPTINIT == gtmcrypt_errno)
+					gtmcrypt_errno = ERR_CRYPTINIT2;
+				gtmcrypt_errno = SET_CRYPTERR_MASK(gtmcrypt_errno);
+				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, SIZEOF(GTMCRYPT_ERRLIT) - 1, GTMCRYPT_ERRLIT);
+			}
+		}
+#		ifdef GTM_SOCKET_SSL_SUPPORT
+		/* The below logic is for prefetching the password for TLS identifiers that may have been set in the environment.
+		 * But, since SSL support for Socket devices is not yet implemented, this logic need not be enabled as of this
+		 * writing. When SSL support for socket devices is implemented, the surrounding #ifdef can be removed.
+		 */
+		if (NULL != getenv("gtmcrypt_config"))
+		{	/* Environment is configured for SSL/TLS (and/or encryption). Check if any environment variable of the form
+			 * `gtmtls_passwd_*' is set to NULL string. If so, nudge the SSL/TLS library to read password(s) from the
+			 * user.
+			 */
+			for (p = envp; *p; p++)
+			{
+				ptr = *p;
+				if (0 == MEMCMP_LIT(ptr, GTMTLS_PASSWD_ENV_PREFIX))
+				{	/* At least one environment variable of $gtmtls_passwd_* is found. */
+					eq = strchr(ptr, '=');
+					if (0 != strlen(eq + 1))
+						break; /* Set to non-empty string. No need to initialize the library now. */
+					/* Set to empty string. */
+					if (NULL == tls_ctx)
+					{
+						if (SS_NORMAL != (status = gtm_tls_loadlibrary()))
+						{
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0,
+									ERR_TEXT, 2, LEN_AND_STR(dl_err));
+						}
+						if (NULL == (tls_ctx = gtm_tls_init(GTM_TLS_API_VERSION,
+											GTMTLS_OP_INTERACTIVE_MODE)))
+						{
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0,
+									ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+						}
+					}
+					assert(NULL != tls_ctx);
+					assert((MAX_TLSID_LEN * 2) > (int)(eq - ptr));
+					memcpy(tlsid_env_name, ptr, (int)(eq - ptr));
+					tlsid_env_name[(int)(eq - ptr)] = '\0';
+					gtm_tls_prefetch_passwd(tls_ctx, tlsid_env_name);
+				}
+			}
 		}
+#		endif
 	}
 #	endif
 	dm_start();
diff --git a/sr_unix/gtm_permissions.c b/sr_unix/gtm_permissions.c
index 94958f3..e4d5ab9 100644
--- a/sr_unix/gtm_permissions.c
+++ b/sr_unix/gtm_permissions.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -89,12 +89,15 @@ int gtm_member_group_id(int uid, int gid)
 }
 
 /* Based on security rules in this routine, set *group_id of the group to be used
-   for shared resources, journals, and temp files.  If a no change then it will be set to -1.
-   Also, set *perm to the permissions to be used.  The precalculated world_write_perm (need to
-   change name to masked_permissions) is to be used in the one case indicated below.
-
-   Populates pdd struct and returns negative value for error, returns non-negative for success. */
-int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enum perm_target_types target_type,
+ * for shared resources, journals, and temp files.  If a no change then it will be set to -1.
+ * Also, set *perm to the permissions to be used.  The precalculated world_write_perm (need to
+ * change name to masked_permissions) is to be used in the one case indicated below.
+ * If the user is root, the *user_id may be set to a target uid if needed; otherwise, it will
+ * be set to -1.
+ *
+ * Populates pdd struct and returns negative value for error, returns non-negative for success.
+ */
+int gtm_permissions(struct stat *stat_buff, int *user_id, int *group_id, int *perm, enum perm_target_types target_type,
 			   struct perm_diag_data *pdd)
 {
 	int		lib_gid = -1;
@@ -125,58 +128,65 @@ int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enu
 
 	/* set default gid */
 #ifdef __osf__
+	*user_id = process_uid;
 	*group_id = process_gid;
 #else
+	*user_id = -1;
 	*group_id = -1;
 #endif
 	/* set no permissions as a default in case none of our conditions match */
 	*perm = 0;
 
+	assertpro((PERM_FILE == target_type) || (PERM_IPC == target_type));
 	if (0006 & stat_buff->st_mode)
 	{
 		/* file is accessible to other */
-		if (opener_in_file_group)		/* otherwise, use default gid */
+		if (opener_is_root)					/* otherwise, use default uid */
+			*user_id = stat_buff->st_uid;
+		if (opener_in_file_group || opener_is_root)		/* otherwise, use default gid */
 			*group_id = stat_buff->st_gid;
 		if (PERM_FILE == target_type)
-			*perm = (!opener_in_file_group && (0020 & stat_buff->st_mode)) ? 0666 : (stat_buff->st_mode & 0666);
+			*perm = (!opener_in_file_group && !opener_is_root && (0020 & stat_buff->st_mode))
+					? 0666 : (stat_buff->st_mode & 0666);
 		else if (PERM_IPC == target_type)
 			*perm = 0666;
-		else
-			assertpro(FALSE);
 	} else if (0600 & stat_buff->st_mode && !(0066 & stat_buff->st_mode))
 	{
 		/* file is only user accessible */
 		/* use default group */
 		assert(opener_is_file_owner || opener_is_root);
+		if (opener_is_root)					/* otherwise, use default uid/gid */
+		{
+			*user_id = stat_buff->st_uid;
+			*group_id = stat_buff->st_gid;
+		}
 		if (PERM_FILE == target_type)
 			*perm = 0600;			/* read write for user */
 		else if (PERM_IPC == target_type)
 			*perm = 0600;			/* read write for user */
-		else
-			assertpro(FALSE);
 	} else if (0060 & stat_buff->st_mode && !(0606 & stat_buff->st_mode))
 	{
 		/* file is only group accessible */
+		if (opener_is_root)					/* otherwise, use default uid */
+			*user_id = stat_buff->st_uid;
 		*group_id = stat_buff->st_gid;			/* use file group */
 		assert(opener_in_file_group || opener_is_root);
 		if (PERM_FILE == target_type)
 			*perm = stat_buff->st_mode & 0060;	/* use file permissions, masked for group read/write */
-		else if (PERM_IPC == target_type)
+		if (PERM_IPC == target_type)
 			*perm = 0660;			/* read/write for group - all readers need write for ipc */
-		else
-			assertpro(FALSE);
 	} else
 	{
 		/* file is accessible to user and group */
-		if (opener_is_file_owner && opener_in_file_group)
+		if (opener_is_file_owner && opener_in_file_group || opener_is_root)
 		{
+			if (opener_is_root)					/* otherwise, use default uid */
+				*user_id = stat_buff->st_uid;
 			*group_id = stat_buff->st_gid;		/* use file group */
 			if (PERM_FILE == target_type)
 				*perm = stat_buff->st_mode & 0660;	/* use file permissions, masked for user/group read/write */
-			else if (PERM_IPC == target_type)
+			if (PERM_IPC == target_type)
 				*perm = 0660;			/* read/write for user/group - all readers need write for ipc */
-			else
-				assertpro(FALSE);
 		} else
 		{
 			if (opener_is_file_owner && !opener_in_file_group)
@@ -184,13 +194,11 @@ int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enu
 				if (gtm_group_restricted)
 				{
 					*group_id = lib_gid;			/* use restricted group */
-					assert(gtm_member_group_id(process_uid, *group_id) || opener_is_root);
+					assert(gtm_member_group_id(process_uid, *group_id));
 					if (PERM_FILE == target_type)
 						*perm = 0660;			/* user/group read/write */
-					else if (PERM_IPC == target_type)
+					if (PERM_IPC == target_type)
 						*perm = 0660;	/* read/write for user/group - all readers need write for ipc */
-					else
-						assertpro(FALSE);
 				} else
 				{
 					/* use default group */
@@ -198,32 +206,26 @@ int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enu
 						*perm = 0666;			/* read/write for all */
 					else if (PERM_IPC == target_type)
 						*perm = 0666;	/* read/write for all - all readers need write for ipc */
-					else
-						assertpro(FALSE);
 				}
-			} else if (!opener_is_file_owner && opener_in_file_group || opener_is_root)
+			} else if (!opener_is_file_owner && opener_in_file_group)
 			{
-				/* opener has access either via file group membership or because he is root */
+				/* opener has access either via file group membership */
 				if (owner_in_file_group)
 				{
 					*group_id = stat_buff->st_gid;		/* use file group */
 					if (PERM_FILE == target_type)
 						*perm = stat_buff->st_mode & 0660;	/* use masked file permissions */
-					else if (PERM_IPC == target_type)
+					if (PERM_IPC == target_type)
 						*perm = 0660;	/* read/write for user/group - all readers need write for ipc */
-					else
-						assertpro(FALSE);
 
 				} else if (gtm_group_restricted)
 				{
 					*group_id = lib_gid;			/* use restricted group */
-					assert(gtm_member_group_id(process_uid, *group_id) || opener_is_root);
+					assert(gtm_member_group_id(process_uid, *group_id));
 					if (PERM_FILE == target_type)
 						*perm = 0660;			/* user/group read/write */
-					else if (PERM_IPC == target_type)
+					if (PERM_IPC == target_type)
 						*perm = 0660;	/* read/write for user/group - all readers need write for ipc */
-					else
-						assertpro(FALSE);
 				} else
 				{
 					*group_id = stat_buff->st_gid;		/* use file group */
@@ -231,8 +233,6 @@ int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enu
 						*perm = 0666;	/* read/write for all - ensure file owner read/write access */
 					else if (PERM_IPC == target_type)
 						*perm = 0666;	/* read/write for all - all readers need write for ipc */
-					else
-						assertpro(FALSE);
 				}
 			}
 		}
diff --git a/sr_unix/gtm_permissions.h b/sr_unix/gtm_permissions.h
index e7b2a7a..cc37088 100644
--- a/sr_unix/gtm_permissions.h
+++ b/sr_unix/gtm_permissions.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -45,7 +45,7 @@ error_def(ERR_PERMGENDIAG);
 
 int gtm_get_group_id(struct stat *stat_buff);
 int gtm_member_group_id(int uid, int gid);
-int gtm_set_group_and_perm(struct stat *stat_buff, int *group_id, int *perm, enum perm_target_types target_type,
-			   struct perm_diag_data *pdd);
+int gtm_permissions(struct stat *stat_buff, int *user_id, int *group_id, int *perm, enum perm_target_types target_type,
+			struct perm_diag_data *pdd);
 
 #endif /* GTM_PERMISSIONS */
diff --git a/sr_unix/gtm_startup_chk.c b/sr_unix/gtm_startup_chk.c
index d327451..6d73477 100644
--- a/sr_unix/gtm_startup_chk.c
+++ b/sr_unix/gtm_startup_chk.c
@@ -60,17 +60,15 @@ int gtm_chk_dist(char *image)
 	int		status;
 	char 		mbuff[MAX_FBUFF + 1];
 	parse_blk	pblk;
-	char		*dist;
 
-	if (NULL != (dist = (char *)GETENV(GTM_DIST)))
+	if (STRLEN(gtm_dist))
 	{
 		assert(IS_VALID_IMAGE && (n_image_types > image_type));	/* assert image_type is initialized */
-		if ((GTM_PATH_MAX - 2) <= (STRLEN(dist) + gtmImageNames[image_type].imageNameLen))
+		if ((GTM_PATH_MAX - 2) <= (STRLEN(gtm_dist) + gtmImageNames[image_type].imageNameLen))
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_DISTPATHMAX, 1,
 					GTM_PATH_MAX - gtmImageNames[image_type].imageNameLen - 2);
 	} else
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_GTMDISTUNDEF);
-	memcpy(gtm_dist, dist, STRLEN(dist));
 	memset(&pblk, 0, SIZEOF(pblk));
 	pblk.buffer = mbuff;
 	pblk.buff_size = MAX_FBUFF;
diff --git a/sr_unix/gtm_test_install.csh b/sr_unix/gtm_test_install.csh
index 08ade96..69bec11 100644
--- a/sr_unix/gtm_test_install.csh
+++ b/sr_unix/gtm_test_install.csh
@@ -69,11 +69,16 @@ setenv gtm_dist $save_gtm_dist
 
 $gtm_dist/mupip journal -extract -forward gtm.mjl 				>& mupip.out
 env gtmgbldir=$gtm_dist/test_gtm/mumps.gld $gtm_dist/mupip integ -reg "*"	>& integ.out
+set mupip_status = $status
 # output the change lines
 echo ""							>>&! $gtm_dist/gtm_test_install.out
 echo "Global changes in the gtm.mjl file:"		>>&! $gtm_dist/gtm_test_install.out
 grep = gtm.mjf | awk -F\\ '{print ($NF)}'		>>&! $gtm_dist/gtm_test_install.out
-cat integ.out						>>&! $gtm_dist/gtm_test_install.out
+if (0 != $mupip_status) then
+	echo "Error: mupip integ returned $status status instead of 0" >>&! $gtm_dist/gtm_test_install.out
+else
+	echo "mupip integ returned a 0 status - as expected" >>&! $gtm_dist/gtm_test_install.out
+endif
 
 cd $gtm_dist
 
@@ -222,7 +227,7 @@ EOF
 	grep ZCHSET gtm.out				>>&! $save_gtm_dist/gtm_test_install.out
 	# test gtmsecshr with an alternate user
 	set XCMD='do ^GTMHELP("",$ztrnlnm("gtm_dist")_"/gtmhelp.gld")'
-	su - gtmtest1 -c "env LD_LIBRARY_PATH=$libpath LC_ALL=$LC_ALL gtm_chset=UTF-8 gtm_dist=$gtm_dist gtmroutines='$gtmroutines' $gtm_dist/mumps -run %XCMD '${XCMD:q}' < /dev/null" > gtmtest.out   #BYPASSOK line length
+	su - gtmtest -c "env LD_LIBRARY_PATH=$libpath LC_ALL=$LC_ALL gtm_chset=UTF-8 gtm_dist=$gtm_dist gtmroutines='$gtmroutines' $gtm_dist/mumps -run %XCMD '${XCMD:q}' < /dev/null" > gtmtest.out   #BYPASSOK line length
 	# if we see the 'Topic? ' prompt, all is well
 	grep -q '^Topic. $' gtmtest.out
 	if ( $status ) cat gtmtest.out			>>&! $save_gtm_dist/gtm_test_install.out
@@ -231,13 +236,18 @@ EOF
 
 	$save_gtm_dist/mupip journal -extract -forward gtm.mjl					>& mupip.out
 	env gtmgbldir=$save_gtm_dist/test_gtm/mumps.gld $save_gtm_dist/mupip integ -reg "*"	>& integ.out
-
+	set mupip_status = $status
 	# output the change lines
 	echo ""						>>&! $save_gtm_dist/gtm_test_install.out
 	echo "Global changes in the gtm.mjl file:"	>>&! $save_gtm_dist/gtm_test_install.out
 	awk -F\\ '/=/{print ($NF)}' gtm.mjf		>>&! $save_gtm_dist/gtm_test_install.out
-	cat integ.out					>>&! $save_gtm_dist/gtm_test_install.out
+	if (0 != $mupip_status) then
+		echo "Error: mupip integ returned $status status instead of 0" >>&! $save_gtm_dist/gtm_test_install.out
+	else
+		echo "mupip integ returned a 0 status - as expected" >>&! $save_gtm_dist/gtm_test_install.out
+	endif
 	$gtm_dist/gtmsecshr				>>&! $save_gtm_dist/gtm_test_install.out
+	$gtm_com/IGS $gtm_dist/gtmsecshr "STOP"
 	cd $save_gtm_dist
 
 else
@@ -253,19 +263,7 @@ ZCHSET= UTF-8
 Global changes in the gtm.mjl file:
 ^a="1"
 ^b="2"
-
-
-Integ of region DEFAULT
-
-No errors detected by integ.
-
-Type           Blocks         Records          % Used      Adjacent
-
-Directory           2               3           0.756            NA
-Index               2               2           0.585             2
-Data                2               2           0.585             2
-Free             4994              NA              NA            NA
-Total            5000               7              NA             4
+mupip integ returned a 0 status - as expected
 EOF
 	#  END  - Fake the UTF-8 mode run for platforms that don't support it
 endif
diff --git a/sr_unix/gtm_test_install.txt b/sr_unix/gtm_test_install.txt
index 6bdfff1..58bbd18 100644
--- a/sr_unix/gtm_test_install.txt
+++ b/sr_unix/gtm_test_install.txt
@@ -1,6 +1,6 @@
 #################################################################
 #								#
-#	Copyright 2011 Fidelity Information Services, Inc       #
+#	Copyright 2011, 2013 Fidelity Information Services, Inc       #
 #								#
 #	This source code contains the intellectual property	#
 #	of its copyright holder(s), and is made available	#
@@ -31,16 +31,10 @@ GTM>
 
 Additional information available:
 
-About_GTM   BREAK       CLOSE       DO          ELSE        FOR
-Functions   GOTO        HALT        HANG        IF          Intr_Spe_Vars
-In_Out_Processing       JOB         KILL        Lang_Features_M
-LOCK        MERGE       M_Utility_Rtns          NEW         OPEN
-Opr_Dbg_Dir_Mode        Prog_Dev_Cycle          QUIT        READ
-SET         TCOMMIT     TRESTART    TROLLBACK   TSTART      USE
-VIEW        WRITE       XECUTE      ZALLOCATE   ZBREAK      ZCOMPILE
-ZCONTINUE   ZDEALLOCATE ZEDIT       ZGOTO       ZHELP       ZKILL
-ZLINK       ZMESSAGE    ZPRINT      ZSHOW       ZSTEP       ZSYSTEM
-ZTCOMMIT    ZTSTART     ZWITHDRAW   ZWRITE
+About_GT.M  Commands    Err_Processing          Functions   Integrate_External
+Internationalization    IO_Processing           ISV         Language_Extensions
+M_Lang_Features         Opr_Dbg_Dir_Mode        Program_Cycle
+Triggers    Utility_Routines
 
 Topic?
 
@@ -54,19 +48,7 @@ ZCHSET= M
 Global changes in the gtm.mjl file:
 ^a="1"
 ^b="2"
-
-
-Integ of region DEFAULT
-
-No errors detected by integ.
-
-Type           Blocks         Records          % Used      Adjacent
-
-Directory           2               3           0.756            NA
-Index               2               2           0.585             2
-Data                2               2           0.585             2
-Free             4994              NA              NA            NA
-Total            5000               7              NA             4
+mupip integ returned a 0 status - as expected
 
 GTM>
 M
@@ -81,16 +63,4 @@ ZCHSET= UTF-8
 Global changes in the gtm.mjl file:
 ^a="1"
 ^b="2"
-
-
-Integ of region DEFAULT
-
-No errors detected by integ.
-
-Type           Blocks         Records          % Used      Adjacent
-
-Directory           2               3           0.756            NA
-Index               2               2           0.585             2
-Data                2               2           0.585             2
-Free             4994              NA              NA            NA
-Total            5000               7              NA             4
+mupip integ returned a 0 status - as expected
diff --git a/sr_unix/gtm_tls.c b/sr_unix/gtm_tls.c
new file mode 100644
index 0000000..e07eb87
--- /dev/null
+++ b/sr_unix/gtm_tls.c
@@ -0,0 +1,159 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gtm_tls.h"
+#include "have_crit.h"
+
+/* This file defines wrapper functions that defer interrupts, invoke the SSL/TLS function and enable interrupts. This guarantees
+ * that system calls invoked by the SSL/TLS library (or OpenSSL) are not interrupted by internal (like SIGALRM) or external
+ * signals (like SIGTERM) thereby avoiding any deadlocks. Note that this file has to be maintained in sync with gtm_tls_interface.h.
+ */
+
+const char		*intrsafe_gtm_tls_get_error(void)
+{
+	const char	*rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_get_error_fptr)();
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_errno(void)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_errno_fptr)();
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+gtm_tls_ctx_t		*intrsafe_gtm_tls_init(int version, int flags)
+{
+	gtm_tls_ctx_t	*rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_init_fptr)(version, flags);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+void			intrsafe_gtm_tls_prefetch_passwd(gtm_tls_ctx_t *tls_ctx, char *env_name)
+{
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	(*gtm_tls_prefetch_passwd_fptr)(tls_ctx, env_name);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+}
+
+gtm_tls_socket_t	*intrsafe_gtm_tls_socket(gtm_tls_ctx_t *ctx, gtm_tls_socket_t *prev_socket, int sockfd, char *id, int flags)
+{
+	gtm_tls_socket_t	*rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_socket_fptr)(ctx, prev_socket, sockfd, id, flags);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_connect(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_connect_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_accept(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_accept_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_renegotiate(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_renegotiate_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_get_conn_info(gtm_tls_socket_t *socket, gtm_tls_conn_info *conn_info)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_get_conn_info_fptr)(socket, conn_info);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_send(gtm_tls_socket_t *socket, char *buf, int send_len)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_send_fptr)(socket, buf, send_len);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_recv(gtm_tls_socket_t *socket, char *buf, int recv_len)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_recv_fptr)(socket, buf, recv_len);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+int			intrsafe_gtm_tls_cachedbytes(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	rv = (*gtm_tls_cachedbytes_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	return rv;
+}
+
+void			intrsafe_gtm_tls_socket_close(gtm_tls_socket_t *socket)
+{
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	(*gtm_tls_socket_close_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+}
+
+void			intrsafe_gtm_tls_session_close(gtm_tls_socket_t **socket)
+{
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	(*gtm_tls_session_close_fptr)(socket);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+}
+
+void			intrsafe_gtm_tls_fini(gtm_tls_ctx_t **ctx)
+{
+	DEFER_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+	(*gtm_tls_fini_fptr)(ctx);
+	ENABLE_INTERRUPTS(INTRPT_IN_TLS_FUNCTION);
+}
+
diff --git a/sr_unix/gtm_tls.h b/sr_unix/gtm_tls.h
new file mode 100644
index 0000000..6a26e8e
--- /dev/null
+++ b/sr_unix/gtm_tls.h
@@ -0,0 +1,80 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#ifndef _GTM_TLS_H
+#define _GTM_TLS_H
+
+#define gtm_tls_get_error		(*gtm_tls_get_error_fptr)
+#define gtm_tls_errno			(*gtm_tls_errno_fptr)
+#define gtm_tls_init			(*gtm_tls_init_fptr)
+#define gtm_tls_prefetch_passwd		(*gtm_tls_prefetch_passwd_fptr)
+#define gtm_tls_socket			(*gtm_tls_socket_fptr)
+#define gtm_tls_connect			(*gtm_tls_connect_fptr)
+#define gtm_tls_accept			(*gtm_tls_accept_fptr)
+#define gtm_tls_renegotiate		(*gtm_tls_renegotiate_fptr)
+#define gtm_tls_get_conn_info		(*gtm_tls_get_conn_info_fptr)
+#define gtm_tls_send			(*gtm_tls_send_fptr)
+#define gtm_tls_recv			(*gtm_tls_recv_fptr)
+#define gtm_tls_cachedbytes		(*gtm_tls_cachedbytes_fptr)
+#define gtm_tls_socket_close		(*gtm_tls_socket_close_fptr)
+#define gtm_tls_session_close		(*gtm_tls_session_close_fptr)
+#define gtm_tls_fini			(*gtm_tls_fini_fptr)
+
+/* It's important that the "gtm_tls_interface.h" include should be *after* the above macro definitions. This way, the function
+ * prototypes defined in the header file will automatically be expanded to function pointers saving us the trouble of explicitly
+ * defining them once again.
+ */
+#include "gtm_tls_interface.h"
+
+#undef gtm_tls_get_error
+#undef gtm_tls_errno
+#undef gtm_tls_init
+#undef gtm_tls_prefetch_passwd
+#undef gtm_tls_socket
+#undef gtm_tls_connect
+#undef gtm_tls_accept
+#undef gtm_tls_renegotiate
+#undef gtm_tls_get_conn_info
+#undef gtm_tls_send
+#undef gtm_tls_recv
+#undef gtm_tls_cachedbytes
+#undef gtm_tls_socket_close
+#undef gtm_tls_session_close
+#undef gtm_tls_fini
+
+/* Now, we need to define prototypes for wrapper functions that will be defined in GT.M to defer interrupts before invoking the
+ * corresponding TLS function. But, to avoid redefining the prototypes, include the gtm_tls_interface.h once again to automatically
+ * generate the prototypes.
+ */
+#define gtm_tls_get_error		intrsafe_gtm_tls_get_error
+#define gtm_tls_errno			intrsafe_gtm_tls_errno
+#define gtm_tls_init			intrsafe_gtm_tls_init
+#define gtm_tls_prefetch_passwd		intrsafe_gtm_tls_prefetch_passwd
+#define gtm_tls_socket			intrsafe_gtm_tls_socket
+#define gtm_tls_connect			intrsafe_gtm_tls_connect
+#define gtm_tls_accept			intrsafe_gtm_tls_accept
+#define gtm_tls_renegotiate		intrsafe_gtm_tls_renegotiate
+#define gtm_tls_get_conn_info		intrsafe_gtm_tls_get_conn_info
+#define gtm_tls_send			intrsafe_gtm_tls_send
+#define gtm_tls_recv			intrsafe_gtm_tls_recv
+#define gtm_tls_cachedbytes		intrsafe_gtm_tls_cachedbytes
+#define gtm_tls_socket_close		intrsafe_gtm_tls_socket_close
+#define gtm_tls_session_close		intrsafe_gtm_tls_session_close
+#define gtm_tls_fini			intrsafe_gtm_tls_fini
+
+#undef _GTM_TLS_INTERFACE_H	/* Allows us to include gtm_tls_interface.h twice. */
+#include "gtm_tls_interface.h"	/* BYPASSOK : intentional duplicate include. */
+
+GBLREF	gtm_tls_ctx_t			*tls_ctx;
+
+int	gtm_tls_loadlibrary(void);
+
+#endif
diff --git a/sr_unix/gtm_tls_funclist.h b/sr_unix/gtm_tls_funclist.h
new file mode 100644
index 0000000..70b442a
--- /dev/null
+++ b/sr_unix/gtm_tls_funclist.h
@@ -0,0 +1,30 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+/* Any time a new function gets added to the GT.M SSL/TLS interface, add the corresponding entry here. This file is included in
+ * `gtm_tls_loadlibrary', by appropriately, defining TLS_DEF, to generate necessary string literals and function pointers which
+ * is used to `dlsym' symbols from the SSL/TLS shared library.
+ */
+TLS_DEF(gtm_tls_get_error)
+TLS_DEF(gtm_tls_errno)
+TLS_DEF(gtm_tls_init)
+TLS_DEF(gtm_tls_prefetch_passwd)
+TLS_DEF(gtm_tls_socket)
+TLS_DEF(gtm_tls_connect)
+TLS_DEF(gtm_tls_accept)
+TLS_DEF(gtm_tls_renegotiate)
+TLS_DEF(gtm_tls_get_conn_info)
+TLS_DEF(gtm_tls_send)
+TLS_DEF(gtm_tls_recv)
+TLS_DEF(gtm_tls_cachedbytes)
+TLS_DEF(gtm_tls_socket_close)
+TLS_DEF(gtm_tls_session_close)
+TLS_DEF(gtm_tls_fini)
diff --git a/sr_unix/gtm_tls_impl.c b/sr_unix/gtm_tls_impl.c
new file mode 100644
index 0000000..be33fbf
--- /dev/null
+++ b/sr_unix/gtm_tls_impl.c
@@ -0,0 +1,869 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+
+#include <libconfig.h>
+
+#include "gtmxc_types.h"
+#include "gtmcrypt_util.h"
+
+#include "gtm_tls_interface.h"
+#include "gtm_tls_impl.h"
+
+GBLDEF	int			tls_errno;
+GBLDEF	config_t		gtm_tls_cfg;
+GBLDEF	gtmtls_passwd_list_t	*gtmtls_passwd_listhead;
+
+STATICDEF DH			*dh512, *dh1024;	/* Diffie-Hellman structures for Ephemeral Diffie-Hellman key exchange. */
+
+#define MAX_CONFIG_LOOKUP_PATHLEN	64
+
+/* Below template translates to: Arrange ciphers in increasing order of strength after excluding the following:
+ * ADH: Anonymous Diffie-Hellman Key Exchange (Since we want both encryption and authentication and ADH provides only former).
+ * LOW: Low strength ciphers.
+ * EXP: Export Ciphers.
+ * MD5 : MD5 message digest.
+ */
+#define CIPHER_LIST			"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
+
+#ifdef DEBUG_SSL
+#define SSL_DPRINT(FP, ...)		{fprintf(FP, __VA_ARGS__); fflush(FP);}	/* BYPASSOK -- cannot use FFLUSH. */
+#else
+#define SSL_DPRINT(FP, ...)
+#endif
+
+/* OpenSSL doesn't provide an easy way to convert an ASN1 time to a string format unless BIOs are used. So, use a memory BIO to
+ * write the string representation of ASN1_TIME in the said buffer.
+ */
+STATICFNDEF int format_ASN1_TIME(ASN1_TIME *tm, char *buf, int maxlen)
+{
+	BIO	*memfp;
+	int	len;
+
+	if (NULL == (memfp = BIO_new(BIO_s_mem())))
+		return -1;
+	ASN1_TIME_print(memfp, tm);
+	len = BIO_pending(memfp);
+	len = len < maxlen ? len : maxlen;
+	if (0 >= BIO_read(memfp, buf, len))
+		return -1;
+	if (0 >= BIO_free(memfp))
+		return -1;
+	buf[len] = '\0';
+	return 0;
+}
+
+STATICFNDEF int ssl_error(SSL *ssl, int err)
+{
+	int		error_code;
+	char		*errptr, *end;
+
+	error_code = SSL_get_error(ssl, err); /* generic error code */
+	switch (error_code)
+	{
+		case SSL_ERROR_ZERO_RETURN:
+			/* SSL/TLS connection has been closed gracefully. The underlying TCP/IP connection is not yet closed. The
+			 * caller should take necessary action to close the underlying transport
+			 */
+			tls_errno = ECONNRESET;
+			break;
+
+		case SSL_ERROR_SYSCALL:
+			tls_errno = errno;
+			if (0 == tls_errno)
+				tls_errno = ECONNRESET;
+			break;
+
+		case SSL_ERROR_WANT_WRITE:
+			return GTMTLS_WANT_WRITE;
+
+		case SSL_ERROR_WANT_READ:
+			return GTMTLS_WANT_READ;
+
+		case SSL_ERROR_WANT_X509_LOOKUP:
+		case SSL_ERROR_WANT_ACCEPT:
+		case SSL_ERROR_WANT_CONNECT:
+			assert(FALSE);
+
+		case SSL_ERROR_SSL:
+			errptr = gtmcrypt_err_string;
+			end = errptr + MAX_GTMCRYPT_ERR_STRLEN;
+			tls_errno = -1;
+			do
+			{
+				error_code = ERR_get_error();
+				if (0 == error_code)
+				{
+					if (errptr == gtmcrypt_err_string)
+					{
+						/* Very first call to ERR_get_error returned 0. This is very unlikely. Nevertheless
+						 * handle this by updating the error string with a generic error.
+						 */
+						UPDATE_ERROR_STRING("Unknown SSL/TLS protocol error.");
+						return -1;
+					}
+					break;
+				} else if ((errptr < end) && (errptr != gtmcrypt_err_string))
+					*errptr++ = ';';
+				if (errptr >= end)
+					continue;	/* We could break here, but we want to clear the OpenSSL error stack. */
+				ERR_error_string_n(error_code, errptr, end - errptr);
+				errptr += STRLEN(errptr);
+			} while (TRUE);
+			break;
+
+		default:
+			tls_errno = -1;
+			UPDATE_ERROR_STRING("Unknown error: %d returned by `SSL_get_error'", error_code);
+			assert(FALSE);
+			break;
+	}
+	return -1;
+}
+
+/* This callback function is called whenever OpenSSL wants to decrypt the private key (e.g., SSL_CTX_check_private_key()). More
+ * importantly, when OpenSSL calls this callback function, it passes a userdata which provides the callback a hint as to which
+ * private key this callback function corresponds to. In our case, this hint is equivalent to the TLSID passed to the plugin when
+ * gtm_tls_socket is called.
+ */
+STATICFNDEF int	passwd_callback(char *buf, int size, int rwflag, void *userdata)
+{
+	passwd_entry_t		*pwent;
+	int			len;
+
+	pwent = (passwd_entry_t *)userdata;
+	assert(NULL != pwent);
+	assert(NULL != pwent->passwd);
+	len = STRLEN(pwent->passwd);
+	strncpy(buf, pwent->passwd, size);
+	return len;
+}
+
+/* The below callback is invoked whenever OpenSSL creates a new session (either because the old session expired or because of a
+ * renegotiation). Store the session back into the API's socket structure.
+ */
+STATICFNDEF int new_session_callback(SSL *ssl, SSL_SESSION *session)
+{
+	gtm_tls_socket_t	*socket;
+
+	/* See SSL_set_app_data for details on why we need to use the compatibility interface: SSL_get_app_data/SSL_set_app_data. */
+	socket = SSL_get_app_data(ssl);
+	assert(NULL != socket);
+	/* Free up the old session. */
+	SSL_DPRINT(stdout, "new_session_callback: references=%d\n", session->references);
+	if (socket->session)
+		SSL_SESSION_free(socket->session);
+	/* Add the new session to the `socket' structure. */
+	socket->session = session;
+	return 1;
+}
+
+STATICFNDEF DH *read_dhparams(const char *dh_fn)
+{
+	BIO		*bio;
+	DH		*dh;
+
+	if (NULL == (bio = BIO_new_file(dh_fn, "r")))
+	{
+		GC_APPEND_OPENSSL_ERROR("Unable to load Diffie-Hellman parameter file: %s.", dh_fn);
+		return NULL;
+	}
+	if (NULL == (dh = (PEM_read_bio_DHparams(bio, NULL, NULL, NULL))))
+	{
+		GC_APPEND_OPENSSL_ERROR("Unable to load Diffie-Hellman parameter file: %s.", dh_fn);
+		return NULL;
+	}
+	return dh;
+}
+
+STATICFNDEF int init_dhparams(void)
+{
+	int		rv1, rv2;
+	const char	*dh512_fn, *dh1024_fn;
+
+	rv1 = config_lookup_string(&gtm_tls_cfg, "tls.dh512", &dh512_fn);
+	rv2 = config_lookup_string(&gtm_tls_cfg, "tls.dh1024", &dh1024_fn);
+	if (!rv1 && !rv2)
+		return 0;	/* No Diffie-Hellman parameters specified in the config file. */
+	if (!rv1)
+	{
+		UPDATE_ERROR_STRING("Configuration parameter `tls.dh512' not specified.");
+		return -1;
+	}
+	if (!rv2)
+	{
+		UPDATE_ERROR_STRING("Configuration parameter `tls.dh1024' not specified.");
+		return -1;
+	}
+	if (NULL == (dh512 = read_dhparams(dh512_fn)))
+		return -1;
+	if (NULL == (dh1024 = read_dhparams(dh1024_fn)))
+		return -1;
+	return 0;
+}
+
+STATICFNDEF DH *tmp_dh_callback(SSL *ssl, int is_export, int keylength)
+{
+	assert(dh512 && dh1024 && (512 <= keylength));
+	return (512 == keylength) ? dh512 : dh1024;
+}
+
+_GTM_APIDEF int		gtm_tls_errno(void)
+{
+	return tls_errno;
+}
+
+_GTM_APIDEF const char	*gtm_tls_get_error(void)
+{
+	return gtmcrypt_err_string;
+}
+
+_GTM_APIDEF gtm_tls_ctx_t	*gtm_tls_init(int version, int flags)
+{
+	const char		*CAfile = NULL, *CApath = NULL, *crl, *CAptr;
+	char			*config_env;
+	int			rv, rv1, rv2, fips_requested, fips_enabled;
+#	if (((LIBCONFIG_VER_MAJOR == 1) && (LIBCONFIG_VER_MINOR >= 4)) || (LIBCONFIG_VER_MAJOR > 1))
+	int			verify_depth, session_timeout;
+#	else
+	long int		verify_depth, session_timeout;
+#	endif
+	SSL_CTX			*ctx;
+	X509_STORE		*store;
+	X509_LOOKUP		*lookup;
+	config_t		*cfg;
+	gtm_tls_ctx_t		*gtm_tls_ctx;
+
+	assert(GTM_TLS_API_VERSION >= version); /* Make sure the caller is using the right API version */
+	/* Initialize the SSL/TLS library, the algorithms/cipher suite and error strings. */
+	SSL_library_init();
+	SSL_load_error_strings();
+	ERR_load_BIO_strings();
+	/* Turn on FIPS mode if requested. */
+	fips_enabled = FALSE;	/* most common case. */
+	IS_FIPS_MODE_REQUESTED(fips_requested);
+	if (fips_requested)
+	{
+		ENABLE_FIPS_MODE(rv, fips_enabled);
+		if (-1 == rv)
+			return NULL; /* Relevant error detail populated in the above macro. */
+	}
+	OpenSSL_add_all_algorithms();
+	OpenSSL_add_all_ciphers();
+	OpenSSL_add_all_digests();
+	/* Setup function pointers to symbols exported by libgtmshr.so. */
+	if (0 != gc_load_gtmshr_symbols())
+		return NULL;
+	/* Setup a SSL context that allows SSLv3 and TLSv1.x but no SSLv2 (which is deprecated due to a great number of security
+	 * vulnerabilities).
+	 */
+	if (NULL == (ctx = SSL_CTX_new(SSLv23_method())))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to create an SSL context.");
+		return NULL;
+	}
+	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+	/* Read the configuration file for more configuration parameters. */
+	if (NULL == (config_env = getenv("gtmcrypt_config")))
+	{
+		UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, "gtmcrypt_config");
+		SSL_CTX_free(ctx);
+		return NULL;
+	}
+	cfg = &gtm_tls_cfg;
+	config_init(cfg);
+	if (!config_read_file(cfg, config_env))
+	{
+		UPDATE_ERROR_STRING("Failed to read config file: %s. At line: %d, %s.", config_env, config_error_line(cfg),
+						config_error_text(cfg));
+		SSL_CTX_free(ctx);
+		config_destroy(cfg);
+		return NULL;
+	}
+	/* Get global SSL configuration parameters */
+	if (config_lookup_int(cfg, "tls.verify-depth", &verify_depth))
+		SSL_CTX_set_verify_depth(ctx, verify_depth);
+	rv1 = config_lookup_string(cfg, "tls.CAfile", &CAfile);
+	rv2 = config_lookup_string(cfg, "tls.CApath", &CApath);
+	/* Setup trust locations for peer verifications. This adds on to any trust locations that was previously loaded. */
+	if ((rv1 || rv2) && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath))
+	{
+		if (rv1 && rv2)
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to load CA verification locations (CAfile = %s; CApath = %s).",
+							CAfile, CApath);
+		} else
+		{
+			CAptr = rv1 ? CAfile : CApath;
+			GC_APPEND_OPENSSL_ERROR("Failed to load CA verification location: %s.", CAptr);
+		}
+		SSL_CTX_free(ctx);
+		config_destroy(cfg);
+		return NULL;
+	}
+	/* Load the default verification paths as well. On most Unix distributions, the default path is set to /etc/ssl/certs. */
+	if (!SSL_CTX_set_default_verify_paths(ctx))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to load default CA verification locations.");
+		SSL_CTX_free(ctx);
+		config_destroy(cfg);
+		return NULL;
+	}
+	/* If a CRL is specified in the configuration file, add it to the cert store. */
+	if (config_lookup_string(cfg, "tls.crl", &crl))
+	{
+		if (NULL == (store = SSL_CTX_get_cert_store(ctx)))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to get handle to internal certificate store.");
+			SSL_CTX_free(ctx);
+			config_destroy(cfg);
+			return NULL;
+		}
+		if (NULL == (lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to get handle to internal certificate store.");
+			SSL_CTX_free(ctx);
+			config_destroy(cfg);
+			return NULL;
+		}
+		if (0 == X509_LOOKUP_load_file(lookup, (char *)crl, X509_FILETYPE_PEM))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to add Certificate Revocation List %s to internal certificate store.",
+							crl);
+			SSL_CTX_free(ctx);
+			config_destroy(cfg);
+			return NULL;
+		}
+		X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+	}
+	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
+	/* Set callbacks to called whenever a SSL session is added. */
+	SSL_CTX_sess_set_new_cb(ctx, new_session_callback);
+	/* Set session timeout value (in seconds). If the current time is greater than the session creation time + session
+	 * timeout, the session is not reused. This is useful only on the server.
+	 */
+	if (config_lookup_int(cfg, "tls.session-timeout", &session_timeout))
+	{
+		if (0 >= session_timeout)
+			SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+		else
+			SSL_CTX_set_timeout(ctx, session_timeout);
+	} else
+		SSL_CTX_set_timeout(ctx, DEFAULT_SESSION_TIMEOUT);
+	if (0 >= SSL_CTX_set_cipher_list(ctx, CIPHER_LIST))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to add Cipher-List command string: %s.", CIPHER_LIST);
+		SSL_CTX_free(ctx);
+		config_destroy(cfg);
+		return NULL;
+	}
+	gtm_tls_ctx = MALLOC(SIZEOF(gtm_tls_ctx_t));
+	gtm_tls_ctx->ctx = ctx;
+	gtm_tls_ctx->flags = flags;
+	gtm_tls_ctx->fips_mode = fips_enabled;
+	gtm_tls_ctx->compile_time_version = OPENSSL_VERSION_NUMBER;
+	gtm_tls_ctx->runtime_version = SSLeay();
+	return gtm_tls_ctx;
+}
+
+_GTM_APIDEF void gtm_tls_prefetch_passwd(gtm_tls_ctx_t *tls_ctx, char *env_name)
+{
+	char			*env_name_ptr, *env_value, prompt[256];
+	gtmtls_passwd_list_t	*pwent_node;
+	passwd_entry_t		*pwent;
+
+	assert((NULL != (env_value = getenv(env_name))) && (0 == STRLEN(env_value)));
+	if (!(GTMTLS_OP_INTERACTIVE_MODE & tls_ctx->flags))
+		return;	/* Not running in an interactive mode. Cannot prompt for password. */
+	env_name_ptr = (char *)env_name;
+	assert(PASSPHRASE_ENVNAME_MAX > STRLEN(env_name_ptr));
+	assert(SIZEOF(GTMTLS_PASSWD_ENV_PREFIX) - 1 < STRLEN(env_name_ptr));
+	env_name_ptr += (SIZEOF(GTMTLS_PASSWD_ENV_PREFIX) - 1);
+	SNPRINTF(prompt, 256, "Enter passphrase for TLSID %s: ", env_name_ptr);
+	pwent = NULL;
+	if (0 == gc_update_passwd(env_name, &pwent, prompt, TRUE))
+	{
+		pwent_node = MALLOC(SIZEOF(gtmtls_passwd_list_t));
+		pwent_node->next = gtmtls_passwd_listhead;
+		pwent_node->pwent = pwent;
+		gtmtls_passwd_listhead = pwent_node;
+	}
+	/* else, something went wrong while acquiring the password. Don't report it now. Later, `gtm_tls_socket' makes another
+	 * attempt to acquire the password.
+	 */
+}
+
+_GTM_APIDEF gtm_tls_socket_t *gtm_tls_socket(gtm_tls_ctx_t *tls_ctx, gtm_tls_socket_t *prev_socket, int sockfd, char *id, int flags)
+{
+	int			len;
+	char			cfg_path[MAX_CONFIG_LOOKUP_PATHLEN], input_env_name[PASSPHRASE_ENVNAME_MAX], *env_name_ptr;
+	char			prompt[256];
+	const char		*cert, *private_key, *format;
+	FILE			*fp;
+	SSL			*ssl;
+	SSL_CTX			*ctx;
+	EVP_PKEY		*evp_pkey = NULL;
+	config_t		*cfg;
+	gtmtls_passwd_list_t	*pwent_node;
+	passwd_entry_t		*pwent;
+	gtm_tls_socket_t	*socket;
+#	ifndef SSL_OP_NO_COMPRESSION
+	STACK_OF(SSL_COMP)*	compression;
+#	endif
+
+	DBG_VERIFY_SOCK_IS_BLOCKING(sockfd);
+	ctx = tls_ctx->ctx;
+	cfg = &gtm_tls_cfg;
+
+	/* Create a SSL object. This object will be used for the actual I/O: recv/send */
+	if (NULL == (ssl = SSL_new(ctx)))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to obtain a new SSL/TLS object.");
+		return NULL;
+	}
+
+	if (VERIFY_PEER(flags))
+	{
+		/* First lookup the certificate and private key associated with the provided id in the configuration file. */
+		SNPRINTF(cfg_path, MAX_CONFIG_LOOKUP_PATHLEN, "tls.%s.cert", id);
+		if (!config_lookup_string(cfg, cfg_path, &cert))
+		{
+			UPDATE_ERROR_STRING("Certificate corresponding to TLSID: %s not found in configuration file.", id);
+			SSL_free(ssl);
+			return NULL;
+		}
+
+		SNPRINTF(cfg_path, MAX_CONFIG_LOOKUP_PATHLEN, "tls.%s.key", id);
+		if (!config_lookup_string(cfg, cfg_path, &private_key))
+		{
+			UPDATE_ERROR_STRING("Private Key corresponding to TLSID: %s not found in configuration file.", id);
+			SSL_free(ssl);
+			return NULL;
+		}
+
+		/* Verify that the format, if specified, is of PEM type as that's the only kind we support now. */
+		SNPRINTF(cfg_path, MAX_CONFIG_LOOKUP_PATHLEN, "tls.%s.format", id);
+		if (config_lookup_string(cfg, cfg_path, &format))
+		{
+			if (((SIZEOF("PEM") - 1) != strlen(format))
+					|| (format[0] != 'P') || (format[1] != 'E') || (format[2] != 'M'))
+			{
+				UPDATE_ERROR_STRING("Unsupported format type %s found for TLSID: %s.", format, id);
+				SSL_free(ssl);
+				return NULL;
+			}
+		}
+		/* Setup the certificate to be used for this connection */
+		if (!SSL_use_certificate_file(ssl, cert, SSL_FILETYPE_PEM))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to add certificate %s.", cert);
+			SSL_free(ssl);
+			return NULL;
+		}
+
+		/* Before setting up the private key, check-up on the password for the private key. */
+		SNPRINTF(input_env_name, PASSPHRASE_ENVNAME_MAX, GTMTLS_PASSWD_ENV_PREFIX "%s", id);
+		if (NULL != (pwent_node = gtmtls_passwd_listhead))
+		{	/* Lookup to see if we have already prefetched the password. */
+			while (NULL != pwent_node)
+			{
+				env_name_ptr = pwent_node->pwent->env_name;
+				len = STRLEN(env_name_ptr);
+				assert(len < PASSPHRASE_ENVNAME_MAX);
+				assert(len > SIZEOF(GTMTLS_PASSWD_ENV_PREFIX) - 1);
+				if ((len == STRLEN(input_env_name)) && (0 == strncmp(input_env_name, env_name_ptr, len)))
+					break;
+				pwent_node = pwent_node->next;
+			}
+		}
+		if (NULL == pwent_node)
+		{	/* Lookup failed. Create a new entry for the given id. */
+			pwent = NULL;
+			SNPRINTF(prompt, 256, "Enter passphrase for TLSID %s:", id);
+			if (0 != gc_update_passwd(input_env_name, &pwent, prompt, GTMTLS_OP_INTERACTIVE_MODE & tls_ctx->flags))
+			{
+				SSL_free(ssl);
+				return NULL;
+			}
+			pwent_node = MALLOC(SIZEOF(gtmtls_passwd_list_t));
+			pwent_node->next = gtmtls_passwd_listhead;
+			pwent_node->pwent = pwent;
+			gtmtls_passwd_listhead = pwent_node;
+		} else
+			pwent = pwent_node->pwent;
+		assert((NULL != pwent) && (NULL != pwent_node));
+		/* Setup the private key corresponding to the certificate and the callback function to obtain the password for the
+		 * key. We cannot use the much simpler SSL_use_PrivateKey file to load the private key file because we want fine
+		 * grained control on the password callback mechanism. For this purpose, use the PEM_read_PrivateKey function which
+		 * supports callbacks for individual private keys.
+		 */
+		fp = fopen(private_key, "r");
+		evp_pkey = PEM_read_PrivateKey(fp, &evp_pkey, &passwd_callback, pwent);
+		fclose(fp);	/* Close the file irrespective of whether the above function succeeded or failed. */
+		if (NULL == evp_pkey)
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to read private key %s.", private_key);
+			SSL_free(ssl);
+			return NULL;
+		}
+		if (!SSL_use_PrivateKey(ssl, evp_pkey))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to use private key %s.", private_key);
+			SSL_free(ssl);
+			return NULL;
+		}
+		/* Verify that private key matches the certificate */
+		if (!SSL_check_private_key(ssl))
+		{
+			GC_APPEND_OPENSSL_ERROR("Consistency check failed for private key: %s and certificate: %s\n",
+							private_key, cert);
+			SSL_free(ssl);
+			return NULL;
+		}
+		SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
+	}
+	/* OpenSSL does not recommend enabling compression as the current state of the SSL/TLS protocol does not specify identifiers
+	 * for compression libraries thereby allowing for incompatibilities when different SSL/TLS implementations are used in the
+	 * client and the server. So, disable compression.
+	 */
+#	ifdef SSL_OP_NO_COMPRESSION
+	SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
+#	else
+	/* OpenSSL versions <= 0.9.8 enabled compression by default and did not provide an easy way to turn-off compression. Below
+	 * is a work-around that zeroes out all the compression methods explicitly in the compression structures effectively
+	 * disabling compression.
+	 */
+	compression = SSL_COMP_get_compression_methods();
+	sk_SSL_COMP_zero(compression);
+#	endif
+	if (0 == (GTMTLS_OP_CLIENT_MODE & flags))
+	{	/* Socket created for server mode operation. Set a session ID context for session resumption at the time of
+		 * reconnection.
+		 */
+		if (0 >= SSL_set_session_id_context(ssl, (const unsigned char *)id, STRLEN(id)))
+		{
+			GC_APPEND_OPENSSL_ERROR("Failed to set Session-ID context to enable session resumption.");
+			SSL_free(ssl);
+			return NULL;
+		}
+		/* Set up Ephemeral Diffie-Hellman key exchange callback. This callback is invoked whenever, during the connection
+		 * time, OpenSSL requires Diffie-Hellman key parameters. The SSL_OP_SINGLE_DH_USE is turned on so that the same
+		 * private key is not used for each session. This means a little extra computation during the time of handshake, but
+		 * is recommended by the OpenSSL community.
+		 */
+		if (-1 == init_dhparams())
+		{
+			SSL_free(ssl);
+			return NULL;
+		}
+		if (dh512 && dh1024)
+		{
+			SSL_set_options(ssl, SSL_OP_SINGLE_DH_USE);
+			SSL_set_tmp_dh_callback(ssl, tmp_dh_callback);
+		}
+	}
+	/* Finally, wrap the Unix TCP/IP socket into SSL/TLS object */
+	if (0 >= SSL_set_fd(ssl, sockfd))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to associate TCP/IP socket descriptor %d with an SSL/TLS descriptor", sockfd);
+		SSL_free(ssl);
+		return NULL;
+	}
+	if (NULL == prev_socket)
+	{
+		socket = MALLOC(SIZEOF(gtm_tls_socket_t));
+		socket->session = NULL;
+	} else
+		socket = prev_socket;
+	socket->flags = flags;
+	socket->ssl = ssl;
+	/* Now, store the `socket' structure in the `SSL' structure so that we can get it back in a callback that receives an
+	 * `SSL' structure. Ideally, we should be using SSL_set_ex_data/SSL_get_ex_data family of functions. But, these functions
+	 * operate on a specific index (obtained by calling SSL_get_ex_new_index). But, since the library should potentially
+	 * support multiple sockets, we need to be able to associate the index returned by OpenSSL with a structure which is not
+	 * straightforward. So, use OpenSSL's compatibility interface which lets the application store *one* piece of application
+	 * data in the SSL structure for later retrieval. It does so by reserving index '0' for the compatibility interface.
+	 */
+	SSL_set_app_data(ssl, socket);	/* This way, we can get back the `socket' structure in a callback that receives `SSL'. */
+	return socket;
+}
+
+_GTM_APIDEF int		gtm_tls_connect(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	assert(socket->flags & GTMTLS_OP_CLIENT_MODE);
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	if (NULL != socket->session)
+	{	/* Old session available. Reuse it. */
+		SSL_DPRINT(stdout, "gtm_tls_connect(1): references=%d\n", ((SSL_SESSION *)(socket->session))->references);
+		if (0 >= (rv = SSL_set_session(socket->ssl, socket->session)))
+			return ssl_error(socket->ssl, rv);
+		SSL_DPRINT(stdout, "gtm_tls_connect(2): references=%d\n", ((SSL_SESSION *)(socket->session))->references);
+	}
+	if (0 < (rv = SSL_connect(socket->ssl)))
+	{
+		if (NULL != socket->session)
+			SSL_DPRINT(stdout, "gtm_tls_connect(3): references=%d\n", ((SSL_SESSION *)(socket->session))->references);
+		return 0;
+	}
+	return ssl_error(socket->ssl, rv);
+}
+
+_GTM_APIDEF int		gtm_tls_accept(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	if (0 < (rv = SSL_accept(socket->ssl)))
+		return 0;
+	return ssl_error(socket->ssl, rv);
+}
+
+_GTM_APIDEF int gtm_tls_renegotiate(gtm_tls_socket_t *socket)
+{
+	int		rv;
+
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	if (0 >= (rv = SSL_renegotiate(socket->ssl)))
+		return ssl_error(socket->ssl, rv);
+	do
+	{
+		if (0 < (rv = SSL_do_handshake(socket->ssl)))
+			return 0;
+		/* On a blocking socket, SSL_do_handshake returns ONLY after successful completion. However, if the system call
+		 * is interrupted (say, by a SIGALRM), it can return with a WANT_READ or WANT_WRITE. Handle it by retrying.
+		 * Ideally, we should return back to the caller and let it handle WANT_READ/WANT_WRITE and call us again, but
+		 * since renegotiation is done seldomly and returning the control back to the caller causes interface issues, we
+		 * handle GTMTLS_WANT_READ or GTMTLS_WANT_WRITE by retrying.
+		 */
+		rv = ssl_error(socket->ssl, rv);
+	} while ((GTMTLS_WANT_READ == rv) || (GTMTLS_WANT_WRITE == rv));
+	return rv;
+}
+
+_GTM_APIDEF int		gtm_tls_get_conn_info(gtm_tls_socket_t *socket, gtm_tls_conn_info *conn_info)
+{
+	long			verify_result, timeout, creation_time;
+	unsigned int		session_id_length, ssl_version;
+	const SSL_CIPHER	*cipher;
+	const COMP_METHOD	*compression_method;
+	char			*ssl_version_ptr, *session_id_ptr;
+	X509			*peer;
+	SSL			*ssl;
+	EVP_PKEY		*pubkey;
+	SSL_SESSION		*session;
+
+	ssl = socket->ssl;
+	if (NULL != (peer = SSL_get_peer_certificate(ssl)))
+	{
+		verify_result = SSL_get_verify_result(ssl);
+		if (X509_V_OK == verify_result)
+		{
+			/* SSL-Session Protocol */
+			switch (ssl_version = SSL_version(ssl))
+			{
+				case SSL2_VERSION:
+					ssl_version_ptr = "SSLv2";
+					break;
+
+				case SSL3_VERSION:
+					ssl_version_ptr = "SSLv3";
+					break;
+
+				case TLS1_VERSION:
+					ssl_version_ptr = "TLSv1";
+					break;
+				/* Older, but still commonly used, OpenSSL versions don't have macros for TLSv1.1 and TLSv1.2
+				 * versions. They are hard coded to 0x0302 and 0x0303 respectively. So, use them as-is here.
+				 */
+				case 0x0302:
+					ssl_version_ptr = "TLSv1.1";
+					break;
+				case 0x0303:
+					ssl_version_ptr = "TLSv1.2";
+					break;
+				default:
+					assert(FALSE && ssl_version);
+					break;
+			}
+			strncpy(conn_info->protocol, ssl_version_ptr, MAX_ALGORITHM_LEN);
+			/* SSL-Session Cipher Algorithm */
+			cipher = SSL_get_current_cipher(ssl);
+			SNPRINTF(conn_info->session_algo, SIZEOF(conn_info->session_algo), "%s", SSL_CIPHER_get_name(cipher));
+			/* Remote Certificate Asymmetric Algorithm */
+			pubkey = X509_get_pubkey(peer);
+			SNPRINTF(conn_info->cert_algo, SIZEOF(conn_info->cert_algo), "%s", OBJ_nid2ln(pubkey->type));
+			/* Is Secure Renegotiation Supported? */
+#			if OPENSSL_VERSION_NUMBER >= 0x009080dfL
+			/* SSL_get_secure_renegotiation_support function was introduced in OpenSSL version >= "0.9.8m". */
+			conn_info->secure_renegotiation = SSL_get_secure_renegotiation_support(ssl);
+#			else
+			conn_info->secure_renegotiation = FALSE;
+#			endif
+			/* Is the session reused? */
+			conn_info->reused = SSL_session_reused(ssl);
+			/* Negotiated Session-ID. */
+			if (NULL == (session = SSL_get1_session(ssl)))	/* `get1' version is used to increment reference count. */
+			{
+				UPDATE_ERROR_STRING("Failed to obtain the handle to negotiated SSL/TLS session");
+				return -1;
+			}
+			session_id_ptr = (char *)SSL_SESSION_get_id(session, &session_id_length);
+			assert(session_id_length <= MAX_SESSION_ID_LEN / 2);
+			GC_HEX(session_id_ptr, conn_info->session_id, session_id_length * 2);
+			conn_info->session_id[session_id_length * 2] = '\0';
+			/* Session expiry timeout. */
+			if (0 >= (timeout = SSL_SESSION_get_timeout(session)))
+				conn_info->session_expiry_timeout = -1;
+			else
+			{
+				creation_time = SSL_SESSION_get_time(session);
+				conn_info->session_expiry_timeout = creation_time + timeout;
+			}
+			SSL_SESSION_free(session);
+			/* Is compression supported? */
+#			ifndef OPENSSL_NO_COMP
+			compression_method = SSL_get_current_compression(ssl);
+			conn_info->compression = compression_method ? (char *)SSL_COMP_get_name(compression_method) : "NONE";
+#			else
+			conn_info->compression = "NONE";
+#			endif
+			/* Remote Certificate Asymmetric Algorithm Strength */
+			conn_info->cert_nbits = EVP_PKEY_bits(pubkey);
+			/* Remote Certificate Subject */
+			X509_NAME_oneline(X509_get_subject_name(peer), conn_info->subject, MAX_X509_LEN);
+			/* Remote Certificate Issuer */
+			X509_NAME_oneline(X509_get_issuer_name(peer), conn_info->issuer, MAX_X509_LEN);
+			/* Certificate Expiry */
+			if (-1 == format_ASN1_TIME(X509_get_notBefore(peer), conn_info->not_before, MAX_TIME_STRLEN))
+				SNPRINTF(conn_info->not_before, MAX_TIME_STRLEN, "Bad certificate date");
+			if (-1 == format_ASN1_TIME(X509_get_notAfter(peer), conn_info->not_after, MAX_TIME_STRLEN))
+				SNPRINTF(conn_info->not_after, MAX_TIME_STRLEN, "Bad certificate date");
+			X509_free(peer);
+			return 0;
+		} else
+		{
+			UPDATE_ERROR_STRING("Peer certificate invalid");
+			X509_free(peer);
+			return -1;
+		}
+	} else
+		UPDATE_ERROR_STRING("No certificate sent from the remote side");
+	return -1;
+}
+
+_GTM_APIDEF int		gtm_tls_send(gtm_tls_socket_t *socket, char *buf, int send_len)
+{
+	int		rv;
+
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	if (0 < (rv = SSL_write(socket->ssl, buf, send_len)))
+	{
+		assert(SSL_ERROR_NONE == SSL_get_error(socket->ssl, rv));
+		return rv;
+	}
+	return ssl_error(socket->ssl, rv);
+}
+
+_GTM_APIDEF int		gtm_tls_recv(gtm_tls_socket_t * socket, char *buf, int recv_len)
+{
+	int		rv;
+
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	if (0 < (rv = SSL_read(socket->ssl, buf, recv_len)))
+	{
+		assert(SSL_ERROR_NONE == SSL_get_error(socket->ssl, rv));
+		return rv;
+	}
+	return ssl_error(socket->ssl, rv);
+}
+
+_GTM_APIDEF int		gtm_tls_cachedbytes(gtm_tls_socket_t *socket)
+{
+	return SSL_pending(socket->ssl);
+}
+
+_GTM_APIDEF void	gtm_tls_socket_close(gtm_tls_socket_t *socket)
+{
+	assert(socket);
+	tls_errno = 0;
+	if (NULL == socket->ssl)
+		return;
+	DBG_VERIFY_SOCK_IS_BLOCKING(GET_SOCKFD(socket->ssl));
+	/* Invoke SSL_shutdown to close the SSL/TLS connection. Although the protocol (and the OpenSSL library) supports
+	 * bidirectional shutdown (which waits for the peer's "close notify" alert as well), we intend to only send the
+	 * "close notify" alert and be done with it. This is because the process is done with the connection when it calls
+	 * this function and we don't want to consume additional time waiting for a "close notify" acknowledge signal from the
+	 * other side.
+	 */
+	SSL_shutdown(socket->ssl);
+	SSL_free(socket->ssl);
+	socket->ssl = NULL;
+}
+
+_GTM_APIDEF void	gtm_tls_session_close(gtm_tls_socket_t **socket)
+{
+	SSL_SESSION		*session;
+	gtm_tls_socket_t	*sock;
+
+	sock = *socket;
+	assert(sock);
+	if (NULL != sock->ssl)
+		gtm_tls_socket_close(sock);
+	if (NULL != (session = sock->session))
+	{
+		SSL_DPRINT(stdout, "gtm_tls_session_close: references=%d\n", session->references);
+		SSL_SESSION_free(session);
+	}
+	sock->session = NULL;
+	FREE(*socket);
+	*socket = NULL;
+}
+
+_GTM_APIDEF void	gtm_tls_fini(gtm_tls_ctx_t **tls_ctx)
+{
+	gtmtls_passwd_list_t	*node, *prev_node;
+
+	/* Free up the SSL/TLS context */
+	assert(*tls_ctx);
+	SSL_CTX_free((*tls_ctx)->ctx);
+	FREE(*tls_ctx);
+	*tls_ctx = NULL;
+	/* Free up the libconfig context */
+	config_destroy(&gtm_tls_cfg);	/* Relinquish all the memory allocated by libconfig */
+	/* Free up the gtmtls_passwd_list_t linked list */
+	node = gtmtls_passwd_listhead;
+	while (NULL != node)
+	{
+		gc_freeup_pwent(node->pwent);
+		prev_node = node;
+		node = node->next;
+		FREE(prev_node);
+	}
+}
diff --git a/sr_unix/gtm_tls_impl.h b/sr_unix/gtm_tls_impl.h
new file mode 100644
index 0000000..1340186
--- /dev/null
+++ b/sr_unix/gtm_tls_impl.h
@@ -0,0 +1,55 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+#ifndef _GTM_TLS_IMPL_H
+#define _GTM_TLS_IMPL_H
+
+STATICFNDEF int format_ASN1_TIME(ASN1_TIME *tm, char *buf, int maxlen);
+STATICFNDEF int ssl_generic_vfy_callback(int preverify_ok, X509_STORE_CTX *ctx);
+STATICFNDEF int	passwd_callback(char *buf, int size, int rwflag, void *userdata);
+STATICFNDEF int new_session_callback(SSL *ssl, SSL_SESSION *session);
+STATICFNDEF void remove_session_callback(SSL_CTX *ctx, SSL_SESSION *session);
+STATICFNDEF DH *read_dhparams(const char *dh_fn);
+STATICFNDEF int init_dhparams(void);
+STATICFNDEF DH *tmp_dh_callback(SSL *ssl, int is_export, int keylength);
+STATICFNDEF int ssl_error(SSL *ssl, int err);
+
+typedef struct gtmtls_passwd_list_struct
+{
+	struct gtmtls_passwd_list_struct *next;
+	passwd_entry_t			 *pwent;
+} gtmtls_passwd_list_t;
+
+#define GET_SOCKFD(TLS)			SSL_get_fd((SSL *)TLS)
+#define VERIFY_PEER(FLAGS)		(FLAGS & GTMTLS_OP_VERIFY_PEER)
+#define DEFAULT_SESSION_TIMEOUT		3600		/* Old sessions can be reused upto 1 hour since the creation time. */
+
+#ifdef DEBUG
+/* Verify that the socket (about to be wrapped or linked to an existing SSL object is actually of blocking type. This library
+ * currently supports only blocking SSL/TLS operations. If ever this check fails, either the callee needs to be examined OR the
+ * implementation needs to account for non-blocking sockets.
+ */
+#define DBG_VERIFY_SOCK_IS_BLOCKING(SOCKFD)											\
+{																\
+	int		flags;													\
+																\
+	assert(0 <= SOCKFD);													\
+	flags = fcntl(SOCKFD, F_GETFL);												\
+	assert(0 == (O_NONBLOCK & flags));											\
+}
+
+#define DBG_VERIFY_AUTORETRY_SET(TLS_DESC)	assert(SSL_MODE_AUTO_RETRY & SSL_CTX_get_mode((SSL_CTX *)TLS_DESC));
+
+#else
+#define DBG_VERIFY_SOCK_IS_NONBLOCKING(SOCKFD)
+#define DBG_VERIFY_AUTORETRY_SET(TLS_DESC)
+#endif
+
+#endif
diff --git a/sr_unix/gtm_tls_interface.h b/sr_unix/gtm_tls_interface.h
new file mode 100644
index 0000000..94309b8
--- /dev/null
+++ b/sr_unix/gtm_tls_interface.h
@@ -0,0 +1,285 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#ifndef _GTM_TLS_INTERFACE_H
+#define _GTM_TLS_INTERFACE_H
+
+#ifndef _GTM_TLS_INTERFACE_DEFINITIONS_INCLUDED
+#define _GTM_TLS_INTERFACE_DEFINITIONS_INCLUDED
+
+#define GTM_TLS_API_VERSION		0x00000001
+
+#define MAX_X509_LEN			256
+#define MAX_ALGORITHM_LEN		64
+#define MAX_TIME_STRLEN			32
+#define MAX_TLSID_LEN			32
+#define MAX_SESSION_ID_LEN		64
+
+#define INVALID_TLS_CONTEXT		NULL
+#define INVALID_TLS_SOCKET		NULL
+/* SSL/TLS protocol allows for renegoitations (change in cipher spec, etc.) to take place at any point during the communication. So,
+ * it is likely for a call to `gtm_tls_recv' or `gtm_tls_send' to initiate a renegoitation sequence in which case a `gtm_tls_recv'
+ * might have to 'send' data and `gtm_tls_send' to 'recv' data. In such cases, the SSL/TLS reference implementation returns one of
+ * the following two return codes. They do not indicate an error situation. Instead, they indicate that the reference implementation
+ * could not successfully complete the operation without reading or writing more data to the underlying TCP/IP connection and gives
+ * a chance to the application to wait for the underlying TCP/IP pipe to become ready for a read (if GTMTLS_WANT_READ is returned)
+ * or write (if GTMTLS_WANT_WRITE is returned).
+ */
+#define GTMTLS_WANT_READ		-2
+#define GTMTLS_WANT_WRITE		-3
+
+#define GTMTLS_PASSWD_ENV_PREFIX	"gtmtls_passwd_"
+
+/* Whether the library is loaded in an interactive environment so that password prompting can happen if needed. */
+#define GTMTLS_OP_INTERACTIVE_MODE	0x00000001
+/* Turn-on compression for SSL/TLS protocol. */
+#define GTMTLS_OP_ENABLE_COMPRESSION	0x00000002
+/* Socket created for a client-mode operation. */
+#define GTMTLS_OP_CLIENT_MODE		0x00000004
+/* Peer verification is needed. */
+#define GTMTLS_OP_VERIFY_PEER		0x00000008
+
+#define GTMTLS_IS_FIPS_MODE(CTX)	(TRUE == CTX->fips_mode)
+#define GTMTLS_RUNTIME_LIB_VERSION(CTX)	(CTX->runtime_version)
+
+typedef struct gtm_tls_conn_info_struct
+{
+	/* SSL Session Information */
+	char		protocol[MAX_ALGORITHM_LEN];	/* Descriptive name of the negoitiated protocol (for instance, TLSv1). */
+	char		session_algo[MAX_ALGORITHM_LEN];/* Algorithm negoitated by the SSL/TLS session. */
+	char		session_id[MAX_SESSION_ID_LEN + 1]; /* Hexadecimal representation of the negotiated Session-ID. */
+	char		*compression;			/* Compression method used for the SSL/TLS session. */
+	int		secure_renegotiation;		/* 1 if SSL/TLS renegotiation is supported and 0 otherwise. */
+	int		reused;				/* Is the session reused? */
+	long		session_expiry_timeout;		/* Time at which this session expires (-1 if doesn't expire). */
+	/* Remote Certificate Information */
+	char		cert_algo[MAX_ALGORITHM_LEN];	/* Certificate's asymmetric cryptography algorithm. */
+	int		cert_nbits;			/* Strength of the certificate's asymmetric cryptography. */
+	char		subject[MAX_X509_LEN];		/* To whom the certificate belongs? */
+	char		issuer[MAX_X509_LEN];		/* CA who issued the certificate. */
+	char		not_before[MAX_TIME_STRLEN];	/* Date before which the certificate is not valid. */
+	char		not_after[MAX_TIME_STRLEN];	/* Date after which the certificate is not valid. */
+} gtm_tls_conn_info;
+
+typedef struct gtm_tls_session_struct
+{
+	int			flags;
+	void			*ssl;
+	void			*session;
+} gtm_tls_socket_t;
+
+typedef struct gtm_tls_ctx_struct
+{
+	int			flags;
+	int			fips_mode;
+	unsigned long		compile_time_version;	/* OpenSSL version that this library is compiled with. */
+	unsigned long		runtime_version;	/* OpenSSL version that this library is currently running with. */
+	void			*ctx;
+} gtm_tls_ctx_t;
+
+#endif	/* _GTM_TLS_INTERFACE_DEFINITIONS_INCLUDED */
+
+/* Note: The below function prototypes should be kept in sync with the corresponding declarations/definitions in sr_unix/gtm_tls.h
+ * and sr_unix/gtm_tls_funclist.h.
+ */
+
+/* Returns the most recent error (null-terminated) related to the workings of the SSL/TLS reference implementation. */
+_GTM_APIDECL const char		*gtm_tls_get_error(void);
+
+/* If the most recent invocation of the SSL/TLS reference implementation resulted in a system call error, `gtm_tls_errno' returns
+ * the value of `errno'. Otherwise, -1 is returned in which case `gtm_tls_get_error' provides more information.
+ */
+_GTM_APIDECL int		gtm_tls_errno(void);
+
+/* Initializes the SSL/TLS context for a process. Typically invoked only once (unless the previous attempt failed). Attributes
+ * necessary to initialize the SSL/TLS context are obtained from the configuration file pointed to by `$gtmcrypt_config'.
+ *
+ * Arguments:
+ *   `version' : The API version that the caller understands. Current version is 0x1.
+ *   `flags'   : Initialization flags as a bitmask. Currently, the only one the API understands is GTMTLS_OP_INTERACTIVE_MODE.
+ *               Set this bitmask if the process doing the SSL/TLS initialization is run in an interactive mode. This lets
+ *               the API decide if it can prompt for a password if a need arises while decrypting the private key.
+ *
+ * Returns a value, of type gtm_tls_ctx_t, representing the initialized SSL/TLS context. This context can be used, later by the
+ * application, to create as many SSL/TLS aware sockets as needed. In case of an error, INVALID_TLS_CONTEXT is returned in which
+ * case gtm_tls_get_error() provides the necessary error detail.
+ */
+_GTM_APIDECL gtm_tls_ctx_t	*gtm_tls_init(int version, int flags);
+
+/* Prefetches the password corresponding to a private key.
+ *
+ * Arguments:
+ *    `tls_ctx'  : The SSL/TLS context corresponding to this process.
+ *    `env_name' : The name of the environment variable that corresponds to the private key in question. The SSL/TLS API identifies
+ *                 a private key by a name that is specified in the configuration file. The name of the environment variable is then
+ *                 obtained by prefixing "gtmtls_passwd_" to the identifier. So, if the identifier is `PRODUCTION', then the name
+ *                 of the environment variable is "gtmtls_passwd_PRODUCTION".
+ *
+ * No return value. Since this is only an attempt to prefetch the password, no error is reported. Another attempt will be made,
+ * later to acquire the password when actually decrypting the private key.
+ *
+ * Note 1: This function is typically invoked whenever the application detects that an environment variable of the form
+ * "gtmtls_passwd_<identifier>" is present in the environment but doesn't have any assoicated value. In such a case the below
+ * function prompts the user to provide the password before continuing any further. The password is not validated, but is stored
+ * for future use.
+ *
+ * Note 2: The function honors the GTMTLS_OP_INTERACTIVE_MODE flag passed to the `gtm_tls_init' function. If the application has
+ * initialized the SSL/TLS API in a non-interactive mode, the API does not prompt the user for password.
+ */
+_GTM_APIDECL void		gtm_tls_prefetch_passwd(gtm_tls_ctx_t *tls_ctx, char *env_name);
+
+/* Converts a Unix TCP/IP socket into a SSL/TLS aware socket.
+ *
+ * Arguments:
+ *    `ctx'         : The SSL/TLS context corresponding to this process.
+ *    `prev_socket` : Pointer to an existing `gtm_tls_socket_t' structure. A non-null value indicates reuse.
+ *    `sockfd'      : The Unix TCP/IP socket identifier.
+ *    `tls_id' : Identifier corresponding to the private key and certificate pair that should be used for future communication.
+ *               The plugin searches for the identifier in the configuration file pointed to by `$gtmcrypt_config' to get other
+ *               information corresponding to this connection (like, path to the private key, certificate and the format of the
+ *               private key).
+ *    `flags'  : Additional configuration options. See GTMTLS_OP* macros for more details.
+ *
+ * Returns a value, of type gtm_tls_socket_t *, representing the initialized SSL/TLS aware socket. This value can be used for actual
+ * communication to provide security. In case of an error, INVALID_TLS_SOCKET is returned in which case gtm_tls_get_error()
+ * provides the necessary error detail. If `prev_socket' is non-NULL, then that storage area is used for setting up the new socket
+ * instead of creating a new storage area.
+ *
+ * Note 1: If the password corresponding to the `tls_id' has not yet been prefetched by the SSL/TLS API, then the API attempts to
+ * read the password from the environment.
+ *
+ * Note 2: The function honors the GTMTLS_OP_INTERACTIVE_MODE flag passed to the `gtm_tls_init' function. If the application has
+ * initialized the SSL/TLS API in a non-interactive mode, this function does not prompt the user for password.
+ */
+_GTM_APIDECL gtm_tls_socket_t *gtm_tls_socket(gtm_tls_ctx_t *ctx, gtm_tls_socket_t *prev_socket, int sockfd, char *id, int flags);
+
+/* Connects using SSL/TLS aware socket. Assumes the other transport endpoint understands SSL/TLS.
+ *
+ * Arguments:
+ *    `socket'       : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *
+ * Returns 0 if the connection is successful. Otherwise, one of -1, GTMTLS_WANT_READ or GTMTLS_WANT_WRITE is returned. In case of
+ * -1, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain the necessary error detail.
+ *
+ * Note: The function makes use of an existing SSL session (if one is available).
+ */
+_GTM_APIDECL int		gtm_tls_connect(gtm_tls_socket_t *socket);
+
+/* Accepts an incoming connection using SSL/TLS aware socket. Assumes the other transport endpoint understands SSL/TLS.
+ *
+ * Arguments:
+ *    `socket' : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *
+ * Returns 0 if the connection is successful. Otherwise, one of -1, GTMTLS_WANT_READ or GTMTLS_WANT_WRITE is returned. In case of
+ * -1, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain the necessary error detail.
+ *
+ */
+_GTM_APIDECL int		gtm_tls_accept(gtm_tls_socket_t *socket);
+
+/* Renegotiates an active SSL/TLS connection. Note: This function does the renegotiation in a blocking fashion and more importantly
+ * handles EINTR internally by retrying the renegotiation.
+ *
+ * Arguments:
+ *    `socket'   : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *
+ * Return value: none.
+ */
+_GTM_APIDECL int		gtm_tls_renegotiate(gtm_tls_socket_t *socket);
+
+/* Obtains additional SSL/TLS related information on the peer. This function is typically invoked to log information for diagnostic
+ * purposes.
+ *
+ * Arguments:
+ *    `socket'   : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *    `conn_info' : A pointer to the `gtm_tls_conn_info' structure.
+ *
+ * Returns 0 if the connection is successful (and conn_info structure is filled). Otherwise, one of -1, GTMTLS_WANT_READ or
+ * GTMTLS_WANT_WRITE is returned. In case of -1, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain the necessary error
+ * detail.
+ */
+_GTM_APIDECL int		gtm_tls_get_conn_info(gtm_tls_socket_t *socket, gtm_tls_conn_info *conn_info);
+
+/* Transmits message securely to the transport endpoint. This function should be invoked ONLY after successful invocations of either
+ * `gtm_tls_connect' or `gtm_tls_accept'.
+ *
+ * Arguments:
+ *    `socket'   : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *    `buf'      : Buffer containing the message that has to be transmitted.
+ *    `send_len' : Length of the message that has to be transmitted.
+ *
+ * If successful, returns the number of bytes (> 0) actually sent through the SSL/TLS connection. Otherwise, one of -1,
+ * GTMTLS_WANT_READ or GTMTLS_WANT_WRITE is returned. In case of -1, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain
+ * the necessary error detail.
+ */
+_GTM_APIDECL int		gtm_tls_send(gtm_tls_socket_t *socket, char *buf, int send_len);
+
+/* Receives message securely from the transport endpoint. This function should be invoked ONLY after successful invocations of
+ * either `gtm_tls_connect' or `gtm_tls_accept'.
+ *
+ * Arguments:
+ *    `socket'   : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *    `buf'      : Buffer in which the received data (after having decrypted) has to be placed.
+ *    `recv_len' : Upper bound on the amount of data that can be received.
+ *                     become ready for a `send' or `recv'.
+ *
+ * If successful, returns the number of bytes (> 0) actually received from the SSL/TLS connection. Otherwise, one of -1,
+ * GTMTLS_WANT_READ or GTMTLS_WANT_WRITE is returned. In case of -1, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain
+ * the necessary error detail.
+ */
+_GTM_APIDECL int		gtm_tls_recv(gtm_tls_socket_t *socket, char *buf, int recv_len);
+
+/* Returns the number of bytes cached in the SSL/TLS layer and is ready for immediate retrieval with the `gtm_tls_recv'.
+ *
+ * Arguments:
+ *    `socket'   : The SSL/TLS socket (initialized using `gtm_tls_socket').
+ *
+ * Note: Data from the peer is received in blocks. Therefore, data can be buffered inside the SSL/TLS layer and is ready for
+ * immediate retrieval with `gtm_tls_recv'. Given this, it is important for the application to call this function, if `select'
+ * or `poll' on the underlying TCP/IP socket indicates that the subsequent `recv' will block, and check if there are any bytes
+ * readily available.
+ */
+_GTM_APIDECL int		gtm_tls_cachedbytes(gtm_tls_socket_t *socket);
+
+/* Close the SSL/TLS socket connection.
+ *
+ * Arguments:
+ *    `socket'   : Pointer to the SSL/TLS socket (initialized using `gtm_tls_socket').
+ *
+ * Note: This function merely shuts down the active SSL/TLS connection. The session is still preserved in the SSL/TLS internal
+ * structures for reuse when a connection is made with the same server at a later point.
+ *
+ * Returns 0 if successful and -1 otherwise. In case of an error, `gtm_tls_errno' and `gtm_tls_get_error' can be used to obtain
+ * necessary error detail.
+ *
+ */
+_GTM_APIDECL void		gtm_tls_socket_close(gtm_tls_socket_t *socket);
+
+/* Closes an active SSL/TLS session. This frees up the session and thus makes the session not resuable for a future connection.
+ * Any subsequent connection will create a new session.
+ *
+ * Note: The function takes a pointer to the gtm_tls_socket_t structure. This is because it forces the actual `socket' value to be
+ * INVALID_TLS_SOCKET.
+ */
+_GTM_APIDECL void		gtm_tls_session_close(gtm_tls_socket_t **socket);
+
+/* Frees up any memory allocated by the SSL/TLS context. This function should typically be invoked at process exit.
+ *
+ * Arguments:
+ *   `ctx'    :  Pointer to the SSL/TLS context (initialized using `gtm_tls_init').
+ *
+ * No return value.
+ *
+ * Note: The function takes a pointer to the gtm_tls_ctx_t structure. This is because it forces the actual `ctx' value to be
+ * INVALID_TLS_CONTEXT.
+ */
+_GTM_APIDECL void		gtm_tls_fini(gtm_tls_ctx_t **ctx);
+
+#endif
diff --git a/sr_unix/gtm_tls_loadlibrary.c b/sr_unix/gtm_tls_loadlibrary.c
new file mode 100644
index 0000000..6ff631d
--- /dev/null
+++ b/sr_unix/gtm_tls_loadlibrary.c
@@ -0,0 +1,124 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+#include "mdef.h"
+
+#include <dlfcn.h>
+#include <errno.h>
+#ifdef _AIX
+#include <sys/ldr.h>
+#endif
+#include "gtm_stdio.h"
+#include "gtm_stdlib.h"
+#include "gtm_string.h"
+#include "gtm_limits.h"
+
+#include "lv_val.h"
+#include "real_len.h"
+#include "fgncal.h"	/* needed for COPY_DLLERR_MSG() */
+#include "gtmmsg.h"
+#include "gtmcrypt.h"
+
+typedef void (*gtm_tls_func_t)();	/* A generic pointer type to the TLS functions exposed by the plugin */
+
+#define TLS_DEF(x) x##_,
+enum
+{
+#include "gtm_tls_funclist.h"	/* BYPASSOK */
+gtm_tls_func_n			/* total number of TLS functions that needs to be dlsym()ed */
+};
+#undef TLS_DEF
+
+#define TLS_DEF(x) GBLDEF gtm_tls_func_t x##_fptr;
+#include "gtm_tls_funclist.h"
+#undef TLS_DEF
+
+#define GTM_TLS_LIBNAME		"libgtmtls.so"
+
+GBLREF	char	dl_err[MAX_ERRSTR_LEN];
+GBLREF	char	gtm_dist[GTM_PATH_MAX];
+
+error_def(ERR_GTMDISTUNDEF);
+
+/* Cannot include gtm_tls.h in this module due to conflicting GBLDEF/GBLREFs. So, redefine the function prototype here to silent
+ * the compiler.
+ */
+int	gtm_tls_loadlibrary(void);
+
+int	gtm_tls_loadlibrary()
+{
+	/* Initialize the table of symbol names to be used in dlsym() */
+#	define TLS_DEF(x) #x,
+	char			*gtm_tls_fname[] = {
+#							include "gtm_tls_funclist.h"
+							NULL
+						   };
+#	undef TLS_DEF
+	/* Initialize the table of locations of function pointers that are set by dlsym() */
+	gtm_tls_func_t		fptr;
+#	define TLS_DEF(x) &x##_fptr,
+	gtm_tls_func_t		*gtm_tls_fptr[] = {
+#							include "gtm_tls_funclist.h"
+							NULL
+						  };
+#	undef TLS_DEF
+	void_ptr_t		*handle;
+	char			*err_str, libpath[GTM_PATH_MAX], util_libpath[GTM_PATH_MAX];
+	int			findx;
+#	ifdef _AIX
+	char			new_libpath_env[GTM_PATH_MAX], *save_libpath_ptr, plugin_dir_path[GTM_PATH_MAX];
+	char			save_libpath[GTM_PATH_MAX];
+#	endif
+
+	assert(STRLEN(gtm_dist));
+#	ifdef _AIX
+	SNPRINTF(plugin_dir_path, GTM_PATH_MAX, "%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME);
+	SNPRINTF(libpath, GTM_PATH_MAX, "%s/%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME, GTM_TLS_LIBNAME);
+	/* Prefix LIBPATH with "$gtm_dist/plugin" so that dlopen can find the helper library (libgtmcryptutil.so). */
+	if (NULL == (save_libpath_ptr = getenv(LIBPATH_ENV)))
+		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s", plugin_dir_path);
+	else
+	{
+		/* Since the setenv below can potentially thrash the save_libpath_ptr, take a copy of it for later restore. */
+		strncpy(save_libpath, save_libpath_ptr, SIZEOF(save_libpath));
+		save_libpath[SIZEOF(save_libpath) - 1] = '\0';
+		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s:%s", plugin_dir_path, save_libpath);
+	}
+	setenv(LIBPATH_ENV, new_libpath_env, TRUE);
+#	else
+	SNPRINTF(libpath, GTM_PATH_MAX, "%s/%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME, GTM_TLS_LIBNAME);
+#	endif
+	if (NULL == (handle = dlopen(libpath, RTLD_GLOBAL | RTLD_NOW)))
+	{
+		COPY_DLLERR_MSG(err_str, dl_err);
+		return -1;
+	}
+#	ifdef _AIX
+	/* Restore old LIBPATH. */
+	if (NULL == save_libpath_ptr)
+		unsetenv(LIBPATH_ENV);
+	else
+		setenv(LIBPATH_ENV, save_libpath, TRUE);
+	/* Now verify that "libgtmcryptutil.so" was really loaded from "$gtm_dist/plugin". */
+	if (!verify_lib_loadpath(GTMCRYPT_UTIL_LIBNAME, plugin_dir_path))
+		return -1;
+#	endif
+	for (findx = 0; findx < gtm_tls_func_n; ++findx)
+	{
+		fptr = (gtm_tls_func_t)dlsym(handle, gtm_tls_fname[findx]);
+		if (NULL == fptr)
+		{
+			COPY_DLLERR_MSG(err_str, dl_err);
+			return -1;
+		}
+		*gtm_tls_fptr[findx] = fptr;
+	}
+	return 0;
+}
diff --git a/sr_unix/gtm_trigger.c b/sr_unix/gtm_trigger.c
index 1856e63..bfdddf4 100644
--- a/sr_unix/gtm_trigger.c
+++ b/sr_unix/gtm_trigger.c
@@ -233,7 +233,7 @@ CONDITION_HANDLER(gtm_trigger_complink_ch)
 	 * have their own handler but other errors are still possible. The primary use of this handler is (1) to remove
 	 * the mv_stent we created and (2) most importantly to turn off the trigger_compile flag.
 	 */
-	START_CH;
+	START_CH(TRUE);
 	TREF(trigger_compile) = FALSE;
 	run_time = gtm_trigger_comp_prev_run_time;
 	if (((unsigned char *)mv_chain == msp) && (MVST_MSAV == mv_chain->mv_st_type)
@@ -263,7 +263,7 @@ CONDITION_HANDLER(gtm_trigger_ch)
 	   always an mdb_condition_handler behind us for an earlier trigger level and we let it handle severe
 	   errors for us as it gives better diagnostics (e.g. GTM_FATAL_ERROR dumps) in addition to the file core dump.
 	*/
-	START_CH;
+	START_CH(TRUE);
 	DBGTRIGR((stderr, "gtm_trigger_ch: Failsafe condition cond handler entered with SIGNAL = %d\n", SIGNAL));
 	if (DUMPABLE)
 		/* Treat fatal errors thusly */
@@ -313,7 +313,7 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 	char		objname[GTM_PATH_MAX + 1];
 	char		zcomp_parms[(GTM_PATH_MAX * 2) + SIZEOF(mident_fixed) + SIZEOF(OBJECT_PARM) + SIZEOF(NAMEOFRTN_PARM)];
 	mstr		save_zsource;
-	int		rtnfd, rc, lenrtnname, lenobjname, len, alphnum_len, retry, save_errno;
+	int		rtnfd, rc, lenrtnname, lenobjname, len, retry, save_errno;
 	char		*mident_suffix_p1, *mident_suffix_p2, *mident_suffix_top, *namesub1, *namesub2, *zcomp_parms_ptr;
 	mval		zlfile, zcompprm;
 	DCL_THREADGBL_ACCESS;
@@ -331,15 +331,8 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 	/* Verify the routine name set by MUPIP TRIGGER and read by gvtr_db_read_hasht() is not in use */
 	if (NULL != find_rtn_hdr(&trigdsc->rtn_desc.rt_name))
 	{	/* Ooops .. need name to be more unique.. */
-		alphnum_len = alphanumeric_table_len;	/* Local copy so can override it for whitebox test */
 		namesub1 = trigdsc->rtn_desc.rt_name.addr + trigdsc->rtn_desc.rt_name.len++;
-		/* If WBTEST_HELPOUT_TRIGNAMEUNIQ is defined, set alphnum_len to 1. This way, we make the maximum
-		 * possible combinations for the uniqe trigger names to be 3 which is significantly lesser than
-		 * the actual number of combinations (62x62 = 3844). For eg., if ^a is a global having triggers defined
-		 * in 4 global directories, then the possible unique trigger names are a#1# ; a#1#A ; a#1#AA.
-		 */
-		GTM_WHITE_BOX_TEST(WBTEST_HELPOUT_TRIGNAMEUNIQ, alphnum_len, 1);
-		mident_suffix_top = (char *)alphanumeric_table + alphnum_len;
+		mident_suffix_top = (char *)alphanumeric_table + alphanumeric_table_len;
 		/* Phase 1. See if any single character can add uniqueness */
 		for (mident_suffix_p1 = (char *)alphanumeric_table; mident_suffix_p1 < mident_suffix_top; mident_suffix_p1++)
 		{
@@ -368,8 +361,9 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 			if (mident_suffix_p1 == mident_suffix_top)
 			{	/* Phase 3: Punt */
 				assert(WBTEST_HELPOUT_TRIGNAMEUNIQ == gtm_white_box_test_case_number);
-				rts_error(VARLSTCNT(5) ERR_TRIGNAMEUNIQ, 3, trigdsc->rtn_desc.rt_name.len - 2,
-					  trigdsc->rtn_desc.rt_name.addr, alphnum_len * alphnum_len);
+				rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_TRIGNAMEUNIQ, 3,
+						trigdsc->rtn_desc.rt_name.len - 2, trigdsc->rtn_desc.rt_name.addr,
+						((alphanumeric_table_len + 1) * alphanumeric_table_len) + 1);
 			}
 		}
 	}
@@ -391,7 +385,7 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 	{
 		save_errno = errno;
 		assert(FALSE);
-		rts_error(VARLSTCNT(12) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("mkstemp()"), CALLFROM,
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("mkstemp()"), CALLFROM,
 			  ERR_TEXT, 2, RTS_ERROR_TEXT(rtnname), save_errno);
 	}
 	assert(0 < rtnfd);	/* Verify file descriptor */
@@ -402,7 +396,7 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 		if (0 != rc)
 		{
 			UNLINK(rtnname);
-			rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
+			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
 		}
 	}
 #	endif
@@ -410,7 +404,7 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 	if (0 != rc)
 	{
 		UNLINK(rtnname);
-		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
 	}
 	if (NULL == memchr(trigdsc->xecute_str.str.addr, '\n', trigdsc->xecute_str.str.len))
 	{
@@ -418,14 +412,14 @@ int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
 		if (0 != rc)
 		{
 			UNLINK(rtnname);
-			rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
+			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
 		}
 	}
 	CLOSEFILE(rtnfd, rc);
 	if (0 != rc)
 	{
 		UNLINK(rtnname);
-		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, rc);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, rc);
 	}
 	assert(MAX_MIDENT_LEN > trigdsc->rtn_desc.rt_name.len);
 	zcomp_parms_ptr = zcomp_parms;
@@ -533,7 +527,8 @@ int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm)
 		if (0 != gtm_trigger_complink(trigdsc, TRUE))
 		{
 			PRN_ERROR;	/* Leave record of what error caused the compilation failure if any */
-			rts_error(VARLSTCNT(4) ERR_TRIGCOMPFAIL, 2, trigdsc->rtn_desc.rt_name.len, trigdsc->rtn_desc.rt_name.addr);
+			rts_error_csa(CSA_ARG(cs_addrs)
+				VARLSTCNT(4) ERR_TRIGCOMPFAIL, 2, trigdsc->rtn_desc.rt_name.len, trigdsc->rtn_desc.rt_name.addr);
 		}
 	}
 	assert(trigdsc->rtn_desc.rt_adr);
@@ -542,7 +537,7 @@ int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm)
 	if (!(frame_pointer->type & SFT_TRIGR))
 	{	/* Create new trigger base frame first that back-stops stack unrolling and return to us */
 		if (GTM_TRIGGER_DEPTH_MAX < (gtm_trigger_depth + 1))	/* Verify we won't nest too deep */
-			rts_error(VARLSTCNT(3) ERR_MAXTRIGNEST, 1, GTM_TRIGGER_DEPTH_MAX);
+			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_MAXTRIGNEST, 1, GTM_TRIGGER_DEPTH_MAX);
 		DBGTRIGR((stderr, "gtm_trigger: Invoking new trigger at frame_pointer 0x%016lx  ctxt value: 0x%016lx\n",
 			  frame_pointer, ctxt));
 		/* Protect against interrupts while we have only a trigger base frame on the stack */
@@ -733,7 +728,7 @@ int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm)
 		{	/* Our TP level was unwound during the trigger so throw an error */
 			DBGTRIGR((stderr, "gtm_trigger: $TLEVEL less than at start - throwing TRIGTLVLCHNG\n"));
 			gtm_trigger_fini(TRUE, FALSE);	/* dump this trigger level */
-			rts_error(VARLSTCNT(4) ERR_TRIGTLVLCHNG, 2, trigdsc->rtn_desc.rt_name.len,
+			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGTLVLCHNG, 2, trigdsc->rtn_desc.rt_name.len,
 				  trigdsc->rtn_desc.rt_name.addr);
 		}
 		rc = 0;			/* Be polite and return 0 for the (hopefully common) success case */
@@ -780,15 +775,14 @@ int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm)
 			}
 		}
 		/* Fall out and return ERR_TPRETRY to caller */
-	} else if (0 == rc)
-		/* We should never get a return code of 0. This would be out-of-design and a signal that something
+	} else
+	{	/* We should never get a return code of 0. This would be out-of-design and a signal that something
 		 * is quite broken. We cannot "rethrow" outside the trigger because it was not initially an error so
 		 * mdb_condition_handler would have no record of it (rethrown errors must have originally occurred in
 		 * or to be RE-thrown) and assert fail at best.
 		 */
-		GTMASSERT;
-	else
-	{	/* We have an unexpected return code due to some error during execution of the trigger that tripped
+		assertpro(0 != rc);
+		/* We have an unexpected return code due to some error during execution of the trigger that tripped
 		 * gtm_trigger's safety handler (i.e. an error occurred in mdb_condition_handler() established by
 		 * dm_start(). Since we are going to unwind the trigger frame and rethrow the error, we also have
 		 * to unwind all the stack frames on top of the trigger frame. Figure out how many frames that is,
@@ -801,7 +795,7 @@ int gtm_trigger(gv_trigger_t *trigdsc, gtm_trigger_parms *trigprm)
 		assert((NULL != frame_pointer) && !(SFT_TRIGR & frame_pointer->type));
 		DBGTRIGR((stderr, "gtm_trigger: Unsupported return code (%d) - unwound %d frames and now rethrowing error\n",
 			  rc, unwinds));
-		rts_error(VARLSTCNT(1) ERR_REPEATERROR);
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_REPEATERROR);
 	}
 	return rc;
 }
@@ -946,26 +940,7 @@ void gtm_trigger_cleanup(gv_trigger_t *trigdsc)
 	/* Remove break points in this routine before rmv from rtntbl */
 	zr_remove(rtnhdr, BREAKMSG);
 	/* Release any $TEXT() info this trigger has loaded */
-	if (NULL != (TREF(rt_name_tbl)).base)
-	{
-		key.var_name = mid->rt_name;
-		COMPUTE_HASH_MNAME(&key);
-		if (NULL != (tabent = lookup_hashtab_mname(TADR(rt_name_tbl), &key)))	/* note assignment */
-		{	/* We have a hash entry. Whether it has a value or not, it has a key name (if this is
-			 * the first time this trigger is being deleted) that may be pointing into the routine we
-			 * are about to remove. Migrate this key name to the stringpool.
-			 */
-			s2pool(&tabent->key.var_name);
-			if (NULL != tabent->value)
-			{	/* Has value, release the source. Entries and source are malloc'd in two blocks on UNIX */
-				src_tbl = (routine_source *)tabent->value;
-				if (NULL != src_tbl->srcbuff)
-					free(src_tbl->srcbuff);
-				free(src_tbl);
-				tabent->value = NULL;
-			}
-		}
-	}
+	free_src_tbl(rtnhdr);
 	/* Remove the routine from the rtn_table */
 	size = INTCAST((char *)rtn_names_end - (char *)mid);
 	if (0 < size)
diff --git a/sr_unix/gtm_unlink_all.c b/sr_unix/gtm_unlink_all.c
index 0b00753..3b5a733 100644
--- a/sr_unix/gtm_unlink_all.c
+++ b/sr_unix/gtm_unlink_all.c
@@ -90,9 +90,9 @@ void gtm_unlink_all(void)
 	/* Step 1: Stop M-Profiling */
 	if (is_tracing_on)
 		turn_tracing_off(NULL);
-	/* Step 2: Unwind M stack back to level 1 */
-	GOLEVEL(1, TRUE);
-	assert(1 == dollar_zlevel());
+	/* Step 2: Unwind M stack back to level 0 */
+	GOLEVEL(0, TRUE);
+	assert(0 == dollar_zlevel());
 	/* Step 3: re-Initialize $ECODE, $REFERENCE, and $TEST */
 	NULLIFY_DOLLAR_ECODE;		/* Clears $ECODE and results returned for $STACK */
 	if (NULL != gv_currkey)
@@ -122,20 +122,7 @@ void gtm_unlink_all(void)
 		 * (in USHBIN builds) we release the literal text section as part of the releasable read-only section.
 		 * Note this code is similar to code in zlput_rname() 'cept this is necessarily UNIX-only.
 		 */
-		tabent_mname = NULL;
-		if (NULL != (TREF(rt_name_tbl)).base)
-		{
-			key.var_name = rtab->rt_name;
-			COMPUTE_HASH_MNAME(&key);
-			if (NULL != (tabent_mname = lookup_hashtab_mname(TADR(rt_name_tbl), &key)) && tabent_mname->value)
-			{	/* Entries and source are malloc'd in two blocks on UNIX */
-				src_tbl = (routine_source *)tabent_mname->value;
-				if (NULL != src_tbl->srcbuff)
-					free(src_tbl->srcbuff);
-				free(src_tbl);
-				tabent_mname->value = NULL;
-			}
-		}
+		free_src_tbl(rtnhdr);
 		if ((0 == strcmp(rtnhdr->routine_name.addr, GTM_DMOD)) || (0 == strcmp(rtnhdr->routine_name.addr, GTM_CIMOD)))
 		{	/* If the routine is GTM$DMOD or GTM$CIMOD, it is allocated in one chunk by make_*mode(). Release it in
 			 * one chunk too.
diff --git a/sr_unix/gtm_utf8.c b/sr_unix/gtm_utf8.c
index 9920eed..f210b9b 100644
--- a/sr_unix/gtm_utf8.c
+++ b/sr_unix/gtm_utf8.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2007 Fidelity Information Services, Inc.*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc.*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,6 +11,7 @@
 
 #include "mdef.h"
 
+#include <stdarg.h>
 #include "gtm_string.h"
 #include "gtm_stdlib.h"
 
@@ -21,24 +22,76 @@
 
 GBLREF	boolean_t	badchar_inhibit;
 GBLREF	boolean_t	gtm_utf8_mode;
+GBLREF	void		(*stx_error_fptr)(int in_error, ...);	/* Function pointer for stx_error() so gtm_utf8.c can avoid pulling
+								 * in stx_error() in gtmsecshr.
+								 */
+GBLREF	void		(*show_source_line_fptr)(boolean_t warn); /* Func ptr for show_source_line() for same reason as above */
 
 error_def(ERR_BADCHAR);
 
+/* Return UTF8 length of mstr string in UTF8 characters */
 int utf8_len(mstr* str)
 {
-	int	charlen, bytelen;
-	char	*ptrtop, *ptr;
+	return utf8_len_real(err_rts, str);
+}
+
+/* This is the same as "utf8_len" except that it invokes UTF8_BADCHAR_STX macro which does a stx_error instead of rts_error
+ * when an invalid UTF8 character is detected in the string (and badchar_inhibit is not enabled).
+ * If UTF8_BADCHAR_STX is invoked, this function returns a -1 signalling a parse error.
+ */
+int utf8_len_stx(mstr* str)
+{
+	return utf8_len_real(err_stx, str);
+}
+
+/* This is the same as "utf8_len" except that it invokes UTF8_BADCHAR_DEC macro which does a dec_err instead of rts_error.
+ * Note only one "error" is raised for any given string and we return the length as best we can with the broken string.
+ */
+int utf8_len_dec(mstr* str)
+{
+	return utf8_len_real(err_dec, str);
+}
+
+/* The routine that does the actual work of determining the length and responding appropriately in the event an invalid
+ * UTF8 character is detected.
+ */
+STATICFNDEF int utf8_len_real(utf8_err_type err_type, mstr* str)
+{
+	int		charlen, bytelen;
+	char		*ptrtop, *ptr;
+	boolean_t	err_raised;
 
 	assert(gtm_utf8_mode);
 	ptr = str->addr;
 	ptrtop = ptr + str->len;
 	charlen = 0;
+	err_raised = FALSE;
 	if (!badchar_inhibit)
 	{
 		for (; ptr < ptrtop; charlen++, ptr += bytelen)
 		{
 			if (!UTF8_VALID(ptr, ptrtop, bytelen))
-				UTF8_BADCHAR(0, ptr, ptrtop, 0, NULL);
+			{
+				switch(err_type)
+				{
+					case err_rts:
+						UTF8_BADCHAR(0, ptr, ptrtop, 0, NULL);
+						break;			/* Never get here but keeps compiler happy */
+					case err_stx:
+						UTF8_BADCHAR_STX(0, ptr, ptrtop, 0, NULL);
+						return -1;
+					case err_dec:
+						if (!err_raised)
+						{
+							UTF8_BADCHAR_DEC(0, ptr, ptrtop, 0, NULL);
+							err_raised = TRUE;
+						}
+						bytelen = 1;		/* Assume only one char is broken */
+						break;
+					default:
+						assertpro(FALSE /* Invalid error type */);
+				}
+			}
 		}
 	} else
 	{
@@ -50,6 +103,9 @@ int utf8_len(mstr* str)
 	return charlen;
 }
 
+/* Similar to utf8_len() except it operates on a given string instead of an mval and does not observe badchar_inhibit.
+ * String must be valid or error is raised.
+ */
 int utf8_len_strict(unsigned char* ptr, int len)
 {
 	int		charlen, bytelen;
@@ -132,7 +188,6 @@ int gtm_wcwidth(wint_t code)
 	UHangulSyllableType	hst;
 
 	assert(gtm_utf8_mode);
-
 	if (0x00ad == code) /* SOFT-HYPHEN, a special format control character */
 		return 1;
 	gc = (UCharCategory)u_getIntPropertyValue((UChar32)code, UCHAR_GENERAL_CATEGORY);
@@ -158,13 +213,52 @@ int gtm_wcwidth(wint_t code)
  */
 void utf8_badchar(int len, unsigned char *str, unsigned char *strtop, int chset_len, unsigned char *chset)
 {
+	utf8_badchar_real(err_rts, len, str, strtop, chset_len, chset);
+	return;
+}
+
+/* This function is the same as "utf8_badchar" except that it does a "stx_error" instead of "rts_error". This helps
+ * to identify the line in the M program that has the compile time error.
+ */
+void utf8_badchar_stx(int len, unsigned char *str, unsigned char *strtop, int chset_len, unsigned char *chset)
+{
+	utf8_badchar_real(err_stx, len, str, strtop, chset_len, chset);
+	return;
+}
+
+/* This function is the same as "utf8_badchar" except that it does a "dec_err()" instead of "rts_error". This helps
+ * to identify the line in the M program that has the compile time error but unlike stx_error(), it does not remove
+ * the relevant generated code and replace it with a runtime OC_RTERROR triple. This is because the runtime code does
+ * the same level of checking as the compiler does so can detect the error "normally" on its own - no need for the
+ * complication with trying to cut out the right set of triples. We can just put out the compiler message and let it
+ * be.
+ */
+void utf8_badchar_dec(int len, unsigned char *str, unsigned char *strtop, int chset_len, unsigned char *chset)
+{
+	utf8_badchar_real(err_dec, len, str, strtop, chset_len, chset);
+	return;
+}
+
+/* This function issues a BADCHAR error and prints the sequences of bytes that comprise the bad multi-byte character.
+ * If "len" is 0, the function determines how many bytes this multi-byte character is comprised of and prints all of it.
+ * If "len" is non-zero, the function prints "len" number of bytes from "str" in the error message.
+ * This is the work-horse routine for the 3 above variants of utf8_badchar*(). The differences are in how the error
+ * is delivered and what happens afterwards. For the 3 options:
+ *
+ *    err_rts    - uses rts_error() to raise the error
+ *    err_stx    - uses stx_error to raise the error
+ *    err_dec	 - uses dec_err to raise the error
+ */
+STATICFNDEF void utf8_badchar_real(utf8_err_type err_type, int len, unsigned char *str, unsigned char *strtop, int chset_len,
+				   unsigned char *chset)
+{
 	unsigned char 	*strptr, *strend, *outstr;
 	unsigned char	errtxt[OUT_BUFF_SIZE];
 	int		tmplen;
 
 	assert(gtm_utf8_mode);
-	if (len == 0)
-	{ /* Determine the maximal length (upto 4 bytes) of the invalid byte sequence */
+	if (0 == len)
+	{	/* Determine the maximal length (upto 4 bytes) of the invalid byte sequence */
 		for (strend = str; len <= 4 && strend < strtop; ++strend, ++len)
 		{
 			if (UTF8_VALID(strend, strtop, tmplen))
@@ -179,12 +273,51 @@ void utf8_badchar(int len, unsigned char *str, unsigned char *strtop, int chset_
 		outstr = (unsigned char*)i2asc((uchar_ptr_t)outstr, *strptr);
 		*outstr = ',';
 	}
-	if (len > 0) /* do not include the last comma */
+	if (0 < len)		/* do not include the last comma */
 		outstr--;
-	if (chset_len > 0)
-		rts_error(VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset);
-	else
-		rts_error(VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME));
+	if (err_dec == err_type)
+	{
+		assert(NULL != show_source_line_fptr);
+		(*show_source_line_fptr)(TRUE);	/* Prints errant source line and pointer to where parsing detected the error */
+	}
+	if (0 < chset_len)
+	{
+		switch(err_type)
+		{
+			case err_rts:
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0],
+					      chset_len, chset);
+				break;		/* Never get here but keeps compiler happy */
+			case err_stx:
+				assert(NULL != stx_error_fptr);
+				(*stx_error_fptr)(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset);
+				break;
+			case err_dec:
+				dec_err(VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset);
+				break;
+			default:
+				assertpro(FALSE /* Invalid error type */);
+		}
+	} else
+	{
+
+		switch(err_type)
+		{
+			case err_rts:
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0],
+					      LEN_AND_LIT(UTF8_NAME));
+				break;		/* Never get here but keeps compiler happy */
+			case err_stx:
+				assert(NULL != stx_error_fptr);
+				(*stx_error_fptr)(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME));
+				break;
+			case err_dec:
+				dec_err(VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME));
+				break;
+			default:
+				assertpro(FALSE /* Invalid error type */);
+		}
+	}
 }
 
 /* This function scans the string from the beginning and stops the moment it finds an invalid byte sequence.
@@ -226,7 +359,7 @@ int trim_U16_line_term(UChar *buffer, int len)
 	for (lt_index = 0; u32_line_term[lt_index]; lt_index++)
 		if (uc32_cp == u32_line_term[lt_index])
 			break;
-	if (U32_LT_LF == lt_index && 1 < len)
+	if ((U32_LT_LF == lt_index) && (1 < len))
 	{
 		U16_GET(buffer, 0, len - 2, len, uc32_cp);
 		if (u32_line_term[U32_LT_CR] == uc32_cp)
@@ -237,6 +370,5 @@ int trim_U16_line_term(UChar *buffer, int len)
 		buffer[len - 1] = 0;
 		return (len - 1);
 	}
-	else
-		return len;		/* no line terminator so return it all */
+	return len;		/* no line terminator so return it all */
 }
diff --git a/sr_unix/gtm_utf8.h b/sr_unix/gtm_utf8.h
index c73e342..f7c9ca2 100644
--- a/sr_unix/gtm_utf8.h
+++ b/sr_unix/gtm_utf8.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2010 Fidelity Information Services, Inc.*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc.*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -797,6 +797,9 @@ int	trim_U16_line_term(UChar *buffer, int len);
 #define	UTF8_BADCHAR(len, str, strtop, chset_len, chset)								\
 	utf8_badchar((len), (unsigned char *)(str), (unsigned char *)(strtop), (chset_len), (unsigned char *)(chset))
 
+#define	UTF8_BADCHAR_DEC(len, str, strtop, chset_len, chset)								\
+	utf8_badchar_dec((len), (unsigned char *)(str), (unsigned char *)(strtop), (chset_len), (unsigned char *)(chset))
+
 #define	UTF8_BADCHAR_STX(len, str, strtop, chset_len, chset)								\
 	utf8_badchar_stx((len), (unsigned char *)(str), (unsigned char *)(strtop), (chset_len), (unsigned char *)(chset))
 
@@ -815,14 +818,27 @@ int	trim_U16_line_term(UChar *buffer, int len);
 		? FALSE													\
 		: u_isprint(code))
 
+/* The utf8_len[_{stx,dec)] routines do slightly different error reporting. This enum defines which type is desired */
+typedef enum
+{
+	err_rts,		/* Use rts_error() */
+	err_stx,		/* Use stx_error() */
+	err_dec			/* Use dec_error() */
+} utf8_err_type;
+
 GBLREF		boolean_t       utf8_patnumeric;
 int		utf8_len(mstr* str);
+int		utf8_len_dec(mstr* str);
 int		utf8_len_stx(mstr* str);
 int		utf8_len_strict(unsigned char* ptr, int len);
+STATICFNDCL int utf8_len_real(utf8_err_type err_type, mstr* str);
 int		gtm_wcwidth(wint_t code);
 int		gtm_wcswidth(unsigned char* ptr, int len, boolean_t strict, int nonprintwidth);
 void		utf8_badchar(int len, unsigned char* str, unsigned char *strtop, int chset_len, unsigned char* chset);
+void		utf8_badchar_dec(int len, unsigned char* str, unsigned char *strtop, int chset_len, unsigned char* chset);
 void		utf8_badchar_stx(int len, unsigned char* str, unsigned char *strtop, int chset_len, unsigned char* chset);
+STATICFNDCL void utf8_badchar_real(utf8_err_type err_type, int len, unsigned char* str, unsigned char *strtop, int chset_len,
+				   unsigned char* chset);
 unsigned char	*gtm_utf8_trim_invalid_tail(unsigned char *str, int len);
 
 /* To prevent GTMSECSHR from pulling in the function "gtmwcswidth" (used in util_output.c) and in turn the entire Unicode
diff --git a/sr_unix/gtm_utf8_stx.c b/sr_unix/gtm_utf8_stx.c
deleted file mode 100644
index d09183a..0000000
--- a/sr_unix/gtm_utf8_stx.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2006, 2007 Fidelity Information Services, Inc.*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#include "mdef.h"
-
-#include "gtm_string.h"
-#include "gtm_stdlib.h"
-
-#include "error.h"
-#include "util.h"
-#include "gtm_icu_api.h"
-#include "gtm_utf8.h"
-
-GBLREF	boolean_t	badchar_inhibit;
-GBLREF	boolean_t	gtm_utf8_mode;
-
-error_def(ERR_BADCHAR);
-
-/* This is the same as "utf8_len" except that it invokes UTF8_BADCHAR_STX macro which does a stx_error instead of rts_error.
- * If UTF8_BADCHAR_STX is invoked, this function returns a -1 signalling a parse error.
- */
-int utf8_len_stx(mstr* str)
-{
-	int	charlen, bytelen;
-	char	*ptrtop, *ptr;
-
-	assert(gtm_utf8_mode);
-	ptr = str->addr;
-	ptrtop = ptr + str->len;
-	charlen = 0;
-	if (!badchar_inhibit)
-	{
-		for (; ptr < ptrtop; charlen++, ptr += bytelen)
-		{
-			if (!UTF8_VALID(ptr, ptrtop, bytelen))
-			{
-				UTF8_BADCHAR_STX(0, ptr, ptrtop, 0, NULL);
-				return -1;
-			}
-		}
-	} else
-	{
-		for (; ptr < ptrtop; charlen++)
-			ptr = (char *)UTF8_MBNEXT(ptr, ptrtop);
-	}
-	assert(ptr == ptrtop);
-	str->char_len = charlen;
-	return charlen;
-}
-
-/* This function is the same as "utf8_badchar" except that it does a "stx_error" instead of "rts_error". This helps
- * to identify the line in the M program that has the compile time error.
- */
-void utf8_badchar_stx(int len, unsigned char *str, unsigned char *strtop, int chset_len, unsigned char *chset)
-{
-	unsigned char 	*strptr, *strend, *outstr;
-	unsigned char	errtxt[OUT_BUFF_SIZE];
-	int		tmplen;
-
-	assert(gtm_utf8_mode);
-	if (len == 0)
-	{ /* Determine the maximal length (upto 4 bytes) of the invalid byte sequence */
-		for (strend = str; len <= 4 && strend < strtop; ++strend, ++len)
-		{
-			if (UTF8_VALID(strend, strtop, tmplen))
-				break;
-		}
-	} else
-		strend = str + len;
-	strptr = str;
-	outstr = &errtxt[0];
-	for (; strptr < strend; ++strptr, ++outstr)
-	{
-		outstr = (unsigned char*)i2asc((uchar_ptr_t)outstr, *strptr);
-		*outstr = ',';
-	}
-	if (len > 0) /* do not include the last comma */
-		outstr--;
-	if (chset_len > 0)
-		stx_error(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset);
-	else
-		stx_error(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME));
-}
diff --git a/sr_unix/gtmci.c b/sr_unix/gtmci.c
index 0f66971..d18bfdd 100644
--- a/sr_unix/gtmci.c
+++ b/sr_unix/gtmci.c
@@ -104,10 +104,16 @@ error_def(ERR_MAXSTRLEN);
 #define REVERT_AND_RETURN						\
 {									\
 	REVERT; /* gtmci_ch */						\
-	TREF(in_gtmci) = FALSE;						\
 	return 0;							\
 }
 
+/* Unwind the M stack back to where the stack pointer (msp) was last saved */
+#define FGNCAL_UNWIND							\
+{									\
+	if (msp < fgncal_stack)						\
+		fgncal_unwind();					\
+}
+
 /* When passing arguments from Java, ensure that the expected types match the actual ones. If not,
  * use the arg_types array to pass back the information needed for a detailed error message.
  */
@@ -154,6 +160,24 @@ error_def(ERR_MAXSTRLEN);
 	}							\
 }
 
+/* Call-ins uses the fgncal_stack global as a marker in the stack for where to unwind the stack back to. This preserves
+ * the call-in base frame(s) but removes any other frames left on the stack as well as the parameter related mv_stents
+ * and any other mv_stents no longer needed. This macro saves the current value of fgncal_stack on the M stack in an
+ * MVST_STCK_SP type mv_stent. Note MVST_STCK_SP is chosen (instead of MVST_STCK) because MVST_STCK_SP doesn't get removed
+ * if the frame is rewritten by a ZGOTO for instance.
+ *
+ * Note: If call-in's use of setjmp/longjmp for returns is changed to use the trigger method of actually unwinding the M
+ * frames and returning "normally", then the usage of fgncal_stack likely becomes superfluous so should be looked at.
+ */
+# define SAVE_FGNCAL_STACK								\
+{											\
+	if (msp != fgncal_stack)							\
+	{										\
+		push_stck(fgncal_stack, 0, (void **)&fgncal_stack, MVST_STCK_SP);	\
+		fgncal_stack = msp;							\
+	}										\
+}
+
 static callin_entry_list* get_entry(const char* call_name)
 {	/* Lookup in a hashtable for entry corresponding to routine name */
 	ht_ent_str      *callin_entry;
@@ -217,19 +241,16 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CALLINAFTERXIT);
 		return ERR_CALLINAFTERXIT;
 	}
-	TREF(in_gtmci) = TRUE;
 	if (!gtm_startup_active || !(frame_pointer->flags & SFF_CI))
 	{
-		if ((status = gtm_init()) != 0)
-		{
-			TREF(in_gtmci) = FALSE;
+		if ((status = gtm_init()) != 0)		/* Note - sets fgncal_stack */
 			return status;
-		}
 	}
 	GTM_PTHREAD_ONLY(assert(gtm_main_thread_id_set && pthread_equal(gtm_main_thread_id, pthread_self())));
+	assert(NULL == TREF(temp_fgncal_stack));
+	FGNCAL_UNWIND;		/* note - this is outside the establish since gtmci_ch calso calls fgncal_unwind() which,
+				 * if this failed, would lead to a nested error which we'd like to avoid */
 	ESTABLISH_RET(gtmci_ch, mumps_status);
-	if (msp < fgncal_stack)	/* Unwind all arguments left on the stack by previous gtm_cij. */
-		fgncal_unwind();
 	if (!c_rtn_name)
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CIRCALLNAME);
 	if (!TREF(ci_table))	/* Load the call-in table only once from env variable GTMCI. */
@@ -297,7 +318,7 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 		REVERT_AND_RETURN;
 	}
 	*has_ret_value = has_return;
-	for (i = 0, mask = ~inp_mask; i < count; ++i, mask >>= 1, java_arg_type++, arg_blob_ptr += GTM64_ONLY(1) NON_GTM64_ONLY(2))
+	for (i = 0, mask = inp_mask; i < count; ++i, mask >>= 1, java_arg_type++, arg_blob_ptr += GTM64_ONLY(1) NON_GTM64_ONLY(2))
 	{	/* Copy the arguments' values into mval containers. Since some arguments might be declared as output-only,
 		 * we need to go over all of them unconditionally, but only do the copying for the ones that are used for
 		 * the input direction (I or IO). The integer values passed to CHECK_FOR_TYPE_MISMATCH as a second argument
@@ -309,32 +330,32 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 		{
 			case gtm_jboolean:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 0, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 					i2mval(&arg_mval, *(int *)arg_blob_ptr);
 				break;
 			case gtm_jint:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 1, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 					i2mval(&arg_mval, *(int *)arg_blob_ptr);
 				break;
 			case gtm_jlong:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 2, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 				i82mval(&arg_mval, *(gtm_int64_t *)arg_blob_ptr);
 				break;
 			case gtm_jfloat:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 3, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 					float2mval(&arg_mval, *(float *)arg_blob_ptr);
 				break;
 			case gtm_jdouble:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 4, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 					double2mval(&arg_mval, *(double *)arg_blob_ptr);
 				break;
 			case gtm_jstring:
 				CHECK_FOR_TYPES_MISMATCH(i + 1, 7, 5, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 				{
 					mstr_parm = *(gtm_string_t **)arg_blob_ptr;
 					arg_mval.mvtype = MV_STR;
@@ -347,7 +368,7 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 				break;
 			case gtm_jbyte_array:
 				CHECK_FOR_TYPES_MISMATCH(i + 1, 8, 6, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 				{
 					mstr_parm = *(gtm_string_t **)arg_blob_ptr;
 					arg_mval.mvtype = MV_STR;
@@ -360,7 +381,7 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 				break;
 			case gtm_jbig_decimal:
 				CHECK_FOR_TYPE_MISMATCH(i + 1, 9, *java_arg_type);
-				if (!(mask & 1))
+				if (MASK_BIT_ON(mask))
 				{
 					mstr_parm = *(gtm_string_t **)arg_blob_ptr;
 					arg_mval.mvtype = MV_STR;
@@ -393,16 +414,19 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 	assert(frame_pointer->flags & SFF_CI);
 	frame_pointer->mpc = frame_pointer->ctxt = PTEXT_ADR(frame_pointer->rvector);
 	REVERT;						/* Revert gtmci_ch. */
-
+	/*				*/
+	/* Drive the call_in routine	*/
+	/*				*/
 	ESTABLISH_RET(stop_image_conditional_core, mumps_status);
-	dm_start();					/* Kick off execution. */
+	dm_start(); 	/* Kick off execution */
 	REVERT;
-
+	/*				*/
+	/* Return value processing	*/
+	/*				*/
 	intrpt_ok_state = old_intrpt_state;		/* Restore the old interrupt state. */
 	var_on_cstack_ptr = save_var_on_cstack_ptr;	/* Restore the old environment's var_on_cstack_ptr. */
 	if (1 != mumps_status)
 	{
-		TREF(in_gtmci) = FALSE;
 		/* dm_start() initializes mumps_status to 1 before execution. If mumps_status is not 1,
 		 * it is either the unhandled error code propaged by $ZT/$ET (from mdb_condition_handler)
 		 * or zero on returning from ZGOTO 0 (ci_ret_code_quit).
@@ -434,7 +458,7 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 		/* Do not process parameters that are either input-only(I) or output(O/IO)
 		 * parameters that are not modified by the M routine.
 		 */
-		if ((mask & 1) && MV_DEFINED(arg_ptr))
+		if (MV_ON(mask, arg_ptr))
 		{	/* Process all output (O/IO) parameters modified by the M routine */
 			switch (arg_type)
 			{
@@ -461,15 +485,15 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 				case gtm_jstring:
 					CHECK_FOR_RET_TYPE_MISMATCH(i, 7, *arg_types);
 					MV_FORCE_STR(arg_ptr);
+					/* Since the ci_gateway.c code temporarily switches the character following the string's
+					 * content in memory to '\0' (for generation of a proper Unicode string), ensure that the
+					 * whole string resides in the stringpool, and that we do have that one byte to play with.
+					 */
+					if (!IS_IN_STRINGPOOL(arg_ptr->str.addr, arg_ptr->str.len))
+						s2pool(&arg_ptr->str);
+					ENSURE_STP_FREE_SPACE(1);
 					(*(gtm_string_t **)arg_blob_ptr)->address = arg_ptr->str.addr;
 					(*(gtm_string_t **)arg_blob_ptr)->length = arg_ptr->str.len;
-					if (((unsigned char *)arg_ptr->str.addr + arg_ptr->str.len) == stringpool.top) /*BYPASSOK*/
-					{	/* Since the ci_gateway.c code temporarily switches the character following the
-						 * string's content in memory to '\n' (for generation of a proper Unicode string),
-						 * ensure that this character is in the stringpool and not elsewhere.
-						 */
-						ENSURE_STP_FREE_SPACE(1);
-					}
 					break;
 				case gtm_jbyte_array:
 					CHECK_FOR_RET_TYPE_MISMATCH(i, 8, *arg_types);
@@ -480,15 +504,17 @@ int gtm_cij(const char *c_rtn_name, char **arg_blob, int count, int *arg_types,
 				case gtm_jbig_decimal:	/* We currently do not support output for big decimal. */
 					break;
 				default:
-					GTMASSERT;
+					assertpro((arg_type >= gtm_jboolean) && (arg_type <= gtm_jbig_decimal));
 			}
 		}
 	}
 	REVERT;
-	TREF(in_gtmci) = FALSE;
+	assert(NULL == TREF(temp_fgncal_stack));
+	FGNCAL_UNWIND;
 	return 0;
 }
 
+/* Common work-routine for gtm_ci() and gtm_cip() to drive callin */
 int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle, va_list temp_var)
 {
 	va_list			var;
@@ -524,18 +550,15 @@ int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle
 		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CALLINAFTERXIT);
 		return ERR_CALLINAFTERXIT;
 	}
-	TREF(in_gtmci) = TRUE;
 	if (!gtm_startup_active || !(frame_pointer->flags & SFF_CI))
 	{
-		if ((status = gtm_init()) != 0)
-		{
-			TREF(in_gtmci) = FALSE;
+		if ((status = gtm_init()) != 0)		/* Note - sets fgncal_stack */
 			return status;
-		}
 	}
+	assert(NULL == TREF(temp_fgncal_stack));
+	FGNCAL_UNWIND;		/* note - this is outside the establish since gtmci_ch calso calls fgncal_unwind() which,
+				 * if this failed, would lead to a nested error which we'd like to avoid */
 	ESTABLISH_RET(gtmci_ch, mumps_status);
-	if (msp < fgncal_stack)	/* unwind all arguments left on the stack by previous gtm_ci */
-		fgncal_unwind();
 	if (!c_rtn_name)
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CIRCALLNAME);
 	if (!TREF(ci_table))	/* load the call-in table only once from env variable GTMCI  */
@@ -601,7 +624,7 @@ int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle
 		 * inp_mask is inversed to achieve this.
 		 */
 		arg_mval.mvtype = MV_XZERO;
-		if (mask & 1)
+		if (MASK_BIT_ON(mask))
 		{ 	/* Output-only(O) params : advance va_arg pointer */
 			switch (entry->parms[i])
 			{
@@ -752,16 +775,19 @@ int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle
 	assert(frame_pointer->flags & SFF_CI);
 	frame_pointer->mpc = frame_pointer->ctxt = PTEXT_ADR(frame_pointer->rvector);
 	REVERT; /* gtmci_ch */
-
+	/*				*/
+	/* Drive the call_in routine	*/
+	/*				*/
 	ESTABLISH_RET(stop_image_conditional_core, mumps_status);
-	dm_start(); /* kick off execution */
+	dm_start(); 	/* Kick off execution */
 	REVERT;
-
+	/*				*/
+	/* Return value processing	*/
+	/*				*/
 	intrpt_ok_state = old_intrpt_state; /* restore the old interrupt state */
 	var_on_cstack_ptr = save_var_on_cstack_ptr; /* restore the old environment's var_on_cstack_ptr */
 	if (1 != mumps_status)
 	{
-		TREF(in_gtmci) = FALSE;
 		/* dm_start() initializes mumps_status to 1 before execution. If mumps_status is not 1,
 		 * it is either the unhandled error code propaged by $ZT/$ET (from mdb_condition_handler)
 		 * or zero on returning from ZGOTO 0 (ci_ret_code_quit).
@@ -789,7 +815,47 @@ int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle
 		/* Do not process parameters that are either input-only(I) or output(O/IO)
 		 * parameters that are not modified by the M routine.
 		 */
-		if (!(mask & 1) || !MV_DEFINED(arg_ptr))
+		if (MV_ON(mask, arg_ptr))
+		{	/* Process all output (O/IO) parameters modified by the M routine */
+			switch (arg_type)
+			{
+                                case gtm_int_star:
+                                        *va_arg(temp_var, gtm_int_t *) = mval2i(arg_ptr);
+					break;
+                                case gtm_uint_star:
+                                        *va_arg(temp_var, gtm_uint_t *) = mval2ui(arg_ptr);
+					break;
+				case gtm_long_star:
+					*va_arg(temp_var, gtm_long_t *) =
+						GTM64_ONLY(mval2i8(arg_ptr)) NON_GTM64_ONLY(mval2i(arg_ptr));
+					break;
+				case gtm_ulong_star:
+					*va_arg(temp_var, gtm_ulong_t *) =
+						GTM64_ONLY(mval2ui8(arg_ptr)) NON_GTM64_ONLY(mval2ui(arg_ptr));
+					break;
+				case gtm_float_star:
+					*va_arg(temp_var, gtm_float_t *) = mval2double(arg_ptr);
+					break;
+				case gtm_double_star:
+					*va_arg(temp_var, gtm_double_t *) = mval2double(arg_ptr);
+					break;
+				case gtm_char_star:
+					gtm_char_ptr = va_arg(temp_var, gtm_char_t *);
+					MV_FORCE_STR(arg_ptr);
+					memcpy(gtm_char_ptr, arg_ptr->str.addr, arg_ptr->str.len);
+					gtm_char_ptr[arg_ptr->str.len] = 0; /* trailing null */
+					break;
+				case gtm_string_star:
+					mstr_parm = va_arg(temp_var, gtm_string_t *);
+					MV_FORCE_STR(arg_ptr);
+					mstr_parm->length = arg_ptr->str.len;
+					memcpy(mstr_parm->address, arg_ptr->str.addr, mstr_parm->length);
+					break;
+				default:
+					va_end(temp_var);
+					assertpro(FALSE);
+			}
+		} else
 		{
 			switch (arg_type)
 			{
@@ -837,54 +903,16 @@ int gtm_ci_exec(const char *c_rtn_name, void *callin_handle, int populate_handle
 					va_end(temp_var);
 					assertpro(FALSE);
 			}
-		} else
-		{	/* Process all output (O/IO) parameters modified by the M routine */
-			switch (arg_type)
-			{
-                                case gtm_int_star:
-                                        *va_arg(temp_var, gtm_int_t *) = mval2i(arg_ptr);
-					break;
-                                case gtm_uint_star:
-                                        *va_arg(temp_var, gtm_uint_t *) = mval2ui(arg_ptr);
-					break;
-				case gtm_long_star:
-					*va_arg(temp_var, gtm_long_t *) =
-						GTM64_ONLY(mval2i8(arg_ptr)) NON_GTM64_ONLY(mval2i(arg_ptr));
-					break;
-				case gtm_ulong_star:
-					*va_arg(temp_var, gtm_ulong_t *) =
-						GTM64_ONLY(mval2ui8(arg_ptr)) NON_GTM64_ONLY(mval2ui(arg_ptr));
-					break;
-				case gtm_float_star:
-					*va_arg(temp_var, gtm_float_t *) = mval2double(arg_ptr);
-					break;
-				case gtm_double_star:
-					*va_arg(temp_var, gtm_double_t *) = mval2double(arg_ptr);
-					break;
-				case gtm_char_star:
-					gtm_char_ptr = va_arg(temp_var, gtm_char_t *);
-					MV_FORCE_STR(arg_ptr);
-					memcpy(gtm_char_ptr, arg_ptr->str.addr, arg_ptr->str.len);
-					gtm_char_ptr[arg_ptr->str.len] = 0; /* trailing null */
-					break;
-				case gtm_string_star:
-					mstr_parm = va_arg(temp_var, gtm_string_t *);
-					MV_FORCE_STR(arg_ptr);
-					mstr_parm->length = arg_ptr->str.len;
-					memcpy(mstr_parm->address, arg_ptr->str.addr, mstr_parm->length);
-					break;
-				default:
-					va_end(temp_var);
-					assertpro(FALSE);
-			}
 		}
 	}
 	va_end(temp_var);
 	REVERT;
-	TREF(in_gtmci) = FALSE;
+	assert(NULL == TREF(temp_fgncal_stack));
+	FGNCAL_UNWIND;
 	return 0;
 }
 
+/* Initial call-in driver version - does name lookup on each call */
 int gtm_ci(const char *c_rtn_name, ...)
 {
 	va_list var;
@@ -893,7 +921,9 @@ int gtm_ci(const char *c_rtn_name, ...)
 	return gtm_ci_exec(c_rtn_name, NULL, FALSE, var);
 }
 
-/* Functionality is same as that of gtmci but accepts a struct containing information about the routine. */
+/* Fast path call-in driver version - Adds a struct parm that contains name resolution info after first call
+ * to speed up dispatching.
+ */
 int gtm_cip(ci_name_descriptor* ci_info, ...)
 {
 	va_list var;
@@ -903,6 +933,7 @@ int gtm_cip(ci_name_descriptor* ci_info, ...)
 }
 
 #ifdef GTM_PTHREAD
+/* Java flavor of gtm_init() */
 int gtm_jinit()
 {
 	gtm_jvm_process = TRUE;
@@ -910,6 +941,10 @@ int gtm_jinit()
 }
 #endif
 
+/* Initialization routine - can be called directly by call-in caller or can be driven by gtm_ci*() implicitly. But
+ * if other GT.M services are to be used prior to a gtm_ci*() call (like timers, gtm_malloc/free, etc), this routine
+ * should be called first.
+ */
 int gtm_init()
 {
 	rhdtyp          	*base_addr;
@@ -932,8 +967,6 @@ int gtm_init()
 		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CALLINAFTERXIT);
 		return ERR_CALLINAFTERXIT;
 	}
-	if (!TREF(in_gtmci))
-		return 0;
 	if (!gtm_startup_active)
 	{	/* call-in invoked from C as base. GT.M hasn't been started up yet. */
 		gtm_imagetype_init(GTM_IMAGE);
@@ -953,7 +986,7 @@ int gtm_init()
 	if (!gtm_startup_active)
 	{	/* GT.M is not active yet. Create GT.M startup environment */
 		invocation_mode = MUMPS_CALLIN;
-		init_gtm();
+		init_gtm();			/* Note - this initializes fgncal_stackbase */
 		gtm_savetraps(); /* nullify default $ZTRAP handling */
 		if (NULL != (dist = (char *)GETENV(GTM_DIST)))
 		{
@@ -966,13 +999,20 @@ int gtm_init()
 		assert(gtm_startup_active);
 		assert(frame_pointer->flags & SFF_CI);
 		TREF(gtmci_nested_level) = 1;
+		/* Now that GT.M is initialized. Mark the new stack pointer (msp) so that errors
+		 * while executing an M routine do not unwind stack below this mark. It important that
+		 * the call-in frames (SFF_CI) that hold nesting information (eg. $ECODE/$STACK data
+		 * of the previous stack) are kept from being unwound.
+		 */
+		SAVE_FGNCAL_STACK;
 	} else if (!(frame_pointer->flags & SFF_CI))
 	{	/* Nested call-in: setup a new CI environment (SFF_CI frame on top of base-frame).
-		 * Mark the beginning of the new stack so that initialization errors in
-		 * call-in frame do not unwind entries of the previous stack (see gtmci_ch).
+		 * Temporarily mark the beginning of the new stack so that initialization errors in
+		 * call-in frame do not unwind entries of the previous stack (see gtmci_ch). For the
+		 * duration that temp_fgncal_stack has a non-NULL value, it overrides fgncal_stack.
 		 */
-		fgncal_stack = msp;
-		/* generate CIMAXLEVELS error if gtmci_nested_level > CALLIN_MAX_LEVEL */
+		TREF(temp_fgncal_stack) = msp;
+		/* Generate CIMAXLEVELS error if gtmci_nested_level > CALLIN_MAX_LEVEL */
 		if (CALLIN_MAX_LEVEL < TREF(gtmci_nested_level))
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_CIMAXLEVELS, 1, TREF(gtmci_nested_level));
 		/* Disallow call-ins within a TP boundary since TP restarts are not supported
@@ -987,16 +1027,20 @@ int gtm_init()
 		SET_CI_ENV(ci_ret_code_exit);
 		gtmci_isv_save();
 		(TREF(gtmci_nested_level))++;
+		/* Now that the base-frames for this call-in level have been created, we can create the mv_stent
+		 * to save the previous call-in level's fgncal_stack value and clear the override. When this call-in
+		 * level pops, fgncal_stack will be restored to the value for the previous level. When a given call
+		 * at *this* level finishes, this current value of fgncal_stack is where the stack is unrolled to to
+		 * be ready for the next call.
+		 */
+		SAVE_FGNCAL_STACK;
+		TREF(temp_fgncal_stack) = NULL;		/* Drop override */
 	}
-	/* Now that GT.M is initialized. Mark the new stack pointer (msp) so that errors
-	 * while executing an M routine do not unwind stack below this mark. It important that
-	 * the call-in frames (SFF_CI), that hold nesting information (eg. $ECODE/$STACK data
-	 * of the previous stack), are kept from being unwound.
-	 */
-	fgncal_stack = msp;
 	REVERT;
+	assert(NULL == TREF(temp_fgncal_stack));
 	return 0;
 }
+
 /* routine exposed to call-in user to exit from active GT.M environment */
 int gtm_exit()
 {
@@ -1035,14 +1079,15 @@ int gtm_exit()
 	 * our exit handler has already been called. Linux and Solaris don't need this, looking at the
 	 * other platforms we support to see if resolutions can be found. SE 05/2007
 	 */
-#ifdef _AIX
+#	ifdef _AIX
 	unatexit(gtm_exit_handler);
-#endif
+#	endif
 	REVERT;
 	gtm_startup_active = FALSE;
 	return 0;
 }
 
+/* Routine to fetch $ZSTATUS after an error has been raised */
 void gtm_zstatus(char *msg, int len)
 {
 	int msg_len;
diff --git a/sr_unix/gtmci.h b/sr_unix/gtmci.h
index cd080f6..5eee97b 100644
--- a/sr_unix/gtmci.h
+++ b/sr_unix/gtmci.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,6 +32,13 @@
 	NON_IA64_ONLY(frame_pointer->old_frame_pointer->mpc = CODE_ADDRESS(g);)	\
 }
 
+/* Macro that allows temp_fgncal_stack to override fgncal_stack. This is used in gtm_init (in gtmci.c)
+ * during creation of a new level to solve chicken and egg problem that old fgncal_stack needs to be
+ * saved but cannot be put into an mv_stent until after the level is actually created. This temp serves
+ * that purpose so only has a non-NULL value for the duration of level creation.
+ */
+#define FGNCAL_STACK ((NULL == TREF(temp_fgncal_stack)) ? fgncal_stack : TREF(temp_fgncal_stack))
+
 void	ci_restart(void);
 void	ci_ret_code(void);
 void	ci_ret_code_exit(void);
diff --git a/sr_unix/gtmci_ch.c b/sr_unix/gtmci_ch.c
index 823f915..287dea2 100644
--- a/sr_unix/gtmci_ch.c
+++ b/sr_unix/gtmci_ch.c
@@ -38,7 +38,8 @@ CONDITION_HANDLER(gtmci_ch)
 {
 	char	src_buf[MAX_ENTRYREF_LEN];
 	mstr	src_line;
-	START_CH;
+
+	START_CH(TRUE);
 	if (DUMPABLE)
 	{
 		gtm_dump();
@@ -47,9 +48,9 @@ CONDITION_HANDLER(gtmci_ch)
 	src_line.len = 0;
 	src_line.addr = &src_buf[0];
 	set_zstatus(&src_line, SIGNAL, NULL, FALSE);
-	TREF(in_gtmci) = FALSE;
-	if (msp < fgncal_stack) /* restore stack to the last marked position */
+	if (msp < FGNCAL_STACK) /* restore stack to the last marked position */
 		fgncal_unwind();
+	else TREF(temp_fgncal_stack) = NULL;	/* If fgncal_unwind() didn't run to clear this, we have to */
 	mumps_status = SIGNAL;
 	UNWIND(NULL, NULL);
 }
diff --git a/sr_unix/gtmcrypt.h b/sr_unix/gtmcrypt.h
index b628213..6789fb2 100644
--- a/sr_unix/gtmcrypt.h
+++ b/sr_unix/gtmcrypt.h
@@ -12,42 +12,33 @@
 #ifndef	GTMCRYPT_H
 #define GTMCRYPT_H
 
-#include <signal.h>
-#include <rtnhdr.h>
-#include "stack_frame.h"
 #include "gtmxc_types.h"
-#include "gtmcrypt_interface.h"
 #include "gtmimagename.h"
-#include "gtm_stdio.h"
-#include "gtm_string.h"
-#include "gtm_stdlib.h"
 #include "have_crit.h"
 #include "deferred_signal_handler.h"
-#include "gtmmsg.h"
-#include "gtmci.h"
 #include "wbox_test_init.h"
+#include "gtmmsg.h"
 #include "error.h"			/* for MAKE_MSG_WARNING macro */
 
-#define MAX_GTMCRYPT_ERR_STRLEN		2048		/* Should be kept in sync with the one in gtmcrypt_ref.h */
-
-typedef xc_status_t			(*gtmcrypt_init_t)(int);
-typedef xc_status_t			(*gtmcrypt_close_t)();
-typedef xc_status_t			(*gtmcrypt_hash_gen_t)(gtmcrypt_key_t, xc_string_t *);
-typedef xc_status_t			(*gtmcrypt_encrypt_t)(gtmcrypt_key_t, xc_string_t *, xc_string_t *);
-typedef xc_status_t			(*gtmcrypt_decrypt_t)(gtmcrypt_key_t, xc_string_t *, xc_string_t *);
-typedef xc_status_t			(*gtmcrypt_getkey_by_name_t)(xc_string_t *, gtmcrypt_key_t *);
-typedef xc_status_t			(*gtmcrypt_getkey_by_hash_t)(xc_string_t *, gtmcrypt_key_t *);
-typedef char*				(*gtmcrypt_strerror_t)();
-
-GBLREF	gtmcrypt_init_t			gtmcrypt_init_fnptr;
-GBLREF	gtmcrypt_close_t		gtmcrypt_close_fnptr;
-GBLREF	gtmcrypt_hash_gen_t		gtmcrypt_hash_gen_fnptr;
-GBLREF	gtmcrypt_encrypt_t		gtmcrypt_encrypt_fnptr;
-GBLREF	gtmcrypt_decrypt_t		gtmcrypt_decrypt_fnptr;
-GBLREF	gtmcrypt_getkey_by_name_t 	gtmcrypt_getkey_by_name_fnptr;
-GBLREF	gtmcrypt_getkey_by_hash_t 	gtmcrypt_getkey_by_hash_fnptr;
-GBLREF	gtmcrypt_strerror_t		gtmcrypt_strerror_fnptr;
+#define	gtmcrypt_init			(*gtmcrypt_init_fnptr)
+#define	gtmcrypt_close			(*gtmcrypt_close_fnptr)
+#define	gtmcrypt_hash_gen		(*gtmcrypt_hash_gen_fnptr)
+#define	gtmcrypt_encrypt		(*gtmcrypt_encrypt_fnptr)
+#define	gtmcrypt_decrypt		(*gtmcrypt_decrypt_fnptr)
+#define	gtmcrypt_getkey_by_name 	(*gtmcrypt_getkey_by_name_fnptr)
+#define	gtmcrypt_getkey_by_hash 	(*gtmcrypt_getkey_by_hash_fnptr)
+#define	gtmcrypt_strerror		(*gtmcrypt_strerror_fnptr)
+
+/* It's important that the "gtmcrypt_interface.h" include should be *after* the above macro definitions. This way, the function
+ * prototypes defined in the header file will automatically be expanded to function pointers saving us the trouble of explicitly
+ * defining them once again.
+ */
+#include "gtmcrypt_interface.h"
+
 GBLREF	boolean_t			gtmcrypt_initialized;
+GBLREF	mstr				pvt_crypt_buf;
+GBLREF	char				dl_err[];
+
 LITREF	char				gtmcrypt_repeat_msg[];
 
 error_def(ERR_CRYPTDLNOOPEN);
@@ -55,43 +46,11 @@ error_def(ERR_CRYPTDLNOOPEN2);
 error_def(ERR_CRYPTHASHGENFAILED);
 error_def(ERR_CRYPTINIT);
 error_def(ERR_CRYPTKEYFETCHFAILED);
-error_def(ERR_CRYPTKEYFETCHFAILEDNF);
-error_def(ERR_CRYPTNOPSWDINTP);
 error_def(ERR_CRYPTOPFAILED);
 
-/* The standard shared library suffix for HPUX on HPPA is .sl.
- * On HPUX/IA64, the standard suffix was changed to .so (to match other Unixes) but for
- * the sake of compatibility, they still accept (and look for) .sl if .so is not present.
- * Nevertheless, we use the standard suffix on all platforms.
- */
-#if (defined(__hpux) && defined(__hppa))
-#	define	GTMCRYPT_LIBNAME	"libgtmcrypt.sl"
-#elif defined(__MVS__)
-#	define	GTMCRYPT_LIBNAME        "libgtmcrypt.dll"
-#else
-#	define	GTMCRYPT_LIBNAME	"libgtmcrypt.so"
-#endif
-
-#define	GTMCRYPT_LIBFLAGS		(RTLD_NOW | RTLD_GLOBAL)
-
-#define	GTMCRYPT_INIT_FNAME		"gtmcrypt_init"
-#define	GTMCRYPT_CLOSE_FNAME		"gtmcrypt_close"
-#define	GTMCRYPT_HASH_GEN_FNAME		"gtmcrypt_hash_gen"
-#define	GTMCRYPT_ENCRYPT_FNAME		"gtmcrypt_encrypt"
-#define	GTMCRYPT_DECRYPT_FNAME		"gtmcrypt_decrypt"
-#define GTMCRYPT_GETKEY_BY_NAME		"gtmcrypt_getkey_by_name"
-#define GTMCRYPT_GETKEY_BY_HASH		"gtmcrypt_getkey_by_hash"
-#define	GTMCRYPT_STRERROR		"gtmcrypt_strerror"
-
-#define	GTM_PASSWD			"gtm_passwd"
-
-#define GTMCRYPT_INVALID_KEY_HANDLE		-1		/* Should be kept in sync with INVALID_HANDLE in gtmcrypt_ref.h */
-
-uint4 gtmcrypt_entry(void);
-
-/* =====================================================================================================*/
-/* 					Error Reporting Macros						*/
-/* =====================================================================================================*/
+/* =====================================================================================================*
+ * 					Error Reporting Macros						*
+ * =====================================================================================================*/
 
 #define CRYPTERR_MASK				0x10000000
 #define REPEAT_MSG_MASK				0x20000000
@@ -103,10 +62,19 @@ uint4 gtmcrypt_entry(void);
 #define CLEAR_CRYPTERR_MASK(ERRID)		(ERRID = ((ERRID) & ~CRYPTERR_MASK))
 #define CLEAR_REPEAT_MSG_MASK(ERRID)		(ERRID = ((ERRID) & ~REPEAT_MSG_MASK))
 
+#define REALLOC_CRYPTBUF_IF_NEEDED(LEN)					\
+{									\
+	if (!pvt_crypt_buf.addr || (pvt_crypt_buf.len < LEN))		\
+	{								\
+		if (pvt_crypt_buf.addr)					\
+			free(pvt_crypt_buf.addr);			\
+		pvt_crypt_buf.addr = (char *)malloc(LEN);		\
+		pvt_crypt_buf.len = LEN;				\
+	}								\
+}
+
 #define GTMCRYPT_REPORT_ERROR(ERRID, MECHANISM, LEN, PTR)									\
 {																\
-	GBLREF	char		dl_err[];											\
-																\
 	int			errid;												\
 	const char		*errptr;											\
 																\
@@ -122,7 +90,7 @@ uint4 gtmcrypt_entry(void);
 	} else															\
 	{															\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		errptr = (const char *) (*gtmcrypt_strerror_fnptr)();								\
+		errptr = (const char *) gtmcrypt_strerror();									\
 		ENABLE_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
 	}															\
 	CLEAR_REPEAT_MSG_MASK(errid);												\
@@ -134,7 +102,7 @@ uint4 gtmcrypt_entry(void);
 /* 					Utility Macros							*/
 /* =====================================================================================================*/
 
-/* Helper macro to package the address and length in a xc_string_t type */
+/* Helper macro to package the address and length in a gtm_string_t type */
 #define PACKAGE_XCSTRING(xcstring, buf, buflen)											\
 {																\
 	xcstring.address = buf;													\
@@ -148,18 +116,16 @@ uint4 gtmcrypt_entry(void);
 
 #define BLK_NEEDS_ENCRYPTION(LEVL, BSIZ)		IS_BLK_ENCRYPTED(LEVL, BSIZ)
 
-#define BLOCK_REQUIRE_ENCRYPTION(FLAG, LEVL, BSIZ) 	(FLAG && IS_BLK_ENCRYPTED(LEVL, BSIZ))
+#define BLK_NEEDS_ENCRYPTION3(FLAG, LEVL, BSIZ) 	(FLAG && IS_BLK_ENCRYPTED(LEVL, BSIZ))
 
 #define ENCR_INITIALIZED 				gtmcrypt_initialized
+
 #define ENCR_WBOX_ENABLED				(gtm_white_box_test_case_enabled 					\
 				 				&& (WBTEST_ENCRYPT_INIT_ERROR == gtm_white_box_test_case_number))
 
 #define ASSERT_ENCRYPTION_INITIALIZED			assert(ENCR_INITIALIZED || ENCR_WBOX_ENABLED)
 
-#define PROMPT_PASSWD(PTR)				(IS_MUMPS_IMAGE								\
-								&& (NULL != (PTR = (char *)getenv(GTM_PASSWD)))			\
-								&& (0 == strlen(PTR)))						\
-
+#define	IS_INTERACTIVE_MODE				(IS_MUMPS_IMAGE)
 
 #define GTMCRYPT_COPY_HASH(SRC, DST)												\
 {																\
@@ -167,92 +133,30 @@ uint4 gtmcrypt_entry(void);
 	DST->is_encrypted = SRC->is_encrypted;											\
 }																\
 
-/* General Note : All macros below (execpt GTMCRYPT_CLOSE) takes in CSA as their first parameter. Currently, most macros don't
- * use CSA, but is supplied by the caller anyways in case later a need to arises to reference CSA.
+/* General Note : All macros below (except GTMCRYPT_CLOSE) takes CSA as their first parameter. Currently, most macros don't
+ * use CSA, but is supplied by the caller anyways in case a need arises, in the future, to reference CSA.
  */
-#define	ALLOC_BUFF_GET_ENCR_KEY(CSA, HASH, ALLOC_SIZE, RC)									\
-{																\
-	assert((0 < ALLOC_SIZE) && (NULL != CSA));										\
-	RC = 0;															\
-	GTMCRYPT_GETKEY(CSA, HASH, CSA->encr_key_handle, RC);									\
-	if (0 == RC)														\
-		(CSA)->encrypted_blk_contents = (char *)malloc(ALLOC_SIZE); 							\
-}
 
 /* Database specific initialization - gets the encryption key corresponding to the HASH (SHA-512 currently) found in the database
  * file header and allocates a buffer large enough to encrypt/decrypt database block sizes.
  */
 #define INIT_DB_ENCRYPTION(CSA, CSD, RC)											\
 {																\
-	GBLREF stack_frame		*frame_pointer;										\
-	GBLREF uint4			dollar_tlevel;										\
-	char 				*ptr, *key_hash;									\
-	boolean_t			call_ci_ret_code_quit, prompt_passwd;							\
-																\
 	RC = 0;															\
-	prompt_passwd = PROMPT_PASSWD(ptr);											\
-	if (prompt_passwd && dollar_tlevel)											\
-	{	/* GT.M call-ins don't support TP transactions (see gtm_ci_exec) */						\
-		rts_error_csa(CSA_ARG(CSA) VARLSTCNT(1) ERR_CRYPTNOPSWDINTP); 							\
-	}															\
-	assert(!IS_MUMPS_IMAGE || !(frame_pointer->flags & SFF_CI)); /* ensures not already in gtm_ci */			\
-	/* ALLOC_BUFF_GET_ENCR_KEY eventually invokes gtmcrypt_getkey_by_hash to obtain the encryption key for the concerned	\
-	 * database. At this point encryption initialization is already done (as part of INIT_PROC_ENCRYPTION) even if the	\
-	 * user had entered a wrong password. But, the wrong password isn't validated until the actual encryption/decryption	\
-	 * happens (which is now). If user fixes the wrong-password situation by setting gtm_passwd to null-string and once	\
-	 * again accesses the database, we'd come back here; but this time, gtmcrypt_getkey_by_hash will end up invoking	\
-	 * gtm_ci (to obtain the password) and so a corresponding ci_ret_code_quit must be done. Make a note of this so we	\
-	 * can accordingly invoke ci_ret_code_quit (after gtmcrypt_getkey_by_hash)						\
-	 */															\
-	call_ci_ret_code_quit = (prompt_passwd && !(frame_pointer->flags & SFF_CI));						\
-	key_hash = CSD->encryption_hash;											\
-	ALLOC_BUFF_GET_ENCR_KEY(CSA, key_hash, (CSD->blk_size + SIZEOF(int4)), RC);						\
-	if (call_ci_ret_code_quit)												\
-		ci_ret_code_quit();												\
+	GTMCRYPT_GETKEY(CSA, CSD->encryption_hash, CSA->encr_key_handle, RC);							\
 }
 
-/* =====================================================================================================*/
-/* 					Plugin Related Macros						*/
-/* =====================================================================================================*/
-
 /* Process specific initialization - dlopen libgtmcrypt.so and invoke gtmcrypt_init() */
 #define INIT_PROC_ENCRYPTION(CSA, RC)												\
 {																\
-	GBLREF stack_frame		*frame_pointer;										\
-	GBLREF uint4			dollar_tlevel;										\
-	boolean_t			call_ci_ret_code_quit, prompt_passwd;							\
-	char 				*ptr;											\
-																\
 	RC = 0;															\
 	if (!gtmcrypt_initialized)												\
 	{															\
 		if (0 == (RC = gtmcrypt_entry()))										\
 		{	/* dlopen succeeded */											\
-			assert(NULL != gtmcrypt_init_fnptr);									\
-			assert(NULL != gtmcrypt_getkey_by_hash_fnptr);								\
-			assert(NULL != gtmcrypt_getkey_by_name_fnptr);								\
-			assert(NULL != gtmcrypt_hash_gen_fnptr);								\
-			assert(NULL != gtmcrypt_encrypt_fnptr); 								\
-			assert(NULL != gtmcrypt_decrypt_fnptr); 								\
-			assert(NULL != gtmcrypt_strerror_fnptr);								\
-			assert(NULL != gtmcrypt_close_fnptr);									\
-			prompt_passwd = PROMPT_PASSWD(ptr);									\
-			if (prompt_passwd && dollar_tlevel)									\
-			{	/* GT.M call-ins don't support TP transactions (see gtm_ci_exec)*/				\
-				rts_error_csa(CSA_ARG(CSA) VARLSTCNT(1) ERR_CRYPTNOPSWDINTP);					\
-			}													\
-			assert(!IS_MUMPS_IMAGE || !(frame_pointer->flags & SFF_CI)); /* ensures not already in gtm_ci */	\
-			/* If password is set to empty string, gtmcrypt_init (called below) invokes gtm_ci to obtain the	\
-			 * password at runtime (if we are MUMPS) in which case ci_ret_code_quit() needs to be invoked. Make	\
-			 * a note of this so we can accordingly invoke ci_ret_code_quit (after gtmcrypt_init)			\
-			 */													\
-			call_ci_ret_code_quit = (prompt_passwd && !(frame_pointer->flags & SFF_CI));				\
-			/* IS_MUMPS_IMAGE below tells the plugin to prompt for password (if not already provided in env) */	\
 			DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);								\
-			xc_status_t init_ret_status = (*gtmcrypt_init_fnptr)(IS_MUMPS_IMAGE);					\
+			gtm_status_t init_ret_status = gtmcrypt_init(IS_INTERACTIVE_MODE ? GTMCRYPT_OP_INTERACTIVE_MODE : 0);	\
 			ENABLE_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);								\
-			if (call_ci_ret_code_quit)										\
-				ci_ret_code_quit();	/* Unwind stack frames */						\
 			if (0 != init_ret_status)										\
 				RC = SET_CRYPTERR_MASK(ERR_CRYPTINIT);								\
 			else													\
@@ -275,7 +179,7 @@ uint4 gtmcrypt_entry(void);
 	{															\
 		PACKAGE_XCSTRING(xc_hash, hash, GTMCRYPT_HASH_LEN);								\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		if (0 != (status = (*gtmcrypt_getkey_by_hash_fnptr)(&xc_hash, &key_handle)))					\
+		if (0 != (status = gtmcrypt_getkey_by_hash(&xc_hash, &key_handle)))						\
 			RC = SET_CRYPTERR_MASK(ERR_CRYPTKEYFETCHFAILED);							\
 		else														\
 			RC = 0;													\
@@ -302,9 +206,9 @@ uint4 gtmcrypt_entry(void);
 		PACKAGE_XCSTRING(xc_filename, filename, filename_len);								\
 		PACKAGE_XCSTRING(xc_hash, hash, GTMCRYPT_HASH_LEN);								\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		if (0 == (status = (*gtmcrypt_getkey_by_name_fnptr)(&xc_filename, &handle)))					\
+		if (0 == (status = gtmcrypt_getkey_by_name(&xc_filename, &handle)))						\
 		{														\
-			if (0 == (status = (*gtmcrypt_hash_gen_fnptr)(handle, &xc_hash)))					\
+			if (0 == (status = gtmcrypt_hash_gen(handle, &xc_hash)))						\
 			{													\
 				memcpy(hash, xc_hash.address, GTMCRYPT_HASH_LEN);						\
 				RC = 0;												\
@@ -327,7 +231,7 @@ uint4 gtmcrypt_entry(void);
 		PACKAGE_XCSTRING(unencrypted_block, inbuf, inbuf_len);								\
 		PACKAGE_XCSTRING(encrypted_block, outbuf, inbuf_len);								\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		if (0 == (status = (*gtmcrypt_encrypt_fnptr)(key_handle, &unencrypted_block, &encrypted_block)))		\
+		if (0 == (status = gtmcrypt_encrypt(key_handle, &unencrypted_block, &encrypted_block)))				\
 			RC = 0;													\
 		else														\
 			RC = SET_CRYPTERR_MASK(ERR_CRYPTOPFAILED);								\
@@ -346,7 +250,7 @@ uint4 gtmcrypt_entry(void);
 		PACKAGE_XCSTRING(encrypted_block, inbuf, inbuf_len);								\
 		PACKAGE_XCSTRING(unencrypted_block, outbuf, inbuf_len);								\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		if (0 == (status = (*gtmcrypt_decrypt_fnptr)(key_handle, &encrypted_block, &unencrypted_block)))		\
+		if (0 == (status = gtmcrypt_decrypt(key_handle, &encrypted_block, &unencrypted_block)))				\
 			RC = 0;													\
 		else														\
 			RC = SET_CRYPTERR_MASK(ERR_CRYPTOPFAILED);								\
@@ -360,10 +264,13 @@ uint4 gtmcrypt_entry(void);
 	if (gtmcrypt_initialized)												\
 	{															\
 		DEFER_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
-		(*gtmcrypt_close_fnptr)();											\
+		gtmcrypt_close();												\
 		gtmcrypt_initialized = FALSE;											\
 		ENABLE_INTERRUPTS(INTRPT_IN_CRYPT_SECTION);									\
 	}															\
 }
 
+uint4 gtmcrypt_entry(void);
+boolean_t verify_lib_loadpath(const char *libname, char *loadpath);
+
 #endif /* GTMCRYPT_H */
diff --git a/sr_unix/gtmcrypt.tab b/sr_unix/gtmcrypt.tab
deleted file mode 100644
index 67b1465..0000000
--- a/sr_unix/gtmcrypt.tab
+++ /dev/null
@@ -1 +0,0 @@
-getpass:char* getpass^GETPASS(I:gtm_int_t)
diff --git a/sr_unix/gtmcrypt_dbk_ref.c b/sr_unix/gtmcrypt_dbk_ref.c
index 517051c..0fe0e8b 100644
--- a/sr_unix/gtmcrypt_dbk_ref.c
+++ b/sr_unix/gtmcrypt_dbk_ref.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc 	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc 	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -9,31 +9,47 @@
  *								*
  ****************************************************************/
 
-#define _FILE_OFFSET_BITS	64	/* Needed to compile gpgme client progs also with large file support */
-
-#include <stdio.h>			/* BYPASSOK -- Plugin doesn't have access to gtm_* header files */
-#include <string.h>			/* BYPASSOK -- see above */
-#include <unistd.h>			/* BYPASSOK -- see above */
-#include <stdlib.h>			/* BYPASSOK -- see above */
-#include <sys/stat.h>			/* BYPASSOK -- see above */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/stat.h>
 #include <ctype.h>
 #include <assert.h>
 #include <errno.h>
 #include <gpgme.h>			/* gpgme functions */
 #include <gpg-error.h>			/* gcry*_err_t */
-#include "gtmxc_types.h"		/* xc_string, xc_status_t and other callin interfaces xc_fileid */
+#include <libconfig.h>
+
+#include "gtmxc_types.h"
+
+#include "gtmcrypt_util.h"
 #include "gtmcrypt_interface.h"		/* Function prototypes for gtmcrypt*.* functions */
+
 #include "gtmcrypt_ref.h"
-#include "gtmcrypt_sym_ref.h"
 #include "gtmcrypt_dbk_ref.h"
+#include "gtmcrypt_sym_ref.h"
 #include "gtmcrypt_pk_ref.h"
 
-#define NEWLINE		0x0A
+#define NEWLINE			0x0A
 
-GBLDEF int		num_entries;
-GBLREF int		can_prompt_passwd;
-GBLDEF gtm_dbkeys_tbl	*tbl_head;
-GBLDEF gtm_dbkeys_tbl	**fast_lookup_entry;
+#define PARSE_ERROR_PREFIX	"Error parsing database key file"
+#define LOOKING_FOR_DB		0x1
+#define LOOKING_FOR_KEY		0x2
+
+#define PARSE_COMPLETED		0x1
+#define KEEP_GOING		0x2
+
+STATICDEF int			n_dbkeys;
+STATICDEF char			gc_dbk_filename[GTM_PATH_MAX];
+STATICDEF gtm_dbkeys_tbl	*tbl_head;
+STATICDEF config_t		gtmcrypt_cfg;
+GBLDEF gtm_dbkeys_tbl		**fast_lookup_entry;
+GBLDEF int			gc_dbk_file_format;
+
+GBLREF	passwd_entry_t		*gtmcrypt_pwent;
+GBLREF	int			gtmcrypt_init_flags;
 
 /* Free up the linked list of database-symmetric key association AFTER scrubbing off the contents of the raw symmetric key and
  * its corresponding hash
@@ -55,24 +71,27 @@ void gc_dbk_scrub_entries()
 		}
 #		endif
 		temp = cur->next;
-		GC_FREE_TBL_ENTRY(cur); /* Note, this will memset the symmetric_key to 0 before free'ing */
+		GTM_XCFILEID_FREE(cur->fileid);
+		memset(cur->symmetric_key, 0, SYMMETRIC_KEY_MAX);
+		memset(cur->symmetric_key_hash, 0, GTMCRYPT_HASH_LEN);
+		FREE(cur);
 		cur = temp;
 	}
 	if (NULL != fast_lookup_entry)
-		GC_FREE(fast_lookup_entry);
-	num_entries = 0;
+		FREE(fast_lookup_entry);
+	n_dbkeys = 0;
 }
 
-/* Given a xc_fileid, containing a unique description of the dat file, the function searches for it's
+/* Given a fileid, containing a unique description of the dat file, the function searches for it's
  * entry in the linked list. On unsuccessful search, returns NULL.
  */
-gtm_dbkeys_tbl* gc_dbk_get_entry_by_fileid(xc_fileid_ptr_t fileid)
+gtm_dbkeys_tbl* gc_dbk_get_entry_by_fileid(gtm_fileid_ptr_t fileid)
 {
 	gtm_dbkeys_tbl *cur = tbl_head;
 
 	while (NULL != cur)
 	{
-		if (!cur->fileid_dirty && (!cur->symmetric_key_dirty) && (gtm_is_file_identical_fptr(fileid, cur->fileid)))
+		if (!cur->fileid_dirty && (!cur->symmetric_key_dirty) && (gtm_is_file_identical(fileid, cur->fileid)))
 			break;
 		cur = (gtm_dbkeys_tbl *)cur->next;
 	}
@@ -80,7 +99,7 @@ gtm_dbkeys_tbl* gc_dbk_get_entry_by_fileid(xc_fileid_ptr_t fileid)
 }
 
 /* Given a hash, the function returns the entry in the linked list that matches with the given hash. Otherwise, NULL is returned */
-gtm_dbkeys_tbl* gc_dbk_get_entry_by_hash(xc_string_t *hash)
+gtm_dbkeys_tbl* gc_dbk_get_entry_by_hash(gtm_string_t *hash)
 {
 	gtm_dbkeys_tbl *cur = tbl_head;
 
@@ -94,13 +113,12 @@ gtm_dbkeys_tbl* gc_dbk_get_entry_by_hash(xc_string_t *hash)
 	return cur;
 }
 
-xc_status_t	gc_dbk_fill_gtm_dbkeys_fname(char *fname)
+STATICFNDEF int	gc_dbk_get_dbkeys_fname(char *fname, int *stat_success)
 {
 	char			*ptr;
-	int			status;
 	struct stat		stat_buf;
 
-	if (ptr = getenv(GTM_DBKEYS))
+	if (NULL != (ptr = getenv(GTM_DBKEYS)))
 	{
 		if (0 == STRLEN(ptr))
 		{
@@ -116,6 +134,7 @@ xc_status_t	gc_dbk_fill_gtm_dbkeys_fname(char *fname)
 				SNPRINTF(fname, GTM_PATH_MAX, "%s", ptr);
 			} else
 			{
+				assert(FALSE);
 				UPDATE_ERROR_STRING("%s is neither a directory nor a regular file", ptr);
 				return GC_FAILURE;
 			}
@@ -128,7 +147,7 @@ xc_status_t	gc_dbk_fill_gtm_dbkeys_fname(char *fname)
 			UPDATE_ERROR_STRING("Cannot find DB keys file - %s. %s", ptr, strerror(errno));
 			return GC_FAILURE;
 		}
-	} else if (ptr = getenv(HOME))
+	} else if (NULL != (ptr = getenv(HOME)))
 	{
 		SNPRINTF(fname, GTM_PATH_MAX, "%s/%s", ptr, DOT_GTM_DBKEYS);
 	} else
@@ -136,173 +155,256 @@ xc_status_t	gc_dbk_fill_gtm_dbkeys_fname(char *fname)
 		UPDATE_ERROR_STRING("Neither $"GTM_DBKEYS "nor $"HOME " is defined");
 		return GC_FAILURE;
 	}
-	return GC_SUCCESS;
-}
-/* Initialize the linked list with minimal things. For each pair of entries in the db key file, load the
- * file names into the linked list and validate the format of the entries. Returns error if the format is
- * not the one that's expected. This is a fatal error and program will not continue on encountering this
- * error. Another fatal error is the 'gtm_dbkeys' env variable not set
- */
-xc_status_t gc_dbk_load_entries_from_file()
-{
-	FILE			*gtm_dbkeys_fp;
-	int			current_state, count, status, space_cnt, line_no = 0, line_type, filename_len;
-	int			looking_for_dat_entry = 1, looking_for_key_entry = 2, buflen, save_errno;
-	const char		*prefix = "Error parsing database key file";
-	char			buf[LINE_MAX], gtm_dbkeys_fname[GTM_PATH_MAX];
-	struct stat		stat_info;
-	static time_t		last_modified = 0;
-	gtm_dbkeys_tbl		*node = NULL;
-
-	if (GC_SUCCESS != gc_dbk_fill_gtm_dbkeys_fname(&gtm_dbkeys_fname[0]))
-		return GC_FAILURE;
-	if (0 != stat(gtm_dbkeys_fname, &stat_info))
+	if (0 != stat(fname, &stat_buf))
 	{
-		save_errno = errno;
-		if (ENOENT == save_errno)
+		*stat_success = FALSE;
+		if (ENOENT == errno)
 		{
-			UPDATE_ERROR_STRING("Cannot find DB keys file - %s", gtm_dbkeys_fname);
+			UPDATE_ERROR_STRING("Cannot find DB keys file - %s", fname);
 		} else
-			UPDATE_ERROR_STRING("Cannot find DB keys file - %s. %s", gtm_dbkeys_fname, strerror(save_errno));
-		return GC_FAILURE;
-	}
-	if (last_modified == stat_info.st_mtime)
-		return GC_SUCCESS;/* Nothing changed since we last read it. So, return success */
-	last_modified = stat_info.st_mtime;
-	if (NULL == (gtm_dbkeys_fp = fopen(gtm_dbkeys_fname, "r")))
-	{
-		save_errno = errno;
-		UPDATE_ERROR_STRING("Cannot open DB keys file - %s. %s", gtm_dbkeys_fname, strerror(save_errno));
+		{
+			UPDATE_ERROR_STRING("Cannot find DB keys file - %s. %s", fname, strerror(errno));
+		}
 		return GC_FAILURE;
 	}
-	/* Read the file and parse the contents and fill a mapping table */
-	/* Note the format of this dbkeys will be like this -
-	 * 	dat <db file1 path>
-	 *	key <key file1 name>
-	 *	dat <db file2 path>
-	 *	key <key file2 name>
+	*stat_success = TRUE;
+	return GC_SUCCESS;
+}
+
+STATICFNDEF int gc_dbk_get_single_entry(void *handle, char **db, char **key, int n)
+{
+	FILE			*fp;
+	int			current_state, space_cnt, line_type, filename_len, buflen;
+	char			buf[LINE_MAX];
+	static int		line_no;
+	config_setting_t	*db_setting, *elem;
+
+	/* The caller makes sure that the file format at this point is either the old $gtm_dbkeys flat file format or the new
+	 * libconfig file format. Assert accordingly. In PRO, if the file format is neither, we fall-through anyways and attempt
+	 * to parse the flat-file provides an appropriate error message to the user.
 	 */
-	current_state = looking_for_dat_entry;	/* To start with we are looking for a database entry */
-	if (tbl_head)
+	assert((LIBCONFIG_FILE_FORMAT == gc_dbk_file_format) || (DBKEYS_FILE_FORMAT == gc_dbk_file_format));
+	if (LIBCONFIG_FILE_FORMAT == gc_dbk_file_format)
 	{
-		gc_dbk_scrub_entries();	/* free up the existing linked list as we are about to create a fresh one */
-		tbl_head = NULL;
+		db_setting = (config_setting_t *)handle;
+		if (n + 1 == config_setting_length(db_setting))
+			return PARSE_COMPLETED;
+		if (NULL != (elem = config_setting_get_elem(db_setting, n)))
+		{
+			if (!config_setting_lookup_string(elem, "dat", (const char **)db))
+			{
+				UPDATE_ERROR_STRING("In config file %s, entry# %d corresponding to database.keys "
+							"does not have a `dat' item", gc_dbk_filename, n + 1);
+				return -1;
+			}
+
+			if (!config_setting_lookup_string(elem, "key", (const char **)key))
+			{
+				UPDATE_ERROR_STRING("In config file %s, entry# %d corresponding to database.keys "
+							"does not have a `key' item", gc_dbk_filename, n + 1);
+				return -1;
+			}
+			return KEEP_GOING;
+		}
+		assert(FALSE);	/* We should never reach here as that would mean we couldn't find the nth entry in database.keys. */
 	}
-	while (!feof(gtm_dbkeys_fp))
+	/* Fall-through: Old $gtm_dbkeys flat file format. Read a single pair of database-key entry. */
+	fp = (FILE *)handle;
+	current_state = LOOKING_FOR_DB;
+	while (!feof(fp))
 	{
-		if (NULL == fgets(buf, LINE_MAX, gtm_dbkeys_fp))
+		if (NULL == fgets(buf, LINE_MAX, fp))
 			break;
 		line_no++;
 		buflen = STRLEN(buf);
 		if (NEWLINE != buf[buflen - 1])
-		{	/* last character in the read buffer is not a newline implying that the line contains more than
-			 * LINE_MAX characters.
+		{	/* Last character in the buffer is not a newline implying that the line contains more than LINE_MAX
+			 * characters.
 			 */
-			 fclose(gtm_dbkeys_fp);
-			 UPDATE_ERROR_STRING("%s. Entry at line: %d longer than %ld characters", prefix, line_no, LINE_MAX);
-			 return GC_FAILURE;
+			UPDATE_ERROR_STRING("%s. Entry at line: %d longer than %ld characters", PARSE_ERROR_PREFIX, line_no,
+							LINE_MAX);
+			return -1;
 		}
-		buf[buflen - 1] = '\0'; /* strip off the newline at the end */
-		space_cnt = 0;
-		while (isspace(buf[space_cnt]))		/* BYPASSOK -- don't have access to gtm_ctype.h */
-			space_cnt++;	/* go past any whitespace characters */
-		assert(space_cnt <= (buflen - 1));
+		buf[--buflen] = '\0'; /* strip off the newline at the end */
+		for (space_cnt = 0; isspace(buf[space_cnt]); space_cnt++)	/* BYPASSOK -- cannot use ISSPACE */
+			;
+		assert(space_cnt <= buflen);
 		if ((0 == space_cnt) && ('\0' != buf[0]))
 		{
 			if (0 == memcmp(buf, DATABASE_LINE_INDICATOR, DATABASE_LINE_INDICATOR_SIZE))
 			{
 				filename_len = buflen - DATABASE_LINE_INDICATOR_SIZE;
 				line_type = DATABASE_LINE_INFO;
-			}
-			else if (0 == memcmp(buf, SYMMETRIC_KEY_LINE_INDICATOR, SYMMETRIC_KEY_LINE_INDICATOR_SIZE))
+			} else if (0 == memcmp(buf, SYMMETRIC_KEY_LINE_INDICATOR, SYMMETRIC_KEY_LINE_INDICATOR_SIZE))
 			{
 				filename_len = buflen - SYMMETRIC_KEY_LINE_INDICATOR_SIZE;
 				line_type = SYMMETRIC_KEY_LINE_INFO;
-			}
-			else
+			} else
 				line_type = -1;
-		} else if (space_cnt < (buflen - 1))
+		} else if (space_cnt < buflen)
 			line_type = -1;		/* line doesn't consist entirely of spaces (but only has leading spaces) */
 		else
 			continue;	/* skip this line as it consists entirely of spaces -- blank line */
-		switch(line_type)
+		switch (line_type)
 		{
 			case DATABASE_LINE_INFO:
-				if (current_state == looking_for_key_entry)
+				if (LOOKING_FOR_KEY == current_state)
 				{
-					fclose(gtm_dbkeys_fp);
-					UPDATE_ERROR_STRING("%s. At line %d: Found DAT entry, expecting KEY entry", prefix,
-								line_no);
-
-					return GC_FAILURE;
+					UPDATE_ERROR_STRING("%s. At line %d: Found DAT entry, expecting KEY entry",
+								PARSE_ERROR_PREFIX, line_no);
+					return -1;
 				}
-				GC_ALLOCATE_TBL_ENTRY(node);
-				memcpy(node->database_fn, &buf[DATABASE_LINE_INDICATOR_SIZE], filename_len + 1);
-				assert('\0' == node->database_fn[filename_len]);
-				node->database_fn_len = filename_len;
-				node->next = tbl_head;
-				tbl_head = node;
-				current_state = looking_for_key_entry;
+				memcpy(*db, &buf[DATABASE_LINE_INDICATOR_SIZE], filename_len + 1);
+				assert('\0' == *(*db + filename_len));
+				current_state = LOOKING_FOR_KEY;
 				break;
 
 			case SYMMETRIC_KEY_LINE_INFO:
-				if (current_state == looking_for_dat_entry)
+				if (LOOKING_FOR_DB == current_state)
 				{
-					fclose(gtm_dbkeys_fp);
-					UPDATE_ERROR_STRING("%s. At line %d: Found KEY entry, expecting DAT entry", prefix,
-								line_no);
-					return GC_FAILURE;
+					UPDATE_ERROR_STRING("%s. At line %d: Found KEY entry, expecting DAT entry",
+								PARSE_ERROR_PREFIX, line_no);
+					return -1;
 				}
-				assert(NULL != node);
-				memcpy(node->symmetric_key_fn, &buf[SYMMETRIC_KEY_LINE_INDICATOR_SIZE], filename_len + 1);
-				assert('\0' == node->symmetric_key_fn[filename_len]);
-				num_entries++;	/* one set of entries processed */
-				current_state = looking_for_dat_entry;
-				break;
+				memcpy(*key, &buf[SYMMETRIC_KEY_LINE_INDICATOR_SIZE], filename_len + 1);
+				assert('\0' == *(*key + filename_len));
+				current_state = LOOKING_FOR_DB;
+				return KEEP_GOING;	/* Done reading a single entry. */
 
 			default:
-				fclose(gtm_dbkeys_fp);
-				UPDATE_ERROR_STRING("%s. At line %d: %s does not start with 'dat '/'key '", prefix, line_no, buf);
-				return GC_FAILURE;
+				UPDATE_ERROR_STRING("%s. At line %d: %s does not start with 'dat '/'key '", PARSE_ERROR_PREFIX,
+							line_no, buf);
+				return -1;
 		}
 	}
-	if (!feof(gtm_dbkeys_fp))
+	if (!feof(fp))
 	{
-		save_errno = errno;
-		UPDATE_ERROR_STRING("Error while reading from database key file. %s", strerror(save_errno));
-		return GC_FAILURE;
+		UPDATE_ERROR_STRING("Error while reading from database key file. %s", strerror(errno));
+		return -1;
 	} else if (0 == line_no)
-	{	/* EOF reached, but did not go past the first line -- no entries in database key file */
-		fclose(gtm_dbkeys_fp);
-		UPDATE_ERROR_STRING("%s. No entries found in DB keys file.", prefix);
-		return GC_FAILURE;
-	} else if (current_state == looking_for_key_entry)
-	{	/* last database file entry has no matching symmetric key file entry */
-		fclose(gtm_dbkeys_fp);
-		UPDATE_ERROR_STRING("%s. No matching KEY entry found for DAT entry at line: %d", prefix, line_no);
+	{
+		UPDATE_ERROR_STRING("%s. No entries found in DB keys file.", PARSE_ERROR_PREFIX);
+		return -1;
+	} else if (LOOKING_FOR_KEY == current_state)
+	{
+		UPDATE_ERROR_STRING("%s. No matching KEY entry found for DAT entry at line: %d", PARSE_ERROR_PREFIX, line_no);
+		return -1;
+	}
+	return PARSE_COMPLETED;
+}
+
+int gc_dbk_init_dbkeys_tbl()
+{
+	FILE			*fp;
+	void			*handle;
+	int			count, status, ret, stat_success;
+	char			err[MAX_GTMCRYPT_ERR_STRLEN], *db, *key, db_fname[GTM_PATH_MAX], key_fname[GTM_PATH_MAX];
+	char			*config_env;
+	struct stat		stat_info;
+	static time_t		last_modified;
+	config_setting_t	*setting;
+	gtm_dbkeys_tbl		*node;
+
+	if (INVALID_FILE_FORMAT == gc_dbk_file_format)
+	{	/* Decide which file format to use: Old format ($gtm_dbkeys) or the new format ($gtmcrypt_config). */
+		if ((GC_SUCCESS != gc_dbk_get_dbkeys_fname(gc_dbk_filename, &stat_success)) || !stat_success)
+		{
+			if (NULL != (config_env = getenv("gtmcrypt_config")))
+			{
+				strncpy(err, gtmcrypt_err_string, MAX_GTMCRYPT_ERR_STRLEN);
+				if (0 != stat(config_env, &stat_info))
+				{
+					UPDATE_ERROR_STRING("Failed to open $gtm_dbkeys. Reason: %s; attempt to read alternate "
+								"config file %s failed as well. Reason: %s", err, config_env,
+								strerror(errno));
+					return GC_FAILURE;
+				}
+			} else
+				return GC_FAILURE;	/* Error string is already updated in gc_dbk_get_dbkeys_fname. */
+			strncpy(gc_dbk_filename, config_env, GTM_PATH_MAX);
+			gc_dbk_file_format = LIBCONFIG_FILE_FORMAT;
+		} else
+			gc_dbk_file_format = DBKEYS_FILE_FORMAT;
+	}
+	assert('\0' != gc_dbk_filename[0]);
+	if (0 != stat(gc_dbk_filename, &stat_info))
+	{
+		assert(FALSE);
+		UPDATE_ERROR_STRING("Cannot stat %s file %s. %s", DBKEYS_FILE_FORMAT == gc_dbk_file_format ? "DB keys" : "config",
+					gc_dbk_filename, strerror(errno));
 		return GC_FAILURE;
 	}
-	GC_MALLOC(fast_lookup_entry, (SIZEOF(fast_lookup_entry) * num_entries), gtm_dbkeys_tbl*);
-	node = tbl_head;
-	count = 0;
-	while (NULL != node)
+	if (last_modified == stat_info.st_mtime)
+		return GC_SUCCESS;	/* Nothing changed since we last read it. So, return success. */
+	handle = NULL;
+	if (DBKEYS_FILE_FORMAT == gc_dbk_file_format)
 	{
-		node->index = count;
-		fast_lookup_entry[count] = node;
-		count++;
-		node = node->next;
+		if (NULL == (fp = fopen(gc_dbk_filename, "r")))
+		{
+			UPDATE_ERROR_STRING("Cannot open DB keys file - %s. %s", gc_dbk_filename, strerror(errno));
+			return GC_FAILURE;
+		}
+		handle = fp;
+	} else
+	{
+		if (!config_read_file(&gtmcrypt_cfg, gc_dbk_filename))
+		{
+			UPDATE_ERROR_STRING("Cannot read config file %s. At line# %d - %s", gc_dbk_filename,
+						config_error_line(&gtmcrypt_cfg), config_error_text(&gtmcrypt_cfg))
+			return GC_FAILURE;
+		}
+		if (NULL == (setting = config_lookup(&gtmcrypt_cfg, "database.keys")))
+		{
+			UPDATE_ERROR_STRING("Failed to lookup database.keys in config file %s", gc_dbk_filename);
+			return GC_FAILURE;
+		}
+		handle = setting;
 	}
-	assert(count == num_entries);
-	fclose(gtm_dbkeys_fp);
-	return GC_SUCCESS;
+	assert(NULL != handle);
+	if (tbl_head)
+	{
+		gc_dbk_scrub_entries();	/* free up the existing linked list as we are about to create a fresh one */
+		tbl_head = NULL;
+	}
+	db = &db_fname[0];
+	key = &key_fname[0];
+	while (KEEP_GOING == (status = gc_dbk_get_single_entry(handle, &db, &key, n_dbkeys)))
+	{
+		assert('\0' == db[strlen(db)]);
+		assert('\0' == key[strlen(key)]);
+		GC_ALLOCATE_TBL_ENTRY(node);
+		strncpy(node->database_fn, db, GTM_PATH_MAX);
+		strncpy(node->symmetric_key_fn, key, GTM_PATH_MAX);
+		node->next = tbl_head;
+		tbl_head = node;
+		n_dbkeys++;
+	}
+	if (PARSE_COMPLETED == status)
+	{
+		fast_lookup_entry = (gtm_dbkeys_tbl **)MALLOC((SIZEOF(fast_lookup_entry) * n_dbkeys));
+		node = tbl_head;
+		for (count = 0, node = tbl_head; NULL != node; node = node->next, count++)
+		{
+			node->index = count;
+			fast_lookup_entry[count] = node;
+		}
+		assert(count == n_dbkeys);
+		ret = 0;
+	} else
+		ret = -1;
+	if (DBKEYS_FILE_FORMAT == gc_dbk_file_format)
+		fclose(fp);
+	else
+		config_destroy(&gtmcrypt_cfg);
+	return ret;
 }
 
-xc_status_t gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_hash)
+int gc_dbk_fill_symkey_hash(gtm_fileid_ptr_t req_fileid, char *req_hash)
 {
-	gtm_dbkeys_tbl	*cur;
-	int		status, concerns_current_file, skip_entry, plain_text_length;
-	xc_fileid_ptr_t	db_fileid;
-	xc_string_t	filename;
+	gtm_dbkeys_tbl		*cur;
+	int			status, concerns_current_file, skip_entry, plain_text_length;
+	gtm_fileid_ptr_t	db_fileid;
+	gtm_string_t		filename;
 
 	cur = tbl_head;
 	while (NULL != cur)
@@ -312,7 +414,7 @@ xc_status_t gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_h
 		{
 			filename.length = cur->database_fn_len;
 			filename.address = cur->database_fn;
-			if (TRUE == gtm_filename_to_id_fptr(&filename, &db_fileid))
+			if (TRUE == GTM_FILENAME_TO_ID(&filename, &db_fileid))
 			{
 				cur->fileid_dirty = FALSE;
 				cur->fileid = db_fileid;
@@ -321,14 +423,17 @@ xc_status_t gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_h
 		if (cur->symmetric_key_dirty) /* Need to fill sym key value */
 		{
 			skip_entry = FALSE;
-			/* Before decrypting the key, let's see if the gtm_passwd in the environment has changed since
-			 * the last time we read from the environment. This way if the user had originally entered a wrong
-			 * password and if he/she is in MUMPS and changes the password through an external call then we should
-			 * be using the new password rather than the old one which might still be hanging in the environment.
+			/* Check & update the value of $gtm_passwd if it changed since we last checked. This way, if the user
+			 * had originally entered a wrong password, but later changed the value (possible in MUMPS using external
+			 * call), we read the up-to-date value instead of issuing an error.
 			 */
-			gc_pk_crypt_prompt_passwd_if_needed(can_prompt_passwd);
+			if (0 != gc_update_passwd(GTM_PASSWD_ENV, &gtmcrypt_pwent, GTMCRYPT_DEFAULT_PASSWD_PROMPT,
+							GTMCRYPT_OP_INTERACTIVE_MODE & gtmcrypt_init_flags))
+			{
+				return GC_FAILURE;
+			}
 			status = gc_pk_get_decrypted_key(cur->symmetric_key_fn, cur->symmetric_key, &plain_text_length);
-			concerns_current_file = (NULL != req_fileid && (gtm_is_file_identical_fptr(cur->fileid, req_fileid)));
+			concerns_current_file = (NULL != req_fileid && (GTM_IS_FILE_IDENTICAL(cur->fileid, req_fileid)));
 			if (0 != status)
 			{
 				/* If we failed because of wrong we password OR we are processing an entry that concerns the file
@@ -349,7 +454,8 @@ xc_status_t gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_h
 			if (!skip_entry)
 			{ 	/* Everything is fine, compute the hash for the key */
 				GC_PK_COMPUTE_HASH(cur->symmetric_key_hash, cur->symmetric_key);
-				GC_SYM_CREATE_HANDLES(cur);
+				if (0 != gc_sym_create_key_handles(cur))
+					return -1;
 				cur->symmetric_key_dirty = FALSE;
 				if (concerns_current_file
 				    || (NULL != req_hash && (0 == memcmp(cur->symmetric_key_hash, req_hash, GTMCRYPT_HASH_LEN))))
@@ -363,7 +469,7 @@ xc_status_t gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_h
 	return GC_SUCCESS;
 }
 
-void	 gc_dbk_get_hash(gtm_dbkeys_tbl *entry,  xc_string_t *hash)
+void	 gc_dbk_get_hash(gtm_dbkeys_tbl *entry,  gtm_string_t *hash)
 {
 	assert(hash->address);
 	assert(NULL != entry);
diff --git a/sr_unix/gtmcrypt_dbk_ref.h b/sr_unix/gtmcrypt_dbk_ref.h
index 238b6c4..7cb6d07 100644
--- a/sr_unix/gtmcrypt_dbk_ref.h
+++ b/sr_unix/gtmcrypt_dbk_ref.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc *
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc *
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,12 +18,14 @@
 #define SYMMETRIC_KEY_LINE_INDICATOR		"key "
 #define DATABASE_LINE_INDICATOR_SIZE		(SIZEOF(DATABASE_LINE_INDICATOR) - 1)
 #define SYMMETRIC_KEY_LINE_INDICATOR_SIZE	(SIZEOF(SYMMETRIC_KEY_LINE_INDICATOR) - 1)
+#define INVALID_FILE_FORMAT			0x0
+#define LIBCONFIG_FILE_FORMAT			0x1
+#define DBKEYS_FILE_FORMAT			0x2
 #ifdef LINE_MAX
 #undef LINE_MAX
 #endif
 #define LINE_MAX				(GTM_PATH_MAX + DATABASE_LINE_INDICATOR_SIZE + 2) /* 2 is just for safety */
 
-
 typedef struct gtm_dbkeys_tbl_struct
 {
 	struct gtm_dbkeys_tbl_struct 	*next;
@@ -35,74 +37,38 @@ typedef struct gtm_dbkeys_tbl_struct
 	char				symmetric_key_fn[GTM_PATH_MAX + 1];
 	unsigned char			symmetric_key[SYMMETRIC_KEY_MAX + 1];
 	unsigned char			symmetric_key_hash[GTMCRYPT_HASH_LEN + 1];
-	xc_fileid_ptr_t			fileid;
+	gtm_fileid_ptr_t		fileid;
 	crypt_key_t			encr_key_handle;
 	crypt_key_t			decr_key_handle;
 } gtm_dbkeys_tbl;
 
+STATICFNDCL gtm_status_t	gc_dbk_get_dbkeys_fname(char *fname, int *stat_success);
+STATICFNDCL int			gc_dbk_get_single_entry(void *handle, char **db, char **key, int n);
+void				gc_dbk_scrub_entries(void);
+void				gc_dbk_get_hash(gtm_dbkeys_tbl *entry,  gtm_string_t *hash);
+gtm_dbkeys_tbl*			gc_dbk_get_entry_by_fileid(gtm_fileid_ptr_t fileid);
+gtm_dbkeys_tbl*			gc_dbk_get_entry_by_hash(gtm_string_t *hash);
+gtm_status_t			gc_dbk_init_dbkeys_tbl(void);
+gtm_status_t			gc_dbk_fill_symkey_hash(gtm_fileid_ptr_t req_fileid, char *req_hash);
 
-
-void					gc_dbk_scrub_entries(void);
-gtm_dbkeys_tbl*				gc_dbk_get_entry_by_fileid(xc_fileid_ptr_t fileid);
-gtm_dbkeys_tbl*				gc_dbk_get_entry_by_hash(xc_string_t *hash);
-xc_status_t				gc_dbk_fill_gtm_dbkeys_fname(char *fname);
-xc_status_t				gc_dbk_load_entries_from_file(void);
-xc_status_t				gc_dbk_fill_sym_key_and_hash(xc_fileid_ptr_t req_fileid, char *req_hash);
-void					gc_dbk_get_hash(gtm_dbkeys_tbl *entry,  xc_string_t *hash);
-
-
-#define GC_FREE_TBL_ENTRY(X)													\
-{																\
-	gtm_xcfileid_free_fptr((X)->fileid);											\
-	memset((X)->symmetric_key, 0, SYMMETRIC_KEY_MAX);									\
-	memset((X)->symmetric_key_hash, 0, GTMCRYPT_HASH_LEN);									\
-	GC_FREE(X);														\
-}
+GBLREF	int		n_dbkeys;
+GBLREF	gtm_dbkeys_tbl	**fast_lookup_entry;
 
 #define GC_ALLOCATE_TBL_ENTRY(X)												\
 {																\
-	GC_MALLOC((X), SIZEOF(gtm_dbkeys_tbl), gtm_dbkeys_tbl);									\
+	X = MALLOC(SIZEOF(gtm_dbkeys_tbl));											\
 	(X)->fileid_dirty = TRUE;												\
 	(X)->symmetric_key_dirty = TRUE;											\
 	(X)->fileid = NULL;													\
 	(X)->index = 0;														\
 }
 
-/* After the preliminary search, if we haven't found our entry in the in-memory linked list for the given hash/fileid, we try
- * reloading the db key file (just in case it has been changed since last time) and re-organize our in-memory linked list
- */
-#define GC_DBK_RELOAD_IF_NEEDED(entry, RC, fileid, req_hash)									\
+#define RETURN_IF_INVALID_HANDLE(HANDLE)											\
 {																\
-	if (NULL == entry)													\
-	{															\
-		if (0 != gc_dbk_load_entries_from_file())									\
-			return GC_FAILURE;											\
-		RC = gc_dbk_fill_sym_key_and_hash(fileid, req_hash);								\
-	}															\
-}
-
-#define GC_DBK_GET_ENTRY_FROM_HANDLE(handle, entry, ret)									\
-{																\
-	GBLREF int			num_entries;										\
-	GBLREF gtm_dbkeys_tbl	**fast_lookup_entry;										\
-																\
-	int				idx;											\
-																\
-	idx = (int)handle;													\
-	if (idx < 0 || (idx > num_entries))											\
+	if (0 > (int)HANDLE || ((int)HANDLE > n_dbkeys))									\
 	{															\
+		assert(FALSE);													\
 		UPDATE_ERROR_STRING("Encryption handle corrupted.");								\
-		entry = NULL;													\
-		return ret;													\
-	} else															\
-		entry = (gtm_dbkeys_tbl *)fast_lookup_entry[idx];								\
-}
-
-#define GC_DBK_FILENAME_TO_ID(filename, fileid)											\
-{																\
-	if (TRUE != gtm_filename_to_id_fptr(filename, &fileid))									\
-	{															\
-		UPDATE_ERROR_STRING("Database file %s not found", filename->address);			 			\
 		return GC_FAILURE;												\
 	}															\
 }
diff --git a/sr_unix/gtmcrypt_entry.c b/sr_unix/gtmcrypt_entry.c
index 7ad8860..9a24894 100644
--- a/sr_unix/gtmcrypt_entry.c
+++ b/sr_unix/gtmcrypt_entry.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,71 +11,142 @@
 
 #include "mdef.h"
 
-#include "gtm_string.h"
-#include "gtm_limits.h"		/* for GTM_PATH_MAX */
-
 #include <dlfcn.h>
 #include <errno.h>
+#ifdef _AIX
+#include <sys/ldr.h>
+#endif
 
-#include "lv_val.h"		/* needed for "fgncal.h" */
-#include "fgncal.h"		/* needed for COPY_DLLERR_MSG() */
-#include "gtmmsg.h"
 #include "gtm_stdio.h"
 #include "gtm_stdlib.h"
+#include "gtm_string.h"
+#include "gtm_limits.h"		/* for GTM_PATH_MAX */
+
+#include "lv_val.h"		/* needed for "fgncal.h" */
 #include "real_len.h"
-#include "gtmcrypt.h"
+#include "fgncal.h"		/* needed for COPY_DLLERR_MSG() */
+#include "gtmmsg.h"
 #include "iosp.h"		/* for SS_NORMAL */
 #include "trans_log_name.h"
+#include "gdsroot.h"
+#include "is_file_identical.h"
 
-#ifndef	GTM_DIST
-#define GTM_DIST	"gtm_dist"
-#endif
-#define GTM_CRYPT_PLUGIN			"$gtm_crypt_plugin"
+#define	GTMCRYPT_LIBNAME		"libgtmcrypt.so"
 #define MAX_GTMCRYPT_PLUGIN_STR_LEN	(SIZEOF(GTMCRYPT_LIBNAME) * 4)
-#define PLUGIN_DIR_NAME			"plugin"
+
+#define GTM_CRYPT_PLUGIN		"$gtm_crypt_plugin"
+
+typedef void (*gtmcrypt_func_t)();	/* A generic pointer type to the gtmcrypt functions exposed by the plugin */
+
+#define GTMCRYPT_DEF(x) x##_,
+enum
+{
+#include "gtmcrypt_funclist.h"	/* BYPASSOK */
+gtmcrypt_func_n			/* total number of gtmcrypt functions that needs to be dlsym()ed */
+};
+#undef GTMCRYPT_DEF
+
+#define GTMCRYPT_DEF(x) GBLDEF gtmcrypt_func_t x##_fnptr;
+#include "gtmcrypt_funclist.h"
+#undef GTMCRYPT_DEF
 
 GBLREF	char	dl_err[MAX_ERRSTR_LEN];
+GBLREF	char	gtm_dist[GTM_PATH_MAX];
+
 error_def(ERR_CRYPTDLNOOPEN);
-error_def(ERR_GTMDISTUNDEF);
+
+/* Including gtmcrypt.h in this module results in conflicting GBLDEF/GBLREFs. So, re-define the function prototype here to
+ * silent the compiler.
+ */
+uint4 gtmcrypt_entry(void);
+boolean_t verify_lib_loadpath(const char *libname, char *loadpath);
+
+#ifdef _AIX
+/* On AIX, there is no known way to specify that dependent libraries (in this case "libgtmcryptutil.so") should also be searched in
+ * the same directory from which the parent library is loaded ($ORIGIN on Linux, HP-UX and Solaris). To work-around that, we
+ * explicitly prefix LIBPATH with "$gtm_dist/plugin" before invoking dlopen. But, to ensure that "libgtmcryptutil.so" was indeed
+ * loaded from "$gtm_dist/plugin", we use loadquery to get the list of loaded modules along with the path from which they are loaded
+ * from and verify against it.
+ */
+boolean_t verify_lib_loadpath(const char *libname, char *loadpath)
+{
+	struct ld_xinfo		*ldxinfo;
+	char			*bufptr, *ptr, cmpptr[GTM_PATH_MAX], buf[GTM_PATH_MAX];
+	int			ret, cmplen, buflen, save_errno;
+
+	buflen = GTM_PATH_MAX;
+	bufptr = &buf[0];
+	while (-1 == loadquery(L_GETXINFO, bufptr, buflen))
+	{
+		save_errno = errno;
+		if (ENOMEM != save_errno)
+		{
+			assert(FALSE);
+			SNPRINTF(dl_err, MAX_ERRSTR_LEN, "System call `loadquery' failed. %s", STRERROR(save_errno));
+			return FALSE;
+		}
+		if (bufptr != &buf[0])
+			free(bufptr);
+		buflen *= 2;
+		bufptr = malloc(buflen);
+	}
+	ldxinfo = (struct ld_xinfo *)bufptr;
+	ret = FALSE;
+	SNPRINTF(cmpptr, GTM_PATH_MAX, "%s/%s", loadpath, libname);
+	while (ldxinfo->ldinfo_next)
+	{
+		/* Point to the offset at which the path of the loaded module is present. */
+		ptr = (char *)ldxinfo + ldxinfo->ldinfo_filename;
+		if (is_file_identical(cmpptr, ptr))
+		{
+			ret = TRUE;
+			break;
+		}
+		ldxinfo = (struct ld_xinfo *)((sm_long_t)ldxinfo + ldxinfo->ldinfo_next);
+	}
+	if (bufptr != &buf[0])
+		free(bufptr);
+	if (!ret)
+		SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Dependent shared library %s was not loaded relative to %s.", libname, loadpath);
+	return ret;
+}
+#endif
 
 uint4 gtmcrypt_entry()
 {
-	void_ptr_t		handle, fptr;
-	char_ptr_t		err_str, env_ptr, libname_ptr, libpath_ptr;
-	char			*gtmcryptlib_fname[] = {
-					GTMCRYPT_INIT_FNAME,
-					GTMCRYPT_CLOSE_FNAME,
-					GTMCRYPT_HASH_GEN_FNAME,
-					GTMCRYPT_ENCRYPT_FNAME,
-					GTMCRYPT_DECRYPT_FNAME,
-					GTMCRYPT_GETKEY_BY_NAME,
-					GTMCRYPT_GETKEY_BY_HASH,
-					GTMCRYPT_STRERROR
+	/* Initialize the table of symbol names to be used in dlsym() */
+#	define GTMCRYPT_DEF(x) #x,
+	char			*gtmcrypt_fname[] = {
+#							include "gtmcrypt_funclist.h"
+							NULL
 				};
-	void			**gtmcryptlib_fptr[] = {
-					(void **)&gtmcrypt_init_fnptr,
-					(void **)&gtmcrypt_close_fnptr,
-					(void **)&gtmcrypt_hash_gen_fnptr,
-					(void **)&gtmcrypt_encrypt_fnptr,
-					(void **)&gtmcrypt_decrypt_fnptr,
-					(void **)&gtmcrypt_getkey_by_name_fnptr,
-					(void **)&gtmcrypt_getkey_by_hash_fnptr,
-					(void **)&gtmcrypt_strerror_fnptr
+#	undef GTMCRYPT_DEF
+	/* Initialize the table of locations of function pointers that are set by dlsym() */
+#	define GTMCRYPT_DEF(x) &x##_fnptr,
+	gtmcrypt_func_t		*gtmcrypt_fnptr[] = {
+#							include "gtmcrypt_funclist.h"
+							NULL
 				};
-	int			findx, num_dlsyms, plugin_dir_len, save_errno;
+#	undef GTMCRYPT_DEF
+	void_ptr_t		handle;
+	char_ptr_t		err_str, libname_ptr;
+	gtmcrypt_func_t		fptr;
+	int			findx, plugin_dir_len, save_errno;
+#	ifdef _AIX
+	char			new_libpath_env[GTM_PATH_MAX], *save_libpath_ptr, save_libpath[GTM_PATH_MAX];
+#	endif
 	char			libpath[GTM_PATH_MAX], buf[MAX_GTMCRYPT_PLUGIN_STR_LEN], plugin_dir_path[GTM_PATH_MAX];
 	char			resolved_libpath[GTM_PATH_MAX], resolved_gtmdist[GTM_PATH_MAX];
-	mstr			trans, env_var = {0, SIZEOF(GTM_CRYPT_PLUGIN) - 1, GTM_CRYPT_PLUGIN};
+	mstr			trans, env_var = {0, LEN_AND_LIT(GTM_CRYPT_PLUGIN)};
 
-	if (NULL == (env_ptr = getenv(GTM_DIST)))
-		rts_error(VARLSTCNT(1) ERR_GTMDISTUNDEF);
-	if (NULL == realpath(env_ptr, &resolved_gtmdist[0]))
+	assert(STRLEN(gtm_dist));
+	if (NULL == realpath(gtm_dist, &resolved_gtmdist[0]))
 	{
 		save_errno = errno;
-		SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Failed to find symbolic link for %s. %s", env_ptr, STRERROR(save_errno));
+		SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Failed to find symbolic link for %s. %s", gtm_dist, STRERROR(save_errno));
 		return ERR_CRYPTDLNOOPEN;
 	}
-	SNPRINTF(plugin_dir_path, GTM_PATH_MAX, "%s/%s", resolved_gtmdist, PLUGIN_DIR_NAME);
+	SNPRINTF(plugin_dir_path, GTM_PATH_MAX, "%s/%s", resolved_gtmdist, GTMCRYPT_PLUGIN_DIR_NAME);
 	plugin_dir_len = STRLEN(plugin_dir_path);
 	if ((SS_NORMAL != TRANS_LOG_NAME(&env_var, &trans, buf, SIZEOF(buf), do_sendmsg_on_log2long)) || (0 >= trans.len))
 	{	/* Either $gtm_crypt_plugin is not defined in the environment variable OR it is set to null-string. Fall-back to
@@ -97,22 +168,41 @@ uint4 gtmcrypt_entry()
 		SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Symbolic link for %s must be relative to %s", libpath, plugin_dir_path);
 		return ERR_CRYPTDLNOOPEN;
 	}
-	handle = dlopen(&resolved_libpath[0], GTMCRYPT_LIBFLAGS);
+#	ifdef _AIX
+	if (NULL == (save_libpath_ptr = getenv(LIBPATH_ENV)))
+		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s", plugin_dir_path);
+	else
+	{
+		/* Since the setenv below can potentially thrash the save_libpath_ptr, take a copy of it for later restore. */
+		strncpy(save_libpath, save_libpath_ptr, SIZEOF(save_libpath));
+		save_libpath[SIZEOF(save_libpath) - 1] = '\0';
+		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s:%s", plugin_dir_path, save_libpath_ptr);
+	}
+	setenv(LIBPATH_ENV, new_libpath_env, TRUE);
+#	endif
+	handle = dlopen(&resolved_libpath[0], RTLD_NOW | RTLD_GLOBAL);
 	if (NULL == handle)
 	{
 		COPY_DLLERR_MSG(err_str, dl_err);
 		return ERR_CRYPTDLNOOPEN;
 	}
-	num_dlsyms = ARRAYSIZE(gtmcryptlib_fptr); /* number of functions to be dlsym'ed */
-	for(findx = 0; findx < num_dlsyms; ++findx)
+#	ifdef _AIX
+	if (NULL == save_libpath_ptr)
+		unsetenv(LIBPATH_ENV);
+	else
+		setenv(LIBPATH_ENV, save_libpath, TRUE);
+	if (!verify_lib_loadpath(GTMCRYPT_UTIL_LIBNAME, plugin_dir_path))
+		return ERR_CRYPTDLNOOPEN;
+#	endif
+	for (findx = 0; findx < gtmcrypt_func_n; ++findx)
 	{
-		fptr = (void *)dlsym(handle, gtmcryptlib_fname[findx]);
+		fptr = (gtmcrypt_func_t)dlsym(handle, gtmcrypt_fname[findx]);
 		if (NULL == fptr)
 		{
 			COPY_DLLERR_MSG(err_str, dl_err);
 			return ERR_CRYPTDLNOOPEN;
 		}
-		*gtmcryptlib_fptr[findx] = fptr;
+		*gtmcrypt_fnptr[findx] = fptr;
 	}
 	return 0;
 }
diff --git a/sr_unix/gtmcrypt_funclist.h b/sr_unix/gtmcrypt_funclist.h
new file mode 100644
index 0000000..c776189
--- /dev/null
+++ b/sr_unix/gtmcrypt_funclist.h
@@ -0,0 +1,23 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+/* Any time a new function gets added to the GT.M encryption interface, add the corresponding entry here. This file is included in
+ * `gtmcrypt_entry', by appropriately, defining GTMCRYPT_DEF, to generate necessary string literals and function pointers which
+ * is used to `dlsym' symbols from the GT.M encryption shared library.
+ */
+GTMCRYPT_DEF(gtmcrypt_strerror)
+GTMCRYPT_DEF(gtmcrypt_init)
+GTMCRYPT_DEF(gtmcrypt_hash_gen)
+GTMCRYPT_DEF(gtmcrypt_encrypt)
+GTMCRYPT_DEF(gtmcrypt_decrypt)
+GTMCRYPT_DEF(gtmcrypt_getkey_by_name)
+GTMCRYPT_DEF(gtmcrypt_getkey_by_hash)
+GTMCRYPT_DEF(gtmcrypt_close)
diff --git a/sr_unix/gtmcrypt_interface.h b/sr_unix/gtmcrypt_interface.h
index 2fdf64d..2511a46 100644
--- a/sr_unix/gtmcrypt_interface.h
+++ b/sr_unix/gtmcrypt_interface.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,13 +12,24 @@
 #ifndef GTMCRYPT_INTERFACE_H
 #define GTMCRYPT_INTERFACE_H
 
-xc_status_t	gtmcrypt_init(int);
-xc_status_t	gtmcrypt_close(void);
-xc_status_t	gtmcrypt_hash_gen(gtmcrypt_key_t, xc_string_t *);
-xc_status_t	gtmcrypt_encrypt(gtmcrypt_key_t, xc_string_t *, xc_string_t *);
-xc_status_t	gtmcrypt_decrypt(gtmcrypt_key_t, xc_string_t *, xc_string_t *);
-xc_status_t	gtmcrypt_getkey_by_hash(xc_string_t *, gtmcrypt_key_t *);
-xc_status_t	gtmcrypt_getkey_by_name(xc_string_t *, gtmcrypt_key_t *);
-char		*gtmcrypt_strerror(void);
+#define GTM_PASSWD_ENV			"gtm_passwd"
 
-#endif /* GTMCRYPT_INTERFACE_H */
+#define GTMCRYPT_HASH_LEN		64
+#define GTMCRYPT_HASH_HEX_LEN		GTMCRYPT_HASH_LEN * 2
+
+#define GTMCRYPT_OP_INTERACTIVE_MODE	0x00000001
+
+#define GTMCRYPT_INVALID_KEY_HANDLE	-1
+
+typedef	int	gtmcrypt_key_t;
+
+_GTM_APIDECL gtm_status_t	gtmcrypt_init(int flags);
+_GTM_APIDECL gtm_status_t	gtmcrypt_close(void);
+_GTM_APIDECL gtm_status_t	gtmcrypt_hash_gen(gtmcrypt_key_t, gtm_string_t *);
+_GTM_APIDECL gtm_status_t	gtmcrypt_encrypt(gtmcrypt_key_t, gtm_string_t *, gtm_string_t *);
+_GTM_APIDECL gtm_status_t	gtmcrypt_decrypt(gtmcrypt_key_t, gtm_string_t *, gtm_string_t *);
+_GTM_APIDECL gtm_status_t	gtmcrypt_getkey_by_hash(gtm_string_t *, gtmcrypt_key_t *);
+_GTM_APIDECL gtm_status_t	gtmcrypt_getkey_by_name(gtm_string_t *, gtmcrypt_key_t *);
+_GTM_APIDECL char		*gtmcrypt_strerror(void);
+
+#endif
diff --git a/sr_unix/gtmcrypt_pk_ref.c b/sr_unix/gtmcrypt_pk_ref.c
index 87f769e..d906c20 100644
--- a/sr_unix/gtmcrypt_pk_ref.c
+++ b/sr_unix/gtmcrypt_pk_ref.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc 	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc 	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,253 +11,44 @@
 
 #define _FILE_OFFSET_BITS	64	/* Needed to compile gpgme client progs also with large file support */
 
-#include <stdio.h>			/* BYPASSOK -- Plugin doesn't have access to gtm_* header files */
-#include <string.h>			/* BYPASSOK -- see above */
-#include <unistd.h>			/* BYPASSOK -- see above */
-#include <stdlib.h>			/* BYPASSOK -- see above */
-#include <sys/stat.h>			/* BYPASSOK -- see above */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
 #include <assert.h>
-#include <sys/types.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <gpgme.h>			/* gpgme functions */
-#include <gpg-error.h>			/* gcry*_err_t */
 #include <dlfcn.h>
 #include <sys/mman.h>
+#include <sys/stat.h>			/* BYPASSOK -- see above */
+#include <sys/types.h>
+
+#include <gpgme.h>			/* gpgme functions */
+#include <gpg-error.h>			/* gcry*_err_t */
+
 #include "gtmxc_types.h"		/* xc_string, xc_status_t and other callin interfaces xc_fileid */
+
+#include "gtmcrypt_util.h"
 #include "gtmcrypt_interface.h"		/* Function prototypes for gtmcrypt*.* functions */
+
 #include "gtmcrypt_ref.h"
+#include "gtmcrypt_dbk_ref.h"
 #include "gtmcrypt_sym_ref.h"
 #include "gtmcrypt_pk_ref.h"
 
-STATICDEF	char		*gtm_passwd;
-STATICDEF	char		*gtm_passwd_env;
-GBLDEF		int		can_prompt_passwd;
-GBLDEF		gpgme_ctx_t	pk_crypt_ctx;
-
-#ifdef __sparc /* for some reason sun does not provide a prototype */
-int setenv(const char* name, const char *value, int overwrite);
-#endif
-
-/* Take a masked/unmasked password and convert it to the other form by doing an XOR operation via an XOR mask.
- * XOR MASK:
- * If the gtm_obfuscation_key exists and points to a file that has readable contents, the XOR mask is the
- * SHA-512 hash of the contents of that file.
- * Otherwise, within a pre-zero'ed buffer the length of the password the contents of the USER environment
- * variable is left-justified and the decimal representation of the inode of the mumps executable is
- * right-justified. The XOR mask is the SHA-512 hash of the contents of that buffer.
- * 	<PASSWORDLEN>
- *	USER0000INODE ---SHA-512--> XOR mask
- * MASKING:
- * The original password value is XOR'ed with the XOR mask, converted to it's hex representation (for easy
- * viewing) and set into the gtm_passwd environment variable. This can then be used by job'ed off child
- * processes.
- * UNMASKING:
- * The contents of the gtm_passwd environment variable converted into its binary representation (from its
- * hex representation). This gtm_passwd value is then XOR'ed with the XOR mask.
- */
-
-int gc_pk_mask_unmask_passwd(char *in, char *out, int len)
-{
-	char		tmp[GTM_PASSPHRASE_MAX], mumps_ex[GTM_PATH_MAX], tobehashed[GTM_PASSPHRASE_MAX], hash[GTMCRYPT_HASH_LEN];
-	char 		*ptr, *mmap_addrs;
-	int		passwd_len, ilen, status, i, save_errno, fd, have_hash;
-	struct stat	stat_info;
-
-	have_hash = FALSE;
-	passwd_len = len < GTM_PASSPHRASE_MAX ? len : GTM_PASSPHRASE_MAX;
-
-	if (ptr = getenv(GTM_OBFUSCATION_KEY))
-	{
-		fd = open(ptr, O_RDONLY);
-		if ((-1 != fd) && (-1 != fstat(fd, &stat_info)) && S_ISREG(stat_info.st_mode))
-		{	/* File pointed by $gtm_obfuscation_key exists and is a regular file */
-			mmap_addrs = mmap(0,stat_info.st_size, PROT_READ, MAP_SHARED, fd, 0);
-			if (MAP_FAILED != mmap_addrs)
-			{
-#				ifdef USE_OPENSSL
-				EVP_Digest(mmap_addrs, stat_info.st_size, (unsigned char *)hash, NULL, EVP_sha512(), NULL);
-#				elif defined USE_GCRYPT
-				GC_SYM_INIT;
-				gcry_md_hash_buffer(GCRY_MD_SHA512, hash, mmap_addrs, stat_info.st_size );
-#				endif
-				have_hash = TRUE;
-				munmap(mmap_addrs, stat_info.st_size);
-			}
-			close(fd);
-		}
-	}
-	if (!have_hash)
-	{
-		memset(tobehashed, 0, passwd_len);
-		memset(mumps_ex, 0, GTM_PATH_MAX);
-		if (!(ptr = getenv(USER)))
-		{
-			UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, USER);
-			return GC_FAILURE;
-		}
-		else
-		{
-			strncpy(tobehashed, ptr, passwd_len);
-			if (!(ptr = getenv(GTM_DIST)))
-			{
-				UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_DIST);
-				return GC_FAILURE;
-			}
-			else
-			{
-				SNPRINTF(mumps_ex, GTM_PATH_MAX, "%s/%s", ptr, "mumps");
-				if (0 == stat(mumps_ex, &stat_info))
-				{
-					SNPRINTF(tmp, GTM_PASSPHRASE_MAX, "%ld", (long) stat_info.st_ino);
-					ilen = (int)STRLEN(tmp);
-					if (ilen < passwd_len)
-						strncpy(tobehashed + (passwd_len - ilen), tmp, ilen);
-					else
-						strncpy(tobehashed, tmp, passwd_len);
-				} else
-				{
-					save_errno = errno;
-					UPDATE_ERROR_STRING("Cannot find MUMPS executable in %s - %s", ptr, strerror(save_errno));
-					return GC_FAILURE;
-				}
-#				ifdef USE_OPENSSL
-				EVP_Digest(tobehashed, passwd_len, (unsigned char *)hash, NULL, EVP_sha512(), NULL);
-#				elif defined USE_GCRYPT
-				GC_SYM_INIT;
-				gcry_md_hash_buffer(GCRY_MD_SHA512, hash, tobehashed, passwd_len );
-#				endif
-				have_hash = TRUE;
-			}
-		}
-	}
-	if (have_hash)
-	{
-		for (i = 0; i < passwd_len; i++)
-			out[i] = in[i] ^ hash[i % GTMCRYPT_HASH_LEN];
-		return GC_SUCCESS;
-	}
-
-	return GC_FAILURE;
-}
-
-int gc_pk_mask_unmask_passwd_interlude(int nparm, gtm_string_t *in, gtm_string_t *out, int len)
-{
-	out->length=len;
-	return gc_pk_mask_unmask_passwd(in->address, out->address, len);
-}
+GBLDEF	passwd_entry_t	*gtmcrypt_pwent;
+GBLDEF	gpgme_ctx_t	pk_crypt_ctx;
 
 void gc_pk_scrub_passwd()
 {
 	/* Nullify the key strings, so that any generated cores will not contain the unencrypted keys */
-	memset(gtm_passwd, 0, STRLEN(gtm_passwd));
-	/* Free gtm_passwd and gtm_passwd_env variables */
-	if (NULL != gtm_passwd)
-		GC_FREE(gtm_passwd);
-	if (NULL != gtm_passwd_env)
-		GC_FREE(gtm_passwd_env);
+	gc_freeup_pwent(gtmcrypt_pwent);
 	/* Finally release the gpgme context */
 	if (NULL != pk_crypt_ctx)
 		gpgme_release(pk_crypt_ctx);
 }
 
-/* Loads the GTMCI variable with the path of the gtmcrypt.tab which will be placed in gtm_dist folder at build time.
- * Here we assume that the tab file be in $gtm_dist/plugin/gtmcrypt
- */
-
-void gc_pk_crypt_load_gtmci_env()
-{
-	const char	*gtm_dist_value;
-	const char	*gtmcrypt_tab_file = "gtmcrypt.tab"; /* Name of the tab file */
-	static char	gtmcrypt_tab_path[TAB_NAME_MAX];  /* Needs to be in scope always */
-
-	gtm_dist_value = getenv(GTM_DIST);
-	assert(NULL != gtm_dist_value);
-	assert(0 != STRLEN(gtm_dist_value));
-
-	SNPRINTF(gtmcrypt_tab_path, TAB_NAME_MAX, "%s/%s/%s", gtm_dist_value, "plugin/gtmcrypt", gtmcrypt_tab_file);
-	setenv(GTMCI, gtmcrypt_tab_path, TRUE);
-}
-
-/* The following function checks if gtm_passwd is already set. If gtm_passwd is not set in the env, it's a serious
- * error condition. We return back immediately. If it's set to empty string, we prompt for passwd immediately. The
- * current implementation of password prompting is done via a mumps call-in to %GETPASS.
- */
-
-xc_status_t gc_pk_crypt_prompt_passwd_if_needed(int prompt_passwd)
-{
-	const char	*password_routine = "getpass";	/* Name of the mumps password routine that will be called. */
-	char		*save_gtmci;			/* Points to the value that was held in GTMCI prior to modification. */
-	char		*lgtm_passwd, tgtm_passwd[GTM_PASSPHRASE_MAX];
-	int		status, len;
-	gtm_int_t	pass_len = GTM_PASSPHRASE_MAX;
-
-	can_prompt_passwd = prompt_passwd;
-	if (!(lgtm_passwd = getenv(GTM_PASSWD)))
-	{
-		UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_PASSWD);
-		return GC_FAILURE;
-	}
-	/* If the masked password in the environment is same as we have in memory then it means that the password
-	 * has not been changed and so the actual value in the gtm_passwd is still good to use. */
-	if (NULL != gtm_passwd_env && (0 == strcmp(gtm_passwd_env, lgtm_passwd)))
-		return GC_SUCCESS;
-	/* If the password is set to an appropriate value, then we know for sure it's in it's masked form. So, we unmask it
-	 * and set it in the global variable and return to the caller. */
-	if (0 < (len = (int)STRLEN(lgtm_passwd)))
-	{
-		if (gtm_passwd)
-			GC_FREE(gtm_passwd);
-		GC_MALLOC(gtm_passwd, len / 2 + 1, char);
-		memset(gtm_passwd, 0, len / 2 + 1);
-		GC_UNHEX(lgtm_passwd, gtm_passwd, len);
-		status = gc_pk_mask_unmask_passwd(gtm_passwd, gtm_passwd, len / 2);
-		if (GC_SUCCESS == status)
-		{
-			/* Now that we have unmasked the gtm_passwd in the environment
-			 * store the masked version in gtm_passwd_env so that future
-			 * calls to this function can make use of this and return early
-			 * if we find no change between the one in the environment and
-			 * the one in the memory */
-			if (NULL != gtm_passwd_env)
-				GC_FREE(gtm_passwd_env);
-			GC_MALLOC(gtm_passwd_env, STRLEN(lgtm_passwd) + 1, char);
-			strcpy(gtm_passwd_env, lgtm_passwd);
-		}
-		return status;
-	} else if (!prompt_passwd)
-	{
-		/* If we are here, it means that the caller of the plugin library was not MUMPS (may be MUPIP, DSE and LKE).
-		 * For the utility programs, we expect the password to be set in the environment to an appropriate masked
-		 * form. If not, it's an error and we return the appropriate error message. */
-		UPDATE_ERROR_STRING(ENV_EMPTY_ERROR ". %s", GTM_PASSWD, "Password prompting not allowed for utilities");
-		return GC_FAILURE;
-	}
-	/* Only if the gtm_passwd is set to empty string, we prompt the user for password */
-	GC_MALLOC(gtm_passwd, GTM_PASSPHRASE_MAX, char);
-	memset(gtm_passwd, 0, GTM_PASSPHRASE_MAX);
-	save_gtmci = getenv(GTMCI);
-	gc_pk_crypt_load_gtmci_env();
-	status = gtm_ci_fptr(password_routine, gtm_passwd, pass_len);
-	if (0 != status)
-	{
-		gtm_zstatus_fptr(gtmcrypt_err_string, MAX_GTMCRYPT_ERR_STRLEN);
-		return GC_FAILURE;
-	}
-	/* Restore the GTMCI variable */
-	if (NULL != save_gtmci) /* To make sure we don't set an environment variable as NULL */
-		setenv(GTMCI, save_gtmci, 1);
-
-	/* After applying a minimal encryption, we set it to the environment variable */
-	GC_MALLOC(lgtm_passwd, STRLEN(gtm_passwd) * 2 + 1, char);
-	gc_pk_mask_unmask_passwd(gtm_passwd, tgtm_passwd, (int)STRLEN(gtm_passwd));
-	GC_HEX(tgtm_passwd, lgtm_passwd, STRLEN(gtm_passwd) * 2);
-	setenv(GTM_PASSWD, lgtm_passwd, TRUE); /* Note that we currently do not free 'gtm_passwd', even if it was
-					       * allocated above, as it needs to be in the env buffer
-					       */
-	return GC_SUCCESS;
-}
-
 /* This function is called whenever gpg needs the passphrase with which the secret key is encrypted. In this case, the passphrase
  * is obtained from the ENVIRONMENT VARIABLE - $gtm_passwd or by invoking the mumps engine during the "gtmcrypt_init()".
  * In either ways, it's guaranteed that when this function is called, the passphrase is already set in the global variable.
@@ -266,15 +57,13 @@ int gc_pk_crypt_passphrase_callback(void *opaque, const char *uid_hint,
 			const char *passphrase_info, int last_was_bad,
 			int fd)
 {
-	int write_ret;
+	int 	write_ret, len;
+
 	assert(0 != fd);
-	assert(NULL != gtm_passwd);
-	/* This is just being cautious. We would have thrown the appropriate error message
-	 * if gtm_passwd have been zero length'ed one.
-	 */
-	assert(0 != STRLEN(gtm_passwd));
-	write_ret = write(fd, gtm_passwd, STRLEN(gtm_passwd));
-	if (STRLEN(gtm_passwd) == write_ret)
+	assert(NULL != gtmcrypt_pwent->passwd);
+	len = STRLEN(gtmcrypt_pwent->passwd);
+	write_ret = write(fd, gtmcrypt_pwent->passwd, len);
+	if (len == write_ret)
 	{
 		write_ret = write(fd, "\n", 1);
 		if (1 == write_ret)
@@ -287,7 +76,6 @@ int gc_pk_crypt_passphrase_callback(void *opaque, const char *uid_hint,
 /* Given the structure that holds the plain data, this function reads through the structure and retrieves the plain text. We
  * also return the number of bytes actually read from the structure.
  */
-
 int gc_pk_crypt_retrieve_plain_text(gpgme_data_t plain_data, unsigned char *plain_text)
 {
 	int	ret;
@@ -322,7 +110,6 @@ gpgme_error_t gc_pk_get_decrypted_key(const char *cipher_file, unsigned char *pl
 {
 	gpgme_error_t	err;
 	gpgme_data_t	cipher_data = NULL, plain_data = NULL;
-	xc_status_t	ret_status;
 	gpg_err_code_t	ecode;
 	char		null_buffer[SYMMETRIC_KEY_MAX];
 
diff --git a/sr_unix/gtmcrypt_pk_ref.h b/sr_unix/gtmcrypt_pk_ref.h
index 4e48943..dd3eb11 100644
--- a/sr_unix/gtmcrypt_pk_ref.h
+++ b/sr_unix/gtmcrypt_pk_ref.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc 	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc 	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,7 @@ int 			gc_pk_mask_unmask_passwd(char *in, char *out, int len);
 int 			gc_pk_mask_unmask_passwd_interlude(int nparm, gtm_string_t *in, gtm_string_t *out, int len);
 void 			gc_pk_scrub_passwd();
 void 			gc_pk_crypt_load_gtmci_env();
-xc_status_t 		gc_pk_crypt_prompt_passwd_if_needed(int prompt_passwd);
+xc_status_t 		gc_pk_update_passwd();
 int 			gc_pk_crypt_passphrase_callback(void *opaque,
 							const char *uid_hint,
 							const char *passphrase_info,
@@ -56,12 +56,6 @@ int			gc_pk_gpghome_has_permissions(void);
 	}														\
 }
 
-#define GC_PK_PROMPT_PASSWD(prompt_passwd)										\
-{															\
-	if (0 != gc_pk_crypt_prompt_passwd_if_needed(prompt_passwd))							\
-		return GC_FAILURE;											\
-}
-
 #define GC_PK_APPEND_UNIQ_STRING(in_buff, symmetric_key)								\
 {															\
 	memcpy(in_buff, symmetric_key, SYMMETRIC_KEY_MAX);								\
@@ -83,7 +77,6 @@ int			gc_pk_gpghome_has_permissions(void);
 	unsigned char	in_buff[HASH_INPUT_BUFF_LEN];									\
 															\
 	GC_PK_APPEND_UNIQ_STRING(in_buff, symmetric_key);								\
-	GC_SYM_INIT;													\
 	gcry_md_hash_buffer(GCRY_MD_SHA512, symmetric_key_hash, in_buff, HASH_INPUT_BUFF_LEN);				\
 	memset(in_buff, 0, HASH_INPUT_BUFF_LEN);									\
 }
diff --git a/sr_unix/gtmcrypt_ref.c b/sr_unix/gtmcrypt_ref.c
index 9cf336d..d94ab1a 100644
--- a/sr_unix/gtmcrypt_ref.c
+++ b/sr_unix/gtmcrypt_ref.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc 	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc *
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,132 +11,114 @@
 
 #define _FILE_OFFSET_BITS	64	/* Needed to compile gpgme client progs also with large file support */
 
-#include <stdio.h>			/* BYPASSOK -- Plugin doesn't have access to gtm_* header files */
-#include <string.h>			/* BYPASSOK -- see above */
-#include <unistd.h>			/* BYPASSOK -- see above */
-#include <stdlib.h>			/* BYPASSOK -- see above */
-#include <sys/stat.h>			/* BYPASSOK -- see above */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/stat.h>
 #include <dlfcn.h>
 #include <assert.h>
 #include <errno.h>
+
 #include <gpgme.h>			/* gpgme functions */
 #include <gpg-error.h>			/* gcry*_err_t */
-#include "gtmxc_types.h"		/* xc_string, xc_status_t and other callin interfaces xc_fileid */
+
+#include <openssl/err.h>
+
+#include "gtmxc_types.h"		/* gtm_string, gtm_status_t and other callin interfaces gtm_fileid */
+
+#include "gtmcrypt_util.h"
 #include "gtmcrypt_interface.h"		/* Function prototypes for gtmcrypt*.* functions */
 
 #include "gtmcrypt_ref.h"
-#include "gtmcrypt_sym_ref.h"
 #include "gtmcrypt_dbk_ref.h"
+#include "gtmcrypt_sym_ref.h"
 #include "gtmcrypt_pk_ref.h"
 
 #ifdef __MVS__
 #define GTMSHR_IMAGENAME	"libgtmshr.dll"
 #endif
 
+#define MESSAGE1		"Verify encrypted key file and your GNUPGHOME settings"
+#define MESSAGE2_DBKEYS		"Verify encryption key in configuration file pointed to by $gtm_dbkeys"
+#define MESSAGE2_LIBCONFIG	"Verify encryption key in configuration file pointed to by $gtmcrypt_config"
+
 GBLDEF	int		gtmcrypt_inited;
-GBLDEF	char		gtmcrypt_err_string[MAX_GTMCRYPT_ERR_STRLEN];
-
-xc_status_t gc_init_interface(int prompt_passwd)
-{ 	/* zOS is special when it comes to dynamic linking.
-	 * (1). Building DLL with UNRESOLVED symbols
-	 * =========================================
-	 * Unlike other Unix platforms, on zOS DLL cannot be built having unresolved symbols and expecting them to get resolved
-	 * by the loader.
-	 * In this particular scenario we have symbols gtm_malloc, gtm_is_file_identical, gtm_free, gtm_filename_to_id and
-	 * gtm_xcfileid_free that are part of mupip executable.
-	 * As an workaround we are using function pointers to call into the interface functions so that we don't have an link-time
-	 * errors.
-	 * At runtime we do an dlopen with NULL which returns handle to global space and dlsym sets the function pointers to point
-	 * to the correct functions at runtime.
-	 *
-	 * (2). DLSYM on symbols that are already resolved from another DLL
-	 * ================================================================
-	 * When mumps calls into libgtmcrypt it has above mentioned symbols already resolved from libgtmshr.dll.
-	 * On zOS, when we try to DLSYM using the handle returned by DLOPEN(NULL,..), DLSYM crashes while trying to find symbols
-	 * that are already loaded from another DLL(libgtmshr.dll).
-	 * As an work around we dlopen libgtmshr.dll when called from MUMPS.
-	 */
-#	ifdef __MVS__
-	void			*handle = NULL;
-	const char		*gtm_dist, *dlerr_ptr;
-	char 			gtmshr_file[GTM_PATH_MAX];
-	int			dir_len;
-
-	if (!(gtm_dist = getenv(GTM_DIST)))
-		UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_DIST);
-	dir_len = STRLEN(gtm_dist);
-	memcpy(&gtmshr_file[0], gtm_dist, dir_len);
-	gtmshr_file[dir_len] = DIR_SEPARATOR;
-	MEMCPY_LIT(&gtmshr_file[dir_len + 1], GTMSHR_IMAGENAME);
-	gtmshr_file[dir_len + STR_LIT_LEN(GTMSHR_IMAGENAME) + 1] = '\0';
-	/* prompt_passwd = TRUE implies plugin is invoked from MUMPS. We need to dlopen libgtmshr when invoked from MUMPS.
-	 * Please refer comment (2) above.
-	 */
-	handle = dlopen(prompt_passwd ? gtmshr_file : NULL, GC_FLAGS);
-	if (NULL == handle)
-	{
-		if (NULL == (dlerr_ptr = dlerror()))
-		{
-			UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. Unknown system error");
-		} else
-	 		UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. %s", dlerr_ptr);
-		return GC_FAILURE;
-	}
-	DLSYM_ERR_AND_EXIT(gtm_is_file_identical_fptr_t, gtm_is_file_identical_fptr, GTM_IS_FILE_IDENTICAL_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_malloc_fptr_t, gtm_malloc_fptr, GTM_MALLOC_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_free_fptr_t, gtm_free_fptr, GTM_FREE_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_filename_to_id_fptr_t, gtm_filename_to_id_fptr, GTM_FILENAME_TO_ID_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_ci_fptr_t, gtm_ci_fptr, GTM_CI_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_zstatus_fptr_t, gtm_zstatus_fptr, GTM_ZSTATUS_FUNC);
-	DLSYM_ERR_AND_EXIT(gtm_xcfileid_free_fptr_t, gtm_xcfileid_free_fptr, GTM_XCFILEID_FREE_FUNC);
-#	else
-	gtm_is_file_identical_fptr = &gtm_is_file_identical;
-	gtm_malloc_fptr = &gtm_malloc;
-	gtm_free_fptr = &gtm_free;
-	gtm_filename_to_id_fptr = &gtm_filename_to_id;
-	gtm_ci_fptr = &gtm_ci;
-	gtm_zstatus_fptr = &gtm_zstatus;
-	gtm_xcfileid_free_fptr = &gtm_xcfileid_free;
-#	endif
-	return GC_SUCCESS;
-}
+GBLDEF	int		gtmcrypt_init_flags;
 
-/* ==================================================================================== */
-/*				Plugin API implementations				*/
-/* ==================================================================================== */
+GBLREF	int		gc_dbk_file_format;
+GBLREF	passwd_entry_t	*gtmcrypt_pwent;
 
-char* gtmcrypt_strerror()
+_GTM_APIDEF char* gtmcrypt_strerror()
 {
 	return gtmcrypt_err_string;
 }
 
+_GTM_APIDEF gtm_status_t gtmcrypt_init(int flags)
+{
+	int		fips_requested, fips_enabled, rv;
 
-xc_status_t gtmcrypt_init(int prompt_passwd)
-{	/* Initialize the encryption environment. If any of the following macros fail, the error return happens within the macro. */
-	if (GC_SUCCESS != gc_init_interface(prompt_passwd))
-		return GC_FAILURE;
 	if (gtmcrypt_inited)
 		return GC_SUCCESS;
+	if (0 != gc_load_gtmshr_symbols())
+		return GC_FAILURE;
+#	ifndef USE_OPENSSL
+	gcry_set_log_handler(gtm_gcry_log_handler, NULL);
+#	endif
+	IS_FIPS_MODE_REQUESTED(fips_requested);
+	if (fips_requested)
+	{
+#		ifndef USE_OPENSSL
+#		ifndef GCRYPT_NO_FIPS
+		if (0 != (rv = gcry_control(GCRYCTL_FORCE_FIPS_MODE)))
+		{
+			GC_APPEND_GCRY_ERROR(rv, "Failed to initialize FIPS mode.");
+			return GC_FAILURE;
+		}
+#		endif
+#		else
+		ENABLE_FIPS_MODE(rv, fips_enabled);
+		if (-1 == rv)
+			return GC_FAILURE; /* Relevant error detail populated in the above macro. */
+#		endif
+	}
+#	ifndef USE_OPENSSL
+	if (0 != gc_sym_init())
+		return GC_FAILURE;
+#	endif
 	GC_PK_INIT;
-	GC_PK_PROMPT_PASSWD(prompt_passwd)
+	/* Update $gtm_passwd for future invocation */
+	if (0 != gc_update_passwd(GTM_PASSWD_ENV, &gtmcrypt_pwent, GTMCRYPT_DEFAULT_PASSWD_PROMPT,
+					GTMCRYPT_OP_INTERACTIVE_MODE & flags))
+	{
+		return GC_FAILURE;
+	}
 	gtmcrypt_inited = TRUE;
+	gtmcrypt_init_flags = flags;
 	return GC_SUCCESS;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_getkey_by_name(xc_string_t *filename, gtmcrypt_key_t *handle)
+_GTM_APIDEF gtm_status_t gtmcrypt_getkey_by_name(gtm_string_t *filename, gtmcrypt_key_t *handle)
 {
-	xc_fileid_ptr_t	fileid = NULL;
-	gtm_dbkeys_tbl	*entry;
-	xc_status_t	status = GC_SUCCESS;
+	gtm_fileid_ptr_t	fileid = NULL;
+	gtm_dbkeys_tbl		*entry;
+	gtm_status_t		status = 0;
 
 	GC_VERIFY_INITED;
-	*handle = INVALID_HANDLE;
+	*handle = GTMCRYPT_INVALID_KEY_HANDLE;
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
-	GC_DBK_FILENAME_TO_ID(filename, fileid);
-	entry = gc_dbk_get_entry_by_fileid(fileid);
-	/* If the load below failed, don't continue */
-	GC_DBK_RELOAD_IF_NEEDED(entry, status, fileid, NULL);
+	if (!GTM_FILENAME_TO_ID(filename, &fileid))
+	{
+		UPDATE_ERROR_STRING("Database file %s not found", filename->address);
+		return GC_FAILURE;
+	}
+	if (NULL == (entry = gc_dbk_get_entry_by_fileid(fileid)))
+	{	/* Try re-loading the configuration/db-keys file before giving up. */
+		if (0 != gc_dbk_init_dbkeys_tbl())
+			return GC_FAILURE;	/* No point continuing. */
+		status = gc_dbk_fill_symkey_hash(fileid, NULL);
+	}
 	if (0 == status)
 	{
 		entry = gc_dbk_get_entry_by_fileid(fileid);
@@ -150,23 +132,23 @@ xc_status_t gtmcrypt_getkey_by_name(xc_string_t *filename, gtmcrypt_key_t *handl
 	return status;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_getkey_by_hash(xc_string_t *hash, gtmcrypt_key_t *handle)
+_GTM_APIDEF gtm_status_t gtmcrypt_getkey_by_hash(gtm_string_t *hash, gtmcrypt_key_t *handle)
 {
 	gtm_dbkeys_tbl	*entry;
-	xc_status_t	status = GC_SUCCESS;
+	gtm_status_t	status = 0;
 	int		err_caused_by_gpg;
 	char		save_err[MAX_GTMCRYPT_ERR_STRLEN], hex_buff[GTMCRYPT_HASH_HEX_LEN + 1];
-	char		*gpg_msg = "Verify encrypted key file and your GNUPGHOME settings";
-	char		*correct_key_msg = "Verify encryption key in DB keys file";
 	char		*alert_msg;
 
-	*handle = INVALID_HANDLE;
+	*handle = GTMCRYPT_INVALID_KEY_HANDLE;
 	GC_VERIFY_INITED;
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
-	entry = gc_dbk_get_entry_by_hash(hash);
-	/* If the load below failed, don't continue */
-	GC_DBK_RELOAD_IF_NEEDED(entry, status, NULL, hash->address);
+	if (NULL == (entry = gc_dbk_get_entry_by_hash(hash)))
+	{	/* Try re-loading the configuration/db-keys file before giving up. */
+		if (0 != gc_dbk_init_dbkeys_tbl())
+			return GC_FAILURE;	/* No point continuing. */
+		status = gc_dbk_fill_symkey_hash(NULL, hash->address);
+	}
 	if (0 == status)
 	{
 		entry = gc_dbk_get_entry_by_hash(hash);
@@ -178,7 +160,13 @@ xc_status_t gtmcrypt_getkey_by_hash(xc_string_t *hash, gtmcrypt_key_t *handle)
 			if (GC_SUCCESS != gc_pk_gpghome_has_permissions())
 				return GC_FAILURE;
 			err_caused_by_gpg = ('\0' != gtmcrypt_err_string[0]);
-			alert_msg = (err_caused_by_gpg ? gpg_msg : correct_key_msg);
+			if (err_caused_by_gpg)
+				alert_msg = MESSAGE1;
+			else
+			{
+				assert((DBKEYS_FILE_FORMAT == gc_dbk_file_format) || (LIBCONFIG_FILE_FORMAT == gc_dbk_file_format));
+				alert_msg = (DBKEYS_FILE_FORMAT == gc_dbk_file_format ? MESSAGE2_DBKEYS : MESSAGE2_LIBCONFIG);
+			}
 			GC_HEX(hash->address, hex_buff, GTMCRYPT_HASH_HEX_LEN);
 			if (err_caused_by_gpg)
 			{
@@ -193,51 +181,57 @@ xc_status_t gtmcrypt_getkey_by_hash(xc_string_t *hash, gtmcrypt_key_t *handle)
 	return status;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_hash_gen(gtmcrypt_key_t handle, xc_string_t *hash)
+_GTM_APIDEF gtm_status_t gtmcrypt_hash_gen(gtmcrypt_key_t handle, gtm_string_t *hash)
 {
 	gtm_dbkeys_tbl	*entry;
 
 	GC_VERIFY_INITED;
-	assert(INVALID_HANDLE != handle);
+	RETURN_IF_INVALID_HANDLE(handle);
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
-	GC_DBK_GET_ENTRY_FROM_HANDLE(handle, entry, GC_FAILURE);
+	entry = (gtm_dbkeys_tbl *)fast_lookup_entry[(int)handle];
 	gc_dbk_get_hash(entry, hash);
 	return GC_SUCCESS;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_encrypt(gtmcrypt_key_t handle, xc_string_t *unencrypted_block, xc_string_t *encrypted_block)
+_GTM_APIDEF gtm_status_t gtmcrypt_encrypt(gtmcrypt_key_t handle, gtm_string_t *unencrypted_block, gtm_string_t *encrypted_block)
 {
-	crypt_key_t	key_handle;
 	gtm_dbkeys_tbl	*entry;
+	crypt_key_t	key;
 
 	GC_VERIFY_INITED;
-	assert(INVALID_HANDLE != handle);
+	RETURN_IF_INVALID_HANDLE(handle);
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
-	GC_DBK_GET_ENTRY_FROM_HANDLE(handle, entry, GC_FAILURE);
-	key_handle = entry->encr_key_handle;
-	GC_SYM_ENCRYPT(key_handle, unencrypted_block, encrypted_block);
+	entry = (gtm_dbkeys_tbl *)fast_lookup_entry[(int)handle];
+	/* NOTE: The below assignment, while seemingly innocuous, is important. `entry->encr_key_handle' is a scalar type in
+	 * OpenSSL (EVP_CIPHER_CTX). The below assignments does a "deep copy" of `entry->encr_key_handle' into `key'. This way,
+	 * we *always* use a fresh copy of the key before encrypting. By doing so, we implicitly reset the encryption state
+	 * engine.
+	 */
+	key = entry->encr_key_handle;
+	GC_SYM_ENCRYPT(&key, unencrypted_block, encrypted_block);
 	return GC_SUCCESS;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_decrypt(gtmcrypt_key_t handle, xc_string_t *encrypted_block, xc_string_t *unencrypted_block)
+_GTM_APIDEF gtm_status_t gtmcrypt_decrypt(gtmcrypt_key_t handle, gtm_string_t *encrypted_block, gtm_string_t *unencrypted_block)
 {
-	crypt_key_t	key_handle;
-	gtm_dbkeys_tbl	*entry;
+	gtm_dbkeys_tbl		*entry;
+	crypt_key_t		key;
 
 	GC_VERIFY_INITED;
-	assert(INVALID_HANDLE != handle);
+	RETURN_IF_INVALID_HANDLE(handle);
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
-	GC_DBK_GET_ENTRY_FROM_HANDLE(handle, entry, GC_FAILURE);
-	key_handle = entry->decr_key_handle;
-	GC_SYM_DECRYPT(key_handle, encrypted_block, unencrypted_block);
+	entry = (gtm_dbkeys_tbl *)fast_lookup_entry[(int)handle];
+	/* NOTE: The below assignment, while seemingly innocuous, is important. `entry->decr_key_handle' is a scalar type in
+	 * OpenSSL (EVP_CIPHER_CTX). The below assignments does a "deep copy" of `entry->decr_key_handle' into `key'. This way,
+	 * we *always* use a fresh copy of the key before decrypting. By doing so, we implicitly reset the encryption state
+	 * engine.
+	 */
+	key = entry->decr_key_handle;
+	GC_SYM_DECRYPT(&key, encrypted_block, unencrypted_block);
 	return GC_SUCCESS;
 }
 
-/* Note: If any of the following macros fail, the error return happens within the macro. */
-xc_status_t gtmcrypt_close()
+_GTM_APIDEF gtm_status_t gtmcrypt_close()
 {
 	GC_VERIFY_INITED;
 	gtmcrypt_err_string[0] = '\0';	/* discard any previously recorded error messages */
diff --git a/sr_unix/gtmcrypt_ref.h b/sr_unix/gtmcrypt_ref.h
index 8139372..9993c1f 100644
--- a/sr_unix/gtmcrypt_ref.h
+++ b/sr_unix/gtmcrypt_ref.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -11,49 +11,17 @@
 #ifndef GTMCRYPT_REF_H
 #define GTMCRYPT_REF_H
 
-#if !defined(DEBUG) && defined(assert)
-# undef assert
-# define assert(x)
+#ifdef USE_OPENSSL
+# include <openssl/blowfish.h>
+# include <openssl/sha.h>
+# include <openssl/evp.h>
+# include <openssl/err.h>
+typedef EVP_CIPHER_CTX		crypt_key_t;
+#else
+# include <gcrypt.h>
+typedef gcry_cipher_hd_t	crypt_key_t;
 #endif
 
-#include "gtm_common_defs.h"		/* To import common macros implemented by GT.M */
-#include "gtm_sizeof.h"			/* for SIZEOF */
-
-/* ==================================================================================== */
-/* Legend to namespaces used -
- * gc_XXXXX    - All functions start with the gc_ namespace
- * gc_dbk_XXX  - All functions related to db key mapping and internal book keeping
- * gc_sym_XXX  - All functions related to usages of symmetric enc/dec activities, primarily using libgcrypt or libcrypto
- * gc_pk_XXX   - All functions related to usages of public/private key enc/dec activities, primarily using libgpgme
- */
-/* ==================================================================================== */
-
-
-/* The value 1023 for PATH_MAX is derived using pathconf("path", _PC_PATH_MAX) on z/OS and
- * we figure other POSIX platforms are at least as capable if they don't define PATH_MAX.
- * Since we can't afford to call a function on each use of PATH_MAX/GTM_PATH_MAX, this
- * value is hardcoded here.
- *
- * Note on Linux (at least), PATH_MAX is actually defined in <sys/param.h>. We would include
- * that here unconditionally but on AIX, param.h includes limits.h. Note that regardless of where
- * it gets defined, PATH_MAX needs to be defined prior to including stdlib.h. This is because in a
- * pro build, at least Linux verifies the 2nd parm of realpath() is PATH_MAX bytes or more.
- * Since param.h sets PATH_MAX to 4K on Linux, this can cause structures defined as GTM_PATH_MAX
- * to raise an error when used in the 2nd argument of realpath().
- * Note : The definition of PATH_MAX and GTM_PATH_MAX is borrowed from gtm_limits.h. Change in one
- * should be reflected in the other.
- */
-#ifndef PATH_MAX
-#  ifdef __linux__
-#    include <sys/param.h>
-#  else
-#    define PATH_MAX 			1023
-#  endif
-#endif
-/* Now define our version which includes space for a terminating NULL byte */
-#define	GTM_PATH_MAX			PATH_MAX + 1
-#define TAB_NAME_MAX			512
-#define GTM_PASSPHRASE_MAX		512
 #define GC_ENCRYPT			1
 #define GC_DECRYPT			0
 #define GC_FAILURE			1
@@ -61,105 +29,13 @@
 #define DOT_GTM_DBKEYS			".gtm_dbkeys"
 #define DOT_GNUPG			".gnupg"
 #define SYMMETRIC_KEY_MAX		32
-#define GTMCRYPT_HASH_LEN		64
-#define GTMCRYPT_HASH_HEX_LEN		GTMCRYPT_HASH_LEN * 2
-#define INVALID_HANDLE			-1
-#define GTMCI				"GTMCI"
-#define MAX_GTMCRYPT_ERR_STRLEN		2048
 
 #define GC_MIN_STATIC_BLOCK_SIZE	4096			/* Have a good size block, so that we dont keep reallocating */
-#define GC_FLAGS			(RTLD_NOW | RTLD_GLOBAL)
 
 /* Some environment variables that encryption plugin cares about */
 #define GNUPGHOME			"GNUPGHOME"
-#define GTM_PASSWD			"gtm_passwd"
-#define GTM_OBFUSCATION_KEY		"gtm_obfuscation_key"
 #define GTM_DBKEYS			"gtm_dbkeys"
 #define HOME				"HOME"
-#define USER				"USER"
-#define GTM_DIST			"gtm_dist"
-
-#define ENV_UNDEF_ERROR			"Environment variable %s not set"
-#define ENV_EMPTY_ERROR			"Environment variable %s set to empty string"
-
-/* Define function pointers to the functions that the encryption plugin imports from libgtmshr.so at runtime */
-#define GTM_MALLOC_FUNC			"gtm_malloc"
-#define GTM_FREE_FUNC			"gtm_free"
-#define GTM_FILENAME_TO_ID_FUNC		"gtm_filename_to_id"
-#define GTM_CI_FUNC			"gtm_ci"
-#define GTM_ZSTATUS_FUNC		"gtm_zstatus"
-#define GTM_IS_FILE_IDENTICAL_FUNC	"gtm_is_file_identical"
-#define GTM_XCFILEID_FREE_FUNC		"gtm_xcfileid_free"
-
-typedef void *				(*gtm_malloc_fptr_t)(size_t);
-typedef void				(*gtm_free_fptr_t)(void *);
-typedef xc_status_t			(*gtm_filename_to_id_fptr_t)(xc_string_t *, xc_fileid_ptr_t *);
-typedef xc_status_t			(*gtm_ci_fptr_t)(const char *c_rtn_name, ...);
-typedef void				(*gtm_zstatus_fptr_t)(char *msg, int len);
-typedef xc_status_t			(*gtm_is_file_identical_fptr_t)(xc_fileid_ptr_t, xc_fileid_ptr_t);
-typedef void				(*gtm_xcfileid_free_fptr_t)(xc_fileid_ptr_t);
-
-GBLDEF gtm_malloc_fptr_t		gtm_malloc_fptr;
-GBLDEF gtm_free_fptr_t			gtm_free_fptr;
-GBLDEF gtm_filename_to_id_fptr_t	gtm_filename_to_id_fptr;
-GBLDEF gtm_ci_fptr_t			gtm_ci_fptr;
-GBLDEF gtm_zstatus_fptr_t		gtm_zstatus_fptr;
-GBLDEF gtm_is_file_identical_fptr_t	gtm_is_file_identical_fptr;
-GBLDEF gtm_xcfileid_free_fptr_t		gtm_xcfileid_free_fptr;
-
-xc_status_t 		gc_init_interface(int prompt_passwd);		/* function that sets up the above function pointers */
-
-GBLREF	char		gtmcrypt_err_string[MAX_GTMCRYPT_ERR_STRLEN];	/* most recent error that the plugin encountered */
-
-#define SNPRINTF(SRC, LEN, ...)													\
-{																\
-	int		rc;													\
-																\
-	do															\
-	{															\
-		rc = snprintf(SRC, LEN, __VA_ARGS__);	/* BYPASSOK */								\
-	} while ((-1 == rc) && (EINTR == errno)); /* EINTR-safe */								\
-}
-
-#define SPRINTF(SRC, ...)													\
-{																\
-	int		rc;													\
-																\
-	do															\
-	{															\
-		rc = sprintf(SRC, __VA_ARGS__);	/* BYPASSOK */									\
-	} while ((-1 == rc) && (EINTR == errno)); /* EINTR-safe */								\
-}
-
-#define UPDATE_ERROR_STRING(...)												\
-{																\
-	SNPRINTF(gtmcrypt_err_string, MAX_GTMCRYPT_ERR_STRLEN, __VA_ARGS__);							\
-}
-
-#define DLSYM_ERR_AND_EXIT(fptr_type, fptr, func_name)										\
-{																\
-	char		*dlerr_ptr;												\
-																\
-	fptr = (fptr_type)dlsym(handle, func_name);										\
-	if (NULL == fptr)													\
-	{															\
-		if (NULL == (dlerr_ptr = dlerror()))										\
-		{														\
-			UPDATE_ERROR_STRING("Unable to resolve symbol %s. Unknown system error", func_name);			\
-		} else														\
-			UPDATE_ERROR_STRING("Unable to resolve symbol %s. %s", func_name, dlerr_ptr);				\
-		return GC_FAILURE;												\
-	}															\
-}
-
-#define GC_MALLOC(blk, len, type)												\
-{																\
-	blk = (type *)gtm_malloc_fptr(len);											\
-	assert(blk);														\
-}
-
-#define GC_FREE(blk)	gtm_free_fptr(blk)
-
 
 /* Following makes sure that at no point we are in the encryption library without gtmcrypt_init getting called
  * prior to the current call
@@ -173,36 +49,4 @@ GBLREF	char		gtmcrypt_err_string[MAX_GTMCRYPT_ERR_STRLEN];	/* most recent error
 	}															\
 }
 
-#define GC_INT(H) ((H >= 'A' && H <= 'F') ? ((H - 'A') + 10) : (H - '0'))
-
-#define GC_UNHEX(a, b, len)													\
-{																\
-	int i;															\
-	for (i = 0; i < len; i += 2)												\
-		b[i/2] = (unsigned char)(GC_INT(a[i]) * 16 + GC_INT(a[i + 1]));							\
-}
-
-#define GC_HEX(a, b, len)													\
-{																\
-	int i;															\
-	for (i = 0; i < len; i += 2)												\
-		SPRINTF(b + i, "%02X", (unsigned char)a[i / 2]);								\
-}
-
-/* Allocate a single block, and reuse everytime this macro is called */
-#ifdef USE_OPENSSL
-#define GC_GET_STATIC_BLOCK(out, block_len)											\
-{																\
-	static char *blk = (char *)NULL;											\
-	static int allocated_len = GC_MIN_STATIC_BLOCK_SIZE;									\
-	if (blk == NULL || (block_len > allocated_len))										\
-	{															\
-		if (blk)													\
-			GC_FREE(blk);												\
-		allocated_len = (block_len > allocated_len) ?  ROUND_UP(block_len, GC_MIN_STATIC_BLOCK_SIZE) : allocated_len; 	\
-		GC_MALLOC(blk, allocated_len, char);										\
-	}															\
-	out = blk;														\
-}
-#endif
 #endif /* GTMCRYPT_REF_H */
diff --git a/sr_unix/gtmcrypt_sym_ref.c b/sr_unix/gtmcrypt_sym_ref.c
new file mode 100644
index 0000000..8331ca2
--- /dev/null
+++ b/sr_unix/gtmcrypt_sym_ref.c
@@ -0,0 +1,140 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "gtmxc_types.h"
+
+#include "gtmcrypt_util.h"
+#include "gtmcrypt_interface.h"		/* Function prototypes for gtmcrypt*.* functions */
+
+#include "gtmcrypt_ref.h"
+#include "gtmcrypt_dbk_ref.h"
+#include "gtmcrypt_sym_ref.h"
+
+#ifndef USE_OPENSSL
+int gc_sym_init()
+{
+	gcry_error_t	rv;
+
+	memset(iv, 0, IV_LEN);
+	if (!gcry_check_version(GCRYPT_VERSION))
+	{
+		UPDATE_ERROR_STRING("libgcrypt version mismatch. %s or higher is required", GCRYPT_VERSION);
+		return -1;
+	}
+	if (0 != (rv = gcry_control(GCRYCTL_DISABLE_SECMEM, 0)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to disable secure memory.");
+		return -1;
+	}
+	if (0 != (rv = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to finish encryption initialization.")
+		return -1;
+	}
+	return 0;
+}
+#endif
+
+int gc_sym_create_key_handles(gtm_dbkeys_tbl *entry)
+{
+	int		rv;
+	unsigned char	*key;
+
+	key = entry->symmetric_key;
+#	ifdef USE_OPENSSL
+	/* Create the encryption key handle. */
+	EVP_CIPHER_CTX_init(&entry->encr_key_handle);
+	if (!EVP_CipherInit(&entry->encr_key_handle, ALGO, key, NULL, GC_ENCRYPT))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to initialize encryption key handle.");
+		return -1;
+	}
+	/* Create the decryption key handle. */
+	EVP_CIPHER_CTX_init(&entry->decr_key_handle);
+	if (0 == (rv = EVP_CipherInit(&entry->decr_key_handle, ALGO, key, NULL, GC_DECRYPT)))
+	{
+		GC_APPEND_OPENSSL_ERROR("Failed to initialize decryption key handle.");
+		return -1;
+	}
+#	else
+	if (0 != (rv = gcry_cipher_open(&entry->encr_key_handle, ALGO, MODE, 0)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to initialize encryption key handle (`gcry_cipher_open').");
+		return -1;
+	}
+	if (0 != (rv = gcry_cipher_setkey(entry->encr_key_handle, key, SYMMETRIC_KEY_MAX)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to initialize encryption key handle (`gcry_cipher_setkey').");
+		return -1;
+	}
+	if (0 != (rv = gcry_cipher_open(&entry->decr_key_handle, ALGO, MODE, 0)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to initialize decryption key handle (`gcry_cipher_open').");
+		return -1;
+	}
+	if (0 != (rv = gcry_cipher_setkey(entry->decr_key_handle, key, SYMMETRIC_KEY_MAX)))
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Failed to initialize decryption key handle (`gcry_cipher_setkey').");
+		return -1;
+	}
+#	endif
+	return 0;
+}
+
+int gc_sym_encrypt_decrypt(crypt_key_t *key, gtm_string_t *in_block, gtm_string_t *out_block, int flag)
+{
+	int		inl, outl, rv, tmp_len;
+	unsigned char	*in, *out;
+
+	assert(in_block->address);
+	assert(0 < in_block->length);
+	in = (unsigned char *)in_block->address;
+	out = (NULL == out_block->address) ? in : (unsigned char *)out_block->address;
+	outl = inl = in_block->length;
+#	ifndef USE_OPENSSL
+	if (out == in)
+	{
+		in = NULL;
+		inl = 0;
+	}
+	/* This is important. We have to reset the IV back to all zeros to reset the encryption state machine. Otherwise, the 'iv'
+	 * from the previous call to this function would be reused for this call resulting in incorrect encryption/decryption.
+	 */
+	gcry_cipher_setiv(*key, iv, IV_LEN);
+	rv = (GC_ENCRYPT == flag) ? gcry_cipher_encrypt(*key, out, outl, in, inl) : gcry_cipher_decrypt(*key, out, outl, in, inl);
+	if (0 != rv)
+	{
+		GC_APPEND_GCRY_ERROR(rv, "Libgcrypt function `gcry_cipher_encrypt' or `gcry_cipher_decrypt' failed.");
+		return -1;
+	}
+#	else
+	if (!EVP_CipherUpdate(key, out, &outl, in, inl))
+	{
+		GC_APPEND_OPENSSL_ERROR("OpenSSL function `EVP_CipherUpdate' failed.")
+		return -1;
+	}
+	if (!EVP_CipherFinal(key, out + outl, &tmp_len))
+	{
+		GC_APPEND_OPENSSL_ERROR("OpenSSL function `EVP_CipherFinal' failed.")
+		return -1;
+	}
+#	endif
+	return 0;
+}
diff --git a/sr_unix/gtmcrypt_sym_ref.h b/sr_unix/gtmcrypt_sym_ref.h
index a895c37..4e620d0 100644
--- a/sr_unix/gtmcrypt_sym_ref.h
+++ b/sr_unix/gtmcrypt_sym_ref.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2009, 2012 Fidelity Information Services, Inc 	*
+ *	Copyright 2009, 2013 Fidelity Information Services, Inc *
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -13,10 +13,6 @@
 #define GTMCRYPT_SYM_REF_H
 
 #ifdef USE_OPENSSL
-# include <openssl/blowfish.h>
-# include <openssl/sha.h>
-# include <openssl/evp.h>
-# include <openssl/err.h>
 # if defined(USE_AES256CFB)
 #  define ALGO			EVP_aes_256_cfb128()
 #  define UNIQ_ENC_PARAM_STRING	"AES256CFB"
@@ -26,9 +22,7 @@
 # else
 #  error			"Unsupported Algorithm for OpenSSL"
 # endif
-typedef EVP_CIPHER_CTX		crypt_key_t;
 #elif defined USE_GCRYPT
-# include <gcrypt.h>
 # if defined(USE_AES256CFB)
 #  define IV_LEN		16
 #  define ALGO			GCRY_CIPHER_AES256
@@ -40,7 +34,6 @@ typedef EVP_CIPHER_CTX		crypt_key_t;
 # endif
 STATICDEF int			gcry_already_inited;
 STATICDEF char			iv[IV_LEN];
-typedef gcry_cipher_hd_t	crypt_key_t;
 #else
 # error 			"Unsupported encryption library. Reference implementation currently supports OpenSSL and Libgcrypt"
 #endif	/* USE_GCRYPT */
@@ -48,142 +41,15 @@ typedef gcry_cipher_hd_t	crypt_key_t;
 #define UNIQ_ENC_PARAM_LEN	SIZEOF(UNIQ_ENC_PARAM_STRING) - 1
 #define HASH_INPUT_BUFF_LEN	UNIQ_ENC_PARAM_LEN + SYMMETRIC_KEY_MAX
 
-/* ==================================================================================== */
-/*           Macros and functions for symmetric encryption tasks                        */
-/* ==================================================================================== */
+#define GC_SYM_DECRYPT(KEY_HANDLE, ENCRYPTED_BLOCK, UNENCRYPTED_BLOCK)								\
+	gc_sym_encrypt_decrypt(KEY_HANDLE, ENCRYPTED_BLOCK, UNENCRYPTED_BLOCK, GC_DECRYPT)
 
-#ifdef USE_OPENSSL
-#define GC_SYM_CREATE_HANDLES(cur_entry)											\
-{																\
-	int		ecode;													\
-	unsigned char	*key = cur_entry->symmetric_key;									\
-																\
-	EVP_CIPHER_CTX_init(&(cur_entry->encr_key_handle));									\
-	ecode = EVP_CipherInit(&(cur_entry->encr_key_handle), ALGO, key, NULL, GC_ENCRYPT);					\
-	GC_SYM_ERROR(ecode, GC_FAILURE);											\
-																\
-	EVP_CIPHER_CTX_init(&(cur_entry->decr_key_handle));									\
-	ecode = EVP_CipherInit(&(cur_entry->decr_key_handle), ALGO, key, NULL, GC_DECRYPT);					\
-	GC_SYM_ERROR(ecode, GC_FAILURE);											\
-}
-
-#define GC_SYM_ERROR(err, return_value)												\
-{																\
-	if (!err)														\
-	{															\
-		ERR_error_string_n(err, gtmcrypt_err_string, MAX_GTMCRYPT_ERR_STRLEN);						\
-		return return_value;												\
-	}															\
-}
-#else
-#define GC_SYM_CREATE_HANDLES(cur_entry)											\
-{																\
-	gcry_error_t	err;													\
-	unsigned char	*key = cur_entry->symmetric_key;									\
-																\
-	GC_SYM_INIT;														\
-	err = gcry_cipher_open(&(cur_entry->encr_key_handle), ALGO, MODE, FLAGS);						\
-	if (!err)														\
-		err = gcry_cipher_setkey(cur_entry->encr_key_handle, key, SYMMETRIC_KEY_MAX);					\
-	GC_SYM_ERROR(err, GC_FAILURE);												\
-	err = gcry_cipher_open(&(cur_entry->decr_key_handle), ALGO, MODE, FLAGS);						\
-	if (!err)														\
-		err = gcry_cipher_setkey(cur_entry->decr_key_handle, key, SYMMETRIC_KEY_MAX);					\
-	GC_SYM_ERROR(err, GC_FAILURE);												\
-}
-#define GC_SYM_ERROR(err, return_value)												\
-{																\
-	if (GPG_ERR_NO_ERROR != err)												\
-	{															\
-		UPDATE_ERROR_STRING("%s", gcry_strerror(err));									\
-		return return_value;												\
-	}															\
-}
-#endif
+#define GC_SYM_ENCRYPT(KEY_HANDLE, UNENCRYPTED_BLOCK, ENCRYPTED_BLOCK)								\
+	gc_sym_encrypt_decrypt(KEY_HANDLE, UNENCRYPTED_BLOCK, ENCRYPTED_BLOCK, GC_ENCRYPT)
 
-#ifdef	USE_GCRYPT
-/* Initialization and error handling functions defined only for libgcrypt.
- * OpenSSL doesn't neeed them. */
-#define GC_SYM_INIT														\
-{																\
-	gcry_error_t	err;													\
-	char		*ver;													\
-																\
-	if (!gcry_already_inited)												\
-	{															\
-		memset(iv, 0, IV_LEN);												\
-		if (!gcry_check_version(GCRYPT_VERSION))									\
-		{														\
-			UPDATE_ERROR_STRING("libgcrypt version mismatch. %s or higher is required", GCRYPT_VERSION);		\
-			return GC_FAILURE;											\
-		}														\
-		if (!(err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0)))								\
-			if (!(err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0)))						\
-				gcry_already_inited = TRUE;									\
-		GC_SYM_ERROR(err, GC_FAILURE);											\
-	}															\
-}
-#endif
-#ifdef	USE_OPENSSL
-#define GC_SYM_COMMON(key_handle, in_block, out_block, flag)									\
-{																\
-	int			block_len, is_inplace, ecode, tmp_len;								\
-	int			out_len;											\
-	char			*static_out_blk;										\
-	unsigned char		*in = NULL, *out = NULL;									\
-																\
-	assert(in_block->address);												\
-	assert(0 != in_block->length);												\
-	in = (unsigned char *)in_block->address;										\
-	block_len = in_block->length;												\
-	out = (unsigned char *)out_block->address;										\
-	if (NULL == out_block->address)												\
-	{															\
-		GC_GET_STATIC_BLOCK(static_out_blk, block_len);									\
-		out = (unsigned char *)static_out_blk;										\
-		is_inplace = TRUE;												\
-	} else															\
-		is_inplace = FALSE;												\
-	ecode = EVP_CipherUpdate(&key_handle, out, &out_len, in, block_len);							\
-	if (ecode)														\
-		ecode = EVP_CipherFinal(&key_handle, out + out_len, &tmp_len);							\
-	GC_SYM_ERROR(ecode, GC_FAILURE);											\
-	if (is_inplace)														\
-		memcpy(in, out, block_len);											\
-}
-#else /* USE_GCRYPT */
-#define GC_SYM_COMMON(key_handle, in_block, out_block, flag)									\
-{																\
-	size_t			inlen, outlen;											\
-	char			*in, *out;											\
-	gcry_error_t		err;												\
-																\
-	inlen = in_block->length;												\
-	in = in_block->address;													\
-	assert(in && inlen);													\
-	if (NULL == out_block->address)												\
-	{	/* IN-PLACE encryption/decryption. Adjust pointers accordingly */						\
-		out = in;													\
-		outlen = inlen;													\
-		in = NULL;													\
-		inlen = 0;													\
-	} else															\
-	{															\
-		out = out_block->address;											\
-		outlen = inlen;													\
-	}															\
-	GC_SYM_INIT;														\
-	gcry_cipher_setiv(key_handle, iv, IV_LEN);										\
-	if (GC_ENCRYPT == flag)													\
-		err = gcry_cipher_encrypt(key_handle, out, outlen, in, inlen);							\
-	else															\
-		err = gcry_cipher_decrypt(key_handle, out, outlen, in, inlen);							\
-	GC_SYM_ERROR(err, GC_FAILURE);												\
-}
+#ifndef USE_OPENSSL
+int gc_sym_init(void);
 #endif
-#define GC_SYM_DECRYPT(key_handle, encrypted_block, unencrypted_block)								\
-	GC_SYM_COMMON(key_handle, encrypted_block, unencrypted_block, GC_DECRYPT)
-
-#define GC_SYM_ENCRYPT(key_handle, unencrypted_block, encrypted_block)								\
-	GC_SYM_COMMON(key_handle, unencrypted_block, encrypted_block, GC_ENCRYPT)
+int gc_sym_create_key_handles(gtm_dbkeys_tbl *entry);
+int gc_sym_encrypt_decrypt(crypt_key_t *key, gtm_string_t *in_block, gtm_string_t *out_block, int flag);
 #endif /* GTMCRYPT_SYM_REF_H */
diff --git a/sr_unix/gtmcrypt_util.c b/sr_unix/gtmcrypt_util.c
new file mode 100644
index 0000000..3c3f261
--- /dev/null
+++ b/sr_unix/gtmcrypt_util.c
@@ -0,0 +1,368 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <termios.h>
+
+#include <gcrypt.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+#include "gtmxc_types.h"
+#include "gtmcrypt_util.h"
+
+#include "gtmcrypt_interface.h"
+
+/* Define the global error string here. Since this module gets linked into libgtmcryptutil.so, the error string global gets
+ * into the shared library automatically and is shared across all different libraries that comprise the encryption reference
+ * implementation.
+ */
+GBLDEF	char	gtmcrypt_err_string[MAX_GTMCRYPT_ERR_STRLEN];
+#ifndef USE_SYSLIB_FUNCS
+GBLDEF gtm_malloc_fnptr_t		gtm_malloc_fnptr;
+GBLDEF gtm_free_fnptr_t			gtm_free_fnptr;
+GBLDEF gtm_filename_to_id_fnptr_t	gtm_filename_to_id_fnptr;
+GBLDEF gtm_is_file_identical_fnptr_t	gtm_is_file_identical_fnptr;
+GBLDEF gtm_xcfileid_free_fnptr_t	gtm_xcfileid_free_fnptr;
+#endif
+
+#define SIGPROCMASK(FUNC, NEWSET, OLDSET, RC)										\
+{															\
+        do														\
+        {														\
+          RC = sigprocmask(FUNC, NEWSET, OLDSET);									\
+        } while (-1 == RC && EINTR == errno);										\
+}
+
+#define Tcsetattr(FDESC, WHEN, TERMPTR, RC, ERRNO)									\
+{															\
+	sigset_t block_ttinout;												\
+	sigset_t oldset;												\
+	int rc;														\
+															\
+	sigemptyset(&block_ttinout);											\
+	sigaddset(&block_ttinout, SIGTTIN);										\
+	sigaddset(&block_ttinout, SIGTTOU);										\
+	SIGPROCMASK(SIG_BLOCK, &block_ttinout, &oldset, rc);								\
+	do														\
+	{														\
+	   RC = tcsetattr(FDESC, WHEN, TERMPTR);									\
+	} while(-1 == RC && EINTR == errno);										\
+	ERRNO = errno;													\
+	SIGPROCMASK(SIG_SETMASK, &oldset, NULL, rc);									\
+}
+
+#ifdef USE_OPENSSL
+#define SHA512(INBUF, INBUF_LEN, OUTBUF, RC)										\
+{															\
+	RC = EVP_Digest(INBUF, INBUF_LEN, (unsigned char *)OUTBUF, NULL, EVP_sha512(), NULL);				\
+	if (0 >= RC)													\
+	{														\
+		RC = -1;												\
+		GC_APPEND_OPENSSL_ERROR("OpenSSL function `EVP_sha512' failed.");					\
+	} else														\
+		RC = 0;													\
+}
+#else
+#define SHA512(INBUF, INBUF_LEN, OUTBUF, RC)										\
+{															\
+	/* First initialize the libgcrypt library */									\
+	RC = 0;														\
+	if (NULL == gcry_check_version(GCRYPT_VERSION))									\
+	{														\
+		UPDATE_ERROR_STRING("libgcrypt version mismatch. %s or higher is required", GCRYPT_VERSION);		\
+		RC = -1;												\
+	} else														\
+		gcry_md_hash_buffer(GCRY_MD_SHA512, OUTBUF, INBUF, INBUF_LEN);						\
+}
+#endif
+
+int gc_load_gtmshr_symbols()
+{
+#	ifndef USE_SYSLIB_FUNCS
+	gtm_malloc_fnptr = &gtm_malloc;
+	gtm_free_fnptr = &gtm_free;
+	gtm_is_file_identical_fnptr = &gtm_is_file_identical;
+	gtm_filename_to_id_fnptr = &gtm_filename_to_id;
+	gtm_xcfileid_free_fnptr = &gtm_xcfileid_free;
+#	endif
+	return 0;
+}
+
+/* Libgcrypt doesn't do a good job of handling error messages and simply dumps them onto the console if
+ * no handler is set. One such example is when libgcrypt is doing a select on /dev/random and when it
+ * is interrupted due to a SIGALRM, libgcrypt dumps an error message onto the console. To avoid this,
+ * setup a dummy handler and swallow libgcrypt messages as long as they are not FATAL or BUG.
+ */
+void gtm_gcry_log_handler(void *opaque, int level, const char *fmt, va_list arg_ptr)
+{
+	assert((GCRY_LOG_FATAL != level) && (GCRY_LOG_BUG != level));
+	return;
+}
+
+int gc_read_passwd(char *prompt, char *buf, int maxlen)
+{
+	struct termios		new_tty, old_tty;
+	int			fd, status, save_errno, istty, i, rv;
+	char			c;
+
+	/* Display the prompt */
+	printf("\n%s", prompt);
+	fflush(stdout);			/* BYPASSOK -- cannot use FFLUSH */
+	/* Determine if the process has a terminal device associated with it */
+	fd = fileno(stdin);
+	if (FALSE != (istty = isatty(fd)))
+	{	/* Turn off terminal echo. */
+		if (0 != (status = tcgetattr(fd, &old_tty)))
+		{
+			UPDATE_ERROR_STRING("Failed to obtain passphrase from terminal. %s", strerror(errno));
+			return -1;
+		}
+		new_tty = old_tty;
+		new_tty.c_lflag &= ~ECHO;
+		/* GT.M terminal settings has ICANON and ICRNL turned-off. This causes the terminal to be treated
+		 * in non-canonical mode and carriage-return to not take effect. Re-enable them so that input can be
+		 * read from the user.
+		 */
+		new_tty.c_lflag |= ICANON;
+		new_tty.c_iflag |= ICRNL;
+		Tcsetattr(fd, TCSAFLUSH, &new_tty, status, save_errno);
+		if (-1 == status)
+		{
+			UPDATE_ERROR_STRING("Failed to obtain passphrase from terminal. %s", strerror(save_errno));
+			return -1;
+		}
+	}
+	/* Read the password. Note: we cannot use fgets() here as that would cause mixing of streams (buffered vs non-buffered). */
+	i = rv = 0;
+	do
+	{
+		while ((-1 == (status = read(fd, &c, 1))) && (EINTR == errno))
+			;
+		if (-1 == status)
+		{
+			save_errno = errno;
+			UPDATE_ERROR_STRING("Failed to obtain passphrase. %s", strerror(save_errno));
+			rv = -1;
+			break;
+		} else if (0 == status)
+		{
+			UPDATE_ERROR_STRING("Failed to obtain passphrase. Encountered premature EOF while reading from terminal.");
+			rv = -1;
+			break;
+		}
+		buf[i++] = c;
+	} while (('\n' != c) && (i < maxlen));
+	if (i == maxlen)
+	{
+		UPDATE_ERROR_STRING("Password too long. Maximum allowed password length is %d characters.", maxlen);
+		rv = -1;
+	}
+	if (-1 != rv)
+	{
+		assert('\n' == buf[i - 1]);
+		buf[i - 1] = '\0';	/* strip off the trailing \n */
+	}
+	if (istty)
+	{	/* Reset terminal settings to how it was at the function entry. */
+		Tcsetattr(fd, TCSAFLUSH, &old_tty, status, save_errno);
+		if (-1 == status)
+		{
+			UPDATE_ERROR_STRING("Failed to obtain passphrase from terminal. %s", strerror(save_errno));
+			return -1;
+		}
+	}
+	return rv;
+}
+
+/* Given a stream of characters representing the obfuscated/unobfuscated password, convert to the other form. The process requires
+ * an intermediate XOR_MASK.
+ *
+ * XOR MASK:
+ * --------
+ * If the gtm_obfuscation_key exists and points to a file that has readable contents, the XOR mask is the SHA-512 hash of the
+ * contents of that file.
+ * Otherwise, within a pre-zero'ed buffer (of size equal to the length of the password), the value of $USER (from the environment)
+ * is left-justified and the decimal representation of the inode of the mumps executable is right-justified. The XOR mask is the
+ * SHA-512 hash of the contents of this buffer.
+ * 	<PASSWORDLEN>
+ *	USER0000INODE => SHA-512 => XOR mask
+ *
+ * MASKING/UNMASKING:
+ * ------------------
+ * The input character pointer (in->address) is XOR'ed with the above XOR mask and copied into out->address.
+ *
+ * The `nparm' value is unused when called from C and is there only so that this function can be used as an external call entry-
+ * point for M.
+ */
+int gc_mask_unmask_passwd(int nparm, gtm_string_t *in, gtm_string_t *out)
+{
+	char		tmp[GTM_PASSPHRASE_MAX], mumps_exe[GTM_PATH_MAX], hash_in[GTM_PASSPHRASE_MAX], hash[GTMCRYPT_HASH_LEN];
+	char 		*ptr, *mmap_addrs;
+	int		passwd_len, len, i, save_errno, fd, have_hash, status;
+	struct stat	stat_info;
+
+	have_hash = FALSE;
+	passwd_len = in->length < GTM_PASSPHRASE_MAX ? in->length : GTM_PASSPHRASE_MAX;
+
+	if (NULL != (ptr = getenv(GTM_OBFUSCATION_KEY)))
+	{
+		if (-1 != (fd = open(ptr, O_RDONLY)))
+		{
+			if ((-1 != fstat(fd, &stat_info)) && S_ISREG(stat_info.st_mode))
+			{	/* File pointed by $gtm_obfuscation_key exists and is a regular file */
+				mmap_addrs = mmap(0, stat_info.st_size, PROT_READ, MAP_SHARED, fd, 0);
+				if (MAP_FAILED != mmap_addrs)
+				{
+					SHA512(mmap_addrs, stat_info.st_size, hash, status);
+					if (0 != status)
+						return -1;
+					have_hash = TRUE;
+					munmap(mmap_addrs, stat_info.st_size);
+				}
+			}
+			close(fd);
+		}
+	}
+	if (!have_hash)
+	{
+		if (!(ptr = getenv(USER_ENV)))
+		{
+			UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, USER_ENV);
+			return -1;
+		}
+		strncpy(hash_in, ptr, passwd_len);
+		if (!(ptr = getenv(GTM_DIST_ENV)))
+		{
+			UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_DIST_ENV);
+			return -1;
+		}
+		SNPRINTF(mumps_exe, GTM_PATH_MAX, "%s/%s", ptr, "mumps");
+		if (0 == stat(mumps_exe, &stat_info))
+		{
+			SNPRINTF(tmp, GTM_PASSPHRASE_MAX, "%ld", (long) stat_info.st_ino);
+			len = (int)STRLEN(tmp);
+			if (len < passwd_len)
+				strncpy(hash_in + (passwd_len - len), tmp, len);
+			else
+				strncpy(hash_in, tmp, passwd_len);
+		} else
+		{
+			save_errno = errno;
+			UPDATE_ERROR_STRING("Cannot find MUMPS executable in %s - %s", ptr, strerror(save_errno));
+			return -1;
+		}
+		SHA512(hash_in, passwd_len, hash, status);
+		if (0 != status)
+			return -1;
+		have_hash = TRUE;
+	}
+	assert(have_hash);
+	for (i = 0; i < passwd_len; i++)
+		out->address[i] = in->address[i] ^ hash[i % GTMCRYPT_HASH_LEN];
+	out->length = passwd_len;
+	return 0;
+}
+
+void gc_freeup_pwent(passwd_entry_t *pwent)
+{
+	assert(NULL != pwent);
+	memset(pwent->passwd, 0, pwent->passwd_len);
+	FREE(pwent->passwd);
+	FREE(pwent->env_value);
+	FREE(pwent);
+}
+
+int gc_update_passwd(char *name, passwd_entry_t **ppwent, char *prompt, int interactive)
+{
+	char		*env_name, *env_value, *passwd, *lpasswd, tmp_passwd[GTM_PASSPHRASE_MAX];
+	int		len, status;
+	gtm_string_t	passwd_str, tmp_passwd_str;
+	passwd_entry_t	*pwent;
+
+	if (!(lpasswd = getenv(name)))
+	{
+		UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, name);
+		return -1;
+	}
+	pwent = *ppwent;
+	if ((NULL != pwent) && (0 == strcmp(pwent->env_value, lpasswd)))
+		return 0;	/* No change in the environment value. Nothing more to do. */
+	len = STRLEN(lpasswd);
+	assert((0 == len % 2) && (GTM_PASSPHRASE_MAX * 2 > len));
+	if (NULL != pwent)
+		gc_freeup_pwent(pwent);
+	pwent = MALLOC(SIZEOF(passwd_entry_t));
+	pwent->env_value = MALLOC(len ? len + 1 : GTM_PASSPHRASE_MAX * 2 + 1);
+	pwent->passwd_len = len ? len / 2 + 1 : GTM_PASSPHRASE_MAX + 1;
+	pwent->passwd = MALLOC(pwent->passwd_len);
+	env_name = pwent->env_name;
+	env_value = pwent->env_value;
+	passwd = pwent->passwd;
+	strncpy(env_name, name, SIZEOF(pwent->env_name));
+	env_name[SIZEOF(pwent->env_name) - 1] = '\0';
+	if (0 < len)
+	{
+		/* First, convert from hexadecimal representation to regular representation */
+		GC_UNHEX(lpasswd, passwd, len);
+		/* Now, unobfuscate to get the real password */
+		passwd_str.address = passwd;
+		passwd_str.length = len / 2;
+		if (0 == (status = gc_mask_unmask_passwd(2, &passwd_str, &passwd_str)))
+		{
+			 strcpy(env_value, lpasswd);	/* Store the hexadecimal representation in environment */
+			 passwd[len / 2] = '\0';	/* null-terminate the password string */
+			*ppwent = pwent;
+		} else
+			gc_freeup_pwent(pwent);
+		return status;
+	}
+	/* Environment variable is set to an empty string. Prompt for password. But, first check if we are running in interactive
+	 * mode. If not, return with an error.
+	 */
+	if (!interactive)
+	{
+		UPDATE_ERROR_STRING("Environment variable %s set to empty string. "
+					"Cannot prompt for password in this mode of operation.", env_name);
+		gc_freeup_pwent(pwent);
+		return -1;
+	}
+	if (-1 == gc_read_passwd(prompt, passwd, GTM_PASSPHRASE_MAX))
+	{
+		gc_freeup_pwent(pwent);
+		return -1;
+	}
+	/* Obfuscate the read password and set it in the environment. */
+	passwd_str.address = passwd;
+	passwd_str.length = (int)STRLEN(passwd);
+	tmp_passwd_str.address = &tmp_passwd[0];
+	if (0 != gc_mask_unmask_passwd(2, &passwd_str, &tmp_passwd_str))
+	{
+		gc_freeup_pwent(pwent);
+		return -1;
+	}
+	/* Since the obfuscated password might contain un-printable characters, represent them as hexadecimal digits. */
+	GC_HEX(tmp_passwd, env_value, tmp_passwd_str.length * 2);
+	setenv(env_name, env_value, TRUE);
+	*ppwent = pwent;
+	return 0;
+}
diff --git a/sr_unix/gtmcrypt_util.h b/sr_unix/gtmcrypt_util.h
new file mode 100644
index 0000000..628d637
--- /dev/null
+++ b/sr_unix/gtmcrypt_util.h
@@ -0,0 +1,234 @@
+/****************************************************************
+ *								*
+ *	Copyright 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+#ifndef __GTMCRYPT_UTIL_H
+#define __GTMCRYPT_UTIL_H
+
+#if !defined(DEBUG) && defined(assert)
+# undef assert
+# define assert(x)
+#endif
+
+#include "gtm_sizeof.h"			/* for SIZEOF */
+#include "gtm_common_defs.h"		/* To import common macros implemented by GT.M */
+
+/* The value 1023 for PATH_MAX is derived using pathconf("path", _PC_PATH_MAX) on z/OS and
+ * we figure other POSIX platforms are at least as capable if they don't define PATH_MAX.
+ * Since we can't afford to call a function on each use of PATH_MAX/GTM_PATH_MAX, this
+ * value is hardcoded here.
+ *
+ * Note on Linux (at least), PATH_MAX is actually defined in <sys/param.h>. We would include
+ * that here unconditionally but on AIX, param.h includes limits.h. Note that regardless of where
+ * it gets defined, PATH_MAX needs to be defined prior to including stdlib.h. This is because in a
+ * pro build, at least Linux verifies the 2nd parm of realpath() is PATH_MAX bytes or more.
+ * Since param.h sets PATH_MAX to 4K on Linux, this can cause structures defined as GTM_PATH_MAX
+ * to raise an error when used in the 2nd argument of realpath().
+ * Note : The definition of PATH_MAX and GTM_PATH_MAX is borrowed from gtm_limits.h. Change in one
+ * should be reflected in the other.
+ */
+#ifndef PATH_MAX
+#  ifdef __linux__
+#    include <sys/param.h>
+#  else
+#    define PATH_MAX 			1023
+#  endif
+#endif
+#define	GTM_PATH_MAX			PATH_MAX + 1
+
+#define GTM_DIST_ENV			"gtm_dist"
+#define USER_ENV			"USER"
+#define ENV_UNDEF_ERROR			"Environment variable %s not set"
+#define ENV_EMPTY_ERROR			"Environment variable %s set to empty string"
+
+#define MAX_GTMCRYPT_ERR_STRLEN		2048
+
+#define GTM_PASSPHRASE_MAX		512
+#define PASSPHRASE_ENVNAME_MAX		64
+#define GTMCRYPT_DEFAULT_PASSWD_PROMPT	"Enter Passphrase: "
+
+#define GTM_OBFUSCATION_KEY		"gtm_obfuscation_key"
+
+#define GTMCRYPT_FIPS_ENV		"gtmcrypt_FIPS"
+
+#define GC_H2D(H) ((H >= 'A' && H <= 'F') ? ((H - 'A') + 10) : (H - '0'))
+
+/* Convert SOURCE, sequence of hexadecimal characters, into decimal representation. LEN denotes the length of the SOURCE string.
+ * NOTE: Hexadecimal characters, presented in SOURCE string, has to be in upper case.
+ */
+#define GC_UNHEX(SOURCE, TARGET, LEN)												\
+{																\
+	int i;															\
+	for (i = 0; i < LEN; i += 2)												\
+		TARGET[i/2] = (unsigned char)(GC_H2D(SOURCE[i]) * 16 + GC_H2D(SOURCE[i + 1]));					\
+}
+
+/* Convert SOURCE, sequence of decimal characters, into hexadecimal representation. LEN denotes the length of the SOURCE string. */
+#define GC_HEX(SOURCE, TARGET, LEN)												\
+{																\
+	int i;															\
+	for (i = 0; i < LEN; i += 2)												\
+		SPRINTF(TARGET + i, "%02X", (unsigned char)SOURCE[i / 2]);							\
+}
+
+#define SNPRINTF(SRC, LEN, ...)													\
+{																\
+	int		rc;													\
+																\
+	do															\
+	{															\
+		rc = snprintf(SRC, LEN, __VA_ARGS__);	/* BYPASSOK */								\
+	} while ((-1 == rc) && (EINTR == errno)); /* EINTR-safe */								\
+}
+
+#define SPRINTF(SRC, ...)													\
+{																\
+	int		rc;													\
+																\
+	do															\
+	{															\
+		rc = sprintf(SRC, __VA_ARGS__);	/* BYPASSOK */									\
+	} while ((-1 == rc) && (EINTR == errno)); /* EINTR-safe */								\
+}
+
+/* Some helper error reporting macros. */
+#define UPDATE_ERROR_STRING(...)												\
+{																\
+	SNPRINTF(gtmcrypt_err_string, MAX_GTMCRYPT_ERR_STRLEN, __VA_ARGS__);							\
+}
+
+#define IS_FIPS_MODE_REQUESTED(RV)											\
+{															\
+	char		*ptr;												\
+															\
+	RV = FALSE;													\
+	if (NULL != (ptr = getenv(GTMCRYPT_FIPS_ENV)))									\
+	{														\
+		if ((0 == strcasecmp(ptr, "YES"))									\
+			|| (0 == strcasecmp(ptr, "TRUE"))								\
+			|| (*ptr == '1')										\
+			|| (*ptr == 'Y')										\
+			|| (*ptr == 'y'))										\
+		{													\
+			RV = TRUE;											\
+		}													\
+	}														\
+}
+
+/* In OpenSSL versions prior to 1.0.1, "FIPS_mode_set", the function that enables/disables FIPS mode, is available only
+ * in a FIPS capable OpenSSL (that is, OpenSSL built from source with "fips" option). From 1.0.1, the function was moved
+ * to "crypto/o_fips.c" and made as a wrapper to the actual FIPS Object Module and so was available on OpenSSL versions
+ * built with or without the "fips" flag. Since the plugin would be run in an environment having OpenSSL with or without
+ * FIPS capability, we first do a dlopen with a special NULL parameter to get access to the global namespace and then
+ * do a dlsym to see if the "FIPS_mode_set" function is available. If not (or "FIPS_mode_set" returns 0), we raise an error.
+ */
+#define ENABLE_FIPS_MODE(RV, FIPS_ENABLED)										\
+{															\
+	void	*handle;												\
+	int	(*FIPS_mode_set_fnptr)(int);										\
+															\
+	handle = dlopen(NULL, (RTLD_NOW | RTLD_GLOBAL));								\
+	RV = 0;														\
+	FIPS_ENABLED = FALSE;												\
+	if (NULL == handle)												\
+	{														\
+		UPDATE_ERROR_STRING("Failed to dlopen the global namespace. Reason: %s.", dlerror());			\
+		assert(FALSE);												\
+		RV = -1;												\
+	} else														\
+	{														\
+		FIPS_mode_set_fnptr = (int(*)(int))dlsym(handle, "FIPS_mode_set");					\
+		if (NULL != FIPS_mode_set_fnptr)									\
+		{	/* Symbol available. Invoke it to enable FIPS mode. */						\
+			if (FIPS_mode_set_fnptr(1))									\
+				FIPS_ENABLED = TRUE;									\
+			else												\
+			{												\
+				GC_APPEND_OPENSSL_ERROR("Failed to initialize FIPS mode.");				\
+				RV = -1;										\
+			}												\
+		} else													\
+		{													\
+			UPDATE_ERROR_STRING("Failed to initialize FIPS mode. Reason: cannot find OpenSSL FIPS "		\
+						"functions in the runtime system.");					\
+			RV = -1;											\
+		}													\
+	}														\
+}
+
+/* OpenSSL specific error handling. */
+#define GC_APPEND_OPENSSL_ERROR(...)											\
+{															\
+	char	*errptr, *end;												\
+	int	rv;													\
+															\
+	errptr = &gtmcrypt_err_string[0];										\
+	end = errptr + MAX_GTMCRYPT_ERR_STRLEN;										\
+	SNPRINTF(errptr, MAX_GTMCRYPT_ERR_STRLEN, __VA_ARGS__);								\
+	errptr += STRLEN(errptr);											\
+	SNPRINTF(errptr, end - errptr, "%s", " Reason: ");								\
+	errptr += STRLEN(errptr);											\
+	rv = ERR_get_error();												\
+	ERR_error_string_n(rv, errptr, end - errptr);									\
+}
+
+/* Libgcrypt specific error handling. */
+#define GC_APPEND_GCRY_ERROR(ERR, ...)											\
+{															\
+	char	*errptr, *end;												\
+															\
+	errptr = &gtmcrypt_err_string[0];										\
+	end = errptr + MAX_GTMCRYPT_ERR_STRLEN;										\
+	SNPRINTF(errptr, MAX_GTMCRYPT_ERR_STRLEN, __VA_ARGS__);								\
+	errptr += STRLEN(errptr);											\
+	SNPRINTF(errptr, end - errptr, "%s", " Reason: ");								\
+	errptr += STRLEN(errptr);											\
+	SNPRINTF(errptr, end - errptr, "%s", gcry_strerror(ERR));							\
+}
+
+#ifndef USE_SYSLIB_FUNCS
+#define	MALLOC			(*gtm_malloc_fnptr)
+#define FREE			(*gtm_free_fnptr)
+#define GTM_FILENAME_TO_ID	(*gtm_filename_to_id_fnptr)
+#define GTM_IS_FILE_IDENTICAL	(*gtm_is_file_identical_fnptr)
+#define GTM_XCFILEID_FREE	(*gtm_xcfileid_free_fnptr)
+#else
+#define MALLOC			malloc
+#define FREE			free
+#endif
+
+typedef struct
+{
+	char			env_name[PASSPHRASE_ENVNAME_MAX];
+	char			*env_value;	/* Obfuscated version of the password stored in the environment (as hex) */
+	char			*passwd;	/* Password in clear text. */
+	int			passwd_len;	/* Length of the password that's allocated. */
+} passwd_entry_t;
+
+typedef void *				(*gtm_malloc_fnptr_t)(size_t);
+typedef void				(*gtm_free_fnptr_t)(void *);
+typedef gtm_status_t			(*gtm_filename_to_id_fnptr_t)(xc_string_t *, xc_fileid_ptr_t *);
+typedef gtm_status_t			(*gtm_is_file_identical_fnptr_t)(xc_fileid_ptr_t, xc_fileid_ptr_t);
+typedef void				(*gtm_xcfileid_free_fnptr_t)(xc_fileid_ptr_t);
+
+GBLREF gtm_malloc_fnptr_t		gtm_malloc_fnptr;
+GBLREF gtm_free_fnptr_t			gtm_free_fnptr;
+GBLREF gtm_filename_to_id_fnptr_t	gtm_filename_to_id_fnptr;
+GBLREF gtm_is_file_identical_fnptr_t	gtm_is_file_identical_fnptr;
+GBLREF gtm_xcfileid_free_fnptr_t	gtm_xcfileid_free_fnptr;
+
+GBLREF	char				gtmcrypt_err_string[MAX_GTMCRYPT_ERR_STRLEN];
+
+int					gc_load_gtmshr_symbols(void);
+void 					gtm_gcry_log_handler(void *opaque, int level, const char *fmt, va_list arg_ptr);
+int					gc_read_passwd(char *prompt, char *buf, int maxlen);
+int					gc_mask_unmask_passwd(int nparm, gtm_string_t *in, gtm_string_t *out);
+void					gc_freeup_pwent(passwd_entry_t *pwent);
+int 					gc_update_passwd(char *name, passwd_entry_t **ppwent, char *prompt, int interactive);
+#endif
diff --git a/sr_unix/gtmlink.c b/sr_unix/gtmlink.c
new file mode 100644
index 0000000..77ac1d8
--- /dev/null
+++ b/sr_unix/gtmlink.c
@@ -0,0 +1,64 @@
+/****************************************************************
+*								*
+*	Copyright 2013 Fidelity Information Services, Inc	*
+*								*
+*	This source code contains the intellectual property	*
+*	of its copyright holder(s), and is made available	*
+*	under a license.  If you do not know the terms of	*
+*	the license, please stop and do not read further.	*
+*								*
+****************************************************************/
+
+#include "mdef.h"
+
+#include "gtm_caseconv.h"
+#include "gtm_string.h"
+#include "gtmlink.h"
+
+LITDEF mstr relink_allowed_mstr[] = {
+	{0, LEN_AND_LIT("NORECURSIVE")},
+	{0, LEN_AND_LIT("RECURSIVE")},		/* if env var $gtm_link = "RECURSIVE", then recursive relink is enabled */
+	{0, LEN_AND_LIT("")}
+};
+
+#define MAX_KEYWORD_LEN	16
+
+void init_relink_allowed(mstr *keyword)
+{
+	mstr	trans;
+	char	buf[MAX_KEYWORD_LEN];
+	int	i;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	DEBUG_ONLY(check_max_keyword_len());
+	if (keyword->len >= MAX_KEYWORD_LEN)
+	{	/* unrecognized keyword - use default */
+		TREF(relink_allowed) = LINK_NORECURSIVE;
+		return;
+	}
+	lower_to_upper((unsigned char *)&buf[0], (unsigned char *)keyword->addr, keyword->len);
+	trans.len = keyword->len;
+	trans.addr = &buf[0];
+	for (i = 0; i < LINK_MAXTYPE; i++)
+	{
+		if (MSTR_EQ(&trans, &relink_allowed_mstr[i]))
+		{
+			TREF(relink_allowed) = i;
+			return;
+		}
+	}
+	/* unrecognized keyword - use default */
+	TREF(relink_allowed) = LINK_NORECURSIVE;
+	return;
+}
+
+#ifdef DEBUG
+void check_max_keyword_len(void)
+{
+	int	i;
+
+	for (i = 0; i < LINK_MAXTYPE; i++)
+		assert(MAX_KEYWORD_LEN > relink_allowed_mstr[i].len);
+}
+#endif
diff --git a/sr_unix/gtmlink.h b/sr_unix/gtmlink.h
new file mode 100644
index 0000000..42b8569
--- /dev/null
+++ b/sr_unix/gtmlink.h
@@ -0,0 +1,26 @@
+/****************************************************************
+*								*
+*	Copyright 2013 Fidelity Information Services, Inc	*
+*								*
+*	This source code contains the intellectual property	*
+*	of its copyright holder(s), and is made available	*
+*	under a license.  If you do not know the terms of	*
+*	the license, please stop and do not read further.	*
+*								*
+****************************************************************/
+#ifndef GTMLINK_H_INCLUDED
+#define GTMLINK_H_INCLUDED
+
+enum gtm_link_type
+{
+	LINK_NORECURSIVE = 0,
+	LINK_RECURSIVE,
+	LINK_MAXTYPE
+};
+
+void init_relink_allowed(mstr *keyword);
+#ifdef DEBUG
+void check_max_keyword_len(void);
+#endif
+
+#endif /* GTMLINK_H_INCLUDED */
diff --git a/sr_unix/gtmrecv_end.c b/sr_unix/gtmrecv_end.c
index 528b93a..f7f2bf7 100644
--- a/sr_unix/gtmrecv_end.c
+++ b/sr_unix/gtmrecv_end.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -44,6 +44,10 @@
 #include "gtmsource.h"
 #include "gtmio.h"
 #include "have_crit.h"
+#include "repl_comm.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 GBLREF	uint4			process_id;
 GBLREF	recvpool_addrs		recvpool;
@@ -163,8 +167,17 @@ int gtmrecv_end1(boolean_t auto_shutdown)
 	/* Close the connection with the Receiver */
 	if (FD_INVALID != gtmrecv_listen_sock_fd)
 		CLOSEFILE_RESET(gtmrecv_listen_sock_fd, rc);	/* resets "gtmrecv_listen_sock_fd" to FD_INVALID */
-	if (FD_INVALID != gtmrecv_sock_fd)
-		CLOSEFILE_RESET(gtmrecv_sock_fd, rc);	/* resets "gtmrecv_sock_fd" to FD_INVALID */
+	repl_close(&gtmrecv_sock_fd);
+#	ifdef GTM_TLS
+	/* Free up the SSL/TLS socket structures. */
+	if (NULL != repl_tls.sock)
+		gtm_tls_session_close(&repl_tls.sock);
+	assert(NULL == repl_tls.sock);
+	/* Free up the SSL/TLS context now that we are shutting down. */
+	if (NULL != tls_ctx)
+		gtm_tls_fini(&tls_ctx);
+	assert(NULL == tls_ctx);
+#	endif
 	repl_log(gtmrecv_log_fp, TRUE, FALSE, "REPL INFO - Current Jnlpool Seqno : %llu\n", jnlpool_seqno);
 	for (idx = 0; idx < MAX_SUPPL_STRMS; idx++)
 	{
diff --git a/sr_unix/gtmrecv_fetchresync.c b/sr_unix/gtmrecv_fetchresync.c
index e147167..7e4ebc6 100644
--- a/sr_unix/gtmrecv_fetchresync.c
+++ b/sr_unix/gtmrecv_fetchresync.c
@@ -16,8 +16,9 @@
 #include "gtm_string.h"
 #include "gtm_inet.h"
 #include "gtm_stdio.h"
+#include "gtm_select.h"
 
-#include <sys/un.h>
+#include "gtm_un.h"
 #include "gtm_time.h" /* needed for difftime() definition; if this file is not included, difftime returns bad values on AIX */
 #include <sys/time.h>
 #include <errno.h>
@@ -56,7 +57,6 @@
 #include "util.h"
 #include "gtmsource.h"
 #include "repl_instance.h"
-#include "iotcpdef.h"
 #include "gtmio.h"
 #include "replgbl.h"
 
@@ -70,10 +70,10 @@
 	{															\
 		if (EREPL_RECV == repl_errno)											\
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,					\
-					LEN_AND_LIT("Error in recv() for " MESSAGE), STATUS);					\
+					LEN_AND_LIT("Error in recv() for " MESSAGE), STATUS);	/* BYPASSOK(recv) */		\
 		else if (EREPL_SEND == repl_errno)										\
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,					\
-					LEN_AND_LIT("Error in send() for " MESSAGE), STATUS);					\
+					LEN_AND_LIT("Error in send() for " MESSAGE), STATUS);	/* BYPASSOK(send) */		\
 		else if (EREPL_SELECT == repl_errno)										\
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,					\
 					LEN_AND_LIT("Error in select() for " MESSAGE), STATUS);					\
@@ -107,7 +107,7 @@ CONDITION_HANDLER(gtmrecv_fetchresync_ch)
 {
 	int	rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if (FD_INVALID != gtmrecv_listen_sock_fd)
 		CLOSEFILE_RESET(gtmrecv_listen_sock_fd, rc);	/* resets "gtmrecv_listen_sock_fd" to FD_INVALID */
 	if (FD_INVALID != gtmrecv_sock_fd)
@@ -124,7 +124,7 @@ int gtmrecv_fetchresync(int port, seq_num *resync_seqno, seq_num max_reg_seqno)
 	unsigned char			*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int				tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
 	int				torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int				status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int				status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	fd_set				input_fds;
 	int				wait_count, save_errno;
 	char				seq_num_str[32], *seq_num_ptr;
@@ -158,6 +158,9 @@ int gtmrecv_fetchresync(int port, seq_num *resync_seqno, seq_num max_reg_seqno)
 	primary_ai.ai_addrlen = SIZEOF(primary_sas);
 	remote_side->proto_ver = REPL_PROTO_VER_UNINITIALIZED;
 	repl_log(stdout, TRUE, TRUE, "Waiting for a connection...\n");
+	assertpro(FD_SETSIZE > gtmrecv_listen_sock_fd);
+	FD_ZERO(&input_fds);
+	FD_SET(gtmrecv_listen_sock_fd, &input_fds);
 	while (TRUE)
 	{
 		t1 = time(NULL);
diff --git a/sr_unix/gtmrecv_poll_actions.c b/sr_unix/gtmrecv_poll_actions.c
index e7ae58c..28490c6 100644
--- a/sr_unix/gtmrecv_poll_actions.c
+++ b/sr_unix/gtmrecv_poll_actions.c
@@ -44,6 +44,9 @@
 #include "memcoherency.h"
 #include "replgbl.h"
 #include "gtmsource.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 GBLREF	repl_msg_ptr_t		gtmrecv_msgp;
 GBLREF	int			gtmrecv_max_repl_msglen;
@@ -102,7 +105,7 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned
 	unsigned char		*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int			tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
 	int			torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int			status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int			status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	int			temp_len, pending_msg_size;
 	int			upd_start_status, upd_start_attempts;
 	int			buffered_data_len;
@@ -129,6 +132,14 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned
 		repl_log(gtmrecv_log_fp, TRUE, TRUE, "Shutdown signalled\n");
 		gtmrecv_end(); /* Won't return */
 	}
+#	ifdef GTM_TLS
+	/* If we sent a REPL_RENEG_ACK, then we cannot afford to send anymore asynchronous messages (like XOFF_ACK_ME) until we
+	 * receive a REPL_RENEG_COMPLETE from the source server. This ensures that while the source server attempts to do a SSL/TLS
+	 * renegotiation, it doesn't have any application data (like XOFF_ACK_ME) sitting in the pipe.
+	 */
+	if (REPLTLS_WAITING_FOR_RENEG_COMPLETE == repl_tls.renegotiate_state)
+		return STOP_POLL;
+#	endif
 	/* Reset report_cnt and next_report_at to 1 when a new upd proc is forked */
 	if ((1 == report_cnt) || (report_cnt == next_report_at))
 	{
@@ -152,8 +163,8 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned
 			if (1 == report_cnt)
 			{
 				send_xoff = TRUE;
-				QWASSIGN(recvpool_ctl->old_jnl_seqno, recvpool_ctl->jnl_seqno);
-				QWASSIGNDW(recvpool_ctl->jnl_seqno, 0);
+				recvpool_ctl->old_jnl_seqno = recvpool_ctl->jnl_seqno;
+				recvpool_ctl->jnl_seqno = 0;
 				/* Even though we have identified that the update process is NOT alive, a waitpid on the update
 				 * process PID is necessary so that the system doesn't leave any zombie process lying around.
 				 * This is possible since any child process that dies without the parent doing a waitpid on it
@@ -193,8 +204,7 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned
 		 */
 		onln_rlbk_flg_set = TRUE;
 		send_xoff = TRUE;
-	}
-	else if (!send_cmp2uncmp && gtmrecv_send_cmp2uncmp)
+	} else if (!send_cmp2uncmp && gtmrecv_send_cmp2uncmp)
 	{
 		send_xoff = TRUE;
 		send_seqno = recvpool_ctl->jnl_seqno;
diff --git a/sr_unix/gtmrecv_process.c b/sr_unix/gtmrecv_process.c
index f0874cb..1fbb5c4 100644
--- a/sr_unix/gtmrecv_process.c
+++ b/sr_unix/gtmrecv_process.c
@@ -17,6 +17,7 @@
 
 #include "gtm_socket.h"
 #include "gtm_inet.h"
+#include "gtm_netdb.h"
 #include "gtm_time.h"
 #include "gtm_fcntl.h"
 #include "gtm_unistd.h"
@@ -38,6 +39,7 @@
 #include "repl_msg.h"
 #include "repl_dbg.h"
 #include "repl_errno.h"
+#include "io.h"
 #include "iosp.h"
 #include "gtm_event_log.h"
 #include "eintr_wrappers.h"
@@ -61,7 +63,6 @@
 #include "gtmmsg.h"
 #include "is_proc_alive.h"
 #include "jnl_typedef.h"
-#include "iotcpdef.h"
 #include "memcoherency.h"
 #include "have_crit.h"			/* needed for ZLIB_UNCOMPRESS */
 #include "deferred_signal_handler.h"	/* needed for ZLIB_UNCOMPRESS */
@@ -75,6 +76,9 @@
 #include "repl_inst_dump.h"		/* for "repl_dump_histinfo" prototype */
 #include "gv_trigger_common.h"
 #include "anticipatory_freeze.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 #define	GTM_ZLIB_UNCMP_ERR_STR		"error from zlib uncompress function "
 #define	GTM_ZLIB_Z_MEM_ERROR_STR	"Out-of-memory " GTM_ZLIB_UNCMP_ERR_STR
@@ -162,6 +166,9 @@ STATICFNDCL	void	gtmrecv_process_need_histinfo_msg(repl_needhistinfo_msg_ptr_t n
 STATICFNDCL	void	do_main_loop(boolean_t crash_restart);
 STATICFNDCL	void	gtmrecv_heartbeat_timer(TID tid, int4 interval_len, int *interval_ptr);
 STATICFNDCL	void	gtmrecv_main_loop(boolean_t crash_restart);
+#ifdef GTM_TLS
+STATICFNDCL	boolean_t gtmrecv_exchange_tls_info(void);
+#endif
 
 GBLREF	gtmrecv_options_t	gtmrecv_options;
 GBLREF	int			gtmrecv_listen_sock_fd;
@@ -201,6 +208,7 @@ error_def(ERR_REPLCOMM);
 error_def(ERR_REPLGBL2LONG);
 error_def(ERR_REPLINSTNOHIST);
 error_def(ERR_REPLINSTREAD);
+error_def(ERR_REPLNOTLS);
 error_def(ERR_REPLTRANS2BIG);
 error_def(ERR_REPLXENDIANFAIL);
 error_def(ERR_RESUMESTRMNUM);
@@ -210,6 +218,8 @@ error_def(ERR_SECONDAHEAD);
 error_def(ERR_STRMNUMIS);
 error_def(ERR_SUPRCVRNEEDSSUPSRC);
 error_def(ERR_TEXT);
+error_def(ERR_TLSCONVSOCK);
+error_def(ERR_TLSHANDSHAKE);
 error_def(ERR_UNIMPLOP);
 error_def(ERR_UPDSYNCINSTFILE);
 
@@ -311,6 +321,11 @@ static	boolean_t	repl_cmp_solve_timer_set;
 		return;								\
 }
 
+/* Wrapper for gtmrecv_poll_actions to handle connection reset. The arguments passed in are typically either the static variables
+ * `data_len', `buff_unprocessed' and `buffp'. But, these values are relevant only when this is being called from do_main_loop as
+ * they indicate how much of the received buffer is still to be processed and the pointer to the beginning of the unprocessed
+ * buffer. Outside do_main_loop (for instance, in gtmrecv_est_conn), gtmrecv_poll_actions is invoked with 0,0, NULL respectively.
+ */
 #define	GTMRECV_POLL_ACTIONS(data_len, buff_unprocessed, buffp)			\
 {										\
 	gtmrecv_poll_actions(data_len, buff_unprocessed, buffp);		\
@@ -579,7 +594,7 @@ STATICFNDEF void do_flow_control(uint4 write_pos)
 	unsigned char		*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int			tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
 	int			torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int			status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int			status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	int			read_pos;
 	seq_num			temp_seq_num;
 	DCL_THREADGBL_ACCESS;
@@ -688,7 +703,7 @@ STATICFNDEF int gtmrecv_est_conn(void)
 	{
 		while (TRUE)
 		{
-			if (0 < (status = fd_ioready(gtmrecv_listen_sock_fd, TRUE, REPL_POLL_WAIT)))
+			if (0 < (status = fd_ioready(gtmrecv_listen_sock_fd, REPL_POLLIN, REPL_POLL_WAIT)))
 				break;
 			if (-1 == status)
 			{
@@ -817,6 +832,13 @@ STATICFNDEF int gtmrecv_est_conn(void)
 	/* Reset prior connection related state variables (see <C9J02_003091_receiver_server_assert_due_to_lingering_XOFF>) */
 	xoff_sent = FALSE;
 	xoff_msg_log_cnt = 0;
+#	ifdef GTM_TLS
+	assert(!repl_tls.enabled);
+	/* We either did not create a TLS/SSL aware socket or the SSL object off of the TLS/SSL aware socket should be NULL since
+	 * we haven't yet connected to the source server. Assert that.
+	 */
+	assert((NULL == repl_tls.sock) || (NULL == repl_tls.sock->ssl));
+#	endif
 	/* Note that even though we are reopening a fresh connection, we should NOT reset the cached information
 	 * last_rcvd_histinfo, last_valid_histinfo etc. in this case as we might just resume processing from where
 	 * the previous connection left off in which case all the cached information is still valid. If we dont
@@ -896,7 +918,7 @@ void	gtmrecv_repl_send(repl_msg_ptr_t msgp, int4 type, int4 len, char *msgtypest
 {
 	unsigned char		*msg_ptr;				/* needed for REPL_SEND_LOOP */
 	int			tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
-	int			status;					/* needed for REPL_SEND_LOOP */
+	int			status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	FILE			*log_fp;
 	DCL_THREADGBL_ACCESS;
 
@@ -1770,7 +1792,7 @@ STATICFNDEF void process_tr_buff(int msg_type)
 							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SECNODZTRIGINTP, 1,
 									&recvpool_ctl->jnl_seqno);
 						else /* (EREPL_INTLFILTER_INCMPLREC == repl_errno) */
-							GTMASSERT;
+							assertpro(repl_errno != repl_errno);
 					}
 				} else
 				{
@@ -2580,20 +2602,86 @@ STATICFNDEF void	gtmrecv_process_need_histinfo_msg(repl_needhistinfo_msg_ptr_t n
 	return;
 }
 
+#ifdef GTM_TLS
+/* The below logic is very similar to `gtmsource_exchange_tls_info' but is kept separate because of the following reasons:
+ * (a) `gtmrecv_poll_actions' needs to be invoked as opposed to `gtmsource_poll_actions'.
+ * (b) The arguments passed to `gtmrecv_poll_actions' are defined as static.
+ * (c) The action taken after `gtmsource_poll_actions' and `gtmrecv_poll_actions' are different.
+ */
+STATICFNDEF boolean_t gtmrecv_exchange_tls_info(void)
+{
+	int			poll_dir, status;
+	char			*errp;
+	repl_tlsinfo_msg_t	reply;
+
+	reply.type = REPL_TLS_INFO;
+	reply.len = MIN_REPL_MSGLEN;
+	reply.API_version = GTM_TLS_API_VERSION;
+	reply.library_version = (uint4)tls_ctx->runtime_version;
+	if (remote_side->cross_endian)
+	{
+		reply.API_version = GTM_BYTESWAP_32(reply.API_version);
+		reply.library_version = GTM_BYTESWAP_32(reply.library_version);
+	}
+	gtmrecv_repl_send((repl_msg_ptr_t)&reply, REPL_TLS_INFO, SIZEOF(repl_tlsinfo_msg_t), "REPL_TLS_INFO", MAX_SEQNO);
+	if (repl_connection_reset || gtmrecv_wait_for_jnl_seqno)
+		return FALSE;
+	/* At this point, the both sides are ready for a TLS/SSL handshake. Create a TLS/SSL aware socket. */
+	if (NULL == (repl_tls.sock = gtm_tls_socket(tls_ctx, repl_tls.sock, gtmrecv_sock_fd, repl_tls.id, GTMTLS_OP_VERIFY_PEER)))
+	{
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSCONVSOCK, 0, ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSCONVSOCK), 0,
+				ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+	} else
+	{
+		/* Do the actual handshake. */
+		poll_dir = REPL_INVALID_POLL_DIRECTION;
+		do
+		{
+			status = repl_do_tls_handshake(gtmrecv_log_fp, gtmrecv_sock_fd, TRUE, &poll_dir);
+			assert(0 == data_len);
+			gtmrecv_poll_actions(data_len, buff_unprocessed, buffp);
+			if (repl_connection_reset || gtmrecv_wait_for_jnl_seqno)
+				return FALSE;
+		} while ((GTMTLS_WANT_READ == status) || (GTMTLS_WANT_WRITE == status));
+		if (SS_NORMAL == status)
+			return TRUE;
+		else if (REPL_CONN_RESET(status))
+		{
+			repl_log(gtmrecv_log_fp, TRUE, TRUE, "Attempt to connect() with TLS/SSL protocol failed. "
+					"Status = %d; %s\n", status, STRERROR(status));
+			repl_close(&gtmrecv_sock_fd);
+			repl_connection_reset = TRUE;
+			return FALSE;
+		}
+		errp = (-1 == status) ? (char *)gtm_tls_get_error() : STRERROR(status);
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSHANDSHAKE, 0, ERR_TEXT, 2, LEN_AND_STR(errp));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSHANDSHAKE), 0, ERR_TEXT, 2, LEN_AND_STR(errp));
+	}
+	repl_log(gtmrecv_log_fp, TRUE, TRUE, "Plaintext fallback enabled. Closing and reconnecting without TLS/SSL.\n");
+	repl_close(&gtmrecv_sock_fd);
+	repl_connection_reset = TRUE;
+	CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */
+	return FALSE;
+}
+#endif
+
 STATICFNDEF void do_main_loop(boolean_t crash_restart)
 {
 	/* The work-horse of the Receiver Server */
 	boolean_t			dont_reply_to_heartbeat = FALSE, is_repl_cmpc;
-	boolean_t			uncmpfail, send_cross_endian, preserve_buffp, recvpool_prepared;
+	boolean_t			uncmpfail, send_cross_endian, recvpool_prepared, copied_to_recvpool;
 	gtmrecv_local_ptr_t		gtmrecv_local;
 	gtm_time4_t			ack_time;
 	int4				msghdrlen, strm_num;
 	int4				need_histinfo_num;
 	int				cmpret;
 	int				msg_type, msg_len;
-	int				status;					/* needed for REPL_{SEND,RECV}_LOOP */
 	int				torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
 	int				tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
+	int				status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	recvpool_ctl_ptr_t		recvpool_ctl;
 	repl_cmpinfo_msg_ptr_t		cmptest_msg;
 	repl_cmpinfo_msg_t		cmpsolve_msg;
@@ -2610,7 +2698,7 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 	seq_num				ack_seqno, temp_ack_seqno;
 	seq_num				request_from, recvd_jnl_seqno;
 	sgmnt_addrs			*repl_csa;
-	uchar_ptr_t			old_buffp;
+	uchar_ptr_t			old_buffp, buffp_start;
 	uint4				recvd_start_flags, len;
 	uLong				cmplen;
 	uLongf				destlen;
@@ -2618,6 +2706,12 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 	unsigned char			remote_jnl_ver;
 	upd_proc_local_ptr_t		upd_proc_local;
 	repl_logfile_info_msg_t		*logfile_msgp, logfile_msg;
+#	ifdef GTM_TLS
+	repl_msg_t			renegotiate_msg;
+	boolean_t			reneg_ack_sent;
+	repl_tlsinfo_msg_t		*need_tlsinfo_msgp;
+	uint4				remote_lib_ver, remote_API_ver;
+#	endif
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -2641,9 +2735,7 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 		while (QWEQ(recvpool_ctl->jnl_seqno, seq_num_zero))
 		{
 			SHORT_SLEEP(GTMRECV_WAIT_FOR_STARTJNLSEQNO);
-			gtmrecv_poll_actions(0, 0, NULL);
-			if (repl_connection_reset)
-				return;
+			GTMRECV_POLL_ACTIONS(0, 0, NULL);
 		}
 		/* The call to "gtmrecv_poll_actions" above might have set the variable "gtmrecv_wait_for_jnl_seqno" to TRUE.
 		 * In that case, we need to reset it to FALSE here as we are now going to wait for the jnl_seqno below.
@@ -2710,6 +2802,13 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 			msgp->start_flags |= START_FLAG_COLL_M;
 		msgp->start_flags |= START_FLAG_VERSION_INFO;
 		GTMTRIG_ONLY(msgp->start_flags |= START_FLAG_TRIGGER_SUPPORT;)
+#		ifdef GTM_TLS
+		if (REPL_TLS_REQUESTED)
+		{
+			assert(NULL != tls_ctx);		/* gtm_tls_init() must have already happened. */
+			msgp->start_flags |= START_FLAG_ENABLE_TLS;
+		}
+#		endif
 		if (send_cross_endian)
 			msgp->start_flags = GTM_BYTESWAP_32(msgp->start_flags);
 		msgp->jnl_ver = this_side->jnl_ver;
@@ -2743,11 +2842,14 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 	repl_recv_lastlog_data_recvd = 0;
 	repl_recv_lastlog_data_procd = 0;
 	msghdrlen = REPL_MSG_HDRLEN;
+	GTMTLS_ONLY(DEBUG_ONLY(reneg_ack_sent = FALSE));
+	GTMTLS_ONLY(repl_tls.renegotiate_state = REPLTLS_RENEG_STATE_NONE);
 	while (TRUE)
 	{
 		recvd_len = gtmrecv_max_repl_msglen - buff_unprocessed;
+		GTMTLS_ONLY(poll_dir = REPL_INVALID_POLL_DIRECTION);
 		while ((SS_NORMAL == (status = repl_recv(gtmrecv_sock_fd,
-							(buffp + buff_unprocessed), &recvd_len, REPL_POLL_WAIT)))
+							(buffp + buff_unprocessed), &recvd_len, REPL_POLL_WAIT, &poll_dir)))
 			       && (0 == recvd_len))
 		{
 			recvd_len = gtmrecv_max_repl_msglen - buff_unprocessed;
@@ -2802,6 +2904,7 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 			repl_log(gtmrecv_log_fp, FALSE, FALSE, "Recvd : %d  Total : %d\n", recvd_len, repl_recv_data_recvd);
 		while (msghdrlen <= buff_unprocessed)
 		{
+			buffp_start = buffp;
 			if (0 == data_len)
 			{
 				assert(0 == ((unsigned long)buffp % REPL_MSG_ALIGN));
@@ -2901,7 +3004,11 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 			buffp += buffered_data_len;
 			buff_unprocessed -= buffered_data_len;
 			data_len -= buffered_data_len;
-			preserve_buffp = (0 != data_len);
+			/* Once we have sent a REPL_RENEG_ACK, the only message we should get is the REPL_RENEG_COMPLETE. */
+			assert(buffp > buff_start);
+			assert(buffp <= (buff_start + gtmrecv_max_repl_msglen));
+			assert(!reneg_ack_sent || (REPL_RENEG_COMPLETE == msg_type));
+			copied_to_recvpool = FALSE;
 			switch(msg_type)
 			{
 				case REPL_TR_JNL_RECS:
@@ -2920,6 +3027,11 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 						gtmrecv_cur_cmpmsglen += buffered_data_len;
 						assert(gtmrecv_cur_cmpmsglen <= gtmrecv_max_repl_cmpmsglen);
 					}
+					/* The partial/complete message is copied either to the receive pool or the private
+					 * compression buffer space. Set copied_to_recvpool to TRUE so that we can safely
+					 * set buffp = buff_start if this is the last message in the current received buffer.
+					 */
+					copied_to_recvpool = TRUE;
 					repl_recv_data_processed += (qw_num)buffered_data_len;
 					if (0 == data_len)
 					{
@@ -2927,7 +3039,6 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 						if (repl_connection_reset || gtmrecv_wait_for_jnl_seqno)
 							return;
 					}
-					preserve_buffp = FALSE;
 					break;
 
 				case REPL_LOSTTNCOMPLETE:
@@ -3339,8 +3450,20 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 						remote_side->null_subs_xform = FALSE;
 						/* this sets null_subs_xform regardless of remote_jnl_ver */
 					remote_side->is_supplementary = start_msg->is_supplementary;
-					remote_side->trigger_supported = (recvd_start_flags & START_FLAG_TRIGGER_SUPPORT)
-														? TRUE : FALSE;
+					remote_side->trigger_supported = (recvd_start_flags & START_FLAG_TRIGGER_SUPPORT) ? TRUE
+															  : FALSE;
+#					ifdef GTM_TLS
+					remote_side->tls_requested = (recvd_start_flags & START_FLAG_ENABLE_TLS) ? TRUE : FALSE;
+					if (REPL_TLS_REQUESTED && !remote_side->tls_requested)
+					{
+						ISSUE_REPLNOTLS(ERR_REPLNOTLS, "Receiver side", "Source side");
+						CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */
+					}
+					/* If we have not requested TLS/SSL and the originating side requested TLS/SSL, the latter
+					 * reports the REPLNOTLS error and so we need not do anything. Hence, the below assert.
+					 */
+					assert(REPL_TLS_REQUESTED || !remote_side->tls_requested);
+#					endif
 					if (this_side->jnl_ver > remote_jnl_ver)
 					{
 						assert(JNL_VER_EARLIEST_REPL <= remote_jnl_ver);
@@ -3459,6 +3582,60 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 						CHECK_REPL_SEND_LOOP_ERROR(status, "REPL_LOGFILE_INFO");
 					}
 					break;
+
+#				ifdef GTM_TLS
+				case REPL_NEED_TLS_INFO:
+					if (0 != data_len)
+						break;
+					assert(REPL_PROTO_VER_TLS_SUPPORT <= REPL_PROTO_VER_THIS);
+					assert(REPL_PROTO_VER_TLS_SUPPORT <= remote_side->proto_ver);
+					assert(REPL_TLS_REQUESTED);
+					assert(NULL != tls_ctx);
+					assert(!repl_tls.enabled);
+					need_tlsinfo_msgp = (repl_tlsinfo_msg_t *)(buffp - msg_len - REPL_MSG_HDRLEN);
+					remote_API_ver = need_tlsinfo_msgp->API_version;
+					remote_lib_ver = need_tlsinfo_msgp->library_version;
+					if (remote_side->cross_endian)
+					{
+						remote_API_ver = GTM_BYTESWAP_32(remote_API_ver);
+						remote_lib_ver = (uint4)GTM_BYTESWAP_32(remote_lib_ver);
+					}
+					repl_log(gtmrecv_log_fp, TRUE, TRUE, "Received REPL_NEED_TLS_INFO message\n");
+					repl_log(gtmrecv_log_fp, TRUE, TRUE, "  Remote side API version: 0x%08x\n", remote_API_ver);
+					repl_log(gtmrecv_log_fp, TRUE, TRUE, "  Remote side Library version: 0x%08x\n",
+														remote_lib_ver);
+					if (!gtmrecv_exchange_tls_info())
+					{
+						if (repl_connection_reset || gtmrecv_wait_for_jnl_seqno)
+							return;
+						assert(PLAINTEXT_FALLBACK);
+						assert(!repl_tls.enabled);
+					} else
+						repl_tls.enabled = TRUE; /* From here on, all communications are secured with SSL */
+					break;
+
+				case REPL_RENEG_ACK_ME:
+					if (0 != data_len)
+						break;
+					assert(!reneg_ack_sent);
+					repl_log(gtmrecv_log_fp, TRUE, TRUE, "Received REPL_RENEG_ACK_ME message\n");
+					gtmrecv_repl_send(&renegotiate_msg, REPL_RENEG_ACK, MIN_REPL_MSGLEN, "REPL_RENEG_ACK",
+								MAX_SEQNO);
+					DEBUG_ONLY(reneg_ack_sent = TRUE);
+					repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_COMPLETE;
+					break;
+
+				case REPL_RENEG_COMPLETE:
+					if (0 != data_len)
+						break;
+					assert(reneg_ack_sent);
+					repl_log(gtmrecv_log_fp, TRUE, TRUE, "Received REPL_RENEG_COMPLETE message."
+								" TLS/SSL connection successfully renegotiated.\n");
+					DEBUG_ONLY(reneg_ack_sent = FALSE);
+					repl_log_tls_info(gtmrecv_log_fp, repl_tls.sock);
+					repl_tls.renegotiate_state = REPLTLS_RENEG_STATE_NONE;
+					break;
+#				endif
 				default:
 					/* Discard the message */
 					repl_log(gtmrecv_log_fp, TRUE, TRUE, "Received UNKNOWN message (type = %d). "
@@ -3473,15 +3650,24 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 				return;
 		}
 		assert(0 == ((unsigned long)(buffp) % REPL_MSG_ALIGN));
-		if (!preserve_buffp)
-		{
-			if ((0 != buff_unprocessed) && (buff_start != buffp))
-			{
-				REPL_DPRINT4("Incmpl msg hdr, moving %d bytes from %lx to %lx\n", buff_unprocessed, (caddr_t)buffp,
-					     (caddr_t)buff_start);
+		if (buff_start != buffp)
+		{	/* We are at the tail of the current received buffer. */
+			if ((0 != data_len) && !copied_to_recvpool)
+			{	/* We have a complete header for a control message, but not the complete message. Move the message
+				 * (including the header) to the beginning of the allocated buffer space and update data_len and
+				 * buff_unprocessed.
+				 */
+				buff_unprocessed += buffered_data_len;
+				data_len += buffered_data_len;
+				if (buffp_start != buff_start)
+					memmove(buff_start, buffp_start, buff_unprocessed + REPL_MSG_HDRLEN);
+				buffp = buff_start + REPL_MSG_HDRLEN; /* + REPL_MSG_HDRLEN since we already processed the header. */
+			} else if (0 != buff_unprocessed)
+			{	/* We have an incomplete header. Move it to the beginning of the allocated buffer space. */
 				memmove(buff_start, buffp, buff_unprocessed);
-			}
-			buffp = buff_start;
+				buffp = buff_start;
+			} else
+				buffp = buff_start;
 		}
 		GTMRECV_POLL_ACTIONS(data_len, buff_unprocessed, buffp);
 	}
@@ -3489,7 +3675,7 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart)
 
 void repl_cmp_solve_rcv_timeout(void)
 {
-	GTMASSERT;
+	assertpro(FALSE);
 }
 
 STATICFNDEF void gtmrecv_heartbeat_timer(TID tid, int4 interval_len, int *interval_ptr)
@@ -3529,6 +3715,13 @@ void gtmrecv_process(boolean_t crash_restart)
 
 	if (ZLIB_CMPLVL_NONE != gtm_zlib_cmp_level)
 		gtm_zlib_init();	/* Open zlib shared library for compression/decompression */
+#	ifdef GTM_TLS
+	if (REPL_TLS_REQUESTED)
+	{
+		repl_do_tls_init(gtmrecv_log_fp);
+		assert(REPL_TLS_REQUESTED || PLAINTEXT_FALLBACK);
+	}
+#	endif
 	recvpool_ctl = recvpool.recvpool_ctl;
 	upd_proc_local = recvpool.upd_proc_local;
 	gtmrecv_local = recvpool.gtmrecv_local;
@@ -3574,6 +3767,6 @@ void gtmrecv_process(boolean_t crash_restart)
 	{
 		gtmrecv_main_loop(crash_restart);
 	} while (repl_connection_reset);
-	GTMASSERT; /* shouldn't reach here */
+	assertpro(FALSE); /* shouldn't reach here */
 	return;
 }
diff --git a/sr_unix/gtmsecshr.c b/sr_unix/gtmsecshr.c
index 415c8d7..8d37b2e 100644
--- a/sr_unix/gtmsecshr.c
+++ b/sr_unix/gtmsecshr.c
@@ -28,7 +28,6 @@
 #include <sys/sem.h>
 #include "gtm_stat.h"
 #include "gtm_socket.h"
-#include <sys/un.h>
 #include <sys/param.h>
 #include <signal.h>
 #if !defined(_AIX) && !defined(__linux__) && !defined(__hpux) && !defined(__CYGWIN__) && !defined(__MVS__)
@@ -39,12 +38,14 @@
 #include "gtm_stdlib.h"
 #include "gtm_sem.h"
 #include "gtm_string.h"
+#include "gtm_un.h"
 #include "gtm_fcntl.h"
 #include <errno.h>
 #include "gtm_time.h"
 #include "gtm_unistd.h"
 #include "gtm_stdio.h"
 #include "gtm_permissions.h"
+#include "gtm_select.h"
 
 #if defined(__MVS__)
 # include "gtm_zos_io.h"
@@ -102,6 +103,7 @@ GBLREF	key_t			gtmsecshr_key;
 GBLREF	uint4			process_id;
 GBLREF	boolean_t		need_core;
 GBLREF	boolean_t		first_syslog;		/* Defined in util_output.c */
+GBLREF	char			gtm_dist[GTM_PATH_MAX];
 
 LITREF	char			gtm_release_name[];
 LITREF	int4			gtm_release_name_len;
@@ -163,7 +165,7 @@ error_def(ERR_TEXT);
  */
 CONDITION_HANDLER(gtmsecshr_cond_hndlr)
 {
-	START_CH;
+	START_CH(TRUE);
 	gtmsecshr_exit(arg, DUMPABLE ? TRUE : FALSE);
 }
 
@@ -234,6 +236,7 @@ int main(int argc, char_ptr_t argv[])
 								 * unexpired time when select exits.
 								 */
 		input_timeval.tv_usec = 0;
+		assertpro(FD_SETSIZE > gtmsecshr_sockfd);
 		FD_ZERO(&wait_on_fd);
 		FD_SET(gtmsecshr_sockfd, &wait_on_fd);
 		gtmsecshr_timer_popped = FALSE;
@@ -304,7 +307,7 @@ void gtmsecshr_init(char_ptr_t argv[], char **rundir, int *rundir_len)
 	int		secshr_sem;
 	int		semop_res, rndirln, modlen;
 	char		*name_ptr, *rndir, *cp, realpathbef[GTM_PATH_MAX], *realpathaft, gtmdist[GTM_PATH_MAX];
-	char		*path, *chrrv, *envvarnm;
+	char		*path, *chrrv;
 	pid_t		pid;
 	struct sembuf	sop[4];
 	gtmsecshr_mesg	mesg;
@@ -386,8 +389,7 @@ void gtmsecshr_init(char_ptr_t argv[], char **rundir, int *rundir_len)
 	*rundir = realpathaft;				/* This value for $gtm_dist is used in later validations */
 	*rundir_len = rndirln;				/* .. and can be used either with this len or NULL char terminator */
 	/* Step 3 */
-	envvarnm = GTM_DIST_LOG;
-	path = GETENV(++envvarnm);			/* Retrieve value for $gtm_dist (bumping ptr past the '$' for getenv)*/
+	path = gtm_dist;
 	chrrv = realpath(path, gtmdist);
 	if ((NULL == chrrv) || (0 != strncmp(realpathaft, gtmdist, GTM_PATH_MAX)))
 	{
@@ -681,12 +683,14 @@ void service_request(gtmsecshr_mesg *buf, int msglen, char *rundir, int rundir_l
 		case WAKE_MESSAGE:
 			/* if (0 != validate_receiver(buf, rundir, rundir_len, save_code))
 				return;		/ * buf->code already set - to be re-enabled when routine is completed */
-			if (buf->code = (-1 == kill((pid_t)buf->mesg.id, SIGALRM)) ? errno : 0)
+			buf->code = 0;
+			if ((-1 == kill((pid_t)buf->mesg.id, SIGALRM)) && (ESRCH != errno))
 			{
 				save_errno = errno;
+				buf->code = save_errno;
 				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFID, 6,
-					RTS_ERROR_LITERAL("Server"), process_id, buf->pid, save_code, buf->mesg.id, ERR_TEXT, 2,
-					RTS_ERROR_LITERAL("Unable to wake up process"), save_errno);
+					     RTS_ERROR_LITERAL("Server"), process_id, buf->pid, save_code, buf->mesg.id,
+					     ERR_TEXT, 2, RTS_ERROR_LITERAL("Unable to wake up process"), save_errno);
 			}
 #			ifdef DEBUG
 			else
@@ -698,12 +702,16 @@ void service_request(gtmsecshr_mesg *buf, int msglen, char *rundir, int rundir_l
 		case CONTINUE_PROCESS:
 			/* if (0 != validate_receiver(buf, rundir, rundir_len, save_code))
 				return;		/ * buf->code already set  - to be re-enabled when routine is completed */
-			if (buf->code = (-1 == kill((pid_t)buf->mesg.id, SIGCONT)) ? errno : 0)
+			buf->code = 0;
+			if ((-1 == kill((pid_t)buf->mesg.id, SIGCONT)) && (ESRCH != errno))
 			{
 				save_errno = errno;
+				buf->code = save_errno;
 				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(13) ERR_GTMSECSHRSRVFID, 6,
-					RTS_ERROR_LITERAL("Server"), process_id, buf->pid, save_code, buf->mesg.id, ERR_TEXT, 2,
-					RTS_ERROR_LITERAL("Unable to request process to resume processing"), save_errno);
+					     RTS_ERROR_LITERAL("Server"), process_id, buf->pid, save_code, buf->mesg.id,
+					     ERR_TEXT, 2,
+					     RTS_ERROR_LITERAL("Unable to request process to resume processing"),
+					     save_errno);
 			}
 #			ifdef DEBUG
 			else
diff --git a/sr_unix/gtmsecshr.h b/sr_unix/gtmsecshr.h
index 0552175..51566e7 100644
--- a/sr_unix/gtmsecshr.h
+++ b/sr_unix/gtmsecshr.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -58,7 +58,6 @@
 #define GTMSECSHR_SOCK_PREFIX		"gtm_secshr"
 #define GTMSECSHR_DIR_SUFFIX		"/gtmsecshrdir"
 #define GTMSECSHR_EXECUTABLE		"gtmsecshr"
-#define GTMSECSHR_PATH			GTM_DIST_LOG "/" GTMSECSHR_EXECUTABLE
 
 #define	ROOTUID				0
 
diff --git a/sr_unix/gtmsecshr_sock_init.c b/sr_unix/gtmsecshr_sock_init.c
index d4da588..2f13983 100644
--- a/sr_unix/gtmsecshr_sock_init.c
+++ b/sr_unix/gtmsecshr_sock_init.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,12 +12,12 @@
 #include "mdef.h"
 
 #include <errno.h>
-#include <sys/un.h>
 
 #include "gtm_stdio.h"
 #include "gtm_string.h"
 #include "gtm_ipc.h"
 #include "gtm_stat.h"
+#include "gtm_un.h"
 #include "gtm_fcntl.h"
 #include "gtm_unistd.h"
 #include "gtm_socket.h"
@@ -44,6 +44,7 @@ GBLREF mstr 			gtmsecshr_pathname;
 GBLREF boolean_t		gtmsecshr_sock_init_done;
 GBLREF uint4			process_id;
 GBLREF int			gtmsecshr_sockfd;
+GBLREF	char			gtm_dist[GTM_PATH_MAX];
 
 static char			gtmsecshr_sockpath[GTM_PATH_MAX];
 static char			gtmsecshr_path[GTM_PATH_MAX];
@@ -63,10 +64,9 @@ error_def(ERR_TEXT);
 
 int4 gtmsecshr_pathname_init(int caller, char *execpath, int execpathln)
 {
-	int			ret_status = 0, status;
+	int			ret_status = 0, status, len;
 	char			*error_mesg;
 	mstr			secshrsock_lognam, secshrsock_transnam;
-	mstr			gtmsecshr_logname;
 	struct stat		buf;
 	int4			max_sock_path_len;
 
@@ -89,11 +89,11 @@ int4 gtmsecshr_pathname_init(int caller, char *execpath, int execpathln)
 		if (SS_LOG2LONG == status)
 		{
 			if (SERVER == caller)
-				send_msg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, secshrsock_lognam.len, secshrsock_lognam.addr,
-					 max_sock_path_len);
+				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3,
+						secshrsock_lognam.len, secshrsock_lognam.addr, max_sock_path_len);
 			else
-				gtm_putmsg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, secshrsock_lognam.len, secshrsock_lognam.addr,
-					   max_sock_path_len);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3,
+						secshrsock_lognam.len, secshrsock_lognam.addr, max_sock_path_len);
 		}
 		ret_status = INVLOGNAME;
 		strcpy(gtmsecshr_sockpath, DEFAULT_GTMSECSHR_SOCK_DIR);
@@ -107,11 +107,11 @@ int4 gtmsecshr_pathname_init(int caller, char *execpath, int execpathln)
 		else
 			error_mesg = "$gtm_tmp not a directory";
 		if (SERVER == caller)
-			send_msg(VARLSTCNT(9) MAKE_MSG_SEVERE(ERR_GTMSECSHRSOCKET), 3,
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) MAKE_MSG_SEVERE(ERR_GTMSECSHRSOCKET), 3,
 				 RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 				 ERR_TEXT, 2, RTS_ERROR_STRING(error_mesg));
 		else
-			gtm_putmsg(VARLSTCNT(9) MAKE_MSG_SEVERE(ERR_GTMSECSHRSOCKET), 3,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) MAKE_MSG_SEVERE(ERR_GTMSECSHRSOCKET), 3,
 				   RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 				   ERR_TEXT, 2, RTS_ERROR_STRING(error_mesg));
 		return INVLOGNAME;
@@ -133,21 +133,25 @@ int4 gtmsecshr_pathname_init(int caller, char *execpath, int execpathln)
 		gtmsecshr_pathname.len = execpathln + STRLEN(GTMSECSHR_EXECUTABLE);
 	} else
 	{	/* Discover path name */
-		gtmsecshr_logname.addr = GTMSECSHR_PATH;
-		gtmsecshr_logname.len = SIZEOF(GTMSECSHR_PATH) - 1;
-		if (SS_NORMAL !=
-		    (status = TRANS_LOG_NAME(&gtmsecshr_logname, &gtmsecshr_pathname, gtmsecshr_path, SIZEOF(gtmsecshr_path),
-					     dont_sendmsg_on_log2long)))
+		len = STRLEN(gtm_dist);
+		if (!len)
 		{
-			if (SS_LOG2LONG == status)
-				gtm_putmsg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, gtmsecshr_logname.len, gtmsecshr_logname.addr,
-					   SIZEOF(gtmsecshr_path) - 1);
 			gtmsecshr_pathname.len = 0;
-			gtm_putmsg(VARLSTCNT(13) ERR_GTMSECSHRSOCKET, 3,
-				   RTS_ERROR_STRING("Caller"), process_id, ERR_TEXT, 2,
-				   RTS_ERROR_LITERAL("Environment variable gtm_dist pointing to an invalid path"),
-				   ERR_TEXT, 2, RTS_ERROR_STRING(gtmsecshr_logname.addr));
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_GTMSECSHRSOCKET, 3,
+					RTS_ERROR_STRING("Caller"), process_id, ERR_TEXT, 2,
+					RTS_ERROR_LITERAL("Environment variable gtm_dist pointing to an invalid path"));
 			ret_status = INVLOGNAME;
+
+		}
+		else {
+			memcpy(gtmsecshr_path, gtm_dist, len);
+			gtmsecshr_path[len] = '/';
+			memcpy(gtmsecshr_path + len + 1, GTMSECSHR_EXECUTABLE, STRLEN(GTMSECSHR_EXECUTABLE));
+			gtmsecshr_pathname.addr = gtmsecshr_path;
+			gtmsecshr_pathname.len = len + 1 + STRLEN(GTMSECSHR_EXECUTABLE);
+			if (GTM_PATH_MAX <= gtmsecshr_pathname.len)
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TEXT, 2,
+					RTS_ERROR_LITERAL("gtmsecshr path too long"));
 		}
 		gtmsecshr_path[gtmsecshr_pathname.len] = '\0';
 	}
@@ -156,12 +160,12 @@ int4 gtmsecshr_pathname_init(int caller, char *execpath, int execpathln)
 	{
 		ret_status = FTOKERR;
 		if (SERVER == caller)
-			gtm_putmsg(VARLSTCNT(14) ERR_GTMSECSHRSOCKET, 3,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(14) ERR_GTMSECSHRSOCKET, 3,
 				   RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 				   ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr ftok :"),
 				   ERR_TEXT, 2, RTS_ERROR_STRING(gtmsecshr_path), errno);
 		else
-			send_msg(VARLSTCNT(14) ERR_GTMSECSHRSOCKET, 3,
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(14) ERR_GTMSECSHRSOCKET, 3,
 				 RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 				 ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr ftok :"),
 				 ERR_TEXT, 2, RTS_ERROR_STRING(gtmsecshr_path), errno);
@@ -205,8 +209,9 @@ int4 gtmsecshr_sock_init(int caller)
 	gtmsecshr_sockpath_len = (int)(SUN_LEN(&gtmsecshr_sock_name));
 	if (FD_INVALID == (gtmsecshr_sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)))
 	{
-		rts_error(VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3, RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"),
-			  process_id, ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr socket create"), errno);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
+				RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"),
+				process_id, ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr socket create"), errno);
 		ret_status = SOCKETERR;
 	}
 	if (SERVER == caller)
@@ -218,7 +223,7 @@ int4 gtmsecshr_sock_init(int caller)
 				if (ENOENT != errno)
 				{
 					save_errno = errno;
-					send_msg(VARLSTCNT(9) ERR_GTMSECSHRSOCKET, 3,
+					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_GTMSECSHRSOCKET, 3,
 						 RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 						 ERR_TEXT, 2, RTS_ERROR_LITERAL("Error unlinking leftover gtmsecshr socket"),
 						save_errno);
@@ -230,7 +235,7 @@ int4 gtmsecshr_sock_init(int caller)
 		{
 			if (0 > BIND(gtmsecshr_sockfd, (struct sockaddr *)&gtmsecshr_sock_name, gtmsecshr_sockpath_len))
 			{
-				rts_error(VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
 					  RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 					  ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr socket bind"),
 			  		errno);
@@ -260,7 +265,7 @@ int4 gtmsecshr_sock_init(int caller)
 				} else if (ENOENT != errno)
 				{
 					save_errno = errno;
-					send_msg(VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
+					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
 						 RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 						 ERR_TEXT, 2, RTS_ERROR_LITERAL("Error unlinking leftover gtmsecshr_cli socket"),
 						save_errno);
@@ -272,7 +277,7 @@ int4 gtmsecshr_sock_init(int caller)
 		}
                 if ( 'z' < suffix)
 		{
-			send_msg(VARLSTCNT(9) ERR_GTMSECSHRSOCKET, 3, RTS_ERROR_LITERAL("Client"), process_id,
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_GTMSECSHRSOCKET, 3, RTS_ERROR_LITERAL("Client"), process_id,
 				ERR_TEXT, 2, RTS_ERROR_LITERAL("Too many left over gtmsecshr_cli sockets"));
 			ret_status = UNLINKERR;
 		}
@@ -280,7 +285,7 @@ int4 gtmsecshr_sock_init(int caller)
 		{
 			if (0 > BIND(gtmsecshr_sockfd, (struct sockaddr *)&gtmsecshr_cli_sock_name, gtmsecshr_cli_sockpath_len))
 			{
-				rts_error(VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
 					  RTS_ERROR_STRING((SERVER == caller) ? "Server" : "Caller"), process_id,
 					  ERR_TEXT, 2, RTS_ERROR_LITERAL("Error with gtmsecshr_cli socket bind"), errno);
 				ret_status = BINDERR;
@@ -300,7 +305,7 @@ int4 gtmsecshr_sock_init(int caller)
 					|| ((lib_gid != GETGID())
 					    && (-1 == CHOWN(gtmsecshr_cli_sock_name.sun_path, -1, lib_gid)))))
 				{
-					rts_error(VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_GTMSECSHRSOCKET, 3,
 						  RTS_ERROR_STRING("Caller"), process_id, ERR_TEXT, 2,
 						  RTS_ERROR_LITERAL("Error changing socket permissions/group"), errno);
 				}
diff --git a/sr_unix/gtmsource.c b/sr_unix/gtmsource.c
index 93f3d2a..b308724 100644
--- a/sr_unix/gtmsource.c
+++ b/sr_unix/gtmsource.c
@@ -61,6 +61,9 @@
 #include "fork_init.h"
 #include "heartbeat_timer.h"
 #include "gtmio.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 GBLDEF	boolean_t		gtmsource_logstats = FALSE, gtmsource_pool2file_transition = FALSE;
 GBLDEF	int			gtmsource_filter = NO_FILTER;
@@ -176,7 +179,7 @@ int gtmsource()
 		gtmsource_exit(gtmsource_statslog() - NORMAL_SHUTDOWN);
 	}
 	assert(gtmsource_options.start);
-#ifndef REPL_DEBUG_NOBACKGROUND
+#	ifndef REPL_DEBUG_NOBACKGROUND
 	/* Set "child_server_running" to FALSE before forking off child. Wait for it to be set to TRUE by the child. */
 	gtmsource_local = jnlpool.gtmsource_local;
 	gtmsource_local->child_server_running = FALSE;
@@ -262,7 +265,7 @@ int gtmsource()
 	if (-1 == (procgp = setsid()))
 		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
 				RTS_ERROR_LITERAL("Source server error in setsid"), errno);
-#endif /* REPL_DEBUG_NOBACKGROUND */
+#	endif /* REPL_DEBUG_NOBACKGROUND */
 	if (ZLIB_CMPLVL_NONE != gtm_zlib_cmp_level)
 		gtm_zlib_init();	/* Open zlib shared library for compression/decompression */
 	REPL_DPRINT1("Setting up regions\n");
@@ -319,7 +322,7 @@ int gtmsource()
 		}
 	}
 	/* after this point we can no longer have the case where all the regions are unreplicated/non-journaled. */
-#ifndef REPL_DEBUG_NOBACKGROUND
+#	ifndef REPL_DEBUG_NOBACKGROUND
 	/* It is necessary for every process that is using the ftok semaphore to increment the counter by 1. This is used
 	 * by the last process that shuts down to delete the ftok semaphore when it notices the counter to be 0.
 	 * Note that the parent source server startup command would have done an increment of the ftok counter semaphore
@@ -336,11 +339,13 @@ int gtmsource()
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
 			RTS_ERROR_LITERAL("Counter semaphore increment failure in child source server"), save_errno);
 	}
-#else
+#	else
 	if (0 != (save_errno = rel_sem_immediate(SOURCE, JNL_POOL_ACCESS_SEM)))
+	{
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
 			RTS_ERROR_LITERAL("Error in rel_sem_immediate"), save_errno);
-#endif /* REPL_DEBUG_NOBACKGROUND */
+	}
+#	endif /* REPL_DEBUG_NOBACKGROUND */
 
 	gtmsource_srv_count++;
 	gtmsource_local->child_server_running = TRUE;	/* At this point, the parent startup command will stop waiting for child */
@@ -361,6 +366,13 @@ int gtmsource()
 		repl_log(gtmsource_log_fp, TRUE, TRUE, "Attached to existing jnlpool with shmid = [%d] and semid = [%d]\n",
 			jnlpool.repl_inst_filehdr->jnlpool_shmid, jnlpool.repl_inst_filehdr->jnlpool_semid);
 	gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "REPLINFO", print_msg);
+#	ifdef GTM_TLS
+	if (REPL_TLS_REQUESTED)
+	{
+		repl_do_tls_init(gtmsource_log_fp);
+		assert(REPL_TLS_REQUESTED || PLAINTEXT_FALLBACK);
+	}
+#	endif
 	if (jnlpool.jnlpool_ctl->freeze)
 	{
 		last_seen_freeze_flag = jnlpool.jnlpool_ctl->freeze;
diff --git a/sr_unix/gtmsource.h b/sr_unix/gtmsource.h
index 3936144..4ccf6b6 100644
--- a/sr_unix/gtmsource.h
+++ b/sr_unix/gtmsource.h
@@ -14,7 +14,6 @@
 
 /* for in_addr_t typedef on Linux */
 #include "gtm_inet.h"
-GBLREF gd_addr	*gd_header;
 #include "min_max.h"
 #include "mdef.h"
 #include "gt_timer.h"
@@ -22,6 +21,7 @@ GBLREF gd_addr	*gd_header;
 
 /* Needs mdef.h, gdsfhead.h and its dependencies */
 #define JNLPOOL_DUMMY_REG_NAME		"JNLPOOL_REG"
+#define MAX_TLSKEY_LEN			32
 #define MAX_FILTER_CMD_LEN		512
 #define MIN_JNLPOOL_SIZE		(1 * 1024 * 1024)
 #define MAX_FREEZE_COMMENT_LEN		1024
@@ -65,7 +65,7 @@ typedef enum
 {
 	GTMSOURCE_DUMMY_STATE = 0,		/* Default state when no source server is up */
 	GTMSOURCE_START,			/* Set at source server startup (in gtmsource.c) */
-	GTMSOURCE_WAITING_FOR_CONNECTION,	/* Set when waiting for receiver to connect (connection got reset etc.) */
+	GTMSOURCE_WAITING_FOR_CONNECTION,	/* Set when waiting for receiver to connect e.g. connection got reset etc. */
 	GTMSOURCE_WAITING_FOR_RESTART,		/* Set when previous state is GTMSOURCE_WAITING_FOR_CONNECTION and
 						 * connection gets established with the receiver server. */
 	GTMSOURCE_SEARCHING_FOR_RESTART,	/* Set when source server scans the jnl files and determines the resend point */
@@ -97,7 +97,7 @@ typedef enum
  * databases, this value needs to be bumped as well.
  */
 
-#define	GTMSOURCE_MAX_SHUTDOWN_WAITLOOP	(MAX(120, (gd_header->n_regions) * 90))
+#define	GTMSOURCE_MAX_SHUTDOWN_WAITLOOP(gdheader)	(MAX(120, (gdheader->n_regions) * 90))
 
 #define GTMSOURCE_SHUTDOWN_PAD_TIME		5 /* seconds */
 
@@ -350,9 +350,10 @@ typedef struct
 	int4			shutdown_time;		/* Time allowed for shutdown in seconds */
 	char			filter_cmd[MAX_FILTER_CMD_LEN];	/* command to run to invoke the external filter (if needed) */
 	global_latch_t		gtmsource_srv_latch;
-#if 0
-	int4			padding;		/* Pad structure out to multiple of 8 bytes - un-"#if 0" if needed */
-#endif
+#	ifdef GTM_TLS
+	uint4			next_renegotiate_time;	/* Time (in future) at which the next SSL/TLS renegotiation happens. */
+	int4			num_renegotiations;	/* Number of SSL/TLS renegotiations that happened so far. */
+#	endif
 } gtmsource_local_struct;
 
 #if defined(__osf__) && defined(__alpha)
@@ -470,6 +471,10 @@ typedef struct
 	char            log_file[MAX_FN_LEN + 1];
 	char		secondary_instname[MAX_INSTNAME_LEN];	/* instance name specified in -INSTSECONDARY qualifier */
 	char		freeze_comment[MAX_FREEZE_COMMENT_LEN];
+#	ifdef GTM_TLS
+	char		tlsid[MAX_TLSKEY_LEN];
+	int4		renegotiate_interval;
+#	endif
 } gtmsource_options_t;
 
 /********** Source server function prototypes **********/
@@ -528,5 +533,8 @@ int		gtmsource_stop_jnl_release_timer(void);
 void		gtmsource_onln_rlbk_clnup(void);
 int		gtmsource_showfreeze(void);
 int		gtmsource_setfreeze(void);
+#ifdef GTM_TLS
+boolean_t	gtmsource_exchange_tls_info(void);
+#endif
 
 #endif /* GTMSOURCE_H */
diff --git a/sr_unix/gtmsource_end.c b/sr_unix/gtmsource_end.c
index c7b714e..bf84438 100644
--- a/sr_unix/gtmsource_end.c
+++ b/sr_unix/gtmsource_end.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -42,6 +42,9 @@
 #include "repl_comm.h"
 #include "have_crit.h"
 #include "anticipatory_freeze.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 GBLREF	jnlpool_addrs		jnlpool;
 GBLREF	jnlpool_ctl_ptr_t	jnlpool_ctl;
@@ -101,6 +104,16 @@ int gtmsource_end1(boolean_t auto_shutdown)
 	gtmsource_free_filter_buff();
 	gtmsource_stop_heartbeat();
 	repl_close(&gtmsource_sock_fd);
+#	ifdef GTM_TLS
+	/* Free up the SSL/TLS socket structures. */
+	if (NULL != repl_tls.sock)
+		gtm_tls_session_close(&repl_tls.sock);
+	assert(NULL == repl_tls.sock);
+	/* Free up the SSL/TLS context now that we are shutting down. */
+	if (NULL != tls_ctx)
+		gtm_tls_fini(&tls_ctx);
+	assert(NULL == tls_ctx);
+#	endif
 	if (jnlpool_seqno)
 	{
 		repl_log(gtmsource_log_fp, TRUE, FALSE, "REPL INFO - Current Jnlpool Seqno : %llu\n", jnlpool_seqno);
diff --git a/sr_unix/gtmsource_get_opt.c b/sr_unix/gtmsource_get_opt.c
index 0510bc9..51478df 100644
--- a/sr_unix/gtmsource_get_opt.c
+++ b/sr_unix/gtmsource_get_opt.c
@@ -44,17 +44,20 @@
 #include "trans_log_name.h"
 #include "iosp.h"		/* for SS_NORMAL */
 #include "gtm_zlib.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#include "heartbeat_timer.h"
+#endif
 
-#define MAX_SECONDARY_LEN 	(MAX_HOST_NAME_LEN + 11) /* +11 for ':' and
-							  * port number */
-
+#define MAX_SECONDARY_LEN 		(MAX_HOST_NAME_LEN + 11) /* +11 for ':' and port number */
 #define DEFAULT_JNLPOOL_SIZE		(64 * 1024 * 1024)
-
 #define DEFAULT_SHUTDOWN_TIMEOUT	30
-
-#define GTMSOURCE_CONN_PARMS_LEN ((10 + 1) * GTMSOURCE_CONN_PARMS_COUNT - 1)
+#define GTMSOURCE_CONN_PARMS_LEN 	((10 + 1) * GTMSOURCE_CONN_PARMS_COUNT - 1)
 
 GBLREF	gtmsource_options_t	gtmsource_options;
+#ifdef GTM_TLS
+GBLREF	repl_tls_info_t		repl_tls;
+#endif
 
 error_def(ERR_GETADDRINFO);
 error_def(ERR_LOGTOOLONG);
@@ -64,7 +67,6 @@ error_def(ERR_TEXT);
 
 int gtmsource_get_opt(void)
 {
-	boolean_t	secondary, dotted_notation, log, log_interval_specified, connect_parms_badval;
 	char		*connect_parm_token_str, *connect_parm;
 	char		*connect_parms_str, tmp_connect_parms_str[GTMSOURCE_CONN_PARMS_LEN + 1];
 	char		secondary_sys[MAX_SECONDARY_LEN], *c, inst_name[MAX_FN_LEN + 1];
@@ -72,15 +74,16 @@ int gtmsource_get_opt(void)
 	char		update_val[SIZEOF("DISABLE")]; /* "ENABLE" or "DISABLE" */
 	char		freeze_val[SIZEOF("OFF")]; /* "ON" or "OFF" */
 	char		freeze_comment[SIZEOF(gtmsource_options.freeze_comment)];
-	int		tries, index = 0, timeout_status, connect_parms_index, status;
-	mstr		log_nam, trans_name;
+	int		tries, index = 0, timeout_status, connect_parms_index, status, renegotiate_interval;
 	struct hostent	*sec_hostentry;
 	unsigned short	log_file_len, filter_cmd_len;
 	unsigned short	secondary_len, inst_name_len, statslog_val_len, update_val_len, connect_parms_str_len;
-	unsigned short	freeze_val_len, freeze_comment_len;
+	unsigned short	freeze_val_len, freeze_comment_len, tlsid_len;
 	int		errcode;
 	int		port_len;
 	char		*ip_end;
+	mstr		log_nam, trans_name;
+	boolean_t	secondary, dotted_notation, log, log_interval_specified, connect_parms_badval, plaintext_fallback;
 
 	memset((char *)&gtmsource_options, 0, SIZEOF(gtmsource_options));
 	gtmsource_options.start = (CLI_PRESENT == cli_present("START"));
@@ -342,6 +345,43 @@ int gtmsource_get_opt(void)
 			gtm_zlib_cmp_level = gtmsource_options.cmplvl;
 		} else
 			gtmsource_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
+		/* Check if SSL/TLS secure communication is requested. */
+#		ifdef GTM_TLS
+		if (CLI_PRESENT == cli_present("TLSID"))
+		{
+			tlsid_len = MAX_TLSID_LEN;
+			if (!cli_get_str("TLSID", repl_tls.id, &tlsid_len))
+			{
+				util_out_print("Error parsing TLSID qualifier", TRUE);
+				return -1;
+			}
+			assert(0 < tlsid_len);
+			if (CLI_PRESENT == cli_present("RENEGOTIATE_INTERVAL"))
+			{
+				if (!cli_get_int("RENEGOTIATE_INTERVAL", &renegotiate_interval))
+				{
+					util_out_print("Error parsing RENEGOTIATE_INTERVAL qualifier", TRUE);
+					return -1;
+				}
+				if (0 > renegotiate_interval)
+				{
+					util_out_print("Negative values are not allowed for RENEGOTIATE_INTERVAL qualifier", TRUE);
+					return -1;
+				} else if ((0 < renegotiate_interval) && (renegotiate_interval < MIN_RENEGOTIATE_TIMEOUT))
+					renegotiate_interval = MIN_RENEGOTIATE_TIMEOUT;
+				renegotiate_interval = renegotiate_interval * 60;	   /* Convert to seconds. */
+			} else
+				renegotiate_interval = DEFAULT_RENEGOTIATE_TIMEOUT * 60; /* Convert to seconds. */
+			/* Convert renegotiate_interval to heartbeat units (# of 8 second intervals). */
+			renegotiate_interval = DIVIDE_ROUND_UP(renegotiate_interval, HEARTBEAT_INTERVAL_IN_SECS);
+			gtmsource_options.renegotiate_interval = renegotiate_interval;
+			/* Check if plaintext-fallback mode is specified. Default option is NOPLAINTEXTFALLBACK. */
+			if (CLI_PRESENT == (plaintext_fallback = cli_present("PLAINTEXTFALLBACK")))
+				repl_tls.plaintext_fallback = (plaintext_fallback != CLI_NEGATED);
+			else
+				repl_tls.plaintext_fallback = FALSE;
+			}
+#		endif
 	}
 	if (gtmsource_options.shut_down)
 	{
diff --git a/sr_unix/gtmsource_heartbeat.c b/sr_unix/gtmsource_heartbeat.c
index bf50cc4..bb7e43a 100644
--- a/sr_unix/gtmsource_heartbeat.c
+++ b/sr_unix/gtmsource_heartbeat.c
@@ -47,7 +47,6 @@ GBLREF	boolean_t		gtmsource_logstats;
 GBLREF	int			gtmsource_log_fd;
 GBLREF 	FILE			*gtmsource_log_fp;
 GBLREF  gtmsource_state_t       gtmsource_state;
-GBLREF	gd_addr          	*gd_header;
 
 GBLDEF	boolean_t			heartbeat_stalled = TRUE;
 GBLDEF	repl_heartbeat_que_entry_t	*repl_heartbeat_que_head = NULL;
@@ -163,7 +162,7 @@ int gtmsource_send_heartbeat(time_t *now)
 	repl_heartbeat_que_entry_t	*heartbeat_element;
 	unsigned char			*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int				tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
-	int				status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int				status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	unsigned char			seq_num_str[32], *seq_num_ptr;
 	gtmsource_local_ptr_t		gtmsource_local;
 
@@ -194,7 +193,6 @@ int gtmsource_send_heartbeat(time_t *now)
 
 		return (SS_NORMAL);
 	}
-
 	if (EREPL_SEND == repl_errno && REPL_CONN_RESET(status))
 	{
 		repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while attempting to send heartbeat. Status = %d ; %s\n",
@@ -206,12 +204,10 @@ int gtmsource_send_heartbeat(time_t *now)
 	if (EREPL_SEND == repl_errno)
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Error sending HEARTBEAT message. Error in send"), status);
-
 	if (EREPL_SELECT == repl_errno)
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Error sending HEARTBEAT message. Error in select"), status);
-
-	GTMASSERT;
+	assertpro((SS_NORMAL == status));
 	return -1; /* This will never get executed, added to make compiler happy */
 }
 
diff --git a/sr_unix/gtmsource_process.c b/sr_unix/gtmsource_process.c
index aca7f0a..81b3172 100644
--- a/sr_unix/gtmsource_process.c
+++ b/sr_unix/gtmsource_process.c
@@ -66,6 +66,11 @@
 #include "replgbl.h"
 #include "gtmsource_srv_latch.h"
 #include "gv_trigger_common.h"
+#include "wbox_test_init.h"
+#ifdef GTM_TLS
+#include "heartbeat_timer.h"
+#include "gtm_repl.h"
+#endif
 
 #define MAX_HEXDUMP_CHARS_PER_LINE	26		/* 2 characters per byte + space, 80 column assumed */
 
@@ -139,6 +144,34 @@
 }
 #endif
 
+#ifdef GTM_TLS
+#define REPLTLS_RENEGOTIATE(SOCK, STATUS)											\
+{																\
+	char	*errp;														\
+	int	save_errno;													\
+																\
+	if (0 != (STATUS = gtm_tls_renegotiate(SOCK)))										\
+	{															\
+		assert(-1 == STATUS);												\
+		save_errno = gtm_tls_errno();											\
+		if (REPL_CONN_RESET(save_errno))										\
+		{														\
+			repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while attempting to renegotiate"		\
+					" TLS/SSL connection.\n");								\
+			gtmsource_state = gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION;			\
+			repl_close(&gtmsource_sock_fd);										\
+		} else														\
+		{														\
+			errp = (-1 == save_errno) ? (char *)gtm_tls_get_error() : STRERROR(save_errno);				\
+			assert(FALSE);												\
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSRENEGOTIATE, 0, ERR_TEXT, 2, LEN_AND_STR(errp));	\
+		}														\
+	} else															\
+		gtmsource_local->num_renegotiations++;										\
+}
+#else
+#endif
+
 
 GBLDEF	repl_msg_ptr_t		gtmsource_msgp = NULL;
 GBLDEF	int			gtmsource_msgbufsiz = 0;
@@ -160,7 +193,6 @@ GBLREF	int			repl_filter_bufsiz;
 GBLREF	volatile time_t		gtmsource_now;
 GBLREF	int			gtmsource_sock_fd;
 GBLREF	jnlpool_addrs		jnlpool;
-GBLREF	gd_addr			*gd_header;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	gd_region		*gv_cur_region;
@@ -182,6 +214,7 @@ GBLREF	repl_conn_info_t	*this_side, *remote_side;
 GBLREF	int4			strm_index;
 GBLREF	uint4			process_id;
 GBLREF	seq_num			gtmsource_save_read_jnl_seqno;
+GBLREF	uint4			heartbeat_counter;
 
 error_def(ERR_JNLNEWREC);
 error_def(ERR_JNLSETDATA2LONG);
@@ -190,10 +223,12 @@ error_def(ERR_REPLFTOKSEM);
 error_def(ERR_REPLGBL2LONG);
 error_def(ERR_REPLINSTNOHIST);
 error_def(ERR_REPLNOMULTILINETRG);
+error_def(ERR_REPLNOTLS);
 error_def(ERR_REPLRECFMT);
 error_def(ERR_REPLXENDIANFAIL);
 error_def(ERR_SECNODZTRIGINTP);
 error_def(ERR_TRIG2NOTRIG);
+error_def(ERR_TLSRENEGOTIATE);
 error_def(ERR_TEXT);
 
 /* Endian converts the given set of journal records (possibly multiple sequence numbers) so that the secondary can consume them
@@ -318,7 +353,7 @@ int gtmsource_process(void)
 	unsigned char			*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int				tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
 	int				torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int				status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int				status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	int				tot_tr_len, send_tr_len, remaining_len, pre_cmpmsglen;
 	int				recvd_msg_type, recvd_start_flags;
 	uchar_ptr_t			in_buff, out_buff, out_buffmsg;
@@ -352,6 +387,11 @@ int gtmsource_process(void)
 	gtm_time4_t			tmp_time4;
 	repl_heartbeat_msg_ptr_t	heartbeat_msg;
 	sm_global_latch_ptr_t		gtmsource_srv_latch;
+#	ifdef GTM_TLS
+	repl_msg_t			renegotiate_msg;
+	uint4				next_renegotiate_hrtbt;
+	DEBUG_ONLY(boolean_t		renegotiation_pending;)
+#	endif
 	DEBUG_ONLY(uchar_ptr_t		save_inbuff;)
 	DEBUG_ONLY(uchar_ptr_t		save_outbuff;)
 	DCL_THREADGBL_ACCESS;
@@ -816,6 +856,11 @@ int gtmsource_process(void)
 					assert(0 < gd_header->n_regions);
 					grab_gtmsource_srv_latch(gtmsource_srv_latch, 2 * gd_header->n_regions * max_epoch_interval,
 									HANDLE_CONCUR_ONLINE_ROLLBACK);
+#					ifdef DEBUG
+					if (WBTEST_ENABLED(WBTEST_HOLD_GTMSOURCE_SRV_LATCH))
+						while (0 == TREF(continue_proc_cnt))
+							LONG_SLEEP(1);
+#					endif
 					if (GTMSOURCE_HANDLE_ONLN_RLBK == gtmsource_state)
 						continue;
 					srch_status = gtmsource_srch_restart(resync_seqno, recvd_start_flags);
@@ -829,6 +874,17 @@ int gtmsource_process(void)
 						assert(this_side->trigger_supported);
 						temp_ulong |= START_FLAG_TRIGGER_SUPPORT;
 					)
+#					ifdef GTM_TLS
+					if (REPL_TLS_REQUESTED)
+					{
+						if (!remote_side->tls_requested)
+						{
+							ISSUE_REPLNOTLS(ERR_REPLNOTLS, "Source side", "Receiver side");
+							CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */
+						} else
+							temp_ulong |= START_FLAG_ENABLE_TLS;
+					}
+#					endif
 					PUT_ULONG(reply_msgp->start_flags, temp_ulong);
 					recvd_start_flags = START_FLAG_NONE;
 					gtmsource_repl_send((repl_msg_ptr_t)reply_msgp, "REPL_WILL_RESTART_WITH_INFO",
@@ -971,6 +1027,33 @@ int gtmsource_process(void)
 				repl_log(gtmsource_log_fp, TRUE, FALSE, "Defaulting to NO compression\n");
 			}
 		}
+#		ifdef GTM_TLS
+		if (!repl_tls.enabled && REPL_TLS_REQUESTED && remote_side->tls_requested)
+		{	/* Now that START_FLAGS have been exchanged and both sides request TLS/SSL, do the handshake and establish
+			 * an TLS/SSL connection. Even though the TCP connection is established much earlier, we want to do the
+			 * TLS/SSL handshake at a point that is close to its purpose which is to send the journal records.
+			 */
+			assert(REPL_PROTO_VER_TLS_SUPPORT <= REPL_PROTO_VER_THIS);
+			assert(REPL_PROTO_VER_TLS_SUPPORT <= remote_side->proto_ver);
+			if (!gtmsource_exchange_tls_info())
+			{
+				switch (gtmsource_state)
+				{
+					case GTMSOURCE_CHANGING_MODE:		/* ACTIVE->PASSIVE mode change in poll actions. */
+						return SS_NORMAL;
+					case GTMSOURCE_WAITING_FOR_CONNECTION:	/* Disconnect during gtmsource_repl_{send,recv} */
+					case GTMSOURCE_WAITING_FOR_RESTART:	/* Got a REPL_XOFF_ACK_ME from receiver. Restart. */
+						continue;
+					default:
+						assert(FALSE);
+				}
+			} else
+			{
+				repl_tls.enabled = TRUE; /* From here on, all communications are secured with TLS/SSL. */
+				REPLTLS_SET_NEXT_RENEGOTIATE_HRTBT(next_renegotiate_hrtbt);
+			}
+		}
+#		endif
 		if (QWLT(gtmsource_local->read_jnl_seqno, sav_read_jnl_seqno) && (NULL != repl_ctl_list))
 		{	/* The journal files may have been positioned ahead of the read_jnl_seqno for the next read.
 			 * Indicate that they have to be repositioned into the past.
@@ -1016,7 +1099,14 @@ int gtmsource_process(void)
 			if (NO_FILTER == gtmsource_filter)
 				gtmsource_free_filter_buff();
 		}
+		/* Reset some variables to their initial value before entering the while loop (to safeguard against stale values) */
 		xon_wait_logged = FALSE;
+		heartbeat_stalled = FALSE;
+#		ifdef GTM_TLS
+		DEBUG_ONLY(renegotiation_pending = FALSE);
+		if (repl_tls.enabled && (0 < gtmsource_options.renegotiate_interval))
+			repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_TIMEOUT;
+#		endif
 		/* Flush "gtmsource_local->read_jnl_seqno" to disk right now. This will serve as a reference point for next timed
 		 * flush to occur.
 		 */
@@ -1084,7 +1174,35 @@ int gtmsource_process(void)
 			 */
 			/* Make sure we don't sleep for an extended period of time if there is something to be sent across */
 			assert((GTMSOURCE_SENDING_JNLRECS != gtmsource_state)
-					|| ((0 == poll_time) || (GTMSOURCE_IDLE_POLL_WAIT == poll_time)));
+					|| ((0 == poll_time) || (GTMSOURCE_IDLE_POLL_WAIT == poll_time))
+					GTMTLS_ONLY(DEBUG_ONLY(|| renegotiation_pending)));
+#			ifdef GTM_TLS
+			assert(repl_tls.enabled || (REPLTLS_RENEG_STATE_NONE == repl_tls.renegotiate_state));
+			if (repl_tls.enabled && (REPLTLS_WAITING_FOR_RENEG_TIMEOUT == repl_tls.renegotiate_state)
+				&& (heartbeat_counter >= next_renegotiate_hrtbt))
+			{	/* Time to renegotiate the TLS/SSL parameters. */
+				heartbeat_stalled = TRUE;	/* Defer heartbeats until renegotiation is done. */
+				DEBUG_ONLY(renegotiation_pending = TRUE);
+				/* Send REPL_RENEG_ACK_ME message to the receiver. */
+				renegotiate_msg.type = REPL_RENEG_ACK_ME;
+				renegotiate_msg.len = MIN_REPL_MSGLEN;
+				gtmsource_repl_send((repl_msg_ptr_t)&renegotiate_msg, "REPL_RENEG_ACK_ME",
+								MAX_SEQNO, INVALID_SUPPL_STRM);
+				if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
+					return SS_NORMAL;
+				if (GTMSOURCE_WAITING_FOR_CONNECTION == gtmsource_state)
+					break;
+				/* We now have to wait for REPL_RENEG_ACK from the receiver. Until then we defer sending journal
+				 * records to the other side. This way, we don't end up having outbound data in the TCP/IP pipe
+				 * during the time of renegotiation. TLS/SSL protocol doesn't handle application data when it is
+				 * in the middle of renegotiation. Similarly, the receiver on receipt of the REPL_RENEG_ACK_ME
+				 * message will defer sending any more messages to us until the renegotiation is completed.
+				 */
+				repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_ACK;
+				repl_log(gtmsource_log_fp, TRUE, TRUE, "Waiting for REPL_RENEG_ACK\n");
+				poll_time = REPL_POLL_WAIT; /* because we are waiting for a REPL_RENEG_ACK */
+			}
+#			endif
 			REPL_RECV_LOOP(gtmsource_sock_fd, gtmsource_msgp, MIN_REPL_MSGLEN, poll_time)
 			{
 				if (0 == recvd_len) /* nothing received in the first attempt, let's try again later */
@@ -1136,18 +1254,34 @@ int gtmsource_process(void)
 								return (SS_NORMAL);	/* "gtmsource_repl_send" did not complete */
 							if (GTMSOURCE_WAITING_FOR_CONNECTION == gtmsource_state)
 								break;	/* "gtmsource_repl_send" did not complete */
+							/* REPL_XOFF_ACK_ME is always followed by either a REPL_START_JNL_SEQNO,
+							 * REPL_CMP2UNCMP or REPL_BADTRANS. We don't want to be doing TLS/SSL
+							 * renegotiation in the middle of these messages as the logic on the
+							 * receiver side is complicated enough to include TLS/SSL renegotiation.
+							 * In all three cases, we go break out of this loop and redo the replication
+							 * handshake. So, set the state to skip renegotiation in the mean time.
+							 */
+#							ifdef GTM_TLS
+							if (repl_tls.enabled)
+								repl_tls.renegotiate_state = REPLTLS_SKIP_RENEGOTIATION;
+#							endif
 						}
 						break;
 					case REPL_XON:
 						gtmsource_state = gtmsource_local->gtmsource_state = GTMSOURCE_SENDING_JNLRECS;
 						poll_time = REPL_POLL_NOWAIT; /* because we received XON and data ready for send */
 						repl_log(gtmsource_log_fp, TRUE, TRUE, "REPL_XON received\n");
-						heartbeat_stalled = FALSE;
+						GTMTLS_ONLY(if (REPLTLS_WAITING_FOR_RENEG_ACK != repl_tls.renegotiate_state))
+							heartbeat_stalled = FALSE;
 						REPL_DPRINT1("Restarting HEARTBEAT\n");
 						break;
 					case REPL_BADTRANS:
 					case REPL_CMP2UNCMP:
 					case REPL_START_JNL_SEQNO:
+						/* A REPL_XOFF_ACK_ME must have been sent before. Ensure by asserting that we are
+						 * waiting for an XON.
+						 */
+						assert(GTMSOURCE_WAITING_FOR_XON == gtmsource_state);
 						QWASSIGN(recvd_seqno, *(seq_num *)&gtmsource_msgp->msg[0]);
 						if (msg_is_cross_endian)
 							recvd_seqno = GTM_BYTESWAP_64(recvd_seqno);
@@ -1196,6 +1330,36 @@ int gtmsource_process(void)
 						}
 						gtmsource_process_heartbeat((repl_heartbeat_msg_ptr_t)gtmsource_msgp);
 						break;
+#					ifdef GTM_TLS
+					case REPL_RENEG_ACK:
+						repl_log(gtmsource_log_fp, TRUE, TRUE, "REPL_RENEG_ACK received\n");
+						REPLTLS_RENEGOTIATE(repl_tls.sock, status);
+						poll_time = REPL_POLL_NOWAIT; /* because we are back to sending data */
+						if (0 != status)
+						{
+							assert(GTMSOURCE_WAITING_FOR_CONNECTION == gtmsource_state);
+							break;
+						}
+						/* Send the REPL_RENEG_COMPLETE message. */
+						renegotiate_msg.type = REPL_RENEG_COMPLETE;
+						renegotiate_msg.len = MIN_REPL_MSGLEN;
+						gtmsource_repl_send((repl_msg_ptr_t)&renegotiate_msg, "REPL_RENEG_COMPLETE",
+										MAX_SEQNO, INVALID_SUPPL_STRM);
+						if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
+							return SS_NORMAL;
+						if (GTMSOURCE_WAITING_FOR_CONNECTION == gtmsource_state)
+							break;
+						repl_log(gtmsource_log_fp, TRUE, TRUE, "Sent REPL_RENEG_COMPLETE message."
+								" TLS/SSL connection successfully renegotiated.\n");
+						assert(heartbeat_stalled);
+						if (GTMSOURCE_WAITING_FOR_XON != gtmsource_state)
+							heartbeat_stalled = FALSE;
+						/* else, heartbeat_stalled will be set back to FALSE when REPL_XON is received. */
+						DEBUG_ONLY(renegotiation_pending = FALSE);
+						REPLTLS_SET_NEXT_RENEGOTIATE_HRTBT(next_renegotiate_hrtbt);
+						repl_log_tls_info(gtmsource_log_fp, repl_tls.sock);
+						break;
+#					endif
 					default:
 						repl_log(gtmsource_log_fp, TRUE, TRUE, "Message of unknown type %d of length %d "
 							"bytes received; hex dump follows\n", gtmsource_msgp->type, recvd_len);
@@ -1210,6 +1374,13 @@ int gtmsource_process(void)
 						assert(FALSE);
 						break;
 				}
+#				ifdef GTM_TLS
+				/* On receipt of a REPL_XOFF_ACK_ME, we should no longer wait-for/attempt TLS/SSL
+				 * renegotiation.
+				 */
+				assert((REPL_XOFF_ACK_ME != gtmsource_msgp->type)
+						|| !repl_tls.enabled || (REPLTLS_SKIP_RENEGOTIATION == repl_tls.renegotiate_state));
+#				endif
 			} else if (SS_NORMAL != status)
 			{
 				if (EREPL_RECV == repl_errno)
@@ -1242,6 +1413,13 @@ int gtmsource_process(void)
 							 LEN_AND_STR(err_string));
 				}
 			}
+#			ifdef GTM_TLS
+			/* If we are waiting for a REPL_RENEG_ACK from the receiver, don't send any more messages (even journal
+			 * records) before completing the renegotiation.
+			 */
+			if (REPLTLS_WAITING_FOR_RENEG_ACK == repl_tls.renegotiate_state)
+				continue;
+#			endif
 			if (GTMSOURCE_WAITING_FOR_XON == gtmsource_state)
 			{
 				if (!xon_wait_logged)
@@ -1264,6 +1442,7 @@ int gtmsource_process(void)
 				break;
 			assert(gtmsource_state == GTMSOURCE_SENDING_JNLRECS);
 			pre_read_seqno = gtmsource_local->read_jnl_seqno;
+			GTMTLS_ONLY(assert(!renegotiation_pending));
 			grab_gtmsource_srv_latch(gtmsource_srv_latch, 2 * gd_header->n_regions * max_epoch_interval,
 							HANDLE_CONCUR_ONLINE_ROLLBACK);
 			if (GTMSOURCE_HANDLE_ONLN_RLBK == gtmsource_state)
@@ -1590,10 +1769,9 @@ int gtmsource_process(void)
 				}
 			} else /* else tot_tr_len < 0, error */
 			{
-				if (0 < data_len) /* Insufficient buffer space, increase the buffer space */
-					gtmsource_alloc_msgbuff(data_len + REPL_MSG_HDRLEN, TRUE);
-				else
-					GTMASSERT; /* Major problems */
+				assertpro(0 < data_len); /* Else major problems */
+				/* Insufficient buffer space, increase the buffer space */
+				gtmsource_alloc_msgbuff(data_len + REPL_MSG_HDRLEN, TRUE);
 			}
 		}
 	}
diff --git a/sr_unix/gtmsource_process_ops.c b/sr_unix/gtmsource_process_ops.c
index a679efa..84cb227 100644
--- a/sr_unix/gtmsource_process_ops.c
+++ b/sr_unix/gtmsource_process_ops.c
@@ -67,6 +67,9 @@
 #include "replgbl.h"
 #include "repl_inst_dump.h"		/* for "repl_dump_histinfo" prototype */
 #include "gtmdbgflags.h"
+#ifdef GTM_TLS
+#include "gtm_repl.h"
+#endif
 
 #define SEND_REPL_LOGFILE_INFO(LOGFILE, LOGFILE_MSG)							\
 {													\
@@ -107,7 +110,9 @@ GBLREF	uchar_ptr_t		repl_filter_buff;
 GBLREF	uint4			process_id;
 GBLREF	unsigned char		*gtmsource_tcombuffp;
 GBLREF	unsigned char		*gtmsource_tcombuff_start;
+#ifdef GTM_TLS
 GBLREF	gtmsource_options_t	gtmsource_options;
+#endif
 
 error_def(ERR_REPL2OLD);
 error_def(ERR_REPLCOMM);
@@ -120,54 +125,70 @@ error_def(ERR_SECNOTSUPPLEMENTARY);
 error_def(ERR_STRMNUMMISMTCH1);
 error_def(ERR_STRMNUMMISMTCH2);
 error_def(ERR_TEXT);
+error_def(ERR_TLSCONVSOCK);
+error_def(ERR_TLSHANDSHAKE);
 
 static	unsigned char		*tcombuff, *msgbuff, *cmpmsgbuff, *filterbuff;
 
 int gtmsource_est_conn()
 {
-	int			connection_attempts, alert_attempts, save_errno, status;
 	char			print_msg[1024], msg_str[1024], *errmsg;
-	gtmsource_local_ptr_t	gtmsource_local;
+	int			connection_attempts, alert_attempts, save_errno, status;
 	int			send_buffsize, recv_buffsize, tcp_s_bufsize;
 	int 			logging_period, logging_interval; /* logging period = soft_tries_period*logging_interval */
+	int			hardtries_period, hardtries_count;
 	int 			logging_attempts;
-	sockaddr_ptr		secondary_sa;
 	int			secondary_addrlen;
+	sockaddr_ptr		secondary_sa;
+	gtmsource_local_ptr_t	gtmsource_local;
 
 	gtmsource_local = jnlpool.gtmsource_local;
+#	ifdef GTM_TLS
+	assert(!repl_tls.enabled); /* Set after REPL_NEED_TLS_INFO/REPL_TLS_INFO messages are exchanged. */
+	assert(REPLTLS_RENEG_STATE_NONE == repl_tls.renegotiate_state);
+	/* We either did not create a TLS/SSL aware socket or the SSL object off of the TLS/SSL aware socket should be NULL since
+	 * we haven't yet connected to the receiver server. Assert that.
+	 */
+	assert((NULL == repl_tls.sock) || (NULL == repl_tls.sock->ssl));
+	/* Since this is a new connection, reset next renegotiation time. */
+	gtmsource_local->next_renegotiate_time = 0;	/* Set to correct value after TLS/SSL handshake is established. */
+#	endif
 	assert(remote_side == &gtmsource_local->remote_side);
 	remote_side->proto_ver = REPL_PROTO_VER_UNINITIALIZED;
 	remote_side->endianness_known = FALSE;
 	/* Connect to the secondary - use hard tries, soft tries ... */
 	connection_attempts = 0;
 	gtmsource_comm_init(); /* set up gtmsource_local.secondary_ai */
+	hardtries_period = gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD];
+	hardtries_count = gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT];
 	repl_log(gtmsource_log_fp, TRUE, TRUE, "Connect hard tries count = %d, Connect hard tries period = %d\n",
-		 gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT],
-		 gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]);
+				hardtries_count, hardtries_period);
 	do
 	{
 		secondary_sa = (sockaddr_ptr)(&gtmsource_local->secondary_inet_addr);
 		secondary_addrlen = gtmsource_local->secondary_addrlen;
-		status = gtm_connect(gtmsource_sock_fd, secondary_sa, secondary_addrlen);
+		CONNECT_SOCKET(gtmsource_sock_fd, secondary_sa, secondary_addrlen, status);
 		if (0 == status)
 			break;
-		repl_log(gtmsource_log_fp, FALSE, FALSE, "%d hard connection attempt failed : %s\n", connection_attempts + 1,
+		repl_log(gtmsource_log_fp, TRUE, TRUE, "%d hard connection attempt failed : %s\n", connection_attempts + 1,
 			 STRERROR(errno));
 		repl_close(&gtmsource_sock_fd);
-		if (REPL_MAX_CONN_HARD_TRIES_PERIOD > jnlpool.gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD])
-			SHORT_SLEEP(gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD])
+		if (REPL_MAX_CONN_HARD_TRIES_PERIOD > hardtries_period)
+		{
+			SHORT_SLEEP(hardtries_period);
+		}
 		else
-			LONG_SLEEP(gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD] % MILLISECS_IN_SEC);
+			LONG_SLEEP_MSEC(hardtries_period);
 		gtmsource_poll_actions(FALSE);
 		if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
 			return (SS_NORMAL);
 		gtmsource_comm_init();
-	} while (++connection_attempts < gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]);
+	} while (++connection_attempts < hardtries_count);
 	gtmsource_poll_actions(FALSE);
 	if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
 		return (SS_NORMAL);
 
-	if (gtmsource_local->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT] <= connection_attempts)
+	if (hardtries_count <= connection_attempts)
 	{	/*Initialize logging period related variables*/
 		logging_period = gtmsource_local->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD];
 		logging_interval = 1;
@@ -183,7 +204,7 @@ int gtmsource_est_conn()
 		{
 			secondary_sa = (sockaddr_ptr)(&gtmsource_local->secondary_inet_addr);
 			secondary_addrlen = gtmsource_local->secondary_addrlen;
-			status = gtm_connect(gtmsource_sock_fd, secondary_sa, secondary_addrlen);
+			CONNECT_SOCKET(gtmsource_sock_fd, secondary_sa, secondary_addrlen, status);
 			if (0 == status)
 				break;
 			repl_close(&gtmsource_sock_fd);
@@ -405,7 +426,7 @@ int gtmsource_recv_restart(seq_num *recvd_jnl_seqno, int *msg_type, int *start_f
 	unsigned char			*msg_ptr;				/* needed for REPL_{SEND,RECV}_LOOP */
 	int				tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
 	int				torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int				status;					/* needed for REPL_{SEND,RECV}_LOOP */
+	int				status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	uint4				remaining_len, len;
 	unsigned char			seq_num_str[32], *seq_num_ptr, *buffp;
 	repl_msg_t			xoff_ack;
@@ -444,8 +465,7 @@ int gtmsource_recv_restart(seq_num *recvd_jnl_seqno, int *msg_type, int *start_f
 			buffp = (unsigned char *)&logfile_msg;
 			/* First copy what we already received */
 			memcpy(buffp, &msg, MIN_REPL_MSGLEN);
-			assert((logfile_msg.fullpath_len > MIN_REPL_MSGLEN)
-					&& logfile_msg.fullpath_len < REPL_LOGFILE_PATH_MAX);
+			assert((logfile_msg.fullpath_len > 0) && (logfile_msg.fullpath_len < REPL_LOGFILE_PATH_MAX));
 			/* Now receive the rest of the message */
 			buffp += MIN_REPL_MSGLEN;
 			remaining_len = msg.len - MIN_REPL_MSGLEN;
@@ -581,13 +601,14 @@ int gtmsource_recv_restart(seq_num *recvd_jnl_seqno, int *msg_type, int *start_f
 			if (remote_side->jnl_ver < V19_JNL_VER)
 				*start_flags &= ~START_FLAG_TRIGGER_SUPPORT; /* zap it for pro, just in case */
 			remote_side->trigger_supported = (*start_flags & START_FLAG_TRIGGER_SUPPORT) ? TRUE : FALSE;
-#				ifdef GTM_TRIGGER
+#			ifdef GTM_TRIGGER
 			if (!remote_side->trigger_supported)
 				repl_log(gtmsource_log_fp, TRUE, TRUE, "Warning : Secondary does not support GT.M "
 					"database triggers. #t updates on primary will not be replicated\n");
-#				endif
+#			endif
 			/* remote_side->null_subs_xform is initialized later in function "gtmsource_process" */
 			(TREF(replgbl)).trig_replic_warning_issued = FALSE;
+			remote_side->tls_requested = (*start_flags & START_FLAG_ENABLE_TLS) ? TRUE : FALSE;
 			if (REPL_PROTO_VER_REMOTE_LOGPATH > remote_side->proto_ver)
 				return SS_NORMAL; /* Remote side doesn't support REPL_LOGFILE_INFO message */
 			SEND_REPL_LOGFILE_INFO(jnlpool.gtmsource_local->log_file, logfile_msg);
@@ -929,9 +950,8 @@ int gtmsource_get_jnlrecs(uchar_ptr_t buff, int *data_len, int maxbufflen, boole
 				return (0);	/* Connection got reset in call to "gtmsource_readfiles" */
 			if (0 < total_tr_len)
 				return (total_tr_len);
-			if (0 < *data_len)
-				return (-1);
-			GTMASSERT;
+			assertpro(0 < *data_len);
+			return (-1);
 	}
 	return (-1); /* This should never get executed, added to make compiler happy */
 }
@@ -947,7 +967,7 @@ void	gtmsource_repl_send(repl_msg_ptr_t msg, char *msgtypestr, seq_num optional_
 {
 	unsigned char		*msg_ptr;				/* needed for REPL_SEND_LOOP */
 	int			tosend_len, sent_len, sent_this_iter;	/* needed for REPL_SEND_LOOP */
-	int			status;					/* needed for REPL_SEND_LOOP */
+	int			status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	char			err_string[1024];
 
 	assert((REPL_MULTISITE_MSG_START > msg->type) || (REPL_PROTO_VER_MULTISITE <= remote_side->proto_ver));
@@ -1010,7 +1030,7 @@ static	boolean_t	gtmsource_repl_recv(repl_msg_ptr_t msg, int4 msglen, int4 msgty
 {
 	unsigned char		*msg_ptr;				/* needed for REPL_RECV_LOOP */
 	int			torecv_len, recvd_len, recvd_this_iter;	/* needed for REPL_RECV_LOOP */
-	int			status;					/* needed for REPL_RECV_LOOP */
+	int			status, poll_dir;			/* needed for REPL_{SEND,RECV}_LOOP */
 	repl_msg_t		xoff_ack;
 	char			err_string[1024];
 	unsigned char		*buff;
@@ -1243,10 +1263,78 @@ boolean_t	gtmsource_get_cmp_info(int4 *repl_zlib_cmp_level_ptr)
 	return TRUE;
 }
 
-void 		repl_cmp_solve_src_timeout(void)
+void 	repl_cmp_solve_src_timeout(void)
 {
-	GTMASSERT;
+	assertpro(FALSE);
+}
+
+#ifdef GTM_TLS
+boolean_t gtmsource_exchange_tls_info(void)
+{
+	int			poll_dir, status, flags;
+	char			*errp;
+	repl_tlsinfo_msg_t	reply, response;
+
+	assert(NULL != tls_ctx);
+	assert(REPL_TLS_REQUESTED);
+	assert(!repl_tls.enabled);
+	/* Send REPL_NEED_TLS_INFO message. We pass our GT.M TLS API version as part of this message. */
+	reply.type = REPL_NEED_TLS_INFO;
+	reply.len = MIN_REPL_MSGLEN;
+	reply.API_version = GTM_TLS_API_VERSION;
+	reply.library_version = (uint4)tls_ctx->runtime_version;
+	gtmsource_repl_send((repl_msg_ptr_t)&reply, "REPL_NEED_TLS_INFO", MAX_SEQNO, INVALID_SUPPL_STRM);
+	if ((GTMSOURCE_CHANGING_MODE == gtmsource_state) || (GTMSOURCE_WAITING_FOR_CONNECTION == gtmsource_state))
+		return FALSE; /* send did not succeed */
+
+	/* Receive REPL_TLS_INFO message. The GT.M TLS API version of the receiver is sent as part of the message. */
+	if (!gtmsource_repl_recv((repl_msg_ptr_t)&response, MIN_REPL_MSGLEN, REPL_TLS_INFO, "REPL_TLS_INFO"))
+		return FALSE; /* recv did not succeed */
+	repl_log(gtmsource_log_fp, TRUE, TRUE, "  Remote side API version: 0x%08x\n", response.API_version);
+	repl_log(gtmsource_log_fp, TRUE, TRUE, "  Remote side Library version: 0x%08x\n", response.library_version);
+	flags = GTMTLS_OP_VERIFY_PEER | GTMTLS_OP_CLIENT_MODE;
+	/* At this point, both sides are ready for a TLS/SSL handshake. Create a TLS/SSL aware socket. */
+	if (NULL == (repl_tls.sock = gtm_tls_socket(tls_ctx, repl_tls.sock, gtmsource_sock_fd, repl_tls.id, flags)))
+	{
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSCONVSOCK, 0, ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSCONVSOCK), 0,
+				ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
+	} else
+	{
+		/* Do the actual handshake. */
+		poll_dir = REPL_INVALID_POLL_DIRECTION;
+		do
+		{
+			status = repl_do_tls_handshake(gtmsource_log_fp, gtmsource_sock_fd, FALSE, &poll_dir);
+			gtmsource_poll_actions(FALSE);
+			if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
+				return FALSE;
+		} while ((GTMTLS_WANT_READ == status) || (GTMTLS_WANT_WRITE == status));
+		if (SS_NORMAL == status)
+			return TRUE;
+		else if (REPL_CONN_RESET(status))
+		{
+			repl_log(gtmsource_log_fp, TRUE, TRUE, "Attempt to connect() with TLS/SSL protocol failed. "
+					"Status = %d; %s\n", status, STRERROR(status));
+			repl_close(&gtmsource_sock_fd);
+			SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN);
+			gtmsource_state = jnlpool.gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION;
+			return FALSE;
+		}
+		errp = (-1 == status) ? (char *)gtm_tls_get_error() : STRERROR(status);
+		if (!PLAINTEXT_FALLBACK)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSHANDSHAKE, 0, ERR_TEXT, 2, LEN_AND_STR(errp));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_TLSHANDSHAKE), 0, ERR_TEXT, 2, LEN_AND_STR(errp));
+	}
+	repl_log(gtmsource_log_fp, TRUE, TRUE, "Plaintext fallback enabled. Closing and reconnecting without TLS/SSL.\n");
+	repl_close(&gtmsource_sock_fd);
+	SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN);
+	gtmsource_state = jnlpool.gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION;
+	CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */
+	return FALSE;
 }
+#endif
 
 /* Note: Do NOT reset input parameter "strm_jnl_seqno" unless receiver instance is supplementary and root primary */
 boolean_t	gtmsource_get_instance_info(boolean_t *secondary_was_rootprimary, seq_num *strm_jnl_seqno)
diff --git a/sr_unix/gtmsource_shutdown.c b/sr_unix/gtmsource_shutdown.c
index 822eb96..9ee4e93 100644
--- a/sr_unix/gtmsource_shutdown.c
+++ b/sr_unix/gtmsource_shutdown.c
@@ -67,7 +67,7 @@ int gtmsource_shutdown(boolean_t auto_shutdown, int exit_status)
 {
 	boolean_t		all_dead, first_time, sem_incremented, regrab_lock;
 	uint4			savepid[NUM_GTMSRC_LCL];
-	int			status, shutdown_status, save_errno;
+	int			status, shutdown_status, save_errno, max_loopcnt;
 	int4			index, maxindex, lcnt, num_src_servers_running;
 	unix_db_info		*udi;
 	gtmsource_local_ptr_t	gtmsourcelocal_ptr;
@@ -151,9 +151,9 @@ int gtmsource_shutdown(boolean_t auto_shutdown, int exit_status)
 		regrab_lock = sem_incremented = TRUE;
 		gvinit();	/* Get the gd header*/
 		/* Wait for ONE particular or ALL source servers to die */
-		repl_log(stdout, TRUE, TRUE, "Waiting for upto [%d] seconds for the source server to shutdown\n",
-			GTMSOURCE_MAX_SHUTDOWN_WAITLOOP);
-		for (lcnt = 1; GTMSOURCE_MAX_SHUTDOWN_WAITLOOP >= lcnt; lcnt++)
+		max_loopcnt = GTMSOURCE_MAX_SHUTDOWN_WAITLOOP(gd_header);
+		repl_log(stdout, TRUE, TRUE, "Waiting for upto [%d] seconds for the source server to shutdown\n", max_loopcnt);
+		for (lcnt = 1; max_loopcnt >= lcnt; lcnt++)
 		{
 			all_dead = TRUE;
 			for (index = 0; index < maxindex; index++)
@@ -172,7 +172,7 @@ int gtmsource_shutdown(boolean_t auto_shutdown, int exit_status)
 			else
 				break;
 		}
-		if (GTMSOURCE_MAX_SHUTDOWN_WAITLOOP < lcnt)
+		if (max_loopcnt < lcnt)
 		{	/* Max timeout over, take stack trace of all the source server(s) which are still running.
 			 * Display the list of pids that wont die along with the secondary instances they correspond to.
 			 * Users need to kill these pids and reissue the shutdown command for the journal pool to be cleaned up.
@@ -305,11 +305,10 @@ int gtmsource_shutdown(boolean_t auto_shutdown, int exit_status)
 		rel_sem_immediate(SOURCE, JNL_POOL_ACCESS_SEM);
 	else
 	{	/* Journal Pool and Access Control Semaphores removed. Invalidate corresponding fields in file header */
-		assert(NORMAL_SHUTDOWN == exit_status);
 		repl_inst_jnlpool_reset();
 	}
 	if (!ftok_sem_release(jnlpool.jnlpool_dummy_reg, TRUE, FALSE))
-		rts_error(VARLSTCNT(1) ERR_JNLPOOLSETUP);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JNLPOOLSETUP);
 	assert(!num_src_servers_running || (ABNORMAL_SHUTDOWN == exit_status));
 	return (((1 == maxindex) && num_src_servers_running) ? shutdown_status : exit_status);
 }
diff --git a/sr_unix/gtmxc_types.h b/sr_unix/gtmxc_types.h
index 985738d..1941697 100644
--- a/sr_unix/gtmxc_types.h
+++ b/sr_unix/gtmxc_types.h
@@ -40,7 +40,6 @@ typedef struct
 	gtm_long_t	length;
 	gtm_char_t	*address;
 }	gtm_string_t;
-typedef	int	gtmcrypt_key_t;
 #ifdef __osf__
 #pragma pointer_size (restore)
 #endif
@@ -59,27 +58,27 @@ typedef struct
 } ci_name_descriptor;
 
 /* Define deprecated types for backward compatibility. */
-typedef gtm_status_t	xc_status_t;
-typedef gtm_int_t	xc_int_t;
-typedef gtm_uint_t	xc_uint_t;
-typedef gtm_long_t	xc_long_t;
-typedef gtm_ulong_t	xc_ulong_t;
-typedef gtm_float_t	xc_float_t;
-typedef gtm_double_t	xc_double_t;
-typedef gtm_char_t	xc_char_t;
-typedef gtm_string_t	xc_string_t;
+typedef gtm_status_t		xc_status_t;
+typedef gtm_int_t		xc_int_t;
+typedef gtm_uint_t		xc_uint_t;
+typedef gtm_long_t		xc_long_t;
+typedef gtm_ulong_t		xc_ulong_t;
+typedef gtm_float_t		xc_float_t;
+typedef gtm_double_t		xc_double_t;
+typedef gtm_char_t		xc_char_t;
+typedef gtm_string_t		xc_string_t;
 typedef gtm_pointertofunc_t	xc_pointertofunc_t;
 typedef gtm_fileid_ptr_t	xc_fileid_ptr_t;
 
 /* Java types with special names for clarity. */
-typedef gtm_int_t	gtm_jboolean_t;
-typedef gtm_int_t	gtm_jint_t;
-typedef gtm_long_t	gtm_jlong_t;
-typedef gtm_float_t	gtm_jfloat_t;
-typedef gtm_double_t	gtm_jdouble_t;
-typedef gtm_char_t	gtm_jstring_t;
-typedef gtm_char_t	gtm_jbyte_array_t;
-typedef gtm_char_t	gtm_jbig_decimal_t;
+typedef gtm_int_t		gtm_jboolean_t;
+typedef gtm_int_t		gtm_jint_t;
+typedef gtm_long_t		gtm_jlong_t;
+typedef gtm_float_t		gtm_jfloat_t;
+typedef gtm_double_t		gtm_jdouble_t;
+typedef gtm_char_t		gtm_jstring_t;
+typedef gtm_char_t		gtm_jbyte_array_t;
+typedef gtm_char_t		gtm_jbig_decimal_t;
 
 /* Call-in interface. */
 gtm_status_t 	gtm_ci(const char *c_rtn_name, ...);
diff --git a/sr_unix/gv_trigger.c b/sr_unix/gv_trigger.c
index 3a4ef22..3ad8457 100644
--- a/sr_unix/gv_trigger.c
+++ b/sr_unix/gv_trigger.c
@@ -141,10 +141,10 @@ LITREF	mval	literal_zero;
 		gvtr_free(gv_target);							\
 	/* check no keysize expansion occurred inside gvcst_root_search */		\
 	assert(gv_currkey->top == save_gv_currkey->top);				\
-	memcpy(gv_currkey, save_gv_currkey, SIZEOF(gv_key) + save_gv_currkey->end);	\
+	COPY_KEY(gv_currkey, save_gv_currkey);						\
 	/* check no keysize expansion occurred inside gvcst_root_search */		\
 	assert(gv_altkey->top == save_gv_altkey->top);					\
-	memcpy(gv_altkey, save_gv_altkey, SIZEOF(gv_key) + save_gv_altkey->end);	\
+	COPY_KEY(gv_altkey, save_gv_altkey);						\
 	TREF(gv_last_subsc_null) = save_gv_last_subsc_null;				\
 	TREF(gv_some_subsc_null) = save_gv_some_subsc_null;				\
 }
@@ -292,7 +292,7 @@ CONDITION_HANDLER(gvtr_tpwrap_ch)
 {
 	int	rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 		assert(TPRESTART_STATE_NORMAL == tprestart_state);
@@ -372,7 +372,6 @@ STATICFNDEF boolean_t	gvtr_get_hasht_gblsubs(mval *subs_mval, mval *ret_mval)
 {
 	uint4		curend;
 	boolean_t	was_null = FALSE, is_null = FALSE, is_defined;
-	short int	max_key;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -380,8 +379,7 @@ STATICFNDEF boolean_t	gvtr_get_hasht_gblsubs(mval *subs_mval, mval *ret_mval)
 	curend = gv_currkey->end; /* note down gv_currkey->end before changing it so we can restore it before function returns */
 	assert(KEY_DELIMITER == gv_currkey->base[curend]);
 	assert(gv_target->gd_csa == cs_addrs);
-	max_key = gv_cur_region->max_key_size;
-	COPY_SUBS_TO_GVCURRKEY(subs_mval, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey */
+	COPY_SUBS_TO_GVCURRKEY(subs_mval, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */
 	is_defined = gvcst_get(ret_mval);
 	assert(!is_defined || (MV_STR & ret_mval->mvtype));	/* assert that gvcst_get() sets type of mval to MV_STR */
 	gv_currkey->end = curend;	/* reset gv_currkey->end to what it was at function entry */
@@ -393,7 +391,6 @@ STATICFNDEF boolean_t	gvtr_get_hasht_gblsubs_and_index(mval *subs_mval, mval *in
 {
 	uint4		curend;
 	boolean_t	was_null = FALSE, is_null = FALSE, is_defined;
-	short int	max_key;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -401,9 +398,8 @@ STATICFNDEF boolean_t	gvtr_get_hasht_gblsubs_and_index(mval *subs_mval, mval *in
 	curend = gv_currkey->end; /* note down gv_currkey->end before changing it so we can restore it before function returns */
 	assert(KEY_DELIMITER == gv_currkey->base[curend]);
 	assert(gv_target->gd_csa == cs_addrs);
-	max_key = gv_cur_region->max_key_size;
-	COPY_SUBS_TO_GVCURRKEY(subs_mval, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey */
-	COPY_SUBS_TO_GVCURRKEY(index, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey */
+	COPY_SUBS_TO_GVCURRKEY(subs_mval, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */
+	COPY_SUBS_TO_GVCURRKEY(index, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */
 	is_defined = gvcst_get(ret_mval);
 	assert(!is_defined || (MV_STR & ret_mval->mvtype));	/* assert that gvcst_get() sets type of mval to MV_STR */
 	gv_currkey->end = curend;	/* reset gv_currkey->end to what it was at function entry */
@@ -474,11 +470,10 @@ STATICFNDEF uint4	gvtr_process_range(gv_namehead *gvt, gvtr_subs_t *subsdsc, int
 		out_key = (gv_key *)keybuff;
 		out_key->end = 0;
 		out_key->top = DBKEYSIZE(MAX_KEY_SZ);
-		mval2subsc(&tmpmval, out_key);
+		mval2subsc(&tmpmval, out_key, gv_cur_region->std_null_coll);
 		gv_target = save_gvt;
-		if(len > 0)
-		{
-		/* Now that mval2subsc is done, free up the allocated dststart buffer */
+		if (0 < len)
+		{	/* Now that mval2subsc is done, free up the allocated dststart buffer */
 			ret = free_last_n_elements(gvt_trigger->gv_trig_list, nelems);
 			assert(ret);
 		}
@@ -619,17 +614,15 @@ STATICFNDEF uint4 gvtr_process_gvsubs(char *start, char *end, gvtr_subs_t *subsd
 
 void	gvtr_db_read_hasht(sgmnt_addrs *csa)
 {
-	gv_namehead		*hasht_tree, *save_gvtarget, *gvt;
-	mname_entry		gvent;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_namehead		*save_gvtarget, *gvt;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
+	gv_key			save_altkey[DBKEYALLOC(MAX_KEY_SZ)];
 	unsigned char		util_buff[MAX_TRIG_UTIL_LEN];
 	gv_key			*save_gv_currkey;
 	gv_key			*save_gv_altkey;
 	mval			tmpmval, *ret_mval;
 	boolean_t		is_defined, was_null = FALSE, is_null = FALSE, zdelim_defined, delim_defined;
 	boolean_t		save_gv_last_subsc_null, save_gv_some_subsc_null;
-	short int		max_key;
 	int4			tmpint4, util_len;
 	gvt_trigger_t		*gvt_trigger;
 	uint4			trigidx, num_gv_triggers, num_pieces, len, cmdtype, index, minpiece, maxpiece;
@@ -653,16 +646,16 @@ void	gvtr_db_read_hasht(sgmnt_addrs *csa)
 	SETUP_THREADGBL_ACCESS;
 	assert(dollar_tlevel);		/* the code below is not designed to work in non-TP */
 	save_gvtarget = gv_target;
-	SETUP_TRIGGER_GLOBAL;
+	SET_GVTARGET_TO_HASHT_GBL(csa);
 	/* Save gv_currkey and gv_altkey */
 	assert(NULL != gv_currkey);
 	assert((SIZEOF(gv_key) + gv_currkey->end) <= SIZEOF(save_currkey));
-	save_gv_currkey = (gv_key *)save_currkey;
-	memcpy(save_gv_currkey, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);
+	save_gv_currkey = &save_currkey[0];
+	MEMCPY_KEY(save_gv_currkey, gv_currkey);
 	assert(NULL != gv_altkey);
 	assert((SIZEOF(gv_key) + gv_altkey->end) <= SIZEOF(save_altkey));
-	save_gv_altkey = (gv_key *)save_altkey;
-	memcpy(save_gv_altkey, gv_altkey, SIZEOF(gv_key) + gv_altkey->end);
+	save_gv_altkey = &save_altkey[0];
+	MEMCPY_KEY(save_gv_altkey, gv_altkey);
 	save_gv_last_subsc_null = TREF(gv_last_subsc_null);
 	save_gv_some_subsc_null = TREF(gv_some_subsc_null);
 	DBGTRIGR((stderr, "gvtr_db_read_hasht: begin\n"));
@@ -713,8 +706,7 @@ void	gvtr_db_read_hasht(sgmnt_addrs *csa)
 	tmpmval.mvtype = MV_STR;
 	tmpmval.str = gvt->gvname.var_name;	/* copy gvname from gvt */
 	ret_mval = &tmpmval;
-	max_key = gv_cur_region->max_key_size;
-	COPY_SUBS_TO_GVCURRKEY(ret_mval, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey */
+	COPY_SUBS_TO_GVCURRKEY(ret_mval, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */
 	/* At this point, gv_currkey points to ^#t("GBL") */
 	/* Now check for ^#t("CIF","#LABEL") to determine what format ^#t("GBL") is stored in (if at all it exists) */
 	is_defined = gvtr_get_hasht_gblsubs((mval *)&literal_hashlabel, ret_mval);
@@ -804,7 +796,7 @@ void	gvtr_db_read_hasht(sgmnt_addrs *csa)
 	{	/* All records to be read in this loop are of the form ^#t("GBL",1,...) so add "1" as a subscript to gv_currkey */
 		i2mval(&tmpmval, trigidx);
 		assert(ret_mval == &tmpmval);
-		COPY_SUBS_TO_GVCURRKEY(ret_mval, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey */
+		COPY_SUBS_TO_GVCURRKEY(ret_mval, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */
 		/* Read in ^#t("GBL",1,"TRIGNAME")="GBL#1" */
 		is_defined =  gvtr_get_hasht_gblsubs((mval *)&literal_trigname, ret_mval);
 		if (!is_defined)
@@ -1430,10 +1422,9 @@ void	gvtr_init(gv_namehead *gvt, uint4 cycle, boolean_t tp_is_implicit, int err_
 			 * In the case of op_tcommit, we expect dollar_tlevel to be 0 and if so we break out of the loop.
 			 * In the tp_restart case, we expect a maximum of 4 tries/retries and much lesser usually.
 			 * Additionally we also want to avoid an infinite loop so limit the loop to what is considered
-			 * a huge iteration count and GTMASSERT if that is reached as it suggests an out-of-design situation.
+			 * a huge iteration count and assertpro if that is reached as it suggests an out-of-design situation.
 			 */
-			if (TPWRAP_HELPER_MAX_ATTEMPTS < loopcnt)
-				GTMASSERT;
+			assertpro(TPWRAP_HELPER_MAX_ATTEMPTS >= loopcnt);
 		}
 		/* It is possible we have restarted one or more times. If so, it is possible for csa->db_trigger_cycle
 		 * to have also been updated one or more times by t_retry() or tp_set_sgm but "cycle" would not have been
@@ -1474,7 +1465,7 @@ int	gvtr_match_n_invoke(gtm_trigger_parms *trigparms, gvtr_invoke_parms_t *gvtr_
 	char			*key_ptr, *key_start, *key_end;
 	char			*keysub_start[MAX_KEY_SZ + 1];
 	gv_key			*save_gv_currkey;
-	char			save_currkey[SIZEOF(short) + SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gv_trigger_t		*trigdsc, *trigstop, *trigstart;
 	int			gtm_trig_status, tfxb_status, num_triggers_invoked, trigmax, trig_list_offset;
 	mstr			*ztupd_mstr;
@@ -1534,9 +1525,9 @@ int	gvtr_match_n_invoke(gtm_trigger_parms *trigparms, gvtr_invoke_parms_t *gvtr_
 	 * gets opened) inside any of the "gtm_trigger" invocations. So we should maintain pointers only
 	 * to the local copy (not the global gv_currkey) for use inside all iterations of the for loop.
 	 */
-	save_gv_currkey = (gv_key *)ROUND_UP2((INTPTR_T)save_currkey, SIZEOF(gv_currkey->end));
-	assert(((char *)save_gv_currkey + SIZEOF(gv_key) + gv_currkey->end) < ARRAYTOP(save_currkey));
-	memcpy(save_gv_currkey, gv_currkey, OFFSETOF(gv_key, base[0]) + gv_currkey->end + 1); /* + 1 for second null terminator */
+	save_gv_currkey = &save_currkey[0];
+	assert(((char *)save_gv_currkey + SIZEOF(gv_key) + gv_currkey->end) < (char *)ARRAYTOP(save_currkey));
+	MEMCPY_KEY(save_gv_currkey, gv_currkey);
 	key_ptr = (char *)save_gv_currkey->base;
 	DEBUG_ONLY(key_start = key_ptr;)
 	key_end = key_ptr + save_gv_currkey->end;
@@ -1588,8 +1579,7 @@ int	gvtr_match_n_invoke(gtm_trigger_parms *trigparms, gvtr_invoke_parms_t *gvtr_
 	{
 		DBGTRIGR((stderr, "gvtr_match_n_invoke: top of trigr scan loop\n"));
 		trigstop = trigstart;		/* Stop when we get back to where we started */
-		if (0 > trigmax)
-			GTMASSERT;		/* Loop ender "just in case" */
+		assertpro(0 <= trigmax);		/* Loop ender "just in case" */
 		assert(trigdsc >= gvt_trigger->gv_trig_array);
 		assert(trigdsc < gvt_trigger->gv_trig_top);
 		assert((trigdsc->cmdmask & gvtr_cmd_mask[gvtr_cmd]) || !is_set_trigger);
diff --git a/sr_unix/gv_trigger.h b/sr_unix/gv_trigger.h
index c2cf291..74c30be 100644
--- a/sr_unix/gv_trigger.h
+++ b/sr_unix/gv_trigger.h
@@ -13,6 +13,7 @@
 #define GV_TRIGGER_H_INCLUDED
 
 #include "gv_trigger_common.h"	/* ^#t related macros (common to both Unix and VMS) */
+#include "hashtab_mname.h"	/* for COMPUTE_HASH_MNAME macro */
 
 error_def(ERR_GVIS);
 error_def(ERR_GVZTRIGFAIL);
@@ -404,18 +405,23 @@ typedef struct gvtr_invoke_parms_struct
 	}										\
 }
 
-#define SETUP_TRIGGER_GLOBAL									\
+#define SET_GVTARGET_TO_HASHT_GBL(CSA)								\
 {												\
-	hasht_tree = csa->hasht_tree;								\
+	mname_entry	gvname;									\
+	gv_namehead	*hasht_tree;								\
+												\
+	GBLREF	gv_namehead	*gv_target;							\
+												\
+	hasht_tree = CSA->hasht_tree;								\
 	if (NULL == hasht_tree)									\
 	{	/* Allocate gv_target like structure for "^#t" global in this database file */	\
-		gvent.var_name.addr = literal_hasht.str.addr;					\
-		gvent.var_name.len = literal_hasht.str.len;					\
-		gvent.marked = FALSE;								\
-		COMPUTE_HASH_MNAME(&gvent);							\
-		hasht_tree = targ_alloc(csa->hdr->max_key_size, &gvent, NULL);			\
-		hasht_tree->gd_csa = csa;							\
-		csa->hasht_tree = hasht_tree;							\
+		gvname.var_name.addr = literal_hasht.str.addr;					\
+		gvname.var_name.len = literal_hasht.str.len;					\
+		gvname.marked = FALSE;								\
+		COMPUTE_HASH_MNAME(&gvname);							\
+		hasht_tree = targ_alloc(CSA->hdr->max_key_size, &gvname, NULL);			\
+		hasht_tree->gd_csa = CSA;							\
+		CSA->hasht_tree = hasht_tree;							\
 	}											\
 	gv_target = hasht_tree;									\
 }
@@ -433,9 +439,8 @@ typedef struct gvtr_invoke_parms_struct
 	 * gv_currkey, gv_target, gv_cur_region, cs_addrs & cs_data to be set up appropriately. gv_currkey & gv_target	\
 	 * are already set up. The remaining should be set up which is asserted below.					\
 	 */														\
-	assert(&FILE_INFO(gv_cur_region)->s_addrs == csa);								\
-	assert(cs_addrs == csa);											\
-	assert(cs_data == csa->hdr);											\
+	assert(&FILE_INFO(gv_cur_region)->s_addrs == cs_addrs);								\
+	assert(cs_data == cs_addrs->hdr);										\
 	/* Do the actual search for ^#t global in the directory tree */							\
 	GVCST_ROOT_SEARCH;												\
 }
@@ -443,18 +448,17 @@ typedef struct gvtr_invoke_parms_struct
 #define	SWITCH_TO_DEFAULT_REGION			\
 {							\
 	GBLREF	uint4		dollar_tlevel;		\
+	GBLREF	gd_addr		*gd_header;		\
+	GBLREF	gv_namehead	*gv_target;		\
 							\
 	gd_region		*default_region;	\
-	gv_namehead		*hasht_tree;		\
-	mname_entry		gvent;			\
 							\
 	assert(NULL != gd_header);			\
 	default_region = gd_header->maps->reg.addr;	\
 	if (!default_region->open)			\
 		gv_init_reg(default_region);		\
 	TP_CHANGE_REG_IF_NEEDED(default_region);	\
-	csa = cs_addrs;					\
-	SETUP_TRIGGER_GLOBAL;				\
+	SET_GVTARGET_TO_HASHT_GBL(cs_addrs);		\
 	assert(NULL != gv_target);			\
 	if (dollar_tlevel)				\
 		tp_set_sgm();				\
diff --git a/sr_unix/gvcst_init_sysops.c b/sr_unix/gvcst_init_sysops.c
index 74acb82..78a5e9e 100644
--- a/sr_unix/gvcst_init_sysops.c
+++ b/sr_unix/gvcst_init_sysops.c
@@ -460,7 +460,7 @@ int db_init(gd_region *reg)
 	boolean_t		shm_setup_ok = FALSE, vermismatch = FALSE, vermismatch_already_printed = FALSE;
 	boolean_t		new_shm_ipc, do_crypt_init = FALSE, replinst_mismatch;
 	char            	machine_name[MAX_MCNAMELEN];
-	int			gethostname_res, stat_res, group_id, perm, save_udi_semid;
+	int			gethostname_res, stat_res, user_id, group_id, perm, save_udi_semid;
 	int4            	status, semval, dblksize, fbwsize, save_errno, wait_time, loopcnt, sem_pid;
 	sm_long_t       	status_l;
 	sgmnt_addrs     	*csa;
@@ -482,6 +482,8 @@ int db_init(gd_region *reg)
 	boolean_t		bypassed_ftok = FALSE, bypassed_access = FALSE;
 	int			jnl_buffer_size;
 	char			s[JNLBUFFUPDAPNDX_SIZE];	/* JNLBUFFUPDAPNDX_SIZE is defined in jnl.h */
+	char			*syscall;
+	void			*mmapaddr;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -510,7 +512,7 @@ int db_init(gd_region *reg)
 	if (-1 == stat_res)
 		RTS_ERROR(VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(reg), errno);
 	/* Setup new group and permissions if indicated by the security rules. */
-	if (gtm_set_group_and_perm(&stat_buf, &group_id, &perm, PERM_IPC, &pdd) < 0)
+	if (gtm_permissions(&stat_buf, &user_id, &group_id, &perm, PERM_IPC, &pdd) < 0)
 	{
 		SEND_MSG(VARLSTCNT(6 + PERMGENDIAG_ARG_COUNT)
 			ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("ipc resources"), RTS_ERROR_STRING(udi->fn),
@@ -598,6 +600,8 @@ int db_init(gd_region *reg)
 				if (-1 == semctl(udi->semid, FTOK_SEM_PER_ID - 1, IPC_STAT, semarg))
 					RTS_ERROR(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
 						  ERR_TEXT, 2, LEN_AND_LIT("Error with database control semctl IPC_STAT1"), errno);
+				if ((-1 != user_id) && (user_id != semstat.sem_perm.uid))
+					semstat.sem_perm.uid = user_id;
 				if ((-1 != group_id) && (group_id != semstat.sem_perm.gid))
 					semstat.sem_perm.gid = group_id;
 				semstat.sem_perm.mode = perm;
@@ -770,8 +774,7 @@ int db_init(gd_region *reg)
 		INIT_DB_ENCRYPTION_IF_NEEDED(do_crypt_init, init_status, reg, csa, tsd);
 		CSD2UDI(tsd, udi);
 		/* Make sure "mu_rndwn_file" has created semaphore for standalone access */
-		if (INVALID_SEMID == udi->semid || 0 == udi->gt_sem_ctime)
-			GTMASSERT;
+		assertpro((INVALID_SEMID != udi->semid) && (0 != udi->gt_sem_ctime));
 		/* Make sure "mu_rndwn_file" has reset shared memory. In pro, just clear it and proceed. */
 		assert((INVALID_SHMID == udi->shmid) && (0 == udi->gt_shm_ctime));
 		/* In pro, just clear it and proceed */
@@ -806,7 +809,7 @@ int db_init(gd_region *reg)
 	{	/* Bypassers are not allowed to create shared memory so we don't end up with conflicting shared memories */
 		if (bypassed_ftok || bypassed_access)
 		{
-			gtm_putmsg_csa(CSA_ARG(csa) ERR_REGOPENRETRY, 2, REG_LEN_STR(reg), DB_LEN_STR(reg));
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_REGOPENRETRY, 4, REG_LEN_STR(reg), DB_LEN_STR(reg));
 			REVERT;
 			return -1; /* Retry calling db_init. Cleanup in gvcst_init() */
 		}
@@ -839,6 +842,8 @@ int db_init(gd_region *reg)
 			RTS_ERROR(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
 				ERR_TEXT, 2, LEN_AND_LIT("Error with database control shmctl IPC_STAT1"), errno);
 		/* change group and permissions */
+		if ((-1 != user_id) && (user_id != shmstat.shm_perm.uid))
+			shmstat.shm_perm.uid = user_id;
 		if ((-1 != group_id) && (group_id != shmstat.shm_perm.gid))
 			shmstat.shm_perm.gid = group_id;
 		shmstat.shm_perm.mode = perm;
@@ -905,12 +910,22 @@ int db_init(gd_region *reg)
 		mmap_sz = stat_buf.st_size - BLK_ZERO_OFF(tsd);
 		assert(0 < mmap_sz);
 		CHECK_LARGEFILE_MMAP(reg, mmap_sz); /* can issue rts_error MMFILETOOLARGE */
-		if (-1 == (sm_long_t)(csa->db_addrs[0] = (sm_uc_ptr_t)MMAP_FD(udi->fd, mmap_sz, BLK_ZERO_OFF(tsd), read_only)))
+#		ifdef _AIX
+		mmapaddr = shmat(udi->fd, 0, (read_only ? (SHM_MAP|SHM_RDONLY) : SHM_MAP));
+#		else
+		mmapaddr = MMAP_FD(udi->fd, mmap_sz, BLK_ZERO_OFF(tsd), read_only);
+#		endif
+		if (-1 == (INTPTR_T)mmapaddr)
 		{
 			RTS_ERROR(VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(reg),
-					ERR_SYSCALL, 5, LEN_AND_LIT("mmap()"), CALLFROM, errno);
+					ERR_SYSCALL, 5, LEN_AND_STR(MEM_MAP_SYSCALL), CALLFROM, errno);
 		}
-		csa->db_addrs[1] = csa->db_addrs[0] + mmap_sz - 1;	/* '- 1' due to 0-based indexing */
+#		ifdef _AIX
+		csa->db_addrs[0] = (sm_uc_ptr_t)((sm_uc_ptr_t)mmapaddr + BLK_ZERO_OFF(tsd));
+#		else
+		csa->db_addrs[0] = mmapaddr;
+#		endif
+		csa->db_addrs[1] = (sm_uc_ptr_t)((sm_uc_ptr_t)csa->db_addrs[0] + mmap_sz - 1);	/* '- 1' due to 0-based indexing */
 		assert(csa->db_addrs[1] > csa->db_addrs[0]);
 		csd = csa->hdr = (sgmnt_data_ptr_t)((sm_uc_ptr_t)csa->lock_addrs[1] + 1);
 	}
@@ -1145,9 +1160,15 @@ int db_init(gd_region *reg)
 		}
 		/* Replication instance file or jnlpool id mismatch. Issue error. */
 		if (replinst_mismatch)
-			RTS_ERROR(VARLSTCNT(10) ERR_REPLINSTMISMTCH, 8,
-				LEN_AND_STR(jnlpool.jnlpool_ctl->jnlpool_id.instfilename), jnlpool.repl_inst_filehdr->jnlpool_shmid,
-				DB_LEN_STR(reg), LEN_AND_STR(csa->nl->replinstfilename), csa->nl->jnlpool_shmid);
+		{
+			if (INVALID_SHMID == csa->nl->jnlpool_shmid)
+				RTS_ERROR(VARLSTCNT(4) ERR_REPLINSTNOSHM, 2, DB_LEN_STR(reg));
+			else
+				RTS_ERROR(VARLSTCNT(10) ERR_REPLINSTMISMTCH, 8,
+					  LEN_AND_STR(jnlpool.jnlpool_ctl->jnlpool_id.instfilename),
+					  jnlpool.repl_inst_filehdr->jnlpool_shmid, DB_LEN_STR(reg),
+					  LEN_AND_STR(csa->nl->replinstfilename), csa->nl->jnlpool_shmid);
+		}
 	}
 	csa->root_search_cycle = csa->nl->root_search_cycle;
 	csa->onln_rlbk_cycle = csa->nl->onln_rlbk_cycle;	/* take local copy of the current Online Rollback cycle */
diff --git a/sr_unix/gvcst_spr_data.c b/sr_unix/gvcst_spr_data.c
new file mode 100644
index 0000000..5cd430c
--- /dev/null
+++ b/sr_unix/gvcst_spr_data.c
@@ -0,0 +1,143 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+#include "error.h"
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "stack_frame.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_data_ch)
+
+mint	gvcst_spr_data(void)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	mint		val, cumul_val;
+	int		reg_index;
+	gd_binding	*start_map, *end_map, *map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	trans_num	gd_targ_tn, *tn_array;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_gvdata */
+	start_map_gvt = gv_target;	/* save gv_target corresponding to start_map so we can restore at end */
+	/* Find out if the next (in terms of $order) key maps to same map as currkey. If so, no spanning activity needed */
+	GVKEY_INCREMENT_ORDER(gv_currkey);
+	end_map = gv_srch_map_linear(start_map, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+	BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_currkey->base, gv_currkey->end - 1, end_map);
+	GVKEY_UNDO_INCREMENT_ORDER(gv_currkey);
+	val = 0;
+	if (start_map == end_map)
+	{
+		assert(gv_target == start_map_gvt);
+		if (start_map_gvt->root)
+			val = gvcst_data();
+		return val;
+	}
+	/* Do any initialization that is independent of retries BEFORE the op_tstart */
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the $data.
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_data_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert(gv_cur_region == start_map->reg.addr);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = start_map;
+	cumul_val = 0;
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map <= end_map; map++)
+	{
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != start_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		if (map != start_map)
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (gv_target->root)
+		{
+			val = gvcst_data();
+			cumul_val = cumul_val | val;
+			if (cumul_val >= 10)
+				break;	/* we cannot get better than 10 or 11 so stop going through regions once we get there */
+		}
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	assert(save_dollar_tlevel == dollar_tlevel);
+	return cumul_val;
+}
diff --git a/sr_unix/gvcst_spr_kill.c b/sr_unix/gvcst_spr_kill.c
new file mode 100644
index 0000000..8cee2d5
--- /dev/null
+++ b/sr_unix/gvcst_spr_kill.c
@@ -0,0 +1,143 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+#ifdef GTM_TRIGGER
+#include <rtnhdr.h>
+#include "gv_trigger.h"		/* for IS_EXPLICIT_UPDATE_NOASSERT macro used by IS_OK_TO_INVOKE_GVCST_KILL macro */
+#endif
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "error.h"
+#include "stack_frame.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+#ifdef DEBUG
+/* See comment in op_gvkill.c for why this GBLREF is necessary. */
+GBLREF	jnl_gbls_t	jgbl;
+#endif
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_kill_ch)
+
+void	gvcst_spr_kill(void)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	int		reg_index;
+	gd_binding	*start_map, *end_map, *map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	trans_num	gd_targ_tn, *tn_array;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_gvkill */
+	start_map_gvt = gv_target;	/* save gv_target corresponding to start_map so we can restore at end */
+	/* Find out if the next (in terms of $order) key maps to same map as currkey. If so, no spanning activity needed */
+	GVKEY_INCREMENT_ORDER(gv_currkey);
+	end_map = gv_srch_map_linear(start_map, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+	BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_currkey->base, gv_currkey->end - 1, end_map);
+	GVKEY_UNDO_INCREMENT_ORDER(gv_currkey);
+	if (start_map == end_map)
+	{
+		assert(gv_target == start_map_gvt);
+		if (IS_OK_TO_INVOKE_GVCST_KILL(start_map_gvt))
+			gvcst_kill(TRUE);
+		return;
+	}
+	/* Do any initialization that is independent of retries BEFORE the op_tstart */
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the kill.
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_kill_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert(gv_cur_region == start_map->reg.addr);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = start_map;
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map <= end_map; map++)
+	{
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != start_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		if (map != start_map)
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (IS_OK_TO_INVOKE_GVCST_KILL(gv_target))
+			gvcst_kill(TRUE);
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	assert(save_dollar_tlevel == dollar_tlevel);
+	return;
+}
diff --git a/sr_unix/gvcst_spr_order.c b/sr_unix/gvcst_spr_order.c
new file mode 100644
index 0000000..8680547
--- /dev/null
+++ b/sr_unix/gvcst_spr_order.c
@@ -0,0 +1,201 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "error.h"
+#include "stack_frame.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey, *gv_altkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_order_ch)
+
+boolean_t	gvcst_spr_order(void)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	boolean_t	found, cumul_found;
+	int		reg_index;
+	gd_binding	*start_map, *first_map, *stop_map, *end_map, *map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	trans_num	gd_targ_tn, *tn_array;
+	char            cumul_key[MAX_KEY_SZ];
+	int		cumul_key_len, prev;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+	gd_binding	*prev_end_map;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	/* Ensure gv_cur_region/gv_target/cs_addrs at function return are identical to values at function entry
+	 * (this is not currently required now that op_gvname fast-path optimization has been removed in GTM-2168
+	 * but might be better to hold onto just in case that optimization is resurrected for non-spanning-globals or so)
+	 */
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_gvorder */
+	start_map_gvt = gv_target;
+	/* gv_currkey has gone through a GVKEY_INCREMENT_ORDER in op_gvorder. Recompute start_map just in case this happens
+	 * to skip a few more regions than the current value of "start_map" (which was computed at op_gvname time).
+	 */
+	map = gv_srch_map_linear(start_map, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	first_map = map;
+	if (map != start_map)
+	{	/* set global variables to point to region corresponding to "map" */
+		reg = map->reg.addr;
+		GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs to new first_map */
+	}
+	/* Find out if the next (in terms of $order) key at the PREVIOUS subscript level maps to same map as currkey.
+	 * If so, no spanning activity needed.
+	 */
+	GVKEY_INCREMENT_PREVSUBS_ORDER(gv_currkey);
+	prev = gv_currkey->prev;
+	stop_map = gv_srch_map_linear(first_map, (char *)&gv_currkey->base[0], prev);
+	BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_currkey->base, gv_currkey->prev, stop_map);
+	GVKEY_UNDO_INCREMENT_PREVSUBS_ORDER(gv_currkey);
+	found = FALSE;
+	if (first_map == stop_map)
+	{	/* At this point, gv_target could be different from start_map_gvt.
+		 * Hence cannot use latter like is used in other gvcst_spr_* modules.
+		 */
+		if (gv_target->root)
+			found = gvcst_order();
+		if (gv_target != start_map_gvt)
+		{	/* Restore gv_cur_region/gv_target etc. */
+			gv_target = start_map_gvt;
+			gv_cur_region = start_map->reg.addr;
+			change_reg();
+		}
+		return found;
+	}
+	/* Do any initialization that is independent of retries BEFORE the op_tstart */
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the $order
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_order_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert(gv_cur_region == first_map->reg.addr);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = first_map;
+	end_map = stop_map;
+	cumul_found = FALSE;
+	cumul_key_len = 0;
+	DEBUG_ONLY(cumul_key[cumul_key_len] = KEY_DELIMITER;)
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map <= end_map; map++)
+	{	/* Scan through each map in the gld and do gvcst_order calls in each map's region.
+		 * Note down the smallest key found across the scanned regions until we find a key that belongs to the
+		 * same map (in the gld) as the currently scanned "map". At which point, the region-spanning order is done.
+		 */
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != first_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		if (map != first_map)
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (gv_target->root)
+		{
+			found = gvcst_order();
+			if (found)
+			{
+				assert(!memcmp(&gv_altkey->base[0], &gv_currkey->base[0], prev));
+				cumul_found = TRUE;
+				assert(gv_altkey->end);
+				assert(gv_altkey->end > prev);
+				assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+				assert(!cumul_key_len || (KEY_DELIMITER == cumul_key[cumul_key_len - 1]));
+				if (!cumul_key_len || (0 < memcmp(&cumul_key[0], &gv_altkey->base[prev], cumul_key_len)))
+				{	/* just found alt_key is less (collation-wise) than cumul_key so update cumul_key */
+					cumul_key_len = gv_altkey->end - prev;
+					assert(cumul_key_len);
+					assert(cumul_key_len < ARRAYSIZE(cumul_key));
+					memcpy(&cumul_key[0], &gv_altkey->base[prev], cumul_key_len);
+					DEBUG_ONLY(prev_end_map = end_map;)
+					/* update end_map as well now that we got an earlier cumul_key */
+					end_map = gv_srch_map_linear(map, (char *)&gv_altkey->base[0], gv_altkey->end - 1);
+					assert(prev_end_map >= end_map);
+				}
+			}
+		}
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	assert(save_dollar_tlevel == dollar_tlevel);
+	if (cumul_found)
+	{	/* Restore accumulated minimal key into gv_altkey */
+		assert(cumul_key_len);
+		memcpy(&gv_altkey->base[0], &gv_currkey->base[0], prev);
+		memcpy(&gv_altkey->base[prev], &cumul_key[0], cumul_key_len);
+		gv_altkey->end = prev + cumul_key_len;
+		gv_altkey->base[gv_altkey->end] = KEY_DELIMITER;
+	}
+	return cumul_found;
+}
diff --git a/sr_unix/gvcst_spr_query.c b/sr_unix/gvcst_spr_query.c
new file mode 100644
index 0000000..e377fa0
--- /dev/null
+++ b/sr_unix/gvcst_spr_query.c
@@ -0,0 +1,163 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "error.h"
+#include "stack_frame.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey, *gv_altkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_query_ch)
+
+boolean_t	gvcst_spr_query(void)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	boolean_t	found, cumul_found;
+	int		reg_index;
+	gd_binding	*start_map, *end_map, *map, *prev_end_map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	trans_num	gd_targ_tn, *tn_array;
+	char            cumul_key[MAX_KEY_SZ];
+	int		cumul_key_len, prev;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_gvquery */
+	start_map_gvt = gv_target;	/* save gv_target corresponding to start_map so we can restore at end */
+	/* Do any initialization that is independent of retries BEFORE the op_tstart */
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the $query
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_query_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert(gv_cur_region == start_map->reg.addr);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = start_map;
+	cumul_found = FALSE;
+	cumul_key_len = 0;
+	DEBUG_ONLY(cumul_key[cumul_key_len] = KEY_DELIMITER;)
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	assert(0 < gvnh_reg->gvspan->end_map_index);
+	assert(gvnh_reg->gvspan->end_map_index < addr->n_maps);
+	end_map = &addr->maps[gvnh_reg->gvspan->end_map_index];
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map <= end_map; map++)
+	{	/* Scan through each map in the gld and do gvcst_query calls in each map's region.
+		 * Note down the smallest key found across the scanned regions until we find a key that belongs to the
+		 * same map (in the gld) as the currently scanned "map". At which point, the region-spanning query is done.
+		 */
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != start_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		if (map != start_map)
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (gv_target->root)
+		{
+			found = gvcst_query();
+			if (found)
+			{
+				cumul_found = TRUE;
+				assert(gv_altkey->end);
+				assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+				assert(!cumul_key_len || (KEY_DELIMITER == cumul_key[cumul_key_len - 1]));
+				if (!cumul_key_len || (0 < memcmp(&cumul_key[0], &gv_altkey->base[0], cumul_key_len)))
+				{	/* just found alt_key is less (collation-wise) than cumul_key so update cumul_key */
+					cumul_key_len = gv_altkey->end + 1;
+					assert(cumul_key_len);
+					assert(cumul_key_len < ARRAYSIZE(cumul_key));
+					memcpy(&cumul_key[0], &gv_altkey->base[0], cumul_key_len);
+					DEBUG_ONLY(prev_end_map = end_map;)
+					/* update end_map as well now that we got an earlier cumul_key */
+					end_map = gv_srch_map_linear(map, (char *)&gv_altkey->base[0], gv_altkey->end - 1);
+					BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_altkey->base, gv_altkey->end - 1, end_map);
+					assert(prev_end_map >= end_map);
+				}
+			}
+		}
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	assert(save_dollar_tlevel == dollar_tlevel);
+	if (cumul_found)
+	{	/* Restore accumulated minimal key into gv_altkey */
+		assert(cumul_key_len);
+		memcpy(&gv_altkey->base[0], &cumul_key[0], cumul_key_len);
+		gv_altkey->end = cumul_key_len - 1;
+		assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+	}
+	return cumul_found;
+}
diff --git a/sr_unix/gvcst_spr_queryget.c b/sr_unix/gvcst_spr_queryget.c
new file mode 100644
index 0000000..38d58d3
--- /dev/null
+++ b/sr_unix/gvcst_spr_queryget.c
@@ -0,0 +1,171 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+#include "mv_stent.h"
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey, *gv_altkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_queryget_ch)
+
+boolean_t	gvcst_spr_queryget(mval *cumul_val)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	int		reg_index;
+	gd_binding	*start_map, *end_map, *map, *prev_end_map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	boolean_t	found, cumul_found;
+	mval		*val;
+	trans_num	gd_targ_tn, *tn_array;
+	char            cumul_key[MAX_KEY_SZ];
+	int		cumul_key_len, prev;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_gvqueryget */
+	start_map_gvt = gv_target;	/* save gv_target corresponding to start_map so we can restore at end */
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the $queryget
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	PUSH_MV_STENT(MVST_MVAL);	/* Need to protect value returned by gvcst_queryget from stpgcol */
+	/* "val" protection might not be necessary specifically for the non-spanning-node gvcst_queryget version.
+	 * And most likely not needed for the spanning-node gvcst_queryget version. But it is not easy to be sure and
+	 * besides it does not hurt that much since only a M-stack entry gets pushed. So we err on the side of caution.
+	 */
+	val = &mv_chain->mv_st_cont.mvs_mval;
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_queryget_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert(gv_cur_region == start_map->reg.addr);
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = start_map;
+	cumul_found = FALSE;
+	cumul_key_len = 0;
+	DEBUG_ONLY(cumul_key[cumul_key_len] = KEY_DELIMITER;)
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	val->mvtype = 0; /* initialize mval in M-stack in case stp_gcol gets called before mkey gets initialized below */
+	assert(0 < gvnh_reg->gvspan->end_map_index);
+	assert(gvnh_reg->gvspan->end_map_index < addr->n_maps);
+	end_map = &addr->maps[gvnh_reg->gvspan->end_map_index];
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map <= end_map; map++)
+	{	/* Scan through each map in the gld and do gvcst_queryget calls in each map's region.
+		 * Note down the smallest key found across the scanned regions until we find a key that belongs to the
+		 * same map (in the gld) as the currently scanned "map". At which point, the region-spanning queryget is done.
+		 */
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != start_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		if (map != start_map)
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (gv_target->root)
+		{
+			found = gvcst_queryget(val);
+			if (found)
+			{
+				cumul_found = TRUE;
+				assert(gv_altkey->end);
+				assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+				assert(!cumul_key_len || (KEY_DELIMITER == cumul_key[cumul_key_len - 1]));
+				if (!cumul_key_len || (0 < memcmp(&cumul_key[0], &gv_altkey->base[0], cumul_key_len)))
+				{	/* just found alt_key is less (collation-wise) than cumul_key so update cumul_key */
+					cumul_key_len = gv_altkey->end + 1;
+					assert(cumul_key_len);
+					assert(cumul_key_len < ARRAYSIZE(cumul_key));
+					memcpy(&cumul_key[0], &gv_altkey->base[0], cumul_key_len);
+					DEBUG_ONLY(prev_end_map = end_map;)
+					/* update end_map as well now that we got an earlier cumul_key */
+					end_map = gv_srch_map_linear(map, (char *)&gv_altkey->base[0], gv_altkey->end - 1);
+					BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_altkey->base, gv_altkey->end - 1, end_map);
+					assert(prev_end_map >= end_map);
+					*cumul_val = *val;
+				}
+			}
+		}
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	POP_MV_STENT();	/* "val" */
+	assert(save_dollar_tlevel == dollar_tlevel);
+	if (cumul_found)
+	{	/* Restore accumulated minimal key into gv_altkey */
+		assert(cumul_key_len);
+		memcpy(&gv_altkey->base[0], &cumul_key[0], cumul_key_len);
+		gv_altkey->end = cumul_key_len - 1;
+		assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+	}
+	return cumul_found;
+}
diff --git a/sr_unix/gvcst_spr_zprevious.c b/sr_unix/gvcst_spr_zprevious.c
new file mode 100644
index 0000000..0fd9eda
--- /dev/null
+++ b/sr_unix/gvcst_spr_zprevious.c
@@ -0,0 +1,197 @@
+/****************************************************************
+ *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
+ *								*
+ *	This source code contains the intellectual property	*
+ *	of its copyright holder(s), and is made available	*
+ *	under a license.  If you do not know the terms of	*
+ *	the license, please stop and do not read further.	*
+ *								*
+ ****************************************************************/
+
+#include "mdef.h"
+
+#include "gdsroot.h"
+#include "gtm_facility.h"
+#include "fileinfo.h"
+#include "gdsbt.h"
+#include "gdsfhead.h"
+#include "filestruct.h"		/* needed for jnl.h */
+#include "gdscc.h"		/* needed for tp.h */
+#include "jnl.h"		/* needed for tp.h */
+#include "gdskill.h"		/* needed for tp.h */
+#include "buddy_list.h"		/* needed for tp.h */
+#include "hashtab_int4.h"	/* needed for tp.h */
+#include "tp.h"			/* needed for T_BEGIN_READ_NONTP_OR_TP macro */
+
+#include "gvcst_protos.h"
+#include "change_reg.h"
+#include "op.h"
+#include "op_tcommit.h"
+#include "tp_frame.h"
+#include "tp_restart.h"
+#include "targ_alloc.h"
+#include "error.h"
+#include "stack_frame.h"
+#include "gtmimagename.h"
+
+LITREF	mval		literal_batch;
+
+GBLREF gv_key		*gv_currkey, *gv_altkey;
+GBLREF gd_region	*gv_cur_region;
+GBLREF uint4		dollar_tlevel;
+
+DEFINE_NSB_CONDITION_HANDLER(gvcst_spr_zprevious_ch)
+
+boolean_t	gvcst_spr_zprevious(void)
+{
+	boolean_t	spr_tpwrapped;
+	boolean_t	est_first_pass;
+	boolean_t	found, cumul_found;
+	int		reg_index;
+	gd_binding	*start_map, *first_map, *stop_map, *end_map, *map, *prev_end_map;
+	gd_region	*reg, *gd_reg_start;
+	gd_addr		*addr;
+	gv_namehead	*start_map_gvt;
+	gvnh_reg_t	*gvnh_reg;
+	trans_num	gd_targ_tn, *tn_array;
+	char            cumul_key[MAX_KEY_SZ], savech;
+	int		cumul_key_len, prev;
+#	ifdef DEBUG
+	int		save_dollar_tlevel;
+#	endif
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	/* Ensure gv_cur_region/gv_target/cs_addrs at function return are identical to values at function entry
+	 * (this is not currently required now that op_gvname fast-path optimization has been removed in GTM-2168
+	 * but might be better to hold onto just in case that optimization is resurrected for non-spanning-globals or so)
+	 */
+	start_map = TREF(gd_targ_map);	/* set up by op_gvname/op_gvnaked/op_gvextnam done just before invoking op_zprevious */
+	start_map_gvt = gv_target;
+	addr = TREF(gd_targ_addr);
+	assert(NULL != addr);
+	gvnh_reg = TREF(gd_targ_gvnh_reg);
+	assert(NULL != gvnh_reg);
+	assert(NULL != gvnh_reg->gvspan);
+	if (TREF(gv_last_subsc_null))
+	{	/* last subscript is "". gv_currkey would have been recomputed in op_zprevious to have a 0xFF byte sequence
+		 * reflecting the maximum possible subscript value. Since this global spans multiple regions, recompute
+		 * the map corresponding to this gv_currkey.
+		 */
+		first_map = gv_srch_map_linear(start_map, (char *)&gv_currkey->base[0], gv_currkey->end - 1);
+	} else
+	{
+		first_map = start_map;
+		BACK_OFF_ONE_MAP_ENTRY_IF_EDGECASE(gv_currkey->base, gv_currkey->end - 1, first_map);
+		if (start_map != first_map)
+		{	/* set global variables to point to new first_map region */
+			reg = first_map->reg.addr;
+			GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs to new first_map */
+		}
+	}
+	/* Check if the previous key at SAME subscript level maps to same map as currkey. If so, no spanning activity needed */
+	GVKEY_SET_SUBS_ZPREVIOUS(gv_currkey, savech);
+	prev = gv_currkey->prev;
+	stop_map = gv_srch_map_linear_backward(first_map, (char *)&gv_currkey->base[0], prev + 1);
+	assert(stop_map <= first_map);
+	GVKEY_UNDO_SET_SUBS_ZPREVIOUS(gv_currkey, savech);
+	found = FALSE;
+	if (first_map == stop_map)
+	{	/* At this point, gv_target could be different from start_map_gvt.
+		 * Hence cannot use latter like is used in other gvcst_spr_* modules.
+		 */
+		if (gv_target->root)
+			found = gvcst_zprevious();
+		return found;
+	}
+	/* Do any initialization that is independent of retries BEFORE the op_tstart */
+	gd_reg_start = &addr->regions[0];
+	tn_array = TREF(gd_targ_reg_array);
+	/* Now that we know the keyrange maps to more than one region, go through each of them and do the $zprevious
+	 * Since multiple regions are potentially involved, need a TP fence.
+	 */
+	DEBUG_ONLY(save_dollar_tlevel = dollar_tlevel);
+	if (!dollar_tlevel)
+	{
+		spr_tpwrapped = TRUE;
+		op_tstart((IMPLICIT_TSTART), TRUE, &literal_batch, 0);
+		ESTABLISH_NORET(gvcst_spr_zprevious_ch, est_first_pass);
+		GVCST_ROOT_SEARCH_AND_PREP(est_first_pass);
+	} else
+		spr_tpwrapped = FALSE;
+	assert((first_map != start_map) || (gv_cur_region == first_map->reg.addr));
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	/* Do any initialization that is dependent on retries AFTER the op_tstart */
+	map = first_map;
+	end_map = stop_map;
+	cumul_found = FALSE;
+	cumul_key_len = 0;
+	DEBUG_ONLY(cumul_key[cumul_key_len] = KEY_DELIMITER;)
+	INCREMENT_GD_TARG_TN(gd_targ_tn); /* takes a copy of incremented "TREF(gd_targ_tn)" into local variable "gd_targ_tn" */
+	/* Verify that initializations that happened before op_tstart are still unchanged */
+	assert(addr == TREF(gd_targ_addr));
+	assert(tn_array == TREF(gd_targ_reg_array));
+	assert(gvnh_reg == TREF(gd_targ_gvnh_reg));
+	for ( ; map >= end_map; map--)
+	{	/* Backward scan through each map in the gld and do gvcst_zprevious calls in each map's region.
+		 * Note down the largest key found across the scanned regions until we find a key that belongs to the
+		 * same map (in the gld) as the currently scanned "map". At which point, the region-spanning zprevious is done.
+		 */
+		reg = map->reg.addr;
+		GET_REG_INDEX(addr, gd_reg_start, reg, reg_index);	/* sets "reg_index" */
+		assert((map != first_map) || (tn_array[reg_index] != gd_targ_tn));
+		assert(TREF(gd_targ_reg_array_size) > reg_index);
+		if (tn_array[reg_index] == gd_targ_tn)
+			continue;
+		GV_BIND_SUBSREG(addr, reg, gvnh_reg);	/* sets gv_target/gv_cur_region/cs_addrs */
+		assert(reg->open);
+		if (gv_target->root)
+		{
+			found = gvcst_zprevious();
+			if (found)
+			{
+				assert(!memcmp(&gv_altkey->base[0], &gv_currkey->base[0], prev));
+				cumul_found = TRUE;
+				assert(gv_altkey->end);
+				assert(gv_altkey->end > prev);
+				assert(KEY_DELIMITER == gv_altkey->base[gv_altkey->end]);
+				assert(!cumul_key_len || (KEY_DELIMITER == cumul_key[cumul_key_len - 1]));
+				if (!cumul_key_len || (0 > memcmp(&cumul_key[0], &gv_altkey->base[prev], cumul_key_len)))
+				{	/* just found alt_key is greater (collation-wise) than cumul_key so update cumul_key */
+					cumul_key_len = gv_altkey->end - prev;
+					assert(cumul_key_len);
+					assert(cumul_key_len < ARRAYSIZE(cumul_key));
+					memcpy(&cumul_key[0], &gv_altkey->base[prev], cumul_key_len);
+					DEBUG_ONLY(prev_end_map = end_map;)
+					/* update end_map as well now that we got a bigger cumul_key */
+					end_map = gv_srch_map_linear_backward(map, (char *)&gv_altkey->base[0], gv_altkey->end - 1);
+					assert(prev_end_map <= end_map);
+				}
+			}
+		}
+		tn_array[reg_index] = gd_targ_tn;
+	}
+	if (gv_target != start_map_gvt)
+	{	/* Restore gv_cur_region/gv_target etc. */
+		gv_target = start_map_gvt;
+		gv_cur_region = start_map->reg.addr;
+		change_reg();
+	}
+	DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
+	if (spr_tpwrapped)
+	{
+		op_tcommit();
+		REVERT; /* remove our condition handler */
+	}
+	assert(save_dollar_tlevel == dollar_tlevel);
+	if (cumul_found)
+	{	/* Restore accumulated minimal key into gv_altkey */
+		assert(cumul_key_len);
+		memcpy(&gv_altkey->base[0], &gv_currkey->base[0], prev);
+		memcpy(&gv_altkey->base[prev], &cumul_key[0], cumul_key_len);
+		gv_altkey->end = prev + cumul_key_len;
+		gv_altkey->base[gv_altkey->end] = KEY_DELIMITER;
+	}
+	return cumul_found;
+}
diff --git a/sr_unix/heartbeat_timer.c b/sr_unix/heartbeat_timer.c
index ab14edb..71127a1 100644
--- a/sr_unix/heartbeat_timer.c
+++ b/sr_unix/heartbeat_timer.c
@@ -143,14 +143,18 @@ void set_enospc_flags(gd_addr *addr_ptr, char enospc_enable_list[], boolean_t ok
 		if ((dba_bg != r_local->dyn.addr->acc_meth) && (dba_mm != r_local->dyn.addr->acc_meth))
 			continue;
 		csa = REG2CSA(r_local);
-		if ((NULL != csa) && (NULL != csa->nl) && ANTICIPATORY_FREEZE_ENABLED(csa))
+		if ((NULL != csa) && (NULL != csa->nl) && INST_FREEZE_ON_NOSPC_ENABLED(csa))
 		{
+			syslog_msg = NULL;
 			switch(enospc_enable_list[i])
 			{
 			case NONE:
-				syslog_msg = "Turning off fake ENOSPC for both database and journal file.";
-				csa->nl->fake_db_enospc = FALSE;
-				csa->nl->fake_jnl_enospc = FALSE;
+				if (csa->nl->fake_db_enospc || csa->nl->fake_jnl_enospc)
+				{
+					syslog_msg = "Turning off fake ENOSPC for both database and journal file.";
+					csa->nl->fake_db_enospc = FALSE;
+					csa->nl->fake_jnl_enospc = FALSE;
+				}
 				break;
 			case DB_ON:
 				syslog_msg = "Turning on fake ENOSPC only for database file.";
@@ -170,7 +174,7 @@ void set_enospc_flags(gd_addr *addr_ptr, char enospc_enable_list[], boolean_t ok
 			default:
 				assert(FALSE);
 			}
-			if (ok_to_interrupt)
+			if (ok_to_interrupt && (NULL != syslog_msg))
 				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TEXT, 2, DB_LEN_STR(r_local), ERR_TEXT, 2,
 					     LEN_AND_STR(syslog_msg));
 		}
diff --git a/sr_unix/incr_link.c b/sr_unix/incr_link.c
index 8e4a75a..e6a03f4 100644
--- a/sr_unix/incr_link.c
+++ b/sr_unix/incr_link.c
@@ -285,10 +285,10 @@ bool incr_link (int file_desc, zro_ent *zro_entry)
 		}
 		zl_error_hskpng(file_desc);
 		if ((hdr->compiler_qlf & CQ_UTF8) && !gtm_utf8_mode)
-			rts_error(VARLSTCNT(6) ERR_INVOBJ, 0,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_INVOBJ, 0,
 				ERR_TEXT, 2, LEN_AND_LIT("Object compiled with CHSET=UTF-8 which is different from $ZCHSET"));
 		else
-			rts_error(VARLSTCNT(6) ERR_INVOBJ, 0,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_INVOBJ, 0,
 				ERR_TEXT, 2, LEN_AND_LIT("Object compiled with CHSET=M which is different from $ZCHSET"));
 	}
 	/* Read in and/or relocate the pointers to the various sections. To understand the size calculations
@@ -634,7 +634,6 @@ boolean_t addr_fix (int file, unsigned char *shdr, urx_rtnref *urx_lcl)
 		rtnid.c[sym_size] = 0;
 		if ('_' == rtnid.c[0])
 			rtnid.c[0] = '%';
-		assert((mid_len(&zlink_mname) != sym_size) || (0 != memcmp(&zlink_mname.c[0], &rtnid.c[0], sym_size)));
 		rtn_str.addr = &rtnid.c[0];
 		rtn_str.len = sym_size;
 		rtn = find_rtn_hdr(&rtn_str);	/* Routine already resolved? */
@@ -750,12 +749,12 @@ void zl_error (int4 file, zro_ent *zroe, int4 err, int4 len, char *addr, int4 le
 	zl_error_hskpng(file);
 	/* 0, 2, or 4 arguments */
 	if (0 == len)
-		rts_error(VARLSTCNT(1) err);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) err);
 	else
 		if (0 == len2)
-			rts_error(VARLSTCNT(4) err, 2, len, addr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) err, 2, len, addr);
 		else
-			rts_error(VARLSTCNT(6) err, 4, len, addr, len2, addr2);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) err, 4, len, addr, len2, addr2);
 }
 
 /* ZL_ERROR-housekeeping */
diff --git a/sr_unix/init_gtm.c b/sr_unix/init_gtm.c
index 7b1a824..3a114ef 100644
--- a/sr_unix/init_gtm.c
+++ b/sr_unix/init_gtm.c
@@ -14,6 +14,7 @@
 #ifdef GTM_PTHREAD
 #  include <pthread.h>
 #endif
+#include <stdarg.h>
 #include "gtm_stdlib.h"
 #include "gtm_string.h"
 
@@ -42,7 +43,9 @@
 #include "stp_parms.h"
 #include "create_fatal_error_zshow_dmp.h"
 #include "mtables.h"
+#include "show_source_line.h"
 
+GBLREF mstr		default_sysid;
 GBLREF void		(*ctrlc_handler_ptr)();
 GBLREF void		(*tp_timeout_action_ptr)(void);
 GBLREF void		(*tp_timeout_clear_ptr)(void);
@@ -51,8 +54,11 @@ GBLREF int		(*op_open_ptr)(mval *v, mval *p, int t, mval *mspace);
 GBLREF void		(*op_write_ptr)(mval *v);
 GBLREF void		(*op_wteol_ptr)(int4 n);
 GBLREF void		(*unw_prof_frame_ptr)(void);
-
-GBLREF mstr		default_sysid;
+GBLREF void		(*stx_error_fptr)(int in_error, ...);	/* Function pointer for stx_error() so gtm_utf8.c can avoid pulling
+								 * stx_error() into gtmsecshr, and thus just about everything else
+								 * as well.
+								 */
+GBLREF	void		(*show_source_line_fptr)(boolean_t warn); /* Func ptr for show_source_line() for same reason as above */
 #ifdef GTM_PTHREAD
 GBLREF pthread_t	gtm_main_thread_id;
 GBLREF boolean_t	gtm_main_thread_id_set;
@@ -60,6 +66,7 @@ GBLREF boolean_t	gtm_jvm_process;
 #endif
 GBLDEF boolean_t	gtm_startup_active = FALSE;
 
+/* Note the function pointer initializations below happen in both the GT.M runtime and in mupip */
 void init_gtm(void)
 {
 	struct startup_vector   svec;
@@ -72,17 +79,17 @@ void init_gtm(void)
 	assert(SIZEOF(int) == 4);
 	assert(SIZEOF(int4) == 4);
 	assert(SIZEOF(short) == 2);
-#ifdef OFF_T_LONG
+#	ifdef OFF_T_LONG
 	assert(SIZEOF(off_t) == 8);
-#else
+#	else
 	assert(SIZEOF(off_t) == 4);
-#endif
+#	endif
 	assert(SIZEOF(sgmnt_data) == ROUND_UP(SIZEOF(sgmnt_data), DISK_BLOCK_SIZE));
-#ifdef KEY_T_LONG
+#	ifdef KEY_T_LONG
 	assert(8 == SIZEOF(key_t));
-#else
+#	else
 	assert(SIZEOF(key_t) == SIZEOF(int4));
-#endif
+#	endif
 	assert(SIZEOF(boolean_t) == 4); /* generated code passes 4 byte arguments, run time rtn might be expecting boolean_t arg */
 	assert(BITS_PER_UCHAR == 8);
 	assert(SIZEOF(enum db_ver) == SIZEOF(int4));
@@ -91,7 +98,6 @@ void init_gtm(void)
 	assert(SIZEOF(chkmval.fnpc_indx) == SIZEOF(chkmval_b.fnpc_indx));
 	assert(OFFSETOF(mval, fnpc_indx) == OFFSETOF(mval_b, fnpc_indx));
 	DEBUG_ONLY(mtables_chk());	/* Validate mtables.c assumptions */
-
 	SFPTR(create_fatal_error_zshow_dmp_fptr, create_fatal_error_zshow_dmp);
 #	ifdef GTM_PTHREAD
 	assert(!gtm_main_thread_id_set);
@@ -110,11 +116,11 @@ void init_gtm(void)
 	op_write_ptr = op_write;
 	op_wteol_ptr = op_wteol;
 	unw_prof_frame_ptr = unw_prof_frame;
-
+	stx_error_fptr = stx_error;
+	show_source_line_fptr = show_source_line;
 	if (MUMPS_COMPILE == invocation_mode)
 		exit(gtm_compile());
-
-	/* this should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup   */
+	/* This should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup   */
 	memset(&svec, 0, SIZEOF(svec));
 	svec.argcnt = SIZEOF(svec);
 	svec.rtn_start = svec.rtn_end = malloc(SIZEOF(rtn_tabent));
diff --git a/sr_unix/install.sh b/sr_unix/install.sh
deleted file mode 100644
index c9a12e2..0000000
--- a/sr_unix/install.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-#################################################################
-#								#
-#	Copyright 2009, 2012 Fidelity Information Services, Inc	#
-#								#
-#	This source code contains the intellectual property	#
-#	of its copyright holder(s), and is made available	#
-#	under a license.  If you do not know the terms of	#
-#	the license, please stop and do not read further.	#
-#								#
-#################################################################
-
-if [ $# -lt 1 ]; then
-	echo "Usage: $0 ENCRYPTION_LIB [ALGORITHM]"
-	echo "ENCRYPTION_LIB is either gcrypt or openssl"
-	echo "	gcrypt : Install encryption plugin built with libgcrypt (if one exists)"
-	echo "	openssl: Install encryption plugin built with OpenSSL (if one exists)"
-	echo "ALGORITHM is either AES256CFB (default) or BLOWFISHCFB"
-	echo "  AES256CFB      : Install encryption plugin built with AES (CFB mode) with 256-bit encryption"
-	echo "  BLOWFISHCFB : Install encryption plugin built with BLOWFISH (CFB mode) with 256-bit encryption"
-	exit 1
-fi
-
-# Since we are installing in the GT.M distribution directory, we better have $gtm_dist set and the plugin and plugin/gtmcrypt
-# subdirectories present for us to do a successful copy.
-if [ "" = $gtm_dist ]; then
-	echo "Environment variable - gtm_dist not defined."
-	exit 1
-fi
-
-if [ ! -d $gtm_dist/plugin ]; then
-	echo "Unable to locate $gtm_dist/plugin. Cannot install encryption library"
-	exit 1
-fi
-
-if [ ! -d $gtm_dist/plugin/gtmcrypt ]; then
-	echo "Unable to locate $gtm_dist/plugin/gtmcrypt. Cannot install helper scripts/executables"
-	exit 1
-fi
-
-encryption_lib=$1
-algorithm="AES256CFB"
-if [ $# -eq 2 ]; then algorithm="$2" ; fi
-
-platform_name=`uname -s`
-cwd=`pwd`
-gtm_dist_plugin="$gtm_dist/plugin"
-
-ext=".so"
-if [ "OS/390" = $platform_name ]; then ext=".dll" ; fi
-
-base_libname="libgtmcrypt"
-generic_libname=$base_libname$ext
-specific_libname=${base_libname}_${encryption_lib}_${algorithm}${ext}
-
-echo "Installing M programs and shared libraries..."
-if [ ! -f $cwd/$specific_libname ]; then
-	echo "Shared library $specific_libname not built. Please check errors from build.sh"
-	exit 1
-fi
-
-if [ ! -f $cwd/maskpass ]; then
-	echo "Helper executable maskpass not built. Please check errors from build.sh"
-	exit 1
-fi
-
-\rm -f $gtm_dist_plugin/$generic_libname			# Remove existing artifacts
-if [ $cwd != $gtm_dist_plugin/gtmcrypt ]; then
-	# Current directory is NOT a part of $gtm_dist/plugin. Just copy the shared libraries to $gtm_dist/plugin
-	\cp $base_libname*$ext $gtm_dist_plugin
-	\cp maskpass $gtm_dist_plugin/gtmcrypt/maskpass
-else
-	# Current directory is $gtm_dist/plugin/gtmcrypt. Move the shared libraries to $gtm_dist/plugin to avoid duplicate copies
-	\mv $base_libname*$ext $gtm_dist_plugin
-fi
-
-\ln -s ./$specific_libname $gtm_dist_plugin/$generic_libname
-
-cat << EOF > $gtm_dist_plugin/gpgagent.tab
-$gtm_dist_plugin/$generic_libname
-unmaskpwd: xc_status_t gc_pk_mask_unmask_passwd_interlude(I:xc_string_t*,O:xc_string_t*[512],I:xc_int_t)
-EOF
-
-cat << EOF > $gtm_dist_plugin/gtmcrypt/gtmcrypt.tab
-getpass:char* getpass^GETPASS(I:gtm_int_t)
-EOF
-
-echo "Installation Complete"
-exit 0
diff --git a/sr_unix/io_get_fgn_driver.c b/sr_unix/io_get_fgn_driver.c
index 4177717..5d9143d 100644
--- a/sr_unix/io_get_fgn_driver.c
+++ b/sr_unix/io_get_fgn_driver.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -14,8 +14,10 @@
 #include "mdef.h"
 #include "io.h"
 
+error_def(ERR_INVMNEMCSPC);
+
 dev_dispatch_struct *io_get_fgn_driver(mstr *s)
-{	error_def(ERR_UNIMPLOP);
-	rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
+{
+	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_INVMNEMCSPC, 2, s->len, s->addr);
 	return ((dev_dispatch_struct *)NULL);
 }
diff --git a/sr_unix/io_open_try.c b/sr_unix/io_open_try.c
index bbb3d40..c1697d5 100644
--- a/sr_unix/io_open_try.c
+++ b/sr_unix/io_open_try.c
@@ -195,9 +195,6 @@ bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mva
 			else if (((SIZEOF("PIPE") - 1) == mspace->str.len)
 			    && (0 == MEMCMP_LIT(dev_type, "PIPE")))
 				tl->iod->type = pi;
-			else if (((SIZEOF("TCP") - 1) == mspace->str.len)
-			    && (0 == MEMCMP_LIT(dev_type, "TCP")))
-				tl->iod->type = tcp;
 			else
 				tl->iod->type = us;
 		}
@@ -311,7 +308,7 @@ bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mva
 	active_device = naml->iod;
 
 	if ((-2 == file_des) && (dev_open != naml->iod->state) && (us != naml->iod->type)
-	    && (tcp != naml->iod->type) && (gtmsocket != naml->iod->type) && (pi != naml->iod->type))
+	    && (gtmsocket != naml->iod->type) && (pi != naml->iod->type))
 	{
 		oflag |= (O_RDWR | O_CREAT | O_NOCTTY);
 		p_offset = 0;
@@ -490,7 +487,7 @@ bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mva
 		cancel_timer(timer_id);
 
 #ifdef KEEP_zOS_EBCDIC
-	if ((tcp != naml->iod->type) && (gtmsocket != naml->iod->type))
+	if (gtmsocket != naml->iod->type)
 	{
 		SET_CODE_SET(naml->iod->in_code_set, OUTSIDE_CH_SET);
 		if (DEFAULT_CODE_SET != naml->iod->in_code_set)
diff --git a/sr_unix/iomt_ch.c b/sr_unix/iomt_ch.c
index 0d2e552..3236e65 100644
--- a/sr_unix/iomt_ch.c
+++ b/sr_unix/iomt_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -22,6 +22,8 @@
 
 GBLREF io_pair  io_curr_device;
 
+error_def (ERR_MTIOERR);
+
 /* iomt_ch.c error handler for an ioctl() failure in iomt_qio() */
 CONDITION_HANDLER(iomt_ch)
 {
@@ -35,9 +37,8 @@ CONDITION_HANDLER(iomt_ch)
 	d_mt_struct	*mt_ptr;
 	char		closep;
 	mval		close_params;
-	error_def (ERR_MTIOERR);
 
-	START_CH
+	START_CH(TRUE);
 	if (arg == ERR_MTIOERR)
 	{
 		dv = io_curr_device.in;
diff --git a/sr_unix/iopi_iocontrol.c b/sr_unix/iopi_iocontrol.c
index a587e50..fffd9b5 100644
--- a/sr_unix/iopi_iocontrol.c
+++ b/sr_unix/iopi_iocontrol.c
@@ -21,7 +21,6 @@
 #include "io.h"
 #include "iormdef.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "gtm_caseconv.h"
 #include "min_max.h"
diff --git a/sr_unix/iopi_open.c b/sr_unix/iopi_open.c
index 8f47bfc..7946ad8 100644
--- a/sr_unix/iopi_open.c
+++ b/sr_unix/iopi_open.c
@@ -42,6 +42,7 @@
 LITREF	unsigned char		io_params_size[];
 ZOS_ONLY(GBLREF boolean_t	gtm_tag_utf8_as_ascii;)
 GBLREF	boolean_t		gtm_pipe_child;
+GBLREF	char			gtm_dist[GTM_PATH_MAX];
 
 error_def(ERR_DEVOPENFAIL);
 error_def(ERR_SYSCALL);
@@ -202,11 +203,10 @@ int parse_pipe(char *cmd_string, char *ret_token)
 		} else
 		{
 			/* look in $gtm_dist in case not explicitly listed or not in the $PATH variable */
-			env_var = GETENV("gtm_dist");
-			if (NULL != env_var)
+			if (!STRLEN(gtm_dist))
 			{
 				/* build a translated path to command */
-				SPRINTF(temp, "%s/%s", env_var, token2);
+				SPRINTF(temp, "%s/%s", gtm_dist, token2);
 				STAT_FILE(temp, &sb, ret_stat);
 				if (0 == ret_stat && (S_ISREG(sb.st_mode)) && (sb.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)))
 					notfound = FALSE;
diff --git a/sr_unix/iorm_close.c b/sr_unix/iorm_close.c
index 94dcfcd..d4e7e49 100644
--- a/sr_unix/iorm_close.c
+++ b/sr_unix/iorm_close.c
@@ -26,12 +26,19 @@
 #include "iosp.h"
 #include "string.h"
 #include "stringpool.h"
+#include "iotimer.h"
+#include "gt_timer.h"
+#include "wake_alarm.h"
+#include "copy.h"
 
 GBLREF io_pair		io_curr_device;
 GBLREF io_pair		io_std_device;
 GBLREF	boolean_t	gtm_pipe_child;
+GBLREF	volatile bool	out_of_time;
 
 error_def(ERR_CLOSEFAIL);
+error_def(ERR_SYSCALL);
+error_def(ERR_DEVPARMTOOSMALL);
 
 LITREF unsigned char	io_params_size[];
 
@@ -48,13 +55,25 @@ void iorm_close(io_desc *iod, mval *pp)
 	struct stat	statbuf, fstatbuf;
 	int		p_offset;
 	pid_t  		done_pid;
-	int  		wait_status, rc;
+#ifdef _BSD
+        union wait      wait_status;
+#else
+        int4            wait_status;
+#endif
+
+	int  		status,rc;
 	unsigned int	*dollarx_ptr;
 	unsigned int	*dollary_ptr;
 	char 		*savepath2 = 0;
 	int		path2len;
 	boolean_t	rm_destroy = TRUE;
 	boolean_t	rm_rundown = FALSE;
+	TID		timer_id;
+	int4		pipe_timeout = 2;	/* default timeout in sec waiting for waitpid */
+
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
 
 	assert (iod->type == rm);
 	if (iod->state != dev_open)
@@ -135,6 +154,11 @@ void iorm_close(io_desc *iod, mval *pp)
 			case iop_rundown:
 				rm_rundown = TRUE;
 				break;
+			case iop_timeout:
+				GET_LONG(pipe_timeout, (pp->str.addr + p_offset));
+				if (1 > pipe_timeout)
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DEVPARMTOOSMALL);
+				break;
 			default:
 				break;
 		}
@@ -211,8 +235,46 @@ void iorm_close(io_desc *iod, mval *pp)
 		{
 			if (!rm_ptr->independent)
 			{
-				WAITPID(rm_ptr->pipe_pid, &wait_status, 0, done_pid);
-				assert(done_pid == rm_ptr->pipe_pid);
+				/* start timer for pipe_timeout sec to wait for reap of close via waitpid.  If this
+				   times out, set dollar_zclose = -99 */
+				out_of_time = FALSE;
+				timer_id = (TID)iorm_close;
+				start_timer(timer_id, pipe_timeout * 1000, wake_alarm, 0, NULL);
+				do
+				{
+					done_pid = waitpid(rm_ptr->pipe_pid, &status, 0); /* BYPASSOK */
+				} while((pid_t)-1 == done_pid && EINTR == errno && !out_of_time);
+
+				if ((pid_t)-1 == done_pid && !out_of_time)
+				{
+					cancel_timer(timer_id);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
+						      RTS_ERROR_LITERAL("waitpid"), CALLFROM, errno);
+				}
+				if (out_of_time)
+				{
+					TREF(dollar_zclose) = -99;
+				} else
+				{
+					/* not an error and didn't timeout */
+					assert(done_pid == rm_ptr->pipe_pid);
+					/* cancel timer since it didn't timeout */
+					cancel_timer(timer_id);
+#ifdef _BSD
+					assert(SIZEOF(wait_status) == SIZEOF(int4));
+					wait_status.w_status = status;
+					/* the WIF* macros expect a union wait_stat as an argument on BSD */
+#else
+					wait_status = status;
+#endif
+					if (WIFEXITED(wait_status))
+						TREF(dollar_zclose) = WEXITSTATUS(wait_status); /* normal exit */
+					else if (WIFSIGNALED(wait_status))
+						/* change the signal to a negative for distinguishing from normal exit codes */
+						TREF(dollar_zclose) = -WTERMSIG(wait_status);
+					else /* set any other non-normal status to -98 */
+						TREF(dollar_zclose) = -98;
+				}
 			}
 		}
 
diff --git a/sr_unix/iorm_get.c b/sr_unix/iorm_get.c
index e874061..ae987e4 100644
--- a/sr_unix/iorm_get.c
+++ b/sr_unix/iorm_get.c
@@ -96,14 +96,15 @@ int	gtm_utf_bomcheck(io_desc *iod, gtm_chset_t *chset, unsigned char *buffer, in
 				bom_bytes = 0;		/* no BOM found */
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE);
 	}
 	return bom_bytes;
 }
 
 /* When we get to this routine it is guaranteed that rm_ptr->done_1st_read is FALSE. */
 
-int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed, boolean_t *bom_timeout)
+int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed,
+			 boolean_t *bom_timeout, ABS_TIME end_time)
 {
 	int4		bytes2read, bytes_read, reclen, bom_bytes2read, bom_bytes_read;
 	int		status = 0;
@@ -112,6 +113,7 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 	int		fildes;
 	int4 sleep_left;
 	int4 sleep_time;
+	ABS_TIME	current_time, time_left;
 
 	rm_ptr = (d_rm_struct *)(io_ptr->dev_sp);
 	fildes = rm_ptr->fildes;
@@ -125,8 +127,21 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 	if (timed)
 	{
 		/* check iorm_get_bom_fol.... for msc_timeout */
+		/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
 		if (0 < *msec_timeout)
 		{
+			/* get the current time */
+			sys_get_curr_time(&current_time);
+			time_left = sub_abs_time(&end_time, &current_time);
+			if (0 > time_left.at_sec)
+			{
+				*msec_timeout = -1;
+				*bom_timeout = TRUE;
+			} else
+				*msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+			/* make sure it terminates with bom_timeout */
+			if (!*bom_timeout && !*msec_timeout)
+				*msec_timeout = 1;
 			sleep_left = *msec_timeout;
 		} else
 			sleep_left = 0;
@@ -136,6 +151,7 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 		io_ptr->dollar.zeof = FALSE;
 	do
 	{
+		/* in follow mode a read will return an EOF if no more bytes are available*/
 		status = read(fildes, &rm_ptr->bom_buf[rm_ptr->bom_buf_cnt], bom_bytes2read - rm_ptr->bom_buf_cnt);
 		if (0 < status) /* we read some chars */
 		{
@@ -151,12 +167,27 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 			/* if a timed read, sleep the minimum of 100 ms and sleep_left.
 			   If not a timed read then just sleep 100 ms */
 			if (TRUE == timed)
+			{
+				/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
+				/* get the current time */
+				sys_get_curr_time(&current_time);
+				time_left = sub_abs_time(&end_time, &current_time);
+				if (0 > time_left.at_sec)
+				{
+					*msec_timeout = -1;
+					*bom_timeout = TRUE;
+				} else
+					*msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+
+				/* make sure it terminates with bom_timeout */
+				if (!*bom_timeout && !*msec_timeout)
+					*msec_timeout = 1;
+				sleep_left = *msec_timeout;
 				sleep_time = MIN(100,sleep_left);
-			else
+			} else
 				sleep_time = 100;
-			SHORT_SLEEP(sleep_time);
-			if (TRUE == timed)
-				sleep_left -= sleep_time;
+			if (0 < sleep_time)
+				SHORT_SLEEP(sleep_time);
 			if (outofband)
 			{
 				return 0;
@@ -184,7 +215,7 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 		get_chset_desc(&chset_names[chset]);
 	}
 	/* if outofband is not set then we are done getting the bom */
-	if (!outofband)
+	if (!outofband && !*bom_timeout)
 		rm_ptr->done_1st_read = TRUE;
 	return 0;
 }
@@ -192,7 +223,7 @@ int	iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout,
 /* If we are in this routine then it is a fixed utf disk read with rm_ptr->follow = TRUE */
 
 int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed,
-		     boolean_t zint_restart, boolean_t *follow_timeout)
+		     boolean_t zint_restart, boolean_t *follow_timeout, ABS_TIME end_time)
 {
 	boolean_t	ret;
 	char		inchar, *temp;
@@ -208,6 +239,7 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 	int4		sleep_left;
 	int4		sleep_time;
 	boolean_t	bom_timeout = FALSE;
+	ABS_TIME	current_time, time_left;
 
 	assert (io_ptr->state == dev_open);
 	rm_ptr = (d_rm_struct *)(io_ptr->dev_sp);
@@ -216,9 +248,23 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 	assert(rm_ptr->fixed);
 	if (!zint_restart)
 	{
-		bytes2read = rm_ptr->recordsize;
-		bytes_already_read = 0;
-		rm_ptr->inbuf_pos = rm_ptr->inbuf_top = rm_ptr->inbuf_off = rm_ptr->inbuf;
+		/* if last operation timed out with some chars then only read up to recordsize bytes */
+		bytes_already_read = rm_ptr->inbuf_top - rm_ptr->inbuf;
+		if (bytes_already_read)
+			rm_ptr->last_was_timeout = 1;
+		else
+			rm_ptr->last_was_timeout = 0;
+		if ((bytes_already_read == rm_ptr->recordsize) || (rm_ptr->fol_bytes_read == rm_ptr->recordsize))
+		{
+			bytes2read = rm_ptr->recordsize;
+			rm_ptr->inbuf_pos = rm_ptr->inbuf_top = rm_ptr->inbuf_off = rm_ptr->inbuf;
+			bytes_already_read = 0;
+			rm_ptr->fol_bytes_read = 0;
+			rm_ptr->last_was_timeout = 0;
+		} else
+			bytes2read = rm_ptr->recordsize - bytes_already_read;
+		/* since it is not a restart bytes_already_read happened in a previous read so save it */
+		rm_ptr->orig_bytes_already_read = bytes_already_read;
 	}
 	else
 	{
@@ -230,18 +276,19 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 		else
 			rm_ptr->inbuf_pos = rm_ptr->inbuf_off = rm_ptr->inbuf;
 	}
-	PIPE_DEBUG(PRINTF("iorm_get_fol: bytes2read: %d, zint_restart: %d\n", bytes2read,zint_restart); DEBUGPIPEFLUSH;);
+	PIPE_DEBUG(PRINTF("iorm_get_fol: bytes2read: %d, bytes_already_read: %d, last_was_timeout: %d, zint_restart: %d\n",
+			  bytes2read,bytes_already_read,rm_ptr->last_was_timeout,zint_restart); DEBUGPIPEFLUSH;);
+	PIPE_DEBUG(PRINTF("iorm_get_fol: inbuf: 0x%08lx, top: 0x%08lx, off: 0x%08lx\n", rm_ptr->inbuf, rm_ptr->inbuf_top,
+			  rm_ptr->inbuf_off); DEBUGPIPEFLUSH;);
 	bytes_read = 0;
 	assert(rm_ptr->bufsize >= rm_ptr->recordsize);
 	errno = status = 0;
-	/* don't reset this if continuing from an interrupt unless we haven't read the bom yet */
-/*	if (!rm_ptr->done_1st_read || FALSE == zint_restart)
-	rm_ptr->inbuf_pos = rm_ptr->inbuf_off = rm_ptr->inbuf;*/
 	chset = io_ptr->ichset;
 	if (!rm_ptr->done_1st_read)
 	{
 		PIPE_DEBUG(PRINTF("do iorm_get_bom_fol: bytes2read: %d\n", bytes2read); DEBUGPIPEFLUSH;)
-			status = iorm_get_bom_fol(io_ptr, tot_bytes_read, msec_timeout, timed, &bom_timeout);
+			status = iorm_get_bom_fol(io_ptr, tot_bytes_read, msec_timeout, timed,
+						  &bom_timeout, end_time);
 		if (!rm_ptr->done_1st_read && outofband)
 		{
 			PIPE_DEBUG(PRINTF("return since iorm_get_bom_fol went outofband\n"); DEBUGPIPEFLUSH;);
@@ -278,8 +325,20 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 		PIPE_DEBUG(PRINTF("iorm_get_fol: bytes2read after bom: %d\n", bytes2read); DEBUGPIPEFLUSH;);
 		if (timed)
 		{
+			/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
 			if (0 < *msec_timeout)
 			{
+				/* get the current time */
+				sys_get_curr_time(&current_time);
+				time_left = sub_abs_time(&end_time, &current_time);
+				if (0 > time_left.at_sec)
+				{
+					*msec_timeout = -1;
+					*follow_timeout = TRUE;
+				} else
+					*msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+				/* make sure it terminates with follow_timeout */
+				if (!*follow_timeout && !*msec_timeout) *msec_timeout = 1;
 				sleep_left = *msec_timeout;
 			} else
 				sleep_left = 0;
@@ -290,10 +349,11 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 		temp = (char *)rm_ptr->inbuf_pos;
 		do
 		{
+			/* in follow mode a read will return an EOF if no more bytes are available*/
 			status = read(fildes, temp, (int)bytes2read - bytes_count);
 			if (0 < status) /* we read some chars */
 			{
-				tot_bytes_read += status;
+				*tot_bytes_read += status;
 				bytes_count += status;
 				temp = temp + status;
 			} else if (0 == status) /* end of file */
@@ -307,12 +367,26 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 				/* if a timed read, sleep the minimum of 100 ms and sleep_left.
 				   If not a timed read then just sleep 100 ms */
 				if (TRUE == timed)
+				{
+					/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
+					/* get the current time */
+					sys_get_curr_time(&current_time);
+					time_left = sub_abs_time(&end_time, &current_time);
+					if (0 > time_left.at_sec)
+					{
+						*msec_timeout = -1;
+						*follow_timeout = TRUE;
+					} else
+						*msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+
+					/* make sure it terminates with follow_timeout */
+					if (!*follow_timeout && !*msec_timeout) *msec_timeout = 1;
+					sleep_left = *msec_timeout;
 					sleep_time = MIN(100,sleep_left);
-				else
+				} else
 					sleep_time = 100;
-				SHORT_SLEEP(sleep_time);
-				if (TRUE == timed)
-					sleep_left -= sleep_time;
+				if (0 < sleep_time)
+					SHORT_SLEEP(sleep_time);
 				if (outofband)
 					break;
 				continue; /* for now try and read again if eof or no input ready */
@@ -348,7 +422,7 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 		bytes_read = 0;
 		if (TRUE == *follow_timeout)
 			status = -2;
-	} else if (bytes_read || status)
+	} else if (bytes_read || status || (bytes_already_read && (TRUE == timed)))
 	{
 		bytes_read += status;
 		rm_ptr->file_pos += status;
@@ -358,15 +432,16 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 			/* It's possible that only one byte is read if this is an interrupt restart one byte from the width
 			 * In that case it's not an error if already_read is non-zero, but we have to adjust bytes_read differently.
 			 */
-			PIPE_DEBUG(PRINTF("pipeget: bytes_read: %d bytes_already_read: %d, zint_restart: %d\n",
+			PIPE_DEBUG(PRINTF("iorm_get_fol: bytes_read: %d bytes_already_read: %d, zint_restart: %d\n",
 					  bytes_read,bytes_already_read,zint_restart); DEBUGPIPEFLUSH;);
-			if (zint_restart && bytes_already_read)
+			if (bytes_already_read)
 			{
 				tmp_bytes_read = bytes_read + bytes_already_read;
 			} else
 			{
 				tmp_bytes_read = bytes_read;
 			}
+			rm_ptr->fol_bytes_read = tmp_bytes_read;
 			assert(tmp_bytes_read >= 2);
 			if (CHSET_UTF16LE == chset)
 			{
@@ -380,7 +455,7 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 			for (pad_ptr = rm_ptr->inbuf + tmp_bytes_read - 2;
 			     0 < tmp_bytes_read && rm_ptr->inbuf <= pad_ptr; pad_ptr-=2)
 			{
-				PIPE_DEBUG(PRINTF("pad 16 loop: bytes_read: %d pad_ptr: %sx\n",
+				PIPE_DEBUG(PRINTF("pad 16 loop: bytes_read: %d pad_ptr: 0x%08lx\n",
 						  bytes_read,pad_ptr); DEBUGPIPEFLUSH;);
 				if ((padcharray[0] == pad_ptr[0]) && (padcharray[1] == pad_ptr[1]))
 					tmp_bytes_read -= 2;
@@ -390,12 +465,16 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 			bytes_read = tmp_bytes_read;
 		} else
 		{	/* strip 1-byte PADCHAR in UTF-8 from tail of line */
-			if (zint_restart && bytes_already_read)
+			if (bytes_already_read)
 				bytes_read = bytes_read + bytes_already_read;
+
+			/* store total of bytes read */
+			rm_ptr->fol_bytes_read = bytes_read;
+
 			assert(CHSET_UTF8 == chset);
 			for (pad_ptr = rm_ptr->inbuf + bytes_read - 1; 0 < bytes_read && rm_ptr->inbuf <= pad_ptr; pad_ptr--)
 			{
-				PIPE_DEBUG(PRINTF("pad 8 loop: bytes_read: %d pad_ptr: %sx\n",
+				PIPE_DEBUG(PRINTF("pad 8 loop: bytes_read: %d pad_ptr: 0x%08lx\n",
 						  bytes_read,pad_ptr); DEBUGPIPEFLUSH;);
 				if (*pad_ptr == padchar)
 					bytes_read--;
@@ -405,7 +484,16 @@ int	iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, bool
 		}
 	}
 	rm_ptr->inbuf_top = rm_ptr->inbuf_pos = rm_ptr->inbuf + bytes_read;
-	rm_ptr->inbuf_off = rm_ptr->inbuf;
+	PIPE_DEBUG(PRINTF("last_was_timeout: %d \n",rm_ptr->last_was_timeout); DEBUGPIPEFLUSH;);
+	if (!zint_restart || (TRUE == rm_ptr->last_was_timeout))
+	{
+		rm_ptr->inbuf_off = rm_ptr->inbuf + rm_ptr->orig_bytes_already_read;
+		/* back out bytes_already_read mod */
+		bytes_read = bytes_read - bytes_already_read + rm_ptr->orig_bytes_already_read;
+		rm_ptr->orig_bytes_already_read = 0;
+		rm_ptr->last_was_timeout = 0;
+	} else
+		rm_ptr->inbuf_off = rm_ptr->inbuf;
 	return (0 <= status ? bytes_read : status);
 }
 
diff --git a/sr_unix/iorm_readfl.c b/sr_unix/iorm_readfl.c
index a5506a2..7115581 100644
--- a/sr_unix/iorm_readfl.c
+++ b/sr_unix/iorm_readfl.c
@@ -56,7 +56,7 @@ error_def(ERR_DEVICEWRITEONLY);
 #define SETZACANCELTIMER					\
 		io_ptr->dollar.za = 9;				\
 		v->str.len = 0;					\
-		if (timed && !out_of_time)			\
+		if (!rm_ptr->follow && timed && !out_of_time)	\
 			cancel_timer(timer_id);
 
 #ifdef UNICODE_SUPPORTED
@@ -132,7 +132,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 	int		do_clearerr = FALSE;
 	int		saved_lastop;
 	int             min_bytes_to_copy;
-	ABS_TIME	cur_time, end_time, time_for_read;
+	ABS_TIME	cur_time, end_time, current_time, time_left;
 	pipe_interrupt	*pipeintr;
 	mv_stent	*mv_zintdev;
 	unsigned int	*dollarx_ptr;
@@ -222,20 +222,24 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 	if (rm_ptr->mupintr)
 	{	/* We have a pending read restart of some sort */
 		if (pipewhich_invalid == pipeintr->who_saved)
-			GTMASSERT;      /* Interrupt should never have an invalid save state */
+			assertpro(FALSE);      /* Interrupt should never have an invalid save state */
 		/* check we aren't recursing on this device */
 		if (dollar_zininterrupt)
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
                 if (pipewhich_readfl != pipeintr->who_saved)
-                        GTMASSERT;      /* ZINTRECURSEIO should have caught */
+                        assertpro(FALSE);      /* ZINTRECURSEIO should have caught */
 		PIPE_DEBUG(PRINTF("piperfl: *#*#*#*#*#*#*#  Restarted interrupted read\n"); DEBUGPIPEFLUSH);
 		mv_zintdev = io_find_mvstent(io_ptr, FALSE);
 		if (mv_zintdev)
 		{
 			if (mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid)
 			{
-				assert(mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.len == pipeintr->bytes_read);
-				buffer_start = (unsigned char *)mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr;
+				bytes_read = pipeintr->bytes_read;
+				assert(mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.len == bytes_read);
+				if (bytes_read)
+					buffer_start = (unsigned char *)mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr;
+				else
+					buffer_start = stringpool.free;
 				zint_restart = TRUE;
 			} else
 			{
@@ -311,7 +315,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 		   don't use temp, so skip the following stringpool checks */
 		if (!utf_active || !rm_ptr->fixed)
 		{
-			if (stringpool.free != (buffer_start + bytes_read)) /* BYPASSOK */
+			if (!IS_AT_END_OF_STRINGPOOL(buffer_start, bytes_read))
 			{	/* Not @ stringpool.free - must move what we have, so we need room for
 				   the whole anticipated message */
 				PIPE_DEBUG(PRINTF("socrfl: .. Stuff put on string pool after our buffer\n"); DEBUGPIPEFLUSH);
@@ -330,32 +334,28 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 				v->str.len = bytes_read;
 				INVOKE_STP_GCOL(exp_width);
 				/* if v->str.len is 0 then v->str.add is ignored by garbage collection so reset it to
-				   stringpool.free */
+					stringpool.free */
 				if (v->str.len == 0)
-					v->str.addr =  (char *)stringpool.free;
+			 		v->str.addr =  (char *)stringpool.free;
 				buffer_start = (unsigned char *)v->str.addr;
 			}
-			if ((buffer_start + bytes_read) < stringpool.free)	/* BYPASSOK */
+			assert((buffer_start + bytes_read) <= stringpool.free);	/* BYPASSOK */
+			if (!IS_AT_END_OF_STRINGPOOL(buffer_start, bytes_read))
+
 			{	/* now need to move it to the top */
 				assert(stp_need == exp_width);
 				memcpy(stringpool.free, buffer_start, bytes_read);
 			} else
-			{	/* it should still be just under the used space */
-				assert(!bytes_read || ((buffer_start + bytes_read) == stringpool.free));	/* BYPASSOK */
-				stringpool.free = buffer_start;
-			}
+				stringpool.free = buffer_start;	/* it should still be just under the used space */
 			v->str.len = 0;		/* Clear in case interrupt or error -- don't want to hold this buffer */
-
 			temp = (char *)(stringpool.free + bytes_read);
 			tot_bytes_read = bytes_count = bytes_read;
 			if (!(rm_ptr->fixed && rm_ptr->follow))
 				width -= bytes_read;
 		}
 	}
-
         if (utf_active)
 		bytes_read = 0;
-
 	out_of_time = FALSE;
 	if (timeout == NO_M_TIMEOUT)
 	{
@@ -377,9 +377,9 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 		timed = TRUE;
 		msec_timeout = timeout2msec(timeout);
 		if (msec_timeout > 0)
-		{
-			/* for the read x:n case a timer started here.  It is checked in the (timed) clause
-			 at the end of this routine and canceled if it has not expired. */
+		{	/* for the read x:n case a timer started here.  It is checked in the (timed) clause
+			 * at the end of this routine and canceled if it has not expired.
+			 */
 			sys_get_curr_time(&cur_time);
 			if (!zint_restart || !pipeintr->end_time_valid)
 				add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
@@ -395,6 +395,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
                                         out_of_time = TRUE;
                                 } else
 					msec_timeout = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000);
+				if (rm_ptr->follow && !out_of_time && !msec_timeout)
+					msec_timeout = 1;
 				PIPE_DEBUG(PRINTF("piperfl: Taking timeout end time from read restart data - "
 						  "computed msec_timeout: %d\n", msec_timeout); DEBUGPIPEFLUSH);
 			}
@@ -402,8 +404,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 			/* if it is a disk read with follow don't start timer, as we use a sleep loop instead */
 			if ((0 < msec_timeout) && !rm_ptr->follow)
 				start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL);
-		}
-		else
+		} else
 		{
 			/* out_of_time is set to TRUE because no timer is set for read x:0 for any device type at
 			 this point.  It will be set to FALSE for a pipe device if it has read one character as
@@ -435,8 +436,21 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 				PIPE_DEBUG(PRINTF(" %d fixed\n", pid); DEBUGPIPEFLUSH);
 				if (timed)
 				{
+					/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
 					if (0 < msec_timeout)
 					{
+						/* get the current time */
+						sys_get_curr_time(&current_time);
+						time_left = sub_abs_time(&end_time, &current_time);
+						if (0 > time_left.at_sec)
+						{
+							msec_timeout = -1;
+							out_of_time = TRUE;
+						} else
+							msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+						/* make sure it terminates with out_of_time */
+						if (!out_of_time && !msec_timeout)
+							msec_timeout = 1;
 						sleep_left = msec_timeout;
 					} else
 						sleep_left = 0;
@@ -446,6 +460,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					io_ptr->dollar.zeof = FALSE;
 				do
 				{
+					/* in follow mode a read will return an EOF if no more bytes are available*/
 					status = read(fildes, temp, width - bytes_count);
 					if (0 < status) /* we read some chars */
 					{
@@ -463,12 +478,28 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						/* if a timed read, sleep the minimum of 100 ms and sleep_left.
 						   If not a timed read then just sleep 100 ms */
 						if (TRUE == timed)
+						{
+							/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
+							/* get the current time */
+							sys_get_curr_time(&current_time);
+							time_left = sub_abs_time(&end_time, &current_time);
+							if (0 > time_left.at_sec)
+							{
+								msec_timeout = -1;
+								out_of_time = TRUE;
+							} else
+								msec_timeout = (int4)(time_left.at_sec * 1000 +
+										      time_left.at_usec / 1000);
+
+							/* make sure it terminates with out_of_time */
+							if (!out_of_time && !msec_timeout)
+								msec_timeout = 1;
+							sleep_left = msec_timeout;
 							sleep_time = MIN(100,sleep_left);
-						else
+						} else
 							sleep_time = 100;
-						SHORT_SLEEP(sleep_time);
-						if (TRUE == timed)
-							sleep_left -= sleep_time;
+						if (0 < sleep_time)
+							SHORT_SLEEP(sleep_time);
 						if (outofband)
 						{
 							PIPE_DEBUG(PRINTF(" %d fixed outofband\n", pid); DEBUGPIPEFLUSH);
@@ -491,7 +522,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 											      the interrupt */
 							(TREF(pipefifo_interrupt))++;
 							outofband_action(FALSE);
-							GTMASSERT;	/* Should *never* return from outofband_action */
+							assertpro(FALSE);	/* Should *never* return from outofband_action */
 							return FALSE;	/* For the compiler.. */
 						}
 						continue; /* for now try and read again if eof or no input ready */
@@ -535,7 +566,6 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					PIPE_DEBUG(PRINTF(" %d temp= %s tot_bytes_read = %d\n", pid, temp, tot_bytes_read);
 						   DEBUGPIPEFLUSH);
 				}
-
 				if (pipe_or_fifo && outofband)
 				{
 					PIPE_DEBUG(PRINTF(" %d fixed outofband\n", pid); DEBUGPIPEFLUSH);
@@ -557,27 +587,39 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					stringpool.free += tot_bytes_read;	/* Don't step on our parade in the interrupt */
 					(TREF(pipefifo_interrupt))++;
 					outofband_action(FALSE);
-					GTMASSERT;	/* Should *never* return from outofband_action */
+					assertpro(FALSE);	/* Should *never* return from outofband_action */
 					return FALSE;	/* For the compiler.. */
 				}
 			}
-
-		} else if (!rm_ptr->pipe && !rm_ptr->fifo)
+		} else if (!rm_ptr->pipe && !rm_ptr->fifo) /* not fixed mode */
 		{	/* rms-file device */
 			if ((rm_ptr->follow) && timed)
 			{
+				/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
 				if (0 < msec_timeout)
 				{
+					/* get the current time */
+					sys_get_curr_time(&current_time);
+					time_left = sub_abs_time(&end_time, &current_time);
+					if (0 > time_left.at_sec)
+					{
+						msec_timeout = -1;
+						out_of_time = TRUE;
+					} else
+						msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+					/* make sure it terminates with out_of_time */
+					if (!out_of_time && !msec_timeout)
+						msec_timeout = 1;
 					sleep_left = msec_timeout;
 				} else
 					sleep_left = 0;
 			}
-
 			/* if zeof is set and follow is TRUE then ignore any previous zeof */
 			if (rm_ptr->follow && (TRUE == io_ptr->dollar.zeof))
 				io_ptr->dollar.zeof = FALSE;
 			do
 			{
+				/* in follow mode a read will return an EOF if no more bytes are available*/
 				if (EOF != (status = getc(filstr)))
 				{
 					inchar = (unsigned char)status;
@@ -609,12 +651,29 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 							/* if a timed read, sleep the minimum of 100 ms and sleep_left.
 							   If not a timed read then just sleep 100 ms */
 							if (TRUE == timed)
+							{
+								/* recalculate msec_timeout and sleep_left as
+								   &end_time - &current_time */
+								/* get the current time */
+								sys_get_curr_time(&current_time);
+								time_left = sub_abs_time(&end_time, &current_time);
+								if (0 > time_left.at_sec)
+								{
+									msec_timeout = -1;
+									out_of_time = TRUE;
+								} else
+									msec_timeout = (int4)(time_left.at_sec * 1000 +
+											      time_left.at_usec / 1000);
+
+								/* make sure it terminates with out_of_time */
+								if (!out_of_time && !msec_timeout)
+									msec_timeout = 1;
+								sleep_left = msec_timeout;
 								sleep_time = MIN(100,sleep_left);
-							else
+							} else
 								sleep_time = 100;
-							SHORT_SLEEP(sleep_time);
-							if (TRUE == timed)
-								sleep_left -= sleep_time;
+							if (0 < sleep_time)
+								SHORT_SLEEP(sleep_time);
 							if (outofband)
 							{
 								PIPE_DEBUG(PRINTF(" %d outofband\n", pid); DEBUGPIPEFLUSH);
@@ -634,11 +693,12 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 								pipeintr->max_bufflen = exp_width;
 								pipeintr->bytes_read = tot_bytes_read;
 								rm_ptr->mupintr = TRUE;
-								stringpool.free += tot_bytes_read;	/* Don't step on our parade
-													   in the interrupt */
+								stringpool.free += tot_bytes_read; /* Don't step on our parade
+												      in the interrupt */
 								(TREF(pipefifo_interrupt))++;
 								outofband_action(FALSE);
-								GTMASSERT;	/* Should *never* return from outofband_action */
+								/* Should *never* return from outofband_action */
+								assertpro(FALSE);
 								return FALSE;	/* For the compiler.. */
 							}
 							continue; /* for now try and read again if eof or no input ready */
@@ -742,7 +802,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					stringpool.free += tot_bytes_read;	/* Don't step on our parade in the interrupt */
 					(TREF(pipefifo_interrupt))++;
 					outofband_action(FALSE);
-					GTMASSERT;	/* Should *never* return from outofband_action */
+					assertpro(FALSE);	/* Should *never* return from outofband_action */
 					return FALSE;	/* For the compiler.. */
 				}
 			} while (bytes_count < width);
@@ -760,7 +820,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 			{	/* need to refill the buffer */
 				if (rm_ptr->follow)
 					buff_len = iorm_get_fol(io_ptr, &tot_bytes_read, &msec_timeout, timed, zint_restart,
-								&follow_timeout);
+								&follow_timeout, end_time);
 				else
 					buff_len = iorm_get(io_ptr, &blocked_in, rm_ptr->pipe, flags, &tot_bytes_read,
 						    timer_id, &msec_timeout, pipe_zero_timeout, zint_restart);
@@ -783,7 +843,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					{
 						pipeintr->end_time = end_time;
 						pipeintr->end_time_valid = TRUE;
-						cancel_timer(timer_id);		/* Worry about timer if/when we come back */
+						if (!rm_ptr->follow)
+							cancel_timer(timer_id);	/* Worry about timer if/when we come back */
 					}
 					pipeintr->max_bufflen = exp_width;
 					/* since nothing read into stringpool.free set pipeintr->bytes_read to zero
@@ -792,7 +853,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					rm_ptr->mupintr = TRUE;
 					(TREF(pipefifo_interrupt))++;
 					outofband_action(FALSE);
-					GTMASSERT;	/* Should *never* return from outofband_action */
+					assertpro(FALSE);	/* Should *never* return from outofband_action */
 					return FALSE;	/* For the compiler.. */
 				}
 				chset = io_ptr->ichset;		/* in case UTF-16 was changed */
@@ -800,6 +861,9 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 			status = tot_bytes_read = buff_len;		/* for EOF checking at the end */
 			char_ptr = rm_ptr->inbuf_off;
 
+			PIPE_DEBUG(PRINTF("iorm_readfl: inbuf: 0x%08lx, top: 0x%08lx, off: 0x%08lx\n", rm_ptr->inbuf,
+					  rm_ptr->inbuf_top,rm_ptr->inbuf_off); DEBUGPIPEFLUSH;);
+			PIPE_DEBUG(PRINTF("iorm_readfl: status: %d, width: %d", status, width); DEBUGPIPEFLUSH;);
 			if (0 < buff_len)
 			{
 				for (char_count = 0; char_count < width && char_ptr < rm_ptr->inbuf_top; char_count++)
@@ -822,7 +886,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						}
 						break;
 					case CHSET_UTF16BE:
-						if (UTF16BE_VALID(char_ptr, rm_ptr->inbuf_top, mblen))
+						if ((2 <= (mblen = (rm_ptr->inbuf_top - char_ptr))) &&
+						    UTF16BE_VALID(char_ptr, rm_ptr->inbuf_top, mblen))
 						{
 							bytes_count += mblen;
 							char_ptr += mblen;
@@ -837,7 +902,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						}
 						break;
 					case CHSET_UTF16LE:
-						if (UTF16LE_VALID(char_ptr, rm_ptr->inbuf_top, mblen))
+						if ((2 <= (mblen = (rm_ptr->inbuf_top - char_ptr))) &&
+						    UTF16LE_VALID(char_ptr, rm_ptr->inbuf_top, mblen))
 						{
 							bytes_count += mblen;
 							char_ptr += mblen;
@@ -852,7 +918,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						}
 						break;
 					default:
-						GTMASSERT;
+						assertpro(FALSE);
 					}
 				}
 				if (rm_ptr->follow && (char_count == width) && (TRUE == follow_timeout))
@@ -864,9 +930,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 				{
 					if (CHSET_UTF8 == chset)
 					{
-						if (temp != (char *)stringpool.free) /* BYPASSOK */
-						{
-							/* make sure enough space to store buffer */
+						if (!IS_AT_END_OF_STRINGPOOL(temp, 0))
+						{	/* make sure enough space to store buffer */
 							ENSURE_STP_FREE_SPACE(GTM_MB_LEN_MAX * width);
 						}
 						memcpy(stringpool.free, rm_ptr->inbuf_off, v->str.len);
@@ -917,8 +982,22 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 				/* rms-file device in follow mode */
 				if (timed)
 				{
+					/* recalculate msec_timeout and sleep_left as &end_time - &current_time */
 					if (0 < msec_timeout)
 					{
+						/* get the current time */
+						sys_get_curr_time(&current_time);
+						time_left = sub_abs_time(&end_time, &current_time);
+						if (0 > time_left.at_sec)
+						{
+							msec_timeout = -1;
+							out_of_time = TRUE;
+						} else
+							msec_timeout = (int4)(time_left.at_sec * 1000 + time_left.at_usec / 1000);
+
+						/* make sure it terminates with out_of_time */
+						if (!out_of_time && !msec_timeout)
+							msec_timeout = 1;
 						sleep_left = msec_timeout;
 					} else
 						sleep_left = 0;
@@ -937,7 +1016,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 					if (rm_ptr->follow)
 					{
 						status = iorm_get_bom_fol(io_ptr, &tot_bytes_read, &msec_timeout, timed,
-									  &bom_timeout);
+									  &bom_timeout, end_time);
 					} else
 						status = iorm_get_bom(io_ptr, &blocked_in, rm_ptr->pipe, flags, &tot_bytes_read,
 							      timer_id, &msec_timeout, pipe_zero_timeout);
@@ -958,7 +1037,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						{
 							pipeintr->end_time = end_time;
 							pipeintr->end_time_valid = TRUE;
-							cancel_timer(timer_id);	/* Worry about timer if/when we come back */
+							if (!rm_ptr->follow)
+								cancel_timer(timer_id);	/* Worry about timer if/when we come back */
 						}
 						pipeintr->max_bufflen = exp_width;
 						/* nothing copied to stringpool.free yet */
@@ -970,7 +1050,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						(TREF(pipefifo_interrupt))++;
 						PIPE_DEBUG(PRINTF(" %d utf1.1 stream outofband\n", pid); DEBUGPIPEFLUSH);
 						outofband_action(FALSE);
-						GTMASSERT;	/* Should *never* return from outofband_action */
+						assertpro(FALSE);	/* Should *never* return from outofband_action */
 						return FALSE;	/* For the compiler.. */
 					}
 					chset = io_ptr->ichset;	/* UTF16 will have changed to UTF16BE or UTF16LE */
@@ -1011,80 +1091,95 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						 *
 						 */
 
-						if (rm_ptr->follow)
+						if (rm_ptr->follow && (FALSE == bom_timeout))
 						{
-							if (FALSE == bom_timeout)
+							/* in follow mode a read will return an EOF if no more bytes are available*/
+							status = read(fildes, rm_ptr->utf_tmp_buffer, CHUNK_SIZE);
+
+							if (0 == status) /* end of file */
 							{
-								status = read(fildes, rm_ptr->utf_tmp_buffer, CHUNK_SIZE);
+								if ((TRUE == timed) && (0 >= sleep_left))
+								{
+									follow_timeout = TRUE;
+									break;
+								}
 
-								if (0 == status) /* end of file */
+								/* if a timed read, sleep the minimum of 100 ms and
+								   sleep_left. If not a timed read then just sleep
+								   100 ms */
+								if (TRUE == timed)
 								{
-									if ((TRUE == timed) && (0 >= sleep_left))
+									/* recalculate msec_timeout and sleep_left as
+									   &end_time - &current_time */
+									/* get the current time */
+									sys_get_curr_time(&current_time);
+									time_left = sub_abs_time(&end_time, &current_time);
+									if (0 > time_left.at_sec)
 									{
-										follow_timeout = TRUE;
-										break;
-									}
+										msec_timeout = -1;
+										out_of_time = TRUE;
+									} else
+										msec_timeout = (int4)(time_left.at_sec * 1000 +
+												      time_left.at_usec / 1000);
 
-									/* if a timed read, sleep the minimum of 100 ms and
-									   sleep_left. If not a timed read then just sleep 100 ms */
-									if (TRUE == timed)
-										sleep_time = MIN(100,sleep_left);
-									else
-										sleep_time = 100;
+									/* make sure it terminates with out_of_time */
+									if (!out_of_time && !msec_timeout)
+										msec_timeout = 1;
+									sleep_left = msec_timeout;
+									sleep_time = MIN(100,sleep_left);
+								} else
+									sleep_time = 100;
+								if (0 < sleep_time)
 									SHORT_SLEEP(sleep_time);
-									if (TRUE == timed)
-										sleep_left -= sleep_time;
-
-									if (outofband)
+								if (outofband)
+								{
+									PIPE_DEBUG(PRINTF(" %d utf2 stream outofband\n",
+											  pid); DEBUGPIPEFLUSH);
+									PUSH_MV_STENT(MVST_ZINTDEV);
+									mv_chain->mv_st_cont.mvs_zintdev.io_ptr = io_ptr;
+									mv_chain->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr
+										= (char *)stringpool.free;
+									mv_chain->mv_st_cont.mvs_zintdev.curr_sp_buffer.len
+										= bytes_count;
+									mv_chain->mv_st_cont.mvs_zintdev.buffer_valid =
+										TRUE;
+									pipeintr->who_saved = pipewhich_readfl;
+									if (0 < msec_timeout && NO_M_TIMEOUT !=
+									    msec_timeout)
 									{
-										PIPE_DEBUG(PRINTF(" %d utf2 stream outofband\n",
-												  pid); DEBUGPIPEFLUSH);
-										PUSH_MV_STENT(MVST_ZINTDEV);
-										mv_chain->mv_st_cont.mvs_zintdev.io_ptr = io_ptr;
-										mv_chain->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr
-											= (char *)stringpool.free;
-										mv_chain->mv_st_cont.mvs_zintdev.curr_sp_buffer.len
-											= bytes_count;
-										mv_chain->mv_st_cont.mvs_zintdev.buffer_valid =
-											TRUE;
-										pipeintr->who_saved = pipewhich_readfl;
-										if (0 < msec_timeout && NO_M_TIMEOUT !=
-										    msec_timeout)
-										{
-											pipeintr->end_time = end_time;
-											pipeintr->end_time_valid = TRUE;
-										}
-										pipeintr->max_bufflen = exp_width;
-										/* streaming mode uses bytes_count to show how many
-										   bytes are in *temp, but the interrupt re-entrant
-										   code uses bytes_read */
-										pipeintr->bytes_read = bytes_count;
-										pipeintr->bytes2read = bytes2read;
-										pipeintr->char_count = char_count;
-										pipeintr->add_bytes = add_bytes;
-										pipeintr->bytes_count = bytes_count;
-										PIPE_DEBUG(PRINTF("utf2 stream outofband "
-												  "char_bytes_read %d add_bytes "
-												  "%d bytes_count %d\n",
-												  char_bytes_read,
-												  add_bytes, bytes_count);
-											   DEBUGPIPEFLUSH);
-										rm_ptr->mupintr = TRUE;
-										/* Don't step on our parade in the interrupt */
-										stringpool.free += bytes_count;
-										(TREF(pipefifo_interrupt))++;
-										outofband_action(FALSE);
-										GTMASSERT;	/* Should *never* return from
-												   outofband_action */
-										return FALSE;	/* For the compiler.. */
+										pipeintr->end_time = end_time;
+										pipeintr->end_time_valid = TRUE;
 									}
-									continue; /* for now try and read again if eof or no input
-										     ready */
-								} else if (-1 == status && errno != EINTR)  /* error returned */
-								{
-									bytes_count = 0;
-									break;
+									pipeintr->max_bufflen = exp_width;
+									/* streaming mode uses bytes_count to show how many
+									   bytes are in *temp, but the interrupt re-entrant
+									   code uses bytes_read */
+									pipeintr->bytes_read = bytes_count;
+									pipeintr->bytes2read = bytes2read;
+									pipeintr->char_count = char_count;
+									pipeintr->add_bytes = add_bytes;
+									pipeintr->bytes_count = bytes_count;
+									PIPE_DEBUG(PRINTF("utf2 stream outofband "
+											  "char_bytes_read %d add_bytes "
+											  "%d bytes_count %d\n",
+											  char_bytes_read,
+											  add_bytes, bytes_count);
+										   DEBUGPIPEFLUSH);
+									rm_ptr->mupintr = TRUE;
+									/* Don't step on our parade in the interrupt */
+									stringpool.free += bytes_count;
+									(TREF(pipefifo_interrupt))++;
+									outofband_action(FALSE);
+									assertpro(FALSE);	/* Should *never* return from
+											   outofband_action */
+									return FALSE;	/* For the compiler.. */
 								}
+								continue; /* for now try and read again if eof or no input
+									     ready */
+							} else if (-1 == status && errno != EINTR)  /* error returned */
+							{
+								bytes_count = 0;
+								break;
 							}
 						} else
 						{
@@ -1100,7 +1195,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 						 * in utf_tot_bytes_read. */
 						/* if chunk read returned some bytes then ignore outofband.  We won't try a
 						 read again until bytes are processed*/
-						if (pipe_or_fifo && outofband && (0 >= status))
+						if ((pipe_or_fifo || rm_ptr->follow) && outofband && (0 >= status))
 						{
 							PIPE_DEBUG(PRINTF(" %d utf2 stream outofband\n", pid); DEBUGPIPEFLUSH);
 							PUSH_MV_STENT(MVST_ZINTDEV);
@@ -1115,7 +1210,8 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 								pipeintr->end_time = end_time;
 								pipeintr->end_time_valid = TRUE;
 								/* Worry about timer if/when we come back */
-								cancel_timer(timer_id);
+								if (!rm_ptr->follow)
+									cancel_timer(timer_id);
 							}
 							pipeintr->max_bufflen = exp_width;
 							/* streaming mode uses bytes_count to show how many bytes are in *temp,
@@ -1133,7 +1229,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 							stringpool.free += bytes_count;
 							(TREF(pipefifo_interrupt))++;
 							outofband_action(FALSE);
-							GTMASSERT;	/* Should *never* return from outofband_action */
+							assertpro(FALSE);	/* Should *never* return from outofband_action */
 							return FALSE;	/* For the compiler.. */
 						}
 
@@ -1334,7 +1430,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 							nextmb = UTF16BE_MBTOWC(char_start, rm_ptr->inbuf_pos, utf_code);
 						else
 							nextmb = UTF16LE_MBTOWC(char_start, rm_ptr->inbuf_pos, utf_code);
-						if (WEOF == utf_code)
+						if ( (WEOF == utf_code) || (nextmb != rm_ptr->inbuf_pos) )
 						{	/* invalid mb char */
 							SETZACANCELTIMER;
 							iorm_readfl_badchar(v, (int)((unsigned char *)temp - stringpool.free),
@@ -1380,7 +1476,7 @@ int	iorm_readfl (mval *v, int4 width, int4 timeout) /* timeout in seconds */
 							break;
 						}
 					} else
-						GTMASSERT;
+						assertpro(FALSE);
 					char_count++;
 					char_start = rm_ptr->inbuf_pos = rm_ptr->inbuf_off = rm_ptr->inbuf;
 					bytes_read = char_bytes_read = 0;
diff --git a/sr_unix/iormdef.h b/sr_unix/iormdef.h
index ee1b9bc..4d8b48f 100644
--- a/sr_unix/iormdef.h
+++ b/sr_unix/iormdef.h
@@ -135,6 +135,10 @@ typedef struct
 	int		outbufsize;	/* Size of outbuf */
 	int4		recordsize;	/* Size of record in bytes */
 	int4		padchar;	/* Character to use for padding */
+	int4		fol_bytes_read;	/* Number of bytes read from current record in utf fix mode with follow */
+	int4		last_was_timeout;	/* last read in utf fix mode with follow was a timeout */
+	int4		orig_bytes_already_read;	/* bytes_already_read from a previous read
+							   in utf fix mode with follow */
 	int		out_bytes;	/* Number of bytes output for this fixed record */
 	uint4		bom_buf_cnt;	/* Count of bytes in BOM buffer */
 	uint4		bom_buf_off;	/* Next available byte in BOM buffer */
@@ -161,9 +165,10 @@ typedef struct
 int gtm_utf_bomcheck(io_desc *iod, gtm_chset_t *chset, unsigned char *buffer, int len);
 int iorm_get_bom(io_desc *io_ptr, int *blocked_in, boolean_t ispipe, int flags, int4 *tot_bytes_read,
 		 TID timer_id, int4 *msec_timeout, boolean_t colon_zero);
-int iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed, boolean_t *bom_timeout);
+int iorm_get_bom_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed,
+		     boolean_t *bom_timeout, ABS_TIME end_time);
 int iorm_get_fol(io_desc *io_ptr, int4 *tot_bytes_read, int4 *msec_timeout, boolean_t timed, boolean_t zint_restart,
-		 boolean_t *follow_timeout);
+		 boolean_t *follow_timeout, ABS_TIME end_time);
 int iorm_get(io_desc *io_ptr, int *blocked_in, boolean_t ispipe, int flags, int4 *tot_bytes_read,
 	     TID timer_id, int4 *msec_timeout, boolean_t colon_zero, boolean_t zint_restart);
 int iorm_write_utf_ascii(io_desc *iod, char *string, int len);
diff --git a/sr_unix/iott_iocontrol.c b/sr_unix/iott_iocontrol.c
index 10ae0cb..06eb394 100644
--- a/sr_unix/iott_iocontrol.c
+++ b/sr_unix/iott_iocontrol.c
@@ -16,7 +16,6 @@
 
 #include "gtm_string.h"
 #include "io.h"
-#include "iotcpdef.h"
 
 GBLREF io_pair		io_curr_device;
 
diff --git a/sr_unix/iott_rdone.c b/sr_unix/iott_rdone.c
index c01f503..71e7f00 100644
--- a/sr_unix/iott_rdone.c
+++ b/sr_unix/iott_rdone.c
@@ -16,8 +16,7 @@
 #include <wchar.h>
 #include <signal.h>
 #include "gtm_string.h"
-
-#include "iotcp_select.h"
+#include "gtm_select.h"
 
 #include "io.h"
 #include "iottdef.h"
@@ -97,16 +96,14 @@ int	iott_rdone (mint *v, int4 timeout)	/* timeout in seconds */
 	if (tt_ptr->mupintr)
 	{	/* restore state to before job interrupt */
 		tt_state = &tt_ptr->tt_state_save;
-		if (ttwhichinvalid == tt_state->who_saved)
-			GTMASSERT;
+		assertpro(ttwhichinvalid != tt_state->who_saved);
 		if (dollar_zininterrupt)
 		{
 			tt_ptr->mupintr = FALSE;
 			tt_state->who_saved = ttwhichinvalid;
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
 		}
-		if (ttrdone != tt_state->who_saved)
-			GTMASSERT;	/* ZINTRECURSEIO should have caught */
+		assertpro(ttrdone == tt_state->who_saved);	/* ZINTRECURSEIO should have caught */
 		mv_zintdev = io_find_mvstent(io_ptr, FALSE);
 		if (NULL != mv_zintdev)
 		{
@@ -235,6 +232,7 @@ int	iott_rdone (mint *v, int4 timeout)	/* timeout in seconds */
 			}
 		} else
 			first_time = FALSE;
+		assertpro(FD_SETSIZE > tt_ptr->fildes);
 		FD_ZERO(&input_fd);
 		FD_SET(tt_ptr->fildes, &input_fd);
 		assert(FD_ISSET(tt_ptr->fildes, &input_fd) != 0);
diff --git a/sr_unix/iott_readfl.c b/sr_unix/iott_readfl.c
index e93ab9a..34356a9 100644
--- a/sr_unix/iott_readfl.c
+++ b/sr_unix/iott_readfl.c
@@ -15,8 +15,8 @@
 #include <wctype.h>
 #include <wchar.h>
 #include "gtm_string.h"
+#include "gtm_select.h"
 
-#include "iotcp_select.h"
 #include "io_params.h"
 #include "io.h"
 #include "trmdef.h"
@@ -111,7 +111,7 @@ void iott_readfl_badchar(mval *vmvalptr, wint_t *dataptr32, int datalen,
 		} else
 			vmvalptr->str.len = datalen;
 		vmvalptr->str.addr = (char *)buffer_start;
-		if (buffer_start == stringpool.free)
+		if (IS_AT_END_OF_STRINGPOOL(buffer_start, 0))
 			stringpool.free += vmvalptr->str.len;	/* The BADCHAR error after this won't do this for us */
         }
         if (NULL != strend && NULL != delimptr)
@@ -190,8 +190,7 @@ int	iott_readfl(mval *v, int4 length, int4 timeout)	/* timeout in seconds */
 	if (tt_ptr->mupintr)
 	{	/* restore state to before job interrupt */
 		tt_state = &tt_ptr->tt_state_save;
-		if (ttwhichinvalid == tt_state->who_saved)
-			GTMASSERT;
+		assertpro(ttwhichinvalid != tt_state->who_saved);
 		if (dollar_zininterrupt)
 		{
 			tt_ptr->mupintr = FALSE;
@@ -199,8 +198,7 @@ int	iott_readfl(mval *v, int4 length, int4 timeout)	/* timeout in seconds */
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
 		}
 		assert(length == tt_state->length);
-		if (ttread != tt_state->who_saved)
-			GTMASSERT;	/* ZINTRECURSEIO should have caught */
+		assertpro(ttread == tt_state->who_saved);	/* ZINTRECURSEIO should have caught */
 		mv_zintdev = io_find_mvstent(io_ptr, FALSE);
 		if (NULL != mv_zintdev && mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid)
 		{	/* looks good so use it */
@@ -363,7 +361,7 @@ int	iott_readfl(mval *v, int4 length, int4 timeout)	/* timeout in seconds */
 					tt_state->more_ptr = more_ptr;
 					memcpy(tt_state->more_buf, more_buf, SIZEOF(more_buf));
 				}
-				if (buffer_start == stringpool.free)
+				if (IS_AT_END_OF_STRINGPOOL(buffer_start, 0))
 					stringpool.free += exp_length;	/* reserve space */
 				tt_state->instr = instr;
 				tt_state->outlen = outlen;
@@ -387,6 +385,7 @@ int	iott_readfl(mval *v, int4 length, int4 timeout)	/* timeout in seconds */
 			break;
 		}
 		errno = 0;
+		assertpro(FD_SETSIZE > tt_ptr->fildes);
 		FD_ZERO(&input_fd);
 		FD_SET(tt_ptr->fildes, &input_fd);
 		assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd));
diff --git a/sr_unix/jnl_file_extend.c b/sr_unix/jnl_file_extend.c
index 90c4834..010bc38 100644
--- a/sr_unix/jnl_file_extend.c
+++ b/sr_unix/jnl_file_extend.c
@@ -82,7 +82,7 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 		csa = &FILE_INFO(jpc->region)->s_addrs;
 		break;
 	default:
-		GTMASSERT;
+		assertpro((dba_mm == jpc->region->dyn.addr->acc_meth) || (dba_bg == jpc->region->dyn.addr->acc_meth));
 	}
 	csd = csa->hdr;
 	assert(csa == cs_addrs && csd == cs_data);
@@ -129,7 +129,7 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 					 * retrying the writes. Therefore, we make the NOSPACEEXT a warning in this case.
 					 */
 					SETUP_THREADGBL_ACCESS;
-					if (!ANTICIPATORY_FREEZE_ENABLED(csa))
+					if (!INST_FREEZE_ON_NOSPC_ENABLED(csa))
 					{
 						send_msg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_NOSPACEEXT, 4,
 								JNL_LEN_STR(csd), new_blocks, avail_blocks);
@@ -305,7 +305,7 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 
 CONDITION_HANDLER(jnl_file_autoswitch_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	assert(in_jnl_file_autoswitch);
 	in_jnl_file_autoswitch = FALSE;
 	jgbl.dont_reset_gbl_jrec_time = jgbl.save_dont_reset_gbl_jrec_time;
diff --git a/sr_unix/jnlpool_init.c b/sr_unix/jnlpool_init.c
index 5437293..7eb2d55 100644
--- a/sr_unix/jnlpool_init.c
+++ b/sr_unix/jnlpool_init.c
@@ -105,10 +105,13 @@ error_def(ERR_TEXT);
 
 #define REMOVE_OR_RELEASE_SEM(NEW_IPC)										\
 {														\
-	if (NEW_IPC)												\
-		remove_sem_set(SOURCE);										\
-	else													\
-		rel_sem_immediate(SOURCE, JNL_POOL_ACCESS_SEM);							\
+	if (!skip_locks)											\
+	{													\
+		if (NEW_IPC)											\
+			remove_sem_set(SOURCE);									\
+		else												\
+			rel_sem_immediate(SOURCE, JNL_POOL_ACCESS_SEM);						\
+	}													\
 }
 
 #define	DETACH_AND_REMOVE_SHM_AND_SEM										\
@@ -290,7 +293,6 @@ void jnlpool_init(jnlpool_user pool_user, boolean_t gtmsource_startup, boolean_t
 		udi->gt_sem_ctime = semarg.buf->sem_ctime;
 	} else
 	{	/* find create time of semaphore from the file header and check if the id is reused by others */
-		assert(repl_instance.crash || jgbl.mur_rollback);
 		semarg.buf = &semstat;
 		if (-1 == semctl(repl_instance.jnlpool_semid, DB_CONTROL_SEM, IPC_STAT, semarg))
 		{
@@ -946,6 +948,12 @@ void jnlpool_init(jnlpool_user pool_user, boolean_t gtmsource_startup, boolean_t
 			 * control semaphore. So, go ahead and initialize the gtmsource_srv_latch for this source server.
 			 */
 			SET_LATCH_GLOBAL(&gtmsourcelocal_ptr->gtmsource_srv_latch, LOCK_AVAILABLE);
+#			ifdef GTM_TLS
+			/* Since the slot is reused for (possibly) a different secondary instance, reset the # of renegotiations
+			 * counter.
+			 */
+			gtmsourcelocal_ptr->num_renegotiations = 0;
+#			endif
 		}
 		if (reset_gtmsrclcl_info)
 		{	/* Initialize all fields of "gtmsource_local" that are also present in the corresponding "gtmsrc_lcl" */
diff --git a/sr_unix/jobchild_init.c b/sr_unix/jobchild_init.c
index d3df53e..91c8647 100644
--- a/sr_unix/jobchild_init.c
+++ b/sr_unix/jobchild_init.c
@@ -48,11 +48,12 @@ GBLREF uint4		process_id;
 error_def(ERR_RUNPARAMERR);
 error_def(ERR_TEXT);
 error_def(ERR_SYSCALL);
+error_def(ERR_JOBSTARTCMDFAIL);
 error_def(ERR_JOBLABOFF);
 
 CONDITION_HANDLER(job_init_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
 	NEXTCH;
 }
@@ -79,23 +80,23 @@ void jobchild_init(void)
 	 * gtm process; else, we are a child process of a job command.
 	 */
 	if ((c = GETENV(CHILD_FLAG_ENV)) && strlen(c))
-	{	/* We are a Jobbed process Get Job parameters and set up environment to run the Job command.
-		 * Clear the environment variable so that subsequent child mumps processes can start normal initialization.
-		 */
+	{	/* We are a Jobbed process Get Job parameters and set up environment to run the Job command. */
+		/* read parameters into parameter structure  - references CHILD_FLAG_ENV */
+		ojchildparms(&jparms, &job_arglist, job_args);
+		/* Clear the environment variable so that subsequent child mumps processes can start normal initialization. */
 		if (PUTENV(CLEAR_CHILD_FLAG_ENV))
 		{
 			util_out_print("Unable to clear gtmj0 process !UL exiting.", TRUE, process_id);
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 		}
-		/* read parameters into parameter structure */
-		ojchildparms(&jparms, &job_arglist, job_args);
 		/* Execute the command to be run before executing the actual M routine */
 		if (jparms.startup.len)
 		{
 			rc = SYSTEM(jparms.startup.addr);
-			if ((0 != rc))
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TEXT, 2,
-						LEN_AND_LIT("STARTUP command failed"));
+			if (-1 == rc)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_JOBSTARTCMDFAIL, 0, errno);
+			else if (0 != rc)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(2) ERR_JOBSTARTCMDFAIL, 0);
 		}
 		if(!job_addr(&jparms.routine, &jparms.label, jparms.offset,
 				(char **)&base_addr, (char **)&transfer_addr))
@@ -127,8 +128,6 @@ void jobchild_init(void)
 			free(jparms.routine.addr);
 		if (jparms.label.len)
 			free(jparms.label.addr);
-		if (jparms.logfile.len)
-			free(jparms.logfile.addr);
 	} else
 	{	/* If we are not a child, setup a dummy mumps routine */
 		if (MUMPS_RUN == invocation_mode)
diff --git a/sr_unix/joberr.h b/sr_unix/joberr.h
index b0839cb..8cb5c8b 100644
--- a/sr_unix/joberr.h
+++ b/sr_unix/joberr.h
@@ -32,11 +32,20 @@ LITDEF joberr_msg joberrs[] = {
 	LIT_AND_LEN("Job error - CHDIR error"),
 	LIT_AND_LEN("Job error in routine specification. Label and offset not found in created process"),
 	LIT_AND_LEN("Job error in setting independent session"),
+	LIT_AND_LEN("Job error in socketpair"),
 	LIT_AND_LEN("Job error in fork"),
 	LIT_AND_LEN("Job error in renaming standard output file"),
 	LIT_AND_LEN("Job error in renaming standard error file"),
 	LIT_AND_LEN("Job error in middle process to parent process pipe communication"),
 	LIT_AND_LEN("Job error in middle process to grandchild process pipe communication"),
+	LIT_AND_LEN("Job error - INPUT socket not found in socket pool"),
+	LIT_AND_LEN("Job error - OUTPUT socket not found in socket pool"),
+	LIT_AND_LEN("Job error - ERROR socket not found in socket pool"),
+	LIT_AND_LEN("Job error in copying INPUT socket descriptor"),
+	LIT_AND_LEN("Job error in copying OUTPUT socket descriptor"),
+	LIT_AND_LEN("Job error in copying ERROR socket descriptor"),
+	LIT_AND_LEN("Job error sending setup command"),
+	LIT_AND_LEN("Job error sending setup data"),
 	LIT_AND_LEN("Job child was stopped by signal"),
 	LIT_AND_LEN("Job child terminated due to signal"),
 	LIT_AND_LEN("") 	/* this is used internally to determine try-again situations */
diff --git a/sr_unix/jobexam_signal_handler.c b/sr_unix/jobexam_signal_handler.c
index 6dfc09f..8e569ba 100644
--- a/sr_unix/jobexam_signal_handler.c
+++ b/sr_unix/jobexam_signal_handler.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -36,24 +36,22 @@
 GBLREF	uint4			process_id;
 GBLREF	enum gtmImageTypes	image_type;
 GBLREF	boolean_t		need_core;
-
 DEBUG_ONLY(GBLREF boolean_t ok_to_UNWIND_in_exit_handling;)
-
 LITREF	gtmImageName		gtmImageNames[];
 
+error_def(ERR_JOBEXAMFAIL);
+error_def(ERR_KILLBYSIG);
+error_def(ERR_KILLBYSIGUINFO);
+error_def(ERR_KILLBYSIGSINFO1);
+error_def(ERR_KILLBYSIGSINFO2);
+error_def(ERR_KILLBYSIGSINFO3);
+
 void jobexam_signal_handler(int sig, siginfo_t *info, void *context)
 {
 	siginfo_t	exi_siginfo;
 	gtmsiginfo_t	signal_info;
 	gtm_sigcontext_t exi_context, *context_ptr;
 
-	error_def(ERR_KILLBYSIG);
-	error_def(ERR_KILLBYSIGUINFO);
-	error_def(ERR_KILLBYSIGSINFO1);
-	error_def(ERR_KILLBYSIGSINFO2);
-	error_def(ERR_KILLBYSIGSINFO3);
-	error_def(ERR_JOBEXAMFAIL);
-
 	if (NULL != info)
 		exi_siginfo = *info;
 	else
@@ -72,37 +70,37 @@ void jobexam_signal_handler(int sig, siginfo_t *info, void *context)
 	switch(signal_info.infotype)
 	{
 		case GTMSIGINFO_NONE:
-			send_msg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, sig);
-			gtm_putmsg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, sig);
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, sig);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, sig);
 			break;
 		case GTMSIGINFO_USER:
-			send_msg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type),
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.send_pid, signal_info.send_uid);
-			gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type),
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.send_pid, signal_info.send_uid);
 			break;
 		case GTMSIGINFO_ILOC + GTMSIGINFO_BADR:
-			send_msg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.int_iadr, signal_info.bad_vadr);
-			gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.int_iadr, signal_info.bad_vadr);
 			break;
 		case GTMSIGINFO_ILOC:
-			send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.int_iadr);
-			gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.int_iadr);
 			break;
 		case GTMSIGINFO_BADR:
-			send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.bad_vadr);
-			gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
 				 process_id, sig, signal_info.bad_vadr);
 			break;
 		default:
 			GTMASSERT;
 	}
-	send_msg(VARLSTCNT(3) ERR_JOBEXAMFAIL, 1, process_id);
+	send_msg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_JOBEXAMFAIL, 1, process_id);
 	/* Create a core to examine later. Note this handler is only enabled for two fatal core types so we don't
 	 * do any futher checking in this regard.
 	 */
@@ -115,7 +113,7 @@ void jobexam_signal_handler(int sig, siginfo_t *info, void *context)
 	 */
 	{	/* Needs new block since START_CH declares a new var used in UNWIND() */
 		int arg = 0;	/* Needed for START_CH macro if debugging enabled */
-		START_CH;
+		START_CH(TRUE);
 		DEBUG_ONLY(ok_to_UNWIND_in_exit_handling = TRUE);
 		UNWIND(NULL, NULL);
 	}
diff --git a/sr_unix/jobsp.h b/sr_unix/jobsp.h
index 4851ebc..71a50a2 100644
--- a/sr_unix/jobsp.h
+++ b/sr_unix/jobsp.h
@@ -18,6 +18,7 @@
 #define MAX_MBXNAM_LEN		16
 #define MAX_PRCNAM_LEN		15
 #define MAX_STDIOE_LEN		1024
+#define MAX_JOBPARM_LEN		1024
 #define TIMEOUT_ERROR		(MAX_SYSERR + 1)	/* a special value to differentiate it from the rest of errno's */
 
 #define CHILD_FLAG_ENV		"gtmj0"
@@ -35,6 +36,11 @@
 #define STARTUP_ENV		"gtmjb"
 #define GTMJCNT_ENV		"gtmjcnt"
 
+#define JOB_SOCKET_PREFIX		"SOCKET:"
+#define IS_JOB_SOCKET(ADDR, LEN)	((LEN >= SIZEOF(JOB_SOCKET_PREFIX)) && (0 == STRNCMP_LIT(ADDR, JOB_SOCKET_PREFIX)))
+#define JOB_SOCKET_HANDLE(ADDR)		(((char *)(ADDR)) + SIZEOF(JOB_SOCKET_PREFIX) - 1)
+#define JOB_SOCKET_HANDLE_LEN(LEN)	(LEN - SIZEOF(JOB_SOCKET_PREFIX) + 1)
+
 GBLDEF int job_errno;
 
 /********************************************************************************************************************
@@ -45,6 +51,8 @@ GBLDEF int job_errno;
  * the situations where trying again by the main thread might succeed (like errors due to insufficient
  * swap space etc..). When the middle process comes across an error that it thinks is worth trying again,
  * it adds joberr_tryagain to the main status (one of the status' upto joberr_tryagain) and exits with the new status.
+ *
+ * Additions to this enum must match the joberrs array in joberr.h.
  *********************************************************************************************************************/
 
 typedef enum
@@ -62,12 +70,21 @@ typedef enum
 	joberr_cd,
 	joberr_rtn,
 	joberr_sid,
+	joberr_sp,
 	joberr_frk,
 	joberr_stdout_rename,
 	joberr_stderr_rename,
 	joberr_pipe_mp,
 	joberr_pipe_mgc,
-	joberr_stp,
+	joberr_stdin_socket_lookup,
+	joberr_stdout_socket_lookup,
+	joberr_stderr_socket_lookup,
+	joberr_io_stdin_socket_dup,
+	joberr_io_stdout_socket_dup,
+	joberr_io_stderr_socket_dup,
+	joberr_io_setup_op_write,
+	joberr_io_setup_write,
+	joberr_stp,			/* These three should stay at the end of the enum. */
 	joberr_sig,
 	joberr_end
 } joberr_t;
@@ -81,13 +98,14 @@ typedef	struct
 {
 	mstr		input, output, error;
 	mstr		gbldir, startup, directory;
-	mstr		logfile;
 	mstr		routine;
 	mstr		label;
 	mstr		cmdline;
 	int4		baspri;
 	int4		offset;
 	job_parm	*parms;
+	size_t		input_prebuffer_size;
+	char		*input_prebuffer;
 } job_params_type;
 
 typedef enum
@@ -103,6 +121,46 @@ typedef enum
 #include "jobparams.h"
 } jp_type;
 
+typedef enum
+{
+	job_done,			/* last message */
+	job_set_params,			/* followed by a job_params_msg message */
+	job_set_parm_list,		/* followed by a job_arg_count_msg and "arg_count" job_arg_msg messages */
+	job_set_input_buffer		/* followed by a job_buffer_size_msg and a data message of "buffer_size" */
+} job_setup_op;
+
+typedef struct
+{
+	size_t		directory_len;
+	char		directory[MAX_JOBPARM_LEN];
+	size_t		gbldir_len;
+	char		gbldir[MAX_JOBPARM_LEN];
+	size_t		startup_len;
+	char		startup[MAX_JOBPARM_LEN];
+	size_t		input_len;
+	char		input[MAX_JOBPARM_LEN];
+	size_t		output_len;
+	char		output[MAX_JOBPARM_LEN];
+	size_t		error_len;
+	char		error[MAX_JOBPARM_LEN];
+	size_t		routine_len;
+	char		routine[MAX_JOBPARM_LEN];
+	size_t		label_len;
+	char		label[MAX_JOBPARM_LEN];
+	int		offset;
+	int		baspri;
+} job_params_msg;
+
+typedef size_t job_arg_count_msg;
+
+typedef struct
+{
+	ssize_t			len;				/* negative len indicates null arg */
+	char			data[MAX_JOBPARM_LEN];
+} job_arg_msg;
+
+typedef size_t job_buffer_size_msg;
+
 int ojchildioset(job_params_type *jparms);
 int ojstartchild(job_params_type *jparms, int argcnt, boolean_t *non_exit_return, int pipe_fds[]);
 void ojparams(char *p, job_params_type *job_params);
diff --git a/sr_unix/libdse.list b/sr_unix/libdse.list
index 8d6dde2..3d7da99 100644
--- a/sr_unix/libdse.list
+++ b/sr_unix/libdse.list
@@ -20,6 +20,7 @@ dse_f_free
 dse_f_key
 dse_f_reg
 dse_fdmp
+dse_find_gvt
 dse_find_roots
 dse_flush
 dse_getki
diff --git a/sr_unix/lke_ctrlc_handler.c b/sr_unix/lke_ctrlc_handler.c
index 438351d..5e28ed7 100644
--- a/sr_unix/lke_ctrlc_handler.c
+++ b/sr_unix/lke_ctrlc_handler.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,7 +29,7 @@ CONDITION_HANDLER(lke_ctrlc_handler)
 {
 	int	dummy1, dummy2;
 
-	START_CH;				/* Drive top level condition handler if we can */
+	START_CH(TRUE);				/* Drive top level condition handler if we can */
 	util_interrupt = 1;
 	if (0 == fast_lock_count && 0 == have_crit(CRIT_HAVE_ANY_REG))
 	{
diff --git a/sr_unix/lowerc_cp.sh b/sr_unix/lowerc_cp.sh
index 9b9d08e..2073c50 100644
--- a/sr_unix/lowerc_cp.sh
+++ b/sr_unix/lowerc_cp.sh
@@ -1,6 +1,6 @@
 #################################################################
 #								#
-#	Copyright 2001, 2011 Fidelity Information Services, Inc	#
+#	Copyright 2001, 2013 Fidelity Information Services, Inc	#
 #								#
 #	This source code contains the intellectual property	#
 #	of its copyright holder(s), and is made available	#
@@ -27,7 +27,7 @@ do
 				ln -s ../$newf$ext $newf$ext
 			else
 				echo $dir/$i "---> " $dir/$newf$ext
-				cp $i $dir/$newf$ext
+				cp -p $i $dir/$newf$ext
 			fi
 		}
 		fi
diff --git a/sr_unix/map_sym.c b/sr_unix/map_sym.c
index 8f53785..7549d68 100644
--- a/sr_unix/map_sym.c
+++ b/sr_unix/map_sym.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -48,6 +48,9 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
 	static MSTR_CONST(xback_sym, "gtm_ac_xback");
 	static MSTR_CONST(verify_sym, "gtm_ac_verify");
 	static MSTR_CONST(version_sym, "gtm_ac_version");
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
 	coll_lib_found = FALSE;
 	if (SS_NORMAL != (status = TRANS_LOG_NAME(fspec, &fspec_trans, buffer, SIZEOF(buffer), do_sendmsg_on_log2long)))
 		return FALSE;
@@ -60,8 +63,12 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
 			coll_lib_found = TRUE;
 			ret_collseq->argtype = 1;
 		} else
-		{	/* Warn about the missing routine */
-			gtm_putmsg(VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback_1()"), ret_collseq->act);
+		{
+			if (!TREF(skip_gtm_putmsg))
+			{	/* Warn about the missing routine */
+				gtm_putmsg_csa(CSA_ARG(NULL)
+					VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback_1()"), ret_collseq->act);
+			}
 			ERR_FGNSYM;
 		}
 	}
@@ -73,9 +80,13 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
 			{
 				coll_lib_found = TRUE;
 				ret_collseq->argtype = 0;
-			}
-			else { /* Warn about the missing routine */
-				gtm_putmsg(VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback()"), ret_collseq->act );
+			} else
+			{
+				if (!TREF(skip_gtm_putmsg))
+				{	/* Warn about the missing routine */
+					gtm_putmsg_csa(CSA_ARG(NULL)
+						VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback()"), ret_collseq->act);
+				}
 				ERR_FGNSYM;
 			}
 		} else /* Neither xform_1 or xform is found */
diff --git a/sr_unix/maskpass.c b/sr_unix/maskpass.c
index d2e7f09..33e5817 100644
--- a/sr_unix/maskpass.c
+++ b/sr_unix/maskpass.c
@@ -11,242 +11,58 @@
 #include "main_pragma.h"
 #include <stdio.h>
 #include <string.h>
-#include <sys/stat.h>
 #include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
 #include <sys/types.h>
-#include <fcntl.h>
+#include <sys/stat.h>
 #include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/mman.h>
-#ifdef USE_OPENSSL
-# include <openssl/sha.h>
-# include <openssl/evp.h>
-#elif defined USE_GCRYPT
-# include <gcrypt.h>
-#else
-# error "Unsupported encryption library. Reference implementation currently supports openssl and gcrypt"
-#endif
-#include <termios.h>
-
-#define MAX_LEN			512
-#define	FSTR_LEN		7		/* %2048s */
-#define GTM_PATH_MAX  		1024
-#define GTM_DIST		"gtm_dist"
-#define HASH_LENGTH		64	/* 512 bits = 64 bytes */
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#define HEX(a, b, len)						\
-{								\
-	int i;							\
-	for (i = 0; i < len; i+=2)				\
-		sprintf(b + i, "%02X", (unsigned char)a[i/2]);	\
-}
-
-#define SIGPROCMASK(FUNC, NEWSET, OLDSET, RC)			\
-{								\
-        do							\
-        {							\
-          RC = sigprocmask(FUNC, NEWSET, OLDSET);		\
-        } while (-1 == RC && EINTR == errno);			\
-}
-
-#define Tcsetattr(FDESC, WHEN, TERMPTR, RC, ERRNO)		\
-{								\
-	sigset_t block_ttinout;					\
-	sigset_t oldset;					\
-	int rc;							\
-	sigemptyset(&block_ttinout);				\
-	sigaddset(&block_ttinout, SIGTTIN);			\
-	sigaddset(&block_ttinout, SIGTTOU);			\
-	SIGPROCMASK(SIG_BLOCK, &block_ttinout, &oldset, rc);	\
-	do							\
-	{							\
-	   RC = tcsetattr(FDESC, WHEN, TERMPTR);		\
-	} while(-1 == RC && EINTR == errno);			\
-	ERRNO = errno;						\
-	SIGPROCMASK(SIG_SETMASK, &oldset, NULL, rc);		\
-}
-
-struct termios 			old_tty, no_echo_tty;
-
-static void maskpass(char passwd[], size_t password_len, char hash[], size_t hash_length)
-{
-	size_t	i;
-	for (i = 0; i < password_len; i++)
-		passwd[i] = passwd[i] ^ hash[i % hash_length];
-}
-
-static int echo_off()
-{
-	int	fd, status, save_errno;
-
-	fd = fileno(stdin);
-	/* Save current TTY settings */
-	status = tcgetattr(fd, &old_tty);
-	if (0 != status)
-		return 1;
-	no_echo_tty = old_tty;
-	no_echo_tty.c_lflag &= ~ECHO; /* Turn off echo */
-	Tcsetattr(fd, TCSAFLUSH, &no_echo_tty, status, save_errno);
-	return status;
-}
-
-static int echo_on()
-{
-	int	fd, status, save_errno;
-
-	fd = fileno(stdin);
-	Tcsetattr(fd, TCSAFLUSH, &old_tty, status, save_errno);
-	return status;
-}
-
-static void prompt_passwd(char passwd[])
-{
-	char		fstr[FSTR_LEN];
-	char		tmp[MAX_LEN + 1]; /* +1 for \n from fgets */
-	char		*fgets_ret;
-	int			echo_off_status;
-
-	memset(tmp, 0, MAX_LEN + 1);
-	printf("Enter Password: ");
-	echo_off_status = echo_off();
-	fgets_ret = fgets(tmp, MAX_LEN + 1, stdin);
-	tmp[strlen(tmp) - 1] = '\0'; /* remove the /n that fgets gives */
-	strncpy(passwd, tmp, MAX_LEN);
-	/* Since echo_on depends on whether echo_off succeeded or not, do echo_on only if echo_off went fine */
-	if (0 == echo_off_status)
-		echo_on();
-}
-
-static int get_hash_via_env_var(char *hash)
-{
-	int 		fd;
-	char 		*ob_key;
-	struct stat 	stat_info;
-	char 		*p;
 
-	if (NULL == (ob_key = (char *) getenv("gtm_obfuscation_key")))
-		return 1;
+#include "gtmxc_types.h"
 
-	fd = open(ob_key, O_RDONLY);
-	if (fd == -1)
-		return 1;
+#include "gtmcrypt_util.h"
 
-	if (fstat(fd, &stat_info) == -1)
-		return 1;
-
-	if (!S_ISREG(stat_info.st_mode))
-		return 1;
-
-	p = mmap(0, stat_info.st_size, PROT_READ, MAP_SHARED, fd, 0);
-	if (MAP_FAILED == p)
-		return 1;
-
-	if (-1 == close(fd))
-		return 1;
-
-#	ifdef USE_OPENSSL
-	EVP_Digest(p, stat_info.st_size, (unsigned char *)hash, NULL, EVP_sha512(), NULL);
-#	elif defined USE_GCRYPT
-	gcry_md_hash_buffer(GCRY_MD_SHA512, hash, p, stat_info.st_size );
-#	endif
-
-	/* Since we have what we want no need to check the status of the munmap */
-	munmap(p, stat_info.st_size);
-
-	return 0;
-}
-
-static int get_hash_via_username_and_inode(char *hash, char *passwd, size_t *passwd_len)
+int main()
 {
-	char		tmp[MAX_LEN], tobehashed[MAX_LEN];
-	char		mumps_ex[GTM_PATH_MAX], *user_ptr, *dist_ptr;
-	size_t		ilen;
+	char		passwd[GTM_PASSPHRASE_MAX], hex_out[GTM_PASSPHRASE_MAX * 2], mumps_exe[GTM_PATH_MAX], *env_ptr;
 	struct stat	stat_info;
+	gtm_string_t	passwd_str;
 
-	memset(tobehashed, 0, MAX_LEN);
-	memset(mumps_ex, 0, GTM_PATH_MAX);
-	/* We need $USER and $gtm_dist to be defined to do the proper masking */
-	if (NULL == (user_ptr = (char *)getenv("USER")))
-	{
-		printf("Environment variable USER not defined.\n");
-		return 1;
-	}
-	if (NULL == (dist_ptr = (char *)getenv(GTM_DIST)))
+	/* Since the obfuscated password depends on $USER and the inode of $gtm_dist/mumps, make sure all the pre-requisites are
+	 * available to this process.
+	 */
+	if (NULL == (env_ptr = (char *)getenv(USER_ENV)))
 	{
-		printf("Enivronment variable gtm_dist not defined.\n");
-		return 1;
+		printf(ENV_UNDEF_ERROR "\n", USER_ENV);
+		exit(EXIT_FAILURE);
 	}
-	snprintf(mumps_ex, GTM_PATH_MAX, "%s/%s", dist_ptr, "mumps");
-	if (0 != stat(mumps_ex, &stat_info))
+	if (NULL == (env_ptr = (char *)getenv(GTM_DIST_ENV)))
 	{
-		printf("Cannot stat %s\n", mumps_ex);
-		return 1;
+		printf(ENV_UNDEF_ERROR "\n", GTM_DIST_ENV);
+		exit(EXIT_FAILURE);
 	}
-	prompt_passwd(passwd);
-	*passwd_len = strlen(passwd);
-	strncpy(tobehashed, user_ptr, MIN(*passwd_len, MAX_LEN));
-	snprintf(tmp, MAX_LEN, "%ld", stat_info.st_ino);
-	ilen = strlen(tmp);
-	/* a potential simplification is to just concatenate the userid and inode */
-	if (ilen < *passwd_len)
-	      strncpy(tobehashed + (*passwd_len - ilen), tmp, ilen);
-	else
-	      strncpy(tobehashed, tmp, *passwd_len);
-
-#	ifdef USE_OPENSSL
-	EVP_Digest(tobehashed, *passwd_len, (unsigned char *)hash, NULL, EVP_sha512(), NULL);
-#	elif defined USE_GCRYPT
-	gcry_md_hash_buffer(GCRY_MD_SHA512, hash, tobehashed, *passwd_len );
-#	endif
-
-	return 0;
-
-}
-
-int main()
-{
-	char		passwd[MAX_LEN], hash[HASH_LENGTH], out[MAX_LEN * 2];
-	size_t		passwd_len;
-
-
-#	ifdef USE_GCRYPT
-	gcry_error_t err;
-
-	/* Initialize libgcrypt so it does not put warning messages in the syslog. */
-	if (!gcry_check_version(GCRYPT_VERSION))
+	SNPRINTF(mumps_exe, GTM_PATH_MAX, "%s/%s", env_ptr, "mumps");
+	if (0 != stat(mumps_exe, &stat_info))
 	{
-		printf("libgcrypt version mismatch. %s or higher is required.\n",
-				GCRYPT_VERSION);
-				exit(EXIT_FAILURE);
+		printf("Cannot stat %s\n", mumps_exe);
+		exit(EXIT_FAILURE);
 	}
-	/* Since we will just be hashing, secure memory is not needed. */
-	if (!(err = gcry_control(GCRYCTL_DISABLE_SECMEM,0)))
-			err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
-	if (GPG_ERR_NO_ERROR != err)
+	/* Read the password (with terminal echo turned off). */
+	if (-1 == gc_read_passwd(GTMCRYPT_DEFAULT_PASSWD_PROMPT, passwd, GTM_PASSPHRASE_MAX))
 	{
-		printf("Libgcrypt error: %s\n", gcry_strerror(err));
+		printf("%s\n", gtmcrypt_err_string);
 		exit(EXIT_FAILURE);
 	}
-#	endif
-
-	passwd_len = (size_t)-1;
-	memset(passwd, 0, MAX_LEN);
-	memset(out, 0, MAX_LEN * 2);
-
-	if (get_hash_via_env_var(hash))
-		if (get_hash_via_username_and_inode(hash, passwd, &passwd_len))
-			exit(EXIT_FAILURE);
-	if ((size_t)-1 == passwd_len)
+	/* Obfuscate the password. */
+	passwd_str.address = &passwd[0];
+	passwd_str.length = (int)STRLEN(passwd);
+	if (-1 == gc_mask_unmask_passwd(2, &passwd_str, &passwd_str))
 	{
-		prompt_passwd(passwd);
-		passwd_len = strlen(passwd);
+		printf("%s\n", gtmcrypt_err_string);
+		exit(EXIT_FAILURE);
 	}
-
-	maskpass(passwd, passwd_len, hash, HASH_LENGTH);
-	HEX(passwd, out, passwd_len * 2);
-	printf("%s\n", out);
+	/* Convert obfuscated password to a hex representation for easy viewing. */
+	GC_HEX(passwd, hex_out, passwd_str.length * 2);
+	printf("%s\n", hex_out);
 	return 0;
 }
diff --git a/sr_unix/mu_cre_file.c b/sr_unix/mu_cre_file.c
index 2b4f64c..225d1d6 100644
--- a/sr_unix/mu_cre_file.c
+++ b/sr_unix/mu_cre_file.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -105,7 +105,7 @@ unsigned char mu_cre_file(void)
 	char		*fgets_res;
 	gd_segment	*seg;
 #	ifdef GTM_CRYPT
-	char		datfile_hash[GTMCRYPT_HASH_LEN];
+	char		hash[GTMCRYPT_HASH_LEN];
 	int		gtmcrypt_errno;
 #	endif
 	ZOS_ONLY(int	realfiletag;)
@@ -241,26 +241,26 @@ unsigned char mu_cre_file(void)
 			 * Also, if the anticipatory freeze scheme is in effect at this point, we would have issued
 			 * a NOSPACECRE warning (see NOSPACEEXT message which goes through a similar transformation).
 			 * But at this point, we are guaranteed to not have access to the journal pool or csa both
-			 * of which are necessary for the ANTICIPATORY_FREEZE_ENABLED(csa) macro so we dont bother
+			 * of which are necessary for the INST_FREEZE_ON_ERROR_ENABLED(csa) macro so we dont bother
 			 * to do the warning transformation in this case.
 			 */
 			assert(NULL == jnlpool.jnlpool_ctl);
 			if (avail_blocks < blocks_for_create)
 			{
-				gtm_putmsg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), &blocks_for_create,
-					   &avail_blocks);
-				send_msg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), &blocks_for_create,
-					 &avail_blocks);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path),
+						&blocks_for_create, &avail_blocks);
+				send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path),
+						&blocks_for_create, &avail_blocks);
 				CLEANUP(EXIT_ERR);
 				return EXIT_ERR;
 			}
 			delta_blocks = avail_blocks - blocks_for_create;
 			if (delta_blocks < blocks_for_extension)
 			{
-				gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR,
-					   &blocks_for_extension, DISK_BLOCK_SIZE, &delta_blocks);
-				send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR,
-					 &blocks_for_extension, DISK_BLOCK_SIZE, &delta_blocks);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path),
+						EXTEND_WARNING_FACTOR, &blocks_for_extension, DISK_BLOCK_SIZE, &delta_blocks);
+				send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path),
+						EXTEND_WARNING_FACTOR, &blocks_for_extension, DISK_BLOCK_SIZE, &delta_blocks);
 			}
 		}
 	}
@@ -317,16 +317,16 @@ unsigned char mu_cre_file(void)
 	/* Check if this file is an encrypted database. If yes, do init */
 	if (gv_cur_region->dyn.addr->is_encrypted)
 	{
-		GTMCRYPT_HASH_GEN(cs_addrs, path, STRLEN(path), datfile_hash, gtmcrypt_errno);
+		GTMCRYPT_HASH_GEN(cs_addrs, path, STRLEN(path), hash, gtmcrypt_errno);
 		if (0 != gtmcrypt_errno)
 		{
 			GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, file.len, file.addr);
 			CLEANUP(EXIT_ERR);
 			return EXIT_ERR;
 		}
-		memcpy(cs_data->encryption_hash, datfile_hash, GTMCRYPT_HASH_LEN);
+		memcpy(cs_data->encryption_hash, hash, GTMCRYPT_HASH_LEN);
 		cs_data->is_encrypted = TRUE; /* Mark this file as encrypted */
-		ALLOC_BUFF_GET_ENCR_KEY(cs_addrs, cs_data->encryption_hash, BLK_SIZE, gtmcrypt_errno);
+		INIT_DB_ENCRYPTION(cs_addrs, cs_data, gtmcrypt_errno);
 		if (0 != gtmcrypt_errno)
 		{
 			GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, file.len, file.addr);
@@ -367,7 +367,8 @@ unsigned char mu_cre_file(void)
 		return EXIT_WRN;
 	}
 	if ((32 * 1024 - SIZEOF(shmpool_blk_hdr)) < cs_data->blk_size)
-		gtm_putmsg(VARLSTCNT(5) ERR_MUNOSTRMBKUP, 3, RTS_ERROR_STRING(path), 32 * 1024 - DISK_BLOCK_SIZE);
+		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_MUNOSTRMBKUP, 3, RTS_ERROR_STRING(path),
+				32 * 1024 - DISK_BLOCK_SIZE);
 	util_out_print("Created file !AD", TRUE, RTS_ERROR_STRING(path));
 	CLEANUP(EXIT_NRM);
 	return EXIT_NRM;
diff --git a/sr_unix/mu_extract.c b/sr_unix/mu_extract.c
index 07b0255..c946f99 100644
--- a/sr_unix/mu_extract.c
+++ b/sr_unix/mu_extract.c
@@ -50,7 +50,9 @@
 #include "gtm_conv.h"
 #include "gtm_utf8.h"
 #include "filestruct.h"
-#include "gvcst_protos.h"	/* for gvcst_root_search in GV_BIND_NAME_AND_ROOT_SEARCH macro */
+#include "hashtab_mname.h"
+#include "gvcst_protos.h"	/* for gvcst_root_search in DO_OP_GVNAME macro */
+#include "change_reg.h"		/* for change_reg call in DO_OP_GVNAME macro */
 
 GBLREF	int		(*op_open_ptr)(mval *v, mval *p, int t, mval *mspace);
 GBLREF	bool		mu_ctrlc_occurred;
@@ -65,7 +67,6 @@ GBLREF	mstr		sys_output;
 
 error_def(ERR_EXTRACTCTRLY);
 error_def(ERR_EXTRACTFILERR);
-error_def(ERR_GTMASSERT);
 error_def(ERR_MUNOACTION);
 error_def(ERR_MUNOFINISH);
 error_def(ERR_MUPCLIERR);
@@ -110,10 +111,8 @@ static readonly unsigned char no_param = (unsigned char)iop_eol;
 {									\
 	MV_FORCE_MVAL(&val, nmfield);					\
 	n2s(&val);							\
-	if (val.mvtype & MV_NUM_APPROX)					\
-		GTMASSERT;						\
-	if (val.str.len > BIN_HEADER_NUMSZ)				\
-		GTMASSERT;						\
+	assertpro(!(val.mvtype & MV_NUM_APPROX));			\
+	assertpro(BIN_HEADER_NUMSZ >= val.str.len);			\
 	for (iter = val.str.len;  iter < BIN_HEADER_NUMSZ;  iter++)	\
 		*outptr++ = '0';					\
 	memcpy(outptr, val.str.addr, val.str.len);			\
@@ -126,7 +125,7 @@ CONDITION_HANDLER(mu_extract_handler)
 	mval				op_val, op_pars;
 	unsigned char			delete_params[2] = { (unsigned char)iop_delete, (unsigned char)iop_eol };
 
-	START_CH;
+	START_CH(TRUE);
 	op_val.mvtype = op_pars.mvtype = MV_STR;
 	op_val.str.addr = (char *)outfilename;
 	op_val.str.len = filename_len;
@@ -141,7 +140,7 @@ CONDITION_HANDLER(mu_extract_handler)
 
 CONDITION_HANDLER(mu_extract_handler1)
 {
-	START_CH;
+	START_CH(TRUE);
 	util_out_print("!/MUPIP is not able to complete the extract due the the above error!/", TRUE);
 	util_out_print("!/WARNING!!!!!! Extract file !AD is incomplete!!!/",
 			TRUE, filename_len, outfilename);
@@ -153,28 +152,31 @@ void mu_extract(void)
 	int 				stat_res, truncate_res;
 	int				reg_max_rec, reg_max_key, reg_max_blk, reg_std_null_coll;
 	int				iter, format, local_errno, int_nlen;
-	boolean_t			freeze = FALSE, logqualifier, success;
+	boolean_t			freeze = FALSE, logqualifier, success, success2;
 	char				format_buffer[FORMAT_STR_MAX_SIZE],  ch_set_name[MAX_CHSET_NAME], cli_buff[MAX_LINE],
-					label_buff[LABEL_STR_MAX_SIZE], gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */
-	glist				gl_head, *gl_ptr;
+					label_buff[LABEL_STR_MAX_SIZE];
+	glist				gl_head, *gl_ptr, *next_gl_ptr;
 	gd_region			*reg, *region_top;
-	mu_extr_stats			global_total, grand_total;
+	mu_extr_stats			global_total, grand_total, spangbl_total;
 	uint4				item_code, devbufsiz, maxfield;
 	unsigned short			label_len, n_len, ch_set_len, buflen;
 	unsigned char			*outbuf, *outptr, *chptr, *leadptr;
 	struct stat                     statbuf;
 	mval				val, curr_gbl_name, op_val, op_pars;
 	mstr				chset_mstr;
+	mname_entry			gvname;
 	gtm_chset_t 			saved_out_set;
 	coll_hdr			extr_collhdr;
 	int				bin_header_size;
 	int	 			reg_no;
 	boolean_t			is_any_file_encrypted = FALSE;
+	gvnh_reg_t			*gvnh_reg;
+	gvnh_spanreg_t			*gvspan, *last_gvspan;
 #	ifdef GTM_CRYPT
-	unsigned short			hash_buff_len;
+	unsigned short			encrypted_hash_array_len;
+	unsigned char			*curr_hash_ptr, *encrypted_hash_array_ptr;
 	sgmnt_data_ptr_t		csd;
 	sgmnt_addrs			*csa;
-	muext_hash_hdr_ptr_t		hash_array;
 #	endif
 
 	/* Initialize all local character arrays to zero before using */
@@ -252,9 +254,9 @@ void mu_extract(void)
 	if (MU_FMT_BINARY == format)
 	{
 #		ifdef GTM_CRYPT
-		hash_buff_len = (SIZEOF(muext_hash_hdr) * gd_header->n_regions);
-		hash_array = (muext_hash_hdr *)malloc(hash_buff_len);
-		memset(hash_array, 0, hash_buff_len);
+		encrypted_hash_array_len = GTMCRYPT_HASH_LEN * gd_header->n_regions;
+		encrypted_hash_array_ptr = malloc(encrypted_hash_array_len);
+		memset(encrypted_hash_array_ptr, 0, encrypted_hash_array_len);
 #		endif
 		for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions,
 				reg_std_null_coll = -1, reg_no = 0;
@@ -273,22 +275,24 @@ void mu_extract(void)
 					}
 				}
 #				ifdef GTM_CRYPT
-				csa = (sgmnt_addrs *)&FILE_INFO(reg)->s_addrs;
+				csa = &FILE_INFO(reg)->s_addrs;
 				csd = csa->hdr;
-				memcpy(hash_array[reg_no].gtmcrypt_hash, csd->encryption_hash, GTMCRYPT_HASH_LEN);
 				if (csd->is_encrypted)
+				{
+					curr_hash_ptr = encrypted_hash_array_ptr + (reg_no * GTMCRYPT_HASH_LEN);
+					memcpy(curr_hash_ptr, csd->encryption_hash, GTMCRYPT_HASH_LEN);
 					is_any_file_encrypted = TRUE;
+				}
 #				endif
 			}
 		}
 		assert(-1 != reg_std_null_coll);
 	}
-	grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0;
-	global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0;
+	MU_EXTR_STATS_INIT(grand_total);
+	MU_EXTR_STATS_INIT(global_total);
 	n_len = SIZEOF(outfilename);
 	if (CLI_PRESENT == cli_present("STDOUT"))
-		/* Redirect to standard output */
-		op_val.str = sys_output;
+		op_val.str = sys_output;	/* Redirect to standard output */
 	else if (FALSE == cli_get_str("FILE", outfilename, &n_len))
 	{
 		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MUPCLIERR);
@@ -394,13 +398,15 @@ void mu_extract(void)
 #		ifdef GTM_CRYPT
 		if (is_any_file_encrypted)
 		{
-			op_val.str.addr = (char *)(&hash_buff_len);
-			op_val.str.len = SIZEOF(hash_buff_len);
+			op_val.str.addr = (char *)(&encrypted_hash_array_len);
+			op_val.str.len = SIZEOF(encrypted_hash_array_len);
 			op_write(&op_val);
-			op_val.str.addr = (char *)hash_array;
-			op_val.str.len = hash_buff_len;
+			op_val.str.addr = (char *)encrypted_hash_array_ptr;
+			op_val.str.len = encrypted_hash_array_len;
 			op_write(&op_val);
 		}
+		assert(NULL != encrypted_hash_array_ptr);
+		free(encrypted_hash_array_ptr);
 #		endif
 	} else
 	{
@@ -438,19 +444,13 @@ void mu_extract(void)
 	REVERT;
 	ESTABLISH(mu_extract_handler1);
 	success = TRUE;
-	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
+	gvspan = NULL;
+	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = next_gl_ptr)
 	{
 		if (mu_ctrly_occurred)
 			break;
-		if (mu_ctrlc_occurred)
-		{
-			gbl_name_buff[0]='^';
-			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
-			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
-				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
-			mu_ctrlc_occurred = FALSE;
-		}
-		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gl_ptr->name.str);
+		DO_OP_GVNAME(gl_ptr);
+			/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 		if (MU_FMT_BINARY == format)
 		{
 			label_len = SIZEOF(extr_collhdr);
@@ -466,32 +466,31 @@ void mu_extract(void)
 			op_write(&op_val);
 		}
 #		ifdef GTM_CRYPT
-		success = mu_extr_gblout(&gl_ptr->name,
-					 &global_total,
-					 format,
-					 hash_array,
-					 is_any_file_encrypted) && success;
+		success2 = mu_extr_gblout(gl_ptr, &global_total, format, is_any_file_encrypted);
 #		else
-		/* Note: Do not change the order of the expression below.
-		 * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all.
-		 * We want mu_extr_gblout() to be called irrespective of the value of success */
-		success = mu_extr_gblout(&gl_ptr->name, &global_total, format) && success;
+		success2 = mu_extr_gblout(gl_ptr, &global_total, format);
 #		endif
-		if (logqualifier)
+		success = success2 && success;
+		gvnh_reg = gl_ptr->gvnh_reg;
+		last_gvspan = gvspan;
+		gvspan = gvnh_reg->gvspan;
+		if (NULL != gvspan)
+		{	/* this global spans more than one region. aggregate stats across all regions */
+			if (last_gvspan != gvspan)
+				MU_EXTR_STATS_INIT(spangbl_total); /* this is the FIRST spanned region. initialize spangbl_total */
+			MU_EXTR_STATS_ADD(spangbl_total, global_total);	/* add global_total to grand_total */
+		}
+		next_gl_ptr = gl_ptr->next;
+		if ((logqualifier || mu_ctrlc_occurred) && (0 < global_total.recknt))
 		{
-			gbl_name_buff[0]='^';
-			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
-			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
-				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
+			ISSUE_RECORDSTAT_MSG(gl_ptr, global_total, PRINT_REG_TRUE);
+			if ((NULL != gvspan) && ((NULL == next_gl_ptr) || (next_gl_ptr->gvnh_reg != gvnh_reg)))
+			{	/* this is the LAST spanned region. Display summary line across all spanned regions */
+				ISSUE_RECORDSTAT_MSG(gl_ptr, spangbl_total, PRINT_REG_FALSE);
+			}
 			mu_ctrlc_occurred = FALSE;
 		}
-		grand_total.recknt += global_total.recknt;
-		if (grand_total.reclen < global_total.reclen)
-			grand_total.reclen = global_total.reclen;
-		if (grand_total.keylen < global_total.keylen)
-			grand_total.keylen = global_total.keylen;
-		if (grand_total.datalen < global_total.datalen)
-			grand_total.datalen = global_total.datalen;
+		MU_EXTR_STATS_ADD(grand_total, global_total);	/* add global_total to grand_total */
 	}
 	assert((MV_STR == op_val.mvtype) && (MV_STR == op_pars.mvtype));
 	op_val.str.addr = (char *)outfilename;;
@@ -505,14 +504,15 @@ void mu_extract(void)
 		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_EXTRACTCTRLY);
 		mupip_exit(ERR_MUNOFINISH);
 	}
-	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT("TOTAL"),
-		grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen);
-		if (MU_FMT_BINARY == format)
-	{	/*      truncate the last newline charactor flushed by op_close */
-		GTMCRYPT_ONLY(
-			if (hash_array)
-				free(hash_array);
-		)
+	if (0 < grand_total.recknt)
+	{
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT("TOTAL"),
+				grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen);
+	} else
+	{
+                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSELECT);
+		UNLINK(outfilename);
+                mupip_exit(ERR_NOSELECT);
 	}
 	mupip_exit(success ? SS_NORMAL : ERR_MUNOFINISH);
 }
diff --git a/sr_unix/mu_int_ch.c b/sr_unix/mu_int_ch.c
index c56e196..4352a64 100644
--- a/sr_unix/mu_int_ch.c
+++ b/sr_unix/mu_int_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -26,7 +26,7 @@ GBLREF gd_region	*gv_cur_region;
 
 CONDITION_HANDLER(mu_int_ch)
 {
-	START_CH
+	START_CH(TRUE);
 	if (!region)
 	{
 		db_ipcs_reset(gv_cur_region);
diff --git a/sr_unix/mu_op_open.c b/sr_unix/mu_op_open.c
index 753bbb2..62c8fe1 100644
--- a/sr_unix/mu_op_open.c
+++ b/sr_unix/mu_op_open.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -95,10 +95,10 @@ int mu_op_open(mval *v, mval *p, int t, mval *mspace)
 			tl = naml;
 			break;
 		case SS_LOG2LONG:
-			rts_error(VARLSTCNT(5) ERR_LOGTOOLONG, 3, v->str.len, v->str.addr, SIZEOF(buf1) - 1);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, v->str.len, v->str.addr, SIZEOF(buf1) - 1);
 			break;
 		default:
-			rts_error(VARLSTCNT(1) stat);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) stat);
 		}
 	}
 	stat = mu_open_try(naml, tl, p, mspace);
@@ -161,7 +161,7 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 				if (-1 == fstat_res)
 				{
 					save_errno = errno;
-					rts_error(VARLSTCNT(8) ERR_SYSCALL, 5,
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 						  RTS_ERROR_LITERAL("fstat()"),
 						  CALLFROM, save_errno);
 				}
@@ -174,7 +174,7 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 					if (-1 == fstat_res)
 					{
 						save_errno = errno;
-						rts_error(VARLSTCNT(8) ERR_SYSCALL, 5,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 							  RTS_ERROR_LITERAL("fstat()"),
 							  CALLFROM, save_errno);
 					}
@@ -191,7 +191,7 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 					else
 					{
 						save_errno = errno;
-						rts_error(VARLSTCNT(8) ERR_SYSCALL, 5,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 							  RTS_ERROR_LITERAL("fstat()"),
 							  CALLFROM, save_errno);
 					}
@@ -225,7 +225,7 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 	} else
 		iod = naml->iod;
 	active_device = iod;
-	if ((-2 == file_des) && (dev_open != iod->state) && (us != iod->type) && (tcp != iod->type))
+	if ((-2 == file_des) && (dev_open != iod->state) && (us != iod->type))
 	{
 		oflag |= (O_RDWR | O_CREAT | O_NOCTTY);
 		p_offset = 0;
@@ -345,7 +345,6 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 		if (-1 == file_des)
 			return FALSE;
 	}
-	assert (tcp != iod->type);
 #ifdef KEEP_zOS_EBCDIC
 	SET_CODE_SET(iod->in_code_set, OUTSIDE_CH_SET);
 	if (DEFAULT_CODE_SET != iod->in_code_set)
@@ -357,7 +356,7 @@ static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspa
 	/* smw 99/12/18 not possible to be -1 here */
 	if (-1 == file_des)
 	{
-		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
 			  RTS_ERROR_LITERAL("open()"),
 			  CALLFROM, save_errno);
 	}
diff --git a/sr_unix/mu_rndwn_all.c b/sr_unix/mu_rndwn_all.c
index b97a907..bd018cf 100644
--- a/sr_unix/mu_rndwn_all.c
+++ b/sr_unix/mu_rndwn_all.c
@@ -63,8 +63,10 @@
 
 #define PRINT_AND_SEND_SHMREMOVED_MSG(MSGBUFF, FNAME_LEN, FNAME, SHMID)							\
 {															\
-	gtm_putmsg(VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_SHMREMOVED, 3, SHMID, FNAME_LEN, FNAME);		\
-	send_msg(VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_SHMREMOVED, 3, SHMID, FNAME_LEN, FNAME);		\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), 					\
+			ERR_SHMREMOVED, 3, SHMID, FNAME_LEN, FNAME);							\
+	send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), 					\
+			ERR_SHMREMOVED, 3, SHMID, FNAME_LEN, FNAME);							\
 }
 
 #define PRINT_AND_SEND_REPLPOOL_FAILURE_MSG(MSGBUFF, REPLPOOL_ID, SHMID)						\
@@ -75,19 +77,22 @@
 	ipcs_ptr = i2asc(ipcs_buff, SHMID);										\
 	*ipcs_ptr = '\0';												\
 	msgid = (JNLPOOL_SEGMENT == REPLPOOL_ID->pool_type) ? ERR_MUJPOOLRNDWNFL : ERR_MURPOOLRNDWNFL;			\
-	gtm_putmsg(VARLSTCNT(10) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), msgid, 4, LEN_AND_STR(ipcs_buff),			\
-			LEN_AND_STR(REPLPOOL_ID->instfilename));							\
-	send_msg(VARLSTCNT(10) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), msgid, 4, LEN_AND_STR(ipcs_buff),			\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), 					\
+				msgid, 4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(REPLPOOL_ID->instfilename));		\
+	send_msg_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), msgid, 4, LEN_AND_STR(ipcs_buff),	\
 			LEN_AND_STR(REPLPOOL_ID->instfilename));							\
 }
 
 #define PRINT_AND_SEND_DBRNDWN_FAILURE_MSG(MSGBUFF, FNAME, SHMID)							\
 {															\
-	gtm_putmsg(VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_MUFILRNDWNFL2, 3, SHMID, LEN_AND_STR(FNAME));	\
-	send_msg(VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_MUFILRNDWNFL2, 3, SHMID, LEN_AND_STR(FNAME));	\
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_MUFILRNDWNFL2, 3, 		\
+			SHMID, LEN_AND_STR(FNAME));									\
+	send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_TEXT, 2, LEN_AND_STR(MSGBUFF), ERR_MUFILRNDWNFL2, 3, 		\
+			SHMID, LEN_AND_STR(FNAME));									\
 }
 
 GBLREF gd_region        *gv_cur_region;
+GBLREF semid_queue_elem	*keep_semids;
 
 LITREF char             gtm_release_name[];
 LITREF int4             gtm_release_name_len;
@@ -119,7 +124,7 @@ STATICDEF	boolean_t	mu_rndwn_all_helper_error = FALSE;
  */
 CONDITION_HANDLER(mu_rndwn_all_helper_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	mu_rndwn_all_helper_error = TRUE;
 	PRN_ERROR;
 	if (SEVERITY == SEVERE)
@@ -144,9 +149,12 @@ STATICFNDEF void mu_rndwn_all_helper(shm_parms *parm_buff, char *fname, int *exi
 			gv_cur_region->dyn.addr->fname_len = strlen(fname);
 			STRNCPY_STR(gv_cur_region->dyn.addr->fname, fname, gv_cur_region->dyn.addr->fname_len);
 			if (mu_rndwn_file(gv_cur_region, FALSE))
-				gtm_putmsg(VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
 			else
+			{	/* Save semid so that it will not be removed by mu_rndwn_sem_all() */
+				add_to_semids_list(FILE_INFO(gv_cur_region)->semid);
 				*exit_status = ERR_MUNOTALLSEC;
+			}
 			mu_gv_cur_reg_free();
 		} else
 		{	/* shm has been cleaned up by "validate_db_shm_entry" so no need of any more cleanup here */
@@ -162,7 +170,7 @@ STATICFNDEF void mu_rndwn_all_helper(shm_parms *parm_buff, char *fname, int *exi
 			ret_status = mu_rndwn_repl_instance(&replpool_id, TRUE, FALSE, &jnlpool_sem_created);
 			ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, parm_buff->shmid);
 			*ipcs_ptr = '\0';
-			gtm_putmsg(VARLSTCNT(6) (JNLPOOL_SEGMENT == replpool_id.pool_type) ?
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) (JNLPOOL_SEGMENT == replpool_id.pool_type) ?
 				(ret_status ? ERR_MUJPOOLRNDWNSUC : ERR_MUJPOOLRNDWNFL) :
 				(ret_status ? ERR_MURPOOLRNDWNSUC : ERR_MURPOOLRNDWNFL),
 				4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(replpool_id.instfilename));
@@ -188,7 +196,7 @@ int mu_rndwn_all(void)
 	if (NULL == (pf = POPEN(IPCS_CMD_STR ,"r")))
         {
 		save_errno = errno;
-		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
                 return ERR_MUNOTALLSEC;
         }
 	fname = (char *)malloc(MAX_FN_LEN + 1);
@@ -286,7 +294,7 @@ boolean_t validate_db_shm_entry(shm_parms *parm_buff, char *fname, int *exit_sta
 		assert(FALSE);/* we were able to attach to this shmid before so should be able to get stats on it */
 		util_out_print("!AD -> Error with shmctl for shmid = !UL",
 			TRUE, fname_len, fname, shmid);
-		gtm_putmsg(VARLSTCNT(1) save_errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 		*exit_stat = ERR_MUNOTALLSEC;
 		shmdt((void *)start_addr);
 		return FALSE;
@@ -314,7 +322,7 @@ boolean_t validate_db_shm_entry(shm_parms *parm_buff, char *fname, int *exit_sta
 			save_errno = errno;
 			util_out_print("Cannot rundown shmid !UL for database file !AD as stat() on the file"
 				" returned the following error", TRUE, shmid, fname_len, fname);
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			shmdt((void *)start_addr);
 			return FALSE;
@@ -330,7 +338,7 @@ boolean_t validate_db_shm_entry(shm_parms *parm_buff, char *fname, int *exit_sta
 		if (SS_NORMAL != status)
 		{
 			util_out_print("!AD -> Error with dbfilop for shmid = !UL", TRUE, fname_len, fname, shmid);
-			gtm_putmsg(VARLSTCNT(5) status, 2, DB_LEN_STR(gv_cur_region), errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) status, 2, DB_LEN_STR(gv_cur_region), errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			shmdt((void *)start_addr);
 			return FALSE;
@@ -341,7 +349,7 @@ boolean_t validate_db_shm_entry(shm_parms *parm_buff, char *fname, int *exit_sta
 		{
 			save_errno = errno;
 			util_out_print("!AD -> Error with LSEEKREAD for shmid = !UL", TRUE, fname_len, fname, shmid);
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			shmdt((void *)start_addr);
 			return FALSE;
@@ -380,10 +388,10 @@ boolean_t validate_db_shm_entry(shm_parms *parm_buff, char *fname, int *exit_sta
 		if (0 != shm_rmid(shmid))
 		{
 			save_errno = errno;
-			gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fname_len, fname,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_DBFILERR, 2, fname_len, fname,
 				   ERR_TEXT, 2, RTS_ERROR_TEXT("Error removing shared memory"));
 			util_out_print("!AD -> Error removing shared memory for shmid = !UL", TRUE, fname_len, fname, shmid);
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			return FALSE;
 		}
@@ -461,7 +469,7 @@ boolean_t validate_replpool_shm_entry(shm_parms *parm_buff, replpool_id_ptr_t re
 		assert(FALSE);/* we were able to attach to this shmid before so should be able to get stats on it */
 		util_out_print("!AD -> Error with shmctl for shmid = !UL",
 				TRUE, LEN_AND_STR(instfilename), shmid);
-		gtm_putmsg(VARLSTCNT(1) save_errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 		*exit_stat = ERR_MUNOTALLSEC;
 		shmdt((void *)start_addr);
 		return FALSE;
@@ -493,7 +501,7 @@ boolean_t validate_replpool_shm_entry(shm_parms *parm_buff, replpool_id_ptr_t re
 			util_out_print("Cannot rundown replpool shmid !UL for instance file"
 				" !AD as open() on the file returned the following error",
 				TRUE, shmid, LEN_AND_STR(instfilename));
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			shmdt((void *)start_addr);
 			return FALSE;
@@ -506,7 +514,7 @@ boolean_t validate_replpool_shm_entry(shm_parms *parm_buff, replpool_id_ptr_t re
 			save_errno = errno;
 			util_out_print("!AD -> Error with LSEEKREAD for shmid = !UL", TRUE,
 				LEN_AND_STR(instfilename), shmid);
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			shmdt((void *)start_addr);
 			return FALSE;
@@ -537,7 +545,7 @@ boolean_t validate_replpool_shm_entry(shm_parms *parm_buff, replpool_id_ptr_t re
 			save_errno = errno;
 			util_out_print("!AD -> Error removing shared memory for shmid = !UL",
 				TRUE, LEN_AND_STR(instfilename), shmid);
-			gtm_putmsg(VARLSTCNT(1) save_errno);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) save_errno);
 			*exit_stat = ERR_MUNOTALLSEC;
 			return FALSE;
 		}
@@ -664,7 +672,7 @@ int mu_rndwn_sem_all(void)
 	if (NULL == (pf = POPEN(IPCS_SEM_CMD_STR ,"r")))
         {
 		save_errno = errno;
-		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
                 return ERR_MUNOTALLSEC;
         }
 	while (NULL != (FGETS(entry, SIZEOF(entry), pf, fgets_res)) && entry[0] != '\n')
@@ -672,11 +680,11 @@ int mu_rndwn_sem_all(void)
 		if (-1 != (semid = parse_sem_id(entry)))
 		{
 			if (is_orphaned_gtm_semaphore(semid))
-			{
+			{	/* semval == 0 and corresponding shared memory has been removed */
 				if (-1 != semctl(semid, 0, IPC_RMID))
 				{
-					gtm_putmsg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
-					send_msg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
+					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
 				}
 			}
 		}
@@ -684,6 +692,7 @@ int mu_rndwn_sem_all(void)
 	pclose(pf);
 	return exit_status;
 }
+
 boolean_t is_orphaned_gtm_semaphore(int semid)
 {
 	int			semno, semval;
@@ -702,7 +711,34 @@ boolean_t is_orphaned_gtm_semaphore(int semid)
 				if (-1 == (semval = semctl(semid, semno, GETVAL)) || semval)
 					return FALSE;
 		}
-		return TRUE;
+		/* We know that the semvals are 0, and this is a GTM semaphore. Now, we can remove it if it is not specifically
+		 * meant to be kept.
+		 */
+		return  !in_keep_sems_list(semid);
 	}
 	return FALSE;
 }
+
+boolean_t in_keep_sems_list(int semid)
+{
+	semid_queue_elem	*iter;
+
+	iter = keep_semids;
+	while (iter)
+	{
+		if (iter->semid == semid)
+			return TRUE;
+		iter = iter->prev;
+	}
+	return FALSE;
+}
+
+void add_to_semids_list(int semid)
+{
+	semid_queue_elem	*new_semid_elem;
+
+	new_semid_elem = (semid_queue_elem*) malloc(SIZEOF(semid_queue_elem));
+	new_semid_elem->semid = semid;
+	new_semid_elem->prev = keep_semids;
+	keep_semids = new_semid_elem;
+}
diff --git a/sr_unix/mu_rndwn_all.h b/sr_unix/mu_rndwn_all.h
index f650317..823fa46 100644
--- a/sr_unix/mu_rndwn_all.h
+++ b/sr_unix/mu_rndwn_all.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,9 +12,16 @@
 #ifndef MU_RNDWN_ALL_INCLUDED
 #define MU_RNDWN_ALL_INCLUDED
 
+typedef struct semid_queue_elem_t
+{
+	int4 semid;
+	struct semid_queue_elem_t *prev;
+} semid_queue_elem;
+
 int mu_rndwn_all(void);
 int mu_rndwn_sem_all(void);
 int parse_sem_id(char *);
 boolean_t is_orphaned_gtm_semaphore(int);
-
+boolean_t in_keep_sems_list(int semid);
+void add_to_semids_list(int semid);
 #endif /* MU_RNDWN_ALL_INCLUDED */
diff --git a/sr_unix/mu_rndwn_file.c b/sr_unix/mu_rndwn_file.c
index 424250d..4a35255 100644
--- a/sr_unix/mu_rndwn_file.c
+++ b/sr_unix/mu_rndwn_file.c
@@ -173,21 +173,6 @@ error_def(ERR_VERMISMATCH);
 	}															\
 }
 
-#define REMOVE_SEMID_IF_ORPHANED(REG, UDI, TSD, SEM_CREATED, SEM_INCREMENTED)							\
-{																\
-	if (is_orphaned_gtm_semaphore(UDI->semid))										\
-	{															\
-		if (0 != sem_rmid(UDI->semid))											\
-		{														\
-			RNDWN_ERR("!AD -> Error removing semaphore.", reg);							\
-			CLNUP_AND_RETURN(REG, UDI, TSD, SEM_CREATED, SEM_INCREMENTED);						\
-		}														\
-		send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, UDI->semid);					\
-		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, UDI->semid);					\
-		UDI->semid = INVALID_SEMID;											\
-	}															\
-}
-
 /* Print an error message that, based on whether replication was enabled at the time of the crash, would instruct
  * the user to a more appropriate operation than RUNDOWN, such as RECOVER or REQROLLBACK.
  */
@@ -322,7 +307,6 @@ boolean_t mu_rndwn_file(gd_region *reg, boolean_t standalone)
 #	endif
 	CSD2UDI(tsd, udi);
 	semarg.buf = &semstat;
-	REMOVE_SEMID_IF_ORPHANED(reg, udi, tsd, sem_created, udi->counter_acc_incremented);
 	if (INVALID_SEMID == udi->semid || (-1 == semctl(udi->semid, DB_CONTROL_SEM, IPC_STAT, semarg)) ||
 #		ifdef GTM64
 		(((tsd->gt_sem_ctime.ctime & 0xffffffff) == 0) && ((tsd->gt_sem_ctime.ctime >> 32) != semarg.buf->sem_ctime)) ||
@@ -529,12 +513,17 @@ boolean_t mu_rndwn_file(gd_region *reg, boolean_t standalone)
 					CLNUP_AND_RETURN(reg, udi, tsd, sem_created, udi->counter_acc_incremented);
 				}
 				udi->counter_acc_incremented = FALSE;
-				if (sem_created && (0 != sem_rmid(udi->semid)))
+				if (0 != sem_rmid(udi->semid))
 				{
 					assert(FALSE); /* We've created the semaphore, so we should be able to remove it */
 					RNDWN_ERR("!AD -> Error removing semaphore.", reg);
 					CLNUP_AND_RETURN(reg, udi, tsd, sem_created, udi->counter_acc_incremented);
 				}
+				if (!sem_created)
+				{
+					send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, udi->semid);
+					gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, udi->semid);
+				}
 				sem_created = FALSE;
 				udi->grabbed_access_sem = FALSE;
 				udi->semid = INVALID_SEMID; /* "orphaned" and "newly" created semaphores are now removed */
@@ -955,6 +944,7 @@ boolean_t mu_rndwn_file(gd_region *reg, boolean_t standalone)
 				free(tsd);
 				tsd = NULL;
 			}
+#			if !defined(_AIX)
 			if (dba_mm == acc_meth)
 			{
 				assert(0 != mmap_sz);
@@ -969,6 +959,7 @@ boolean_t mu_rndwn_file(gd_region *reg, boolean_t standalone)
 					CLNUP_AND_RETURN(reg, udi, tsd, sem_created, udi->counter_acc_incremented);
 				}
 			}
+#			endif
 		} else
 			glob_sec_init = FALSE;
 	} else
@@ -1039,10 +1030,15 @@ boolean_t mu_rndwn_file(gd_region *reg, boolean_t standalone)
 			RNDWN_ERR("!AD -> Error removing semaphore.", reg);
 			CLNUP_AND_RETURN(reg, udi, tsd, sem_created, udi->counter_acc_incremented);
 		}
-		sem_created = FALSE;
+		if (!sem_created)
+		{
+			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, udi->semid);
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(3) ERR_SEMREMOVED, 1, udi->semid);
+		}
 		udi->grabbed_access_sem = FALSE;
 		udi->counter_acc_incremented = FALSE;
 		udi->semid = INVALID_SEMID;
+		sem_created = FALSE;
 	}
 	REVERT;
 	RESET_GV_CUR_REGION;
@@ -1065,7 +1061,7 @@ CONDITION_HANDLER(mu_rndwn_file_ch)
 	unix_db_info	*udi;
 	sgmnt_addrs	*csa;
 
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
 	assert(NULL != rundown_reg);
 	if (NULL != rundown_reg)
diff --git a/sr_unix/mu_rndwn_repl_instance.c b/sr_unix/mu_rndwn_repl_instance.c
index b16b1de..732f0df 100644
--- a/sr_unix/mu_rndwn_repl_instance.c
+++ b/sr_unix/mu_rndwn_repl_instance.c
@@ -99,7 +99,7 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 	unix_db_info		*udi;
 	int			save_errno, sem_id, shm_id, status;
 	sgmnt_addrs		*repl_csa;
-	boolean_t		was_crit;
+	boolean_t		was_crit, remove_sem;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -177,8 +177,9 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 				ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, shm_id);
 				*ipcs_ptr = '\0';
 				if (rndwn_both_pools && ((SS_NORMAL != jnlpool_stat) || ipc_rmvd))
-					gtm_putmsg(VARLSTCNT(6) (jnlpool_stat ? ERR_MUJPOOLRNDWNFL : ERR_MUJPOOLRNDWNSUC),
-						4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6)
+							(jnlpool_stat ? ERR_MUJPOOLRNDWNFL : ERR_MUJPOOLRNDWNSUC),
+							4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename));
 			}
 			assert(ipc_rmvd || (NULL != jnlpool_ctl));
 			assert((NULL == jnlpool.jnlpool_ctl) || (SS_NORMAL == jnlpool_stat) || jgbl.onlnrlbk);
@@ -191,8 +192,10 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 				 */
 				if (NULL == jnlpool_ctl)
 				{
-					if (((sem_created || (SS_NORMAL == jnlpool_stat))
-						&& (SS_NORMAL == mu_replpool_release_sem(&repl_instance, JNLPOOL_SEGMENT, TRUE))))
+					remove_sem = sem_created || (SS_NORMAL == jnlpool_stat);
+					if (!remove_sem)
+						add_to_semids_list(repl_instance.jnlpool_semid);
+					if (SS_NORMAL == mu_replpool_release_sem(&repl_instance, JNLPOOL_SEGMENT, remove_sem))
 					{	/* Now that semaphores are removed, reset fields in file header */
 						if (!sem_created)
 						{	/* If sem_id was created by mu_replpool_grab_sem then do NOT report the
@@ -203,8 +206,9 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 							 */
 							ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, sem_id);
 							*ipcs_ptr = '\0';
-							gtm_putmsg(VARLSTCNT(9) ERR_MUJPOOLRNDWNSUC, 4, LEN_AND_STR(ipcs_buff),
-								LEN_AND_STR(instfilename), ERR_SEMREMOVED, 1, sem_id);
+							gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_MUJPOOLRNDWNSUC, 4,
+									LEN_AND_STR(ipcs_buff),
+									LEN_AND_STR(instfilename), ERR_SEMREMOVED, 1, sem_id);
 						}
 						repl_inst_jnlpool_reset();
 					}
@@ -222,25 +226,13 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 						repl_inst_write(instfilename, (off_t)0, (sm_uc_ptr_t)&repl_instance,
 									SIZEOF(repl_inst_hdr));
 				}
-				/* If semaphore is not created and the journal pool rundown failed (due to attached processes),
-				 * rundown process continues to holds the journal pool access control semaphore. This way, we hold
-				 * the semaphore on behalf of the source server (now no longer alive) to prevent mu_rndwn_sem_all
-				 * (invoked later) from cleaning up this orphaned semaphore (which causes REPLREQROLLBACK if the
-				 * source server is restarted). But, since the semaphore is not released (until the rundown process
-				 * dies), holds_sem[SOURCE][JNL_POOL_ACCESS_SEM] continues to remain TRUE. This causes asserts in
-				 * ftok_sem_get if mu_rndwn_repl_instance is invoked for a different journal/receive pool. To
-				 * workaround it, set holds_sem[SOURCE][JNL_POOL_ACCESS_SEM] to FALSE. This is an interim solution
-				 * until we record such semaphores in an ignore-list (or some such) and change mu_rndwn_sem_all to
-				 * skip the ones that are present in the ignore list.
-				 */
-				holds_sem[SOURCE][JNL_POOL_ACCESS_SEM] = FALSE;
 			}
 		} else if (rndwn_both_pools && (INVALID_SHMID != shm_id))
 		{
 			ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, shm_id);
 			*ipcs_ptr = '\0';
 			if (rndwn_both_pools)
-				gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
 					LEN_AND_STR(instfilename));
 		}
 		*jnlpool_sem_created = sem_created;
@@ -273,8 +265,9 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 				ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, shm_id);
 				*ipcs_ptr = '\0';
 				if (rndwn_both_pools && ((SS_NORMAL != recvpool_stat) || ipc_rmvd))
-					gtm_putmsg(VARLSTCNT(6) (recvpool_stat ? ERR_MURPOOLRNDWNFL : ERR_MURPOOLRNDWNSUC),
-						4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename));
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6)
+							(recvpool_stat ? ERR_MURPOOLRNDWNFL : ERR_MURPOOLRNDWNSUC),
+							4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename));
 			}
 			assert((TRUE == ipc_rmvd) || (SS_NORMAL != recvpool_stat) || jgbl.onlnrlbk);
 			assert((INVALID_SHMID != repl_instance.recvpool_shmid) || (0 == repl_instance.recvpool_shmid_ctime));
@@ -284,8 +277,10 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 			{	/* Invoked by MUPIP RUNDOWN in which case the semaphores needs to be removed. But, remove the
 				 * semaphore ONLY if we created it here OR the receive pool was successfully removed.
 				 */
-				if ((sem_created || (SS_NORMAL == recvpool_stat))
-					&& (SS_NORMAL == mu_replpool_release_sem(&repl_instance, RECVPOOL_SEGMENT, TRUE)))
+				remove_sem = sem_created || (SS_NORMAL == jnlpool_stat);
+				if (!remove_sem)
+					add_to_semids_list(repl_instance.jnlpool_semid);
+				if (SS_NORMAL == mu_replpool_release_sem(&repl_instance, RECVPOOL_SEGMENT, remove_sem))
 				{	/* Now that semaphores are removed, reset fields in file header */
 					if (!sem_created)
 					{	/* if sem_id was "created" by mu_replpool_grab_sem then do NOT report the
@@ -296,8 +291,9 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 						 */
 						ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, sem_id);
 						*ipcs_ptr = '\0';
-						gtm_putmsg(VARLSTCNT(9) ERR_MURPOOLRNDWNSUC, 4, LEN_AND_STR(ipcs_buff),
-							LEN_AND_STR(instfilename), ERR_SEMREMOVED, 1, sem_id);
+						gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_MURPOOLRNDWNSUC, 4,
+								LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename),
+								ERR_SEMREMOVED, 1, sem_id);
 					}
 					if (NULL != jnlpool_ctl)
 					{	/* Journal pool is not yet removed. So, grab lock before resetting semid/shmid
@@ -321,26 +317,14 @@ boolean_t mu_rndwn_repl_instance(replpool_identifier *replpool_id, boolean_t imm
 					if ((NULL != jnlpool_ctl) && !was_crit)
 						rel_lock(jnlpool.jnlpool_dummy_reg);
 				}
-				/* If semaphore is not created and the receive pool rundown failed (due to attached processes),
-				 * rundown process continues to holds the receive pool access control semaphore. This way, we hold
-				 * the semaphore on behalf of the receiver server (now no longer alive) to prevent mu_rndwn_sem_all
-				 * (invoked later) from cleaning up this orphaned semaphore (which causes REPLREQROLLBACK if the
-				 * receiver is restarted). But, since the semaphore is not released (until the rundown process
-				 * dies), holds_sem[RECV][RECV_POOL_ACCESS_SEM] continues to remain TRUE. This causes asserts in
-				 * ftok_sem_get if mu_rndwn_repl_instance is invoked for a different journal/receive pool. To
-				 * workaround it, set holds_sem[SOURCE][RECV_POOL_ACCESS_SEM] to FALSE. This is an interim solution
-				 * until we record such semaphores in an ignore-list (or some such) and change mu_rndwn_sem_all to
-				 * skip the ones that are present in the ignore list.
-				 */
-				assert((sem_created || (SS_NORMAL == recvpool_stat)) || holds_sem[RECV][RECV_POOL_ACCESS_SEM]);
-				DEBUG_ONLY(set_sem_set_recvr(sem_id));
+				assert(!holds_sem[RECV][RECV_POOL_ACCESS_SEM]);
 			}
 		} else if (rndwn_both_pools && (INVALID_SHMID != shm_id))
 		{
 			ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, shm_id);
 			*ipcs_ptr = '\0';
 			if (rndwn_both_pools)
-				gtm_putmsg(VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
 					LEN_AND_STR(instfilename));
 		}
 	}
@@ -389,7 +373,7 @@ CONDITION_HANDLER(mu_rndwn_repl_instance_ch)
 	sgmnt_addrs	*csa;
 	gd_region	*reg;
 
-	START_CH;
+	START_CH(TRUE);
 	reg = jnlpool.jnlpool_dummy_reg;
 	assert(NULL != reg);
 	if (NULL != reg)
diff --git a/sr_unix/mu_rndwn_replpool.c b/sr_unix/mu_rndwn_replpool.c
index ae3cad7..350e614 100644
--- a/sr_unix/mu_rndwn_replpool.c
+++ b/sr_unix/mu_rndwn_replpool.c
@@ -254,7 +254,7 @@ CONDITION_HANDLER(mu_rndwn_replpool_ch)
 	int			status, save_errno;
 	repl_inst_hdr_ptr_t	inst_hdr;
 
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR; /* flush the error string */
 	if (SEVERITY == SEVERE)
 		NEXTCH;
diff --git a/sr_unix/mu_size_arsample.c b/sr_unix/mu_size_arsample.c
index fdcf001..79b9c7a 100644
--- a/sr_unix/mu_size_arsample.c
+++ b/sr_unix/mu_size_arsample.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -46,6 +46,7 @@
 #include "sleep_cnt.h"
 #include "wcs_sleep.h"
 #include "memcoherency.h"
+#include "change_reg.h"
 
 #include "gtm_time.h"
 #include "mvalconv.h"
@@ -132,7 +133,7 @@ STATICFNDCL void accum_stats_ar(stat_t *stat, double *r, boolean_t ar);
 }
 
 
-int4 mu_size_arsample(mval *gn, uint4 M, boolean_t ar, int seed)
+int4 mu_size_arsample(glist *gl_ptr, uint4 M, boolean_t ar, int seed)
 {
 	enum cdb_sc		status;
 	trans_num		ret_tn;
@@ -146,10 +147,11 @@ int4 mu_size_arsample(mval *gn, uint4 M, boolean_t ar, int seed)
 
 	SETUP_THREADGBL_ACCESS;
 	inctn_opcode = inctn_invalid_op;
-	op_gvname(VARLSTCNT(1) gn);
+	DO_OP_GVNAME(gl_ptr);
+		/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 	if (0 == gv_target->root)
         {       /* Global does not exist (online rollback). Not an error. */
-                gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
                 return EXIT_NRM;
         }
 	if (!seed)
@@ -180,7 +182,8 @@ int4 mu_size_arsample(mval *gn, uint4 M, boolean_t ar, int seed)
 				ABORT_TRANS_IF_GBL_EXIST_NOMORE(lcl_t_tries, tn_aborted);
 				if (tn_aborted)
 				{	/* Global does not exist (online rollback). Not an error. */
-					gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+                			gtm_putmsg_csa(CSA_ARG(NULL)
+						VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 					return EXIT_NRM;
 				}
 				continue;
diff --git a/sr_unix/mu_size_impsample.c b/sr_unix/mu_size_impsample.c
index 73a7620..ce02343 100644
--- a/sr_unix/mu_size_impsample.c
+++ b/sr_unix/mu_size_impsample.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -46,6 +46,7 @@
 #include "sleep_cnt.h"
 #include "wcs_sleep.h"
 #include "memcoherency.h"
+#include "change_reg.h"
 
 #include "gtm_time.h"
 #include "mvalconv.h"
@@ -125,7 +126,7 @@ STATICFNDEF void init_stats_impsmpl(stat_t *stat)
 /*
  * Importance Sampling
  */
-int4 mu_size_impsample(mval *gn, int4 M, int4 seed)
+int4 mu_size_impsample(glist *gl_ptr, int4 M, int4 seed)
 {
 	enum cdb_sc		status;
 	trans_num		ret_tn;
@@ -139,10 +140,11 @@ int4 mu_size_impsample(mval *gn, int4 M, int4 seed)
 
 	SETUP_THREADGBL_ACCESS;
 	inctn_opcode = inctn_invalid_op;
-	op_gvname(VARLSTCNT(1) gn);
+	DO_OP_GVNAME(gl_ptr);
+		/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 	if (0 == gv_target->root)
         {       /* Global does not exist (online rollback). Not an error. */
-                gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+                gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
                 return EXIT_NRM;
         }
 	if (!seed)
@@ -173,7 +175,8 @@ int4 mu_size_impsample(mval *gn, int4 M, int4 seed)
 				ABORT_TRANS_IF_GBL_EXIST_NOMORE(lcl_t_tries, tn_aborted);
 				if (tn_aborted)
 				{	/* Global does not exist (online rollback). Not an error. */
-					gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+					gtm_putmsg_csa(CSA_ARG(NULL)
+						VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 					return EXIT_NRM;
 				}
 				continue;
diff --git a/sr_unix/mu_size_scan.c b/sr_unix/mu_size_scan.c
index 0f7d96d..5602c6c 100644
--- a/sr_unix/mu_size_scan.c
+++ b/sr_unix/mu_size_scan.c
@@ -45,6 +45,7 @@
 #include "sleep_cnt.h"
 #include "wcs_sleep.h"
 #include "memcoherency.h"
+#include "change_reg.h"
 
 #include "gtm_time.h"
 #include "mvalconv.h"
@@ -109,7 +110,7 @@ GBLDEF	INTPTR_T		saveoff[MAX_BT_DEPTH + 1];
 enum cdb_sc dfs(int lvl, sm_uc_ptr_t pBlkBase, boolean_t endtree, boolean_t skiprecs);
 enum cdb_sc read_block(block_id nBlkId, sm_uc_ptr_t *pBlkBase_ptr, int *nLevl_ptr, int desired_levl);
 
-int4 mu_size_scan(mval *gn, int4 level)
+int4 mu_size_scan(glist *gl_ptr, int4 level)
 {
 	enum cdb_sc		status;
 	trans_num		ret_tn;
@@ -126,10 +127,11 @@ int4 mu_size_scan(mval *gn, int4 level)
 
 	SETUP_THREADGBL_ACCESS;
 	inctn_opcode = inctn_invalid_op;
-	op_gvname(VARLSTCNT(1) gn);
+	DO_OP_GVNAME(gl_ptr);
+		/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 	if (0 == gv_target->root)
 	{	/* Global does not exist (online rollback). Not an error. */
-		gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 		return EXIT_NRM;
 	}
 	gv_target->alt_hist->depth = MAX_BT_DEPTH;	/* initialize: don't copy to saveoff if restart before a single success */
@@ -159,7 +161,7 @@ int4 mu_size_scan(mval *gn, int4 level)
 			ABORT_TRANS_IF_GBL_EXIST_NOMORE(lcl_t_tries, tn_aborted);
 			if (tn_aborted)
 			{	/* Global does not exist (online rollback). Not an error. */
-				gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 				return EXIT_NRM;
 			}
 			continue;
@@ -170,7 +172,7 @@ int4 mu_size_scan(mval *gn, int4 level)
 		level += nLevl;
 	if (level < 0 || nLevl < level)
 	{
-		gtm_putmsg(VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.LEVEL"));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.LEVEL"));
 		return EXIT_ERR;
 	}
 	targ_levl = level;
@@ -192,7 +194,7 @@ int4 mu_size_scan(mval *gn, int4 level)
 			ABORT_TRANS_IF_GBL_EXIST_NOMORE(lcl_t_tries, tn_aborted);
 			if (tn_aborted)
 			{	/* Global does not exist (online rollback). Not an error. */
-				gtm_putmsg(VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 				return EXIT_NRM;
 			}
 			/* update saveoff */
diff --git a/sr_unix/mu_swap_root.c b/sr_unix/mu_swap_root.c
index 4043154..6cc8564 100644
--- a/sr_unix/mu_swap_root.c
+++ b/sr_unix/mu_swap_root.c
@@ -50,14 +50,7 @@
 #include "t_create.h"
 #include "t_write_map.h"
 #include "t_write.h"
-#ifdef GTM_TRIGGER
-#include "hashtab_mname.h"
-#include "gv_trigger.h"
-#include "gv_trigger_common.h"
-#include "targ_alloc.h"
-#endif
-
-GTMTRIG_ONLY(LITREF	mval	literal_hasht;)
+#include "change_reg.h"
 
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	sgmnt_addrs		*cs_addrs;
@@ -92,7 +85,7 @@ error_def(ERR_MUTRUNCNOTBG);
 #define RETRY_SWAP		(0)
 #define ABORT_SWAP		(1)
 
-boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr)
+boolean_t mu_swap_root(glist *gl_ptr, int *root_swap_statistic_ptr)
 {
 	sgmnt_data_ptr_t	csd;
 	sgmnt_addrs		*csa;
@@ -108,10 +101,6 @@ boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr)
 	boolean_t		tn_aborted;
 	unsigned int		lcl_t_tries;
 	enum cdb_sc		status;
-#	ifdef GTM_TRIGGER
-	gv_namehead		*hasht_tree;
-	mname_entry		gvent;
-#	endif
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -121,18 +110,8 @@ boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr)
 	dir_hist_ptr = gv_target->alt_hist;
 	gvt_hist_ptr = &(gv_target->hist);
 	inctn_opcode = inctn_invalid_op;
-#	ifdef GTM_TRIGGER
-	if (IS_MNAME_HASHT_GBLNAME(gn->str))
-	{	/* Initialize ^#t global for this region. */
-		csa = cs_addrs;	/* needed for SETUP_TRIGGER_GLOBAL and INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED macros */
-		SETUP_TRIGGER_GLOBAL;
-		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
-		DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC(CHECK_CSA_TRUE);
-		if (0 == gv_target->root)
-			return TRUE;
-	} else
-#	endif	/* Initialization for current global */
-		op_gvname(VARLSTCNT(1) (gn));
+	DO_OP_GVNAME(gl_ptr);
+		/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
 	csa = cs_addrs;
 	cnl = csa->nl;
 	csd = cs_data;	/* Be careful to keep csd up to date. With MM, cs_data can change, and
@@ -140,7 +119,7 @@ boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr)
 			 */
 	if (0 == gv_target->root)
 	{	/* Global does not exist (online rollback). No problem. */
-		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 		return TRUE;
 	}
 	if (dba_mm == csd->acc_meth)
@@ -205,7 +184,7 @@ boolean_t mu_swap_root(mval *gn, int *root_swap_statistic_ptr)
 			ABORT_TRANS_IF_GBL_EXIST_NOMORE(lcl_t_tries, tn_aborted);
 			if (tn_aborted)
 			{	/* It is not an error if the global (that once existed) doesn't exist anymore (due to ROLLBACK) */
-				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_GBLNOEXIST, 2, gn->str.len, gn->str.addr);
+				gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_GBLNOEXIST, 2, GNAME(gl_ptr).len, GNAME(gl_ptr).addr);
 				return TRUE;
 			}
 			continue;
diff --git a/sr_unix/mu_truncate.c b/sr_unix/mu_truncate.c
index 771a13c..36e4fbe 100644
--- a/sr_unix/mu_truncate.c
+++ b/sr_unix/mu_truncate.c
@@ -127,6 +127,7 @@ boolean_t mu_truncate(int4 truncate_percent)
 	int4			blks_in_lmap, blk;
 	gtm_uint64_t		before_trunc_file_size;
 	off_t			trunc_file_size;
+	off_t			padding;
 	uchar_ptr_t		lmap_addr;
 	boolean_t		was_crit;
 	uint4			found_busy_blk;
@@ -387,10 +388,7 @@ boolean_t mu_truncate(int4 truncate_percent)
 	CHECK_TN(csa, csd, curr_tn);
 	udi = FILE_INFO(gv_cur_region);
 	/* Information used by recover_truncate to check if the file size and csa->ti->total_blks are INCONSISTENT */
-	before_trunc_file_size = gds_file_size(gv_cur_region->dyn.addr->file_cntl); /* in DISK_BLOCKs */
-	assert((off_t)before_trunc_file_size * DISK_BLOCK_SIZE > (off_t)(old_total - new_total) * csd->blk_size);
-	trunc_file_size = (off_t)before_trunc_file_size * DISK_BLOCK_SIZE
-		- (off_t)(old_total - new_total) * csd->blk_size; /* in bytes */
+	trunc_file_size = BLK_ZERO_OFF(csd) + ((off_t)csd->blk_size * new_total) + DISK_BLOCK_SIZE;
 	csd->after_trunc_total_blks = new_total;
 	csd->before_trunc_free_blocks = csa->ti->free_blocks;
 	csd->before_trunc_total_blks = old_total; /* Flags interrupted truncate for recover_truncate */
diff --git a/sr_unix/mubfilcpy.c b/sr_unix/mubfilcpy.c
index 9e388d6..dad8a27 100644
--- a/sr_unix/mubfilcpy.c
+++ b/sr_unix/mubfilcpy.c
@@ -104,6 +104,7 @@ bool	mubfilcpy (backup_reg_list *list)
 	uint4			ustatus, size;
 	muinc_blk_hdr_ptr_t	sblkh_p;
 	ZOS_ONLY(int		realfiletag;)
+	int			user_id;
 	int			group_id;
 	int			perm;
 	struct perm_diag_data	pdd;
@@ -216,7 +217,7 @@ bool	mubfilcpy (backup_reg_list *list)
 	}
 	FSTAT_FILE(((unix_db_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fd, &stat_buf, fstat_res);
 	if (-1 != fstat_res)
-		if (gtm_set_group_and_perm(&stat_buf, &group_id, &perm, PERM_FILE, &pdd) < 0)
+		if (gtm_permissions(&stat_buf, &user_id, &group_id, &perm, PERM_FILE, &pdd) < 0)
 		{
 			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 				ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("backup file"),
@@ -232,7 +233,8 @@ bool	mubfilcpy (backup_reg_list *list)
 		}
 	/* setup new group and permissions if indicated by the security rules.
 	 */
-	if ((-1 == fstat_res) || (-1 == FCHMOD(backup_fd, perm)) || ((-1 != group_id) && (-1 == fchown(backup_fd, -1, group_id))))
+	if ((-1 == fstat_res) || (-1 == FCHMOD(backup_fd, perm))
+		|| (((-1 != user_id) || (-1 != group_id)) && (-1 == fchown(backup_fd, user_id, group_id))))
 	{
 		save_errno = errno;
 		errptr = (char *)STRERROR(save_errno);
diff --git a/sr_unix/mubinccpy.c b/sr_unix/mubinccpy.c
index 77f08be..0414ebc 100644
--- a/sr_unix/mubinccpy.c
+++ b/sr_unix/mubinccpy.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -45,8 +45,6 @@
 #include "mupipbckup.h"
 #include "gtmio.h"
 #include "gtm_pipe.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "iotimer.h"
 #include "eintr_wrappers.h"
 #include "sleep_cnt.h"
@@ -82,7 +80,6 @@ GBLREF	gd_region		*gv_cur_region;
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	uchar_ptr_t		mubbuf;
-GBLREF	tcp_library_struct	tcp_routines;
 GBLREF	uint4			pipe_child;
 GBLREF	uint4			process_id;
 GBLREF	boolean_t		debug_mupip;
@@ -164,6 +161,7 @@ bool	mubinccpy (backup_reg_list *list)
 	int			rc;
 	int                     fstat_res;
 	struct stat		stat_buf;
+	int			user_id;
 	int			group_id;
 	int			perm;
 	struct perm_diag_data	pdd;
@@ -212,14 +210,14 @@ bool	mubinccpy (backup_reg_list *list)
 			{
 				FSTAT_FILE(db_fd, &stat_buf, fstat_res);
 				if (-1 != fstat_res)
-					if (gtm_set_group_and_perm(&stat_buf, &group_id, &perm, PERM_FILE, &pdd) < 0)
+					if (gtm_permissions(&stat_buf, &user_id, &group_id, &perm, PERM_FILE, &pdd) < 0)
 					{
-						send_msg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+						send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 							ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("backup file"),
 							RTS_ERROR_STRING(((unix_db_info *)
 								(gv_cur_region->dyn.addr->file_cntl->file_info))->fn),
 							PERMGENDIAG_ARGS(pdd));
-						gtm_putmsg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+						gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 							ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("backup file"),
 							RTS_ERROR_STRING(((unix_db_info *)
 								(gv_cur_region->dyn.addr->file_cntl->file_info))->fn),
@@ -228,7 +226,7 @@ bool	mubinccpy (backup_reg_list *list)
 					}
 				/* setup new group and permissions if indicated by the security rules. */
 				if ((-1 == fstat_res) || (-1 == FCHMOD(backup->fd, perm))
-					|| ((-1 != group_id) && (-1 == fchown(backup->fd, -1, group_id))))
+					|| (((-1 != user_id) || (-1 != group_id)) && (-1 == fchown(backup->fd, user_id, group_id))))
 				{
 					PERROR("fchmod/fchown error: ");
 					util_out_print("ERROR: Cannot access incremental backup file !AD.",
@@ -256,7 +254,6 @@ bool	mubinccpy (backup_reg_list *list)
 			break;
 		case backup_to_tcp:
 			common_write = tcp_write;
-			iotcp_fillroutine();
 			backup = (BFILE *)malloc(SIZEOF(BFILE));
 			backup->blksiz = DISK_BLOCK_SIZE;
 			backup->remaining = 0; /* number of zeros to be added in the end, just use this field */
@@ -351,7 +348,7 @@ bool	mubinccpy (backup_reg_list *list)
 	DEBUG_INCBKUP_ONLY(blks_this_lmap = 0);
 	if (cs_addrs->nl->onln_rlbk_pid)
 	{
-		gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
+		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DBROLLEDBACK);
 		free(outptr);
 		free(bm_blk_buff);
 		CLEANUP_AND_RETURN_FALSE;
@@ -395,7 +392,7 @@ bool	mubinccpy (backup_reg_list *list)
 			}
 			if (cs_addrs->nl->onln_rlbk_pid)
 			{
-				gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DBROLLEDBACK);
 				free(outptr);
 				free(bm_blk_buff);
 				CLEANUP_AND_RETURN_FALSE;
@@ -523,7 +520,7 @@ bool	mubinccpy (backup_reg_list *list)
 	}
 	if (cs_addrs->nl->onln_rlbk_pid)
 	{
-		gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
+		gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DBROLLEDBACK);
 		free(outptr);
 		free(bm_blk_buff);
 		CLEANUP_AND_RETURN_FALSE;
@@ -551,7 +548,7 @@ bool	mubinccpy (backup_reg_list *list)
 			if (cs_addrs->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(cs_addrs, NULL))
 			{
 				assert(FALSE);
-				gtm_putmsg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1,
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1,
 					cs_addrs->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(gv_cur_region));
 				rel_crit(gv_cur_region);
 				CLEANUP_AND_RETURN_FALSE;
@@ -569,7 +566,7 @@ bool	mubinccpy (backup_reg_list *list)
 			backup_buffer_flush(gv_cur_region);
 			if (++counter > MAX_BACKUP_FLUSH_TRY)
 			{
-				gtm_putmsg(VARLSTCNT(1) ERR_BCKUPBUFLUSH);
+				gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_BCKUPBUFLUSH);
 				CLEANUP_AND_RETURN_FALSE;
 			}
 			if (counter & 0xF)
@@ -578,7 +575,7 @@ bool	mubinccpy (backup_reg_list *list)
 			{	/* Force shmpool recovery to see if it can find the lost blocks */
 				if (!shmpool_lock_hdr(gv_cur_region))
 				{
-					gtm_putmsg(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region),
+					gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region),
 						   ERR_ERRCALL, 3, CALLFROM);
 					assert(FALSE);
 					CLEANUP_AND_RETURN_FALSE;
@@ -692,7 +689,7 @@ bool	mubinccpy (backup_reg_list *list)
 		util_out_print("Process !UL encountered the following error.", TRUE,
 			cs_addrs->shmpool_buffer->failed);
 		if (0 != cs_addrs->shmpool_buffer->backup_errno)
-			gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
+			gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
 		util_out_print("!AD, backup for DB file !AD, is not valid.", TRUE,
 			file->len, file->addr, DB_LEN_STR(gv_cur_region));
 	} else
@@ -729,7 +726,7 @@ void exec_write(BFILE *bf, char *buf, int nbytes)
 
 	if ((nwritten < nbytes) && (-1 == nwritten))
 	{
-		gtm_putmsg(VARLSTCNT(1) errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 		CLOSEFILE_RESET(bf->fd, rc);	/* resets "bf->fd" to FD_INVALID */
 		if ((pipe_child > 0) && (FALSE != is_proc_alive(pipe_child, 0)))
 			WAITPID(pipe_child, (int *)&status, 0, waitpid_res);
@@ -748,7 +745,8 @@ void tcp_write(BFILE *bf, char *buf, int nbytes)
 	send_retry = 5;
 	do
 	{
-		if (-1 != (iostatus = tcp_routines.aa_send(bf->fd, buf + nwritten, nbytes - nwritten, 0)))
+		SEND(bf->fd, buf + nwritten, nbytes - nwritten, 0, iostatus);
+		if (-1 != iostatus)
 		{
 			nwritten += iostatus;
 			if (nwritten == nbytes)
@@ -762,7 +760,7 @@ void tcp_write(BFILE *bf, char *buf, int nbytes)
 
 	if ((nwritten != nbytes) && (-1 == iostatus))
 	{
-		gtm_putmsg(VARLSTCNT(1) errno);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 		CLOSEFILE_RESET(bf->fd, rc);	/* resets "bf->fd" to FD_INVALID */
 		backup_write_errno = errno;
 	}
@@ -775,7 +773,7 @@ CONDITION_HANDLER(iob_io_error1)
 	char	s[80];
 	char	*fgets_res;
 
-	START_CH;
+	START_CH(TRUE);
 	if (SIGNAL == ERR_IOEOF)
 	{
 		PRINTF("End of media reached, please mount next volume and press Enter: ");
@@ -797,7 +795,7 @@ CONDITION_HANDLER(iob_io_error2)
 	int	dummy1, dummy2;
 	char	s[80];
 
-	START_CH;
+	START_CH(TRUE);
 	PRN_ERROR;
 	if (!debug_mupip)
 		UNLINK(incbackupfile);
diff --git a/sr_unix/mupip.c b/sr_unix/mupip.c
index 7fef06e..307163b 100644
--- a/sr_unix/mupip.c
+++ b/sr_unix/mupip.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,8 +21,6 @@
 #include "gtm_string.h"
 #include "iosp.h"
 #include "error.h"
-#include "min_max.h"
-#include "init_root_gv.h"
 #include "interlock.h"
 #include "gtmimagename.h"
 #include "gdsroot.h"
@@ -78,7 +76,6 @@ GBLREF	int			(*op_open_ptr)(mval *v, mval *p, int t, mval *mspace);
 GBLREF	bool			in_backup;
 GBLREF	bool			licensed;
 GBLREF	int			(*func)();
-GBLREF	mval			curr_gbl_root;
 GBLREF	global_latch_t		defer_latch;
 GBLREF	spdesc			rts_stringpool, stringpool;
 GBLREF	char			cli_err_str[];
@@ -113,7 +110,6 @@ int main (int argc, char **argv)
 	if (argc < 2)			/* Interactive mode */
 		display_prompt();
 	/*      this call should be after cli_lex_setup() due to S390 A/E conversion    */
-	INIT_GBL_ROOT(); /* Needed for GVT initialization */
 	init_gtm();
 	while (TRUE)
 	{	func = 0;
@@ -122,9 +118,9 @@ int main (int argc, char **argv)
 		else if (res)
 		{
 			if (1 < argc)
-				rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
 			else
-				gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
 		}
 		if (func)
 			func();
diff --git a/sr_unix/mupip_cmd.c b/sr_unix/mupip_cmd.c
index 18310c8..e2404a0 100644
--- a/sr_unix/mupip_cmd.c
+++ b/sr_unix/mupip_cmd.c
@@ -471,34 +471,37 @@ static CLI_ENTRY	inst_freeze_qual[] = {
 };
 
 static CLI_ENTRY	gtmsource_qual[] = {
-	{"ACTIVATE",         0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"BUFFSIZE",         0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
-	{"CHANGELOG",        0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"CHECKHEALTH",      0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"CMPLVL",           0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
-	{"CONNECTPARAMS",    0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"DEACTIVATE",       0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"DETAIL",           0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"FILTER",           0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"FREEZE",           0, inst_freeze_qual, 0,                      0, 0,                                  0, VAL_NOT_REQ,    0, NON_NEG, VAL_STR, 0 },
-	{"INSTSECONDARY",    0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"JNLPOOL",          0, inst_edit_qual,   0,                      0, cli_disallow_mupip_replic_editinst, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"LOG",              0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"LOG_INTERVAL",     0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
-	{"LOSTTNCOMPLETE",   0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"NEEDRESTART",      0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"PASSIVE",          0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"PROPAGATEPRIMARY", 0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"ROOTPRIMARY",      0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"SECONDARY",        0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"SHOWBACKLOG",      0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"SHUTDOWN",         0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"START",            0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"STATSLOG",         0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
-	{"STOPSOURCEFILTER", 0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"TIMEOUT",          0, 0,                gtmsource_timeout_parm, 0, 0,                                  0, VAL_NOT_REQ,    1, NEG,     VAL_NUM, 0 },
-	{"UPDNOTOK",         0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
-	{"UPDOK",            0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"ACTIVATE",             0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"BUFFSIZE",             0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
+	{"CHANGELOG",            0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"CHECKHEALTH",          0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"CMPLVL",               0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
+	{"CONNECTPARAMS",        0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"DEACTIVATE",           0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"DETAIL",               0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"FILTER",               0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"FREEZE",               0, inst_freeze_qual, 0,                      0, 0,                                  0, VAL_NOT_REQ,    0, NON_NEG, VAL_STR, 0 },
+	{"INSTSECONDARY",        0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"JNLPOOL",              0, inst_edit_qual,   0,                      0, cli_disallow_mupip_replic_editinst, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"LOG",                  0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"LOG_INTERVAL",         0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
+	{"LOSTTNCOMPLETE",       0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"NEEDRESTART",          0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"PASSIVE",              0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"PLAINTEXTFALLBACK",    0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 1, NEG,     VAL_N_A, 0 },
+	{"PROPAGATEPRIMARY",     0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"RENEGOTIATE_INTERVAL", 0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"ROOTPRIMARY",          0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"SECONDARY",            0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"SHOWBACKLOG",          0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"SHUTDOWN",             0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"START",                0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"STATSLOG",             0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"STOPSOURCEFILTER",     0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"TIMEOUT",              0, 0,                gtmsource_timeout_parm, 0, 0,                                  0, VAL_NOT_REQ,    1, NEG,     VAL_NUM, 0 },
+	{"TLSID",                0, 0,                0,                      0, 0,                                  0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
+	{"UPDNOTOK",             0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+	{"UPDOK",                0, 0,                0,                      0, 0,                                  0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
 	{ 0 }
 };
 
@@ -525,6 +528,7 @@ static CLI_ENTRY	gtmrecv_qual[] = {
 	{"LOG",              0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
 	{"LOG_INTERVAL",     0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
 	{"NORESYNC",         0, 0, 0,                      0,                     0, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
+        {"PLAINTEXTFALLBACK",0, 0, 0,                      0,                     0, 0, VAL_DISALLOWED, 1, NEG,     VAL_N_A, 0 },
 	{"RESUME",           0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_NUM, 0 },
 	{"REUSE",            0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
 	{"SHOWBACKLOG",      0, 0, 0,                      0,                     0, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
@@ -533,6 +537,7 @@ static CLI_ENTRY	gtmrecv_qual[] = {
 	{"STATSLOG",         0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
 	{"STOPSOURCEFILTER", 0, 0, 0,                      0,                     0, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
 	{"TIMEOUT",          0, 0, gtmrecv_timeout_parm,   0,                     0, 0, VAL_NOT_REQ,    1, NEG,     VAL_NUM, 0 },
+	{"TLSID",            0, 0, 0,                      0,                     0, 0, VAL_REQ,        0, NON_NEG, VAL_STR, 0 },
 	{"UPDATEONLY",       0, 0, 0,                      0,                     0, 0, VAL_DISALLOWED, 0, NON_NEG, VAL_N_A, 0 },
 	{"UPDATERESYNC",     0, 0, 0,                      0,                     0, 0, VAL_NOT_REQ,    0, NON_NEG, VAL_STR, 0 },
 	{ 0 }
diff --git a/sr_unix/mupip_cmd_disallow.c b/sr_unix/mupip_cmd_disallow.c
index 2b177de..fe32ba0 100644
--- a/sr_unix/mupip_cmd_disallow.c
+++ b/sr_unix/mupip_cmd_disallow.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2002, 2012 Fidelity Information Services, Inc.*
+ *	Copyright 2002, 2013 Fidelity Information Services, Inc.*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -349,12 +349,19 @@ boolean_t cli_disallow_mupip_replic_source(void)
 	disallow_return_value = cli_check_any2(VARLSTCNT(11) p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
 	CLI_DIS_CHECK_N_RESET;
 
-	/* BUFFSIZE, CMPLVL, FILTER, PASSIVE are supported only with START qualifier */
+	/* It's an error to specify TLSID and PLAINTEXTFALLBACK qualifiers on platforms that don't support SSL/TLS communication. */
+#	ifndef GTM_TLS
+	disallow_return_value = (d_c_cli_present("PLAINTEXTFALLBACK") || d_c_cli_present("TLSID"));
+	CLI_DIS_CHECK_N_RESET;
+#	endif
+	/* BUFFSIZE, CMPLVL, FILTER, PASSIVE, PLAINTEXTFALLBACK and TLSID  are supported only with START qualifier */
 	disallow_return_value = (!d_c_cli_present("START")
 					&& (d_c_cli_present("BUFFSIZE")
 						|| d_c_cli_present("CMPLVL")
 						|| d_c_cli_present("FILTER")
-						|| d_c_cli_present("PASSIVE")));
+						|| d_c_cli_present("PASSIVE")
+						|| d_c_cli_present("PLAINTEXTFALLBACK")
+						|| d_c_cli_present("TLSID")));
 	CLI_DIS_CHECK_N_RESET;
 	/* CONNECTPARAMS, SECONDARY are supported only with START or ACTIVATE qualifiers */
 	disallow_return_value = (!d_c_cli_present("START") && !d_c_cli_present("ACTIVATE")
@@ -411,6 +418,11 @@ boolean_t cli_disallow_mupip_replic_source(void)
 	/* DETAIL is compatible only with JNLPOOL */
 	disallow_return_value = (!d_c_cli_present("JNLPOOL") && d_c_cli_present("DETAIL"));
 	CLI_DIS_CHECK_N_RESET;
+#	ifdef GTM_TLS
+	/* PLAINTEXTFALLBACK is supported only with TLSID qualifier */
+	disallow_return_value = (!d_c_cli_present("TLSID") && d_c_cli_present("PLAINTEXTFALLBACK"));
+	CLI_DIS_CHECK_N_RESET;
+#	endif
 	return FALSE;
 }
 
diff --git a/sr_unix/mupip_cvtgbl.c b/sr_unix/mupip_cvtgbl.c
index 53cff74..dcd59c8 100644
--- a/sr_unix/mupip_cvtgbl.c
+++ b/sr_unix/mupip_cvtgbl.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -80,9 +80,9 @@ void mupip_cvtgbl(void)
 			mupip_exit(ERR_MUPCLIERR);
 	} else if (!cli_get_str("FILE", fn, &fn_len))  /* User wants to read from a file. */
 		mupip_exit(ERR_MUPCLIERR); /* Neither -STDIN nor file name specified. */
+	file_input_init(fn, fn_len);
 	if (mupip_error_occurred)
 		exit(-1);
-	file_input_init(fn, fn_len);
 	mu_outofband_setup();
 	if ((cli_status = cli_present("BEGIN")) == CLI_PRESENT)
 	{
diff --git a/sr_unix/mupip_endiancvt.c b/sr_unix/mupip_endiancvt.c
index 2cb4623..b4da949 100644
--- a/sr_unix/mupip_endiancvt.c
+++ b/sr_unix/mupip_endiancvt.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -44,8 +44,6 @@
 #include "error.h"
 #include "gtmio.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gt_timer.h"
 #include "stp_parms.h"
 #include "gtm_stat.h"
@@ -102,6 +100,9 @@ boolean_t		is_encrypted = FALSE;
 gtmcrypt_key_t		encr_key_handle;
 #endif
 
+/* No journal pool for endiancvt, so ignore csa everywhere. Saves a bunch of CSA_ARG(NULL)s. */
+#define GTM_PUTMSG_CSA(...)	gtm_putmsg_csa(CSA_ARG(NULL) __VA_ARGS__)
+
 typedef struct
 {	/* adapted from dbcertify.h */
 	unsigned int	top;		/* Offset to top of the key */
@@ -251,57 +252,57 @@ void mupip_endiancvt(void)
 			if (GDSMVCURR != swap_mdbver)
 			{
 				check_error = NOTCURRMDBFORMAT;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			swap_uint4 = GTM_BYTESWAP_32(old_data->kill_in_prog);
 			if (0 != swap_uint4)
 			{
 				check_error = KILLINPROG;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			swap_uint4 = GTM_BYTESWAP_32(old_data->abandoned_kills);
 			if (0 != swap_uint4)
 			{
 				check_error = ABANDONED_KILLS;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			swap_uint4 = GTM_BYTESWAP_32(old_data->rc_srv_cnt);
 			if (0 != swap_uint4)
 			{
 				check_error = GTCMSERVERACTIVE;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 		}
 		swap_dbver = (enum db_ver)GTM_BYTESWAP_32(old_data->desired_db_format);
 		if (GDSVCURR != swap_dbver)
 		{
 			check_error = NOTCURRDBFORMAT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		assert(SIZEOF(int4) == SIZEOF(old_data->fully_upgraded));
 		swap_boolean = GTM_BYTESWAP_32(old_data->fully_upgraded);
 		if (!swap_boolean)
 		{
 			check_error = NOTFULLYUPGRADED;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		swap_uint4 = GTM_BYTESWAP_32(old_data->recov_interrupted);
 		if (0 != swap_uint4)
 		{
 			check_error = RECOVINTRPT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		swap_uint4 = GTM_BYTESWAP_32(old_data->createinprogress);
 		if (0 != swap_uint4)
 		{
 			check_error = DBCREATE;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		swap_uint4 = GTM_BYTESWAP_32(old_data->file_corrupt);
 		if (0 != swap_uint4)
 		{
 			check_error = DBCORRUPT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 	} else
 	{
@@ -315,7 +316,7 @@ void mupip_endiancvt(void)
 			mu_gv_cur_reg_free();
 			free(old_data);
 			CLOSEFILE_RESET(db_fd, rc);	/* resets "db_fd" to FD_INVALID */
-			gtm_putmsg(VARLSTCNT(4) MAKE_MSG_TYPE(ERR_MUSTANDALONE, ERROR), 2, n_len, db_name);
+			GTM_PUTMSG_CSA(VARLSTCNT(4) MAKE_MSG_TYPE(ERR_MUSTANDALONE, ERROR), 2, n_len, db_name);
 			mupip_exit(ERR_MUNOACTION);
 		}
 		if (gv_cur_region->read_only && !outdb_specified)
@@ -323,7 +324,7 @@ void mupip_endiancvt(void)
 			DO_STANDALONE_CLNUP_IF_NEEDED(endian_native);
 			free(old_data);
 			CLOSEFILE_RESET(db_fd, rc);	/* resets "db_fd" to FD_INVALID */
-			gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, n_len, db_name);
+			GTM_PUTMSG_CSA(VARLSTCNT(4) ERR_DBRDONLY, 2, n_len, db_name);
 			mupip_exit(ERR_MUNOACTION);
 		}
 		if (!override_specified)
@@ -331,48 +332,48 @@ void mupip_endiancvt(void)
 			if (GDSMVCURR != old_data->minor_dbver)
 			{
 				check_error = NOTCURRMDBFORMAT;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			if (0 != old_data->kill_in_prog)
 			{
 				check_error = KILLINPROG;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			if (0 != old_data->abandoned_kills)
 			{
 				check_error = ABANDONED_KILLS;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 			if (0 != old_data->rc_srv_cnt)
 			{
 				check_error = GTCMSERVERACTIVE;
-				gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+				GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 			}
 		}
 		if (GDSVCURR != old_data->desired_db_format)
 		{
 			check_error = NOTCURRDBFORMAT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		if (!old_data->fully_upgraded)
 		{
 			check_error = NOTFULLYUPGRADED;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		if (0 != old_data->recov_interrupted)
 		{
 			check_error = RECOVINTRPT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		if (0 != old_data->createinprogress)
 		{
 			check_error = DBCREATE;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		if (0 != old_data->file_corrupt)
 		{
 			check_error = DBCORRUPT;
-			gtm_putmsg(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
+			GTM_PUTMSG_CSA(VARLSTCNT(6) ERR_NOENDIANCVT, 4, n_len, db_name, LEN_AND_STR(check_error));
 		}
 		if (!check_error && !outdb_specified)
 		{
@@ -598,7 +599,7 @@ void mupip_endiancvt(void)
 	if (outdb_specified)
 		CLOSEFILE_RESET(outdb_fd, rc);	/* resets "outdb_fd" to FD_INVALID */
 	/* Display success message only after all data has been synced to disk and the file descriptors closed */
-	gtm_putmsg(VARLSTCNT(7) ERR_ENDIANCVT, 5, n_len, db_name, from_endian, to_endian, ENDIANTHIS);
+	GTM_PUTMSG_CSA(VARLSTCNT(7) ERR_ENDIANCVT, 5, n_len, db_name, from_endian, to_endian, ENDIANTHIS);
  	mupip_exit(SS_NORMAL);
 }
 
@@ -863,8 +864,8 @@ int4	endian_process(endian_info *info, sgmnt_data *new_data, sgmnt_data *old_dat
 				recycled_done++;
 			} else if (BLK_FREE == lbm_status)
 				free_done++;		/* count before changing recycled to free */
-			else if (BLK_MAPINVALID == lbm_status)
-				GTMASSERT;
+			else
+				assertpro(BLK_MAPINVALID != lbm_status);
 		}
 		if (info->inplace)
 		{
@@ -1105,7 +1106,7 @@ char *endian_read_dbblk(endian_info *info, block_id blk_to_get)
 		bp = (blk_hdr_ptr_t)buff;
 		assert((bp->bsiz <= info->bsize) && (bp->bsiz >= SIZEOF(*bp)));
 		req_dec_blk_size = MIN(info->bsize, bp->bsiz) - (SIZEOF(*bp));
-		if (BLOCK_REQUIRE_ENCRYPTION(is_encrypted, bp->levl, req_dec_blk_size))
+		if (BLK_NEEDS_ENCRYPTION3(is_encrypted, bp->levl, req_dec_blk_size))
 		{
 			ASSERT_ENCRYPTION_INITIALIZED;
 			inbuf = (char *)(bp + 1);
diff --git a/sr_unix/mupip_exit_handler.c b/sr_unix/mupip_exit_handler.c
index c1fc50f..92f9929 100644
--- a/sr_unix/mupip_exit_handler.c
+++ b/sr_unix/mupip_exit_handler.c
@@ -106,7 +106,7 @@ void mupip_exit_handler(void)
 		mupip_jnl_recover = FALSE;
 	}
 	jgbl.dont_reset_gbl_jrec_time = jgbl.forw_phase_recovery = FALSE;
-	cancel_timer(0);		/* Cancel all timers - No unpleasant surprises */
+	CANCEL_TIMERS;			/* Cancel all unsafe timers - No unpleasant surprises */
 	secshr_db_clnup(NORMAL_TERMINATION);
 	if (dollar_tlevel)
 		OP_TROLLBACK(0);
diff --git a/sr_unix/mupip_restore.c b/sr_unix/mupip_restore.c
index d32e2a8..7f2c0ac 100644
--- a/sr_unix/mupip_restore.c
+++ b/sr_unix/mupip_restore.c
@@ -17,6 +17,7 @@
 #include "gtm_inet.h"
 #include "gtm_stdio.h"
 #include "gtm_string.h"
+#include "gtm_select.h"
 
 #include <sys/wait.h>
 #include <stddef.h>
@@ -43,8 +44,6 @@
 #include "error.h"
 #include "gtmio.h"
 #include "iotimer.h"
-#include "iotcpdef.h"
-#include "iotcproutine.h"
 #include "gtm_pipe.h"
 #include "gt_timer.h"
 #include "stp_parms.h"
@@ -72,7 +71,6 @@
 
 GBLDEF	inc_list_struct		in_files;
 GBLREF	uint4			pipe_child;
-GBLREF	tcp_library_struct	tcp_routines;
 GBLREF	gd_region		*gv_cur_region;
 GBLREF	uint4			restore_read_errno;
 
@@ -107,7 +105,7 @@ CONDITION_HANDLER(iob_io_error)
 	char 	s[80];
 	char 	*fgets_res;
 
-	START_CH;
+	START_CH(TRUE);
 	if (SIGNAL == ERR_IOEOF)
 	{
 		PRINTF("End of media reached, please mount next volume and press Enter: ");
@@ -304,7 +302,6 @@ void mupip_restore(void)
 				if ((0 == cli_get_int("NETTIMEOUT", (int4 *)&timeout)) || (0 > timeout))
 					timeout = DEFAULT_BKRS_TIMEOUT;
 				in = (BFILE *)malloc(SIZEOF(BFILE));
-				iotcp_fillroutine();
 				if (0 > (in->fd = tcp_open(addr, port, timeout, TRUE)))
 				{
 					util_out_print("Error establishing TCP connection to !AD.",
@@ -539,7 +536,7 @@ void mupip_restore(void)
 			assert((size <= old_blk_size) && (size >= SIZEOF(blk_hdr)));
 			in_len = MIN(old_blk_size, size) - SIZEOF(blk_hdr);
 			if (!is_same_hash
-				&& (BLOCK_REQUIRE_ENCRYPTION(is_bkup_file_encrypted, (((blk_hdr_ptr_t)blk_ptr)->levl), in_len)))
+				&& (BLK_NEEDS_ENCRYPTION3(is_bkup_file_encrypted, (((blk_hdr_ptr_t)blk_ptr)->levl), in_len)))
 			{
 				inptr = blk_ptr + SIZEOF(blk_hdr);
 				GTMCRYPT_DECRYPT(NULL, bkup_key_handle, inptr, in_len, NULL, gtmcrypt_errno);
@@ -554,7 +551,7 @@ void mupip_restore(void)
 			offset = (old_start_vbn - 1) * DISK_BLOCK_SIZE + ((off_t)old_blk_size * blk_num);
 #			ifdef GTM_CRYPT
 			if (!is_same_hash
-				&& (BLOCK_REQUIRE_ENCRYPTION(old_data.is_encrypted, (((blk_hdr_ptr_t)blk_ptr)->levl), in_len)))
+				&& (BLK_NEEDS_ENCRYPTION3(old_data.is_encrypted, (((blk_hdr_ptr_t)blk_ptr)->levl), in_len)))
 			{
 				inptr = blk_ptr + SIZEOF(blk_hdr);
 				GTMCRYPT_ENCRYPT(NULL, target_key_handle, inptr, in_len, NULL, gtmcrypt_errno);
@@ -706,21 +703,22 @@ STATICFNDEF void exec_read(BFILE *bf, char *buf, int nbytes)
 	return;
 }
 
-/* the logic here can be reused in iotcp_readfl.c and iosocket_readfl.c */
+/* the logic here can be reused in iosocket_readfl.c */
 STATICFNDEF void tcp_read(BFILE *bf, char *buf, int nbytes)
 {
 	int     	needed, status;
 	char		*curr;
 	fd_set          fs;
-	ABS_TIME	save_nap, nap;
+	struct timeval	save_nap, nap;
 	int		rc;
 
 	needed = nbytes;
 	curr = buf;
-	nap.at_sec = 1;
-	nap.at_usec = 0;
+	nap.tv_sec = 1;
+	nap.tv_usec = 0;
 	while (1)
 	{
+		assertpro(FD_SETSIZE > bf->fd);
 		FD_ZERO(&fs);
 		FD_SET(bf->fd, &fs);
 		assert(0 != FD_ISSET(bf->fd, &fs));
@@ -728,11 +726,11 @@ STATICFNDEF void tcp_read(BFILE *bf, char *buf, int nbytes)
 		 * function, and not all callers of aa_select behave the same when EINTR is returned.
 		 */
 		save_nap = nap;
-		status = tcp_routines.aa_select(bf->fd + 1, (void *)(&fs), (void *)0, (void *)0, &nap);
+		status = select(bf->fd + 1, (void *)(&fs), (void *)0, (void *)0, &nap);
 		nap = save_nap;
 		if (status > 0)
 		{
-			status = tcp_routines.aa_recv(bf->fd, curr, needed, 0);
+			RECV(bf->fd, curr, needed, 0, status);
 			if ((0 == status) || (needed == status))        /* lost connection or all set */
 			{
 				break;
diff --git a/sr_unix/mupip_rundown.c b/sr_unix/mupip_rundown.c
index 499bd3b..44b5155 100644
--- a/sr_unix/mupip_rundown.c
+++ b/sr_unix/mupip_rundown.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -66,6 +66,7 @@ GBLREF	jnlpool_ctl_ptr_t	jnlpool_ctl;
 GBLREF	jnlpool_addrs		jnlpool;
 GBLREF	boolean_t		holds_sem[NUM_SEM_SETS][NUM_SRC_SEMS];
 GBLREF	boolean_t		argumentless_rundown;
+GBLREF	semid_queue_elem	*keep_semids;
 
 error_def(ERR_MUFILRNDWNSUC);
 error_def(ERR_MUJPOOLRNDWNFL);
@@ -92,6 +93,7 @@ void mupip_rundown(void)
 	unsigned int		full_len;
 	char			*instfilename;
 	unsigned char		ipcs_buff[MAX_IPCS_ID_BUF], *ipcs_ptr;
+	semid_queue_elem	*prev_elem;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -166,7 +168,7 @@ void mupip_rundown(void)
 				}
 			}
 			if (TRUE == mu_rndwn_file(gv_cur_region, FALSE))
-				gtm_putmsg(VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
 			else
 				exit_status = ERR_MUNOTALLSEC;
 		}
@@ -234,8 +236,8 @@ void mupip_rundown(void)
 						mupip_exit(ERR_MUNOTALLSEC);
 					} else
 					{
-						gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4, LEN_AND_STR(ipcs_buff),
-								LEN_AND_STR(instfilename));
+						gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4,
+							       LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename));
 						repl_instance.jnlpool_shmid = INVALID_SHMID;
 						repl_instance.jnlpool_shmid_ctime = 0;
 						shm_removed = TRUE;
@@ -244,7 +246,7 @@ void mupip_rundown(void)
 				{
 					util_out_print("Replpool segment (id = !UL) for replication instance !AD is in"
 							" use by another process.", TRUE, shmid, LEN_AND_STR(instfilename));
-					gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, LEN_AND_STR(ipcs_buff),
 								LEN_AND_STR(instfilename));
 				}
 				/* Now, go ahead and release/remove the access control semaphores */
@@ -258,8 +260,9 @@ void mupip_rundown(void)
 						assert(0 == repl_instance.jnlpool_semid_ctime);
 						if (!jnlpool_sem_created)
 						{
-							gtm_putmsg(VARLSTCNT(9) ERR_MUJPOOLRNDWNSUC, 4, LEN_AND_STR(ipcs_buff),
-									LEN_AND_STR(instfilename), ERR_SEMREMOVED, 1, semid);
+							gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_MUJPOOLRNDWNSUC, 4,
+								       LEN_AND_STR(ipcs_buff), LEN_AND_STR(instfilename),
+								       ERR_SEMREMOVED, 1, semid);
 						}
 						repl_instance.crash = FALSE; /* No more semaphore IDs. Reset crash bit */
 					}
@@ -306,6 +309,13 @@ void mupip_rundown(void)
 			exit_status = mu_rndwn_sem_all();
 		else
 			mu_rndwn_sem_all();
+		/* Free keep_semids queue */
+		while (keep_semids)
+		{
+			prev_elem = keep_semids->prev;
+			free(keep_semids);
+			keep_semids = prev_elem;
+		}
 	}
 	mupip_exit(exit_status);
 }
diff --git a/sr_unix/mupip_size.c b/sr_unix/mupip_size.c
index 8f4d1d5..5b4d6cc 100644
--- a/sr_unix/mupip_size.c
+++ b/sr_unix/mupip_size.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -57,7 +57,6 @@ typedef struct {
 	enum {arsample, scan, impsample}	heuristic;
 	int4 					samples;
 	int4 					level;
-	mval					*global_name;
 	int4					seed;
 } mupip_size_cfg_t;
 
@@ -74,7 +73,7 @@ void mupip_size(void)
 	uint4			status = EXIT_NRM;
 	glist			gl_head, exclude_gl_head, *gl_ptr;
 	/* configuration default values */
-	mupip_size_cfg_t	mupip_size_cfg = { impsample, 1000, 1, 0, 0 };
+	mupip_size_cfg_t	mupip_size_cfg = { impsample, 1000, 1, 0 };
 	char			cli_buff[MAX_LINE];
 	int4			reg_max_rec, reg_max_key, reg_max_blk;
 	unsigned short		n_len;
@@ -114,9 +113,10 @@ void mupip_size(void)
 	}
 	/* gv_select will select globals for this clause*/
 	gv_select(cli_buff, n_len, FALSE, "SELECT", &gl_head, &reg_max_rec, &reg_max_key, &reg_max_blk, restrict_reg);
-	if (!gl_head.next){
+	if (!gl_head.next)
+	{
 		error_mupip = TRUE;
-		gtm_putmsg(VARLSTCNT(1) ERR_NOSELECT);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSELECT);
 	}
 	mupip_size_check_error();
 
@@ -137,12 +137,11 @@ void mupip_size(void)
 			if (!valid || mupip_size_cfg.level <= -MAX_BT_DEPTH || MAX_BT_DEPTH <= mupip_size_cfg.level)
 			{
 				error_mupip = TRUE;
-				gtm_putmsg(VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.LEVEL"));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.LEVEL"));
 			}
 		}
 		/* else level is already initialized with default value */
-	}
-	else if (cli_present("HEURISTIC.ARSAMPLE") == CLI_PRESENT || cli_present("HEURISTIC.IMPSAMPLE") == CLI_PRESENT)
+	} else if (cli_present("HEURISTIC.ARSAMPLE") == CLI_PRESENT || cli_present("HEURISTIC.IMPSAMPLE") == CLI_PRESENT)
 	{
 		if (cli_present("HEURISTIC.ARSAMPLE") == CLI_PRESENT)
 			mupip_size_cfg.heuristic = arsample;
@@ -153,18 +152,17 @@ void mupip_size(void)
 			boolean_t valid = cli_get_int("HEURISTIC.SAMPLES", &(mupip_size_cfg.samples));
 			if (!valid || mupip_size_cfg.samples <= 0){
 				error_mupip = TRUE;
-				gtm_putmsg(VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SAMPLES"));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SAMPLES"));
 			}
 		}
 		/* else samples is already initialized with default value */
-
 		/* undocumented SEED parameter used for testing sampling method */
 		if (cli_present("HEURISTIC.SEED"))
 		{
 			boolean_t valid = cli_get_int("HEURISTIC.SEED", &(mupip_size_cfg.seed));
 			if (!valid){
 				error_mupip = TRUE;
-				gtm_putmsg(VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SEED"));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SEED"));
 			}
 		}
 		/* else seed will be based on the time */
@@ -174,22 +172,21 @@ void mupip_size(void)
 	/* run mupip size on each global */
 	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
 	{
-		util_out_print("!/Global: !AD ", FLUSH, gl_ptr->name.str.len, gl_ptr->name.str.addr);
-
-		mupip_size_cfg.global_name = &(gl_ptr->name);
+		util_out_print("!/Global: !AD (region !AD)", FLUSH,
+			GNAME(gl_ptr).len, GNAME(gl_ptr).addr, REG_LEN_STR(gl_ptr->reg));
 		switch (mupip_size_cfg.heuristic)
 		{
 		case scan:
-			status |= mu_size_scan(mupip_size_cfg.global_name, mupip_size_cfg.level);
+			status |= mu_size_scan(gl_ptr, mupip_size_cfg.level);
 			break;
 		case arsample:
-			status |= mu_size_arsample(mupip_size_cfg.global_name, mupip_size_cfg.samples, TRUE, mupip_size_cfg.seed);
+			status |= mu_size_arsample(gl_ptr, mupip_size_cfg.samples, TRUE, mupip_size_cfg.seed);
 			break;
 		case impsample:
-			status |= mu_size_impsample(mupip_size_cfg.global_name, mupip_size_cfg.samples, mupip_size_cfg.seed);
+			status |= mu_size_impsample(gl_ptr, mupip_size_cfg.samples, mupip_size_cfg.seed);
 			break;
 		default:
-			GTMASSERT;
+			assertpro(FALSE && mupip_size_cfg.heuristic);
 			break;
 		}
 		if (mu_ctrlc_occurred || mu_ctrly_occurred)
diff --git a/sr_unix/mupip_size.h b/sr_unix/mupip_size.h
index e83feb0..b14b079 100644
--- a/sr_unix/mupip_size.h
+++ b/sr_unix/mupip_size.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2012, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -15,9 +15,9 @@
 #include "cdb_sc.h"
 
 void mupip_size(void);
-int4 mu_size_arsample(mval *gn, uint M, boolean_t ar, int seed);
-int4 mu_size_impsample(mval *gn, int4 M, int4 seed);
-int4 mu_size_scan(mval *gn, int4 level);
+int4 mu_size_arsample(glist *gl_ptr, uint M, boolean_t ar, int seed);
+int4 mu_size_impsample(glist *gl_ptr, int4 M, int4 seed);
+int4 mu_size_scan(glist *gl_ptr, int4 level);
 enum cdb_sc rand_traverse(double *r);
 
 #endif
diff --git a/sr_unix/mupip_trigger.c b/sr_unix/mupip_trigger.c
index d2dc947..3579268 100644
--- a/sr_unix/mupip_trigger.c
+++ b/sr_unix/mupip_trigger.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -16,7 +16,6 @@
 #include "gtm_limits.h"
 #include "gtm_stat.h"
 #include "gtm_string.h"
-#include "muextr.h"		/* for glist */
 #include "cli.h"
 #include "gdsroot.h"
 #include "gdsbt.h"
diff --git a/sr_unix/mutex.c b/sr_unix/mutex.c
index 53421d0..0e706f4 100644
--- a/sr_unix/mutex.c
+++ b/sr_unix/mutex.c
@@ -19,10 +19,10 @@
 #include "gtm_stdlib.h"
 #include "gtm_unistd.h"
 #include "gtm_stdio.h"
+#include "gtm_select.h"
 
 #include <errno.h>
 #include <sys/un.h>
-#include <iotcp_select.h>
 #if defined(__sparc) || defined(__hpux) || defined(__MVS__) || defined(__linux__) || defined(__CYGWIN__)
 #include "gtm_limits.h"
 #else
@@ -68,11 +68,11 @@
 #define MUTEX_LCKALERT_PERIOD		4
 #endif
 
-/* The following CAREFUL_* macros invoke the corresponding * macros except in the case csa->hdr is NULL.
+/* The following PROBE_* macros invoke the corresponding * macros except in the case csa->hdr is NULL.
  * This is possible if the csa corresponds to the journal pool where there is no notion of a db hdr.
  * In that case, we skip invoking the * macros.
  */
-#define	CAREFUL_SET_TRACEABLE_VAR(CSA, VALUE)					\
+#define	PROBE_SET_TRACEABLE_VAR(CSA, VALUE)					\
 {										\
 	sgmnt_data_ptr_t	lcl_csd;					\
 										\
@@ -83,7 +83,7 @@
 		SET_TRACEABLE_VAR(CSA->nl->wc_blocked, TRUE);			\
 }
 
-#define	CAREFUL_BG_TRACE_PRO_ANY(CSA, EVENT)					\
+#define	PROBE_BG_TRACE_PRO_ANY(CSA, EVENT)					\
 {										\
 	sgmnt_data_ptr_t	lcl_csd;					\
 										\
@@ -239,14 +239,14 @@ static	void	clean_initialize(mutex_struct_ptr_t addr, int n, bool crash)
 #		  else
 		if ((NULL == (status = msem_init(&q_free_entry->mutex_wake_msem, MSEM_LOCKED))) || ((msemaphore *)-1 == status))
 #		  endif
-			rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
 				RTS_ERROR_TEXT("Error with mutex wait memory semaphore initialization"), errno);
 #		endif
 		/* Initialize fl,bl links to 0 before INSQTI as it (gtm_insqti in relqueopi.c) asserts this */
 		DEBUG_ONLY(((que_ent_ptr_t)q_free_entry)->fl = 0;)
 		DEBUG_ONLY(((que_ent_ptr_t)q_free_entry)->bl = 0;)
 		if (INTERLOCK_FAIL == INSQTI((que_ent_ptr_t)q_free_entry++, (que_head_ptr_t)&addr->freehead))
-			rts_error(VARLSTCNT(6) ERR_MUTEXERR, 0, ERR_TEXT, 2,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUTEXERR, 0, ERR_TEXT, 2,
 				RTS_ERROR_TEXT("Interlock instruction failure in mutex initialize"));
 	}
 	SET_LATCH_GLOBAL(&addr->semaphore, LOCK_AVAILABLE);
@@ -374,7 +374,7 @@ static	enum cdb_sc mutex_long_sleep(mutex_struct_ptr_t addr, mutex_lock_t mutex_
 						bad_heartbeat = heartbeat_counter + MUTEX_MAX_HEARTBEAT_WAIT - 1;
 					/* -1 since we were interrupted this time */
 				} else
-					rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
+					rts_error_csa(CSA_ARG(csa) VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2,
 						RTS_ERROR_TEXT("Error with mutex wake msem"), errno);
 			}
 			/* wakeup_status is set to true, if I was able to lock...somebody woke me up;
@@ -393,6 +393,7 @@ static	enum cdb_sc mutex_long_sleep(mutex_struct_ptr_t addr, mutex_lock_t mutex_
 			 */
 			timeout_intr_slpcnt = MUTEX_INTR_SLPCNT;
 			MUTEX_DPRINT4("%d: Sleeping for %d s %d us\n", process_id, timeout.tv_sec, timeout.tv_usec);
+			assertpro(FD_SETSIZE > mutex_sock_fd);
 			FD_SET(mutex_sock_fd, &mutex_wait_on_descs);
 			MUTEX_TRACE_CNTR(mutex_trc_slp);
 			/*
@@ -412,7 +413,7 @@ static	enum cdb_sc mutex_long_sleep(mutex_struct_ptr_t addr, mutex_lock_t mutex_
 						break;
 					}
 				} else
-					rts_error(VARLSTCNT(5) ERR_TEXT, 2,
+					rts_error_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_TEXT, 2,
 						RTS_ERROR_TEXT("Error with mutex select. Running in degraded mode"), errno);
 				timeout_val >>= 1;
 				timeout.tv_sec = timeout_val / ONE_MILLION;
@@ -420,6 +421,7 @@ static	enum cdb_sc mutex_long_sleep(mutex_struct_ptr_t addr, mutex_lock_t mutex_
 				MUTEX_DPRINT4("%d: Interrupted select, new timeout %d s %d us\n", process_id, timeout.tv_sec,
 					timeout.tv_usec);
 				/* the next line deals with the case that an interrupted select has changed mutex_wait_on_descs */
+				assertpro(FD_SETSIZE > mutex_sock_fd);
 				FD_SET(mutex_sock_fd, &mutex_wait_on_descs);
 				MUTEX_TRACE_CNTR(mutex_trc_slp);
 			}
@@ -596,9 +598,9 @@ static	enum cdb_sc mutex_sleep(sgmnt_addrs *csa, mutex_lock_t mutex_lock_type)
 			{
 				/* Record queue full event in db file header if applicable.
 				 * Take care not to do it for jnlpool which has no concept of a db cache.
-				 * In that case csa->hdr is NULL so use CAREFUL_BG_TRACE_PRO_ANY macro.
+				 * In that case csa->hdr is NULL so use PROBE_BG_TRACE_PRO_ANY macro.
 				 */
-				CAREFUL_BG_TRACE_PRO_ANY(csa, mutex_queue_full);
+				PROBE_BG_TRACE_PRO_ANY(csa, mutex_queue_full);
 				MUTEX_DPRINT2("%d: Free Queue full\n", process_id);
 				/*
 				* When I can't find a free slot in the queue
@@ -859,15 +861,16 @@ static enum cdb_sc mutex_lock(gd_region *reg,
 						{	/* not rollback - send_msg after trace less likely to lose process */
 							GET_C_STACK_FROM_SCRIPT("MUTEXLCKALERT", process_id, in_crit_pid,
 								csa->critical->crit_cycle);
-							send_msg(VARLSTCNT(6) ERR_MUTEXLCKALERT, 4, DB_LEN_STR(reg), in_crit_pid,
-								 csa->critical->crit_cycle);
+							send_msg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_MUTEXLCKALERT, 4,
+									DB_LEN_STR(reg), in_crit_pid, csa->critical->crit_cycle);
 							try_recovery = TRUE;	/* set off a salvage */
 							continue;	/* make sure to act on it soon, likely this process */
 						}
 						/* If the holding PID belongs to online rollback which holds crit on database and
 						 * journal pool for its entire duration, use a different message
 						 */
-						send_msg(VARLSTCNT(5) ERR_ORLBKINPROG, 3, csa->nl->onln_rlbk_pid, DB_LEN_STR(reg));
+						send_msg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_ORLBKINPROG, 3,
+								csa->nl->onln_rlbk_pid, DB_LEN_STR(reg));
 						assert(csa->nl->in_crit == csa->nl->onln_rlbk_pid);
 					}
 				} else
@@ -966,24 +969,24 @@ void mutex_salvage(gd_region *reg)
 			csa->nl->in_crit = 0;
 			/* Mutex crash repaired, want to do write cache recovery, just in case.
 			 * Take care not to do it for jnlpool which has no concept of a db cache.
-			 * In that case csa->hdr is NULL so use CAREFUL_SET_TRACEABLE_VAR macro.
+			 * In that case csa->hdr is NULL so use PROBE_SET_TRACEABLE_VAR macro.
 			 */
-			CAREFUL_SET_TRACEABLE_VAR(csa, TRUE);
+			PROBE_SET_TRACEABLE_VAR(csa, TRUE);
 			mutex_salvaged = TRUE;
 			MUTEX_DPRINT2("%d : mutex salvaged, culprit was our own process\n", process_id);
 		} else if (!is_proc_alive(holder_pid, UNIX_ONLY(0) VMS_ONLY(holder_imgcnt)))
 		{	/* Release the COMPSWAP lock AFTER setting csa->nl->in_crit to 0 as an assert in
 			 * grab_crit (checking that csa->nl->in_crit is 0) relies on this order.
 			 */
-			send_msg(VARLSTCNT(5) ERR_MUTEXFRCDTERM, 3, holder_pid, REG_LEN_STR(reg));
+			send_msg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_MUTEXFRCDTERM, 3, holder_pid, REG_LEN_STR(reg));
 			csa->nl->in_crit = 0;
 			/* Mutex crash repaired, want to do write cache recovery, in case previous holder of crit had set
 			 * some cr->in_cw_set to a non-zero value. Not doing cache recovery could cause incorrect
-			 * GTMASSERTs in PIN_CACHE_RECORD macro in t_end/tp_tend.
+			 * GTMASSERTs in PIN_CACHE_RECORD macro in t_end/tp_tend.				BYPASSOK(GTMASSERT)
 			 * Take care not to do it for jnlpool which has no concept of a db cache.
-			 * In that case csa->hdr is NULL so use CAREFUL_SET_TRACEABLE_VAR macro.
+			 * In that case csa->hdr is NULL so use PROBE_SET_TRACEABLE_VAR macro.
 			 */
-			CAREFUL_SET_TRACEABLE_VAR(csa, TRUE);
+			PROBE_SET_TRACEABLE_VAR(csa, TRUE);
 			COMPSWAP_UNLOCK(&csa->critical->semaphore, holder_pid, holder_imgcnt, LOCK_AVAILABLE, 0);
 			mutex_salvaged = TRUE;
 			/* Reset jb->blocked as well if the holder_pid had it set */
@@ -1005,10 +1008,10 @@ void mutex_salvage(gd_region *reg)
 		assert((NULL != csa->hdr) || (csa == &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs));
 		if (mutex_salvaged && (NULL != csa->hdr))
 		{
-			BG_TRACE_PRO_ANY(csa, wcb_mutex_salvage); /* no need to use CAREFUL_BG_TRACE_PRO_ANY macro
+			BG_TRACE_PRO_ANY(csa, wcb_mutex_salvage); /* no need to use PROBE_BG_TRACE_PRO_ANY macro
 								   * since we already checked for csa->hdr non-NULL.
 								   */
-			send_msg(VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wcb_mutex_salvage"),
+			send_msg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wcb_mutex_salvage"),
 				process_id, &csa->ti->curr_tn, DB_LEN_STR(reg));
 		}
 	}
diff --git a/sr_unix/obj_code.c b/sr_unix/obj_code.c
index 78b8e02..ee186eb 100644
--- a/sr_unix/obj_code.c
+++ b/sr_unix/obj_code.c
@@ -36,6 +36,7 @@
 #include "objlabel.h"
 #include "stringpool.h"
 #include "min_max.h"
+#include "rtn_src_chksum.h"
 
 GBLDEF uint4 			lits_text_size, lits_mval_size;
 
@@ -103,7 +104,7 @@ error_def(ERR_TEXT);
 
 void cg_lab (mlabel *mlbl, char *do_emit);
 
-void obj_code (uint4 src_lines, uint4 checksum)
+void obj_code (uint4 src_lines, void *checksum_ctx)
 {
 	int		i;
 	uint4		lits_pad_size, object_pad_size, lnr_pad_size;
@@ -203,7 +204,7 @@ void obj_code (uint4 src_lines, uint4 checksum)
 	object_pad_size = PADLEN(code_size, OBJECT_SIZE_ALIGNMENT);
 	code_size += object_pad_size;
 	gtm_object_size = code_size;
-	rhead.checksum = checksum;
+	set_rtnhdr_checksum(&rhead, (gtm_rtn_src_chksum_ctx *)checksum_ctx);
 	rhead.objlabel = MAGIC_COOKIE;
 	rhead.temp_mvals = sa_temps[TVAL_REF];
 	rhead.temp_size = sa_temps_offset[TCAD_REF];
diff --git a/sr_unix/obj_file.c b/sr_unix/obj_file.c
index b8d7709..eaa3b6c 100644
--- a/sr_unix/obj_file.c
+++ b/sr_unix/obj_file.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -67,6 +67,8 @@ void	drop_object_file(void)
         }
 }
 
+error_def(ERR_OBJFILERR);
+error_def(ERR_STRINGOFLOW);
 
 /*
  *	emit_link_reference
@@ -108,12 +110,11 @@ void	emit_link_reference(int4 refoffset, mstr *name)
 void	emit_immed(char *source, uint4 size)
 {
 	short int 	write;
-	error_def(ERR_STRINGOFLOW);
 
 	if (run_time)
 	{
-		if (stringpool.free + size > stringpool.top)
-			rts_error(VARLSTCNT(1) ERR_STRINGOFLOW);
+		if (!IS_STP_SPACE_AVAILABLE_PRO(size))
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_STRINGOFLOW);
 		memcpy(stringpool.free, source, size);
 		stringpool.free += size;
 	} else
@@ -142,11 +143,10 @@ void	emit_immed(char *source, uint4 size)
 void	buff_emit(void)
 {
 	int	stat;
-	error_def(ERR_OBJFILERR);
 
 	DOWRITERC(object_file_des, emit_buff, emit_buff_used, stat);
 	if (0 != stat)
-		rts_error(VARLSTCNT(5) ERR_OBJFILERR, 2, object_name_len, object_file_name, stat);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_OBJFILERR, 2, object_name_len, object_file_name, stat);
 	emit_buff_used = 0;
 }
 
@@ -185,8 +185,12 @@ struct sym_table *define_symbol(unsigned char psect, mstr *name)
 		sym = symbols;
 		sym1 = NULL;
 		while (sym)
-		{
-			if ((cmp = memvcmp(name->addr, (int)name->len, &sym->name[0], sym->name_len - 1)) <= 0)
+		{	/* Consider this a match only if type is N_EXT. If we are inserting an external reference symbol
+			 * for the current routine name, we may find a N_TEXT entry. But in this case, we want to add another
+			 * (N_EXT) entry so that the symbol table is correctly formed.
+			 */
+			if ((0 >= (cmp = memvcmp(name->addr, (int)name->len, &sym->name[0], sym->name_len - 1)))
+				&& (N_EXT == sym->n.n_type))
 				break;
 			sym1 = sym;
 			sym = sym->next;
@@ -210,6 +214,8 @@ struct sym_table *define_symbol(unsigned char psect, mstr *name)
 			assert(compsyms_hashtab->base);
 			for (sym = symbols; sym; sym = sym->next)
 			{
+				if (N_EXT != sym->n.n_type)	/* Consider this a match only if type is N_EXT. See comment above */
+					continue;
 				symkey.str.addr = (char *)&sym->name[0];
 				symkey.str.len = sym->name_len - 1;
 				COMPUTE_HASH_STR(&symkey);
diff --git a/sr_unix/ojchildioset.c b/sr_unix/ojchildioset.c
index 1c24595..d6b5572 100644
--- a/sr_unix/ojchildioset.c
+++ b/sr_unix/ojchildioset.c
@@ -23,11 +23,14 @@
 #include "gtmio.h"
 #include "eintr_wrappers.h"
 #include "gtmmsg.h"
+#include "io.h"
+#include "iosocketdef.h"
 #ifdef __MVS__
 #include "gtm_zos_io.h"
 #endif
 
-GBLREF int		job_errno;
+GBLREF	int			job_errno;
+GBLREF	d_socket_struct		*socket_pool;
 
 ZOS_ONLY(error_def(ERR_BADTAG);)
 error_def(ERR_JOBFAIL);
@@ -44,21 +47,154 @@ int ojchildioset(job_params_type *jparms)
 	char 		fname_buf[MAX_STDIOE_LEN], buf[MAX_STDIOE_LEN];
 	int		rc;
 	joberr_t	joberr = joberr_gen;
+	int4		index;
+	mstr_len_t	handle_len;
+	socket_struct	*socketptr;
 	ZOS_ONLY(int	realfiletag;)
 
-/*
- * Redirect input
- */
-	strncpy(fname_buf, jparms->input.addr, jparms->input.len);
-	*(fname_buf + jparms->input.len) = '\0';
+	/*
+	 * Open Input
+	 */
+	if (IS_JOB_SOCKET(jparms->input.addr, jparms->input.len))
+	{
+		handle_len = JOB_SOCKET_HANDLE_LEN(jparms->input.len);
+		index = iosocket_handle(JOB_SOCKET_HANDLE(jparms->input.addr), &handle_len, FALSE, socket_pool);
+		if (-1 == index)
+		{
+			joberr = joberr_stdin_socket_lookup;
+			job_errno = EINVAL;
+			return joberr;
+		}
+		socketptr = socket_pool->socket[index];
+		FCNTL3(socketptr->sd, F_DUPFD, 1, dup_ret);
+		if (-1 == dup_ret)
+		{
+			joberr = joberr_io_stdin_socket_dup;
+			job_errno = errno;
+			return joberr;
+		}
+		in_fd = dup_ret;
+		jparms->input_prebuffer_size = socketptr->buffered_length;
+		if (0 < jparms->input_prebuffer_size)
+		{	/* copy any buffered reads */
+			jparms->input_prebuffer = malloc(jparms->input_prebuffer_size);
+			memcpy(jparms->input_prebuffer, socketptr->buffer + socketptr->buffered_offset,
+				jparms->input_prebuffer_size);
+		}
+	} else
+	{
+		strncpy(fname_buf, jparms->input.addr, jparms->input.len);
+		*(fname_buf + jparms->input.len) = '\0';
+
+		OPENFILE(fname_buf, O_RDONLY, in_fd);
+		if (FD_INVALID == in_fd)
+		{
+			joberr = joberr_io_stdin_open;
+			job_errno = errno;
+			return joberr;
+		}
+		jparms->input_prebuffer_size = 0;
+	}
 
-	OPENFILE(fname_buf, O_RDONLY, in_fd);
-	if (FD_INVALID == in_fd)
+	/*
+	 * Open Output
+	 */
+	if (IS_JOB_SOCKET(jparms->output.addr, jparms->output.len))
 	{
-		joberr = joberr_io_stdin_open;
-		job_errno = errno;
-		return joberr;
+		handle_len = JOB_SOCKET_HANDLE_LEN(jparms->output.len);
+		index = iosocket_handle(JOB_SOCKET_HANDLE(jparms->output.addr), &handle_len, FALSE, socket_pool);
+		if (-1 == index)
+		{
+			joberr = joberr_stdout_socket_lookup;
+			job_errno = EINVAL;
+			return joberr;
+		}
+		FCNTL3(socket_pool->socket[index]->sd, F_DUPFD, 1, dup_ret);
+		if (-1 == dup_ret)
+		{
+			joberr = joberr_io_stdout_socket_dup;
+			job_errno = errno;
+			return joberr;
+		}
+		out_fd = dup_ret;
+	} else
+	{
+		strncpy(fname_buf, jparms->output.addr, jparms->output.len);
+		*(fname_buf + jparms->output.len) = '\0';
+
+		CREATE_FILE(fname_buf, 0666, out_fd);
+		if (FD_INVALID == out_fd)
+		{
+			joberr = joberr_io_stdout_creat;
+			job_errno = errno;
+			return joberr;
+		}
+#		ifdef __MVS__
+		/* tagging as ASCII is fine now, that might change in the future for gtm_utf8_mode */
+		if (-1 == gtm_zos_set_tag(out_fd, TAG_ASCII, TAG_TEXT, TAG_FORCE, &realfiletag))
+			TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_ASCII);
+#		endif
+		CLOSEFILE_RESET(out_fd, rc);	/* resets "out_fd" to FD_INVALID */
+
+		OPENFILE(fname_buf, O_WRONLY, out_fd);
+		if (FD_INVALID == out_fd)
+		{
+			joberr = joberr_io_stdout_open;
+			job_errno = errno;
+			return joberr;
+		}
+	}
+
+	/*
+	 * Open Error
+	 */
+	if (IS_JOB_SOCKET(jparms->error.addr, jparms->error.len))
+	{
+		handle_len = JOB_SOCKET_HANDLE_LEN(jparms->error.len);
+		index = iosocket_handle(JOB_SOCKET_HANDLE(jparms->error.addr), &handle_len, FALSE, socket_pool);
+		if (-1 == index)
+		{
+			joberr = joberr_stderr_socket_lookup;
+			job_errno = EINVAL;
+			return joberr;
+		}
+		FCNTL3(socket_pool->socket[index]->sd, F_DUPFD, 1, dup_ret);
+		if (-1 == dup_ret)
+		{
+			joberr = joberr_io_stderr_socket_dup;
+			job_errno = errno;
+			return joberr;
+		}
+		err_fd = dup_ret;
+	} else
+	{
+		strncpy(fname_buf, jparms->error.addr, jparms->error.len);
+		*(fname_buf + jparms->error.len) = '\0';
+
+		CREATE_FILE(fname_buf, 0666, err_fd);
+		if (FD_INVALID == err_fd)
+		{
+			joberr = joberr_io_stderr_creat;
+			job_errno = errno;
+			return joberr;
+		}
+#		ifdef __MVS__
+		if (-1 == gtm_zos_set_tag(err_fd, TAG_EBCDIC, TAG_TEXT, TAG_FORCE, &realfiletag))
+			TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_EBCDIC);
+#		endif
+		CLOSEFILE_RESET(err_fd, rc);	/* resets "err_fd" to FD_INVALID */
+		OPENFILE(fname_buf, O_WRONLY, err_fd);
+		if (FD_INVALID == err_fd)
+		{
+			joberr = joberr_io_stderr_open;
+			job_errno = errno;
+			return joberr;
+		}
 	}
+
+	/*
+	 * Redirect Input
+	 */
 	CLOSEFILE(0, rc);
 	FCNTL3(in_fd, F_DUPFD, 0, dup_ret);
 	if (-1 == dup_ret)
@@ -67,41 +203,16 @@ int ojchildioset(job_params_type *jparms)
 		job_errno = errno;
 		return joberr;
 	}
-#ifdef __MVS__
+#	ifdef __MVS__
 	/* policy tagging because by default input is /dev/null */
 	if (-1 == gtm_zos_tag_to_policy(in_fd, TAG_UNTAGGED, &realfiletag))
 		TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_UNTAGGED);
-#endif
+#	endif
 	CLOSEFILE_RESET(in_fd, rc);	/* resets "in_fd" to FD_INVALID */
 
-/*
- * Redirect Output
- */
-	strncpy(fname_buf, jparms->output.addr, jparms->output.len);
-	*(fname_buf + jparms->output.len) = '\0';
-
-	CREATE_FILE(fname_buf, 0666, out_fd);
-	if (FD_INVALID == out_fd)
-	{
-		joberr = joberr_io_stdout_creat;
-		job_errno = errno;
-		return joberr;
-	}
-#ifdef __MVS__
-	/* tagging as ASCII is fine now, that might change in the future for gtm_utf8_mode */
-	if (-1 == gtm_zos_set_tag(out_fd, TAG_ASCII, TAG_TEXT, TAG_FORCE, &realfiletag))
-		TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_ASCII);
-#endif
-	CLOSEFILE_RESET(out_fd, rc);	/* resets "out_fd" to FD_INVALID */
-
-	OPENFILE(fname_buf, O_WRONLY, out_fd);
-	if (FD_INVALID == out_fd)
-	{
-		joberr = joberr_io_stdout_open;
-		job_errno = errno;
-		return joberr;
-	}
-
+	/*
+	 * Redirect Output
+	 */
 	CLOSEFILE(1, rc);
 	FCNTL3(out_fd, F_DUPFD, 0, dup_ret);
 	if (-1 == dup_ret)
@@ -111,31 +222,10 @@ int ojchildioset(job_params_type *jparms)
 		return joberr;
 	}
 	CLOSEFILE_RESET(out_fd, rc);	/* resets "out_fd" to FD_INVALID */
-/*
- * Redirect Error
- */
-	strncpy(fname_buf, jparms->error.addr, jparms->error.len);
-	*(fname_buf + jparms->error.len) = '\0';
 
-	CREATE_FILE(fname_buf, 0666, err_fd);
-	if (FD_INVALID == err_fd)
-	{
-		joberr = joberr_io_stderr_creat;
-		job_errno = errno;
-		return joberr;
-	}
-#ifdef __MVS__
-	if (-1 == gtm_zos_set_tag(err_fd, TAG_EBCDIC, TAG_TEXT, TAG_FORCE, &realfiletag))
-		TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_EBCDIC);
-#endif
-	CLOSEFILE_RESET(err_fd, rc);	/* resets "err_fd" to FD_INVALID */
-	OPENFILE(fname_buf, O_WRONLY, err_fd);
-	if (FD_INVALID == err_fd)
-	{
-		joberr = joberr_io_stderr_open;
-		job_errno = errno;
-		return joberr;
-	}
+	/*
+	 * Redirect Error
+	 */
 	CLOSEFILE(2, rc);
 	FCNTL3(err_fd, F_DUPFD, 0, dup_ret);
 	if (-1 == dup_ret)
diff --git a/sr_unix/ojchildparms.c b/sr_unix/ojchildparms.c
index 0adf395..a99afb0 100644
--- a/sr_unix/ojchildparms.c
+++ b/sr_unix/ojchildparms.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -18,17 +18,29 @@
 
 #include "gtm_string.h"
 #include "gtm_stdlib.h"
+#include "gtm_unistd.h"
+#include "eintr_wrappers.h"
 #include "job.h"
 #include "compiler.h"
 #include "gcall.h"
 #include "stringpool.h"
 #include "op.h"		/* for op_nullexp() */
+#include "io.h"
+#include "iosocketdef.h"
 
-GBLREF	spdesc stringpool;
+#include <errno.h>
+
+GBLREF	spdesc		stringpool;
+GBLREF	io_log_name	*dollar_principal;
+GBLREF	io_pair		io_std_device;
+
+error_def(ERR_CLOSEFAIL);
+error_def(ERR_JOBSETUP);
+error_def(ERR_STRINGOFLOW);
 
 /*
  * ------------------------------------------------
- * Get parameters from environment variables into
+ * Get parameters from passed socket into
  * parameter structure
  * ------------------------------------------------
  */
@@ -37,171 +49,155 @@ void ojchildparms(job_params_type *jparms, gcall_args *g_args, mval *arglst)
 	char			*sp, *parmbuf;
 	char			parm_string[8];
 	int4			argcnt, i;
-
-	error_def(ERR_STRINGOFLOW);
-
-	/* getenv() may use static buffer so for any parms we fetch a value for, rebuffer them so they
-	   don't go away. We use malloc'd space because the stringpool garbage collector does not know
-	   about these private (to this routine) structures and we can't use "temp stringpool space" as
-	   is used in other modules since we will be putting the parms in the stringpool below. The
-	   storage allocated here will be released in jobchild_init() when it is done with it.
-	*/
-	if (jparms->directory.addr = GETENV(CWD_ENV))
-	{
-		jparms->directory.len = STRLEN(jparms->directory.addr);
-		if (0 != jparms->directory.len)
-		{
-			parmbuf = malloc(jparms->directory.len+1);
-			memcpy(parmbuf, jparms->directory.addr, jparms->directory.len+1);
-		 	jparms->directory.addr = parmbuf;
-	 	}
-	} else
-		jparms->directory.len = 0;
-
-	if (jparms->gbldir.addr = GETENV(GBLDIR_ENV))
-	{
-		jparms->gbldir.len = STRLEN(jparms->gbldir.addr);
-		if (0 != jparms->gbldir.len)
-		{
-			parmbuf = malloc(jparms->gbldir.len+1);
-			memcpy(parmbuf, jparms->gbldir.addr, jparms->gbldir.len+1);
-			jparms->gbldir.addr = parmbuf;
-		}
-	} else
-		jparms->gbldir.len = 0;
-
-	if (jparms->startup.addr = GETENV(STARTUP_ENV))
-	{
-		jparms->startup.len = STRLEN(jparms->startup.addr);
-		if (0 != jparms->startup.len)
-		{
-			parmbuf = malloc(jparms->startup.len+1);
-			memcpy(parmbuf, jparms->startup.addr, jparms->startup.len+1);
-			jparms->startup.addr = parmbuf;
-		}
-	} else
-		jparms->startup.len = 0;
-
-	if (jparms->input.addr = GETENV(IN_FILE_ENV))
-	{
-		jparms->input.len = STRLEN(jparms->input.addr);
-		if (0 != jparms->input.len)
-		{
-			parmbuf = malloc(jparms->input.len+1);
-			memcpy(parmbuf, jparms->input.addr, jparms->input.len+1);
-			jparms->input.addr = parmbuf;
-		}
-	} else
-		jparms->input.len = 0;
-
-	if (jparms->output.addr = GETENV(OUT_FILE_ENV))
-	{
-		jparms->output.len = STRLEN(jparms->output.addr);
-		if (0 != jparms->output.len)
-		{
-			parmbuf = malloc(jparms->output.len+1);
-			memcpy(parmbuf, jparms->output.addr, jparms->output.len+1);
-			jparms->output.addr = parmbuf;
-		}
-	} else
-		jparms->output.len = 0;
-
-	if (jparms->error.addr = GETENV(ERR_FILE_ENV))
-	{
-		jparms->error.len = STRLEN(jparms->error.addr);
-		if (0 != jparms->error.len)
-		{
-			parmbuf = malloc(jparms->error.len+1);
-			memcpy(parmbuf, jparms->error.addr, jparms->error.len+1);
-			jparms->error.addr = parmbuf;
-		}
-	} else
-		jparms->error.len = 0;
-
-	if (jparms->routine.addr = GETENV(ROUTINE_ENV))
-	{
-		jparms->routine.len = STRLEN(jparms->routine.addr);
-		if (0 != jparms->routine.len)
-		{
-			parmbuf = malloc(jparms->routine.len+1);
-			memcpy(parmbuf, jparms->routine.addr, jparms->routine.len+1);
-			jparms->routine.addr = parmbuf;
-		}
-	} else
-		jparms->routine.len = 0;
-
-	if (jparms->label.addr = GETENV(LABEL_ENV))
-	{
-		jparms->label.len = STRLEN(jparms->label.addr);
-		if (0 != jparms->label.len)
-		{
-			parmbuf = malloc(jparms->label.len+1);
-			memcpy(parmbuf, jparms->label.addr, jparms->label.len+1);
-			jparms->label.addr = parmbuf;
-		}
-	} else
-		jparms->label.len = 0;
-
-	if (jparms->logfile.addr = GETENV(LOG_FILE_ENV))
-	{
-		jparms->logfile.len = STRLEN(jparms->logfile.addr);
-		if (0 != jparms->logfile.len)
-		{
-			parmbuf = malloc(jparms->logfile.len+1);
-			memcpy(parmbuf, jparms->logfile.addr, jparms->logfile.len+1);
-			jparms->logfile.addr = parmbuf;
-		}
-	} else
-		jparms->logfile.len = 0;
-
-	if (sp = GETENV(OFFSET_ENV))
-		jparms->offset = (int)(ATOL(sp));
-	else
-		jparms->offset = 0;
-
-	if (sp = GETENV(PRIORITY_ENV))
-		jparms->baspri = (int)(ATOL(sp));
-	else
-		jparms->baspri = 0;
-
-	if (!(sp = GETENV(GTMJCNT_ENV)))
-		GTMASSERT;
-
-	if (argcnt = (int)(ATOL(sp)))
+	int			setup_fd;
+	int			rc;
+	job_setup_op		setup_op;
+	boolean_t		setup_done = FALSE;
+	job_params_msg		params;
+	job_arg_count_msg	arg_count;
+	job_arg_msg		arg_msg;
+	job_buffer_size_msg	buffer_size;
+	d_socket_struct		*dsocketptr;
+	socket_struct		*socketptr;
+
+	assertpro((sp = GETENV(CHILD_FLAG_ENV)) && sp[0]);	/* note assignment */
+	setup_fd = (int)ATOL(sp);
+
+	g_args->callargs = 0;
+
+	while(!setup_done)
 	{
-		ENSURE_STP_FREE_SPACE(argcnt * MAX_TRANS_NAME_LEN);
-		g_args->callargs = argcnt + 4;
-		g_args->truth = 1;
-		g_args->retval = 0;
-		g_args->mask = 0;
-		g_args->argcnt = argcnt;
-		memcpy(parm_string,"gtmj000",8);
-		for (i = 0; i < argcnt; i++)
+		RECV(setup_fd, &setup_op, SIZEOF(setup_op), 0, rc);
+		if (rc < 0)
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("setup operation"), errno, 0);
+		assert(SIZEOF(setup_op) == rc);
+		switch(setup_op)
 		{
-			if (sp = GETENV(parm_string))
+		case job_done:
+			setup_done = TRUE;
+			break;
+
+		case job_set_params:
+			RECV(setup_fd, &params, SIZEOF(params), 0, rc);
+			if (rc < 0)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("job parameters"), errno, 0);
+			assert(SIZEOF(params) == rc);
+
+			jparms->directory.len = params.directory_len;
+			jparms->gbldir.len = params.gbldir_len;
+			jparms->startup.len = params.startup_len;
+			jparms->input.len = params.input_len;
+			jparms->output.len = params.output_len;
+			jparms->error.len = params.error_len;
+			jparms->routine.len = params.routine_len;
+			jparms->label.len = params.label_len;
+			jparms->baspri = params.baspri;
+			jparms->offset = params.offset;
+
+			if (0 != params.directory_len)
+			{
+				jparms->directory.addr = malloc(jparms->directory.len + 1);
+				memcpy(jparms->directory.addr, params.directory, jparms->directory.len + 1);
+			}
+			if (0 != params.gbldir_len)
+			{
+				jparms->gbldir.addr = malloc(jparms->gbldir.len + 1);
+				memcpy(jparms->gbldir.addr, params.gbldir, jparms->gbldir.len + 1);
+			}
+			if (0 != params.startup_len)
+			{
+				jparms->startup.addr = malloc(jparms->startup.len + 1);
+				memcpy(jparms->startup.addr, params.startup, jparms->startup.len + 1);
+			}
+			if (0 != params.input_len)
+			{
+				jparms->input.addr = malloc(jparms->input.len + 1);
+				memcpy(jparms->input.addr, params.input, jparms->input.len + 1);
+			}
+			if (0 != params.output_len)
+			{
+				jparms->output.addr = malloc(jparms->output.len + 1);
+				memcpy(jparms->output.addr, params.output, jparms->output.len + 1);
+			}
+			if (0 != params.error_len)
+			{
+				jparms->error.addr = malloc(jparms->error.len + 1);
+				memcpy(jparms->error.addr, params.error, jparms->error.len + 1);
+			}
+			if (0 != params.routine_len)
+			{
+				jparms->routine.addr = malloc(jparms->routine.len + 1);
+				memcpy(jparms->routine.addr, params.routine, jparms->routine.len + 1);
+			}
+			if (0 != params.label_len)
 			{
-				if (!IS_STP_SPACE_AVAILABLE_PRO(STRLEN(sp)))
-					rts_error(VARLSTCNT(1) (ERR_STRINGOFLOW));
-				arglst[i].str.len = STRLEN(sp);
-				arglst[i].str.addr = (char *)stringpool.free;
-				memcpy(stringpool.free, sp, arglst[i].str.len);
-				stringpool.free += arglst[i].str.len;
-				arglst[i].mvtype = MV_STR;
-			} else
-				op_nullexp(&arglst[i]);
-			g_args->argval[i] = &arglst[i];
-			if (parm_string[6] == '9')
+				jparms->label.addr = malloc(jparms->label.len + 1);
+				memcpy(jparms->label.addr, params.label, jparms->label.len + 1);
+			}
+
+			break;
+
+		case job_set_parm_list:
+			RECV(setup_fd, &arg_count, SIZEOF(arg_count), 0, rc);
+			if (rc < 0)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("argument count"), errno, 0);
+			assert(SIZEOF(arg_count) == rc);
+			g_args->callargs = arg_count + 4;
+			g_args->truth = 1;
+			g_args->retval = 0;
+			g_args->mask = 0;
+			g_args->argcnt = arg_count;
+			for (i = 0; i < arg_count; i++)
 			{
-				if (parm_string[5] == '9')
+				RECV(setup_fd, &arg_msg, SIZEOF(arg_msg), 0, rc);
+				if (rc < 0)
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("argument"),
+							errno, 0);
+				assert(SIZEOF(arg_msg) == rc);
+				if (0 > arg_msg.len)
+					g_args->argval[i] = op_nullexp();	/* negative len indicates null arg */
+				else
 				{
-					parm_string[4] = parm_string[4] + 1;
-					parm_string[5] = '0';
-				} else
-					parm_string[5] = parm_string[5] + 1;
-				parm_string[6] = '0';
-			} else
-				parm_string[6] = parm_string[6] + 1;
+					if (!IS_STP_SPACE_AVAILABLE_PRO(STRLEN(sp)))
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) (ERR_STRINGOFLOW));
+					arglst[i].str.len = arg_msg.len;
+					arglst[i].str.addr = (char *)stringpool.free;
+					memcpy(stringpool.free, arg_msg.data, arg_msg.len);
+					stringpool.free += arg_msg.len;
+					arglst[i].mvtype = MV_STR;
+					g_args->argval[i] = &arglst[i];
+				}
+			}
+			break;
+
+		case job_set_input_buffer:
+			assertpro(io_std_device.in && (gtmsocket == io_std_device.in->type));
+			dsocketptr = (d_socket_struct *)(io_std_device.in->dev_sp);
+			assertpro(dsocketptr);
+			assertpro(-1 != dsocketptr->current_socket);
+			assertpro(dsocketptr->current_socket < dsocketptr->n_socket);
+			socketptr = dsocketptr->socket[dsocketptr->current_socket];
+
+			RECV(setup_fd, &buffer_size, SIZEOF(buffer_size), 0, rc);
+			if (rc < 0)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("input buffer size"),
+						errno, 0);
+			assert(SIZEOF(buffer_size) == rc);
+			assertpro(buffer_size <= DEFAULT_SOCKET_BUFFER_SIZE);
+			assertpro(buffer_size <= socketptr->buffer_size);
+
+			RECV(setup_fd, socketptr->buffer, buffer_size, 0, rc);
+			if (rc < 0)
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JOBSETUP, 2, LEN_AND_LIT("input buffer"), errno, 0);
+			assert(buffer_size == rc);
+			socketptr->buffered_length = buffer_size;
+			socketptr->buffered_offset = 0;
+			break;
+
+		default:
+			assertpro(FALSE && setup_op);
 		}
-	} else
-		g_args->callargs = 0;
+	}
+	if ((rc = close(setup_fd)) < 0)
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CLOSEFAIL, 1, setup_fd, errno, 0);
 }
diff --git a/sr_unix/ojparams.c b/sr_unix/ojparams.c
index 4adbd2d..9600faa 100644
--- a/sr_unix/ojparams.c
+++ b/sr_unix/ojparams.c
@@ -15,6 +15,8 @@
 
 #include "job.h"
 #include "min_max.h"
+#include "io.h"
+#include "iosocketdef.h"
 
 /*
  * ---------------------------------------------------------
@@ -23,7 +25,6 @@
  */
 
 static readonly char definput[] = "/dev/null";
-static readonly char deflogfile[] = "/dev/null";
 
 static char *defoutbuf;
 static char *deferrbuf;
@@ -33,6 +34,8 @@ MSTR_CONST(deferrext, ".mje");
 
 LITREF jp_datatype	job_param_datatypes[];
 
+GBLREF	d_socket_struct		*socket_pool;
+
 error_def		(ERR_PARFILSPC);
 
 /*
@@ -47,7 +50,7 @@ void ojparams (char *p, job_params_type *job_params)
 {
 	unsigned char		ch;
 	int4			status;
-
+	mstr_len_t		handle_len;
 
 		/* Initializations */
 	job_params->baspri = 0;
@@ -56,8 +59,6 @@ void ojparams (char *p, job_params_type *job_params)
 	job_params->error.len = 0;
 	job_params->gbldir.len = 0;
 	job_params->startup.len = 0;
-	job_params->logfile.addr = 0;
-	job_params->logfile.len = 0;
 	job_params->directory.len = 0;
 	job_params->directory.addr = 0;
 	job_params->cmdline.len = 0;
@@ -100,14 +101,6 @@ void ojparams (char *p, job_params_type *job_params)
 			}
 			break;
 
-		case jp_logfile:
-			if (*p != 0)
-			{
-				job_params->logfile.len = (int)((unsigned char) *p);
-				job_params->logfile.addr = p + 1;
-			}
-			break;
-
 		case jp_output:
 			if (*p != 0)
 			{
@@ -139,6 +132,7 @@ void ojparams (char *p, job_params_type *job_params)
 		case jp_account:
 		case jp_detached:
 		case jp_image:
+		case jp_logfile:
 		case jp_noaccount:
 		case jp_nodetached:
 		case jp_noswapping:
@@ -147,7 +141,7 @@ void ojparams (char *p, job_params_type *job_params)
 		case jp_swapping:
 			break;
 		default:
-		        GTMASSERT;
+		        assertpro(ch != ch);
 		}
 
 		switch (job_param_datatypes[ch])
@@ -163,7 +157,9 @@ void ojparams (char *p, job_params_type *job_params)
 			p += ((int)((unsigned char)*p)) + 1;
 			break;
 		default:
-			GTMASSERT;
+			assertpro((jpdt_nul == job_param_datatypes[ch])
+				|| (jpdt_num == job_param_datatypes[ch])
+				|| (jpdt_str == job_param_datatypes[ch]));
 		}
 	}
 
@@ -177,6 +173,14 @@ void ojparams (char *p, job_params_type *job_params)
 		job_params->input.len = STRLEN(definput);
 		job_params->input.addr = definput;
 	}
+	else if (IS_JOB_SOCKET(job_params->input.addr, job_params->input.len))
+	{
+		handle_len = JOB_SOCKET_HANDLE_LEN(job_params->input.len);
+		if ((NULL == socket_pool) || (-1 == iosocket_handle(JOB_SOCKET_HANDLE(job_params->input.addr),
+									&handle_len, FALSE, socket_pool)))
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_PARFILSPC, 4, 5, "INPUT",
+				job_params->input.len, job_params->input.addr);
+	}
 	else
 		if (!(status = ojchkfs (job_params->input.addr,
 		  job_params->input.len, TRUE)))
@@ -200,6 +204,14 @@ void ojparams (char *p, job_params_type *job_params)
 		  + defoutext.len;
 		job_params->output.addr = &defoutbuf[0];
 	}
+	else if (IS_JOB_SOCKET(job_params->output.addr, job_params->output.len))
+	{
+		handle_len = JOB_SOCKET_HANDLE_LEN(job_params->output.len);
+		if ((NULL == socket_pool) || (-1 == iosocket_handle(JOB_SOCKET_HANDLE(job_params->output.addr),
+									&handle_len, FALSE, socket_pool)))
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_PARFILSPC, 4, 5, "OUTPUT",
+				job_params->output.len, job_params->output.addr);
+	}
 	else
 		if (!(status = ojchkfs (job_params->output.addr,
 		  job_params->output.len, FALSE)))
@@ -223,6 +235,14 @@ void ojparams (char *p, job_params_type *job_params)
 		  + deferrext.len;
 		job_params->error.addr = &deferrbuf[0];
 	}
+	else if (IS_JOB_SOCKET(job_params->error.addr, job_params->error.len))
+	{
+		handle_len = JOB_SOCKET_HANDLE_LEN(job_params->error.len);
+		if ((NULL == socket_pool) || (-1 == iosocket_handle(JOB_SOCKET_HANDLE(job_params->error.addr),
+									&handle_len, FALSE, socket_pool)))
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_PARFILSPC, 4, 5, "ERROR",
+				job_params->error.len, job_params->error.addr);
+	}
 	else
 		if (!(status = ojchkfs (job_params->error.addr,
 		  job_params->error.len, FALSE)))
@@ -253,18 +273,5 @@ void ojparams (char *p, job_params_type *job_params)
 		  job_params->directory.len, FALSE)))
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_PARFILSPC, 4, 7, "DEFAULT",
 			  job_params->directory.len, job_params->directory.addr);
-/*
- * Logfile
- */
-	if (job_params->logfile.len == 0)
-	{
-		job_params->logfile.len = STRLEN(deflogfile);
-		job_params->logfile.addr = deflogfile;
-	}
-	else
-		if (!(status = ojchkfs (job_params->logfile.addr,
-		  job_params->logfile.len, FALSE)))
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_PARFILSPC, 4, 7, "LOGFILE",
-			  job_params->logfile.len, job_params->logfile.addr);
 }
 
diff --git a/sr_unix/ojstartchild.c b/sr_unix/ojstartchild.c
index c1b7db1..17f368c 100644
--- a/sr_unix/ojstartchild.c
+++ b/sr_unix/ojstartchild.c
@@ -112,6 +112,24 @@ GBLREF char	gtm_dist[GTM_PATH_MAX];
 	}												\
 }
 
+#define SETUP_OP_FAIL()									\
+{											\
+	kill(child_pid, SIGTERM);							\
+	joberr = joberr_io_setup_op_write;						\
+	job_errno = errno;								\
+	DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);		\
+	_exit(joberr);									\
+}
+
+#define SETUP_DATA_FAIL()								\
+{											\
+	kill(child_pid, SIGTERM);							\
+	joberr = joberr_io_setup_write;							\
+	job_errno = errno;								\
+	DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);		\
+	_exit(joberr);									\
+}
+
 error_def(ERR_JOBFAIL);
 error_def(ERR_JOBPARTOOLONG);
 error_def(ERR_LOGTOOLONG);
@@ -122,7 +140,7 @@ error_def(ERR_TEXT);
  */
 
 void job_term_handler(int sig);
-static int io_rename(job_params_type *jparms, const int jobid);
+static int io_rename(job_params_msg *params, const int jobid);
 
 /* Middle process sets the entryref for the jobbed-off process by calling job_addr(). job_addr() internally calls op_zlink(). If
  * rts_error occurs when we are in the job_addr() function, the topmost condition handler inherited from parent process will be
@@ -132,9 +150,12 @@ static int io_rename(job_params_type *jparms, const int jobid);
 static CONDITION_HANDLER(middle_child)
 {
 	int pipe_status;
-	/* As of now, middle process could encounter rts_error only while setting entryref. Hence the following assert. */
-	assert(joberr == joberr_rtn);
+	START_CH(FALSE);
 	DOWRITERC(pipe_fd, &job_errno, SIZEOF(job_errno), pipe_status);
+	/* As of now, middle process could encounter rts_error only while setting entryref. Hence the following assert.
+	 * Do assert after write to prevent parent hang.
+	 */
+	assert(joberr == joberr_rtn);
 	_exit(joberr);
 }
 
@@ -171,26 +192,26 @@ void job_term_handler(int sig)
 			return;
 }
 
-static int io_rename(job_params_type *jparms, const int jobid)
+static int io_rename(job_params_msg *params, const int jobid)
 {
 	char path[MAX_STDIOE_LEN];
 
-	strncpy(path, jparms->output.addr, jparms->output.len);
-	*(jparms->output.addr + jparms->output.len) = '\0';
-	SPRINTF(&path[jparms->output.len], ".%d", jobid);
-	if (rename(jparms->output.addr, path))
+	strncpy(path, params->output, params->output_len);
+	SNPRINTF(&path[params->output_len], MAX_STDIOE_LEN - params->output_len, ".%d", jobid);
+	if (rename(params->output, path))
 	{
 		job_errno = errno;
 		return(joberr_stdout_rename);
 	}
-	strncpy(path, jparms->error.addr, jparms->error.len);
-	*(jparms->error.addr + jparms->error.len) = '\0';
-	SPRINTF(&path[jparms->error.len], ".%d", jobid);
-	if (rename(jparms->error.addr, path))
+	params->output_len = strlen(params->output);
+	strncpy(path, params->error, params->error_len);
+	SNPRINTF(&path[params->error_len], MAX_STDIOE_LEN - params->error_len,  ".%d", jobid);
+	if (rename(params->error, path))
 	{
 		job_errno = errno;
 		return(joberr_stderr_rename);
 	}
+	params->error_len = strlen(params->error);
 	return 0;
 }
 
@@ -225,13 +246,19 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 	int			wait_status, save_errno, kill_ret;
 	int			rc, dup_ret, in_fd;
 	int			status;
-	pid_t			par_pid, child_pid, done_pid;
+	pid_t			child_pid, done_pid;
 	job_parm		*jp;
 	rhdtyp			*base_addr;
 	struct sigaction	act, old_act;
 	int			pipe_status, env_len;
 	int			mproc_fds[2]; 	/* pipe between middle process and grandchild process */
 	int			decision;
+	int			setup_fds[2];	/* socket pair for setup of final mumps process */
+	job_setup_op		setup_op;
+	job_params_msg		params;
+	job_arg_count_msg	arg_count;
+	job_arg_msg		arg_msg;
+	job_buffer_size_msg	buffer_size;
 
 #ifdef	__osf__
 /* These must be O/S-compatible 64-bit pointers for OSF/1.  */
@@ -247,8 +274,6 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 #ifdef	__osf__
 #pragma pointer_size (restore)
 #endif
-	par_pid = getppid();
-
 	FORK_RETRY(child_pid);
 	if (child_pid == 0)
 	{
@@ -277,31 +302,36 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 			DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);
 			_exit(joberr);
 		}
-		/* Redirect input before potentially changing the default directory below.*/
-		strncpy(fname_buf, jparms->input.addr, jparms->input.len);
-		*(fname_buf + jparms->input.len) = '\0';
-
-		OPENFILE(fname_buf, O_RDONLY, in_fd);
-		if (FD_INVALID == in_fd)
-		{
-			joberr = joberr_io_stdin_open;
-			job_errno = errno;
-			return joberr;
-		}
-		CLOSEFILE(0, rc);
-		FCNTL3(in_fd, F_DUPFD, 0, dup_ret);
-		if (-1 == dup_ret)
+		if (!IS_JOB_SOCKET(jparms->input.addr, jparms->input.len))
 		{
-			joberr = joberr_io_stdin_dup;
-			job_errno = errno;
-			return joberr;
-		}
+			/* Redirect input before potentially changing the default directory below.*/
+			strncpy(fname_buf, jparms->input.addr, jparms->input.len);
+			*(fname_buf + jparms->input.len) = '\0';
+
+			OPENFILE(fname_buf, O_RDONLY, in_fd);
+			if (FD_INVALID == in_fd)
+			{
+				joberr = joberr_io_stdin_open;
+				job_errno = errno;
+				DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);
+				_exit(joberr);
+			}
+			CLOSEFILE(0, rc);
+			FCNTL3(in_fd, F_DUPFD, 0, dup_ret);
+			if (-1 == dup_ret)
+			{
+				joberr = joberr_io_stdin_dup;
+				job_errno = errno;
+				DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);
+				_exit(joberr);
+			}
 #ifdef __MVS__
-		/* policy tagging because by default input is /dev/null */
-		if (-1 == gtm_zos_tag_to_policy(in_fd, TAG_UNTAGGED, &realfiletag))
-			TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_UNTAGGED);
+			/* policy tagging because by default input is /dev/null */
+			if (-1 == gtm_zos_tag_to_policy(in_fd, TAG_UNTAGGED, &realfiletag))
+				TAG_POLICY_SEND_MSG(fname_buf, errno, realfiletag, TAG_UNTAGGED);
 #endif
-		CLOSEFILE_RESET(in_fd, rc);	/* resets "in_fd" to FD_INVALID */
+			CLOSEFILE_RESET(in_fd, rc);	/* resets "in_fd" to FD_INVALID */
+		}
 		if (0 != jparms->directory.len)
 		{
 			/* If directory is specified, change it */
@@ -347,18 +377,36 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 			_exit(joberr);
 		}
 
+		joberr = joberr_sp;
+		if (-1 == (rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, setup_fds)))
+		{
+			job_errno = errno;
+			DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);
+			_exit(joberr);
+		}
+
 		/* clone self and exit */
 		FORK_RETRY(child_pid);
-		if (child_pid)	/* BYPASSOK: we exec immediately, no FORK_CLEAN needed */
+		if (child_pid)
 		{
 			/* This is still the middle process.  */
 			/* Close the read end of the pipe between middle process and grandchild process. */
-			CLOSEFILE_RESET(mproc_fds[0], pipe_status);	/* resets "pipe_fds[0]" to FD_INVALID */
+			CLOSEFILE_RESET(mproc_fds[0], pipe_status);	/* resets "mproc_fds[0]" to FD_INVALID */
+			CLOSEFILE_RESET(setup_fds[1], pipe_status);	/* resets "setup_fds[0]" to FD_INVALID */
 			assert(SIZEOF(pid_t) == SIZEOF(child_pid));
+			/* params data for 'output' and 'error' is populated here because io_rename() needs it in case appending of
+			 * JOB ID to Standard Output and Standard Error is required.
+			 */
+			params.output_len = jparms->output.len;
+			memcpy(params.output, jparms->output.addr, jparms->output.len);
+			params.output[jparms->output.len] = '\0';
+			params.error_len = jparms->error.len;
+			memcpy(params.error, jparms->error.addr, jparms->error.len);
+			params.error[jparms->error.len] = '\0';
 			/* if the Job pid need to be appended to the std out/err file names */
 			if (jobpid)
 			{
-				joberr = io_rename(jparms, child_pid);
+				joberr = io_rename(&params, child_pid);
 				if (joberr)
 				{
 					/* Inform grandchild that it will have to exit. If pipe operation failed terminate
@@ -372,31 +420,118 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 					_exit(joberr);
 				}
 			}
-			/* write child_pid into pipe to be read by parent process(P) for $ZJOB */
-			DOWRITERC(pipe_fds[1], &child_pid, SIZEOF(child_pid), pipe_status);
-			/* Failed to send parent new JOBID. Terminate the child and exit middle process. */
+
+			/* Inform grandchild that everything is properly set for it and it is ready to continue. */
+			decision = JOB_CONTINUE;
+			DOWRITERC(mproc_fds[1], &decision, SIZEOF(decision), pipe_status);
 			if (pipe_status)
 			{
-				/* Inform grandchild that it will have to exit. If pipe operation failed terminate the
-				 * grandchild.
-				 */
-				joberr = joberr_pipe_mp;
-				decision = JOB_EXIT;
-				DOWRITERC(mproc_fds[1], &decision, SIZEOF(decision), pipe_status);
-				if (pipe_status)
-					kill(child_pid, SIGTERM);
+				kill(child_pid, SIGTERM);
+				joberr = joberr_pipe_mgc;
+				job_errno = errno;
+				DOWRITERC(pipe_fds[1], &job_errno, SIZEOF(job_errno), pipe_status);
 				_exit(joberr);
+			}
+
+			/* send job parameters and arguments to final mumps process over setup socket */
+			setup_op = job_set_params;
+			SEND(setup_fds[0], &setup_op, SIZEOF(setup_op), 0, rc);
+			if (rc < 0)
+				SETUP_OP_FAIL();
+
+			params.directory_len = jparms->directory.len;
+			memcpy(params.directory, jparms->directory.addr, jparms->directory.len);
+			if (0 < jparms->gbldir.len)
+			{
+				params.gbldir_len = jparms->gbldir.len;
+				memcpy(params.gbldir, jparms->gbldir.addr, jparms->gbldir.len);
+				params.gbldir[jparms->gbldir.len] = '\0';
 			} else
 			{
-				/* Inform grandchild that everything is properly set for it and it is ready to continue. */
-				decision = JOB_CONTINUE;
-				DOWRITERC(mproc_fds[1], &decision, SIZEOF(decision), pipe_status);
-				/* If pipe_status is non-zero i.e. error occurred in pipe operation or total
-				 * SIZEOF(decision) bytes are not written in the pipe. In this case, we let the grandchild
-				 * handle its own fate as we have already conveyed back the grandchild's pid to parent
-				 * process and all the setup for the grandchild is successfully done.
-				 */
+				pgbldir_str = GETENV(GBLDIR_ENV);
+				if (pgbldir_str && *pgbldir_str)
+				{
+					params.gbldir_len = STRLEN(pgbldir_str);
+					memcpy(params.gbldir, pgbldir_str, params.gbldir_len);
+				} else
+					params.gbldir_len = 0;
 			}
+			params.startup_len = jparms->startup.len;
+			memcpy(params.startup, jparms->startup.addr, jparms->startup.len);
+			params.startup[jparms->startup.len] = '\0';
+			params.input_len = jparms->input.len;
+			memcpy(params.input, jparms->input.addr, jparms->input.len);
+			params.input[jparms->input.len] = '\0';
+			/* 'output' and 'error' are already moved to params above */
+			params.routine_len = jparms->routine.len;
+			memcpy(params.routine, jparms->routine.addr, jparms->routine.len);
+			params.routine[jparms->routine.len] = '\0';
+			params.label_len = jparms->label.len;
+			memcpy(params.label, jparms->label.addr, jparms->label.len);
+			params.label[jparms->label.len] = '\0';
+			params.offset = jparms->offset;
+			params.baspri = jparms->baspri;
+			SEND(setup_fds[0], &params, SIZEOF(params), 0, rc);
+			if (rc < 0)
+				SETUP_DATA_FAIL();
+
+			setup_op = job_set_parm_list;
+			SEND(setup_fds[0], &setup_op, SIZEOF(setup_op), 0, rc);
+			if (rc < 0)
+				SETUP_OP_FAIL();
+
+			arg_count = argcnt;
+			SEND(setup_fds[0], &arg_count, SIZEOF(arg_count), 0, rc);
+			if (rc < 0)
+				SETUP_DATA_FAIL();
+
+			for (jp = jparms->parms;  jp ; jp = jp->next)
+			{
+				if (jp->parm->str.len > MAX_JOB_LEN - 2)
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
+				if (0 == jp->parm->mvtype)
+					arg_msg.len = -1;	/* negative len indicates null arg */
+				else
+				{
+					MV_FORCE_STR(jp->parm);
+					arg_msg.len = jp->parm->str.len;
+					memcpy(arg_msg.data, jp->parm->str.addr, jp->parm->str.len);
+				}
+
+				SEND(setup_fds[0], &arg_msg, SIZEOF(arg_msg), 0, rc);
+				if (rc < 0)
+					SETUP_DATA_FAIL();
+			}
+
+			if (0 < jparms->input_prebuffer_size)
+			{
+				setup_op = job_set_input_buffer;
+				SEND(setup_fds[0], &setup_op, SIZEOF(setup_op), 0, rc);
+				if (rc < 0)
+					SETUP_OP_FAIL();
+
+				buffer_size = jparms->input_prebuffer_size;
+				SEND(setup_fds[0], &buffer_size, SIZEOF(buffer_size), 0, rc);
+				if (rc < 0)
+					SETUP_DATA_FAIL();
+
+				SEND(setup_fds[0], jparms->input_prebuffer, jparms->input_prebuffer_size, 0, rc);
+				if (rc < 0)
+					SETUP_DATA_FAIL();
+				/* input_prebuffer leaks, but the middle process is about to exit, so don't worry about it */
+			}
+
+			/* tell job to proceed */
+			setup_op = job_done;
+			SEND(setup_fds[0], &setup_op, SIZEOF(setup_op), 0, rc);
+			if (rc < 0)
+				SETUP_OP_FAIL();
+
+			/* write child_pid into pipe to be read by parent process(P) for $ZJOB */
+			/* Ignore the status if this fails, as the child is already running, and there is likely not a parent
+			 * to report to.
+			 */
+			DOWRITERC(pipe_fds[1], &child_pid, SIZEOF(child_pid), pipe_status);
 			_exit(EXIT_SUCCESS);
 		}
 		/* This is now the grandchild process (actual Job process) -- an orphan as soon as the exit(EXIT_SUCCESS) above
@@ -405,6 +540,7 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 		ESTABLISH_RET(grand_child, 0);
 		sigaction(SIGTERM, &old_act, 0);		/* restore the SIGTERM handler */
 		CLOSEFILE_RESET(mproc_fds[1], pipe_status);	/* resets "mproc_fds[0]" to FD_INVALID */
+		CLOSEFILE_RESET(setup_fds[0], pipe_status);	/* resets "setup_fds[0]" to FD_INVALID */
 		DOREADRC(mproc_fds[0], &decision, SIZEOF(decision), pipe_status);
 		if (pipe_status)	 /* We failed to read the communication from middle process */
 	                rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JOBFAIL, 0, ERR_TEXT, 2,
@@ -463,7 +599,7 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 		 *	each line above is an entry in the environment array.
 		 */
 
-		env_ind = env_ary = (char **)malloc((environ_count + MAX_JOB_QUALS + argcnt + 1)*SIZEOF(char *));
+		env_ind = env_ary = (char **)malloc((environ_count + MAX_JOB_QUALS + 1)*SIZEOF(char *));
 
 #ifdef	__osf__
 #pragma pointer_size (restore)
@@ -476,7 +612,7 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 #ifdef KEEP_zOS_EBCDIC
 #pragma convlit(suspend)
 #endif
-		SPRINTF_ENV_NUM(c1, CHILD_FLAG_ENV, par_pid, env_ind);
+		SPRINTF_ENV_NUM(c1, CHILD_FLAG_ENV, setup_fds[1], env_ind);
 #ifdef KEEP_zOS_EBCDIC
 #pragma convlit(resume)
 #endif
@@ -503,188 +639,6 @@ int ojstartchild (job_params_type *jparms, int argcnt, boolean_t *non_exit_retur
 #pragma convlit(resume)
 #endif
 		}
-		/* pass startup program to child */
-		if (jparms->startup.len != 0)
-		{
-			if (jparms->startup.len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			strncpy(pbuff, jparms->startup.addr, jparms->startup.len);
-			*(pbuff + jparms->startup.len) = '\0';
-			string_len = STRLEN("%s=%s") + STRLEN(STARTUP_ENV) + STRLEN(pbuff) - 4;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_STR(c1, STARTUP_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-		/* pass input file to child */
-		if (jparms->input.len != 0)
-		{
-			if (jparms->input.len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			strncpy(pbuff, jparms->input.addr, jparms->input.len);
-			*(pbuff + jparms->input.len) = '\0';
-			string_len = STRLEN("%s=%s") + STRLEN(IN_FILE_ENV) + STRLEN(pbuff) - 4;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_STR(c1, IN_FILE_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-
-		/* pass output file to child */
-		if (jparms->output.addr != 0)
-		{
-			if (jparms->output.len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			strncpy(pbuff, jparms->output.addr, jparms->output.len);
-			*(pbuff + jparms->output.len) = '\0';
-			if (jobpid)
-				SPRINTF(&pbuff[jparms->output.len], ".%d", getpid());
-			string_len = STRLEN("%s=%s") + STRLEN(OUT_FILE_ENV) + STRLEN(pbuff) - 4;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_STR(c1, OUT_FILE_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-
-		/* pass error file to child */
-		if (jparms->error.len != 0)
-		{
-			if (jparms->error.len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			strncpy(pbuff, jparms->error.addr, jparms->error.len);
-			*(pbuff + jparms->error.len) = '\0';
-			if (jobpid)
-				SPRINTF(&pbuff[jparms->error.len], ".%d", getpid());
-			string_len = STRLEN("%s=%s") + STRLEN(ERR_FILE_ENV) + STRLEN(pbuff) - 4;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_STR(c1, ERR_FILE_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-
-		/* pass routine name to child */
-		if (jparms->routine.len != 0)
-		{
-			if (jparms->routine.len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			strncpy(pbuff, jparms->routine.addr, jparms->routine.len);
-			*(pbuff + jparms->routine.len) = '\0';
-			string_len = STRLEN("%s=%s") + STRLEN(ROUTINE_ENV) + STRLEN(pbuff) - 4;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_STR(c1, ROUTINE_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-
-		/* pass label name to child */
-		if (jparms->label.len > TEMP_BUFF_SIZE)
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-		strncpy(pbuff, jparms->label.addr, jparms->label.len);
-		*(pbuff + jparms->label.len) = '\0';
-		string_len = STRLEN("%s=%s") + STRLEN(LABEL_ENV) + STRLEN(pbuff) - 4;
-		if (string_len > TEMP_BUFF_SIZE)
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-		c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-		SPRINTF_ENV_STR(c1, LABEL_ENV, pbuff, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-
-		/* pass the offset */
-		string_len = STRLEN("%s=%ld") + STRLEN(OFFSET_ENV) + MAX_NUM_LEN - 5;
-		if (string_len > TEMP_BUFF_SIZE)
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-		c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-		SPRINTF_ENV_NUM(c1, OFFSET_ENV, jparms->offset, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-
-		/* pass Priority to child */
-		if (jparms->baspri != 0)
-		{
-			string_len = STRLEN("%s=%ld") + STRLEN(PRIORITY_ENV) + MAX_NUM_LEN - 5;
-			if (string_len > TEMP_BUFF_SIZE)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-			SPRINTF_ENV_NUM(c1, PRIORITY_ENV, jparms->baspri, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
-		}
-
-		for (index = 0, jp = jparms->parms;  jp ;  index++, jp = jp->next)
-		{
-			if (jp->parm->str.len > MAX_JOB_LEN - 2)
-				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-			if (0 != jp->parm->mvtype)
-			{
-				MV_FORCE_STR(jp->parm);
-				string_len = STRLEN(PARM_STR) + jp->parm->str.len + 1;
-				if (string_len > MAX_JOB_LEN)
-					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-				c1 = (char *)malloc(string_len);
-#			ifdef KEEP_zOS_EBCDIC
-				__getEstring1_a_copy(c1, STR_AND_LEN(PARM_STRING));
-				__getEstring1_a_copy(c1 + strlen(PARM_STRING), jp->parm->str.addr, jp->parm->str.len);
-#			else
-				SPRINTF(c1, GTMJ_FMT, index);
-				memcpy(c1 + strlen(PARM_STR), jp->parm->str.addr, jp->parm->str.len);
-#			endif
-				*(c1 + string_len - 1) = 0;
-				*env_ind++ = c1;
-			}
-		}
-		string_len = STRLEN("%s=%ld") + STRLEN(GTMJCNT_ENV) + MAX_NUM_LEN - 5;
-		if (string_len > TEMP_BUFF_SIZE)
-			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JOBPARTOOLONG);
-		c1 = (char *)malloc(string_len + 1);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(suspend)
-#endif
-		SPRINTF_ENV_NUM(c1, GTMJCNT_ENV, index, env_ind);
-#ifdef KEEP_zOS_EBCDIC
-#pragma convlit(resume)
-#endif
 
 #ifdef	__osf__
 /* Make sure SIZEOF(char *) is correct.  */
diff --git a/sr_unix/op_fnfgncal.c b/sr_unix/op_fnfgncal.c
index e932216..a2a5492 100644
--- a/sr_unix/op_fnfgncal.c
+++ b/sr_unix/op_fnfgncal.c
@@ -111,6 +111,8 @@ GBLREF pthread_t	gtm_main_thread_id;
 GBLREF boolean_t	gtm_main_thread_id_set;
 #endif
 
+LITREF mval		skiparg;
+
 error_def(ERR_JNI);
 error_def(ERR_MAXSTRLEN);
 error_def(ERR_TEXT);
@@ -150,7 +152,7 @@ STATICFNDEF void extarg2mval(void *src, enum gtm_types typ, mval *dst, boolean_t
 
 	if (java)
 	{
-		switch(typ)
+		switch (typ)
 		{
 			case gtm_notfound:
 				break;
@@ -215,7 +217,7 @@ STATICFNDEF void extarg2mval(void *src, enum gtm_types typ, mval *dst, boolean_t
 		return;
 	}
 	/* The following switch is for non-Java call-outs. */
-	switch(typ)
+	switch (typ)
 	{
 		case gtm_notfound:
 			break;
@@ -376,7 +378,7 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 	gparam_list	*param_list;
 	gtm_long_t	*free_space_pointer;
 	int		i, j, save_mumps_status;
-	int4 		m1, m2, n;
+	int4 		m1, m2, n, space_n;
 	INTPTR_T	status;
 	mval		*v;
 	va_list		var_copy;
@@ -428,60 +430,96 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 		*types_descr_dptr = 'v';
 	types_descr_dptr++;
 	assert(2 * gtm_jtype_count == SIZEOF(gtm_jtype_chars));
-	for (i = argcnt + 2, j = -2, m1 = entry_ptr->input_mask, m2 = mask & entry_ptr->output_mask; 0 < i; i--, j++)
+	for (i = argcnt + 2, j = -2, m1 = entry_ptr->input_mask, m2 = entry_ptr->output_mask, space_n = 0; 0 < i; i--, j++)
 	{	/* Enforce mval values and record expected argument types. */
 		v = va_arg(var, mval *);
 		if (0 > j)
 		{
 			MV_FORCE_STR(v);
-			n += v->str.len + SIZEOF(gtm_long_t) + 1;
+			n += SIZEOF(void *) + v->str.len + 1;
 			continue;
 		}
-		if (m1 & 1)
+		if (MASK_BIT_ON(m1))
+		{
+			MV_FORCE_DEFINED_UNLESS_SKIPARG(v);
+		}
+		/* Estimate how much allocation we are going to need for arguments which require more than pointer-size space. */
+		if (MASK_BIT_ON(m1) && ((gtm_jstring == entry_ptr->parms[j]) || (gtm_jbyte_array == entry_ptr->parms[j])))
 		{
-			if ((gtm_jstring == entry_ptr->parms[j]) || (gtm_jbyte_array == entry_ptr->parms[j]))
+			if (MV_DEFINED(v))
 			{
 				MV_FORCE_STR(v);
-				n += v->str.len + SIZEOF(gtm_long_t) + 1;
+				n += SIZEOF(gtm_long_t) + SIZEOF(void *) + v->str.len + 1;  /* length + pointer + string + '\0' */
 			} else
-			{
-				MV_FORCE_DEFINED(v);
-			}
+				n += SIZEOF(gtm_long_t) + SIZEOF(void *) + 1;		    /* length + pointer + '\0' */
+			space_n += SIZEOF(gtm_long_t) + SIZEOF(void *);
+		}
+#		ifdef GTM64
+		else if (MASK_BIT_ON(m2) || (gtm_jfloat == entry_ptr->parms[j]) || (gtm_jdouble == entry_ptr->parms[j]))
+		{	/* Account for a pointer space, since floats and doubles cannot be passed by value. */
+			n += SIZEOF(void *);
+			space_n += SIZEOF(void *);
+		}
+#		else
+		else if ((gtm_jdouble == entry_ptr->parms[j]) || (gtm_jlong == entry_ptr->parms[j]))
+		{	/* Account for a pointer space, since longs and doubles cannot be passed by value on 32-bit boxes, and also
+			 * make room for a potential 8-byte alignment.
+			 */
+			n += SIZEOF(void *) + SIZEOF(gtm_int64_t);
+			space_n += SIZEOF(void *) + SIZEOF(gtm_int64_t);
+		} else if (MASK_BIT_ON(m2) || (gtm_jfloat == entry_ptr->parms[j]))
+		{	/* Account for a pointer space, since floats cannot be passed by value. */
+			n += SIZEOF(void *);
+			space_n += SIZEOF(void *);
 		}
+#		endif
 		jtype_char = entry_ptr->parms[j] - gtm_jtype_start_idx;
 		if ((0 > jtype_char) || (gtm_jtype_count <= jtype_char))
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
 		else
-			*types_descr_dptr = gtm_jtype_chars[(m2 & 1) ? (gtm_jtype_count + jtype_char) : jtype_char];
+			*types_descr_dptr = gtm_jtype_chars[MASK_BIT_ON(m2) ? (gtm_jtype_count + jtype_char) : jtype_char];
 		types_descr_dptr++;
 		m1 >>= 1;
 		m2 >>= 1;
 	}
 	va_end(var);
-        /* Double the size, to take care of any alignments in the middle. */
-	param_list = (gparam_list *)malloc(n * 2);
+        /* Allocate space for argument handling. Overall, the allocated space has the following structure:
+	 *   ___________________________________________
+	 *  |            |              |               |
+	 *  | param_list | space buffer | string buffer |
+	 *  |____________|______________|_______________|
+	 *
+	 * All input-output and output-only parameters have to be passed by reference, which means that param_list contains a
+	 * pointer to the space buffer where the actual value is stored. Furthermore, in case of gtm_jstring_t and gtm_jbyte_array_t
+	 * another pointer from within the space buffer is referencing an area inside the string buffer. Note, however, that certain
+	 * arguments, such as gtm_jfloat_t and gtm_jdouble_t, and gtm_jlong_t on 32-bit boxes, are always passed by reference.
+	 */
+	param_list = (gparam_list *)malloc(n);
 	param_list->arg[0] = (void *)types_descr_ptr;
 	/* Adding 3 to account for type descriptions, class name, and method name arguments. */
 	free_space_pointer = (gtm_long_t *)((char *)param_list + SIZEOF(intszofptr_t) + (SIZEOF(void *) * (argcnt + 3)));
 	/* Adding 3 for the same reason as above and another 3 to account for the fact that each of type description, class name,
 	 * and method name arguments require room in the free_space buffer, which comes ahead of free_string buffer in memory.
 	 */
-	free_string_pointer_start = free_string_pointer = (char *)param_list + entry_ptr->parmblk_size + (SIZEOF(void *) * (3 + 3));
+	free_string_pointer_start = free_string_pointer
+		= (char *)param_list + entry_ptr->parmblk_size + (SIZEOF(void *) * 3) + space_n;
 	/* Load-up the parameter list */
 	VAR_COPY(var, var_copy);
 	/* We need to enter this loop even if argcnt == 0, so that the class and method arguments get set. */
-	for (i = (0 == argcnt ? -1 : 0), j = 1, m1 = entry_ptr->input_mask, m2 = mask & entry_ptr->output_mask; i < argcnt; j++)
+	for (i = (0 == argcnt ? -1 : 0), j = 1, m1 = entry_ptr->input_mask, m2 = entry_ptr->output_mask; i < argcnt; j++)
 	{
 		v = va_arg(var_copy, mval *);
 		if (j < 3)
 		{
 			param_list->arg[j] = free_string_pointer;
 			if (v->str.len)
+			{
 				memcpy(free_string_pointer, v->str.addr, v->str.len);
-			free_string_pointer += v->str.len;
-			*free_string_pointer++ = 0;
+				free_string_pointer += v->str.len;
+			}
+			*free_string_pointer++ = '\0';
 			/* In case there are 0 arguments. */
-			if (2 == j && 0 > i)
+			if ((2 == j) && (0 > i))
 				i = 0;
 			continue;
 		}
@@ -489,52 +527,45 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 		switch (entry_ptr->parms[i])
 		{
 			case gtm_jboolean:
-				if (m2 & 1)
+				if (MASK_BIT_ON(m2))
 				{	/* Output expected. */
 					param_list->arg[j] = free_space_pointer;
-					*((gtm_int_t *)free_space_pointer) = (m1 & 1) ? ((gtm_int_t)(mval2i(v) ? 1 : 0)) : 0;
+					*((gtm_int_t *)free_space_pointer) = (gtm_int_t)(MV_ON(m1, v) ? (mval2i(v) ? 1 : 0) : 0);
 					free_space_pointer++;
-				} else if (m1 & 1)
-					param_list->arg[j] = (void *)((gtm_long_t)(mval2i(v) ? 1 : 0));
+				} else	/* Input expected. */
+					param_list->arg[j] = (void *)(gtm_long_t)(MV_ON(m1, v) ? (mval2i(v) ? 1 : 0) : 0);
 				break;
 			case gtm_jint:
-				if (m2 & 1)
+				if (MASK_BIT_ON(m2))
 				{	/* Output expected. */
 					param_list->arg[j] = free_space_pointer;
-					*((gtm_int_t *)free_space_pointer) = (m1 & 1) ? (gtm_int_t)mval2i(v) : 0;
+					*((gtm_int_t *)free_space_pointer) = (gtm_int_t)(MV_ON(m1, v) ? mval2i(v) : 0);
 					free_space_pointer++;
-				} else if (m1 & 1)
-					param_list->arg[j] = (void *)(gtm_long_t)mval2i(v);
+				} else	/* Input expected. */
+					param_list->arg[j] = (void *)(gtm_long_t)(MV_ON(m1, v) ? mval2i(v) : 0);
 				break;
 			case gtm_jlong:
-				if (m2 & 1)
+#				ifndef GTM64
+				/* Only need to do this rounding on non-64 it platforms because this one type has a 64-bit
+				 * alignment requirement on those platforms.
+				 */
+				free_space_pointer = (gtm_long_t *)(ROUND_UP2(((INTPTR_T)free_space_pointer), SIZEOF(gtm_int64_t)));
+#				else
+				if (MASK_BIT_ON(m2))
 				{	/* Output expected. */
-#					ifndef GTM64
-					free_space_pointer = (gtm_long_t *)(ROUND_UP2(((INTPTR_T)free_space_pointer),
-						SIZEOF(gtm_int64_t)));
-#					endif
-					param_list->arg[j] = free_space_pointer;
-					*((gtm_int64_t *)free_space_pointer) = (m1 & 1) ? (gtm_int64_t)mval2i8(v) : 0;
-					free_space_pointer = (gtm_long_t *)((char *)free_space_pointer + SIZEOF(gtm_int64_t));
-				} else if (m1 & 1)
-				{
-#					ifdef GTM64
-					param_list->arg[j] = (void *)(gtm_int64_t)mval2i8(v);
-#					else
-					/* Only need to do this rounding on non-64 it platforms because this one type has a 64 bit
-					 * alignment requirement on those platforms.
-					 */
-					free_space_pointer = (gtm_long_t *)(ROUND_UP2(((INTPTR_T)free_space_pointer),
-						SIZEOF(gtm_int64_t)));
+#				endif
 					param_list->arg[j] = free_space_pointer;
-					*((gtm_int64_t *)free_space_pointer) = (gtm_int64_t)mval2i8(v);
+					*((gtm_int64_t *)free_space_pointer) = (gtm_int64_t)(MV_ON(m1, v) ? mval2i8(v) : 0);
 					free_space_pointer = (gtm_long_t *)((char *)free_space_pointer + SIZEOF(gtm_int64_t));
-#					endif
-				}
+#				ifdef GTM64
+				} else	/* Input expected. */
+					param_list->arg[j] = (void *)(gtm_int64_t)(MV_ON(m1, v) ? mval2i8(v) : 0);
+#				endif
 				break;
 			case gtm_jfloat:
+				/* Have to go with additional storage either way due to the limitations of callg. */
 				param_list->arg[j] = free_space_pointer;
-				*((float *)free_space_pointer) = (m1 & 1) ? (float)mval2double(v) : (float)0.0;
+				*((float *)free_space_pointer) = (float)(MV_ON(m1, v) ? mval2double(v) : 0.0);
 				free_space_pointer++;
 				break;
 			case gtm_jdouble:
@@ -544,23 +575,31 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 				 */
 				free_space_pointer = (gtm_long_t *)(ROUND_UP2(((INTPTR_T)free_space_pointer), SIZEOF(double)));
 #				endif
+				/* Have to go with additional storage either way due to the limitations of callg. */
 				param_list->arg[j] = free_space_pointer;
-				*((double *)free_space_pointer) = (m1 & 1) ? (double)mval2double(v) : (double)0.0;
+				*((double *)free_space_pointer) = (double)(MV_ON(m1, v) ? mval2double(v) : 0.0);
 				free_space_pointer = (gtm_long_t *)((char *)free_space_pointer + SIZEOF(double));
 				break;
 			case gtm_jstring:
 			case gtm_jbyte_array:
 				param_list->arg[j] = free_space_pointer;
-				*free_space_pointer++ = (gtm_long_t)v->str.len;
-				*(char **)free_space_pointer = (char *)free_string_pointer;
-				free_space_pointer++;
-				if (m1 & 1)
+				/* If this is input-enabled and defined, it should have been forced to string in an earlier loop. */
+				assert(!MV_ON(m1, v) || MV_IS_STRING(v));
+				if (MV_ON(m1, v) && v->str.len)
 				{
-					if (v->str.len)
-						memcpy(free_string_pointer, v->str.addr, v->str.len);
+					*free_space_pointer++ = (gtm_long_t)v->str.len;
+					memcpy(free_string_pointer, v->str.addr, v->str.len);
+					*(char **)free_space_pointer = (char *)free_string_pointer;
 					free_string_pointer += v->str.len;
-					*free_string_pointer++ = 0;
+				} else
+				{	/* If an argument is for output only, an empty string, or skipped altogether, we still want
+					 * a valid length and a pointer to an empty null-terminated character array.
+					 */
+					*free_space_pointer++ = 0;
+					*(char **)free_space_pointer = (char *)free_string_pointer;
 				}
+				free_space_pointer++;
+				*free_string_pointer++ = '\0';
 				break;
 			default:
 				va_end(var_copy);
@@ -598,7 +637,8 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 	if (frame_pointer->flags & SFF_CI)
 		ci_ret_code_quit();
 	/* Only process the input-output and output-only arguments if the external call succeeded; otherwise, return -1
-	 * if non-void return is expected. */
+	 * if non-void return is expected.
+	 */
 	if (!error_in_xc)
 	{	/* Compute space requirement for return values. */
 		n = 0;
@@ -608,7 +648,7 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 			v = va_arg(var, mval *);
 			if (j < 3)
 				continue;
-			if (m1 & 1)
+			if (MASK_BIT_ON(m1))
 				n += extarg_getsize(param_list->arg[j], entry_ptr->parms[i], v);
 			i++;
 			m1 = m1 >> 1;
@@ -624,7 +664,7 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 			v = va_arg(var_copy, mval *);
 			if (j < 3)
 				continue;
-			if (m1 & 1)
+			if (MASK_BIT_ON(m1))
 				extarg2mval((void *)param_list->arg[j], entry_ptr->parms[i], v, TRUE, TRUE);
 			i++;
 			m1 = m1 >> 1;
@@ -645,7 +685,7 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 					memcpy(tmp_buff_ptr, package->str.addr, package->str.len);
 					tmp_buff_ptr += package->str.len;
 				}
-				*tmp_buff_ptr = 0;
+				*tmp_buff_ptr = '\0';
 				xtrnl_table_name = GETENV(str_buffer);
 				if (NULL == xtrnl_table_name)
 				{ 	/* Environment variable for the package not found. This part of code is for more safety.
@@ -664,7 +704,7 @@ STATICFNDEF void op_fgnjavacal(mval *dst, mval *package, mval *extref, uint4 mas
 	return;
 }
 
-void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 mask, int4 argcnt, ...)
+void op_fnfgncal(uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 mask, int4 argcnt, ...)
 {
 	boolean_t	java = FALSE;
 	char		*free_string_pointer, *free_string_pointer_start;
@@ -742,40 +782,51 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 	for (i = 0, m1 = entry_ptr->input_mask; i < argcnt; i++, m1 = m1 >> 1)
 	{
 		v = va_arg(var, mval *);
-		/* If it is an input value of char* or char **, add the length. Also a good time to force it into string form */
-		switch(entry_ptr->parms[i])
+		/* For char*, char **, and gtm_string_t * types, add the length. Also a good time to force it into string form. */
+		switch (entry_ptr->parms[i])
 		{
+			case gtm_string_star:	/* CAUTION: Fall-through. */
 			case gtm_char_star:
 				n += (-1 != entry_ptr->param_pre_alloc_size[i]) ? entry_ptr->param_pre_alloc_size[i] : 0;
-				/* Caution fall through */
+				/* CAUTION: Fall-through. */
 			case gtm_char_starstar:
-				if (m1 & 1)
+				if (MASK_BIT_ON(m1))
 				{
-					MV_FORCE_STR(v);
-					n += v->str.len + 1;
+					if (MV_DEFINED(v))
+					{
+						MV_FORCE_STR(v);
+						n += v->str.len + 1;	/* gtm_string_star does not really need the extra byte */
+					} else
+					{
+						MV_FORCE_DEFINED_UNLESS_SKIPARG(v);
+						n += 1;
+					}
 				}
 				break;
-			case gtm_string_star:
-				if (m1 & 1)
-				{
-					MV_FORCE_STR(v);
-					n += v->str.len + 1;
-				} else
-					n += (-1 != entry_ptr->param_pre_alloc_size[i]) ? entry_ptr->param_pre_alloc_size[i] : 0;
-				break;
+#			ifndef GTM64
 			case gtm_double_star:
 				n += SIZEOF(double);
-				if (m1 & 1)
-					MV_FORCE_DEFINED(v);
-				break;
+				/* CAUTION: Fall-through. */
+#			endif
 			default:
-				if (m1 & 1)
-					MV_FORCE_DEFINED(v);
-				break;
+				if (MASK_BIT_ON(m1))
+				{
+					MV_FORCE_DEFINED_UNLESS_SKIPARG(v);
+				}
 		}
 	}
 	va_end(var);
-        /* Double the size, to take care of any alignments in the middle  */
+        /* Double the size, to take care of any alignments in the middle. Overall, the allocated space has the following structure:
+	 *   ___________________________________________
+	 *  |            |              |               |
+	 *  | param_list | space buffer | string buffer |
+	 *  |____________|______________|_______________|
+	 *
+	 * For pointer-type arguments (gtm_long_t *, gtm_float_t *, etc.) the value in param_list is a pointer to a slot inside the
+	 * space buffer, unless it is gtm_char_t *, in which case the string buffer is used. For double-pointer types (char ** or
+	 * gtm_string_t *) the value in param_list is always a pointer inside the space buffer, where a pointer to an area inside
+	 * the string buffer is stored.
+	 */
 	param_list = (gparam_list *)malloc(n * 2);
 	free_space_pointer = (gtm_long_t *)((char *)param_list + SIZEOF(intszofptr_t) + (SIZEOF(void *) * argcnt));
 	free_string_pointer_start = free_string_pointer = (char *)param_list + entry_ptr->parmblk_size;
@@ -784,54 +835,42 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 	for (i = 0, m1 = entry_ptr->input_mask; i < argcnt; i++, m1 = m1 >> 1)
 	{
 		v = va_arg(var, mval *);
-		/* Note that even in this second pass at these mvals, we need to do the MV_FORCE processing because
-		 * in a NOUNDEF environment, undefiend mvals were NOT modified in the first pass and thus reamin undefined
-		 * in this pass.
-		 */
-		if (gtm_char_star != entry_ptr->parms[i] && (m1 & 1))
-			MV_FORCE_DEFINED(v);	/* Redefine undef'd mvals */
 		/* Verify that all input values are defined */
 		pre_alloc_size = entry_ptr->param_pre_alloc_size[i];
-		switch(entry_ptr->parms[i])
-		{	/* Note the int/long types are handled separately here in anticipation of correct handling
-			 * of "long" types on 64 bit hardware in the future. For the time being however, they are
-			 * using the same mval2i interface routine so are both restricted to 32 bits.
-			 */
+		switch (entry_ptr->parms[i])
+		{
 			case gtm_uint:
-				if (m1 & 1)
-					param_list->arg[i] = (void *)(gtm_long_t)mval2ui(v);
-				/* Note: output gtm_int and gtm_uint is an error (only "star" flavor can be modified) */
+				param_list->arg[i] = (void *)(gtm_ulong_t)(MV_ON(m1, v) ? mval2ui(v) : 0);
+				/* Note: output gtm_int and gtm_uint is an error (only "star" flavor can be modified). */
 				break;
 			case gtm_int:
-				if (m1 & 1)
-					param_list->arg[i] = (void *)(gtm_long_t)mval2i(v);
+				param_list->arg[i] = (void *)(gtm_long_t)(MV_ON(m1, v) ? mval2i(v) : 0);
 				break;
 			case gtm_ulong:
-				if (m1 & 1)
-				{
-					GTM64_ONLY(param_list->arg[i] = (void *)(gtm_uint64_t)mval2ui8(v));
-					NON_GTM64_ONLY(param_list->arg[i] = (void *)(gtm_ulong_t)mval2ui(v));
-				}
-				/* Note: output xc_long and xc_ulong is an error as described above */
+				param_list->arg[i] = (void *)GTM64_ONLY((gtm_uint64_t)) NON_GTM64_ONLY((gtm_ulong_t))
+					(MV_ON(m1, v) ? GTM64_ONLY(mval2ui8(v)) NON_GTM64_ONLY(mval2ui(v)) : 0);
+				/* Note: output xc_long and xc_ulong is an error as described above. */
 				break;
 			case gtm_long:
-				if (m1 & 1)
-				{
-					GTM64_ONLY(param_list->arg[i] = (void *)(gtm_int64_t)mval2i8(v));
-					NON_GTM64_ONLY(param_list->arg[i] = (void *)(gtm_long_t)mval2i(v));
-				}
+				param_list->arg[i] = (void *)GTM64_ONLY((gtm_int64_t)) NON_GTM64_ONLY((gtm_long_t))
+					(MV_ON(m1, v) ? GTM64_ONLY(mval2i8(v)) NON_GTM64_ONLY(mval2i(v)) : 0);
 				break;
 			case gtm_char_star:
 				param_list->arg[i] = free_string_pointer;
-				if (m1 & 1)
-				{
-					if (v->str.len)
+				if (MASK_BIT_ON(m1))
+				{	/* If this is defined and input-enabled, it should have already been forced to string. */
+					assert(!MV_DEFINED(v) || MV_IS_STRING(v));
+					if (MV_DEFINED(v) && v->str.len)
+					{
 						memcpy(free_string_pointer, v->str.addr, v->str.len);
-					free_string_pointer += v->str.len;
-					*free_string_pointer++ = 0;
-				} else if (-1 != pre_alloc_size)
+						free_string_pointer += v->str.len;
+					}
+					*free_string_pointer++ = '\0';
+				} else if (0 < pre_alloc_size)
+				{
+					*free_string_pointer = '\0';
 					free_string_pointer += pre_alloc_size;
-				else /* Output and no pre-allocation specified */
+				} else /* Output and no pre-allocation specified */
 				{
 					if (0 == package->str.len)
 						/* Default package - do not display package name */
@@ -844,52 +883,64 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 				break;
 			case gtm_char_starstar:
 				param_list->arg[i] = free_space_pointer;
-				if (m1 & 1)
+				/* If this is defined and input-enabled, it should have been forced to string in an earlier loop. */
+				assert(!MV_ON(m1, v) || MV_IS_STRING(v));
+				*(char **)free_space_pointer = free_string_pointer;
+				if (MV_ON(m1, v) && v->str.len)
 				{
-					*(char **)free_space_pointer = free_string_pointer;
-					if (v->str.len)
-						memcpy(free_string_pointer, v->str.addr, v->str.len);
+					memcpy(free_string_pointer, v->str.addr, v->str.len);
 					free_string_pointer += v->str.len;
-					*free_string_pointer++ = 0;
-				} else
-					*(char **)free_space_pointer = free_string_pointer++;
+				}
+				*free_string_pointer++ = '\0';
 				free_space_pointer++;
 				break;
 			case gtm_int_star:
 				param_list->arg[i] = free_space_pointer;
-				*((gtm_int_t *)free_space_pointer) = (m1 & 1) ? (gtm_int_t)mval2i(v) : 0;
+				*((gtm_int_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_int_t)mval2i(v) : 0;
 				free_space_pointer++;
 				break;
 			case gtm_uint_star:
 				param_list->arg[i] = free_space_pointer;
-				*((gtm_uint_t *)free_space_pointer) = (m1 & 1) ? (gtm_uint_t)mval2ui(v) : 0;
+				*((gtm_uint_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_uint_t)mval2ui(v) : 0;
 				free_space_pointer++;
 				break;
 			case gtm_long_star:
 				param_list->arg[i] = free_space_pointer;
-				GTM64_ONLY(*((gtm_int64_t *)free_space_pointer) = (m1 & 1) ? (gtm_int64_t)mval2i8(v) : 0);
-				NON_GTM64_ONLY(*((gtm_long_t *)free_space_pointer) = (m1 & 1) ? (gtm_long_t)mval2i(v) : 0);
+				GTM64_ONLY(*((gtm_int64_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_int64_t)mval2i8(v) : 0);
+				NON_GTM64_ONLY(*((gtm_long_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_long_t)mval2i(v) : 0);
 				free_space_pointer++;
 				break;
 			case gtm_ulong_star:
 				param_list->arg[i] = free_space_pointer;
-				GTM64_ONLY(*((gtm_uint64_t *)free_space_pointer) = (m1 & 1) ? (gtm_uint64_t)mval2ui8(v) : 0);
-				NON_GTM64_ONLY(*((gtm_ulong_t *)free_space_pointer) = (m1 & 1) ? (gtm_ulong_t)mval2ui(v) : 0);
+				GTM64_ONLY(*((gtm_uint64_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_uint64_t)mval2ui8(v) : 0);
+				NON_GTM64_ONLY(*((gtm_ulong_t *)free_space_pointer) = MV_ON(m1, v) ? (gtm_ulong_t)mval2ui(v) : 0);
 				free_space_pointer++;
 				break;
 			case gtm_string_star:
 				param_list->arg[i] = free_space_pointer;
-				*free_space_pointer++ = (gtm_long_t)v->str.len;
-				*(char **)free_space_pointer = (char *)free_string_pointer;
-				free_space_pointer++;
-				if (m1 & 1)
-				{
-					if (v->str.len)
+				if (MASK_BIT_ON(m1))
+				{	/* If this is defined and input-enabled, it should have already been forced to string. */
+					assert(!MV_DEFINED(v) || MV_IS_STRING(v));
+					if (MV_DEFINED(v) && v->str.len)
+					{
+						*free_space_pointer++ = (gtm_long_t)v->str.len;
+						*(char **)free_space_pointer = (char *)free_string_pointer;
 						memcpy(free_string_pointer, v->str.addr, v->str.len);
-					free_string_pointer += v->str.len;
-				} else if (-1 != pre_alloc_size)
+						free_string_pointer += v->str.len;
+						free_space_pointer++;
+					} else
+					{
+						*free_space_pointer++ = 0;
+						*free_space_pointer++ = 0;	/* Effectively a NULL pointer. */
+					}
+				} else if (0 < pre_alloc_size)
+				{
+					*free_space_pointer++ = (gtm_long_t)pre_alloc_size;
+					*(char **)free_space_pointer = (char *)free_string_pointer;
+					*free_string_pointer = '\0';
+					free_space_pointer++;
 					free_string_pointer += pre_alloc_size;
-				else /* Output and no pre-allocation specified */
+				} else /* Output and no pre-allocation specified */
 				{
 					if (0 == package->str.len)
 						/* Default package - do not display package name */
@@ -904,7 +955,7 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 				break;
 			case gtm_float_star:
 				param_list->arg[i] = free_space_pointer;
-				*((float *)free_space_pointer) = (m1 & 1) ? (float)mval2double(v) : (float)0.0;
+				*((float *)free_space_pointer) = MV_ON(m1, v) ? (float)mval2double(v) : (float)0.0;
 				free_space_pointer++;
 				break;
 			case gtm_double_star:
@@ -914,12 +965,12 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 				NON_GTM64_ONLY(free_space_pointer = (gtm_long_t *)(ROUND_UP2(((INTPTR_T)free_space_pointer),
 											    SIZEOF(double))));
 				param_list->arg[i] = free_space_pointer;
-				*((double *)free_space_pointer) = (m1 & 1) ? (double)mval2double(v) : (double)0.0;
-				free_space_pointer = (gtm_long_t *)((char *)free_space_pointer + SIZEOF(double));
+				*((double *)free_space_pointer) = MV_ON(m1, v) ? (double)mval2double(v) : 0.0;
+				free_space_pointer += (SIZEOF(double) / SIZEOF(gtm_long_t));
 				break;
 			case gtm_pointertofunc:
-				if (((callintogtm_vectorindex = (int4)mval2i(v)) >= gtmfunc_unknown_function)
-				    || (callintogtm_vectorindex < 0))
+				callintogtm_vectorindex = MV_DEFINED(v) ? (int4)mval2i(v) : 0;
+				if ((callintogtm_vectorindex >= gtmfunc_unknown_function) || (callintogtm_vectorindex < 0))
 				{
 					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZCVECTORINDX, 1, callintogtm_vectorindex,
 						ERR_TEXT, 2, RTS_ERROR_TEXT("Passing Null vector"));
@@ -960,7 +1011,7 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 	for (i = 0, m1 = mask & entry_ptr->output_mask; i < argcnt; i++, m1 = m1 >> 1)
 	{
 		v = va_arg(var, mval *);
-		if (m1 & 1)
+		if (MASK_BIT_ON(m1))
 			n += extarg_getsize(param_list->arg[i], entry_ptr->parms[i], v);
 	}
 	va_end(var);
@@ -972,7 +1023,7 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 	for (i = 0, m1 = mask & entry_ptr->output_mask; i < argcnt; i++, m1 = m1 >> 1)
 	{
 		v = va_arg(var, mval *);
-		if (m1 & 1)
+		if (MASK_BIT_ON(m1))
 			extarg2mval((void *)param_list->arg[i], entry_ptr->parms[i], v, FALSE, TRUE);
 	}
 	va_end(var);
@@ -991,13 +1042,11 @@ void op_fnfgncal (uint4 n_mvals, mval *dst, mval *package, mval *extref, uint4 m
 				memcpy(tmp_buff_ptr, package->str.addr, package->str.len);
 				tmp_buff_ptr += package->str.len;
 			}
-			*tmp_buff_ptr = 0;
+			*tmp_buff_ptr = '\0';
 			xtrnl_table_name = GETENV(str_buffer);
 			if (NULL == xtrnl_table_name)
-			{
-				/* Environment variable for the package not found.
-				 * This part of code is for more safety. We should
-				 * not come into this path at all.
+			{	/* Environment variable for the package not found. This part of code is for more safety.
+				 * We should not come into this path at all.
 				 */
 				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTENV, 2, LEN_AND_STR(str_buffer));
 			}
diff --git a/sr_unix/op_fnzpeek.c b/sr_unix/op_fnzpeek.c
index 2cda909..62b0ebe 100644
--- a/sr_unix/op_fnzpeek.c
+++ b/sr_unix/op_fnzpeek.c
@@ -134,7 +134,7 @@ LITDEF zpeek_data_typ zpeek_data[] =
  */
 CONDITION_HANDLER(op_fnzpeek_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	NEXTCH;		/* In the unlikely event it gets driven, just be a pass-thru */
 }
 
@@ -152,7 +152,7 @@ void op_fnzpeek_signal_handler(int sig, siginfo_t *info, void *context)
 	 */
 	{	/* Needs new block since START_CH declares a new var used in UNWIND() */
 		int arg = 0;	/* Needed for START_CH macro if debugging enabled */
-		START_CH;
+		START_CH(TRUE);
 		DEBUG_ONLY(ok_to_UNWIND_in_exit_handling = TRUE);
 		UNWIND(NULL, NULL);
 	}
@@ -366,7 +366,7 @@ STATICFNDEF int op_fnzpeek_stpcopy(char *zpeekadr, int len, mval *ret, char fmtc
  */
 CONDITION_HANDLER(op_fnzpeek_getpool_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (DUMPABLE)
 		NEXTCH;		/* Let next (more robust) handler deal with it */
 	UNWIND(NULL, NULL);
diff --git a/sr_unix/op_fnzsearch.c b/sr_unix/op_fnzsearch.c
index 0656a4d..c99d4ca 100644
--- a/sr_unix/op_fnzsearch.c
+++ b/sr_unix/op_fnzsearch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -76,7 +76,7 @@ int op_fnzsearch(mval *file, mint indx, mval *ret)
 	TREF(lv_null_subs) = LVNULLSUBS_OK;	/* $ZSearch processing depends on this */
 	MV_FORCE_STR(file);
 	if (file->str.len > MAX_FBUFF)
-		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF);
 	MV_FORCE_MVAL(((mval *)TADR(fnzsearch_sub_mval)), indx);
 	TREF(fnzsearch_lv_vars) = op_srchindx(VARLSTCNT(2) TREF(zsearch_var), (mval *)TADR(fnzsearch_sub_mval));
 	if (TREF(fnzsearch_lv_vars))
@@ -103,7 +103,7 @@ int op_fnzsearch(mval *file, mint indx, mval *ret)
 			{
 				if (errno == ENOENT)
 					continue;
-				rts_error(VARLSTCNT(1) errno);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 			}
 			break;
 		}
@@ -150,7 +150,7 @@ int op_fnzsearch(mval *file, mint indx, mval *ret)
 				{
 					if (errno == ENOENT)
 						continue;
-					rts_error(VARLSTCNT(1) errno);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) errno);
 				}
 				break;
 			}
@@ -407,7 +407,7 @@ STATICFNDEF CONDITION_HANDLER(fnzsrch_ch)
 {
 	int	dummy1, dummy2;
 
-	START_CH;
+	START_CH(TRUE);
 	TREF(lv_null_subs) = TREF(fnzsearch_nullsubs_sav);
 	NEXTCH;
 }
@@ -416,7 +416,7 @@ STATICFNDEF CONDITION_HANDLER(dir_ch)
 {
 	int	dummy1, dummy2;
 
-	START_CH;
+	START_CH(TRUE);
 	if (DUMP)
 	{
 		NEXTCH;
diff --git a/sr_unix/op_job.c b/sr_unix/op_job.c
index 5fd3a61..0b3d3e6 100644
--- a/sr_unix/op_job.c
+++ b/sr_unix/op_job.c
@@ -48,6 +48,7 @@
 #include "change_reg.h"
 #include "setterm.h"
 #include "getzposition.h"
+#include "iosocketdef.h"
 #ifdef DEBUG
 #include "have_crit.h"		/* for the TPNOTACID_CHECK macro */
 #endif
@@ -61,6 +62,7 @@ GBLREF	uint4		dollar_trestart;
 GBLREF	int		dollar_truth;
 GBLREF	uint4		dollar_zjob;
 GBLREF	int4		outofband;
+GBLREF	d_socket_struct	*socket_pool;
 static	int4	tid;	/* Job Timer ID */
 
 error_def(ERR_TEXT);
@@ -108,6 +110,8 @@ int	op_job(int4 argcnt, ...)
 	char		combuf[128];
 	mstr		command;
 	job_parm	*jp;
+	mstr_len_t	handle_len;
+	int4		index;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -188,6 +192,10 @@ int	op_job(int4 argcnt, ...)
 	job_errno = -1;
 	non_exit_return = FALSE;
 	status = ojstartchild(&job_params, argcnt, &non_exit_return, pipe_fds);
+	/* the child process (M), that wrote to pipe, would have been exited by now. Close the write-end to make the following read
+	 * non-blocking. also resets "pipe_fds[1]" to FD_INVALID
+	 */
+	CLOSEFILE_RESET(pipe_fds[1], pipe_status);
 	if (!non_exit_return)
 	{
 #ifdef _BSD
@@ -220,10 +228,6 @@ int	op_job(int4 argcnt, ...)
 		free(job_params.parms);
 	if (timed && !ojtimeout)
 		cancel_timer((TID)&tid);
-	/* the child process (M), that wrote to pipe, would have been exited by now. Close the write-end to make the following read
-	 * non-blocking. also resets "pipe_fds[1]" to FD_INVALID
-	 */
-	CLOSEFILE_RESET(pipe_fds[1], pipe_status);
 	assert(SIZEOF(pid_t) == SIZEOF(zjob_pid));
 	DOREADRC(pipe_fds[0], &zjob_pid, SIZEOF(zjob_pid), pipe_status);
 	/* empty pipe (pipe_status == -1) is ignored and not reported as error */
@@ -296,6 +300,29 @@ int	op_job(int4 argcnt, ...)
 			dollar_truth = 1;
 		assert(0 < zjob_pid);
 		dollar_zjob = zjob_pid;
+
+		if (IS_JOB_SOCKET(job_params.input.addr, job_params.input.len))
+		{
+			handle_len = JOB_SOCKET_HANDLE_LEN(job_params.input.len);
+			index = iosocket_handle(JOB_SOCKET_HANDLE(job_params.input.addr), &handle_len, FALSE, socket_pool);
+			if (-1 != index)
+				iosocket_close_one(socket_pool, index);
+		}
+		if (IS_JOB_SOCKET(job_params.output.addr, job_params.output.len))
+		{
+			handle_len = JOB_SOCKET_HANDLE_LEN(job_params.output.len);
+			index = iosocket_handle(JOB_SOCKET_HANDLE(job_params.output.addr), &handle_len, FALSE, socket_pool);
+			if (-1 != index)
+				iosocket_close_one(socket_pool, index);
+		}
+		if (IS_JOB_SOCKET(job_params.error.addr, job_params.error.len))
+		{
+			handle_len = JOB_SOCKET_HANDLE_LEN(job_params.error.len);
+			index = iosocket_handle(JOB_SOCKET_HANDLE(job_params.error.addr), &handle_len, FALSE, socket_pool);
+			if (-1 != index)
+				iosocket_close_one(socket_pool, index);
+		}
+
 		return TRUE;
 	}
 	return FALSE; /* This will never get executed, added to make compiler happy */
diff --git a/sr_unix/op_setextract.c b/sr_unix/op_setextract.c
index 820c87a..cc1fb45 100644
--- a/sr_unix/op_setextract.c
+++ b/sr_unix/op_setextract.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -99,7 +99,7 @@ void op_setextract(mval *src, mval *expr, int schar, int echar, mval *dst)
 	/* Calculate total string len */
 	dstlen = (size_t)pfxlen + padlen + (size_t)expr->str.len + (size_t)sfxlen;
 	if (MAX_STRLEN < dstlen)
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 	ENSURE_STP_FREE_SPACE((int)dstlen);
 	srcbase = (unsigned char *)src->str.addr;
 	straddr = stringpool.free;
@@ -123,7 +123,7 @@ void op_setextract(mval *src, mval *expr, int schar, int echar, mval *dst)
 		memcpy(straddr, srcbase + sfxoff, sfxlen);
 		straddr += sfxlen;
 	}
-	assert((straddr - stringpool.free) == dstlen);
+	assert(IS_AT_END_OF_STRINGPOOL(straddr, -dstlen));
 	MV_INIT_STRING(dst, straddr - stringpool.free, (char *)stringpool.free);
 	if (0 < char_len)
 	{
diff --git a/sr_unix/op_setp1.c b/sr_unix/op_setp1.c
index 31ba31e..ff20c93 100644
--- a/sr_unix/op_setp1.c
+++ b/sr_unix/op_setp1.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -262,7 +262,7 @@ void op_setp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 	/* Calculate total string len. delim_cnt has needed padding delimiters for null fields */
 	str_len = (size_t)expr->str.len + (size_t)pfx_str_len + (delim_cnt * (size_t)dlmlen) + (size_t)sfx_str_len;
 	if (MAX_STRLEN < str_len)
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 	ENSURE_STP_FREE_SPACE((int)str_len);
 	str_addr = stringpool.free;
 	start_pfx = (unsigned char *)src->str.addr;
@@ -290,7 +290,7 @@ void op_setp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 		memcpy(str_addr, start_pfx + sfx_start_offset, sfx_str_len);
 		str_addr += sfx_str_len;
 	}
-	assert((str_addr - stringpool.free) == str_len);
+	assert(IS_AT_END_OF_STRINGPOOL(str_addr, -str_len));
 	dst->mvtype = MV_STR;
 	dst->str.len = INTCAST(str_addr - stringpool.free);
 	dst->str.addr = (char *)stringpool.free;
diff --git a/sr_unix/op_setpiece.c b/sr_unix/op_setpiece.c
index 39d2883..25ec023 100644
--- a/sr_unix/op_setpiece.c
+++ b/sr_unix/op_setpiece.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -125,7 +125,7 @@ void op_setpiece(mval *src, mval *del, mval *expr, int4 first, int4 last, mval *
 		str_len += (size_t)(src->str.len - second_src_ind);
 	if (MAX_STRLEN < str_len)
 	{
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 		return;
 	}
 	ENSURE_STP_FREE_SPACE((int)str_len);
@@ -153,7 +153,7 @@ void op_setpiece(mval *src, mval *del, mval *expr, int4 first, int4 last, mval *
 		memcpy(str_addr, tmp_str, len);
 		str_addr += len;
 	}
-	assert((str_addr - stringpool.free) == str_len);
+	assert(IS_AT_END_OF_STRINGPOOL(str_addr, -str_len));
 	dst->mvtype = MV_STR;
 	dst->str.len = INTCAST(str_addr - stringpool.free);
 	dst->str.addr = (char *)stringpool.free;
diff --git a/sr_unix/op_zhelp_xfr.c b/sr_unix/op_zhelp_xfr.c
index 7097156..c9ae080 100644
--- a/sr_unix/op_zhelp_xfr.c
+++ b/sr_unix/op_zhelp_xfr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -41,25 +41,20 @@ void op_zhelp_xfr(mval *subject, mval *lib)
 	action->mvtype = MV_STR;
 
 	mval_lex(subject, &x);
-	if (x.addr == (char *)stringpool.free)
-	{	action->str.len += x.len;
+	if (IS_AT_END_OF_STRINGPOOL(x.addr, 0))
+	{
+		action->str.len += x.len;
 		stringpool.free += x.len;
-	}
-	else
+	} else
 		op_cat(VARLSTCNT(3) action, action, subject);
-
 	op_cat(VARLSTCNT(3) action, action, &com);	/* add "," */
-
 	mval_lex(lib, &x);
-	if (x.addr == (char *)stringpool.free)
-	{	action->str.len += x.len;
+	if (IS_AT_END_OF_STRINGPOOL(x.addr, 0))
+	{
+		action->str.len += x.len;
 		stringpool.free += x.len;
-	}
-	else
+	} else
 		op_cat(VARLSTCNT(3) action, action, lib);
-
 	op_cat(VARLSTCNT(3) action, action, &rpar);	/* add ")" */
-
 	op_commarg(action,indir_linetail);
 }
-
diff --git a/sr_unix/op_zlink.c b/sr_unix/op_zlink.c
index b81d7c4..1fbf0e9 100644
--- a/sr_unix/op_zlink.c
+++ b/sr_unix/op_zlink.c
@@ -1,6 +1,5 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+/**************************************************************** *								*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,6 +33,20 @@
 #define OBJ			2
 #define NOTYPE			3
 
+/* On certain platforms the st_mtime field of the stat structure got replaced by a timespec st_mtim field, which in turn has tv_sec
+ * and tv_nsec fields. For compatibility reasons, those platforms define an st_mtime macro which points to st_mtim.tv_sec. Whenever
+ * we detect such a situation, we define a nanosecond flavor of that macro to point to st_mtim.tv_nsec. On HPUX Itanium and older
+ * AIX boxes the stat structure simply has additional fields with the nanoseconds value, yet the names of those field are different
+ * on those two architectures, so we choose our mapping accordingly.
+ */
+#if defined st_mtime
+#  define st_nmtime		st_mtim.tv_nsec
+#elif defined(_AIX)
+#  define st_nmtime		st_mtime_n
+#elif defined(__hpux) && defined(__ia64)
+#  define st_nmtime		st_nmtime
+#endif
+
 GBLREF spdesc			stringpool;
 GBLREF command_qualifier	glb_cmd_qlf, cmd_qlf;
 GBLREF mval			dollar_zsource;
@@ -67,7 +80,7 @@ void op_zlink (mval *v, mval *quals)
 	SETUP_THREADGBL_ACCESS;
 	MV_FORCE_STR(v);
 	if (!v->str.len || (MAX_FBUFF < v->str.len))
-		rts_error(VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
+		rts_error_csa(NULL, VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
 	object_file_des = FD_INVALID;
 	srcdir = objdir = (zro_ent *) 0;
 	expdir = FALSE;
@@ -79,9 +92,9 @@ void op_zlink (mval *v, mval *quals)
 		pblk.fop = F_SYNTAXO;
 		status = parse_file(&v->str, &pblk);
 		if (!(status & 1))
-			rts_error(VARLSTCNT(5) ERR_FILEPARSE, 2, v->str.len, v->str.addr, status);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_FILEPARSE, 2, v->str.len, v->str.addr, status);
 		if (pblk.fnb & F_WILD)
-			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
+			rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
 				ERR_WILDCARD, 2, v->str.len, v->str.addr);
 		file.addr = pblk.buffer;
 		file.len = pblk.b_esl;
@@ -128,7 +141,7 @@ void op_zlink (mval *v, mval *quals)
 		{
 			if (file.len + SIZEOF(DOTM) > SIZEOF(srcnamebuf) ||
 			  file.len + SIZEOF(DOTOBJ) > SIZEOF(objnamebuf))
-				rts_error(VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
+				rts_error_csa(NULL, VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
 			memmove(srcnamebuf, file.addr, file.len);
 			memcpy(&srcnamebuf[file.len], DOTM, SIZEOF(DOTM));
 			srcnamelen = file.len + SIZEOF(DOTM) - 1;
@@ -148,20 +161,22 @@ void op_zlink (mval *v, mval *quals)
 			{
 				zro_search(&objstr, &objdir, 0, 0, TRUE);
 				if (!objdir)
-					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
-						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
+					rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len,
+						dollar_zsource.str.addr, ERR_FILENOTFND,2, dollar_zsource.str.len,
+						dollar_zsource.str.addr);
 			} else if (SRC == type)
 			{
 				zro_search(&objstr, &objdir, &srcstr, &srcdir, TRUE);
 				if (!srcdir)
-					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf,
+					rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf,
 						ERR_FILENOTFND, 2, srcnamelen, srcnamebuf);
 			} else
 			{
 				zro_search(&objstr, &objdir, &srcstr, &srcdir, NON_USHBIN_ONLY(TRUE) USHBIN_ONLY(FALSE));
 				if (!objdir && !srcdir)
-					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
-						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
+					rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len,
+						dollar_zsource.str.addr, ERR_FILENOTFND,2, dollar_zsource.str.len,
+						dollar_zsource.str.addr);
 			}
 		}
 	} else
@@ -185,7 +200,7 @@ void op_zlink (mval *v, mval *quals)
 		 */
 		zro_search(&objstr, &objdir, &srcstr, &srcdir, NON_USHBIN_ONLY(TRUE) USHBIN_ONLY(FALSE));
 		if (!objdir && !srcdir)
-			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
+			rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
 				ERR_FILENOTFND, 2, v->str.len, v->str.addr);
 		qualifier.mvtype = MV_STR;
 		qualifier.str = TREF(dollar_zcompile);
@@ -197,7 +212,7 @@ void op_zlink (mval *v, mval *quals)
 		{
 			assert(ZRO_TYPE_OBJLIB != objdir->type);
 			if (objdir->str.len + objnamelen + 2 > SIZEOF(objnamebuf))
-				rts_error(VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
+				rts_error_csa(NULL, VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
 			if (objdir->str.len)
 			{
 				tslash = ('/' == objdir->str.addr[objdir->str.len - 1]) ? 0 : 1;
@@ -211,12 +226,15 @@ void op_zlink (mval *v, mval *quals)
 		}
 		OPEN_OBJECT_FILE(objnamebuf, O_RDONLY, object_file_des);
 		if (FD_INVALID == object_file_des)
-			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, errno);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
+			errno);
 		if (USHBIN_ONLY(!incr_link(object_file_des, NULL)) NON_USHBIN_ONLY(!incr_link(object_file_des)))
-			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_VERSION);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
+			ERR_VERSION);
 		CLOSEFILE_RESET(object_file_des, status);	/* resets "object_file_des" to FD_INVALID */
 		if (-1 == status)
-			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, errno);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
+			errno);
 	} else	/* either NO type or SOURCE type */
 	{
 		cmd_qlf.object_file.str.addr = obj_file;
@@ -229,7 +247,7 @@ void op_zlink (mval *v, mval *quals)
 		{
 			assert(ZRO_TYPE_OBJLIB != objdir->type);
 			if (srcdir->str.len + srcnamelen > SIZEOF(srcnamebuf) - 1)
-				rts_error(VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
+				rts_error_csa(NULL, VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
 			if (srcdir->str.len)
 			{
 				tslash = ('/' == srcdir->str.addr[srcdir->str.len - 1]) ? 0 : 1;
@@ -245,17 +263,14 @@ void op_zlink (mval *v, mval *quals)
 		{
 			if (ZRO_TYPE_OBJLIB == objdir->type)
 			{
-				NON_USHBIN_ONLY(GTMASSERT;)
+				NON_USHBIN_ONLY(assertpro(FALSE));
 				assert(objdir->shrlib);
 				assert(objdir->shrsym);
-				USHBIN_ONLY(
-					if (!incr_link(0, objdir))
-						GTMASSERT;
-				)
+				USHBIN_ONLY(assertpro(incr_link(0, objdir)));
 				return;
 			}
 			if (objdir->str.len + objnamelen > SIZEOF(objnamebuf) - 1)
-				rts_error(VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
+				rts_error_csa(NULL, VARLSTCNT(4) ERR_ZLINKFILE, 2, v->str.len, v->str.addr);
 			if (objdir->str.len)
 			{
 				tslash = ('/' == objdir->str.addr[objdir->str.len - 1]) ? 0 : 1;
@@ -276,7 +291,7 @@ void op_zlink (mval *v, mval *quals)
 				if (ENOENT == errno)
 					obj_found = FALSE;
 				else
-					rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+					rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
 			} else
 				obj_found = TRUE;
 		} else
@@ -287,7 +302,7 @@ void op_zlink (mval *v, mval *quals)
 			if ((ENOENT == errno) && (SRC != type))
 				src_found = FALSE;
 			else
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE,2,srcnamelen,srcnamebuf,errno);
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE,2,srcnamelen,srcnamebuf,errno);
 		} else
 			src_found = TRUE;
 		if (SRC != type)
@@ -298,19 +313,22 @@ void op_zlink (mval *v, mval *quals)
 				{
 					FSTAT_FILE(object_file_des, &obj_stat, status);
 					if (-1 == status)
-						rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
-					if (src_stat.st_mtime > obj_stat.st_mtime)
+						rts_error_csa(NULL,VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+					if ((src_stat.st_mtime > obj_stat.st_mtime)
+						|| ((src_stat.st_mtime == obj_stat.st_mtime)
+							&& (src_stat.st_nmtime > obj_stat.st_nmtime)))
 					{
 						CLOSEFILE_RESET(object_file_des, status);	/* resets "object_file_des"
 												 * to FD_INVALID */
 						if (-1 == status)
-							rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+							rts_error_csa(NULL,VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf,
+								errno);
 						compile = TRUE;
 					}
 				} else
 					compile = TRUE;
 			} else if (!obj_found)
-				rts_error (VARLSTCNT(8) ERR_ZLINKFILE, 2, objnamelen, objnamebuf,
+				rts_error_csa(NULL, VARLSTCNT(8) ERR_ZLINKFILE, 2, objnamelen, objnamebuf,
 					ERR_FILENOTFND, 2, objnamelen, objnamebuf);
 		}
 		if (compile)
@@ -326,7 +344,7 @@ void op_zlink (mval *v, mval *quals)
 			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
 			{
 				cmd_qlf.qlf = glb_cmd_qlf.qlf;
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
 			}
 			zlcompile(srcnamelen, (uchar_ptr_t)srcnamebuf);
 			if ((SRC == type) && !(qlf & CQ_OBJECT))
@@ -334,17 +352,16 @@ void op_zlink (mval *v, mval *quals)
 		}
 		CONVERT_OBJECT_LOCK(object_file_des, F_RDLCK, status);
 		if (-1 == status)
-			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
 		status = USHBIN_ONLY(incr_link(object_file_des, NULL)) NON_USHBIN_ONLY(incr_link(object_file_des));
 		if (!status)
 		{	/* due only to version mismatch, so recompile */
 			CLOSEFILE_RESET(object_file_des, status);	/* resets "object_file_des" to FD_INVALID */
 			if (-1 == status)
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
-			if (compile)
-				GTMASSERT;
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+			assertpro(!compile);
 			if (!src_found)
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_VERSION);
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_VERSION);
 			zl_cmd_qlf(&quals->str, &cmd_qlf);
 			if (!MV_DEFINED(&cmd_qlf.object_file))
 			{
@@ -356,16 +373,16 @@ void op_zlink (mval *v, mval *quals)
 			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
 			{
 				cmd_qlf.qlf = glb_cmd_qlf.qlf;
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
 			}
 			CONVERT_OBJECT_LOCK(object_file_des, F_RDLCK, status);
 			if (-1 == status)
-				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
-			if (USHBIN_ONLY(!incr_link(object_file_des, NULL)) NON_USHBIN_ONLY(!incr_link(object_file_des)))
-				GTMASSERT;
+				rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+				assertpro(! (USHBIN_ONLY(!incr_link(object_file_des, NULL))
+					NON_USHBIN_ONLY(!incr_link(object_file_des))) );
 		}
 		CLOSEFILE_RESET(object_file_des, status);	/* resets "object_file_des" to FD_INVALID */
 		if (-1 == status)
-			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
+			rts_error_csa(NULL, VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, errno);
 	}
 }
diff --git a/sr_unix/pinentry.m b/sr_unix/pinentry.m
index 3c08965..f0961db 100644
--- a/sr_unix/pinentry.m
+++ b/sr_unix/pinentry.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2010 Fidelity Information Services, Inc	;
+;	Copyright 2010, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -20,8 +20,11 @@ pinentry	; Substitute pinentry that returns an unobfuscated password
 	For  Quit:done  Read in Quit:'$Length(in)  Do
 	. If "GETPIN"=$Translate($Piece(in," ",1),"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ") Do
 	. . Set obfpwds=""
-	. . For i=1:2:$Length(obfpwd) Set obfpwds=obfpwds_$ZCHar(16*($Find("0123456789ABCDEF",$Extract(obfpwd,i))-2)+$Find("0123456789ABCDEF",$Extract(obfpwd,i+1))-2)
-	. . Write:'$&gpgagent.unmaskpwd(obfpwds,.clrpwds,$Length(obfpwds)) "D ",clrpwds,!
+	. . For i=1:2:$Length(obfpwd) Do
+	. . . Set msb=$Find("0123456789ABCDEF",$Extract(obfpwd,i))-2
+	. . . Set lsb=$Find("0123456789ABCDEF",$Extract(obfpwd,i+1))-2
+	. . . Set obfpwds=obfpwds_$ZCHar(16*msb+lsb)
+	. . Write:'$&gpgagent.unmaskpwd(obfpwds,.clrpwds) "D ",clrpwds,!
 	. . Set done=1
 	. Write "OK",!
 	Quit
diff --git a/sr_unix/repl_inst_dump.c b/sr_unix/repl_inst_dump.c
index 06c3cd6..94e7e63 100644
--- a/sr_unix/repl_inst_dump.c
+++ b/sr_unix/repl_inst_dump.c
@@ -36,7 +36,6 @@
 #include "gtmrecv.h"
 #include "repl_inst_dump.h"
 #include "repl_log.h"		/* for "repl_log" prototype */
-#include "iotcpdef.h"		/* for SA_MAXLEN */
 
 LITDEF	char	state_array[][23] = {
 			"DUMMY_STATE",
@@ -987,6 +986,14 @@ void	repl_inst_dump_gtmsourcelocal(gtmsource_local_ptr_t gtmsourcelocal_ptr)
 			util_out_print( PREFIX_SOURCELOCAL "Filter Command              !AZ",
 				TRUE, idx, gtmsourcelocal_ptr->filter_cmd);
 		}
+		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, next_renegotiate_time),
+					SIZEOF(gtmsourcelocal_ptr->next_renegotiate_time));
+		util_out_print(PREFIX_SOURCELOCAL, FALSE, idx);
+		PRINT_TIME("Next Renegotiate Time       ", gtmsourcelocal_ptr->next_renegotiate_time);
+		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, num_renegotiations),
+					SIZEOF(gtmsourcelocal_ptr->num_renegotiations));
+		util_out_print(PREFIX_SOURCELOCAL "Number of TLS/SSL renegotiations      !10UL [0x!XL]", TRUE, idx,
+					gtmsourcelocal_ptr->num_renegotiations, gtmsourcelocal_ptr->num_renegotiations);
 		PRINT_DASHES;
 	}
 }
diff --git a/sr_unix/repl_instance.c b/sr_unix/repl_instance.c
index 4311201..b7a3888 100644
--- a/sr_unix/repl_instance.c
+++ b/sr_unix/repl_instance.c
@@ -118,15 +118,17 @@ boolean_t repl_inst_get_name(char *fn, unsigned int *fn_len, unsigned int bufsiz
 		if (issue_rts_error == error_action)
 		{
 			if (SS_LOG2LONG == status)
-				rts_error(VARLSTCNT(5) ERR_LOGTOOLONG, 3, log_nam.len, log_nam.addr, SIZEOF(temp_inst_fn) - 1);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, log_nam.len, log_nam.addr,
+					      SIZEOF(temp_inst_fn) - 1);
 			else
-				rts_error(VARLSTCNT(1) ERR_REPLINSTUNDEF);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REPLINSTUNDEF);
 		} else if (issue_gtm_putmsg == error_action)
 		{
 			if (SS_LOG2LONG == status)
-				gtm_putmsg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, log_nam.len, log_nam.addr, SIZEOF(temp_inst_fn) - 1);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, log_nam.len, log_nam.addr,
+					       SIZEOF(temp_inst_fn) - 1);
 			else
-				gtm_putmsg(VARLSTCNT(1) ERR_REPLINSTUNDEF);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REPLINSTUNDEF);
 		}
 	}
 	return ret;
@@ -175,7 +177,7 @@ void	repl_inst_read(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 	}
 	OPENFILE(fn, O_RDONLY, fd);
 	if (FD_INVALID == fd)
-		rts_error(VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
 	assert(0 < buflen);
 	if (0 != offset)
 	{
@@ -194,8 +196,8 @@ void	repl_inst_read(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 		{	/* Have read the entire label in the instance file header. Check if it is the right version */
 			if (memcmp(buff, GDS_REPL_INST_LABEL, GDS_REPL_INST_LABEL_SZ - 1))
 			{
-				rts_error(VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
-					GDS_REPL_INST_LABEL_SZ - 1, GDS_REPL_INST_LABEL, GDS_REPL_INST_LABEL_SZ - 1, buff);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
+					      GDS_REPL_INST_LABEL_SZ - 1, GDS_REPL_INST_LABEL, GDS_REPL_INST_LABEL_SZ - 1, buff);
 			}
 		}
 		if (0 == status)
@@ -205,14 +207,14 @@ void	repl_inst_read(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 			/* Check endianness match */
 			if (GTM_IS_LITTLE_ENDIAN != replhdr->is_little_endian)
 			{
-				rts_error(VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
-					LEN_AND_LIT(ENDIANTHIS), LEN_AND_LIT(ENDIANOTHER));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
+					      LEN_AND_LIT(ENDIANTHIS), LEN_AND_LIT(ENDIANOTHER));
 			}
 			/* Check 64bitness match */
 			if (GTM_IS_64BIT != replhdr->is_64bit)
 			{
-				rts_error(VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
-					LEN_AND_LIT(GTM_BITNESS_THIS), LEN_AND_LIT(GTM_BITNESS_OTHER));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLINSTFMT, 6, LEN_AND_STR(fn),
+					      LEN_AND_LIT(GTM_BITNESS_THIS), LEN_AND_LIT(GTM_BITNESS_OTHER));
 			}
 			/* At the time of this writing, the only minor version supported is 1.
 			 * Whenever this gets updated, we need to add code to do the online upgrade.
@@ -228,14 +230,15 @@ void	repl_inst_read(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 	if (0 != status)
 	{
 		if (-1 == status)
-			rts_error(VARLSTCNT(6) ERR_REPLINSTREAD, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLINSTREAD, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn));
 		else
-			rts_error(VARLSTCNT(7) ERR_REPLINSTREAD, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn), status);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLINSTREAD, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn),
+				      status);
 	}
 	CLOSEFILE_RESET(fd, status);	/* resets "fd" to FD_INVALID */
 	assert(0 == status);
 	if (0 != status)
-		rts_error(VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
 }
 
 /* Description:
@@ -290,9 +293,9 @@ void	repl_inst_write(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 	if (FD_INVALID == fd)
 	{
 		if (!in_repl_inst_create)
-			rts_error(VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
 		else
-			rts_error(VARLSTCNT(5) ERR_REPLINSTCREATE, 2, LEN_AND_STR(fn), errno);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTCREATE, 2, LEN_AND_STR(fn), errno);
 	}
 #ifdef __MVS__
 	if (-1 == (in_repl_inst_create ? gtm_zos_set_tag(fd, TAG_BINARY, TAG_NOTTEXT, TAG_FORCE, &realfiletag) :
@@ -303,11 +306,12 @@ void	repl_inst_write(char *fn, off_t offset, sm_uc_ptr_t buff, size_t buflen)
 	REPL_INST_LSEEKWRITE(fd, offset, buff, buflen, status);
 	assert(0 == status);
 	if (0 != status)
-		rts_error(VARLSTCNT(7) ERR_REPLINSTWRITE, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn), status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLINSTWRITE, 4, buflen, (qw_off_t *)&offset, LEN_AND_STR(fn),
+			      status);
 	CLOSEFILE_RESET(fd, status);	/* resets "fd" to FD_INVALID */
 	assert(0 == status);
 	if (0 != status)
-		rts_error(VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
 }
 
 /* Description:
@@ -344,15 +348,15 @@ void	repl_inst_sync(char *fn)
 	oflag = O_RDWR;
 	OPENFILE3(fn, oflag, 0666, fd);
 	if (FD_INVALID == fd)
-		rts_error(VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTOPEN, 2, LEN_AND_STR(fn), errno);
 	GTM_REPL_INST_FSYNC(fd, status);
 	assert(0 == status);
 	if (0 != status)
-		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fsync()"), CALLFROM, errno);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fsync()"), CALLFROM, errno);
 	CLOSEFILE_RESET(fd, status);	/* resets "fd" to FD_INVALID */
 	assert(0 == status);
 	if (0 != status)
-		rts_error(VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_REPLINSTCLOSE, 2, LEN_AND_STR(fn), status);
 }
 
 /* Description:
@@ -441,7 +445,7 @@ void	repl_inst_ftok_sem_lock(void)
 		if (!ftok_sem_lock(reg, FALSE, FALSE))
 		{
 			assert(FALSE);
-			rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, LEN_AND_STR(udi->fn));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REPLFTOKSEM, 2, LEN_AND_STR(udi->fn));
 		}
 	}
 	assert(udi->grabbed_ftok_sem);
@@ -469,7 +473,7 @@ void	repl_inst_ftok_sem_release(void)
 		if (!ftok_sem_release(reg, FALSE, FALSE))
 		{
 			assert(FALSE);
-			rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, LEN_AND_STR(udi->fn));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REPLFTOKSEM, 2, LEN_AND_STR(udi->fn));
 		}
 	}
 	assert(!udi->grabbed_ftok_sem);
@@ -605,7 +609,7 @@ int4	repl_inst_wrapper_histinfo_find_seqno(seq_num seqno, int4 strm_idx, repl_hi
 	{
 		status = ERR_REPLINSTNOHIST;
 		SPRINTF(histdetail, "seqno "INT8_FMT" "INT8_FMTX, seqno - 1, seqno - 1);
-		gtm_putmsg(VARLSTCNT(6) ERR_REPLINSTNOHIST, 4, LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLINSTNOHIST, 4, LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
 	} else
 		assert(0 <= local_histinfo->histinfo_num);
 	return status;
@@ -659,8 +663,8 @@ void	repl_inst_histinfo_add(repl_histinfo *histinfo)
 		assert(jnlpool.jnlpool_ctl->last_histinfo_seqno == last_histinfo->start_seqno);
 		if (histinfo->start_seqno < last_histinfo->start_seqno)
 		{	/* cannot create histinfo with out-of-order start_seqno */
-			rts_error(VARLSTCNT(8) ERR_REPLINSTSEQORD, 6, LEN_AND_LIT("New history record"),
-				&histinfo->start_seqno, &last_histinfo->start_seqno, LEN_AND_STR(udi->fn));
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLINSTSEQORD, 6, LEN_AND_LIT("New history record"),
+				      &histinfo->start_seqno, &last_histinfo->start_seqno, LEN_AND_STR(udi->fn));
 		}
 	}
 	strm_histinfo_num = jnlpool.repl_inst_filehdr->last_histinfo_num[strm_idx];
@@ -864,8 +868,8 @@ seq_num	repl_inst_histinfo_truncate(seq_num rollback_seqno)
 				assert(FALSE);
 				NON_GTM64_ONLY(SPRINTF(histdetail, "seqno [0x%llx]", rollback_seqno - 1));
 				GTM64_ONLY(SPRINTF(histdetail, "seqno [0x%lx]", rollback_seqno - 1));
-				gtm_putmsg(VARLSTCNT(6) MAKE_MSG_WARNING(ERR_REPLINSTNOHIST), 4,
-							LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_REPLINSTNOHIST), 4,
+					       LEN_AND_STR(histdetail), LEN_AND_STR(udi->fn));
 			}
 			index = -1;
 			/* Since we are rolling back all history records in the instance file,
@@ -1223,7 +1227,7 @@ int4	repl_inst_reset_zqgblmod_seqno_and_tn(void)
 	/* We use the same code dse uses to open all regions but we must make sure they are all open before proceeding. */
 	all_files_open = region_init(FALSE);
 	if (!all_files_open)
-		rts_error(VARLSTCNT(1) ERR_NOTALLDBOPN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOTALLDBOPN);
 	repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;
 	for (reg = gd_header->regions, reg_top = reg + gd_header->n_regions;  reg < reg_top;  reg++)
 	{
diff --git a/sr_unix/repl_instance.h b/sr_unix/repl_instance.h
index db69aa2..1f01e96 100644
--- a/sr_unix/repl_instance.h
+++ b/sr_unix/repl_instance.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -177,20 +177,20 @@ typedef struct gtmsrc_lcl_struct
 #define	OK_TO_LOG_FALSE		FALSE
 #define	OK_TO_LOG_TRUE		TRUE
 
-#define GET_INSTFILE_NAME(sendmsg, err_act)									\
-{														\
-	if ((SS_NORMAL == (status = TRANS_LOG_NAME(&log_nam, &trans_name, temp_inst_fn, SIZEOF(temp_inst_fn),	\
-							sendmsg)))						\
-		&& (0 != trans_name.len))									\
-	{													\
-		temp_inst_fn[trans_name.len] = '\0';								\
-		if (!get_full_path(trans_name.addr, trans_name.len, fn, fn_len, bufsize, &ustatus) && err_act)	\
-		{												\
-			gtm_putmsg(VARLSTCNT(9) ERR_REPLINSTACC, 2, trans_name.len, trans_name.addr,		\
-				ERR_TEXT, 2, RTS_ERROR_LITERAL("full path could not be found"), ustatus);	\
-		} else												\
-			ret = TRUE;										\
-	}													\
+#define GET_INSTFILE_NAME(sendmsg, err_act)										\
+{															\
+	if ((SS_NORMAL == (status = TRANS_LOG_NAME(&log_nam, &trans_name, temp_inst_fn, SIZEOF(temp_inst_fn),		\
+							sendmsg)))							\
+		&& (0 != trans_name.len))										\
+	{														\
+		temp_inst_fn[trans_name.len] = '\0';									\
+		if (!get_full_path(trans_name.addr, trans_name.len, fn, fn_len, bufsize, &ustatus) && err_act)		\
+		{													\
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_REPLINSTACC, 2, trans_name.len, trans_name.addr,	\
+				ERR_TEXT, 2, RTS_ERROR_LITERAL("full path could not be found"), ustatus);		\
+		} else													\
+			ret = TRUE;											\
+	}														\
 }
 
 typedef enum {
diff --git a/sr_unix/repl_ipc_cleanup.c b/sr_unix/repl_ipc_cleanup.c
index 7ec0112..a9839cd 100644
--- a/sr_unix/repl_ipc_cleanup.c
+++ b/sr_unix/repl_ipc_cleanup.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
diff --git a/sr_unix/repl_msg.h b/sr_unix/repl_msg.h
index ee47e53..5ade5bf 100644
--- a/sr_unix/repl_msg.h
+++ b/sr_unix/repl_msg.h
@@ -51,6 +51,11 @@ enum
 	REPL_NEED_STRMINFO,		/* 32 */  /* sent by a supplementary source server to a supplementary receiver server */
 	REPL_STRMINFO,			/* 33 */  /* sent in response to a REPL_NEED_STRMINFO message */
 	REPL_LOGFILE_INFO,		/* 34 */  /* sent (at time of handshake) to communicate to one another the $CWD/logfile */
+	REPL_NEED_TLS_INFO,		/* 35 */  /* sent to get the SSL/TLS information from the receiver. */
+	REPL_TLS_INFO,			/* 36 */  /* Receiver's response to REPL_NEED_TLS_INFO message. */
+	REPL_RENEG_ACK_ME,		/* 37 */  /* Start a renegotiation request with the receiver server. */
+	REPL_RENEG_ACK,			/* 38 */  /* Receiver's acknowledgement of REPL_RENEG_ACK_ME message. */
+	REPL_RENEG_COMPLETE,		/* 39 */  /* Completion of SSL/TLS renegotiation between the Source and Receiver server. */
 	REPL_MSGTYPE_LAST=256		/* 256 */
 	/* any new message need to be added before REPL_MSGTYPE_LAST */
 };
@@ -63,7 +68,8 @@ enum
 							 */
 #define	REPL_PROTO_VER_SUPPLEMENTARY	(char)0x3	/* Versions V5.5-000 and above that support supplementary instances */
 #define	REPL_PROTO_VER_REMOTE_LOGPATH	(char)0x4	/* Versions V6.0-003 and above that send remote $CWD as part of handshake */
-#define	REPL_PROTO_VER_THIS		REPL_PROTO_VER_REMOTE_LOGPATH
+#define REPL_PROTO_VER_TLS_SUPPORT	(char)0x5	/* Versions V6.1-000 and above that supports SSL/TLS communication. */
+#define	REPL_PROTO_VER_THIS		REPL_PROTO_VER_TLS_SUPPORT
 							/* The current/latest version of the communication protocol between the
 							 * primary (source server) and secondary (receiver server or rollback)
 							 */
@@ -88,6 +94,7 @@ enum
 #define	START_FLAG_TRIGGER_SUPPORT		0x00000020
 #define	START_FLAG_SRCSRV_IS_VMS		0x00000040	/* Obsolete but preserve slot */
 #define	START_FLAG_NORESYNC			0x00000080
+#define START_FLAG_ENABLE_TLS			0x00000100
 
 #define	MIN_REPL_MSGLEN		32 /* To keep compiler happy with
 				    * the definition of repl_msg_t as well
@@ -384,6 +391,15 @@ typedef struct
 {
 	int4		type;
 	int4		len;
+	uint4		API_version;		/* The GT.M TLS version understood by this side. */
+	uint4		library_version;	/* The SSL/TLS implementation library that this side is linked with at runtime. */
+	char		filler_32[16];
+} repl_tlsinfo_msg_t;
+
+typedef struct
+{
+	int4		type;
+	int4		len;
 	int4		fullpath_len;
 	uint4		pid;
 	char		proto_ver;
diff --git a/sr_unix/rtnhdr.h b/sr_unix/rtnhdr.h
index d72f8c9..9bbe6e8 100644
--- a/sr_unix/rtnhdr.h
+++ b/sr_unix/rtnhdr.h
@@ -11,6 +11,8 @@
 #ifndef RTNHDR_H_INCLUDED
 #define RTNHDR_H_INCLUDED
 
+#include "srcline.h"
+
 /* rtnhdr.h - routine header for shared binary Unix platforms */
 
 /* There are several references to this structure from assembly language; these include:
@@ -94,7 +96,7 @@ typedef struct	rhead_struct
 	unsigned char		*shared_ptext_adr;	/* If set, ptext_adr points to local copy, this points to old shared copy */
 	unsigned char		*ptext_adr;		/* (#) address of start of instructions (offset in original rtnhdr) */
 	unsigned char		*ptext_end_adr;		/* (#) address of end of instructions + 1 (offset in original rtnhdr) */
-	int4			checksum;		/* verification value */
+	int4			checksum;		/* 4-byte source code checksum (for platforms where MD5 is unavailable) */
 	int4			temp_mvals;		/* (#) temp_mvals value of current module version */
 	int4			temp_size;		/* (#) temp_size value of current module version */
 	struct rhead_struct	*current_rhead_adr;	/* (#) address of routine header of current module version */
@@ -102,6 +104,9 @@ typedef struct	rhead_struct
 #	ifdef GTM_TRIGGER
 	void_ptr_t		trigr_handle;		/* Type is void to avoid needing gv_trigger.h for gv_trigger_t type addr */
 #	endif
+	unsigned char		checksum_md5[16];	/* 16-byte MD5 checksum of routine source code */
+	struct rhead_struct	*active_rhead_adr;	/* chain of active old versions, fully reserved for continued use */
+	routine_source		*source_code;		/* source code used by $TEXT */
 } rhdtyp;
 
 /* Routine table entry */
@@ -207,14 +212,17 @@ struct	sym_table
 
 /* Prototypes */
 int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig);
+void free_src_tbl(rhdtyp *rtn_vector);
 unsigned char *find_line_start(unsigned char *in_addr, rhdtyp *routine);
 int4 *find_line_addr(rhdtyp *routine, mstr *label, int4 offset, mident **lent_name);
 rhdtyp *find_rtn_hdr(mstr *name);
+boolean_t find_rtn_tabent(rtn_tabent **res, mstr *name);
 bool zlput_rname(rhdtyp *hdr);
 void zlmov_lnames(rhdtyp *hdr);
 rhdtyp *make_dmode(void);
 void comp_lits(rhdtyp *rhead);
 rhdtyp  *op_rhdaddr(mval *name, rhdtyp *rhd);
+rhdtyp	*op_rhdaddr1(mval *name);
 lnr_tabent **op_labaddr(rhdtyp *routine, mval *label, int4 offset);
 void urx_resolve(rhdtyp *rtn, lab_tabent *lbl_tab, lab_tabent *lbl_top);
 char *rtnlaboff2entryref(char *entryref_buff, mident *rtn, mident *lab, int offset);
diff --git a/sr_unix/runall.csh b/sr_unix/runall.csh
index be64b40..739c998 100644
--- a/sr_unix/runall.csh
+++ b/sr_unix/runall.csh
@@ -182,12 +182,15 @@ gtmcrypt_dbk_ref gtmcrypt
 gtmcrypt_pk_ref gtmcrypt
 gtmcrypt_sym_ref gtmcrypt
 gtmcrypt_ref gtmcrypt
+gtmcrypt_util gtmcrypt
 maskpass gtmcrypt
+gtm_tls_impl gtmcrypt
 LABEL
 
 # this first set of excluded modules are from the list above of modules that get built as plugins. Only plugins
 # should be metioned in this list.
-set exclude_compile_list = "gtmcrypt_dbk_ref gtmcrypt_sym_ref gtmcrypt_pk_ref gtmcrypt_ref maskpass"
+set exclude_compile_list = "gtmcrypt_dbk_ref gtmcrypt_sym_ref gtmcrypt_pk_ref gtmcrypt_ref maskpass gtm_tls_impl"
+set exclude_compile_list = "$exclude_compile_list gtmcrypt_util"
 # modules that should never be built or compiled are in this list. They are used in other capacities (e.g. used to
 # generate other routines) but are NOT part of the GTM runtime. Other scripts compile and use these routines.
 set exclude_build_list = "gtm_threadgbl_deftypes"
diff --git a/sr_unix/secshr_client.c b/sr_unix/secshr_client.c
index f4831ad..c7eddba 100644
--- a/sr_unix/secshr_client.c
+++ b/sr_unix/secshr_client.c
@@ -16,7 +16,6 @@
 #include <signal.h>
 #include <sys/wait.h>
 #include <sys/time.h>
-#include <sys/un.h>
 #include <sys/sem.h>
 #include <sys/shm.h>
 #include <sys/param.h>
@@ -40,6 +39,7 @@
 #include "eintr_wrappers.h"
 #include "util.h"
 #include "send_msg.h"
+#include "gtm_un.h"
 #include "gtmmsg.h"
 #include "wcs_backoff.h"
 #include "trans_log_name.h"
@@ -64,13 +64,13 @@ GBLREF int			server_start_tries;
 GBLREF boolean_t		gtmsecshr_sock_init_done;
 GBLREF uint4			process_id;
 GBLREF ipcs_mesg		db_ipcs;
+GBLREF char			gtm_dist[GTM_PATH_MAX];
 
 LITREF char			gtm_release_name[];
 LITREF int4			gtm_release_name_len;
 
 static int			secshr_sem;
 static boolean_t		gtmsecshr_file_check_done;
-static mstr			gtmsecshr_logname;
 static char			gtmsecshr_path[GTM_PATH_MAX];
 static volatile boolean_t	client_timer_popped;
 static unsigned long		cur_seqno;
@@ -179,6 +179,7 @@ int send_mesg2gtmsecshr(unsigned int code, unsigned int id, char *path, int path
 	char			*gtm_tmp_ptr;
 	struct stat		stat_buf;
 	struct shmid_ds		shm_info;
+	int			len;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -191,15 +192,9 @@ int send_mesg2gtmsecshr(unsigned int code, unsigned int id, char *path, int path
 	timer_id = (TID)send_mesg2gtmsecshr;
 	if (!gtmsecshr_file_check_done)
 	{
-		gtmsecshr_logname.addr = GTMSECSHR_PATH;
-                gtmsecshr_logname.len = SIZEOF(GTMSECSHR_PATH);
-		status = TRANS_LOG_NAME(&gtmsecshr_logname, &gtmsecshr_pathname, gtmsecshr_path, SIZEOF(gtmsecshr_path),
-					dont_sendmsg_on_log2long);
-                if (SS_NORMAL != status)
+		len = STRLEN(gtm_dist);
+		if (!len)
 		{
-			if (SS_LOG2LONG == status)
-				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3,
-					gtmsecshr_logname.len, gtmsecshr_logname.addr, SIZEOF(gtmsecshr_path) - 1);
                         send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_GTMSECSHRSTART, 3,
 					RTS_ERROR_TEXT("Client"), process_id, ERR_TEXT, 2,
 					RTS_ERROR_STRING(secshrstart_error_code[INVTRANSGTMSECSHR]));
@@ -207,6 +202,14 @@ int send_mesg2gtmsecshr(unsigned int code, unsigned int id, char *path, int path
 					RTS_ERROR_TEXT("Client"), process_id, ERR_TEXT, 2,
 					RTS_ERROR_STRING(secshrstart_error_code[INVTRANSGTMSECSHR]));
 		}
+		memcpy(gtmsecshr_path, gtm_dist, len);
+		gtmsecshr_path[len] =  '/';
+		memcpy(gtmsecshr_path + len + 1, GTMSECSHR_EXECUTABLE, STRLEN(GTMSECSHR_EXECUTABLE));
+		gtmsecshr_pathname.addr = gtmsecshr_path;
+		gtmsecshr_pathname.len = len + 1 + STRLEN(GTMSECSHR_EXECUTABLE);
+		if (GTM_PATH_MAX <= gtmsecshr_pathname.len)
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_TEXT, 2,
+					RTS_ERROR_LITERAL("gtmsecshr path too long"));
 		gtmsecshr_pathname.addr[gtmsecshr_pathname.len] = '\0';
 		if (-1 == Stat(gtmsecshr_pathname.addr, &stat_buf))
 			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
diff --git a/sr_unix/sleep.h b/sr_unix/sleep.h
index 3a1bc6a..e6ec0b3 100644
--- a/sr_unix/sleep.h
+++ b/sr_unix/sleep.h
@@ -170,7 +170,7 @@ int m_nsleep(int nseconds);
 # endif
 
 # ifdef _UWIN
-# include "iotcp_select.h"
+# include "gtm_select.h"
 # define usleep_func gtm_usleep
 # endif
 
diff --git a/sr_unix/source_file.c b/sr_unix/source_file.c
index ed67b46..0540f27 100644
--- a/sr_unix/source_file.c
+++ b/sr_unix/source_file.c
@@ -125,7 +125,8 @@ void	compile_source_file(unsigned short flen, char *faddr, boolean_t MFtIsReqd)
 			{
 				CLOSEFILE_RESET(object_file_des, rc);	/* resets "object_file_des" to FD_INVALID */
 				if (-1 == rc)
-					rts_error(VARLSTCNT(5) ERR_OBJFILERR, 2, object_name_len, object_file_name, errno);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_OBJFILERR, 2,
+							object_name_len, object_file_name, errno);
 			}
 			if (tt_so_do_once)
 				break;
@@ -139,7 +140,7 @@ CONDITION_HANDLER(source_ch)
 {
 	int	dummy1, dummy2;
 
-	START_CH;
+	START_CH(TRUE);
 	if (DUMP)
 	{
 		NEXTCH;
@@ -170,7 +171,7 @@ bool	open_source_file (void)
 	fstr.len = source_name_len;
 	status = parse_file(&fstr, &pblk);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(5) ERR_FILEPARSE, 2, fstr.len, fstr.addr, status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_FILEPARSE, 2, fstr.len, fstr.addr, status);
 	pars.mvtype = MV_STR;
 	pars.str.len = SIZEOF(open_params_list);
 	pars.str.addr = (char *)open_params_list;
@@ -244,10 +245,10 @@ int4	read_source_file (void)
 	REVERT;
 	memcpy((char *)source_buffer, val.str.addr, val.str.len);
 	cp = source_buffer + val.str.len;
-	*cp = '\0';
 	/*	if there is a newline charactor (end of a line)	*/
 	if (!(io_curr_device.in->dollar.x))
-		*(cp+1) = '\0';
+		*cp++ = '\n';
+	*cp = '\0';
 	if ( FALSE != io_curr_device.in->dollar.zeof )
 		return -1;
 	io_curr_device = tmp_list_dev;	/*	restore list file after reading	if it's opened	*/
@@ -258,7 +259,7 @@ CONDITION_HANDLER(read_source_ch)
 {
 	int	dummy1, dummy2;
 
-	START_CH;
+	START_CH(TRUE);
 	UNWIND(dummy1, dummy2);
 }
 
diff --git a/sr_unix/ss_initiate.c b/sr_unix/ss_initiate.c
index 58bbedb..0194fa6 100644
--- a/sr_unix/ss_initiate.c
+++ b/sr_unix/ss_initiate.c
@@ -86,13 +86,13 @@ ZOS_ONLY(error_def(ERR_TEXT);)
 
 
 #define SNAPSHOT_TMP_PREFIX	"gtm_snapshot_"
-#define ISSUE_WRITE_ERROR_AND_EXIT(reg, RC, csa, tempfilename)								\
-{															\
-	gtm_putmsg(VARLSTCNT(7) ERR_SSFILOPERR, 4, LEN_AND_LIT("write"), LEN_AND_STR(tempfilename), RC);		\
-	if (csa->now_crit)												\
-		rel_crit(csa->region);											\
+#define ISSUE_WRITE_ERROR_AND_EXIT(reg, RC, csa, tempfilename)									\
+{																\
+	gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(7) ERR_SSFILOPERR, 4, LEN_AND_LIT("write"), LEN_AND_STR(tempfilename), RC);	\
+	if (csa->now_crit)													\
+		rel_crit(csa->region);												\
 	UNFREEZE_REGION_IF_NEEDED(csa->hdr, reg);										\
-	return FALSE;													\
+	return FALSE;														\
 }
 
 #define TOT_BYTES_REQUIRED(BLKS)	DIVIDE_ROUND_UP(BLKS, 8) /* One byte can represent 8 blocks' before image state */
@@ -137,15 +137,15 @@ ZOS_ONLY(error_def(ERR_TEXT);)
 		{											\
 			RC = errno;									\
 			assert(FALSE);									\
-			gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("Error with shmdt"), 	\
-					CALLFROM, RC);							\
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_SYSCALL, 5,			\
+					LEN_AND_LIT("Error with shmdt"), CALLFROM, RC);			\
 		}											\
 		if (0 != shmctl(SS_SHMID, IPC_RMID, 0))							\
 		{											\
 			RC = errno;									\
 			assert(FALSE);									\
-			gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("Error with shmctl"),	\
-					CALLFROM, RC);							\
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_SYSCALL, 5,			\
+					LEN_AND_LIT("Error with shmctl"), CALLFROM, RC);		\
 		}											\
 	}												\
 	SS_SHMID = shmget(IPC_PRIVATE, SS_SHMSIZE, RWDALL | IPC_CREAT);					\
@@ -153,15 +153,15 @@ ZOS_ONLY(error_def(ERR_TEXT);)
 	{												\
 		RC = errno;										\
 		assert(FALSE);										\
-		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("Error with shmget"), CALLFROM,	\
-				RC);									\
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_SYSCALL, 5,				\
+				LEN_AND_LIT("Error with shmget"), CALLFROM, RC);			\
 	}												\
 	if (-1 == (sm_long_t)(SS_SHMADDR = do_shmat(SS_SHMID, 0, 0)))					\
 	{												\
 		RC = errno;										\
 		assert(FALSE);										\
-		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("Error with shmat"), CALLFROM,	\
-			RC);										\
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_SYSCALL, 5,				\
+				LEN_AND_LIT("Error with shmat"), CALLFROM, RC);				\
 	}												\
 }
 
@@ -205,7 +205,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	shm_snapshot_ptr_t	ss_shm_ptr;
 	snapshot_context_ptr_t	lcl_ss_ctx, ss_orphan_ctx;
 	snapshot_filhdr_ptr_t	ss_filhdr_ptr;
-	int			shdw_fd, tmpfd, fclose_res, fstat_res, status, perm, group_id, pwrite_res, dsk_addr = 0;
+	int			shdw_fd, tmpfd, fclose_res, fstat_res, status, perm, user_id, group_id, pwrite_res, dsk_addr = 0;
 	int			retries, idx, this_snapshot_idx, save_errno, ss_shmsize, ss_shm_vbn;
 	ZOS_ONLY(int		realfiletag;)
 	long			ss_shmid = INVALID_SHMID;
@@ -216,6 +216,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	enum db_acc_method	acc_meth;
 	void			*ss_shmaddr;
 	gtm_uint64_t		db_file_size, native_size;
+	DEBUG_ONLY(gtm_uint64_t db_size;)
 	uint4			tempnamprefix_len, crit_counter, tot_blks, prev_ss_shmsize, fstat_status;
 	pid_t			*kip_pids_arr_ptr;
 	mstr			tempdir_log, tempdir_full, tempdir_trans;
@@ -255,7 +256,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 			ss_release(NULL);
 		else
 		{
-			gtm_putmsg(VARLSTCNT(5) ERR_MAXSSREACHED, 3, MAX_SNAPSHOTS, REG_LEN_STR(reg));
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_MAXSSREACHED, 3, MAX_SNAPSHOTS, REG_LEN_STR(reg));
 			ss_release_lock(reg);
 			UNFREEZE_REGION_IF_NEEDED(csd, reg);
 			return FALSE;
@@ -328,7 +329,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	/* Verify if we can stat the temporary directory */
 	if (FILE_STAT_ERROR == (fstat_res = gtm_file_stat(&tempdir_trans, NULL, &tempdir_full, FALSE, &fstat_status)))
 	{
-		gtm_putmsg(VARLSTCNT(5) ERR_SSTMPDIRSTAT, 2, tempdir_trans.len, tempdir_trans.addr, fstat_status);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_SSTMPDIRSTAT, 2, tempdir_trans.len, tempdir_trans.addr, fstat_status);
 		UNFREEZE_REGION_IF_NEEDED(csd, reg);
 		return FALSE;
 	}
@@ -346,7 +347,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	if (FD_INVALID == tmpfd)
 	{
 		status = errno;
-		gtm_putmsg(VARLSTCNT(5) ERR_SSTMPCREATE, 2, tempdir_trans.len, tempdir_trans.addr, status);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_SSTMPCREATE, 2, tempdir_trans.len, tempdir_trans.addr, status);
 		UNFREEZE_REGION_IF_NEEDED(csd, reg);
 		return FALSE;
 	}
@@ -364,7 +365,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	if (FD_INVALID == shdw_fd)
 	{
 		status = errno;
-		gtm_putmsg(VARLSTCNT(7) ERR_SSFILOPERR, 4, LEN_AND_LIT("open"),
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(7) ERR_SSFILOPERR, 4, LEN_AND_LIT("open"),
 				tempdir_full.len, tempdir_full.addr, status);
 		UNFREEZE_REGION_IF_NEEDED(csd, reg);
 		return FALSE;
@@ -389,13 +390,13 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 		 * INTEG started by read-only processes to create snapshot files that are writable by processes having write
 		 * permissions on the database file.
 		 */
-		if (gtm_set_group_and_perm(&stat_buf, &group_id, &perm, PERM_IPC, &pdd) < 0)
+		if (gtm_permissions(&stat_buf, &user_id, &group_id, &perm, PERM_IPC, &pdd) < 0)
 		{
-			send_msg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+			send_msg_csa(CSA_ARG(csa) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 				ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("snapshot file"),
 				RTS_ERROR_STRING(((unix_db_info *)(reg->dyn.addr->file_cntl->file_info))->fn),
 				PERMGENDIAG_ARGS(pdd));
-			gtm_putmsg(VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6+PERMGENDIAG_ARG_COUNT)
 				ERR_PERMGENFAIL, 4, RTS_ERROR_STRING("snapshot file"),
 				RTS_ERROR_STRING(((unix_db_info *)(reg->dyn.addr->file_cntl->file_info))->fn),
 				PERMGENDIAG_ARGS(pdd));
@@ -404,10 +405,10 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 		}
 	}
 	if ((-1 == fstat_res) || (-1 == FCHMOD(shdw_fd, perm))
-		|| ((-1 != group_id) && (-1 == fchown(shdw_fd, -1, group_id))))
+		|| (((-1 != user_id) || (-1 != group_id)) && (-1 == fchown(shdw_fd, user_id, group_id))))
 	{
 		status = errno;
-		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("fchmod/fchown"), CALLFROM, status);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("fchmod/fchown"), CALLFROM, status);
 		UNFREEZE_REGION_IF_NEEDED(csd, reg);
 		return FALSE;
 	}
@@ -579,7 +580,8 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 		{	/* We have a consistent copy of the total blocks and csd->kill_in_prog is FALSE inside crit. No need for
 			 * retry.
 			 */
-			assert(native_size == (((gtm_uint64_t)tot_blks * (csd->blk_size / DISK_BLOCK_SIZE)) + (csd->start_vbn)));
+			DEBUG_ONLY(db_size = ((gtm_uint64_t)tot_blks * (csd->blk_size / DISK_BLOCK_SIZE)) + (csd->start_vbn);)
+			assert((native_size == db_size) || (native_size == ROUND_UP(db_size, (OS_PAGE_SIZE / DISK_BLOCK_SIZE))));
 			break;
 		}
 	}
@@ -589,7 +591,8 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	 * proceed gracefully
 	 */
 	assert(csa->now_crit);
-	assert(native_size == (((gtm_uint64_t)tot_blks * (csd->blk_size / DISK_BLOCK_SIZE)) + (csd->start_vbn)));
+	DEBUG_ONLY(db_size = ((gtm_uint64_t)tot_blks * (csd->blk_size / DISK_BLOCK_SIZE)) + (csd->start_vbn);)
+	assert((native_size == db_size) || (native_size == ROUND_UP(db_size, (OS_PAGE_SIZE / DISK_BLOCK_SIZE))));
 	assert(NULL != ss_shmaddr);
 	assert(0 == ((long)ss_shmaddr % OS_PAGE_SIZE));
 	assert(0 == ss_shmsize % OS_PAGE_SIZE);
@@ -612,7 +615,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 		/* If -ONLINE was specified explicitly, then it is an ERROR. Issue the error and return FALSE. */
 		if (online_specified)
 		{
-			gtm_putmsg(VARLSTCNT(4) ERR_SSV4NOALLOW, 2, DB_LEN_STR(reg));
+			gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_SSV4NOALLOW, 2, DB_LEN_STR(reg));
 			util_out_print(NO_ONLINE_ERR_MSG, TRUE);
 			GET_CRIT_AND_DECR_INHIBIT_KILLS(reg, cnl);
 			UNFREEZE_REGION_IF_NEEDED(csd, reg);
@@ -642,7 +645,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 								   * phase 2 commits are done with before returning */
 	{
 		assert(process_id != csd->freeze); /* We would not have frozen the region if the database is read-write */
-		gtm_putmsg(VARLSTCNT(6) ERR_BUFFLUFAILED, 4, LEN_AND_STR(calling_utility), DB_LEN_STR(reg));
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) ERR_BUFFLUFAILED, 4, LEN_AND_STR(calling_utility), DB_LEN_STR(reg));
 		GET_CRIT_AND_DECR_INHIBIT_KILLS(reg, cnl);
 		return FALSE;
 	}
@@ -701,7 +704,7 @@ boolean_t	ss_initiate(gd_region *reg, 			/* Region in which snapshot has to be s
 	{	/* A concurrent online rollback happened since we did the gvcst_init. The INTEG is not reliable.
 		 * Cleanup and exit
 		 */
-		gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
+		gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(1) ERR_DBROLLEDBACK);
 		UNFREEZE_REGION_IF_NEEDED(csa, reg);
 		return FALSE;
 	}
diff --git a/sr_unix/trigger.h b/sr_unix/trigger.h
index 6ef90aa..ba431ab 100644
--- a/sr_unix/trigger.h
+++ b/sr_unix/trigger.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -157,149 +157,135 @@ typedef enum
 	TREF(gv_some_subsc_null) = FALSE;					\
 }
 
-#define BUILD_HASHT_SUB_CURRKEY_T(TRIG_VAL, SUB, LEN)							\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB, LEN);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
+#define BUILD_HASHT_SUB_CURRKEY_T(TRIG_VAL, SUB, LEN)						\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB, LEN);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
 }
 
-#define	BUILD_HASHT_SUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2)					\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB2;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
-}
-
-#define BUILD_HASHT_SUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, LEN2)					\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB2, LEN2);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
-}
-
-#define	BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3) 				\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB2;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB3;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
-}
-
-#define BUILD_HASHT_SUB_MSUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3, LEN3)			\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB2;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB3, LEN3);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
-}
-
-#define	BUILD_HASHT_SUB_SUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, LEN2, SUB3, LEN3) 		\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB2, LEN2);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	STR2MVAL(TRIG_VAL, SUB3, LEN3);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
-}
-
-#define BUILD_HASHT_SUB_MSUB_SUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3, LEN3, SUB4)		\
-{													\
-	short int		max_key;								\
-	boolean_t		was_null = FALSE, is_null = FALSE;					\
-	mval			*subsc_ptr;								\
-	DCL_THREADGBL_ACCESS;										\
-													\
-	SETUP_THREADGBL_ACCESS;										\
-	max_key = gv_cur_region->max_key_size;								\
-	BUILD_HASHT_CURRKEY_NAME;									\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB1, LEN1);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB2;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &TRIG_VAL;										\
-	STR2MVAL(TRIG_VAL, SUB3, LEN3);									\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	subsc_ptr = &SUB4;										\
-	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, max_key, gv_currkey, was_null, is_null);			\
-	TREF(gv_last_subsc_null) = is_null;								\
-	TREF(gv_some_subsc_null) = was_null;								\
+#define	BUILD_HASHT_SUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2)				\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB2;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
+}
+
+#define BUILD_HASHT_SUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, LEN2)				\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB2, LEN2);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
+}
+
+#define	BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3) 			\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB2;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB3;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
+}
+
+#define BUILD_HASHT_SUB_MSUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3, LEN3)		\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB2;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB3, LEN3);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
+}
+
+#define	BUILD_HASHT_SUB_SUB_SUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, LEN2, SUB3, LEN3) 	\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB2, LEN2);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	STR2MVAL(TRIG_VAL, SUB3, LEN3);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
+}
+
+#define BUILD_HASHT_SUB_MSUB_SUB_MSUB_CURRKEY_T(TRIG_VAL, SUB1, LEN1, SUB2, SUB3, LEN3, SUB4)	\
+{												\
+	boolean_t		was_null = FALSE, is_null = FALSE;				\
+	mval			*subsc_ptr;							\
+	DCL_THREADGBL_ACCESS;									\
+												\
+	SETUP_THREADGBL_ACCESS;									\
+	BUILD_HASHT_CURRKEY_NAME;								\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB1, LEN1);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB2;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &TRIG_VAL;									\
+	STR2MVAL(TRIG_VAL, SUB3, LEN3);								\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	subsc_ptr = &SUB4;									\
+	COPY_SUBS_TO_GVCURRKEY(subsc_ptr, gv_cur_region, gv_currkey, was_null, is_null);	\
+	TREF(gv_last_subsc_null) = is_null;							\
+	TREF(gv_some_subsc_null) = was_null;							\
 }
 
 #define	TRIGGER_GLOBAL_ASSIGNMENT_STR(TRIG_VAL, VALUE, LEN, RES)					\
@@ -462,44 +448,43 @@ typedef enum
 	TRIGGER_GLOBAL_ASSIGNMENT_STR(trig_val, VALUE, LEN, RES);					\
 }
 
-#define	INT2STR(INT, STR)									\
-{												\
-	char		*lcl_ptr;								\
-	int		num_len;								\
-												\
-	lcl_ptr = STR;										\
-	num_len = 0;										\
-	I2A(lcl_ptr, num_len, INT);								\
-	assert(MAX_DIGITS_IN_INT >= num_len);							\
-	*(lcl_ptr + num_len) = '\0';								\
+#define	INT2STR(INT, STR)			\
+{						\
+	char		*lcl_ptr;		\
+	int		num_len;		\
+						\
+	lcl_ptr = STR;				\
+	num_len = 0;				\
+	I2A(lcl_ptr, num_len, INT);		\
+	assert(MAX_DIGITS_IN_INT >= num_len);	\
+	*(lcl_ptr + num_len) = '\0';		\
 }
 
-#define SAVE_TRIGGER_REGION_INFO							\
-{											\
-	save_gv_target = gv_target;							\
-	save_gv_cur_region = gv_cur_region;						\
-	save_sgm_info_ptr = sgm_info_ptr;						\
-	assert(NULL != gv_currkey);							\
-	assert((SIZEOF(gv_key) + gv_currkey->end) <= SIZEOF(save_currkey));		\
-	save_gv_currkey = (gv_key *)&save_currkey[0];					\
-	memcpy(save_gv_currkey, gv_currkey, SIZEOF(gv_key) + gv_currkey->end);		\
-}
-#define RESTORE_TRIGGER_REGION_INFO							\
-{											\
-	gv_target = save_gv_target;							\
-	sgm_info_ptr = save_sgm_info_ptr;						\
-	/* check no keysize expansion occurred inside gvcst_root_search */		\
-	assert(gv_currkey->top == save_gv_currkey->top);				\
-	memcpy(gv_currkey, save_gv_currkey, SIZEOF(gv_key) + save_gv_currkey->end);	\
-	if (NULL != save_gv_cur_region)							\
-	{										\
-		TP_CHANGE_REG_IF_NEEDED(save_gv_cur_region);				\
-	} else										\
-	{										\
-		gv_cur_region = NULL;							\
-		cs_data = NULL;								\
-		cs_addrs = NULL;							\
-	}										\
+#define SAVE_TRIGGER_REGION_INFO(SAVE_KEY)					\
+{										\
+	save_gv_target = gv_target;						\
+	save_gv_cur_region = gv_cur_region;					\
+	save_sgm_info_ptr = sgm_info_ptr;					\
+	assert(NULL != gv_currkey);						\
+	assert((SIZEOF(gv_key) + gv_currkey->end) <= SIZEOF(SAVE_KEY));		\
+	memcpy(&SAVE_KEY[0], gv_currkey, SIZEOF(gv_key) + gv_currkey->end);	\
+}
+#define RESTORE_TRIGGER_REGION_INFO(SAVE_KEY)					\
+{										\
+	gv_target = save_gv_target;						\
+	sgm_info_ptr = save_sgm_info_ptr;					\
+	/* check no keysize expansion occurred inside gvcst_root_search */	\
+	assert(gv_currkey->top == SAVE_KEY[0].top);				\
+	memcpy(gv_currkey, &SAVE_KEY[0], SIZEOF(gv_key) + SAVE_KEY[0].end);	\
+	if (NULL != save_gv_cur_region)						\
+	{									\
+		TP_CHANGE_REG_IF_NEEDED(save_gv_cur_region);			\
+	} else									\
+	{									\
+		gv_cur_region = NULL;						\
+		cs_data = NULL;							\
+		cs_addrs = NULL;						\
+	}									\
 }
 
 #endif /* MUPIP_TRIGGER_INCLUDED */
diff --git a/sr_unix/trigger_compare.c b/sr_unix/trigger_compare.c
index c07e2b2..cad5cc1 100644
--- a/sr_unix/trigger_compare.c
+++ b/sr_unix/trigger_compare.c
@@ -29,7 +29,7 @@
 #include "mvalconv.h"			/* Needed for MV_FORCE_MVAL and MV_FORCE_UMVAL */
 #include "op.h"
 #include "nametabtyp.h"
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "gdscc.h"			/* needed for tp.h */
 #include "gdskill.h"			/* needed for tp.h */
 #include "buddy_list.h"			/* needed for tp.h */
@@ -37,6 +37,7 @@
 #include "filestruct.h"			/* needed for jnl.h */
 #include "jnl.h"			/* needed for tp.h */
 #include "tp.h"
+#include "hashtab_mname.h"
 
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	gd_addr			*gd_header;
@@ -183,11 +184,8 @@ boolean_t search_triggers(char *trigvn, int trigvn_len, char **values, uint4 *va
 {
 	mval			collision_indx;
 	mval			*collision_indx_ptr;
-	sgmnt_addrs		*csa;
 	mval			data_val;
-	mstr			gbl_name;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree;
+	mname_entry		gvname;
 	boolean_t		have_value;
 	mval			key_val;
 	int4			len;
@@ -205,6 +203,7 @@ boolean_t search_triggers(char *trigvn, int trigvn_len, char **values, uint4 *va
 	int			trig_index;
 	char			*xecute_buff;
 	int4			xecute_len;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -242,11 +241,12 @@ boolean_t search_triggers(char *trigvn, int trigvn_len, char **values, uint4 *va
 		ptr++;
 		A2I(ptr, key_val.str.addr + key_val.str.len, trig_index);
 		assert(-1 != trig_index);
-		gbl_name.addr = trigvn;
-		gbl_name.len = trigvn_len;
-		GV_BIND_NAME_ONLY(gd_header, &gbl_name);
-		csa = gv_target->gd_csa;
-		SETUP_TRIGGER_GLOBAL;
+		gvname.var_name.addr = trigvn;
+		gvname.var_name.len = trigvn_len;
+		COMPUTE_HASH_MNAME(&gvname);
+		GV_BIND_NAME_ONLY(gd_header, &gvname, gvnh_reg);
+		assert(cs_addrs == gv_target->gd_csa);
+		SET_GVTARGET_TO_HASHT_GBL(cs_addrs);
 		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 		MV_FORCE_MVAL(&mv_trig_indx, trig_index);
 		for (sub_indx = 0; sub_indx < NUM_TOTAL_SUBS; sub_indx++)
diff --git a/sr_unix/trigger_delete.c b/sr_unix/trigger_delete.c
index df0d02e..63fa7c4 100644
--- a/sr_unix/trigger_delete.c
+++ b/sr_unix/trigger_delete.c
@@ -30,7 +30,7 @@
 #include "mv_stent.h"			/* for COPY_SUBS_TO_GVCURRKEY macro */
 #include "gvsub2str.h"			/* for COPY_SUBS_TO_GVCURRKEY */
 #include "format_targ_key.h"		/* for COPY_SUBS_TO_GVCURRKEY */
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "hashtab_str.h"
 #include "wbox_test_init.h"
 #include "trigger_delete_protos.h"
@@ -45,6 +45,7 @@
 #include "op.h"
 #include "util.h"
 #include "zshow.h"			/* for format2zwr() prototype */
+#include "hashtab_mname.h"
 
 GBLREF	gd_region		*gv_cur_region;
 GBLREF	sgm_info		*sgm_info_ptr;
@@ -104,8 +105,7 @@ STATICFNDEF void cleanup_trigger_hash(char *trigvn, int trigvn_len, char **value
 {
 	sgmnt_addrs		*csa;
 	uint4			len;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -113,8 +113,9 @@ STATICFNDEF void cleanup_trigger_hash(char *trigvn, int trigvn_len, char **value
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
+	csa = cs_addrs;
 	assert(0 != gv_target->root);
 	if (gv_cur_region->read_only)
 		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
@@ -126,19 +127,13 @@ STATICFNDEF void cleanup_trigger_hash(char *trigvn, int trigvn_len, char **value
 	{
 		SEARCH_AND_KILL_BY_HASH(trigvn, trigvn_len, kill_hash, match_index, csa);
 	}
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 }
 
 STATICFNDEF void cleanup_trigger_name(char *trigvn, int trigvn_len, char *trigger_name, int trigger_name_len)
 {
-	sgmnt_addrs		*csa;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree;
 	int4			result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_altkey;
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	gv_namehead		*save_gvtarget;
@@ -161,12 +156,12 @@ STATICFNDEF void cleanup_trigger_name(char *trigvn, int trigvn_len, char *trigge
 		used_trigvn_len = MIN(trigvn_len, MAX_AUTO_TRIGNAME_LEN);
 		memcpy(trunc_name, trigvn, used_trigvn_len);
 	}
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	if (0 != gv_target->root)
 	{
 		if (gv_cur_region->read_only)
-			rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+			rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 		if (is_auto_name)
 		{
 			/* $get(^#t("#TNAME",<trunc_name>,"#TNCOUNT")) */
@@ -199,22 +194,18 @@ STATICFNDEF void cleanup_trigger_name(char *trigvn, int trigvn_len, char *trigge
 					    trigger_name_len - 1);
 		gvcst_kill(is_auto_name);
 	}
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 }
 
 STATICFNDEF int4 update_trigger_name_value(int trigvn_len, char *trig_name, int trig_name_len, int new_trig_index)
 {
-	sgmnt_addrs		*csa;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree;
 	int			len;
 	char			name_and_index[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT];
 	char			new_trig_name[MAX_TRIGNAME_LEN + 1];
 	int			num_len;
 	char			*ptr;
 	int4			result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -224,10 +215,10 @@ STATICFNDEF int4 update_trigger_name_value(int trigvn_len, char *trig_name, int
 	SETUP_THREADGBL_ACCESS;
 	if (MAX_AUTO_TRIGNAME_LEN < trigvn_len)
 		return PUT_SUCCESS;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	if (gv_cur_region->read_only)
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 	assert(0 != gv_target->root);
 	/* $get(^#t("#TNAME",^#t(GVN,index,"#TRIGNAME")) */
 	BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trig_name, trig_name_len - 1);
@@ -252,7 +243,7 @@ STATICFNDEF int4 update_trigger_name_value(int trigvn_len, char *trig_name, int
 	/* set ^#t(GVN,index,"#TRIGNAME")=trig_name $C(0) new_trig_index */
 	SET_TRIGGER_GLOBAL_SUB_SUB_STR(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trig_name, trig_name_len - 1,
 		name_and_index, len, result);
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return result;
 }
 
@@ -268,8 +259,7 @@ STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **
 	int			num_len;
 	char			*ptr;
 	int4			result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -277,8 +267,9 @@ STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
+	csa = cs_addrs;
 	if (gv_cur_region->read_only)
 		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 	assert(0 != gv_target->root);
@@ -307,7 +298,7 @@ STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **
 			tmp_str, len, result);
 		if (PUT_SUCCESS != result)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			return result;
 		}
 	}
@@ -334,10 +325,10 @@ STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **
 		tmp_str, len, result);
 	if (PUT_SUCCESS != result)
 	{
-		RESTORE_TRIGGER_REGION_INFO;
+		RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		return result;
 	}
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return PUT_SUCCESS;
 }
 
@@ -346,16 +337,13 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 	sgmnt_addrs		*csa;
 	char			curr_name[MAX_MIDENT_LEN + 1];
 	uint4			curr_name_len, orig_name_len;
-	mstr			gbl_name;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree;
+	mname_entry		gvname;
 	int			len;
 	mval			mv_curr_nam;
 	boolean_t		name_found;
 	char			*ptr;
 	char			*name_tail_ptr;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	char			save_name[MAX_MIDENT_LEN + 1];
@@ -368,6 +356,7 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 	int			trig_indx;
 	int			badpos;
 	boolean_t		wildcard;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -387,7 +376,7 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 	/* $data(^#t) */
 	SWITCH_TO_DEFAULT_REGION;
 	if (gv_cur_region->read_only)
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	if (0 == gv_target->root)
 	{
@@ -406,7 +395,7 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 		BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), curr_name, curr_name_len);
 		if (gvcst_get(&trig_gbl))
 		{
-			SAVE_TRIGGER_REGION_INFO;
+			SAVE_TRIGGER_REGION_INFO(save_currkey);
 			ptr = trig_gbl.str.addr;
 			trigvn_len = STRLEN(trig_gbl.str.addr);
 			assert(MAX_MIDENT_LEN >= trigvn_len);
@@ -414,13 +403,15 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 			ptr += trigvn_len + 1;
 			/* the index is just beyon the length of the GVN string */
 			A2I(ptr, trig_gbl.str.addr + trig_gbl.str.len, trig_indx);
-			gbl_name.addr = trigvn;
-			gbl_name.len = trigvn_len;
-			GV_BIND_NAME_ONLY(gd_header, &gbl_name);
+			gvname.var_name.addr = trigvn;
+			gvname.var_name.len = trigvn_len;
+			COMPUTE_HASH_MNAME(&gvname);
+			GV_BIND_NAME_ONLY(gd_header, &gvname, gvnh_reg);
+			assert(cs_addrs == gv_target->gd_csa);
+			csa = cs_addrs;
 			if (gv_cur_region->read_only)
 				rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
-			csa = gv_target->gd_csa;
-			SETUP_TRIGGER_GLOBAL;
+			SET_GVTARGET_TO_HASHT_GBL(csa);
 			INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 			/* $get(^#t(GVN,"COUNT") */
 			BUILD_HASHT_SUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT));
@@ -453,7 +444,7 @@ boolean_t trigger_delete_name(char *trigger_name, uint4 trigger_name_len, uint4
 					util_out_print_gtmio("Deleted trigger named '!AD' for global ^!AD",
 							FLUSH, curr_name_len, curr_name, trigvn_len, trigvn);
 			}
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			name_found = TRUE;
 		} else
 		{ /* no names match, if !wildcard report an error */
@@ -493,8 +484,6 @@ int4 trigger_delete(char *trigvn, int trigvn_len, mval *trigger_count, int index
 	char			*ptr1;
 	int4			result;
 	int4			retval;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
 	stringkey		kill_hash, set_hash;
 	int			sub_indx;
 	char			tmp_trig_str[MAX_BUFF_SIZE];
@@ -702,17 +691,13 @@ void trigger_delete_all(void)
 	sgmnt_addrs		*csa;
 	mval			curr_gbl_name;
 	int			cycle;
-	mstr			gbl_name;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree, *gvt;
+	gv_namehead		*gvt;
 	mval			*mv_count_ptr;
 	mval			*mv_cycle_ptr;
 	mval			mv_indx;
 	gd_region		*reg;
 	int			reg_indx;
 	int4			result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -735,7 +720,7 @@ void trigger_delete_all(void)
 	}
 	SWITCH_TO_DEFAULT_REGION;
 	if (gv_cur_region->read_only)
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	if (0 != gv_target->root)
 	{
@@ -753,7 +738,7 @@ void trigger_delete_all(void)
 		gv_cur_region = reg;
 		change_reg();
 		csa = cs_addrs;
-		SETUP_TRIGGER_GLOBAL;
+		SET_GVTARGET_TO_HASHT_GBL(csa);
 		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 		/* There might not be any ^#t in this region, so check */
 		if (0 != gv_target->root)
diff --git a/sr_unix/trigger_fill_xecute_buffer.c b/sr_unix/trigger_fill_xecute_buffer.c
index 2981c28..2541dd5 100644
--- a/sr_unix/trigger_fill_xecute_buffer.c
+++ b/sr_unix/trigger_fill_xecute_buffer.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -23,7 +23,7 @@
 #include "mv_stent.h"			/* for COPY_SUBS_TO_GVCURRKEY macro */
 #include "gvsub2str.h"			/* for COPY_SUBS_TO_GVCURRKEY */
 #include "format_targ_key.h"		/* for COPY_SUBS_TO_GVCURRKEY */
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "filestruct.h"			/* for INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED (FILE_INFO) */
 #include "mvalconv.h"
 #include "gdscc.h"			/* needed for tp.h */
@@ -45,7 +45,6 @@
 
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	sgmnt_addrs		*cs_addrs;
-GBLREF	gd_addr			*gd_header;
 GBLREF	gv_key			*gv_currkey;
 GBLREF	gd_region		*gv_cur_region;
 GBLREF	sgm_info		*sgm_info_ptr;
@@ -67,7 +66,7 @@ STATICFNDCL void trigger_fill_xecute_buffer_read_trigger_source(gv_trigger_t *tr
 /* Similar condition handler to above without the tp-restart - just unwind and let caller do the restart */
 CONDITION_HANDLER(trigger_fill_xecute_buffer_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 		UNWIND(NULL, NULL);
@@ -108,24 +107,21 @@ int trigger_fill_xecute_buffer(gv_trigger_t *trigdsc)
 	 * weight but has a dependence on the restartability of the trigger-drive logic for getting the triggers reloaded as
 	 * necessary.
 	 */
-	if (0 < dollar_tlevel)
-	{
-		if (!tp_pointer->implicit_trigger		/* Case 2 */
-		    || (tp_pointer->implicit_tstart && tp_pointer->implicit_trigger
-			&& (tstart_trigger_depth != gtm_trigger_depth)))	/* Case 3 */
-		{	/* Test for Case 3/4 where we get to do very little: */
-			assert((!tp_pointer->implicit_trigger) || (0 < gtm_trigger_depth));
-			trigger_fill_xecute_buffer_read_trigger_source(trigdsc);
-		} else
-		{	/* Test for Case 1 where we only need a condition handler */
-			assert(tp_pointer->implicit_tstart && tp_pointer->implicit_trigger);
-			assert(tstart_trigger_depth == gtm_trigger_depth);
-			ESTABLISH_RET(trigger_fill_xecute_buffer_ch, SIGNAL);
-			trigger_fill_xecute_buffer_read_trigger_source(trigdsc);
-			REVERT;
-		}
+	assertpro(0 < dollar_tlevel);
+	if (!tp_pointer->implicit_trigger		/* Case 2 */
+		|| (tp_pointer->implicit_tstart && tp_pointer->implicit_trigger
+		&& (tstart_trigger_depth != gtm_trigger_depth)))	/* Case 3 */
+	{	/* Test for Case 3/4 where we get to do very little: */
+		assert((!tp_pointer->implicit_trigger) || (0 < gtm_trigger_depth));
+		trigger_fill_xecute_buffer_read_trigger_source(trigdsc);
 	} else
-		GTMASSERT;
+	{	/* Test for Case 1 where we only need a condition handler */
+		assert(tp_pointer->implicit_tstart && tp_pointer->implicit_trigger);
+		assert(tstart_trigger_depth == gtm_trigger_depth);
+		ESTABLISH_RET(trigger_fill_xecute_buffer_ch, SIGNAL);
+		trigger_fill_xecute_buffer_read_trigger_source(trigdsc);
+		REVERT;
+	}
 	/* return our bounty to caller */
 	trigdsc->xecute_str.mvtype = MV_STR;
 	return 0;	/* Could return ERR_TPRETRY if return is via our condition handler */
@@ -135,7 +131,6 @@ int trigger_fill_xecute_buffer(gv_trigger_t *trigdsc)
  */
 STATICFNDEF void trigger_fill_xecute_buffer_read_trigger_source(gv_trigger_t *trigdsc)
 {
-	mname_entry		gvent;
 	enum cdb_sc		cdb_status;
 	int4			index;
 	mstr			gbl, xecute_buff;
@@ -144,15 +139,14 @@ STATICFNDEF void trigger_fill_xecute_buffer_read_trigger_source(gv_trigger_t *tr
 	sgmnt_data_ptr_t	csd;
 	gvt_trigger_t		*gvt_trigger;
 	gv_namehead		*gvt;
-	gv_namehead		*hasht_tree, *save_gv_target;
-	gv_key			*save_gv_currkey;
+	gv_namehead		*save_gv_target;
 	gd_region		*save_gv_cur_region;
 	sgm_info		*save_sgm_info_ptr;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 
 	assert(0 < dollar_tlevel);
 	assert(NULL != trigdsc);
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 
 	gvt_trigger = trigdsc->gvt_trigger;			/* We now know our base block now */
 	index = trigdsc - gvt_trigger->gv_trig_array + 1;	/* We now know our trigger index value */
@@ -185,13 +179,13 @@ STATICFNDEF void trigger_fill_xecute_buffer_read_trigger_source(gv_trigger_t *tr
 		assert(IS_GTM_IMAGE);
 		t_retry(cdb_sc_triggermod);
 	}
-	SETUP_TRIGGER_GLOBAL;
+	SET_GVTARGET_TO_HASHT_GBL(csa);
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	assert(0 == trigdsc->xecute_str.str.len);	/* Make sure not replacing/losing a buffer */
 	xecute_buff.addr = trigger_gbl_fill_xecute_buffer(gbl.addr, gbl.len, &trig_index, NULL, (int4 *)&xecute_buff.len);
 	trigdsc->xecute_str.str = xecute_buff;
 	/* Restore gv_target/gv_currkey which need to be kept in sync */
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return;
 }
 #endif /* GTM_TRIGGER */
diff --git a/sr_unix/trigger_gbl_fill_xecute_buffer.c b/sr_unix/trigger_gbl_fill_xecute_buffer.c
index e24a335..b120082 100644
--- a/sr_unix/trigger_gbl_fill_xecute_buffer.c
+++ b/sr_unix/trigger_gbl_fill_xecute_buffer.c
@@ -57,7 +57,7 @@ STATICFNDCL CONDITION_HANDLER(trigger_gbl_fill_xecute_buffer_ch);
  */
 STATICFNDEF CONDITION_HANDLER(trigger_gbl_fill_xecute_buffer_ch)
 {
-	START_CH;
+	START_CH(TRUE);
 	if (!DUMPABLE && (NULL != xecute_buff))
 		free(xecute_buff);
 	NEXTCH;
diff --git a/sr_unix/trigger_read_name_entry.c b/sr_unix/trigger_read_name_entry.c
index 780a34a..be21fcc 100644
--- a/sr_unix/trigger_read_name_entry.c
+++ b/sr_unix/trigger_read_name_entry.c
@@ -24,7 +24,7 @@
 #include "mv_stent.h"			/* for COPY_SUBS_TO_GVCURRKEY macro */
 #include "gvsub2str.h"			/* for COPY_SUBS_TO_GVCURRKEY */
 #include "format_targ_key.h"		/* for COPY_SUBS_TO_GVCURRKEY */
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "gdscc.h"			/* needed for tp.h */
 #include "gdskill.h"			/* needed for tp.h */
 #include "buddy_list.h"			/* needed for tp.h */
@@ -34,7 +34,6 @@
 #include "tp.h"				/* for sgm_info */
 
 GBLREF	sgmnt_data_ptr_t	cs_data;
-GBLREF	gd_addr			*gd_header;
 GBLREF	gd_region		*gv_cur_region;
 GBLREF	gv_key			*gv_currkey;
 GBLREF	sgm_info		*sgm_info_ptr;
@@ -43,9 +42,7 @@ LITREF	mval			literal_hasht;
 
 boolean_t trigger_read_name_entry(mident *trig_name, mval *val)
 {
-	sgmnt_addrs		*csa;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -53,19 +50,17 @@ boolean_t trigger_read_name_entry(mident *trig_name, mval *val)
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	/* Trigger name should end with # -- so assert it */
-	assert(TRIGNAME_SEQ_DELIM == trig_name->addr[trig_name->len - 1]);
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	if (0 == gv_target->root)
 	{
-		RESTORE_TRIGGER_REGION_INFO;
+		RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		return FALSE;
 	}
 	BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trig_name->addr, trig_name->len - 1);
 	status = gvcst_get(val);
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return status;
 }
 #endif
diff --git a/sr_unix/trigger_select.c b/sr_unix/trigger_select.c
index b7cc1fa..4508ba8 100644
--- a/sr_unix/trigger_select.c
+++ b/sr_unix/trigger_select.c
@@ -53,6 +53,7 @@
 #include "gtmimagename.h"
 #include "gtmio.h"
 #include "have_crit.h"
+#include "hashtab_mname.h"
 
 GBLREF	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
@@ -200,7 +201,6 @@ STATICFNDEF void write_out_trigger(char *gbl_name, uint4 gbl_name_len, uint4 fil
 	char			out_rec[MAX_BUFF_SIZE];
 	char			*out_rec_ptr;
 	char			*ptr1, *ptr2;
-	mname_entry		gvent;
 	mval			mi, trigger_count, trigger_value;
 	mval			*mv_trig_cnt_ptr;
 	boolean_t		multi_line;
@@ -397,14 +397,11 @@ STATICFNDEF void write_gbls_or_names(char *gbl_name, uint4 gbl_name_len, uint4 f
 {
 	char			save_name[MAX_MIDENT_LEN], curr_name[MAX_MIDENT_LEN];
 	boolean_t		wildcard;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
-	gv_key			*save_gv_currkey;
-	gv_namehead		*hasht_tree, *save_gv_target;
+	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
-	sgmnt_addrs		*csa;
-	mname_entry		gvent;
-	mstr			ms_gbl_nam;
+	mname_entry		ms_gvname;
 	mval			mv_curr_nam;
         mval                    mi, trigger_count, trig_gbl;
         mval                    *mv_trig_cnt_ptr, mv_trigger_val;
@@ -412,6 +409,7 @@ STATICFNDEF void write_gbls_or_names(char *gbl_name, uint4 gbl_name_len, uint4 f
 	char			*ptr;
 	uint4			curr_name_len;
 	int			trigvn_len;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -452,12 +450,12 @@ STATICFNDEF void write_gbls_or_names(char *gbl_name, uint4 gbl_name_len, uint4 f
 			ptr += trigvn_len + 1;
 			A2I(ptr, mv_trigger_val.str.addr + mv_trigger_val.str.len, indx);
 			STR2MVAL(trig_gbl, mv_trigger_val.str.addr, trigvn_len);
-			SAVE_TRIGGER_REGION_INFO;
-			ms_gbl_nam.addr = mv_trigger_val.str.addr;
-			ms_gbl_nam.len = trigvn_len;
-			GV_BIND_NAME_ONLY(gd_header, &ms_gbl_nam);
-			csa = gv_target->gd_csa;
-			SETUP_TRIGGER_GLOBAL;
+			SAVE_TRIGGER_REGION_INFO(save_currkey);
+			ms_gvname.var_name.addr = mv_trigger_val.str.addr;
+			ms_gvname.var_name.len = trigvn_len;
+			COMPUTE_HASH_MNAME(&ms_gvname);
+			GV_BIND_NAME_ONLY(gd_header, &ms_gvname, gvnh_reg);
+			SET_GVTARGET_TO_HASHT_GBL(gv_target->gd_csa);
 			INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 		} else
 		{
@@ -467,7 +465,7 @@ STATICFNDEF void write_gbls_or_names(char *gbl_name, uint4 gbl_name_len, uint4 f
 		write_out_trigger(trig_gbl.str.addr, trig_gbl.str.len, file_name_len, op_val, indx);
 		if (trig_name)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		}
 		if (wildcard)
 		{
@@ -493,13 +491,7 @@ STATICFNDEF void dump_all_triggers(uint4 file_name_len, mval *op_val)
 {
 	mval			curr_gbl_name, val;
 	gd_region		*reg;
-	sgmnt_addrs		*csa;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree, *save_gvtarget;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
-	gv_key			*save_gv_altkey;
+	gv_namehead		*save_gvtarget;
 	unsigned char		*key;
 	mval			trigger_value;
 	int			reg_index;
@@ -517,8 +509,7 @@ STATICFNDEF void dump_all_triggers(uint4 file_name_len, mval *op_val)
 			gv_init_reg(reg);
 		gv_cur_region = reg;
 		change_reg();
-		csa = cs_addrs;
-		SETUP_TRIGGER_GLOBAL;
+		SET_GVTARGET_TO_HASHT_GBL(cs_addrs);
 		INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 		if (0 != gv_target->root)
 		{
@@ -546,16 +537,11 @@ boolean_t trigger_select(char *select_list, uint4 select_list_len, char *file_na
 {
 	char			*sel_ptr, *strtok_ptr, *prev_ptr, *ptr1, *ptr2;
 	int			gbl_len, prev_len;
-	mstr			gbl_name;
-	sgmnt_addrs		*csa;
-	gv_namehead		*hasht_tree, *save_gvtarget;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
-	gv_key			*save_gv_altkey;
+	mname_entry		gvname;
+	gv_namehead		*save_gvtarget;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	char			save_select_list[MAX_BUFF_SIZE];
-	mname_entry		gvent;
 	mval			trigger_value;
 	int			len, len1, badpos;
 	int			local_errno;
@@ -566,6 +552,7 @@ boolean_t trigger_select(char *select_list, uint4 select_list_len, char *file_na
 	mval			op_val, op_pars;
 	boolean_t		select_status;
 	io_pair			save_io_curr_device;
+	gvnh_reg_t		*gvnh_reg;
 
 	static readonly unsigned char	open_params_list[] =
 	{
@@ -661,21 +648,21 @@ boolean_t trigger_select(char *select_list, uint4 select_list_len, char *file_na
 						select_status, badpos);
 					continue;
 				}
-				SAVE_TRIGGER_REGION_INFO;
+				SAVE_TRIGGER_REGION_INFO(save_currkey);
 				gbl_len = NAM_LEN(sel_ptr + 1, (int)(ptr1 - sel_ptr) - 1);
 				ptr1 = sel_ptr + 1;
 				if ((prev_len != gbl_len) || (0 != memcmp(prev_ptr, ptr1, gbl_len)))
 				{
-					gbl_name.addr = ptr1;
-					gbl_name.len = gbl_len;
 					prev_ptr = ptr1;
 					prev_len = gbl_len;
-					GV_BIND_NAME_ONLY(gd_header, &gbl_name);
+					gvname.var_name.addr = ptr1;
+					gvname.var_name.len = gbl_len;
+					COMPUTE_HASH_MNAME(&gvname);
+					GV_BIND_NAME_ONLY(gd_header, &gvname, gvnh_reg);
 					if ('*' == *(ptr1 + gbl_len))
-						gbl_name.len++;
+						gvname.var_name.len++;
 				}
-				csa = gv_target->gd_csa;
-				SETUP_TRIGGER_GLOBAL;
+				SET_GVTARGET_TO_HASHT_GBL(gv_target->gd_csa);
 			} else
 			{
 				if (len1 != (badpos = validate_input_trigger_name(ptr1, len1, NULL))) /* assignment is intended */
@@ -687,15 +674,15 @@ boolean_t trigger_select(char *select_list, uint4 select_list_len, char *file_na
 				if (TRIGNAME_SEQ_DELIM == *(sel_ptr + (len1 - 1)))
 					/* drop the trailing # sign */
 					len1--;
-				gbl_name.addr = sel_ptr;
-				gbl_name.len = len1;
-				SAVE_TRIGGER_REGION_INFO;
+				gvname.var_name.addr = sel_ptr;
+				gvname.var_name.len = len1;
+				SAVE_TRIGGER_REGION_INFO(save_currkey);
 				SWITCH_TO_DEFAULT_REGION;
 			}
 			INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 			if (0 != gv_target->root)
-				write_gbls_or_names(gbl_name.addr, gbl_name.len, file_name_len, &op_val, trig_name);
-			RESTORE_TRIGGER_REGION_INFO;
+				write_gbls_or_names(gvname.var_name.addr, gvname.var_name.len, file_name_len, &op_val, trig_name);
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		} while (NULL != (sel_ptr = strtok_r(NULL, ",", &strtok_ptr)));	/* Embedded assignment is intended */
 	}
 	if (0 != file_name_len)
diff --git a/sr_unix/trigger_source_read_andor_verify.c b/sr_unix/trigger_source_read_andor_verify.c
index 102532e..e96ebb1 100644
--- a/sr_unix/trigger_source_read_andor_verify.c
+++ b/sr_unix/trigger_source_read_andor_verify.c
@@ -28,7 +28,7 @@
 #include "gvsub2str.h"			/* for COPY_SUBS_TO_GVCURRKEY */
 #include "format_targ_key.h"		/* for COPY_SUBS_TO_GVCURRKEY */
 #include "hashtab.h"			/* for STR_HASH (in COMPUTE_HASH_MNAME) */
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "filestruct.h"			/* for INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED (FILE_INFO) */
 #include "mvalconv.h"
 #include "gdscc.h"			/* needed for tp.h */
@@ -48,6 +48,7 @@
 #include "cdb_sc.h"
 #include "mv_stent.h"
 #include "gv_trigger_protos.h"
+#include "hashtab_mname.h"
 
 GBLREF	uint4			dollar_tlevel;
 GBLREF	sgmnt_addrs		*cs_addrs;
@@ -104,7 +105,7 @@ CONDITION_HANDLER(trigger_source_raov_ch)
 {
 	int	rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 		/* This only happens at the outer-most TP layer so state should be normal now */
@@ -150,13 +151,11 @@ CONDITION_HANDLER(trigger_source_raov_ch)
  */
 int trigger_source_read_andor_verify(mstr *trigname, trigger_action trigger_op)
 {
-	gv_key			*save_gv_currkey;
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
 	int			src_fetch_status;
-	sgmnt_addrs		*csa;	/* Used in SWITCH_TO_DEFAULT_REGION macro */
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	uint4			cycle;
 	DEBUG_ONLY(unsigned int	lcl_t_tries;)
 	enum cdb_sc		failure;
@@ -171,7 +170,7 @@ int trigger_source_read_andor_verify(mstr *trigname, trigger_action trigger_op)
 		gvinit();
 		SWITCH_TO_DEFAULT_REGION;
 	}
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	DBGTRIGR((stderr, "trigger_source_raov: Entered with trigger action %d\n", trigger_op));
 	/* First determination is if a TP fence is already in operation or not */
 	if (0 == dollar_tlevel)
@@ -204,7 +203,7 @@ int trigger_source_read_andor_verify(mstr *trigname, trigger_action trigger_op)
 				|| !gv_target || !gv_target->root);
 			assert((cdb_sc_onln_rlbk2 != failure) || TREF(dollar_zonlnrlbk));
 			if (cdb_sc_onln_rlbk2 == failure)
-				rts_error(VARLSTCNT(1) ERR_DBROLLEDBACK);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DBROLLEDBACK);
 			/* else if (cdb_sc_onln_rlbk1 == status) we don't need to do anything other than proceeding with the next
 			 * retry. Even though online rollback restart resets root block to zero for all gv_targets, ^#t root is
 			 * always established in gvtr_db_read_hasht (called below). We don't care about the root block being reset
@@ -216,7 +215,7 @@ int trigger_source_read_andor_verify(mstr *trigname, trigger_action trigger_op)
 		/* no return if TP restart */
 		src_fetch_status = trigger_source_raov(trigname, trigger_op);
 	assert((0 == src_fetch_status) || (TRIG_FAILURE_RC == src_fetch_status));
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return src_fetch_status;
 }
 
@@ -248,11 +247,10 @@ STATICFNDEF int trigger_source_raov_tpwrap_helper(mstr *trigname, trigger_action
  */
 STATICFNDEF int trigger_source_raov(mstr *trigname, trigger_action trigger_op)
 {
-	mname_entry		gvent;
-	sgmnt_addrs		*csa;
+	sgmnt_addrs		*csa=NULL;
 	sgmnt_data_ptr_t	csd;
 	rhdtyp			*rtn_vector;
-	gv_namehead		*gvt, *hasht_tree;
+	gv_namehead		*gvt;
 	gvt_trigger_t		*gvt_trigger;
 	mstr			gbl, xecute_buff;
 	int			index;
@@ -326,7 +324,7 @@ STATICFNDEF int trigger_source_raov(mstr *trigname, trigger_action trigger_op)
 			if (NULL == gvt_trigger)
 			{	/* No triggers were loaded for this region (all gone now) */
 				CLEAR_IMPLICIT_TP_BEFORE_ERROR;
-				rts_error(VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
 			}
 			gvt->db_trigger_cycle = cycle_start;
 			gvt->db_dztrigger_cycle = csa->db_dztrigger_cycle;
@@ -351,7 +349,7 @@ STATICFNDEF int trigger_source_raov(mstr *trigname, trigger_action trigger_op)
 			/* Else we need the trigger source loaded */
 			if (0 == ((gv_trigger_t *)rtn_vector->trigr_handle)->xecute_str.str.len)
 			{
-				SETUP_TRIGGER_GLOBAL;
+				SET_GVTARGET_TO_HASHT_GBL(csa);
 				INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 				assert(0 == trigdsc->xecute_str.str.len);	/* Make sure not replacing/losing a buffer */
 				i2mval(&trig_index, index);
@@ -373,7 +371,8 @@ STATICFNDEF int trigger_source_raov(mstr *trigname, trigger_action trigger_op)
 		if (0 != gtm_trigger_complink(trigdsc, TRUE))
 		{
 			PRN_ERROR;	/* Flush out any compiler messages for compile record */
-			rts_error(VARLSTCNT(4) ERR_TRIGCOMPFAIL, 2, trigdsc->rtn_desc.rt_name.len, trigdsc->rtn_desc.rt_name.addr);
+			rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGCOMPFAIL, 2,
+					trigdsc->rtn_desc.rt_name.len, trigdsc->rtn_desc.rt_name.addr);
 		}
 		assert(trigdsc->rtn_desc.rt_adr);
 		assert(trigdsc->rtn_desc.rt_adr == CURRENT_RHEAD_ADR(trigdsc->rtn_desc.rt_adr));
@@ -396,19 +395,20 @@ STATICFNDEF int trigger_source_raov(mstr *trigname, trigger_action trigger_op)
 /* Routine called when need triggers loaded for a given global */
 STATICFNDEF boolean_t trigger_source_raov_trigload(mstr *trigname, gv_trigger_t **ret_trigdsc)
 {
-	mname_entry		gvent;
 	mval			val;
 	char			*ptr;
 	int			len;
 	sgmnt_addrs		*csa;
 	sgmnt_data_ptr_t	csd;
-	gv_namehead		*gvt, *hasht_tree;
+	gv_namehead		*gvt;
 	gvt_trigger_t		*gvt_trigger;
-	mstr			gbl, xecute_buff;
+	mstr			xecute_buff;
+	mname_entry		gvname;
 	int			index;
 	mval			trig_index;
 	gv_trigger_t		*trigdsc;
 	uint4			cycle_start;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -418,7 +418,7 @@ STATICFNDEF boolean_t trigger_source_raov_trigload(mstr *trigname, gv_trigger_t
 		if (!TREF(in_op_fntext))
 		{
 			CLEAR_IMPLICIT_TP_BEFORE_ERROR;
-			rts_error(VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
 		}
 		return TRIG_FAILURE;
 	}
@@ -429,9 +429,10 @@ STATICFNDEF boolean_t trigger_source_raov_trigload(mstr *trigname, gv_trigger_t
 	assert(('\0' == *ptr) && (val.str.len > len));
 	ptr++;
 	A2I(ptr, val.str.addr + val.str.len, index);
-	gbl.addr = val.str.addr;
-	gbl.len = len;
-	GV_BIND_NAME_ONLY(gd_header, &gbl);	/* does tp_set_sgm() */
+	gvname.var_name.addr = val.str.addr;
+	gvname.var_name.len = len;
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_ONLY(gd_header, &gvname, gvnh_reg);	/* does tp_set_sgm() */
 	gvt = gv_target;
 	assert(cs_addrs == gvt->gd_csa);
 	csa = gvt->gd_csa;
@@ -444,19 +445,20 @@ STATICFNDEF boolean_t trigger_source_raov_trigload(mstr *trigname, gv_trigger_t
 	if (NULL == gvt_trigger)
 	{	/* No trigger were loaded for this region (all gone now) */
 		CLEAR_IMPLICIT_TP_BEFORE_ERROR;
-		rts_error(VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
+		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGNAMENF, 2, trigname->len, trigname->addr);
 	}
 	gvt->db_trigger_cycle = cycle_start;
 	gvt->db_dztrigger_cycle = csa->db_dztrigger_cycle;
 	gvt->trig_local_tn = local_tn;		/* Mark this trigger as being referenced in this transaction */
 	DBGTRIGR((stderr, "trigger_source_raov_trigload: gvt->db_trigger_cycle updated to %d\n",
 		  gvt->db_trigger_cycle));
-	SETUP_TRIGGER_GLOBAL;
+	SET_GVTARGET_TO_HASHT_GBL(csa);
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	trigdsc = &gvt_trigger->gv_trig_array[index - 1];
 	assert(0 == trigdsc->xecute_str.str.len);	/* Make sure not replacing/losing a buffer */
 	i2mval(&trig_index, index);
-	xecute_buff.addr = trigger_gbl_fill_xecute_buffer(gbl.addr, gbl.len, &trig_index, NULL, (int4 *)&xecute_buff.len);
+	xecute_buff.addr = trigger_gbl_fill_xecute_buffer(gvname.var_name.addr, gvname.var_name.len,
+								&trig_index, NULL, (int4 *)&xecute_buff.len);
 	trigdsc->xecute_str.str = xecute_buff;
 	*ret_trigdsc = trigdsc;
 	return TRIG_SUCCESS;
diff --git a/sr_unix/trigger_tpwrap_ch.c b/sr_unix/trigger_tpwrap_ch.c
index 5a43805..cebace9 100644
--- a/sr_unix/trigger_tpwrap_ch.c
+++ b/sr_unix/trigger_tpwrap_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -40,7 +40,7 @@ CONDITION_HANDLER(trigger_tpwrap_ch)
 {
 	int	rc;
 
-	START_CH;
+	START_CH(TRUE);
 	if ((int)ERR_TPRETRY == SIGNAL)
 	{
 		assert(TPRESTART_STATE_NORMAL == tprestart_state);
diff --git a/sr_unix/trigger_trgfile.c b/sr_unix/trigger_trgfile.c
index 2ef752d..071cc63 100644
--- a/sr_unix/trigger_trgfile.c
+++ b/sr_unix/trigger_trgfile.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2010, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2010, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -63,7 +63,6 @@ GBLREF	sgm_info		*first_sgm_info;
 GBLREF	bool			mupip_error_occurred;
 GBLREF	gv_key			*gv_currkey;
 GBLREF	sgm_info		*sgm_info_ptr;
-GBLREF	gd_addr			*gd_header;
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	int			tprestart_state;
 GBLREF	io_pair			io_curr_device;
@@ -218,7 +217,7 @@ boolean_t trigger_trgfile_tpwrap(char *trigger_filename, uint4 trigger_filename_
 				|| !gv_target || !gv_target->root);
 			assert((cdb_sc_onln_rlbk2 != failure) || !IS_GTM_IMAGE || TREF(dollar_zonlnrlbk));
 			if (cdb_sc_onln_rlbk2 == failure)
-				rts_error(VARLSTCNT(1) ERR_DBROLLEDBACK);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DBROLLEDBACK);
 			/* else if (cdb_sc_onln_rlbk1 == status) we don't need to do anything other than trying again. Since this
 			 * is ^#t global, we don't need to GVCST_ROOT_SEARCH before continuing with the next restart because the
 			 * trigger load logic already takes care of doing INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED before doing the
@@ -230,10 +229,9 @@ boolean_t trigger_trgfile_tpwrap(char *trigger_filename, uint4 trigger_filename_
 			 * In the case of op_tcommit, we expect dollar_tlevel to be 0 and if so we break out of the loop.
 			 * In the tp_restart case, we expect a maximum of 4 tries/retries and much lesser usually.
 			 * Additionally we also want to avoid an infinite loop so limit the loop to what is considered
-			 * a huge iteration count and GTMASSERT if that is reached as it suggests an out-of-design situation.
+			 * a huge iteration count and assertpro if that is reached as it suggests an out-of-design situation.
 			 */
-			if (TPWRAP_HELPER_MAX_ATTEMPTS < loopcnt)
-				GTMASSERT;
+			assertpro(TPWRAP_HELPER_MAX_ATTEMPTS >= loopcnt);
 		}
 	} else
 	{
diff --git a/sr_unix/trigger_update.c b/sr_unix/trigger_update.c
index 3fe6b58..4ee82ab 100644
--- a/sr_unix/trigger_update.c
+++ b/sr_unix/trigger_update.c
@@ -34,7 +34,7 @@
 #include "mv_stent.h"			/* for COPY_SUBS_TO_GVCURRKEY macro */
 #include "gvsub2str.h"			/* for COPY_SUBS_TO_GVCURRKEY */
 #include "format_targ_key.h"		/* for COPY_SUBS_TO_GVCURRKEY */
-#include "targ_alloc.h"			/* for SETUP_TRIGGER_GLOBAL & SWITCH_TO_DEFAULT_REGION */
+#include "targ_alloc.h"			/* for SET_GVTARGET_TO_HASHT_GBL & SWITCH_TO_DEFAULT_REGION */
 #include "gdsblk.h"
 #include "gdscc.h"			/* needed for tp.h */
 #include "gdskill.h"			/* needed for tp.h */
@@ -55,6 +55,7 @@
 #include "tp_frame.h"
 #include "t_retry.h"
 #include "gtmimagename.h"
+#include "hashtab_mname.h"
 
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF	sgm_info		*first_sgm_info;
@@ -81,6 +82,7 @@ error_def(ERR_TPRETRY);
 error_def(ERR_TRIGDEFBAD);
 error_def(ERR_TRIGMODINTP);
 error_def(ERR_TRIGMODREGNOTRW);
+error_def(ERR_TRIGNOSPANGBL);
 
 LITREF	mval			gvtr_cmd_mval[GVTR_CMDTYPES];
 LITREF	int4			gvtr_cmd_mask[GVTR_CMDTYPES];
@@ -141,17 +143,20 @@ LITREF	char 			*trigger_subs[];
 								BITMAP |= gvtr_cmd_mask[GVTR_CMDTYPE_ZTRIGGER];	\
 								break;						\
 							default:						\
-							        GTMASSERT;					\
+								/* Parsing should have found invalid command */	\
+							        assertpro(FALSE && lcl_ptr[2]);			\
 								break;						\
 						}								\
 						break;								\
 					default:								\
-						GTMASSERT;	/* Parsing should have found invalid command */ \
+						/* Parsing should have found invalid command */			\
+						assertpro(FALSE && lcl_ptr[1]);					\
 						break;								\
 				}										\
 				break;										\
 			default:										\
-				GTMASSERT;	/* Parsing should have found invalid command */			\
+				/* Parsing should have found invalid command */					\
+				assertpro(FALSE && lcl_ptr[0]);							\
 				break;										\
 		}												\
 	} while (lcl_ptr = strtok_r(NULL, ",", &strtok_ptr));							\
@@ -207,12 +212,14 @@ LITREF	char 			*trigger_subs[];
 							BITMAP |= OPTIONS_NOI;					\
 							break;							\
 						default:							\
-							GTMASSERT;	/* Parsing should have found invalid command */ \
+							/* Parsing should have found invalid command */		\
+							assertpro(FALSE && lcl_ptr[2]);				\
 							break;							\
 					}									\
 					break;									\
 				default:									\
-					GTMASSERT;	/* Parsing should have found invalid command */		\
+					/* Parsing should have found invalid command */				\
+					assertpro(FALSE && lcl_ptr[0]);						\
 					break;									\
 			}											\
 		} while (lcl_ptr = strtok_r(NULL, ",", &strtok_ptr));						\
@@ -400,9 +407,7 @@ STATICFNDEF int4 update_trigger_name(char *trigvn, int trigvn_len, int trigger_i
 
 STATICFNDEF boolean_t check_unique_trigger_name(char *trigvn, int trigvn_len, char *trigger_name, uint4 trigger_name_len)
 {
-	sgmnt_addrs		*csa;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -411,29 +416,29 @@ STATICFNDEF boolean_t check_unique_trigger_name(char *trigvn, int trigvn_len, ch
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
+	DEBUG_ONLY(if (WBTEST_HELPOUT_TRIGNAMEUNIQ == gtm_white_box_test_case_number) return TRUE;)
 	/* We only check user supplied names for uniqueness (since autogenerated names are unique). */
 	if (0 == trigger_name_len)
 		return TRUE;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	if (0 == gv_target->root)
 	{
-		RESTORE_TRIGGER_REGION_INFO;
+		RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		return TRUE;
 	}
 	assert((MAX_HASH_INDEX_LEN + 1 + MAX_DIGITS_IN_INT) > gv_cur_region->max_rec_size);
 	/* $get(^#t("#TNAME",trigger_name) */
 	BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trigger_name, trigger_name_len);
 	status = !gvcst_get(&val);
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return status;
 }
 
 STATICFNDEF int4 add_trigger_hash_entry(char *trigvn, int trigvn_len, char *cmd_value, int trigindx, boolean_t add_kill_hash,
 		stringkey *kill_hash, stringkey *set_hash)
 {
-	sgmnt_addrs		*csa;
 	int			hash_indx;
 	char			indx_str[MAX_DIGITS_IN_INT];
 	uint4			len;
@@ -443,8 +448,7 @@ STATICFNDEF int4 add_trigger_hash_entry(char *trigvn, int trigvn_len, char *cmd_
 	int			num_len;
 	char			*ptr;
 	int4			result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -452,10 +456,10 @@ STATICFNDEF int4 add_trigger_hash_entry(char *trigvn, int trigvn_len, char *cmd_
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	if (gv_cur_region->read_only)
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
  	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	set_cmp = (NULL != strchr(cmd_value, 'S'));
 	mv_indx_ptr = &mv_indx;
@@ -482,7 +486,7 @@ STATICFNDEF int4 add_trigger_hash_entry(char *trigvn, int trigvn_len, char *cmd_
 			name_and_index,	len, result);
 		if (PUT_SUCCESS != result)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			return result;
 		}
 	} else
@@ -502,12 +506,12 @@ STATICFNDEF int4 add_trigger_hash_entry(char *trigvn, int trigvn_len, char *cmd_
 			name_and_index,	len, result);
 		if (PUT_SUCCESS != result)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			return result;
 		}
 	} else
 		kill_hash->hash_code = 0;
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return PUT_SUCCESS;
 }
 
@@ -524,8 +528,7 @@ STATICFNDEF boolean_t trigger_already_exists(char *trigvn, int trigvn_len, char
 	boolean_t		kill_cmp, kill_found;
 	int			kill_indx;
 	boolean_t		name_match;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -538,20 +541,21 @@ STATICFNDEF boolean_t trigger_already_exists(char *trigvn, int trigvn_len, char
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	/* test with SET and/or KILL hash */
 	set_cmp = (NULL != strchr(values[CMD_SUB], 'S'));
 	kill_cmp = ((NULL != strchr(values[CMD_SUB], 'K')) || (NULL != strchr(values[CMD_SUB], 'R')));
 	set_found = kill_found = set_name_match = kill_name_match = FALSE;
+	csa = cs_addrs;
 	if (set_cmp)
 	{ /* test for SET hash match if SET command specified */
 		set_found = search_triggers(trigvn, trigvn_len, values, value_len, set_trigger_hash, &hash_indx, &set_indx, 0,
 				TRUE);
 		if (set_found)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			i2mval(&trigindx, set_indx);
 			BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigindx, trigger_subs[TRIGNAME_SUB],
 					STRLEN(trigger_subs[TRIGNAME_SUB]));
@@ -568,7 +572,7 @@ STATICFNDEF boolean_t trigger_already_exists(char *trigvn, int trigvn_len, char
 				FALSE);
 		if (kill_found)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			i2mval(&trigindx, kill_indx);
 			BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigindx, trigger_subs[CMD_SUB],
 							 STRLEN(trigger_subs[CMD_SUB]));
@@ -618,7 +622,7 @@ STATICFNDEF boolean_t trigger_already_exists(char *trigvn, int trigvn_len, char
 	 * components match or not.  If there is no set, then the name match is only based on the kill components.
 	 */
 	*full_match = (set_cmp) ? set_name_match : kill_name_match;
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return (set_found || kill_found);
 }
 
@@ -949,13 +953,11 @@ STATICFNDEF int4 modify_record(char *trigvn, int trigvn_len, char add_delete, in
 STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigger_count, char *user_trigname_str,
 				       uint4 user_trigname_len)
 {
-	sgmnt_addrs		*csa;
 	char			name_and_index[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT];
 	char			*ptr1;
 	int			rndm_int;
 	int			seq_num;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
+	gv_key			save_currkey[DBKEYALLOC(MAX_KEY_SZ)];
 	gd_region		*save_gv_cur_region;
 	gv_namehead		*save_gv_target;
 	sgm_info		*save_sgm_info_ptr;
@@ -982,10 +984,10 @@ STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigg
 		trigname_len = user_trigname_len;
 		strncpy(trig_name, user_trigname_str, user_trigname_len);
 	}
-	SAVE_TRIGGER_REGION_INFO;
+	SAVE_TRIGGER_REGION_INFO(save_currkey);
 	SWITCH_TO_DEFAULT_REGION;
 	if (gv_cur_region->read_only)
-		rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
+		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	if (0 == user_trigname_len)
 	{	/* autogenerated name */
@@ -998,7 +1000,7 @@ STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigg
 			seq_num = gvcst_get(val_ptr) ? mval2i(val_ptr) + 1 : 1;
 			if (MAX_TRIGNAME_SEQ_NUM < seq_num)
 			{
-				RESTORE_TRIGGER_REGION_INFO;
+				RESTORE_TRIGGER_REGION_INFO(save_currkey);
 				return TOO_MANY_TRIGGERS;
 			}
 		}
@@ -1008,7 +1010,7 @@ STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigg
 			LITERAL_HASHSEQNUM, STRLEN(LITERAL_HASHSEQNUM), unique_seq_str, STRLEN(unique_seq_str), result);
 		if (PUT_SUCCESS != result)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			return result;
 		}
 		/* set ^#t("#TNAME",GVN,"#TNCOUNT")++ */
@@ -1020,7 +1022,7 @@ STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigg
 			LITERAL_HASHTNCOUNT, STRLEN(LITERAL_HASHTNCOUNT), val, result);
 		if (PUT_SUCCESS != result)
 		{
-			RESTORE_TRIGGER_REGION_INFO;
+			RESTORE_TRIGGER_REGION_INFO(save_currkey);
 			return result;
 		}
 	} else
@@ -1045,12 +1047,12 @@ STATICFNDEF int4 gen_trigname_sequence(char *trigvn, int trigvn_len, mval *trigg
 		name_and_index, trigvn_len + 1 + trigger_count->str.len, result);
 	if (PUT_SUCCESS != result)
 	{
-		RESTORE_TRIGGER_REGION_INFO;
+		RESTORE_TRIGGER_REGION_INFO(save_currkey);
 		return result;
 	}
 	*seq_ptr++ = TRIGNAME_SEQ_DELIM;
 	*seq_ptr = '\0';
-	RESTORE_TRIGGER_REGION_INFO;
+	RESTORE_TRIGGER_REGION_INFO(save_currkey);
 	return SEQ_SUCCESS;
 }
 
@@ -1063,9 +1065,7 @@ boolean_t trigger_update_rec(char *trigger_rec, uint4 len, boolean_t noprompt, u
 	boolean_t		cmd_modified;
 	char			db_trig_name[MAX_USER_TRIGNAME_LEN + 1];
 	boolean_t		full_match;
-	mstr			gbl_name, var_name;
-	mname_entry		gvent;
-	gv_namehead		*hasht_tree;
+	mname_entry		gvname;
 	boolean_t		kill_cmp;
 	int4			max_len;
 	boolean_t 		multi_line, multi_line_xecute;
@@ -1077,10 +1077,6 @@ boolean_t trigger_update_rec(char *trigger_rec, uint4 len, boolean_t noprompt, u
 	int4			rec_len;
 	int4			rec_num;
 	boolean_t		result;
-	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
-	gv_key			*save_gv_currkey;
-	gv_key			*save_gv_altkey;
 	gv_namehead		*save_gvtarget;
 	boolean_t		set_cmp;
 	boolean_t		skip_set_trigger;
@@ -1108,6 +1104,7 @@ boolean_t trigger_update_rec(char *trigger_rec, uint4 len, boolean_t noprompt, u
 	int4			max_xecute_size;
 	boolean_t		no_error;
 	boolean_t		newtrigger;
+	gvnh_reg_t		*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -1215,12 +1212,20 @@ boolean_t trigger_update_rec(char *trigger_rec, uint4 len, boolean_t noprompt, u
 		STR_HASH(values[XECUTE_SUB], value_len[XECUTE_SUB], kill_trigger_hash.hash_code, kill_trigger_hash.hash_code);
 		io_curr_device = io_save_device;
 	}
-	gbl_name.addr = trigvn;
-	gbl_name.len = trigvn_len;
-	GV_BIND_NAME_ONLY(gd_header, &gbl_name);
+	gvname.var_name.addr = trigvn;
+	gvname.var_name.len = trigvn_len;
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_ONLY(gd_header, &gvname, gvnh_reg);
+	/* Trigger updates are not currently supported for globals spanning multiple regions */
+	if (NULL != gvnh_reg->gvspan)
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TRIGNOSPANGBL, 2, trigvn_len, trigvn);
+	/* Now that we know this is not a spanning global, there is no need to do a GV_BIND_SUBSNAME* macro call.
+	 * gv_cur_region/gv_target already point to the correct region.
+	 */
 	if (gv_cur_region->read_only)
 		rts_error_csa(CSA_ARG(gv_target->gd_csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(gv_cur_region));
-	csa = gv_target->gd_csa;
+	assert(cs_addrs == gv_target->gd_csa);
+	csa = cs_addrs;
 	/* Now that the gv_target of the global the trigger refers to is setup, check if we are attempting to modify/delete a
 	 * trigger for a global that has already had a trigger fire in this transaction. For these single-region (at a time)
 	 * checks, we can do them all the time as they are cheap.
@@ -1237,7 +1242,7 @@ boolean_t trigger_update_rec(char *trigger_rec, uint4 len, boolean_t noprompt, u
 		 */
 		csa->db_dztrigger_cycle++;
 	}
-	SETUP_TRIGGER_GLOBAL;
+	SET_GVTARGET_TO_HASHT_GBL(csa);
 	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
 	new_name = check_unique_trigger_name(trigvn, trigvn_len, values[TRIGNAME_SUB], value_len[TRIGNAME_SUB]);
 	cmd_modified = skip_set_trigger = newtrigger = FALSE;
@@ -1661,10 +1666,9 @@ boolean_t trigger_update(char *trigger_rec, uint4 len)
 			 * In the case of op_tcommit, we expect dollar_tlevel to be 0 and if so we break out of the loop.
 			 * In the tp_restart case, we expect a maximum of 4 tries/retries and much lesser usually.
 			 * Additionally we also want to avoid an infinite loop so limit the loop to what is considered
-			 * a huge iteration count and GTMASSERT if that is reached as it suggests an out-of-design situation.
+			 * a huge iteration count and assertpro if that is reached as it suggests an out-of-design situation.
 			 */
-			if (TPWRAP_HELPER_MAX_ATTEMPTS < loopcnt)
-				GTMASSERT;
+			assertpro(TPWRAP_HELPER_MAX_ATTEMPTS >= loopcnt);
 		}
 	} else
 	{
diff --git a/sr_unix/ttt.txt b/sr_unix/ttt.txt
index 41ec42a..1dfd69c 100644
--- a/sr_unix/ttt.txt
+++ b/sr_unix/ttt.txt
@@ -510,7 +510,8 @@ OC_GETTRUTH:	movab	val.0,r1
 		jsb	xfer.xf_gettruth
 OC_GVDATA:	pushab	val.0
 		calls	#1,xfer.xf_gvdata
-OC_GVEXTNAM:	irepab	val.2
+OC_GVEXTNAM:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvextnam
 OC_GVGET:	pushab	val.0
 		calls	#1,xfer.xf_gvget
@@ -518,9 +519,11 @@ OC_GVINCR:	pushab	val.0		; result of $INCR
 		pushab	val.2		; r->operand[1] = increment (global-variable to increment is gv_currkey so no operand[0])
 		calls	#2,xfer.xf_gvincr
 OC_GVKILL:	calls	#0,xfer.xf_gvkill
-OC_GVNAKED:	irepab	val.2
+OC_GVNAKED:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvnaked
-OC_GVNAME:	irepab	val.2
+OC_GVNAME:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvname
 OC_GVNEXT:	pushab	val.0
 		calls	#1,xfer.xf_gvnext
@@ -734,8 +737,8 @@ OC_NEWINTRINSIC:  pushl	val.1
 		jsb	xfer.xf_newintrinsic
 OC_NEWVAR:	pushl	val.1
 		jsb	xfer.xf_newvar
-OC_NULLEXP:	pushab	val.0
-		calls	#1,xfer.xf_nullexp
+OC_NULLEXP:	calls	#0,xfer.xf_nullexp
+		movl    r0,addr.0
 OC_NUMCMP:	movab	val.1,r0
 		movab	val.2,r1
 		jsb	xfer.xf_numcmp
@@ -997,7 +1000,8 @@ OC_RFRSHLVN:	pushl	val.2
 		pushab	val.1
 		calls	#2,xfer.xf_rfrshlvn
 		movl	r0,addr.0
-OC_SAVGVN:	irepab	val.2
+OC_SAVGVN:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_savgvn
 OC_SAVLVN:	irepab	val.2
 		calls	val.1,xfer.xf_savlvn
diff --git a/sr_unix/util_exit_handler.c b/sr_unix/util_exit_handler.c
index 3f3f06a..c20ee63 100644
--- a/sr_unix/util_exit_handler.c
+++ b/sr_unix/util_exit_handler.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -43,7 +43,7 @@ void util_exit_handler()
 	if (exit_handler_active)	/* Don't recurse if exit handler exited */
 		return;
 	exit_handler_active = TRUE;
-	SET_PROCESS_EXITING_TRUE;	/* set this BEFORE cancelling timers as wcs_phase2_commit_wait relies on this */
+	SET_PROCESS_EXITING_TRUE;	/* set this BEFORE canceling timers as wcs_phase2_commit_wait relies on this */
 	if (IS_DSE_IMAGE)
 	{	/* Need to clear csa->hold_onto_crit in case it was set */
 		for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
@@ -60,7 +60,7 @@ void util_exit_handler()
 			}
 		}
 	}
-	cancel_timer(0);		/* Cancel all timers - No unpleasant surprises */
+	CANCEL_TIMERS;		/* Cancel all unsafe timers - No unpleasant surprises */
 	secshr_db_clnup(NORMAL_TERMINATION);
 	assert(!dollar_tlevel);	/* MUPIP and GT.M are the only ones which can run TP and they have their own exit handlers.
 				 * So no need to run op_trollback here like mupip_exit_handler and gtm_exit_handler. */
diff --git a/sr_unix/versions.csh b/sr_unix/versions.csh
index 6f53ac2..8b319bd 100644
--- a/sr_unix/versions.csh
+++ b/sr_unix/versions.csh
@@ -20,7 +20,7 @@
 
 #	gtm_curpro is the current production version
 if (`uname -s` != "OS/390") then
-	setenv	gtm_curpro	"V60001"
+	setenv	gtm_curpro	"V60003"
 else
 	setenv	gtm_curpro	"V53004A"	# until newer version built on z/OS
 endif
diff --git a/sr_unix/wait_for_disk_space.c b/sr_unix/wait_for_disk_space.c
index 5a3b5de..18d5f10 100644
--- a/sr_unix/wait_for_disk_space.c
+++ b/sr_unix/wait_for_disk_space.c
@@ -27,7 +27,7 @@ GBLDEF	uint4			lseekwrite_target;
 #endif
 
 GBLREF	jnlpool_addrs		jnlpool;
-GBLREF	volatile int4		exit_state;
+GBLREF	int4			exit_state;
 GBLREF	int4			exi_condition;
 GBLREF	int4			forced_exit_err;
 
@@ -61,8 +61,7 @@ void wait_for_disk_space(sgmnt_addrs *csa, char *fn, int fd, off_t offset, char
 	/* If anticipatory freeze scheme is not in effect, or if this database does not care about it,
 	 * or DSKNOSPCAVAIL is not configured as a custom error, return right away.
 	 */
-	if (!ANTICIPATORY_FREEZE_ENABLED(csa) || (NULL == is_anticipatory_freeze_needed_fnptr)
-			|| !(*is_anticipatory_freeze_needed_fnptr)(csa, ERR_DSKNOSPCAVAIL))
+	if (!INST_FREEZE_ON_NOSPC_ENABLED(csa))
 		return;
 	fn_len = STRLEN(fn);
 	repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;
diff --git a/sr_unix/wcs_flu.c b/sr_unix/wcs_flu.c
index c106053..5d64af9 100644
--- a/sr_unix/wcs_flu.c
+++ b/sr_unix/wcs_flu.c
@@ -109,8 +109,9 @@ error_def(ERR_WRITERSTUCK);
 				 * a little over a minute) we wait for twice the time in the debug version.		\
 				 */											\
 				GET_C_STACK_MULTIPLE_PIDS("WRITERSTUCK", cnl->wtstart_pid, MAX_WTSTART_PID_SLOTS, 1);	\
-				assert((gtm_white_box_test_case_enabled) && 						\
-				(WBTEST_BUFOWNERSTUCK_STACK == gtm_white_box_test_case_number));			\
+				assert((gtm_white_box_test_case_enabled)						\
+					&& ((WBTEST_BUFOWNERSTUCK_STACK == gtm_white_box_test_case_number)		\
+						|| (WBTEST_SLEEP_IN_WCS_WTSTART == gtm_white_box_test_case_number)));	\
 				cnl->wcsflu_pid = 0;									\
 				SIGNAL_WRITERS_TO_RESUME(cnl);								\
 				if (!WAS_CRIT)										\
@@ -173,6 +174,7 @@ boolean_t wcs_flu(uint4 options)
 	cache_que_head_ptr_t	crq;
         struct shmid_ds         shm_buf;
 	uint4			fsync_dskaddr;
+	int4			rc;
 
 	jnl_status = 0;
 	flush_hdr = options & WCSFLU_FLUSH_HDR;
@@ -296,8 +298,12 @@ boolean_t wcs_flu(uint4 options)
 		if (WBTEST_ENABLED(WBTEST_WCS_FLU_FAIL)
 			|| ((csd->freeze || flush_msync) && (csa->ti->last_mm_sync != csa->ti->curr_tn)))
 		{
-			if (!(WBTEST_ENABLED(WBTEST_WCS_FLU_FAIL))
-				&& (0 == MSYNC((caddr_t)(MM_BASE_ADDR(csa)), (caddr_t)csa->db_addrs[1])))
+			#ifdef _AIX
+			GTM_DB_FSYNC(csa, udi->fd, rc);
+			#else
+			rc = MSYNC((caddr_t)(MM_BASE_ADDR(csa)), (caddr_t)csa->db_addrs[1]);
+			#endif
+			if (!(WBTEST_ENABLED(WBTEST_WCS_FLU_FAIL)) && (0 == rc))
 			{	/* Save when did last full sync */
 				csa->ti->last_mm_sync = csa->ti->curr_tn;
 			} else
@@ -472,7 +478,7 @@ boolean_t wcs_flu(uint4 options)
 					if (cnl->wcs_active_lvl || crq->fl)
 					{
 						REL_CRIT_BEFORE_RETURN;
-						GTMASSERT;
+						assertpro(FALSE);
 					}
 				}
 			}
@@ -504,7 +510,7 @@ boolean_t wcs_flu(uint4 options)
 				GET_C_STACK_MULTIPLE_PIDS("MAXJNLQIOLOCKWAIT", cnl->wtstart_pid, MAX_WTSTART_PID_SLOTS, 1);
 				assert(FALSE);
 				REL_CRIT_BEFORE_RETURN;
-				GTMASSERT;
+				assertpro(FALSE);
 			}
 			wcs_sleep(SLEEP_JNLQIOLOCKWAIT);	/* since it is a short lock, sleep the minimum */
 
diff --git a/sr_unix/wcs_wtstart.c b/sr_unix/wcs_wtstart.c
index 4074c15..ac60613 100644
--- a/sr_unix/wcs_wtstart.c
+++ b/sr_unix/wcs_wtstart.c
@@ -74,6 +74,37 @@
 
 #define DBIOERR_LOGGING_PERIOD			100
 
+#ifdef DEBUG
+GBLREF int4	exit_state;
+STATICDEF int	wcs_wtstart_count;
+
+/* White-box-test-activated macro to sleep in one of the predetermined places (based on the count variable)
+ * inside wcs_wtstart. The sleep allows for the delivery of an interrupt in a specific window of code.
+ */
+#  define SLEEP_ON_WBOX_COUNT(COUNT)								\
+{												\
+	if (WBTEST_ENABLED(WBTEST_SLEEP_IN_WCS_WTSTART)						\
+		&& (COUNT == (gtm_white_box_test_case_count % 100)))				\
+	{											\
+		if ((gtm_white_box_test_case_count / 100) == ++wcs_wtstart_count)		\
+		{	/* Resetting this allows us to avoid redundant sleeps while having the	\
+			 * white-box logic variables still enabled (to avoid asserts).		\
+			 */									\
+			gtm_white_box_test_case_count = 0;					\
+			DBGFPF((stderr, "WCS_WTSTART: STARTING SLEEP\n"));			\
+			while (TRUE)								\
+			{									\
+				SHORT_SLEEP(999);						\
+				if (0 < exit_state)						\
+					DBGFPF((stderr, "exit_state is %d\n", exit_state));	\
+			}									\
+		}										\
+	}											\
+}
+#else
+#  define SLEEP_ON_WBOX_COUNT(COUNT)
+#endif
+
 GBLREF	boolean_t	*lseekIoInProgress_flags;	/* needed for the LSEEK* macros in gtmio.h */
 GBLREF	uint4		process_id;
 GBLREF	sm_uc_ptr_t	reformat_buffer;
@@ -155,6 +186,10 @@ int4	wcs_wtstart(gd_region *region, int4 writes)
 		return err_status;			/* Already here, get out */
 	}
 	cnl = csa->nl;
+	/* Defer interrupts to protect against an inconsistent state caused by mismatch of such values as
+	 * cnl->intent_wtstart and cnl->in_wtstart.
+	 */
+	DEFER_INTERRUPTS(INTRPT_IN_WCS_WTSTART);
 	INCR_INTENT_WTSTART(cnl);	/* signal intent to enter wcs_wtstart */
 	/* the above interlocked instruction does the appropriate write memory barrier to publish this change to the world */
 	SHM_READ_MEMORY_BARRIER;	/* need to do this to ensure uptodate value of cnl->wc_blocked is read */
@@ -164,10 +199,16 @@ int4	wcs_wtstart(gd_region *region, int4 writes)
 		BG_TRACE_ANY(csa, wrt_blocked);
 		if (ANTICIPATORY_FREEZE_AVAILABLE)
 			POP_GV_CUR_REGION(sav_cur_region, sav_cs_addrs, sav_cs_data)
+		ENABLE_INTERRUPTS(INTRPT_IN_WCS_WTSTART);
 		return err_status;
 	}
+	SLEEP_ON_WBOX_COUNT(1);
 	csa->in_wtstart = TRUE;				/* Tell ourselves we're here and make the csa->in_wtstart (private copy) */
+	/* Ideally, we would like another SLEEP_ON_WBOX_COUNT here, but that could cause assert failures in concurrent wcs_wtstarts.
+	 * Because it is highly unlikely for an interrupt-deferred process to get killed at exactly this spot, do not test that.
+	 */
 	INCR_CNT(&cnl->in_wtstart, &cnl->wc_var_lock);	/* and cnl->in_wtstart (shared copy) assignments as close as possible.   */
+	SLEEP_ON_WBOX_COUNT(2);
 	SAVE_WTSTART_PID(cnl, process_id, index);
 	assert(cnl->in_wtstart > 0 && csa->in_wtstart);
 
@@ -198,7 +239,9 @@ int4	wcs_wtstart(gd_region *region, int4 writes)
 	assert(((sm_long_t)ahead & 7) == 0);
 	queue_empty = FALSE;
 	csa->wbuf_dqd++;			/* Tell rundown we have an orphaned block in case of interrupt */
+	SLEEP_ON_WBOX_COUNT(3);
 	was_crit = csa->now_crit;
+	SLEEP_ON_WBOX_COUNT(4);
 	for (n1 = n2 = 0, csrfirst = NULL; (n1 < max_ent) && (n2 < max_writes) && !cnl->wc_blocked; ++n1)
 	{	/* If not-crit, avoid REMQHI by peeking at the active queue and if it is found to have a 0 fl link, assume
 		 * there is nothing to flush and break out of the loop. This avoids unnecessary interlock usage (GTM-7635).
@@ -311,10 +354,7 @@ int4	wcs_wtstart(gd_region *region, int4 writes)
 				assert(((blk_hdr_ptr_t)bp)->bver);	/* GDSV4 (0) version uses this field as a block length so
 									   should always be > 0 */
 				if (IS_GDS_BLK_DOWNGRADE_NEEDED(csr->ondsk_blkver))
-				{	/* Need to downgrade/reformat this block back to a previous format. But, first defer timer
-					 * or external interrupts from using the reformat buffer while we are modifying it.
-					 */
-					DEFER_INTERRUPTS(INTRPT_IN_REFORMAT_BUFFER_USE);
+				{	/* Need to downgrade/reformat this block back to a previous format. */
 					assert(0 == reformat_buffer_in_use);
 					DEBUG_ONLY(reformat_buffer_in_use++;)
 					DEBUG_DYNGRD_ONLY(PRINTF("WCS_WTSTART: Block %d being dynamically downgraded on write\n", \
@@ -371,11 +411,8 @@ int4	wcs_wtstart(gd_region *region, int4 writes)
 				}
 				if ((blk_hdr_ptr_t)reformat_buffer == bp)
 				{
-					assert(INTRPT_OK_TO_INTERRUPT != intrpt_ok_state);
 					DEBUG_ONLY(reformat_buffer_in_use--;)
 					assert(0 == reformat_buffer_in_use);
-					/* allow interrupts now that we are done using the reformat buffer */
-					ENABLE_INTERRUPTS(INTRPT_IN_REFORMAT_BUFFER_USE);
 				}
 			}
 			/* Trigger I/O error if white box test case is turned on */
@@ -465,6 +502,7 @@ writes_completed:
 			BG_TRACE_ANY(csa, wrt_noblks_wrtn);
 		assert(cnl->in_wtstart > 0 && csa->in_wtstart);
 	)
+	SLEEP_ON_WBOX_COUNT(5);
 	if (csa->dbsync_timer && n1)
 	{	/* If we already have a dbsync timer active AND we found at least one dirty cache record in the active queue
 		 * now, this means there has not been enough time period of idleness since the last update and so there is
@@ -473,12 +511,15 @@ writes_completed:
 		 */
 		CANCEL_DBSYNC_TIMER(csa);
 	}
-	DECR_CNT(&cnl->in_wtstart, &cnl->wc_var_lock);
+	CAREFUL_DECR_CNT(cnl->in_wtstart, cnl->wc_var_lock);
+	/* Ideally, we would like another SLEEP_ON_WBOX_COUNT here, but that could cause assert failures in concurrent wcs_wtstarts.
+	 * Because it is highly unlikely for an interrupt-deferred process to get killed at exactly this spot, do not test that.
+	 */
 	CLEAR_WTSTART_PID(cnl, index);
-	/* Defer interrupts to protect the decrement of cnl->intent_wtstart and potential addition of a new dbsync timer */
-	DEFER_INTERRUPTS(INTRPT_IN_WCS_WTSTART);
 	csa->in_wtstart = FALSE;			/* This process can write again */
+	SLEEP_ON_WBOX_COUNT(6);
 	DECR_INTENT_WTSTART(cnl);
+	SLEEP_ON_WBOX_COUNT(7);
 	if (queue_empty)			/* Active queue has become empty. */
 		wcs_clean_dbsync_timer(csa);	/* Start a timer to flush-filehdr (and write epoch if before-imaging) */
 	ENABLE_INTERRUPTS(INTRPT_IN_WCS_WTSTART);
diff --git a/sr_unix/zshow_devices.c b/sr_unix/zshow_devices.c
index 987a9c1..bff8b5a 100644
--- a/sr_unix/zshow_devices.c
+++ b/sr_unix/zshow_devices.c
@@ -24,7 +24,6 @@
 #include "iottdef.h"
 #include "trmdef.h"
 #include "iormdef.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "zshow_params.h"
@@ -51,7 +50,7 @@ static readonly char	space_text[] = {' '};
 
 LITREF mstr		chset_names[];
 LITREF nametabent	dev_param_names[];
-LITREF unsigned char	dev_param_index[];
+LITREF uint4		dev_param_index[];
 LITREF zshow_index	zshow_param_index[];
 GBLREF bool		ctrlc_on;
 GBLREF io_log_name	*io_root_log_name;
@@ -133,6 +132,7 @@ void zshow_devices(zshow_out *output)
 			,"CREATED"
 		};
 	static readonly char morereadtime_text[] = "MOREREADTIME=";
+	char	*charptr;
 
 	v.mvtype = MV_STR;
 	for (l = io_root_log_name;  l != 0;  l = l->next)
@@ -287,7 +287,7 @@ void zshow_devices(zshow_out *output)
 								assert(gtm_utf8_mode);
 								break;
 							default:
-								GTMASSERT;
+								assertpro(l->iod->ichset != l->iod->ichset);
 						}
 						switch(l->iod->ochset)
 						{
@@ -303,7 +303,7 @@ void zshow_devices(zshow_out *output)
 								assert(gtm_utf8_mode);
 								break;
 							default:
-								GTMASSERT;
+								assertpro(l->iod->ochset != l->iod->ochset);
 						}
 						if (tt_ptr->mupintr)
 							ZS_STR_OUT(&v, interrupt_text);
@@ -415,7 +415,7 @@ void zshow_devices(zshow_out *output)
 								ZS_ONE_OUT(&v, space_text);
 								break;
 							default:
-								GTMASSERT;
+								assertpro(l->iod->ichset != l->iod->ichset);
 						}
 						switch(l->iod->ochset)
 						{
@@ -439,7 +439,7 @@ void zshow_devices(zshow_out *output)
 								ZS_ONE_OUT(&v, space_text);
 								break;
 							default:
-								GTMASSERT;
+								assertpro(l->iod->ochset != l->iod->ochset);
 						}
 #ifdef __MVS__
 						if (TAG_ASCII != l->iod->file_tag)
@@ -543,7 +543,7 @@ void zshow_devices(zshow_out *output)
 									ZS_ONE_OUT(&v, space_text);
 									break;
 								default:
-									GTMASSERT;
+									assertpro(l->iod->ichset != l->iod->ichset);
 							}
 							switch(l->iod->ochset)
 							{
@@ -567,7 +567,7 @@ void zshow_devices(zshow_out *output)
 									ZS_ONE_OUT(&v, space_text);
 									break;
 								default:
-									GTMASSERT;
+									assertpro(l->iod->ochset != l->iod->ochset);
 							}
 							/* socket type */
 							if (socketptr->passive)
@@ -588,7 +588,7 @@ void zshow_devices(zshow_out *output)
 							}
 							ZS_ONE_OUT(&v, space_text);
 							/* address + port */
-							if (socketptr->passive)
+							if ((socket_local != socketptr->protocol) && socketptr->passive)
 							{
 								ZS_STR_OUT(&v, port_text);
 								tmpport = (int)socketptr->local.port;
@@ -607,10 +607,13 @@ void zshow_devices(zshow_out *output)
 									v.str.len = 0;
 								}
 								zshow_output(output, &v.str);
-								ZS_ONE_OUT(&v, at_text);
-								tmpport = (int)socketptr->remote.port;
-								MV_FORCE_MVAL(&m, tmpport);
-								mval_write(output, &m, FALSE);
+								if (socket_local != socketptr->protocol)
+								{
+									ZS_ONE_OUT(&v, at_text);
+									tmpport = (int)socketptr->remote.port;
+									MV_FORCE_MVAL(&m, tmpport);
+									mval_write(output, &m, FALSE);
+								}
 								ZS_ONE_OUT(&v, space_text);
 								if (NULL != socketptr->local.saddr_ip)
 								{
@@ -622,6 +625,20 @@ void zshow_devices(zshow_out *output)
 									tmpport = (int)socketptr->local.port;
 									MV_FORCE_MVAL(&m, tmpport);
 									mval_write(output, &m, FALSE);
+								} else if (socket_local == socketptr->protocol)
+								{
+									ZS_STR_OUT(&v, local_text);
+									if (NULL != socketptr->local.sa)
+									{
+										charptr = ((struct sockaddr_un *)
+											(socketptr->local.sa))->sun_path;
+										ZS_VAR_STR_OUT(&v, charptr);
+									} else if (NULL != socketptr->remote.sa)
+									{ /* CONNECT shows remote path as LOCAL */
+										charptr = ((struct sockaddr_un *)
+											(socketptr->remote.sa))->sun_path;
+										ZS_VAR_STR_OUT(&v, charptr);
+									}
 								}
 							}
 							ZS_ONE_OUT(&v, space_text);
diff --git a/sr_unix_cm/gtcm_loop.c b/sr_unix_cm/gtcm_loop.c
index d21fc21..bfb0b16 100644
--- a/sr_unix_cm/gtcm_loop.c
+++ b/sr_unix_cm/gtcm_loop.c
@@ -96,6 +96,7 @@ void gtcm_loop(omi_conn_ll *cll)
 /*	Pay attention to the network visible end point */
 	if (INV_FD_P((nfds = cll->nve)))
 	    break;
+	assertpro(FD_SETSIZE > cll->nve);
 	FD_SET(cll->nve, &r_fds);
 	FD_SET(cll->nve, &e_fds);
 	if (psock >= 0)
@@ -103,6 +104,7 @@ void gtcm_loop(omi_conn_ll *cll)
 
 /*	We will service transactions from any existing connection */
 	for (cptr = cll->head; cptr; cptr = cptr->next) {
+	    assertpro(FD_SETSIZE > cptr->fd);
 	    FD_SET(cptr->fd, &r_fds);
 	    FD_SET(cptr->fd, &e_fds);
 	    if (cptr->fd > nfds)
diff --git a/sr_unix_cm/omi_dbms_ch.c b/sr_unix_cm/omi_dbms_ch.c
index d869217..1fbb6ed 100644
--- a/sr_unix_cm/omi_dbms_ch.c
+++ b/sr_unix_cm/omi_dbms_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,11 +31,7 @@ CONDITION_HANDLER(omi_dbms_ch)
     GBLREF int4	 omi_errno;
     int		dummy1, dummy2;
 
-    START_CH;
-
-    if (SEVERITY == SUCCESS || SEVERITY == INFO) {
-	CONTINUE;
-    }
+    START_CH(TRUE);
 
     PRN_ERROR;
     gtcm_rep_err("",SIGNAL);
@@ -46,5 +42,4 @@ CONDITION_HANDLER(omi_dbms_ch)
     }
 
     NEXTCH;
-
 }
diff --git a/sr_unix_cm/omi_gvextnam.c b/sr_unix_cm/omi_gvextnam.c
index e1f6c42..f5c2da3 100644
--- a/sr_unix_cm/omi_gvextnam.c
+++ b/sr_unix_cm/omi_gvextnam.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -35,6 +35,7 @@ static char rcsid[] = "$Header:$";
 #include "gbldirnam.h"
 #include "dpgbldir.h"
 #include "gvcst_protos.h"	/* for gvcst_root_search in GV_BIND_NAME_AND_ROOT_SEARCH macro */
+#include "hashtab_mname.h"
 
 GBLREF gv_key		*gv_currkey;
 GBLREF gd_region	*gv_cur_region;
@@ -44,12 +45,15 @@ int	omi_gvextnam (omi_conn *cptr, uns_short len, char *ref)
 {
 	bool		was_null, is_null;
 	mval		v;
+	mname_entry	gvname;
 	char		*ptr, *end, c[MAX_FBUFF + 1];
 	omi_li		li;
 	omi_si		si;
 	parse_blk	pblk;
 	int4		status;
 	gd_segment	*cur_seg, *last_seg;
+	gvnh_reg_t	*gvnh_reg;
+	gd_region	*reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -95,10 +99,13 @@ int	omi_gvextnam (omi_conn *cptr, uns_short len, char *ref)
 	si.value--;
 	if (ptr + si.value > end)
 		return -OMI_ER_PR_INVGLOBREF;
-	v.str.len   = si.value;
-	v.str.addr  = ptr;
 	gd_header   = cptr->ga;
-	GV_BIND_NAME_AND_ROOT_SEARCH(cptr->ga, &v.str);
+	gvname.var_name.len   = si.value;
+	gvname.var_name.addr  = ptr;
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	/* gv_cur_region will not be set in case gvnh_reg->gvspan is non-NULL. So use region from gvnh_reg */
+	reg = gvnh_reg->gd_reg;
 	ptr        += si.value;
 	/* Refine the gd_addr given these subscripts */
 	was_null = is_null  = FALSE;
@@ -112,13 +119,15 @@ int	omi_gvextnam (omi_conn *cptr, uns_short len, char *ref)
 		v.str.len  = si.value;
 		v.str.addr = ptr;
 		is_null    = (si.value == 0);
-		mval2subsc(&v, gv_currkey);
+		mval2subsc(&v, gv_currkey, reg->std_null_coll);
 		ptr       += si.value;
 	}
 	TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (except the last subscript)
 						in current key */
 	TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */
-	if (was_null  &&  NEVER == gv_cur_region->null_subs)
+	if (was_null && (NEVER == reg->null_subs))
 		return -OMI_ER_DB_INVGLOBREF;
+	/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH (e.g. setting gv_cur_region for spanning globals). */
+	GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey, reg);
 	return 0;
 }
diff --git a/sr_unix_cm/omi_prc_ordr.c b/sr_unix_cm/omi_prc_ordr.c
index 0589c09..5a3f669 100644
--- a/sr_unix_cm/omi_prc_ordr.c
+++ b/sr_unix_cm/omi_prc_ordr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,6 +34,7 @@ static char rcsid[] = "$Header:$";
 #include "stringpool.h"
 #include "op.h"
 #include "gvcst_protos.h"	/* for gvcst_root_search in GV_BIND_NAME_AND_ROOT_SEARCH macro */
+#include "hashtab_mname.h"
 
 GBLREF gv_namehead	*gv_target;
 GBLREF gv_key		*gv_currkey;
@@ -43,9 +44,11 @@ GBLREF bool		undef_inhibit;
 int omi_prc_ordr(omi_conn *cptr, char *xend, char *buff, char *bend)
 {
 	char		*bptr;
-	int			 rv;
-	omi_li		 len;
-	mval		 vo, vd, vg;
+	int		rv;
+	mname_entry	gvname;
+	omi_li		len;
+	mval		vo, vd, vg;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -95,9 +98,10 @@ int omi_prc_ordr(omi_conn *cptr, char *xend, char *buff, char *bend)
 					REVERT;
 					return -OMI_ER_PR_INVGLOBREF;
 				}
-				vo.str.addr++;	vo.str.len--;
-				GV_BIND_NAME_AND_ROOT_SEARCH(cptr->ga, &vo.str);
-				vo.str.addr--;	vo.str.len++;
+				gvname.var_name.addr = vo.str.addr + 1;
+				gvname.var_name.len = vo.str.len - 1;
+				COMPUTE_HASH_MNAME(&gvname);
+				GV_BIND_NAME_AND_ROOT_SEARCH(cptr->ga, &gvname, gvnh_reg);
 				TREF(gv_last_subsc_null) = FALSE;
 			} else
 			{
diff --git a/sr_unix_cm/rc_dbms_ch.c b/sr_unix_cm/rc_dbms_ch.c
index 6498bcf..69d9fc7 100644
--- a/sr_unix_cm/rc_dbms_ch.c
+++ b/sr_unix_cm/rc_dbms_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,11 +31,7 @@ CONDITION_HANDLER(rc_dbms_ch)
     GBLREF int4	 rc_errno;
     int		dummy1, dummy2;
 
-    START_CH;
-
-    if (SEVERITY == SUCCESS || SEVERITY == INFO) {
-	CONTINUE;
-    }
+    START_CH(TRUE);
 
     if (SEVERITY == WARNING || SEVERITY == ERROR) {
 	rc_errno = RC_GLOBERRUNSPEC;
@@ -44,5 +40,4 @@ CONDITION_HANDLER(rc_dbms_ch)
     }
 
     NEXTCH;
-
 }
diff --git a/sr_unix_cm/rc_fnd_file.c b/sr_unix_cm/rc_fnd_file.c
index 9d48307..cceedda 100644
--- a/sr_unix_cm/rc_fnd_file.c
+++ b/sr_unix_cm/rc_fnd_file.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -66,11 +66,14 @@ short rc_fnd_file(rc_xdsid *xdsid)
 	gv_namehead	*g;
 	short		dsid, node;
 	gd_binding	*map;
+	gd_addr		*addr;
 	char		buff[1024], *cp, *cp1;
 	mstr		fpath1, fpath2;
 	mval		v;
+	mname_entry	gvname;
 	int		i, keysize;
 	int             len, node2;
+	gvnh_reg_t	*gvnh_reg;
 
 	GET_SHORT(dsid, &xdsid->dsid.value);
 	GET_SHORT(node, &xdsid->node.value);
@@ -100,7 +103,7 @@ short rc_fnd_file(rc_xdsid *xdsid)
 		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
 		memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len);
 		gv_cur_region->dyn.addr->fname_len = fpath2.len;
-		gv_cur_region->dyn.addr->acc_meth = dba_bg;
+		REG_ACC_METH(gv_cur_region) = dba_bg;
 		ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS);
 		gvcst_init(gv_cur_region);
 		REVERT;
@@ -126,30 +129,19 @@ short rc_fnd_file(rc_xdsid *xdsid)
 			gv_cur_region = NULL;
 			return RC_FILEACCESS;
 		}
-		gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size);
-		GVKEY_INIT(gv_currkey, gv_keysize);
-		GVKEY_INIT(gv_altkey, gv_keysize);
+		GVKEYSIZE_INIT_IF_NEEDED;	/* sets up "gv_keysize", "gv_currkey" and "gv_altkey" in sync if not already done */
 		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1));
 		g = cs_addrs->dir_tree;
 		g->first_rec = (gv_key*)(g->clue.base + gv_keysize);
 		g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize);
 		g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize;
-		g->clue.prev = g->clue.end = 0;
+		/* No need to initialize g->clue.prev as it is never used */
+		g->clue.end = 0;
 		g->root = DIR_ROOT;
-		dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
-		dsid_list->gda->n_maps = 3;
-		dsid_list->gda->n_regions = 1;
-		dsid_list->gda->n_segments = 1;
-		dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr));
+		addr = dsid_list->gda = (gd_addr *)malloc(SIZEOF(gd_addr) + DUMMY_GBLDIR_TOT_MAP_SIZE);
+		memset(addr, 0, SIZEOF(gd_addr) + DUMMY_GBLDIR_TOT_MAP_SIZE);
+		DUMMY_GLD_MAP_INIT(addr, RELATIVE_OFFSET_FALSE, gv_cur_region);
 		dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size;
-		map = dsid_list->gda->maps;
-		map ++;
-		memset(map->name, 0, SIZEOF(map->name));
-		map->name[0] = '%';
-		map->reg.addr = gv_cur_region;
-		map++;
-		map->reg.addr = gv_cur_region;
-		memset(map->name, -1, SIZEOF(map->name));
 		dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
 		init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
 		change_reg();
@@ -169,22 +161,23 @@ short rc_fnd_file(rc_xdsid *xdsid)
 	{	/*	need to open new database, add to list, set fdi_ptr */
 		gd_header = dsid_list->gda;
 		gv_currkey->end = 0;
-		v.mvtype = MV_STR;
-		v.str.len = RC_NSPACE_GLOB_LEN-1;
-		v.str.addr = RC_NSPACE_GLOB;
-		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
+		gvname.var_name.len  = RC_NSPACE_GLOB_LEN - 1;
+		gvname.var_name.addr = RC_NSPACE_GLOB;
+		COMPUTE_HASH_MNAME(&gvname);
+		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+		assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
 		if (!gv_target->root)	/* No namespace global */
 			return RC_UNDEFNAMSPC;
 		v.mvtype = MV_STR;
 		v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1;
 		v.str.addr = RC_NSPACE_DSI_SUB;
-		mval2subsc(&v,gv_currkey);
+		mval2subsc(&v, gv_currkey, gv_cur_region->std_null_coll);
 		node2 = node;
 		MV_FORCE_MVAL(&v,node2);
-		mval2subsc(&v,gv_currkey);
+		mval2subsc(&v, gv_currkey, gv_cur_region->std_null_coll);
 		i = dsid / 256;
 		MV_FORCE_MVAL(&v,i);
-		mval2subsc(&v,gv_currkey);
+		mval2subsc(&v, gv_currkey, gv_cur_region->std_null_coll);
 		if (gvcst_get(&v))
 			return RC_UNDEFNAMSPC;
 		for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++)
@@ -207,7 +200,7 @@ short rc_fnd_file(rc_xdsid *xdsid)
 		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
 		memcpy(gv_cur_region->dyn.addr->fname, cp, len);
 		gv_cur_region->dyn.addr->fname_len = len;
-		gv_cur_region->dyn.addr->acc_meth = dba_bg;
+		REG_ACC_METH(gv_cur_region) = dba_bg;
 		ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS);
 		gvcst_init(gv_cur_region);
 		REVERT;
@@ -259,29 +252,20 @@ short rc_fnd_file(rc_xdsid *xdsid)
 			return RC_FILEACCESS;
 		}
 		rel_crit(gv_cur_region);
+		GVKEYSIZE_INIT_IF_NEEDED;
 		keysize = DBKEYSIZE(gv_cur_region->max_key_size);
-		GVKEYSIZE_INCREASE_IF_NEEDED(keysize);
 		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1));
 		g = cs_addrs->dir_tree;
 		g->first_rec = (gv_key*)(g->clue.base + keysize);
 		g->last_rec = (gv_key*)(g->first_rec->base + keysize);
 		g->clue.top = g->last_rec->top = g->first_rec->top = keysize;
-		g->clue.prev = g->clue.end = 0;
+		/* No need to initialize g->clue.prev as it is not currently used */
+		g->clue.end = 0;
 		g->root = DIR_ROOT;
-		fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
-		fdi_ptr->gda->n_maps = 3;
-		fdi_ptr->gda->n_regions = 1;
-		fdi_ptr->gda->n_segments = 1;
-		fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr));
+		addr = fdi_ptr->gda = (gd_addr *)malloc(SIZEOF(gd_addr) + DUMMY_GBLDIR_TOT_MAP_SIZE);
+		memset(addr, 0, SIZEOF(gd_addr) + DUMMY_GBLDIR_TOT_MAP_SIZE);
+		DUMMY_GLD_MAP_INIT(addr, RELATIVE_OFFSET_FALSE, gv_cur_region);
 		fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size;
-		map = fdi_ptr->gda->maps;
-		map ++;
-		memset(map->name, 0, SIZEOF(map->name));
-		map->name[0] = '%';
-		map->reg.addr = gv_cur_region;
-		map++;
-		map->reg.addr = gv_cur_region;
-		memset(map->name, -1, SIZEOF(map->name));
 		fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
 		init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
 		fdi_ptr->next = dsid_list->next;
@@ -310,7 +294,7 @@ short rc_fnd_file(rc_xdsid *xdsid)
 /* clean up from gvcst_init() failure, when dsid_list was NULL (open first db) */
 static CONDITION_HANDLER(rc_fnd_file_ch1)
 {	/* undo setup */
-	START_CH
+	START_CH(FALSE);
 	free(dsid_list->fname);
 	dsid_list = NULL;
 	free(gv_cur_region->dyn.addr);
@@ -323,7 +307,7 @@ static CONDITION_HANDLER(rc_fnd_file_ch1)
 /* clean up from gvcst_init() failure, when dsid_list was non-NULL (open new db) */
 static CONDITION_HANDLER(rc_fnd_file_ch2)
 {	/* undo setup */
-	START_CH
+	START_CH(FALSE);
 	free(fdi_ptr->fname);
 	fdi_ptr->fname = NULL;
 	free(fdi_ptr);
diff --git a/sr_unix_cm/rc_gbl_ord.c b/sr_unix_cm/rc_gbl_ord.c
index 684fe79..d98888f 100644
--- a/sr_unix_cm/rc_gbl_ord.c
+++ b/sr_unix_cm/rc_gbl_ord.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -27,6 +27,7 @@
 #include "t_begin.h"
 #include "t_retry.h"
 #include "t_end.h"
+#include "hashtab_mname.h"
 
 GBLREF int		rc_size_return;
 GBLREF gd_addr		*gd_header;
@@ -39,16 +40,17 @@ GBLDEF rc_oflow	*rc_overflow;
 GBLREF gd_region	*gv_cur_region;
 GBLREF trans_num	rc_read_stamp;
 
+error_def(ERR_GVGETFAIL);
 
 void rc_gbl_ord(rc_rsp_page *rsp)
 {
 	blk_hdr		*bp;
 	bool		found;
 	enum cdb_sc	status;
-	mstr		name;
+	mname_entry	gvname;
 	short		bsiz, size_return;
 	srch_blk_status	*bh;
-	error_def(ERR_GVGETFAIL);
+	gvnh_reg_t	*gvnh_reg;
 
 	for (;;)
 	{
@@ -62,9 +64,11 @@ void rc_gbl_ord(rc_rsp_page *rsp)
 			rsp->rstatus.value = 0;
 			return;
 		}
-		name.addr = (char *)&gv_altkey->base[0];
-		name.len = gv_altkey->end - 1;
-		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &name);
+		gvname.var_name.addr = (char *)&gv_altkey->base[0];
+		gvname.var_name.len = gv_altkey->end - 1;
+		COMPUTE_HASH_MNAME(&gvname);
+		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+		assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
 		if (gv_target->root != 0)
 		{
 			/* Look to see if key exists */
@@ -117,9 +121,7 @@ void rc_gbl_ord(rc_rsp_page *rsp)
 			if (found)
 				break;
 		}
-		*(&gv_currkey->base[0] + gv_currkey->end - 1) = 1;
-		*(&gv_currkey->base[0] + gv_currkey->end + 1) = 0;
-		gv_currkey->end += 1;
+		GVKEY_INCREMENT_ORDER(gv_currkey);
 	}
 	PUT_LONG(rsp->pageaddr, bh->blk_num);
 	rsp->frag_offset.value = 0;
diff --git a/sr_unix_cm/rc_mval2subsc.c b/sr_unix_cm/rc_mval2subsc.c
index d0f528d..c209963 100644
--- a/sr_unix_cm/rc_mval2subsc.c
+++ b/sr_unix_cm/rc_mval2subsc.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -56,7 +56,7 @@ static readonly unsigned char neg_code[100] =
 	0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65
 };
 
-unsigned char *mval2subsc(mval *v, gv_key *g)
+unsigned char *mval2subsc(mval *v, gv_key *g, boolean_t std_null_coll)
 {
         char            buf1[MAX_KEY_SZ + 1];
 	mstr		mstr_buf1;
@@ -90,7 +90,7 @@ unsigned char *mval2subsc(mval *v, gv_key *g)
 			s2n(v);
 			mvt = v->mvtype;
 			if (!(mvt & MV_NM))
-				rts_error(VARLSTCNT(1) ERR_NUMOFLOW);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NUMOFLOW);
 		}
 		else
 		{
@@ -116,7 +116,7 @@ unsigned char *mval2subsc(mval *v, gv_key *g)
 		{
 			if (0 == (end = format_targ_key(buff, MAX_ZWR_KEY_SZ, g, TRUE)))
 				end = &buff[MAX_ZWR_KEY_SZ - 1];
-			rts_error(VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
 		}
 		if (n > 0)
 		{
@@ -133,17 +133,15 @@ unsigned char *mval2subsc(mval *v, gv_key *g)
 						{
 							end = &buff[MAX_ZWR_KEY_SZ - 1];
 						}
-						rts_error(VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
+						rts_error_csa(CSA_ARG(NULL)
+							VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
 					}
 					ch++;	/* promote character */
 				}
 				*out_ptr++ = ch;
 			} while (--n > 0);
 		} else
-		{
-			*out_ptr++ = (!TREF(transform) || 0 == gv_cur_region->std_null_coll)
-				? STR_SUB_PREFIX : SUBSCRIPT_STDCOL_NULL;
-		}
+			*out_ptr++ = (0 == std_null_coll) ? STR_SUB_PREFIX : SUBSCRIPT_STDCOL_NULL;
 		goto ALLDONE;
 	}
 	/* Its a number, is it an integer? */
@@ -293,7 +291,7 @@ ALLDONE:
 	{	/* take of extra space and one for last zero */
 		if ((end = format_targ_key(buff, MAX_ZWR_KEY_SZ, g, TRUE)) == 0)
 			end = &buff[MAX_ZWR_KEY_SZ - 1];
-		rts_error(VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GVSUBOFLOW, 0, ERR_GVIS, 2, end - buff, buff);
 	}
 	return out_ptr;
 }
diff --git a/sr_unix_cm/rc_prc_getr.c b/sr_unix_cm/rc_prc_getr.c
index cfd45c6..225c81c 100644
--- a/sr_unix_cm/rc_prc_getr.c
+++ b/sr_unix_cm/rc_prc_getr.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -29,6 +29,7 @@
 #include "t_retry.h"
 #include "t_begin.h"
 #include "gvcst_protos.h"	/* for gvcst_search,gvcst_rtsib,gvcst_lftsib prototype */
+#include "hashtab_mname.h"
 
 GBLREF int		rc_size_return;
 GBLREF gd_addr		*gd_header;
@@ -48,7 +49,7 @@ int rc_prc_getr(rc_q_hdr *qhdr)
 	int		key_size, data_len, i;
 	bool		dollar_order, two_histories;
 	char		*cp2, *cp1;
-	mval		v;
+	mname_entry	gvname;
 	short		rsiz, bsiz, fmode, size_return;
 	rec_hdr		*rp;
 	blk_hdr		*bp;
@@ -57,6 +58,7 @@ int rc_prc_getr(rc_q_hdr *qhdr)
 	rc_req_getr	*req;
 	rc_rsp_page	*rsp;
 	srch_blk_status	*bh;
+	gvnh_reg_t	*gvnh_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -81,15 +83,14 @@ int rc_prc_getr(rc_q_hdr *qhdr)
 		REVERT;
 		return 0;
 	}
-	v.mvtype = MV_STR;
 	cp2 = req->key.key + req->key.len.value;
 	for (cp1 = req->key.key; *cp1 && cp1 < cp2; cp1++)
 		;
-	v.str.len = INTCAST(cp1 - req->key.key);
-	v.str.addr = req->key.key;
-	if (v.str.len > MAX_MIDENT_LEN)	/* GT.M does not support global variables > MAX_MIDENT_LEN chars */
+	gvname.var_name.len = INTCAST(cp1 - req->key.key);
+	gvname.var_name.addr = req->key.key;
+	if (gvname.var_name.len > MAX_MIDENT_LEN)	/* GT.M does not support global variables > MAX_MIDENT_LEN chars */
 	{
-		if (!(v.str.len == (MAX_MIDENT_LEN + 1) && v.str.addr[MAX_MIDENT_LEN] == 0x01))
+		if (!(gvname.var_name.len == (MAX_MIDENT_LEN + 1) && gvname.var_name.addr[MAX_MIDENT_LEN] == 0x01))
 		{
 		    qhdr->a.erc.value = RC_KEYTOOLONG;
 		    rsp->size_return.value = 0;
@@ -100,7 +101,9 @@ int rc_prc_getr(rc_q_hdr *qhdr)
 		    return -1;
 		}
 	}
-	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
 	memcpy(gv_currkey->base, req->key.key, req->key.len.value);
 	gv_currkey->end = req->key.len.value;
 	dollar_order = FALSE;
@@ -135,16 +138,15 @@ int rc_prc_getr(rc_q_hdr *qhdr)
 	{
 		if (TREF(gv_last_subsc_null))
 			gv_currkey->base[gv_currkey->prev] = 01;
-		else {
+		else
+		{
 			if (dollar_order)
-			{	gv_currkey->end++;
+			{
+				gv_currkey->end++;
 				gv_currkey->base[gv_currkey->end] = 0;
-			}else
+			} else
 			{
-				gv_currkey->base[gv_currkey->end] = 1;
-				gv_currkey->base[gv_currkey->end + 1] = 0;
-				gv_currkey->base[gv_currkey->end + 2] = 0;
-				gv_currkey->end += 2;
+				GVKEY_INCREMENT_QUERY(gv_currkey);
 			}
 		}
 	}
diff --git a/sr_unix_cm/rc_prc_kill.c b/sr_unix_cm/rc_prc_kill.c
index dd26958..4173985 100644
--- a/sr_unix_cm/rc_prc_kill.c
+++ b/sr_unix_cm/rc_prc_kill.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,6 +24,7 @@
 #include "error.h"
 #include "gtcm.h"
 #include "gvcst_protos.h"	/* for gvcst_kill prototype */
+#include "hashtab_mname.h"
 
 GBLREF gv_key 		*gv_currkey;
 GBLREF gv_namehead 	*gv_target;
@@ -32,14 +33,14 @@ GBLREF gd_addr		*gd_header;
 GBLREF int		gv_keysize;
 GBLREF sgmnt_data	*cs_data;
 
-int
-rc_prc_kill(rc_q_hdr *qhdr)
+int rc_prc_kill(rc_q_hdr *qhdr)
 {
     rc_kill	*req;
     rc_kill	*rsp;
     int		 i;
-    mval	v;
+    mname_entry	gvname;
     char	*cp1;
+    gvnh_reg_t	*gvnh_reg;
 
     ESTABLISH_RET(rc_dbms_ch, RC_SUCCESS);
     if ((qhdr->a.erc.value = rc_fnd_file(&qhdr->r.xdsid)) != RC_SUCCESS)
@@ -60,12 +61,11 @@ rc_prc_kill(rc_q_hdr *qhdr)
 #endif
 	return -1;
     }
-    v.mvtype = MV_STR;
     for (cp1 = req->key.key; *cp1; cp1++)
 	;
-    v.str.len = INTCAST(cp1 - req->key.key);
-    v.str.addr = req->key.key;
-	if (v.str.len > 8)	/* GT.M does not support global variables > 8 chars */
+    gvname.var_name.len = INTCAST(cp1 - req->key.key);
+    gvname.var_name.addr = req->key.key;
+	if (gvname.var_name.len > 8)	/* GT.M does not support global variables > 8 chars */
 	{	qhdr->a.erc.value = RC_KEYTOOLONG;
 		REVERT;
 #ifdef DEBUG
@@ -73,20 +73,20 @@ rc_prc_kill(rc_q_hdr *qhdr)
 #endif
 		return -1;
 	}
-	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
-    memcpy(gv_currkey->base, req->key.key, req->key.len.value);
-    gv_currkey->end = req->key.len.value;
-    gv_currkey->base[gv_currkey->end] = 0;
-    for (i = gv_currkey->end - 2; i > 0; i--)
-	if (!gv_currkey->base[i - 1])
-	    break;
-    gv_currkey->prev = i;
-
-    if (gv_target->root)
-	gvcst_kill(TRUE);
-
-    REVERT;
-    return 0;
-
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
+	memcpy(gv_currkey->base, req->key.key, req->key.len.value);
+	gv_currkey->end = req->key.len.value;
+	gv_currkey->base[gv_currkey->end] = 0;
+	for (i = gv_currkey->end - 2; i > 0; i--)
+	{
+		if (!gv_currkey->base[i - 1])
+			break;
+	}
+	gv_currkey->prev = i;
+	if (gv_target->root)
+	    gvcst_kill(TRUE);
+	REVERT;
+	return 0;
 }
-
diff --git a/sr_unix_cm/rc_prc_set.c b/sr_unix_cm/rc_prc_set.c
index 30fc354..d0ba028 100644
--- a/sr_unix_cm/rc_prc_set.c
+++ b/sr_unix_cm/rc_prc_set.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,6 +25,7 @@
 #include "rc_oflow.h"
 #include "gtcm.h"
 #include "gvcst_protos.h"	/* for gvcst_put prototype */
+#include "hashtab_mname.h"	/* for COMPUTE_HASH_MNAME prototype */
 
 GBLREF rc_oflow	*rc_overflow;
 GBLREF gv_key 		*gv_currkey;
@@ -41,45 +42,42 @@ int rc_prc_set(rc_q_hdr *qhdr)
     short	len;
     int		 i;
     mval	 v;
+    mname_entry	gvname;
     char	*cp1;
+    gvnh_reg_t	*gvnh_reg;
 
     ESTABLISH_RET(rc_dbms_ch, RC_SUCCESS);
     if ((qhdr->a.erc.value = rc_fnd_file(&qhdr->r.xdsid)) != RC_SUCCESS)
     {
 	REVERT;
-#ifdef DEBUG
-	gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"rc_fnd_file.");
-#endif
+	DEBUG_ONLY(gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"rc_fnd_file.");)
 	return -1;
     }
-assert(rc_overflow->buff != 0);
+	assert(rc_overflow->buff != 0);
 
     rsp = req = (rc_set *)qhdr;
     if (req->key.len.value > cs_data->max_key_size)
     {
 	qhdr->a.erc.value = RC_KEYTOOLONG;
 	REVERT;
-#ifdef DEBUG
-	gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"RC_KEYTOOLONG.");
-#endif
+	DEBUG_ONLY(gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"RC_KEYTOOLONG.");)
 	return -1;
     }
-    v.mvtype = MV_STR;
     for (cp1 = req->key.key; *cp1; cp1++)
 	;
-    v.str.len = INTCAST(cp1 - req->key.key);
-    v.str.addr = req->key.key;
-	if (v.str.len > 8)	/* GT.M does not support global variables > 8 chars */
+    gvname.var_name.len = INTCAST(cp1 - req->key.key);
+    gvname.var_name.addr = req->key.key;
+	if (gvname.var_name.len > 8)	/* GT.M does not support global variables > 8 chars */
 	{	qhdr->a.erc.value = RC_KEYTOOLONG;
 		REVERT;
-#ifdef DEBUG
-	gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"RC_KEYTOOLONG.");
-#endif
+		DEBUG_ONLY(gtcm_cpktdmp((char *)qhdr,qhdr->a.len.value,"RC_KEYTOOLONG.");)
 		return -1;
 	}
-	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
     memcpy(gv_currkey->base, req->key.key, req->key.len.value);
-assert(rc_overflow->buff != 0);
+	assert(rc_overflow->buff != 0);
     gv_currkey->end = req->key.len.value;
     gv_currkey->base[gv_currkey->end] = 0;
     for (i = gv_currkey->end - 2; i > 0; i--)
@@ -88,9 +86,9 @@ assert(rc_overflow->buff != 0);
     gv_currkey->prev = i;
     data = (rc_swstr *)(req->key.key + req->key.len.value);
     GET_SHORT (len, &data->len.value);
+    v.mvtype = MV_STR;
     v.str.len = len;
     v.str.addr = data->str;
-    v.mvtype = MV_STR;
     if (gv_currkey->end + 1 + v.str.len + SIZEOF(rec_hdr) > gv_cur_region->max_rec_size)
     {
 	qhdr->a.erc.value = RC_KEYTOOLONG;
diff --git a/sr_unix_cm/rc_prc_setf.c b/sr_unix_cm/rc_prc_setf.c
index a3ef3fb..43c1116 100644
--- a/sr_unix_cm/rc_prc_setf.c
+++ b/sr_unix_cm/rc_prc_setf.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -24,6 +24,7 @@
 #include "error.h"
 #include "gtcm.h"
 #include "gvcst_protos.h"	/* for gvcst_put prototype */
+#include "hashtab_mname.h"	/* for COMPUTE_HASH_MNAME prototype */
 
 GBLREF gv_key 		*gv_currkey;
 GBLREF gv_namehead 	*gv_target;
@@ -38,6 +39,8 @@ int rc_prc_setf(rc_q_hdr *qhdr)
     char	*cp1;
     int		 i;
     mval	 v;
+    mname_entry	gvname;
+    gvnh_reg_t	*gvnh_reg;
 
     ESTABLISH_RET(rc_dbms_ch, RC_SUCCESS);
     if ((qhdr->a.erc.value = rc_fnd_file(&qhdr->r.xdsid)) != RC_SUCCESS)
@@ -62,7 +65,10 @@ int rc_prc_setf(rc_q_hdr *qhdr)
 #endif
 		return -1;
 	}
-	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
+	gvname.var_name = v.str;
+	COMPUTE_HASH_MNAME(&gvname);
+	GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+	assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
     memcpy(gv_currkey->base, req->key.key, req->key.len.value);
     gv_currkey->end = req->key.len.value;
     gv_currkey->base[gv_currkey->end] = 0;
diff --git a/sr_unix_gnp/cmi_close.c b/sr_unix_gnp/cmi_close.c
index 55ae35c..5a2b6b2 100644
--- a/sr_unix_gnp/cmi_close.c
+++ b/sr_unix_gnp/cmi_close.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -27,6 +27,7 @@ cmi_status_t cmi_close(struct CLB *lnk)
 	previous = QUEENT2CLB(qp, cqe);
 	remqt(&previous->cqe);
 	CLOSEFILE(lnk->mun, status);
+	assertpro(FD_SETSIZE > lnk->mun);
 	FD_CLR(lnk->mun, &tsk->rs);
 	FD_CLR(lnk->mun, &tsk->ws);
 	FD_CLR(lnk->mun, &tsk->es);
diff --git a/sr_unix_gnp/cmi_init.c b/sr_unix_gnp/cmi_init.c
index e41cadf..45956cd 100644
--- a/sr_unix_gnp/cmi_init.c
+++ b/sr_unix_gnp/cmi_init.c
@@ -124,6 +124,7 @@ cmi_status_t cmi_init(cmi_descriptor *tnd, unsigned char tnr,
 		SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc);
 		return status;
 	}
+	assertpro(FD_SETSIZE > ntd_root->listen_fd);
 	FD_SET(ntd_root->listen_fd, &ntd_root->rs);
 	FD_SET(ntd_root->listen_fd, &ntd_root->es);
 	ntd_root->err = err;
diff --git a/sr_unix_gnp/cmi_open.c b/sr_unix_gnp/cmi_open.c
index 355ebf4..2504271 100644
--- a/sr_unix_gnp/cmi_open.c
+++ b/sr_unix_gnp/cmi_open.c
@@ -17,7 +17,7 @@
 #include "gtm_netdb.h"
 #include "gtm_inet.h"
 #include "gtm_string.h"
-#include "iotcp_select.h"
+#include "gtm_select.h"
 
 #include "cmidef.h"
 #include "gtmio.h"
@@ -80,13 +80,14 @@ cmi_status_t cmi_open(struct CLB *lnk)
 		freeaddrinfo(ai_head);
 		return errno;
 	}
-	rval = connect(new_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+	rval = connect(new_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);		/* BYPASSOK(connect) */
 	if ((-1 == rval) && ((EINTR == errno) || (EINPROGRESS == errno)
 #if (defined(__osf__) && defined(__alpha)) || defined(__sun) || defined(__vms)
             || (EWOULDBLOCK == errno)
 #endif
 		))
 	{	/* connection attempt will continue so wait for completion */
+		assertpro(FD_SETSIZE > new_fd);
 		do
 		{
 			if ((EINTR == errno) && outofband && (jobinterrupt != outofband))
diff --git a/sr_unix_gnp/cmi_peer_info.c b/sr_unix_gnp/cmi_peer_info.c
index f48eaae..5bf0680 100644
--- a/sr_unix_gnp/cmi_peer_info.c
+++ b/sr_unix_gnp/cmi_peer_info.c
@@ -20,7 +20,6 @@
 #include "gtm_netdb.h"
 #include "gtm_socket.h"
 #include "gtm_stdio.h"
-#include "iotcpdef.h"
 #include "gtm_string.h"	/* for rts_error */
 
 /* return in a the char * the ASCII representation of a network address.
diff --git a/sr_unix_gnp/cmj_clb_async.c b/sr_unix_gnp/cmj_clb_async.c
index c8c8548..1460597 100644
--- a/sr_unix_gnp/cmj_clb_async.c
+++ b/sr_unix_gnp/cmj_clb_async.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,6 +21,7 @@ cmi_status_t cmj_clb_set_async(struct CLB *lnk)
 	cmi_status_t status = SS_NORMAL;
 
 	CMI_DPRINT(("in cmj_clb_set_async sta = %d\n", lnk->sta));
+	assertpro(FD_SETSIZE > lnk->mun);
 	switch (lnk->sta)
 	{
 	case CM_CLB_READ:
diff --git a/sr_unix_gnp/cmj_err.c b/sr_unix_gnp/cmj_err.c
index 21b70a6..fdfd6cc 100644
--- a/sr_unix_gnp/cmj_err.c
+++ b/sr_unix_gnp/cmj_err.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2004 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -22,6 +22,7 @@ void cmj_err(struct CLB *lnk, cmi_reason_t reason, cmi_status_t status)
 	lnk->deferred_event = TRUE;
 	lnk->deferred_reason = reason;
 	lnk->deferred_status = status;
+	assertpro(FD_SETSIZE > lnk->mun);
 	FD_CLR(lnk->mun, &tsk->rs);
 	FD_CLR(lnk->mun, &tsk->ws);
 	FD_CLR(lnk->mun, &tsk->es);
diff --git a/sr_unix_gnp/cmj_firstone.c b/sr_unix_gnp/cmj_firstone.c
index 3f2a784..0da0872 100644
--- a/sr_unix_gnp/cmj_firstone.c
+++ b/sr_unix_gnp/cmj_firstone.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,6 +20,7 @@ int cmj_firstone(fd_set *s, int n)
 {
 	int i;
 
+	assertpro(FD_SETSIZE >= n);
 	for (i = 0; i < n; i++) {
 		if (FD_ISSET(i, s)) {
 			FD_CLR(i, s);
diff --git a/sr_unix_gnp/cmj_incoming_call.c b/sr_unix_gnp/cmj_incoming_call.c
index 3213880..6a85d8c 100644
--- a/sr_unix_gnp/cmj_incoming_call.c
+++ b/sr_unix_gnp/cmj_incoming_call.c
@@ -65,6 +65,7 @@ void cmj_incoming_call(struct NTD *tsk)
 		lnk->peer_ai.ai_addrlen = sz;
 		insqh(&lnk->cqe, &tsk->cqh);
 		lnk->ntd = tsk;
+		assertpro(FD_SETSIZE > rval);
 		FD_SET(rval, &tsk->es);
 		/* setup for callback processing */
 		lnk->deferred_event = TRUE;
diff --git a/sr_unix_gnp/cmu_getclb.c b/sr_unix_gnp/cmu_getclb.c
index df020c3..aff4a53 100644
--- a/sr_unix_gnp/cmu_getclb.c
+++ b/sr_unix_gnp/cmu_getclb.c
@@ -15,7 +15,6 @@
 #include "eintr_wrappers.h"
 #include "gtm_netdb.h"
 #include "gtm_socket.h"
-#include "iotcpdef.h"
 
 GBLREF struct NTD *ntd_root;
 
diff --git a/sr_unix_gnp/gtcm_ch.c b/sr_unix_gnp/gtcm_ch.c
index db1a6e4..42b134e 100644
--- a/sr_unix_gnp/gtcm_ch.c
+++ b/sr_unix_gnp/gtcm_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -63,7 +63,7 @@ CONDITION_HANDLER(gtcm_ch)
 	char		time_str[CTIME_BEFORE_NL + 2], *time_ptr; /* for GET_CUR_TIME macro */
 	short		short_len;
 
-	START_CH;
+	START_CH(FALSE);
 	undef_inhibit = FALSE;	/* reset undef_inhibit to the default value in case it got reset temporarily and there was an error.
 				 * currently, only $INCREMENT temporarily resets this (in gtcmtr_increment.c)
 				 */
@@ -96,7 +96,7 @@ CONDITION_HANDLER(gtcm_ch)
 	{
 		memcpy(sevmsgbuf, TREF(util_outbuff_ptr), msglen);
 		util_out_print(NULL, OPER);	/* write msg to operator log */
-		gtm_putmsg_noflush(VARLSTCNT(4) ERR_SERVERERR, 2, msglen, sevmsgbuf);
+		gtm_putmsg_noflush_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SERVERERR, 2, msglen, sevmsgbuf);
 		msglen = (int)(TREF(util_outptr) - TREF(util_outbuff_ptr));
 	}
 	if (curr_entry)
diff --git a/sr_unix_nsb/obj_code.c b/sr_unix_nsb/obj_code.c
index 30d1c1c..9751ba7 100644
--- a/sr_unix_nsb/obj_code.c
+++ b/sr_unix_nsb/obj_code.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -35,6 +35,7 @@
 #include "cg_var.h"
 #include "gtm_string.h"
 #include "stringpool.h"
+#include "rtn_src_chksum.h"
 
 GBLREF boolean_t		run_time;
 GBLREF command_qualifier	cmd_qlf;
@@ -81,7 +82,7 @@ void	cg_lab (mlabel *l, int4 base);
  *
  */
 
-void	obj_code (uint4 src_lines, uint4 checksum)
+void	obj_code (uint4 src_lines, void *checksum_ctx)
 {
 	rhdtyp		rhead;
 	mline		*mlx, *mly;
@@ -111,7 +112,7 @@ void	obj_code (uint4 src_lines, uint4 checksum)
 	if (!(cmd_qlf.qlf & CQ_OBJECT))
 		return;
 	rhead.ptext_ptr = SIZEOF(rhead);
-	rhead.checksum = checksum;
+	set_rtnhdr_checksum(&rhead, (gtm_rtn_src_chksum_ctx *)checksum_ctx);
 	rhead.vartab_ptr = code_size;
 	rhead.vartab_len = mvmax;
 	code_size += mvmax * SIZEOF(var_tabent);
diff --git a/sr_unix_nsb/opcode_def.h b/sr_unix_nsb/opcode_def.h
index 2265270..4a6826b 100644
--- a/sr_unix_nsb/opcode_def.h
+++ b/sr_unix_nsb/opcode_def.h
@@ -222,7 +222,7 @@ OPCODE_DEF(OC_ZG1, (OCT_NULL))
 OPCODE_DEF(OC_NEWINTRINSIC, (OCT_NULL))
 OPCODE_DEF(OC_GVZWITHDRAW, (OCT_NULL))
 OPCODE_DEF(OC_LVZWITHDRAW, (OCT_NULL))
-OPCODE_DEF(OC_NULLEXP, (OCT_MVAL))
+OPCODE_DEF(OC_NULLEXP, (OCT_MVADDR | OCT_MVAL | OCT_EXPRLEAF))
 OPCODE_DEF(OC_EXFUNRET, (OCT_NULL))
 OPCODE_DEF(OC_FNLVNAME, (OCT_MVAL | OCT_EXPRLEAF))
 OPCODE_DEF(OC_LKEXTNAME, (OCT_NULL))
diff --git a/sr_unix_nsb/rtnhdr.h b/sr_unix_nsb/rtnhdr.h
index b341116..e8e65bf 100644
--- a/sr_unix_nsb/rtnhdr.h
+++ b/sr_unix_nsb/rtnhdr.h
@@ -11,6 +11,8 @@
 #ifndef RTNHDR_H_INCLUDED
 #define RTNHDR_H_INCLUDED
 
+#include "srcline.h"
+
 /* rtnhdr.h - routine header */
 
 /* There are several references to this structure from assembly language; these include:
@@ -93,6 +95,8 @@ typedef struct	rhead_struct
 #	ifdef GTM_TRIGGER
 	void_ptr_t	trigr_handle;		/* Type is void to avoid needing gv_trigger.h to define gv_trigger_t addr */
 #	endif
+	unsigned char	checksum_md5[16];	/* 16-byte MD5 checksum of routine source code */
+	routine_source	*source_code;		/* source code used by $TEXT */
 } rhdtyp;
 
 /* Routine table entry */
@@ -137,13 +141,16 @@ typedef struct
 #define NOVERIFY	FALSE
 
 int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig);
+void free_src_tbl(rhdtyp *rtn_vector);
 unsigned char *find_line_start(unsigned char *in_addr, rhdtyp *routine);
 int4 *find_line_addr(rhdtyp *routine, mstr *label, int4 offset, mident **lent_name);
 rhdtyp *find_rtn_hdr(mstr *name);
+boolean_t find_rtn_tabent(rtn_tabent **res, mstr *name);
 bool zlput_rname(rhdtyp *hdr);
 rhdtyp *make_dmode(void);
 void comp_lits(rhdtyp *rhead);
 rhdtyp  *op_rhdaddr(mval *name, rhdtyp *rhd);
+rhdtyp	*op_rhdaddr1(mval *name);
 lnr_tabent *op_labaddr(rhdtyp *routine, mval *label, int4 offset);
 void urx_resolve(rhdtyp *rtn, lab_tabent *lbl_tab, lab_tabent *lbl_top);
 char *rtnlaboff2entryref(char *entryref_buff, mident *rtn, mident *lab, int offset);
diff --git a/sr_unix_nsb/ttt.txt b/sr_unix_nsb/ttt.txt
index a9d35e6..a633269 100644
--- a/sr_unix_nsb/ttt.txt
+++ b/sr_unix_nsb/ttt.txt
@@ -474,7 +474,8 @@ OC_GETTRUTH:	movab	val.0,r1
 		jsb	xfer.xf_gettruth
 OC_GVDATA:	pushab	val.0
 		calls	#1,xfer.xf_gvdata
-OC_GVEXTNAM:	irepab	val.2
+OC_GVEXTNAM:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvextnam
 OC_GVGET:	pushab	val.0
 		calls	#1,xfer.xf_gvget
@@ -482,9 +483,11 @@ OC_GVINCR:	pushab	val.0		; result of $INCR
 		pushab	val.2		; r->operand[1] = increment (global-variable to increment is gv_currkey so no operand[0])
 		calls	#2,xfer.xf_gvincr
 OC_GVKILL:	calls	#0,xfer.xf_gvkill
-OC_GVNAKED:	irepab	val.2
+OC_GVNAKED:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvnaked
-OC_GVNAME:	irepab	val.2
+OC_GVNAME:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvname
 OC_GVNEXT:	pushab	val.0
 		calls	#1,xfer.xf_gvnext
@@ -685,8 +688,8 @@ OC_NEWINTRINSIC:  pushl	val.1
 		jsb	xfer.xf_newintrinsic
 OC_NEWVAR:	pushl	val.1
 		jsb	xfer.xf_newvar
-OC_NULLEXP:	pushab	val.0
-		calls	#1,xfer.xf_nullexp
+OC_NULLEXP:	calls	#0,xfer.xf_nullexp
+		movl    r0,addr.0
 OC_NUMCMP:	movab	val.1,r0
 		movab	val.2,r1
 		jsb	xfer.xf_numcmp
@@ -986,7 +989,8 @@ OC_RFRSHLVN:	pushl	val.2
 		pushab	val.1
 		calls	#2,xfer.xf_rfrshlvn
 		movl	r0,addr.0
-OC_SAVGVN:	irepab	val.2
+OC_SAVGVN:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_savgvn
 OC_SAVLVN:	irepab	val.2
 		calls	val.1,xfer.xf_savlvn
diff --git a/sr_vms_cm/gtcm_server.c b/sr_vms_cm/gtcm_server.c
index d4aeaa7..4edd131 100644
--- a/sr_vms_cm/gtcm_server.c
+++ b/sr_vms_cm/gtcm_server.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -114,7 +114,6 @@ gtcm_server()
 	uint4		status;
 	int		i, receive(), value;
 	mstr		name1, name2;
-	gd_addr		*get_next_gdr();
 	struct NTD	*cmu_ntdroot();
 	connection_struct *prev_curr_entry;
 	struct	dsc$descriptor_s	dprd;
@@ -141,7 +140,7 @@ gtcm_server()
 		MEMCPY_LIT(nbuff, "GTCMSVR");
 		node_name.dsc$w_length = SIZEOF("GTCMSVR") - 1;
 	} else
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	sys$setprn(&proc_name);
 	status = lib$get_foreign(&timout, 0, &outlen, 0);
 	if ((status & 1) && (6 > outlen))
@@ -185,7 +184,7 @@ gtcm_server()
 	{
 		licensed = TRUE;
 		if (days < 14)
-			rts_error(VARLSTCNT(1) ERR_WILLEXPIRE);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WILLEXPIRE);
 	} else
 	{
 		licensed = FALSE;
@@ -202,7 +201,7 @@ gtcm_server()
 	status = cmi_init(&node_name, 0, 0, gtcm_init_ast, gtcm_link_accept);
 	if (!(status & 1))
 	{
-		rts_error(VARLSTCNT(1) ((status ^ 3) | 4));
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ((status ^ 3) | 4));
 		sys$exit(status);
 	}
 	ntd_root = cmu_ntdroot();
@@ -225,9 +224,9 @@ gtcm_server()
 		assert(!lib$ast_in_prog());
 		status = sys$dclast(&gtcm_remove_from_action_queue, 0, 0);
 		if (SS$_NORMAL != status)
-			rts_error(VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0);
 		if (INTERLOCK_FAIL == curr_entry)
-			rts_error(VARLSTCNT(1) CMERR_CMINTQUE);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) CMERR_CMINTQUE);
 		if (EMPTY_QUEUE != curr_entry)
 		{
 			switch (*curr_entry->clb_ptr->mbf)
@@ -322,14 +321,15 @@ gtcm_server()
 				default:
 					reply = FALSE;
 					if (SS$_NORMAL == status)
-                                                rts_error(VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf);
+                                                rts_error_csa(CSA_ARG(NULL)
+							VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf);
 					break;
 			}
 			if (curr_entry)		/* curr_entry can be NULL if went through gtcmtr_terminate */
 			{
 				status = sys$gettim(&curr_entry->lastact[0]);
 				if (SS$_NORMAL != status)
-					rts_error(VARLSTCNT(1) status);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 				/* curr_entry is used by gtcm_mbxread_ast to determine if it needs to defer the interrupt message */
 				prev_curr_entry = curr_entry;
 				if (CM_WRITE == reply)
@@ -344,7 +344,7 @@ gtcm_server()
 					{  /* valid interrupt cancel msg, handle in gtcm_mbxread_ast */
 						status = sys$dclast(gtcm_int_unpack, prev_curr_entry, 0);
 						if (SS$_NORMAL != status)
-							rts_error(VARLSTCNT(1) status);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 					} else  if (CM_READ == reply)
 					{
 						prev_curr_entry->clb_ptr->ast = gtcm_read_ast;
diff --git a/sr_vvms/bin_load.c b/sr_vvms/bin_load.c
index cb9154c..297c434 100644
--- a/sr_vvms/bin_load.c
+++ b/sr_vvms/bin_load.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,6 +38,8 @@
 #include "mvalconv.h"
 #include "mu_gvis.h"
 #include "gtmmsg.h"
+#include "hashtab_mname.h"
+#include "min_max.h"
 
 #define 	CR 13
 #define 	LF 10
@@ -52,7 +54,6 @@ GBLREF bool		mupip_error_occurred;
 GBLREF spdesc 		stringpool;
 GBLREF gv_key		*gv_altkey;
 GBLREF gv_key		*gv_currkey;
-GBLREF gd_region	*gv_cur_region;
 GBLREF gd_addr		*gd_header;
 GBLREF int4		gv_keysize;
 GBLREF gv_namehead	*gv_target;
@@ -86,7 +87,6 @@ error_def(ERR_TEXT);
 
 void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 {
-
 	boolean_t	need_xlation, new_gvn;
 	char 		*buff, std_null_coll[BIN_HEADER_NUMSZ + 1];
 	coll_hdr	db_collhdr, extr_collhdr;
@@ -100,6 +100,9 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 	unsigned char	*btop, *cp1, *cp2, *end_buff, *gvkey_char_ptr, hdr_lvl ,*tmp_ptr, *tmp_key_ptr,
 			cmpc_str[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], dup_key_str[MAX_KEY_SZ + 1], src_buff[MAX_KEY_SZ + 1];
 	unsigned short	next_cmpc, rec_len;
+	mname_entry	gvname;
+	gvnh_reg_t	*gvnh_reg;
+	gd_region	*dummy_reg;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -110,9 +113,9 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 	rec_count = 1;
 	status = sys$get(inrab);
 	if (RMS$_EOF == status)
-		rts_error(VARLSTCNT(1) ERR_PREMATEOF);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PREMATEOF);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	len = inrab->rab$w_rsz;
 	buff = inrab->rab$l_rbf;
 	while ((0 < len) && ((LF == buff[len - 1]) || (CR == buff[len - 1])))
@@ -123,7 +126,7 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
         if (0 != memcmp(buff, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || '2' > hdr_lvl
 	    || *(BIN_HEADER_VERSION) < hdr_lvl)
 	{				/* ignore the level check */
-		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_LDBINFMT);
 		return;
 	}
 	if ('3' < hdr_lvl)
@@ -133,8 +136,8 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 		extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10);
 		if (0 != extr_std_null_coll && 1!= extr_std_null_coll)
 		{
-                	rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"),
-				ERR_LDBINFMT);
+                	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5)
+				ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT);
 			return;
 		}
 	} else
@@ -195,18 +198,19 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 	{
 		status = sys$get(inrab);
 		if (RMS$_EOF == status)
-			rts_error(VARLSTCNT(1) ERR_PREMATEOF);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PREMATEOF);
 		if (!(status & 1))
-			rts_error(VARLSTCNT(1) status);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 		if (SIZEOF(coll_hdr) != inrab->rab$w_rsz)
                 {
-                        rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
+                        rts_error_csa(CSA_ARG(NULL)
+				VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
 			return;
                 }
 		extr_collhdr = *((coll_hdr *)(inrab->rab$l_rbf));
 		new_gvn = TRUE;
 	} else
-		gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
 	if (begin < 2)
 		begin = 2;
 	for ( ; rec_count < begin; )
@@ -215,11 +219,11 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 		if (RMS$_EOF == status)
 		{
 			sys$close(infab);
-			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_LOADEOF, 1, begin);
 			mupip_exit(ERR_MUNOACTION);
 		}
 		if (RMS$_NORMAL != status)
-			rts_error(VARLSTCNT(1) status);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 		if (SIZEOF(coll_hdr) == inrab->rab$w_rsz)
 		{
 			assert(hdr_lvl > '2');
@@ -239,6 +243,7 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 	other_rsz = 0;
 	assert(NULL == tmp_gvkey);	/* GVKEY_INIT macro relies on this */
 	GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* tmp_gvkey will point to malloced memory after this */
+	gvnh_reg = NULL;
 	for ( ; !mupip_DB_full; )
 	{
 		if (++rec_count > end)
@@ -303,15 +308,21 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 		v.str.len = cp1 - (unsigned char *)v.str.addr - 1;
 		if (hdr_lvl <= '2' || new_gvn)
 		{
-			GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
-			max_key = gv_cur_region->max_key_size;
+			gvname.var_name = v.str;
+			gvname.var_name.len = MIN(gvname.var_name.len, MAX_MIDENT_LEN);
+			COMPUTE_HASH_MNAME(&gvname);
+			GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &gvname, gvnh_reg);
+			/* "gv_cur_region" will be set at this point in case the global does NOT span regions.
+			 * For globals that do span regions, "gv_cur_region" will be set just before the call to op_gvput
+			 */
+			max_key = gvnh_reg->gd_reg->max_key_size;
 			db_collhdr.act = gv_target->act;
 			db_collhdr.ver = gv_target->ver;
 			db_collhdr.nct = gv_target->nct;
 		}
 		if ((0 != rp->cmpc) || (v.str.len > rp->rsiz) || mupip_error_occurred)
 		{
-			rts_error(VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
 			mu_gvis();
 			util_out_print(0, TRUE);
 			continue;
@@ -319,9 +330,8 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 		if (new_gvn)
 		{
 			global_key_count = 1;
-			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver ||
-				db_collhdr.nct != extr_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll))
-				/* do we need to bother about 'ver' change ??? */
+			if ((db_collhdr.act != extr_collhdr.act) || (db_collhdr.ver != extr_collhdr.ver)
+				|| (db_collhdr.nct != extr_collhdr.nct) || (gvnh_reg->gd_reg->std_null_coll != extr_std_null_coll))
 			{
 				if (extr_collhdr.act)
 				{
@@ -329,13 +339,13 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 					{
 						if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver))
 						{
-							rts_error(VARLSTCNT(8) ERR_COLLTYPVERSION, 2,
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_COLLTYPVERSION, 2,
 								extr_collhdr.act, extr_collhdr.ver,
 								ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
 						}
 					} else
 					{
-						rts_error(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
 							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
 					}
 				}
@@ -345,13 +355,13 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 					{
 						if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver))
 						{
-							rts_error(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act,
-								db_collhdr.ver,
+							rts_error_csa(CSA_ARG(NULL)
+								VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver,
 								ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
 						}
 					} else
 					{
-						rts_error(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
 							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
 					}
 				}
@@ -371,7 +381,7 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 			}
 			if (rec_len + (unsigned char *)rp > btop)
 			{
-				rts_error(VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
 				mu_gvis();
 				util_out_print(0, TRUE);
 				break;
@@ -388,7 +398,7 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 				if ((cp1 > ((unsigned char *)rp + rec_len)) ||
 				    (cp2 > ((unsigned char *)gv_currkey + gv_currkey->top)))
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
 					mu_gvis();
 					util_out_print(0, TRUE);
 					break;
@@ -411,8 +421,8 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 				} else
 					next_cmpc = 0;
 				assert(hdr_lvl >= '3');
-				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
-				 	extr_std_null_coll != gv_cur_region->std_null_coll);
+				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct
+						|| (extr_std_null_coll != gvnh_reg->gd_reg->std_null_coll));
 							/* the length of the key might change (due to nct variation),
 							 * so get a copy of the original key from the extract */
 				memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1);
@@ -449,7 +459,7 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 					tmp_gvkey->end = 0;
 					if (extr_collseq)
 						gv_target->collseq = save_gv_target_collseq;
-					mval2subsc(&tmp_mval, tmp_gvkey);
+					mval2subsc(&tmp_mval, tmp_gvkey, gvnh_reg->gd_reg->std_null_coll);
 					/* we now have the correctly transformed subscript */
 					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
 					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
@@ -457,20 +467,10 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 					gv_currkey->end += tmp_gvkey->end;
 					gvkey_char_ptr++;
 				}
-				if ((gv_cur_region->std_null_coll != extr_std_null_coll) && gv_currkey->prev)
-				{
-					if (extr_std_null_coll == 0)
-					{
-						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
-					} else
-					{
-						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
-					}
-				}
 			}
 			if (gv_currkey->end >= max_key)
 			{
-				rts_error(VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
 				mu_gvis();
 				util_out_print(0, TRUE);
 				continue;
@@ -479,12 +479,16 @@ void bin_load(uint4 begin, uint4 end, struct RAB *inrab, struct FAB *infab)
 			v.str.len = rec_len - (cp1 - (unsigned char *)rp);
 			if (max_data_len < v.str.len)
 				max_data_len = v.str.len;
+			/* The below macro finishes the task of GV_BIND_NAME_AND_ROOT_SEARCH
+			 * (e.g. setting gv_cur_region for spanning globals).
+			 */
+			GV_BIND_SUBSNAME_IF_GVSPAN(gvnh_reg, gd_header, gv_currkey, dummy_reg);
 			op_gvput(&v);
 			if (mupip_error_occurred)
 			{
 				if (!mupip_DB_full)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT, 2, rec_count, global_key_count);
 					util_out_print(0, TRUE);
 				}
 				break;
diff --git a/sr_vvms/buildaux.com b/sr_vvms/buildaux.com
index 1470215..95ac3e4 100644
--- a/sr_vvms/buildaux.com
+++ b/sr_vvms/buildaux.com
@@ -1,6 +1,6 @@
 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 $!								!
-$!	Copyright 2001, 2005 Fidelity Information Services, Inc	!
+$!	Copyright 2001, 2013 Fidelity Information Services, Inc	!
 $!								!
 $!	This source code contains the intellectual property	!
 $!	of its copyright holder(s), and is made available	!
@@ -153,17 +153,12 @@ $	xtra = "," + f$parse(f$search("gtm$src:gde*.msg"),,,"NAME")
 $	set noon
 $	search/nooutput gtm$src:gde.m patcode
 $	if $severity .eq. 1 then $ xtra = xtra + ",_patcode"
-$	define/user gdeobj 'objdir'mumps.olb
-$	define/user sys$error nl:
-$	define/user sys$output nl:
-$	gtm_library/extract=gdeoget/output=nl: 'objdir'mumps.olb
-$	if $severity .eq. 1 then $ xtra = xtra + ",gdeoget"
 $	set on
 $	gdedsf = ""
 $	if dsffiles then gdedsf = "/dsf=gde.dsf"
 $	define/user gdeobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'gde.map/full/exe='targdir'gde.exe'lnkopt' 'gdedsf' gdeobj/incl=(gde'xtra'),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt
+$	link/map='mapfile'gde.map/full/exe='targdir'gde.exe'lnkopt' 'gdedsf' gdeobj/incl=(gde'xtra'),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt  ! BYPASSOK
 gdeobj/incl=(_lclcol,gdeadd,gdechang,gdetempl,gdedelet,gdeexit,gdeget,gdemsgin)
 gdeobj/incl=(gdehelp,gdesetgd,gdeinit,gdelocks,gdelog,gdemap,gdeparse,gdeput,gdequit)
 gdeobj/incl=(gderenam,gdescan,gdeshow,gdespawn,gdeverif)
@@ -180,7 +175,7 @@ $	dsedsf = ""
 $	if dsffiles then dsedsf = "/dsf=dse.dsf"
 $	define/user dseobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'dse.map/full/cross/exe='targdir'dse.exe'lnkopt' 'dsedsf' dseobj/libr/incl=dse,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'dse.map/full/cross/exe='targdir'dse.exe'lnkopt' 'dsedsf' dseobj/libr/incl=dse,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = DSE.EXE
 $ endif
 $!
@@ -193,7 +188,7 @@ $	mupipdsf = ""
 $	if dsffiles then mupipdsf = "/dsf=mupip.dsf"
 $	define/user mupipobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'mupip.map/full/cross/exe='targdir'mupip.exe'lnkopt' 'mupipdsf' mupipobj/libr/incl=mupip,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'mupip.map/full/cross/exe='targdir'mupip.exe'lnkopt' 'mupipdsf' mupipobj/libr/incl=mupip,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = MUPIP.EXE
 $ endif
 $!
@@ -206,7 +201,7 @@ $	dbcertifydsf = ""
 $	if dsffiles then dbcertifydsf = "/dsf=dbcertify.dsf"
 $	define/user dbcertifyobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'dbcertify.map/full/cross/exe='targdir'dbcertify.exe'lnkopt' 'dbcertifydsf' dbcertifyobj/libr/incl=dbcertify,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'dbcertify.map/full/cross/exe='targdir'dbcertify.exe'lnkopt' 'dbcertifydsf' dbcertifyobj/libr/incl=dbcertify,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = DBCERTIFY.EXE
 $ endif
 $!
@@ -219,7 +214,7 @@ $	lkedsf = ""
 $	if dsffiles then lkedsf = "/dsf=lke.dsf"
 $	define/user lkeobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'lke.map/full/exe='targdir'lke.exe'lnkopt' 'lkedsf' lkeobj/libr/incl=lke,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'lke.map/full/exe='targdir'lke.exe'lnkopt' 'lkedsf' lkeobj/libr/incl=lke,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = LKE.EXE
 $ endif
 $!
@@ -233,7 +228,7 @@ $	then
 $		@gtm$tools:build_print_stage "Building LMU" "middle"
 $		define/user lmuobj 'objdir'mumps.olb
 $		define/user target 'targdir'
-$		link/map='mapfile'lmu.map/full/exe='targdir'lmu.exe'lnkopt' lmuobj/libr/incl=lmu,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$		link/map='mapfile'lmu.map/full/exe='targdir'lmu.exe'lnkopt' lmuobj/libr/incl=lmu,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = LMU.EXE
 $	endif
 $ endif
@@ -266,7 +261,7 @@ $	gtmstopdsf = ""
 $	if dsffiles then gtmstopdsf = "/dsf=gtm$stop.dsf"
 $	define/user gtmstopobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/exe=gtm$stop.exe/map='mapfile'gtm$stop.map/full 'gtmstopdsf' gtmstopobj/incl=(gtmstop,gtmstopzc,merrors),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt
+$	link/exe=gtm$stop.exe/map='mapfile'gtm$stop.map/full 'gtmstopdsf' gtmstopobj/incl=(gtmstop,gtmstopzc,merrors),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt  ! BYPASSOK
 gtm$vrt:[pct]_dh.obj,_do.obj,_exp.obj,_st.obj
 name = GTM$STOP.EXE
 $ endif
@@ -283,7 +278,7 @@ $	cmidsf = ""
 $	if dsffiles then cmidsf = "/dsf=cmishr.dsf"
 $	define/user cmiobj 'objdir'cmi.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'cmishr.map/full/share='targdir'cmishr.exe'lnkopt' 'cmidsf' cmiobj/libr'xtra',gtm$tools:'cmilink'/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'cmishr.map/full/share='targdir'cmishr.exe'lnkopt' 'cmidsf' cmiobj/libr'xtra',gtm$tools:'cmilink'/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = CMISHR.EXE
 $	set security/protect=(o:rwed,s:rwed,g:re,w:re) 'targdir'cmishr.exe
 $	if p2 .eqs. "P"
@@ -305,7 +300,7 @@ $	gtcmsrvdsf = ""
 $	if dsffiles then gtcmsrvdsf = "/dsf=gtcm_server.dsf"
 $	define/user gtcmobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'gtcm_server.map/full/exe='targdir'gtcm_server.exe'lnkopt' 'gtcmsrvdsf' gtcmobj/libr/incl=gtcm_server,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'gtcm_server.map/full/exe='targdir'gtcm_server.exe'lnkopt' 'gtcmsrvdsf' gtcmobj/libr/incl=gtcm_server,target:secshrlink.opt/opt,target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = GTCM_SERVER.EXE
 $ endif
 $!
@@ -329,7 +324,7 @@ $	gtcmstpdsf = ""
 $	if dsffiles then gtcmstpdsf = "/dsf=gtcm_stop.dsf"
 $	define/user gtcmstopobj 'objdir'mumps.olb
 $	define/user target 'targdir'
-$	link/map='mapfile'gtcm_stop.map/full/exe='targdir'gtcm_stop.exe gtcmstopobj/incl=(gtcmstop,gtmstopzc,merrors),target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt
+$	link/map='mapfile'gtcm_stop.map/full/exe='targdir'gtcm_stop.exe gtcmstopobj/incl=(gtcmstop,gtmstopzc,merrors),target:cluster.opt/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 gtm$vrt:[pct]_dh.obj,_exp.obj
 name = GTCM_STOP.EXE
 $ endif
@@ -349,7 +344,7 @@ $	then
 $		@gtm$tools:build_print_stage "Building IBI_XFM" "middle"
 $		define/user ibiobj 'objdir'mumps.olb
 $		define/user target 'targdir'
-$		link/share='targdir'ibi_xfm.exe/map='mapfile'ibi_xfm.map/full ibiobj/libr/incl=dsm_api_vector,sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt
+$		link/share='targdir'ibi_xfm.exe/map='mapfile'ibi_xfm.map/full ibiobj/libr/incl=dsm_api_vector,sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt  ! BYPASSOK
 GTMSHR/SHARE
 GSMATCH=LEQ,4,0
 name=DSM$SHARE
@@ -371,7 +366,7 @@ $	then
 $		@gtm$tools:build_print_stage "Building DDPSERVER" "middle"
 $		define/user ddpobj 'objdir'mumps.olb
 $		define/user target 'targdir'
-$		link/map='mapfile'ddpserver.map/full/exe='targdir'ddpserver.exe'lnkopt' ddpobj/libr/incl=ddpserver,sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt
+$		link/map='mapfile'ddpserver.map/full/exe='targdir'ddpserver.exe'lnkopt' ddpobj/libr/incl=ddpserver,sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt  ! BYPASSOK
 gtmshr/share
 gtmsecshr/share
 name = DDPSERVER.EXE
@@ -379,7 +374,7 @@ $		@gtm$tools:build_print_stage "Building DDPGVUSR" "middle"
 $		ddplink ="ddplink." + f$element(alpha,",","vax,axp")
 $		define/user ddpobj 'objdir'mumps.olb
 $		define/user target 'targdir'
-$		link/share='targdir'ddpgvusr.exe'lnkopt'/map='mapfile'DDPGVUSR.MAP/full ddpobj/incl=(DDPGVUSR),gtm$tools:'ddplink'/opt,sys$input/opt,target:release_name.opt/opt
+$		link/share='targdir'ddpgvusr.exe'lnkopt'/map='mapfile'DDPGVUSR.MAP/full ddpobj/incl=(DDPGVUSR),gtm$tools:'ddplink'/opt,sys$input/opt,target:release_name.opt/opt  ! BYPASSOK
 name = DDPGVUSR.EXE
 $		if p2 .eqs. "P"
 $		then
@@ -400,7 +395,7 @@ $			set def [-]
 $!
 $			define/user ddpobj 'objdir'mumps.olb
 $			define/user target 'targdir'
-$			link/exe='targdir'gtcmddpstop.exe/map='mapfile'gtcmddpstop.map/full ddpobj/incl=(stpimg),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt
+$			link/exe='targdir'gtcmddpstop.exe/map='mapfile'gtcmddpstop.map/full ddpobj/incl=(stpimg),sys$input/opt,target:cluster.opt/opt,target:release_name.opt/opt  ! BYPASSOK
 ddpobj/incl=(pid,gtmstopzc,merrors)
 gtm$vrt:[pct]_dh.obj,_exp.obj
 SYMBOL=GTM$CTRLC_ENABLE,0
diff --git a/sr_vvms/ccp_exi_ch.c b/sr_vvms/ccp_exi_ch.c
index 7567a2b..94ca1b9 100644
--- a/sr_vvms/ccp_exi_ch.c
+++ b/sr_vvms/ccp_exi_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001 Sanchez Computer Associates, Inc.	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -21,6 +21,6 @@ static uint4	depth = UNWIND_LEVELS;
 
 CONDITION_HANDLER(ccp_exi_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	UNWIND(&depth, 0);
 }
diff --git a/sr_vvms/cli.c b/sr_vvms/cli.c
index 6936c82..dcd0db5 100644
--- a/sr_vvms/cli.c
+++ b/sr_vvms/cli.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2005 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,7 +30,7 @@ error_def(ERR_STRNOTVALID);
 
 CONDITION_HANDLER(clich)
 {
-	START_CH;
+	START_CH(FALSE);
 	CONTINUE;
 }
 
@@ -54,12 +54,12 @@ boolean_t cli_get_hex(char *e, uint4 *dst)
 			buf[retlength] = 0;	/* for cli_str_to_hex */
 			if (!cli_str_to_hex(ptr, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return (FALSE);
 			}
 			return (TRUE);
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return (FALSE);
 }
@@ -84,12 +84,12 @@ boolean_t cli_get_hex64(char *e, gtm_uint64_t *dst)
 			buf[retlength] = 0;	/* for cli_str_to_hex64 */
 			if (!cli_str_to_hex64(ptr, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return (FALSE);
 			}
 			return (TRUE);
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return (FALSE);
 }
@@ -114,12 +114,12 @@ boolean_t cli_get_uint64(char *e, gtm_uint64_t *dst)
 			buf[retlength] = 0;	/* for cli_str_to_uint64 */
 			if (!cli_str_to_uint64(ptr, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return (FALSE);
 			}
 			return (TRUE);
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return (FALSE);
 }
@@ -145,12 +145,12 @@ boolean_t cli_get_int(char *e, int *dst)		/* entity, destination */
 			buf[retlength] = 0;	/* for cli_str_to_int */
 			if (!cli_str_to_int(bufpt, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return FALSE;
 			} else
 				return TRUE;
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return FALSE;
 }
@@ -176,12 +176,12 @@ boolean_t cli_get_int64(char *e, gtm_int64_t *dst)		/* entity, destination */
 			buf[retlength] = 0;	/* for cli_str_to_int64 */
 			if (!cli_str_to_int64(bufpt, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return FALSE;
 			} else
 				return TRUE;
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return FALSE;
 }
@@ -207,12 +207,12 @@ boolean_t cli_get_num(char *e, int *dst)		/* entity, destination */
 			buf[retlength] = 0;	/* for cli_str_to_num */
 			if (!cli_str_to_num(bufpt, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return FALSE;
 			} else
 				return TRUE;
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return FALSE;
 }
@@ -238,12 +238,12 @@ boolean_t cli_get_num64(char *e, gtm_int64_t *dst)		/* entity, destination */
 			buf[retlength] = 0;	/* for cli_str_to_num64 */
 			if (!cli_str_to_num64(bufpt, dst))
 			{
-				gtm_putmsg(VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_STRNOTVALID, 2, retlength, buf);
 				return FALSE;
 			} else
 				return TRUE;
 		} else
-			gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 	}
 	return FALSE;
 }
@@ -333,7 +333,7 @@ int4 cli_t_f_n(char *e)	/* entity */
 			return (-1);
 	} else
 	{
-		gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 		return (-1);
 	}
 }
@@ -364,7 +364,7 @@ int4 cli_n_a_e(char *e)	/* entity */
 			return (-1);
 	} else
 	{
-		gtm_putmsg(VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
+		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_STRNOTVALID, 2, retlength, buf, status);
 		return (-1);
 	}
 }
diff --git a/sr_vvms/dbinit_ch.c b/sr_vvms/dbinit_ch.c
index 53f25d2..75c27bd 100644
--- a/sr_vvms/dbinit_ch.c
+++ b/sr_vvms/dbinit_ch.c
@@ -61,7 +61,7 @@ CONDITION_HANDLER(dbinit_ch)
 	uint4 		prvprv1[2], prvprv2[2], prvadr[2];
        	$DESCRIPTOR(desc, name_buff);
 
-	START_CH;
+	START_CH(FALSE);
 	if (SUCCESS == SEVERITY || INFO == SEVERITY)
 	{
 		PRN_ERROR;
diff --git a/sr_vvms/do_zcall.c b/sr_vvms/do_zcall.c
index 5463476..dfb6f25 100644
--- a/sr_vvms/do_zcall.c
+++ b/sr_vvms/do_zcall.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -76,6 +76,8 @@ static readonly short	dsizes[N_DSIZES] = {
 GBLREF spdesc	stringpool;
 GBLREF io_pair	io_std_device;
 
+LITREF mval	skiparg;
+
 error_def(ERR_MAXSTRLEN);
 error_def(ERR_VMSMEMORY2);
 error_def(ERR_ZCALLTABLE);
@@ -144,7 +146,7 @@ void do_zcall(mval		*dst,
 			case ZC$DTYPE_H_FLOATING:
 				break;
 			default:
-				rts_error(VARLSTCNT(1) ERR_ZCUNKTYPE);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCUNKTYPE);
 		}
 		switch (inp->mechanism)	/* guard mechanism */
 		{
@@ -154,12 +156,12 @@ void do_zcall(mval		*dst,
 			case ZC$MECH_DESCRIPTOR64:
 				break;
 			default:
-				rts_error(VARLSTCNT(1) ERR_ZCUNKMECH);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCUNKMECH);
 		}
 		assertpro(mvpp <= mvallistend);
 		lclp = lcllist + inp->position - 1;
 		if (lclp->initted)
-			rts_error(VARLSTCNT(5) ERR_ZCALLTABLE, 0, ERR_ZCPOSOVR, 1, inp->position);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZCALLTABLE, 0, ERR_ZCPOSOVR, 1, inp->position);
 		lclp->skip = FALSE;
 		lclp->zctab = inp;
 		if (ZC$MECH_DESCRIPTOR64 == inp->mechanism)
@@ -178,7 +180,7 @@ void do_zcall(mval		*dst,
 			case ZC$IQUAL_OPTIONAL:
 				if (mvpp == mvallistend)
 					lclp->skip = TRUE;
-				else if (!MV_DEFINED(*mvpp) && (*mvpp)->str.addr == (*mvpp))
+				else if (!MV_DEFINED(*mvpp) && M_ARG_SKIPPED(*mvpp))
 				{
 					lclp->skip = TRUE;
 					mvpp++;
@@ -186,11 +188,11 @@ void do_zcall(mval		*dst,
 					use_value = VAL_INPUTMVAL;
 				break;
 			case ZC$IQUAL_OPTIONAL_0:
-				if (mvpp == mvallistend || (!MV_DEFINED(*mvpp) && (*mvpp)->str.addr == (*mvpp)))
+				if ((mvpp == mvallistend) || (!MV_DEFINED(*mvpp) && M_ARG_SKIPPED(*mvpp)))
 				{
 					if (!(ZC$MECH_REFERENCE == inp->mechanism ||
 					      ZC$MECH_DESCRIPTOR == inp->mechanism || ZC$MECH_DESCRIPTOR64 == inp->mechanism))
-						rts_error(VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCOPT0);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCOPT0);
 					lclp->skip = TRUE;
 					if (is_a_desc64)
 						dsc64->dsc64$pq_pointer = 0;
@@ -213,11 +215,11 @@ void do_zcall(mval		*dst,
 				break;
 			case ZC$IQUAL_REQUIRED:
 				if (mvpp == mvallistend || (!MV_DEFINED(*mvpp) && (*mvpp)->str.addr == (*mvpp)))
-					rts_error(VARLSTCNT(1) ERR_ZCINPUTREQ);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCINPUTREQ);
 				use_value = VAL_INPUTMVAL;
 				break;
 			default:
-				rts_error(VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCUNKQUAL);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCUNKQUAL);
 		}
 		switch (use_value)
 		{
@@ -234,7 +236,7 @@ void do_zcall(mval		*dst,
 					if (!is_a_desc64)
 					{
 						if (65535 < (*mvpp)->str.len)
-							rts_error(VARLSTCNT(1) ERR_ZCWRONGDESC);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCWRONGDESC);
 						dsc->dsc$w_length =(*mvpp)->str.len ;
 						dsc->dsc$a_pointer = (*mvpp)->str.addr;
 					} else
@@ -299,13 +301,13 @@ void do_zcall(mval		*dst,
 			case VAL_NONE:
 				break;
 			default:
-				GTMASSERT;
+				assertpro(FALSE && use_value);
 				break;		/* though not necessary, keep compiler on some platforms happy */
 		}
 		lclp->initted = TRUE;
 	}
 	assert(inp == (zctabinput *)firstout);
-	if (mvpp < mvallistend) rts_error(VARLSTCNT(1) ERR_ZCCONMSMTCH);
+	if (mvpp < mvallistend) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCCONMSMTCH);
 	assert(mvpp == mvallistend);
 	is_a_desc64 = FALSE;
 	for (outp = firstout; outp < lastout; outp++)
@@ -325,7 +327,7 @@ void do_zcall(mval		*dst,
 			case ZC$DTYPE_H_FLOATING:
 				break;
 			default:
-				rts_error(VARLSTCNT(1) ERR_ZCUNKTYPE);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCUNKTYPE);
 		}
 		switch (outp->mechanism)	/* guard mechanism */
 		{
@@ -335,7 +337,7 @@ void do_zcall(mval		*dst,
 			case ZC$MECH_DESCRIPTOR64:
 				break;
 			default:
-				rts_error(VARLSTCNT(1) ERR_ZCUNKMECH);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZCUNKMECH);
 		}
 		switch (outp->qualifier)	/* guard qualifier */
 		{
@@ -344,7 +346,7 @@ void do_zcall(mval		*dst,
 			case ZC$OQUAL_PREALLOCATE:
 				break;
 			default:
-				rts_error(VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCUNKQUAL);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZCALLTABLE, 0, ERR_ZCUNKQUAL);
 		}
 		lclp = lcllist + outp->position - 1;
 		if (lclp->initted)
@@ -352,7 +354,7 @@ void do_zcall(mval		*dst,
 			inp = lclp->zctab;
 			if (lclp->skip || outp->type != inp->type || outp->mechanism != inp->mechanism ||
 			    inp->type == ZC$DTYPE_STRING || outp->qualifier == ZC$OQUAL_PREALLOCATE)
-				rts_error(VARLSTCNT(5) ERR_ZCALLTABLE, 0, ERR_ZCPOSOVR, 1, outp->position);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZCALLTABLE, 0, ERR_ZCPOSOVR, 1, outp->position);
 		} else
 		{
 			lclp->skip = FALSE;
@@ -394,11 +396,11 @@ void do_zcall(mval		*dst,
 					if (!(status & 1))
 					{
 						if (LIB$_INSVIRMEM == status)
-							rts_error(VARLSTCNT(3) ERR_VMSMEMORY2, 1, alloclen);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_VMSMEMORY2, 1, alloclen);
 						else
-						{
+						{	/* Only other return code is fatal internal error */
 							assert(LIB$_FATERRLIB == status);
-							GTMASSERT;	/* Only other return code is fatal internal error */
+							assertpro(LIB$_INSVIRMEM == status);	/* to force dump file creation */
 						}
 					}
 				} else
@@ -480,14 +482,14 @@ void do_zcall(mval		*dst,
 						dstlen += dsc->dsc$w_length;
 					else {
 						if (MAX_STRLEN < dsc64->dsc64$q_length)
-							rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 						dstlen += dsc64->dsc64$q_length;
 					}
 				}
 			}
 		}
 		if (MAX_STRLEN < dstlen)
-			rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 		ENSURE_STP_FREE_SPACE(dstlen);
 		/* Construct destination mval */
 		dst->str.addr = stringpool.free;
@@ -535,11 +537,11 @@ void do_zcall(mval		*dst,
 						else
 							dsc64->dsc64$q_length = outp->value;
 						if ((status = lib$sfree1_dd(&lclp->dsc)) != SS$_NORMAL)
-							rts_error(VARLSTCNT(3) ERR_ZCCONVERT, 0, status);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZCCONVERT, 0, status);
 					} else if (DSC64$K_CLASS_D == *class && (dsc->dsc$a_pointer || dsc64->dsc64$pq_pointer))
 					{
 						if ((status = lib$sfree1_dd(&lclp->dsc)) != SS$_NORMAL)
-							rts_error(VARLSTCNT(3) ERR_ZCCONVERT, 0, status);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_ZCCONVERT, 0, status);
 					}
 				} else
 				{
@@ -554,7 +556,7 @@ void do_zcall(mval		*dst,
 		dst->mvtype = MV_STR;
 		if (dstlen == 0)
 		{
-			assert(stringpool.free == dst->str.addr);
+			assert(IS_AT_END_OF_STRINGPOOL(dst->str.addr, 0));
 			dst->str.len = 0;
 		} else
 		{
diff --git a/sr_vvms/dpgbldir_sysops.c b/sr_vvms/dpgbldir_sysops.c
index 0f42b7b..44d3ee1 100644
--- a/sr_vvms/dpgbldir_sysops.c
+++ b/sr_vvms/dpgbldir_sysops.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -34,7 +34,10 @@
 #include "trans_log_name.h"
 #include "gtm_logicals.h"
 
-GBLREF mval		dollar_zgbldir;
+GBLREF mval	dollar_zgbldir;
+GBLREF gd_addr	*gd_header;
+
+error_def(ERR_ZGBLDIRACC);
 
 char LITDEF gde_labels[GDE_LABEL_NUM][GDE_LABEL_SIZE] =
 {
@@ -72,8 +75,6 @@ void *open_gd_file(mstr *v)
 	struct FAB	*fab;
 	int4		status;
 
-	error_def(ERR_ZGBLDIRACC);
-
 	fab = malloc(SIZEOF(struct FAB));
 	*fab = cc$rms_fab;
 	fab->fab$l_fna = v->addr;
@@ -90,11 +91,11 @@ void *open_gd_file(mstr *v)
 		if (!dollar_zgbldir.str.len || ((dollar_zgbldir.str.len == v->len)
 							&& !memcmp(dollar_zgbldir.str.addr, v->addr, v->len)))
 		{
-			rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, v->len, v->addr,
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, v->len, v->addr,
 				LEN_AND_LIT(".  Cannot continue"), LEN_AND_LIT(""), status);
 			assert(FALSE);
 		}
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, v->len, v->addr, LEN_AND_LIT(".  Retaining "),
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, v->len, v->addr, LEN_AND_LIT(".  Retaining "),
 			dollar_zgbldir.str.len, dollar_zgbldir.str.addr, status);
 	}
 	return fab;
@@ -105,13 +106,11 @@ void file_read(struct FAB *file_ptr, int4 size, char *buff, int4 pos)
 	int4		status;
 	short		iosb[4];
 
-	error_def(ERR_ZGBLDIRACC);
-
 	status = sys$qiow(EFN$C_ENF,file_ptr->fab$l_stv, IO$_READVBLK, &iosb[0], 0, 0, buff, size, pos, 0, 0, 0);
 	if (status == SS$_NORMAL)
 		status = iosb[0];
 	if (status != SS$_NORMAL)
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->fab$b_fns,file_ptr->fab$l_fna,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZGBLDIRACC, 6, file_ptr->fab$b_fns,file_ptr->fab$l_fna,
 			LEN_AND_LIT(""), LEN_AND_LIT(""), status);
 	return;
 }
@@ -140,6 +139,7 @@ void dpzgbini(void)
 		dollar_zgbldir.str.addr = temp_mstr.addr;
 	}
 	s2pool(&dollar_zgbldir.str);
+	gd_header = NULL;
 }
 
 mstr *get_name(mstr *ms)
@@ -148,12 +148,11 @@ mstr *get_name(mstr *ms)
 	char	c[MAX_TRANS_NAME_LEN];
 	mstr	ms1, *new;
 
-	error_def(ERR_ZGBLDIRACC);
-
 	if ((status = trans_log_name(ms,&ms1,&c[0])) == SS$_NORMAL)
 		ms = &ms1;
 	else if (status != SS$_NOLOGNAM)
-		rts_error(VARLSTCNT(9) ERR_ZGBLDIRACC, 6, ms->len, ms->addr, LEN_AND_LIT(""), LEN_AND_LIT(""), status);
+		rts_error_csa(CSA_ARG(NULL)
+			VARLSTCNT(9) ERR_ZGBLDIRACC, 6, ms->len, ms->addr, LEN_AND_LIT(""), LEN_AND_LIT(""), status);
 	new = malloc(SIZEOF(mstr));
 	new->len = ms->len;
 	new->addr = malloc(ms->len);
diff --git a/sr_vvms/dse.c b/sr_vvms/dse.c
index 5009428..2927834 100644
--- a/sr_vvms/dse.c
+++ b/sr_vvms/dse.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,8 +32,6 @@
 #include "filestruct.h"
 #include "cli.h"
 #include "error.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "io.h"
 #include "iottdef.h"
 #include "jnl.h"
@@ -69,10 +67,7 @@ GBLREF int4		exi_condition;
 GBLREF int4 		lkid;
 GBLREF boolean_t        dse_running;
 GBLREF gv_namehead	*gv_target;
-GBLREF mval		curr_gbl_root;
 GBLREF gd_region	*gv_cur_region;
-GBLREF gd_binding       *gd_map;
-GBLREF gd_binding       *gd_map_top;
 GBLREF gd_addr          *gd_header;
 GBLREF gd_addr          *original_header;
 GBLREF sgmnt_addrs	*cs_addrs;
@@ -109,12 +104,13 @@ void dse(void)
 	gtm_imagetype_init(DSE_IMAGE);
 	gtm_env_init();	/* read in all environment variables */
 	TREF(transform) = TRUE;
+	TREF(no_spangbls) = TRUE;	/* dse operates on a per-region basis irrespective of global mapping in gld */
 	util_out_open(0);
 	SET_EXIT_HANDLER(exi_blk, generic_exit_handler, exi_condition);	/* Establish exit handler */
 	ESTABLISH(util_base_ch);
 	status =lp_id(&lkid);
 	if (SS$_NORMAL != status)
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	get_page_size();
 	getjobnum();
 	INVOKE_INIT_SECSHR_ADDRS;
@@ -125,7 +121,6 @@ void dse(void)
 	initialize_pattern_table();
 	gvinit();
 	region_init(FALSE);
-	INIT_GBL_ROOT();
 	sys$assign(&desc, &sysout_channel, 0, 0);
 	if (sysout_channel)
 	{
@@ -143,7 +138,9 @@ void dse(void)
 	util_out_print("!/File  !_!AD", TRUE, DB_LEN_STR(gv_cur_region));
 	util_out_print("Region!_!AD!/", TRUE, REG_LEN_STR(gv_cur_region));
 	dse_ctrlc_setup();
-	CREATE_DUMMY_GBLDIR(gd_header, original_header, gv_cur_region, gd_map, gd_map_top);
+	/* Since DSE operates on a region-by-region basis (for the most part), do not use a global directory at all from now on */
+	original_header = gd_header;
+	gd_header = NULL;
 	status = lib$get_foreign(&command, 0, &outlen, 0);
 	if ((status & 1) && outlen > 0)
 	{
@@ -153,7 +150,7 @@ void dse(void)
 			dse_exit();
 		else if (CLI$_NORMAL == status)
 		{
-    			ESTABLISH(util_ch);
+			ESTABLISH(util_ch);
 			CLI$DISPATCH();
 			REVERT;
 		}
@@ -164,14 +161,14 @@ void dse(void)
 
 static void dse_process(void)
 {
-    uint4	status;
+	uint4	status;
 
-    ESTABLISH(util_ch);
-    status = CLI$DCL_PARSE(0, &DSE_CMD, &lib$get_input, &lib$get_input, &prompt);
-    if (RMS$_EOF == status)
-	dse_exit();
-    else if (CLI$_NORMAL == status)
-	CLI$DISPATCH();
-    if (util_interrupt)
-	rts_error(VARLSTCNT(1) ERR_CTRLC);
+	ESTABLISH(util_ch);
+	status = CLI$DCL_PARSE(0, &DSE_CMD, &lib$get_input, &lib$get_input, &prompt);
+	if (RMS$_EOF == status)
+		dse_exit();
+	else if (CLI$_NORMAL == status)
+		CLI$DISPATCH();
+	if (util_interrupt)
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_CTRLC);
 }
diff --git a/sr_vvms/dtgbldir.c b/sr_vvms/dtgbldir.c
index c299276..f3d90e9 100644
--- a/sr_vvms/dtgbldir.c
+++ b/sr_vvms/dtgbldir.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -68,12 +68,12 @@ main()
 	ilist.ret_addr = &ret_addr;
 	status = sys$crelnm(0, &proc_tab, &gbldir, &acmo, &ilist);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	ilist.buf_len = SIZEOF(file_name2) - 1;
 	ilist.buf_addr = file_name2;
 	status = sys$crelnm(0, &proc_tab, &dtlog, &acmo, &ilist);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 
 /************************* Create global directory files for tests *************************************************/
 	fab = cc$rms_fab;
@@ -86,31 +86,8 @@ main()
 	status = sys$create(&fab);
 	if (status != RMS$_CREATED && status != RMS$_FILEPURGED && status != RMS$_NORMAL)
 		sys$exit(status);
-	size = SIZEOF(header_struct) + SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding) + SIZEOF(gd_region) + SIZEOF(gd_segment);
-	header = malloc(((size  + 511) / 512) * 512);
-	header->filesize = size;
-	size = ((size + 511) / 512) * 512;
-	memcpy(header->label, label, SIZEOF(label)-1);
-	addr = (char*)header + SIZEOF(header_struct);
-	addr->maps = SIZEOF(gd_addr);
-	addr->n_maps = 3;
-	addr->regions = (int4)(addr->maps) + 3 * SIZEOF(gd_binding);
-	addr->n_regions = 1;
-	addr->segments = (int4)(addr->regions) + SIZEOF(gd_region);
-	addr->n_segments = 1;
-	addr->link = addr->tab_ptr = addr->id = addr->local_locks = 0;
-	addr->max_rec_size = 100;
-	addr->end = addr->segments + SIZEOF(gd_segment);
-	long_ptr = (char*)addr + (int4)(addr->maps);
-	*long_ptr++ = 0xFFFF2F23;
-	*long_ptr++ = 0xFFFFFFFF;
-	*long_ptr++ = addr->regions;
-	*long_ptr++ = 0xFFFFFF24;
-	*long_ptr++ = 0xFFFFFFFF;
-	*long_ptr++ = addr->regions;
-	*long_ptr++ = 0xFFFFFFFF;
-	*long_ptr++ = 0xFFFFFFFF;
-	*long_ptr++ = addr->regions;
+	DUMMY_GLD_INIT(header, addr, region, segment, size, RELATIVE_OFFSET_TRUE);
+	/* the above macro invocation initializes "header", "addr", "region", "segment" and "size" */
 	region = (char*)addr + (int4)(addr->regions);
 	segment = (char*)addr + (int4)(addr->segments);
 	memset(region, 0, SIZEOF(gd_region));
@@ -137,9 +114,9 @@ main()
 	segment->file_cntl = 0;
 	status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	if (!(iosb[0] & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	sys$dassgn(fab.fab$l_stv);
 	region->rname_len = 5;
 	memcpy(region->rname,"TEMP2",5);
@@ -154,9 +131,9 @@ main()
 		sys$exit(status);
 	status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	if (!(iosb[0] & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	sys$dassgn(fab.fab$l_stv);
 	region->rname_len = 5;
 	memcpy(region->rname, "TEMP3", 5);
@@ -171,9 +148,9 @@ main()
 		sys$exit(status);
 	status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0);
 	if (!(status & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	if (!(iosb[0] & 1))
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	sys$dassgn(fab.fab$l_stv);
 
 /*************************** Run tests********************************************/
diff --git a/sr_vvms/errorsp.h b/sr_vvms/errorsp.h
index 262c89f..9b21458 100644
--- a/sr_vvms/errorsp.h
+++ b/sr_vvms/errorsp.h
@@ -82,7 +82,7 @@ GBLREF int4		 error_condition;
 					return SS$_NORMAL; \
 				}
 
-#define START_CH		error_def(ERR_TPRETRY);								\
+#define START_CH(flag_assert)	error_def(ERR_TPRETRY);								\
 				DCL_THREADGBL_ACCESS;								\
 														\
 				SETUP_THREADGBL_ACCESS;								\
diff --git a/sr_vvms/exi_ch.c b/sr_vvms/exi_ch.c
index 193b021..0d2c9a0 100644
--- a/sr_vvms/exi_ch.c
+++ b/sr_vvms/exi_ch.c
@@ -25,7 +25,7 @@ static int      		depth = UNWIND_LEVELS;
 
 CONDITION_HANDLER(exi_ch)
 {
-        START_CH;
+        START_CH(FALSE);
 	SET_FORCED_EXIT_STATE;
         UNWIND(&depth, NULL);
 }
diff --git a/sr_vvms/fgncal_ch.c b/sr_vvms/fgncal_ch.c
index 9f5d22a..c638e07 100644
--- a/sr_vvms/fgncal_ch.c
+++ b/sr_vvms/fgncal_ch.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,7 +38,7 @@ CONDITION_HANDLER(fgncal_ch)
 {
         int4            status;
 
-        START_CH;
+        START_CH(FALSE);
         if (DUMP)
         {
                 gtm_dump();
diff --git a/sr_vvms/gbldirnam.h b/sr_vvms/gbldirnam.h
index f014131..1c9d716 100644
--- a/sr_vvms/gbldirnam.h
+++ b/sr_vvms/gbldirnam.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2008 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,4 +12,4 @@
 #define GDE_LABEL_SIZE 13
 #define GDE_LABEL_NUM 1
 /* Note, GDE_LABEL_LITERAL must be maintained in gdeinit.m if changes are made here */
-#define GDE_LABEL_LITERAL "GTCGBLDIR009"
+#define GDE_LABEL_LITERAL "GTCGBLDIR010"
diff --git a/sr_vvms/gdeget.m b/sr_vvms/gdeget.m
index e618779..117bc10 100644
--- a/sr_vvms/gdeget.m
+++ b/sr_vvms/gdeget.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -12,38 +12,51 @@ gdeget:	;read in an existing GD or create a default
 LOAD
 	n abs,contents,rel,xregs,xsegs,reglist,map,$et
 	i debug s $et="b"
-	e  s $et="g ABORT^GDE:($p($p($zs,"","",3),""-"")'=""%GDE"") u io w !,$p($zs,"","",3,999),! h"
+	e  s $et="g ABORT^GDE:($p($p($zs,"","",3),""-"")'=""%GDE"") u io w !,$p($zs,"","",3,999),! d GETOUT^GDEEXIT h"
 	s abs=1,update=0,chset=$SELECT($ZV["OS390":"ISO8859-1",1:"")
 	o file:(exc="g badfile":rewind:recordsize=SIZEOF("dsk_blk"):readonly:fixed:blocksize=SIZEOF("dsk_blk"):ichset=chset)
 	u file r rec
 	i debug u @useio
 ; header
-	s label=$e(rec,1,12)
+	s label=$ze(rec,1,12)
+	n gldfmt
+	set v600=0
+	s gldfmt=+$ze(label,10,12)
+	i gldfmt=9 s label=hdrlab,v600=1,update=1			;autoconvert
+	i (v600=1) n SIZEOF d v600init
 	set v5ft1=0
-	i (label="GTCGBLDIR008")!(label="GTCGBDUNX004") s label=hdrlab,v5ft1=1,update=1			;autoconvert
+	i gldfmt=8 s label=hdrlab,v5ft1=1,update=1			;autoconvert
 	i v5ft1=1 n SIZEOF d v5ft1init
 	set v44=0
-	i (label="GTCGBLDIR007")!(label="GTCGBDUNX003") s label=hdrlab,v44=1,update=1			;autoconvert
+	i gldfmt=7 s label=hdrlab,v44=1,update=1			;autoconvert
 	i v44=1 n MAXNAMLN,MAXSEGLN,MAXREGLN,SIZEOF d v44init
 	s v30=0
-	i (label="GTCGBLDIR006")!(label="GTCGBDUNX002") s label=hdrlab,v30=4,update=1			;autoconvert
-	i label'=hdrlab d cretmps,CONVERT^GDEOGET,verify s update=1 q					;autoconvert
-	s filesize=$$bin2num($e(rec,13,16))
+	i gldfmt=6 s label=hdrlab,v30=4,update=1			;autoconvert
+	i label'=hdrlab zm gdeerr("GDUNKNFMT"):file,gdeerr("INPINTEG")
+	s filesize=$$bin2num($ze(rec,13,16))
 	s abs=abs+SIZEOF("gd_header")
 ; contents
-	i $e(rec,abs,abs+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; filler
-	s abs=abs+4
-	s contents("maxrecsize")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("mapcnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("regioncnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("segmentcnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	i $e(rec,abs,abs+1)'=$tr($j("",2)," ",ZERO) zm gdeerr("INPINTEG")				; filler
-	s abs=abs+2
-	s contents("maps")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("regions")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("segments")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
+	s ptrsize=4
+	i $ze(rec,abs,abs+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")	; gd_addr.local_locks
+	s abs=abs+ptrsize
+	s contents("maxrecsize")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	n cntsize  s cntsize=$s((gldfmt>9):4,1:2)				; counters are 4-bytes since V6.1
+	s contents("mapcnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("regioncnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("segmentcnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	i '(gldfmt>9) d
+	. i $ze(rec,abs,abs+cntsize-1)'=$tr($j("",cntsize)," ",ZERO) zm gdeerr("INPINTEG") ; filler
+	. s abs=abs+cntsize
+	e  d
+	. s contents("gblnamecnt")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	. s contents("varmapslen")=$$bin2num($ze(rec,abs,abs+cntsize-1)),abs=abs+cntsize
+	s contents("maps")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	s contents("regions")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	s contents("segments")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	i (gldfmt>9) s contents("gblnames")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
 	s abs=abs+12								;skip link, tab_ptr and id pointers
-	s contents("end")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
+	s contents("end")=$$bin2num($ze(rec,abs,abs+3)),abs=abs+4
+	i (gldfmt>9) s abs=abs+16	; reserved for runtime fillers
 	i contents("regioncnt")'=contents("segmentcnt") zm gdeerr("INPINTEG")
 	i contents("regioncnt")-1>contents("mapcnt") zm gdeerr("INPINTEG")
 ; verify offsets
@@ -51,19 +64,33 @@ LOAD
 	s x=contents("maps")
 	i x+1'=(abs-SIZEOF("gd_header")) zm gdeerr("INPINTEG")
 	s x=x+(contents("mapcnt")*SIZEOF("gd_map"))
+	i (gldfmt>9)  s x=x+contents("varmapslen")		; add variable maps section too if available
 	i x'=contents("regions") zm gdeerr("INPINTEG")
 	s x=x+(contents("regioncnt")*SIZEOF("gd_region"))
 	i x'=contents("segments") zm gdeerr("INPINTEG")
 	s x=x+(contents("segmentcnt")*(SIZEOF("gd_segment")-v30))
+	i (gldfmt>9) d
+	. i x'=contents("gblnames") zm gdeerr("INPINTEG")
+	. s x=x+(contents("gblnamecnt")*(SIZEOF("gd_gblname")))
 	i x'=contents("end") zm gdeerr("INPINTEG")
 	s rel=abs
 ; maps - verify that mapped regions and regions are 1-to-1
 	k reglist
-	f i=1:1:contents("mapcnt") d map
-	zm:'$$MAP2NAM^GDEMAP(.map) gdeerr("INPINTEG")
+	i '(gldfmt>9) d
+	. f i=1:1:contents("mapcnt") d mapPreV61
+	e  d
+	. n maparray,tmpabs,newabs
+	. f i=1:1:contents("mapcnt") d mapfixed(i)	; read through fixed    section of MAPS
+	. s tmpabs=abs
+	. f i=1:1:contents("mapcnt") d mapvariable(i)	; read through variable section of MAPS
+	. s newabs=(((abs-1)+(ptrsize-1))\ptrsize*ptrsize)+1 ; make "abs" 8-byte aligned for 64bit platforms (and 4-byte for 32-bit)
+	. s rel=rel+(newabs-abs)			; adjust "rel" to take "abs"-8-byte-alignment-adjustment into account
+	. s abs=newabs
+	. i (abs-tmpabs)'=contents("varmapslen") zm gdeerr("INPINTEG")
 	s s=""
 	f i=1:1:contents("regioncnt") s s=$o(reglist(s))
-	i $l($o(reglist(s))) zm gdeerr("INPINTEG")
+	i $zl($o(reglist(s))) zm gdeerr("INPINTEG")
+	i i'=contents("regioncnt") zm gdeerr("INPINTEG")
 ; regions
 	k regs,xregs s regs=0
 	f i=1:1:contents("regioncnt") d region
@@ -72,6 +99,13 @@ LOAD
 	k segs,xsegs s segs=0
 	f i=1:1:contents("segmentcnt") d segment
 	i segs'=contents("segmentcnt") zm gdeerr("INPINTEG")
+; gblnames
+	i (gldfmt>9) d
+	. k gnams s gnams=0
+	. f i=1:1:contents("gblnamecnt") d gblname(i)
+	e  s gnams=0
+	; wait until "gnams" is setup before checking maps, as "gnams" is used in case of subscripted gvns in map entries
+	zm:'$$MAP2NAM^GDEMAP(.map) gdeerr("INPINTEG")
 ; template access method
 	s tmpacc=$$gderead(4)
 	i accmeth'[("\"_tmpacc) zm gdeerr("INPINTEG")
@@ -81,23 +115,24 @@ LOAD
 	f s="ALLOCATION","BEFORE_IMAGE","BUFFER_SIZE" d tmpreg(s)
 	i 'v30 d tmpreg("COLLATION_DEFAULT")
 	f s="EXTENSION","FILE_NAME" d tmpreg(s)
-	f s="JOURNAL","KEY_SIZE","NULL_SUBSCRIPTS","RECORD_SIZE" d tmpreg(s) ;,"STOP_ENABLE"
+	f s="JOURNAL","KEY_SIZE","NULL_SUBSCRIPTS","RECORD_SIZE" d tmpreg(s)
 	; need to handle versioning
 	i 'v44&'v30 d tmpreg("STDNULLCOLL")
-	f i=2:1:$l(accmeth,"\") s am=$p(accmeth,"\",i) d
-	. i am="MM" d:$l(rec)-(rel-1)<3 nextrec i +$e(rec,rel,rel+2)'=2 d tmpmm q
+	f i=2:1:$zl(accmeth,"\") s am=$p(accmeth,"\",i) d
+	. i am="MM" d:$zl(rec)-(rel-1)<3 nextrec i +$ze(rec,rel,rel+2)'=2 n tmpsegcommon d tmpmm q
 	. f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","BUCKET_SIZE","DEFER","EXTENSION_COUNT","FILE_TYPE" d tmpseg(am,s)
 	. f s="GLOBAL_BUFFER_COUNT","LOCK_SPACE" d tmpseg(am,s)
+	. i (gldfmt>9) d tmpseg(am,"MUTEX_SLOTS")
 	. i 'v30 d tmpseg(am,"RESERVED_BYTES")					;autoconvert, can be condensed someday
 	. d tmpseg(am,"WINDOW_SIZE")
 	c file
 ; resolve
 	s s=""
-	f  s s=$o(nams(s)) q:'$l(s)  zm:'$d(xregs(nams(s))) gdeerr("INPINTEG") s nams(s)=xregs(nams(s))
-	f  s s=$o(regs(s)) q:'$l(s)  zm:'$d(xsegs(regs(s,"DYNAMIC_SEGMENT"))) gdeerr("INPINTEG") d
+	f  s s=$o(nams(s)) q:'$zl(s)  zm:'$d(xregs(nams(s))) gdeerr("INPINTEG") s nams(s)=xregs(nams(s))
+	f  s s=$o(regs(s)) q:'$zl(s)  zm:'$d(xsegs(regs(s,"DYNAMIC_SEGMENT"))) gdeerr("INPINTEG") d
 	. s regs(s,"DYNAMIC_SEGMENT")=xsegs(regs(s,"DYNAMIC_SEGMENT"))
-	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD") d
-	. s x="" f  s x=$o(segs(s,x)) q:x=""  i x'="FILE_NAME",'$l(tmpseg(am,x)) zm:segs(s,x) gdeerr("INPINTEG") s segs(s,x)=""
+	f  s s=$o(segs(s)) q:'$zl(s)  s am=segs(s,"ACCESS_METHOD") d
+	. s x="" f  s x=$o(segs(s,x)) q:x=""  i x'="FILE_NAME",'$zl(tmpseg(am,x)) zm:segs(s,x) gdeerr("INPINTEG") s segs(s,x)=""
 	; fall through !
 verify:	s x=$$ALL^GDEVERIF
 	i 'x zm gdeerr("INPINTEG")
@@ -107,131 +142,191 @@ verify:	s x=$$ALL^GDEVERIF
 
 badfile ;file access failed
 	s:'debug $et="" u file:exc="" s abortzs=$zs zm gdeerr("GDREADERR"):file,+abortzs
+	d GETOUT^GDEEXIT
 	h
 	;
 bin2num:(bin)	; binary number -> number
 	n num,i
 	s num=0
-	i endian=TRUE f i=$l(bin):-1:1 s num=$a(bin,i)*HEX($l(bin)-i*2)+num
-	e  f i=1:1:$l(bin) s num=$a(bin,i)*HEX(i-1*2)+num
+	i endian=TRUE f i=$zl(bin):-1:1 s num=$a(bin,i)*HEX($zl(bin)-i*2)+num
+	e  f i=1:1:$zl(bin) s num=$a(bin,i)*HEX(i-1*2)+num
 	q num
 	;
 
 ;----------------------------------------------------------------------------------------------------------------------------------
-map:
-	i $l(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
-	s s=$e(rec,rel,rel+SIZEOF("mident")-1),rel=rel+SIZEOF("mident")
-	s x=$f(s,$c(0))-2 i x=-2 s x=SIZEOF("mident")
-	s s=$e(s,1,x)
-	s x=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	s map(s)=x
+regoffchk:(x)	; check region offset
 	s reglist(x)="",x=x-contents("regions")
 	i x#SIZEOF("gd_region") zm gdeerr("INPINTEG")
 	i x\SIZEOF("gd_region")'<contents("regioncnt") zm gdeerr("INPINTEG")
+	q
+
+mapPreV61:
+	i $zl(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
+	s s=$ze(rec,rel,rel+SIZEOF("mident")-1),rel=rel+SIZEOF("mident")
+	s x=$f(s,ZERO)-2 i x=-2 s x=SIZEOF("mident")
+	s s=$ze(s,1,x)
+	s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s map(s)=x
+	d regoffchk(x)
+	s abs=abs+SIZEOF("gd_map")
+	q
+
+mapfixed:(i)
+	n regoffset,keyoffset,gvnamelen,gvkeylen
+	i $zl(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
+	s keyoffset=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s regoffset=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s gvnamelen=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s gvkeylen=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s maparray(i,1)=keyoffset
+	s maparray(i,2)=regoffset
+	s maparray(i,3)=gvnamelen
+	s maparray(i,4)=gvkeylen+1	; include second null byte as well
+	d regoffchk(regoffset)
 	s abs=abs+SIZEOF("gd_map")
 	q
+
+mapvariable:(i)
+	n keyoffset,regoffset,gvnamelen,gvkeylen,s
+	s keyoffset=maparray(i,1)
+	s regoffset=maparray(i,2)
+	s gvnamelen=maparray(i,3)
+	s gvkeylen=maparray(i,4)
+	i (keyoffset+1+SIZEOF("gd_header"))'=abs zm gdeerr("INPINTEG")
+	i (keyoffset+gvkeylen)>contents("regions") zm gdeerr("INPINTEG")
+	f  q:(($zl(rec)-(rel-1))'<gvkeylen)  d nextrec
+	s s=$ze(rec,rel,rel+gvkeylen-1)
+	i $ze(s,gvnamelen+1)'=ZERO zm gdeerr("INPINTEG")
+	i $ze(s,gvkeylen-1)'=ZERO zm gdeerr("INPINTEG")
+	i $ze(s,gvkeylen)'=ZERO zm gdeerr("INPINTEG")
+	s s=$ze(s,1,gvkeylen-2)
+	s map(s)=regoffset
+	s rel=rel+gvkeylen
+	s abs=abs+gvkeylen
+	q
+
 region:
-	i $l(rec)-(rel-1)<SIZEOF("gd_region") d nextrec
+	i $zl(rec)-(rel-1)<SIZEOF("gd_region") d nextrec
 	s regs=regs+1
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s s=$e(rec,rel,rel+l-1),rel=rel+MAXREGLN,xregs(abs-1-SIZEOF("gd_header"))=s
-	s regs(s,"KEY_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s regs(s,"RECORD_SIZE")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	s regs(s,"DYNAMIC_SEGMENT")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
+	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s s=$ze(rec,rel,rel+l-1),rel=rel+MAXREGLN,xregs(abs-1-SIZEOF("gd_header"))=s
+	s regs(s,"KEY_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s regs(s,"RECORD_SIZE")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s regs(s,"DYNAMIC_SEGMENT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
 	s x=regs(s,"DYNAMIC_SEGMENT")-contents("segments")
 	i x#(SIZEOF("gd_segment")-v30) zm gdeerr("INPINTEG")						; autoconvert
 	i x\(SIZEOF("gd_segment")-v30)'<contents("segmentcnt") zm gdeerr("INPINTEG")			; autoconvert
-	i $e(rec,rel,rel+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; static segment
-	s rel=rel+4
-	i $e(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; OPEN state
+	i $ze(rec,rel,rel+ptrsize-1)'=$tr($j("",ptrsize)," ",ZERO) zm gdeerr("INPINTEG")		; static segment
+	s rel=rel+ptrsize
+	i $ze(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; OPEN state
 	s rel=rel+1
-	i $e(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; lock_write
+	i $ze(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; lock_write
 	s rel=rel+1
-	s regs(s,"NULL_SUBSCRIPTS")=$$bin2num($e(rec,rel)),rel=rel+1
-	s regs(s,"JOURNAL")=$$bin2num($e(rec,rel)),rel=rel+1
-	s regs(s,"ALLOCATION")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4					; journal options
-	s regs(s,"EXTENSION")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s regs(s,"BUFFER_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s regs(s,"BEFORE_IMAGE")=$$bin2num($e(rec,rel)),rel=rel+1
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")				; 4 chars
+	s regs(s,"NULL_SUBSCRIPTS")=$$bin2num($ze(rec,rel)),rel=rel+1
+	s regs(s,"JOURNAL")=$$bin2num($ze(rec,rel)),rel=rel+1
+	s regs(s,"ALLOCATION")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4					; journal options
+	s regs(s,"EXTENSION")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s regs(s,"BUFFER_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s regs(s,"BEFORE_IMAGE")=$$bin2num($ze(rec,rel)),rel=rel+1
+	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")				; 4 chars
 	s rel=rel+4
-	s regs(s,"COLLATION_DEFAULT")=$$bin2num($e(rec,rel)),rel=rel+1					; default collating type
+	s regs(s,"COLLATION_DEFAULT")=$$bin2num($ze(rec,rel)),rel=rel+1					; default collating type
 	; stdnullcoll is applicable from V5
-	i 'v44&'v30 s regs(s,"STDNULLCOLL")=$$bin2num($e(rec,rel))
+	i 'v44&'v30 s regs(s,"STDNULLCOLL")=$$bin2num($ze(rec,rel))
 	e  d
-	. i $e(rec,rel)'=$tr($j("",1)," ",ZERO) zm gdeerr("INPINTEG")					; 1 chars
+	. i $ze(rec,rel)'=$tr($j("",1)," ",ZERO) zm gdeerr("INPINTEG")					; 1 chars
 	. s regs(s,"STDNULLCOLL")=0
 	s rel=rel+1
-	s l=$$bin2num($e(rec,rel)),rel=rel+1 ;jnl_file_len
-	s regs(s,"FILE_NAME")=$e(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
-	i $e(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")				; reserved
+	s l=$$bin2num($ze(rec,rel)),rel=rel+1 ;jnl_file_len
+	s regs(s,"FILE_NAME")=$ze(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
+	i $ze(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")				; reserved
 	s rel=rel+8
+	i (gldfmt>9) s rel=rel+16	; reserved for runtime fillers
 	s abs=abs+SIZEOF("gd_region")
 	q
 segment:
-	i $l(rec)-(rel-1)<(SIZEOF("gd_segment")-v30) d nextrec						; autoconvert
+	i $zl(rec)-(rel-1)<(SIZEOF("gd_segment")-v30) d nextrec						; autoconvert
 	s segs=segs+1
-	s x=$$bin2num($e(rec,rel+SIZEOF("am_offset")-v30,rel+SIZEOF("am_offset")-v30+3))		; autoconvert
+	s x=$$bin2num($ze(rec,rel+SIZEOF("am_offset")-v30,rel+SIZEOF("am_offset")-v30+3))		; autoconvert
 	s am=$s(x=1:"BG",x=2:"MM",x=4:"USER",1:"ERROR")
 	i am="ERROR" zm gdeerr("INPINTEG")
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s s=$e(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xsegs(abs-1-SIZEOF("gd_header"))=s
+	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s s=$ze(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xsegs(abs-1-SIZEOF("gd_header"))=s
 	s segs(s,"ACCESS_METHOD")=am
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s segs(s,"FILE_NAME")=$e(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
-	s segs(s,"BLOCK_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s segs(s,"EXTENSION_COUNT")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s segs(s,"ALLOCATION")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
+	s l=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s segs(s,"FILE_NAME")=$ze(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
+	s segs(s,"BLOCK_SIZE")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s segs(s,"EXTENSION_COUNT")=$$bin2num($ze(rec,rel,rel+1)),rel=rel+2
+	s segs(s,"ALLOCATION")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
 	s rel=rel+4
-	i $e(rec,rel,rel+3)'=".DAT" zm gdeerr("INPINTEG")
+	i $ze(rec,rel,rel+3)'=".DAT" zm gdeerr("INPINTEG")
 	s rel=rel+4
-	s segs(s,"DEFER")=$$bin2num($e(rec,rel))
+	s segs(s,"DEFER")=$$bin2num($ze(rec,rel))
 	s rel=rel+1
-	s x=$$bin2num($e(rec,rel)),rel=rel+1
+	s x=$$bin2num($ze(rec,rel)),rel=rel+1
 	s segs(s,"FILE_TYPE")=$s(x=0:"DYNAMIC",1:"ERROR")
 	i segs(s,"FILE_TYPE")="ERROR" zm gdeerr("INPINTEG")
-	s segs(s,"BUCKET_SIZE")=$$bin2num($e(rec,rel))
+	s segs(s,"BUCKET_SIZE")=$$bin2num($ze(rec,rel))
 	s rel=rel+1
-	s segs(s,"WINDOW_SIZE")=$$bin2num($e(rec,rel))
+	s segs(s,"WINDOW_SIZE")=$$bin2num($ze(rec,rel))
 	s rel=rel+1
-	s segs(s,"LOCK_SPACE")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	s segs(s,"GLOBAL_BUFFER_COUNT")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	i 'v30 s segs(s,"RESERVED_BYTES")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4		;autoconvert
+	s segs(s,"LOCK_SPACE")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	s segs(s,"GLOBAL_BUFFER_COUNT")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	i 'v30 s segs(s,"RESERVED_BYTES")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4		;autoconvert
 	e  s segs(s,"RESERVED_BYTES")=0
+	i (gldfmt>9) d
+	. s segs(s,"MUTEX_SLOTS")=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4
+	e  s segs(s,"MUTEX_SLOTS")=defseg("MUTEX_SLOTS")
 	s rel=rel+4										; access method already processed
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; file_cntl pointer
+	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; file_cntl pointer
 	s rel=rel+4
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; repl_list pointer
+	i $ze(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; repl_list pointer
 	s rel=rel+4
+	i (gldfmt>9) s rel=rel+16	; reserved for runtime fillers
 	s abs=abs+SIZEOF("gd_segment")-v30
 	q
+gblname(i);
+	n x,y
+	i $zl(rec)-(rel-1)<SIZEOF("gd_gblname") d nextrec
+	s gnams=gnams+1
+	s s=$ze(rec,rel,rel+SIZEOF("mident")-1),rel=rel+SIZEOF("mident")
+	s x=$zf(s,ZERO)-2 i x=-2 zm gdeerr("INPINTEG")	; it better be null terminated
+	s s=$ze(s,1,x)
+	s x=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4 	; read 4 bytes
+	i x>maxgnam("COLLATION") zm gdeerr("INPINTEG")	; collation # should be <= 255
+	s y=$$bin2num($ze(rec,rel,rel+3)),rel=rel+4 	; read 4 bytes
+	d chkcoll^GDEPARSE(x,s,y)
+	s gnams(s,"COLLATION")=x
+	s gnams(s,"COLLVER")=y
+	s abs=abs+SIZEOF("gd_gblname")
+	q
 gderead:(max)
 	n s
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
+	i $zl(rec)-(rel-1)<3 d nextrec
+	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
 	i l>max zm gdeerr("INPINTEG")
-	i $l(rec)-(rel-1)<l d nextrec
-	s s=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
+	i $zl(rec)-(rel-1)<l d nextrec
+	s s=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
 	q s
 	;
 tmpreg:(s)
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $l(rec)-(rel-1)<l d nextrec
-	s tmpreg(s)=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
+	i $zl(rec)-(rel-1)<3 d nextrec
+	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
+	i $zl(rec)-(rel-1)<l d nextrec
+	s tmpreg(s)=$ze(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
 	q
 tmpseg:(a,s)
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $l(rec)-(rel-1)<l d nextrec
-	s tmpseg(a,s)=$s($l(tmpseg(a,s)):$e(rec,rel,rel+l-1),1:"") s rel=rel+l,abs=abs+l
+	i $zl(rec)-(rel-1)<3 d nextrec
+	s l=$ze(rec,rel,rel+2),rel=rel+3,abs=abs+3
+	i $zl(rec)-(rel-1)<l d nextrec
+	s tmpseg(a,s)=$s($zl(tmpseg(a,s)):$ze(rec,rel,rel+l-1),1:"") s rel=rel+l,abs=abs+l
 	q
 nextrec:
 	n nextrec
 	u file r nextrec
 	i debug u @useio
-	s rec=$e(rec,rel,$l(rec))_nextrec,rel=1
+	s rec=$ze(rec,rel,$zl(rec))_nextrec,rel=1
 	q
 ;----------------------------------------------------------------------------------------------------------------------------------
 
@@ -241,9 +336,10 @@ CREATE
 	s header=$tr($j("",SIZEOF("gd_header")-16)," ",ZERO)
 	s nams=2,(nams("*"),nams("#"))=defreg
 	s regs=1,regs(defreg,"DYNAMIC_SEGMENT")=defseg,reg="regs(defreg)"
+	s gnams=0
 	d cretmps
 	s x=""
-	f  s x=$o(tmpreg(x)) q:'$l(x)  s @reg@(x)=tmpreg(x)
+	f  s x=$o(tmpreg(x)) q:'$zl(x)  s @reg@(x)=tmpreg(x)
 	s segs=1
 	s am=tmpacc d maktseg
 	q
@@ -259,19 +355,31 @@ cretmps:
 	s tmpreg("NULL_SUBSCRIPTS")=0
 	s tmpreg("RECORD_SIZE")=256
 	s tmpreg("STDNULLCOLL")=0
-	;s tmpreg("STOP_ENABLED")=1
+	n tmpsegcommon
+	; First define segment characteristics that are identical to BG and MM access methods (done inside "tmpmm")
+	; Then define overrides specific to BG and MM
+	d tmpmm
+	m tmpseg("BG")=tmpsegcommon	; copy over all common templates into BG access method first
+	; now add BG specific overrides
 	s tmpseg("BG","ACCESS_METHOD")="BG"
-	s tmpseg("BG","ALLOCATION")=100
-	s tmpseg("BG","BLOCK_SIZE")=1024
-	s tmpseg("BG","BUCKET_SIZE")=""
 	s tmpseg("BG","DEFER")=""
-	s tmpseg("BG","EXTENSION_COUNT")=100
-	s tmpseg("BG","FILE_TYPE")="DYNAMIC"
 	s tmpseg("BG","GLOBAL_BUFFER_COUNT")=defglo
-	s tmpseg("BG","RESERVED_BYTES")=0
-	s tmpseg("BG","LOCK_SPACE")=40
-	s tmpseg("BG","WINDOW_SIZE")=""
-	d tmpmm
+	; now define USER access method defaults
+	d tmpuser
+	s tmpacc="BG"	; set default access method to BG
+	q
+tmpmm:	;
+	d tmpsegcommon
+	m tmpseg("MM")=tmpsegcommon	; copy over all common stuff into MM access method first
+	; now add MM specific overrides
+	s tmpseg("MM","ACCESS_METHOD")="MM"
+	s tmpseg("MM","DEFER")=1
+	s tmpseg("MM","GLOBAL_BUFFER_COUNT")=1024
+	q
+tmpsegcommon:
+	m tmpsegcommon=defseg
+	q
+tmpuser:
 	s tmpseg("USER","ACCESS_METHOD")="USER"
 	s tmpseg("USER","ALLOCATION")=""
 	s tmpseg("USER","BLOCK_SIZE")=""
@@ -279,27 +387,15 @@ cretmps:
 	s tmpseg("USER","DEFER")=""
 	s tmpseg("USER","EXTENSION_COUNT")=""
 	s tmpseg("USER","FILE_TYPE")="DYNAMIC"
+	s tmpseg("USER","MUTEX_SLOTS")=0
 	s tmpseg("USER","GLOBAL_BUFFER_COUNT")=""
 	s tmpseg("USER","RESERVED_BYTES")=0
 	s tmpseg("USER","LOCK_SPACE")=""
 	s tmpseg("USER","WINDOW_SIZE")=""
-	s tmpacc="BG"
-	q
-tmpmm:	s tmpseg("MM","ACCESS_METHOD")="MM"
-	s tmpseg("MM","ALLOCATION")=100
-	s tmpseg("MM","BLOCK_SIZE")=1024
-	s tmpseg("MM","BUCKET_SIZE")=""
-	s tmpseg("MM","DEFER")=1
-	s tmpseg("MM","EXTENSION_COUNT")=100
-	s tmpseg("MM","FILE_TYPE")="DYNAMIC"
-	s tmpseg("MM","GLOBAL_BUFFER_COUNT")=1024
-	s tmpseg("MM","RESERVED_BYTES")=0
-	s tmpseg("MM","LOCK_SPACE")=40
-	s tmpseg("MM","WINDOW_SIZE")=""
 	q
-maktseg:	s segs(defseg,"FILE_NAME")=defdb
+maktseg: s segs(defseg,"FILE_NAME")=defdb
 	s seg="segs(defseg)",x=""
-	f  s x=$o(tmpseg(am,x)) q:'$l(x)  s @seg@(x)=tmpseg(am,x)
+	f  s x=$o(tmpseg(am,x)) q:'$zl(x)  s @seg@(x)=tmpseg(am,x)
 	q
 v44init:
 	s SIZEOF("am_offset")=308
@@ -310,12 +406,11 @@ v44init:
 	s SIZEOF("gd_region")=316
 	s SIZEOF("gd_segment")=320
 	s SIZEOF("mident")=8
+	s SIZEOF("blk_hdr")=7
 	s SIZEOF("rec_hdr")=3
 	s SIZEOF("dsk_blk")=512
 	s SIZEOF("max_str")=32767
 	s MAXNAMLN=SIZEOF("mident"),MAXREGLN=16,MAXSEGLN=16
-	i ver'="VMS" s SIZEOF("blk_hdr")=8
-	e  s SIZEOF("blk_hdr")=7
 	q
 v5ft1init:
 	s SIZEOF("am_offset")=324
@@ -332,3 +427,17 @@ v5ft1init:
 	i ver'="VMS" s SIZEOF("blk_hdr")=8
 	e  s SIZEOF("blk_hdr")=7
 	q
+v600init:
+	s SIZEOF("am_offset")=324
+	s SIZEOF("file_spec")=256
+	s SIZEOF("gd_header")=16
+	s SIZEOF("gd_contents")=44
+	s SIZEOF("gd_map")=36
+	s SIZEOF("gd_region")=332
+	s SIZEOF("gd_segment")=336
+	s SIZEOF("mident")=32
+	s SIZEOF("blk_hdr")=16
+	s SIZEOF("rec_hdr")=3
+	s SIZEOF("dsk_blk")=512
+	s SIZEOF("max_str")=32767
+	q
diff --git a/sr_vvms/gdeoget.m b/sr_vvms/gdeoget.m
deleted file mode 100644
index 963b016..0000000
--- a/sr_vvms/gdeoget.m
+++ /dev/null
@@ -1,436 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;								;
-;	Copyright 2006 Fidelity Information Services, Inc	;
-;								;
-;	This source code contains the intellectual property	;
-;	of its copyright holder(s), and is made available	;
-;	under a license.  If you do not know the terms of	;
-;	the license, please stop and do not read further.	;
-;								;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-gdeget:	;read in an existing GD or create a default
-CONVERT	n accmeth,hdrlab,MAXSEGLN,MAXREGLN,SIZEOF,RMS,csegs,cregs,contents d gdeinit
-	;s label=$e(rec,1,12)
-	s (v23,v24,v25)=0 										; to allow autoconvert
-	i label="GTCGBLDIR001" s label=hdrlab,(v23,v24)=1,update=1					; to allow autoconvert
-	i label="GTCGBLDIR002" s label=hdrlab,v24=1,update=1						; to allow autoconvert
-	i label="GTCGBLDIR003" s label=hdrlab,v25=1,update=1						; to allow autoconvert
-	i label'=hdrlab zm gdeerr("GDUNKNFMT"):file,gdeerr("INPINTEG")
-	s filesize=$$bin2num($e(rec,13,16))
-	s header=$e(rec,17,SIZEOF("gd_header")),abs=abs+SIZEOF("gd_header")
-; contents
-	i $e(rec,abs,abs+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; filler
-	s abs=abs+4
-	s contents("maxrecsize")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("mapcnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("maps")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("regioncnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("regions")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("segmentcnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("segments")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("gdscnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("gdsfiledata")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("rmscnt")=$$bin2num($e(rec,abs,abs+1)),abs=abs+2
-	s contents("rmsfiledata")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s contents("end")=$$bin2num($e(rec,abs,abs+3)),abs=abs+4
-	s abs=abs+22
-	i contents("regioncnt")'=contents("segmentcnt") zm gdeerr("INPINTEG")
-	i contents("regioncnt")-1>contents("mapcnt") zm gdeerr("INPINTEG")
-; verify offsets
-	i abs'=(SIZEOF("gd_header")+SIZEOF("gd_contents")+1) zm gdeerr("INPINTEG")
-	s x=contents("maps")
-	i x+1'=(abs-SIZEOF("gd_header")) zm gdeerr("INPINTEG")
-	s x=x+(contents("mapcnt")*SIZEOF("gd_map"))
-	i x'=contents("regions") zm gdeerr("INPINTEG")
-	s x=x+(contents("regioncnt")*SIZEOF("gd_region"))
-	i x'=contents("segments") zm gdeerr("INPINTEG")
-	s x=x+(contents("segmentcnt")*SIZEOF("gd_segment"))
-	i x'=contents("gdsfiledata") zm gdeerr("INPINTEG")
-	s x=x+(contents("gdscnt")*SIZEOF("gds_filedata"))
-	i x'=contents("rmsfiledata") zm gdeerr("INPINTEG")
-	s x=x+(contents("rmscnt")*SIZEOF("rms_filedata"))
-	i x'=contents("end") zm gdeerr("INPINTEG")
-	s rel=abs
-; maps - verify that mapped regions and regions are 1-to-1
-	k reglist
-	f i=1:1:contents("mapcnt") d map
-	s s=""
-	f i=1:1:contents("regioncnt") s s=$o(reglist(s))
-	i $l($o(reglist(s))) zm gdeerr("INPINTEG")
-; regions
-	k cregs,xregs s cregs=0
-	f i=1:1:contents("regioncnt") d region
-	i cregs'=contents("regioncnt") zm gdeerr("INPINTEG")
-; segments
-	k csegs,xsegs s csegs=0
-	f i=1:1:contents("segmentcnt") d segment
-	i csegs'=contents("segmentcnt") zm gdeerr("INPINTEG")
-; gdsfiledata
-	f i=1:1:contents("gdscnt") d fabdata(SIZEOF("gds_filedata"),0)
-; rmsfiledata
-	f i=1:1:contents("rmscnt") d fabdata(SIZEOF("rms_filedata"),SIZEOF("struct RAB"))
-; names
-	k nams s nams=0
-	i $l(rec)-(rel-1)<3 d nextrec
-	s nams=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	f i=1:1:nams d name
-; regions
-	k regs s regs=0
-	i $l(rec)-(rel-1)<3 d nextrec
-	s regs=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i regs<contents("regioncnt") zm gdeerr("INPINTEG")
-	f i=1:1:regs d gdereg
-; template access method
-	s tmpacc=$$gderead(4)
-	i accmeth'[("\"_tmpacc) zm gdeerr("INPINTEG")
-; segments
-	k segs s segs=0
-	i $l(rec)-(rel-1)<3 d nextrec
-	s segs=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i segs<contents("segmentcnt") zm gdeerr("INPINTEG")
-	f i=1:1:segs d gdeseg
-; templates
-	;k tmpreg,tmpseg
-	f s="ALLOCATION","BEFORE_IMAGE","BUFFER_SIZE","EXTENSION","FILE_NAME" d tmpreg(s)
-	i v24 d tmpreg(s) s tmpreg("ALLOCATION")=100,tmpreg("BEFORE_IMAGE")=1			; to allow autoconvert
-	i v24 s tmpreg("BUFFER_SIZE")=128,tmpreg("EXTENSION")=100,tmpreg("FILE_NAME")=""	; to allow autoconvert
-	;											;,tmpreg("STOP_ENABLE")=0
-	f s="JOURNAL","KEY_SIZE","LOCK_WRITE","NULL_SUBSCRIPTS","RECORD_SIZE" d tmpreg(s) 	;,"STOP_ENABLE"
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE" d tmpseg("BG",s)
-	f s="EXTENSION_COUNT","FILE_TYPE","GLOBAL_BUFFER_COUNT" d tmpseg("BG",s)
-	i v23 s tmpseg("BG","LOCK_SPACE")=20							; to allow autoconvert
-	e  s s="LOCK_SPACE" d tmpseg("BG",s)							; remove else
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","DEFER","EXTENSION_COUNT","FILE_TYPE" d tmpseg("MM",s)
-	i v23 s tmpseg("MM","LOCK_SPACE")=20							; to allow autoconvert
-	e  s s="LOCK_SPACE" d tmpseg("MM",s)							; remove else
-	f s="ACCESS_METHOD","ALLOCATION","BLOCK_SIZE","BUCKET_SIZE","EXTENSION_COUNT" d tmpseg("RMS",s)
-	f s="FILE_TYPE","GLOBAL_BUFFER_COUNT","WINDOW_SIZE" d tmpseg("RMS",s)
-	i v25 s tmpseg("USER","ACCESS_METHOD")="USER",tmpseg("USER","FILE_TYPE")="DYNAMIC"	; to allow autoconvert
-	e  f s="ACCESS_METHOD","FILE_TYPE" d tmpseg("USER",s)					; remove else
-; resolve
-	s s=""
-	f  s s=$o(cregs(s)) q:'$l(s)  i '$d(regs(s)) zm gdeerr("INPINTEG")
-	f  s s=$o(csegs(s)) q:'$l(s)  i '$d(segs(s)) zm gdeerr("INPINTEG")
-	f  s s=$o(cregs(s)) q:'$l(s)  i '$d(xsegs(cregs(s,"DYNAMIC_SEGMENT"))) zm gdeerr("INPINTEG")
-	f  s s=$o(regs(s)) q:'$l(s)  i '$d(segs(regs(s,"DYNAMIC_SEGMENT"))) zm gdeerr("INPINTEG")
-	c file
-	d tmpres
-	f  s s=$o(regs(s)) q:'$l(s)  k regs(s,"LOCK_WRITE") d regres f x=$o(regs(s,x)) q:'$l(x)  d
-	. s:$d(minreg(x))&(regs(s,x)<minreg(x)) regs(s,x)=minreg(x)
-	. s:$d(maxreg(x))&(regs(s,x)>maxreg(x)) regs(s,x)=maxreg(x)
-	f  s s=$o(segs(s)) q:'$l(s)  s am=segs(s,"ACCESS_METHOD"),x="" s:am="RMS" am="BG" d
-	. d segres f  s x=$o(segs(s,am,x)) q:x=""  s segs(s,x)=segs(s,am,x) k segs(s,am,x) d
-	. . s:$d(minseg(am,x))&(segs(s,x)<minseg(am,x)) segs(s,x)=minseg(am,x)
-	. . s:$d(maxseg(am,x))&(segs(s,x)>maxseg(am,x)) segs(s,x)=maxseg(am,x)
-	. f i=1:1:$l(accmeth,"\") s x=$p(accmeth,"\",i) i am'=x k segs(s,x)
-	k minseg("RMS"),maxseg("RMS"),tmpseg("RMS")
-	i tmpacc="RMS" s tmpacc="BG"
-	q
-
-tmpres:	k tmpreg("LOCK_WRITE")
-	s x="" s x=$o(tmpreg(x)) q:x=""  d
-	. s:$d(minreg(x))&(tmpreg(x)<minreg(x)) tmpreg(x)=minreg(x)
-	. s:$d(maxreg(x))&(tmpreg(x)>maxreg(x)) tmpreg(x)=maxreg(x)
-	s am="" f  s am=$o(tmpseq(am)) q:am=""  s x="" f  s x=$o(tmpseq(am,x)) q:x=""  d
-	. s:$d(minseg(am,x))&(tmpseg(am,x)<minseg(am,x)) tmpseg(am,x)=minseg(am,x)
-	. s:$d(maxseg(am,x))&(tmpseg(am,x)>maxseg(am,x)) tmpseg(am,x)=maxseg(am,x)
-	q
-
-regres:	s x="" f  s x=$o(tmpreg(x)) q:x=""  s:'$d(regs(s,x)) regs(s,x)=tmpreg(x)
-	q
-
-segres:	s x="" f  s x=$o(tmpseg(am,x)) q:x=""  s:'$d(segs(s,am,x)) segs(s,am,x)=tmpseg(am,x)
-	q
-
-; verify
-	s x=$$ALL^GDEVERIF
-	i 'x zm gdeerr("INPINTEG")
-	q
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-badfile ;file access failed
-	s:'debug $et="" s abortzs=$zs zm gdeerr("GDREADERR"):file,+abortzs
-	h
-	;
-bin2num:(bin)	; binary number -> number
-	n num,i
-	s num=0
-	f i=1:1:$l(bin) s num=$a(bin,i)*HEX(i-1*2)+num
-	q num
-	;
-str2hex:(in)
-	n i,j,out
-	s out=""
-	f i=1:1 s j=$a(in,i) q:j=-1  f k=j\16,j#16 s out=out_$s(k<10:k,1:$c(k+55))
-	q out
-	;
-num2long:(num)
-	i num<0 zm gdeerr("INPINTEG")
-	i num'<TWO(32) zm gdeerr("INPINTEG")
-	q $c(num/TWO(24),num/TWO(16)#256,num/256#256,num#256)
-	;
-num2shrt:(num)
-	i num<0 zm gdeerr("INPINTEG")
-	i num'<TWO(16) zm gdeerr("INPINTEG")
-	q $c(num\256,num#256)
-	;
-dec2hex:(in)
-	q $$str2hex($$num2long(in))
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-map:
-	i $l(rec)-(rel-1)<SIZEOF("gd_map") d nextrec
-	s x=$$bin2num($e(rec,rel+SIZEOF("mident"),rel+SIZEOF("gd_map")-1))
-	s reglist(x)="",x=x-contents("regions")
-	i x#SIZEOF("gd_region") zm gdeerr("INPINTEG")
-	i x\SIZEOF("gd_region")'<contents("regioncnt") zm gdeerr("INPINTEG")
-	s rel=rel+SIZEOF("gd_map")
-	s abs=abs+SIZEOF("gd_map")
-	q
-region:
-	i $l(rec)-(rel-1)<SIZEOF("gd_region") d nextrec
-	s cregs=cregs+1
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s s=$e(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xregs(abs-1-SIZEOF("gd_header"))=s
-	s cregs(s,"DYNAMIC_SEGMENT")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	s x=cregs(s,"DYNAMIC_SEGMENT")-contents("segments")
-	i x#SIZEOF("gd_segment") zm gdeerr("INPINTEG")
-	i x\SIZEOF("gd_segment")'<contents("segmentcnt") zm gdeerr("INPINTEG")
-	i $e(rec,rel,rel+3)'=$c(0,0,0,0) zm gdeerr("INPINTEG")						; static segment
-	s rel=rel+4
-	s cregs(s,"RECORD_SIZE")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	s cregs(s,"KEY_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	i $e(rec,rel)'=ZERO zm gdeerr("INPINTEG")							; OPEN state
-	s rel=rel+1
-	s cregs(s,"LOCK_WRITE")=$$bin2num($e(rec,rel)),rel=rel+1
-	s cregs(s,"NULL_SUBSCRIPTS")=$$bin2num($e(rec,rel)),rel=rel+1
-	s cregs(s,"JOURNAL")=$$bin2num($e(rec,rel)),rel=rel+1
-	i $e(rec,rel,rel+7)'=$tr($j("",8)," ",ZERO) zm gdeerr("INPINTEG")				; gbl_lk_root, lcl_lk_root
-	s rel=rel+8
-	s cregs(s,"ALLOCATION")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4					; journal options
-	s cregs(s,"EXTENSION")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s cregs(s,"BUFFER_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s cregs(s,"BEFORE_IMAGE")=$$bin2num($e(rec,rel)),rel=rel+1
-	i 'v23,'v24,$e(rec,rel,rel+10)'=$tr($j("",11)," ",ZERO) zm gdeerr("INPINTEG")			; 7 filler + 4 for jnllsb
-	s rel=rel+11
-	s l=$$bin2num($e(rec,rel)),rel=rel+1
-	s cregs(s,"FILE_NAME")=$e(rec,rel,rel+l-1),rel=rel+SIZEOF("jnl_filename")
-	i $e(rec,rel,rel+46)'=$tr($j("",47)," ",ZERO) zm gdeerr("INPINTEG")				; reserved
-	s rel=rel+47
-	s abs=abs+SIZEOF("gd_region")
-	q
-segment:
-	i $l(rec)-(rel-1)<SIZEOF("gd_segment") d nextrec
-	s csegs=csegs+1
-	s x=$$bin2num($e(rec,rel+SIZEOF("am_offset"),rel+SIZEOF("am_offset")+3))
-	s am=$s(x=0:"RMS",x=1:"BG",x=2:"MM",x=4:"USER",1:"ERROR")
-	i am="ERROR" zm gdeerr("INPINTEG")
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s s=$e(rec,rel,rel+l-1),rel=rel+MAXSEGLN,xsegs(abs-1-SIZEOF("gd_header"))=s
-	s (csegs(s,"ACCESS_METHOD"),csegs(s,am,"ACCESS_METHOD"))=am
-	s l=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	s csegs(s,am,"FILE_NAME")=$e(rec,rel,rel+l-1),rel=rel+SIZEOF("file_spec")
-	s x=$$bin2num($e(rec,rel)),rel=rel+1
-	s csegs(s,am,"FILE_TYPE")=$s(x=0:"DYNAMIC",1:"ERROR")
-	i csegs(s,am,"FILE_TYPE")="ERROR" zm gdeerr("INPINTEG")
-	i "USER"=am s rel=rel+8
-	e  s csegs(s,am,"BLOCK_SIZE")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	e  s csegs(s,am,"ALLOCATION")=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	e  s csegs(s,am,"EXTENSION_COUNT")=$$bin2num($e(rec,rel,rel+1)),rel=rel+2
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; reserved for clb
-	s rel=rel+4
-	i "BG|MM"[am s csegs(s,am,"LOCK_SPACE")=$s(v23:20,1:$$bin2num($e(rec,rel)))		; allow autoconv
-	s rel=rel+1
-	i 'v24 i $e(rec,rel,rel+3)'=".DAT" zm gdeerr("INPINTEG")				; if to allow autoconv
-	s rel=rel+4
-	i $e(rec,rel,rel+3)'=$tr($j("",4)," ",ZERO) zm gdeerr("INPINTEG")			; filler
-	s rel=rel+4
-	s rel=rel+4									; access method already processed
-	s xfile(s)=$$bin2num($e(rec,rel,rel+3)),rel=rel+4
-	i "MM"=am s csegs(s,am,"DEFER")=$$bin2num($e(rec,rel+36))
-	s rel=rel+96
-	s abs=abs+SIZEOF("gd_segment")
-	q
-fabdata:(datasize,offset)
-	n fna,x,y
-	i $l(rec)-(rel-1)<datasize d nextrec
-	s x=$e(rec,rel+1+offset,rel+datasize-1)
-	s fna=$$bin2num($e(x,RMS("FAB$L_FNA"),RMS("FAB$L_FNA")+3))
-	s y=fna-contents("segments")
-	i y#SIZEOF("gd_segment")'=SIZEOF("fna_offset") zm gdeerr("INPINTEG")
-	i y\SIZEOF("gd_segment")'<contents("segmentcnt") zm gdeerr("INPINTEG")
-	s y=fna-SIZEOF("fna_offset")
-	i '$d(xsegs(y)) zm gdeerr("INPINTEG")
-	s s=xsegs(y)
-	i '$d(csegs(s,"ACCESS_METHOD")) zm gdeerr("INPINTEG")
-	s am=csegs(s,"ACCESS_METHOD")
-	i csegs(s,am,"ALLOCATION")'=$$bin2num($e(x,RMS("FAB$L_ALQ"),RMS("FAB$L_ALQ")+3)) zm gdeerr("INPINTEG")
-	i csegs(s,am,"EXTENSION_COUNT")'=$$bin2num($e(x,RMS("FAB$W_DEQ"),RMS("FAB$W_DEQ")+1)) zm gdeerr("INPINTEG")
-	i "RMS"=am s csegs(s,am,"WINDOW_SIZE")=$$bin2num($e(x,RMS("FAB$B_RTV")))
-	s y=$$bin2num($e(x,RMS("FAB$L_DNA"),RMS("FAB$L_DNA")+3))-contents("segments")
-	i 'v24 i y#SIZEOF("gd_segment")'=SIZEOF("dna_offset") zm gde("INPINTEG")		; if to allow autoconvert
-	i $l(csegs(s,am,"FILE_NAME"))'=$$bin2num($e(x,RMS("FAB$B_FNS"))) zm gdeerr("INPINTEG")
-	i 'v24 i $$bin2num($e(x,RMS("FAB$B_DNS")))'=4						; if to allow autoconvert
-	i csegs(s,am,"BLOCK_SIZE")'=$$bin2num($e(x,RMS("FAB$W_BLS"),RMS("FAB$W_BLS")+1)) zm gdeerr("INPINTEG")
-	i "RMS"=am s csegs(s,am,"BUCKET_SIZE")=$$bin2num($e(x,RMS("FAB$B_BKS")))
-	i "BG|RMS"[am s csegs(s,am,"GLOBAL_BUFFER_COUNT")=$$bin2num($e(x,RMS("FAB$W_GBC"),RMS("FAB$W_GBC")+1))
-	s rel=rel+datasize,abs=abs+datasize
-	q
-name:
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>SIZEOF("mident") zm gdeerr("INPINTEG")
-	i $l(rec)-(rel-1)<l d nextrec
-	s s=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>MAXREGLN zm gdeerr("INPINTEG")
-	i $l(rec)-(rel-1)<l d nextrec
-	s nams(s)=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-gdereg:
-	s s=$$gderead(MAXREGLN)
-	s regs(s,"DYNAMIC_SEGMENT")=$$gderead(MAXSEGLN)
-	s regs(s,"ALLOCATION")=$$gderead(10)
-	s regs(s,"EXTENSION")=$$gderead($l(maxreg("EXTENSION")))
-	s regs(s,"FILE_NAME")=$$gderead(SIZEOF("jnl_filename"))
-	s regs(s,"BUFFER_SIZE")=$$gderead(5)
-	i v24 s regs(s,"ALLOCATION")=100,regs(s,"EXTENSION")=100,regs(s,"FILE_NAME")=""		; to allow autoconvert
-	i  s regs(s,"BUFFER_SIZE")=128,regs(s,"BEFORE_IMAGE")=1	;,regs(s,"STOP_ENABLE")=0	; to allow autoconvert
-	i  s x=$$gderead(5),x=$$gderead(5)							; to allow autoconvert
-	e  s regs(s,"BEFORE_IMAGE")=$$gderead(1) ;s regs(s,""STOP_ENABLE")=$$gderead(1)		; remove else
-	s regs(s,"JOURNAL")=$$gderead(1)
-	s regs(s,"KEY_SIZE")=$$gderead(5)
-	s regs(s,"LOCK_WRITE")=$$gderead(1)
-	s regs(s,"NULL_SUBSCRIPTS")=$$gderead(1)
-	s regs(s,"RECORD_SIZE")=$$gderead(5)
-	q
-gdeseg:
-	s s=$$gderead(MAXSEGLN)
-	s segs(s,"ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"BG","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"BG","ALLOCATION")=$$gderead(10)
-	s segs(s,"BG","BLOCK_SIZE")=$$gderead($l(maxseg("BG","BLOCK_SIZE")))
-	s segs(s,"BG","EXTENSION_COUNT")=$$gderead($l(maxseg("BG","EXTENSION_COUNT")))
-	s segs(s,"BG","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"BG","FILE_TYPE")=$$gderead(7)
-	s segs(s,"BG","GLOBAL_BUFFER_COUNT")=$$gderead(5)
-	s segs(s,"BG","LOCK_SPACE")=$s(v23:20,1:$$gderead(3))				; to allow autoconvert
-	s segs(s,"MM","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"MM","ALLOCATION")=$$gderead(10)
-	s segs(s,"MM","BLOCK_SIZE")=$$gderead($l(maxseg("MM","BLOCK_SIZE")))
-	s segs(s,"MM","DEFER")=$$gderead(1)
-	s segs(s,"MM","EXTENSION_COUNT")=$$gderead($l(maxseg("MM","EXTENSION_COUNT")))
-	s segs(s,"MM","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"MM","FILE_TYPE")=$$gderead(7)
-	s segs(s,"MM","LOCK_SPACE")=$s(v23:20,1:$$gderead(3))				; to allow autoconvert
-	s segs(s,"RMS","ACCESS_METHOD")=$$gderead(4)
-	s segs(s,"RMS","ALLOCATION")=$$gderead(10)
-	s segs(s,"RMS","BLOCK_SIZE")=$$gderead(5)
-	s segs(s,"RMS","BUCKET_SIZE")=$$gderead(5)
-	s segs(s,"RMS","EXTENSION_COUNT")=$$gderead($l(maxseg("RMS","EXTENSION_COUNT")))
-	s segs(s,"RMS","FILE_NAME")=$$gderead(SIZEOF("file_spec"))
-	s segs(s,"RMS","FILE_TYPE")=$$gderead(7)
-	s segs(s,"RMS","GLOBAL_BUFFER_COUNT")=$$gderead(5)
-	s segs(s,"RMS","WINDOW_SIZE")=$$gderead(5)
-	s segs(s,"USER","ACCESS_METHOD")=$s(v25:"USER",1:$$gderead(4))				; to allow autoconvert
-	s segs(s,"USER","FILE_NAME")=$s(v25:"MUMPS",1:$$gderead(SIZEOF("file_spec")))		; to allow autoconvert
-	s segs(s,"USER","FILE_TYPE")=$s(v25:"DYNAMIC",1:$$gderead(7))				; to allow autoconvert
-	q
-gderead:(max)
-	n s
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i l>max zm gdeerr("INPINTEG")
-	i $l(rec)-(rel-1)<l d nextrec
-	s s=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q s
-	;
-tmpreg:(s)
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $l(rec)-(rel-1)<l d nextrec
-	s tmpreg(s)=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-tmpseg:(a,s)
-	i $l(rec)-(rel-1)<3 d nextrec
-	s l=$e(rec,rel,rel+2),rel=rel+3,abs=abs+3
-	i $l(rec)-(rel-1)<l d nextrec
-	s tmpseg(a,s)=$e(rec,rel,rel+l-1),rel=rel+l,abs=abs+l
-	q
-nextrec:
-	n nextrec
-	u file r nextrec
-	i debug u @useio
-	s rec=$e(rec,rel,$l(rec))_nextrec,rel=1
-	q
-
-;----------------------------------------------------------------------------------------------------------------------------------
-
-gdeinit:
-	s accmeth="\BG\MM\RMS\USER"
-	s hdrlab="GTCGBLDIR004"
-	s SIZEOF("am_offset")=296
-	s SIZEOF("blk_hdr")=7
-	s SIZEOF("dna_offset")=288
-	s SIZEOF("file_spec")=255
-	s SIZEOF("fna_offset")=19
-	s SIZEOF("gd_header")=288
-	s SIZEOF("gd_contents")=64
-	s SIZEOF("gd_map")=12
-	s SIZEOF("gd_region")=160
-	s SIZEOF("gd_segment")=400
-	s SIZEOF("gds_filedata")=80
-	s SIZEOF("jnl_filename")=49
-	s SIZEOF("mident")=8
-	s SIZEOF("rec_hdr")=3
-	s SIZEOF("dsk_blk")=512
-	s SIZEOF("rms_filedata")=224
-	s SIZEOF("struct FAB")=80,SIZEOF("struct RAB")=68
-;
-	s MAXNAMLN=SIZEOF("mident"),MAXREGLN=15,MAXSEGLN=15
-;define offsets into rms structures
-	;fab
-	;s RMS("FAB$B_BID")=0
-	s RMS("FAB$B_BLN")=1
-	;s RMS("FAB$W_IFI")=2
-	s RMS("FAB$L_FOP")=4
-	;s RMS("FAB$L_STS")=8
-	s RMS("FAB$L_STV")=12
-	s RMS("FAB$L_ALQ")=16
-	s RMS("FAB$W_DEQ")=20
-	s RMS("FAB$B_FAC")=22
-	;s RMS("FAB$B_SHR")=23
-	;s RMS("FAB$L_CTX")=24
-	s RMS("FAB$B_RTV")=28
-	;s RMS("FAB$B_ORG")=29
-	;s RMS("FAB$B_RAT")=30
-	;s RMS("FAB$B_RFM")=31
-	;s RMS("FAB$L_JNL")=32
-	s RMS("FAB$L_XAB")=36
-	;s RMS("FAB$L_NAM")=40
-	s RMS("FAB$L_FNA")=44
-	s RMS("FAB$L_DNA")=48
-	s RMS("FAB$B_FNS")=52
-	s RMS("FAB$B_DNS")=53
-	;s RMS("FAB$W_MRS")=54
-	;s RMS("FAB$L_MRN")=56
-	s RMS("FAB$W_BLS")=60
-	s RMS("FAB$B_BKS")=62
-	s RMS("FAB$B_FSZ")=63
-	;s RMS("FAB$L_DEV")=64
-	;s RMS("FAB$L_SDC")=68
-	s RMS("FAB$W_GBC")=72
-	;s RMS("FAB$B_ACMODES")=74
-	;s RMS("FAB$B_RCF")=75
-	;rab
-	s RMS("RAB$L_FAB")=60
-	s RMS("RAB$L_XAB")=64
-; rms
-	s minseg("RMS","ALLOCATION")=10,minseg("RMS","BLOCK_SIZE")=SIZEOF("dsk_blk"),minseg("RMS","BUCKET_SIZE")=0
-	s minseg("RMS","EXTENSION_COUNT")=0,minseg("RMS","GLOBAL_BUFFER_COUNT")=0,minseg("RMS","WINDOW_SIZE")=0
-	s maxseg("RMS","ALLOCATION")=TWO(24),maxseg("RMS","BLOCK_SIZE")=HEX(4)-SIZEOF("dsk_blk"),maxseg("RMS","BUCKET_SIZE")=63
-	s maxseg("RMS","EXTENSION_COUNT")=HEX(4)-1,maxseg("RMS","GLOBAL_BUFFER_COUNT")=32767,maxseg("RMS","WINDOW_SIZE")=255
-	q
diff --git a/sr_vvms/gdeput.m b/sr_vvms/gdeput.m
index 4e870a8..28fa098 100644
--- a/sr_vvms/gdeput.m
+++ b/sr_vvms/gdeput.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -10,34 +10,55 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 gdeput:	;output the result of the session to the global directory file
 GDEPUT()
-	n rec,gds,cregs,csegs,cregcnt,csegcnt,maxrecsize,mapcnt,map
-	d PUTMAKE^GDEMAP
-	s s="",gdeputzs=""
-	f mapcnt=0:1 s s=$o(map(s)) q:'$l(s)  s cregs(map(s))=""
+	n rec,gds,cregs,csegs,cregcnt,csegcnt,maxrecsize,mapcnt,map,hasSpanGbls,isSpanned,curMapSpanning,prevMapSpanning
+	n varmapslen,vargblnamelen,tmplen,ptrsize,varmapoff,gnamcnt,gblnamelen,filler16byte,filler12byte
+	d CREATEGLDMAP^GDEMAP
+	s ptrsize=4
+	s s="",gdeputzs="",varmapslen=0,mapcnt=0,hasSpanGbls=0
+	f  s s=$o(map(s)),tmplen=$l(s) q:'tmplen  d
+	. s cregs(map(s))=""
+	. s varmapslen=(varmapslen+tmplen+2) ; varmapslen needs to account 2 null terminating bytes
+	. s varmapslen($incr(mapcnt))=tmplen
+	. s gblnamelen=$zf(s,ZERO)
+	. i gblnamelen'=0 s hasSpanGbls=1
+	. s gblnamelen=$s(gblnamelen=0:tmplen,1:gblnamelen-2)
+	. s vargblnamelen(mapcnt)=gblnamelen
+	s varmapslen=(varmapslen+ptrsize-1)\ptrsize*ptrsize	; do 8-byte or 4-byte rounding up as appropriate
 	s maxrecsize=0
 	f cregcnt=0:1 s s=$o(cregs(s)) q:'$l(s)  d
 	. s csegs(regs(s,"DYNAMIC_SEGMENT"))=s i maxrecsize<regs(s,"RECORD_SIZE") s maxrecsize=regs(s,"RECORD_SIZE")
+	. s isSpanned(s)=0
 	f csegcnt=0:1 s s=$o(csegs(s)) q:'$l(s)  d fdatum
 	i cregcnt'=csegcnt d error1
-	s x=SIZEOF("gd_contents")+(mapcnt*SIZEOF("gd_map")),s=""
+	s x=SIZEOF("gd_contents")+(mapcnt*SIZEOF("gd_map"))+varmapslen,s=""
 	f i=0:1 s s=$o(cregs(s)) q:'$l(s)  s cregs(s,"offset")=i*SIZEOF("gd_region")+x
 	s x=x+(cregcnt*SIZEOF("gd_region"))
 	f i=0:1 s s=$o(csegs(s)) q:'$l(s)  s csegs(s,"offset")=i*SIZEOF("gd_segment")+x
 	s x=x+(csegcnt*SIZEOF("gd_segment"))
+	s gnamcnt=gnams
 	s rec=""
+	s $p(filler12byte,ZERO,12)=ZERO
+	s $p(filler16byte,ZERO,16)=ZERO
 ; contents
-	s rec=rec_$c(0,0,0,0)									; not used
-	s rec=rec_$$num2bin(4,maxrecsize)							; max rec size
+	s rec=rec_$tr($j("",ptrsize)," ",ZERO)			; not used (gd_addr.local_locks)
+	s rec=rec_$$num2bin(4,maxrecsize)			; max rec size
 	s filesize=SIZEOF("gd_contents")
-	s rec=rec_$$num2bin(2,mapcnt)_$$num2bin(2,cregcnt)_$$num2bin(2,csegcnt)_$$num2bin(2,0)	; maps,regs,segs,filler
-	s rec=rec_$$num2bin(4,filesize)								; mapptr
-	s filesize=filesize+(mapcnt*SIZEOF("gd_map"))
-	s rec=rec_$$num2bin(4,filesize)								; regionptr
+	s rec=rec_$$num2bin(4,mapcnt)_$$num2bin(4,cregcnt)	; maps,regs
+	s rec=rec_$$num2bin(4,csegcnt)_$$num2bin(4,gnamcnt) 	; segs,gblnames
+	s rec=rec_$$num2bin(4,varmapslen)			; varmapslen
+	s rec=rec_$$num2bin(ptrsize,filesize)			; mapptr
+	s varmapoff=filesize+(mapcnt*SIZEOF("gd_map"))     	; offset of variable length map section
+	s filesize=varmapoff+varmapslen
+	s rec=rec_$$num2bin(ptrsize,filesize)			; regionptr
 	s filesize=filesize+(cregcnt*SIZEOF("gd_region"))
-	s rec=rec_$$num2bin(4,filesize)								; segmentptr
-	s filesize=filesize+(csegcnt*SIZEOF("gd_segment")),base=filesize
-	s rec=rec_$tr($j("",12)," ",ZERO)							; reserved
-	s rec=rec_$$num2bin(4,filesize)								; end
+	s rec=rec_$$num2bin(ptrsize,filesize)			; segmentptr
+	s filesize=filesize+(csegcnt*SIZEOF("gd_segment"))
+	s rec=rec_$$num2bin(ptrsize,filesize)			; gblnameptr
+	s filesize=filesize+(gnamcnt*SIZEOF("gd_gblname"))
+	s rec=rec_$tr($j("",(3*ptrsize))," ",ZERO)		; reserved
+	s rec=rec_$$num2bin(ptrsize,filesize)			; end
+	s rec=rec_$$num2bin(4,hasSpanGbls)			; has_span_gbls
+	s rec=rec_filler12byte					; for runtime filler
 	s rec=hdrlab_$$num2bin(4,$l(hdrlab)+4+filesize)_rec
 	i create zm gdeerr("GDCREATE"):file
 	e  s:$ZVersion["VMS" $p(file,";",2)=$p(file,";",2)+1  zm gdeerr("GDUPDATE"):file
@@ -47,12 +68,18 @@ GDEPUT()
 	s chset=$SELECT($ZV["OS390":"ISO8859-1",1:"")
 	o tempfile:(rewind:noreadonly:newversion:recordsize=512:fixed:blocksize=512:exception=gdexcept:ochset=chset)
 ; maps
-	s s=""
-	f  s s=$o(map(s)) q:'$l(s)  d map
+	s s="",curMapSpanning=0,prevMapSpanning=0
+	f i=1:1 s s=$o(map(s)) q:'$l(s)  d mapfixed(i,s)
+	f i=1:1 s s=$o(map(s)) q:'$l(s)  d mapvariable(i,s)
+	; write padding if not 4-byte aligned after variable maps section
+	s tmplen=varmapoff#ptrsize
+	i tmplen s tmplen=ptrsize-tmplen,rec=rec_$tr($j("",tmplen)," ",ZERO)
 ; cregs
 	f  s s=$o(cregs(s)) q:'$l(s)  d cregion
 ; csegs
 	f  s s=$o(csegs(s)) q:'$l(s)  d csegment
+; cgnams
+	f  s s=$o(gnams(s)) q:'$l(s)  d cgblname(s)
 ; template access method
 	i accmeth'[("\"_tmpacc) d error1
 	s rec=rec_$tr($j($l(tmpacc),3)," ",0)
@@ -62,7 +89,7 @@ GDEPUT()
 	f i=2:1:$l(accmeth,"\") s am=$p(accmeth,"\",i) s s="" d
 	. f  s s=$o(tmpseg(am,s)) q:'$l(s)  s rec=rec_$tr($j($l(tmpseg(am,s)),3)," ",0),rec=rec_tmpseg(am,s)
 	u tempfile
-	f  s record=$e(rec,1,512),rec=$e(rec,513,9999) q:'$l(record)  w record,!
+	f  s record=$e(rec,1,512),rec=$e(rec,513,MAXSTRLEN) q:'$l(record)  w record,!
 	u @useio
 	i $ZV'["VMS" o file c file:delete
 	c tempfile:rename=file
@@ -75,10 +102,26 @@ fdatum:
 	s filetype=$s((x="BG")!(x="MM"):"GDS",x="USER":"USER",1:"ERROR")
 	i filetype="ERROR" d error1
 	q
-map:
+mapfixed:(i,key)
+	n tmpmaplen,tmpnamelen,reg
 	d writerec
-	i $l(s)'=SIZEOF("mident") d error1
-	s rec=rec_s_$$num2bin(4,cregs(map(s),"offset"))
+	s tmpmaplen=varmapslen(i)
+	s rec=rec_$$num2bin(4,varmapoff)		; gvkey.offset
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0) 	; add padding
+	s reg=map(key)
+	s rec=rec_$$num2bin(4,cregs(reg,"offset"))	; reg.offset
+	i (gtm64=TRUE) s rec=rec_$$num2bin(4,0)		; add padding
+	s tmpnamelen=vargblnamelen(i)
+	s rec=rec_$$num2bin(4,tmpnamelen)		; gvname_len
+	s rec=rec_$$num2bin(4,tmpmaplen+1)		; gvkey_len
+	s varmapoff=varmapoff+tmpmaplen+2
+	s curMapSpanning=(tmpnamelen'=tmpmaplen)
+	i (curMapSpanning!prevMapSpanning) s isSpanned(reg)=1
+	s prevMapSpanning=curMapSpanning
+	q
+mapvariable:(i,key)
+	d writerec
+	s rec=rec_key_ZERO_ZERO
 	q
 cregion:
 	d writerec
@@ -102,6 +145,8 @@ cregion:
 	s rec=rec_$$num2bin(1,$l(regs(s,"FILE_NAME")))
 	s rec=rec_regs(s,"FILE_NAME")_$tr($j("",SIZEOF("file_spec")-$l(regs(s,"FILE_NAME")))," ",ZERO)
 	s rec=rec_$tr($j("",8)," ",ZERO)							; reserved
+	s rec=rec_$$num2bin(4,isSpanned(s))							; is_spanned
+	s rec=rec_filler12byte									; runtime filler
 	q
 csegment:
 	d writerec
@@ -123,11 +168,24 @@ csegment:
 	s rec=rec_$$num2bin(4,segs(s,"LOCK_SPACE"))
 	s rec=rec_$$num2bin(4,segs(s,"GLOBAL_BUFFER_COUNT"))
 	s rec=rec_$$num2bin(4,segs(s,"RESERVED_BYTES"))
+	s rec=rec_$$num2bin(4,segs(s,"MUTEX_SLOTS"))
 	s x=$s(am="BG":1,am="MM":2,am="USER":4,1:-1)
 	i x=-1 d error1
 	s rec=rec_$$num2bin(4,x)
 	s rec=rec_$$num2bin(4,0)		; file_cntl ptr
 	s rec=rec_$$num2bin(4,0)		; repl_list ptr
+	s rec=rec_filler16byte			; runtime filler
+	q
+cgblname:(s)
+	n len,coll,ver
+	d writerec
+	s len=$zl(s)
+	s rec=rec_s_$tr($j("",SIZEOF("mident")-len)," ",ZERO)
+	s rec=rec_$$num2bin(4,gnams(s,"COLLATION"))
+	s coll=gnams(s,"COLLATION")
+	s rec=rec_$$num2bin(4,coll)
+	s ver=$view("YCOLLATE",coll)
+	s rec=rec_$$num2bin(4,ver)
 	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
@@ -142,12 +200,12 @@ num2tiny:(num)
 num2shrt:(num)
 	i (num<0)!(num'<TWO(16)) d error1
 	i endian=TRUE q $c(num\256,num#256)
-	e  q $c(num#256,num\256)
+	q $c(num#256,num\256)
 	;
 num2long:(num)
 	i (num<0)!(num'<TWO(32)) d error1
 	i endian=TRUE q $c(num/16777216,num/65536#256,num/256#256,num#256)
-	e  q $c(num#256,num/256#256,num/65536#256,num/16777216)
+	q $c(num#256,num/256#256,num/65536#256,num/16777216)
 
 num2error:()
 	d error1
@@ -164,11 +222,14 @@ error1:
 	zm $$fatal(gdeerr("VERIFY")):"FAILED"
 	;
 writerec:
-	i $l(rec)<512 q
-	s record=$e(rec,1,512),rec=$e(rec,513,9999)
+	n len
+	s len=$l(rec)
+	i len<512 q
+	s len=len\512*512
+	s record=$e(rec,1,len),rec=$e(rec,len+1,MAXSTRLEN)
+	; At this point, "rec" is guaranteed to be less than 512 bytes.
 	u tempfile w record,! u @useio
 	q
-	;
 writeerr
 	u @useio
 	c tempfile:delete
diff --git a/sr_vvms/gdeverif.m b/sr_vvms/gdeverif.m
index f336854..50f9894 100644
--- a/sr_vvms/gdeverif.m
+++ b/sr_vvms/gdeverif.m
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2006, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2006, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -12,6 +12,7 @@ verify:	;implement the verb: VERIFY, also invoked from show and GDEGET
 ALL()	;external
 	n verified,gqual s verified=1
 	s gqual="NAME" d ALLNAM
+	s gqual="GBLNAME" d ALLGBL
 	s gqual="REGION" d ALLREG,usereg
 	s gqual="SEGMENT" d ALLSEG,useseg
 	d ALLTEM
@@ -22,8 +23,34 @@ ALL()	;external
 ; called from GDEPARSE.M
 
 ALLNAM
-	n NAME s NAME=""
-	f  s NAME=$o(nams(NAME)) q:'$l(NAME)  d name1
+	n NAME,hassubs s NAME="",hassubs=0
+	f  s NAME=$o(nams(NAME)) q:'$zl(NAME)  d name1  i +$g(nams(NAME,"NSUBS")) s hassubs=1
+	; if using subscripted names, check that all regions where a globals spans has STDNULLCOLL set to TRUE
+	i hassubs d
+	. n map,currMap,nextMap,nextMapHasSubs,reg,gblname,mapreg
+	. d NAM2MAP^GDEMAP
+	. s currMap="",nextMap="",nextMapHasSubs=0
+	. f  s currMap=$o(map(currMap),-1) q:currMap="#)"  d
+	. . s hassubs=$zf(currMap,ZERO,0)
+	. . ; Check if current map entry has subscripts. If so this map entry should have STDNULLCOLL set.
+	. . ; Also check if next map entry had subscripts. If so this map entry should have STDNULLCOLL set
+	. . ; 	That is because a portion of the global in the next map entry lies in the current map entry region.
+	. . i (hassubs!nextMapHasSubs) d
+	. . . ; check if region has STDNULLCOLL defined to true
+	. . . s reg=map(currMap)
+	. . . i '+$g(regs(reg,"STDNULLCOLL")) d
+	. . . . s verified=0
+	. . . . i nextMapHasSubs d
+	. . . . . s gblname=$ze(nextMap,1,nextMapHasSubs-2)
+	. . . . . i '$d(mapreg(reg,gblname)) zm gdeerr("STDNULLCOLLREQ"):reg:"^"_gblname s mapreg(reg,gblname)=""
+	. . . . i hassubs d
+	. . . . . s gblname=$ze(currMap,1,hassubs-2)
+	. . . . . i '$d(mapreg(reg,gblname)) zm gdeerr("STDNULLCOLLREQ"):reg:"^"_gblname s mapreg(reg,gblname)=""
+	. . s nextMapHasSubs=hassubs,nextMap=currMap
+	q
+ALLGBL
+	n GBLNAME s GBLNAME=""
+	f  s GBLNAME=$o(gnams(GBLNAME)) q:""=GBLNAME  d gblname1
 	q
 ALLREG
 	n REGION s REGION=""
@@ -40,8 +67,29 @@ ALLSEG
 	f  s s=$o(segs(s)) q:'$l(s)  d:$d(reffils(segs(s,"FILE_NAME"))) dupfile s reffils(segs(s,"FILE_NAME"),s)=""
 	q
 NAME
-	i '$d(nams(NAME)) k verified zm $$info(gdeerr("OBJNOTFND")):"Name":$s(NAME'="#":NAME,1:"Local Locks") q
-name1:	i '$d(regs(nams(NAME))) s verified=0 zm gdeerr("MAPBAD"):"Region":nams(NAME):"Name":$s(NAME'="#":NAME,1:"Local Locks")
+	i '$d(nams(NAME)) k verified d  q
+	. zm $$info(gdeerr("OBJNOTFND")):"Name":$s(NAME'="#":$$namedisp^GDESHOW(NAME,0),1:"Local Locks")
+name1:	i '$d(regs(nams(NAME))) d
+	. s verified=0
+	. zm gdeerr("MAPBAD"):"Region":nams(NAME):"Name":$s(NAME'="#":$$namedisp^GDESHOW(NAME,0),1:"Local Locks")
+	q
+GBLNAME
+	i '$d(gnams(GBLNAME)) k verified zm $$info(gdeerr("OBJNOTFND")):"Global Name":GBLNAME q
+gblname1:
+	n s,sval,errissued s s=""
+	f  s s=$o(gnams(GBLNAME,s)) q:""=s  s sval=gnams(GBLNAME,s) d
+	. s errissued=0
+	. i $d(mingnam(s)),mingnam(s)>sval s errissued=1 zm gdeerr("VALTOOSMALL"):sval:mingnam(s):s
+	. i $d(maxgnam(s)),maxgnam(s)<sval s errissued=1 zm gdeerr("VALTOOBIG"):sval:maxgnam(s):s
+	. i errissued s verified=0 zm gdeerr("GBLNAMEIS"):GBLNAME
+	. i (s="COLLATION") d
+	. . i $d(gnams(GBLNAME,"COLLVER")) d
+	. . . d chkcoll^GDEPARSE(sval,GBLNAME,gnams(GBLNAME,"COLLVER"))
+	. . e  d chkcoll^GDEPARSE(sval,GBLNAME)
+	; now that all gblnames and names have been read, do some checks between them
+	; ASSERT : i $d(namrangeoverlap)  zsh "*"  h
+	d gblnameeditchecks^GDEPARSE("*",0)	; check all name specifications are good given the gblname collation settings
+	; ASSERT : i $d(namrangeoverlap)  zsh "*"  h
 	q
 REGION
 	i '$d(regs(REGION)) k verified zm $$info(gdeerr("OBJNOTFND")):"Region":REGION q
@@ -112,7 +160,7 @@ segelm:	i s'="FILE_NAME",'$l(tmpseg(am,s)) zm $$info(gdeerr("QUALBAD")):s
 rec2blk:	s y=s-f-SIZEOF("blk_hdr")
 	i x>y s verified=0 zm gdeerr("RECSIZIS"):x,gdeerr("REGIS"):REGION,gdeerr("RECTOOBIG"):s:f:y,gdeerr("SEGIS"):am:SEGMENT
 	q
-buf2blk:	i REGION="TEMPLATE","USER"[am,am'=tmpacc q
+buf2blk:	i REGION="TEMPLATE" q
 	i "USER"[am s verified=0 zm gdeerr("NOJNL"):am,gdeerr("REGIS"):REGION,gdeerr("SEGIS"):am:SEGMENT
 	s y=s/256
 	i y>x s verified=0 zm gdeerr("BUFSIZIS"):x,gdeerr("REGIS"):REGION,gdeerr("BUFTOOSMALL"):s:y,gdeerr("SEGIS"):am:SEGMENT
@@ -120,12 +168,6 @@ buf2blk:	i REGION="TEMPLATE","USER"[am,am'=tmpacc q
 mmbichk:	i REGION="TEMPLATE",am="MM",tmpacc'="MM" q
 	i am="MM" s verified=0 zm gdeerr("MMNOBEFORIMG"),gdeerr("REGIS"):REGION,gdeerr("SEGIS"):am:SEGMENT
 	q
-prefix(str1,str2)  ;check whether str1 is a prefix of str2
-	n len1,len2
-	s len1=$l(str1),len2=$l(str2)
-	q:(len1>len2)!'len1 0
-	i ($e(str2,1,len1)=str1) q 1
-	q 0
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
 ; called from GDEADD.M and GDECHANG.M
@@ -140,6 +182,8 @@ RQUALS(rquals)
 	s x="RECORD_SIZE",x=$s($d(rquals(x)):rquals(x),$d(regs(REGION,x)):regs(REGION,x),1:tmpreg(x))
 	i s+4>x s verified=0 zm gdeerr("KEYSIZIS"):s,gdeerr("KEYTOOBIG"):x:x-4,gdeerr("REGIS"):REGION
 	i REGION="TEMPLATE" s s=tmpseg(tmpacc,"BLOCK_SIZE"),f=tmpseg(tmpacc,"RESERVED_BYTES")
+	; note "else" used in two consecutive lines intentionally (instead of using a do block inside one else).
+	; this is because we want the QUIT to quit out of RQUALS and the NEW of SEGMENT,am to happen at the RQUALS level.
 	e  s s="DYNAMIC_SEGMENT",s=$s($d(rquals(s)):rquals(s),$d(regs(REGION,s)):regs(REGION,s),1:0)
 	e  q:'$d(segs(s)) verified n SEGMENT,am d
 	. s SEGMENT=s,am=segs(s,"ACCESS_METHOD"),s=$g(segs(s,"BLOCK_SIZE")),f=$g(segs(s,"RESERVED_BYTES"))
@@ -160,7 +204,8 @@ SQUALS(am,squals)
 	s s="WINDOW_SIZE"
 	i SEGMENT="TEMPLATE" s x=tmpreg("RECORD_SIZE") d segreg q verified
 	n REGION s REGION=""
-	f  s REGION=$o(regs(REGION)) q:'$l(REGION)  i regs(REGION,"DYNAMIC_SEGMENT")=SEGMENT s s=regs(REGION,"RECORD_SIZE") d segreg
+	f  s REGION=$o(regs(REGION)) q:'$l(REGION)  d
+	. i regs(REGION,"DYNAMIC_SEGMENT")=SEGMENT s s=regs(REGION,"RECORD_SIZE") d segreg
 	q verified
 segreg:
 	i am'="USER" d
@@ -168,9 +213,9 @@ segreg:
 	. s f="RESERVED_BYTES",f=$s($d(squals(f)):squals(f),$d(segs(SEGMENT,s)):seg(SEGMENT,f),1:tmpseg(am,f))
 	. s x="RECORD_SIZE",x=$s($d(regs(REGION,x)):regs(REGION,x),1:tmpreg(x))
 	. d rec2blk
-	i '$s(SEGMENT="TEMPLATE":tmpreg("JOURNAL"),1:regs(REGION,"JOURNAL")) q
+	i '$s(SEGMENT="TEMPLATE":0,1:regs(REGION,"JOURNAL")) q
 	s x=$s(SEGMENT="TEMPLATE":tmpreg("BUFFER_SIZE"),1:regs(REGION,"BUFFER_SIZE")) d buf2blk
-	i nommbi,$s(SEGMENT="TEMPLATE":tmpreg("BEFORE_IMAGE"),1:regs(REGION,"BEFORE_IMAGE")) d mmbichk
+	i nommbi,$s(SEGMENT="TEMPLATE":0,1:regs(REGION,"BEFORE_IMAGE")) d mmbichk
 	q
 
 ;-----------------------------------------------------------------------------------------------------------------------------------
@@ -184,13 +229,3 @@ TSQUALS(am,squals)
 	n REGION,SEGMENT s (REGION,SEGMENT)="TEMPLATE"
 	q $$SQUALS(am,.squals)
 
-;-----------------------------------------------------------------------------------------------------------------------------------
-; called from GDEADD.M, GDECHANG.M and GDETEMPL.M, [GTM-7184]
-NQUALS(rquals)
-	n nullsub s nullsub=rquals("NULL_SUBSCRIPTS")
-	i ($$prefix(nullsub,"NEVER")!$$prefix(nullsub,"FALSE")) s rquals("NULL_SUBSCRIPTS")=0
-	e  d
-	. i ($$prefix(nullsub,"ALWAYS")!$$prefix(nullsub,"TRUE")) s rquals("NULL_SUBSCRIPTS")=1
-	. e  d
-	. . i ($$prefix(nullsub,"EXISTING")) s rquals("NULL_SUBSCRIPTS")=2
-	q
diff --git a/sr_vvms/gds_rundown.c b/sr_vvms/gds_rundown.c
index a2886f8..4eed2f9 100644
--- a/sr_vvms/gds_rundown.c
+++ b/sr_vvms/gds_rundown.c
@@ -99,7 +99,7 @@ CONDITION_HANDLER(gds_rundown_ch)
 	uint4			outaddrs[2], retadr[2], status;
 	boolean_t		nonclst_bg;
 
-        START_CH;
+        START_CH(FALSE);
 
 	if (PRO_ONLY(mu_rndwn_process &&) DUMPABLE && !SUPPRESS_DUMP)
 		TERMINATE;
@@ -166,7 +166,7 @@ CONDITION_HANDLER(gds_rundown_ch)
 		cs_addrs->lock_addrs[0] = NULL;
 	}
         PRN_ERROR;
-	gtm_putmsg(VARLSTCNT(4) ERR_DBRNDWN, 2, REG_LEN_STR(gv_cur_region));
+	gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBRNDWN, 2, REG_LEN_STR(gv_cur_region));
         UNWIND(NULL, NULL);
 }
 
@@ -260,9 +260,9 @@ void	gds_rundown(void)
 						jnl_put_jrt_pfin(cs_addrs);
 						if (SS_NORMAL != (jnl_status = jnl_flush(gv_cur_region)))
 						{
-							send_msg(VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(cs_data),
-								ERR_TEXT, 2,
-									RTS_ERROR_TEXT("Error with journal flush in gds_rundown1"),
+							send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_JNLFLUSH, 2,
+								JNL_LEN_STR(cs_data), ERR_TEXT, 2,
+								RTS_ERROR_TEXT("Error with journal flush in gds_rundown1"),
 								jnl_status);
 							assert(NOJNL == jpc->channel);/* jnl file lost has been triggered */
 							/* In this routine, all code that follows from here on does not
@@ -439,8 +439,8 @@ void	gds_rundown(void)
 							{
 								if (SS_NORMAL != (jnl_status = jnl_flush(gv_cur_region)))
 								{
-									send_msg(VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(cs_data),
-										ERR_TEXT, 2,
+									send_msg_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_JNLFLUSH, 2,
+										JNL_LEN_STR(cs_data), ERR_TEXT, 2,
 										RTS_ERROR_TEXT( \
 										"Error with journal flush in gds_rundown2"),
 										jnl_status);
@@ -521,10 +521,13 @@ void	gds_rundown(void)
 			ipc_deleted = TRUE;
 		} else if (is_src_server || is_updproc)
 		{
-			gtm_putmsg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region), process_id, process_id);
-			send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region), process_id, process_id);
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region),
+					process_id, process_id);
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region),
+					process_id, process_id);
 		} else
-			send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region), process_id, process_id);
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(gv_cur_region),
+					process_id, process_id);
 	}
 	/* ------------------------- take care of locks ------------------------------------ */
 	if (TRUE == clustered)
@@ -558,16 +561,16 @@ void	gds_rundown(void)
 	{
 		GET_CUR_TIME;
 		if (is_src_server)
-			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
 				LEN_AND_LIT("Source server"), REG_LEN_STR(gv_cur_region));
 		if (is_updproc)
-			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
 				LEN_AND_LIT("Update process"), REG_LEN_STR(gv_cur_region));
 		if (mupip_jnl_recover)
 		{
-			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
+			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
 				LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(gv_cur_region));
-			send_msg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
+			send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
 				LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(gv_cur_region));
 		}
 	}
diff --git a/sr_vvms/generic_exit_handler.c b/sr_vvms/generic_exit_handler.c
index f3e2255..08cb088 100644
--- a/sr_vvms/generic_exit_handler.c
+++ b/sr_vvms/generic_exit_handler.c
@@ -88,10 +88,6 @@ void generic_exit_handler(void)
 {
 	void		(*signal_routine)();
 	boolean_t	is_mupip, is_gtm;
-	int4		lcnt;
-	gd_addr		*addr_ptr;
-	gd_region	*reg, *r_top;
-	sgmnt_addrs	*csa;
 	static int	invoke_cnt = 0;	/* how many times generic_exit_handler was invoked in the lifetime of this process */
 
 	is_gtm = IS_GTM_IMAGE;
diff --git a/sr_vvms/get_src_line.c b/sr_vvms/get_src_line.c
index 328b720..040f914 100644
--- a/sr_vvms/get_src_line.c
+++ b/sr_vvms/get_src_line.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -25,26 +25,28 @@
 #include "gt_timer.h"
 #include "zbreak.h"
 #include "hashtab_mname.h"
+#include "rtn_src_chksum.h"
 
 #define RT_TBL_SZ 20
 
 int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig)
 {
-	struct FAB	fab;
-	struct RAB	rab;
-	struct NAM	nam;
-	bool		added;
-	unsigned char	buff[MAX_SRCLINE], *cp1, *cp2, *cp3, *chkcalc;
-	unsigned char	es[255], srcnamebuf[SIZEOF(mident_fixed) + STR_LIT_LEN(DOTM)];
-	boolean_t	badfmt, found;
-	int		*lt_ptr, tmp_int, status;
-	uint4		checksum, lcnt, srcint, srcstat, *src_tbl;
-	mstr		src;
-	rhdtyp		*rtn_vector;
-	zro_ent		*srcdir;
-	mstr		*base, *current, *top;
-	ht_ent_mname	*tabent;
-	var_tabent	rtnent;
+	struct FAB		fab;
+	struct RAB		rab;
+	struct NAM		nam;
+	bool			added;
+	unsigned char		buff[MAX_SRCLINE], *cp1, *cp2, *cp3;
+	unsigned char		es[255], srcnamebuf[SIZEOF(mident_fixed) + STR_LIT_LEN(DOTM)];
+	boolean_t		badfmt, found;
+	int			*lt_ptr, tmp_int, status;
+	uint4			lcnt, srcstat, *src_tbl;
+	mstr			src;
+	rhdtyp			*rtn_vector;
+	zro_ent			*srcdir;
+	mstr			*base, *current, *top;
+	ht_ent_mname		*tabent;
+	var_tabent		rtnent;
+	gtm_rtn_src_chksum_ctx	checksum_ctx;
 	DCL_THREADGBL_ACCESS;
 
 	SETUP_THREADGBL_ACCESS;
@@ -119,13 +121,13 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 				hiber_start(WAIT_FOR_FILE_TIME);
 			}
 			if (RMS$_NORMAL != status)
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 			rab = cc$rms_rab;
 			rab.rab$l_fab = &fab;
 			rab.rab$l_ubf = buff;
 			rab.rab$w_usz = SIZEOF(buff);
 			if (RMS$_NORMAL != (status = sys$connect(&rab)))
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 		}
 
 		tmp_int = found ? rtn_vector->lnrtab_len : 0;
@@ -135,7 +137,7 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 		base = (mstr *)(src_tbl + 2);
 		*(src_tbl + 1) = tmp_int;	/* So zlput_rname knows how big we are */
 		badfmt = FALSE;
-		checksum = 0;
+		rtn_src_chksum_init(&checksum_ctx);
 		for (current = base + 1, top = base + tmp_int;  current < top;  current++)
 		{
 			status = sys$get(&rab);
@@ -146,7 +148,7 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 			} else  if (RMS$_NORMAL != status)
 			{
 				free(src_tbl);
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 			}
 			if (rab.rab$w_rsz)
 			{
@@ -155,21 +157,7 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 					cp1 < cp2 && (' ' != *cp1) && ('\t' != *cp1);  cp1++)
 						;
 				/* calculate checksum */
-				for (chkcalc = buff;  chkcalc < cp2;)
-				{
-					srcint = 0;
-					if (cp2 - chkcalc < SIZEOF(int4))
-					{
-						memcpy(&srcint, chkcalc, cp2 - chkcalc);
-						chkcalc = cp2;
-					} else
-					{
-						srcint = *(int4 *)chkcalc;
-						chkcalc += SIZEOF(int4);
-					}
-					checksum ^= srcint;
-					checksum >>= 1;
-				}
+				rtn_src_chksum_line(&checksum_ctx, buff, cp2 - buff);
 				current->len = rab.rab$w_rsz;
 				current->addr = malloc(rab.rab$w_rsz);
 				memcpy(current->addr, buff, rab.rab$w_rsz);
@@ -186,7 +174,9 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 			if (!badfmt)
 			{
 				status = sys$get(&rab);
-				if ((RMS$_EOF != status) || checksum != rtn_vector->checksum)
+				rtn_src_chksum_digest(&checksum_ctx);
+				if ((RMS$_EOF != status)
+					|| !rtn_src_chksum_match(get_ctx_checksum(&checksum_ctx), get_rtnhdr_checksum(rtn_vector)))
 					badfmt = TRUE;
 			}
 			sys$close(&fab);
@@ -215,3 +205,62 @@ int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_
 	}
 	return srcstat;
 }
+
+void free_src_tbl(rhdtyp *rtn_vector)
+{
+	ht_ent_mname    *tabent;
+	mname_entry	key;
+	uint4		entries;
+	mstr		*curline;
+	uint4		*src_tbl;
+	DCL_THREADGBL_ACCESS;
+
+	SETUP_THREADGBL_ACCESS;
+	/* If source has been read in for old routine, free space. Since routine name is the key, do this before
+	   (in USHBIN builds) we release the literal text section as part of the releasable read-only section.
+	 */
+	tabent = NULL;
+	if (NULL != (TREF(rt_name_tbl)).base)
+	{
+		key.var_name = rtn_vector->routine_name;
+		COMPUTE_HASH_MNAME(&key);
+		tabent = lookup_hashtab_mname(TADR(rt_name_tbl), &key);
+		if ((NULL != tabent) && tabent->value)
+		{
+			src_tbl = (uint4 *)tabent->value;
+			/* Must delete the entries piece-meal */
+			entries = *(src_tbl + 1);
+			/* Don't count line 0 which we bypass */
+			if (0 != entries)
+				entries--;
+			/* curline start is 2 uint4s into src_tbl and then space past line 0 or
+			   we end up freeing the storage for line 0/1 twice since they have the
+			   same pointers.
+			*/
+			for (curline = RECAST(mstr *)(src_tbl + 2) + 1; 0 != entries; --entries, ++curline)
+			{
+				assert(curline->len);
+				free(curline->addr);
+			}
+			free(tabent->value);
+			/* Comment below kept intact from when UNIX also used a $TEXT hash table. [BC 9/13]
+			 *
+			 * Note that there are two possible ways to proceed here to clear this entry:
+			 *   1. Just clear the value as we do below.
+			 *   2. Use the DELETE_HTENT() macro to remove the entry entirely from the hash table.
+			 *
+			 * We choose #1 since a routine that had had its source loaded is likely to have it reloaded
+			 * and if the source load rtn has to re-add the key, it won't reuse the deleted key (if it
+			 * remained a deleted key) until all other hashtable slots have been used up (creating a long
+			 * collision chain). A deleted key may not remain a deleted key if it was reached with no
+			 * collisions but will instead be turned into an unused key and be immediately reusable.
+			 * But since it is likely to be reused, we just zero the entry but this creates a necessity
+			 * that the key be maintained. If this is a non-USBHIN platform, everything stays around
+			 * anyway so that's not an issue. However, in a USHBIN platform, the literal storage the key
+			 * is pointing to gets released. For that reason, in the USHBIN processing section below, we
+			 * update the key to point to the newly loaded module's routine name.
+			 */
+			tabent->value = NULL;
+		}
+	}
+}
diff --git a/sr_vvms/goq_m11_load.c b/sr_vvms/goq_m11_load.c
index 9513df2..df1aa60 100644
--- a/sr_vvms/goq_m11_load.c
+++ b/sr_vvms/goq_m11_load.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -30,6 +30,7 @@
 #include "mvalconv.h"
 #include "mu_gvis.h"
 #include "quad2asc.h"
+#include "hashtab_mname.h"
 
 #define ODD 1
 #define NEGORZRO 1
@@ -80,6 +81,8 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 	gv_key		*goq_currkey;
 	int		goq_key_sub, goq_subsc_map[2][129];
 	mval		v, exist;
+	mname_entry	gvname;
+	gvnh_reg_t	*gvnh_reg;
 
 	if (end > 0)
 		is_end = TRUE;
@@ -124,14 +127,14 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					   (rec_count * goq_blk_size / 512) + 1,0,0,0);
 
 			if (status != SS$_NORMAL)
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 
 			sys$synch(efn_bg_qio_read, &iosb[0]);
 			if (iosb[0] == SS$_ENDOFFILE)
 				break;
 
 			if (iosb[0] != SS$_NORMAL)
-				rts_error(VARLSTCNT(1) iosb[0]);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) iosb[0]);
 			rec_count++;
 			len = *goq_blk_used;
 		}
@@ -139,7 +142,7 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 		if ((is_end && rec_count >= end) || iosb[0] == SS$_ENDOFFILE)
 			break;
 		if (len >= goq_blk_size)
-		{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,0);
+		{	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,0);
 			continue;
 		}
 		goq_rp = in_buff;
@@ -164,13 +167,16 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 
 		if (goq_rp->cmpc != 0 || v.str.len > goq_currkey->top)
 		{
-			rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 			continue;
 		}
-		GV_BIND_NAME_AND_ROOT_SEARCH (gd_header, &v.str);
+		gvname.var_name = v.str;
+		COMPUTE_HASH_MNAME(&gvname);
+		GV_BIND_NAME_AND_ROOT_SEARCH (gd_header, &gvname, gvnh_reg);
+		assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
 		if (mupip_error_occurred)
 		{
-			rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 			mu_gvis();
 			util_out_print(0,TRUE);
 			continue;
@@ -194,7 +200,7 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			n += goq_rp->subsc_len + 2 * SIZEOF(char); /* size of key */
 			if ((unsigned char *) goq_rp + n > btop)
 			{
-				rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 				mu_gvis();
 				util_out_print(0,TRUE);
 				break;
@@ -242,8 +248,8 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 								case '9': *b++ = '0';
 									break;
 								default:
-									rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,
-										global_key_count);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)
+										ERR_CORRUPT,2,rec_count, global_key_count);
 									 mu_gvis();
 									 util_out_print(0,TRUE);
 							}
@@ -251,7 +257,9 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 						if (!mupip_error_occurred)
 						{
 							if (*cp1++ != M11_NEG)
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
@@ -267,7 +275,9 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 							v.str.len = b - (unsigned char *) v.str.addr;
 							s2n(&v);
 							if (mupip_error_occurred)
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
@@ -275,14 +285,13 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 							else
 								v.mvtype = MV_NM;
 						}
-					}
-					else if (exp == M11_ZRO)
+					} else if (M11_ZRO == exp)
 					{
 						v.mvtype = MV_NM;
 						v.m[1] = 0;
-					}
-					else
-					{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					} else
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
@@ -305,7 +314,7 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					v.str.len = b - (unsigned char *) v.str.addr;
 					if (cp1 > cp2)
 					{
-						rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
@@ -316,7 +325,8 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					}
 					s2n(&v);
 					if (mupip_error_occurred)
-					{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
@@ -336,17 +346,17 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					v.str.len = b - (unsigned char *) v.str.addr;
 					if (cp1 > cp2)
 					{
-						rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
 					}
 				}
-				mval2subsc(&v,gv_currkey);
+				mval2subsc(&v, gv_currkey, gvnh_reg->gd_reg->std_null_coll);
 				gv_currkey->prev = 0;
 				if (mupip_error_occurred)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					mu_gvis();
 					util_out_print(0,TRUE);
 					break;
@@ -388,7 +398,7 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			{
 				if (!mupip_DB_full)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					util_out_print(0,TRUE);
 				}
 				break;
@@ -404,7 +414,7 @@ void  goq_m11_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			{
 				if (goq_rp->cmpc > goq_currkey->end)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					break;
 				}
 				cp1 = &goq_rp->subsc[0];
diff --git a/sr_vvms/goq_mvx_load.c b/sr_vvms/goq_mvx_load.c
index 1ac0873..b59f08c 100644
--- a/sr_vvms/goq_mvx_load.c
+++ b/sr_vvms/goq_mvx_load.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -32,6 +32,7 @@
 #include "mvalconv.h"
 #include "mu_gvis.h"
 #include "quad2asc.h"
+#include "hashtab_mname.h"
 
 #define NEGORZRO 1
 #define MVX_ZRO 48
@@ -84,6 +85,8 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 		} 	*goq_rp;
 	short int	*goq_blk_used;
 	gv_key		*goq_currkey;
+	mname_entry	gvname;
+	gvnh_reg_t	*gvnh_reg;
 
 	/* goq_key_sub = number of discrete items in key to convert (i.e., global name and subscripts)
 	   goq_subsc_map = array of positions separating discrete items in key:
@@ -138,14 +141,14 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					   (rec_count * goq_blk_size / 512) + 1,0,0,0);
 
 			if (status != SS$_NORMAL)
-				rts_error(VARLSTCNT(1) status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 
 			sys$synch(efn_bg_qio_read, &iosb[0]);
 			if (iosb[0] == SS$_ENDOFFILE)
 				break;
 
 			if (iosb[0] != SS$_NORMAL)
-				rts_error(VARLSTCNT(1) iosb[0]);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) iosb[0]);
 			rec_count++;
 			len = *goq_blk_used;
 		}
@@ -153,7 +156,7 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 		if ((is_end && rec_count > end) || iosb[0] == SS$_ENDOFFILE)
 			break;
 		if (len >= goq_blk_size)
-		{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,0);
+		{	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,0);
 			continue;
 		}
 		goq_rp = in_buff;
@@ -180,13 +183,16 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 
 		if (goq_rp->cmpc != 0 || v.str.len > goq_currkey->top)
 		{
-			rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 			continue;
 		}
-		GV_BIND_NAME_AND_ROOT_SEARCH (gd_header, &v.str);
+		gvname.var_name = v.str;
+		COMPUTE_HASH_MNAME(&gvname);
+		GV_BIND_NAME_AND_ROOT_SEARCH (gd_header, &gvname, gvnh_reg);
+		assert(NULL == gvnh_reg->gvspan); /* so GV_BIND_SUBSNAME_IF_GVSPAN is not needed */
 		if (mupip_error_occurred)
 		{
-			rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 			mu_gvis();
 			util_out_print(0,TRUE);
 			continue;
@@ -216,7 +222,7 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			n += goq_rp->subsc_len + 2 * SIZEOF(char);
 			if ((unsigned char *) goq_rp + n > btop)
 			{
-				rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 				mu_gvis();
 				util_out_print(0,TRUE);
 				break;
@@ -263,8 +269,8 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 								case '9': *b++ = '0';
 									break;
 								default:
-									rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,
-										global_key_count);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)
+										ERR_CORRUPT,2,rec_count, global_key_count);
 									 mu_gvis();
 									 util_out_print(0,TRUE);
 							}
@@ -272,18 +278,20 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 						if (!mupip_error_occurred)
 						{
 							if (cp1 >= cp2)
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
-							}
-							else if (*cp1++ == MVX_NEG)
+							} else if (*cp1++ == MVX_NEG)
  							{
 								if (cp1 < cp2)
 								{
 									if (*cp1)
-									{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,
-											global_key_count);
+									{
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)
+											ERR_CORRUPT,2,rec_count, global_key_count);
 										mu_gvis();
 										util_out_print(0,TRUE);
 										break;
@@ -292,9 +300,10 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 									{	cp1++;
 									}
 								}
-							}
-							else
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							} else
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
@@ -310,31 +319,33 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 							v.str.len = b - (unsigned char *) v.str.addr;
 							s2n(&v);
 							if (mupip_error_occurred)
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
 							}
 						}
-					}
-					else if (exp == MVX_ZRO)
+					} else if (exp == MVX_ZRO)
 					{
 						MV_FORCE_MVAL(&v,0) ;
 						if (cp1 < cp2)
 						{
 							if (!*cp1)
-							{	cp1++;
-							}
+								cp1++;
 							else
-							{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+							{
+								rts_error_csa(CSA_ARG(NULL)
+									VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 								mu_gvis();
 								util_out_print(0,TRUE);
 								break;
 							}
 						}
-					}
-					else
-					{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					} else
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
@@ -356,10 +367,11 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					if (cp1 < cp2)
 					{
 						if (!*cp1)
-						{	cp1++;
-						}
+							cp1++;
 						else
-						{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+						{
+							rts_error_csa(CSA_ARG(NULL)
+								VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 							mu_gvis();
 							util_out_print(0,TRUE);
 							break;
@@ -371,7 +383,8 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					}
 					s2n(&v);
 					if (mupip_error_occurred)
-					{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					{
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 						mu_gvis();
 						util_out_print(0,TRUE);
 						break;
@@ -389,21 +402,22 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 					if (cp1 < cp2)
 					{
 						if (!*cp1)
-						{	cp1++;
-						}
+							cp1++;
 						else
-						{	rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+						{
+							rts_error_csa(CSA_ARG(NULL)
+								VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 							mu_gvis();
 							util_out_print(0,TRUE);
 							break;
 						}
 					}
 				}
-				mval2subsc(&v,gv_currkey);
+				mval2subsc(&v, gv_currkey, gvnh_reg->gd_reg->std_null_coll);
 				gv_currkey->prev = 0;
 				if (mupip_error_occurred)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					mu_gvis();
 					util_out_print(0,TRUE);
 					break;
@@ -464,7 +478,7 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			{
 				if (!mupip_DB_full)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					util_out_print(0,TRUE);
 				}
 				break;
@@ -480,7 +494,7 @@ void	goq_mvx_load(struct FAB *infab, char *in_buff, uint4 rec_count, uint4 end)
 			{
 				if (goq_rp->cmpc > goq_currkey->end)
 				{
-					rts_error(VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CORRUPT,2,rec_count,global_key_count);
 					break;
 				}
 				cp1 = &goq_rp->subsc[0];
diff --git a/sr_vvms/gt_timer.h b/sr_vvms/gt_timer.h
index 4f0bc80..438d9bc 100644
--- a/sr_vvms/gt_timer.h
+++ b/sr_vvms/gt_timer.h
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -58,8 +58,9 @@ typedef struct tag_ts {
 	struct tag_ts	*next;		/* Pointer to next */
 } GT_TIMER;
 
-#define GT_WAKE sys$wake(0,0)
-#define hiber_start_wait_any hiber_start
+#define GT_WAKE			sys$wake(0,0)
+#define hiber_start_wait_any	hiber_start
+#define CANCEL_TIMERS		cancel_timer(0)
 
 int4 abs_time_comp(ABS_TIME *atp1, ABS_TIME *atp2);
 void add_int_to_abs_time(ABS_TIME *atps, int4 ival, ABS_TIME *atpd);
diff --git a/sr_vvms/gtm_env_translate.c b/sr_vvms/gtm_env_translate.c
index 4cf068f..1998a1b 100644
--- a/sr_vvms/gtm_env_translate.c
+++ b/sr_vvms/gtm_env_translate.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,7 +38,7 @@ CONDITION_HANDLER(gtm_env_xlate_ch)
 {
 	int4    status;
 
-	START_CH;
+	START_CH(FALSE);
 	PRN_ERROR;
 	if (DUMP)
 		NEXTCH;
@@ -87,22 +87,22 @@ mval* gtm_env_translate(mval* val1, mval* val2, mval* val_xlated)
 			status = lib$find_image_symbol(&filename, &entry_point, &RFPTR(gtm_env_xlate_entry), 0);
 			REVERT;
 			if (0 == (status & 1))
-				rts_error(VARLSTCNT(1) ERR_XTRNTRANSDLL);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_XTRNTRANSDLL);
 		}
 		val_xlated->str.addr = NULL;
 		ret_gtm_env_xlate = IVFPTR(gtm_env_xlate_entry)(&val1->str, &val2->str, &dollar_zdir.str, &val_xlated->str);
 		if (MAX_DBSTRLEN < val_xlated->str.len)
-			rts_error(VARLSTCNT(4) ERR_XTRNRETVAL, 2, val_xlated->str.len, MAX_DBSTRLEN);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_XTRNRETVAL, 2, val_xlated->str.len, MAX_DBSTRLEN);
 		if (0 != ret_gtm_env_xlate)
 		{
 			if ((val_xlated->str.len) && (val_xlated->str.addr))
-				rts_error(VARLSTCNT(6) ERR_XTRNTRANSERR, 0, ERR_TEXT,  2,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_XTRNTRANSERR, 0, ERR_TEXT,  2,
 					  val_xlated->str.len, val_xlated->str.addr);
 			else
-				rts_error(VARLSTCNT(1) ERR_XTRNTRANSERR);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_XTRNTRANSERR);
 		}
 		if ((NULL == val_xlated->str.addr) && (0 != val_xlated->str.len))				\
-			rts_error(VARLSTCNT(1) ERR_XTRNRETSTR);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_XTRNRETSTR);
 		val_xlated->mvtype = MV_STR;
 		val1 = val_xlated;
 	}
diff --git a/sr_vvms/gtm_logicals.h b/sr_vvms/gtm_logicals.h
index 1964332..6c70468 100644
--- a/sr_vvms/gtm_logicals.h
+++ b/sr_vvms/gtm_logicals.h
@@ -29,6 +29,9 @@
 #define	GTM_TPRESTART_LOG_DELTA		"GTM_TPRESTART_LOG_DELTA"
 #define	GTM_TPRESTART_LOG_LIMIT		"GTM_TPRESTART_LOG_FIRST"
 #define	GTM_ZMAXTPTIME			"GTM_ZMAXTPTIME"
+/* 	GTM_DIRTREE_COLLHDR_ALWAYS	"GTM_DIRTREE_COLLHDR_ALWAYS"	dbg-only use in gvcst_put hence no #define for it or
+									else the D9I10002703 subtest will need changes for this.
+									*/
 
 /* White-box testing */
 #define	GTM_WHITE_BOX_TEST_CASE_COUNT	"GTM_WHITE_BOX_TEST_CASE_COUNT"
diff --git a/sr_vvms/gtmrecv_fetchresync.c b/sr_vvms/gtmrecv_fetchresync.c
index a176df5..b6f5a97 100644
--- a/sr_vvms/gtmrecv_fetchresync.c
+++ b/sr_vvms/gtmrecv_fetchresync.c
@@ -72,7 +72,7 @@ error_def(ERR_TEXT);
 
 CONDITION_HANDLER(gtmrecv_fetchresync_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	/* Remove semaphores created */
 	remove_sem_set(RECV);
 	repl_close(&gtmrecv_listen_sock_fd);
@@ -164,6 +164,7 @@ int gtmrecv_fetchresync(int port, seq_num *resync_seqno)
 	primary_ai.ai_addr = (sockaddr_ptr)&primary_sas;
 	primary_ai.ai_addrlen = SIZEOF(primary_sas);
 	repl_log(stdout, TRUE, TRUE, "Waiting for a connection...\n");
+	assertpro(FD_SETSIZE > gtmrecv_listen_sock_fd);
 	FD_ZERO(&input_fds);
 	FD_SET(gtmrecv_listen_sock_fd, &input_fds);
 	t1 = time(NULL);
diff --git a/sr_vvms/gtmrecv_process.c b/sr_vvms/gtmrecv_process.c
index 2ffecdc..c750e41 100644
--- a/sr_vvms/gtmrecv_process.c
+++ b/sr_vvms/gtmrecv_process.c
@@ -13,11 +13,13 @@
 
 #include "gtm_socket.h"
 #include "gtm_inet.h"
+#include "gtm_netdb.h"
 #include "gtm_time.h"
 #include "gtm_fcntl.h"
 #include "gtm_unistd.h"
 #include "gtm_string.h"
 #include "gtm_stdio.h"
+#include "gtm_select.h"
 
 #include <sys/time.h>
 #include <errno.h>
@@ -45,7 +47,6 @@
 #include "repl_filter.h"
 #include "repl_log.h"
 #include "gtmsource.h"
-#include "gtm_netdb.h"
 #include "sgtm_putmsg.h"
 #include "gt_timer.h"
 #include "min_max.h"
@@ -272,6 +273,7 @@ static int gtmrecv_est_conn(void)
 	gtmrecv_comm_init((in_port_t)gtmrecv_local->listen_port);
 	primary_ai.ai_addrlen = SIZEOF(primary_sas);
 	repl_log(gtmrecv_log_fp, TRUE, TRUE, "Waiting for a connection...\n");
+	assertpro(FD_SETSIZE > gtmrecv_listen_sock_fd);
 	FD_ZERO(&input_fds);
 	FD_SET(gtmrecv_listen_sock_fd, &input_fds);
 	/*
@@ -674,7 +676,7 @@ static void process_tr_buff(void)
 							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_SECNODZTRIGINTP, 1,
 									&recvpool_ctl->jnl_seqno);
 						else /* (EREPL_INTLFILTER_INCMPLREC == repl_errno) */
-							GTMASSERT;
+							assertpro(repl_errno != repl_errno);
 					}
 				} else
 				{
@@ -1108,6 +1110,6 @@ void gtmrecv_process(boolean_t crash_restart)
 	{
 		gtmrecv_main_loop(crash_restart);
 	} while (repl_connection_reset);
-	GTMASSERT; /* shouldn't reach here */
+	assertpro(FALSE); /* shouldn't reach here */
 	return;
 }
diff --git a/sr_vvms/gtmsource_heartbeat.c b/sr_vvms/gtmsource_heartbeat.c
index 9df5ec6..3c3ab02 100644
--- a/sr_vvms/gtmsource_heartbeat.c
+++ b/sr_vvms/gtmsource_heartbeat.c
@@ -47,7 +47,6 @@ GBLREF	boolean_t		gtmsource_logstats;
 GBLREF	int			gtmsource_log_fd;
 GBLREF 	FILE			*gtmsource_log_fp;
 GBLREF  gtmsource_state_t       gtmsource_state;
-GBLREF	gd_addr          	*gd_header;
 
 GBLDEF	boolean_t			heartbeat_stalled = TRUE;
 GBLDEF	repl_heartbeat_que_entry_t	*repl_heartbeat_que_head = NULL;
@@ -83,7 +82,7 @@ int gtmsource_init_heartbeat(void)
 	REPL_DPRINT4("Initialized heartbeat, heartbeat_period = %d s, heartbeat_max_wait = %d s, num_q_entries = %d\n",
 			heartbeat_period, heartbeat_max_wait, num_q_entries);
 	if (!(repl_heartbeat_que_head = (repl_heartbeat_que_entry_t *)malloc(num_q_entries * SIZEOF(repl_heartbeat_que_entry_t))))
-		rts_error(VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Error in allocating heartbeat queue"), errno);
 
 	memset(repl_heartbeat_que_head, 0, num_q_entries * SIZEOF(repl_heartbeat_que_entry_t));
@@ -183,7 +182,6 @@ int gtmsource_send_heartbeat(time_t *now)
 		    GTMSOURCE_CHANGING_MODE == gtmsource_state)
 			return (SS_NORMAL);
 	}
-
 	if (SS_NORMAL == status)
 	{
 		insqt((que_ent_ptr_t)heartbeat_element, (que_ent_ptr_t)repl_heartbeat_que_head);
@@ -197,7 +195,6 @@ int gtmsource_send_heartbeat(time_t *now)
 
 		return (SS_NORMAL);
 	}
-
 	if (EREPL_SEND == repl_errno && REPL_CONN_RESET(status))
 	{
 		repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while attempting to send heartbeat. Status = %d ; %s\n",
@@ -207,14 +204,12 @@ int gtmsource_send_heartbeat(time_t *now)
 		return (SS_NORMAL);
 	}
 	if (EREPL_SEND == repl_errno)
-		rts_error(VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Error sending HEARTBEAT message. Error in send"), status);
-
 	if (EREPL_SELECT == repl_errno)
-		rts_error(VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
 			LEN_AND_LIT("Error sending HEARTBEAT message. Error in select"), status);
-
-	GTMASSERT;
+	assertpro((SS_NORMAL == status));
 }
 
 int gtmsource_process_heartbeat(repl_heartbeat_msg_t *heartbeat_msg)
diff --git a/sr_vvms/gtmsource_process.c b/sr_vvms/gtmsource_process.c
index 7bf4f24..e59a41f 100644
--- a/sr_vvms/gtmsource_process.c
+++ b/sr_vvms/gtmsource_process.c
@@ -86,7 +86,6 @@ GBLREF	int			gtmsource_log_fd;
 GBLREF	FILE			*gtmsource_log_fp;
 GBLREF	boolean_t		gtmsource_logstats;
 GBLREF	int			gtmsource_filter;
-GBLREF	gd_addr			*gd_header;
 GBLREF	seq_num			seq_num_zero, seq_num_minus_one, seq_num_one;
 GBLREF	unsigned char		jnl_ver, remote_jnl_ver;
 GBLREF	unsigned int		jnl_source_datalen, jnl_dest_maxdatalen;
@@ -831,10 +830,9 @@ int gtmsource_process(void)
 				}
 			} else /* else tot_tr_len < 0, error */
 			{
-				if (0 < data_len) /* Insufficient buffer space, increase the buffer space */
-					gtmsource_alloc_msgbuff(data_len + REPL_MSG_HDRLEN);
-				else
-					GTMASSERT; /* Major problems */
+				assertpro(0 < data_len); /* Else major problems */
+				/* Insufficient buffer space, increase the buffer space */
+				gtmsource_alloc_msgbuff(data_len + REPL_MSG_HDRLEN);
 			}
 		}
 	}
diff --git a/sr_vvms/io_open_try.c b/sr_vvms/io_open_try.c
index f4cf697..7f783d2 100644
--- a/sr_vvms/io_open_try.c
+++ b/sr_vvms/io_open_try.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -62,10 +62,7 @@ bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mva
 			if (!tl->iod->type && mspace && mspace->str.len)
 			{
 				lower_to_upper(dev_type, mspace->str.addr, mspace->str.len);
-				if (((SIZEOF("TCP") - 1) == mspace->str.len)
-					&& (0 == memcmp(dev_type, LIT_AND_LEN("TCP"))))
-					tl->iod->type = tcp;
-				else if (((SIZEOF("SOCKET") - 1) == mspace->str.len)
+				if (((SIZEOF("SOCKET") - 1) == mspace->str.len)
 					&& (0 == memcmp(dev_type, LIT_AND_LEN("SOCKET"))))
 					tl->iod->type = gtmsocket;
 				else
diff --git a/sr_vvms/iotcp_select.h b/sr_vvms/iotcp_select.h
deleted file mode 100644
index d4253fa..0000000
--- a/sr_vvms/iotcp_select.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-#ifndef FD_SET
-/*
- *  from BSD 4.3 (could grab a copy from CCKIM for 4.2)
- *
- *
- */
-
-#ifndef NBBY
-#define	NBBY	8		/* number of bits in a byte */
-#endif
-/*
- * Select uses bit masks of file descriptors in longs.
- * These macros manipulate such bit fields (the filesystem macros use chars).
- * FD_SETSIZE may be defined by the user, but the default here
- * should be >= NOFILE (param.h).
- */
-#ifndef	FD_SETSIZE
-#define	FD_SETSIZE	256
-#endif
-
-typedef uint4	fd_mask;
-#define NFDBITS	(SIZEOF(fd_mask) * NBBY)	/* bits per mask */
-#ifndef howmany
-#define	howmany(x, y)	(((x)+((y)-1))/(y))
-#endif
-
-#ifndef fd_set
-typedef	struct fd_set {
-	fd_mask	fds_bits[howmany(FD_SETSIZE, NFDBITS)];
-} fd_set;
-#endif
-
-#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_ZERO(p)	memset((char *)(p), '\0', SIZEOF(*(p)))
-#undef NEED_FD_SET
-#endif /* ifndef(FD_SET) */
diff --git a/sr_vvms/iotcp_string.c b/sr_vvms/iotcp_string.c
deleted file mode 100644
index 65a6ea2..0000000
--- a/sr_vvms/iotcp_string.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************
- *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
- *								*
- *	This source code contains the intellectual property	*
- *	of its copyright holder(s), and is made available	*
- *	under a license.  If you do not know the terms of	*
- *	the license, please stop and do not read further.	*
- *								*
- ****************************************************************/
-
-/* ZY: self-defined string operation routines
- *     since string routines cause multiply-defined problem on VMS
- */
-
-#include "mdef.h"     /* 96/12/30 smw for memcmp */
-
-char *vmssp_strcpy(char *s1, char *s2)
-{
-	char *p, *q;
-	p = s1;
-	q = s2;
-	for (; *q; ++q)
-		*p++ = *q;
-	*p = '\0';
-	return(s1);
-}
-
-
-char *vmssp_strcat(char *s1, char *s2)
-{
-	char  *p, *q;
-	for (p=s1; *p; ++p);
-	for (q=s2; *q; ++q)
-		*p++ = *q;
-	*p = '\0';
-	return(s1);
-}
-
-
-int vmssp_sprintf(char *s1, char *format, char *sour, unsigned short num)
-{
-	char correct_format[10];
-	char *str, *p, q[10];
-	int  t, i, j;
-
-	vmssp_strcpy(correct_format, "%s,%d");
-	if (memcmp(format, correct_format, 6))
-		/* How to print error by GTM staff?
-		   printf("Error: sprintf format is not correct!\n");
-		*/
-		return(-1);
-
-	str = s1;
-	for (p=sour,i=0; *p; p++,i++)
-		*str++ = *p;
-	*str++ = ',';
-	i++;
-	for(t=num,j=0; t>9; )
-	{
-		q[j++] = (t % 10) + '0';
-		t = (int)t/10;
-	}
-	q[j] = t + '0';
-	for (; j>=0 ; --j, ++i)
-		*str++ = q[j];
-	*str = '\0';
-	return(i);
-}
-
-
-int vmssp_sscanf(char *str, char *format, char *rel, short *num)
-{
-	char correct_format[10];
-	char *p;
-	int  t;
-
-	if (!(*str))      /* empty string, unix returns EOF */
-		return(-1);
-
-	vmssp_strcpy(correct_format, "%[^,],%hu");
-	if (memcmp(format, correct_format, 10))
-		/* How to print error by GTM staff?
-		   printf("Error: sscanf format is not correct!\n");
-		*/
-		return(-1);
-
-	for (p=str; *p && *p!=','; p++)
-		*rel++ = *p;
-	*rel = '\0';
-	if (!(*p))
-		/* no , match */
-		return(-1);
-	else
-	{
-		for (p++, *num=0; *p; p++)
-		{
-			t = *p - '0';
-			*num = *num * 10 + t;
-		}
-		if (*str == ',')
-			return(1);
-		else
-			return(2);
-	}
-}
-
diff --git a/sr_vvms/jnl_file_extend.c b/sr_vvms/jnl_file_extend.c
index 8ebdfac..655f8d8 100644
--- a/sr_vvms/jnl_file_extend.c
+++ b/sr_vvms/jnl_file_extend.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -141,16 +141,16 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 				{
 					if (new_blocks > avail_blocks)
 					{	/* if we cannot satisfy the requst, it is an error */
-						send_msg(VARLSTCNT(6) ERR_NOSPACEEXT, 4, JNL_LEN_STR(csd),
+						send_msg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_NOSPACEEXT, 4, JNL_LEN_STR(csd),
 							new_blocks, avail_blocks);
 						new_blocks = 0;
 						jpc->status = SS_NORMAL;
 					} else
-						send_msg(VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, JNL_LEN_STR(csd),
+						send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, JNL_LEN_STR(csd),
 							(avail_blocks - new_blocks));
 				}
 			} else
-				send_msg(VARLSTCNT(5) ERR_JNLFILEXTERR, 2, JNL_LEN_STR(csd), status);
+				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_JNLFILEXTERR, 2, JNL_LEN_STR(csd), status);
 			fab.fab$w_deq = new_blocks;
 			rab = cc$rms_rab;
 			rab.rab$l_fab = &fab;
@@ -162,7 +162,7 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 			{
 				new_alq = jb->filesize + new_blocks;
 				if (csd->autoswitchlimit < ((new_blocks * EXTEND_WARNING_FACTOR) + jb->filesize))
-					send_msg(VARLSTCNT(5) ERR_JNLSPACELOW, 3, JNL_LEN_STR(csd),
+					send_msg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_JNLSPACELOW, 3, JNL_LEN_STR(csd),
 						csd->autoswitchlimit - jb->filesize);
 				/* switch journal file if the request cannot be satisfied */
 				if (csd->autoswitchlimit < new_alq)
@@ -233,7 +233,8 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 							fc->op_buff = (sm_uc_ptr_t)csd;
 							fc->op_len = SGMNT_HDR_LEN;
 							fc->op_pos = 1;
-							send_msg(VARLSTCNT(4) ERR_NEWJNLFILECREAT, 2, JNL_LEN_STR(csd));
+							send_msg_csa(CSA_ARG(NULL) VARLSTCNT(4)
+									ERR_NEWJNLFILECREAT, 2, JNL_LEN_STR(csd));
 							/* Dequeue the journal lock on the current jnl generation */
 							jpc->status = gtm_deq(jpc->jnllsb->lockid, NULL, PSL$C_USER, 0);
 							assert(SS$_NORMAL == jpc->status);
@@ -241,8 +242,9 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 							if ((SS_NORMAL != (status = set_jnl_file_close(SET_JNL_FILE_CLOSE_EXTEND)))
 								|| (SS_NORMAL != (status = dbfilop(fc))))
 							{
-								send_msg(VARLSTCNT(7) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region),
-											status, 0, gds_info->fab->fab$l_stv);
+								send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_DBFILERR, 2,
+										DB_LEN_STR(gv_cur_region),
+										status, 0, gds_info->fab->fab$l_stv);
 								jpc->status = ERR_JNLNOCREATE;
 							} else
 							{
@@ -259,18 +261,19 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 									{
 										if (!(IS_RMS_ERROR(jpc->status2) ||
 												IS_SYSTEM_ERROR(jpc->status2)))
-											rts_error(VARLSTCNT(9) jnl_status, 4,
-												JNL_LEN_STR(csd),
+											rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9)
+												jnl_status, 4, JNL_LEN_STR(csd),
 												DB_LEN_STR(gv_cur_region),
 												jpc->status, 0, jpc->status2);
 										else
-											rts_error(VARLSTCNT(8) jnl_status, 4,
-												JNL_LEN_STR(csd),
+											rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8)
+												jnl_status, 4, JNL_LEN_STR(csd),
 												DB_LEN_STR(gv_cur_region),
 												jpc->status, jpc->status2);
 									}
 									else
-										rts_error(VARLSTCNT(7) jnl_status, 4,
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7)
+											jnl_status, 4,
 											JNL_LEN_STR(csd), DB_LEN_STR(gv_cur_region),
 											jpc->status);
 								}
@@ -291,13 +294,15 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 							}
 						} else
 						{
-							send_msg(VARLSTCNT(4) ERR_JNLNOCREATE, 2, JNL_LEN_STR(csd));
+							send_msg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_JNLNOCREATE, 2,
+									JNL_LEN_STR(csd));
 							jpc->status = ERR_JNLNOCREATE;
 						}
 					} else
 					{
 						assert(FALSE);
-						rts_error(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(gv_cur_region));
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd),
+									DB_LEN_STR(gv_cur_region));
 					}
 				} else
 				{	/* nullify extension jnl blocks */
@@ -315,8 +320,8 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 						if (SYSCALL_ERROR(jpc->status))
 						{
 							assert(FALSE);
-							rts_error(VARLSTCNT(6) ERR_JNLWRERR, 2, JNL_LEN_STR(csd), jpc->status,
-								rab.rab$l_stv);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JNLWRERR, 2,
+									JNL_LEN_STR(csd), jpc->status, rab.rab$l_stv);
 						}
 					}
 					jb->filesize = new_alq;	/* Actually this is virtual file size blocks */
@@ -324,7 +329,8 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 					if (SYSCALL_ERROR(jpc->status))
 					{
 						assert(FALSE);
-						rts_error(VARLSTCNT(5) ERR_JNLRDERR, 2, JNL_LEN_STR(csd), jpc->status);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_JNLRDERR, 2,
+								JNL_LEN_STR(csd), jpc->status);
 					}
 					assert((header.virtual_size + new_blocks) == new_alq);
 					header.virtual_size = new_alq;
@@ -333,7 +339,8 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 					if (SYSCALL_ERROR(jpc->status))
 					{
 						assert(FALSE);
-						rts_error(VARLSTCNT(5) ERR_JNLWRERR, 2, JNL_LEN_STR(csd), jpc->status);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_JNLWRERR, 2,
+								JNL_LEN_STR(csd), jpc->status);
 					}
 					assert(!need_extend);	/* ensure we won't go through the for loop again */
 					free(buff);
@@ -377,7 +384,7 @@ uint4 jnl_file_extend(jnl_private_control *jpc, uint4 total_jnl_rec_size)
 
 CONDITION_HANDLER(jnl_file_autoswitch_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	assert(in_jnl_file_autoswitch);
 	in_jnl_file_autoswitch = FALSE;
 	jgbl.dont_reset_gbl_jrec_time = jgbl.save_dont_reset_gbl_jrec_time;
diff --git a/sr_vvms/jnlpool_init.c b/sr_vvms/jnlpool_init.c
index 5964869..83ad29c 100644
--- a/sr_vvms/jnlpool_init.c
+++ b/sr_vvms/jnlpool_init.c
@@ -89,7 +89,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(jnlpool_init_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	if (!(IS_GTM_ERROR(SIGNAL)) || DUMPABLE || SEVERITY == ERROR)
 	{	/* Release resources we have aquired */
 		if (gsec_is_registered)
diff --git a/sr_vvms/map_sym.c b/sr_vvms/map_sym.c
index 7b46824..2544f07 100644
--- a/sr_vvms/map_sym.c
+++ b/sr_vvms/map_sym.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -49,7 +49,9 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
         static MSTR_CONST(xback_sym, "gtm_ac_xback");
         static MSTR_CONST(verify_sym, "gtm_ac_verify");
         static MSTR_CONST(version_sym, "gtm_ac_version");
+	DCL_THREADGBL_ACCESS;
 
+	SETUP_THREADGBL_ACCESS;
 	ESTABLISH(map_sym_ch);
 	fspec_desc.dsc$w_length = fspec->len;
 	fspec_desc.dsc$b_dtype = DSC$K_DTYPE_T;
@@ -73,7 +75,9 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
 			ret_collseq->argtype = 1;
 		} else
 		{
-			gtm_putmsg(VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback_1()"), ret_collseq->act );
+			if (!TREF(skip_gtm_putmsg))
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_COLLFNMISSING, 3,
+						LEN_AND_LIT("gtm_ac_xback_1()"), ret_collseq->act);
 			CHECK_ERR_STAT;
 		}
 	}
@@ -97,7 +101,9 @@ boolean_t map_collseq(mstr *fspec, collseq *ret_collseq)
 				ret_collseq->argtype = 0;
 			} else
 			{
-				gtm_putmsg(VARLSTCNT(5) ERR_COLLFNMISSING, 3, LEN_AND_LIT("gtm_ac_xback()"), ret_collseq->act );
+				if (!TREF(skip_gtm_putmsg))
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_COLLFNMISSING, 3,
+							LEN_AND_LIT("gtm_ac_xback()"), ret_collseq->act);
 				CHECK_ERR_STAT;
 			}
 		} else /* Neither xform_1 or xform is found */
@@ -127,7 +133,7 @@ STATICFNDEF CONDITION_HANDLER(map_sym_ch)
 {
 	int4 	status;
 
-	START_CH;
+	START_CH(FALSE);
 
 	if (DUMP)
 		NEXTCH;
diff --git a/sr_vvms/mu_extract.c b/sr_vvms/mu_extract.c
index 1ae671c..fbb21f9 100644
--- a/sr_vvms/mu_extract.c
+++ b/sr_vvms/mu_extract.c
@@ -35,6 +35,8 @@
 #include "mu_outofband_setup.h"
 #include "gtmmsg.h"
 #include "mvalconv.h"
+#include "hashtab_mname.h"
+#include "change_reg.h"		/* for DO_OP_GVNAME macro */
 
 error_def(ERR_DBRDONLY);
 error_def(ERR_EXTRACTCTRLY);
@@ -43,7 +45,6 @@ error_def(ERR_EXTRCLOSEERR);
 error_def(ERR_EXTRFMT);
 error_def(ERR_EXTRIOERR);
 error_def(ERR_FREEZE);
-error_def(ERR_GTMASSERT);
 error_def(ERR_MUNOACTION);
 error_def(ERR_MUNOFINISH);
 error_def(ERR_MUPCLIERR);
@@ -68,17 +69,15 @@ GBLREF gv_namehead      *gv_target;
 	MV_FORCE_MVAL(&val, nmfield);					\
 	stringpool.free = stringpool.base;				\
 	n2s(&val);							\
-	if (val.mvtype & MV_NUM_APPROX)					\
-		GTMASSERT;						\
-	if (val.str.len > BIN_HEADER_NUMSZ)				\
-		GTMASSERT;						\
+	assertpro(!(val.mvtype & MV_NUM_APPROX));			\
+	assertpro(BIN_HEADER_NUMSZ >= val.str.len);			\
 	for (iter = val.str.len;  iter < BIN_HEADER_NUMSZ;  iter++)	\
 		*outptr++ = '0';					\
 	memcpy(outptr, val.str.addr, val.str.len);			\
 	outptr += val.str.len;						\
 }
 
-LITDEF mval	mu_bin_datefmt	= DEFINE_MVAL_LITERAL(MV_STR, 0, 0, SIZEOF(BIN_HEADER_DATEFMT) - 1, BIN_HEADER_DATEFMT, 0, 0);
+LITDEF mval	mu_bin_datefmt	= DEFINE_MVAL_LITERAL(MV_STR, 0, 0, SIZEOF(BIN_HEADER_DATEFMT) - 1, BIN_HEADER_DATEFMT, 0, 0);	/* BYPASSOK */
 GBLDEF struct FAB	mu_outfab;
 GBLDEF struct RAB 	mu_outrab;
 
@@ -87,13 +86,12 @@ void mu_extract(void)
 	int				reg_max_rec, reg_max_key, reg_max_blk, max_extract_rec_len, status,len, i, format;
 	int				reg_std_null_coll, iter;
 	unsigned char                  	cli_buff[MAX_LINE];
-	boolean_t			logqualifier, freeze = FALSE, success;
+	boolean_t			logqualifier, freeze = FALSE, success, success2;
 	mval				val;
 	char				format_buffer[FORMAT_STR_MAX_SIZE];
-	char				gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */
-	glist				gl_head, *gl_ptr;
+	glist				gl_head, *gl_ptr, *next_gl_ptr;
 	gd_region			*reg, *region_top;
-	mu_extr_stats			global_total,grand_total;
+	mu_extr_stats			global_total, grand_total, spangbl_total;
 	uint4			        item_code, devbufsiz, maxfield;
 	unsigned char			outfilename[256];
 	unsigned short			label_len, n_len;
@@ -109,7 +107,9 @@ void mu_extract(void)
 	static readonly $DESCRIPTOR(log_str,log_text);
 	struct dsc$descriptor_s label_buff;
 	$DESCRIPTOR(dir, "");
-	coll_hdr        extr_collhdr;
+	coll_hdr        		extr_collhdr;
+	gvnh_reg_t			*gvnh_reg;
+	gvnh_spanreg_t			*gvspan, *last_gvspan;
 
 	mu_outofband_setup();
 
@@ -141,8 +141,8 @@ void mu_extract(void)
 		cli_buff[0] = '*';
 		n_len = 1;
 	}
-	grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0;
-	global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0;
+	MU_EXTR_STATS_INIT(grand_total);
+	MU_EXTR_STATS_INIT(global_total);
 	/* gv_select will select globals */
 	gv_select(cli_buff, n_len, freeze, select_text, &gl_head, &reg_max_rec, &reg_max_key, &reg_max_blk, FALSE);
 	if (!gl_head.next)
@@ -323,19 +323,13 @@ void mu_extract(void)
 		}
 	}
 	success = TRUE;
-	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
+	gvspan = NULL;
+	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = next_gl_ptr)
 	{
 		if (mu_ctrly_occurred)
 			break;
-		if (mu_ctrlc_occurred)
-		{
-			gbl_name_buff[0]='^';
-			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
-			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
-				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
-			mu_ctrlc_occurred = FALSE;
-		}
-		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header,&gl_ptr->name.str);
+		DO_OP_GVNAME(gl_ptr);
+			/* sets gv_target/gv_currkey/gv_cur_region/cs_addrs/cs_data to correspond to <globalname,reg> in gl_ptr */
                 if (MU_FMT_BINARY == format)
                 {
                        	extr_collhdr.act = gv_target->act;
@@ -352,26 +346,28 @@ void mu_extract(void)
 				mupip_exit(ERR_MUNOACTION);
 			}
 		}
-		/* Note: Do not change the order of the expression below.
-		 * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all.
-		 * We want mu_extr_gblout() to be called irrespective of the value of success */
-		success = mu_extr_gblout(&gl_ptr->name, &mu_outrab, &global_total, format) && success;
-		if (logqualifier)
+		success2 = mu_extr_gblout(gl_ptr, &mu_outrab, &global_total, format);
+		success = success2 && success;
+		gvnh_reg = gl_ptr->gvnh_reg;
+		last_gvspan = gvspan;
+		gvspan = gvnh_reg->gvspan;
+		if (NULL != gvspan)
+		{	/* this global spans more than one region. aggregate stats across all regions */
+			if (last_gvspan != gvspan)
+				MU_EXTR_STATS_INIT(spangbl_total); /* this is the FIRST spanned region. initialize spangbl_total */
+			MU_EXTR_STATS_ADD(spangbl_total, global_total);	/* add global_total to grand_total */
+		}
+		next_gl_ptr = gl_ptr->next;
+		if (logqualifier || mu_ctrlc_occurred)
 		{
-			gbl_name_buff[0]='^';
-			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
-			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_RECORDSTAT, 6,  gl_ptr->name.str.len + 1, gbl_name_buff,
-				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
+			ISSUE_RECORDSTAT_MSG(gl_ptr, global_total, PRINT_REG_TRUE);
+			if ((NULL != gvspan) && ((NULL == next_gl_ptr) || (next_gl_ptr->gvnh_reg != gvnh_reg)))
+			{	/* this is the LAST spanned region. Display summary line across all spanned regions */
+				ISSUE_RECORDSTAT_MSG(gl_ptr, spangbl_total, PRINT_REG_FALSE);
+			}
 			mu_ctrlc_occurred = FALSE;
 		}
-		grand_total.recknt += global_total.recknt;
-		if (grand_total.reclen < global_total.reclen)
-			grand_total.reclen = global_total.reclen;
-		if (grand_total.keylen < global_total.keylen)
-			grand_total.keylen = global_total.keylen;
-		if (grand_total.datalen < global_total.datalen)
-			grand_total.datalen = global_total.datalen;
-
+		MU_EXTR_STATS_ADD(grand_total, global_total);	/* add global_total to grand_total */
 	}
 	status = sys$close(&mu_outfab);
 	if (status != RMS$_NORMAL)
diff --git a/sr_vvms/mubinccpy.c b/sr_vvms/mubinccpy.c
index 7c056ac..80d65f3 100644
--- a/sr_vvms/mubinccpy.c
+++ b/sr_vvms/mubinccpy.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2010 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -12,6 +12,7 @@
 #include "mdef.h"
 #include "gtm_string.h"
 #include "gtm_stdio.h"
+#include "eintr_wrappers.h"
 
 #include <rms.h>
 #include <ssdef.h>
@@ -19,6 +20,7 @@
 #include <errno.h>
 #include "gtm_socket.h"
 #include "gtm_inet.h"
+#include "gtm_netdb.h"
 #include <efndef.h>
 
 #include "gdsroot.h"
@@ -33,8 +35,6 @@
 #include "muextr.h"
 #include "murest.h"
 #include "mupipbckup.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "sleep_cnt.h"
 #include "util.h"
 #include "cli.h"
@@ -66,7 +66,6 @@ GBLREF  gd_region               *gv_cur_region;
 GBLREF 	sgmnt_addrs		*cs_addrs;
 GBLREF	sgmnt_data_ptr_t	cs_data;
 GBLREF 	unsigned char 		*mubbuf;
-GBLREF	tcp_library_struct      tcp_routines;
 GBLREF  int4                    backup_write_errno;
 GBLREF	int4			backup_close_errno;
 GBLREF	boolean_t		debug_mupip;
@@ -84,6 +83,9 @@ GBLREF	uint4			process_id;
 						return FALSE;           \
 				}
 
+/* VMS-only code, which never uses CSA_ARG(). Using GTM_PUTMSG avoids cosmetic warnings. */
+#define GTM_PUTMSG		gtm_putmsg
+
 LITREF	mval		mu_bin_datefmt;
 
 /* forward declarations */
@@ -92,6 +94,11 @@ static void file_close(char *temp);
 static void tcp_write(char *temp, char *buf, int nbytes);
 static void tcp_close(char *temp);
 
+error_def(ERR_BCKUPBUFLUSH);
+error_def(ERR_COMMITWAITSTUCK);
+error_def(ERR_DBCCERR);
+error_def(ERR_ERRCALL);
+
 bool mubinccpy(backup_reg_list *list)
 {
 	static readonly mval	null_str = {MV_STR, 0, 0 , 0 , 0, 0};
@@ -120,11 +127,6 @@ bool mubinccpy(backup_reg_list *list)
 	enum db_ver		dummy_odbv;
 	int4			blk_bsiz;
 
-	error_def(ERR_BCKUPBUFLUSH);
-	error_def(ERR_COMMITWAITSTUCK);
-	error_def(ERR_DBCCERR);
-	error_def(ERR_ERRCALL);
-
 	assert(list->reg == gv_cur_region);
 	assert(incremental);
 	/* Make sure inc_header  can be same size on all platforms. Some platforms pad 8 byte aligned structures
@@ -172,7 +174,7 @@ bool mubinccpy(backup_reg_list *list)
 				case RMS$_FILEPURGED:
 					break;
 				default:
-					gtm_putmsg(status, 0, mubincfab.fab$l_stv);
+					GTM_PUTMSG(status, 0, mubincfab.fab$l_stv);
 					util_out_print("Error: Cannot create backup file !AD.",
 						       TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna);
 					return FALSE;
@@ -183,7 +185,7 @@ bool mubinccpy(backup_reg_list *list)
 			mubincrab.rab$l_rop = RAB$M_WBH;
 			if (RMS$_NORMAL != (status = sys$connect(&mubincrab)))
 			{
-				gtm_putmsg(status, 0, mubincrab.rab$l_stv);
+				GTM_PUTMSG(status, 0, mubincrab.rab$l_stv);
 				util_out_print("Error: Cannot connect to backup file !AD.",
 					       TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna);
 				mubincfab.fab$l_fop |= FAB$M_DLT;
@@ -200,7 +202,6 @@ bool mubinccpy(backup_reg_list *list)
 				       fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr);
 			return FALSE;
 		case backup_to_tcp:
-			iotcp_fillroutine();
 			/* parse it first */
 			switch (match = SSCANF(file->addr, "%[^:]:%hu", addr, &port))
 			{
@@ -301,7 +302,7 @@ bool mubinccpy(backup_reg_list *list)
 							      0, 0, 0)))
 			    || (SS$_NORMAL != (status = rd_iosb[0])))
 			{
-				gtm_putmsg(VARLSTCNT(1) status);
+				GTM_PUTMSG(VARLSTCNT(1) status);
 				util_out_print("Error reading data from database !AD.", TRUE,
 					       fcb->fab$b_fns, fcb->fab$l_fna);
 				free(outptr);
@@ -455,7 +456,7 @@ bool mubinccpy(backup_reg_list *list)
 			 */
 			if (cs_addrs->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(cs_addrs, NULL))
 			{
-				gtm_putmsg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1,
+				GTM_PUTMSG(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1,
 					cs_addrs->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(gv_cur_region));
 				rel_crit(gv_cur_region);
 				free(outptr);
@@ -479,7 +480,7 @@ bool mubinccpy(backup_reg_list *list)
 				util_out_print("Process !UL encountered the following error.", TRUE,
 					       cs_addrs->shmpool_buffer->failed);
 				if (0 != cs_addrs->shmpool_buffer->backup_errno)
-					gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
+					GTM_PUTMSG(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
 				free(outptr);
 				free(bm_blk_buff);
 				error_mupip = TRUE;
@@ -489,7 +490,7 @@ bool mubinccpy(backup_reg_list *list)
 			backup_buffer_flush(gv_cur_region);
 			if (++counter > MAX_BACKUP_FLUSH_TRY)
 			{
-				gtm_putmsg(VARLSTCNT(1) ERR_BCKUPBUFLUSH);
+				GTM_PUTMSG(VARLSTCNT(1) ERR_BCKUPBUFLUSH);
 				free(outptr);
 				free(bm_blk_buff);
 				error_mupip = TRUE;
@@ -502,7 +503,7 @@ bool mubinccpy(backup_reg_list *list)
 			{	/* Force shmpool recovery to see if it can find the lost blocks */
 				if (!shmpool_lock_hdr(gv_cur_region))
 				{
-					gtm_putmsg(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region),
+					GTM_PUTMSG(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region),
 						   ERR_ERRCALL, 3, CALLFROM);
 					free(outptr);
 					free(bm_blk_buff);
@@ -533,7 +534,7 @@ bool mubinccpy(backup_reg_list *list)
 
 		if (RMS$_NORMAL != status)
 		{
-			gtm_putmsg(status, 0, temp_fab.fab$l_stv);
+			GTM_PUTMSG(status, 0, temp_fab.fab$l_stv);
 			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
 			free(outptr);
 			free(bm_blk_buff);
@@ -544,7 +545,7 @@ bool mubinccpy(backup_reg_list *list)
 
 		if (RMS$_NORMAL != (status = sys$connect(&temp_rab)))
 		{
-			gtm_putmsg(status, 0, temp_rab.rab$l_stv);
+			GTM_PUTMSG(status, 0, temp_rab.rab$l_stv);
 			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
 			free(outptr);
 			free(bm_blk_buff);
@@ -573,7 +574,7 @@ bool mubinccpy(backup_reg_list *list)
 
 		if (RMS$_NORMAL != status)
 		{
-			gtm_putmsg(status, 0, temp_rab.rab$l_stv);
+			GTM_PUTMSG(status, 0, temp_rab.rab$l_stv);
 			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
 			free(outptr);
 			free(bm_blk_buff);
@@ -585,7 +586,7 @@ bool mubinccpy(backup_reg_list *list)
 		/* ---------------- Close the temporary file ----------------------- */
 		if (RMS$_NORMAL != (status = sys$close(&temp_fab)))
 		{
-			gtm_putmsg(status, 0, temp_fab.fab$l_stv);
+			GTM_PUTMSG(status, 0, temp_fab.fab$l_stv);
 			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
 			free(outptr);
 			free(bm_blk_buff);
@@ -641,7 +642,7 @@ bool mubinccpy(backup_reg_list *list)
 		util_out_print("Process !UL encountered the following error.", TRUE,
 			       cs_addrs->shmpool_buffer->failed);
 		if (0 != cs_addrs->shmpool_buffer->backup_errno)
-			gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
+			GTM_PUTMSG(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
 		free(outptr);
 		free(bm_blk_buff);
 		error_mupip = TRUE;
@@ -676,7 +677,8 @@ static void tcp_write(char *temp, char *buf, int nbytes)
 
 	do
 	{
-		if (-1 != (iostatus = tcp_routines.aa_send(socket, buf + nwritten, nbytes - nwritten, 0)))
+		SEND(socket, buf + nwritten, nbytes - nwritten, 0, iostatus);
+		if (-1 != iostatus)
 		{
 			nwritten += iostatus;
 			if (nwritten == nbytes)
@@ -687,8 +689,8 @@ static void tcp_write(char *temp, char *buf, int nbytes)
 
 	if ((nwritten != nbytes) && (-1 == iostatus))
 	{
-		gtm_putmsg(VARLSTCNT(1) errno);
-		tcp_routines.aa_close(socket);
+		GTM_PUTMSG(VARLSTCNT(1) errno);
+		close(socket);
 		backup_write_errno = errno;
 	}
 
@@ -700,7 +702,7 @@ static void tcp_close(char *temp)
 	int 	socket;
 
 	socket = *((int *)(temp));
-	tcp_routines.aa_close(socket);
+	close(socket);
 
 	return;
 }
@@ -709,7 +711,6 @@ static void file_write(char *temp, char *buf, int nbytes)
 {
 	uint4		status;
 	struct RAB	*rab;
-	void		gtm_putmsg();
 
 	assert(nbytes > 4);
 	rab = (struct RAB *)(temp);
@@ -718,7 +719,7 @@ static void file_write(char *temp, char *buf, int nbytes)
 	if (RMS$_NORMAL != (status = sys$put(rab)))
 	{
 		backup_write_errno = status;
-		gtm_putmsg(status, 0, rab->rab$l_stv);
+		GTM_PUTMSG(status, 0, rab->rab$l_stv);
 		(rab->rab$l_fab)->fab$l_fop |= FAB$M_DLT;
 		sys$close(rab->rab$l_fab);
 	}
@@ -730,7 +731,6 @@ static void file_close(char *temp)
 {
 	uint4		status;
 	struct RAB	*rab;
-	void 		gtm_putmsg();
 
 	rab = (struct RAB *)(temp);
 	if (error_mupip)
@@ -739,7 +739,7 @@ static void file_close(char *temp)
 	if (status != RMS$_NORMAL)
 	{
 		backup_close_errno = status;
-		gtm_putmsg(status);
+		GTM_PUTMSG(status);
 		util_out_print("FATAL ERROR: System Service failure.",TRUE);
 	}
 
diff --git a/sr_vvms/mupip.c b/sr_vvms/mupip.c
index eba05b0..42e3075 100644
--- a/sr_vvms/mupip.c
+++ b/sr_vvms/mupip.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,8 +31,6 @@
 #include "buddy_list.h"		/* needed for tp.h */
 #include "hashtab_int4.h"	/* needed for tp.h */
 #include "tp.h"
-#include "min_max.h"		/* needed for init_root_gv.h */
-#include "init_root_gv.h"
 #include "desblk.h"		/* for desblk structure */
 #include "repl_msg.h"
 #include "gtmsource.h"
@@ -57,7 +55,6 @@ GBLREF desblk		exi_blk;
 GBLREF bool		licensed;
 GBLREF int4		lkid, lid;
 GBLREF bool		in_backup;
-GBLREF mval		curr_gbl_root;
 GBLREF int4		exi_condition;
 GBLREF spdesc		rts_stringpool, stringpool;
 
@@ -132,12 +129,11 @@ mupip()
 	{
 		licensed = FALSE;
 		if (LP_INVCSM != status)
-			rts_error(VARLSTCNT(1) status);
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	}
 #	endif
 	ast_init();
 	initialize_pattern_table();
-	INIT_GBL_ROOT();
 	stp_init(STP_INITSIZE);
 	rts_stringpool = stringpool;
 	mupip_getcmd();
diff --git a/sr_vvms/mupip_restore.c b/sr_vvms/mupip_restore.c
index b73fd1a..5a3f542 100644
--- a/sr_vvms/mupip_restore.c
+++ b/sr_vvms/mupip_restore.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -20,7 +20,10 @@
 #include <errno.h>
 #include "gtm_socket.h"
 #include "gtm_inet.h"
+#include "gtm_netdb.h"
 #include "gtm_time.h"
+#include "eintr_wrappers.h"
+#include "gtm_select.h"
 
 #include "gdsroot.h"
 #include "gtm_facility.h"
@@ -34,8 +37,6 @@
 #include "gdsbml.h"
 #include "mupipbckup.h"
 #include "murest.h"
-#include "iotcproutine.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "io.h"
 #include "iotimer.h"
@@ -69,10 +70,13 @@
 					}					\
 				}
 
+
+/* No csa needed for VMS code, so use GTM_PUTMSG to avoid lots of CSA_ARG(NULL) boilerplate. */
+#define GTM_PUTMSG	gtm_putmsg
+
 GBLDEF	inc_list_struct 	in_files;
 GBLREF 	gd_region		*gv_cur_region;
 GBLREF	uint4			restore_read_errno;
-GBLREF  tcp_library_struct	tcp_routines;
 GBLREF  bool			mubtomag;
 GBLREF 	int4 			mubmaxblk;
 
@@ -122,7 +126,7 @@ void mupip_restore(void)
 		mupip_exit(ERR_MUNODBNAME);
 	if (!mu_rndwn_file(TRUE))
 	{
-		gtm_putmsg(VARLSTCNT(4) ERR_MUSTANDALONE, 2, DB_LEN_STR(gv_cur_region));
+		GTM_PUTMSG(VARLSTCNT(4) ERR_MUSTANDALONE, 2, DB_LEN_STR(gv_cur_region));
 		mupip_exit(ERR_MUPRESTERR);
 	}
 	fc = gv_cur_region->dyn.addr->file_cntl;
@@ -131,7 +135,7 @@ void mupip_restore(void)
 	status = dbfilop(fc);
 	if (SS$_NORMAL != status)
 	{
-		gtm_putmsg(VARLSTCNT(1) status);
+		GTM_PUTMSG(VARLSTCNT(1) status);
 		util_out_print("Error accessing output file !AD. Aborting restore.", TRUE, DB_LEN_STR(gv_cur_region));
 		mupip_exit(status);
 	}
@@ -199,7 +203,7 @@ void mupip_restore(void)
 				if ((RMS$_NORMAL != (status = sys$open(&infab))) ||
 					(RMS$_NORMAL != (status = sys$connect(&inrab))))
 				{
-					gtm_putmsg(VARLSTCNT(1) status);
+					GTM_PUTMSG(VARLSTCNT(1) status);
 					util_out_print("Error accessing input file !AD. Aborting restore.", TRUE,
 						infab.fab$b_fns, infab.fab$l_fna);
 					free(inbuf);
@@ -242,7 +246,6 @@ void mupip_restore(void)
 				}
 				if ((0 == cli_get_int("NETTIMEOUT", &timeout)) || (0 > timeout))
 					timeout = DEFAULT_BKRS_TIMEOUT;
-				iotcp_fillroutine();
 				if (0 > (backup_socket = tcp_open(addr, port, timeout, TRUE)))
 				{
 					util_out_print("Error establishing TCP connection to !AD.", TRUE,
@@ -462,7 +465,7 @@ void mupip_restore(void)
 			case backup_to_file:
 				if (RMS$_NORMAL != (status = sys$close(&infab)))
 				{
-					gtm_putmsg(VARLSTCNT(1) status);
+					GTM_PUTMSG(VARLSTCNT(1) status);
 					util_out_print("WARNING:  DB file !AD restore aborted, file !AD not valid", TRUE,
 						DB_LEN_STR(gv_cur_region),
 						ptr->input_file.len, ptr->input_file.addr);;
@@ -480,7 +483,7 @@ void mupip_restore(void)
 #			endif
 				break;
 			case backup_to_tcp:
-				tcp_routines.aa_close(backup_socket);
+				close(backup_socket);
 				break;
 		}
 	}
@@ -503,7 +506,7 @@ static void record_read(char *temp, char *buf, int nbytes) /* *nbytes is what we
 	status = sys$get(rab);
 	if (RMS$_NORMAL != status)
 	{
-		gtm_putmsg(VARLSTCNT(1) status);
+		GTM_PUTMSG(VARLSTCNT(1) status);
 		util_out_print("Error accessing input file !AD. Aborting restore.", TRUE,
 			rab->rab$l_fab->fab$b_fns, rab->rab$l_fab->fab$l_fna);
 		sys$close(rab->rab$l_fab);
@@ -518,22 +521,23 @@ static void tcp_read(char *temp, char *buf, int nbytes) /* asking for *nbytes, h
 	int		socket, needed, status;
 	char		*curr;
 	fd_set		fs;
-	ABS_TIME	nap;
+	struct timeval	nap;
 
 	needed = nbytes;
 	curr = buf;
 	socket = *(int *)(temp);
-	nap.at_sec = 1;
-	nap.at_usec = 0;
+	nap.tv_sec = 1;
+	nap.tv_usec = 0;
 	while (1)
 	{
+		assertpro(FD_SETSIZE > socket);
 		FD_ZERO(&fs);
 		FD_SET(socket, &fs);
 		assert(0 != FD_ISSET(socket, &fs));
-		status = tcp_routines.aa_select(socket + 1, (void *)(&fs), (void *)0, (void *)0, &nap);
+		status = select(socket + 1, (void *)(&fs), (void *)0, (void *)0, &nap);
 		if (status > 0)
 		{
-			status = tcp_routines.aa_recv(socket, curr, needed, 0);
+			RECV(socket, curr, needed, 0, status);
 			if ((0 == status) || (needed == status))	/* lost connection or all set */
 			{
 				break;
@@ -545,8 +549,8 @@ static void tcp_read(char *temp, char *buf, int nbytes) /* asking for *nbytes, h
 		}
 		if ((status < 0) && (errno != EINTR))
 		{
-			gtm_putmsg(VARLSTCNT(1) errno);
-			tcp_routines.aa_close(socket);
+			GTM_PUTMSG(VARLSTCNT(1) errno);
+			close(socket);
 			restore_read_errno = errno;
 			break;
 		}
diff --git a/sr_vvms/mupip_rundown.c b/sr_vvms/mupip_rundown.c
index 8f7192e..9f55754 100644
--- a/sr_vvms/mupip_rundown.c
+++ b/sr_vvms/mupip_rundown.c
@@ -105,7 +105,7 @@ error_def(ERR_VMSMEMORY);
 
 CONDITION_HANDLER(mupip_rundown_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	if ((0 != rndwn_pid) && !(SEVERITY & SUCCESS))
 	{
 		if (DUMPABLE)
@@ -204,12 +204,14 @@ void mupip_rundown(void)
 							status = del_sec(SEC$M_SYSGBL, &d_sec, 0);
 					}
 					if (status & 1)
-						rts_error(VARLSTCNT(4) ERR_MUSECDEL, 2, d_sec.dsc$w_length, d_sec.dsc$a_pointer);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSECDEL, 2,
+								d_sec.dsc$w_length, d_sec.dsc$a_pointer);
 					else
 					{
 						if (status)
-							gtm_putmsg(VARLSTCNT(1) status);
-						rts_error(VARLSTCNT(4) ERR_MUSECNOTDEL, 2, d_sec.dsc$w_length, d_sec.dsc$a_pointer);
+							gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSECNOTDEL, 2,
+								d_sec.dsc$w_length, d_sec.dsc$a_pointer);
 						exit_status = ERR_MUNOTALLSEC;
 					}
 				} else if ((0 == memcmp("GT$P", mbuff, SIZEOF("GT$P") - 1)) ||
@@ -225,10 +227,12 @@ void mupip_rundown(void)
 						replpool_id.pool_type = RECVPOOL_SEGMENT;
 					sgmnt_found = FALSE;
 					if (mu_rndwn_replpool(&replpool_id, TRUE, &sgmnt_found) && sgmnt_found)
-						rts_error(VARLSTCNT(4) ERR_MUREPLSECDEL, 2, LEN_AND_STR(mbuff));
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUREPLSECDEL, 2,
+								LEN_AND_STR(mbuff));
 					else if (sgmnt_found)
 					{
-						rts_error(VARLSTCNT(4) ERR_MUREPLSECNOTDEL, 2, LEN_AND_STR(mbuff));
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUREPLSECNOTDEL, 2,
+								LEN_AND_STR(mbuff));
 						exit_status = ERR_MUNOTALLSEC;
 					}
 				}
@@ -300,22 +304,22 @@ void mupip_rundown(void)
 			if (status & 1)
 			{
 #ifdef	IPCRM_FOR_SANCHEZ_ONLY
-				rts_error(VARLSTCNT(6) ERR_MUDESTROYSUC, 4,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUDESTROYSUC, 4,
 					name_dsc.dsc$w_length, name_dsc.dsc$a_pointer, DB_LEN_STR(gv_cur_region));
 #else
-				rts_error(VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
 #endif
 			}
 			else
 			{
 				if (status)
-					gtm_putmsg(VARLSTCNT(1) status);
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 #ifdef	IPCRM_FOR_SANCHEZ_ONLY
-				rts_error(VARLSTCNT(6) ERR_MUDESTROYFAIL, 4,
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUDESTROYFAIL, 4,
 					name_dsc.dsc$w_length, name_dsc.dsc$a_pointer, DB_LEN_STR(gv_cur_region));
 				exit_status = ERR_MUNOACTION;
 #else
-				gtm_putmsg(VARLSTCNT(4) ERR_MUFILRNDWNFL, 2, DB_LEN_STR(gv_cur_region));
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUFILRNDWNFL, 2, DB_LEN_STR(gv_cur_region));
 				exit_status = ERR_MUNOTALLSEC;
 #endif
 			}
@@ -334,7 +338,7 @@ void mupip_rundown(void)
 					replpool_id.gtmgbldir, &full_len, SIZEOF(replpool_id.gtmgbldir), &status))
 			{
 				util_out_print("Failed to get full path for gtmgbldir, !AD", TRUE, tran_name->len, tran_name->addr);
-				gtm_putmsg(VARLSTCNT(1) status);
+				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 				exit_status = ERR_MUNOTALLSEC;
 			} else
 			{
@@ -346,11 +350,11 @@ void mupip_rundown(void)
 				replpool_id.pool_type = JNLPOOL_SEGMENT;
 				sgmnt_found = FALSE;
 				if (mu_rndwn_replpool(&replpool_id, FALSE, &sgmnt_found) && sgmnt_found)
-					rts_error(VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
 							tran_name->len, replpool_id.gtmgbldir);
 				else if (sgmnt_found)
 				{
-					gtm_putmsg(VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, res_name[0], &res_name[1],
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUJPOOLRNDWNFL, 4, res_name[0], &res_name[1],
 							tran_name->len, replpool_id.gtmgbldir);
 					exit_status = ERR_MUNOTALLSEC;
 				}
@@ -360,11 +364,11 @@ void mupip_rundown(void)
 				replpool_id.pool_type = RECVPOOL_SEGMENT;
 				sgmnt_found = FALSE;
 				if (mu_rndwn_replpool(&replpool_id, FALSE, &sgmnt_found) && sgmnt_found)
-					rts_error(VARLSTCNT(6) ERR_MURPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MURPOOLRNDWNSUC, 4, res_name[0], &res_name[1],
 							tran_name->len, replpool_id.gtmgbldir);
 				else if (sgmnt_found)
 				{
-					gtm_putmsg(VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, res_name[0], &res_name[1],
+					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MURPOOLRNDWNFL, 4, res_name[0], &res_name[1],
 							tran_name->len, replpool_id.gtmgbldir);
 					exit_status = ERR_MUNOTALLSEC;
 				}
diff --git a/sr_vvms/obj_code.c b/sr_vvms/obj_code.c
index 0d586e1..6e7edd1 100644
--- a/sr_vvms/obj_code.c
+++ b/sr_vvms/obj_code.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -31,6 +31,7 @@
 #include "cg_var.h"
 #include "gtm_string.h"
 #include "stringpool.h"
+#include "rtn_src_chksum.h"
 
 GBLREF boolean_t		run_time;
 GBLREF command_qualifier	cmd_qlf;
@@ -77,7 +78,7 @@ void cg_lab (mlabel *l, int4 base);
  *
  */
 
-void	obj_code (uint4 src_lines, uint4 checksum)
+void	obj_code (uint4 src_lines, void *checksum_ctx)
 {
 	rhdtyp		rhead;
 	mline		*mlx, *mly;
@@ -113,7 +114,7 @@ void	obj_code (uint4 src_lines, uint4 checksum)
 	if (!(cmd_qlf.qlf & CQ_OBJECT))
 		return;
 	rhead.ptext_ptr = SIZEOF(rhead);
-	rhead.checksum = checksum;
+	set_rtnhdr_checksum(&rhead, (gtm_rtn_src_chksum_ctx *)checksum_ctx);
 	rhead.vartab_ptr = code_size;
 	rhead.vartab_len = mvmax;
 	code_size += mvmax * SIZEOF(var_tabent);
diff --git a/sr_vvms/op_fnzfile.c b/sr_vvms/op_fnzfile.c
index 2d8b2a7..3cd9b4a 100644
--- a/sr_vvms/op_fnzfile.c
+++ b/sr_vvms/op_fnzfile.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -99,6 +99,9 @@ typedef struct
 	unsigned y;
 }quad_struct;
 
+error_def(ERR_ZFILNMBAD);
+error_def(ERR_ZFILKEYBAD);
+
 void op_fnzfile(mval *name,mval *key,mval *ret)
 {
 	struct NAM	nm;
@@ -110,25 +113,21 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 	quad_struct 	*cdt;
 	quad_struct 	*edt;
 	quad_struct 	*rdt;
-	int4 days;
-	int4 seconds;
-	error_def(ERR_ZFILNMBAD);
-	error_def(ERR_ZFILKEYBAD);
+	int4		days;
+	int4		seconds;
 	struct FAB	f;
-	int4 	status;
-	char 	index,slot,last_slot;
-	char	buf[MAX_KW_LEN] ;
+	int4		status;
+	char		index,slot,last_slot;
+	char		buf[MAX_KW_LEN] ;
 
 	assert(stringpool.free >= stringpool.base);
 	assert(stringpool.top >= stringpool.free);
 	MV_FORCE_STR(name);
 	if (name->str.len == 0)
-	{	rts_error(VARLSTCNT(4) ERR_ZFILNMBAD,2,4,"NULL");
-	}
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZFILNMBAD,2,4,"NULL");
 	MV_FORCE_STR(key);
 	if (key->str.len == 0 || key->str.len != KEY_LEN)
-	{	rts_error(VARLSTCNT(4) ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
-	}
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
 	lower_to_upper(buf,key->str.addr,MIN(key->str.len,MAX_KW_LEN)) ;
 	nm = cc$rms_nam;
 	dat = cc$rms_xabdat;
@@ -143,18 +142,17 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 	sum.xab$l_nxt = &pro;
 	pro.xab$l_nxt = &fhc;
 	if ((index = buf[0] - 'A') < MIN_ZF_INDEX || index > MAX_ZF_INDEX)
-		rts_error(VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
 	if (!(last_slot = zfile_index[ index ].last_index))
-		rts_error(VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
 	slot = zfile_index[ index ].index;
 	for ( ; slot < last_slot ; slot++ )
 	{
 		if (!memcmp(zfile_key[slot].name,buf,3))
-		{	break;
-		}
+			break;
 	}
 	if (slot == last_slot)
-		rts_error(VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4)  ERR_ZFILKEYBAD,2,key->str.len,key->str.addr);
 	f  = cc$rms_fab;
 	f.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_SHRDEL | FAB$M_SHRUPD;
 	f.fab$l_nam = &nm;
@@ -162,7 +160,7 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 	f.fab$l_fna = name->str.addr;
 	f.fab$b_fns = name->str.len;
 	if ((status = sys$open(&f)) != RMS$_NORMAL)
-		rts_error(VARLSTCNT(1) status);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	ENSURE_STP_FREE_SPACE(MAX_ZF_LEN);
 	switch( slot )
 	{
@@ -172,12 +170,12 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 	case ZF_BDT:
 	{	ret->mvtype = MV_STR;
 		if (!bdt->x && !bdt->y)
-		{	ret->str.len = 0;
+		{
+			ret->str.len = 0;
 			break;
 		}
 		if ((status= lib$day( &days, bdt, &seconds )) != SS$_NORMAL)
-		{	rts_error(VARLSTCNT(1)  status );
-		}
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1)  status );
 		days += DAYS;
 		seconds /= CENTISECONDS;
 		ret->str.addr = stringpool.free;
@@ -202,8 +200,7 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 	case ZF_CDT:
 	{
 		if ((status= lib$day( &days, cdt, &seconds )) != SS$_NORMAL)
-		{	rts_error(VARLSTCNT(1)  status );
-		}
+			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1)  status );
 		days += DAYS;
 		seconds /= CENTISECONDS;
 		ret->mvtype = MV_STR;
@@ -256,7 +253,7 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 		if ((status= lib$day(	 &days
 					,edt
 					,&seconds	)) != SS$_NORMAL)
-		{	rts_error(VARLSTCNT(1)  status );
+		{	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1)  status );
 		}
 		days += DAYS;
 		seconds /= CENTISECONDS;
@@ -409,9 +406,8 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 			stringpool.free += RAT_LEN;
 			*stringpool.free++ = ',';
 		}
-		if (stringpool.free != ret->str.addr)
-		{	stringpool.free--;
-		}
+		if (!IS_AT_END_OF_STRINGPOOL(ret->str.addr, 0));
+			stringpool.free--;
 		ret->str.len = (char *) stringpool.free - ret->str.addr;
 		break;
 	case ZF_RCK:
@@ -426,7 +422,7 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 		if ((status= lib$day(	 &days
 					,rdt
 					,&seconds	)) != SS$_NORMAL)
-		{	rts_error(VARLSTCNT(1)  status );
+		{	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1)  status );
 		}
 		days += DAYS;
 		seconds /= CENTISECONDS;
@@ -490,7 +486,6 @@ void op_fnzfile(mval *name,mval *key,mval *ret)
 		assert(0);
 	}
 	if ((status = sys$close(&f)) != RMS$_NORMAL)
-	{	rts_error(VARLSTCNT(1)  status );
-	}
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
 	return;
 }
diff --git a/sr_vvms/op_setzp1.c b/sr_vvms/op_setzp1.c
index eeaca0c..c8cf916 100644
--- a/sr_vvms/op_setzp1.c
+++ b/sr_vvms/op_setzp1.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2006, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2006, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -232,7 +232,7 @@ void op_setzp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 	/* Calculate total string len. delim_cnt has needed padding delimiters for null fields */
 	str_len = (size_t)expr->str.len + (size_t)pfx_str_len + delim_cnt + (size_t)sfx_str_len;
 	if (MAX_STRLEN < str_len)
-		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
+		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MAXSTRLEN);
 	ENSURE_STP_FREE_SPACE((int)str_len);
 	str_addr = stringpool.free;
 	start_pfx = (unsigned char *)src->str.addr;
@@ -257,7 +257,7 @@ void op_setzp1(mval *src, int delim, mval *expr, int ind, mval *dst)
 		memcpy(str_addr, start_pfx + sfx_start_offset, sfx_str_len);
 		str_addr += sfx_str_len;
 	}
-	assert((str_addr - stringpool.free) == str_len);
+	assert(IS_AT_END_OF_STRINGPOOL(str_addr, -str_len));
 	dst->mvtype = MV_STR;
 	dst->str.len = str_addr - stringpool.free;
 	dst->str.addr = (char *)stringpool.free;
diff --git a/sr_vvms/rtnhdr.h b/sr_vvms/rtnhdr.h
index 2f28c4b..427bf14 100644
--- a/sr_vvms/rtnhdr.h
+++ b/sr_vvms/rtnhdr.h
@@ -137,13 +137,16 @@ typedef struct
 #define NOVERIFY	FALSE
 
 int get_src_line(mval *routine, mval *label, int offset, mstr **srcret, boolean_t verifytrig);
+void free_src_tbl(rhdtyp *rtn_vector);
 unsigned char *find_line_start(unsigned char *in_addr, rhdtyp *routine);
 int4 *find_line_addr(rhdtyp *routine, mstr *label, int4 offset, mident **lent_name);
 rhdtyp *find_rtn_hdr(mstr *name);
+boolean_t find_rtn_tabent(rtn_tabent **res, mstr *name);
 bool zlput_rname(rhdtyp *hdr);
 rhdtyp *make_dmode(void);
 void comp_lits(rhdtyp *rhead);
 rhdtyp  *op_rhdaddr(mval *name, rhdtyp *rhd);
+rhdtyp	*op_rhdaddr1(mval *name);
 lnr_tabent *op_labaddr(rhdtyp *routine, mval *label, int4 offset);
 void urx_resolve(rhdtyp *rtn, lab_tabent *lbl_tab, lab_tabent *lbl_top);
 char *rtnlaboff2entryref(char *entryref_buff, mident *rtn, mident *lab, int offset);
diff --git a/sr_vvms/ttt.c b/sr_vvms/ttt.c
index 83e0ae3..e08ca54 100644
--- a/sr_vvms/ttt.c
+++ b/sr_vvms/ttt.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2012 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -13,683 +13,683 @@
 #include "vxi.h"
 #include "vxt.h"
 #include "xfer_enum.h"
-LITDEF short ttt[4203] = {
+LITDEF short ttt[4220] = {
 
-/*    0 */	0,0,0,0,322,3463,2919,566,
-/*    8 */	2297,2904,2934,1978,418,3413,2099,3035,
-/*   16 */	2176,2167,3646,3683,2140,2149,2215,2161,
-/*   24 */	2206,2185,2122,786,801,813,825,864,
-/*   32 */	882,903,932,962,977,992,1010,3020,
-/*   40 */	1082,1115,1151,1217,1268,1565,1598,1613,
-/*   48 */	1643,1709,1739,1763,1826,1847,1862,3478,
-/*   56 */	3500,0,0,0,0,581,0,522,
-/*   64 */	0,1964,0,3006,0,0,0,0,
-/*   72 */	0,0,354,430,2275,2281,2696,2723,
-/*   80 */	2741,2844,2782,2773,2859,3552,3636,2955,
-/*   88 */	0,2985,3101,3064,3049,3079,3427,3277,
-/*   96 */	3558,3570,3585,3609,3618,3603,3594,3312,
-/*  104 */	3679,3692,3714,3751,3763,3784,3808,3874,
-/*  112 */	0,0,2892,2257,3153,4152,660,4155,
-/*  120 */	714,2753,3119,536,542,4158,2360,2447,
-/*  128 */	2347,489,2383,2467,2131,2405,2477,4161,
-/*  136 */	2242,2233,4165,1286,4166,350,346,3301,
-/*  144 */	442,4170,4173,4176,2971,4179,4182,4185,
-/*  152 */	4188,4191,4194,3449,0,2868,2536,2514,
-/*  160 */	1526,2505,2293,2113,2819,1999,739,2809,
-/*  168 */	0,0,2312,3627,3655,1490,3579,2395,
-/*  176 */	1992,551,3775,1811,2224,1202,337,3105,
-/*  184 */	623,692,604,670,3739,1130,3707,2948,
-/*  192 */	2251,2883,2962,642,1022,2823,4197,2457,
-/*  200 */	3826,3844,3859,513,2838,3097,1925,3895,
-/*  208 */	3886,1304,3441,595,1628,1697,2420,4200,
-/*  216 */	3512,2493,748,843,3136,3667,3536,3522,
-/*  224 */	3529,3518,724,917,2370,1064,2334,1052,
-/*  232 */	2194,1037,1097,2432,1460,1403,1388,1442,
-/*  240 */	1358,1370,1415,1343,1427,1475,769,3399,
-/*  248 */	0,941,950,3256,1838,3235,2321,3931,
-/*  256 */	3901,3907,3919,3941,1241,1253,1175,1187,
-/*  264 */	1229,3490,1673,1910,0,1316,1502,1547,
-/*  272 */	3333,1580,1658,1685,1796,1775,3375,1721,
-/*  280 */	3354,1892,0,0,1952,3964,1874,3163,
-/*  288 */	3175,3187,3199,2732,2747,1514,453,1331,
-/*  296 */	0,651,3211,3223,0,3955,0,0,
-/*  304 */	0,0,3730,3976,3987,3999,4008,4022,
-/*  312 */	4035,4045,4062,4071,4080,4092,4104,4116,
-/*  320 */	4131,4143,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,
-/*  328 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_add,
-/*  336 */	VXT_END,
-/*  337 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_bindparm,
-/*  345 */	VXT_END,
-/*  346 */	VXI_INCL,VXT_VAL,1,VXT_END,
-/*  350 */	VXI_CLRL,VXT_VAL,0,VXT_END,
-/*  354 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_break,VXT_END,
-/*  358 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callb,VXI_BRB,VXT_JMP,
-/*  366 */	1,VXT_END,
-/*  368 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_calll,VXI_JMP,VXT_JMP,
-/*  376 */	1,VXT_END,
-/*  378 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callw,VXI_BRW,VXT_JMP,
-/*  386 */	1,VXT_END,
-/*  388 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspb,VXI_BRB,VXT_JMP,
-/*  396 */	1,VXT_END,
-/*  398 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspl,VXI_JMP,VXT_JMP,
-/*  406 */	1,VXT_END,
-/*  408 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspw,VXI_BRW,VXT_JMP,
-/*  416 */	1,VXT_END,
-/*  418 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
-/*  426 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_cat,VXT_END,
-/*  430 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/*  438 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_close,VXT_END,
-/*  442 */	VXI_BICB2,VXT_LIT,1,VXT_REG,0x5A,VXI_CALLS,VXT_LIT,0,
-/*  450 */	VXT_XFER,SIZEOF(char *) * (short int)xf_dt_false,VXT_END,
-/*  453 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_clralsvars,
-/*  461 */	VXT_END,
-/*  462 */	VXI_TSTL,VXT_VAL,1,VXT_END,
-/*  466 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2bool,
-/*  474 */	VXT_END,
-/*  475 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2mint,
-/*  483 */	VXI_MOVL,VXT_REG,0x50,VXT_VAL,0,VXT_END,
-/*  489 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/*  497 */	SIZEOF(char *) * (short int)xf_commarg,VXT_END,
-/*  499 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVL,VXT_VAL,1,
-/*  507 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mint2mval,VXT_END,
-/*  513 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2num,
-/*  521 */	VXT_END,
-/*  522 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/*  530 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_contain,VXT_END,
-/*  536 */	VXI_MOVL,VXT_REG,0x6C,VXT_ADDR,0,VXT_END,
-/*  542 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_currtn,
-/*  550 */	VXT_END,
-/*  551 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/*  559 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_cvtparm,VXT_END,
-/*  566 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/*  574 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_div,VXT_END,
-/*  581 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
-/*  589 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_equ,VXT_END,
-/*  595 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_equnul,
-/*  603 */	VXT_END,
-/*  604 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  612 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_LIT,0,VXI_JSB,
-/*  620 */	VXT_XFER,SIZEOF(char *) * (short int)xf_exfun,VXT_END,
-/*  623 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  631 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_JSB,
-/*  639 */	VXT_XFER,SIZEOF(char *) * (short int)xf_exfun,VXT_END,
-/*  642 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_exfunret,
-/*  650 */	VXT_END,
-/*  651 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_exfunretals,
-/*  659 */	VXT_END,
-/*  660 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_GREF,1,VXI_JSB,VXT_XFER,
-/*  668 */	SIZEOF(char *) * (short int)xf_extcall,VXT_END,
-/*  670 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  678 */	3,VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,
-/*  686 */	VXT_GREF,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_extexfun,VXT_END,
-/*  692 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  700 */	3,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,
-/*  708 */	VXT_GREF,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_extexfun,VXT_END,
-/*  714 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_GREF,1,VXI_JSB,VXT_XFER,
-/*  722 */	SIZEOF(char *) * (short int)xf_extjmp,VXT_END,
-/*  724 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/*  732 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_exp,VXT_END,
-/*  739 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fetch,
-/*  747 */	VXT_END,
-/*  748 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  756 */	3,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHL,VXT_LIT,0,VXI_CALLS,
-/*  764 */	VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfgncal,VXT_END,
-/*  769 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/*  777 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fgnlookup,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/*  785 */	VXT_END,
-/*  786 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
-/*  794 */	2,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnascii,VXT_END,
-/*  801 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
-/*  809 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnchar,VXT_END,
-/*  813 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/*  821 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fndata,VXT_END,
-/*  825 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
-/*  833 */	2,VXI_PUSHL,VXT_VAL,3,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/*  841 */	SIZEOF(char *) * (short int)xf_fnextract,VXT_END,
-/*  843 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  851 */	3,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,
-/*  859 */	VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfgncal,VXT_END,
-/*  864 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/*  872 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/*  880 */	SIZEOF(char *) * (short int)xf_fnfind,VXT_END,
-/*  882 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/*  890 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/*  898 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfnumber,VXT_END,
-/*  903 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
-/*  911 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget,VXT_END,
-/*  917 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/*  925 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget2,VXT_END,
-/*  932 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fngvget,
-/*  940 */	VXT_END,
-/*  941 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fngvget1,
-/*  949 */	VXT_END,
-/*  950 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/*  958 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget1,VXT_END,
-/*  962 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/*  970 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnincr,VXT_END,
-/*  977 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/*  985 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnj2,VXT_END,
-/*  992 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 1000 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1008 */	SIZEOF(char *) * (short int)xf_fnj3,VXT_END,
-/* 1010 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1018 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlength,VXT_END,
-/* 1022 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1030 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvname,VXT_END,
-/* 1037 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,
-/* 1045 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvnameo2,VXT_END,
-/* 1052 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1060 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvprvname,VXT_END,
-/* 1064 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
-/* 1072 */	3,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,2,VXT_XFER,
-/* 1080 */	SIZEOF(char *) * (short int)xf_fnname,VXT_END,
-/* 1082 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1090 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnnext,VXT_END,
-/* 1097 */	VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,
-/* 1105 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1113 */	SIZEOF(char *) * (short int)xf_fno2,VXT_END,
-/* 1115 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1123 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnorder,VXT_END,
-/* 1130 */	VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,
-/* 1138 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 1146 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnp1,VXT_END,
-/* 1151 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,
-/* 1159 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 1167 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpiece,VXT_END,
-/* 1175 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1183 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnqlength,VXT_END,
-/* 1187 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1195 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnqsubscript,VXT_END,
-/* 1202 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1210 */	0,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnquery,VXT_END,
-/* 1217 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1225 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnrandom,VXT_END,
-/* 1229 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1237 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnreverse,VXT_END,
-/* 1241 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1249 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnstack1,VXT_END,
-/* 1253 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 1261 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnstack2,VXT_END,
-/* 1268 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 1276 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1284 */	SIZEOF(char *) * (short int)xf_fntext,VXT_END,
-/* 1286 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 1294 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1302 */	SIZEOF(char *) * (short int)xf_fntranslate,VXT_END,
-/* 1304 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
-/* 1312 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnview,VXT_END,
-/* 1316 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
-/* 1324 */	2,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzascii,VXT_END,
-/* 1331 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1339 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzahandle,VXT_END,
-/* 1343 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 1351 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitand,VXT_END,
-/* 1358 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 1366 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitcoun,VXT_END,
-/* 1370 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1378 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1386 */	SIZEOF(char *) * (short int)xf_fnzbitfind,VXT_END,
-/* 1388 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 1396 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitget,VXT_END,
-/* 1403 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 1411 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitlen,VXT_END,
-/* 1415 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 1423 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitnot,VXT_END,
-/* 1427 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 1435 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitor,VXT_END,
-/* 1442 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1450 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1458 */	SIZEOF(char *) * (short int)xf_fnzbitset,VXT_END,
-/* 1460 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 1468 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitstr,VXT_END,
-/* 1475 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 1483 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitxor,VXT_END,
-/* 1490 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
-/* 1498 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzcall,VXT_END,
-/* 1502 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
-/* 1510 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzchar,VXT_END,
-/* 1514 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1522 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzdata,VXT_END,
-/* 1526 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
-/* 1534 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 1542 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzdate,VXT_END,
-/* 1547 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
-/* 1555 */	2,VXI_PUSHL,VXT_VAL,3,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1563 */	SIZEOF(char *) * (short int)xf_fnzextract,VXT_END,
-/* 1565 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1573 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzfile,VXT_END,
-/* 1580 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 1588 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1596 */	SIZEOF(char *) * (short int)xf_fnzfind,VXT_END,
-/* 1598 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1606 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetdvi,VXT_END,
-/* 1613 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 1621 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetjpi,VXT_END,
-/* 1628 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1636 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetlki,VXT_END,
-/* 1643 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1651 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetsyi,VXT_END,
-/* 1658 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1666 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzj2,VXT_END,
-/* 1673 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1681 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzjobexam,VXT_END,
-/* 1685 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1693 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzlength,VXT_END,
-/* 1697 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1705 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzlkid,VXT_END,
-/* 1709 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1717 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzm,VXT_END,
-/* 1721 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 1729 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1737 */	SIZEOF(char *) * (short int)xf_fnzp1,VXT_END,
-/* 1739 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
-/* 1747 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 1755 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzparse,VXT_END,
-/* 1763 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1771 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpid,VXT_END,
-/* 1775 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 1783 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 1791 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpiece,VXT_END,
-/* 1796 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1804 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpopulation,VXT_END,
-/* 1811 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1819 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzprevious,VXT_END,
-/* 1826 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1834 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpriv,VXT_END,
-/* 1838 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzqgblmod,
-/* 1846 */	VXT_END,
-/* 1847 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 1855 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsearch,VXT_END,
-/* 1862 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1870 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsetprv,VXT_END,
-/* 1874 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 1882 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1890 */	SIZEOF(char *) * (short int)xf_fnzsubstr,VXT_END,
-/* 1892 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 1900 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
-/* 1908 */	SIZEOF(char *) * (short int)xf_fnztranslate,VXT_END,
-/* 1910 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 1918 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsigproc,VXT_END,
-/* 1925 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,6,VXI_PUSHAB,VXT_VAL,
-/* 1933 */	5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,
-/* 1941 */	VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,7,
-/* 1949 */	VXT_XFER,SIZEOF(char *) * (short int)xf_fnztrnlnm,VXT_END,
-/* 1952 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 1960 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwidth,VXT_END,
-/* 1964 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 1972 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_follow,VXT_END,
-/* 1978 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
-/* 1986 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forcenum,VXT_END,
-/* 1992 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forchk1,VXT_END,
-/* 1999 */	VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2007 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forinit,VXT_END,
-/* 2012 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldob,VXI_BRB,VXT_JMP,
-/* 2020 */	1,VXT_END,
-/* 2022 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldol,VXI_JMP,VXT_JMP,
-/* 2030 */	1,VXT_END,
-/* 2032 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldow,VXI_BRW,VXT_JMP,
-/* 2040 */	1,VXT_END,
-/* 2042 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
-/* 2050 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
-/* 2058 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
-/* 2061 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
-/* 2069 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
-/* 2077 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
-/* 2080 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
-/* 2088 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
-/* 2096 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
-/* 2099 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_getindx,
-/* 2107 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 2113 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_gettruth,
-/* 2121 */	VXT_END,
-/* 2122 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvdata,
-/* 2130 */	VXT_END,
-/* 2131 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,
-/* 2139 */	VXT_END,
-/* 2140 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
-/* 2148 */	VXT_END,
-/* 2149 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 2157 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
-/* 2161 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
-/* 2167 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,
-/* 2175 */	VXT_END,
-/* 2176 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,
-/* 2184 */	VXT_END,
-/* 2185 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
-/* 2193 */	VXT_END,
-/* 2194 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 2202 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
-/* 2206 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
-/* 2214 */	VXT_END,
-/* 2215 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
-/* 2223 */	VXT_END,
-/* 2224 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
-/* 2232 */	VXT_END,
-/* 2233 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
-/* 2241 */	VXT_END,
-/* 2242 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
-/* 2250 */	VXT_END,
-/* 2251 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
-/* 2257 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 2265 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
-/* 2273 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
-/* 2275 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
-/* 2281 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 2289 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
-/* 2293 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
-/* 2297 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2305 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
-/* 2312 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
-/* 2320 */	VXT_END,
-/* 2321 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2329 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
-/* 2334 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2342 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
-/* 2347 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2355 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
-/* 2360 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2368 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
-/* 2370 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2378 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
-/* 2383 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
-/* 2391 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2395 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2403 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
-/* 2405 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2413 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
-/* 2420 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
-/* 2428 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2432 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2440 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
-/* 2447 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2455 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
-/* 2457 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2465 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
-/* 2467 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2475 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
-/* 2477 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2485 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
-/* 2493 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2501 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
-/* 2505 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
-/* 2513 */	VXT_END,
-/* 2514 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2522 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
-/* 2524 */	VXI_BRB,VXT_JMP,1,VXT_END,
-/* 2528 */	VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2532 */	VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2536 */	VXI_JMP,VXT_VAL,1,VXT_END,
-/* 2540 */	VXI_BEQL,VXT_JMP,1,VXT_END,
-/* 2544 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2551 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2558 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
-/* 2562 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2569 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2576 */	VXI_BGTR,VXT_JMP,1,VXT_END,
-/* 2580 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2587 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2594 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
-/* 2598 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2605 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2612 */	VXI_BLSS,VXT_JMP,1,VXT_END,
-/* 2616 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2623 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2630 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
-/* 2634 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2641 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2648 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2654 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2662 */	VXT_END,
-/* 2663 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
-/* 2671 */	VXT_END,
-/* 2672 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2678 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2686 */	VXT_END,
-/* 2687 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
-/* 2695 */	VXT_END,
-/* 2696 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
-/* 2704 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
-/* 2712 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
-/* 2720 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
-/* 2723 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
-/* 2731 */	VXT_END,
-/* 2732 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
-/* 2740 */	VXT_END,
-/* 2741 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
-/* 2747 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
-/* 2753 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2761 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
-/* 2769 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2773 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
-/* 2781 */	VXT_END,
-/* 2782 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
-/* 2790 */	VXT_END,
-/* 2791 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2797 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/*    0 */	0,0,0,0,325,3477,2931,569,
+/*    8 */	2309,2916,2946,1981,421,3427,2102,3049,
+/*   16 */	2185,2173,3660,3697,2146,2155,2227,2167,
+/*   24 */	2218,2197,2125,789,804,816,828,867,
+/*   32 */	885,906,935,965,980,995,1013,3034,
+/*   40 */	1085,1118,1154,1220,1271,1568,1601,1616,
+/*   48 */	1646,1712,1742,1766,1829,1850,1865,3492,
+/*   56 */	3514,0,0,0,0,584,0,525,
+/*   64 */	0,1967,0,3020,0,0,0,0,
+/*   72 */	0,0,357,433,2287,2293,2708,2735,
+/*   80 */	2753,2856,2794,2785,2871,3566,3650,2967,
+/*   88 */	0,2999,3115,3078,3063,3093,3441,3291,
+/*   96 */	3572,3584,3599,3623,3632,3617,3608,3326,
+/*  104 */	3693,3706,3728,3765,3777,3798,3822,3888,
+/*  112 */	0,0,2904,2269,3167,4169,663,4172,
+/*  120 */	717,2765,3133,539,545,4175,2372,2459,
+/*  128 */	2359,492,2395,2479,2134,2417,2489,4178,
+/*  136 */	2254,2245,4182,1289,4183,353,349,3315,
+/*  144 */	445,4187,4190,4193,2985,4196,4199,4202,
+/*  152 */	4205,4208,4211,3463,0,2880,2548,2526,
+/*  160 */	1529,2517,2305,2116,2831,2002,742,2821,
+/*  168 */	0,0,2324,3641,3669,1493,3593,2407,
+/*  176 */	1995,554,3789,1814,2236,1205,340,3119,
+/*  184 */	626,695,607,673,3753,1133,3721,2960,
+/*  192 */	2263,2895,2974,645,1025,2835,4214,2469,
+/*  200 */	3840,3858,3873,516,2850,3111,1928,3909,
+/*  208 */	3900,1307,3455,598,1631,1700,2432,4217,
+/*  216 */	3526,2505,751,846,3150,3681,3550,3536,
+/*  224 */	3543,3532,727,920,2382,1067,2346,1055,
+/*  232 */	2206,1040,1100,2444,1463,1406,1391,1445,
+/*  240 */	1361,1373,1418,1346,1430,1478,772,3413,
+/*  248 */	0,944,953,3270,1841,3249,2333,3945,
+/*  256 */	3915,3921,3933,3955,1244,1256,1178,1190,
+/*  264 */	1232,3504,1676,1913,0,1319,1505,1550,
+/*  272 */	3347,1583,1661,1688,1799,1778,3389,1724,
+/*  280 */	3368,1895,0,0,1955,3978,1877,3177,
+/*  288 */	3189,3201,3213,2744,2759,1517,456,1334,
+/*  296 */	0,654,3225,3237,0,3969,0,0,
+/*  304 */	0,0,3744,3990,4001,4013,4022,4036,
+/*  312 */	4049,4059,4076,4088,4097,4109,4121,4133,
+/*  320 */	4148,4160,0,0,0,VXI_PUSHAB,VXT_VAL,0,
+/*  328 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/*  336 */	3,VXT_XFER,SIZEOF(char *) * (short int)xf_add,VXT_END,
+/*  340 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_bindparm,
+/*  348 */	VXT_END,
+/*  349 */	VXI_INCL,VXT_VAL,1,VXT_END,
+/*  353 */	VXI_CLRL,VXT_VAL,0,VXT_END,
+/*  357 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_break,VXT_END,
+/*  361 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callb,VXI_BRB,VXT_JMP,
+/*  369 */	1,VXT_END,
+/*  371 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_calll,VXI_JMP,VXT_JMP,
+/*  379 */	1,VXT_END,
+/*  381 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callw,VXI_BRW,VXT_JMP,
+/*  389 */	1,VXT_END,
+/*  391 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspb,VXI_BRB,VXT_JMP,
+/*  399 */	1,VXT_END,
+/*  401 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspl,VXI_JMP,VXT_JMP,
+/*  409 */	1,VXT_END,
+/*  411 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_callspw,VXI_BRW,VXT_JMP,
+/*  419 */	1,VXT_END,
+/*  421 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
+/*  429 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_cat,VXT_END,
+/*  433 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/*  441 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_close,VXT_END,
+/*  445 */	VXI_BICB2,VXT_LIT,1,VXT_REG,0x5A,VXI_CALLS,VXT_LIT,0,
+/*  453 */	VXT_XFER,SIZEOF(char *) * (short int)xf_dt_false,VXT_END,
+/*  456 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_clralsvars,
+/*  464 */	VXT_END,
+/*  465 */	VXI_TSTL,VXT_VAL,1,VXT_END,
+/*  469 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2bool,
+/*  477 */	VXT_END,
+/*  478 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2mint,
+/*  486 */	VXI_MOVL,VXT_REG,0x50,VXT_VAL,0,VXT_END,
+/*  492 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/*  500 */	SIZEOF(char *) * (short int)xf_commarg,VXT_END,
+/*  502 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVL,VXT_VAL,1,
+/*  510 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mint2mval,VXT_END,
+/*  516 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_mval2num,
+/*  524 */	VXT_END,
+/*  525 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/*  533 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_contain,VXT_END,
+/*  539 */	VXI_MOVL,VXT_REG,0x6C,VXT_ADDR,0,VXT_END,
+/*  545 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_currtn,
+/*  553 */	VXT_END,
+/*  554 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/*  562 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_cvtparm,VXT_END,
+/*  569 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/*  577 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_div,VXT_END,
+/*  584 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
+/*  592 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_equ,VXT_END,
+/*  598 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_equnul,
+/*  606 */	VXT_END,
+/*  607 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  615 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_LIT,0,VXI_JSB,
+/*  623 */	VXT_XFER,SIZEOF(char *) * (short int)xf_exfun,VXT_END,
+/*  626 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  634 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_JSB,
+/*  642 */	VXT_XFER,SIZEOF(char *) * (short int)xf_exfun,VXT_END,
+/*  645 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_exfunret,
+/*  653 */	VXT_END,
+/*  654 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_exfunretals,
+/*  662 */	VXT_END,
+/*  663 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_GREF,1,VXI_JSB,VXT_XFER,
+/*  671 */	SIZEOF(char *) * (short int)xf_extcall,VXT_END,
+/*  673 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  681 */	3,VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,
+/*  689 */	VXT_GREF,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_extexfun,VXT_END,
+/*  695 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  703 */	3,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,
+/*  711 */	VXT_GREF,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_extexfun,VXT_END,
+/*  717 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_GREF,1,VXI_JSB,VXT_XFER,
+/*  725 */	SIZEOF(char *) * (short int)xf_extjmp,VXT_END,
+/*  727 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/*  735 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_exp,VXT_END,
+/*  742 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fetch,
+/*  750 */	VXT_END,
+/*  751 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  759 */	3,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHL,VXT_LIT,0,VXI_CALLS,
+/*  767 */	VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfgncal,VXT_END,
+/*  772 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/*  780 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fgnlookup,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/*  788 */	VXT_END,
+/*  789 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
+/*  797 */	2,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnascii,VXT_END,
+/*  804 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
+/*  812 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnchar,VXT_END,
+/*  816 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/*  824 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fndata,VXT_END,
+/*  828 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
+/*  836 */	2,VXI_PUSHL,VXT_VAL,3,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/*  844 */	SIZEOF(char *) * (short int)xf_fnextract,VXT_END,
+/*  846 */	VXT_IREPAB,VXT_VAL,5,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  854 */	3,VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,
+/*  862 */	VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfgncal,VXT_END,
+/*  867 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/*  875 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/*  883 */	SIZEOF(char *) * (short int)xf_fnfind,VXT_END,
+/*  885 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/*  893 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/*  901 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnfnumber,VXT_END,
+/*  906 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
+/*  914 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget,VXT_END,
+/*  920 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/*  928 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget2,VXT_END,
+/*  935 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fngvget,
+/*  943 */	VXT_END,
+/*  944 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fngvget1,
+/*  952 */	VXT_END,
+/*  953 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/*  961 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnget1,VXT_END,
+/*  965 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/*  973 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnincr,VXT_END,
+/*  980 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/*  988 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnj2,VXT_END,
+/*  995 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 1003 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1011 */	SIZEOF(char *) * (short int)xf_fnj3,VXT_END,
+/* 1013 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1021 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlength,VXT_END,
+/* 1025 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1033 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvname,VXT_END,
+/* 1040 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,
+/* 1048 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvnameo2,VXT_END,
+/* 1055 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1063 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnlvprvname,VXT_END,
+/* 1067 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
+/* 1075 */	3,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,2,VXT_XFER,
+/* 1083 */	SIZEOF(char *) * (short int)xf_fnname,VXT_END,
+/* 1085 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1093 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnnext,VXT_END,
+/* 1100 */	VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,
+/* 1108 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1116 */	SIZEOF(char *) * (short int)xf_fno2,VXT_END,
+/* 1118 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1126 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnorder,VXT_END,
+/* 1133 */	VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,
+/* 1141 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 1149 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnp1,VXT_END,
+/* 1154 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,
+/* 1162 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 1170 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpiece,VXT_END,
+/* 1178 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1186 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnqlength,VXT_END,
+/* 1190 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1198 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnqsubscript,VXT_END,
+/* 1205 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1213 */	0,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnquery,VXT_END,
+/* 1220 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1228 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnrandom,VXT_END,
+/* 1232 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1240 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnreverse,VXT_END,
+/* 1244 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1252 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnstack1,VXT_END,
+/* 1256 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 1264 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnstack2,VXT_END,
+/* 1271 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 1279 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1287 */	SIZEOF(char *) * (short int)xf_fntext,VXT_END,
+/* 1289 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 1297 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1305 */	SIZEOF(char *) * (short int)xf_fntranslate,VXT_END,
+/* 1307 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
+/* 1315 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnview,VXT_END,
+/* 1319 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
+/* 1327 */	2,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzascii,VXT_END,
+/* 1334 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1342 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzahandle,VXT_END,
+/* 1346 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 1354 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitand,VXT_END,
+/* 1361 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 1369 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitcoun,VXT_END,
+/* 1373 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1381 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1389 */	SIZEOF(char *) * (short int)xf_fnzbitfind,VXT_END,
+/* 1391 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 1399 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitget,VXT_END,
+/* 1406 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 1414 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitlen,VXT_END,
+/* 1418 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 1426 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitnot,VXT_END,
+/* 1430 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 1438 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitor,VXT_END,
+/* 1445 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1453 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1461 */	SIZEOF(char *) * (short int)xf_fnzbitset,VXT_END,
+/* 1463 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 1471 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitstr,VXT_END,
+/* 1478 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 1486 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzbitxor,VXT_END,
+/* 1493 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
+/* 1501 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzcall,VXT_END,
+/* 1505 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_VAL,
+/* 1513 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzchar,VXT_END,
+/* 1517 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1525 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzdata,VXT_END,
+/* 1529 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
+/* 1537 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 1545 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzdate,VXT_END,
+/* 1550 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHL,VXT_VAL,
+/* 1558 */	2,VXI_PUSHL,VXT_VAL,3,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1566 */	SIZEOF(char *) * (short int)xf_fnzextract,VXT_END,
+/* 1568 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1576 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzfile,VXT_END,
+/* 1583 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 1591 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1599 */	SIZEOF(char *) * (short int)xf_fnzfind,VXT_END,
+/* 1601 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1609 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetdvi,VXT_END,
+/* 1616 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 1624 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetjpi,VXT_END,
+/* 1631 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1639 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetlki,VXT_END,
+/* 1646 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1654 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fngetsyi,VXT_END,
+/* 1661 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1669 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzj2,VXT_END,
+/* 1676 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1684 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzjobexam,VXT_END,
+/* 1688 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1696 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzlength,VXT_END,
+/* 1700 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1708 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzlkid,VXT_END,
+/* 1712 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1720 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzm,VXT_END,
+/* 1724 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 1732 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1740 */	SIZEOF(char *) * (short int)xf_fnzp1,VXT_END,
+/* 1742 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
+/* 1750 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 1758 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzparse,VXT_END,
+/* 1766 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1774 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpid,VXT_END,
+/* 1778 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 1786 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 1794 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpiece,VXT_END,
+/* 1799 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1807 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpopulation,VXT_END,
+/* 1814 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1822 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzprevious,VXT_END,
+/* 1829 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1837 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpriv,VXT_END,
+/* 1841 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzqgblmod,
+/* 1849 */	VXT_END,
+/* 1850 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 1858 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsearch,VXT_END,
+/* 1865 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1873 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsetprv,VXT_END,
+/* 1877 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 1885 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1893 */	SIZEOF(char *) * (short int)xf_fnzsubstr,VXT_END,
+/* 1895 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 1903 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,4,VXT_XFER,
+/* 1911 */	SIZEOF(char *) * (short int)xf_fnztranslate,VXT_END,
+/* 1913 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 1921 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzsigproc,VXT_END,
+/* 1928 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,6,VXI_PUSHAB,VXT_VAL,
+/* 1936 */	5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,
+/* 1944 */	VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,7,
+/* 1952 */	VXT_XFER,SIZEOF(char *) * (short int)xf_fnztrnlnm,VXT_END,
+/* 1955 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 1963 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwidth,VXT_END,
+/* 1967 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 1975 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_follow,VXT_END,
+/* 1981 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
+/* 1989 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forcenum,VXT_END,
+/* 1995 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forchk1,VXT_END,
+/* 2002 */	VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2010 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forinit,VXT_END,
+/* 2015 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldob,VXI_BRB,VXT_JMP,
+/* 2023 */	1,VXT_END,
+/* 2025 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldol,VXI_JMP,VXT_JMP,
+/* 2033 */	1,VXT_END,
+/* 2035 */	VXI_PUSHL,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_forlcldow,VXI_BRW,VXT_JMP,
+/* 2043 */	1,VXT_END,
+/* 2045 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
+/* 2053 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
+/* 2061 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
+/* 2064 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
+/* 2072 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
+/* 2080 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
+/* 2083 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_JMP,1,VXI_PUSHAB,VXT_VAL,
+/* 2091 */	4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,
+/* 2099 */	VXT_XFER,SIZEOF(char *) * (short int)xf_forloop,VXT_END,
+/* 2102 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_getindx,
+/* 2110 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 2116 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_gettruth,
+/* 2124 */	VXT_END,
+/* 2125 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvdata,
+/* 2133 */	VXT_END,
+/* 2134 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2142 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,VXT_END,
+/* 2146 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
+/* 2154 */	VXT_END,
+/* 2155 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 2163 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
+/* 2167 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
+/* 2173 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2181 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,VXT_END,
+/* 2185 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2193 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,VXT_END,
+/* 2197 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
+/* 2205 */	VXT_END,
+/* 2206 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 2214 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
+/* 2218 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
+/* 2226 */	VXT_END,
+/* 2227 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
+/* 2235 */	VXT_END,
+/* 2236 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
+/* 2244 */	VXT_END,
+/* 2245 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
+/* 2253 */	VXT_END,
+/* 2254 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
+/* 2262 */	VXT_END,
+/* 2263 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
+/* 2269 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 2277 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
+/* 2285 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
+/* 2287 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
+/* 2293 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 2301 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
+/* 2305 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
+/* 2309 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2317 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
+/* 2324 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
+/* 2332 */	VXT_END,
+/* 2333 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2341 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
+/* 2346 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2354 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
+/* 2359 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2367 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
+/* 2372 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2380 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
+/* 2382 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2390 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
+/* 2395 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
+/* 2403 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2407 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2415 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
+/* 2417 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2425 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
+/* 2432 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
+/* 2440 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2444 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2452 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
+/* 2459 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2467 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
+/* 2469 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2477 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
+/* 2479 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2487 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
+/* 2489 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2497 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
+/* 2505 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2513 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
+/* 2517 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
+/* 2525 */	VXT_END,
+/* 2526 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2534 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
+/* 2536 */	VXI_BRB,VXT_JMP,1,VXT_END,
+/* 2540 */	VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2544 */	VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2548 */	VXI_JMP,VXT_VAL,1,VXT_END,
+/* 2552 */	VXI_BEQL,VXT_JMP,1,VXT_END,
+/* 2556 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2563 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2570 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
+/* 2574 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2581 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2588 */	VXI_BGTR,VXT_JMP,1,VXT_END,
+/* 2592 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2599 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2606 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
+/* 2610 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2617 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2624 */	VXI_BLSS,VXT_JMP,1,VXT_END,
+/* 2628 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2635 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2642 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
+/* 2646 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2653 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2660 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2666 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
+/* 2674 */	VXT_END,
+/* 2675 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2683 */	VXT_END,
+/* 2684 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2690 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
+/* 2698 */	VXT_END,
+/* 2699 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2707 */	VXT_END,
+/* 2708 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
+/* 2716 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
+/* 2724 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
+/* 2732 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
+/* 2735 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
+/* 2743 */	VXT_END,
+/* 2744 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
+/* 2752 */	VXT_END,
+/* 2753 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
+/* 2759 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
+/* 2765 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2773 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
+/* 2781 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2785 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
+/* 2793 */	VXT_END,
+/* 2794 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
+/* 2802 */	VXT_END,
 /* 2803 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2809 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2817 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
-/* 2819 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
-/* 2823 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 2831 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2838 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
-/* 2844 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2852 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2859 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
-/* 2867 */	VXT_END,
-/* 2868 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2876 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
-/* 2883 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
-/* 2891 */	VXT_END,
-/* 2892 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2900 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
-/* 2904 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2912 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
-/* 2919 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2927 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
-/* 2934 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
-/* 2942 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
-/* 2948 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
-/* 2955 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
-/* 2962 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,
-/* 2970 */	VXT_END,
-/* 2971 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 2979 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
-/* 2985 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 2993 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3001 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
-/* 3006 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3014 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
-/* 3020 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3028 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpopulation,VXT_END,
-/* 3035 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
-/* 3043 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3049 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 3057 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
-/* 3064 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 3072 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
-/* 3079 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 3087 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3095 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
-/* 3097 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
-/* 3101 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
-/* 3105 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
-/* 3113 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
-/* 3119 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3127 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3135 */	VXT_END,
-/* 3136 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3144 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3152 */	VXT_END,
-/* 3153 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3161 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
-/* 3163 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3171 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
-/* 3175 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3183 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
-/* 3187 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3195 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
-/* 3199 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3207 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
-/* 3211 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3219 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
-/* 3223 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3231 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
-/* 3235 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3243 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3251 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
-/* 3256 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3264 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3272 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
-/* 3277 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3285 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3293 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
-/* 3301 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_CALLS,VXT_LIT,0,
-/* 3309 */	VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,VXT_END,
-/* 3312 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3320 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
-/* 3328 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
-/* 3333 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3341 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3349 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
-/* 3354 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3362 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3370 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
-/* 3375 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3383 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3391 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
-/* 3399 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3407 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
-/* 3413 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
-/* 3421 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3427 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
-/* 3435 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3441 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
-/* 3449 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
-/* 3457 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3463 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3471 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
-/* 3478 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3486 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
-/* 3490 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3498 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
-/* 3500 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3508 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
-/* 3512 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
-/* 3518 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
-/* 3522 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
-/* 3529 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
-/* 3536 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3544 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
-/* 3552 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
-/* 3558 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3566 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
-/* 3570 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
-/* 3578 */	VXT_END,
-/* 3579 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
-/* 3585 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
-/* 3593 */	VXT_END,
-/* 3594 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
-/* 3602 */	VXT_END,
-/* 3603 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
-/* 3609 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
-/* 3617 */	VXT_END,
-/* 3618 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
-/* 3626 */	VXT_END,
-/* 3627 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
-/* 3635 */	VXT_END,
-/* 3636 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3644 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
-/* 3646 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
-/* 3654 */	VXT_END,
-/* 3655 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3663 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
-/* 3667 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3675 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
-/* 3679 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3683 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
-/* 3691 */	VXT_END,
-/* 3692 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3700 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
-/* 3707 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
-/* 3714 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
-/* 3722 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
-/* 3730 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
-/* 3738 */	VXT_END,
-/* 3739 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3747 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
-/* 3751 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3759 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
-/* 3763 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 3771 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
-/* 3775 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
-/* 3783 */	VXT_END,
-/* 3784 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
-/* 3792 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3800 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
-/* 3808 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
-/* 3816 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3824 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3826 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3834 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3842 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3844 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3852 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3859 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3867 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3874 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3882 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
-/* 3886 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
-/* 3894 */	VXT_END,
-/* 3895 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
-/* 3901 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
-/* 3907 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3915 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 3919 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3927 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 3931 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
-/* 3939 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
-/* 3941 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
-/* 3949 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3955 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
-/* 3963 */	VXT_END,
-/* 3964 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3972 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
-/* 3976 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
-/* 3984 */	VXT_ADDR,0,VXT_END,
-/* 3987 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3995 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
-/* 3999 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
-/* 4007 */	VXT_END,
-/* 4008 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
-/* 4016 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 4022 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 4030 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
-/* 4035 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 4043 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
-/* 4045 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4053 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 4061 */	VXT_END,
-/* 4062 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,
-/* 4070 */	VXT_END,
-/* 4071 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
-/* 4079 */	VXT_END,
-/* 4080 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4088 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
-/* 4092 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4100 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
-/* 4104 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4112 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
-/* 4116 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 4124 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
-/* 4131 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 4139 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
-/* 4143 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
-/* 4151 */	VXT_END,
-/* 4152 */	358,378,368,2524,2532,2528,2791,2803,
-/* 4160 */	2797,0,0,0,499,475,466,0,
-/* 4168 */	0,462,2042,2080,2061,2672,2687,2678,
-/* 4176 */	2648,2663,2654,2540,2551,2544,2630,2641,
-/* 4184 */	2634,2576,2587,2580,2594,2605,2598,2612,
-/* 4192 */	2623,2616,2558,2569,2562,2012,2032,2022,
-/* 4200 */	388,408,398};
+/* 2809 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2815 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2821 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2829 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
+/* 2831 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
+/* 2835 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 2843 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2850 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
+/* 2856 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2864 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2871 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
+/* 2879 */	VXT_END,
+/* 2880 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2888 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
+/* 2895 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
+/* 2903 */	VXT_END,
+/* 2904 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2912 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
+/* 2916 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2924 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
+/* 2931 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2939 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
+/* 2946 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
+/* 2954 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
+/* 2960 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
+/* 2967 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
+/* 2974 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,VXI_MOVL,VXT_REG,0x50,
+/* 2982 */	VXT_ADDR,0,VXT_END,
+/* 2985 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 2993 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
+/* 2999 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3007 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3015 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
+/* 3020 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3028 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
+/* 3034 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3042 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_fnpopulation,VXT_END,
+/* 3049 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
+/* 3057 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3063 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3071 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
+/* 3078 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3086 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
+/* 3093 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 3101 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3109 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
+/* 3111 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
+/* 3115 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
+/* 3119 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
+/* 3127 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
+/* 3133 */	VXI_PUSHAB,VXT_GREF,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3141 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3149 */	VXT_END,
+/* 3150 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3158 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3166 */	VXT_END,
+/* 3167 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3175 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
+/* 3177 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3185 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
+/* 3189 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3197 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
+/* 3201 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3209 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
+/* 3213 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3221 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
+/* 3225 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3233 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
+/* 3237 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3245 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
+/* 3249 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3257 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3265 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
+/* 3270 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3278 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3286 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
+/* 3291 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3299 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3307 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
+/* 3315 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_CALLS,VXT_LIT,0,
+/* 3323 */	VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,VXT_END,
+/* 3326 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3334 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
+/* 3342 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
+/* 3347 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3355 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3363 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
+/* 3368 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3376 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3384 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
+/* 3389 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3397 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3405 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
+/* 3413 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3421 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
+/* 3427 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
+/* 3435 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3441 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
+/* 3449 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3455 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
+/* 3463 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
+/* 3471 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3477 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3485 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
+/* 3492 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3500 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
+/* 3504 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3512 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
+/* 3514 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3522 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
+/* 3526 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
+/* 3532 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
+/* 3536 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
+/* 3543 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
+/* 3550 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3558 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
+/* 3566 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
+/* 3572 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3580 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
+/* 3584 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
+/* 3592 */	VXT_END,
+/* 3593 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
+/* 3599 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
+/* 3607 */	VXT_END,
+/* 3608 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
+/* 3616 */	VXT_END,
+/* 3617 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
+/* 3623 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
+/* 3631 */	VXT_END,
+/* 3632 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
+/* 3640 */	VXT_END,
+/* 3641 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
+/* 3649 */	VXT_END,
+/* 3650 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3658 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
+/* 3660 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
+/* 3668 */	VXT_END,
+/* 3669 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3677 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
+/* 3681 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3689 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
+/* 3693 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3697 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
+/* 3705 */	VXT_END,
+/* 3706 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3714 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
+/* 3721 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
+/* 3728 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
+/* 3736 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
+/* 3744 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
+/* 3752 */	VXT_END,
+/* 3753 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3761 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
+/* 3765 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3773 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
+/* 3777 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 3785 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
+/* 3789 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
+/* 3797 */	VXT_END,
+/* 3798 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
+/* 3806 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3814 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
+/* 3822 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
+/* 3830 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3838 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3840 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3848 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3856 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3858 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3866 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3873 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3881 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3888 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3896 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
+/* 3900 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
+/* 3908 */	VXT_END,
+/* 3909 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
+/* 3915 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
+/* 3921 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3929 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3933 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3941 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3945 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
+/* 3953 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
+/* 3955 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
+/* 3963 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3969 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
+/* 3977 */	VXT_END,
+/* 3978 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3986 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
+/* 3990 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
+/* 3998 */	VXT_ADDR,0,VXT_END,
+/* 4001 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4009 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
+/* 4013 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
+/* 4021 */	VXT_END,
+/* 4022 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
+/* 4030 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 4036 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 4044 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
+/* 4049 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 4057 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
+/* 4059 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4067 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 4075 */	VXT_END,
+/* 4076 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 4084 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,VXT_END,
+/* 4088 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
+/* 4096 */	VXT_END,
+/* 4097 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4105 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
+/* 4109 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4117 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
+/* 4121 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4129 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
+/* 4133 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 4141 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
+/* 4148 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 4156 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
+/* 4160 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
+/* 4168 */	VXT_END,
+/* 4169 */	361,381,371,2536,2544,2540,2803,2815,
+/* 4177 */	2809,0,0,0,502,478,469,0,
+/* 4185 */	0,465,2045,2083,2064,2684,2699,2690,
+/* 4193 */	2660,2675,2666,2552,2563,2556,2642,2653,
+/* 4201 */	2646,2588,2599,2592,2606,2617,2610,2624,
+/* 4209 */	2635,2628,2570,2581,2574,2015,2035,2025,
+/* 4217 */	391,411,401};
diff --git a/sr_vvms/ttt.txt b/sr_vvms/ttt.txt
index 9ce62fa..c678a2f 100644
--- a/sr_vvms/ttt.txt
+++ b/sr_vvms/ttt.txt
@@ -1,6 +1,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;								;
-;	Copyright 2001, 2012 Fidelity Information Services, Inc	;
+;	Copyright 2001, 2013 Fidelity Information Services, Inc	;
 ;								;
 ;	This source code contains the intellectual property	;
 ;	of its copyright holder(s), and is made available	;
@@ -496,7 +496,8 @@ OC_GETTRUTH:	movab	val.0,r1
 		jsb	xfer.xf_gettruth
 OC_GVDATA:	pushab	val.0
 		calls	#1,xfer.xf_gvdata
-OC_GVEXTNAM:	irepab	val.2
+OC_GVEXTNAM:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvextnam
 OC_GVGET:	pushab	val.0
 		calls	#1,xfer.xf_gvget
@@ -504,9 +505,11 @@ OC_GVINCR:	pushab	val.0		; result of $INCR
 		pushab	val.2		; r->operand[1] = increment (global-variable to increment is gv_currkey so no operand[0])
 		calls	#2,xfer.xf_gvincr
 OC_GVKILL:	calls	#0,xfer.xf_gvkill
-OC_GVNAKED:	irepab	val.2
+OC_GVNAKED:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvnaked
-OC_GVNAME:	irepab	val.2
+OC_GVNAME:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_gvname
 OC_GVNEXT:	pushab	val.0
 		calls	#1,xfer.xf_gvnext
@@ -707,8 +710,8 @@ OC_NEWINTRINSIC:  pushl	val.1
 		jsb	xfer.xf_newintrinsic
 OC_NEWVAR:	pushl	val.1
 		jsb	xfer.xf_newvar
-OC_NULLEXP:	pushab	val.0
-		calls	#1,xfer.xf_nullexp
+OC_NULLEXP:	calls	#0,xfer.xf_nullexp
+		movl    r0,addr.0
 OC_NUMCMP:	movab	val.1,r0
 		movab	val.2,r1
 		jsb	xfer.xf_numcmp
@@ -984,7 +987,8 @@ OC_RFRSHLVN:	pushl	val.2
 		pushab	val.1
 		calls	#2,xfer.xf_rfrshlvn
 		movl	r0,addr.0
-OC_SAVGVN:	irepab	val.2
+OC_SAVGVN:	irepab	val.3
+		pushl	val.2	; hash_code
 		calls	val.1,xfer.xf_savgvn
 OC_SAVLVN:	irepab	val.2
 		calls	val.1,xfer.xf_savlvn
diff --git a/sr_vvms/zro_load.c b/sr_vvms/zro_load.c
index eec0882..9f9cad0 100644
--- a/sr_vvms/zro_load.c
+++ b/sr_vvms/zro_load.c
@@ -1,6 +1,6 @@
 /****************************************************************
  *								*
- *	Copyright 2001, 2011 Fidelity Information Services, Inc	*
+ *	Copyright 2001, 2013 Fidelity Information Services, Inc	*
  *								*
  *	This source code contains the intellectual property	*
  *	of its copyright holder(s), and is made available	*
@@ -38,7 +38,7 @@ error_def		(ERR_NOLBRSRC);
 
 CONDITION_HANDLER(zro_load_ch)
 {
-	START_CH;
+	START_CH(FALSE);
 	if (zro_str)
 		free(zro_str);
 	zro_str = NULL;
@@ -99,23 +99,25 @@ void  zro_load (mstr *str)
 		{
 			file = FALSE;
 			if (toktyp != TK_IDENT)
-				rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FSEXP);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FSEXP);
 			if (oi + 1 >= ZRO_MAX_ENTS)
-				rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr,
+					ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
 			fab.fab$b_fns = tok.len;
 			fab.fab$l_fna = tok.addr;
 			status = sys$parse (&fab);
 			if (!(status & 1))
-				rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr,
-					  status);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
+					ERR_FILEPARSE, 2, tok.len, tok.addr, status);
 			if (nam.nam$l_fnb & (NAM$M_WILDCARD))
-				rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_WILDCARD, 2, tok.len, tok.addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
+					ERR_WILDCARD, 2, tok.len, tok.addr);
 			if (nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE | NAM$M_EXP_VER))
 			{
 				file = TRUE;
 				status = sys$search(&fab);
 				if (!(status & 1))
-					rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr,
 						  ERR_FILEPARSE, 2, tok.len, tok.addr, status);
 			}
 			array[0].count++;
@@ -133,19 +135,21 @@ void  zro_load (mstr *str)
 			{
 				GETTOK;
 				if (toktyp != TK_IDENT)
-					rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_QUALEXP);
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2,
+							str->len, str->addr, ERR_QUALEXP);
 				if (tok.len == 3)
 				{
 					lower_to_upper (qual, tok.addr, 3);
 					if (!memcmp (qual, "SRC", 3))
 					{
 						if (file)
-							rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_NOLBRSRC);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZROSYNTAX, 2,
+									str->len, str->addr, ERR_NOLBRSRC);
 
 						GETTOK;
 						if (si >= ZRO_MAX_ENTS)
-							rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr,
-								  ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_ZROSYNTAX, 2,
+									str->len, str->addr, ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
 						if (toktyp == TK_COMMA || toktyp == TK_EOL)
 						{
 							array[oi + 1].count = 1;
@@ -158,24 +162,25 @@ void  zro_load (mstr *str)
 							if (toktyp != TK_LPAREN)
 							{
 								if (toktyp != TK_IDENT)
-									rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len,
-										  str->addr, ERR_FSEXP);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5)
+											ERR_ZROSYNTAX, 2, str->len,
+										  	str->addr, ERR_FSEXP);
 								fab.fab$b_fns = tok.len;
 								fab.fab$l_fna = tok.addr;
 								status = sys$parse (&fab);
 								if (!(status & 1))
-									rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len,
-										  str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr,
-										  status);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9)
+										ERR_ZROSYNTAX, 2, str->len, str->addr,
+										ERR_FILEPARSE, 2, tok.len, tok.addr, status);
 								if (nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE
 										     | NAM$M_EXP_VER))
-									rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len,
-										  str->addr, ERR_DIRONLY, 2, tok.len,
-										  tok.addr);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8)
+										ERR_ZROSYNTAX, 2, str->len, str->addr,
+										ERR_DIRONLY, 2, tok.len, tok.addr);
 								if (nam.nam$l_fnb & (NAM$M_WILDCARD))
-									rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len,
-										  str->addr, ERR_WILDCARD, 2, tok.len,
-										  tok.addr);
+									rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8)
+										ERR_ZROSYNTAX, 2, str->len, str->addr,
+										ERR_WILDCARD, 2, tok.len, tok.addr);
 								array[oi + 1].count = 1;
 								array[si].type = ZRO_TYPE_SOURCE;
 								array[si].node_present = (nam.nam$l_fnb & (NAM$M_NODE));
@@ -190,27 +195,30 @@ void  zro_load (mstr *str)
 								{
 									GETTOK;
 									if (toktyp != TK_IDENT)
-										rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr, ERR_FSEXP);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5)
+											ERR_ZROSYNTAX, 2, str->len,
+											str->addr, ERR_FSEXP);
 									if (si >= ZRO_MAX_ENTS)
-										rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr,ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7)
+											ERR_ZROSYNTAX, 2, str->len,
+											str->addr,ERR_MAXARGCNT, 1, ZRO_MAX_ENTS);
 									fab.fab$b_fns = tok.len;
 									fab.fab$l_fna = tok.addr;
 									status = sys$parse (&fab);
 									if (!(status & 1))
-										rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr,ERR_FILEPARSE, 2, tok.len,
-											  tok.addr, status);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(9)
+											ERR_ZROSYNTAX, 2, str->len,
+											str->addr,ERR_FILEPARSE, 2, tok.len,
+											tok.addr, status);
 									if (nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE
 											     | NAM$M_EXP_VER))
-										rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr, ERR_DIRONLY, 2, tok.len,
-											  tok.addr);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8)
+											ERR_ZROSYNTAX, 2, str->len, str->addr,
+											ERR_DIRONLY, 2, tok.len, tok.addr);
 									if (nam.nam$l_fnb & (NAM$M_WILDCARD))
-										rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr, ERR_WILDCARD, 2, tok.len,
-											  tok.addr);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8)
+											ERR_ZROSYNTAX, 2, str->len, str->addr,
+											ERR_WILDCARD, 2, tok.len, tok.addr);
 									array[oi + 1].count++;
 									array[si].type = ZRO_TYPE_SOURCE;
 									array[si].node_present = (nam.nam$l_fnb & (NAM$M_NODE));
@@ -221,15 +229,17 @@ void  zro_load (mstr *str)
 									if (toktyp == TK_RPAREN)
 										break;
 									if (toktyp != TK_COMMA)
-										rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len,
-											  str->addr, ERR_COMMAORRPAREXP);
+										rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5)
+											ERR_ZROSYNTAX, 2, str->len, str->addr,
+											ERR_COMMAORRPAREXP);
 								}
 								GETTOK;
 							}
 						} else
-							rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_QUALVAL);
+							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5)
+								ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_QUALVAL);
 					} else
-						rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
 							  ERR_BADQUAL, 2, tok.len, tok.addr);
 				} else if (tok.len == 5)
 				{
@@ -239,10 +249,10 @@ void  zro_load (mstr *str)
 						array[oi + 1].count = 0;
 						GETTOK;
 					} else
-						rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
+						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
 							  ERR_BADQUAL, 2, tok.len, tok.addr);
 				} else
-					rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
+					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr,
 						  ERR_BADQUAL, 2, tok.len, tok.addr);
 			} else if (toktyp == TK_COMMA || toktyp == TK_EOL)
 			{
@@ -260,7 +270,7 @@ void  zro_load (mstr *str)
 			else if (toktyp == TK_EOL)
 				break;
 			else
-				rts_error(VARLSTCNT(4) ERR_ZROSYNTAX, 2, str->len, str->addr);
+				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZROSYNTAX, 2, str->len, str->addr);
 			oi = si;
 		}
 	}
diff --git a/sr_vvms/zshow_devices.c b/sr_vvms/zshow_devices.c
index 2fc6158..f4bc387 100644
--- a/sr_vvms/zshow_devices.c
+++ b/sr_vvms/zshow_devices.c
@@ -26,7 +26,6 @@
 #include "iombdef.h"
 #include "iomtdef.h"
 #include "iormdef.h"
-#include "iotcpdef.h"
 #include "gt_timer.h"
 #include "iosocketdef.h"
 #include "nametabtyp.h"
@@ -42,7 +41,7 @@ typedef struct
 } uic_struct;
 
 LITREF nametabent dev_param_names[];
-LITREF unsigned char dev_param_index[];
+LITREF uint4 dev_param_index[];
 LITREF zshow_index zshow_param_index[];
 
 static readonly char space_text[] = {' '};
diff --git a/sr_x86_64/gdeerrors_ctl.c b/sr_x86_64/gdeerrors_ctl.c
index 90dc1b3..07cc7be 100644
--- a/sr_x86_64/gdeerrors_ctl.c
+++ b/sr_x86_64/gdeerrors_ctl.c
@@ -26,14 +26,14 @@ LITDEF	err_msg gdeerrors[] = {
 	"KEYTOOBIG", "But record size !AD can only support key size !AD", 4,
 	"KEYSIZIS", "Key size is !AD", 2,
 	"KEYWRDAMB", "!AD is ambiguous for !AD", 4,
-	"KEYWRDBAD", "!AD is not a valid !AD", 4,
+	"KEYWRDBAD", "!AD is not a valid !AD in this context", 4,
 	"LOADGD", "Loading Global Directory file !/	!AD", 2,
 	"LOGOFF", "No longer logging to file !AD", 2,
 	"LOGON", "Logging to file !AD", 2,
 	"LVSTARALON", "The * name cannot be deleted or renamed", 0,
 	"MAPBAD", "!AD !AD for !AD !AD does not exist", 8,
 	"MAPDUP", "!AD !AD and !AD both map to !AD !AD", 10,
-	"NAMSTARTBAD", "!AD must start with '%' or an alphabetic character", 2,
+	"NAMENDBAD", "Subscripted name !AD must end with right parenthesis", 2,
 	"NOACTION", "Not updating Global Directory !AD", 2,
 	"RPAREN", "List must end with right parenthesis or continue with comma", 0,
 	"NOEXIT", "Cannot exit because of verification failure", 0,
@@ -45,7 +45,7 @@ LITDEF	err_msg gdeerrors[] = {
 	"OBJNOTCHG", "Not changing !AD !AD", 4,
 	"OBJNOTFND", "!AD !AD does not exist", 4,
 	"OBJREQD", "!AD required", 2,
-	"PREFIXBAD", "!AD must start with an alphabetic character to be a !AD", 4,
+	"PREFIXBAD", "!AD - !AD !AD must start with an alphabetic character", 6,
 	"QUALBAD", "!AD is not a valid qualifier", 2,
 	"QUALDUP", "!AD qualifier appears more than once in the list", 2,
 	"QUALREQD", "!AD required", 2,
@@ -70,7 +70,33 @@ LITDEF	err_msg gdeerrors[] = {
 	"NONASCII", "!AD is illegal for a !AD as it contains non-ASCII characters", 4,
 	"CRYPTNOMM", "!AD is an encrypted database. Cannot support MM access method.", 2,
 	"JNLALLOCGROW", "Increased Journal ALLOCATION from [!AD blocks] to [!AD blocks] to match AUTOSWITCHLIMIT for !AD !AD", 8,
-	"KEYFORBLK", "But block size !AD can only support key size !AD", 4,
+	"KEYFORBLK", "But block size !AD and reserved bytes !AD limit key size to !AD", 6,
+	"STRMISSQUOTE", "Missing double-quote at end of string specification !AD", 2,
+	"GBLNAMEIS", "in gblname !AD", 2,
+	"NAMSUBSEMPTY", "Subscript #!UL is empty in name specification", 3,
+	"NAMSUBSBAD", "Subscript #!UL with value !AD in name specification is an invalid number or string", 3,
+	"NAMNUMSUBSOFLOW", "Subscript #!UL with value !AD in name specification has a numeric overflow", 3,
+	"NAMNUMSUBNOTEXACT", "Subscript #!UL with value !AD in name specification is not an exact GT.M number", 3,
+	"MISSINGDELIM", "Delimiter !AD expected before !AD !AD", 6,
+	"NAMRANGELASTSUB", "Ranges in name specification !AD are allowed only in the last subscript", 2,
+	"NAMSTARSUBSMIX", "Name specification !AD cannot contain * and subscripts at the same time", 2,
+	"NAMLPARENNOTBEG", "Subscripted Name specification !AD needs to have a left parenthesis at the beginning of subscripts", 2,
+	"NAMRPARENNOTEND", "Subscripted Name specification !AD cannot have anything following the right parenthesis at the end of subscripts", 2,
+	"NAMONECOLON", "Subscripted Name specification !AD must have at most one colon (range) specification", 2,
+	"NAMRPARENMISSING", "Subscripted Name specification !AD is missing one or more right parentheses at the end of subscripts", 2,
+	"NAMGVSUBSMAX", "Subscripted Name specification !AD has more than the maximum # of subscripts (!UL)", 3,
+	"NAMNOTSTRSUBS", "Subscript #!UL with value !AD in name specification is not a properly formatted string subscript", 3,
+	"NAMSTRSUBSFUN", "Subscript #!UL with value !AD in name specification uses function other than $C/$CHAR/$ZCH/$ZCHAR", 3,
+	"NAMSTRSUBSLPAREN", "Subscript #!UL with value !AD in name specification does not have left parenthesis following $ specification", 3,
+	"NAMSTRSUBSCHINT", "Subscript #!UL with value !AD in name specification does not have a positive integer inside $C/$CHAR/$ZCH/$ZCHAR", 3,
+	"NAMSTRSUBSCHARG", "Subscript #!UL with value !AD in name specification specifies a $C/$ZCH with number !UL that is invalid in the current $zchset", 4,
+	"GBLNAMCOLLUNDEF", "Error opening shared library of collation sequence #!UL for GBLNAME !AD", 3,
+	"NAMRANGEORDER", "Range in name specification !AD specifies out-of-order subscripts using collation sequence #!UL", 3,
+	"NAMRANGEOVERLAP", "Range in name specifications !AD and !AD overlap using collation sequence #!UL", 5,
+	"NAMGVSUBOFLOW", "Subscripted name !AD...!AD is too long to represent in the database using collation value #!UL", 5,
+	"GBLNAMCOLLRANGE", "Collation sequence #!UL is out of range (0 thru 255)", 3,
+	"STDNULLCOLLREQ", "Region !AD needs Standard Null Collation enabled because global !AD spans through it", 4,
+	"GBLNAMCOLLVER", "Global directory indicates GBLNAME !AD has collation sequence #!UL with a version #!UL but shared library reports different version #!UL", 5,
 };
 
 LITDEF	int GDE_BLKSIZ512 = 150503435;
@@ -93,7 +119,7 @@ LITDEF	int GDE_LOGON = 150503563;
 LITDEF	int GDE_LVSTARALON = 150503570;
 LITDEF	int GDE_MAPBAD = 150503579;
 LITDEF	int GDE_MAPDUP = 150503587;
-LITDEF	int GDE_NAMSTARTBAD = 150503594;
+LITDEF	int GDE_NAMENDBAD = 150503594;
 LITDEF	int GDE_NOACTION = 150503603;
 LITDEF	int GDE_RPAREN = 150503610;
 LITDEF	int GDE_NOEXIT = 150503619;
@@ -131,9 +157,35 @@ LITDEF	int GDE_NONASCII = 150503866;
 LITDEF	int GDE_CRYPTNOMM = 150503874;
 LITDEF	int GDE_JNLALLOCGROW = 150503883;
 LITDEF	int GDE_KEYFORBLK = 150503891;
+LITDEF	int GDE_STRMISSQUOTE = 150503898;
+LITDEF	int GDE_GBLNAMEIS = 150503907;
+LITDEF	int GDE_NAMSUBSEMPTY = 150503914;
+LITDEF	int GDE_NAMSUBSBAD = 150503922;
+LITDEF	int GDE_NAMNUMSUBSOFLOW = 150503930;
+LITDEF	int GDE_NAMNUMSUBNOTEXACT = 150503938;
+LITDEF	int GDE_MISSINGDELIM = 150503946;
+LITDEF	int GDE_NAMRANGELASTSUB = 150503954;
+LITDEF	int GDE_NAMSTARSUBSMIX = 150503962;
+LITDEF	int GDE_NAMLPARENNOTBEG = 150503970;
+LITDEF	int GDE_NAMRPARENNOTEND = 150503978;
+LITDEF	int GDE_NAMONECOLON = 150503986;
+LITDEF	int GDE_NAMRPARENMISSING = 150503994;
+LITDEF	int GDE_NAMGVSUBSMAX = 150504002;
+LITDEF	int GDE_NAMNOTSTRSUBS = 150504010;
+LITDEF	int GDE_NAMSTRSUBSFUN = 150504018;
+LITDEF	int GDE_NAMSTRSUBSLPAREN = 150504026;
+LITDEF	int GDE_NAMSTRSUBSCHINT = 150504034;
+LITDEF	int GDE_NAMSTRSUBSCHARG = 150504042;
+LITDEF	int GDE_GBLNAMCOLLUNDEF = 150504050;
+LITDEF	int GDE_NAMRANGEORDER = 150504058;
+LITDEF	int GDE_NAMRANGEOVERLAP = 150504066;
+LITDEF	int GDE_NAMGVSUBOFLOW = 150504074;
+LITDEF	int GDE_GBLNAMCOLLRANGE = 150504082;
+LITDEF	int GDE_STDNULLCOLLREQ = 150504091;
+LITDEF	int GDE_GBLNAMCOLLVER = 150504098;
 
 GBLDEF	err_ctl gdeerrors_ctl = {
 	248,
 	"GDE",
 	&gdeerrors[0],
-	58};
+	84};
diff --git a/sr_x86_64/merrors_ansi.h b/sr_x86_64/merrors_ansi.h
index 38cc6a1..0df7c77 100644
--- a/sr_x86_64/merrors_ansi.h
+++ b/sr_x86_64/merrors_ansi.h
@@ -510,8 +510,8 @@ const static readonly int error_ansi[] = {
 	   0,	/* NOPRINCIO */
 	   0,	/* INVPORTSPEC */
 	   0,	/* INVADDRSPEC */
-	  78,	/* SOCKPARMREQ */
-	   0,	/* IPADDRREQ */
+	  78,	/* UNUSEDMSG677 */
+	   0,	/* UNUSEDMSG678 */
 	  80,	/* SOCKWAIT */
 	  81,	/* SOCKACPT */
 	  80,	/* SOCKINIT */
@@ -614,7 +614,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* NOFORKCORE */
 	   0,	/* JNLREAD */
 	   0,	/* JNLMINALIGN */
-	   0,	/* UNUSEDMSG781 */
+	   0,	/* JOBSTARTCMDFAIL */
 	   0,	/* JNLPOOLSETUP */
 	   0,	/* JNLSTATEOFF */
 	   0,	/* RECVPOOLSETUP */
@@ -677,7 +677,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* BUFFLUFAILED */
 	   0,	/* MUQUALINCOMP */
 	   0,	/* DISTPATHMAX */
-	   0,	/* UNUSEDMSG844 */
+	   0,	/* FILEOPENFAIL */
 	   0,	/* IMAGENAME */
 	   0,	/* GTMSECSHRPERM */
 	   0,	/* GTMDISTUNDEF */
@@ -805,7 +805,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* SEMWT2LONG */
 	   0,	/* REPLINSTOPEN */
 	   0,	/* REPLINSTCLOSE */
-	   0,	/* UNUSEDMSG972 */
+	   0,	/* JOBSETUP */
 	   0,	/* DBCRERR8 */
 	   0,	/* NUMPROCESSORS */
 	   0,	/* DBADDRANGE8 */
@@ -940,7 +940,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* ZDIROUTOFSYNC */
 	   0,	/* GBLNOEXIST */
 	   0,	/* MAXBTLEVEL */
-	   0,	/* UNUSEDMSG1107 */
+	  35,	/* INVMNEMCSPC */
 	   0,	/* JNLALIGNSZCHG */
 	   0,	/* UNUSEDMSG1109 */
 	   0,	/* GVFAILCORE */
@@ -1152,7 +1152,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* CRYPTKEYFETCHFAILED */
 	   0,	/* CRYPTKEYFETCHFAILEDNF */
 	   0,	/* CRYPTHASHGENFAILED */
-	   0,	/* CRYPTNOPSWDINTP */
+	   0,	/* UNUSEDMSG1319 */
 	   0,	/* BADTAG */
 	   0,	/* ICUVERLT36 */
 	   0,	/* ICUSYMNOTFOUND */
@@ -1251,7 +1251,7 @@ const static readonly int error_ansi[] = {
 	   0,	/* SECNOTSUPPLEMENTARY */
 	   0,	/* SUPRCVRNEEDSSUPSRC */
 	   0,	/* UNUSEDMSG1417 */
-	   0,	/* UNUSEDMSG1418 */
+	   0,	/* SETITIMERFAILED */
 	   0,	/* UPDSYNC2MTINS */
 	   0,	/* UPDSYNCINSTFILE */
 	   0,	/* REUSEINSTNAME */
@@ -1361,4 +1361,23 @@ const static readonly int error_ansi[] = {
 	   0,	/* INSTFRZDEFER */
 	   0,	/* REGOPENRETRY */
 	   0,	/* REGOPENFAIL */
+	   0,	/* REPLINSTNOSHM */
+	   0,	/* DEVPARMTOOSMALL */
+	   0,	/* REMOTEDBNOSPGBL */
+	   0,	/* NCTCOLLSPGBL */
+	   0,	/* ACTCOLLMISMTCH */
+	   0,	/* GBLNOMAPTOREG */
+	   0,	/* ISSPANGBL */
+	   0,	/* TPNOSUPPORT */
+	   0,	/* GVSUBSERR */
+	   0,	/* TRIGNOSPANGBL */
+	   0,	/* FILTERTIMEDOUT */
+	   0,	/* TLSDLLNOOPEN */
+	   0,	/* TLSINIT */
+	   0,	/* TLSCONVSOCK */
+	   0,	/* TLSHANDSHAKE */
+	   0,	/* TLSCONNINFO */
+	   0,	/* TLSIOERROR */
+	   0,	/* TLSRENEGOTIATE */
+	   0,	/* REPLNOTLS */
 	};
diff --git a/sr_x86_64/merrors_ctl.c b/sr_x86_64/merrors_ctl.c
index a409df6..c8412e9 100644
--- a/sr_x86_64/merrors_ctl.c
+++ b/sr_x86_64/merrors_ctl.c
@@ -42,7 +42,7 @@ LITDEF	err_msg merrors[] = {
 	"DBRDERR", "Cannot read database file !AD after opening", 2,
 	"CCEDUMPNOW", "", 0,
 	"DEVPARINAP", "Device parameter inappropriate to this command", 0,
-	"RECORDSTAT", "!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL  max rec len: !UL", 6,
+	"RECORDSTAT", "!AD:!_  Key cnt: !UL  max subsc len: !UL  max rec len: !UL  max node len: !UL", 6,
 	"NOTGBL", "!_!AD!/!_!_!_\"^\" Expected", 2,
 	"DEVPARPROT", "The protection specification is invalid", 0,
 	"PREMATEOF", "Premature end of file detected", 0,
@@ -512,12 +512,12 @@ LITDEF	err_msg merrors[] = {
 	"NOPRINCIO", "Unable to write to principal device", 0,
 	"INVPORTSPEC", "Invalid port specification", 0,
 	"INVADDRSPEC", "Invalid IP address specification", 0,
-	"SOCKPARMREQ", "Socket device parameter is required for TCP open", 0,
-	"IPADDRREQ", "Active connection requires IP address", 0,
+	"UNUSEDMSG677", "SOCKPARMREQ last used in V6.0-002", 0,
+	"UNUSEDMSG678", "IPADDRREQ last used in V6.0-002", 0,
 	"SOCKWAIT", "Error waiting for socket connection", 0,
 	"SOCKACPT", "Error accepting socket connection", 0,
-	"SOCKINIT", "Error initializing TCP socket: (errno == !UL) !AD", 3,
-	"OPENCONN", "Error opening TCP connection", 0,
+	"SOCKINIT", "Error initializing socket: (errno == !UL) !AD", 3,
+	"OPENCONN", "Error opening socket connection", 0,
 	"DEVNOTIMP", "!AD device not implemented on in this environment", 2,
 	"JNLEXTR", "Error writing journal extract file: !AD", 2,
 	"DBREMOTE", "Database region !AD is remote; perform maintenance on the server node", 2,
@@ -543,7 +543,7 @@ LITDEF	err_msg merrors[] = {
 	"MUNOACTION", "MUPIP unable to perform requested action", 0,
 	"RMBIGSHARE", "File with BIGRECORD specified may only be shared if READONLY", 0,
 	"TPRESTART", "Database !AD; code: !AD; blk: 0x!XL in glbl: ^!AD; pvtmods: !UL, blkmods: !UL, blklvl: !UL, type: !UL, readset: !UL, writeset: !UL, local_tn: 0x!16 at XQ", 14,
-	"SOCKWRITE", "Write to a TCP/IP socket failed", 0,
+	"SOCKWRITE", "Write to a socket failed", 0,
 	"DBCNTRLERR", "Database file !AD: control error suspected but not found", 2,
 	"NOTERMENV", "Environment variable TERM not set.  Assuming \"unknown.\"", 0,
 	"NOTERMENTRY", "TERM = \"!AD\" has no \"terminfo\" entry.  Possible terminal handling problems.", 2,
@@ -616,7 +616,7 @@ LITDEF	err_msg merrors[] = {
 	"NOFORKCORE", "Unable to fork off process to create core.  Core creation postponed.", 0,
 	"JNLREAD", "Error reading from journal file !AD at offset [0x!XL]", 3,
 	"JNLMINALIGN", "Journal Record Alignment !UL is less than the minimum value of !UL", 2,
-	"UNUSEDMSG781", "JNLDSKALIGN : Last used in V4.3-000", 0,
+	"JOBSTARTCMDFAIL", "JOB command STARTUP script invocation failed", 0,
 	"JNLPOOLSETUP", "Journal Pool setup error", 0,
 	"JNLSTATEOFF", "ROLLBACK or RECOVER BACKWARD cannot proceed as database file !AD does not have journaling ENABLED and ON", 2,
 	"RECVPOOLSETUP", "Receive Pool setup error", 0,
@@ -679,7 +679,7 @@ LITDEF	err_msg merrors[] = {
 	"BUFFLUFAILED", "Error flushing buffers from !AD for database file !AD", 4,
 	"MUQUALINCOMP", "Incompatible qualifiers - FILE and REGION", 0,
 	"DISTPATHMAX", "$gtm_dist path is greater than maximum (!UL)", 1,
-	"UNUSEDMSG844", "MAXTRACEHEIGHT last used in V5.4-002", 0,
+	"FILEOPENFAIL", "Failed to open file !AD", 2,
 	"IMAGENAME", "The executing module name should be !AD instead of !AD", 4,
 	"GTMSECSHRPERM", "The gtmsecshr module in $gtm_dist does not have the correct permission and uid", 0,
 	"GTMDISTUNDEF", "Environment variable $gtm_dist is not defined", 0,
@@ -807,7 +807,7 @@ LITDEF	err_msg merrors[] = {
 	"SEMWT2LONG", "Process !UL waited !UL second(s) for the !AD lock for region !AD, lock held by pid !UL", 7,
 	"REPLINSTOPEN", "Error opening replication instance file !AD", 2,
 	"REPLINSTCLOSE", "Error closing replication instance file !AD", 2,
-	"UNUSEDMSG972", "JNLNOTFOUND : Last used in V4.4-000", 0,
+	"JOBSETUP", "Error receiving !AD from parent process", 2,
 	"DBCRERR8", "Database file !AD, cr location 0x!XJ blk = 0x!XL error: !AD was 0x!16 at XQ, expecting 0x!16 at XQ -- called from module !AD at line !UL", 11,
 	"NUMPROCESSORS", "Could not determine number of processors", 0,
 	"DBADDRANGE8", "Database file !AD, element location 0x!XJ: blk = 0x!XL: control 0x!16 at XQ was outside !AD range 0x!16 at XQ to 0x!16 at XQ", 9,
@@ -942,7 +942,7 @@ LITDEF	err_msg merrors[] = {
 	"ZDIROUTOFSYNC", "$ZDIRECTORY !AD is not the same as its cached value !AD", 4,
 	"GBLNOEXIST", "Global !AD no longer exists", 2,
 	"MAXBTLEVEL", "Global !AD reached maximum level", 2,
-	"UNUSEDMSG1107", "JNLSTRESTFL : found no evidence it ever was used in a production release", 0,
+	"INVMNEMCSPC", "Unsupported mnemonicspace !AD", 2,
 	"JNLALIGNSZCHG", "Journal ALIGNSIZE is rounded up to !UL blocks (closest next higher power of two)", 1,
 	"UNUSEDMSG1109", "MAXTRACELEVEL : last used in V5.4-002B", 0,
 	"GVFAILCORE", "A core file is being created for later analysis if necessary", 0,
@@ -1154,7 +1154,7 @@ LITDEF	err_msg merrors[] = {
 	"CRYPTKEYFETCHFAILED", "Could not retrieve encryption key corresponding to file !AD. !AD", 4,
 	"CRYPTKEYFETCHFAILEDNF", "Could not retrieve encryption key during !AD operation key. !AD", 4,
 	"CRYPTHASHGENFAILED", "Could not generate cryptographic hash for symmetric key corresponding to file !AD. !AD", 4,
-	"CRYPTNOPSWDINTP", "Cannot prompt for password inside a TP transaction.", 0,
+	"UNUSEDMSG1319", "CRYPTNOPSWDINTP : Last used in V6.0-003", 0,
 	"BADTAG", "Unable to use file !AD (CCSID !UL) with CCSID !UL", 4,
 	"ICUVERLT36", "!AD !UL.!UL. ICU version greater than or equal to 3.6 should be used", 4,
 	"ICUSYMNOTFOUND", "Symbol !AD not found in the ICU libraries. ICU needs to be built with symbol-renaming disabled or gtm_icu_version environment variable needs to be properly specified", 2,
@@ -1253,7 +1253,7 @@ LITDEF	err_msg merrors[] = {
 	"SECNOTSUPPLEMENTARY", "!AD is a Supplementary Instance and so cannot act as a source to non-Supplementary Instance !AD ", 4,
 	"SUPRCVRNEEDSSUPSRC", "Instance !AD is not configured to perform local updates so it cannot act as a receiver for non-Supplementary Instance !AD", 4,
 	"UNUSEDMSG1417", "SYNCTOSAMETYPE: Never used before so slot free for reuse", 0,
-	"UNUSEDMSG1418", "TARGINSRUNNING: Never used before so slot free for reuse", 0,
+	"SETITIMERFAILED", "A setitimer() call returned an error status of !UL", 1,
 	"UPDSYNC2MTINS", "Can only UPDATERESYNC with an empty instance file", 0,
 	"UPDSYNCINSTFILE", "Error with instance file name specified in UPDATERESYNC qualifier", 0,
 	"REUSEINSTNAME", "Error with instance name specified in REUSE qualifier", 0,
@@ -1359,10 +1359,29 @@ LITDEF	err_msg merrors[] = {
 	"HOSTCONFLICT", "Host !AD could not open database file !AD because it is marked as already open on node !AD", 6,
 	"GETADDRINFO", "Error in getting address info", 0,
 	"GETNAMEINFO", "Error in getting name info", 0,
-	"SOCKBIND", "Error in binding TCP socket", 0,
+	"SOCKBIND", "Error in binding socket", 0,
 	"INSTFRZDEFER", "Instance Freeze initiated by !AD error on region !AD deferred due to critical resource conflict", 4,
 	"REGOPENRETRY", "Attempt to open region !AD (!AD) using startup shortcut failed due to conflicting database shutdown. Retrying...", 4,
 	"REGOPENFAIL", "Failed to open region !AD (!AD) due to conflicting database shutdown activity", 4,
+	"REPLINSTNOSHM", "Database !AD has no active connection to a replication journal pool; please verify that the database is listed in your instance file", 2,
+	"DEVPARMTOOSMALL", "Deviceparameter must be greater than zero (0)", 0,
+	"REMOTEDBNOSPGBL", "Database region !AD contains portion of a spanning global and so cannot point to a remote file", 2,
+	"NCTCOLLSPGBL", "Database region !AD contains portion of spanning global ^!AD and so cannot support non-zero numeric collation type", 4,
+	"ACTCOLLMISMTCH", "Global ^!AD inherits alternative collation sequence #!UL from global directory but database file !AD contains different collation sequence #!UL for this global", 6,
+	"GBLNOMAPTOREG", "Global !AD does not map to region !AD in current global directory", 4,
+	"ISSPANGBL", "Operation cannot be performed on global ^!AD as it spans multiple regions in current global directory", 2,
+	"TPNOSUPPORT", "Operation cannot be performed while inside of a TP transaction", 0,
+	"GVSUBSERR", "Invalid subscripted global name specification in $VIEW() function", 0,
+	"TRIGNOSPANGBL", "Triggers cannot be installed/deleted for global name !AD as it spans multiple regions in current global directory", 2,
+	"FILTERTIMEDOUT", "Replication server timed out attempting to read seqno !16 at XQ from external filter", 1,
+	"TLSDLLNOOPEN", "Failed to load GT.M TLS/SSL library for secure communication", 0,
+	"TLSINIT", "Failed to initialize GT.M TLS/SSL library for secure communication", 0,
+	"TLSCONVSOCK", "Failed to convert Unix TCP/IP socket to TLS/SSL aware socket", 0,
+	"TLSHANDSHAKE", "Connection to remote side using TLS/SSL protocol failed", 0,
+	"TLSCONNINFO", "Failed to obtain information on the TLS/SSL connection", 0,
+	"TLSIOERROR", "Error during TLS/SSL !AD operation", 2,
+	"TLSRENEGOTIATE", "Failed to renegotiate TLS/SSL connection", 0,
+	"REPLNOTLS", "!AD requested TLS/SSL communication but the !AD was either not started with TLSID qualifier or does not support TLS/SSL protocol", 4,
 };
 
 LITDEF	int ERR_ACK = 150372361;
@@ -1864,8 +1883,8 @@ LITDEF	int ERR_CCPSIGDMP = 150376323;
 LITDEF	int ERR_NOPRINCIO = 150376332;
 LITDEF	int ERR_INVPORTSPEC = 150376338;
 LITDEF	int ERR_INVADDRSPEC = 150376346;
-LITDEF	int ERR_SOCKPARMREQ = 150376354;
-LITDEF	int ERR_IPADDRREQ = 150376362;
+LITDEF	int ERR_UNUSEDMSG677 = 150376354;
+LITDEF	int ERR_UNUSEDMSG678 = 150376362;
 LITDEF	int ERR_SOCKWAIT = 150376370;
 LITDEF	int ERR_SOCKACPT = 150376378;
 LITDEF	int ERR_SOCKINIT = 150376386;
@@ -1968,7 +1987,7 @@ LITDEF	int ERR_BCKUPBUFLUSH = 150377154;
 LITDEF	int ERR_NOFORKCORE = 150377160;
 LITDEF	int ERR_JNLREAD = 150377170;
 LITDEF	int ERR_JNLMINALIGN = 150377176;
-LITDEF	int ERR_UNUSEDMSG781 = 150377186;
+LITDEF	int ERR_JOBSTARTCMDFAIL = 150377186;
 LITDEF	int ERR_JNLPOOLSETUP = 150377194;
 LITDEF	int ERR_JNLSTATEOFF = 150377202;
 LITDEF	int ERR_RECVPOOLSETUP = 150377210;
@@ -2031,7 +2050,7 @@ LITDEF	int ERR_RECSIZENOTEVEN = 150377658;
 LITDEF	int ERR_BUFFLUFAILED = 150377666;
 LITDEF	int ERR_MUQUALINCOMP = 150377674;
 LITDEF	int ERR_DISTPATHMAX = 150377682;
-LITDEF	int ERR_UNUSEDMSG844 = 150377690;
+LITDEF	int ERR_FILEOPENFAIL = 150377690;
 LITDEF	int ERR_IMAGENAME = 150377698;
 LITDEF	int ERR_GTMSECSHRPERM = 150377706;
 LITDEF	int ERR_GTMDISTUNDEF = 150377714;
@@ -2159,7 +2178,7 @@ LITDEF	int ERR_MUTEXRSRCCLNUP = 150378683;
 LITDEF	int ERR_SEMWT2LONG = 150378690;
 LITDEF	int ERR_REPLINSTOPEN = 150378698;
 LITDEF	int ERR_REPLINSTCLOSE = 150378706;
-LITDEF	int ERR_UNUSEDMSG972 = 150378714;
+LITDEF	int ERR_JOBSETUP = 150378714;
 LITDEF	int ERR_DBCRERR8 = 150378723;
 LITDEF	int ERR_NUMPROCESSORS = 150378728;
 LITDEF	int ERR_DBADDRANGE8 = 150378739;
@@ -2294,7 +2313,7 @@ LITDEF	int ERR_INVZDIRFORM = 150379762;
 LITDEF	int ERR_ZDIROUTOFSYNC = 150379768;
 LITDEF	int ERR_GBLNOEXIST = 150379779;
 LITDEF	int ERR_MAXBTLEVEL = 150379786;
-LITDEF	int ERR_UNUSEDMSG1107 = 150379794;
+LITDEF	int ERR_INVMNEMCSPC = 150379794;
 LITDEF	int ERR_JNLALIGNSZCHG = 150379803;
 LITDEF	int ERR_UNUSEDMSG1109 = 150379810;
 LITDEF	int ERR_GVFAILCORE = 150379818;
@@ -2506,7 +2525,7 @@ LITDEF	int ERR_CRYPTJNLWRONGHASH = 150381458;
 LITDEF	int ERR_CRYPTKEYFETCHFAILED = 150381466;
 LITDEF	int ERR_CRYPTKEYFETCHFAILEDNF = 150381474;
 LITDEF	int ERR_CRYPTHASHGENFAILED = 150381482;
-LITDEF	int ERR_CRYPTNOPSWDINTP = 150381490;
+LITDEF	int ERR_UNUSEDMSG1319 = 150381490;
 LITDEF	int ERR_BADTAG = 150381498;
 LITDEF	int ERR_ICUVERLT36 = 150381506;
 LITDEF	int ERR_ICUSYMNOTFOUND = 150381514;
@@ -2605,7 +2624,7 @@ LITDEF	int ERR_MUUSERECOV = 150382250;
 LITDEF	int ERR_SECNOTSUPPLEMENTARY = 150382258;
 LITDEF	int ERR_SUPRCVRNEEDSSUPSRC = 150382266;
 LITDEF	int ERR_UNUSEDMSG1417 = 150382275;
-LITDEF	int ERR_UNUSEDMSG1418 = 150382283;
+LITDEF	int ERR_SETITIMERFAILED = 150382284;
 LITDEF	int ERR_UPDSYNC2MTINS = 150382290;
 LITDEF	int ERR_UPDSYNCINSTFILE = 150382298;
 LITDEF	int ERR_REUSEINSTNAME = 150382306;
@@ -2715,9 +2734,28 @@ LITDEF	int ERR_SOCKBIND = 150383130;
 LITDEF	int ERR_INSTFRZDEFER = 150383139;
 LITDEF	int ERR_REGOPENRETRY = 150383147;
 LITDEF	int ERR_REGOPENFAIL = 150383154;
+LITDEF	int ERR_REPLINSTNOSHM = 150383162;
+LITDEF	int ERR_DEVPARMTOOSMALL = 150383170;
+LITDEF	int ERR_REMOTEDBNOSPGBL = 150383178;
+LITDEF	int ERR_NCTCOLLSPGBL = 150383186;
+LITDEF	int ERR_ACTCOLLMISMTCH = 150383194;
+LITDEF	int ERR_GBLNOMAPTOREG = 150383202;
+LITDEF	int ERR_ISSPANGBL = 150383210;
+LITDEF	int ERR_TPNOSUPPORT = 150383218;
+LITDEF	int ERR_GVSUBSERR = 150383226;
+LITDEF	int ERR_TRIGNOSPANGBL = 150383234;
+LITDEF	int ERR_FILTERTIMEDOUT = 150383242;
+LITDEF	int ERR_TLSDLLNOOPEN = 150383250;
+LITDEF	int ERR_TLSINIT = 150383258;
+LITDEF	int ERR_TLSCONVSOCK = 150383266;
+LITDEF	int ERR_TLSHANDSHAKE = 150383274;
+LITDEF	int ERR_TLSCONNINFO = 150383280;
+LITDEF	int ERR_TLSIOERROR = 150383290;
+LITDEF	int ERR_TLSRENEGOTIATE = 150383298;
+LITDEF	int ERR_REPLNOTLS = 150383306;
 
 GBLDEF	err_ctl merrors_ctl = {
 	246,
 	"GTM",
 	&merrors[0],
-	1350};
+	1369};
diff --git a/sr_x86_64/ttt.c b/sr_x86_64/ttt.c
index e0bfaf8..c85f77d 100644
--- a/sr_x86_64/ttt.c
+++ b/sr_x86_64/ttt.c
@@ -13,49 +13,49 @@
 #include "vxi.h"
 #include "vxt.h"
 #include "xfer_enum.h"
-LITDEF short ttt[4291] = {
+LITDEF short ttt[4305] = {
 
-/*    0 */	0,0,0,0,325,3550,3023,567,
-/*    8 */	2347,3008,3038,2028,421,3500,2149,3124,
-/*   16 */	2226,2217,3733,3770,2190,2199,2265,2211,
-/*   24 */	2256,2235,2172,773,788,800,812,854,
+/*    0 */	0,0,0,0,325,3561,3032,567,
+/*    8 */	2356,3017,3047,2028,421,3511,2149,3135,
+/*   16 */	2232,2220,3744,3781,2193,2202,2274,2214,
+/*   24 */	2265,2244,2172,773,788,800,812,854,
 /*   32 */	872,893,922,952,967,982,1000,1159,
 /*   40 */	1072,1105,1138,1216,1267,1597,1630,1645,
-/*   48 */	1675,1741,1771,1795,1858,1879,1894,3565,
-/*   56 */	3587,0,0,0,0,582,0,523,
-/*   64 */	0,2014,0,3110,0,0,0,0,
-/*   72 */	0,0,357,433,2325,2331,2756,2783,
-/*   80 */	2801,2904,2842,2833,2919,3639,3723,3059,
-/*   88 */	0,3089,3190,3153,3138,3168,3514,3366,
-/*   96 */	3645,3657,3672,3696,3705,3690,3681,3399,
-/*  104 */	3766,3779,3801,3838,3850,3871,3895,3961,
-/*  112 */	0,0,2952,2307,3242,4240,661,4243,
-/*  120 */	715,2813,3208,537,543,4246,2410,2507,
-/*  128 */	2397,490,2433,2527,2181,2465,2537,4249,
-/*  136 */	2292,2283,4253,1285,4254,353,349,3390,
-/*  144 */	445,4258,4261,4264,3075,4267,4270,4273,
-/*  152 */	4276,4279,4282,3536,0,2928,2596,2574,
-/*  160 */	1558,2565,2343,2163,2879,2049,740,2869,
-/*  168 */	0,0,2362,3714,3742,1489,3666,2445,
-/*  176 */	2042,552,3862,1843,2274,1201,340,3194,
-/*  184 */	624,693,605,671,3826,1120,3794,3052,
-/*  192 */	2301,2943,3066,643,1012,2883,4285,2517,
-/*  200 */	3913,3931,3946,514,2898,3186,1975,3988,
-/*  208 */	3973,1303,3528,596,1660,1729,2480,4288,
-/*  216 */	3599,2553,749,830,3225,3754,3623,3609,
-/*  224 */	3616,3605,725,907,2420,1054,2384,1042,
-/*  232 */	2244,1027,1087,2492,1459,1402,1387,1441,
-/*  240 */	1357,1369,1414,1342,1426,1474,0,3486,
-/*  248 */	0,931,940,3345,1870,3324,2371,2455,
-/*  256 */	2978,2984,2996,2964,1240,1252,1174,1186,
-/*  264 */	1228,3577,1705,1906,0,1315,1501,1579,
-/*  272 */	3420,1612,1690,1717,1828,1807,3462,1753,
-/*  280 */	3441,1939,1513,1528,2002,4003,1921,3252,
-/*  288 */	3264,3276,3288,2792,2807,1546,454,1330,
-/*  296 */	1957,652,3300,3312,3982,3994,0,0,
-/*  304 */	0,0,3817,4015,4026,4038,4047,4061,
-/*  312 */	4074,4084,4101,4110,4119,4131,4143,4155,
-/*  320 */	4170,4182,4191,4203,4219,VXI_PUSHAB,VXT_VAL,0,
+/*   48 */	1675,1741,1771,1795,1858,1879,1894,3576,
+/*   56 */	3598,0,0,0,0,582,0,523,
+/*   64 */	0,2014,0,3121,0,0,0,0,
+/*   72 */	0,0,357,433,2334,2340,2765,2792,
+/*   80 */	2810,2913,2851,2842,2928,3650,3734,3068,
+/*   88 */	0,3100,3201,3164,3149,3179,3525,3377,
+/*   96 */	3656,3668,3683,3707,3716,3701,3692,3410,
+/*  104 */	3777,3790,3812,3849,3861,3882,3906,3972,
+/*  112 */	0,0,2961,2316,3253,4254,661,4257,
+/*  120 */	715,2822,3219,537,543,4260,2419,2516,
+/*  128 */	2406,490,2442,2536,2181,2474,2546,4263,
+/*  136 */	2301,2292,4267,1285,4268,353,349,3401,
+/*  144 */	445,4272,4275,4278,3086,4281,4284,4287,
+/*  152 */	4290,4293,4296,3547,0,2937,2605,2583,
+/*  160 */	1558,2574,2352,2163,2888,2049,740,2878,
+/*  168 */	0,0,2371,3725,3753,1489,3677,2454,
+/*  176 */	2042,552,3873,1843,2283,1201,340,3205,
+/*  184 */	624,693,605,671,3837,1120,3805,3061,
+/*  192 */	2310,2952,3075,643,1012,2892,4299,2526,
+/*  200 */	3924,3942,3957,514,2907,3197,1975,3999,
+/*  208 */	3984,1303,3539,596,1660,1729,2489,4302,
+/*  216 */	3610,2562,749,830,3236,3765,3634,3620,
+/*  224 */	3627,3616,725,907,2429,1054,2393,1042,
+/*  232 */	2253,1027,1087,2501,1459,1402,1387,1441,
+/*  240 */	1357,1369,1414,1342,1426,1474,0,3497,
+/*  248 */	0,931,940,3356,1870,3335,2380,2464,
+/*  256 */	2987,2993,3005,2973,1240,1252,1174,1186,
+/*  264 */	1228,3588,1705,1906,0,1315,1501,1579,
+/*  272 */	3431,1612,1690,1717,1828,1807,3473,1753,
+/*  280 */	3452,1939,1513,1528,2002,4014,1921,3263,
+/*  288 */	3275,3287,3299,2801,2816,1546,454,1330,
+/*  296 */	1957,652,3311,3323,3993,4005,0,0,
+/*  304 */	0,0,3828,4026,4037,4049,4058,4072,
+/*  312 */	4085,4095,4112,4124,4133,4145,4157,4169,
+/*  320 */	4184,4196,4205,4217,4233,VXI_PUSHAB,VXT_VAL,0,
 /*  328 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
 /*  336 */	3,VXT_XFER,SIZEOF(char *) * (short int)xf_add,VXT_END,
 /*  340 */	VXT_IREPL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_bindparm,
@@ -351,358 +351,358 @@ LITDEF short ttt[4291] = {
 /* 2171 */	VXT_END,
 /* 2172 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvdata,
 /* 2180 */	VXT_END,
-/* 2181 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,
-/* 2189 */	VXT_END,
-/* 2190 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
-/* 2198 */	VXT_END,
-/* 2199 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 2207 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
-/* 2211 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
-/* 2217 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,
-/* 2225 */	VXT_END,
-/* 2226 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,
-/* 2234 */	VXT_END,
-/* 2235 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
-/* 2243 */	VXT_END,
-/* 2244 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 2252 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
-/* 2256 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
-/* 2264 */	VXT_END,
-/* 2265 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
+/* 2181 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2189 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvextnam,VXT_END,
+/* 2193 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvget,
+/* 2201 */	VXT_END,
+/* 2202 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 2210 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvincr,VXT_END,
+/* 2214 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvkill,VXT_END,
+/* 2220 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2228 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnaked,VXT_END,
+/* 2232 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2240 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvname,VXT_END,
+/* 2244 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvnext,
+/* 2252 */	VXT_END,
+/* 2253 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 2261 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_gvo2,VXT_END,
+/* 2265 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvorder,
 /* 2273 */	VXT_END,
-/* 2274 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
+/* 2274 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvput,
 /* 2282 */	VXT_END,
-/* 2283 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
+/* 2283 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvquery,
 /* 2291 */	VXT_END,
-/* 2292 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
+/* 2292 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvrectarg,
 /* 2300 */	VXT_END,
-/* 2301 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
-/* 2307 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 2315 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
-/* 2323 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
-/* 2325 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
-/* 2331 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 2339 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
-/* 2343 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
-/* 2347 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2355 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
-/* 2362 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
-/* 2370 */	VXT_END,
-/* 2371 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2379 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
-/* 2384 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2392 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
-/* 2397 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2405 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
-/* 2410 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2418 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
-/* 2420 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 2428 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
-/* 2433 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
-/* 2441 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2445 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2453 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
-/* 2455 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
-/* 2463 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
-/* 2465 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2473 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
-/* 2480 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
-/* 2488 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2492 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2500 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
-/* 2507 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2515 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
-/* 2517 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2525 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
-/* 2527 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2535 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
-/* 2537 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2545 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
-/* 2553 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2561 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
-/* 2565 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
-/* 2573 */	VXT_END,
-/* 2574 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2582 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
-/* 2584 */	VXI_BRB,VXT_JMP,1,VXT_END,
-/* 2588 */	VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2592 */	VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2596 */	VXI_JMP,VXT_VAL,1,VXT_END,
-/* 2600 */	VXI_BEQL,VXT_JMP,1,VXT_END,
-/* 2604 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2611 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2618 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
-/* 2622 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2629 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2636 */	VXI_BGTR,VXT_JMP,1,VXT_END,
-/* 2640 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2647 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2654 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
-/* 2658 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2665 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2672 */	VXI_BLSS,VXT_JMP,1,VXT_END,
-/* 2676 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2683 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2690 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
-/* 2694 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
-/* 2701 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
-/* 2708 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2714 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2722 */	VXT_END,
-/* 2723 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2301 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_gvsavtarg,
+/* 2309 */	VXT_END,
+/* 2310 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_gvzwithdraw,VXT_END,
+/* 2316 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 2324 */	3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,
+/* 2332 */	SIZEOF(char *) * (short int)xf_gvzwrite,VXT_END,
+/* 2334 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_halt,VXT_END,
+/* 2340 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 2348 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_hang,VXT_END,
+/* 2352 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_hardret,VXT_END,
+/* 2356 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2364 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_idiv,VXT_END,
+/* 2371 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_igetsrc,
+/* 2379 */	VXT_END,
+/* 2380 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2388 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_inddevparms,VXT_END,
+/* 2393 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2401 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname,VXT_END,
+/* 2406 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2414 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indfun,VXT_END,
+/* 2419 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2427 */	SIZEOF(char *) * (short int)xf_indglvn,VXT_END,
+/* 2429 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 2437 */	0,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indincr,VXT_END,
+/* 2442 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvadr,VXI_MOVL,VXT_REG,
+/* 2450 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2454 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2462 */	SIZEOF(char *) * (short int)xf_indlvarg,VXT_END,
+/* 2464 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,
+/* 2472 */	SIZEOF(char *) * (short int)xf_indmerge,VXT_END,
+/* 2474 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2482 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indname,VXT_END,
+/* 2489 */	VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indlvnamadr,VXI_MOVL,VXT_REG,
+/* 2497 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2501 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2509 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indo2,VXT_END,
+/* 2516 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2524 */	SIZEOF(char *) * (short int)xf_indpat,VXT_END,
+/* 2526 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2534 */	SIZEOF(char *) * (short int)xf_indrzshow,VXT_END,
+/* 2536 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2544 */	SIZEOF(char *) * (short int)xf_indset,VXT_END,
+/* 2546 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2554 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indtext,VXT_END,
+/* 2562 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2570 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_iocontrol,VXT_END,
+/* 2574 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_iretmvad,
+/* 2582 */	VXT_END,
+/* 2583 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2591 */	SIZEOF(char *) * (short int)xf_iretmval,VXT_END,
+/* 2593 */	VXI_BRB,VXT_JMP,1,VXT_END,
+/* 2597 */	VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2601 */	VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2605 */	VXI_JMP,VXT_VAL,1,VXT_END,
+/* 2609 */	VXI_BEQL,VXT_JMP,1,VXT_END,
+/* 2613 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2620 */	VXI_BNEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2627 */	VXI_BGEQ,VXT_JMP,1,VXT_END,
+/* 2631 */	VXI_BLSS,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2638 */	VXI_BLSS,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2645 */	VXI_BGTR,VXT_JMP,1,VXT_END,
+/* 2649 */	VXI_BLEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2656 */	VXI_BLEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2663 */	VXI_BLEQ,VXT_JMP,1,VXT_END,
+/* 2667 */	VXI_BGTR,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2674 */	VXI_BGTR,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2681 */	VXI_BLSS,VXT_JMP,1,VXT_END,
+/* 2685 */	VXI_BGEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2692 */	VXI_BGEQ,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2699 */	VXI_BNEQ,VXT_JMP,1,VXT_END,
+/* 2703 */	VXI_BNEQ,VXT_LIT,6,VXI_JMP,VXT_JMP,1,VXT_END,
+/* 2710 */	VXI_BEQL,VXT_LIT,3,VXI_BRW,VXT_JMP,1,VXT_END,
+/* 2717 */	VXI_BLBC,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2723 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
 /* 2731 */	VXT_END,
-/* 2732 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
-/* 2738 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
-/* 2746 */	VXT_END,
-/* 2747 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2732 */	VXI_BLBS,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2740 */	VXT_END,
+/* 2741 */	VXI_BLBS,VXT_REG,0x5A,VXT_JMP,1,VXT_END,
+/* 2747 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,6,VXI_JMP,VXT_JMP,1,
 /* 2755 */	VXT_END,
-/* 2756 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
-/* 2764 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
-/* 2772 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
-/* 2780 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
-/* 2783 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
-/* 2791 */	VXT_END,
-/* 2792 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
+/* 2756 */	VXI_BLBC,VXT_REG,0x5A,VXT_LIT,3,VXI_BRW,VXT_JMP,1,
+/* 2764 */	VXT_END,
+/* 2765 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,7,VXI_PUSHL,VXT_VAL,
+/* 2773 */	6,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,
+/* 2781 */	VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,
+/* 2789 */	VXT_XFER,SIZEOF(char *) * (short int)xf_job,VXT_END,
+/* 2792 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_kill,
 /* 2800 */	VXT_END,
-/* 2801 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
-/* 2807 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
-/* 2813 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 2821 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
-/* 2829 */	0x50,VXT_ADDR,0,VXT_END,
-/* 2833 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
-/* 2841 */	VXT_END,
-/* 2842 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
+/* 2801 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_killalias,
+/* 2809 */	VXT_END,
+/* 2810 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killall,VXT_END,
+/* 2816 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_killaliasall,VXT_END,
+/* 2822 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 2830 */	3,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_labaddr,VXI_MOVL,VXT_REG,
+/* 2838 */	0x50,VXT_ADDR,0,VXT_END,
+/* 2842 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckdecr,
 /* 2850 */	VXT_END,
-/* 2851 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2857 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2863 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
-/* 2869 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 2877 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
-/* 2879 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
-/* 2883 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 2891 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2898 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
-/* 2904 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2912 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
-/* 2919 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
-/* 2927 */	VXT_END,
-/* 2928 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 2936 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
-/* 2943 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
-/* 2951 */	VXT_END,
-/* 2952 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 2960 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
-/* 2964 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
-/* 2972 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 2978 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
-/* 2984 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 2992 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 2996 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3004 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
-/* 3008 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3016 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
-/* 3023 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3031 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
-/* 3038 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
-/* 3046 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
-/* 3052 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
-/* 3059 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
-/* 3066 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,
-/* 3074 */	VXT_END,
-/* 3075 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3083 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
-/* 3089 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3097 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3105 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
-/* 3110 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3118 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
-/* 3124 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
-/* 3132 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3138 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 3146 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
-/* 3153 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 3161 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
-/* 3168 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
-/* 3176 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3184 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
-/* 3186 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
-/* 3190 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
-/* 3194 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
-/* 3202 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
-/* 3208 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3216 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3224 */	VXT_END,
-/* 3225 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3233 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 3241 */	VXT_END,
-/* 3242 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3250 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
-/* 3252 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3260 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
-/* 3264 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3272 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
-/* 3276 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3284 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
-/* 3288 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3296 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
-/* 3300 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3308 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
-/* 3312 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
-/* 3320 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
-/* 3324 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3332 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3340 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
-/* 3345 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3353 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3361 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
-/* 3366 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3374 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3382 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
-/* 3390 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,
-/* 3398 */	VXT_END,
-/* 3399 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3407 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
-/* 3415 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
-/* 3420 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3428 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3436 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
-/* 3441 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3449 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 3457 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
-/* 3462 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 3470 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3478 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
-/* 3486 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
-/* 3494 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
-/* 3500 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
-/* 3508 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 3514 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
-/* 3522 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3528 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
-/* 3536 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
-/* 3544 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
-/* 3550 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3558 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
-/* 3565 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3573 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
-/* 3577 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3585 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
-/* 3587 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3595 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
-/* 3599 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
-/* 3605 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
-/* 3609 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
-/* 3616 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
-/* 3623 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
-/* 3631 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
-/* 3639 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
-/* 3645 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3653 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
-/* 3657 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
-/* 3665 */	VXT_END,
-/* 3666 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
-/* 3672 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
-/* 3680 */	VXT_END,
-/* 3681 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
-/* 3689 */	VXT_END,
-/* 3690 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
-/* 3696 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
-/* 3704 */	VXT_END,
-/* 3705 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
-/* 3713 */	VXT_END,
-/* 3714 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
-/* 3722 */	VXT_END,
-/* 3723 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 3731 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
-/* 3733 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
-/* 3741 */	VXT_END,
-/* 3742 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3750 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
-/* 3754 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3762 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
-/* 3766 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3770 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
-/* 3778 */	VXT_END,
-/* 3779 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 3787 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
-/* 3794 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
-/* 3801 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
-/* 3809 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
-/* 3817 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
-/* 3825 */	VXT_END,
-/* 3826 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3834 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
-/* 3838 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3846 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
-/* 3850 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
-/* 3858 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
-/* 3862 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
-/* 3870 */	VXT_END,
-/* 3871 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
-/* 3879 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
-/* 3887 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
-/* 3895 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
-/* 3903 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3911 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3913 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
-/* 3921 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
-/* 3929 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
-/* 3931 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3939 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3946 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3954 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
-/* 3961 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 3969 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
-/* 3973 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
-/* 3981 */	VXT_END,
-/* 3982 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztrigger,VXT_END,
-/* 3988 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
-/* 3994 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
-/* 4002 */	VXT_END,
-/* 4003 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4011 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
-/* 4015 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
-/* 4023 */	VXT_ADDR,0,VXT_END,
-/* 4026 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4034 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
-/* 4038 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
-/* 4046 */	VXT_END,
-/* 4047 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
-/* 4055 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
-/* 4061 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
-/* 4069 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
-/* 4074 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
-/* 4082 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
-/* 4084 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4092 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
-/* 4100 */	VXT_END,
-/* 4101 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,
-/* 4109 */	VXT_END,
-/* 4110 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
-/* 4118 */	VXT_END,
-/* 4119 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4127 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
-/* 4131 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4139 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
-/* 4143 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
-/* 4151 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
-/* 4155 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
-/* 4163 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
-/* 4170 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 4178 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
-/* 4182 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
-/* 4190 */	VXT_END,
-/* 4191 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
-/* 4199 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_litc,VXT_END,
-/* 4203 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXI_PUSHAB,
-/* 4211 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_stolitc,VXT_END,
-/* 4219 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
-/* 4227 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
-/* 4235 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpeek,VXT_END,
-/* 4240 */	361,381,371,2584,2592,2588,2851,2863,
-/* 4248 */	2857,0,0,0,500,476,467,0,
-/* 4256 */	0,463,2092,2130,2111,2732,2747,2738,
-/* 4264 */	2708,2723,2714,2600,2611,2604,2690,2701,
-/* 4272 */	2694,2636,2647,2640,2654,2665,2658,2672,
-/* 4280 */	2683,2676,2618,2629,2622,2062,2082,2072,
-/* 4288 */	391,411,401};
+/* 2851 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lckincr,
+/* 2859 */	VXT_END,
+/* 2860 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2866 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2872 */	VXI_MOVAB,VXT_JMP,1,VXT_ADDR,0,VXT_END,
+/* 2878 */	VXT_IREPL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 2886 */	SIZEOF(char *) * (short int)xf_linefetch,VXT_END,
+/* 2888 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_linestart,VXT_END,
+/* 2892 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 2900 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2907 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_lkinit,VXT_END,
+/* 2913 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2921 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lkname,VXT_END,
+/* 2928 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lock,
+/* 2936 */	VXT_END,
+/* 2937 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 2945 */	2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvpatwrite,VXT_END,
+/* 2952 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwithdraw,
+/* 2960 */	VXT_END,
+/* 2961 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 2969 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_lvzwrite,VXT_END,
+/* 2973 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_m_srchindx,
+/* 2981 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 2987 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_merge,VXT_END,
+/* 2993 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3001 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3005 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3013 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_merge_arg,VXT_END,
+/* 3017 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3025 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_flt_mod,VXT_END,
+/* 3032 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3040 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_mul,VXT_END,
+/* 3047 */	VXI_MOVAB,VXT_VAL,0,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,1,
+/* 3055 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_neg,VXT_END,
+/* 3061 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newintrinsic,VXT_END,
+/* 3068 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_newvar,VXT_END,
+/* 3075 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_nullexp,VXI_MOVL,VXT_REG,0x50,
+/* 3083 */	VXT_ADDR,0,VXT_END,
+/* 3086 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3094 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_numcmp,VXT_END,
+/* 3100 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3108 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3116 */	VXT_LIT,4,VXT_XFER,SIZEOF(char *) * (short int)xf_open,VXT_END,
+/* 3121 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3129 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_pattern,VXT_END,
+/* 3135 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_putindx,
+/* 3143 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3149 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3157 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_rdone,VXT_END,
+/* 3164 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 3172 */	0,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_read,VXT_END,
+/* 3179 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,
+/* 3187 */	1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3195 */	SIZEOF(char *) * (short int)xf_readfl,VXT_END,
+/* 3197 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXT_END,
+/* 3201 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_ret,VXT_END,
+/* 3205 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVL,VXT_VAL,2,
+/* 3213 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_retarg,VXT_END,
+/* 3219 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3227 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3235 */	VXT_END,
+/* 3236 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3244 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rhdaddr,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 3252 */	VXT_END,
+/* 3253 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3261 */	SIZEOF(char *) * (short int)xf_rterror,VXT_END,
+/* 3263 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3271 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setals2als,VXT_END,
+/* 3275 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3283 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsin2alsct,VXT_END,
+/* 3287 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3295 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsctin2als,VXT_END,
+/* 3299 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3307 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setalsct2alsct,VXT_END,
+/* 3311 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3319 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2als,VXT_END,
+/* 3323 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,2,VXI_CALLS,VXT_LIT,
+/* 3331 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_setfnretin2alsct,VXT_END,
+/* 3335 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3343 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3351 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setextract,VXT_END,
+/* 3356 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3364 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3372 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setp1,VXT_END,
+/* 3377 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3385 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3393 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setpiece,VXT_END,
+/* 3401 */	VXI_BISB2,VXT_LIT,1,VXT_REG,0x5A,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_dt_true,
+/* 3409 */	VXT_END,
+/* 3410 */	VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3418 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,3,VXI_CALLS,
+/* 3426 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzbrk,VXT_END,
+/* 3431 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3439 */	2,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3447 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzextract,VXT_END,
+/* 3452 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3460 */	4,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 3468 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_setzp1,VXT_END,
+/* 3473 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 3481 */	3,VXI_PUSHAB,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3489 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,6,VXT_XFER,SIZEOF(char *) * (short int)xf_setzpiece,VXT_END,
+/* 3497 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x50,VXI_MOVAB,VXT_VAL,2,
+/* 3505 */	VXT_REG,0x51,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sorts_after,VXT_END,
+/* 3511 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_srchindx,
+/* 3519 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 3525 */	VXI_MOVAB,VXT_VAL,2,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,1,
+/* 3533 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3539 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXT_END,
+/* 3547 */	VXI_MOVAB,VXT_VAL,1,VXT_REG,0x51,VXI_MOVAB,VXT_VAL,0,
+/* 3555 */	VXT_REG,0x50,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_sto,VXT_END,
+/* 3561 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3569 */	1,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_sub,VXT_END,
+/* 3576 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3584 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svget,VXT_END,
+/* 3588 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3596 */	SIZEOF(char *) * (short int)xf_psvput,VXT_END,
+/* 3598 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3606 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_svput,VXT_END,
+/* 3610 */	VXI_MOVL,VXT_REG,0x50,VXT_REG,0x5A,VXT_END,
+/* 3616 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tcommit,VXT_END,
+/* 3620 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trollback,VXT_END,
+/* 3627 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_trestart,VXT_END,
+/* 3634 */	VXT_IREPAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,
+/* 3642 */	2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_tstart,VXT_END,
+/* 3650 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_unlock,VXT_END,
+/* 3656 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3664 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_use,VXT_END,
+/* 3668 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_view,
+/* 3676 */	VXT_END,
+/* 3677 */	VXI_CMPL,VXT_VAL,1,VXT_VAL,2,VXT_END,
+/* 3683 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_write,
+/* 3691 */	VXT_END,
+/* 3692 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wteol,
+/* 3700 */	VXT_END,
+/* 3701 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_wtff,VXT_END,
+/* 3707 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wtone,
+/* 3715 */	VXT_END,
+/* 3716 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_wttab,
+/* 3724 */	VXT_END,
+/* 3725 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_xkill,
+/* 3733 */	VXT_END,
+/* 3734 */	VXT_IREPAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 3742 */	SIZEOF(char *) * (short int)xf_xnew,VXT_END,
+/* 3744 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zallocate,
+/* 3752 */	VXT_END,
+/* 3753 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3761 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zattach,VXT_END,
+/* 3765 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3773 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zcompile,VXT_END,
+/* 3777 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3781 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zdeallocate,
+/* 3789 */	VXT_END,
+/* 3790 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 3798 */	1,VXI_CALLS,VXT_LIT,2,VXT_XFER,SIZEOF(char *) * (short int)xf_zedit,VXT_END,
+/* 3805 */	VXI_PUSHL,VXT_VAL,1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zg1,VXT_END,
+/* 3812 */	VXI_PUSHL,VXT_VAL,1,VXI_PUSHL,VXT_VAL,4,VXI_PUSHAB,VXT_VAL,
+/* 3820 */	3,VXI_PUSHAB,VXT_VAL,2,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zgoto,VXT_END,
+/* 3828 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zhalt,
+/* 3836 */	VXT_END,
+/* 3837 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3845 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zhelp,VXT_END,
+/* 3849 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3857 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zlink,VXT_END,
+/* 3861 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 3869 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zmess,VXT_END,
+/* 3873 */	VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zprevious,
+/* 3881 */	VXT_END,
+/* 3882 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_VAL,5,VXI_PUSHAB,VXT_VAL,
+/* 3890 */	4,VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,
+/* 3898 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_zprint,VXT_END,
+/* 3906 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,
+/* 3914 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3922 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3924 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,
+/* 3932 */	2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,3,VXT_XFER,
+/* 3940 */	SIZEOF(char *) * (short int)xf_zshow,VXT_END,
+/* 3942 */	VXI_PUSHL,VXT_LIT,0,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3950 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3957 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3965 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_zstep,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_zcont,VXT_END,
+/* 3972 */	VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_restartpc,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 3980 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_zsystem,VXT_END,
+/* 3984 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_ztcommit,
+/* 3992 */	VXT_END,
+/* 3993 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztrigger,VXT_END,
+/* 3999 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_ztstart,VXT_END,
+/* 4005 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_zwritesvn,
+/* 4013 */	VXT_END,
+/* 4014 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4022 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzwrite,VXT_END,
+/* 4026 */	VXI_CALLS,VXT_LIT,0,VXT_XFER,SIZEOF(char *) * (short int)xf_igetdst,VXI_MOVL,VXT_REG,0x50,
+/* 4034 */	VXT_ADDR,0,VXT_END,
+/* 4037 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4045 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget1,VXT_END,
+/* 4049 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnpop,
+/* 4057 */	VXT_END,
+/* 4058 */	VXI_PUSHL,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_glvnslot,
+/* 4066 */	VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,VXT_END,
+/* 4072 */	VXI_PUSHL,VXT_VAL,3,VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,
+/* 4080 */	1,VXI_JSB,VXT_XFER,SIZEOF(char *) * (short int)xf_indsavglvn,VXT_END,
+/* 4085 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_JSB,VXT_XFER,
+/* 4093 */	SIZEOF(char *) * (short int)xf_indsavlvn,VXT_END,
+/* 4095 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4103 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshlvn,VXI_MOVL,VXT_REG,0x50,VXT_ADDR,0,
+/* 4111 */	VXT_END,
+/* 4112 */	VXT_IREPAB,VXT_VAL,3,VXI_PUSHL,VXT_VAL,2,VXI_CALLS,VXT_VAL,
+/* 4120 */	1,VXT_XFER,SIZEOF(char *) * (short int)xf_savgvn,VXT_END,
+/* 4124 */	VXT_IREPAB,VXT_VAL,2,VXI_CALLS,VXT_VAL,1,VXT_XFER,SIZEOF(char *) * (short int)xf_savlvn,
+/* 4132 */	VXT_END,
+/* 4133 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4141 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_shareslot,VXT_END,
+/* 4145 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4153 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_stoglvn,VXT_END,
+/* 4157 */	VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,
+/* 4165 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_rfrshgvn,VXT_END,
+/* 4169 */	VXI_PUSHAB,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,
+/* 4177 */	0,VXI_CALLS,VXT_LIT,3,VXT_XFER,SIZEOF(char *) * (short int)xf_indfnname2,VXT_END,
+/* 4184 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 4192 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_indget2,VXT_END,
+/* 4196 */	VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_indmerge2,
+/* 4204 */	VXT_END,
+/* 4205 */	VXI_PUSHAB,VXT_VAL,1,VXI_PUSHAB,VXT_VAL,0,VXI_CALLS,VXT_LIT,
+/* 4213 */	2,VXT_XFER,SIZEOF(char *) * (short int)xf_litc,VXT_END,
+/* 4217 */	VXI_MOVC3,VXT_LIT,16,VXT_VAL,2,VXT_VAL,1,VXI_PUSHAB,
+/* 4225 */	VXT_VAL,1,VXI_CALLS,VXT_LIT,1,VXT_XFER,SIZEOF(char *) * (short int)xf_stolitc,VXT_END,
+/* 4233 */	VXI_PUSHAB,VXT_VAL,0,VXI_PUSHAB,VXT_VAL,4,VXI_PUSHL,VXT_VAL,
+/* 4241 */	3,VXI_PUSHL,VXT_VAL,2,VXI_PUSHAB,VXT_VAL,1,VXI_CALLS,
+/* 4249 */	VXT_LIT,5,VXT_XFER,SIZEOF(char *) * (short int)xf_fnzpeek,VXT_END,
+/* 4254 */	361,381,371,2593,2601,2597,2860,2872,
+/* 4262 */	2866,0,0,0,500,476,467,0,
+/* 4270 */	0,463,2092,2130,2111,2741,2756,2747,
+/* 4278 */	2717,2732,2723,2609,2620,2613,2699,2710,
+/* 4286 */	2703,2645,2656,2649,2663,2674,2667,2681,
+/* 4294 */	2692,2685,2627,2638,2631,2062,2082,2072,
+/* 4302 */	391,411,401};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/fis-gtm.git



More information about the debian-med-commit mailing list