diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h
index 97757097758d85b050ce3f1a78373f04c0422f3b..a202a7c4e26195541780509d69e58069a0e5d3b2 100644
--- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h
+++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h
@@ -1,134 +1,182 @@
 #ifndef __ADARA_H
 #define __ADARA_H
 
+//
+// SNS ADARA SYSTEM - Common Library
+// 
+// This repository contains the software for the next-generation Data
+// Acquisition System (DAS) at the Spallation Neutron Source (SNS) at
+// Oak Ridge National Laboratory (ORNL) -- "ADARA".
+// 
+// Copyright (c) 2015, UT-Battelle LLC
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+
 #include <string>
 #include <stdexcept>
 
 namespace ADARA {
 
-const std::string VERSION = "1.1.0";
+const std::string VERSION = "1.3.0";
+const std::string TAG_NAME = "XXX_TAG_NAME_XXX";
 
-#define ADARA_PKT_TYPE(type, ver) ((((uint32_t)type) << 8) | (ver))
+#define ADARA_PKT_TYPE(type, ver)  ((((uint32_t) type) << 8) | (ver))
 namespace PacketType {
-enum Enum {
-  RAW_EVENT_V0 = ADARA_PKT_TYPE(0x0000, 0),
-  RTDL_V0 = ADARA_PKT_TYPE(0x0001, 0),
-  SOURCE_LIST_V0 = ADARA_PKT_TYPE(0x0002, 0),
-  BANKED_EVENT_V0 = ADARA_PKT_TYPE(0x4000, 0),
-  BEAM_MONITOR_EVENT_V0 = ADARA_PKT_TYPE(0x4001, 0),
-  PIXEL_MAPPING_V0 = ADARA_PKT_TYPE(0x4002, 0),
-  RUN_STATUS_V0 = ADARA_PKT_TYPE(0x4003, 0),
-  RUN_INFO_V0 = ADARA_PKT_TYPE(0x4004, 0),
-  TRANS_COMPLETE_V0 = ADARA_PKT_TYPE(0x4005, 0),
-  CLIENT_HELLO_V0 = ADARA_PKT_TYPE(0x4006, 0),
-  STREAM_ANNOTATION_V0 = ADARA_PKT_TYPE(0x4007, 0),
-  SYNC_V0 = ADARA_PKT_TYPE(0x4008, 0),
-  HEARTBEAT_V0 = ADARA_PKT_TYPE(0x4009, 0),
-  GEOMETRY_V0 = ADARA_PKT_TYPE(0x400A, 0),
-  BEAMLINE_INFO_V0 = ADARA_PKT_TYPE(0x400B, 0),
-  DEVICE_DESC_V0 = ADARA_PKT_TYPE(0x8000, 0),
-  VAR_VALUE_U32_V0 = ADARA_PKT_TYPE(0x8001, 0),
-  VAR_VALUE_DOUBLE_V0 = ADARA_PKT_TYPE(0x8002, 0),
-  VAR_VALUE_STRING_V0 = ADARA_PKT_TYPE(0x8003, 0)
-};
+	enum Enum {
+		RAW_EVENT_V0		= ADARA_PKT_TYPE(0x0000, 0),
+		RTDL_V0			= ADARA_PKT_TYPE(0x0001, 0),
+		SOURCE_LIST_V0		= ADARA_PKT_TYPE(0x0002, 0),
+		MAPPED_EVENT_V0		= ADARA_PKT_TYPE(0x0003, 0),
+		BANKED_EVENT_V0		= ADARA_PKT_TYPE(0x4000, 0),
+		BANKED_EVENT_V1		= ADARA_PKT_TYPE(0x4000, 1),
+		BEAM_MONITOR_EVENT_V0	= ADARA_PKT_TYPE(0x4001, 0),
+		BEAM_MONITOR_EVENT_V1	= ADARA_PKT_TYPE(0x4001, 1),
+		PIXEL_MAPPING_V0	= ADARA_PKT_TYPE(0x4002, 0),
+		RUN_STATUS_V0		= ADARA_PKT_TYPE(0x4003, 0),
+		RUN_INFO_V0		= ADARA_PKT_TYPE(0x4004, 0),
+		TRANS_COMPLETE_V0	= ADARA_PKT_TYPE(0x4005, 0),
+		CLIENT_HELLO_V0		= ADARA_PKT_TYPE(0x4006, 0),
+		STREAM_ANNOTATION_V0	= ADARA_PKT_TYPE(0x4007, 0),
+		SYNC_V0			= ADARA_PKT_TYPE(0x4008, 0),
+		HEARTBEAT_V0		= ADARA_PKT_TYPE(0x4009, 0),
+		GEOMETRY_V0		= ADARA_PKT_TYPE(0x400A, 0),
+		BEAMLINE_INFO_V0	= ADARA_PKT_TYPE(0x400B, 0),
+		BEAMLINE_INFO_V1	= ADARA_PKT_TYPE(0x400B, 1),
+		DATA_DONE_V0		= ADARA_PKT_TYPE(0x400C, 0),
+		BEAM_MONITOR_CONFIG_V0	= ADARA_PKT_TYPE(0x400D, 0),
+		DETECTOR_BANK_SETS_V0	= ADARA_PKT_TYPE(0x400E, 0),
+		DEVICE_DESC_V0		= ADARA_PKT_TYPE(0x8000, 0),
+		VAR_VALUE_U32_V0	= ADARA_PKT_TYPE(0x8001, 0),
+		VAR_VALUE_DOUBLE_V0	= ADARA_PKT_TYPE(0x8002, 0),
+		VAR_VALUE_STRING_V0	= ADARA_PKT_TYPE(0x8003, 0),
+	};
 }
 
 /* These are defined in the SNS Timing Master Functional System Description,
  * section 1.3.4.
  */
 namespace PulseFlavor {
-enum Enum {
-  NO_BEAM = 0,
-  NORMAL = 1,
-  NORMAL_TGT_1 = 1,
-  NORMAL_TGT_2 = 2,
-  DIAG_10us = 3,
-  DIAG_50us = 4,
-  DIAG_100us = 5,
-  SPECIAL_PHYSICS_1 = 6,
-  SPECIAL_PHYSICS_2 = 7
-};
+	enum Enum {
+		NO_BEAM		  = 0,
+		NORMAL		  = 1,
+		NORMAL_TGT_1	  = 1,
+		NORMAL_TGT_2	  = 2,
+		DIAG_10us	  = 3,
+		DIAG_50us	  = 4,
+		DIAG_100us	  = 5,
+		SPECIAL_PHYSICS_1 = 6,
+		SPECIAL_PHYSICS_2 = 7
+	};
 }
 
 namespace RunStatus {
-enum Enum {
-  NO_RUN = 0,
-  NEW_RUN = 1,
-  RUN_EOF = 2,
-  RUN_BOF = 3,
-  END_RUN = 4,
-  STATE = 5
-};
+	enum Enum {
+		NO_RUN	= 0,
+		NEW_RUN	= 1,
+		RUN_EOF	= 2,
+		RUN_BOF	= 3,
+		END_RUN	= 4,
+		STATE	= 5,
+	};
 }
 
 namespace VariableStatus {
-enum Enum {
-  OK = 0, // EPICS: NO_ALARM
-  READ_ERROR = 1,
-  WRITE_ERROR = 2,
-  HIHI_LIMIT = 3,
-  HIGH_LIMIT = 4,
-  LOLO_LIMIT = 5,
-  LOW_LIMIT = 6,
-  BAD_STATE = 7,
-  CHANGED_STATE = 8,
-  NO_COMMUNICATION = 9,
-  COMMUNICATION_TIMEOUT = 10,
-  HARDWARE_LIMIT = 11,
-  BAD_CALCULATION = 12,
-  INVALID_SCAN = 13,
-  LINK_FAILED = 14,
-  INVALID_STATE = 15,
-  BAD_SUBROUTINE = 16,
-  UNDEFINED_ALARM = 17,
-  DISABLED = 18,
-  SIMULATED = 19,
-  READ_PERMISSION = 20,
-  WRITE_PERMISSION = 21,
-  UPSTREAM_DISCONNECTED = 0xfffe,
-  NOT_REPORTED = 0xffff
-};
+	enum Enum {
+		OK			= 0,	// EPICS: NO_ALARM
+		READ_ERROR		= 1,
+		WRITE_ERROR		= 2,
+		HIHI_LIMIT		= 3,
+		HIGH_LIMIT		= 4,
+		LOLO_LIMIT		= 5,
+		LOW_LIMIT		= 6,
+		BAD_STATE		= 7,
+		CHANGED_STATE		= 8,
+		NO_COMMUNICATION	= 9,
+		COMMUNICATION_TIMEOUT	= 10,
+		HARDWARE_LIMIT		= 11,
+		BAD_CALCULATION		= 12,
+		INVALID_SCAN		= 13,
+		LINK_FAILED		= 14,
+		INVALID_STATE		= 15,
+		BAD_SUBROUTINE		= 16,
+		UNDEFINED_ALARM		= 17,
+		DISABLED		= 18,
+		SIMULATED		= 19,
+		READ_PERMISSION		= 20,
+		WRITE_PERMISSION	= 21,
+		UPSTREAM_DISCONNECTED	= 0xfffe,
+		NOT_REPORTED		= 0xffff,
+	};
 }
 
 namespace VariableSeverity {
-enum Enum {
-  OK = 0, // EPICS: NO_ALARM
-  MINOR_ALARM = 1,
-  MAJOR_ALARM = 2,
-  INVALID = 3,
-  NOT_REPORTED = 0xffff
-};
+	enum Enum {
+		OK			= 0,	// EPICS: NO_ALARM
+		MINOR_ALARM		= 1,
+		MAJOR_ALARM		= 2,
+		INVALID			= 3,
+		NOT_REPORTED		= 0xffff,
+	};
 }
 
 namespace MarkerType {
-enum Enum {
-  GENERIC,
-  SCAN_START,
-  SCAN_STOP,
-  PAUSE,
-  RESUME,
-  OVERALL_RUN_COMMENT
-};
+	enum Enum {
+		GENERIC,
+		SCAN_START,
+		SCAN_STOP,
+		PAUSE,
+		RESUME,
+		OVERALL_RUN_COMMENT,
+	};
 }
 
 struct Event {
-  uint32_t tof;
-  uint32_t pixel;
+	uint32_t tof;
+	uint32_t pixel;
 };
 
 struct Header {
-  uint32_t payload_len;
-  uint32_t pkt_format;
-  uint32_t ts_sec;
-  uint32_t ts_nsec;
+	uint32_t payload_len;
+	uint32_t pkt_format;
+	uint32_t ts_sec;
+	uint32_t ts_nsec;
 };
 
 class invalid_packet : public std::runtime_error {
 public:
-  explicit invalid_packet(const std::string &msg) : runtime_error(msg) {}
+	explicit invalid_packet(const std::string &msg) : runtime_error(msg) {}
 };
 
-enum { EPICS_EPOCH_OFFSET = 631152000 };
+enum {
+	EPICS_EPOCH_OFFSET = 631152000
+};
 
 } /* namespace ADARA */
 
diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h
index 9a616c43892aa2a1c6b4dd1beba99e4ca39b8a34..79f0be62c836ca73176e29cbec0c3c9df19df539 100644
--- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h
+++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h
@@ -2,6 +2,9 @@
 #define __ADARA_PACKETS_H
 
 #include <stdint.h>
+#include <string>
+#include <sstream>
+#include <string.h>
 
 #include "ADARA.h"
 #include "MantidKernel/System.h"
@@ -11,10 +14,10 @@ namespace ADARA {
 class DLLExport PacketHeader {
 public:
   PacketHeader(const uint8_t *data) {
-    const uint32_t *field = (const uint32_t *)data;
+  const uint32_t *field = (const uint32_t *) data;
 
     m_payload_len = field[0];
-    m_type = (PacketType::Enum)field[1];
+  m_type = (PacketType::Enum) field[1];
 
 #if 0
 // NOTE: Windows doesn't have struct timespec and Mantid doesn't really need this,
@@ -26,7 +29,7 @@ public:
 		m_timestamp.tv_nsec = field[3];
 #endif
 
-    m_pulseId = ((uint64_t)field[2]) << 32;
+    m_pulseId = ((uint64_t) field[2]) << 32;
     m_pulseId |= field[3];
   }
 
@@ -61,10 +64,12 @@ public:
   virtual ~Packet();
 
   const uint8_t *packet(void) const { return m_data; }
-  const uint8_t *payload(void) const { return m_data + header_length(); }
+	const uint8_t *payload(void) const {
+		return m_data + header_length();
+	}
 
 protected:
-  const uint8_t *m_data;
+	const uint8_t *	m_data;
   uint32_t m_len;
   bool m_allocated;
 
@@ -83,22 +88,25 @@ public:
   uint16_t pktSeq(void) const { return (m_fields[1] >> 16) & 0x7fff; }
   uint16_t dspSeq(void) const { return m_fields[1] & 0x7fff; }
   PulseFlavor::Enum flavor(void) const {
-    return static_cast<PulseFlavor::Enum>((m_fields[2] >> 24) & 0x7);
+    return static_cast<PulseFlavor::Enum>
+                    ((m_fields[2] >> 24) & 0x7);
   }
   uint32_t pulseCharge(void) const { return m_fields[2] & 0x00ffffff; }
-  bool badVeto(void) const { return !!(m_fields[3] & 0x8000000); }
+  bool badVeto(void) const { return !!(m_fields[3] & 0x80000000); }
   bool badCycle(void) const { return !!(m_fields[3] & 0x40000000); }
-  uint8_t timingStatus(void) const { return (uint8_t)(m_fields[3] >> 22); }
-  uint16_t veto(void) const { return (m_fields[3] >> 10) & 0xfff; }
+  uint8_t timingStatus(void) const {
+    return (uint8_t) (m_fields[3] >> 22);
+  }
+  uint16_t vetoFlags(void) const { return (m_fields[3] >> 10) & 0xfff; }
   uint16_t cycle(void) const { return m_fields[3] & 0x3ff; }
   uint32_t intraPulseTime(void) const { return m_fields[4]; }
   bool tofCorrected(void) const { return !!(m_fields[5] & 0x80000000); }
   uint32_t tofOffset(void) const { return m_fields[5] & 0x7fffffff; }
   uint32_t tofField(void) const { return m_fields[5]; }
 
-  const Event *events(void) const { return (const Event *)&m_fields[6]; }
+  const Event *events(void) const { return (const Event *) &m_fields[6]; }
   uint32_t num_events(void) const {
-    return (m_payload_len - 24) / static_cast<uint32_t>(2 * sizeof(uint32_t));
+  return (m_payload_len - 24) / (uint32_t) (2 * sizeof(uint32_t));
   }
 
 private:
@@ -106,6 +114,16 @@ private:
 
   RawDataPkt(const uint8_t *data, uint32_t len);
 
+  friend class Parser;
+  friend class MappedDataPkt;
+};
+
+class DLLExport MappedDataPkt : public RawDataPkt {
+public:
+  MappedDataPkt(const MappedDataPkt &pkt);
+private:
+  MappedDataPkt(const uint8_t *data, uint32_t len);
+
   friend class Parser;
 };
 
@@ -114,20 +132,41 @@ public:
   RTDLPkt(const RTDLPkt &pkt);
 
   PulseFlavor::Enum flavor(void) const {
-    return static_cast<PulseFlavor::Enum>((m_fields[0] >> 24) & 0x7);
+    return static_cast<PulseFlavor::Enum>
+                      ((m_fields[0] >> 24) & 0x7);
   }
   uint32_t pulseCharge(void) const { return m_fields[0] & 0x00ffffff; }
-  bool badVeto(void) const { return !!(m_fields[1] & 0x8000000); }
+  bool badVeto(void) const { return !!(m_fields[1] & 0x80000000); }
   bool badCycle(void) const { return !!(m_fields[1] & 0x40000000); }
-  uint8_t timingStatus(void) const { return (uint8_t)(m_fields[1] >> 22); }
-  uint16_t veto(void) const { return (m_fields[1] >> 10) & 0xfff; }
+  uint8_t timingStatus(void) const {
+    return (uint8_t) (m_fields[1] >> 22);
+  }
+  uint16_t vetoFlags(void) const { return (m_fields[1] >> 10) & 0xfff; }
   uint16_t cycle(void) const { return m_fields[1] & 0x3ff; }
   uint32_t intraPulseTime(void) const { return m_fields[2]; }
   bool tofCorrected(void) const { return !!(m_fields[3] & 0x80000000); }
   uint32_t tofOffset(void) const { return m_fields[3] & 0x7fffffff; }
   uint32_t ringPeriod(void) const { return m_fields[4] & 0xffffff; }
 
-  // TODO implement accessor for optional fields
+  // accessor methods for optional FNA/Frame Data fields
+
+  uint32_t FNA(uint32_t index) const
+  {
+    // If out of bounds, just return "0" for "Unused Frame"... ;-D
+    if ( index > 24 )
+      return( 0 );
+    else
+      return ( m_fields[ 5 + index ] >> 24 ) & 0xff;
+  }
+
+  uint32_t frameData(uint32_t index) const
+  {
+    // Out of bounds, return "-1" (0xffffff) for Bogus "Frame Data" ;-b
+    if ( index > 24 )
+      return( -1 );
+    else
+      return m_fields[ 5 + index ] & 0xffffff;
+  }
 
 private:
   const uint32_t *m_fields;
@@ -141,9 +180,9 @@ class DLLExport SourceListPkt : public Packet {
 public:
   SourceListPkt(const SourceListPkt &pkt);
 
-  const uint32_t *ids(void) const { return (const uint32_t *)payload(); }
+  const uint32_t *ids(void) const { return (const uint32_t *) payload(); }
   uint32_t num_ids(void) const {
-    return payload_length() / static_cast<uint32_t>(sizeof(uint32_t));
+    return (uint32_t) payload_length() / (uint32_t) sizeof(uint32_t);
   }
 
 private:
@@ -162,13 +201,14 @@ public:
     PULSE_VETO = 0x0004,
     MISSING_RTDL = 0x0008,
     MAPPING_ERROR = 0x0010,
-    DUPLICATE_PULSE = 0x0020
+    DUPLICATE_PULSE = 0x0020,
   };
 
   uint32_t pulseCharge(void) const { return m_fields[0]; }
   uint32_t pulseEnergy(void) const { return m_fields[1]; }
   uint32_t cycle(void) const { return m_fields[2]; }
-  uint32_t flags(void) const { return m_fields[3]; }
+  uint32_t vetoFlags(void) const { return (m_fields[3] >> 20) & 0xfff; }
+  uint32_t flags(void) const { return m_fields[3] & 0xfffff; }
 
   // The source, bank and event accessors all return NULL if we've
   // incremented past the end
@@ -222,7 +262,8 @@ public:
   uint32_t pulseCharge(void) const { return m_fields[0]; }
   uint32_t pulseEnergy(void) const { return m_fields[1]; }
   uint32_t cycle(void) const { return m_fields[2]; }
-  uint32_t flags(void) const { return m_fields[3]; }
+  uint32_t vetoFlags(void) const { return (m_fields[3] >> 20) & 0xfff; }
+  uint32_t flags(void) const { return m_fields[3] & 0xfffff; }
 
   // bool firstSection() const;
   bool nextSection() const; // iterate over the sections in the packet
@@ -331,14 +372,15 @@ public:
   AnnotationPkt(const AnnotationPkt &pkt);
 
   bool resetHint(void) const { return !!(m_fields[0] & 0x80000000); }
-  MarkerType::Enum type(void) const {
+	MarkerType::Enum marker_type(void) const {
     uint16_t type = (m_fields[0] >> 16) & 0x7fff;
     return static_cast<MarkerType::Enum>(type);
   }
   uint32_t scanIndex(void) const { return m_fields[1]; }
   const std::string &comment(void) const {
     if (!m_comment.length() && (m_fields[0] & 0xffff)) {
-      m_comment.assign((const char *)&m_fields[2], m_fields[0] & 0xffff);
+      m_comment.assign((const char *) &m_fields[2],
+                        m_fields[0] & 0xffff);
     }
 
     return m_comment;
@@ -392,11 +434,15 @@ class DLLExport BeamlineInfoPkt : public Packet {
 public:
   BeamlineInfoPkt(const BeamlineInfoPkt &pkt);
 
+	const uint32_t &targetNumber(void) const { return m_targetNumber; }
+
   const std::string &id(void) const { return m_id; }
   const std::string &shortName(void) const { return m_shortName; }
   const std::string &longName(void) const { return m_longName; }
 
 private:
+	uint32_t m_targetNumber;
+
   std::string m_id;
   std::string m_shortName;
   std::string m_longName;
@@ -406,6 +452,206 @@ private:
   friend class Parser;
 };
 
+class DLLExport BeamMonitorConfigPkt : public Packet {
+public:
+  BeamMonitorConfigPkt(const BeamMonitorConfigPkt &pkt);
+
+  uint32_t beamMonCount(void) const { return m_fields[0]; }
+
+  uint32_t bmonId(uint32_t index) const
+  {
+    if ( index < beamMonCount() )
+      return m_fields[(index * 6) + 1];
+    else
+      return( 0 );
+  }
+
+  uint32_t tofOffset(uint32_t index) const
+  {
+    if ( index < beamMonCount() )
+      return m_fields[(index * 6) + 2];
+    else
+      return( 0 );
+  }
+
+  uint32_t tofMax(uint32_t index) const
+  {
+    if ( index < beamMonCount() )
+      return m_fields[(index * 6) + 3];
+    else
+      return( 0 );
+  }
+
+  uint32_t tofBin(uint32_t index) const
+  {
+    if ( index < beamMonCount() )
+      return m_fields[(index * 6) + 4];
+    else
+      return( 0 );
+  }
+
+  double distance(uint32_t index) const
+  {
+    if ( index < beamMonCount() )
+      return *(const double *) &m_fields[(index * 6) + 5];
+    else
+      return( 0.0 );
+  }
+
+private:
+  const uint32_t *m_fields;
+
+  BeamMonitorConfigPkt(const uint8_t *data, uint32_t len);
+
+  friend class Parser;
+};
+
+class DLLExport DetectorBankSetsPkt : public Packet {
+public:
+  DetectorBankSetsPkt(const DetectorBankSetsPkt &pkt);
+
+  // Detector Bank Set Name, alphanumeric characters...
+  static const size_t SET_NAME_SIZE = 16;
+
+  // Throttle Suffix, alphanumeric, no spaces/punctuation...
+  static const size_t THROTTLE_SUFFIX_SIZE = 16;
+
+  enum Flags {
+    EVENT_FORMAT    = 0x0001,
+    HISTO_FORMAT    = 0x0002,
+  };
+
+  uint32_t detBankSetCount(void) const { return m_fields[0]; }
+
+  uint32_t sectionOffset(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return( m_sectionOffsets[index] );
+    else
+      return( 0 );   // Minimum Valid offset is always past Header...
+  }
+
+  std::string name(uint32_t index) const
+  {
+    if ( index < detBankSetCount() ) {
+      char name_c[SET_NAME_SIZE + 1];   // give them an inch...
+      memset( (void *) name_c, '\0', SET_NAME_SIZE + 1 );
+      strncpy(name_c,
+              (const char *) &(m_fields[ m_sectionOffsets[index] ]),
+              SET_NAME_SIZE);
+      return( std::string(name_c) );
+    } else {
+      return( "<Out Of Range!>" );
+    }
+  }
+
+  uint32_t flags(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return m_fields[ m_sectionOffsets[index] + m_name_offset ];
+    else
+      return( 0 );
+  }
+
+  uint32_t bankCount(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return m_fields[ m_sectionOffsets[index] + m_name_offset + 1 ];
+    else
+      return( 0 );
+  }
+
+  const uint32_t *banklist(uint32_t index) const
+  {
+    if ( index < detBankSetCount() ) {
+      return (const uint32_t *) &m_fields[ m_sectionOffsets[index]
+                                          + m_name_offset + 2 ];
+    }
+    else {
+      // Shouldn't be asking for this if bankCount() returned 0...!
+      return( (const uint32_t *) NULL );
+    }
+  }
+
+  uint32_t tofOffset(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return m_fields[ m_after_banks_offset[index] ];
+    else
+      return( 0 );
+  }
+
+  uint32_t tofMax(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return m_fields[ m_after_banks_offset[index] + 1 ];
+    else
+      return( 0 );
+  }
+
+  uint32_t tofBin(uint32_t index) const
+  {
+    if ( index < detBankSetCount() )
+      return m_fields[ m_after_banks_offset[index] + 2 ];
+    else
+      return( 0 );
+  }
+
+  double throttle(uint32_t index) const
+  {
+    if ( index < detBankSetCount() ) {
+      return *(const double *) &m_fields[
+            m_after_banks_offset[index] + 3 ];
+    }
+    else
+      return( 0.0 );
+  }
+
+  std::string suffix(uint32_t index) const
+  {
+    if ( index < detBankSetCount() ) {
+      char suffix_c[THROTTLE_SUFFIX_SIZE + 1];   // give them an inch
+      memset( (void *) suffix_c, '\0', THROTTLE_SUFFIX_SIZE + 1 );
+      strncpy(suffix_c,
+          (const char *) &(m_fields[m_after_banks_offset[index] + 5]),
+          THROTTLE_SUFFIX_SIZE);
+      return( std::string(suffix_c) );
+    } else {
+      std::stringstream ss;
+      ss << "out-of-range-";
+      ss << index;
+      return( ss.str() );
+    }
+  }
+
+private:
+    const uint32_t *m_fields;
+
+    static const uint32_t m_name_offset =
+        SET_NAME_SIZE / sizeof(uint32_t);
+
+    static const uint32_t m_suffix_offset =
+        THROTTLE_SUFFIX_SIZE / sizeof(uint32_t);
+
+    uint32_t *m_sectionOffsets;
+
+    uint32_t *m_after_banks_offset;
+
+    DetectorBankSetsPkt(const uint8_t *data, uint32_t len);
+
+    friend class Parser;
+};
+
+class DLLExport DataDonePkt : public Packet {
+public:
+  DataDonePkt(const DataDonePkt &pkt);
+
+private:
+  DataDonePkt(const uint8_t *data, uint32_t len);
+
+  friend class Parser;
+};
+
 class DLLExport DeviceDescriptorPkt : public Packet {
 public:
   DeviceDescriptorPkt(const DeviceDescriptorPkt &pkt);
@@ -435,10 +681,11 @@ public:
   uint32_t devId(void) const { return m_fields[0]; }
   uint32_t varId(void) const { return m_fields[1]; }
   VariableStatus::Enum status(void) const {
-    return static_cast<VariableStatus::Enum>(m_fields[2] >> 16);
+      return static_cast<VariableStatus::Enum> (m_fields[2] >> 16);
   }
   VariableSeverity::Enum severity(void) const {
-    return static_cast<VariableSeverity::Enum>(m_fields[2] & 0xffff);
+    return static_cast<VariableSeverity::Enum>
+                        (m_fields[2] & 0xffff);
   }
   uint32_t value(void) const { return m_fields[3]; }
 
@@ -462,12 +709,13 @@ public:
   uint32_t devId(void) const { return m_fields[0]; }
   uint32_t varId(void) const { return m_fields[1]; }
   VariableStatus::Enum status(void) const {
-    return static_cast<VariableStatus::Enum>(m_fields[2] >> 16);
+    return static_cast<VariableStatus::Enum> (m_fields[2] >> 16);
   }
   VariableSeverity::Enum severity(void) const {
-    return static_cast<VariableSeverity::Enum>(m_fields[2] & 0xffff);
+    return static_cast<VariableSeverity::Enum>
+                                (m_fields[2] & 0xffff);
   }
-  double value(void) const { return *(const double *)&m_fields[3]; }
+  double value(void) const { return *(const double *) &m_fields[3]; }
 
   void remapDevice(uint32_t dev) {
     uint32_t *fields = (uint32_t *)const_cast<uint8_t *>(payload());
@@ -489,10 +737,11 @@ public:
   uint32_t devId(void) const { return m_fields[0]; }
   uint32_t varId(void) const { return m_fields[1]; }
   VariableStatus::Enum status(void) const {
-    return static_cast<VariableStatus::Enum>(m_fields[2] >> 16);
+    return static_cast<VariableStatus::Enum> (m_fields[2] >> 16);
   }
   VariableSeverity::Enum severity(void) const {
-    return static_cast<VariableSeverity::Enum>(m_fields[2] & 0xffff);
+    return static_cast<VariableSeverity::Enum>
+                              (m_fields[2] & 0xffff);
   }
   const std::string &value(void) const { return m_val; }
 
diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAParser.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAParser.h
index dafaece450e8f1b2e1d6fd05627837441269c587..d7619e66cb79ce2ae6b6fc7258b27b31a08b00ee 100644
--- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAParser.h
+++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAParser.h
@@ -4,6 +4,7 @@
 #include <string>
 #include <stdint.h>
 #include <stdexcept>
+#include <map>
 
 #include "ADARA.h"
 #include "ADARAPackets.h"
@@ -53,7 +54,9 @@ protected:
     return NULL;
   }
 
-  unsigned int bufferFillLength(void) const { return m_size - m_len; }
+  unsigned int bufferFillLength(void) const {
+      return m_size - m_len;
+  }
 
   void bufferBytesAppended(unsigned int count) {
     if (bufferFillLength() < count) {
@@ -78,7 +81,7 @@ protected:
     * Partial packet chunks will be counted as completed when the last
     * fragment is processed.
     **/
-  int bufferParse(unsigned int max_packets = 0);
+  int bufferParse(std::string & log_info, unsigned int max_packets = 0);
 
   /** Flush the internal buffers and get ready to restart parsing.
     **/
@@ -101,8 +104,10 @@ protected:
   /**@{*/
   virtual bool rxPacket(const Packet &pkt);
   virtual bool rxUnknownPkt(const Packet &pkt);
-  virtual bool rxOversizePkt(const PacketHeader *hdr, const uint8_t *chunk,
-                             unsigned int chunk_offset, unsigned int chunk_len);
+  virtual bool rxOversizePkt(const PacketHeader *hdr,
+                             const uint8_t *chunk,
+                             unsigned int chunk_offset,
+                             unsigned int chunk_len);
   /**@}*/
 
   /** @name Specific rxPacket Functions
@@ -120,6 +125,7 @@ protected:
     **/
   /**@{*/
   virtual bool rxPacket(const RawDataPkt &pkt);
+  virtual bool rxPacket(const MappedDataPkt &pkt);
   virtual bool rxPacket(const RTDLPkt &pkt);
   virtual bool rxPacket(const SourceListPkt &pkt);
   virtual bool rxPacket(const BankedEventPkt &pkt);
@@ -134,14 +140,31 @@ protected:
   virtual bool rxPacket(const HeartbeatPkt &pkt);
   virtual bool rxPacket(const GeometryPkt &pkt);
   virtual bool rxPacket(const BeamlineInfoPkt &pkt);
+  virtual bool rxPacket(const BeamMonitorConfigPkt &pkt);
+  virtual bool rxPacket(const DetectorBankSetsPkt &pkt);
+  virtual bool rxPacket(const DataDonePkt &pkt);
   virtual bool rxPacket(const DeviceDescriptorPkt &pkt);
   virtual bool rxPacket(const VariableU32Pkt &pkt);
   virtual bool rxPacket(const VariableDoublePkt &pkt);
   virtual bool rxPacket(const VariableStringPkt &pkt);
   /**@}*/
+  
+  /* Collect a log string with statistics on "discarded" packet types,
+    * i.e. packets that for one reason or another were _Not_ parsed
+    * or processed.
+    *
+    * Since we don't have a common logging approach in this software suite
+    * (<sigh/>), we just fill up a happy logging string with info
+    * and return it for the caller's logger du jour.
+    */
+  void getDiscardedPacketsLogString(std::string & log_info);
+
+  /* Reset the collected "discarded packet" statistics.
+    */
+  void resetDiscardedPacketsStats(void);
 
 private:
-  uint8_t *m_buffer;
+  uint8_t * m_buffer;
   unsigned int m_size;
   unsigned int m_max_size;
   unsigned int m_len;
@@ -149,6 +172,8 @@ private:
   unsigned int m_restart_offset;
   unsigned int m_oversize_len;
   unsigned int m_oversize_offset;
+
+  std::map<PacketType::Enum, uint64_t>	m_discarded_packets;
 };
 
 } /* namespacce ADARA */
diff --git a/Code/Mantid/Framework/LiveData/src/ADARA/ADARAPackets.cpp b/Code/Mantid/Framework/LiveData/src/ADARA/ADARAPackets.cpp
index fbf5a1af1a7e873ca0ab11106fab09791f519e7c..0204ceb436dd5127be84afd83306f5e3a79d0ba6 100644
--- a/Code/Mantid/Framework/LiveData/src/ADARA/ADARAPackets.cpp
+++ b/Code/Mantid/Framework/LiveData/src/ADARA/ADARAPackets.cpp
@@ -6,57 +6,57 @@
 using namespace ADARA;
 
 static bool validate_status(uint16_t val) {
-  VariableStatus::Enum e = static_cast<VariableStatus::Enum>(val);
+	VariableStatus::Enum e = static_cast<VariableStatus::Enum>(val);
 
-  /* No default case so that we get warned when new status values
-   * get added.
-   */
+	/* No default case so that we get warned when new status values
+	 * get added.
+	 */
   switch (e) {
-  case VariableStatus::OK:
-  case VariableStatus::READ_ERROR:
-  case VariableStatus::WRITE_ERROR:
-  case VariableStatus::HIHI_LIMIT:
-  case VariableStatus::HIGH_LIMIT:
-  case VariableStatus::LOLO_LIMIT:
-  case VariableStatus::LOW_LIMIT:
-  case VariableStatus::BAD_STATE:
-  case VariableStatus::CHANGED_STATE:
-  case VariableStatus::NO_COMMUNICATION:
-  case VariableStatus::COMMUNICATION_TIMEOUT:
-  case VariableStatus::HARDWARE_LIMIT:
-  case VariableStatus::BAD_CALCULATION:
-  case VariableStatus::INVALID_SCAN:
-  case VariableStatus::LINK_FAILED:
-  case VariableStatus::INVALID_STATE:
-  case VariableStatus::BAD_SUBROUTINE:
-  case VariableStatus::UNDEFINED_ALARM:
-  case VariableStatus::DISABLED:
-  case VariableStatus::SIMULATED:
-  case VariableStatus::READ_PERMISSION:
-  case VariableStatus::WRITE_PERMISSION:
-  case VariableStatus::UPSTREAM_DISCONNECTED:
-  case VariableStatus::NOT_REPORTED:
-    return false;
-  }
-
-  return true;
+	case VariableStatus::OK:
+	case VariableStatus::READ_ERROR:
+	case VariableStatus::WRITE_ERROR:
+	case VariableStatus::HIHI_LIMIT:
+	case VariableStatus::HIGH_LIMIT:
+	case VariableStatus::LOLO_LIMIT:
+	case VariableStatus::LOW_LIMIT:
+	case VariableStatus::BAD_STATE:
+	case VariableStatus::CHANGED_STATE:
+	case VariableStatus::NO_COMMUNICATION:
+	case VariableStatus::COMMUNICATION_TIMEOUT:
+	case VariableStatus::HARDWARE_LIMIT:
+	case VariableStatus::BAD_CALCULATION:
+	case VariableStatus::INVALID_SCAN:
+	case VariableStatus::LINK_FAILED:
+	case VariableStatus::INVALID_STATE:
+	case VariableStatus::BAD_SUBROUTINE:
+	case VariableStatus::UNDEFINED_ALARM:
+	case VariableStatus::DISABLED:
+	case VariableStatus::SIMULATED:
+	case VariableStatus::READ_PERMISSION:
+	case VariableStatus::WRITE_PERMISSION:
+	case VariableStatus::UPSTREAM_DISCONNECTED:
+	case VariableStatus::NOT_REPORTED:
+		return false;
+	}
+
+	return true;
 }
 
 static bool validate_severity(uint16_t val) {
-  VariableSeverity::Enum e = static_cast<VariableSeverity::Enum>(val);
+	VariableSeverity::Enum e = static_cast<VariableSeverity::Enum>(val);
 
-  /* No default case so that we get warned when new severities get added.
-   */
-  switch (e) {
-  case VariableSeverity::OK:
-  case VariableSeverity::MINOR_ALARM:
-  case VariableSeverity::MAJOR_ALARM:
-  case VariableSeverity::INVALID:
-  case VariableSeverity::NOT_REPORTED:
-    return false;
-  }
+	/* No default case so that we get warned when new severities get added.
+	 */
+	switch (e) {
+	case VariableSeverity::OK:
+	case VariableSeverity::MINOR_ALARM:
+	case VariableSeverity::MAJOR_ALARM:
+	case VariableSeverity::INVALID:
+	case VariableSeverity::NOT_REPORTED:
+		return false;
+	}
 
-  return true;
+	return true;
 }
 
 Packet::Packet(const uint8_t *data, uint32_t len)
@@ -64,13 +64,13 @@ Packet::Packet(const uint8_t *data, uint32_t len)
 
 Packet::Packet(const Packet &pkt)
     : PacketHeader(pkt.packet()), m_allocated(true) {
-  m_data = new uint8_t[pkt.packet_length()];
-  m_len = pkt.packet_length();
+	m_data = new uint8_t[pkt.packet_length()];
+	m_len = pkt.packet_length();
   memcpy(const_cast<uint8_t *>(m_data), pkt.packet(), m_len);
 }
 
 Packet::~Packet() {
-  if (m_allocated)
+	if (m_allocated)
     delete[] m_data;
 }
 
@@ -78,8 +78,8 @@ Packet::~Packet() {
 
 RawDataPkt::RawDataPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len < (6 * sizeof(uint32_t)))
-    throw invalid_packet("RawDataPacket is too short");
+	if (m_payload_len < (6 * sizeof(uint32_t)))
+		throw invalid_packet("RawDataPacket is too short");
 }
 
 RawDataPkt::RawDataPkt(const RawDataPkt &pkt)
@@ -87,13 +87,26 @@ RawDataPkt::RawDataPkt(const RawDataPkt &pkt)
 
 /* ------------------------------------------------------------------------ */
 
+MappedDataPkt::MappedDataPkt(const uint8_t *data, uint32_t len) :
+    RawDataPkt(data, len)
+{
+    if (m_payload_len < (6 * sizeof(uint32_t)))
+        throw invalid_packet("MappedDataPacket is too short");
+}
+
+MappedDataPkt::MappedDataPkt(const MappedDataPkt &pkt) :
+    RawDataPkt(pkt)
+{}
+
+/* ------------------------------------------------------------------------ */
+
 RTDLPkt::RTDLPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len != 120)
-    throw invalid_packet("RTDL Packet is incorrect length");
+	if (m_payload_len != 120)
+		throw invalid_packet("RTDL Packet is incorrect length");
 
-  if ((m_fields[4] >> 24) != 4)
-    throw invalid_packet("Missing ring period");
+	if ((m_fields[4] >> 24) != 4)
+		throw invalid_packet("Missing ring period");
 }
 
 RTDLPkt::RTDLPkt(const RTDLPkt &pkt)
