diff --git a/lib/decoding/Vector.h b/lib/decoding/Vector.h
index 88ab654..23b4dd3 100644
--- a/lib/decoding/Vector.h
+++ b/lib/decoding/Vector.h
@@ -1,23 +1,23 @@
 /**@file Simplified Vector template with aliases. */
 /*
 * Copyright 2008 Free Software Foundation, Inc.
+* Copyright 2014 Range Networks, Inc.
 *
-* This software is distributed under the terms of the GNU Public License.
+* This software is distributed under the terms of the GNU Affero Public License.
 * See the COPYING file in the main directory for details.
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+        This program is free software: you can redistribute it and/or modify
+        it under the terms of the GNU Affero General Public License as published by
+        the Free Software Foundation, either version 3 of the License, or
+        (at your option) any later version.
+        This program is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+        GNU Affero General Public License for more details.
+        You should have received a copy of the GNU Affero General Public License
+        along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
@@ -29,216 +29,358 @@
 #include <string.h>
 #include <iostream>
 #include <assert.h>
+#include <stdio.h>
+// We cant use Logger.h in this file...
+extern int gVectorDebug;
+//#define ENABLE_VECTORDEBUG
+#ifdef ENABLE_VECTORDEBUG
+#define VECTORDEBUG(...) { printf(__VA_ARGS__); printf(" this=%p [%p,%p,%p]\n",(void*)this,(void*)&mData,mStart,mEnd); }
+//#define VECTORDEBUG(msg) { std::cout<<msg<<std::endl; }
+#else
+#define VECTORDEBUG(...)
+#endif
+
+#define BITVECTOR_REFCNTS 0
+
+#if BITVECTOR_REFCNTS
+// (pat) Started to add refcnts, decided against it for now.
+template <class T> class RCData : public RefCntBase {
+        public:
+        T* mPointer;
+};
+#endif
+
 
 /**
-	A simplified Vector template with aliases.
-	Unlike std::vector, this class does not support dynamic resizing.
-	Unlike std::vector, this class does support "aliases" and subvectors.
+        A simplified Vector template with aliases.
+        Unlike std::vector, this class does not support dynamic resizing.
+        Unlike std::vector, this class does support "aliases" and subvectors.
 */
