diff --git a/src/register/iipCaptureData.h b/src/register/iipCaptureData.h
deleted file mode 100755
index e47b5bc..0000000
--- a/src/register/iipCaptureData.h
+++ /dev/null
@@ -1,406 +0,0 @@
-// clang-format off
-/* IBM_PROLOG_BEGIN_TAG                                                   */
-/* This is an automatically generated prolog.                             */
-/*                                                                        */
-/* $Source: src/usr/diag/prdf/common/framework/register/iipCaptureData.h $ */
-/*                                                                        */
-/* OpenPOWER HostBoot Project                                             */
-/*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
-/* [+] International Business Machines Corp.                              */
-/*                                                                        */
-/*                                                                        */
-/* Licensed under the Apache License, Version 2.0 (the "License");        */
-/* you may not use this file except in compliance with the License.       */
-/* You may obtain a copy of the License at                                */
-/*                                                                        */
-/*     http://www.apache.org/licenses/LICENSE-2.0                         */
-/*                                                                        */
-/* Unless required by applicable law or agreed to in writing, software    */
-/* distributed under the License is distributed on an "AS IS" BASIS,      */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
-/* implied. See the License for the specific language governing           */
-/* permissions and limitations under the License.                         */
-/*                                                                        */
-/* IBM_PROLOG_END_TAG                                                     */
-
-#ifndef iipCaptureData_h
-#define iipCaptureData_h
-
-// Class Specification *************************************************
-//
-// Class name:   CaptureData
-// Parent class: None.
-//
-// Summary: This class provides a queue-like buffer for recording Scan
-//          Comm Register data.
-//
-//          When this class is constructed or the Clear() member
-//          function is called, the buffer is empty.  The Add()
-//          function adds data to the front or back of this buffer.
-//          The data is ordered according to the sequence of Add()
-//          calls and the Place parameter (FRONT or BACK).  A Scan
-//          Comm Register is passed to the Add() function and the
-//          register is read during the Add() function.  The data is
-//          then stored internally.  Whenever the Copy() member
-//          function is called, the current internal data is copied to
-//          the specified buffer with respect to the current ordering.
-//          Only the number of bytes specified are copied.  Therefore,
-//          any data that MUST be copied should be added using the
-//          FRONT placement.
-//
-// Cardinality: N
-//
-// Performance/Implementation:
-//   Space Complexity: Linear based on the number of Add() calls
-//   Time Complexity:  All member functions constant unless otherwise
-//                     stated.
-//
-// Usage Examples:
-//
-// BIT8 data[BUFFER_SIZE];
-//
-// void foo(TARGETING::TargetHandle_t chipId, ScanCommRegisterAccess & scr)
-//   {
-//   CaptureData captureData;
-//
-//   captureData.Add(chipId, scr, CaptureData::FRONT);
-//   captureData.Add(chipId, scr, CaptureData::BACK);
-//
-//   int bytesCopied = captureData.Copy(data, BUFFER_SIZE);
-//   }
-//
-// End Class Specification *********************************************
-
-/*--------------------------------------------------------------------*/
-/* Reference the virtual function tables and inline function
-   defintions in another translation unit.                            */
-/*--------------------------------------------------------------------*/
-
-#include <list>
-
-#include <hei_includes.hpp>
-
-#include <prdfPlatServices.H>
-#include <functional>  // @jl04 a Needed for the unary function in new predicate.
-
-#ifdef __HOSTBOOT_MODULE
-
-  // FIXME: RTC 73204 was opened to add support for these in hostboot. They will
-  //        need to be removed once the issue has been resolved.
-  #ifndef htonl
-    #define htonl(foo) (foo)
-  #endif
-
-  #ifndef htons
-    #define htons(foo) (foo)
-  #endif
-
-  #ifndef ntohl
-    #define ntohl(foo) (foo)
-  #endif
-
-  #ifndef ntohs
-    #define ntohs(foo) (foo)
-  #endif
-
-#else
-
-  #include <netinet/in.h>
-
-#endif
-
-namespace libhei
-{
-
-// Forward Declarations
-class Register;
-class ScanCommRegisterAccess;
-class BitString;
-
-// @jl04 a start
-// @jl04 a Added this enumeration for error log compression, elimination of secondary regs.
-  enum RegType
-  {
-    PRIMARY   = 1,
-    SECONDARY = 2
-  };
-// @jl04 a Stop
-
-/**
- Capture data class
- @author Doug Gilbert
- @version V5R2
-*/
-class CaptureData
-{
-public:
-
-  enum Place
-  {
-    FRONT,
-    BACK
-  };
-
-  enum
-  {
-    INITIAL_DATA_COUNT = 80,
-    ENTRY_FIXED_SIZE = 8,
-    MAX_ENTRY_SIZE = 128
-  };
-
-  /**
-   Constructor
-   */
-  CaptureData(void);
-
-  /*
-   Copy constructor - default is ok
-   */
-//  CaptureData(const CaptureData & c);
-
-  /*
-   Assignment operator - default is ok
-   */
-//  CaptureData & operator=(const CaptureData & c);
-
-  /**
-   Destructor
-   */
-// dg05d  ~CaptureData(void);   // compiler default is ok
-
-  /**
-   Clear out capture data
-   <ul>
-   <br><b>Parameters:None
-   <br><b>Returns:Nothing
-   <br><b>Requirments:None.
-   <br><b>Promises: All capture data cleared ( copy(...) == 0 )
-   </ul><br>
-   */
-  void Clear(void);
-
-  // dg00 start
-  /**
-   Add scr & data to capture log
-   <ul>
-   <br><b>Parameter:  chipHandle     target handle of chip object
-   <br><b>Parameter:  scan comm id (unique one btye code representing scan comm address)
-   <br><b>Parameter:  Scan comm register object
-   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
-   <br><b>Returns:   Nothing
-   <br><b>Requires:  Nothing
-   <br><b>Promises:  scr.Read()
-   <br><b>Notes:     This is the required Add() method for Regatta and beyond
-   </ul><br>
-   */
-  void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
-            Register & scr, Place place = BACK,
-            RegType type = PRIMARY);  // @jl04 c. Changed this to add the type to the end of the parms.
-  // dg00 end
-
-  /*  REMOVE for FSP
-   Add scr & data to capture log
-   <ul>
-   <br><b>Parameter:  chipHandle     target handle of chip object
-   <br><b>Parameter:  Scan comm register object
-   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
-   <br><b>Returns:   Nothing
-   <br><b>Requires:  Nothing
-   <br><b>Promises:  scr.Read()
-   <br><b>Notes:     This is the required Add() method for pre-Regatta
-   </ul><br>
-
-  void Add(TARGETING::TargetHandle_t chipId, Register & scr,
-      Place place = BACK);
-*/
-
-  // dg02 start
-  /**
-   Add scr & data to capture log
-   <ul>
-   <br><b>Parameter:  i_pchipHandle Handle of chip object
-   <br><b>Parameter:  scan comm id (unique one btye code representing scan comm address)
-   <br><b>Parameter:  BitString
-   <br><b>Parameter:  Optional location in capure vector [FRONT | BACK] def = BACK
-   <br><b>Returns:   Nothing
-   <br><b>Requires:  Nothing
-   <br><b>Promises:
-   <br><b>Notes:     This is available for Regatta and beyond. Not implemented on Condor
-   </ul><br>
-   */
-  void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
-            const BitString & bs, Place place = BACK);
-
-  // dg02 end
-
-// start @jl04a
-  /**
-   Drop scr & data from capture log
-   <ul>
-   <br><b>Parameter:  Type of capture vector [PRIMARY | SECONDARY] def = PRIMARY. SECONDARIES dropped on connected.
-   <br><b>Returns:   Nothing
-   <br><b>Requires:  Nothing
-   <br><b>Promises:
-   </ul><br>
-   */
-void Drop(RegType type);  //@jl04a
-// end @jl04a
-
-    /**
-     * @brief  Copies the capture data to a buffer.
-     *
-     * The capture data is copied to the buffer in the order it exists in the
-     * vector until all entries have been added or until the buffer is full.
-     *
-     * @param  i_buffer     Pointer to buffer.
-     * @param  i_bufferSize Maximum size of the buffer.
-     * @return The actual size of the data buffer. The value will always be less
-     *         than or equal to the maximum buffer size.
-     */
-    uint32_t Copy( uint8_t * i_buffer, uint32_t i_bufferSize ) const;
-
-  // dg08a -->
-  /**
-   Reconstruct data from flat data
-   <ul>
-   <br><b>Parameter:  i_flatdata ptr to flat data
-   <br><b>Returns:   reference to the new capture data
-   <br><b>Requirements: None
-   <br><b>Promises:  CaptureData created form flatdata
-   <br><b>Note:  i_flatdata -> (uin32_t)size + data created by Copy()
-                 data is network ordered bytes.
-   <ul><br>
-   */
-  CaptureData & operator=(const uint8_t *i_flatdata);
-  // <-- dg08a
-
-private:
-
-  // Notes *************************************************************
-  //
-  // Instead of maintaining an actual data buffer, an auxiliary data
-  // structure is used to maintain data in a specific order.  The main
-  // reason for this is that since data can be entered in the front or
-  // back of the buffer, the data must be copied to maintain the order.
-  // It is more efficient to copy a number of pointers than a large
-  // data buffer.  However, there is added complexity since the data
-  // structure contains a pointer to dynamic data that must be
-  // allocated/deallocated properly.
-  //
-  // A vector of data structures is maintained that is given an initial
-  // size.  The vector can grow dynamically, but this can be expensive
-  // in terms of copying and memory fragmentation.  To prevent this, the
-  // number of calls to Add() between calls to Clear() should not exceed
-  // the enum INITIAL_DATA_COUNT.
-  //
-  // End Notes *********************************************************
-
-  class Data
-  {
-  public:
-    // Ctor
-    Data(TARGETING::TargetHandle_t i_pchipHandle= nullptr,   // dg01
-         uint16_t a = 0,
-         uint16_t  dbl = 0,
-         uint8_t * dPtr = nullptr)
-    :
-    chipHandle(i_pchipHandle),
-    address(a),
-    dataByteLength(dbl),
-    dataPtr(dPtr)
-    {}
-
-    ~Data(void)                     // dg05a
-    {                               // dg05a
-      if(dataPtr != nullptr)           // dg05a
-      {                             // dg05a
-        delete [] dataPtr;          // pw01
-      }                             // dg05a
-    }                               // dg05a
-    // Data
-    TARGETING::TargetHandle_t  chipHandle;
-    uint16_t address;
-    uint16_t  dataByteLength;
-    uint8_t * dataPtr;
-
-    RegType registerType;          // @jl04a
-
-    Data(const Data & d);
-    Data & operator=(const Data & d);
-  };
-
-// We should probably use a link list instead of a vector
-  typedef std::list<Data> DataContainerType;
-  typedef DataContainerType::iterator DataIterator;
-  typedef DataContainerType::const_iterator ConstDataIterator;
-
-  DataContainerType             data;
-
-    /** Private function to facilitate the adding of caputre data to the
-     *  internal vector */
-    void AddDataElement( TARGETING::TargetHandle_t i_trgt, int i_scomId,
-                         const BitString * i_bs, Place i_place,
-                         RegType i_type = PRIMARY );
-
-  // Predicate for deciding to delete an element of data from a Capture Data list.
-  class prdfCompareCaptureDataType : public std::unary_function<Data &, bool>
-  {
-    public:
-      prdfCompareCaptureDataType(RegType i_ctor_input) : __private_storage(i_ctor_input){};
-      bool operator() (Data &i)
-      {
-        return (i.registerType == __private_storage);
-      };
-
-
-    private:
-    //Private storage for value passed in.
-      RegType __private_storage;
-    //Constructor allows a value to be passed in to compare against.
-  };
-
-  // Predicate for deciding whether to delete an
-  // element of data from a Capture Data list.
-  class prdfCompareCaptureDataEntry :
-      public std::unary_function<Data &, bool>
-  {
-    public:
-      prdfCompareCaptureDataEntry(
-                    TARGETING::TargetHandle_t chipHandle,
-                    uint16_t address) :
-                    __chipHandle(chipHandle),
-                    __address(address) {};
-      bool operator() (Data &i)
-      {
-        return ((i.chipHandle == __chipHandle) &&
-                (i.address    == __address));
-      };
-
-    private:
-      TARGETING::TargetHandle_t  __chipHandle;
-      uint16_t __address;
-  };
-
-public:
-
-  /**
-   * @brief   Merge scom register data from two captures
-   * @param   i_cd  secondary capture data to merge
-   */
-  void mergeData(CaptureData & i_cd);
-
-  /**
-   * @brief   Get the Scom data pointer
-   * @return  the Scom data pointer
-   */
-  DataContainerType * getData() { return &data; }
-
-
-
-};
-
-} // end namespace libhei
-
-#endif
-// clang-format on
diff --git a/src/register/prdfCaptureData.C b/src/register/prdfCaptureData.C
deleted file mode 100755
index a984f24..0000000
--- a/src/register/prdfCaptureData.C
+++ /dev/null
@@ -1,406 +0,0 @@
-// clang-format off
-/* IBM_PROLOG_BEGIN_TAG                                                   */
-/* This is an automatically generated prolog.                             */
-/*                                                                        */
-/* $Source: src/usr/diag/prdf/common/framework/register/prdfCaptureData.C $ */
-/*                                                                        */
-/* OpenPOWER HostBoot Project                                             */
-/*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
-/* [+] International Business Machines Corp.                              */
-/*                                                                        */
-/*                                                                        */
-/* Licensed under the Apache License, Version 2.0 (the "License");        */
-/* you may not use this file except in compliance with the License.       */
-/* You may obtain a copy of the License at                                */
-/*                                                                        */
-/*     http://www.apache.org/licenses/LICENSE-2.0                         */
-/*                                                                        */
-/* Unless required by applicable law or agreed to in writing, software    */
-/* distributed under the License is distributed on an "AS IS" BASIS,      */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
-/* implied. See the License for the specific language governing           */
-/* permissions and limitations under the License.                         */
-/*                                                                        */
-/* IBM_PROLOG_END_TAG                                                     */
-
-/**
-  @file prdfCaptureData.C
-  @brief Squadrons implementation of capture data
-*/
-//----------------------------------------------------------------------
-//  Includes
-//----------------------------------------------------------------------
-
-#include <hei_macros.hpp>
-#include <register/hei_hardware_register.hpp>
-#include <util/hei_bit_string.hpp>
-
-#include <iipchip.h>
-#include <iipCaptureData.h>
-#include <string.h>
-#include <algorithm>    // @jl04 a Add this for the Drop function.
-
-using namespace TARGETING;
-
-namespace libhei
-{
-
-//---------------------------------------------------------------------
-// Member Function Specifications
-//---------------------------------------------------------------------
-
-CaptureData::CaptureData(void):data()
-{
-//  data.reserve(INITIAL_DATA_COUNT);
-}
-
-// dg05d CaptureData::~CaptureData(void)
-// dg05d {
-// dg05d   if(!data.empty())
-// dg05d   {
-// dg05d     Clear();
-// dg05d   }
-// dg05d }
-
-void CaptureData::Clear(void)
-{
-
-  if(!data.empty())
-  {
-// dg05d   for(DataContainerType::iterator i  = data.begin();i != data.end();i++)
-// dg05d   {
-// dg05d     delete [] (*i).dataPtr;
-// dg05d   }
-
-    data.erase(data.begin(), data.end());
-
-  }                             /* if not empty */
-}
-
-//------------------------------------------------------------------------------
-
-void CaptureData::AddDataElement( TargetHandle_t i_trgt, int i_scomId,
-                                  const BitString * i_bs,
-                                  Place i_place, RegType i_type )
-{
-    // Initial values of the bit string buffer if i_bs has a zero value.
-    uint8_t * buf = nullptr;
-    size_t sz_buf = 0;
-
-    // Add buffer only if the value is non-zero.
-    if ( !i_bs->isZero() )
-    {
-        // Get the size of i_bs and ensure byte alignment.
-        sz_buf = (i_bs->getBitLen() + 8-1) / 8;
-
-        // Since we are using a BitString below, which does everything on a
-        // CPU_WORD boundary, we must make sure the buffer is CPU_WORD aligned.
-        const size_t sz_word = sizeof(CPU_WORD);
-        sz_buf = ((sz_buf + sz_word-1) / sz_word) * sz_word;
-
-        // Allocate memory for the buffer.
-        buf = new uint8_t[sz_buf];
-        memset( buf, 0x00, sz_buf );
-
-        // Use a BitString to copy i_bs to the buffer.
-        BitString bs ( i_bs->getBitLen(), (CPU_WORD *)buf );
-        bs.setString( *i_bs );
-
-        // Create the new data element.
-        Data element( i_trgt, i_scomId, sz_buf, buf );
-        element.registerType = i_type;
-
-        // Add the new element to the data.
-        if ( FRONT == i_place )
-            data.insert( data.begin(), element );
-        else
-            data.push_back( element );
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void CaptureData::Add( TargetHandle_t i_trgt, int32_t i_scomId,
-                       Register & io_scr,
-                       Place i_place, RegType i_type )
-{
-    if ( SUCCESS == io_scr.Read() )
-    {
-        AddDataElement( i_trgt, i_scomId, io_scr.GetBitString(),
-                        i_place, i_type );
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void CaptureData::Add( TargetHandle_t i_trgt, int i_scomId,
-                       const BitString & i_bs, Place i_place )
-{
-    AddDataElement( i_trgt, i_scomId, &i_bs, i_place );
-}
-
-//------------------------------------------------------------------------------
-
-// start jl04a
-void CaptureData::Drop(RegType i_type)
-{
-  //  Function below requires a predicate function above to Drop
-  //  a data element from the capture data if it is
-  //    defined as secondary data instead of primary data in the rule files.
-  //  This predicate has to exist within the CaptureData Class because the
-  //  class "Data" is defined within CaptureData class.
-  data.erase( std::remove_if(data.begin(),data.end(),
-              prdfCompareCaptureDataType(i_type)), data.end() );
-}
-// end jl04a
-
-//------------------------------------------------------------------------------
-
-template <class T>
-void __bufferAdd( uint8_t* & i_idx, T i_val )
-{
-    memcpy( i_idx, &i_val, sizeof(i_val) );
-    i_idx += sizeof(i_val);
-}
-
-bool __bufferFull( uint8_t * i_buf, size_t i_bufSize,
-                   uint8_t * i_idx, size_t i_idxSize )
-{
-    if ( (i_buf + i_bufSize) < (i_idx + i_idxSize) )
-    {
-        HEI_ERR( "[CaptureData::Copy] Buffer is full. Some data may have "
-                  "been lost" );
-        return true;
-    }
-
-    return false;
-}
-
-/* CaptureData Format:
- *        capture data -> ( <chip header> <registers> )*
- *        chip header -> ( <chip id:32> <# registers:32> )
- *        registers -> ( <reg id:16> <reg byte len:16> <bytes>+ )
- */
-uint32_t CaptureData::Copy( uint8_t * i_buffer, uint32_t i_bufferSize ) const
-{
-    TargetHandle_t curTrgt = nullptr;
-
-    uint32_t * regCntPtr = nullptr;
-
-    uint8_t * curIdx = i_buffer;
-
-    for ( auto & entry : data )
-    {
-        // We only need the target data when the target for this entry does not
-        // match the previous entry.
-        if ( entry.chipHandle != curTrgt )
-        {
-            // Ensure we have enough space for the entry header.
-            if ( __bufferFull( i_buffer, i_bufferSize, curIdx,
-                               (sizeof(HUID) + sizeof(uint32_t)) ) )
-            {
-                break;
-            }
-
-            // Update current target.
-            curTrgt = entry.chipHandle;
-
-            // Add HUID to buffer.
-            __bufferAdd( curIdx, htonl(PlatServices::getHuid(curTrgt)) );
-
-            // Update the current count pointer.
-            regCntPtr = (uint32_t *)curIdx;
-
-            // Zero out the register count.
-            __bufferAdd( curIdx, htonl(0) );
-        }
-
-        // Go to next entry if the data byte length is 0.
-        if ( 0 == entry.dataByteLength )
-            continue;
-
-        // Ensure we have enough space for the entry header.
-        if ( __bufferFull( i_buffer, i_bufferSize, curIdx,
-                           (2 * sizeof(uint16_t) + entry.dataByteLength) ) )
-        {
-            break;
-        }
-
-        // Write register ID.
-        __bufferAdd( curIdx, htons(entry.address) );
-
-        // Write data length.
-        __bufferAdd( curIdx, htons(entry.dataByteLength) );
-
-        // Write the data.
-        // >>> TODO: RTC 199045 The data should already be in network format.
-        //           However, that is not the case. Instead, the data is
-        //           converted here, which would be is fine if we were only
-        //           adding registers, but we have additional capture data,
-        //           especially in the memory subsytem, that are actually stored
-        //           in the network format, but swizzled before adding to the
-        //           capture data. Which means we are doing too much.
-        //           Unfortunately, it currently works and will take some time
-        //           to actually do it right. Therefore, we will leave this
-        //           as-is and try to make the appropriate fix later.
-        uint32_t l_dataWritten = 0;
-        while ((l_dataWritten + 4) <= entry.dataByteLength)
-        {
-            uint32_t l_temp32;
-            memcpy(&l_temp32, &entry.dataPtr[l_dataWritten], sizeof(l_temp32));
-            l_temp32 = htonl(l_temp32);
-            memcpy(curIdx, &l_temp32, 4);
-            l_dataWritten += 4; curIdx += 4;
-        }
-        if (l_dataWritten != entry.dataByteLength)
-        {
-            // TODO: RTC 199045 This is actually pretty bad because it will read
-            //       four bytes of memory, sizzle the four bytes, then write
-            //       less than four bytes to the buffer. This could cause a
-            //       buffer overrun exception if we were at the end of memory.
-            //       Also, how can we trust the right most bytes to be correct
-            //       since they technically should not be part of the entry
-            //       data? Again, we don't seem to be hitting this bug and it
-            //       will take time to fix it (see note above). Therefore, we
-            //       will leave it for now and fix it when we have time.
-            uint32_t l_temp32;
-            memcpy(&l_temp32, &entry.dataPtr[l_dataWritten], sizeof(l_temp32));
-            l_temp32 = htonl(l_temp32);
-            memcpy(curIdx, &l_temp32, entry.dataByteLength - l_dataWritten);
-            curIdx += entry.dataByteLength - l_dataWritten;
-        }
-        // <<< TODO: RTC 199045
-
-        // Update entry count. It is important to update the buffer just in
-        // case we happen to run out of room in the buffer and need to exit
-        // early.
-        *regCntPtr = htonl( ntohl(*regCntPtr) + 1 );
-    }
-
-    return curIdx - i_buffer;
-}
-
-// dg08a -->
-CaptureData & CaptureData::operator=(const uint8_t *i_flatdata)
-{
-    uint32_t l_tmp32 = 0;
-    uint16_t l_tmp16 = 0;
-
-    HUID  l_chipHuid = INVALID_HUID;
-    const size_t l_huidSize = sizeof(l_chipHuid);
-
-    // Read size.
-    memcpy(&l_tmp32, i_flatdata, sizeof(uint32_t));
-    uint32_t size = ntohl(l_tmp32);
-    i_flatdata += sizeof(uint32_t);
-
-    Clear();
-
-    // Calculate end of buffer.
-    const uint8_t *eptr = i_flatdata + size;
-
-    while(i_flatdata < eptr)
-    {
-        // Read chip Handle.
-        memcpy(&l_chipHuid , i_flatdata,l_huidSize );
-        i_flatdata += l_huidSize ;
-        TargetHandle_t l_pchipHandle  =nullptr;
-        l_chipHuid =  ntohl(l_chipHuid);
-        l_pchipHandle = PlatServices::getTarget(l_chipHuid );
-        if(nullptr ==l_pchipHandle)
-        {
-            continue;
-        }
-
-        // Read # of entries.
-        memcpy(&l_tmp32, i_flatdata, sizeof(uint32_t));
-        i_flatdata += sizeof(l_tmp32);
-        uint32_t entries = ntohl(l_tmp32);
-
-        // Input each entry.
-        for(uint32_t i = 0; i < entries; ++i)
-        {
-            // Read register id.
-            memcpy(&l_tmp16, i_flatdata, sizeof(uint16_t));
-            i_flatdata += sizeof(uint16_t);
-            int regid = ntohs(l_tmp16);
-
-            // Read byte count.
-            memcpy(&l_tmp16, i_flatdata, sizeof(uint16_t));
-            i_flatdata += sizeof(uint16_t);
-            uint32_t bytecount = ntohs(l_tmp16);
-
-            // Read data for register.
-            BitStringBuffer bs(bytecount * 8);
-            for(uint32_t bc = 0; bc < bytecount; ++bc)
-            {
-                bs.setFieldJustify(bc*8,8,(CPU_WORD)(*(i_flatdata+bc))); //mp01a
-            }
-            i_flatdata += bytecount;
-
-            // Add to capture data.
-            Add(l_pchipHandle, regid, bs);
-        }
-    }
-
-    return *this;
-}
-
-// <-- dg08a
-
-void CaptureData::mergeData(CaptureData & i_cd)
-{
-    DataContainerType l_data = *(i_cd.getData());
-
-    if( !l_data.empty() )
-    {
-        // Remove duplicate entries from secondary capture data
-        for (ConstDataIterator i = data.begin(); i != data.end(); i++)
-        {
-            l_data.remove_if(prdfCompareCaptureDataEntry(i->chipHandle,
-                                                         i->address) );
-        }
-
-        // Add secondary capture data to primary one
-        data.insert( data.end(),
-                     l_data.begin(),
-                     l_data.end() );
-    }
-}
-
-
-// copy ctor for Data class
-CaptureData::Data::Data(const Data & d):
-chipHandle(d.chipHandle), address(d.address),
-dataByteLength(d.dataByteLength), dataPtr(nullptr)
-{
-    if(d.dataPtr != nullptr)
-    {
-        dataPtr = new uint8_t[dataByteLength];
-
-        memcpy(dataPtr, d.dataPtr, dataByteLength);
-    }
-}
-
-CaptureData::Data & CaptureData::Data::operator=(const Data & d)
-{
-    chipHandle = d.chipHandle;
-    address = d.address;
-    dataByteLength = d.dataByteLength;
-    if(dataPtr != nullptr)
-    {
-        delete[]dataPtr;
-        dataPtr = nullptr;
-    }
-    if(d.dataPtr != nullptr)
-    {
-        dataPtr = new uint8_t[dataByteLength];
-        memcpy(dataPtr, d.dataPtr, dataByteLength);
-    }
-
-    return *this;
-}
-
-} // end namespace libhei
-// clang-format on