@@ -114,8 +127,8 @@ BankedEventPkt::BankedEventPkt(const uint8_t *data, uint32_t len)
     m_TOFOffset(0), m_isCorrected(false), m_bankNum(0), m_bankStartIndex(0),
     m_bankId(0), m_eventCount(0)
 {
-  if (m_payload_len < (4 * sizeof(uint32_t)))
-    throw invalid_packet("BankedEvent packet is too short");
+	if (m_payload_len < (4 * sizeof(uint32_t)))
+		throw invalid_packet("BankedEvent packet is too short");
 
   m_lastFieldIndex = (payload_length() / 4) - 1;
 }
@@ -239,8 +252,8 @@ void BankedEventPkt::firstEventInBank() const {
 BeamMonitorPkt::BeamMonitorPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()),
       m_sectionStartIndex(0), m_eventNum(0) {
-  if (m_payload_len < (4 * sizeof(uint32_t)))
-    throw invalid_packet("BeamMonitor packet is too short");
+	if (m_payload_len < (4 * sizeof(uint32_t)))
+		throw invalid_packet("BeamMonitor packet is too short");
 }
 
 BeamMonitorPkt::BeamMonitorPkt(const BeamMonitorPkt &pkt)
@@ -322,8 +335,8 @@ PixelMappingPkt::PixelMappingPkt(const PixelMappingPkt &pkt) : Packet(pkt) {}
 
 RunStatusPkt::RunStatusPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len != (3 * sizeof(uint32_t)))
