Refactoring of the TMMBRSet class, giving it a reasonably tight interface.

The CL also fixes a number of line length and tab issues in touched files.

BUG=
TEST=

Review URL: https://webrtc-codereview.appspot.com/553005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2168 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.cc b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
index 9caac86..2fc7c83 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -649,7 +649,7 @@
       if ((timeNow - receiveInfo->lastTimeReceived) >
           5 * RTCP_INTERVAL_AUDIO_MS) {
         // no rtcp packet for the last five regular intervals, reset limitations
-        receiveInfo->TmmbrSet.lengthOfSet = 0;
+        receiveInfo->TmmbrSet.clearSet();
         // prevent that we call this over and over again
         receiveInfo->lastTimeReceived = 0;
         // send new TMMBN to all channels using the default codec
@@ -687,23 +687,22 @@
                  __FUNCTION__);
     return -1;
   }
-  if (receiveInfo->TmmbnBoundingSet.lengthOfSet > 0) {
+  if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
     boundingSetRec->VerifyAndAllocateSet(
-        receiveInfo->TmmbnBoundingSet.lengthOfSet + 1);
-    for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet; i++) {
-      if(receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i] == _SSRC) {
+        receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
+    for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
+        i++) {
+      if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
         // owner of bounding set
         tmmbrOwner = true;
       }
-      boundingSetRec->ptrTmmbrSet[i] =
-          receiveInfo->TmmbnBoundingSet.ptrTmmbrSet[i];
-      boundingSetRec->ptrPacketOHSet[i] =
-          receiveInfo->TmmbnBoundingSet.ptrPacketOHSet[i];
-      boundingSetRec->ptrSsrcSet[i] =
-          receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i];
+      boundingSetRec->SetEntry(i,
+                               receiveInfo->TmmbnBoundingSet.Tmmbr(i),
+                               receiveInfo->TmmbnBoundingSet.PacketOH(i),
+                               receiveInfo->TmmbnBoundingSet.Ssrc(i));
     }
   }
-  return receiveInfo->TmmbnBoundingSet.lengthOfSet;
+  return receiveInfo->TmmbnBoundingSet.lengthOfSet();
 }
 
 // no need for critsect we have _criticalSectionRTCPReceiver
@@ -992,13 +991,10 @@
 RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
                               const RTCPUtility::RTCPPacket& rtcpPacket)
 {
-    const unsigned int idx = receiveInfo.TmmbnBoundingSet.lengthOfSet;
-
-    receiveInfo.TmmbnBoundingSet.ptrTmmbrSet[idx]    = rtcpPacket.TMMBNItem.MaxTotalMediaBitRate;
-    receiveInfo.TmmbnBoundingSet.ptrPacketOHSet[idx] = rtcpPacket.TMMBNItem.MeasuredOverhead;
-    receiveInfo.TmmbnBoundingSet.ptrSsrcSet[idx]     = rtcpPacket.TMMBNItem.SSRC;
-
-    ++receiveInfo.TmmbnBoundingSet.lengthOfSet;
+    receiveInfo.TmmbnBoundingSet.AddEntry(
+        rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
+        rtcpPacket.TMMBNItem.MeasuredOverhead,
+        rtcpPacket.TMMBNItem.SSRC);
 }
 
 // no need for critsect we have _criticalSectionRTCPReceiver
@@ -1376,7 +1372,7 @@
         return 0;
       }
       for (WebRtc_UWord32 i = 0;
-          (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet); i++) {
+           (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
         if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
                                      _clock.GetTimeInMS()) == 0) {
           num++;
@@ -1393,7 +1389,7 @@
                      __FUNCTION__);
         return -1;
       }
-      num += receiveInfo->TmmbrSet.lengthOfSet;
+      num += receiveInfo->TmmbrSet.lengthOfSet();
       receiveInfoIt++;
     }
   }
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc b/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
index 0058aca..1b74c68 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -147,40 +147,26 @@
     }
 }
 
