diff --git a/src/register/prdfCaptureData.C b/src/register/prdfCaptureData.C
new file mode 100755
index 0000000..3911350
--- /dev/null
+++ b/src/register/prdfCaptureData.C
@@ -0,0 +1,403 @@
+/* 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 <iipbits.h>
+#include <prdfHomRegisterAccess.H>  // dg06a
+#include <prdfScomRegister.H>
+#include <iipchip.h>
+#include <iipCaptureData.h>
+#include <string.h>
+#include <algorithm>    // @jl04 a Add this for the Drop function.
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+//---------------------------------------------------------------------
+// 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,
+                       SCAN_COMM_REGISTER_CLASS & 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) )
+    {
+        PRDF_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  =NULL;
+        l_chipHuid =  ntohl(l_chipHuid);
+        l_pchipHandle = PlatServices::getTarget(l_chipHuid );
+        if(NULL ==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(NULL)
+{
+    if(d.dataPtr != NULL)
+    {
+        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 != NULL)
+    {
+        delete[]dataPtr;
+        dataPtr = NULL;
+    }
+    if(d.dataPtr != NULL)
+    {
+        dataPtr = new uint8_t[dataByteLength];
+        memcpy(dataPtr, d.dataPtr, dataByteLength);
+    }
+
+    return *this;
+}
+
+} // end of namespace PRDF