-    throw invalid_packet("RunStatus packet is incorrect size");
+	if (m_payload_len != (3 * sizeof(uint32_t)))
+		throw invalid_packet("RunStatus packet is incorrect size");
 }
 
 RunStatusPkt::RunStatusPkt(const RunStatusPkt &pkt)
@@ -335,15 +348,15 @@ RunInfoPkt::RunInfoPkt(const uint8_t *data, uint32_t len) : Packet(data, len) {
   uint32_t size = *(const uint32_t *)payload();
   const char *xml = (const char *)payload() + sizeof(uint32_t);
 
-  if (m_payload_len < sizeof(uint32_t))
-    throw invalid_packet("RunInfo packet is too short");
-  if (m_payload_len < (size + sizeof(uint32_t)))
-    throw invalid_packet("RunInfo packet has oversize string");
+	if (m_payload_len < sizeof(uint32_t))
+		throw invalid_packet("RunInfo packet is too short");
+	if (m_payload_len < (size + sizeof(uint32_t)))
+		throw invalid_packet("RunInfo packet has oversize string");
 
-  /* TODO it would be better to create the string on access
-   * rather than object construction; the user may not care.
-   */
-  m_xml.assign(xml, size);
+	/* TODO it would be better to create the string on access
+	 * rather than object construction; the user may not care.
+	 */
+	m_xml.assign(xml, size);
 }
 
 RunInfoPkt::RunInfoPkt(const RunInfoPkt &pkt) : Packet(pkt), m_xml(pkt.m_xml) {}
@@ -356,17 +369,17 @@ TransCompletePkt::TransCompletePkt(const uint8_t *data, uint32_t len)
   const char *reason = (const char *)payload() + sizeof(uint32_t);
 
   m_status = (uint16_t)(size >> 16);
-  size &= 0xffff;
-  if (m_payload_len < sizeof(uint32_t))
-    throw invalid_packet("TransComplete packet is too short");
-  if (m_payload_len < (size + sizeof(uint32_t)))
-    throw invalid_packet("TransComplete packet has oversize "
-                         "string");
+	size &= 0xffff;
+	if (m_payload_len < sizeof(uint32_t))
+		throw invalid_packet("TransComplete packet is too short");
+	if (m_payload_len < (size + sizeof(uint32_t)))
+		throw invalid_packet("TransComplete packet has oversize "
+				     "string");
 