-// don't use TmmbrSet.VerifyAndAllocate this version keeps the data
+// Increase size of TMMBRSet if needed, and also take care of
+// the _tmmbrSetTimeouts array.
 void
 RTCPReceiveInformation::VerifyAndAllocateTMMBRSet(const WebRtc_UWord32 minimumSize)
 {
-    if(minimumSize > TmmbrSet.sizeOfSet)
+    if(minimumSize > TmmbrSet.sizeOfSet())
     {
+        TmmbrSet.VerifyAndAllocateSetKeepingData(minimumSize);
         // make sure that our buffers are big enough
-        WebRtc_UWord32* ptrTmmbrSet = new WebRtc_UWord32[minimumSize];
-        WebRtc_UWord32* ptrTmmbrPacketOHSet = new WebRtc_UWord32[minimumSize];
-        WebRtc_UWord32* ptrTmmbrSsrcSet = new WebRtc_UWord32[minimumSize];
         WebRtc_UWord32* tmmbrSetTimeouts = new WebRtc_UWord32[minimumSize];
 
-        if(TmmbrSet.lengthOfSet > 0)
+        if(TmmbrSet.lengthOfSet() > 0)
         {
-            // copy old values
-            memcpy(ptrTmmbrSet, TmmbrSet.ptrTmmbrSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
-            memcpy(ptrTmmbrPacketOHSet, TmmbrSet.ptrPacketOHSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
-            memcpy(ptrTmmbrSsrcSet, TmmbrSet.ptrSsrcSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
-            memcpy(tmmbrSetTimeouts, _tmmbrSetTimeouts, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
-        }
-        if(TmmbrSet.ptrTmmbrSet)
-        {
-            delete [] TmmbrSet.ptrTmmbrSet;
-            delete [] TmmbrSet.ptrPacketOHSet;
-            delete [] TmmbrSet.ptrSsrcSet;
+            memcpy(tmmbrSetTimeouts, _tmmbrSetTimeouts,
+                   sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet());
         }
         if(_tmmbrSetTimeouts)
         {
             delete [] _tmmbrSetTimeouts;
         }
-        TmmbrSet.ptrTmmbrSet = ptrTmmbrSet;
-        TmmbrSet.ptrPacketOHSet = ptrTmmbrPacketOHSet;
-        TmmbrSet.ptrSsrcSet = ptrTmmbrSsrcSet;
-        TmmbrSet.sizeOfSet = minimumSize;
         _tmmbrSetTimeouts = tmmbrSetTimeouts;
     }
 }
@@ -191,26 +177,26 @@
                                         const WebRtc_UWord32 currentTimeMS)
 {
     // serach to see if we have it in our list
-    for(WebRtc_UWord32 i = 0; i < TmmbrSet.lengthOfSet; i++)
+    for(WebRtc_UWord32 i = 0; i < TmmbrSet.lengthOfSet(); i++)
     {
-        if(TmmbrSet.ptrSsrcSet[i] == senderSSRC)
+        if(TmmbrSet.Ssrc(i) == senderSSRC)
         {
             // we already have this SSRC in our list
             // update it
-            TmmbrSet.ptrPacketOHSet[i] = TMMBRItem.MeasuredOverhead;
-            TmmbrSet.ptrTmmbrSet[i] = TMMBRItem.MaxTotalMediaBitRate;
+            TmmbrSet.SetEntry(i,
+                              TMMBRItem.MaxTotalMediaBitRate,
+                              TMMBRItem.MeasuredOverhead,
+                              senderSSRC);
             _tmmbrSetTimeouts[i] = currentTimeMS;
             return;
         }
     }
-    VerifyAndAllocateTMMBRSet(TmmbrSet.lengthOfSet+1);
-
-    const WebRtc_UWord32 idx = TmmbrSet.lengthOfSet;
-    TmmbrSet.ptrPacketOHSet[idx] = TMMBRItem.MeasuredOverhead;
-    TmmbrSet.ptrTmmbrSet[idx] = TMMBRItem.MaxTotalMediaBitRate;
-    TmmbrSet.ptrSsrcSet[idx] = senderSSRC;
+    const WebRtc_UWord32 idx = TmmbrSet.lengthOfSet();
+    VerifyAndAllocateTMMBRSet(idx+1);
+    TmmbrSet.AddEntry(TMMBRItem.MaxTotalMediaBitRate,
+                      TMMBRItem.MeasuredOverhead,
+                      senderSSRC);
     _tmmbrSetTimeouts[idx] = currentTimeMS;
-    TmmbrSet.lengthOfSet++;
 }
 
 WebRtc_Word32
@@ -219,11 +205,11 @@
                                     TMMBRSet* candidateSet,
                                     const WebRtc_UWord32 currentTimeMS)
 {
-    if(sourceIdx >= TmmbrSet.lengthOfSet)
+    if(sourceIdx >= TmmbrSet.lengthOfSet())
     {
         return -1;
     }
-    if(targetIdx >= candidateSet->sizeOfSet)
+    if(targetIdx >= candidateSet->sizeOfSet())
     {
         return -1;
     }
@@ -233,21 +219,17 @@
     if(timeNow - _tmmbrSetTimeouts[sourceIdx] > 5*RTCP_INTERVAL_AUDIO_MS)
     {
         // value timed out
-        const WebRtc_UWord32 move = TmmbrSet.lengthOfSet - (sourceIdx + 1);
-        if(move > 0)
-        {
-            memmove(&(TmmbrSet.ptrTmmbrSet[sourceIdx]), &(TmmbrSet.ptrTmmbrSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
-            memmove(&(TmmbrSet.ptrPacketOHSet[sourceIdx]),&(TmmbrSet.ptrPacketOHSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
-            memmove(&(TmmbrSet.ptrSsrcSet[sourceIdx]),&(TmmbrSet.ptrSsrcSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
+        TmmbrSet.RemoveEntry(sourceIdx);
+        const WebRtc_UWord32 move = TmmbrSet.lengthOfSet() - (sourceIdx + 1);
+        if (move > 0) {
             memmove(&(_tmmbrSetTimeouts[sourceIdx]),&(_tmmbrSetTimeouts[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
         }
-        TmmbrSet.lengthOfSet--;
         return -1;
     }
-
-    candidateSet->ptrTmmbrSet[targetIdx] = TmmbrSet.ptrTmmbrSet[sourceIdx];
-    candidateSet->ptrPacketOHSet[targetIdx] = TmmbrSet.ptrPacketOHSet[sourceIdx];
-    candidateSet->ptrSsrcSet[targetIdx] = TmmbrSet.ptrSsrcSet[sourceIdx];
+    candidateSet->SetEntry(targetIdx,
+                           TmmbrSet.Tmmbr(sourceIdx),
+                           TmmbrSet.PacketOH(sourceIdx),
+                           TmmbrSet.Ssrc(sourceIdx));
     return 0;
 }
 
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc b/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
index ff9ed1a..5bfdb73 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
@@ -258,8 +258,8 @@
   TMMBRSet candidate_set;
   candidate_set.VerifyAndAllocateSet(1);
   EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(1, 0, &candidate_set));
-  EXPECT_LT(0U, candidate_set.ptrTmmbrSet[0]);
-  EXPECT_EQ(kMediaRecipientSsrc, candidate_set.ptrSsrcSet[0]);
+  EXPECT_LT(0U, candidate_set.Tmmbr(0));
+  EXPECT_EQ(kMediaRecipientSsrc, candidate_set.Ssrc(0));
 }
 
 TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
@@ -328,7 +328,7 @@
   TMMBRSet candidate_set;
   candidate_set.VerifyAndAllocateSet(3);
   EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
-  EXPECT_LT(0U, candidate_set.ptrTmmbrSet[0]);
+  EXPECT_LT(0U, candidate_set.Tmmbr(0));
   // We expect the timeout to be 25 seconds. Advance the clock by 12
   // seconds, timing out the first packet.
   system_clock_->AdvanceClock(12000);
@@ -336,7 +336,7 @@
   EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
   // Odd behaviour: There's only one left after timeout, not 2.
   EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
-  EXPECT_EQ(kMediaRecipientSsrc + 2, candidate_set.ptrSsrcSet[0]);
+  EXPECT_EQ(kMediaRecipientSsrc + 2, candidate_set.Ssrc(0));
 }
 
 
diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.cc b/src/modules/rtp_rtcp/source/rtcp_sender.cc
index 2fe0380..6383f8f 100644
--- a/src/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -1134,18 +1134,21 @@
 
     // get current bounding set from RTCP receiver
     bool tmmbrOwner = false;
-    TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); // store in candidateSet, allocates one extra slot
+    // store in candidateSet, allocates one extra slot
+    TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet();
 
-    // holding _criticalSectionRTCPSender while calling RTCPreceiver which will accuire _criticalSectionRTCPReceiver
-    // is a potental deadlock but since RTCPreceiver is not doing the revese we should be fine
-    WebRtc_Word32 lengthOfBoundingSet = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet);
+    // holding _criticalSectionRTCPSender while calling RTCPreceiver which
+    // will accuire _criticalSectionRTCPReceiver is a potental deadlock but
+    // since RTCPreceiver is not doing the reverse we should be fine
+    WebRtc_Word32 lengthOfBoundingSet
+        = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet);
 
     if(lengthOfBoundingSet > 0)
     {
         for (WebRtc_Word32 i = 0; i < lengthOfBoundingSet; i++)
         {
-            if( candidateSet->ptrTmmbrSet[i] == _tmmbr_Send &&
-                candidateSet->ptrPacketOHSet[i] == _packetOH_Send)
+            if( candidateSet->Tmmbr(i) == _tmmbr_Send &&
+                candidateSet->PacketOH(i) == _packetOH_Send)
             {
                 // do not send the same tuple
                 return 0;
@@ -1155,9 +1158,10 @@
         {
             // use received bounding set as candidate set
             // add current tuple
-            candidateSet->ptrTmmbrSet[lengthOfBoundingSet]    = _tmmbr_Send;
-            candidateSet->ptrPacketOHSet[lengthOfBoundingSet] = _packetOH_Send;
-            candidateSet->ptrSsrcSet[lengthOfBoundingSet] = _SSRC;
+            candidateSet->SetEntry(lengthOfBoundingSet,
+                                   _tmmbr_Send,
+                                   _packetOH_Send,
+                                   _SSRC);
             int numCandidates = lengthOfBoundingSet+ 1;
 
             // find bounding set
@@ -1236,7 +1240,7 @@
         return -1;
     }
     // sanity
-    if(pos + 12 + boundingSet->lengthOfSet*8 >= IP_PACKET_SIZE)
+    if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE)
     {
         WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
         return -2;
@@ -1265,15 +1269,15 @@
 
     // Additional Feedback Control Information (FCI)
     int numBoundingSet = 0;
-    for(WebRtc_UWord32 n=0; n< boundingSet->lengthOfSet; n++)
+    for(WebRtc_UWord32 n=0; n< boundingSet->lengthOfSet(); n++)
     {
-        if (boundingSet->ptrTmmbrSet[n] > 0)
+        if (boundingSet->Tmmbr(n) > 0)
         {
-            WebRtc_UWord32 tmmbrSSRC = boundingSet->ptrSsrcSet[n];
+            WebRtc_UWord32 tmmbrSSRC = boundingSet->Ssrc(n);
             ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, tmmbrSSRC);
             pos += 4;
 
-            WebRtc_UWord32 bitRate = boundingSet->ptrTmmbrSet[n] * 1000;
+            WebRtc_UWord32 bitRate = boundingSet->Tmmbr(n) * 1000;
             WebRtc_UWord32 mmbrExp = 0;
             for(int i=0; i<64; i++)
             {
@@ -1284,7 +1288,7 @@
                 }
             }
             WebRtc_UWord32 mmbrMantissa = (bitRate >> mmbrExp);
-            WebRtc_UWord32 measuredOH = boundingSet->ptrPacketOHSet[n];
+            WebRtc_UWord32 measuredOH = boundingSet->PacketOH(n);
 
             rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
             rtcpbuffer[pos++]=(WebRtc_UWord8)(mmbrMantissa >> 7);
diff --git a/src/modules/rtp_rtcp/source/rtcp_sender_test.cc b/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
index 59fb71b..2d86682 100644
--- a/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
@@ -204,13 +204,8 @@
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
   TMMBRSet bounding_set;
   bounding_set.VerifyAndAllocateSet(1);
-  const WebRtc_UWord32 idx = bounding_set.lengthOfSet;
-  // TODO(hta): Make an accessor on TMMBRSet to do this insertion.
   const WebRtc_UWord32 kSourceSsrc = 12345;
-  bounding_set.ptrPacketOHSet[idx] = 0;
-  bounding_set.ptrTmmbrSet[idx] = 32768;  // bits per second
-  bounding_set.ptrSsrcSet[idx] = kSourceSsrc;
-  bounding_set.lengthOfSet++;
+  bounding_set.AddEntry(32768, 0, kSourceSsrc);
 
   EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
   ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
@@ -224,6 +219,6 @@
   // We expect 1 member of the incoming set.
   EXPECT_EQ(1, test_transport_->rtcp_receiver_->BoundingSet(owner,
       &incoming_set));
-  EXPECT_EQ(kSourceSsrc, incoming_set.ptrSsrcSet[0]);
+  EXPECT_EQ(kSourceSsrc, incoming_set.Ssrc(0));
 }
 }  // namespace webrtc
diff --git a/src/modules/rtp_rtcp/source/tmmbr_help.cc b/src/modules/rtp_rtcp/source/tmmbr_help.cc
index 6fba710..50f0e08 100644
--- a/src/modules/rtp_rtcp/source/tmmbr_help.cc
+++ b/src/modules/rtp_rtcp/source/tmmbr_help.cc
@@ -10,56 +10,91 @@
 
 #include "tmmbr_help.h"
 
+#include <assert.h>
 #include <limits>
+#include <string.h>
 #include "rtp_rtcp_config.h"
 
 namespace webrtc {
 TMMBRSet::TMMBRSet() :
-    ptrTmmbrSet(0),
-    ptrPacketOHSet(0),
-    ptrSsrcSet(0),
-    sizeOfSet(0),
-    lengthOfSet(0)
+    _sizeOfSet(0),
+    _lengthOfSet(0)
 {
 }
 
 TMMBRSet::~TMMBRSet()
 {
-    delete [] ptrTmmbrSet;
-    delete [] ptrPacketOHSet;
-    delete [] ptrSsrcSet;
-    ptrTmmbrSet = 0;
-    ptrPacketOHSet = 0;
-    ptrSsrcSet = 0;
-    sizeOfSet = 0;
-    lengthOfSet = 0;
+    _sizeOfSet = 0;
+    _lengthOfSet = 0;
 }
 
 void
 TMMBRSet::VerifyAndAllocateSet(WebRtc_UWord32 minimumSize)
 {
-    if(minimumSize > sizeOfSet)
+    if(minimumSize > _sizeOfSet)
     {
         // make sure that our buffers are big enough
-        if(ptrTmmbrSet)
-        {
-            delete [] ptrTmmbrSet;
-            delete [] ptrPacketOHSet;
-            delete [] ptrSsrcSet;
-        }
-        ptrTmmbrSet = new WebRtc_UWord32[minimumSize];
-        ptrPacketOHSet = new WebRtc_UWord32[minimumSize];
-        ptrSsrcSet = new WebRtc_UWord32[minimumSize];
-        sizeOfSet = minimumSize;
+        _data.resize(minimumSize);
+        _sizeOfSet = minimumSize;
     }
     // reset memory
-    for(WebRtc_UWord32 i = 0; i < sizeOfSet; i++)
+    for(WebRtc_UWord32 i = 0; i < _sizeOfSet; i++)
     {
-        ptrTmmbrSet[i] = 0;
-        ptrPacketOHSet[i] = 0;
-        ptrSsrcSet[i] = 0;
+        _data.at(i).tmmbr = 0;
+        _data.at(i).packet_oh = 0;
+        _data.at(i).ssrc = 0;
     }
-    lengthOfSet = 0;
+    _lengthOfSet = 0;
+}
+
+void
+TMMBRSet::VerifyAndAllocateSetKeepingData(WebRtc_UWord32 minimumSize)
+{
+    if(minimumSize > _sizeOfSet)
+    {
+        {
+          _data.resize(minimumSize);
+        }
+        _sizeOfSet = minimumSize;
+    }
+}
+
+void TMMBRSet::SetEntry(unsigned int i,
+                         WebRtc_UWord32 tmmbrSet,
+                         WebRtc_UWord32 packetOHSet,
+                         WebRtc_UWord32 ssrcSet) {
+  assert(i < _sizeOfSet);
+  _data.at(i).tmmbr = tmmbrSet;
+  _data.at(i).packet_oh = packetOHSet;
+  _data.at(i).ssrc = ssrcSet;
+  if (i >= _lengthOfSet) {
+    _lengthOfSet = i + 1;
+  }
+}
+
+void TMMBRSet::AddEntry(WebRtc_UWord32 tmmbrSet,
+                        WebRtc_UWord32 packetOHSet,
+                        WebRtc_UWord32 ssrcSet) {
+  assert(_lengthOfSet < _sizeOfSet);
+  SetEntry(_lengthOfSet, tmmbrSet, packetOHSet, ssrcSet);
+}
+
+void TMMBRSet::RemoveEntry(WebRtc_UWord32 sourceIdx) {
+  assert(sourceIdx < _lengthOfSet);
+  _data.erase(_data.begin() + sourceIdx);
+  _lengthOfSet--;
+  _data.resize(_sizeOfSet);  // Ensure that size remains the same.
+}
+
+void TMMBRSet::SwapEntries(WebRtc_UWord32 i, WebRtc_UWord32 j) {
+    SetElement temp;
+    temp = _data[i];
+    _data[i] = _data[j];
+    _data[j] = temp;
+}
+
+void TMMBRSet::ClearEntry(WebRtc_UWord32 idx) {
+  SetEntry(idx, 0, 0, 0);
 }
 
 TMMBRHelp::TMMBRHelp()
@@ -84,7 +119,7 @@
 {
     CriticalSectionScoped lock(_criticalSection);
 
-    if(minimumSize > _boundingSet.sizeOfSet)
+    if(minimumSize > _boundingSet.sizeOfSet())
     {
         // make sure that our buffers are big enough
         if(_ptrIntersectionBoundingSet)
@@ -111,16 +146,16 @@
 
     if (boundingSetToSend == NULL)
     {
-        _boundingSetToSend.lengthOfSet = 0;
+        _boundingSetToSend.clearSet();
         return 0;
     }
 
-    VerifyAndAllocateBoundingSetToSend(boundingSetToSend->lengthOfSet);
-
-    for (WebRtc_UWord32 i = 0; i < boundingSetToSend->lengthOfSet; i++)
+    VerifyAndAllocateBoundingSetToSend(boundingSetToSend->lengthOfSet());
+    _boundingSetToSend.clearSet();
+    for (WebRtc_UWord32 i = 0; i < boundingSetToSend->lengthOfSet(); i++)
     {
         // cap at our configured max bitrate
-        WebRtc_UWord32 bitrate = boundingSetToSend->ptrTmmbrSet[i];
+        WebRtc_UWord32 bitrate = boundingSetToSend->Tmmbr(i);
         if(maxBitrateKbit)
         {
             // do we have a configured max bitrate?
@@ -129,12 +164,10 @@
                 bitrate = maxBitrateKbit;
             }
         }
-
-        _boundingSetToSend.ptrTmmbrSet[i]    = bitrate;
-        _boundingSetToSend.ptrPacketOHSet[i] = boundingSetToSend->ptrPacketOHSet[i];
-        _boundingSetToSend.ptrSsrcSet[i]     = boundingSetToSend->ptrSsrcSet[i];
+        _boundingSetToSend.SetEntry(i, bitrate,
+                                    boundingSetToSend->PacketOH(i),
+                                    boundingSetToSend->Ssrc(i));
     }
-    _boundingSetToSend.lengthOfSet = boundingSetToSend->lengthOfSet;
     return 0;
 }
 
@@ -175,33 +208,34 @@
 
     // Work on local variable, will be modified
     TMMBRSet    candidateSet;
-    candidateSet.VerifyAndAllocateSet(_candidateSet.sizeOfSet);
+    candidateSet.VerifyAndAllocateSet(_candidateSet.sizeOfSet());
 
-    // Number of set candidates
-    WebRtc_Word32 numSetCandidates = 0;
-    for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; i++)
+    // TODO(hta) Figure out if this should be lengthOfSet instead.
+    for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet(); i++)
     {
-        if(_candidateSet.ptrTmmbrSet[i])
+        if(_candidateSet.Tmmbr(i))
         {
-            numSetCandidates++;
-            candidateSet.ptrTmmbrSet[i]    = _candidateSet.ptrTmmbrSet[i];
-            candidateSet.ptrPacketOHSet[i] = _candidateSet.ptrPacketOHSet[i];
-            candidateSet.ptrSsrcSet[i]     = _candidateSet.ptrSsrcSet[i];
+            candidateSet.AddEntry(_candidateSet.Tmmbr(i),
+                                  _candidateSet.PacketOH(i),
+                                  _candidateSet.Ssrc(i));
         }
         else
         {
             // make sure this is zero if tmmbr = 0
-            _candidateSet.ptrPacketOHSet[i] = 0;
+            assert(_candidateSet.PacketOH(i) == 0);
+            // Old code:
+            // _candidateSet.ptrPacketOHSet[i] = 0;
         }
     }
-    candidateSet.lengthOfSet = numSetCandidates;
 
+    // Number of set candidates
+    WebRtc_Word32 numSetCandidates = candidateSet.lengthOfSet();
     // Find bounding set
     WebRtc_UWord32 numBoundingSet = 0;
     if (numSetCandidates > 0)
     {
         numBoundingSet =  FindTMMBRBoundingSet(numSetCandidates, candidateSet);
-        if(numBoundingSet < 1 || (numBoundingSet > _candidateSet.sizeOfSet))
+        if(numBoundingSet < 1 || (numBoundingSet > _candidateSet.sizeOfSet()))
         {
             return -1;
         }
@@ -217,17 +251,18 @@
     CriticalSectionScoped lock(_criticalSection);
 
     WebRtc_UWord32 numBoundingSet = 0;
-    VerifyAndAllocateBoundingSet(candidateSet.sizeOfSet);
+    VerifyAndAllocateBoundingSet(candidateSet.sizeOfSet());
 
     if (numCandidates == 1)
     {
-        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+        // TODO(hta): lengthOfSet instead of sizeOfSet?
+        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
         {
-            if(candidateSet.ptrTmmbrSet[i] > 0)
+            if (candidateSet.Tmmbr(i) > 0)
             {
-                _boundingSet.ptrTmmbrSet[numBoundingSet]    = candidateSet.ptrTmmbrSet[i];
-                _boundingSet.ptrPacketOHSet[numBoundingSet] = candidateSet.ptrPacketOHSet[i];
-                _boundingSet.ptrSsrcSet[numBoundingSet]     = candidateSet.ptrSsrcSet[i];
+                _boundingSet.AddEntry(candidateSet.Tmmbr(i),
+                                    candidateSet.PacketOH(i),
+                                    candidateSet.Ssrc(i));
                 numBoundingSet++;
             }
         }
@@ -238,110 +273,103 @@
     } else
     {
         // 1. Sort by increasing packetOH
-        WebRtc_UWord32 temp;
-        for (int i = candidateSet.sizeOfSet - 1; i >= 0; i--)
+        for (int i = candidateSet.sizeOfSet() - 1; i >= 0; i--)
         {
             for (int j = 1; j <= i; j++)
             {
-                if (candidateSet.ptrPacketOHSet[j-1] > candidateSet.ptrPacketOHSet[j])
+                if (candidateSet.PacketOH(j-1) > candidateSet.PacketOH(j))
                 {
-                    temp = candidateSet.ptrPacketOHSet[j-1];
-                    candidateSet.ptrPacketOHSet[j-1] = candidateSet.ptrPacketOHSet[j];
-                    candidateSet.ptrPacketOHSet[j] = temp;
-                    temp = candidateSet.ptrTmmbrSet[j-1];
-                    candidateSet.ptrTmmbrSet[j-1] = candidateSet.ptrTmmbrSet[j];
-                    candidateSet.ptrTmmbrSet[j] = temp;
-                    temp = candidateSet.ptrSsrcSet[j-1];
-                    candidateSet.ptrSsrcSet[j-1] = candidateSet.ptrSsrcSet[j];
-                    candidateSet.ptrSsrcSet[j] = temp;
+                    candidateSet.SwapEntries(j-1, j);
                 }
             }
         }
         // 2. For tuples with same OH, keep the one w/ the lowest bitrate
-        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
         {
-            if (candidateSet.ptrTmmbrSet[i] > 0)
+            if (candidateSet.Tmmbr(i) > 0)
             {
                 // get min bitrate for packets w/ same OH
-                WebRtc_UWord32 currentPacketOH = candidateSet.ptrPacketOHSet[i];
-                WebRtc_UWord32 currentMinTMMBR = candidateSet.ptrTmmbrSet[i];
+                WebRtc_UWord32 currentPacketOH = candidateSet.PacketOH(i);
+                WebRtc_UWord32 currentMinTMMBR = candidateSet.Tmmbr(i);
                 WebRtc_UWord32 currentMinIndexTMMBR = i;
-                for (WebRtc_UWord32 j = i+1; j < candidateSet.sizeOfSet; j++)
+                for (WebRtc_UWord32 j = i+1; j < candidateSet.sizeOfSet(); j++)
                 {
-                    if(candidateSet.ptrPacketOHSet[j] == currentPacketOH)
+                    if(candidateSet.PacketOH(j) == currentPacketOH)
                     {
-                        if(candidateSet.ptrTmmbrSet[j] < currentMinTMMBR)
+                        if(candidateSet.Tmmbr(j) < currentMinTMMBR)
                         {
-                            currentMinTMMBR = candidateSet.ptrTmmbrSet[j];
+                            currentMinTMMBR = candidateSet.Tmmbr(j);
                             currentMinIndexTMMBR = j;
                         }
                     }
                 }
                 // keep lowest bitrate
-                for (WebRtc_UWord32 j = 0; j < candidateSet.sizeOfSet; j++)
+                for (WebRtc_UWord32 j = 0; j < candidateSet.sizeOfSet(); j++)
                 {
-                    if(candidateSet.ptrPacketOHSet[j] == currentPacketOH && j != currentMinIndexTMMBR)
+                  if(candidateSet.PacketOH(j) == currentPacketOH
+                     && j != currentMinIndexTMMBR)
                     {
-                        candidateSet.ptrTmmbrSet[j]    = 0;
-                        candidateSet.ptrPacketOHSet[j] = 0;
-                        candidateSet.ptrSsrcSet[j]     = 0;
-                        numCandidates--;
+                        candidateSet.ClearEntry(j);
                     }
                 }
             }
         }
-        // 3. Select and remove tuple w/ lowest tmmbr. (If more than 1, choose the one w/ highest OH).
+        // 3. Select and remove tuple w/ lowest tmmbr.
+        // (If more than 1, choose the one w/ highest OH).
         WebRtc_UWord32 minTMMBR = 0;
         WebRtc_UWord32 minIndexTMMBR = 0;
-        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
         {
-            if (candidateSet.ptrTmmbrSet[i] > 0)
+            if (candidateSet.Tmmbr(i) > 0)
             {
-                minTMMBR = candidateSet.ptrTmmbrSet[i];
+                minTMMBR = candidateSet.Tmmbr(i);
                 minIndexTMMBR = i;
                 break;
             }
         }
 
-        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
         {
-            if (candidateSet.ptrTmmbrSet[i] > 0 && candidateSet.ptrTmmbrSet[i] <= minTMMBR)
+            if (candidateSet.Tmmbr(i) > 0 && candidateSet.Tmmbr(i) <= minTMMBR)
             {
                 // get min bitrate
-                minTMMBR = candidateSet.ptrTmmbrSet[i];
+                minTMMBR = candidateSet.Tmmbr(i);
                 minIndexTMMBR = i;
             }
         }
         // first member of selected list
-        _boundingSet.ptrTmmbrSet[numBoundingSet]    = candidateSet.ptrTmmbrSet[minIndexTMMBR];
-        _boundingSet.ptrPacketOHSet[numBoundingSet] = candidateSet.ptrPacketOHSet[minIndexTMMBR];
-        _boundingSet.ptrSsrcSet[numBoundingSet]     = candidateSet.ptrSsrcSet[minIndexTMMBR];
+        _boundingSet.SetEntry(numBoundingSet,
+                              candidateSet.Tmmbr(minIndexTMMBR),
+                              candidateSet.PacketOH(minIndexTMMBR),
+                              candidateSet.Ssrc(minIndexTMMBR));
+
         // set intersection value
         _ptrIntersectionBoundingSet[numBoundingSet] = 0;
         // calculate its maximum packet rate (where its line crosses x-axis)
-        _ptrMaxPRBoundingSet[numBoundingSet] = _boundingSet.ptrTmmbrSet[numBoundingSet]*1000 / float(8*_boundingSet.ptrPacketOHSet[numBoundingSet]);
+        _ptrMaxPRBoundingSet[numBoundingSet]
+            = _boundingSet.Tmmbr(numBoundingSet) * 1000
+            / float(8 * _boundingSet.PacketOH(numBoundingSet));
         numBoundingSet++;
         // remove from candidate list
-        candidateSet.ptrTmmbrSet[minIndexTMMBR]    = 0;
-        candidateSet.ptrPacketOHSet[minIndexTMMBR] = 0;
-        candidateSet.ptrSsrcSet[minIndexTMMBR]     = 0;
+        candidateSet.ClearEntry(minIndexTMMBR);
         numCandidates--;
 
-        // 4. Discard from candidate list all tuple w/ lower OH (next tuple must be steeper)
-        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+        // 4. Discard from candidate list all tuple w/ lower OH
+        // (next tuple must be steeper)
+        for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
         {
-            if(candidateSet.ptrTmmbrSet[i] > 0 && candidateSet.ptrPacketOHSet[i] < _boundingSet.ptrPacketOHSet[0])
+            if(candidateSet.Tmmbr(i) > 0
+               && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0))
             {
-                candidateSet.ptrTmmbrSet[i]    = 0;
-                candidateSet.ptrPacketOHSet[i] = 0;
-                candidateSet.ptrSsrcSet[i]     = 0;
+                candidateSet.ClearEntry(i);
                 numCandidates--;
             }
         }
 
         if (numCandidates == 0)
         {
-            _boundingSet.lengthOfSet = numBoundingSet;
+            // Should be true already:_boundingSet.lengthOfSet = numBoundingSet;
+            assert(_boundingSet.lengthOfSet() == numBoundingSet);
             return numBoundingSet;
         }
 
@@ -355,47 +383,54 @@
             if (getNewCandidate)
             {
                 // 5. Remove first remaining tuple from candidate list
-                for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+                for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
                 {
-                    if (candidateSet.ptrTmmbrSet[i] > 0)
+                    if (candidateSet.Tmmbr(i) > 0)
                     {
-                        curCandidateTMMBR    = candidateSet.ptrTmmbrSet[i];
-                        curCandidatePacketOH = candidateSet.ptrPacketOHSet[i];
-                        curCandidateSSRC     = candidateSet.ptrSsrcSet[i];
+                        curCandidateTMMBR    = candidateSet.Tmmbr(i);
+                        curCandidatePacketOH = candidateSet.PacketOH(i);
+                        curCandidateSSRC     = candidateSet.Ssrc(i);
                         curCandidateIndex    = i;
-                        candidateSet.ptrTmmbrSet[curCandidateIndex]    = 0;
-                        candidateSet.ptrPacketOHSet[curCandidateIndex] = 0;
-                        candidateSet.ptrSsrcSet[curCandidateIndex]     = 0;
+                        candidateSet.ClearEntry(curCandidateIndex);
                         break;
                     }
                 }
             }
 
-            // 6. Calculate packet rate and intersection of the current line with line of last tuple in selected list
-            float packetRate = float(curCandidateTMMBR - _boundingSet.ptrTmmbrSet[numBoundingSet-1])*1000 / (8*(curCandidatePacketOH - _boundingSet.ptrPacketOHSet[numBoundingSet-1]));
+            // 6. Calculate packet rate and intersection of the current
+            // line with line of last tuple in selected list
+            float packetRate
+                = float(curCandidateTMMBR
+                        - _boundingSet.Tmmbr(numBoundingSet-1))*1000
+                / (8*(curCandidatePacketOH
+                      - _boundingSet.PacketOH(numBoundingSet-1)));
 
-            // 7. If the packet rate is equal or lower than intersection of last tuple in selected list,
+            // 7. If the packet rate is equal or lower than intersection of
+            //    last tuple in selected list,
             //    remove last tuple in selected list & go back to step 6
             if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1])
             {
                 // remove last tuple and goto step 6
                 numBoundingSet--;
-                _boundingSet.ptrTmmbrSet[numBoundingSet]    = 0;
-                _boundingSet.ptrPacketOHSet[numBoundingSet] = 0;
-                _boundingSet.ptrSsrcSet[numBoundingSet]     = 0;
+                _boundingSet.ClearEntry(numBoundingSet);
                 _ptrIntersectionBoundingSet[numBoundingSet] = 0;
                 _ptrMaxPRBoundingSet[numBoundingSet]        = 0;
                 getNewCandidate = false;
             } else
             {
-                // 8. If packet rate is lower than maximum packet rate of last tuple in selected list, add current tuple to selected list
+                // 8. If packet rate is lower than maximum packet rate of
+                // last tuple in selected list, add current tuple to selected
+                // list
                 if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1])
                 {
-                    _boundingSet.ptrTmmbrSet[numBoundingSet]    = curCandidateTMMBR;
-                    _boundingSet.ptrPacketOHSet[numBoundingSet] = curCandidatePacketOH;
-                    _boundingSet.ptrSsrcSet[numBoundingSet]     = curCandidateSSRC;
+                    _boundingSet.SetEntry(numBoundingSet,
+                                          curCandidateTMMBR,
+                                          curCandidatePacketOH,
+                                          curCandidateSSRC);
                     _ptrIntersectionBoundingSet[numBoundingSet] = packetRate;
-                    _ptrMaxPRBoundingSet[numBoundingSet] = _boundingSet.ptrTmmbrSet[numBoundingSet]*1000 / float(8*_boundingSet.ptrPacketOHSet[numBoundingSet]);
+                    _ptrMaxPRBoundingSet[numBoundingSet]
+                        = _boundingSet.Tmmbr(numBoundingSet)*1000
+                        / float(8*_boundingSet.PacketOH(numBoundingSet));
                     numBoundingSet++;
                 }
                 numCandidates--;
@@ -405,7 +440,6 @@
             // 9. Go back to step 5 if any tuple remains in candidate list
         } while (numCandidates > 0);
     }
-    _boundingSet.lengthOfSet = numBoundingSet;
     return numBoundingSet;
 }
 
@@ -417,8 +451,9 @@
     // Empty bounding set.
     return false;
   }
