diff --git a/src/register/hei_operator_register.hpp b/src/register/hei_operator_register.hpp
new file mode 100755
index 0000000..14875b4
--- /dev/null
+++ b/src/register/hei_operator_register.hpp
@@ -0,0 +1,671 @@
+#pragma once
+
+#include <algorithm>
+
+#include <iipscr.h>
+#include <prdrCommon.H>
+
+namespace libhei
+{
+
+class NotRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    NotRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    NotRegister(SCAN_COMM_REGISTER_CLASS & i_arg) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg),
+        iv_iBS(i_arg.GetBitLength())
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    NotRegister & operator=(const NotRegister & r)
+    {
+        iv_child = r.iv_child;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const { return iv_child->Read();  }
+    virtual uint32_t Write()      { return iv_child->Write(); }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        (*iv_bs) = ~(*iv_child->GetBitString(i_type));
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const { return iv_child->GetId(); }
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const NotRegister & r) const
+    { return r.iv_child == iv_child; }
+
+    bool operator<(const NotRegister & r) const
+    { return iv_child < r.iv_child; }
+
+    bool operator>=(const NotRegister & r) const
+    { return iv_child >= r.iv_child; }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_child;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class SummaryRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    SummaryRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    SummaryRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+        iv_iBS(i_arg.GetBitLength())
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    SummaryRegister & operator=(const SummaryRegister & r)
+    {
+        iv_child = r.iv_child;
+        iv_amount = r.iv_amount;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const
+    {
+        uint32_t rc = iv_child->Read();
+        if ( PRD_SCANCOM_FAILURE == rc )
+        {
+            // This is a bit unusual, but we are going to ignore SCOM failures.
+            // This takes care of a corner case where one of the summary
+            // registers in the list returns an error, but there is another
+            // summary register with an active attention, which would be ignored
+            // if we return a bad rc.
+            PRDF_INF( "[SummaryRegister::read] SCOM failure on register ID "
+                      "0x%04x, ignoring error", iv_child->GetId() );
+            rc = SUCCESS;
+            iv_child->clearAllBits(); // just in case
+        }
+        return rc;
+    }
+
+    virtual uint32_t Write()      { return iv_child->Write(); }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        iv_bs->clearAll();
+
+        PRDF::BitString tmp = *iv_child->GetBitString(i_type);
+
+        //if any bits are set in iv_child, then set the iv_amount bit
+        if (0 != tmp.getSetCount())
+        {
+            iv_bs->setBit(0);
+            *iv_bs = *iv_bs >> iv_amount;
+        }
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const { return iv_child->GetId(); }
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const SummaryRegister & r) const
+    { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+    bool operator<(const SummaryRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount < r.iv_amount;
+        return iv_child < r.iv_child;
+    }
+
+    bool operator>=(const SummaryRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount >= r.iv_amount;
+        return iv_child >= r.iv_child;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_child;
+    uint16_t iv_amount;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class LeftShiftRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    LeftShiftRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    LeftShiftRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+        iv_iBS(i_arg.GetBitLength())
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    LeftShiftRegister & operator=(const LeftShiftRegister & r)
+    {
+        iv_child = r.iv_child;
+        iv_amount = r.iv_amount;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const { return iv_child->Read();  }
+    virtual uint32_t Write()      { return iv_child->Write(); }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        (*iv_bs) = (*iv_child->GetBitString(i_type)) << iv_amount;
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const { return iv_child->GetId(); }
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const LeftShiftRegister & r) const
+    { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+    bool operator<(const LeftShiftRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount < r.iv_amount;
+        return iv_child < r.iv_child;
+    }
+
+    bool operator>=(const LeftShiftRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount >= r.iv_amount;
+        return iv_child >= r.iv_child;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_child;
+    uint16_t iv_amount;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class RightShiftRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    RightShiftRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    RightShiftRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+        iv_iBS(i_arg.GetBitLength())
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    RightShiftRegister & operator=(const RightShiftRegister & r)
+    {
+        iv_child = r.iv_child;
+        iv_amount = r.iv_amount;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const { return iv_child->Read();  }
+    virtual uint32_t Write()      { return iv_child->Write(); }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        (*iv_bs) = (*iv_child->GetBitString(i_type)) >> iv_amount;
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const { return iv_child->GetId(); }
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const RightShiftRegister & r) const
+    { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+    bool operator<(const RightShiftRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount < r.iv_amount;
+        return iv_child < r.iv_child;
+    }
+
+    bool operator>=(const RightShiftRegister & r) const
+    {
+        if (iv_child == r.iv_child)
+            return iv_amount >= r.iv_amount;
+        return iv_child >= r.iv_child;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_child;
+    uint16_t iv_amount;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+
+class AndRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    AndRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_left(NULL), iv_right(NULL), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    AndRegister( SCAN_COMM_REGISTER_CLASS & i_left,
+                 SCAN_COMM_REGISTER_CLASS & i_right ) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_left(&i_left), iv_right(&i_right),
+        iv_iBS(std::min(i_left.GetBitLength(),
+                        i_right.GetBitLength()))
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    AndRegister & operator=(const AndRegister & r)
+    {
+        iv_left = r.iv_left;
+        iv_right = r.iv_right;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const
+    {
+        return iv_left->Read() | iv_right->Read();
+    }
+    virtual uint32_t Write()
+    {
+        return iv_left->Write() | iv_right->Write();
+    }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        (*iv_bs) = *iv_left->GetBitString(i_type);
+        (*iv_bs) = (*iv_bs) & (*iv_right->GetBitString(i_type));
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const
+    {
+        return Prdr::SignatureOp::combineSig(iv_left->GetId(),
+                                             iv_right->GetId());
+    }
+
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const AndRegister & r) const
+    { return (r.iv_left == iv_left) && (r.iv_right == iv_right); }
+
+    bool operator<(const AndRegister & r) const
+    {
+        if (iv_left == r.iv_left)
+            return iv_right < r.iv_right;
+        return iv_left < r.iv_left;
+    }
+
+    bool operator>=(const AndRegister & r) const
+    {
+        if (iv_left == r.iv_left)
+            return iv_right >= r.iv_right;
+        return iv_left >= r.iv_left;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_left;
+    SCAN_COMM_REGISTER_CLASS * iv_right;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class OrRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+
+    OrRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_left(NULL), iv_right(NULL), iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    OrRegister( SCAN_COMM_REGISTER_CLASS & i_left,
+                SCAN_COMM_REGISTER_CLASS & i_right ) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_left(&i_left), iv_right(&i_right),
+        iv_iBS(std::min(i_left.GetBitLength(),
+                        i_right.GetBitLength()))
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    OrRegister & operator=(const OrRegister & r)
+    {
+        iv_left = r.iv_left;
+        iv_right = r.iv_right;
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const
+    {
+        return iv_left->Read() | iv_right->Read();
+    }
+
+    virtual uint32_t Write()
+    {
+        return iv_left->Write() | iv_right->Write();
+    }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE ) const
+    {
+        (*iv_bs) = *iv_left->GetBitString(i_type);
+        (*iv_bs) = (*iv_bs) | (*iv_right->GetBitString(i_type));
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const
+    {
+        return Prdr::SignatureOp::combineSig( iv_left->GetId(),
+                                              iv_right->GetId() );
+    }
+
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const OrRegister & r) const
+    { return (r.iv_left == iv_left) && (r.iv_right == iv_right); }
+
+    bool operator<(const OrRegister & r) const
+    {
+        if (iv_left == r.iv_left)
+            return iv_right < r.iv_right;
+        return iv_left < r.iv_left;
+    }
+
+    bool operator>=(const OrRegister & r) const
+    {
+        if (iv_left == r.iv_left)
+            return iv_right >= r.iv_right;
+        return iv_left >= r.iv_left;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    SCAN_COMM_REGISTER_CLASS * iv_left;
+    SCAN_COMM_REGISTER_CLASS * iv_right;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class NullRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    NullRegister(int size) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_iBS(size)
+    {}
+
+    NullRegister & operator=(const NullRegister & r)
+    {
+        iv_iBS = r.iv_iBS;
+        return *this;
+    }
+
+    virtual uint32_t Read() const { return 0; }
+    virtual uint32_t Write()      { return 0; }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        return &iv_iBS;
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    BitStringBuffer iv_iBS;
+
+    virtual uint16_t GetId() const
+    { return Prdr::SignatureOp::DEFAULT_SIGNATURE; }
+
+    virtual void SetId(uint16_t i_id) {}
+
+};
+
+class AttnTypeRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    AttnTypeRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_check(&cv_null), iv_recov(&cv_null),
+        iv_special(&cv_null), iv_proccs(&cv_null), iv_hostattn(&cv_null),
+        iv_iBS(0)
+    {
+        iv_bs = &iv_iBS;
+    }
+
+    AttnTypeRegister( SCAN_COMM_REGISTER_CLASS *i_check,
+                      SCAN_COMM_REGISTER_CLASS *i_recov,
+                      SCAN_COMM_REGISTER_CLASS *i_special,
+                      SCAN_COMM_REGISTER_CLASS *i_proccs,
+                      SCAN_COMM_REGISTER_CLASS *i_hostattn ) :
+        SCAN_COMM_REGISTER_CLASS( ),
+        iv_check(    NULL == i_check    ? &cv_null : i_check),
+        iv_recov(    NULL == i_recov    ? &cv_null : i_recov),
+        iv_special(  NULL == i_special  ? &cv_null : i_special),
+        iv_proccs(   NULL == i_proccs   ? &cv_null : i_proccs),
+        iv_hostattn( NULL == i_hostattn ? &cv_null : i_hostattn),
+        iv_iBS(0)         // will fully initialize this inside ctor.
+    {
+        uint32_t l_length = 1024;
+        l_length = std::min(l_length, iv_check->GetBitLength());
+        l_length = std::min(l_length, iv_recov->GetBitLength());
+        l_length = std::min(l_length, iv_special->GetBitLength());
+        l_length = std::min(l_length, iv_proccs->GetBitLength());
+        l_length = std::min(l_length, iv_hostattn->GetBitLength());
+        iv_iBS = BitStringBuffer(l_length);
+        iv_bs = &iv_iBS;
+    }
+
+    AttnTypeRegister & operator=(const AttnTypeRegister & r)
+    {
+        //iv_null = r.iv_null; <-- don't do this!
+        iv_check    = (r.iv_check    == &r.cv_null ? &cv_null : r.iv_check);
+        iv_recov    = (r.iv_recov    == &r.cv_null ? &cv_null : r.iv_recov);
+        iv_special  = (r.iv_special  == &r.cv_null ? &cv_null : r.iv_special);
+        iv_proccs   = (r.iv_proccs   == &r.cv_null ? &cv_null : r.iv_proccs);
+        iv_hostattn = (r.iv_hostattn == &r.cv_null ? &cv_null : r.iv_hostattn);
+        iv_iBS = r.iv_iBS;
+        //iv_bs = r.iv_bs; <-- don't do this!
+        return *this;
+    }
+
+    virtual uint32_t Read() const
+    {
+        return iv_check->Read()   | iv_recov->Read() |
+               iv_special->Read() | iv_proccs->Read() |
+               iv_hostattn->Read();
+    }
+
+    virtual uint32_t Write()
+    {
+        return iv_check->Write()   | iv_recov->Write() |
+               iv_special->Write() | iv_proccs->Write() |
+               iv_hostattn->Write();
+    }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        switch (i_type)
+        {
+            case CHECK_STOP:
+                (*iv_bs) = BitStringBuffer(
+                                            *iv_check->GetBitString(i_type));
+                break;
+
+            case RECOVERABLE:
+                (*iv_bs) = BitStringBuffer(
+                                            *iv_recov->GetBitString(i_type));
+                break;
+
+            case SPECIAL:
+                (*iv_bs) = BitStringBuffer(
+                                            *iv_special->GetBitString(i_type));
+                break;
+
+            case PROC_CS:
+                (*iv_bs) = BitStringBuffer(
+                                            *iv_proccs->GetBitString(i_type));
+                break;
+
+            case HOST_ATTN:
+                (*iv_bs) = BitStringBuffer(
+                                            *iv_hostattn->GetBitString(i_type));
+                break;
+        }
+
+        return iv_bs;
+    }
+
+    virtual uint16_t GetId() const
+    {
+        uint16_t l_rc = Prdr::SignatureOp::DEFAULT_SIGNATURE;
+        l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_check->GetId());
+        l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_recov->GetId());
+        l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_special->GetId());
+        l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_proccs->GetId());
+        l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_hostattn->GetId());
+        return l_rc;
+    }
+
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const AttnTypeRegister & r) const
+    {
+        return (r.iv_check   == iv_check)   && (r.iv_recov  == iv_recov) &&
+               (r.iv_special == iv_special) && (r.iv_proccs == iv_proccs) &&
+               (r.iv_special == iv_hostattn);
+    }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    static NullRegister cv_null;
+
+    SCAN_COMM_REGISTER_CLASS * iv_check;
+    SCAN_COMM_REGISTER_CLASS * iv_recov;
+    SCAN_COMM_REGISTER_CLASS * iv_special;
+    SCAN_COMM_REGISTER_CLASS * iv_proccs;
+    SCAN_COMM_REGISTER_CLASS * iv_hostattn;
+
+    BitStringBuffer * iv_bs;
+    BitStringBuffer iv_iBS;
+};
+
+class ConstantRegister : public SCAN_COMM_REGISTER_CLASS
+{
+  public:
+    ConstantRegister() :
+        SCAN_COMM_REGISTER_CLASS( ), iv_iBS(0)
+    {}
+
+    ConstantRegister( const BitStringBuffer & i_arg ) :
+        SCAN_COMM_REGISTER_CLASS( ), iv_iBS(i_arg)
+    {}
+
+    ConstantRegister & operator=(const ConstantRegister & r)
+    {
+        iv_iBS = r.iv_iBS;
+        return *this;
+    }
+
+    virtual uint32_t Read() const { return SUCCESS; }
+    virtual uint32_t Write()      { return SUCCESS; }
+
+    const BitString * GetBitString(
+                    ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+    {
+        return &iv_iBS;
+    }
+
+    virtual uint16_t GetId() const
+    { return Prdr::SignatureOp::DEFAULT_SIGNATURE; }
+
+    virtual void SetId(uint16_t i_id) {}
+
+    bool operator==(const ConstantRegister & r) const
+    { return r.iv_iBS == iv_iBS; }
+
+  protected:
+    BitString & AccessBitString(void) { return iv_iBS; }
+    void SetBitString(const BitString *) {}
+
+  private:
+    BitStringBuffer iv_iBS;
+};
+
+} // end namespace libhei
+
