From f36d6db42bde718b1f8e08acd175d55cffd77e56 Mon Sep 17 00:00:00 2001
From: nkindlon <nek3d@virginia.edu>
Date: Mon, 7 Apr 2014 22:32:49 -0400
Subject: [PATCH] Merge converted to PFM, first check-in

---
 Makefile                                      |   2 +-
 src/intersectFile/intersectFile.cpp           |   2 +-
 src/mergeBed/Makefile                         |  35 --
 src/mergeBed/mergeBed.cpp                     | 359 ------------------
 src/mergeBed/mergeBed.h                       |  72 ----
 src/mergeFile/Makefile                        |  46 +++
 src/mergeFile/mergeFile.cpp                   |  39 ++
 src/mergeFile/mergeFile.h                     |  37 ++
 src/{mergeBed => mergeFile}/mergeMain.cpp     | 118 +-----
 src/nekSandbox1/nekSandboxMain.cpp            |   6 +-
 src/sampleFile/SampleFile.cpp                 |   2 +-
 src/utils/BinTree/BinTree.cpp                 |   2 +-
 src/utils/Contexts/ContextBase.cpp            |  30 +-
 src/utils/Contexts/ContextBase.h              |  47 ++-
 src/utils/Contexts/ContextMap.cpp             |  10 -
 src/utils/Contexts/ContextMap.h               |   4 -
 src/utils/Contexts/ContextMerge.cpp           | 164 ++++++++
 src/utils/Contexts/ContextMerge.h             |  31 ++
 src/utils/Contexts/Makefile                   |   8 +-
 .../FileRecordTools/FileRecordMergeMgr.cpp    | 204 ++++++++++
 .../FileRecordTools/FileRecordMergeMgr.h      |  55 +++
 src/utils/FileRecordTools/FileRecordMgr.cpp   | 185 +--------
 src/utils/FileRecordTools/FileRecordMgr.h     |  77 +---
 src/utils/FileRecordTools/Makefile            |  10 +-
 src/utils/FileRecordTools/Records/Makefile    |   6 +-
 src/utils/FileRecordTools/Records/Record.h    |   5 +-
 .../FileRecordTools/Records/StrandQueue.cpp   | 131 +++++++
 .../FileRecordTools/Records/StrandQueue.h     |  47 +++
 .../FileRecordTools/Records/recordsTar.tar.gz | Bin 54443 -> 0 bytes
 src/utils/KeyListOps/KeyListOps.h             |  14 +
 src/utils/NewChromsweep/NewChromsweep.cpp     |   4 +-
 src/utils/RecordOutputMgr/RecordOutputMgr.cpp |  22 +-
 src/utils/RecordOutputMgr/RecordOutputMgr.h   |   1 +
 src/utils/general/DualQueue.h                 | 124 ------
 src/utils/general/ParseTools.cpp              |   3 +
 src/utils/general/ParseTools.h                |   2 +-
 test/merge/test-merge.sh                      |  48 +--
 37 files changed, 930 insertions(+), 1022 deletions(-)
 delete mode 100644 src/mergeBed/Makefile
 delete mode 100644 src/mergeBed/mergeBed.cpp
 delete mode 100644 src/mergeBed/mergeBed.h
 create mode 100644 src/mergeFile/Makefile
 create mode 100644 src/mergeFile/mergeFile.cpp
 create mode 100644 src/mergeFile/mergeFile.h
 rename src/{mergeBed => mergeFile}/mergeMain.cpp (52%)
 create mode 100644 src/utils/Contexts/ContextMerge.cpp
 create mode 100644 src/utils/Contexts/ContextMerge.h
 create mode 100644 src/utils/FileRecordTools/FileRecordMergeMgr.cpp
 create mode 100644 src/utils/FileRecordTools/FileRecordMergeMgr.h
 create mode 100644 src/utils/FileRecordTools/Records/StrandQueue.cpp
 create mode 100644 src/utils/FileRecordTools/Records/StrandQueue.h
 delete mode 100644 src/utils/FileRecordTools/Records/recordsTar.tar.gz
 delete mode 100644 src/utils/general/DualQueue.h

diff --git a/Makefile b/Makefile
index 26767488..8a7911fa 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ SUBDIRS = $(SRC_DIR)/annotateBed \
 		  $(SRC_DIR)/linksBed \
 		  $(SRC_DIR)/maskFastaFromBed \
 		  $(SRC_DIR)/mapFile \
-		  $(SRC_DIR)/mergeBed \
+		  $(SRC_DIR)/mergeFile \
 		  $(SRC_DIR)/multiBamCov \
 		  $(SRC_DIR)/multiIntersectBed \
 		   $(SRC_DIR)/nekSandbox1 \
diff --git a/src/intersectFile/intersectFile.cpp b/src/intersectFile/intersectFile.cpp
index 928d1d9a..e61f4d23 100644
--- a/src/intersectFile/intersectFile.cpp
+++ b/src/intersectFile/intersectFile.cpp
@@ -81,7 +81,7 @@ bool FileIntersect::processUnsortedFiles()
 
 
 	while (!queryFRM->eof()) {
-		Record *queryRecord = queryFRM->allocateAndGetNextRecord();
+		Record *queryRecord = queryFRM->getNextRecord();
 		if (queryRecord == NULL) {
 			continue;
 		}
diff --git a/src/mergeBed/Makefile b/src/mergeBed/Makefile
deleted file mode 100644
index 0eaaa645..00000000
--- a/src/mergeBed/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-UTILITIES_DIR = ../utils/
-OBJ_DIR = ../../obj/
-BIN_DIR = ../../bin/
-
-# -------------------
-# define our includes
-# -------------------
-INCLUDES = -I$(UTILITIES_DIR)/bedFile/ \
-           -I$(UTILITIES_DIR)/lineFileUtilities/ \
-           -I$(UTILITIES_DIR)/gzstream/ \
-           -I$(UTILITIES_DIR)/fileType/ \
-           -I$(UTILITIES_DIR)/VectorOps/ \
-           -I$(UTILITIES_DIR)/version/
-
-# ----------------------------------
-# define our source and object files
-# ----------------------------------
-SOURCES= mergeMain.cpp mergeBed.cpp mergeBed.h
-OBJECTS= mergeMain.o mergeBed.o
-BUILT_OBJECTS= $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS))
-
-
-all: $(BUILT_OBJECTS)
-
-.PHONY: all
-
-$(BUILT_OBJECTS): $(SOURCES)
-	@echo "  * compiling" $(*F).cpp
-	@$(CXX) -c -o $@ $(*F).cpp $(LDFLAGS) $(CXXFLAGS) $(INCLUDES)
-
-clean:
-	@echo "Cleaning up."
-	@rm -f $(OBJ_DIR)/mergeMain.o $(OBJ_DIR)/mergeBed.o
-
-.PHONY: clean
\ No newline at end of file
diff --git a/src/mergeBed/mergeBed.cpp b/src/mergeBed/mergeBed.cpp
deleted file mode 100644
index dae9887b..00000000
--- a/src/mergeBed/mergeBed.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/*****************************************************************************
-  mergeBed.cpp
-
-  (c) 2009 - Aaron Quinlan
-  Hall Laboratory
-  Department of Biochemistry and Molecular Genetics
-  University of Virginia
-  aaronquinlan@gmail.com
-
-  Licenced under the GNU General Public License 2.0 license.
-******************************************************************************/
-#include "lineFileUtilities.h"
-#include "mergeBed.h"
-
-
-
-void BedMerge::ReportMergedNames(const vector<string> &names) {
-    if (names.size() > 0) {
-        printf("\t");
-        vector<string>::const_iterator nameItr = names.begin();
-        vector<string>::const_iterator nameEnd = names.end();
-        for (; nameItr != nameEnd; ++nameItr) {
-            if (nameItr < (nameEnd - 1))
-                cout << *nameItr << _delimiter;
-            else
-                cout << *nameItr;
-        }
-    }
-    else {
-        cerr << endl 
-             << "*****" << endl 
-             << "*****ERROR: "
-             << "No names found to report for the -names option. Exiting." 
-             << endl 
-             << "*****" << endl;
-        exit(1);
-    }
-}
-
-
-void BedMerge::ReportMergedScores(const vector<string> &scores) {
-    
-    // setup a VectorOps instances for the list of scores.
-    // VectorOps methods used for each possible operation.
-    VectorOps vo(scores);
-    std::stringstream buffer;
-    if (scores.size() > 0) {
-        if (_scoreOp == "sum")
-            buffer << setprecision (PRECISION) << vo.GetSum();
-        else if (_scoreOp == "min")
-            buffer << setprecision (PRECISION) << vo.GetMin();
-        else if (_scoreOp == "max")
-            buffer << setprecision (PRECISION) << vo.GetMax();
-        else if (_scoreOp == "mean")
-            buffer << setprecision (PRECISION) << vo.GetMean();
-        else if (_scoreOp == "median")
-            buffer << setprecision (PRECISION) << vo.GetMedian();
-        else if (_scoreOp == "mode")
-            buffer << setprecision (PRECISION) << vo.GetMode();
-        else if (_scoreOp == "antimode")
-            buffer << setprecision (PRECISION) << vo.GetAntiMode();
-        else if (_scoreOp == "collapse")
-            buffer << setprecision (PRECISION) << vo.GetCollapse(_delimiter);
-        cout << "\t" << buffer.str();
-    }
-    else {        
-        cerr << endl 
-             << "*****" << endl 
-             << "*****ERROR: No scores found to report for the -scores option. Exiting." << endl 
-             << "*****" << endl;
-        exit(1);
-    }
-}
-
-// ===============
-// = Constructor =
-// ===============
-BedMerge::BedMerge(string &bedFile, 
-                   bool numEntries, 
-                   int  maxDistance, 
-                   bool forceStrand, 
-                   bool reportNames, 
-                   bool reportScores,
-                   const string &scoreOp,
-                   const string &delimiter) :
-    _bedFile(bedFile),
-    _numEntries(numEntries),
-    _forceStrand(forceStrand),
-    _reportNames(reportNames),
-    _reportScores(reportScores),
-    _scoreOp(scoreOp),
-    _maxDistance(maxDistance),
-    _delimiter(delimiter)
-{
-    _bed = new BedFile(bedFile);
-
-    if (_forceStrand == false)
-        MergeBed();
-    else
-        MergeBedStranded();
-}
-
-
-// =================
-// =   Destructor  =
-// =================
-BedMerge::~BedMerge(void) {
-}
-
-
-// ===============================================
-// Convenience method for reporting merged blocks
-// ================================================
-void BedMerge::Report(string chrom, int start, 
-                      int end, const vector<string> &names, 
-                      const vector<string> &scores, int mergeCount) 
-{
-    // ARQ: removed to force all output to be zero-based, BED format, reagrdless of input type
-    //if (_bed->isZeroBased == false) {start++;}
-    
-    printf("%s\t%d\t%d", chrom.c_str(), start, end);
-    // just the merged intervals
-    if (_numEntries == false && _reportNames == false && 
-        _reportScores == false) {
-        printf("\n");
-    }
-    // merged intervals and counts    
-    else if (_numEntries == true && _reportNames == false && 
-        _reportScores == false) {
-        printf("\t%d\n", mergeCount);
-    }
-    // merged intervals, counts, and scores
-    else if (_numEntries == true && _reportNames == false && 
-        _reportScores == true) {
-        printf("\t%d", mergeCount);
-        ReportMergedScores(scores);
-        printf("\n");
-    }
-    // merged intervals, counts, and names
-    else if (_numEntries == true && _reportNames == true && 
-        _reportScores == false) {
-        ReportMergedNames(names);
-        printf("\t%d\n", mergeCount);
-    }
-    // merged intervals, counts, names, and scores
-    else if (_numEntries == true && _reportNames == true && 
-        _reportScores == true) {
-        ReportMergedNames(names);
-        ReportMergedScores(scores);
-        printf("\t%d\n", mergeCount);
-    }
-    // merged intervals and names        
-    else if (_numEntries == false && _reportNames == true && 
-        _reportScores == false) {
-        ReportMergedNames(names);
-        printf("\n");
-    }
-    // merged intervals and scores        
-    else if (_numEntries == false && _reportNames == false && 
-        _reportScores == true) {
-        ReportMergedScores(scores);
-        printf("\n");
-    }
-    // merged intervals, names, and scores        
-    else if (_numEntries == false && _reportNames == true && 
-        _reportScores == true) {
-        ReportMergedNames(names);
-        ReportMergedScores(scores);
-        printf("\n");
-    }
-}
-
-
-// =========================================================
-// Convenience method for reporting merged blocks by strand
-// =========================================================
-void BedMerge::ReportStranded(string chrom, int start, 
-                              int end, const vector<string> &names, 
-                              const vector<string> &scores, int mergeCount,
-                              string strand) 
-{
-    // ARQ: removed to force all output to be zero-based, BED format, reagrdless of input type
-    //if (_bed->isZeroBased == false) {start++;}
-    
-    printf("%s\t%d\t%d", chrom.c_str(), start, end);
-    // just the merged intervals
-    if (_numEntries == false && _reportNames == false && 
-        _reportScores == false) {
-        printf("\t\t\t%s\n", strand.c_str());
-    }
-    // merged intervals and counts    
-    else if (_numEntries == true && _reportNames == false &&
-        _reportScores == false) {
-        printf("\t\t%d\t%s\n", mergeCount, strand.c_str());
-    }
-    // merged intervals, counts, and scores
-    else if (_numEntries == true && _reportNames == false &&
-        _reportScores == true) {
-        printf("\t%d", mergeCount);
-        ReportMergedScores(scores);
-        printf("\t%s\n", strand.c_str());
-    }
-    // merged intervals, counts, and names
-    else if (_numEntries == true && _reportNames == true &&
-        _reportScores == false) {
-        ReportMergedNames(names);
-        printf("\t%d\t%s", mergeCount, strand.c_str());
-        printf("\n");
-    }
-    // merged intervals, counts, names, and scores
-    else if (_numEntries == true && _reportNames == true &&
-        _reportScores == true) {
-        ReportMergedNames(names);
-        ReportMergedScores(scores);
-        printf("\t%s\t%d", strand.c_str(), mergeCount);
-        printf("\n");
-    }
-    // merged intervals and names        
-    else if (_numEntries == false && _reportNames == true &&
-        _reportScores == false) {
-        ReportMergedNames(names);
-        printf("\t.\t%s\n", strand.c_str());
-    }
-    // merged intervals and scores        
-    else if (_numEntries == false && _reportNames == false && 
-        _reportScores == true) {
-        printf("\t");
-        ReportMergedScores(scores);
-        printf("\t%s\n", strand.c_str());
-    }
-    // merged intervals, names, and scores        
-    else if (_numEntries == false && _reportNames == true && 
-        _reportScores == true) {
-        ReportMergedNames(names);
-        ReportMergedScores(scores);
-        printf("\t%s\n", strand.c_str());
-    }
-}
-
-
-// =====================================================
-// = Merge overlapping BED entries into a single entry =
-// =====================================================
-void BedMerge::MergeBed() {
-    int mergeCount = 1;
-    vector<string> names;
-    vector<string> scores;
-    int start = -1;
-    int end   = -1;
-    BED prev, curr;
-    
-    _bed->Open();
-    while (_bed->GetNextBed(curr, true)) { // true = force sorted intervals
-        if (_bed->_status != BED_VALID)
-            continue;            
-        // new block, no overlap
-        if ( (((int) curr.start - end) > _maxDistance) || 
-            (curr.chrom != prev.chrom)) 
-        {
-            if (start >= 0) {
-                Report(prev.chrom, start, end, names, scores, mergeCount);
-                // reset
-                mergeCount = 1;
-                names.clear();
-                scores.clear();
-            }
-            start = curr.start;
-            end   = curr.end;
-            if (!curr.name.empty())
-                names.push_back(curr.name);
-            if (!curr.score.empty())
-            scores.push_back(curr.score);
-        }
-        // same block, overlaps
-        else {
-            if ((int) curr.end > end) 
-                end = curr.end;
-            if (!curr.name.empty())
-                names.push_back(curr.name);
-            if (!curr.score.empty())
-                scores.push_back(curr.score);
-            mergeCount++;
-        }
-        prev = curr;
-    }
-    if (start >= 0) {
-        Report(prev.chrom, start, end, names, scores, mergeCount);
-    }
-}
-
-
-// ===============================================================================
-// = Merge overlapping BED entries into a single entry, accounting for strandedness =
-// ================================================================================
-void BedMerge::MergeBedStranded() {
-
-    // load the "B" bed file into a map so
-    // that we can easily compare "A" to it for overlaps
-    _bed->loadBedFileIntoMapNoBin();
-
-    // loop through each chromosome and merge their BED entries
-    masterBedMapNoBin::const_iterator m    = _bed->bedMapNoBin.begin();
-    masterBedMapNoBin::const_iterator mEnd = _bed->bedMapNoBin.end();
-    for (; m != mEnd; ++m) {
-        
-        // bedList is already sorted by start position.
-        string chrom        = m->first;
-
-        // make a list of the two strands to merge separately.
-        vector<string> strands(2);
-        strands[0] = "+";
-        strands[1] = "-";
-        // do two passes, one for each strand.
-        for (unsigned int s = 0; s < strands.size(); s++) {
-            int mergeCount = 1;
-            int numOnStrand = 0;
-            vector<string> names;
-            vector<string> scores;
-
-            // merge overlapping features for this chromosome.
-            int start = -1;
-            int end   = -1;
-            vector<BED>::const_iterator bedItr = m->second.begin();
-            vector<BED>::const_iterator bedEnd = m->second.end();
-            for (; bedItr != bedEnd; ++bedItr) {
-                // if forcing strandedness, move on if the hit
-                // is not on the current strand.
-                if (bedItr->strand != strands[s]) { continue; }
-                else { numOnStrand++; }
-                if ( (((int) bedItr->start - end) > _maxDistance) || 
-                    (end < 0)) 
-                {
-                    if (start >= 0) {
-                        ReportStranded(chrom, start, end, names, 
-                                       scores, mergeCount, strands[s]);
-                        // reset
-                        mergeCount = 1;
-                        names.clear();
-                        scores.clear();
-                    }
-                    start = bedItr->start;
-                    end   = bedItr->end;
-                    if (!bedItr->name.empty())  names.push_back(bedItr->name);
-                    if (!bedItr->score.empty()) scores.push_back(bedItr->score);
-                }
-                else {
-                    if ((int) bedItr-> end > end) end = bedItr->end;
-                    mergeCount++;
-                    if (!bedItr->name.empty())  names.push_back(bedItr->name);
-                    if (!bedItr->score.empty()) scores.push_back(bedItr->score);
-                }
-            }
-            if (start >= 0) {
-                ReportStranded(chrom, start, end, names, 
-                               scores, mergeCount, strands[s]);
-            }
-        }
-    }
-}
diff --git a/src/mergeBed/mergeBed.h b/src/mergeBed/mergeBed.h
deleted file mode 100644
index d9b0c143..00000000
--- a/src/mergeBed/mergeBed.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************
-  mergeBed.h
-
-  (c) 2009 - Aaron Quinlan
-  Hall Laboratory
-  Department of Biochemistry and Molecular Genetics
-  University of Virginia
-  aaronquinlan@gmail.com
-
-  Licenced under the GNU General Public License 2.0 license.
-******************************************************************************/
-#include "bedFile.h"
-#include <vector>
-#include <algorithm>
-#include <numeric>
-#include <iostream>
-#include <iomanip>
-#include <fstream>
-#include <limits.h>
-#include <stdlib.h>
-#include "VectorOps.h"
-
-using namespace std;
-
-const int PRECISION = 21;
-
-//************************************************
-// Class methods and elements
-//************************************************
-class BedMerge {
-
-public:
-
-  // constructor
-  BedMerge(string &bedFile, bool numEntries, 
-           int maxDistance, bool forceStrand, 
-           bool reportNames, bool reportScores, 
-           const string &scoreOp, const string &delimiter);
-
-  // destructor
-  ~BedMerge(void);
-
-  void MergeBed();
-  void MergeBedStranded();
-
-private:
-
-    string _bedFile;
-    bool   _numEntries;
-    bool   _forceStrand;
-    bool   _reportNames;
-    bool   _reportScores;
-    string _scoreOp;
-    int    _maxDistance;
-    string _delimiter;
-    // instance of a bed file class.
-    BedFile *_bed;
-
-    void Report(string chrom, int start, int end, 
-                const vector<string> &names, 
-                const vector<string> &scores, 
-                int mergeCount);
-
-    void ReportStranded(string chrom, int start, int end, 
-                        const vector<string> &names, 
-                        const vector<string> &scores, 
-                        int mergeCount, 
-                        string strand);
-    void ReportMergedNames(const vector<string> &names);
-    void ReportMergedScores(const vector<string> &scores);
-    
-};
diff --git a/src/mergeFile/Makefile b/src/mergeFile/Makefile
new file mode 100644
index 00000000..50f40042
--- /dev/null
+++ b/src/mergeFile/Makefile
@@ -0,0 +1,46 @@
+UTILITIES_DIR = ../utils/
+OBJ_DIR = ../../obj/
+BIN_DIR = ../../bin/
+
+# -------------------
+# define our includes
+# -------------------
+INCLUDES = -I$(UTILITIES_DIR)/Contexts/ \
+			-I$(UTILITIES_DIR)/general/ \
+			-I$(UTILITIES_DIR)/fileType/ \
+			-I$(UTILITIES_DIR)/gzstream/ \
+           -I$(UTILITIES_DIR)/GenomeFile/ \
+           -I$(UTILITIES_DIR)/BamTools/include \
+           -I$(UTILITIES_DIR)/BamTools/src \
+           -I$(UTILITIES_DIR)/BlockedIntervals \
+           -I$(UTILITIES_DIR)/BamTools-Ancillary \
+           -I$(UTILITIES_DIR)/FileRecordTools/ \
+           -I$(UTILITIES_DIR)/FileRecordTools/FileReaders/ \
+           -I$(UTILITIES_DIR)/FileRecordTools/Records/ \
+			-I$(UTILITIES_DIR)/KeyListOps/ \
+           -I$(UTILITIES_DIR)/RecordOutputMgr/ \
+           -I$(UTILITIES_DIR)/NewChromsweep \
+           -I$(UTILITIES_DIR)/BinTree \
+           -I$(UTILITIES_DIR)/version/
+
+# ----------------------------------
+# define our source and object files
+# ----------------------------------
+SOURCES= mergeMain.cpp mergeFile.cpp mergeFile.h
+OBJECTS= mergeMain.o mergeFile.o
+BUILT_OBJECTS= $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS))
+
+
+all: $(BUILT_OBJECTS)
+
+.PHONY: all
+
+$(BUILT_OBJECTS): $(SOURCES)
+	@echo "  * compiling" $(*F).cpp
+	@$(CXX) -c -o $@ $(*F).cpp $(LDFLAGS) $(CXXFLAGS) $(INCLUDES)
+
+clean:
+	@echo "Cleaning up."
+	@rm -f $(OBJ_DIR)/mergeMain.o $(OBJ_DIR)/mergeFile.o
+
+.PHONY: clean
\ No newline at end of file
diff --git a/src/mergeFile/mergeFile.cpp b/src/mergeFile/mergeFile.cpp
new file mode 100644
index 00000000..f772629c
--- /dev/null
+++ b/src/mergeFile/mergeFile.cpp
@@ -0,0 +1,39 @@
+/*****************************************************************************
+  mergeFile.cpp
+
+  (c) 2009 - Aaron Quinlan
+  Hall Laboratory
+  Department of Biochemistry and Molecular Genetics
+  University of Virginia
+  aaronquinlan@gmail.com
+
+  Licenced under the GNU General Public License 2.0 license.
+******************************************************************************/
+#include "mergeFile.h"
+
+
+MergeFile::MergeFile(ContextMerge *context)
+: _context(context),
+  _recordOutputMgr(NULL)
+{
+	_recordOutputMgr = new RecordOutputMgr();
+	_recordOutputMgr->init(_context);
+}
+
+MergeFile::~MergeFile()
+{
+	delete _recordOutputMgr;
+	_recordOutputMgr = NULL;
+}
+
+bool MergeFile::merge()
+{
+    RecordKeyList hitSet;
+    FileRecordMgr *frm = _context->getFile(0);
+    while (!frm->eof()) {
+    	Record *key = frm->getNextRecord(&hitSet);
+    	if (key == NULL) continue;
+		_recordOutputMgr->printRecord(hitSet.getKey(), _context->getColumnOpsVal(hitSet));
+    }
+    return true;
+}
diff --git a/src/mergeFile/mergeFile.h b/src/mergeFile/mergeFile.h
new file mode 100644
index 00000000..0d876c67
--- /dev/null
+++ b/src/mergeFile/mergeFile.h
@@ -0,0 +1,37 @@
+/*****************************************************************************
+  mergeFile.h
+
+  (c) 2009 - Aaron Quinlan
+  Hall Laboratory
+  Department of Biochemistry and Molecular Genetics
+  University of Virginia
+  aaronquinlan@gmail.com
+
+  Licenced under the GNU General Public License 2.0 license.
+******************************************************************************/
+
+#ifndef MERGE_FILE_H_
+#define MERGE_FILE_H_
+
+//************************************************
+// Class methods and elements
+//************************************************
+
+#include "ContextMerge.h"
+#include "RecordOutputMgr.h"
+
+class MergeFile {
+
+public:
+  MergeFile(ContextMerge *context);
+  ~MergeFile();
+
+  bool merge();
+
+private:
+  ContextMerge *_context;
+  RecordOutputMgr *_recordOutputMgr;
+    
+};
+
+#endif
diff --git a/src/mergeBed/mergeMain.cpp b/src/mergeFile/mergeMain.cpp
similarity index 52%
rename from src/mergeBed/mergeMain.cpp
rename to src/mergeFile/mergeMain.cpp
index 28b869af..3f443e27 100644
--- a/src/mergeBed/mergeMain.cpp
+++ b/src/mergeFile/mergeMain.cpp
@@ -9,7 +9,7 @@
 
   Licenced under the GNU General Public License 2.0 license.
 ******************************************************************************/