-  /* TODO it would be better to create the string on access
-   * rather than object construction; the user may not care.
-   */
-  m_reason.assign(reason, size);
+	/* TODO it would be better to create the string on access
+	 * rather than object construction; the user may not care.
+	 */
+	m_reason.assign(reason, size);
 }
 
 TransCompletePkt::TransCompletePkt(const TransCompletePkt &pkt)
@@ -376,8 +389,8 @@ TransCompletePkt::TransCompletePkt(const TransCompletePkt &pkt)
 
 ClientHelloPkt::ClientHelloPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len) {
-  if (m_payload_len != sizeof(uint32_t))
-    throw invalid_packet("ClientHello packet is incorrect size");
+	if (m_payload_len != sizeof(uint32_t))
+		throw invalid_packet("ClientHello packet is incorrect size");
 
   m_reqStart = *(const uint32_t *)payload();
 }
@@ -389,13 +402,13 @@ ClientHelloPkt::ClientHelloPkt(const ClientHelloPkt &pkt)
 
 AnnotationPkt::AnnotationPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len < (2 * sizeof(uint32_t)))
-    throw invalid_packet("AnnotationPkt packet is incorrect size");
+	if (m_payload_len < (2 * sizeof(uint32_t)))
+		throw invalid_packet("AnnotationPkt packet is incorrect size");
 
-  uint16_t size = m_fields[0] & 0xffff;
-  if (m_payload_len < (size + (2 * sizeof(uint32_t))))
-    throw invalid_packet("AnnotationPkt packet has oversize "
-                         "string");
+	uint16_t size = m_fields[0] & 0xffff;
+	if (m_payload_len < (size + (2 * sizeof(uint32_t))))
+		throw invalid_packet("AnnotationPkt packet has oversize "
+				     "string");
 }
 
 AnnotationPkt::AnnotationPkt(const AnnotationPkt &pkt)
@@ -404,12 +417,12 @@ AnnotationPkt::AnnotationPkt(const AnnotationPkt &pkt)
 /* ------------------------------------------------------------------------ */
 
 SyncPkt::SyncPkt(const uint8_t *data, uint32_t len) : Packet(data, len) {
-  uint32_t size = *(const uint32_t *)(payload() + 24);
+	uint32_t size = *(const uint32_t *)(payload() + 24);
 
-  if (m_payload_len < 28)
-    throw invalid_packet("Sync packet is too small");
-  if (m_payload_len < (size + 28))
-    throw invalid_packet("Sync packet has oversize string");
+	if (m_payload_len < 28)
+		throw invalid_packet("Sync packet is too small");
+	if (m_payload_len < (size + 28))
+		throw invalid_packet("Sync packet has oversize string");
 }
 
 SyncPkt::SyncPkt(const SyncPkt &pkt) : Packet(pkt) {}
@@ -418,8 +431,8 @@ SyncPkt::SyncPkt(const SyncPkt &pkt) : Packet(pkt) {}
 
 HeartbeatPkt::HeartbeatPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len) {
-  if (m_payload_len)
-    throw invalid_packet("Heartbeat packet is incorrect size");
+	if (m_payload_len)
+		throw invalid_packet("Heartbeat packet is incorrect size");
 }
 
 HeartbeatPkt::HeartbeatPkt(const HeartbeatPkt &pkt) : Packet(pkt) {}
@@ -431,15 +444,15 @@ GeometryPkt::GeometryPkt(const uint8_t *data, uint32_t len)
   uint32_t size = *(const uint32_t *)payload();
   const char *xml = (const char *)payload() + sizeof(uint32_t);
 
-  if (m_payload_len < sizeof(uint32_t))
-    throw invalid_packet("Geometry packet is too short");
-  if (m_payload_len < (size + sizeof(uint32_t)))
-    throw invalid_packet("Geometry packet has oversize string");
+	if (m_payload_len < sizeof(uint32_t))
+		throw invalid_packet("Geometry packet is too short");
+	if (m_payload_len < (size + sizeof(uint32_t)))
+		throw invalid_packet("Geometry packet has oversize string");
 
-  /* TODO it would be better to create the string on access
-   * rather than object construction; the user may not care.
-   */
-  m_xml.assign(xml, size);
+	/* TODO it would be better to create the string on access
+	 * rather than object construction; the user may not care.
+	 */
+	m_xml.assign(xml, size);
 }
 
 GeometryPkt::GeometryPkt(const GeometryPkt &pkt)
@@ -451,49 +464,200 @@ BeamlineInfoPkt::BeamlineInfoPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len) {
   const char *info = (const char *)payload() + sizeof(uint32_t);
   uint32_t sizes = *(const uint32_t *)payload();
-  uint32_t id_len, shortName_len, longName_len, info_len;
+	uint32_t id_len, shortName_len, longName_len, info_len;
+
+	if (m_payload_len < sizeof(uint32_t))
+		throw invalid_packet("Beamline info packet is too short");
+
+	longName_len = sizes & 0xff;
+	shortName_len = (sizes >> 8) & 0xff;
+	id_len = (sizes >> 16) & 0xff;
+	m_targetNumber = (sizes >> 24) & 0xff;	// formerly "Unused" in V0...
+
+	// Unspecified (Version 0 Packet) Target Number Defaults to 1.
+	if ( m_targetNumber == 0 )
+		m_targetNumber = 1;
+
+	info_len = id_len + shortName_len + longName_len;
+
+	if (m_payload_len < (info_len + sizeof(uint32_t)))
+		throw invalid_packet("Beamline info packet has undersize data");
+
+	m_id.assign(info, id_len);
+	info += id_len;
+	m_shortName.assign(info, shortName_len);
+	info += shortName_len;
+	m_longName.assign(info, longName_len);
+}
+
+BeamlineInfoPkt::BeamlineInfoPkt(const BeamlineInfoPkt &pkt) :
+	Packet(pkt), m_targetNumber(pkt.m_targetNumber),
+	m_id(pkt.m_id), m_shortName(pkt.m_shortName), m_longName(pkt.m_longName)
+{}
+
+/* ------------------------------------------------------------------------ */
+
+BeamMonitorConfigPkt::BeamMonitorConfigPkt(const uint8_t *data,
+		uint32_t len) :
+	Packet(data, len), m_fields((const uint32_t *)payload())
+{
+	size_t sectionSize = sizeof(double) + (4 * sizeof(uint32_t));
 
-  if (m_payload_len < sizeof(uint32_t))
-    throw invalid_packet("Beamline info packet is too short");
+	if (m_payload_len !=
+			(sizeof(uint32_t) + (beamMonCount() * sectionSize))) {
+		std::string msg("BeamMonitorConfig packet is incorrect length: ");
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+}
 
-  longName_len = sizes & 0xff;
-  shortName_len = (sizes >> 8) & 0xff;
-  id_len = (sizes >> 16) & 0xff;
+BeamMonitorConfigPkt::BeamMonitorConfigPkt(
+		const BeamMonitorConfigPkt &pkt ) :
+	Packet(pkt), m_fields((const uint32_t *)payload())
+{}
 
-  info_len = id_len + shortName_len + longName_len;
+/* ------------------------------------------------------------------------ */
 
-  if (m_payload_len < (info_len + sizeof(uint32_t)))
-    throw invalid_packet("Beamline info packet has undersize data");
+DetectorBankSetsPkt::DetectorBankSetsPkt(const uint8_t *data,
+		uint32_t len) :
+	Packet(data, len), m_fields((const uint32_t *)payload()),
+	m_sectionOffsets(NULL), m_after_banks_offset(NULL)
+{
+	// Get Number of Detector Bank Sets...
+	//    - Basic Packet Size Sanity Check
+
+	if ( m_payload_len < sizeof(uint32_t) ) {
+		std::string msg("DetectorBankSets packet is too short for Count! ");
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+
+	uint32_t numSets = detBankSetCount();
+
+	// Don't Allocate Anything if there are No Detector Bank Sets...
+	if ( numSets < 1 )
+		return;
+
+	m_sectionOffsets = new uint32_t[numSets];
+
+	m_after_banks_offset = new uint32_t[numSets];
+
+	// Traverse Detector Bank Sets...
+	//    - Set Section Offsets
+	//    - Set "After Banks" Offsets
+
+	// Base Section Sizes (w/o Bank Ids)
+	uint32_t baseSectionOffsetPart1 = 0
+		+ m_name_offset   // name
+		+ 2;   // flags & bank id count
+	uint32_t baseSectionOffsetPart2 = 0
+		+ 3   // histo params
+		+ 2   // throttle rate (double)
+		+ m_suffix_offset;
+	uint32_t baseSectionOffsetNoBanks =
+		baseSectionOffsetPart1 + baseSectionOffsetPart2;
+
+	// Running Section Offset (in number of uint32_t elements)
+	uint32_t sectionOffset = 1;   // for Detector Bank Set Count...
+
+	for ( uint32_t i=0 ; i < numSets ; i++ )
+	{
+		// Section Offset
+		m_sectionOffsets[i] = sectionOffset;
+
+		if ( m_payload_len < ( ( sectionOffset + baseSectionOffsetNoBanks )
+				* sizeof(uint32_t) ) ) {
+			std::string msg("DetectorBankSets packet: too short for Set ");
+			msg += boost::lexical_cast<std::string>( i + 1 );
+			msg += " of ";
+			msg += boost::lexical_cast<std::string>(numSets);
+			msg += " sectionOffset=";
+			msg += boost::lexical_cast<std::string>(sectionOffset);
+			msg += " baseSectionOffsetNoBanks=";
+			msg += boost::lexical_cast<std::string>(
+				baseSectionOffsetNoBanks);
+			msg += " payload_len=";
+			msg += boost::lexical_cast<std::string>(m_payload_len);
+			delete[] m_sectionOffsets;
+			m_sectionOffsets = (uint32_t *) NULL;
+			delete[] m_after_banks_offset;
+			m_after_banks_offset = (uint32_t *) NULL;
+			throw invalid_packet(msg);
+		}
+
+		// Offset thru end of Bank Ids list...
+		sectionOffset += baseSectionOffsetPart1
+			+ bankCount(i);   // just in time m_sectionOffset delivery...!
+
+		// Save as "After Banks" Offset...
+		m_after_banks_offset[i] = sectionOffset;
+
+		// Rest of Set Offset...
+		sectionOffset += baseSectionOffsetPart2;
+	}
+
+	// Final Payload Size Check... ;-D
+	if ( m_payload_len < ( sectionOffset * sizeof(uint32_t) ) ) {
+		std::string msg("DetectorBankSets packet: overall too short ");
+		msg += " numSets=";
+		msg += boost::lexical_cast<std::string>(numSets);
+		msg += " baseSectionOffsetNoBanks=";
+		msg += boost::lexical_cast<std::string>(
+			baseSectionOffsetNoBanks);
+		msg += " final sectionOffset=";
+		msg += boost::lexical_cast<std::string>(sectionOffset);
+		msg += " payload_len=";
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		delete[] m_sectionOffsets;
+		m_sectionOffsets = (uint32_t *) NULL;
+		delete[] m_after_banks_offset;
+		m_after_banks_offset = (uint32_t *) NULL;
+		throw invalid_packet(msg);
+	}
+}
+
+DetectorBankSetsPkt::DetectorBankSetsPkt(
+		const DetectorBankSetsPkt &pkt ) :
+	Packet(pkt), m_fields((const uint32_t *)payload())
+{
+	if ( m_sectionOffsets != NULL )
+		delete[] m_sectionOffsets;
 
-  m_id.assign(info, id_len);
-  info += id_len;
-  m_shortName.assign(info, shortName_len);
-  info += shortName_len;
-  m_longName.assign(info, longName_len);
+	if ( m_after_banks_offset != NULL )
+		delete[] m_after_banks_offset;
 }
 
-BeamlineInfoPkt::BeamlineInfoPkt(const BeamlineInfoPkt &pkt)
-    : Packet(pkt), m_id(pkt.m_id), m_shortName(pkt.m_shortName),
-      m_longName(pkt.m_longName) {}
+/* ------------------------------------------------------------------------ */
+
+DataDonePkt::DataDonePkt(const uint8_t *data, uint32_t len) :
+	Packet(data, len)
+{
+	if (m_payload_len)
+		throw invalid_packet("DataDone packet is incorrect size");
+}
+
+DataDonePkt::DataDonePkt(const DataDonePkt &pkt) :
+	Packet(pkt)
+{}
 
 /* ------------------------------------------------------------------------ */
 
 DeviceDescriptorPkt::DeviceDescriptorPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len) {
   const uint32_t *fields = (const uint32_t *)payload();
-  uint32_t size;
-
-  if (m_payload_len < (2 * sizeof(uint32_t)))
-    throw invalid_packet("DeviceDescriptor packet is too short");
-  size = fields[1];
-  if (m_payload_len < (size + (2 * sizeof(uint32_t))))
-    throw invalid_packet("DeviceDescriptor packet has oversize "
-                         "string");
-
-  /* TODO it would be better to create the string on access
-   * rather than object construction; the user may not care.
-   */
-  m_devId = fields[0];
+	uint32_t size;
+
+	if (m_payload_len < (2 * sizeof(uint32_t)))
+		throw invalid_packet("DeviceDescriptor packet is too short");
+	size = fields[1];
+	if (m_payload_len < (size + (2 * sizeof(uint32_t))))
+		throw invalid_packet("DeviceDescriptor packet has oversize "
+				     "string");
+
+	/* TODO it would be better to create the string on access
+	 * rather than object construction; the user may not care.
+	 */
+	m_devId = fields[0];
   m_desc.assign((const char *)&fields[2], size);
 }
 
@@ -504,24 +668,24 @@ DeviceDescriptorPkt::DeviceDescriptorPkt(const DeviceDescriptorPkt &pkt)
 
 VariableU32Pkt::VariableU32Pkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len != (4 * sizeof(uint32_t))) {
-    std::string msg("VariableValue (U32) packet is incorrect "
-                    "length: ");
-    msg += boost::lexical_cast<std::string>(m_payload_len);
-    throw invalid_packet(msg);
-  }
-  if (validate_status(status())) {
-    std::string msg("VariableValue (U32) packet has invalid "
-                    "status: ");
-    msg += boost::lexical_cast<std::string>(status());
-    throw invalid_packet(msg);
-  }
-  if (validate_severity(severity())) {
-    std::string msg("VariableValue (U32) packet has invalid "
-                    "severity: ");
-    msg += boost::lexical_cast<std::string>(severity());
-    throw invalid_packet(msg);
-  }
+	if (m_payload_len != (4 * sizeof(uint32_t))) {
+		std::string msg("VariableValue (U32) packet is incorrect "
+				"length: ");
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+	if (validate_status(status())) {
+		std::string msg("VariableValue (U32) packet has invalid "
+				"status: ");
+		msg += boost::lexical_cast<std::string>(status());
+		throw invalid_packet(msg);
+	}
+	if (validate_severity(severity())) {
+		std::string msg("VariableValue (U32) packet has invalid "
+				"severity: ");
+		msg += boost::lexical_cast<std::string>(severity());
+		throw invalid_packet(msg);
+	}
 }
 
 VariableU32Pkt::VariableU32Pkt(const VariableU32Pkt &pkt)