-  for(WebRtc_UWord32 i = 0; (i < length) && (i < _boundingSet.sizeOfSet); ++i) {
-    if(_boundingSet.ptrSsrcSet[i] == ssrc) {
+  for(WebRtc_UWord32 i = 0;
+      (i < length) && (i < _boundingSet.sizeOfSet()); ++i) {
+    if(_boundingSet.Ssrc(i) == ssrc) {
       return true;
     }
   }
@@ -428,14 +463,14 @@
 bool TMMBRHelp::CalcMinBitRate( WebRtc_UWord32* minBitrateKbit) const {
   CriticalSectionScoped lock(_criticalSection);
 
-  if (_candidateSet.sizeOfSet == 0) {
+  if (_candidateSet.sizeOfSet() == 0) {
     // Empty bounding set.
     return false;
   }
   *minBitrateKbit = std::numeric_limits<uint32_t>::max();
 
-  for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; ++i) {
-    WebRtc_UWord32 curNetBitRateKbit = _candidateSet.ptrTmmbrSet[i];
+  for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet(); ++i) {
+    WebRtc_UWord32 curNetBitRateKbit = _candidateSet.Tmmbr(i);
     if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) {
       curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
     }
diff --git a/src/modules/rtp_rtcp/source/tmmbr_help.h b/src/modules/rtp_rtcp/source/tmmbr_help.h
index 6b3cd97..45ce1c4 100644
--- a/src/modules/rtp_rtcp/source/tmmbr_help.h
+++ b/src/modules/rtp_rtcp/source/tmmbr_help.h
@@ -11,6 +11,7 @@
 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
 
+#include <vector>
 #include "typedefs.h"
 
 #include "critical_section_wrapper.h"
@@ -27,12 +28,55 @@
     ~TMMBRSet();
 
     void VerifyAndAllocateSet(WebRtc_UWord32 minimumSize);
+    void VerifyAndAllocateSetKeepingData(WebRtc_UWord32 minimumSize);
+    // Number of valid data items in set.
+    WebRtc_UWord32 lengthOfSet() const { return _lengthOfSet; }
+    // Presently allocated max size of set.
+    WebRtc_UWord32 sizeOfSet() const { return _sizeOfSet; }
+    void clearSet() {
+      _lengthOfSet = 0;
+    }
+    WebRtc_UWord32 Tmmbr(int i) const {
+      return _data.at(i).tmmbr;
+    }
+    WebRtc_UWord32 PacketOH(int i) const {
+      return _data.at(i).packet_oh;
+    }
+    WebRtc_UWord32 Ssrc(int i) const {
+      return _data.at(i).ssrc;
+    }
+    void SetEntry(unsigned int i,
+                  WebRtc_UWord32 tmmbrSet,
+                  WebRtc_UWord32 packetOHSet,
+                  WebRtc_UWord32 ssrcSet);
 
-    WebRtc_UWord32*   ptrTmmbrSet;
-    WebRtc_UWord32*   ptrPacketOHSet;
-    WebRtc_UWord32*   ptrSsrcSet;
-    WebRtc_UWord32    sizeOfSet;
-    WebRtc_UWord32    lengthOfSet;
+    void AddEntry(WebRtc_UWord32 tmmbrSet,
+                  WebRtc_UWord32 packetOHSet,
+                  WebRtc_UWord32 ssrcSet);
+
+    // Remove one entry from table, and move all others down.
+    void RemoveEntry(WebRtc_UWord32 sourceIdx);
+
+    void SwapEntries(WebRtc_UWord32 firstIdx,
+                     WebRtc_UWord32 secondIdx);
+
+    // Set entry data to zero, but keep it in table.
+    void ClearEntry(WebRtc_UWord32 idx);
+
+ private:
+    class SetElement {
+      public:
+        SetElement() : tmmbr(0), packet_oh(0), ssrc(0) {}
+        WebRtc_UWord32 tmmbr;
+        WebRtc_UWord32 packet_oh;
+        WebRtc_UWord32 ssrc;
+    };
+
+    std::vector<SetElement> _data;
+    // Number of places allocated.
+    WebRtc_UWord32    _sizeOfSet;
+    // NUmber of places currently in use.
+    WebRtc_UWord32    _lengthOfSet;
 };
 
 class TMMBRHelp