-#include "mergeBed.h"
+#include "mergeFile.h"
 #include "version.h"
 
 using namespace std;
@@ -26,113 +26,21 @@ void merge_help(void);
 
 int merge_main(int argc, char* argv[]) {
 
-    // our configuration variables
-    bool showHelp = false;
-
-    // input files
-    string bedFile  = "stdin";
-    int maxDistance = 0;
-    string scoreOp  = "";
-
-    // input arguments
-    bool haveBed         = true;
-    bool numEntries      = false;
-    bool haveMaxDistance = false;
-    bool forceStrand     = false;
-    bool reportNames     = false;
-    bool reportScores    = false;
-    string delimiter     = ",";
-
-    for(int i = 1; i < argc; i++) {
-        int parameterLength = (int)strlen(argv[i]);
-
-        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
-        (PARAMETER_CHECK("--help", 5, parameterLength))) {
-            showHelp = true;
+    ContextMerge *context = new ContextMerge();
+    if (!context->parseCmdArgs(argc, argv, 1) || context->getShowHelp() || !context->isValidState()) {
+        if (!context->getErrorMsg().empty()) {
+            cerr << context->getErrorMsg() << endl;
         }
-    }
-
-    if(showHelp) merge_help();
-
-    // do some parsing (all of these parameters require 2 strings)
-    for(int i = 1; i < argc; i++) {
-
-        int parameterLength = (int)strlen(argv[i]);
-
-        if(PARAMETER_CHECK("-i", 2, parameterLength)) {
-            if ((i+1) < argc) {
-                bedFile = argv[i + 1];
-                i++;
-            }
-        }
-        else if(PARAMETER_CHECK("-n", 2, parameterLength)) {
-            numEntries = true;
-        }
-        else if(PARAMETER_CHECK("-d", 2, parameterLength)) {
-            if ((i+1) < argc) {
-                haveMaxDistance = true;
-                maxDistance = atoi(argv[i + 1]);
-                i++;
-            }
-        }
-        else if (PARAMETER_CHECK("-s", 2, parameterLength)) {
-            forceStrand = true;
-        }
-        else if (PARAMETER_CHECK("-nms", 4, parameterLength)) {
-            reportNames = true;
-        }
-        else if (PARAMETER_CHECK("-scores", 7, parameterLength)) {
-            reportScores = true;
-            if ((i+1) < argc) {
-                scoreOp      = argv[i + 1];
-                i++;
-            }
-        }
-        else if (PARAMETER_CHECK("-delim", 6, parameterLength)) {
-            if ((i+1) < argc) {
-                delimiter      = argv[i + 1];
-                i++;
-            }
-        }
-        else {
-            cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
-            showHelp = true;
-        }
-    }
-
-    // make sure we have both input files
-    if (!haveBed) {
-        cerr << endl << "*****" << endl << "*****ERROR: Need -i BED file. " << endl << "*****" << endl;
-        showHelp = true;
-    }
-    if ((reportScores == true) && (scoreOp != "sum")  
-         && (scoreOp != "max")  && (scoreOp != "min") 
-         && (scoreOp != "mean") && (scoreOp != "mode") 
-         && (scoreOp != "median") && (scoreOp != "antimode") 
-         && (scoreOp != "collapse")) 
-    {
-        cerr << endl 
-             << "*****" 
-             << endl 
-             << "*****ERROR: Invalid scoreOp selection \"" 
-             << scoreOp 
-             << endl 
-             << "\"  *****" 
-             << endl;
-        showHelp = true;
-    }
-
-    if (!showHelp) {
-        BedMerge *bm = new BedMerge(bedFile, numEntries, 
-                                    maxDistance, forceStrand, 
-                                    reportNames, reportScores, 
-                                    scoreOp, delimiter);
-        delete bm;
-    }
-    else {
         merge_help();
+        delete context;
+        return 0;
     }
-    return 0;
+    MergeFile *mergeFile = new MergeFile(context);
+
+    bool retVal = mergeFile->merge();
+    delete mergeFile;
+    delete context;
+    return retVal ? 0 : 1;
 }
 
 void merge_help(void) {
diff --git a/src/nekSandbox1/nekSandboxMain.cpp b/src/nekSandbox1/nekSandboxMain.cpp
index ac3fb319..6e895b2e 100644
--- a/src/nekSandbox1/nekSandboxMain.cpp
+++ b/src/nekSandbox1/nekSandboxMain.cpp
@@ -6,7 +6,7 @@ using namespace std;
 #include <cstdio>
 #include "RecordKeyList.h"
 #include "NewChromsweep.h"
-#include "DualQueue.h"
+//#include "DualQueue.h"
 #include "ParseTools.h"
 #include <sstream>
 #include <iomanip>
@@ -145,7 +145,7 @@ int nek_sandbox1_main(int argc,char** argv)
 //	bool headerFound = false;
 //	QuickString outbuf;
 //	while (!frm.eof()) {
-//		Record *record = frm.allocateAndGetNextRecord();
+//		Record *record = frm.getNextRecord();
 //		if (!headerFound && frm.hasHeader()) {
 //			cout << frm.getHeader() << endl;
 //			headerFound = true;
@@ -287,7 +287,7 @@ void testDualQueue(Context *context) {
 
 	printf("Original record order is:\n");
 	while (!frm.eof()) {
-		Record *record = frm.allocateAndGetNextRecord();
+		Record *record = frm.getNextRecord();
 		if (record == NULL) {
 			continue;
 		}
diff --git a/src/sampleFile/SampleFile.cpp b/src/sampleFile/SampleFile.cpp
index 8291824c..096327e2 100644
--- a/src/sampleFile/SampleFile.cpp
+++ b/src/sampleFile/SampleFile.cpp
@@ -51,7 +51,7 @@ bool SampleFile::takeSample()
 
 
 	while (!_inputFile->eof()) {
-		Record *record = _inputFile->allocateAndGetNextRecord();
+		Record *record = _inputFile->getNextRecord();
 		if (record == NULL) {
 			continue;
 		}
diff --git a/src/utils/BinTree/BinTree.cpp b/src/utils/BinTree/BinTree.cpp
index 54696f69..f5cddd83 100644
--- a/src/utils/BinTree/BinTree.cpp
+++ b/src/utils/BinTree/BinTree.cpp
@@ -74,7 +74,7 @@ void BinTree::loadDB()
 
 	Record *record = NULL;
 	while (!_databaseFile->eof()) {
-		record = _databaseFile->allocateAndGetNextRecord();
+		record = _databaseFile->getNextRecord();
 		//In addition to NULL records, we also don't want to add unmapped reads.
 		if (record == NULL || record->isUnmapped()) {
 			continue;
diff --git a/src/utils/Contexts/ContextBase.cpp b/src/utils/Contexts/ContextBase.cpp
index 16d2402c..c76d29b4 100644
--- a/src/utils/Contexts/ContextBase.cpp
+++ b/src/utils/Contexts/ContextBase.cpp
@@ -13,7 +13,6 @@ ContextBase::ContextBase()
 :
   _program(UNSPECIFIED_PROGRAM),
   _allFilesOpened(false),
-  _useMergedIntervals(false),
   _genomeFile(NULL),
   _outputFileType(FileRecordTypeChecker::UNKNOWN_FILE_TYPE),
   _outputTypeDetermined(false),
@@ -45,7 +44,6 @@ ContextBase::ContextBase()
   _maxNumDatabaseFields(0),
   _useFullBamTags(false),
   _reportCount(false),
-  _maxDistance(0),
   _reportNames(false),
   _reportScores(false),
   _numOutputRecords(0),
@@ -53,11 +51,16 @@ ContextBase::ContextBase()
   _seed(0),
   _forwardOnly(false),
   _reverseOnly(false),
-  _hasColumnOpsMethods(false)
+  _hasColumnOpsMethods(false),
+  _desiredStrand(FileRecordMergeMgr::ANY_STRAND),
+  _maxDistance(0),
+  _useMergedIntervals(false)
+
 {
 	_programNames["intersect"] = INTERSECT;
 	_programNames["sample"] = SAMPLE;
 	_programNames["map"] = MAP;
+	_programNames["merge"] = MERGE;
 
 	if (hasColumnOpsMethods()) {
 		_keyListOps = new KeyListOps();
@@ -233,11 +236,12 @@ bool ContextBase::openFiles() {
 	_files.resize(_fileNames.size());
 
 	for (int i = 0; i < (int)_fileNames.size(); i++) {
-		FileRecordMgr *frm = new FileRecordMgr(_fileNames[i], _sortedInput);
+		FileRecordMgr *frm = getNewFRM(_fileNames[i]);
 		if (hasGenomeFile()) {
 			frm->setGenomeFile(_genomeFile);
 		}
 		frm->setFullBamFlags(_useFullBamTags);
+		frm->setIsSorted(_sortedInput);
 		if (!frm->open()) {
 			return false;
 		}
@@ -391,8 +395,9 @@ bool ContextBase::handle_c()
         markUsed(_i - _skipFirstArgs);
         _i++;
         markUsed(_i - _skipFirstArgs);
+        return true;
     }
-    return true;
+    return false;
 }
 
 
@@ -412,7 +417,7 @@ bool ContextBase::handle_o()
 }
 
 
-// for col ops, -null is a NULL vakue assigned
+// for col ops, -null is a NULL value assigned
 // when no overlaps are detected.
 bool ContextBase::handle_null()
 {
@@ -424,8 +429,9 @@ bool ContextBase::handle_null()
         markUsed(_i - _skipFirstArgs);
         _i++;
         markUsed(_i - _skipFirstArgs);
+        return true;
     }
-    return true;
+    return false;
 }
 
 //for col ops, delimStr will appear between each item in
@@ -459,3 +465,13 @@ const QuickString &ContextBase::getColumnOpsVal(RecordKeyList &keyList) const {
 	return _keyListOps->getOpVals(keyList);
 }
 
+FileRecordMgr *ContextBase::getNewFRM(const QuickString &filename) {
+	if (!_useMergedIntervals) {
+		return new FileRecordMgr(filename);
+	} else {
+		FileRecordMergeMgr *frm = new FileRecordMergeMgr(filename);
+		frm->setStrandType(_desiredStrand);
+		frm->setMaxDistance(_maxDistance);
+		return frm;
+	}
+}
diff --git a/src/utils/Contexts/ContextBase.h b/src/utils/Contexts/ContextBase.h
index b4bf1227..2c194a68 100644
--- a/src/utils/Contexts/ContextBase.h
+++ b/src/utils/Contexts/ContextBase.h
@@ -20,7 +20,7 @@
 #include "version.h"
 #include "BedtoolsTypes.h"
 #include "FileRecordTypeChecker.h"
-#include "FileRecordMgr.h"
+#include "FileRecordMergeMgr.h"
 #include "NewGenomeFile.h"
 #include "api/BamReader.h"
 #include "api/BamAux.h"
@@ -59,6 +59,7 @@ public:
 
 	bool getUseMergedIntervals() const { return _useMergedIntervals; }
 	void setUseMergedIntervals(bool val) { _useMergedIntervals = val; }
+	FileRecordMergeMgr::WANTED_STRAND_TYPE getDesiredStrand() const { return _desiredStrand; }
 
 	void openGenomeFile(const QuickString &genomeFilename);
 	void openGenomeFile(const BamTools::RefVector &refVector);
@@ -106,23 +107,23 @@ public:
     virtual bool getUseFullBamTags() const { return _useFullBamTags; }
     virtual void setUseFullBamTags(bool val) { _useFullBamTags = val; }
 
-	//
-	// MERGE METHODS
-	//
-    virtual bool getReportCount() const { return _reportCount; }
-    virtual void setReportCount(bool val) { _reportCount = val; }
-
-    virtual int getMaxDistance() const { return _maxDistance; }
-    virtual void setMaxDistance(int distance) { _maxDistance = distance; }
-
-    virtual bool getReportNames() const { return _reportNames; }
-    virtual void setReportNames(bool val) { _reportNames = val; }
-
-    virtual bool getReportScores() const { return _reportScores; }
-    virtual void setReportScores(bool val) { _reportScores = val; }
-
-    virtual const QuickString &getScoreOp() const { return _scoreOp; }
-    virtual void setScoreOp(const QuickString &op) { _scoreOp = op; }
+//	//
+//	// MERGE METHODS
+//	//
+//    virtual bool getReportCount() const { return _reportCount; }
+//    virtual void setReportCount(bool val) { _reportCount = val; }
+//
+//    virtual int getMaxDistance() const { return _maxDistance; }
+//    virtual void setMaxDistance(int distance) { _maxDistance = distance; }
+//
+//    virtual bool getReportNames() const { return _reportNames; }
+//    virtual void setReportNames(bool val) { _reportNames = val; }
+//
+//    virtual bool getReportScores() const { return _reportScores; }
+//    virtual void setReportScores(bool val) { _reportScores = val; }
+//
+//    virtual const QuickString &getScoreOp() const { return _scoreOp; }
+//    virtual void setScoreOp(const QuickString &op) { _scoreOp = op; }
 
 
 	// METHODS FOR PROGRAMS WITH USER_SPECIFIED NUMBER
@@ -160,7 +161,6 @@ protected:
 	bool _allFilesOpened;
 	map<QuickString, PROGRAM_TYPE> _programNames;
 
-	bool _useMergedIntervals;
 	NewGenomeFile *_genomeFile;
 
 	ContextFileType _outputFileType;
@@ -200,7 +200,6 @@ protected:
     int _maxNumDatabaseFields;
     bool _useFullBamTags;
 	bool _reportCount;
-	int _maxDistance;
 	bool _reportNames;
 	bool _reportScores;
 	QuickString _scoreOp;
@@ -212,14 +211,22 @@ protected:
 	bool _forwardOnly;
 	bool _reverseOnly;
 
+	//Members for column operations
 	bool _hasColumnOpsMethods;
 	KeyListOps *_keyListOps;
 	QuickString _nullStr; //placeholder return value when col ops aren't valid.
 
+	//Members for merged records
+	FileRecordMergeMgr::WANTED_STRAND_TYPE _desiredStrand;
+	int _maxDistance;
+	bool _useMergedIntervals;
+
+
 	void markUsed(int i) { _argsProcessed[i] = true; }
 	bool isUsed(int i) const { return _argsProcessed[i]; }
 	bool cmdArgsValid();
 	bool openFiles();
+	virtual FileRecordMgr *getNewFRM(const QuickString &filename);
 
 	//set cmd line params and counter, i, as members so code
 	//is more readable (as opposed to passing all 3 everywhere).
diff --git a/src/utils/Contexts/ContextMap.cpp b/src/utils/Contexts/ContextMap.cpp
index e3f82417..e6abc519 100644
--- a/src/utils/Contexts/ContextMap.cpp
+++ b/src/utils/Contexts/ContextMap.cpp
@@ -47,13 +47,3 @@ bool ContextMap::parseCmdArgs(int argc, char **argv, int skipFirstArgs) {
 	}
 	return ContextIntersect::parseCmdArgs(argc, argv, _skipFirstArgs);
 }
-//
-//
-//bool ContextMap::isValidState()
-//{
-//	if (!ContextIntersect::isValidState()) {
-//		return false;
-//	}
-//}
-//
-//
diff --git a/src/utils/Contexts/ContextMap.h b/src/utils/Contexts/ContextMap.h
index 9b7280e5..b5bf5959 100644
--- a/src/utils/Contexts/ContextMap.h
+++ b/src/utils/Contexts/ContextMap.h
@@ -15,12 +15,8 @@ class ContextMap : public ContextIntersect {
 public:
 	ContextMap();
 	virtual ~ContextMap();
-//	virtual bool isValidState();
-//
 	virtual bool parseCmdArgs(int argc, char **argv, int skipFirstArgs);
-//
     virtual bool hasIntersectMethods() const { return true; }
-//
 
 private:
 
diff --git a/src/utils/Contexts/ContextMerge.cpp b/src/utils/Contexts/ContextMerge.cpp
new file mode 100644
index 00000000..5d6c58aa
--- /dev/null
+++ b/src/utils/Contexts/ContextMerge.cpp
@@ -0,0 +1,164 @@
+/*
+ * ContextMerge.cpp
+ *
+ *  Created on: Mar 26, 2014
+ *      Author: nek3d
+ */
+
+
+#include "ContextMerge.h"
+
+ContextMerge::ContextMerge()
+{
+	setUseMergedIntervals(true);
+	setColumnOpsMethods(true);
+
+	//merge has no default columnOps the way map does, so we'll need to clear those.
+	_keyListOps->setColumns("");
+	_keyListOps->setOperations("");
+
+}
+
+ContextMerge::~ContextMerge()
+{
+
+}
+
+
+bool ContextMerge::parseCmdArgs(int argc, char **argv, int skipFirstArgs)
+{
+	_argc = argc;
+	_argv = argv;
+	_skipFirstArgs = skipFirstArgs;
+	if (_argc < 2) {
+		setShowHelp(true);
+		return false;
+	}
+
+	setProgram(_programNames[argv[0]]);
+
+	_argsProcessed.resize(_argc - _skipFirstArgs, false);
+
+	for (_i=_skipFirstArgs; _i < argc; _i++) {
+		if (isUsed(_i - _skipFirstArgs)) {
+			continue;
+		}
+		else if (strcmp(_argv[_i], "-n") == 0) {
+			if (!handle_n()) return false;
+		}
+		else if (strcmp(_argv[_i], "-nms") == 0) {
+			if (!handle_nms()) return false;
+		}
+		else if (strcmp(_argv[_i], "-scores") == 0) {
+			if (!handle_scores()) return false;
+		}
+		else if (strcmp(_argv[_i], "-delim") == 0) {
+			if (!handle_delim()) return false;
+		}
+		else if (strcmp(_argv[_i], "-d") == 0) {
+			if (!handle_d()) return false;
+		}
+		else if (strcmp(_argv[_i], "-s") == 0) {
+			if (!handle_s()) return false;
+		}
+		else if (strcmp(_argv[_i], "-S") == 0) {
+			if (!handle_S()) return false;
+		}
+	}
+	return ContextBase::parseCmdArgs(argc, argv, _skipFirstArgs);
+}
+
+bool ContextMerge::isValidState()
+{
+	// Special: The merge program does not have default
+	//column operations, so if none were entered, disable column ops.
+	if (_keyListOps->getColumns().empty() && _keyListOps->getOperations().empty()) {
+		setColumnOpsMethods(false);
+		delete _keyListOps;
+		_keyListOps = NULL;
+	}
+	if (!ContextBase::isValidState()) {
+		return false;
+	}
+	if (_files.size() != 1) {
+		_errorMsg = "\n***** ERROR: input file not specified. *****";
+		// Allow one and only input file for now
+		return false;
+	}
+	return true;
+}
+
+
+bool ContextMerge::handle_d() {
+    if ((_i+1) < _argc) {
+    	if (isNumeric(_argv[_i+1])) {
+			int dist = str2chrPos(_argv[_i+1]);
+			if (dist >=0 ) {
+				_maxDistance = dist;
+		    	markUsed(_i - _skipFirstArgs);
+		        _i++;
+		        markUsed(_i - _skipFirstArgs);
+				return true;
+			}
+    	}
+    }
+	_errorMsg = "\n***** ERROR: -d option must be followed by an integer value *****";
+	return false;
+}
+
+bool ContextMerge::handle_n()
+{
+	//This is the same as telling map "-c any -o count"
+	_keyListOps->addColumns("1"); //doesn't really matter which column, but the default column
+	//for keyListOps is score, which not every record necessarily has.
+	_keyListOps->addOperations("count");
+	markUsed(_i - _skipFirstArgs);
+    return true;
+}
+
+bool ContextMerge::handle_nms()
+{
+	//This is the same as telling map "-c 4 -o collapse"
+	_keyListOps->addColumns("4");
+	_keyListOps->addOperations("collapse");
+	markUsed(_i - _skipFirstArgs);
+    return true;
+}
+
+
+bool ContextMerge::handle_scores()
+{
+    if ((_i+1) < _argc) {
+    	_keyListOps->addColumns("5");
+    	_keyListOps->addOperations(_argv[_i+1]);
+    	markUsed(_i - _skipFirstArgs);
+        _i++;
+        markUsed(_i - _skipFirstArgs);
+        return true;
+    }
+	_errorMsg = "\n***** ERROR: -scores option given, but no operation specified. *****";
+
+    return false;
+}
+
+bool ContextMerge::handle_s() {
+	_desiredStrand = FileRecordMergeMgr::SAME_STRAND_EITHER;
+	markUsed(_i - _skipFirstArgs);
+	return true;
+}
+
+bool ContextMerge::handle_S() {
+    if ((_i+1) < _argc) {
+    	if (_argv[_i+1][0] == '+') {
+			_desiredStrand = FileRecordMergeMgr::SAME_STRAND_FORWARD;
+    	} else if (_argv[_i+1][0] == '-') {
+			_desiredStrand = FileRecordMergeMgr::SAME_STRAND_REVERSE;
+    	}
+    	markUsed(_i - _skipFirstArgs);
+        _i++;
+        markUsed(_i - _skipFirstArgs);
+        return true;
+    }
+	_errorMsg = "\n***** ERROR: -S option must be followed by + or -. *****";
+	return false;
+}
diff --git a/src/utils/Contexts/ContextMerge.h b/src/utils/Contexts/ContextMerge.h
new file mode 100644
index 00000000..f2690833
--- /dev/null
+++ b/src/utils/Contexts/ContextMerge.h
@@ -0,0 +1,31 @@
+/*
+ * ContextMerge.h
+ *
+ *  Created on: Mar 26, 2014
+ *      Author: nek3d
+ */
+
+#ifndef CONTEXTMERGE_H_
+#define CONTEXTMERGE_H_
+
+#include "ContextBase.h"
+#include "FileRecordMergeMgr.h"
+
+class ContextMerge: public ContextBase {
+public:
+	ContextMerge();
+	~ContextMerge();
+	virtual bool parseCmdArgs(int argc, char **argv, int skipFirstArgs);
+	virtual bool isValidState();
+
+protected:
+	bool handle_d();
+	bool handle_n();
+	bool handle_nms();
+	bool handle_scores();
+	bool handle_s();
+	bool handle_S();
+};
+
+
+#endif /* CONTEXTMERGE_H_ */
diff --git a/src/utils/Contexts/Makefile b/src/utils/Contexts/Makefile
index 4b2ed429..1856b82b 100644
--- a/src/utils/Contexts/Makefile
+++ b/src/utils/Contexts/Makefile
@@ -19,8 +19,9 @@ INCLUDES =  -I$(UTILITIES_DIR)/general/ \
 # ----------------------------------
 # define our source and object files
 # ----------------------------------
-SOURCES= ContextBase.cpp ContextBase.h ContextIntersect.cpp ContextIntersect.h ContextMap.cpp ContextMap.h ContextSample.cpp ContextSample.h
-OBJECTS= ContextBase.o ContextIntersect.o ContextMap.o ContextSample.o
+SOURCES= ContextBase.cpp ContextBase.h ContextIntersect.cpp ContextIntersect.h ContextMap.cpp \
+	ContextMap.h ContextSample.cpp ContextSample.h ContextMerge.h ContextMerge.cpp
+OBJECTS= ContextBase.o ContextIntersect.o ContextMap.o ContextSample.o ContextMerge.o
 _EXT_OBJECTS=ParseTools.o QuickString.o
 EXT_OBJECTS=$(patsubst %,$(OBJ_DIR)/%,$(_EXT_OBJECTS))
 BUILT_OBJECTS= $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS))
@@ -38,6 +39,7 @@ clean:
 	@rm -f $(OBJ_DIR)/ContextBase.o \
 	       $(OBJ_DIR)/ContextIntersect.o \
 	       $(OBJ_DIR)/ContextMap.o \
-	       $(OBJ_DIR)/ContextSample.o
+	       $(OBJ_DIR)/ContextSample.o \
+	       $(OBJ_DIR)/ContextMerge.o \
 
 .PHONY: clean
\ No newline at end of file
diff --git a/src/utils/FileRecordTools/FileRecordMergeMgr.cpp b/src/utils/FileRecordTools/FileRecordMergeMgr.cpp
new file mode 100644
index 00000000..c82206b3
--- /dev/null
+++ b/src/utils/FileRecordTools/FileRecordMergeMgr.cpp
@@ -0,0 +1,204 @@
+/*
+ * FileRecordMergeMgr.cpp
+ *
+ *  Created on: Mar 19, 2014
+ *      Author: nek3d
+ */
+
+
+#include "FileRecordMergeMgr.h"
+
+FileRecordMergeMgr::FileRecordMergeMgr(const QuickString & filename)
+: FileRecordMgr(filename),
+  _desiredStrand(ANY_STRAND),
+  _maxDistance(0)
+{
+}
+
+//Record *FileRecordMergeMgr::allocateAndGetNextMergedRecord(WANT_STRAND_TYPE desiredStrand, int maxDistance) {
+//	RecordKeyList recList;
+//	if (!allocateAndGetNextMergedRecord(recList, desiredStrand, maxDistance)) {
+//		return NULL;
+//	}
+//	deleteAllMergedItemsButKey(recList);
+//	return const_cast<Record *>(recList.getKey()); //want key to be non-const
+//}
+
+Record *FileRecordMergeMgr::getNextRecord(RecordKeyList *recList)
+{
+	if (!recList->allClear()) {
+		deleteMergedRecord(*recList);
+	}
+
+	_mustBeForward = _desiredStrand == SAME_STRAND_FORWARD;
+	_mustBeReverse = _desiredStrand == SAME_STRAND_REVERSE;
+
+	Record *startRecord = tryToTakeFromStorage();
+
+	// if we couldn't use a previously stored record for starters,
+	//then begin with a new one that matches strand criteria.
+	while (startRecord == NULL) {
+		startRecord = FileRecordMgr::getNextRecord();
+		if (startRecord == NULL) { //hit EOF!!
+			return NULL;
+		}
+
+		if ((_mustBeForward && (startRecord->getStrandVal() != Record::FORWARD)) || (_mustBeReverse && (startRecord->getStrandVal() != Record::REVERSE))) {
+			//record is reverse, only want forward, OR record is forward, wanted reverse
+			deleteRecord(startRecord);
+			startRecord = NULL;
+		}
+		if (startRecord->getStrandVal() == Record::UNKNOWN && _desiredStrand != ANY_STRAND) {
+			//there is an unknown strand, but the user specified strandedness.
+			deleteRecord(startRecord);
+			startRecord = NULL;
+		}
+	}
+
+	// OK!! We have a start record! Re-evaluate strand requirements for next recored.
+
+	_mustBeForward = _desiredStrand == SAME_STRAND_FORWARD || (_desiredStrand == SAME_STRAND_EITHER && (startRecord->getStrandVal() == Record::FORWARD));
+	_mustBeReverse = _desiredStrand == SAME_STRAND_REVERSE || (_desiredStrand == SAME_STRAND_EITHER && (startRecord->getStrandVal() == Record::REVERSE));
+	bool mustKeepOpposite = (_desiredStrand == SAME_STRAND_EITHER);
+
+	const QuickString &currChrom = startRecord->getChrName();
+	_foundChroms.insert(currChrom);
+
+	bool madeComposite = false;
+	recList->push_back(startRecord);
+	recList->setKey(startRecord); //key of recList will just be the startRecord unless we're able to merge more.
+
+	Record::strandType currStrand = startRecord->getStrandVal();
+	bool mustMatchStrand = _desiredStrand != ANY_STRAND;
+
+	int currEnd = startRecord->getEndPos();
+	//now look for more records to merge with this one.
+	//stop when they're out of range, not on the same chromosome, or we hit EOF.
+	//ignore if they don't comply with strand.
+	Record *nextRecord = NULL;
+	while (nextRecord == NULL) {
+		bool takenFromStorage = false;
+		nextRecord = mustMatchStrand ? tryToTakeFromStorage(currStrand) : tryToTakeFromStorage();
+		if (nextRecord == NULL) {
+			nextRecord = FileRecordMgr::getNextRecord();
+		} else {
+			takenFromStorage = true;
+		}
+		if (nextRecord == NULL) { // EOF hit
+			break;
+		}
+		//delete any record from file with an unknown strand if we are doing stranded merge, but first check
+		//that it's chrom was the same and it's not out of range. If either is true, stop scanning.
+		bool mustDelete = (mustMatchStrand && nextRecord->getStrandVal() == Record::UNKNOWN);
+
+		//check that we are still on the same chromosome.
+		const QuickString &newChrom = nextRecord->getChrName();
+		if (newChrom != currChrom) { //hit a different chromosome.
+			if (_foundChroms.find(newChrom) == _foundChroms.end() || takenFromStorage) {
+				//haven't seen this chromosome before, sort order is already enforced in the base class method.
+				if (!mustDelete) {
+					addToStorage(nextRecord);
+				} else {
+					deleteRecord(nextRecord);
+				}
+				nextRecord = NULL;
+				break;
+			}
+		}
+
+		//check whether it's in range
+		int nextStart = nextRecord->getStartPos();
+		if (nextStart > currEnd + _maxDistance) {
+			//no, it's out of range.
+			if (!mustDelete) {
+				addToStorage(nextRecord);
+			} else {
+				deleteRecord(nextRecord);
+			}
+			nextRecord = NULL;
+			break;
+		}
+
+		// NOW, going back, we can delete any unknown strand records. But don't stop scanning.
+		if (mustDelete) {
+			deleteRecord(nextRecord);
+			nextRecord = NULL;
+			continue;
+		}
+		//if taken from file, and wrong strand, store or delete.
+		if (!takenFromStorage && ((_mustBeForward && (nextRecord->getStrandVal() != Record::FORWARD)) || (_mustBeReverse && (nextRecord->getStrandVal() != Record::REVERSE)))) {
+			if (mustKeepOpposite) {
+				addToStorage(nextRecord);
+			} else {
+				deleteRecord(nextRecord);
+			}
+			nextRecord = NULL;
+			continue; //get the next record
+		}
+		//ok, they're on the same chrom and in range, and the strand is good. Do a merge.
+		recList->push_back(nextRecord);
+		madeComposite = true;
+		int nextEnd = nextRecord->getEndPos();
+		if (nextEnd > currEnd) {
+			currEnd = nextEnd;
+		}
+		nextRecord = NULL;
+	}
+	if (madeComposite) {
+		Record *newKey = _recordMgr->allocateRecord();
+		(*newKey) = (*startRecord);
+		newKey->setEndPos(currEnd);
+		recList->setKey(newKey);
+	}
+	_totalMergedRecordLength += (unsigned long)(recList->getKey()->getEndPos() - recList->getKey()->getStartPos());
+	return const_cast<Record *>(recList->getKey());
+}
+
+void FileRecordMergeMgr::addToStorage(Record *record) {
+	//if the strand requirements are strict, and the record doesn't match,
+	//store in the "round file".
+
+	if ((_desiredStrand == SAME_STRAND_FORWARD && record->getStrandVal() != Record::FORWARD) ||
+			(_desiredStrand == SAME_STRAND_REVERSE && record->getStrandVal() != Record::REVERSE) ||
+			(_desiredStrand != ANY_STRAND && record->getStrandVal() == Record::UNKNOWN)) {
+		deleteRecord(record);
+		return;
+	}
+	_storedRecords.push(record);
+}
+
+Record *FileRecordMergeMgr::tryToTakeFromStorage() {
+	Record *record = _storedRecords.top();
+	if (record != NULL) {
+		_storedRecords.pop();
+	}
+	return record;
+}
+
+Record *FileRecordMergeMgr::tryToTakeFromStorage(Record::strandType strand) {
+	Record *record = _storedRecords.top(strand);
+	if (record != NULL) {
+		_storedRecords.pop(strand);
+	}
+	return record;
+}
+
+void FileRecordMergeMgr::deleteMergedRecord(RecordKeyList &recList)
+{
+	deleteAllMergedItemsButKey(recList);
+	deleteRecord(recList.getKey());
+	recList.setKey(NULL);
+}
+
+void FileRecordMergeMgr::deleteAllMergedItemsButKey(RecordKeyList &recList) {
+	//if the key is also in the list, this method won't delete it.
+	for (RecordKeyList::const_iterator_type iter = recList.begin(); iter != recList.end(); iter = recList.next()) {
+		if (iter->value() == recList.getKey()) {
+			continue;
+		}
+		deleteRecord(iter->value());
+	}
+	recList.clearList();
+}
+
+
diff --git a/src/utils/FileRecordTools/FileRecordMergeMgr.h b/src/utils/FileRecordTools/FileRecordMergeMgr.h
new file mode 100644
index 00000000..5bbfb529
--- /dev/null
+++ b/src/utils/FileRecordTools/FileRecordMergeMgr.h
@@ -0,0 +1,55 @@
+/*
+ * FileRecordMergeMgr.h
+ *
+ *  Created on: Mar 19, 2014
+ *      Author: nek3d
+ */
+
+#ifndef FILERECORDMERGEMGR_H_
+#define FILERECORDMERGEMGR_H_
+
+#include "FileRecordMgr.h"
+#include "StrandQueue.h"
+
+class FileRecordMergeMgr : public FileRecordMgr {
+
+public:
+	FileRecordMergeMgr(const QuickString & filename);
+
+	//////////////////////////////////////////////////////////////////////////////////
+	//
+	// 			MERGED RECORDS
+	//
+	// This will give a single "meta" record containing "flattened" or merged records.
+	//
+	// Pass an empty RecordKeyList. When done, will have a pair: 1st is the final merged record,
+	//			second is list of constituent Records merged.
+	//
+	///////////////////////////////////////////////////////////////////////////////////
+
+	Record *getNextRecord(RecordKeyList *keyList = NULL);
+	void deleteMergedRecord(RecordKeyList &recList); // MUST use this method for cleanup!
+
+	typedef enum { SAME_STRAND_FORWARD, //must all be forward strand
+			SAME_STRAND_REVERSE, //must all be reverse strand
+			SAME_STRAND_EITHER, //must be same strand, but can be either forward or reverse
+			ANY_STRAND } //do no care about strand (Default value)
+	WANTED_STRAND_TYPE;
+
+	void setStrandType(WANTED_STRAND_TYPE strand) { _desiredStrand = strand; }
+	void setMaxDistance(int maxDistance) { _maxDistance = maxDistance; }
+
+private:
+
+	WANTED_STRAND_TYPE _desiredStrand;
+	int _maxDistance;
+	StrandQueue _storedRecords;
+
+	void deleteAllMergedItemsButKey(RecordKeyList &recList);
+	void addToStorage(Record *record);
+	Record *tryToTakeFromStorage();
+	Record *tryToTakeFromStorage(Record::strandType strand);
+};
+
+
+#endif /* FILERECORDMERGEMGR_H_ */
diff --git a/src/utils/FileRecordTools/FileRecordMgr.cpp b/src/utils/FileRecordTools/FileRecordMgr.cpp
index 38fc056b..0edf73a6 100644
--- a/src/utils/FileRecordTools/FileRecordMgr.cpp
+++ b/src/utils/FileRecordTools/FileRecordMgr.cpp
@@ -4,7 +4,7 @@
 #include "Record.h"
 #include "NewGenomeFile.h"
 
-FileRecordMgr::FileRecordMgr(const QuickString &filename, bool isSorted)
+FileRecordMgr::FileRecordMgr(const QuickString &filename)
 :
   _filename(filename),
   _bufStreamMgr(NULL),
@@ -12,7 +12,7 @@ FileRecordMgr::FileRecordMgr(const QuickString &filename, bool isSorted)
   _fileType(FileRecordTypeChecker::UNKNOWN_FILE_TYPE),
   _recordType(FileRecordTypeChecker::UNKNOWN_RECORD_TYPE),
   _recordMgr(NULL),
-  _isSortedInput(isSorted),
+  _isSortedInput(false),
   _freeListBlockSize(512),
   _useFullBamTags(false),
   _prevStart(INT_MAX),
@@ -88,7 +88,7 @@ bool FileRecordMgr::eof(){
 	return _fileReader->eof();
 }
 
-Record *FileRecordMgr::allocateAndGetNextRecord()
+Record *FileRecordMgr::getNextRecord(RecordKeyList *keyList)
 {
 	if (!_fileReader->isOpen()) {
 		return NULL;
@@ -120,6 +120,9 @@ Record *FileRecordMgr::allocateAndGetNextRecord()
 	}
 	assignChromId(record);
 	_totalRecordLength += (unsigned long)(record->getEndPos() - record->getStartPos());
+	if (keyList != NULL) {
+		keyList->setKey(record);
+	}
 	return record;
 }
 
@@ -198,6 +201,10 @@ void FileRecordMgr::deleteRecord(const Record *record) {
 	_recordMgr->deleteRecord(record);
 }
 
+void FileRecordMgr::deleteRecord(RecordKeyList *keyList) {
+	_recordMgr->deleteRecord(keyList->getKey());
+}
+
 void FileRecordMgr::allocateFileReader()
 {
 	switch (_fileType) {
@@ -224,175 +231,3 @@ const BamTools::RefVector & FileRecordMgr::getBamReferences() {
 	}
 	return static_cast<BamFileReader *>(_fileReader)->getReferences();
 }
-
-#ifdef false
-
-Record *FileRecordMgr::allocateAndGetNextMergedRecord(WANT_STRAND_TYPE desiredStrand, int maxDistance) {
-	RecordKeyList recList;
-	if (!allocateAndGetNextMergedRecord(recList, desiredStrand, maxDistance)) {
-		return NULL;
-	}
-	deleteAllMergedItemsButKey(recList);
-	return const_cast<Record *>(recList.getKey()); //want key to be non-const
-}
-
-bool FileRecordMgr::allocateAndGetNextMergedRecord(RecordKeyList & recList, WANT_STRAND_TYPE desiredStrand, int maxDistance)
-{
-	if (!recList.allClear()) {
-		deleteMergedRecord(recList);
-	}
-
-	_mustBeForward = desiredStrand == SAME_STRAND_FORWARD;
-	_mustBeReverse = desiredStrand == SAME_STRAND_REVERSE;
-
-	Record *startRecord = tryToTakeFromStorage();
-
-	// if we couldn't use a previously stored record for starters,
-	//then begin with a new one that matches strand criteria.
-	while (startRecord == NULL) {
-		startRecord = allocateAndGetNextRecord();
-		if (startRecord == NULL) { //hit EOF!!
-			return false;
-		}
-
-		if (_mustBeForward && !startRecord->getStrand()) {
-			//record is reverse, wanted forward.
-			addToStorage(startRecord);
-			startRecord = NULL;
-		} else if (_mustBeReverse && startRecord->getStrand()) {
-			//record is forward, wanted reverse
-			addToStorage(startRecord);
-			startRecord = NULL;
-		}
-	}
-
-	// OK!! We have a start record!
-
-	_mustBeForward = desiredStrand == SAME_STRAND_FORWARD || (desiredStrand == SAME_STRAND_EITHER && startRecord->getStrand());
-	_mustBeReverse = desiredStrand == SAME_STRAND_REVERSE || (desiredStrand == SAME_STRAND_EITHER && !startRecord->getStrand());
-
-	const QuickString &currChrom = startRecord->getChrName();
-	_foundChroms.insert(currChrom);
-
-	bool madeComposite = false;
-	recList.push_back(startRecord);
-	recList.setKey(startRecord); //key of recList will just be the startRecord unless we're able to merge more.
-
-	bool currStrand = startRecord->getStrand();
-	bool mustMatchStrand = desiredStrand != ANY_STRAND;
-
-	int currEnd = startRecord->getEndPos();
-	//now look for more records to merge with this one.
-	//stop when they're out of range, not on the same chromosome, or we hit EOF.
-	//ignore if they don't comply with strand.
-	Record *nextRecord = NULL;
-	while (nextRecord == NULL) {
-		bool takenFromStorage = false;
-		nextRecord = mustMatchStrand ? tryToTakeFromStorage(currStrand) : tryToTakeFromStorage();
-		if (nextRecord == NULL) {
-			nextRecord = allocateAndGetNextRecord();
-		} else {
-			takenFromStorage = true;
-		}
-		if (nextRecord == NULL) { // EOF hit
-			break;
-		}
-		const QuickString &newChrom = nextRecord->getChrName();
-		if (newChrom != currChrom) { //hit a different chromosome.
-			if (_foundChroms.find(newChrom) == _foundChroms.end() || takenFromStorage) {
-				//haven't seen this chromosome before.
-				addToStorage(nextRecord);
-				break;
-			} else {
-				//different strand, but we've already seen this chrom. File is not sorted.
-				fprintf(stderr, "ERROR: Input file %s is not sorted by chromosome, startPos.\n", _context->getInputFileName(_contextFileIdx).c_str());
-				deleteRecord(nextRecord);
-				deleteMergedRecord(recList);
-				exit(1);
-			}
-		}
-		int nextStart = nextRecord->getStartPos();
-		//is the record out of range?
-		if (nextStart > currEnd + maxDistance) {
-			//yes, it's out of range.
-			addToStorage(nextRecord);
-			break;
-		}
-
-		//ok, they're on the same chrom and in range. Are we happy with the strand?
-		if (mustMatchStrand && nextRecord->getStrand() != currStrand) {
-			//no, we're not.
-			addToStorage(nextRecord);
-			nextRecord = NULL;
-			continue;
-		}
-		//everything's good! do a merge.
-		recList.push_back(nextRecord);
-		madeComposite = true;
-		int nextEnd = nextRecord->getEndPos();
-		if (nextEnd > currEnd) {
-			currEnd = nextEnd;
-		}
-		nextRecord = NULL;
-	}
-	if (madeComposite) {
-		Record *newKey = _recordMgr->allocateRecord();
-		(*newKey) = (*startRecord);
-		newKey->setEndPos(currEnd);
-		recList.setKey(newKey);
-	}
-	_totalMergedRecordLength += (unsigned long)(recList.getKey()->getEndPos() - recList.getKey()->getStartPos());
-	return true;
-}
-
-void FileRecordMgr::addToStorage(Record *record) {
-	_storedRecords.push(record);
-}
-
-Record *FileRecordMgr::tryToTakeFromStorage() {
-	Record *record = _storedRecords.empty() ? NULL : const_cast<Record *>(_storedRecords.top());
-	if (record != NULL) {
-		_storedRecords.pop();
-	}
-	return record;
-}
-
-Record *FileRecordMgr::tryToTakeFromStorage(bool strand) {
-	Record *record = NULL;
-	if(strand) {
-		if (_storedRecords.emptyForward()) {
-			return NULL;
-		} else {
-			record = const_cast<Record *>(_storedRecords.topForward());
-			_storedRecords.popForward();
-			return record;
-		}
-	} else {
-		if (_storedRecords.emptyReverse()) {
-			return NULL;
-		} else {
-			record = const_cast<Record *>(_storedRecords.topReverse());
-			_storedRecords.popReverse();
-			return record;
-		}
-	}
-}
-
-void FileRecordMgr::deleteMergedRecord(RecordKeyList &recList)
-{
-	deleteAllMergedItemsButKey(recList);
-	deleteRecord(recList.getKey());
-	recList.setKey(NULL);
-}
-
-void FileRecordMgr::deleteAllMergedItemsButKey(RecordKeyList &recList) {
-	//if the key is also in the list, this method won't delete it.
-	for (RecordKeyList::const_iterator_type iter = recList.begin(); iter != recList.end(); iter = recList.next()) {
-		if (iter->value() == recList.getKey()) {
-			continue;
-		}
-		deleteRecord(iter->value());
-	}
-	recList.clearList();
-}
-#endif
diff --git a/src/utils/FileRecordTools/FileRecordMgr.h b/src/utils/FileRecordTools/FileRecordMgr.h
index b4e76e92..0994a7c7 100644
--- a/src/utils/FileRecordTools/FileRecordMgr.h
+++ b/src/utils/FileRecordTools/FileRecordMgr.h
@@ -32,12 +32,20 @@ class NewGenomeFile;
 
 class FileRecordMgr {
 public:
-	FileRecordMgr(const QuickString & filename, bool isSorted = false);
-	~FileRecordMgr();
+	FileRecordMgr(const QuickString & filename);
+	virtual ~FileRecordMgr();
 	bool open();
 	void close();
 	bool eof();
 
+	//This is an all-in-one method to give the user a new record that is initialized with
+	//the next entry in the data file.
+	//NOTE!! User MUST pass back the returned pointer to deleteRecord method for cleanup!
+	//Also Note! User must check for NULL returned, meaning we failed to get the next record.
+	virtual Record *getNextRecord(RecordKeyList *keyList = NULL);
+	void deleteRecord(const Record *);
+	virtual void deleteRecord(RecordKeyList *keyList);
+
 	const QuickString &getFileName() const { return _filename;}
 	bool hasHeader() const { return _fileReader->hasHeader(); }
 	const QuickString &getHeader() const { return _fileReader->getHeader(); }
@@ -69,55 +77,6 @@ public:
 	const BamTools::RefVector &getBamReferences();
 
 	int getNumFields() const { return _fileReader->getNumFields(); }
-	//This is an all-in-one method to give the user a new record that is initialized with
-	//the next entry in the data file.
-	//NOTE!! User MUST pass back the returned pointer to deleteRecord method for cleanup!
-	//Also Note! User must check for NULL returned, meaning we failed to get the next record.
-	Record *allocateAndGetNextRecord();
-	void deleteRecord(const Record *);
-
-#ifdef false
-	//////////////////////////////////////////////////////////////////////////////////
-	//
-	// 			MERGED RECORDS
-	//
-	//this will give a single "meta" record containing "flattened" or merged records.
-	//
-	// 1st ARG: Pass an empty RecordKeyList. When done, will have a pair: 1st is the final merged record,
-	//			second is list of constituent Records merged.
-	//			** NOTE ** If the RecordKeyList is not empty, this method will empty it for you and delete all contents!
-	//
-	// 2nd ARG: Choose from WANT_STRAND_TYPE, defined below below
-	//
-	// 3rd ARG: allows for nearby records, i.e. maxDistance 100 will merge records <= 100 bases apart. Default 0 means only
-	//			merge records that actually intersect.
-	//
-	// Return value: true if any records found. False if eof hit before records matching requested parameters found.
-
-	typedef enum { SAME_STRAND_FORWARD, //must all be forward strand
-			SAME_STRAND_REVERSE, //must all be reverse strand
-			SAME_STRAND_EITHER, //must be same strand, but can be either forward or reverse
-			ANY_STRAND } //do no care about strand (Default value)
-	WANT_STRAND_TYPE;
-
-	//
-	// WARNING!! Specifying a strand will keep all records on the other strand in memory!!
-	// This is done so that requests for records on that other strand can still be met.
-	// For now, use this method at any time to purge the kept records from memory, such as
-	// when changing chromosomes, for example.
-	void purgeKeepList();
-	bool allocateAndGetNextMergedRecord(RecordKeyList & recList, WANT_STRAND_TYPE desiredStrand = ANY_STRAND, int maxDistance = 0);
-	void deleteMergedRecord(RecordKeyList &recList); // MUST use this method for cleanup!
-
-	//this method will allocate a new record of merged records, but the returned record should only be passed to the deleteRecord method
-	//for cleanup, not to the delete mmerged record.
-	Record *allocateAndGetNextMergedRecord(WANT_STRAND_TYPE desiredStrand = ANY_STRAND, int maxDistance = 0);
-
-	//
-	// 				END MERGED RECORDS
-	//
-	//////////////////////////////////////////////////////////////////////////////////
-#endif
 
 	//File statistics
 	unsigned long getTotalRecordLength() const { return _totalRecordLength; } //sum of length of all returned records
@@ -140,7 +99,9 @@ public:
 		_hasGenomeFile = true;
 	}
 
-private:
+	void setIsSorted(bool val) { _isSortedInput = val; }
+
+protected:
 	QuickString _filename;
 	BufferedStreamMgr *_bufStreamMgr;
 
@@ -158,8 +119,6 @@ private:
 	int _prevStart;
 	int _prevChromId;
 
-	//members for handling merged records
-//	DualQueue<Record *, DualQueueAscending > _storedRecords;
 
 	bool _mustBeForward;
 	bool _mustBeReverse;
@@ -177,16 +136,6 @@ private:
 	void testInputSortOrder(Record *record);
 	void assignChromId(Record *);
 	void sortError(const Record *record, bool genomeFileError);
-
-
-#ifdef false
-	void deleteAllMergedItemsButKey(RecordKeyList &recList);
-	void addToStorage(Record *record);
-	Record *tryToTakeFromStorage();
-	Record *tryToTakeFromStorage(bool strand);
-#endif
-
-
 };
 
 
diff --git a/src/utils/FileRecordTools/Makefile b/src/utils/FileRecordTools/Makefile
index 9d021179..fce099b8 100644
--- a/src/utils/FileRecordTools/Makefile
+++ b/src/utils/FileRecordTools/Makefile
@@ -21,8 +21,8 @@ SUBDIRS = ./FileReaders \
 # ----------------------------------
 # define our source and object files
 # ----------------------------------
-SOURCES= FileRecordMgr.cpp FileRecordMgr.h
-OBJECTS= FileRecordMgr.o RecordOutputMgr.o
+SOURCES= FileRecordMgr.cpp FileRecordMgr.h FileRecordMergeMgr.cpp FileRecordMergeMgr.h 
+OBJECTS= FileRecordMgr.o FileRecordMergeMgr.o
 _EXT_OBJECTS=SingleLineDelimTextFileReader.o BamFileReader.o Bed3Interval.o Bed6Interval.o BedPlusInterval.o Bed12Interval.o BamRecord.o \
 	SingleLineDelimTransferBuffer.o FileRecordTypeChecker.o QuickString.o ParseTools.o RecordKeyList.o BufferedStreamMgr.o
 EXT_OBJECTS=$(patsubst %,$(OBJ_DIR)/%,$(_EXT_OBJECTS))
@@ -31,6 +31,8 @@ BUILT_OBJECTS= $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS))
 $(BUILT_OBJECTS): $(SOURCES) $(SUBDIRS)
 	@echo "  * compiling FileRecordMgr.cpp"
 	@$(CXX) -c -o $(OBJ_DIR)/FileRecordMgr.o FileRecordMgr.cpp $(LDFLAGS) $(CXXFLAGS) $(INCLUDES)
+	@echo "  * compiling FileRecordMergeMgr.cpp"
+	@$(CXX) -c -o $(OBJ_DIR)/FileRecordMergeMgr.o FileRecordMergeMgr.cpp $(LDFLAGS) $(CXXFLAGS) $(INCLUDES)
 	
 	
 
@@ -42,10 +44,8 @@ $(SUBDIRS): $(OBJ_DIR)
 clean:
 	@echo "Cleaning up."
 	@rm -f $(OBJ_DIR)/FileRecordMgr.o
-	@rm -f $(OBJ_DIR)/RecordMgr.o
 	@rm -f $(OBJ_DIR)/FileRecordTypeChecker.o
-	@rm -f $(OBJ_DIR)/SingleLineDelimTextFileReader.o
-	@rm -f $(OBJ_DIR)/SingleLineDelimTransferBuffer.o
+	@rm -f $(OBJ_DIR)/FileRecordMergeMgr.o
 	
 
 .PHONY: clean
\ No newline at end of file
diff --git a/src/utils/FileRecordTools/Records/Makefile b/src/utils/FileRecordTools/Records/Makefile
index 6bfd6106..556cc82d 100644
--- a/src/utils/FileRecordTools/Records/Makefile
+++ b/src/utils/FileRecordTools/Records/Makefile
@@ -21,9 +21,9 @@ SOURCES= RecordMgr.cpp RecordMgr.h Record.h Record.cpp Bed3Interval.h Bed3Interv
 	Bed4Interval.h Bed4Interval.cpp BedGraphInterval.h BedGraphInterval.cpp Bed5Interval.h Bed5Interval.cpp \
 	Bed6Interval.h Bed6Interval.cpp \
 	BedPlusInterval.h BedPlusInterval.cpp Bed12Interval.h Bed12Interval.cpp BamRecord.h BamRecord.cpp VcfRecord.h VcfRecord.cpp \
-	GffRecord.h GffRecord.cpp RecordKeyList.h RecordKeyList.cpp BlockMgr.h BlockMgr.cpp
+	GffRecord.h GffRecord.cpp RecordKeyList.h RecordKeyList.cpp BlockMgr.h BlockMgr.cpp StrandQueue.h StrandQueue.cpp
 OBJECTS= RecordMgr.o Record.o Bed3Interval.o Bed4Interval.o BedGraphInterval.o Bed5Interval.o Bed6Interval.o BedPlusInterval.o Bed12Interval.o BamRecord.o \
-		VcfRecord.o GffRecord.o RecordKeyList.o BlockMgr.o
+		VcfRecord.o GffRecord.o RecordKeyList.o BlockMgr.o StrandQueue.o
 _EXT_OBJECTS=ParseTools.o QuickString.o ChromIdLookup.o
 EXT_OBJECTS=$(patsubst %,$(OBJ_DIR)/%,$(_EXT_OBJECTS))
 BUILT_OBJECTS= $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS))
@@ -40,6 +40,6 @@ clean:
 	@echo "Cleaning up."
 	@rm -f $(OBJ_DIR)/RecordMgr.o $(OBJ_DIR)/Record.o $(OBJ_DIR)/Bed3Interval.o $(OBJ_DIR)/Bed4Interval.o \
 		$(OBJ_DIR)/BedGraphInterval.o $(OBJ_DIR)/Bed5Interval.o $(OBJ_DIR)/Bed6Interval.o \
-		$(OBJ_DIR)/BedPlusInterval.o $(OBJ_DIR)/Bed12Interval.o $(OBJ_DIR)/BamRecord.o $(OBJ_DIR)/VcfRecord.o $(OBJ_DIR)/GffRecord.o $(OBJ_DIR)/BlockMgr.o
+		$(OBJ_DIR)/BedPlusInterval.o $(OBJ_DIR)/Bed12Interval.o $(OBJ_DIR)/BamRecord.o $(OBJ_DIR)/VcfRecord.o $(OBJ_DIR)/GffRecord.o $(OBJ_DIR)/BlockMgr.o $(OBJ_DIR)/StrandQueue.o
 
 .PHONY: clean
\ No newline at end of file
diff --git a/src/utils/FileRecordTools/Records/Record.h b/src/utils/FileRecordTools/Records/Record.h
index d8071c1e..8e4376c1 100644
--- a/src/utils/FileRecordTools/Records/Record.h
+++ b/src/utils/FileRecordTools/Records/Record.h
@@ -152,6 +152,9 @@ protected:
 	bool _isMateUnmapped;
 };
 