@@ -531,24 +695,24 @@ VariableU32Pkt::VariableU32Pkt(const VariableU32Pkt &pkt)
 
 VariableDoublePkt::VariableDoublePkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  if (m_payload_len != (sizeof(double) + (3 * sizeof(uint32_t)))) {
-    std::string msg("VariableValue (double) packet is incorrect "
-                    "length: ");
-    msg += boost::lexical_cast<std::string>(m_payload_len);
-    throw invalid_packet(msg);
-  }
-  if (validate_status(status())) {
-    std::string msg("VariableValue (double) packet has invalid "
-                    "status: ");
-    msg += boost::lexical_cast<std::string>(status());
-    throw invalid_packet(msg);
-  }
-  if (validate_severity(severity())) {
-    std::string msg("VariableValue (double) packet has invalid "
-                    "severity: ");
-    msg += boost::lexical_cast<std::string>(severity());
-    throw invalid_packet(msg);
-  }
+	if (m_payload_len != (sizeof(double) + (3 * sizeof(uint32_t)))) {
+		std::string msg("VariableValue (double) packet is incorrect "
+				"length: ");
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+	if (validate_status(status())) {
+		std::string msg("VariableValue (double) packet has invalid "
+				"status: ");
+		msg += boost::lexical_cast<std::string>(status());
+		throw invalid_packet(msg);
+	}
+	if (validate_severity(severity())) {
+		std::string msg("VariableValue (double) packet has invalid "
+				"severity: ");
+		msg += boost::lexical_cast<std::string>(severity());
+		throw invalid_packet(msg);
+	}
 }
 
 VariableDoublePkt::VariableDoublePkt(const VariableDoublePkt &pkt)