-template <class T> class Vector {
+// (pat) Nov 2013:  Vector and the derived classes BitVector and SoftVector were originally written with behavior
+// that differed for const and non-const cases, making them very difficult to use and resulting in many extremely
+// difficult to find bugs in the code base.
+// Ultimately these classes should all be converted to reference counted methodologies, but as an interim measure
+// I am rationalizing their behavior until we flush out all places in the code base that inadvertently depended
+// on the original behavior.  This is done with assert statements in BitVector methods.
+// ====
+// What the behavior was probably supposed to be:
+//              Vectors can 'own' the data they point to or not.  Only one Vector 'owns' the memory at a time,
+//              so that automatic destruction can be used.  So whenever there is an operation that yields one
+//              vector from another the options were: clone (allocate a new vector from memory), alias (make the
+//              new vector point into the memory of the original vector) or shift (the new Vector steals the
+//              memory ownership from the original vector.)
+//              The const copy-constructor did a clone, the non-const copy constructor did a shiftMem, and the segment and
+//              related methods (head, tail, etc) returned aliases.
+//              Since a copy-constructor is inserted transparently in sometimes surprising places, this made the
+//              class very difficult to use.  Moreover, since the C++ standard specifies that a copy-constructor is used
+//              to copy the return value from functions, it makes it literally impossible for a function to fully control
+//              the return value.  Our code has relied on the "Return Value Optimization" which says that the C++ compiler
+//              may omit the copy-construction of the return value even if the copy-constructor has side-effects, which ours does.
+//              This methodology is fundamentally incompatible with C++.
+// What the original behavior actually was:
+//      class Vector:
+//              The copy-constructor and assignment operators did a clone for the const case and a shift for the non-const case.
+//                      This is really horrible.
+//              The segment methods were identical for const and non-const cases, always returning an alias.
+//              This also resulted in zillions of redundant mallocs and copies throughout the code base.
+//      class BitVector:
+//              Copy-constructor:
+//                      BitVector did not have any copy-constructors, and I think the intent was that it would have the same behavior
+//                      as Vector, but that is not how C++ works: with no copy-constructor the default copy-constructor
+//                      uses only the const case, so only the const Vector copy-constructor was used.  Therefore it always cloned,
+//                      and the code base relied heavily on the "Return Value Optimization" to work at all.
+//              Assignment operator:
+//                      BitVector did not have one, so C++ makes a default one that calls Vector::operator=() as a side effect,
+//                      which did a clone; not sure if there was a non-const version and no longer care.
+//              segment methods:
+//                      The non-const segment() returned an alias, and the const segment() returned a clone.
+//                      I think the intent was that the behavior should be the same as Vector, but there was a conversion
+//                      of the result of the const segment() method from Vector to BitVector which caused the Vector copy-constructor
+//                      to be (inadvertently) invoked, resulting in the const version of the segment method returning a clone.
+// What the behavior is now:
+//      VectorBase:
+//              There is a new VectorBase class that has only the common methods and extremely basic constructors.
+//              The VectorBase class MUST NOT CONTAIN: copy constructors, non-trivial constructors called from derived classes,
+//              or any method that returns a VectorBase type object.  Why?  Because any of the above when used in derived classes
+//              can cause copy-constructor invocation, often surprisingly, obfuscating the code.
+//              Each derived class must provide its own: copy-constructors and segment() and related methods, since we do not
+//              want to inadvertently invoke a copy-constructor to convert the segment() result from VectorBase to the derived type.
+//      BitVector:
+//              The BitVector copy-constructor and assignment operator (inherited from VectorBase) paradigm is:
+//              if the copied Vector owned memory, perform a clone so the new vector owns memory also,
+//              otherwise just do a simple copy, which is another alias.  This isnt perfect but works every place
+//              in our code base and easier to use than the previous paradigm.
+//              The segment method always returns an alias.
+//              If you want a clone of a segment, use cloneSegment(), which replaces the previous: const segment(...) const method.
+//              Note that the semantics of cloneSegment still rely on the Return Value Optimization.  Oh well, we should use refcnts.
+//      Vector:
+//              I left Vector alone (except for rearrangement to separate out VectorBase.)  Vector should just not be used.
+//      SoftVector:
+//              SoftVector and signalVector should be updated similar to BitVector, but I did not want to disturb them.
+// What the behavior should be:
+//              All these should be reference-counted, similar to ByteVector.
+template <class T> class VectorBase
+{
+        // TODO -- Replace memcpy calls with for-loops. (pat) in case class T is not POD [Plain Old Data]
 
-	// TODO -- Replace memcpy calls with for-loops.
+        protected:
+#if BITVECTOR_REFCNTS
+        typedef RefCntPointer<RCData<T> > VectorDataType;
+#else
+        typedef T* VectorDataType;
+#endif
+        VectorDataType mData;           ///< allocated data block.
+        T* mStart;              ///< start of useful data
+        T* mEnd;                ///< end of useful data + 1
 
-	public:
+        // Init vector with specified size.  Previous contents are completely discarded.  This is only used for initialization.
+        void vInit(size_t elements)
+        {
+                mData = elements ? new T[elements] : NULL;
+                mStart = mData;  // This is where mStart get set to zero
+                mEnd = mStart + elements;
+        }
 
-	/**@name Iterator types. */
-	//@{
-	typedef T* iterator;
-	typedef const T* const_iterator;
-	//@}
+        /** Assign from another Vector, shifting ownership. */
+        // (pat) This should be eliminated, but it is used by Vector and descendents.
+        void shiftMem(VectorBase<T>&other)
+        {
+                VECTORDEBUG("VectorBase::shiftMem(%p)",(void*)&other);
+                this->clear();
+                this->mData=other.mData;
+                this->mStart=other.mStart;
+                this->mEnd=other.mEnd;
+                other.mData=NULL;
+        }
 
-	protected:
+        // Assign from another Vector, making this an alias to other.
+        void makeAlias(const VectorBase<T> &other)
+        {
+                if (this->getData()) {
+                        assert(this->getData() != other.getData()); // Not possible by the semantics of Vector.
+                        this->clear();
+                }
+                this->mStart=const_cast<T*>(other.mStart);
+                this->mEnd=const_cast<T*>(other.mEnd);
+        }
 
-	T* mData;		///< allocated data block, if any
-	T* mStart;		///< start of useful data
-	T* mEnd;		///< end of useful data + 1
+        public:
 
-	public:
+        /** Return the size of the Vector in units, ie, the number of T elements. */
+        size_t size() const
+        {
+                assert(mStart>=mData);
+                assert(mEnd>=mStart);
+                return mEnd - mStart;
+        }
 
-	/** Return the size of the Vector. */
-	size_t size() const
-	{
-		assert(mStart>=mData);
-		assert(mEnd>=mStart);
-		return mEnd - mStart;
-	}
+        /** Return size in bytes. */
+        size_t bytes() const { return this->size()*sizeof(T); }
 
-	/** Return size in bytes. */
-	size_t bytes() const { return size()*sizeof(T); }
+        /** Change the size of the Vector in items (not bytes), discarding content. */
+        void resize(size_t newElements) {
+                //VECTORDEBUG("VectorBase::resize("<<(void*)this<<","<<newElements<<")");
+                VECTORDEBUG("VectorBase::resize(%p,%d) %s",this,newElements, (mData?"delete":""));
+                if (mData!=NULL) delete[] mData;
+                vInit(newElements);
+        }
 
-	/** Change the size of the Vector, discarding content. */
-	void resize(size_t newSize)
-	{
-		if (mData!=NULL) delete[] mData;
-		if (newSize==0) mData=NULL;
-		else mData = new T[newSize];
-		mStart = mData;
-		mEnd = mStart + newSize;
-	}
-
-	/** Release memory and clear pointers. */
-	void clear() { resize(0); }
+        /** Release memory and clear pointers. */
+        void clear() { this->resize(0); }
 
 
-	/** Copy data from another vector. */
-	void clone(const Vector<T>& other)
-	{
-		resize(other.size());
-		memcpy(mData,other.mStart,other.bytes());
-	}
+        /** Copy data from another vector. */
+        void clone(const VectorBase<T>& other) {
+                this->resize(other.size());
+                memcpy(mData,other.mStart,other.bytes());
+        }
+
+        void vConcat(const VectorBase<T>&other1, const VectorBase<T>&other2) {
+                this->resize(other1.size()+other2.size());
+                memcpy(this->mStart, other1.mStart, other1.bytes());
+                memcpy(this->mStart+other1.size(), other2.mStart, other2.bytes());
+        }
+
+        protected:
+
+        VectorBase() : mData(0), mStart(0), mEnd(0) {}
+
+        /** Build a Vector with explicit values. */
+        VectorBase(VectorDataType wData, T* wStart, T* wEnd) :mData(wData),mStart(wStart),mEnd(wEnd) {
+                //VECTORDEBUG("VectorBase("<<(void*)wData);
+                VECTORDEBUG("VectorBase(%p,%p,%p)",this->getData(),wStart,wEnd);
+        }
+
+        public:
+
+        /** Destroy a Vector, deleting held memory. */
+        ~VectorBase() {
+                //VECTORDEBUG("~VectorBase("<<(void*)this<<")");
+                VECTORDEBUG("~VectorBase(%p)",this);
+                this->clear();
+        }
+
+        bool isOwner() { return !!this->mData; }        // Do we own any memory ourselves?
+
+        std::string inspect() const {
+                char buf[100];
+                snprintf(buf,100," mData=%p mStart=%p mEnd=%p ",(void*)mData,mStart,mEnd);
+                return std::string(buf);
+        }
 
 
+        /**
+                Copy part of this Vector to a segment of another Vector.
+                @param other The other vector.
+                @param start The start point in the other vector.
+                @param span The number of elements to copy.
+        */
+        void copyToSegment(VectorBase<T>& other, size_t start, size_t span) const
+        {
+                T* base = other.mStart + start;
+                assert(base+span<=other.mEnd);
+                assert(mStart+span<=mEnd);
+                memcpy(base,mStart,span*sizeof(T));
+        }
+
+        /** Copy all of this Vector to a segment of another Vector. */
+        void copyToSegment(VectorBase<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
+
+        void copyTo(VectorBase<T>& other) const { copyToSegment(other,0,size()); }
+
+        /**
+                Copy a segment of this vector into another.
+                @param other The other vector (to copt into starting at 0.)
+                @param start The start point in this vector.
+                @param span The number of elements to copy.
+                WARNING: This function does NOT resize the result - you must set the result size before entering.
+        */
+        void segmentCopyTo(VectorBase<T>& other, size_t start, size_t span) const
+        {
+                const T* base = mStart + start;
+                assert(base+span<=mEnd);
+                assert(other.mStart+span<=other.mEnd);
+                memcpy(other.mStart,base,span*sizeof(T));
+        }
+
+        void fill(const T& val)
+        {
+                T* dp=mStart;
+                while (dp<mEnd) *dp++=val;
+        }
+
+        void fill(const T& val, unsigned start, unsigned length)
+        {
+                T* dp=mStart+start;
+                T* end=dp+length;
+                assert(end<=mEnd);
+                while (dp<end) *dp++=val;
+        }
+
+        /** Assign from another Vector. */
+        // (pat) This is used for both const and non-const cases.
+        // If the original vector owned memory, clone it, otherwise just copy the segment data.
+        void operator=(const VectorBase<T>& other) {
+                //std::cout << "Vector=(this="<<this->inspect()<<",other="<<other.inspect()<<")"<<endl;
+                if (other.getData()) {
+                        this->clone(other);
+                } else {
+                        this->makeAlias(other);
+                }
+                //std::cout << "Vector= after(this="<<this->inspect()<<")"<<endl;
+        }
 
 
-	//@{
+        T& operator[](size_t index)
+        {
+                assert(mStart+index<mEnd);
+                return mStart[index];
+        }
 
-	/** Build an empty Vector of a given size. */
-	Vector(size_t wSize=0):mData(NULL) { resize(wSize); }
+        const T& operator[](size_t index) const
+        {
+                assert(mStart+index<mEnd);
+                return mStart[index];
+        }
 
-	/** Build a Vector by shifting the data block. */
-	Vector(Vector<T>& other)
-		:mData(other.mData),mStart(other.mStart),mEnd(other.mEnd)
-	{ other.mData=NULL; }
-
-	/** Build a Vector by copying another. */
-	Vector(const Vector<T>& other):mData(NULL) { clone(other); }
-
-	/** Build a Vector with explicit values. */
-	Vector(T* wData, T* wStart, T* wEnd)
-		:mData(wData),mStart(wStart),mEnd(wEnd)
-	{ }
-
-	/** Build a vector from an existing block, NOT to be deleted upon destruction. */
-	Vector(T* wStart, size_t span)
-		:mData(NULL),mStart(wStart),mEnd(wStart+span)
-	{ }
-
-	/** Build a Vector by concatenation. */
-	Vector(const Vector<T>& other1, const Vector<T>& other2)
-		:mData(NULL)
-	{
-		resize(other1.size()+other2.size());
-		memcpy(mStart, other1.mStart, other1.bytes());
-		memcpy(mStart+other1.size(), other2.mStart, other2.bytes());
-	}
-
-	//@}
-
-	/** Destroy a Vector, deleting held memory. */
-	~Vector() { clear(); }
-
-
-
-
-	//@{
-
-	/** Assign from another Vector, shifting ownership. */
-	void operator=(Vector<T>& other)
-	{
-		clear();
-		mData=other.mData;
-		mStart=other.mStart;
-		mEnd=other.mEnd;
-		other.mData=NULL;
-	}
-
-	/** Assign from another Vector, copying. */
-	void operator=(const Vector<T>& other) { clone(other); }
-
-	//@}
-
-
-	//@{
-
-	/** Return an alias to a segment of this Vector. */
-	Vector<T> segment(size_t start, size_t span)
-	{
-		T* wStart = mStart + start;
-		T* wEnd = wStart + span;
-		assert(wEnd<=mEnd);
-		return Vector<T>(NULL,wStart,wEnd);
-	}
-
-	/** Return an alias to a segment of this Vector. */
-	const Vector<T> segment(size_t start, size_t span) const
-	{
-		T* wStart = mStart + start;
-		T* wEnd = wStart + span;
-		assert(wEnd<=mEnd);
-		return Vector<T>(NULL,wStart,wEnd);
-	}
-
-	Vector<T> head(size_t span) { return segment(0,span); }
-	const Vector<T> head(size_t span) const { return segment(0,span); }
-	Vector<T> tail(size_t start) { return segment(start,size()-start); }
-	const Vector<T> tail(size_t start) const { return segment(start,size()-start); }
-
-	/**
-		Copy part of this Vector to a segment of another Vector.
-		@param other The other vector.
-		@param start The start point in the other vector.
-		@param span The number of elements to copy.
-	*/
-	void copyToSegment(Vector<T>& other, size_t start, size_t span) const
-	{
-		T* base = other.mStart + start;
-		assert(base+span<=other.mEnd);
-		assert(mStart+span<=mEnd);
-		memcpy(base,mStart,span*sizeof(T));
-	}
-
-	/** Copy all of this Vector to a segment of another Vector. */
-	void copyToSegment(Vector<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
-
-	void copyTo(Vector<T>& other) const { copyToSegment(other,0,size()); }
-
-	/**
-		Copy a segment of this vector into another.
-		@param other The other vector (to copt into starting at 0.)
-		@param start The start point in this vector.
-		@param span The number of elements to copy.
-	*/
-	void segmentCopyTo(Vector<T>& other, size_t start, size_t span)
-	{
-		T* base = mStart + start;
-		assert(base+span<=mEnd);
-		assert(other.mStart+span<=other.mEnd);
-		memcpy(other.mStart,base,span*sizeof(T));
-	}
-
-	void fill(const T& val)
-	{
-		T* dp=mStart;
-		while (dp<mEnd) *dp++=val;
-	}
-
-
-	//@}
-
-
-	//@{
-
-	T& operator[](size_t index)
-	{
-		assert(mStart+index<mEnd);
-		return mStart[index];
-	}
-
-	const T& operator[](size_t index) const
-	{
-		assert(mStart+index<mEnd);
-		return mStart[index];
-	}
-
-	const T* begin() const { return mStart; }
-	T* begin() { return mStart; }
-	const T* end() const { return mEnd; }
-	T* end() { return mEnd; }
-	//@}
-
-
+        const T* begin() const { return this->mStart; }
+        T* begin() { return this->mStart; }
+        const T* end() const { return this->mEnd; }
+        T* end() { return this->mEnd; }
+#if BITVECTOR_REFCNTS
+        const T*getData() const { return this->mData.isNULL() ? 0 : this->mData->mPointer; }
+#else
+        const T*getData() const { return this->mData; }
+#endif
 };
 
+// (pat) Nov 2013.  This class retains the original poor behavior.  See comments at VectorBase
+template <class T> class Vector : public VectorBase<T>
+{
+        public:
+
+        /** Build an empty Vector of a given size. */
+        Vector(size_t wSize=0) { this->resize(wSize); }
+
+        /** Build a Vector by shifting the data block. */
+        Vector(Vector<T>& other) : VectorBase<T>(other.mData,other.mStart,other.mEnd) { other.mData=NULL; }
+
+        /** Build a Vector by copying another. */
+        Vector(const Vector<T>& other):VectorBase<T>() { this->clone(other); }
+
+        /** Build a Vector with explicit values. */
+        Vector(T* wData, T* wStart, T* wEnd) : VectorBase<T>(wData,wStart,wEnd) { }
+
+        /** Build a vector from an existing block, NOT to be deleted upon destruction. */
+        Vector(T* wStart, size_t span) : VectorBase<T>(NULL,wStart,wStart+span) { }
+
+        /** Build a Vector by concatenation. */
+        Vector(const Vector<T>& other1, const Vector<T>& other2):VectorBase<T>() {
+                assert(this->mData == 0);
+                this->vConcat(other1,other2);
+        }
+
+        //@{
+
+        /** Assign from another Vector, shifting ownership. */
+        void operator=(Vector<T>& other) { this->shiftMem(other); }
+
+        /** Assign from another Vector, copying. */
+        void operator=(const Vector<T>& other) { this->clone(other); }
+
+        /** Return an alias to a segment of this Vector. */
+        Vector<T> segment(size_t start, size_t span)
+        {
+                T* wStart = this->mStart + start;
+                T* wEnd = wStart + span;
+                assert(wEnd<=this->mEnd);
+                return Vector<T>(NULL,wStart,wEnd);
+        }
+
+        /** Return an alias to a segment of this Vector. */
+        const Vector<T> segment(size_t start, size_t span) const
+        {
+                T* wStart = this->mStart + start;
+                T* wEnd = wStart + span;
+                assert(wEnd<=this->mEnd);
+                return Vector<T>(NULL,wStart,wEnd);
+        }
+
+        Vector<T> head(size_t span) { return segment(0,span); }
+        const Vector<T> head(size_t span) const { return segment(0,span); }
+        Vector<T> tail(size_t start) { return segment(start,this->size()-start); }
+        const Vector<T> tail(size_t start) const { return segment(start,this->size()-start); }
+
+        /**@name Iterator types. */
+        //@{
+        typedef T* iterator;
+        typedef const T* const_iterator;
+        //@}
+
+        //@}
+};
+
+
 
 
 
@@ -246,8 +388,8 @@
 template <class T>
 std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
 {
-	for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
-	return os;
+        for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
+        return os;
 }
 
 