-
+class RecordPtrSortFunctor {
+public:
+	bool operator()(const Record *rec1, const Record *rec2) const { return *rec1 > *rec2; }
+};
 
 #endif /* RECORD_H_ */
diff --git a/src/utils/FileRecordTools/Records/StrandQueue.cpp b/src/utils/FileRecordTools/Records/StrandQueue.cpp
new file mode 100644
index 00000000..aa53313b
--- /dev/null
+++ b/src/utils/FileRecordTools/Records/StrandQueue.cpp
@@ -0,0 +1,131 @@
+/*
+ * StrandQueue.cpp
+ *
+ *  Created on: Mar 31, 2014
+ *      Author: nek3d
+ */
+
+#include "StrandQueue.h"
+
+StrandQueue::StrandQueue() {
+
+	for (int i=0; i < NUM_QUEUES; i++) {
+		queueType *queue = new queueType();
+		_queues.push_back(queue);
+	}
+	_strandIdxs.resize(3);
+	_strandIdxs[0] = Record::FORWARD;
+	_strandIdxs[1] = Record::REVERSE;
+	_strandIdxs[2] = Record::UNKNOWN;
+}
+
+StrandQueue::~StrandQueue() {
+	for (int i=0; i < NUM_QUEUES; i++) {
+		delete _queues[i];
+	}
+}
+
+Record *StrandQueue::top() const
+{
+	int minIdx = getMinIdx();
+	if (minIdx == -1) return NULL;
+	return const_cast<Record *>(_queues[minIdx]->top());
+}
+
+void StrandQueue::pop() {
+	int minIdx = getMinIdx();
+	if (minIdx == -1) return;
+	_queues[minIdx]->pop();
+}
+
+Record * StrandQueue::top(Record::strandType strand) const {
+	const Record *record = NULL;
+	switch (strand) {
+	case Record::FORWARD:
+		if (_queues[0]->empty()) return NULL;
+		record = _queues[0]->top();
+		break;
+	case Record::REVERSE:
+		if (_queues[1]->empty()) return NULL;
+
+		record = _queues[1]->top();
+		break;
+	case Record::UNKNOWN:
+		if (_queues[0]->empty()) return NULL;
+		record = _queues[2]->top();
+		break;
+	default:
+		break;
+	}
+	return const_cast<Record *>(record);
+}
+
+void StrandQueue::pop(Record::strandType strand) const {
+	switch (strand) {
+	case Record::FORWARD:
+		if (_queues[0]->empty()) return;
+		_queues[0]->pop();
+		break;
+	case Record::REVERSE:
+		if (_queues[1]->empty()) return;
+		_queues[1]->pop();
+		break;
+	case Record::UNKNOWN:
+		if (_queues[2]->empty()) return;
+		_queues[2]->pop();
+		break;
+	default:
+		break;
+	}
+}
+
+void StrandQueue::push(Record *record) {
+	switch (record->getStrandVal()) {
+	case Record::FORWARD:
+		_queues[0]->push(record);
+		break;
+	case Record::REVERSE:
+		_queues[1]->push(record);
+		break;
+	case Record::UNKNOWN:
+		_queues[2]->push(record);
+		break;
+	default:
+		break;
+	}
+}
+
+size_t StrandQueue::size() const {
+	size_t sumSize = 0;
+	for (int i = 0; i < NUM_QUEUES; i++) {
+		sumSize += _queues[i]->size();
+	}
+	return sumSize;
+}
+
+bool StrandQueue::empty() const {
+	for (int i = 0; i < NUM_QUEUES; i++) {
+		if (!_queues[i]->empty()) {
+			return false;
+		}
+	}
+	return true;
+}
+
+
+int StrandQueue::getMinIdx() const {
+	if (empty()) return -1;
+	const Record *minRec = NULL;
+	int minIdx = -1;
+	for (int i = 0; i < NUM_QUEUES; i++) {
+		if (_queues[i]->empty()) continue;
+		const Record *currTop = _queues[i]->top();
+		if (currTop == NULL) continue;
+		if (minRec == NULL || *currTop < *minRec) {
+			minRec = currTop;
+			minIdx = i;
+		}
+	}
+	return minIdx;
+}
+
diff --git a/src/utils/FileRecordTools/Records/StrandQueue.h b/src/utils/FileRecordTools/Records/StrandQueue.h
new file mode 100644
index 00000000..e6f0bb49
--- /dev/null
+++ b/src/utils/FileRecordTools/Records/StrandQueue.h
@@ -0,0 +1,47 @@
+/*
+ * StrandQueue.h
+ *
+ *  Created on: Jan 29, 2013
+ *      Author: nek3d
+ */
+#ifndef STRANDQUEUE_H_
+#define STRANDQUEUE_H_
+
+using namespace std;
+
+#include <vector>
+#include <queue>
+#include <cstdio>
+#include <cstdlib>
+#include "Record.h"
+
+class StrandQueue {
+public:
+	StrandQueue();
+	~StrandQueue();
+
+	Record * top() const;
+	void pop();
+	Record * top(Record::strandType strand) const;
+	void pop(Record::strandType strand) const;
+	void push(Record *record);
+	size_t size() const;
+	bool empty() const;
+
+private:
+//	static RecordPtrSortFunctor _recSortFunctor;
+	typedef priority_queue<Record *, vector<const Record *>, RecordPtrSortFunctor > queueType;
+	vector<queueType *> _queues;
+	static const int NUM_QUEUES = 3;
+
+	//we want to be able to iterate over the enumerated strand types in Record.h,
+	//which are FORWARD, REVERSE, and UNKNOWN. However, iterating over an enum is hard to
+	//do, so we'll use a suggestion found in a forum, and put the enum values into a vector.
+	vector<Record::strandType> _strandIdxs;
+
+	int getMinIdx() const; //will return the idx of queue with the current min val.
+
+};
+
+
+#endif // STRANDQUEUE_H_
diff --git a/src/utils/FileRecordTools/Records/recordsTar.tar.gz b/src/utils/FileRecordTools/Records/recordsTar.tar.gz
deleted file mode 100644
index 321a88e4935d73f7034cce0611f9191d27bfeaa2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 54443
zcmV)GK)$~piwFSQlGRcG1MGbVJk{O*I7%`~MKZ!A3E6vOkC44eC0$(Ha4+{>v!tws
zL`Ed5g(xygQK3N;8fI2S85tSb-2dke*S$vLd7gT{&;Qrw^$ho%_j#Z9d7t+==e<6k
zqXu>{f!M+kcEYx<u4KRF5d|J;X-Ulg#bl(!i2n~f5@Mo~Vq{|C;?hzQVq#*FGGwB_
z4>1`skmxU>hvacbqQD3chztgClCb**-1qALqYr1uYBGn2S`)GreZEfn*vhlN9Mvqk
ztdFRppgkVQBYiNkVLXRNdX%<Rf5?9L3*GD0yyqq5CAQc)gv~S=nty$ex|8+z%2tNT
z+*8J$?(Sc27JPnPTkZcI+7KFfV5X-K;;Zn*U0!H9Kf4|li~f+`)X;aN-cee?CGb$M
zZ~hxc)ad9#TZLU$o{jTDnRw3l%FrnHj;0h>R-i+VHeK9!r#!LSl1y1Fh<z(KJV=o#
zY_xIs*7Lnmb<I#oe)^)+$X)@1QI@Z?S7Eyaib5u@9B6Q;PJAfm>ozhvGBFX>8QrF;
zD@oI*LB{S*6?x!UT~g44szE;5$gq;+qqkul_h};}k8qX+)EJ=sBGabc3+}r7>RQ73
zGgn+3%ipM?<XD5R&>^?CsD`KXLL^rkK2F}mOT|q|Hhk(n!|aBmN7=76s%i!d(cP&o
zjSNw(f$-M$*3%faWZn20$+!7yY?>ssy2i*JF4>jwPCdKb+mmxf#dLG1LEWWSBqh=(
zl{il5gg-5hJS0r}+)AbFmLnrXBr<ldNo^(gBJZaiS8F}k#%(uqO@PDAkma^rLpKhg
zl-J3XC+bg1sU(T**JeR8OeWiV@-|HuqZ{4{C9D{`{N)QQFNde{;SIJs@9o5y$9s}2
zK1ps~C8}~|7i+BR%Uzpl8I(hVOT0FZrkGr%9kM(geILDJZCK``{u82&ZJTJvX4={w
z9E<@6dz%}_%~V8)UgWuQIp<b?b?6XPFKtb#y`&JFOx!|fiX+{qXy|LaHFNPv*cyk;
zQRF;3cZ)s^J3On#9cg+{L?OeIY~vcWjf10uS&`+UZRM9Oo-wHNZm+#99cR`kdn)%9
z?F&>AQ&Co>#}%(g!MObV!^TCNysMi}NY;Inlk!;a5ul?>$CSn%=*)a1SR*;Cn_E->
zY+~8eT9xU){&}Vv$d{2`eRE#HD|T!4Pm(UDDO5hvPG=1%>=7_da)IyF<H!%3YHhJ-
zyFo9Vqh;Dx)H3Kr?fya*?aq2r(QUTL3B{@}i<TPm*q1TfW_6@a^+haoT}cmJ-3-}T
z@he}vWlshVJT|<bq`W6NtPonqrm^Wn^ywh_hJ=aS0^>&I>dcefk5=t(Ipka;a3=LW
z^Vg1n5Y^@xS4KmvmB!bn_fAASo~qS6qhjMHhHMx!C~2Ok2tIpUhnLOu&OV81AA7O2
z$D2}LF^&cr`?P2)gs*!kxsB6ARHow5`|b<}c~hQ)iTx`RZoXlBVmUG(>JH-5R|g5n
zt<!y?byCrZq07JR<tr2nC0{A8Wstz+oSQXUs`{R)E(8>m*ZUE4ccofy;%!&9pmVY*
zesK2mH3g=&S~8DkLl2+lL}jI<)|(Y`k{OL06?@5f=u=1h>8$K6V5npYnKUCPlp3C|
zc>A>=^ie5V*dQY@_+q3W6*R9Y(S+A7Q{Tpf`LUL1Kow<G%{n#pqfhyu-1YG{gLmE0
zUcbVq-v6X}-my0`aa124I9}Ulb-wz&m6_4?Xww?1pw}m4*(?wVk9VyG^>WWTup9Oj
zujZVMP}I=vt(k6!5xLf>dR@HKgpV@mqUy(8*T0JGTz}8x6FYs<lf8$|9Lib8v?sK_
zCA5C}^^|@oQYv1Cz3RhY{H68$%$x$|&o<TjmG@NneU=K(mlH~)e!osyzjUYn>(6|j
z4`ioT`9Bfv^>?NZ^tvbXmVsOz+Q&^DKu<+6a$++d=gj7JoO&w0Be};}6?mhhUV1lZ
zt+hy`WG}YoFp6I-Whc^06{%{k^0xh&yy@5TmXow+pZSK!Wn{fWUVV72MofJcE)!R%
zJKN^ccX_&~FuyPYJ@A2Hl=CptxU<T(!JT!};I&&`hIAeq>X-?6la%!E4xK8jl+iX^
zv{-MWr11*=Udi(-{Y>|To(gPoa;AK2_Pm1b+<4vj^Ak5Yf;yY8?KNPs<+2Qxqj0dk
zr25F1Jo?qT3!fOk8@#eM?(<d;yu_r|6jZBt-JB^K+O;Ncd&7s^&<ev<hu+YfRB18g
zqTXY${tE@w$nIT6GGcnSQ$SnGrnTF-G&nqtpq`m1T`m7eX?%5~L%0dWE}wlXTedd{
zNz?A?T=o8f1=#0|$==Y;j7GkY21&_Umu_`uJqfCg3-arkjGu;u1ep!yDD?&lUP_B9
zDEAgieXdfm^VW{ihy<O~PmfwV9C~afy}CclcKDx9F-u2umL&?)W;bSS&2GKPQkV1i
zP(W&7A#HocwTJcm`@!%HhgLf`A9CvXB&4!y?QjR5`Shp<O_PDP%ZhYf(d_|@H}4of
z`oL2VxP>abYNt44Mix8+3Sts%&@PJ<RIg@EUA5b!(m|k6((uB0iSkw_)*}gzn=87e
z*rpCn4hT0+D>R|AxMt9!dkbAg&;dmX+b0HumG+Ill?uvYYx27?e(M?c{fygMpG3r)
zXxcN$hiYlJ^hK;Xc!@LKHXxoW@mfIQAcMZGDwBJ4Vex)WL!kn1M>fH0i7zfce<U20
zlKWOX=~S)LZjCA1F#$R1U@ntS`HB>D)Tn_EW_)KKxauEU(VBJ1jK3_r3&aq#8AKb|
zl`VK7@Vs|%*9Gx9sh#>RlJ}$b?t5)jKn8zY+RRfes?w6l5_m^YROZMF{n?wnVr?eF
z_Gw%8oNfL(Dbi@M0-b-r_V63QwOZyfGO~NpkGwLKQ+#->REEiVt!w>CGg{YzJ4qSF
z6<rephh_Hp4j&y&DT<f3k4MKT^vv$eSg}*(HCo1^vq)hgYPKzwQnLp=k%um%tU$L=
zv=rSxh6vaW3X0iL!M4_H_;!m*^Bq20F{5kON)Fc7@HO{jmfmLyitavmDkY%h{>OI)
zl6wm89bTC-TM_4Mb0;B{^YY+xKAqgL-J-^FpNb9yUGZ!PQ%NlIZaZ*syLpx0BdRy4
z?$wh?yuG6)=r_*&QrhS@hq6Y|h2w%>!xE|UjnJTh_KL*1?CZTy_QO$%tDfx^Ib#;i
ze2jKXRm9|>tWwv3&}XpFgs{L~`Nx(8=4zRDd_N!}?hc*Uo*KU{uu|u-b6W#N0jy(}
zw<#<9Grdo~3t#7oZgc$?GM_#-Ga%BpTvctZtlc1FdQKF9+HfFDHA&j;qnKB9Qsvhe
z)3P%&MXwrNc1`%fvvSpk{E%DGZRM#Qezr{G9cX1ktsD1t(j04vpgCr7oT6Aa%PeJ2
zvaar+?#bOQx8l)xj@DXHyJfHP!Q*u-{3qd>M(~!%<kq-;s7>Xy`{OMIhX>hC9%{><
zu7{;hwN<txFy*7Ori%tTa%16BUYCZfry8QrZ_79)s>vpLg3b*kk&jna_#HUL6jyg#
zGy2@Rrm`^}uJe*-L+oGZ3_f@kxeNA6hR?UE<-;Rh5!F2($G$$ZX-(vfW4$V<Bf0hD
z9f)w5u$T%H*TYtseIhfB`~BqHUz|sG%w&1w-mC8zZ8M+7%>T5*3xDn@xUHw~3fDrF
zS*NC<whvE~YXkS4^rJb!h(5EWTz7iv=1IT4!yC|V-#k@z623I<pySs!CHio$jPSs7
z^x@R&AB$3Mp`|RQ(ZUbKkMDsCpjo&mURbA0I~+Um^^x{O7N0>4eAn!-T3-2tJoWfF
z<*pgpln$1eS<7B|i6^D|9V7Rh41FFYS5a^<Br`TQsEAw)*~tFoVvKI*K=LDwy_eTL
z*S}$^SmgW4xPR~2k0ACYiOq*$+2`L*wU$`4xhNg3w>DrOeuhp+Xo*ITu^-i)m9a1J
z??4+IpKh}}Kb>{ue)IlWU|y!-n{{>%q2Zdd1I>}sZ5M>m`;h$G(4PG|vwqPl+cO|N
zWcHJ250AX*q9*d$q9)kQks{9_%jWt-YT8%id-!zd4_=EcAfp;_;<`~oElc^(@<B1(
zU<<VL!NjVVYwZtb0-nE_SX1#h<ynu@vxp~kmck`#`M2l4Lq~~Jf8AtVrZ)jMEcf$b
zEuJa5m-`ky(6R6G^jObGcOfUOUGe@_?vE-?YHeyvd0(`>U&=+?uzS>YT2I@wzX?TK
zRe3$$xhpd!sQiS{RAC8^RXVj--ISpMdmp+98a`cr=;pK^AVzmHr5HXjpal%vHhg`t
z^2iXiL0}}8mCB~=5C`=K-FBO1<3!eM(>sIG4iWRoK^Ak5#vXNvH|1$<Z%xfh)IzUH
zA@dI7cy)pCY<z$y?S)knJ4Xz?&zl+hR>pP7Iy1DNTHzcM+j*0ZC+R2{q&>rInn}GG
zF>ZOxn@qsT!1Iu^M?o>=DL94foySH3<6z13A^Agb0y$=#1@gO_yFT{V*Y>;*T~oZ~
z6s(;uq`+^@o{MQLuAkGX6EZjJ@PG^g{3Uwsd@zTdMYCO$qRG;?Pzs8;Ep^4AEOMl0
zn!D?08U<?wrCQM~S2F)l)d8^B14F?L$89tpaOWS?vN7is($Q{rUQ-dnpM`2P9c3z5
zXRPji`c06rzb{%b!Ml|^;mCpUVrl!AJ=>Ky8*PF!F7!D<UbJ|JB-yl{ewboTedTlK
z*4`3^&=~snjPKO%YzekR*(x6^52*Hh{U(05Y8d6oeu{wGqZ607Ay=3!3ij;lofLT1
z;2xgy<xT8bT6ZzI`@6*R8E1wYt=6#}^4LvN=d(6@cjd<HogNN#dlEM_n96K=U!Axn
zH);Lwtq1HPWpVf9_Ml+wJ**EI-{c?L_7J9W-TG+<PpABBu#ja<`<|lX!L1hR<2OB?
z<R$KTa#+tk#Mxf=CXybcS;<{{mHTa0T;4v>T@v>mupfK*wJma;C|77nmxTD<BZGIt
zUWM;r^^I^IlV_zfQd=>BwmqrYtq(!=9-=dk4foHKl2WO&Z4O#hPYGJ{<avd=;7m<=
zY|p`jo%hc_kA;XCUplehSs`bA@0U}Rx^7P97s3+m@1&GCIhND>_~yhVSGlP+W%gB8
z?;hH9+3hw^Mms!=ugMRTx1aFyWbK*RcA9eS5W1?h0^Mn#bPavmp~T;;c;EmUWsywo
zk(+X#;+p<*&i5*tx1B&b1q!*%e4<ys;CNN3q0U6mjQzgP=AQoBPda5qhWCEx>x-17
z9c$##jC18Yac{lV*<h}8WMCXs^-5J(fqTGuHud+$Oq2m74j$wXmZ)Ruk3^Z>Rr${3
zu-2^`wAD3`?|qYP6Q$aCpk_e5RWsJ=1Q&<O<*28d(EjGC4h-_v#X|+F&sD&7oYnRb
ze7!f?)QP=0I-*(eotHsb%A*4hH6pWG6b9cl2h+bE57XEWrUbR-!%jPC$DE2+PD9ex
zY`c?V?x@{mnHaxv4K>qR#RI&jr-!xrRsD2hUvEw|+dSm)mXq#EPN`>b*?HkFFJsk=
z*!?P1^HkiFq~0eck8$)sH}k(27-x=P4o8rKwAD-+UNR^u?jJ5am#9qMk#4P+^+~p=
z?E&S!Yo76~`+1)iOr2;O8RnFq8XUL2neYkblodMLrf@i8JjrwD)Nqm*?U9{DG9?am
zj?t%PuT{BjxB}7oa2O^$!MEzp7yd1u!XK&KK_)eZMeemMaZSASzC`wIFt;I<P3I^u
zO>P0_9mzM-KC!lYw71>RX7G@yp5jFJ*UzDQgTPD$0uR^~cW(4!3~N36Mu7iVUvDn`
zE9P7y2HgUuP1kN6OlwWwOXg*_KGAN~IqNk7emD8H2Lv=4-A|7gqAtv<cn=uIr7J|H
zW>=uEl!oQB(SxrWJ(qp;no3WlmV8ar4OqBGEN5ZfzCDfgvah7{UIiQ`Uvt#l*yd%j
z)#GDMThuv%T152&IwWW(MJ=B&QPvoWucBj3GPTvvlL>ww9Qg*Matlni|H4{b2}j>a
zd--c6uB#F}?AABJ_v#Fc@@%Y)eVL|Ox3Yd)rk930eU(&R&kn~Oo(0sJ8X8BYz&s*f
zF6E1z`+9ooJ7Zbs>sUBM&4DXSmGXjR#~{O<$F6(9Dfw`|0D49AV32JE=eo6)6>T53
zzc^1nw0^7CK{79$$*FO5*+;h5Q`dZeRI+9zmvYo`)V=6bpqJFTahXwf@Zr^$20rJ~
zIV9wPy(IupvpCz!0=8-OrSF>J3Hq7=U9~ggYH6J{54HG&lFHWx_YIFrPQQFC;E&)h
ze5m%=LY_loq#yLm({kwE>~lw}JcQ6RBc%3bX|NQlchKDl|LZTAOx<dCP0#QZI#p?`
z+N{TU!Eo20(&WyOYM)I5J6`viHk`>%Te-JT@azSvsF;roRyU4UYGhKb>-iw;8j*UX
z)ii=yE|B9%TzXn*4bnJJteQgBqIUN<x{k;5j05F%4%t`wb%o7(4w>$2x~w}l>k0B7
zOS$RghvqAwi^y+RANAdY_TjKog=y5b?r%xs)Zy!vd6mFZJ^}^B(k1C<J$?o8cv=|{
zB+aa;+qzPnV$Y6JE3$Atm3X$;;3Kj3<w}j#Pbz>4(kV;%LF@PS#+aWqG&|N*`MCYW
zRL_7!`+#R@oAT?n(|sW|GTgO}y;ruyC$69$N3M8ZuC4_sKQGiYz7qVh_e(J{qLFO$
z_}02Qy>SM%1Djm}S!`&ak23t#Kh~?B(%i}$FuB4a+xVhu{~pr|ml13|pq)JVTaf{U
z{mQmYqpr{1yva|U>fP%0%yH!ur=WgZp_&Ba`}LDW1<x3rY?R!3PD)8j_hwICZno7c
zh_WronWX6%L9*Vfk;>&ye`z1C^_7=?cbry7z_TL=x?06t7<&bcrsA~08tWNoEc>9$
zt9UEZ6j;Zl_V;cg^!nF@^F9cEdVEZ4miEw2^K5sCYW1j?%My~p^2c@v8LoNDVP%x4
zJryPSeo$QUNJCSd(x6h6e~E<RB;`KJN@>=+<u6BW-AW!CgT5G~wlmq9=<saQmrb3o
zBuzygJ$KYNv+)gQ7hN9NbGrn23LT@jVzhVm3ue2Iuea7pDZdpg`H034m38vCszcJ%
zgI8WM8S?cvncbt4GM9c0JLUOSWMb<h=tkNnJ)E!1P6eN#8Q+wUZR~T)L0g&iYuE0E
z!&72<t4i+f5k|evy8Pl|Vj#b$VXYNv<@*te)dL6A@2FO#`q;=;DLvP6k~3fb?%=u1
zpqI(?;(gBIW;a@7rar1vi4|!ogiVZ}wDys$?4^>oK9gQ_OYW}60C}L}ZR6Lh`*YR(
zqF$!lN>ec4%DDH1ZAfy9s{Pj{^Gv&7&@m%DwtLYV+{tEa!+SPsHf{DbsO>)5etTa_
zCKpF6sGxI(??sh}et4`*8Ku)(;7=DnaLC!)%`n}XLtkuTs0%dhR)pS>hor5$$3m5K
zQtEP{%a`i{+mT-O`tRMuHNFP&vyy+_nD~^5qx>AZpm<~P`Vi=&Y*2xa=A~m499)<3
zo_~BBr%*Z06`a%Dc#2AGb{o~W$+@zJB9ETFQR7WdZb$g7qq?PBz?^^K+2EH%b&uAM
zx(0{x_=d!(3%ulO0?v*LX*0iYj4$qXFw(T%*Lq$`N1cm$!hA<0MeV6LE4C9a)IR0f
z%WEt1U7h*V&;oX2iRm`)%aQB*c!;sKDacK|xYe>|P~}w|Vz6#opRU7pM)ZpfkMz+^
z5A)K$jy%t>J&&$FkkQ@X$J$p{RWXa)lw^w@l%I{tpIu#+R1XiE9r{#z{o|nRRr5Rf
zZC5%eJa65j=!UFI*$>iJmDjs+;AB5NIorzet^7kltS+w~*r--KJEU@_!NIWYWOLry
zJ#Aav;IG&4J29W}e;$5~>(skTE4Nf`nbf%&8FEv*E5rO|xbbyYPWqhjvnz^M`OhAQ
zz8!i?b;Lv1?Wkzxt%6|T34@zCBaW$C#kf<fBkp`5tDiVD6T$0etXg~Xqzg@{UY*~d
zjKJ-2>(}L!tGNzn2{P;R+)+Qx%#BcBS#>T-0=ybL{*o)GrkL+tnY-$nHD`9^$U&ZD
ztuPqP5M>CEk7|9m;_awOoOZx*o`n7Wl#P$}Dxc66Jal-i-B$JZ+WOt=^>i9wCjIm`
z>{c*cPuz5!Mh#@UDe2PKiS}bhHqvb%7o;oLZN^~GA#5Pp@6NdH4&VEo^j1{P@0^)~
zji~M^H0@L1(y6g{Q9#XMcSWUUt<#Q>>*73Tw|t^GdWEX;JeT~vH94sP<nYbwWlAsX
znyuP&$vHE7%lTNa{m#J%*^H;!Lc1kD2GDMNY`MyJNAdx2$0xSEno90@7aqUc;qz7T
z`9(jdhq^7a<zsaEt(9Dnhg%!8ubyi-q0-U)DB5j<?@Hl(ky_|8IqBijw%a?b!(XUO
zwtJmK<!XGjk-8svl;vr?RNUi;=M_51EEL}R4%t88WlwvyEj3WYx@zUxn<8vvFFtC@
zh=xqMy|8sG>5sVF_(3wQ%d$g>=UV>TMwn*Sr0;vx>>X6eES*IjsaM+l1_sBH;tDgy
zIX#EEB|-qJoPPS6Yu`YIviZ31mSHEQ7>f(!-0{i7`4MNPjzM?m6o6Z_ySKR>kzf#x
z^b*f(@?0G~+)h8~k#0OJ)c?|FK)1i<UB}a#8?L$t(y;N?PgtJ+QV0E<4^9zY+4NTJ
z1oP<dt6j|p+Kul99WV27AKfxpy#EBsnVHLJn`g&?9X_!omKhfVJ6`CO@%5`vA9kiW
z*b#pO;}<^tk(0u~P@-d?o*X)}XGeKyq@EAwa8E~~@F*hZLJ13{T`)&niE_jkV#mF!
z$hGWtvT`a(`m~=ett0#T?l`6D<=)dd9vbEyItk#>b!Qc{*U8(l9@YmR^r+I%q=&(2
ztI4{g&y)xksG(-PM0G*~uI<?98#v5{S}{`e-XfW*{6_Mzv!8CP9$FL6Ao-Y9^{rO8
zxAU`%7?E<3_pAniz2KQk=Y5{-L7_JCbj2g&PERJeU3CllR3ENfY@sC3lT&p=`zz(g
z(d5lHpEXx(e|SwukeqjfVe|z5?sI;}bRDCSAN8-jdz77B{CxjM_se%#KIiXGLrB4P
zt&W3995aF3pdJu1w!8w9TVq^on$0m%S?xXPR;u{{o)14|H=1V5baXGM_^C(NO<_U5
zcJ`x55Biv5L$)`6nea!vJMG4l^VnqfQ~lOGHPl;S!3tyfpGSE7y*3^{p!E)Yvwn|l
zwfYFx)TJ*Rvh>E5UK^W19(7w?Kkt<qWtimiE;Kk`d#UQZF8V{m`NMUlG<nQxn>(3~
zih>=x^wz=2Ua-X6v~p;BnurcHMcb@rYZIJ7pFNFkgWlQ4jLv@5xbFcPwT-hL&6ay`
zy^P=casIC&!PLbD35Yh&%%%sYM=rL0HecPPmBkg#aif1|mh=8|g?8c3EZOeWnmbDd
z9BjQVghyJhC2ym%kMRrIcP@2D+vRCb$yBTA8W{=SO&XzvmrTl?D;!LUj)brkBljoN
zIZf=lCwY^<!YW2Ow?h*;P`mrYwX~07pPzYyZ!r31n+1(XlzfFg(T(n;-)_9w9T8(9
zG<pO+X1u$t<tW^ro-5t-yk*&oagh(x^>3jl`B23j=sxM)gVy~Who^e0JFCMCkJr|J
zZt77!7}gZ+P_`}cMu=mc)kOEq;OF+SGLfqN$8?z1yzZ+QXt0<KFmv0m(*Eg_ZV{nl
zib`@mGjE1BIUGCkd3?+~<58%KZFO0OX47O>G%VNpCFcv%F7eIeRGf?}-pLnBXov-h
zCK+7sFqb`jg6p*@-4?ip%X5Y=dc~66-0~^P^m#`0@GUu~i}t0SUEQYcXvo;K#Y4M<
z>|ShD>nzG=<U{W%4~S~O<-yOVb*KZN0arFgvLkLJ#iD5~efLUhKc^@!Iv8%a!PSK=
zrSE#WZ2)Qq$m8nO{k=TKG2W1t3H^1Gp9%(LK20~9=fn=?r?sxDiG>v0W@j_o_PovP
z8e%ACU}^=em)l4yYr&qg#?JIQ&Yphp1Kkb%4GsNIWb5~3zmds)#U>_1*Fu&3s-ppV
z@J18k?kel)zL|T@=hxGLr0Fxi>}sC$W-sI9wdHeQn(}quY}egEVc>%{pYk>TQXc9u
z4gS#9khWv0d;GTWvy|wXAOY9R7OFiNqCE9&GvlKj15=I<ubVYH3xX`(YC-x8!D9mU
zpXqoIlA)R_9BbuOoF6tPAGex%Gmx><Z>nikQ%}y#*qK>FdHPwOndy(8Q?sh1naQsg
zZEbH+Ay=T&no3XHGJR?%aK5=~>jyh$RG(QDH@q#zIaMyVqDpKVa}}9FeFEGARw$Y(
zu`xq}zfaHUXq;uKnN&n2ixbbq$a;;-oi|yJ^h_u;qGS4}2U`Fc3bnYhWyJ61=mCcl
zBYvUL=z)YIa;dfPyLO74rvE7Pa>n=L&1}Oex-!N4Z^K^cN6DFNb=`O6oXDD|$_djS
zJNm2*y@rY&^DrHVkvFUGj+&KZz3i6kkou51=VkeOk=1-*8+1TZ=1uFb#tR?cZ`^vm
zou518R%mzlB=`Gco$O;b;@cD3)3|c%Dvoz^f`-Q72i6`g72J9NTIc)8UTwpL*Fqbf
zBKO@}H+U7{It`6|rTs=o>yAst`@ECe(zL!LZAq16d30mtW$C0x7kPO7Eg5<%dGm61
zUp(bg!7NjLhTk?d&Qz;Y+mF*z_uw9~wyQ>^TVYl{;cCyj$Bj0UomV_XL9I+X<#lQ|
z^hAdcV@n1-g5l{MUH;;-MCz^Cr?|Y|=?St$lKI46JTkeV_r_Vd_&TxP`k|R2#w){u
zSNE;mR3mg^*fRu{+Lznyar*vdo=r@do6kH}bKQ5serVOymJIPq@5ERYyEKO>UT)f_
zT8SFS4NMG{_copjOMNwdck`(uN`fJe9zz*9Cizf~bTExXedf5NuQzJ%Rh+8tWB&Ly
zNnR?XP?S-Of;O4Hl_jr7FL3MbQ`J|FTJye6P#HUL>{zYLiW_`AU3bsy9rJqPnm!!O
zmO3c<LI`CL@!;iFv{Zk?u5sHIN$>13m%v?qXAuEi{JVy|Jhlnnrf+Oy7WXevns~OW
z-m8HB_$E4D8`E@_7|quiUgBNZ2P2-UkDS@oexfnezmVl3`wf2$4OvkGea*+mQS4)l
zJX@)BXm-=fcD>cy;a||<^;~pJ<*r_*M^yNWGqD#U$ayc&8Tm$i%z50(r)SFHUL>4e
zD}1sGF3WN*pR2{|)H4W!72l!NQZ_1kHw5vo^Jd{uWK_`4W4x)%eC|2-+hDD3shUvF
zCpIW9_qfW+{OcUHXX<PdHBeovw?vEVo%noQKGWIpjE_G^OIh~A;K6+I-ZMMKgO6M-
zP0V0CT;?3>P}4XnE!UGW5>Z0wSu-<jq$T#0A^xpYpN`0_&w>06wOySVMwaeM<XgT{
zoWF|@zW6z$L*v-A);)4wk<eX_W08JVgKy)E&pmN$G1|2GZc5MkwRwju+OILiN2Asp
zVr=rvq^Q^gw{*)3+bE<-d&{QP%}*<BW~_O=v&y+^9deM63)|Rh6?aTW^;{Ra@~X#W
z%Tb}`baN}FGF^_s8!j~HWGBa4N6Xv-+kM%UrdRJ;>vLnLm3`(L){#cX=e?3Ptg`o9
zkGF4>O=A){WYIGDxmVHB{`iF5i0Erj@0E+<=LaY)T}#yEhCaAwZ@&=VkZk>geB2~O
z#w><I>B8G>tE#$pK82k*f_9*zefm*&DsL*b4@6(T6V;iDUgzw5tC@ZZ?Iid1ZWL@v
zDPxO%rpDHtbqrE{8qZjE^+X)s_+lT`cw~&%$TNgQRIP#5gNA+AwS;;i_E4XDB9Q(?
z*U!w7PC|q(_^nwrM}TCi>9&ec&C{YEy8HuUrH4dy67?sk#79jM4!`(f_WshTv^AnV
z&f3C0HicI^x#L;hJwIsmtY}bSpfsS|6*Vi?`&NvBPmjyfD~-z1ycldmabP@TJU;{;
z0xlL`*U8)H-K>0KqYul`YBd)7bIHkyH8+gm$IzMZ5Bb88dY>8IOmI(LP}=3n%^YoN
z5F5t&<xT0Ws&Nah{&jEE%0iwzI(~)x$Qf5z4&gm+2@l2@-%GvlA$K>8b4v!9k4QCI
zqEA)76>OOpE^Hhu@?;yDwa&<W^JK~|)IQ_(Yjo?=vKeIuIlo!arm<YULlk4HD-Q?w
zD5_pFP4T6CCHdBpCFmS;AUv%qwW->kdyH$NF^ir=GD2|UVU2U>wBz+LgXjC744zy|
zc{Vk;o?k2K5sYSM@peCmNL%9U*Y56NR@Cci5rgUjHBo6_G~+WhreB$4rk}SKIGmFU
zsy7?W_-yRO&{=cuR&#^m?d0<;Ytzki&$NVAGfi}w@{ny8SNE#8yEaCk08-U%`j-F5
zY+_Cn)i%cVOR7;VD`o|b^E`lf&py)uck5O)nQQip+@8L>+iYv}rLH1HONK_d%ZYt$
z0*AyXc6Dw(er@Ha44r5RkzUiFI-vvf!4#f$E=(8HDlAJ@h}w65*yg4uIVp8ve@xoR
zIN^<I(EcqdQDPr99`vm^*}>mE5WML%o!K5=<4s)=rt&J6zDOl83%oq2D=f#IXY}FP
zBR;36!?)}%L_Dk$Z_RL!4sU#^yguy=)upQ%jUeR+$g4YV%#{&a8z-;0kM6vuaEa9_
z1r9D~xB;>fs0egVJ;}O%5?PD>@=6^(L!ZxaK2zD#$x=67%l$N~VPxg~>y>q1dxS1t
zA8a=d;mX_jr4uond<-3SIu<Qhr5smvC-uwp&{h{1Jm#X@Kq2D>IpsdF7Uj={Z%015
zh;K|#yLYPCWn>4W&t73`%v3?#>Z3(ZLZof#I@@04GN)ZzseaRq$s{lcq<&MNn$qoq
z__NDlTn{2u3fjrz){z~$TIIb*NMhVxYRzDODd=HqTBOI2AV+XBG8%U7<*?N&zBLRS
zr8-KhHg8j}yCL<t_pS&>J}4nYwD_Hx-k>ithvx^|XOFjqR}K2>rB4fq=B=soYEILs
z2!5nmMYEY)+gyWo-Sv)W26iWkCoC62<PFc<)N&K|TDO(XM>EJPen%@L?HupL3gqe5
z67M*3A(;IhUAW5;3fp99j`9`eBaSE3Rz^l05O24LR`nE5PX2oJ_*N+;eutIetH(+>
z)kDNR^x1>66A#j9B%j@GCIVige!Xw&#k1$Cj82%34cYIEgsR>Z(1_Qe*dFdL>)o|h
zOe?-79u-xU9TUj~w|ZM!=e@hQZH1%(B)CwZ-X5GBdf?>PMKbGfiXK*z;L}26!3Q42
zoOCP|WjE2(G&$ZFQ{1Jc<GG>x%eLlVeh1B(m^$%Gav`F<7jt+w90KW5-D7a6ODWkO
z;?A2bZd^QcduXFL`OuDV9zpY?1ySa1jhb?vn>`OcpGbds_;^#(xz%>e!>gsvMzgi+
zt=b|H{(@7pENXB%oaqrln3-ur5Pot+h?f}Uc);!+Z@2r^qdQaK_V>hG?>~^u6LWea
z8Prnle(H(`pXgoFOQvP+T<-e)4=%<vY4Q|QR_d=R%ZqG}+}&FeK=q}m(_Q6r(ANOQ
zLcQh-;e~3j+k?@Qy{ThSp`X0?Mn0wHjur2Dqq8AB`Ao%q&UJ-mrn-vT4RcR>T&y0{
zh|>xPk>t?JS+|GACPS<w_EpasJ=t;wGtYt}cXA&OO||;<8F!}~)3iQf|M*=%GwX3>
z`|_2XR5s~$`g<o2I!Wh2YS(FKHJ2VgNgcNPDJS3ho9&y-P5M)d(W_3btXij7%s_w5
zKKH|Z|C-i#RF+AB>udV5C+P`~?&OE@8$?{z)Z;$bTmlN62ub$Ybbd;Ntql5vo>NtT
z!mCsV#S(hgS*1`s!OaU~AfNp*+jgZoNd0Jq>>eFigGY=8wB$Q=4s*cRDPBpz@}3;l
z^rZjXZ)L3R^v(`y`L>+dTR37Uz;o@rFIG~49M2u1cScB#?zv#+tR`Rn)&{ZLVt2hc
zeCA^&wa}%rEMv+SLmw!1&UV7CWS>TRZEMSmt+hCfn%Sg0vE~^4dxzQS>)nCYM#Zhs
zU)(QVdQ{@qy!wP$Aw4MRZsphtAIH*?`yOY@L2KKUsS-~=l&^f=#%UyWAR*$Y)I<Ne
z7@8++6p!ke)3(4pRAaP1c6{_5S4^83h>!(+P~BiZ&TY!xb1k9?)JcE7!)+MVuXotA
zdBj9_t%RR4<@)wvnohYV)31W!r=&!j?>{>z+ttN7VXICVq?!3y?~1Nd8J%o0U0cXl
zqSpxDSygo-t<28GlmHVY@pGxGKN)aw*_`JWa7|pl{tK0#qWxau>2@Ba(`88+Ri|IC
zc|WK?m-gX+*nx|$KSq}fD!+RFfo*DYW>J*9eIL5-K}s%KrYWJNcGhoGQaAdN{qgEG
z9o`MmVaK9QlaI!1^7HdOGTMro5RLe9@oQCZr_zVX+_4o?nrjZ{O2tcE-4%qi3wIt=
zQFo0GgH&CT*WG+~k8FodGwqr#{c8J^{Sq~9{)GvRr$)8J7%soN`uO?1vQ2}I*=P-u
zPsNCXQDZLkJ=3D>dK{D~>Ze@Tk3V?`bLrS|V$}I?q*e<>_nK#dDvw02r*`R4M#!ty
zHxA3{8CO<@Qr%inH*vA;YKmY(zITE^Wn&1vBt_fN?LK~oo8B7VQ}bg!@@`Q2<g*ch
zb@Bo0^|sIMr>@VYrd#2oPZq6drBOoZlRNZ*eV;McZ5#U7w_$QZ+u&`xf=<_1pEH$F
zr12MtS{JHenZWMWx2c7$=js08=-_s;q<WSkrCzU@V`(qi==15UxXzT#-pn1T7+88B
zERS;|TQKwE=Z^6+X4ev?QN{ZCu>$mUJf}{k-oBaB{J^x5%dza-eah{%jpj#p_&i!i
zec(vAp&>$q@$182DgJRex=6F?kQMibc~<N;bDSOP>)LKM*48vdA8KK{EgvnjZ~Fw=
zK*_W4+PLUvO{EJPDS5Ucj~q)6G-kO=`^jxU*{A#?9rF&I?o$Gm8;z!O{H$x9$J~w{
z(c?~IO*<NW>2Ss>-S&j9A7sxJru4De4%=LiGG|+@f91>GDVMnHU28MEFZ0=FO(c#v
z)9gi>zT7KH*>{iMQ6$!XcdB9AjI7K?3&~hY<JT81p03)@_<{$t>24n5di&KEpT2zM
zSfwAhHad6phQx;#BFUg<tW`cLb3TaALTns$AdhA%k$rBSd4)M<?~0NB>!&qgJDFv?
zrgv9%Y^px^v?RC3;f6C(UCPdwu6DPrld9AtOIlXxsQ)2B``CwjU9`Ll<7Vhy?{-Qx
z3(Y@x@}aJfmRE)kEpu{~Nx)#s<qC@6m@Ff)f{VK?p1eauLrXnEpr%h=A#Otrq;KD8
z+^pC0=2T?)rm?HLDG(CWy!);0_IlnrDC{6Eb;moK?NWdnbz*+D`)az`zNbY`+WSvy
zt7P*Xb<9ytz8RfbS<M~-b!s^#t=uWevh`(M)tgV9SDxnGhO6uo3v;&=c<FT^H9Ph*
z(;IK^74kEi8+}%Thc8E_R#zv5KtFdl7E%s)?2$4W7d8ZQNr><cwM=U;iTZ?Ot?&)C
zPb{V=wbtVRS-!|jmL^X=GmCN@?qB~DwSGL_G|Q3Rc;Bj~X>Gr^S0_B9)LzS;rgV{&
zhoL_~l(V~s1{8x(suMX=5$mZ>ZSvGl$=fwpY1C`{Fjg}}IVh$%L>AIOHC^6{OcOjT
z_=3BR$uo^YP3X`?fqPpkLD{#NH_Q~8mnT41o$7lUzUMx)GFz?^RNFWOQ_u7p5V&Vp
z3CcAMezMOQ{BbOuCGaiVdm%@mhVqJjONnQao{!lWEN>-5Hx{Hsq~<?nGc3D2bK^y;
zRH(GA@_lIj#y$tgoh;~8mZ|qOu<a3d`kVZ-Ct<@Z7D?A?#U7(mv+EIkexVQSkq~rY
zNc9N%lI6SMnF*w*jUT8!sYN_fIeymzZ}+&cG42i9n|k^px6eA$TE#y;csTVDJ-LYC
zOZ~M4>nq>^?`(PAv;^Gf)QFF_02>sFmU&y+`Br2ES)85GIvEL7T4Mw0mQj6S*RHxw
zqS1@y$({PD)u)jHPr^<!l$D|q_a1ZE^yG?100&AcbhVf1u72rE-Lq{UHe?D+^#&c?
za-f;@b<Vl_v==Bj)$Uh5^%U<fh^X;GnYu;BGzXM6n7ApQY^&QSw&zW<p{I-N5LNH$
z^)ANmOc3Gsig#HblfS!GY54h`5j|h4`|Z-22imJksI$)9-q7NB5=lidlX89bYN58=
z8-rKZm><5hpSrL|<b~j=vKQ~rF7LK;&(^p0AIK<~QMQ-{mU$KWrscaP^48)JcvK^~
zz39#B)hQbyx#@+>S+{^={M>J6&GIUqn$=OY^#%nc#1+gqD0;mk<J6A`>^C1h>wQE>
zM7(RmuzZ5oyW-U&k&@)f!NvR-C-OF}RsK|0o<Dofw2GyxwlNH>=K1*C=QCe2Ig4hs
zH_e)>kh2)GC_<lFSrp`?51d!t{BEmy2V^Khu82{j?LkLvIhEv=qsZufdK%t~b$ik*
z#jKPpj;!m>g`TTt?4JGLdIsbLXU_G|FdqrtRv@wVgqN|j{io;;c?VwB7QU?Id^He8
zF#&^r9;d$7K;=wVC~}R?>&$Am!cC`lzNGpj!Q_+2p)=AGw;IvRJ92aFh8qJrU)z7Y
zmTTFbzm>LAFGQw8vUihzo|E1K{;ZndyX#tQ3<uY79@1xyJn)$@l#&Ow@14KvT3!MA
z&MS`h6DTy|@}&@W9m-BVS9E~iP(&AgU3)(lmZo)uE&cMtiDwsC!~6GbonU%3(4VOj
z<Pyi?RDBcqV0PD?+VQO!&(U{SKj+z~7`;2!tidC7x&7`~_c2XoVHVj&g&Rf>4{uiV
zc~aZH)~ER1L$`ya{2n^eY_jwpDSc(*QXflYY^N1w*1h+h@x{}g7woOa$C2$jm=fZ2
zJ@(Xu<*eG~otthvy=5}>%&CuIXPr^gXUNK#^|eY_KXJEr<<fKqh^)CKImx5G`VBS5
zU55=Nt5PV$YC0}ci`A8!y!^q`@5@Q)q4z7^Qj5{4`EO$&PD^2y5#M+$Kt7XONa{v9
z8-+e-tM!Vnj<6S{r|WL4H+r)&C#$dNSRrrn-3&t(A&G$M>-*o|S+RnFpXyCEU-wW5
zI#|od?xQrbRD3#>Ud{He?;rS;%K1XwUlgG0od@_QvR<v9EGpHV1=epg`u=25YI|T`
zf7EU=f6++#ap$cD_2;Q;Ys{dA{I~L;kR&%si>gEm#>b7eZ%S6=PX=uYeAr>LIXY%1
z^8Ird^Pzi^(^1I2&9bl~FGuRc+TVHJs(BZ9R?%=3O5s$lYtkTX+Fj@{TOZGpbY>e@
zvem%$t-e0gcEdBB*{As@n4>@!n6iqjG+C(Mtyhj*oy}^%_d)M<s>BmMb>qa=r{s){
z?%G4{Jnm5f+Ms8h;bCST?QV=VBio9e%6g`nX3@AO4Kp3*y}8=Z;y$N)imT}aznWnH
z;si9as-{9O5_&`-=95KR&pzJ__}7~cYx5_+_hW!<dUg|Phjkg5Bl*Ame#)Qc*FI{5
z_rDx}Ss&ki|4URtOhOv>{uc&H4D<e%n6%8F_rHG2BO*Wp5&#iN0q_%30#Zjnz$l0v
z2o946X+Ug2l7b*{Q896B9p+JWM>)a~@*pf<fKm|}nk`U!m>t9(q^7EGqN#3ZqG7FV
zO|u0kfx;l9g#akb*4f<-0^(MK*h%ZaP!NO%*jd<-o2bSJj6g!n;BaRoX}PgG)Yi!q
zg@D2wNGrguP!V7xs?Jacm<t4k!qn2(I)jl&kQUS#Vgdo%K@bY~5&&><A&v>VAl`aV
zBuas19u!vrk_WlE+c-mQLBv#p4%6UD<!Pwx5l{%s4utO%0fAr;?I0jf0&r3je(~`u
z&`^6o5h!;6i7gz4L=knx3wMPez$iFEk#A8IrkxGI7!VW&MQI`6*pcwf4+kVbjCnC6
z$=FGOJ>XCb`4BLIZ&9%;z;YBH5&Hom-BD`p_JRO<6bQ4BP`Ez<9te^$6C~h-`-2}h
z(x1TnPvOC_k)&#l=B29s;us9vot>BJ|66TLATD5Ff?y8ViGeuVA^#~(n8RGauC5Tf
zZ&Ebh5GNIwPRzVrA?l70TPFxYULL=2%`A;HK@JcUrj8Ha8gv+hfS}wFu;tnU>)x8E
zy#mM==#L=L*yRlX5v^JfFVF?y*W!MxZHRy|=%_Ig2ebi@s5=58u4A`!BYY)}0@7ti
z!W{q=b`tn7c<nKN8MwPFW-`84pbkG}bDhrjDkhHY%oPDgL2QA|R35wdml`wapm0MX
zp;<)44r*@?L12LGfijRSu0{}K1F;3WBe5GSK&>+b<O22v3IX~+^G$$Rfgot8MMO}J
zU>FGH2mwfk!CfGjNfRbw$I%6w)3-zv0HE;&{-xOhEET9dNJM~SlgAth|Muzj=lR|P
z9AskRg!A{;d;{P+`kyrBoqwGECnF{;CXRXkUq(XmkN)>N9uh^2ND@dCD^p<II|Hf=
z459&XhPs$RyioJ{0}1F3TO`WP8ET_MLqmcO*zSmb^6}HiTcaGYn=Wtw^9hOZ3(|ma
zC7Lk1x!*R<a9byJxH}9BK|^zx#&;3kqYDvZfbi!FaSe!fLBmD*6)7|v*d!7BfNn=k
ztm_ds!$Dw<PoklK6hYW>VWKjHIS62A3+jOqOf3`zaWUDcHeZP^z|_q%VZM64i~wN@
z^?@K4Kw!(}AuzNo0>Kty27y1b1OU2#-vFbrdgB77k*Ja16bq1mJ>hT6q~H`*8!!?m
zLuomK9RNZ|IZJ|@s4<2((EM*9CBgwMEeIlFGjM)m&a9<DWd!HN>zjbG03e?G%LB;?
z5)0=y@rjAf!D46Q8-QX2K<u30#!V_(NEAXGIQWg=NWLWoPAp`LAc@9JDpJIdi^hZ(
z3ZiMliUw9MSRfjBqhaxiAy^ZOh9e}lkZgPjegcH&4Uq*z<KgD{x)>D4MUrw7mMyNq
zv1pl2Notnk!Lrr|UN@v!#2j1;JP?LOxIcw4T05{2ZrhLAhM|PCbn)E(c&m9i_@OpL
zOW}v$7fH~Mw<4^MpJ+0-Qhs(mma<rXXpRKu8etmznXlhBUq5fX|CRatGo62RI+vf%
z?|4L(nICMcW%oty{V3rD|8NTe_BM`|B?MvtVc)XxF$5t!p(tBN5Z`<iP-qLBf*={d
zh@U$aNd*C5615Ei0(MfsgUT)f#m)XAKsjQ-dDV{;NKBL%ie#b}!-_3}ozn#u0E#aL
z#A}4}kaiGzu)8yg2$FQZ2+SmKi@3EfW=8&PGw08<%(KAi`z3vR$NrZR6PF;^{}PfC
z82evBM&ghC|2rOh{D)KumWlxxz&$|XvOf_7($oM@8klLCSg7ie1cDY;d?Ofy55RoW
z(8PEk@o^dw3;wUhYKW2G;x(iWhHpkzzGD*q?MTbdM?IF+bAM^%<e!O<{EBb{M*5Zw
zNGxyx{fLK%IDCQ+37E}0wiX8>h}=S$*aZoDkR)v}*yf@6F>wV_^O+RY(qv$~Y0D6S
z@jWd|0;U~-08Pw<9wsr=i7|XLnu4K32dC03LCBo4vlJb3t(HQHaInErH19YAN`3$f
z^6w(Bbp%cefn{4Sngq3Z7v>T{sd+cvQauy3#bBF<#`aC(4<W_$-3d`6XoSmAg;N)o
zr3%+}DeOeH1cAyq-{j9?M*a$<xEcI$j6cXstk%3NH*q@k^7P?aFV9b$p*2tGoGbU|
zu_J#KVq(7jAlBa-h9!x^&Iddfp6>YID~bDlz69s6Cnl80V8caiiGA}VfFyR<5;X)@
zyod-AICdb|u>n-M15yb_VxqQC1PG3RIshsMKss(Fksy0G0%Q+H0wVwc2dS$&3Wdpx
zS<u5mOLcK2!8Tn?*}R>JjrS4<d>1Hle}caMu?G-;iC-N4{eJ$R*j)afjHHAV_WSSB
zQqq6yzu)nY8ebB`#@Ant|3cwP%SD7G=DkM5zp!Cjd~lZt<mi$xb8$%`z-9B`7Q`UG
zW1b<M?TCJ2LStYQ)YjS-*j#sfv#Ed*X~1&MPewu)33j~G^m}9Zxe)7;aYao0(bf@R
z0Cs_3C|f%A2*6+sIwLp|?>Jr(P8@&(_WpS&LaPOV#0ALkjTQirV8U|@g>Z+Ega?Q?
z^CQu<1#W7hf&Y+OdyeiOZh#vD|4)<rodDF|8wM8bj{@TYA3sh0--^flFAeWI?g-E#
za=C@~qlCmT|8fh0WWE(~AnNL`2OLOT`FKt(^5c`Z@rf4SB0vdZK*9q2wznVWM)?sx
z|G#~j{ds=&AwBeeO&{OU|HMTJ?|(>211cca|1b7O|NAWu!T(Pr1<Serf6n_av5fOy
zVj186+zTjw;T4c&U-J0zzyV?S^Kk?G+ZI0(F(9;_3m8ZcdldfGyBa?mQTP)&_=TYZ
ziN%qF-{QfNSo9tNvHyxh*znS3jdX&#YC#c5l$j$Ss5s2K9U(9y3?BjVmPp<wU7LSg
zIsX?PKzt<sW&e*jaN5uLf5gRQ#IXJ!NvS{Q|L=H6+&}Y@@HgB)n7t3@?2*(VcJ@f>
zEaB`S0y(-Q%$$RS2=E`zL0``KvLFY2NsowxAjleqw_U%JEG_v1b~R~E+#*YykPr7`
z&IvqWKS{&)b7PmG>o4U}{#6?PZa(Pm9m9|1KrZQ;__;af#$`f&GZB)AxWDd}kR)~_
zz!vx<mdqGj${X@0WAI;oNO%2T)5mwte=%tZsX6;!Mn+l`YyXS?vHyR|L$Lpeq+lug
zU)LQ55|_a`03?3U0U)`I1AwHQhUOa)s2{ZA2}V3&3?#{a^QQfenDPW1bEZ6zPV&c4
z|F0P8lK+ySF8S?D6B1ckY<^4re)Ah3O6uRX|D?nT?|+L+h)Uw(|9|qof6GI%`AX^h
zqxPSa4zc|wrL%<nM+9<oNtikNj|lL8*8W=(KoS#L2ezmmu@I$n{v`|X2ZQ7IVf-Y;
z|B5~Ni%0Z7Xnp?lh?gDmFECbd@9SYB=2G7>O^HbPMW!hhLW(3@j$sKA$UkAe{@dI7
z4?m>4{;%od`}W`5`(IMx;xgj6`0t<Z|NWMSVE++G!E*6mF^QiF081@n|4EVBfB&5M
zM;OB2F#iZR=FC4LmE@24_g^vpr2ZxIPwLy|ABiks%s&$APwL+YzLLCg`ETWai;B<N
zf8zM~pV*)M|93n;@*&p0YX1>^B7pc8vHeE`a&$?UIs0$9??nB#?7t-;q_D}?2ry3N
z2iqM2MA8)d+X8>;e8+5D^l6j7VK)9so8w1Qu<@+;$r1hs%*<cSfd9Nz`tuB0mP5bL
zh{c6iznS^H)Ynmdw;hWEktWRy$8heSjnw|zC)l6o?>wZZ{;%odXY7AzQHekK-@ox8
z*#AUQ@DJJl(#zQY(!a|7pa06sU$_4WIOgnsB9-)y{r_LF|E2#W`(OIo_CJX%EwcZm
z|0Vl>Cj#v1_$z$?-_8G(7M-{MC8UA<UqVXqkN@|#JS4j>sU-X(J^&JwSU&(s39&C=
z0qD_XVds1T3mW{-`USpYzAqTYzm^;Pqjdb+`N2O<=l`HROl-0)HIQFqwtg=qcmXMY
z(t`i5Jd1bzf4-0J+J7<x`wycHV9tMW(Ld+^Z+U*9{kPLZ)ku388*owGKWPV&2=w2u
z1xfJC*@FvIl0P=#f5j%miroKZTJR#707gK$zglD)E?h7Fn0*NJZshEa{G}n_@7@0-
zDm|b7D=mh#|0E^<<p2Jbhh*0!k%XT!|7aF8$C`S?1(++J0FBVy1^WUzex-==6Yg{(
zZG3cbYe2)qeCZIo7@>-y3Lq$G2lf}gHTFxqI(A-2VI<TC*c5=e?c1?BDWGyXLr@UV
zJjgz%)toL#_^K~)Pgr%Bl$a&H15DcDXYPu^kdOU^`4Hs%WlW2PfP-}L#)B;ZKtsKN
zo%7g8%kj8?LVYlxwgXd1fOmny_;7s)&QpbrR4-!nqUJ<g<`du};V?fxfEy@WI5=z-
zmi^Sg)`ssHz&+nJ7TtX37!t8SI2s6WM17NduTsF(4Kpkl#FKa{{{|)0)I^+hbw@f{
z+kkDI_y9E6T7Xbr5X2cUY>4PpTAp4-5)uK53DgtFT}C1?T@llQfMDmDWKw*;aZ4Ae
z$o>sq2)+ltZzNq1wE*$*Vs#!v44pW+SPG2)JG3s<{O8EVOE^KY7kFiePiG;V7GsF#
zHFi}3v%B<O0^(Af$BUc7ZvZQSMDf#%XQMqB5FX6+o!F~69l>@WFb16s=3}k)IHdv!
zg2926j$d0KPe(8c<OxQCAYQImWkDD(97`_AMN4sMd0x06_zBWYv&>pwgm_6e7ZkLe
zl$nB{#d`s%=q~!gAE`8a{~EC+wms1$cdYLo4kUC6Db4rbyF7jWz!hJAfzqX2Obdz^
zG5#-(<e$16>pw8izw06VUuDF%IPp*1$3#3L(#;e*x`hhJa>K&9CJ96@?V2PV!S_6q
zA|hbG=yG$10GKc|f??j6jTUp`u|4K%NFXHCYi`^1ggQH8EHuFW_kduUV((NYo;yJh
z#)S!#U{Y%Y0c3U{TnY_lT>wbI_?wl5F|AceI>z<^lHQK%#Q_dN!Ld}#PdWbBnHvO1
zNs)9b#T>1K${h>pwl5<=I4;kf;Uw}wz_sA~vs$o0FO$AR<dglA^z;ACv&icE1$}%k
z|65v&aQ_qbTi}5GFDmmV|L3<n1phCo6#PRjU?V+q(`7us3#-0y3)FmQ*#l6B;RvOl
z_6U=h>wo=XC}K2o{$Nrs#Xsr}{&P9h@And0W8`wNmsmu^0FHvlgWQoAnlR@$ARABz
zm<t5s&cVBRFggKvk+|7{VIWtaF$@I-J3D)WY=E{Ppaq~LxPW1{fKdoV31WJH;?$Hy
z)}cLCt$?9`wsuf^d!Wt+g7SnwFbW7134+@k0#*f9H^J%`!1A(zV5qc(yF#(n<8ofB
zA9HId{4OW?LIr0D?U>kMKX((&;@+1OJV0;5Tu8IDN`!M*0U%4>b+ddA$X|&ZccIST
zKy5(kY{h#>u-Eb|vY>$i5*+jMMT}zc^+pR7{cn7xbkR;p*dhO(_XqPC6>8kcu!F=G
zs6-?}KzF#?9PlF`?0f`)Q^aKNVf-`;tOQ4}2Lx*dAaMo&7y-dLY_M1K*kRT@kxGxd
z0%)Q8b%|SZ794;7+Q(M0_c-Z0Ab!=mf0*an`X46Q5BL2qNl|eLNf{|j{<o;ipYMPE
zmItr@5lO*Ps-HgC8zd(ABVYd_=x}owNy13DGj~z3Ivm&*yinN90SPQ*(pojr%SlP9
zz%D=Y*>JEcR0L?E>Wn|Rm#%g9!UeSOBLLI_{9o7*7B%ilEL^upOsRpno*us-4G2?(
zNmVk0X<%IZP&mxc70HKn0FzdmIze4ARTxhw)_1)SB|d^d;1(YV07hlOXOa;Sd6bCC
z!!(2_!vf4ij#om<xhw3Dd^osW5O0ja3*vRc{UL}`WqDnIrGgz9j_A1@Fg%nnfCgyE
z$B*?6<J7MCw6Gt&jT4g^MxY0C7GNizk3b0#4fCmCz^;wikYNy82oecKc!R+9fUw|?
zD1dr*6bRU$G1sYqu*BHHf$0V`CucAQ%mohY%2-9|JG83mf16UU%XjD`{j$g$-{zh4
z3pt5xI*$nx)WAj)7Usk)Kcn*;{HduW=z~PpoeBU=@L$9yy%=dpV5KDo10}h|62L>i
zi4_{+yD|Z0VfGk|gN(Sz4n>eC2qRXQ$|ZS&t-wt^?uRc9(_#fd353Mm#kXwr+=YBt
zN-zoo06#~%8Qcj1!>FZ8i~)bMrXa2ZLC`kAZGyztcPh+d#B}jPDDn48;=PkgA|-H)
zh+$lcL{uL+LiB@6k*Ie9OYN~%m^~j71*ldCK@hhl0)g4&?Exq|kS78TC{|eXz$yaT
zAwiywn7|g&)ftMtcM!1ePzZ0~{V;C)D5)V{P!yk#7(dBuEOv+!-(ZUO7Gs+exP-eu
zij*~`_zFNV-A;V96plyxpjN`Rn0Fqr(nr8XbQcvKEoocKoRK!gwZ#cKehmm9=GFpW
z)WL0mokSI8r;4=+aS-#9C`jl?5Jb2x3X5^^7J$P_;1%Y-BtpI*c(%-n2X>;rvfk$o
z)9<eJdBCODISvfJqyT8_Q7kX74s`${3|*B#ytbIXG{7kEq8TNe&3ydA>T^(Yc@wto
z2*kI=0KduLq)86~b3i%b!h_4kU<jlv4#8jzFt{t`6abJA05P(GDZ}i;*lZ40pd(Da
z0|p%*2^fw7tO<=jFZpoz@Eu@|n{7JV<OzS968&vN^tU$lZ^E{ZFV)AF5)F2{B90z~
zCBQX^5E^U)VcTM3*>hu5#K2&}4qQuUGW@{yfoVZaO$={93XfN9@L`B=kcQ8yz(Flu
z2S2c=@WMd&16ajGz2TEPs0o$$&PkyZ77>YyCF26_^ZX+^wwKr;O-u|;<Uv~49TExy
z&OcyjVr3Wa8G>R|=&iPxO;HdpPdMtZTca31>0J2|(qo9}A|w|4DqaD7F1^#tE%o`$
zX1NYYH%OxHiT7}VrxCLcVm6;e8|p%xRY+;BLwrBDcWQ8}9|=LJ<L*RTaB9w#@-K#l
zyXe?0hQ^jIgeL4P#1{h+)oWtM!AIEEiR+diYDtPrF~P+JfVi^7)L>$d3qf&(*mG(w
zgokT`ojwe=NzMr~I122nHb48z92Hn;!%m#L3vq@83ADUCcFr+ZAY)yL)+o%rfcb^n
zqp^}|195=Dup29;oNK-U69Jwpo-c&~mf&0*bD1L-(?Uqe19LMnRv4%;Gy*FeG0zqJ
z#9)$r5X&4C^AS&=`BH}}&W8G?Z8V>j_*?n1c!}U>#V-&N{@{l?hXxx|!2E^Pu`$*I
zsf5@=VRqPG5IaK;2*Mfcy1ZSupxhCPTCyAgK?0j6fn8V?1V=9bf@3d{ZG+kQ2%K<n
zMS0H+dfrYY5U>EtTxuaOAg8%9Q+F4_*1nYV&rRe{$TxnRI=K14|C*mp;%ct>di<;|
z-I#cCNx26=;73i=l4Np;8LB-8O>8XAGmd~va3MVZoHjED@;$yeE^3LwfB*>bVl#J?
zVyOe5wZX{w8Uk%U!E<bP^L)egPQvzi2rgofdCo75f|&U~Ob}jfbe37u#MO(J_R@_>
z=%8M7nqsM)2iIA+2`+3hH$bAXE@*>ogiSLBdttXmOu8-Di*K&81$(9-0ndU8eD_#P
zP#CcF;xmg$@XYPV3$V-;6XAg4#RP{1gHDJ*As!0YBj%vyQ!c5g7m689iNRJalunF7
zi2D-<;7c>7_W9ydJV}t@yTGc;_RerHa6T@?C<4OQEV1_}fvjzDPEPEg@lCW4U|WoK
zI6vta{3MXTWI|mLfcE3ehsm|YjfHxShGj`uyo$d|0fCA0+clArx$NdcO`IUjwJhy_
z9s9y*S-5c#XH_rU=H|0piJHzI7esFeke)0A^?*Pt5@+5nW$n%-TVc#U;uiQc{r~Nk
zR_Fcnzpjt(<^RY?iZ6)&h)GF`{)zwmj%PvqXUW8$ACLav6Mys!)pzOdG$G0OAu6L0
z5i!GLF5nVu90BXa8G^(aq)5OzL_+N#nDhrQ$Qg`qz&i5rZZvmWM-UhZ!bT0Su~;=#
zeS9ra7{F?TfZMs-La<dXU>Mi|0zyKtCOBjc4C{Hs<VhgiZG@nBe>I_3pn`@5m*atr
z__~4tY=EJ!KpfgyGCr_WoC~i%5WT{>Fwix3Pc0$RGoQ4CpAq7`r1=OBu<INp`85~v
z$9KTDup^KFeq+W)|M7ogoLacQ=8{|hLa=)ob_>RYNJtY>@Kc0MJ8=O+=j=>i3W4dv
zB&1;7z!(D`E{vz?F9et7hVvulmjaILoe&g$QeEb<eVwt#9ug}^&dzhBV^f0hWaFdt
zKVcH%d(!~OLbzb0+S3sVh$L{_AaVJ?1ls@vC2$^JN`Sy41KD^3+;?#WV{;XVNCdzj
zU|UCQPZ&YA#RwQK>j;d+21VdhkNG};103W6fdGAA)166=b}SME;V1^#A~1?96pZg3
zSmP)-wlfTIIK(&yKM@CsM}|Q+cMO75ot<%m!xHC;kz8!Pvkhc!xI`!74@ej>qi`)T
zQjMRfUu&A;CKu=!&}A?=9zeg?fCl{kvG*j<aaGrm(*ubG2}=UOEY7!((PC-FGnPh1
zk_DD5n=!U*OY#E2xFgM%G<asdm_H+7j7@W#01c%Ov$P2u0yba=Xq=M7w1Bg)7(z-*
z!wxoS2?P#%ps8t~xbNP#|7B(*jSQ#JKR(Brx7>H%{qNuV-n-inP?0Vjspe2PkNo=D
z-0ELk-DI-(-MKGS$tOrEspX9hge!@?0I)jQxojwt7$#h<iC?Dy=csWjf2X+l0%r!?
z9>)VoXB8WseGLl;UDDP_Ev{kCW%(kI3<0ezC9|Hw4XDs2rwCg<mkONBzSsa@PF^$y
zwWv3Y(I{GgT>NNOx*JrmEOI82lA^Y-S<%A&er7>2aRxvI_J0kLh>ZW;Nb^61XHUle
zI4F<Yv&fY&{=i=XR#TJsQ-tqQDmS@n@helBFe7NUSCZlnXj{2VpBYd}`ZHwvrWOoj
ztlUsQ_aPL<k8`AVsxtC8d}uv=C1=%=ofp+g;BBK{*f9Q`cV{znc2fJTsHuIM)zyJP
zjIpwP0f<*CZPr2Hv3S5Z6Kr5cOx!l4fwiMKa@<N+X31WwFJq!HGj5}(0VR>KHfe^&
z$-QP@EN4UiO2XOgEb#Y{7~c9BRxUe~%W~^uIvkhjOqQe0jO<a!nIR5p@L{xGwsHfw
z&%uohMTg+0;{tVX2q5FYh6S1=vV&MPiw%XA)LE!bk?js31O}Oktnm%ZPMIj9U@*um
z0|?n520J4KBmPh_XDb^^zAG9g`!_-cLVv}qK)xh(03STUg(Ap@U`^l(_ifUk1eu44
zEL^Yv?Gi@Fj?kzKRLWBiDvR0&V;L|`8AvDk*Tb6z8BN`g*AY>k_9I!OP^5aFevPCb
zevz&(&)-X%X#&*NbB)vTxFXLXgWy+AFK^0x9FCO_yckzrM-(^Z`z<b1xp;3A5Hww9
z07doD7QAPVvMETGE)x!TBG!ZS{2UD(3pf&gc4><!8#6=2w$B#`u(Sjnm&5XBoZz1(
zwVfSC#TCYwzM#0~f^qt?!=hZpRo>`Fgd#k{9sb(^Oo_m<B4B0&`mem!2sL^j-D=G7
z^#i9NDt%qS6=VxJfopEnKqs(K@+2L1V?pB3OMm~^mW^5}1^gJAo#__lsBQ4osZBfs
zU>0z;b{hMZcK@&J`b!H~c?#YC&l2(fBjJX6i2oRhG*0G!Iw%jl|5sK)DLjA4_LJYg
zC@KKGG>^aUsJwdx>SOim6#&qqS2>V2Px|uyKlJ4-;LF;LY~91rk@5S&5Ef+6$j=3U
z3WLJ^7lJ7A=ubtIw~uB%_e|-T>E$4*_=fUJX7zl=@0Z8n0Xz!VY56UGR-C3KMlN@0
zwTe4Rd%C_lSc>>O3T-)il`lm)mWq&mYIC_8(MtLLLn~xk9hXz8#-2Ylf7Hq6;66)Y
z>rA*#naD8;#(!b^zxr9BNF>w<`@h-Y$@nh^<yqRcXzl!H7h&~*Kv4W6>@ir@7VY$?
z>P@7BWh;83i=#c!j&5gzTsD!kgJq`}b?%3hvYjAdRtDSs**<Nfo$ZTP%<t$X!0VzF
zRoZ~nK}F_+Yf(^cz3iZIF4%*4bQ&<zgo7vj8^Ct}dkFs)OnsVXkcDR2N|}I<e;e)*
z734eMf(`9VAAmFD<I$R3*9QSunKxPUz7Z-zP$n|*2n6wYK~6~BOILKYcXZE{rYxXP
zRDKN_{Dfghg`*aeoz!SQq5fRd`qb-9>a`~B3<mBZ)~-Qs)8H{wL~j!DXrf0-a>Y(!
zW2r9dj^Efqdaf&fL(R%QaTZhlX2UB7HA7R~>V^%1$ow}BDU7^ye}BRPI@)`*S7-5e
zWa+QO(#dbRDQ)S5wR9p{E^1j0+E@xTEc`Ge4J>8KmScjJoRd|ywqteAT0Si$7=Wd2
zT*)uy^|RQr*5!ssKeby$)le*J=X%LbZ$@oJ72}iDLHMD<udXg@TM=C>I~w_V%1&iu
zU)x05YMn`OVA+{VJI`(c^-Wosvl=?EFRi+4${A+gpk<UB<U|gtu|$&0s+_c_Sx}8H
zcFGwQRqd-+R~vPGMxA9;oFVJTUyJ82SUhiGceR0y#NV9pR>J|?jHR2zIPLHgwvdEY
z<)k!|GV1ybWrFJZaTV)jj#Z`Cs0$2MfL`ldZ+dNmZ%rgGRL7#!E4B5hRw+wWDOOjk
zQmigs6^LB7;^iad4~qPsaO00d3dVm4)rTVN{;$5FF)|D9|3Z`YzX#=U8LhfZI^qed
zm3x6UH3@5tCNyS<#=*58qMHbHq$r@eMx~xBidS@=)wy(4CoR6n%vj9oQie)do3K};
zQ=lA(>!nL#S<_KNGYANa5{{s;LFy6sIh{9h9_96OJVs<;x-l72pA|IIx@cUhiN+m<
z8mx+!G^_Rjtd9Ps{eUuRFP5cQ(#%;&icpoVp~%v0xkAL_m4m~c#!x1yn#J(B)rA~0
zq6K0S^k>@98x>(%0b=Vep;KZDK^=+6X0^4@SF43`$ta#=%97Db)g>cqxV?{aNkCWt
zuSFr0OH{iw-6k`~?L!r7py`t^kZ_yX4^F(|c8GhSNUBbEEfifVB^tJPEGQ0*y^`sU
zg{4DcjapobPddRCB1~&O!WbKhr^`Hu&QlVyw3di0t)nN4oTqNH=_Cqw4&omcd^r$@
z1>4oNs>RjD=|+_yInP|R5i079CKZqdqS}q3x(NM|EE^Y+E%|V4DGo)t9wrLI)_fSY
zdSU3mF*YXjbi_dYELW|p6-K;H!U)rT+c7fpg~5ms&;e}ly2-4%Sy*yWI6u+f&kNBf
z(CHVz+Dgv=Es8oAF2k+6l{R3h(=XSut(58d&?!p#htB!0;$zR-N9EMGV~=wZPW)Y%
zD@f=0G^2%yIH5E&x`#+bEZKxM^4v5YJte@wAjgDKt>P?V4_dio+=%6}RthZRQTd_L
zlyNsj*paUw!y+6gyC%Qa0eD6Gjhu}Jk{GU@z(BVPD^14Y@0*9YCy4WMsz)(V%?On?
zDqu3XBwQb5UDakhZQ3@Cx*uS}N)tq|H_WBc+7LZn5@@msCKR>MDs2$dG6~ZrNDjm@
zaX5CWU@=;MER80Mpc_itBV=sw5wpOA)G=+UzP05$hG;$NPDF-|P)g}X%YRK5+m&hw
zQ7#aG=-nLPctF=1=oRkf)jUa!zE&~zjyf@qw{8T3XsByrCWBsTsJp(BM=^yRoRFIO
zqG!-$K_2Mh?YoB%RROvH6Cwi^b2;bJ^@`+#4XH=D(u_NebH$j$e_im}T4f*(QS(q|
z9Jp4D!whJ}ss^VPSe57om9})Bs~Fa^Tvilpi@?S211wX0+}jYex1T#SOJZaxzE7z$
z)SZqX4-G#hC{?FSTI4pOZsFRf!dV;!X>qc)Jp2RQ(8%{YWF_EzkC>Ii<dY*5izCU@
z@3fZCEM2D(4VeZkF8IK~1&$00j+#}@@dHK=YGw)Z$zo!pq}dN<%FsU^%f@<XC`Z~o
zz@(DOi52`=9Dt3*P(zTkb#7joC@}MH75gmU`zs+V6g_w8yWJLJ7VvPnMR)x4-UKTG
zmfB&TBhS%_Q@U>ZEVeYR9%U}H=89#<Le6NXE*@Ax^*Vr`w8zYunwcRVHkXcDo`Xuz
zY%C5H0dc5o2+z|W4rY;+XU0-eRd2MA)0`~L2{RUcgkf73Kt$D%o0&{ouD_YbUJ6i)
z8CuFLGy$~I42eyO{ZecfX}L)D4CKj@?}Gmg&)PmKnM<YD4x4>?%mfTmNDUqWv1}D<
z2SEvF=Z)<DKFBQw0n5m7E|*<v^{*vg=zw{uVe&AG*ow>tr<IN;;s5d)c*=Q^s(mtK
zJ&S%O_YxEd1N#Xh%$XtbQ-@G)P*K5ri19-QM`C8c5h8pHVK^*YVBmn!abW`7Fati=
z<(WpaXepwvabo>BrnQ-H<Ih71$N!!k;{Jd2ky&Bz{|kld>nHDj55`07KMNUu&M9pB
z=@&JDT7<f-K|L)&xlyL>f~YF(v<lxy49qrE)}!~cT1ah3SyTp94JZstnT+tWA64Lb
zRV+oHI2zHx$M96KI)#W*KqfOyc;yCT!P2f(^Sb8O5+bea=<4pM6-R}QY<I=tj}~RB
zs@bI)b7z&vG}YMPv?v^laq6g`jM+TZXOsd4s@RLYyD{%A-04$z1H(@Z;nBxwa4Di&
zx-34qp2ExCllSs~NxIR{AVTj!{we~9J<k3#$%$|8GMBZhh}7vd^Jv^}NbG~rf8%^4
z)N>@_x_v7fMF}kJG6d!)Ft3qBKh<F$2h_ZHJs|j)BTKbN9#p!062Pdv{ZrzoU}QEK
z7fD1!O(z!Y(%cIH)<=m~0OJWIl1EQ(GIVe?kniw*B#=Gx5I}(Nnm#gAf`fW;aUmfO
zC7xI)eYJQV+F7PZTWcQg)nhfF+R%F;U>^^F9222~97fHeuBWRSrk7;pGs}(BxpabS
zbY5Nu<xE(Sa(+?9v^##-z^6Z|@hfLmdX8UNS6TG<F0W;N;#7tc*mz7?t;;)YIj$7h
zhIoH;X!Z*AH@LF6b>PGQ(|*jq5a&<lXWMyre(^nZZm;(%xbFKfB(i(iL%H{=?~|%8
z&naWqJeaEhoRc0+Uwzt+o)ep0jRn7-Kt~(4>fJf>GzO|&g2AnE*2D-4u`JxG(pqwy
z7>H#P!zSiQz`Nrls1Qi2wAkmtu!h1nt85c|H<H#!bpUTCyRDQ-EmzTt1k-mV(zcnQ
zVVrm}U@Ma{!nNUm5$$KmE$~j0DPZ73v>`tXjXN=H((nm*=h%xXRhkP7bc3}tZdA@T
zQp`Y33mid!iij5ENX1=FWUL8toZ+=_=LxaZFir*yq69&&uoI1wM@a@Z(x_9JkI_3Q
zPt%44VFtaVXrl`l0=3ad9&kkudME&pvoVty)v6@>a!CwYk2kP*jgOZztPu<ML6e~+
zvc?D!3}QWzcfbO548rvijF95Dy{OYs$_==~3V8Bn$4#cz!g+-VD~UlRr~phFx`VwV
zimK~$WRF6Yqav@I>($CBDahYRP)=nPb5(kq1%Wo=CipiIcrlxRt_95CVv95;RDw)I
zxMB<$Qbj~kA*(M#-fkk(mrKa-Csc>YS4E<qYs=WpSpveo32h>RCP>L3cWlm5HRzhL
ztVCAEI%u|5UY*niZXSpyEYUyzDXYxME{Ze9alY8%Y*jE{U@(|qfebAgp~j)*hB%Y4
zv>Hg}bVitBEI+u0us9P8t#u)5h-M9WwghOxE0JCt{Mk--(58?X1BDy6OdYaRO=H*{
z7fBq~4n7KZ?9}BjU9g=h_xM=V?JN>qO-+qKwrQQw&V|PG>C?$?FRKImUX1>j4J2be
z6I?2|zBc-$wyo&FYEZ|MPD@sF_YlTv=Q5@U$|%(PF=UrwNr|-bxT;XvthaJpH5%)+
ztz<515|#qcY7NGiLF-MJaK?>Lz(MlD#tsutdvCW#aW_R+bnkj26<fzeBjJzPOb(I*
z8KP$`*Ypw5tlXAWndHa_Vw@n6qw%U}f)X}6>ZoE<I|ceTX^|m&h&X{`rTEQenZpTE
zT63abB{$*39}X3(Gztp_qZlVi;KCLWVcfB#ZPARNQVMhVYYbU-f^I%yHVfcsWfB94
zG(8)jRK`6H4aA8%7Tk8E$t&O?KY1Lij5(AsZL(X4QIII}Ky)xbBOqvz_cC&)0#091
z<<`JaCC}21inNC#DcyLxfHT`w<<O(qtkOu5ij3t&iV%`Tnuu|^tWLVCj{9-B2~EHl
z1^hq5p~gms|L5#bXfpoeL3#4Utkz1n=|B5PJpk63>uLH^)d=6GgD#aIyG=^Kpg+b0
zgI~KRNj-9#Q<Ioz#sPWCS|}#RVfe4vW1vlr>AC#}M2uHQPw#7d(ONncup9!+)|g<2
z*6a)~R!Y%x+wgmU_RdS<Xu=Yb7>X@2jv+FYj0ZSPSmK6F%c(K#SYczP6c=QgKLr3o
zdWE$vz%=QC%lw*lRx&au20C&?nrz6YGpltP(}>>EFoSGRQavo+6OA54A;=b3;i9}z
z;{eH%Ot>*3YsVK6w#oz+u+9((@(0ZxldmiM(P_0?L+h&?UzD5(jo+cP@~4WDZA$hR
z3dcW3gNx7D<KX%eGDac!-_RI#$p3IdWcH-|KNyc{{~=a^ml?=>vyUeMDJlloSsiCD
zj&}E`CLc->JcaUXc=#ihxAi3Tj2gPIRg5*bNrhv}z}aH6Y(ZhR@S0Y!m1uTCp)EVD
zxT&<R@epRhG(&7BsM(obs0)gMEqr!5w4ZbP!jcwy??{T-urw?Ey~MTHKjd%5w*vWF
zF|iJfm|WKcIjupNtqW<mTfln*R14tY7q6#qPeo4Z*g9a$w@e$ZxvBDiNWcKi`Hk0<
zK60CmDastOxLE@5lDCZd!JsBl>4knOwvNWzKqT$K7`rn_lVwHImC!pj1|f;r1mLo$
z4?xfZy*jwR#1>faTe0bekjE64&ZRy4LWSR7p;0#`1%V7Dh$CVaFxu(u7kUQ8Eqe21
zn?o^3uajI4@uVRz7feN4P#g!mT7-E}jZC(ZOm-wK?Wl~D2{F8s$?2&o_2PL+s=9?z
zzOlxW2urQ4^`+*WVhxdbv~w?5ew|%Kw?}gg00NE=JoO~CLJ|2jv_(PpVNfI}&o=Om
zlnnHuLh`@Q&V7X-|EHG!Aygll<&yv5`pNVEL3y0w7URQ|``KiciAMZn4hg7=P%0Dd
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
YFZzrAqQB@b`u{ZjU!B1#1po*F00@zL#sB~S

diff --git a/src/utils/KeyListOps/KeyListOps.h b/src/utils/KeyListOps/KeyListOps.h
index 3c26d2c2..5046ec18 100644
--- a/src/utils/KeyListOps/KeyListOps.h
+++ b/src/utils/KeyListOps/KeyListOps.h
@@ -18,10 +18,24 @@ public:
 	KeyListOps();
 
 	void setColumns(const QuickString &columns) { _columns = columns; }
+	void addColumns(const QuickString &newCols) {
+		if (!_columns.empty()) _columns += ",";
+		_columns += newCols;
+	}
 	void setOperations(const QuickString & operation) { _operations = operation; }
+	void addOperations(const QuickString &newOps) {
+		if (!_operations.empty()) _operations += ",";
+		_operations += newOps;
+	}
+
 	void setNullValue(const QuickString & nullValue) { _methods.setNullValue(nullValue); }
 	void setDelimStr(const QuickString & delimStr) { _methods.setDelimStr(delimStr); }
 
+	const QuickString &getColumns() { return _columns; }
+	const QuickString &getOperations() { return _operations; }
+	const QuickString &getNullValue() { return _methods.getNullValue(); }
+	const QuickString &getDelimStr() { return _methods.getDelimStr(); }
+
 	void setKeyList(RecordKeyList *keyList) { _methods.setKeyList(keyList); }
 
 	typedef enum { SUM, MEAN, STDDEV, SAMPLE_STDDEV, MEDIAN, MODE, ANTIMODE, MIN, MAX, ABSMIN, ABSMAX, COUNT, DISTINCT, COUNT_DISTINCT,
diff --git a/src/utils/NewChromsweep/NewChromsweep.cpp b/src/utils/NewChromsweep/NewChromsweep.cpp
index 5e6045be..c04fefb1 100644
--- a/src/utils/NewChromsweep/NewChromsweep.cpp
+++ b/src/utils/NewChromsweep/NewChromsweep.cpp
@@ -185,7 +185,7 @@ bool NewChromSweep::next(RecordKeyList &next) {
 void NewChromSweep::nextRecord(bool query) {
 	if (query) {
 //		if (!_context->getUseMergedIntervals()) {
-			_currQueryRec = _queryFRM->allocateAndGetNextRecord();
+			_currQueryRec = _queryFRM->getNextRecord();
 //		} else {
 //			_currQueryRec = _queryFRM->allocateAndGetNextMergedRecord(_context->getSameStrand() ? FileRecordMgr::SAME_STRAND_EITHER : FileRecordMgr::ANY_STRAND);
 //		}
@@ -194,7 +194,7 @@ void NewChromSweep::nextRecord(bool query) {
 		}
 	} else { //database
 //		if (!_context->getUseMergedIntervals()) {
-			_currDatabaseRec = _databaseFRM->allocateAndGetNextRecord();
+			_currDatabaseRec = _databaseFRM->getNextRecord();
 //		} else {
 //			_currDatabaseRec = _databaseFRM->allocateAndGetNextMergedRecord(_context->getSameStrand() ? FileRecordMgr::SAME_STRAND_EITHER : FileRecordMgr::ANY_STRAND);
 //		}
diff --git a/src/utils/RecordOutputMgr/RecordOutputMgr.cpp b/src/utils/RecordOutputMgr/RecordOutputMgr.cpp
index 55cb70ec..9ab8b52b 100644
--- a/src/utils/RecordOutputMgr/RecordOutputMgr.cpp
+++ b/src/utils/RecordOutputMgr/RecordOutputMgr.cpp
@@ -76,9 +76,15 @@ bool RecordOutputMgr::printKeyAndTerminate(RecordKeyList &keyList) {
 	if (bamCode == BAM_AS_BAM) {
 		return true;
 	} else if (bamCode == NOT_BAM) {
-		keyList.getKey()->print(_outBuf);
+		if (_context->getProgram() == ContextBase::MERGE) {
+			//when printing merged records, we want to force the printing into
+			//bed3 format, which is surprisingly difficult to do. Had to use the following:
+			const Bed3Interval *bed3 = static_cast<const Bed3Interval *>(keyList.getKey());
+			bed3->Bed3Interval::print(_outBuf);
+		} else {
+			keyList.getKey()->print(_outBuf);
+		}
 		return false;
-
 	}
 	//otherwise, it was BAM_AS_BED, and the key was printed.
 	return false;
@@ -114,6 +120,7 @@ void RecordOutputMgr::printRecord(const Record *record)
 
 void RecordOutputMgr::printRecord(const Record *record, const QuickString & value)
 {	
+	_afterVal = value;
 	printRecord(record);
 	_outBuf.append(value);
 	newline();
@@ -206,6 +213,17 @@ void RecordOutputMgr::printRecord(RecordKeyList &keyList, RecordKeyList *blockLi
 		}
 		_currBamBlockList = NULL;
 		return;
+	} else if (_context->getProgram() == ContextBase::MERGE) {
+		if (!printKeyAndTerminate(keyList)) {
+			if (_context->getDesiredStrand() != FileRecordMergeMgr::ANY_STRAND) {
+				//add the sign of the record
+				tab();
+				_outBuf.append(keyList.getKey()->getStrand());
+			}
+			if (!_afterVal.empty()) tab();
+		}
+		_currBamBlockList = NULL;
+		return;
 	}
 }
 
diff --git a/src/utils/RecordOutputMgr/RecordOutputMgr.h b/src/utils/RecordOutputMgr/RecordOutputMgr.h
index b6296fda..07891cc2 100644
--- a/src/utils/RecordOutputMgr/RecordOutputMgr.h
+++ b/src/utils/RecordOutputMgr/RecordOutputMgr.h
@@ -44,6 +44,7 @@ private:
 	//
 	BlockMgr *_bamBlockMgr;
 	const BlockMgr *_splitInfo;
+	QuickString _afterVal; //to store values to be printed after record, such as column operations.
 	//some helper functions to neaten the code.
 	void tab() { _outBuf.append('\t'); }
 	void newline() { _outBuf.append('\n'); }
diff --git a/src/utils/general/DualQueue.h b/src/utils/general/DualQueue.h
deleted file mode 100644
index 1cee4158..00000000
--- a/src/utils/general/DualQueue.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * DualQueue.h
- *
- *  Created on: Jan 29, 2013
- *      Author: nek3d
- */
-#ifdef false
-#ifndef DUALQUEUE_H_
-#define DUALQUEUE_H_
-
-using namespace std;
-
-#include <vector>
-#include <queue>
-#include <cstdio>
-#include <cstdlib>
-
-template <class T> class DualQueueAscending {
-public:
-	bool operator() ( const T &item1, const T &item2) const {
-
-		printf("\n\nIn comparison method:\n item1=\n");
-//		item1->print();
-		printf("\nitem2=\n");
-//		item2->print();
-		printf("\n");
-
-		if( *(item1) < *(item2) ) {
-			printf("Item1 less than item2. Returning false.\n");
-			return false;
-		}
-		printf("Item1 not less than item2. Returning true.\n");
-		return true;
-	}
-};
-
-template <class T> class DualQueueDescending {
-public:
-	bool operator() ( const T &item1, const T &item2) const {
-		if( *(item2) < *(item1) ) {
-			return false;
-		}
-		return true;
-	}
-};
-
-
-template <class T, template<class T> class CompareFunc> class DualQueue {
-public:
-	DualQueue() {}
-	~DualQueue() {}
-
-	const T & top() const {
-		if (empty()) {
-			fprintf(stderr, "ERROR. Tried to top from empty dualQueue.\n");
-			exit(1);
-		}
-		if (emptyForward()) {
-			return topReverse();
-		}
-		if (emptyReverse()) {
-			return topForward();
-		}
-
-		return (topFowardHigherPriorityThanTopReverse() ? topForward() : topReverse());
-	}
-	void pop() {
-		if (empty()) {
-			fprintf(stderr, "ERROR. Tried to pop from empty dualQueue.\n");
-			exit(1);
-		}
-		if (emptyForward()) {
-			popReverse();
-			return;
-		}
-		if (emptyReverse()) {
-			popForward();
-			return;
-		}
-		topFowardHigherPriorityThanTopReverse() ? popForward() : popReverse();
-	}
-	void push(const T &item) { item->getStrand() ? pushForward(item) : pushReverse(item); }
-	size_t size() const { return sizeForward() + sizeReverse(); }
-	bool empty() const { return _forwardQueue.empty() && _reverseQueue.empty(); }
-
-	const T & topForward() const { return _forwardQueue.top(); }
-	void popForward() { _forwardQueue.pop(); }
-	void pushForward(const T &item) { _forwardQueue.push(item); }
-	size_t sizeForward() const { return _forwardQueue.size(); }
-	bool emptyForward() const { return _forwardQueue.empty(); }
-
-
-	const T & topReverse() const { return _reverseQueue.top(); }
-	void popReverse() { _reverseQueue.pop(); }
-	void pushReverse(const T &item) { _reverseQueue.push(item); }
-	size_t sizeReverse() const { return _reverseQueue.size(); }
-	bool emptyReverse() const { return _reverseQueue.empty(); }
-
-
-private:
-	typedef priority_queue<T, vector<T>, CompareFunc<T> > queueType;
-	queueType _forwardQueue;
-	queueType _reverseQueue;
-
-	bool topFowardHigherPriorityThanTopReverse() const {
-		printf("\n\nIn priority method:\n TopForward=\n");
-//		topForward()->print();
-		printf("\nTopReverse=\n");
-//		topReverse()->print();
-		printf("\n");
-		if (CompareFunc<T>()(topForward(), topReverse())) {
-			printf("Forward higher priority than reverse.\n");
-			return true;
-		} else {
-			printf("Reverse higher priority than forward.\n");
-			return false;
-		}
-	}
-
-};
-
-
-#endif /* DUALQUEUE_H_ */
-#endif
diff --git a/src/utils/general/ParseTools.cpp b/src/utils/general/ParseTools.cpp
index ad5764b4..bef426a4 100644
--- a/src/utils/general/ParseTools.cpp
+++ b/src/utils/general/ParseTools.cpp
@@ -19,6 +19,9 @@ int str2chrPos(const QuickString &str) {
 }
 
 int str2chrPos(const char *str, size_t ulen) {
+	if (ulen == 0) {
+		ulen = strlen(str);
+	}
 	int len=(int)ulen;
 	if (len < 1 || len > 10) {
 		return INT_MIN; //can't do more than 9 digits and a minus sign
diff --git a/src/utils/general/ParseTools.h b/src/utils/general/ParseTools.h
index 2132d0e4..405d631a 100644
--- a/src/utils/general/ParseTools.h
+++ b/src/utils/general/ParseTools.h
@@ -22,7 +22,7 @@ bool isNumeric(const QuickString &str);
 //Empty strings, too long strings, or strings containing anything other than
 //digits (with the excpetion of a minus sign in the first position)
 //will result in error. Errors return INT_MIN.
-int str2chrPos(const char *str, size_t len);
+int str2chrPos(const char *str, size_t len = 0);
 int str2chrPos(const QuickString &str);
 
 
diff --git a/test/merge/test-merge.sh b/test/merge/test-merge.sh
index ee7f6290..165e1e86 100644
--- a/test/merge/test-merge.sh
+++ b/test/merge/test-merge.sh
@@ -30,18 +30,22 @@ $BT merge -i a.bed > obs
 check obs exp
 rm obs exp
 
-
+###########################################################
+#
+# NOTE: Testing for sorted input is now deprecated, as the
+# FileRecordMgr is already testing for that.
+#
 ###########################################################
 # Test #2
 #  Enforce coordinate sorted input.
 ###########################################################
-echo "    merge.t2...\c"
-command -v tac 2>/dev/null || alias tac="sed '1!G;h;\$!d'"
-tac a.bed | $BT merge -i - 2> obs
-echo "ERROR: input file: (-) is not sorted by chrom then start.
-       The start coordinate at line 3 is less than the start at line 2" > exp
-check obs exp
-rm obs exp
+#echo "    merge.t2...\c"
+#command -v tac 2>/dev/null || alias tac="sed '1!G;h;\$!d'"
+#tac a.bed | $BT merge -i - 2> obs
+#echo "ERROR: input file: (-) is not sorted by chrom then start.
+#       The start coordinate at line 3 is less than the start at line 2" > exp
+#check obs exp
+#rm obs exp
 
 
 ###########################################################
@@ -64,11 +68,9 @@ rm obs exp
 ###########################################################
 echo "    merge.t4...\c"
 echo \
-"chr1	10	20
-*****
-*****ERROR: No names found to report for the -names option. Exiting.
-*****" > exp
-$BT merge -i a.bed -nms > obs 2>&1
+"*****
+***** ERROR: Requested column 4, but database file a.bed only has fields 1 - 3." > exp
+$BT merge -i a.bed -nms 2>&1 > /dev/null | head -3 | tail -2 > obs
 check obs exp
 rm obs exp
 
@@ -130,7 +132,7 @@ chr1	30	100	a2,a3,a4	9	3
 chr2	10	20	a1	5	1
 chr2	30	40	a2	6	1
 chr2	42	100	a3,a4	15	2" > exp
-$BT merge -i a.full.bed -nms -n -scores sum> obs
+$BT merge -i a.full.bed -nms -scores sum -n> obs
 check obs exp
 rm obs exp
 
@@ -139,15 +141,15 @@ rm obs exp
 ###########################################################
 echo "    merge.t9...\c"
 echo \
-"chr1	10	20	a1	1	+	1
-chr1	30	40	a2	2	+	1
-chr1	45	100	a4	4	+	1
-chr1	40	50	a3	3	-	1
-chr2	10	20	a1	5	+	1
-chr2	30	40	a2	6	+	1
-chr2	42	50	a3	7	+	1
-chr2	45	100	a4	8	-	1" > exp
-$BT merge -i a.full.bed -s -nms -n -scores sum> obs
+"chr1	10	20	+	a1	1	1
+chr1	30	40	+	a2	2	1
+chr1	40	50	-	a3	3	1
+chr1	45	100	+	a4	4	1
+chr2	10	20	+	a1	5	1
+chr2	30	40	+	a2	6	1
+chr2	42	50	+	a3	7	1
+chr2	45	100	-	a4	8	1" > exp
+$BT merge -i a.full.bed -s -nms -scores sum -n> obs
 check obs exp
 rm obs exp
 
-- 
GitLab