@@ -558,39 +722,39 @@ VariableDoublePkt::VariableDoublePkt(const VariableDoublePkt &pkt)
 
 VariableStringPkt::VariableStringPkt(const uint8_t *data, uint32_t len)
     : Packet(data, len), m_fields((const uint32_t *)payload()) {
-  uint32_t size;
-
-  if (m_payload_len < (4 * sizeof(uint32_t))) {
-    std::string msg("VariableValue (string) packet is too short ");
-    msg += boost::lexical_cast<std::string>(m_payload_len);
-    throw invalid_packet(msg);
-  }
-  size = m_fields[3];
-  if (m_payload_len < (size + (2 * sizeof(uint32_t)))) {
-    std::string msg("VariableValue (string) packet has oversize "
-                    "string: ");
-    msg += boost::lexical_cast<std::string>(size);
-    msg += " vs payload ";
-    msg += boost::lexical_cast<std::string>(m_payload_len);
-    throw invalid_packet(msg);
-  }
-
-  if (validate_status(status())) {
-    std::string msg("VariableValue (string) packet has invalid "
-                    "status: ");
-    msg += boost::lexical_cast<std::string>(status());
-    throw invalid_packet(msg);
-  }
-  if (validate_severity(severity())) {
-    std::string msg("VariableValue (string) packet has invalid "
-                    "severity: ");
-    msg += boost::lexical_cast<std::string>(severity());
-    throw invalid_packet(msg);
-  }
-
-  /* TODO it would be better to create the string on access
-   * rather than object construction; the user may not care.
-   */
+	uint32_t size;
+
+	if (m_payload_len < (4 * sizeof(uint32_t))) {
+		std::string msg("VariableValue (string) packet is too short ");
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+	size = m_fields[3];
+	if (m_payload_len < (size + (2 * sizeof(uint32_t)))) {
+		std::string msg("VariableValue (string) packet has oversize "
+				"string: ");
+		msg += boost::lexical_cast<std::string>(size);
+		msg += " vs payload ";
+		msg += boost::lexical_cast<std::string>(m_payload_len);
+		throw invalid_packet(msg);
+	}
+
+	if (validate_status(status())) {
+		std::string msg("VariableValue (string) packet has invalid "
+				"status: ");
+		msg += boost::lexical_cast<std::string>(status());
+		throw invalid_packet(msg);
+	}
+	if (validate_severity(severity())) {
+		std::string msg("VariableValue (string) packet has invalid "
+				"severity: ");
+		msg += boost::lexical_cast<std::string>(severity());
+		throw invalid_packet(msg);
+	}
+
+	/* TODO it would be better to create the string on access
+	 * rather than object construction; the user may not care.
+	 */
   m_val.assign((const char *)&m_fields[4], size);
 }
 
diff --git a/Code/Mantid/Framework/LiveData/src/ADARA/ADARAParser.cpp b/Code/Mantid/Framework/LiveData/src/ADARA/ADARAParser.cpp
index 9c5232b1616275a6557819ea62608f40bf84383d..f40b81e8b6a6d97efcfa87774f0ade4eb262bad3 100644
--- a/Code/Mantid/Framework/LiveData/src/ADARA/ADARAParser.cpp
+++ b/Code/Mantid/Framework/LiveData/src/ADARA/ADARAParser.cpp
@@ -1,3 +1,4 @@
+#include <sstream>
 #include <string.h>
 
 #include "MantidLiveData/ADARA/ADARAParser.h"
@@ -6,210 +7,277 @@ using namespace ADARA;
 
 /* ------------------------------------------------------------------------ */
 
-Parser::Parser(unsigned int initial_buffer_size, unsigned int max_pkt_size)
-    : m_size(initial_buffer_size), m_max_size(max_pkt_size), m_len(0),
-      m_restart_offset(0), m_oversize_len(0), m_oversize_offset(0) {
-  m_buffer = new uint8_t[initial_buffer_size];
+Parser::Parser(unsigned int initial_buffer_size, unsigned int max_pkt_size) :
+		m_size(initial_buffer_size), m_max_size(max_pkt_size), m_len(0),
+		m_restart_offset(0), m_oversize_len(0)
+{
+	m_buffer = new uint8_t[initial_buffer_size];
+	m_discarded_packets.clear();
 }
 
-Parser::~Parser() { delete[] m_buffer; }
+Parser::~Parser()
+{
+	delete [] m_buffer;
+}
+
+void Parser::reset(void)
+{
+	m_len = 0;
+	m_oversize_len = 0;
+	m_restart_offset = 0;
 
-void Parser::reset(void) {
-  m_len = 0;
-  m_oversize_len = 0;
-  m_restart_offset = 0;
+	m_discarded_packets.clear();
 }
 
-int Parser::bufferParse(unsigned int max_packets) {
-  unsigned int valid_len = m_len - m_restart_offset;
-  uint8_t *p = m_buffer + m_restart_offset;
-  unsigned int processed = 0;
-  bool stopped = false;
-
-  /* Is there anything to do? */
-  if (!valid_len)
-    return 0;
-
-  /* If we don't care how many packets we process, then set the limit
-   * above the range of possibility to avoid needing to check for zero
-   * multiple times.
-   */
-  if (!max_packets)
-    max_packets = m_size;
-
-  /* If we're processing an oversize packet, then we will find its
-   * data at the front of the buffer. We'll either consume our
-   * entire buffer, or find the end of the oversize packet and
-   * process the rest of the buffer as normal.
-   */
-  if (m_oversize_len) {
-    unsigned int chunk_len;
-
-    chunk_len = m_oversize_len;
-    if (valid_len < chunk_len)
-      chunk_len = valid_len;
-    stopped = rxOversizePkt(NULL, p, m_oversize_offset, chunk_len);
-    m_oversize_offset += chunk_len;
-    m_oversize_len -= chunk_len;
-    valid_len -= chunk_len;
-    p += chunk_len;
-
-    /* Did we finish this packet? */
-    if (!m_oversize_len)
-      processed++;
-  }
-
-  while (valid_len >= PacketHeader::header_length() &&
-         processed < max_packets && !stopped) {
-    PacketHeader hdr(p);
-
-    if (hdr.payload_length() % 4)
-      throw invalid_packet("Payload length not "
-                           "multiple of 4");
-
-    if (m_max_size < hdr.packet_length()) {
-      /* This packet is over the maximum limit; we'll
-       * call the oversize handler with this first
-       * chunk, consuming our entire buffer.
-       */
-      stopped = rxOversizePkt(&hdr, p, 0, valid_len);
-      m_oversize_len = hdr.packet_length() - valid_len;
-      m_oversize_offset = valid_len;
-      valid_len = 0;
-      break;
-    }
-
-    if (m_size < hdr.packet_length()) {
-      /* This packet is too big to possibly fit in our
-       * current buffer, so we need to grow. Once we've
-       * resized, return to our caller as we obviously
-       * don't have the full packet yet.
-       */
-      unsigned int new_size = m_size;
-      uint8_t *new_buffer;
-
-      do {
-        new_size *= 2;
-      } while (new_size < hdr.packet_length());
-
-      if (new_size > m_max_size)
-        new_size = m_max_size;
-
-      new_buffer = new uint8_t[new_size];
-      memcpy(new_buffer, p, valid_len);
-
-      delete[] m_buffer;
-      m_buffer = new_buffer;
-      m_size = new_size;
-
-      /* We moved the data to the front of the buffer as
-       * part of the resize; account for that.
-       */
-      m_restart_offset = 0;
-      m_len = valid_len;
-      return processed;
-    }
-
-    if (valid_len < hdr.packet_length())
-      break;
-
-    Packet pkt(p, hdr.packet_length());
-
-    p += hdr.packet_length();
-    valid_len -= hdr.packet_length();
-
-    stopped = rxPacket(pkt);
-    processed++;
-  }
-
-  /* We're done processing for this round. Update our position and/or
-   * amount of buffered data so that we restart in the correct spot
-   * on our next call.
-   *
-   * We only need to move data if we ran out of data to process --
-   * ie, we processed fewer packets than requested without being
-   * stopped by a callback. This moves any possible fragment of a
-   * packet to the front, maximizing the room for more data. If this
-   * occurs coincidentally with a stop request, the next call to
-   * to bufferParse() will only see the fragment and stop, but that
-   * should be rare.
-   */
-  if (valid_len) {
-    if (!stopped && processed < max_packets) {
-      if (p != m_buffer)
-        memmove(m_buffer, p, valid_len);
-      m_len = valid_len;
-      m_restart_offset = 0;
-    } else {
-      /* We know that the offset will fit into an unsigned
-       * int, as that is the type we use for the buffer size.
-       */
-      m_restart_offset = (unsigned int)(p - m_buffer);
-    }
-  } else {
-    /* We used up the buffer. */
-    m_len = 0;
-    m_restart_offset = 0;
-  }
-
-  /* We need an 32 GB buffer before we can fit 2^31 packets, so
-   * casting to int is safe here.
-   */
-  return stopped ? -(int)processed : (int)processed;
+int Parser::bufferParse(std::string & log_info, unsigned int max_packets)
+{
+	unsigned int valid_len = m_len - m_restart_offset;
+	uint8_t *p = m_buffer + m_restart_offset;
+	unsigned int processed = 0;
+	bool stopped = false;
+
+	/* Is there anything to do? */
+	if (!valid_len) {
+		log_info.append("bufferParse() nothing to do; ");
+		return 0;
+	}
+
+	/* If we don't care how many packets we process, then set the limit
+	 * above the range of possibility to avoid needing to check for zero
+	 * multiple times.
+	 */
+	if (!max_packets)
+		max_packets = m_size;
+
+	/* If we're processing an oversize packet, then we will find its
+	 * data at the front of the buffer. We'll either consume our
+	 * entire buffer, or find the end of the oversize packet and
+	 * process the rest of the buffer as normal.
+	 */
+	if (m_oversize_len) {
+		unsigned int chunk_len;
+
+		chunk_len = m_oversize_len;
+		if (valid_len < chunk_len)
+			chunk_len = valid_len;
+		stopped = rxOversizePkt(NULL, p, m_oversize_offset, chunk_len);
+		m_oversize_offset += chunk_len;
+		m_oversize_len -= chunk_len;
+		valid_len -= chunk_len;
+		p += chunk_len;
+
+		/* Did we finish this packet? */
+		if (!m_oversize_len)
+			processed++;
+	}
+
+	while (valid_len >= PacketHeader::header_length() &&
+					processed < max_packets && !stopped) {
+
+		PacketHeader hdr(p);
+
+		if (hdr.payload_length() % 4)
+			throw invalid_packet("Payload length not "
+					     "multiple of 4");
+
+		if (m_max_size < hdr.packet_length()) {
+			/* This packet is over the maximum limit; we'll
+			 * call the oversize handler with this first
+			 * chunk, consuming our entire buffer.
+			 */
+			stopped = rxOversizePkt(&hdr, p, 0, valid_len);
+			m_oversize_len = hdr.packet_length() - valid_len;
+			m_oversize_offset = valid_len;
+			valid_len = 0;
+			break;
+		}
+
+		if (m_size < hdr.packet_length()) {
+			/* This packet is too big to possibly fit in our
+			 * current buffer, so we need to grow. Once we've
+			 * resized, return to our caller as we obviously
+			 * don't have the full packet yet.
+			 */
+			unsigned int new_size = m_size;
+			uint8_t *new_buffer;
+
+			do {
+				new_size *= 2;
+			} while (new_size < hdr.packet_length());
+
+			if (new_size > m_max_size)
+				new_size = m_max_size;
+
+			new_buffer = new uint8_t[new_size];
+			memcpy(new_buffer, p, valid_len);
+
+			delete [] m_buffer;
+			m_buffer = new_buffer;
+			m_size = new_size;
+
+			/* We moved the data to the front of the buffer as
+			 * part of the resize; account for that.
+			 */
+			m_restart_offset = 0;
+			m_len = valid_len;
+
+			// log what we did...
+			std::stringstream ss;
+			ss << processed;
+			log_info.append("bufferParse(): resized, processed ");
+			log_info.append(ss.str());
+			log_info.append(" packets; ");
+
+			return processed;
+		}
+
+		if (valid_len < hdr.packet_length())
+			break;
+
+		Packet pkt(p, hdr.packet_length());
+
+		p += hdr.packet_length();
+		valid_len -= hdr.packet_length();
+
+		stopped = rxPacket(pkt);
+		processed++;
+
+		// log failed packet parsing...!
+		if ( stopped ) {
+			std::stringstream ss;
+			log_info.append(
+				"bufferParse(): rxPacket() returned error for type=");
+			ss << pkt.type();
+			log_info.append(ss.str());
+			log_info.append(", stopped; ");
+		}
+	}
+
+	/* We're done processing for this round. Update our position and/or
+	 * amount of buffered data so that we restart in the correct spot
+	 * on our next call.
+	 *
+	 * We only need to move data if we ran out of data to process --
+	 * ie, we processed fewer packets than requested without being
+	 * stopped by a callback. This moves any possible fragment of a
+	 * packet to the front, maximizing the room for more data. If this
+	 * occurs coincidentally with a stop request, the next call to
+	 * to bufferParse() will only see the fragment and stop, but that
+	 * should be rare.
+	 */
+	if (valid_len) {
+		if (!stopped && processed < max_packets) {
+			if (p != m_buffer)
+				memmove(m_buffer, p, valid_len);
+			m_len = valid_len;
+			m_restart_offset = 0;
+		} else {
+			/* We know that the offset will fit into an unsigned
+			 * int, as that is the type we use for the buffer size.
+			 */
+			m_restart_offset = (unsigned int) (p - m_buffer);
+		}
+	} else {
+		/* We used up the buffer. */
+		m_len = 0;
+		m_restart_offset = 0;
+	}
+
+	/* We need an 32 GB buffer before we can fit 2^31 packets, so
+	 * casting to int is safe here.
+	 */
+
+	std::stringstream ss;
+	int rc;
+	
+	if ( stopped ) {
+		rc = - (int) processed;
+		// add to "stopped" log info...
+		ss << processed;
+		log_info.append("had parsed ");
+		log_info.append(ss.str());
+		log_info.append(" packets; ");
+	}
+	else {
+		rc = (int) processed;
+		// create log info...
+		ss << rc;
+		log_info.append("bufferParse(): Done. Parsed ");
+		log_info.append(ss.str());
+		log_info.append(" packets; ");
+	}
+
+	return rc;
 }
 
-bool Parser::rxPacket(const Packet &pkt) {
-#define MAP_TYPE(pkt_type, obj_type)                                           \
-  case pkt_type: {                                                             \
-    obj_type raw(pkt.packet(), pkt.packet_length());                           \
-    return rxPacket(raw);                                                      \
-  }
-
-  switch (pkt.type()) {
-    MAP_TYPE(PacketType::RAW_EVENT_V0, RawDataPkt);
-    MAP_TYPE(PacketType::RTDL_V0, RTDLPkt);
-    MAP_TYPE(PacketType::SOURCE_LIST_V0, SourceListPkt);
-    MAP_TYPE(PacketType::BANKED_EVENT_V0, BankedEventPkt);
-    MAP_TYPE(PacketType::BEAM_MONITOR_EVENT_V0, BeamMonitorPkt);
-    MAP_TYPE(PacketType::PIXEL_MAPPING_V0, PixelMappingPkt);
-    MAP_TYPE(PacketType::RUN_STATUS_V0, RunStatusPkt);
-    MAP_TYPE(PacketType::RUN_INFO_V0, RunInfoPkt);
-    MAP_TYPE(PacketType::TRANS_COMPLETE_V0, TransCompletePkt);
-    MAP_TYPE(PacketType::CLIENT_HELLO_V0, ClientHelloPkt);
-    MAP_TYPE(PacketType::STREAM_ANNOTATION_V0, AnnotationPkt);
-    MAP_TYPE(PacketType::SYNC_V0, SyncPkt);
-    MAP_TYPE(PacketType::HEARTBEAT_V0, HeartbeatPkt);
-    MAP_TYPE(PacketType::GEOMETRY_V0, GeometryPkt);
-    MAP_TYPE(PacketType::BEAMLINE_INFO_V0, BeamlineInfoPkt);
-    MAP_TYPE(PacketType::DEVICE_DESC_V0, DeviceDescriptorPkt);
-    MAP_TYPE(PacketType::VAR_VALUE_U32_V0, VariableU32Pkt);
-    MAP_TYPE(PacketType::VAR_VALUE_DOUBLE_V0, VariableDoublePkt);
-    MAP_TYPE(PacketType::VAR_VALUE_STRING_V0, VariableStringPkt);
-
-    /* No default handler; we want the compiler to warn about
-     * the unhandled PacketType values when we add new packets.
-     */
-  }
-
-  return rxUnknownPkt(pkt);
+bool Parser::rxPacket(const Packet &pkt)
+{
+#define MAP_TYPE(pkt_type, obj_type)					\
+	case pkt_type: {						\
+		obj_type raw(pkt.packet(), pkt.packet_length());	\
+		return rxPacket(raw);					\
+	}
+
+	switch (pkt.type()) {
+		MAP_TYPE(PacketType::RAW_EVENT_V0, RawDataPkt);
+		MAP_TYPE(PacketType::MAPPED_EVENT_V0, MappedDataPkt);
+		MAP_TYPE(PacketType::RTDL_V0, RTDLPkt);
+		MAP_TYPE(PacketType::SOURCE_LIST_V0, SourceListPkt);
+		MAP_TYPE(PacketType::BANKED_EVENT_V0, BankedEventPkt);
+		MAP_TYPE(PacketType::BANKED_EVENT_V1, BankedEventPkt);
+		MAP_TYPE(PacketType::BEAM_MONITOR_EVENT_V0, BeamMonitorPkt);
+		MAP_TYPE(PacketType::BEAM_MONITOR_EVENT_V1, BeamMonitorPkt);
+		MAP_TYPE(PacketType::PIXEL_MAPPING_V0, PixelMappingPkt);
+		MAP_TYPE(PacketType::RUN_STATUS_V0, RunStatusPkt);
+		MAP_TYPE(PacketType::RUN_INFO_V0, RunInfoPkt);
+		MAP_TYPE(PacketType::TRANS_COMPLETE_V0, TransCompletePkt);
+		MAP_TYPE(PacketType::CLIENT_HELLO_V0, ClientHelloPkt);
+		MAP_TYPE(PacketType::STREAM_ANNOTATION_V0, AnnotationPkt);
+		MAP_TYPE(PacketType::SYNC_V0, SyncPkt);
+		MAP_TYPE(PacketType::HEARTBEAT_V0, HeartbeatPkt);
+		MAP_TYPE(PacketType::GEOMETRY_V0, GeometryPkt);
+		MAP_TYPE(PacketType::BEAMLINE_INFO_V0, BeamlineInfoPkt);
+		MAP_TYPE(PacketType::BEAMLINE_INFO_V1, BeamlineInfoPkt);
+		MAP_TYPE(PacketType::BEAM_MONITOR_CONFIG_V0, BeamMonitorConfigPkt);
+		MAP_TYPE(PacketType::DETECTOR_BANK_SETS_V0, DetectorBankSetsPkt);
+		MAP_TYPE(PacketType::DATA_DONE_V0, DataDonePkt);
+		MAP_TYPE(PacketType::DEVICE_DESC_V0, DeviceDescriptorPkt);
+		MAP_TYPE(PacketType::VAR_VALUE_U32_V0, VariableU32Pkt);
+		MAP_TYPE(PacketType::VAR_VALUE_DOUBLE_V0, VariableDoublePkt);
+		MAP_TYPE(PacketType::VAR_VALUE_STRING_V0, VariableStringPkt);
+
+		/* No default handler; we want the compiler to warn about
+		 * the unhandled PacketType values when we add new packets.
+		 */
+	}
+
+	return rxUnknownPkt(pkt);
 #undef MAP_TYPE
 }
 
-bool Parser::rxUnknownPkt(const Packet &) {
-  /* Default is to discard the data */
-  return false;
+bool Parser::rxUnknownPkt(const Packet &pkt)
+{
+	/* Default is to discard the data */
+	(m_discarded_packets[pkt.type()])++;
+	return false;
 }
 
-bool Parser::rxOversizePkt(const PacketHeader *, const uint8_t *, unsigned int,
-                           unsigned int) {
-  /* Default is to discard the data */
-  return false;
+bool Parser::rxOversizePkt(const PacketHeader *hdr, const uint8_t *,
+				unsigned int, unsigned int)
+{
+	// NOTE: ADARA::PacketHeader *hdr can be NULL...! ;-o
+	/* Default is to discard the data */
+	if (hdr != NULL)
+		(m_discarded_packets[hdr->type()])++;
+	return false;
 }
 
-#define EXPAND_HANDLER(type)                                                   \
-  bool Parser::rxPacket(const type &) { return false; }
+#define EXPAND_HANDLER(_class) \
+bool Parser::rxPacket(const _class &pkt) \
+	{ (m_discarded_packets[pkt.type()])++; return false; }
 
 EXPAND_HANDLER(RawDataPkt)
+EXPAND_HANDLER(MappedDataPkt)
 EXPAND_HANDLER(RTDLPkt)
 EXPAND_HANDLER(SourceListPkt)
 EXPAND_HANDLER(BankedEventPkt)
@@ -224,7 +292,42 @@ EXPAND_HANDLER(SyncPkt)
 EXPAND_HANDLER(HeartbeatPkt)
 EXPAND_HANDLER(GeometryPkt)
 EXPAND_HANDLER(BeamlineInfoPkt)
+EXPAND_HANDLER(BeamMonitorConfigPkt)
+EXPAND_HANDLER(DetectorBankSetsPkt)
+EXPAND_HANDLER(DataDonePkt)
 EXPAND_HANDLER(DeviceDescriptorPkt)
 EXPAND_HANDLER(VariableU32Pkt)
 EXPAND_HANDLER(VariableDoublePkt)
 EXPAND_HANDLER(VariableStringPkt)
+
+void Parser::getDiscardedPacketsLogString(std::string & log_info)
+{
+	log_info = "Discarded ADARA Packet/Counts: ";
+
+	uint64_t total_discarded = 0;
+
+	// Append Each Discarded Packet Type Count...
+	for (std::map<PacketType::Enum, uint64_t>::iterator
+			it = m_discarded_packets.begin();
+			it != m_discarded_packets.end(); ++it)
+	{
+		std::stringstream ss;
+		ss << std::hex << "0x" << it->first << std::dec
+			<< "=" << it->second << "; ";
+		log_info.append(ss.str());
+
+		total_discarded += it->second;
+	}
+
+	// Append Total Discarded Packet Count
+	std::stringstream ss;
+	ss << "Total=" << total_discarded;
+	log_info.append(ss.str());
+}
+
+void Parser::resetDiscardedPacketsStats(void)
+{
+	// Reset Associative Map, Start Clean Stats...
+	m_discarded_packets.clear();
+}
+
diff --git a/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp
index 60e074ffa4001ebc89d36da584aa53a68b0cce8d..92525ca8480f6d609eb5b8713c9efeff537a3219 100644
--- a/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp
+++ b/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp
@@ -265,7 +265,12 @@ void SNSLiveEventDataListener::run() {
           bufferBytesAppended(bytesRead);
         }
       }
-      int packetsParsed = bufferParse();
+
+      std::string bufferParseLog;
+      // bufferParse() wants a string where it can save log messages.
+      // We don't actually use the messages for anything, though.
+      int packetsParsed = bufferParse( bufferParseLog);
+      bufferParseLog.clear();  // keep the string from growing without bound
       if (packetsParsed == 0) {
         // No packets were parsed.  Sleep a little to let some data accumulate
         // before calling read again.  (Keeps us from spinlocking the cpu...)
@@ -1157,7 +1162,7 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::AnnotationPkt &pkt) {
   {
     Poco::ScopedLock<Poco::FastMutex> scopedLock(m_mutex);
     // We have to lock the mutex prior to calling mutableRun()
-    switch (pkt.type()) {
+    switch (pkt.marker_type()) {
     case ADARA::MarkerType::GENERIC:
       // Do nothing.  We log the comment field below for all types
       break;
diff --git a/Code/Mantid/Framework/LiveData/test/ADARAPacketTest.h b/Code/Mantid/Framework/LiveData/test/ADARAPacketTest.h
index 294cebe69ab155f924b73c703ad91f12d8feb7ee..ba329522b4b85cebd7906336cf64aa2e76b91044 100644
--- a/Code/Mantid/Framework/LiveData/test/ADARAPacketTest.h
+++ b/Code/Mantid/Framework/LiveData/test/ADARAPacketTest.h
@@ -121,7 +121,7 @@ public:
     if( pkt != NULL)
     {
       TS_ASSERT_EQUALS( pkt->cycle(), 60);
-      TS_ASSERT_EQUALS( pkt->veto(), 0x4);
+      TS_ASSERT_EQUALS( pkt->vetoFlags(), 0x4);
       TS_ASSERT_EQUALS( pkt->badVeto(), false);
       TS_ASSERT_EQUALS( pkt->timingStatus(), 0x1e);
       TS_ASSERT_EQUALS( pkt->flavor(), 1);
@@ -175,6 +175,7 @@ public:
 protected:
   // The rxPacket() functions just make a copy of the packet available in the public member
   // The test class will handle everything from there.
+  using ADARA::Parser::rxPacket;
 #define DEFINE_RX_PACKET( PktType) \
   virtual bool rxPacket( const PktType &pkt) { m_pkt.reset( new PktType( pkt)); return false; }
 
@@ -258,11 +259,14 @@ private:
     bufferBytesAppended( len);
 
     int packetsParsed = 0;
-    TS_ASSERT_THROWS_NOTHING( (packetsParsed = bufferParse( 1)));
+    std::string bufferParseLog;
+    // bufferParse() wants a string where it can save log messages.
+    // We don't actually use the messages for anything, though.
+    TS_ASSERT_THROWS_NOTHING( (packetsParsed = bufferParse( bufferParseLog, 1)));
     TS_ASSERT( packetsParsed == 1);
     TS_ASSERT( m_pkt != boost::shared_ptr<ADARA::Packet>());  // verify m_pkt has been updated
 
-    TS_ASSERT( bufferParse( 0) == 0); // try to parse again, make sure there's nothing to parse
+    TS_ASSERT( bufferParse( bufferParseLog, 0) == 0); // try to parse again, make sure there's nothing to parse
     TS_ASSERT( bufferFillAddress() == m_initialBufferAddr);  // verify that there's nothing in the buffer
   }