diff --git a/destileria2.sol b/destileria2.sol
index d5216826d7824f325271353588cbc746802f25b7..00fddb5e7e04e8d27f5e93f24dc05f244d8af8ab 100644
--- a/destileria2.sol
+++ b/destileria2.sol
@@ -15,7 +15,7 @@ pragma solidity >=0.4;
 
 contract destileria2
 {
-    enum UserType { UserNotFound, UserOwner, UserDistributor, UserBeneficiary }
+    enum UserType { NotFound, Owner, Distributor, Beneficiary }
     // no hace falte 'indexed' ya que solamente va a haber
     // un evento de este tipo
     event deployed(address creator);
@@ -40,7 +40,8 @@ contract destileria2
     // Used for reclaiming unused positions in the userIndex
     uint256[] public    deletedEntries;
     // Last time we did replenishAll, where did we stop?
-    uint256             allstopmarker = 0;
+    uint256   public    allstopmarker = 0;
+    mapping(UserType => string) public userTypeNames;
 
     constructor() payable
     {
@@ -61,10 +62,14 @@ contract destileria2
         userIndex.push(UserEntry({
             // This entry can be returned when no matches were found
             addr: address(0),
-            userType: UserType.UserNotFound,
+            userType: UserType.NotFound,
             topUpLimit: 0,
             deleted: true
         }));
+        userTypeNames[UserType.NotFound]    = "User Not Found";
+        userTypeNames[UserType.Owner]       = "Owner";
+        userTypeNames[UserType.Distributor] = "Distributor";
+        userTypeNames[UserType.Beneficiary] = "Beneficiary";
     }
 
     receive() external payable {}
@@ -77,167 +82,152 @@ contract destileria2
 
     modifier onlyDistributorOrOwner
     {
-        require(contains(UserType.UserDistributor, msg.sender) || msg.sender == owner);
+        require(contains(UserType.Distributor, msg.sender) || msg.sender == owner);
         _;
     }
 
-    function addBeneficiary(address addr, uint256 topuplimit) public onlyDistributorOrOwner returns(bool)
+    function addDistributor(address addr, uint256 topuplimit) public onlyOwner
     {
-        if (topuplimit == 0)
-            return false;
-        // User must not exist already
-        if (getUserType(addr) != UserType.UserNotFound)
-            return false;
-        if (topuplimit > getTopUpLimit(UserType.UserDistributor, msg.sender))
-            return false;
-        emit added(msg.sender, addr, UserType.UserBeneficiary, topuplimit);
-        return !insert(UserType.UserBeneficiary, addr, topuplimit);
+        require(topuplimit > 0, "The topuplimit must be a positive number");
+        require(getUserType(addr) == UserType.NotFound, "The distributor to add must not already be a listed user of any type.");
+        insert(UserType.Distributor, addr, topuplimit);
+        emit added(msg.sender, addr, UserType.Distributor, topuplimit);
     }
 
-    function addDistributor(address addr, uint256 topuplimit) public onlyOwner returns(bool)
+    function addBeneficiary(address addr, uint256 topuplimit) public onlyDistributorOrOwner
     {
-        if (topuplimit == 0)
-            return false;
-        // User must not exist already
-        if (getUserType(addr) != UserType.UserNotFound)
-            return false;
-        emit added(msg.sender, addr, UserType.UserDistributor, topuplimit);
-        return !insert(UserType.UserDistributor, addr, topuplimit);
+        require(topuplimit > 0, "topuplimit must be a positive integer.");
+        require(getUserType(addr) == UserType.NotFound, "The distributor to add must not already be a listed user of any type.");
+        insert(UserType.Beneficiary, addr, topuplimit);
+        emit added(msg.sender, addr, UserType.Beneficiary, topuplimit);
     }
 
-    function kick(UserType victimtype, address addr) private returns(bool)
+    function kick(UserType victimtype, address addr) private
     {
-        if (!contains(victimtype, addr))
-            return false;
+        require(contains(victimtype, addr), "Address unknown.");
+        remove(victimtype, addr);
         emit kicked(msg.sender, addr);
-        return remove(victimtype, addr);
     }
 
-    function kickDistributor(address addr) public onlyOwner returns(bool)
+    function kickDistributor(address addr) public onlyOwner
     {
-        return kick(UserType.UserDistributor, addr);
+        kick(UserType.Distributor, addr);
     }
 
-    function kickBeneficiary(address addr) public onlyDistributorOrOwner returns(bool)
+    function kickBeneficiary(address addr) public onlyDistributorOrOwner
     {
-        return kick(UserType.UserBeneficiary, addr);
+        kick(UserType.Beneficiary, addr);
     }
 
-    function changeLimit(address addr, uint256 topuplimit) public onlyDistributorOrOwner returns(bool)
+    function changeLimit(address addr, uint256 topuplimit) public onlyDistributorOrOwner
     {
         uint256 pos = addressToUserEntryIndex[addr];
-        if (pos == 0)
-            return false;
+        require(pos == 0, "Address unknown.");
         UserEntry memory entry = userIndex[pos];
-        if (entry.userType != UserType.UserDistributor && entry.userType != UserType.UserBeneficiary)
-            return false;
+        require(entry.userType == UserType.Distributor || entry.userType == UserType.Beneficiary, "Only Beneficiaries and Distributors have limits associated.");
         if (msg.sender != owner)
         {
             // Only our owner can change limits for Distributors
-            if (entry.userType == UserType.UserDistributor)
-                return false;
+            require(entry.userType == UserType.Distributor, "Only the contract owner can changed limits for Distriburs.");
             // Distributors must obey the limit
-            if (topuplimit > getTopUpLimit(UserType.UserDistributor, msg.sender))
-                return false;
+            require(topuplimit > getTopUpLimit(UserType.Distributor, msg.sender), "Distributors can not set a limit to exceed its own limit.");
         }
         // all is fine - now we change the limit
         userIndex[pos].topUpLimit = topuplimit;
         emit limitChanged(msg.sender, addr, topuplimit);
-        return true;
     }
 
-    function replenish(address victim, uint256 amount) public payable onlyDistributorOrOwner returns(bool)
+    function replenish(address victim, uint256 amount) public payable onlyDistributorOrOwner
     {
-        if (getUserType(victim) != UserType.UserBeneficiary)
-            return false;
-        uint256 topuplimit = getTopUpLimit(UserType.UserBeneficiary, victim);
+        require(amount > 0, "The topup amount must be a positive integer.");
+        require(getUserType(victim) == UserType.Beneficiary, "Address is not listed as beneficiary.");
+        uint256 topuplimit = getTopUpLimit(UserType.Beneficiary, victim);
         // Does the destination account have less than his limit?
-        if (victim.balance + amount > topuplimit)
-            return false;
+        require(victim.balance + amount <= topuplimit, "Desired topup will make the destination address exceed his topup limit.");
         // avoid uint256 overflow
-        if (victim.balance + amount < victim.balance)
-            return false;
+        require(victim.balance + amount > victim.balance, "Giving that amount, will make his balance overflow.");
         // Do we have enough ether to send?
-        if (address(this).balance < amount)
-            return false;
+        require(address(this).balance >= amount, "The contract does not have enough balance to send that amount.");
         // Do the transfer and emit an event
         address payable addrpayable = address(uint160(victim));
         addrpayable.transfer(amount);
         emit replenished(msg.sender, victim, amount);
-        return true;
     }
 
     // To use this function, you should set gasLimit to at least gasEstimate + 50000
-    function replenishList(address[] calldata accs, uint256[] calldata amounts) public payable
+    function replenishList(address[] calldata accs, uint256[] calldata amounts) public payable onlyDistributorOrOwner
     {
-        require(accs.length == amounts.length);
+        require(accs.length == amounts.length, "The two lists given as parameters are not of the same length.");
         uint256 i = 0;
-        while (i < accs.length && gasleft()>49999)
+        while (i < accs.length && gasleft() >= 32768)
         {
             // we don't like overflow
             if (accs[i].balance + amounts[i] < accs[i].balance)
                 continue;
             // Don't allow amounts which will make the balance go above the top up limit.
-            if (accs[i].balance + amounts[i] < getTopUpLimit(UserType.UserBeneficiary, accs[i]))
+            if (accs[i].balance + amounts[i] < getTopUpLimit(UserType.Beneficiary, accs[i]))
                 replenish(accs[i], amounts[i]);
             i++;
         }
     }
 
     // Pay to as many as possible, until we run out of ether (or run through the list
-    function replenishAll() public payable onlyDistributorOrOwner returns(bool)
+    function replenishAll() public payable onlyDistributorOrOwner
     {
-        if (userIndex.length == 0)
-            return false;
+        require(userIndex.length > 0, "There are no users registered.");
+        require(address(this).balance > 0, "We need wei, in order for us to send to others. Our balance is zero.");
         // The index may have shrunk under the stopmarker
         if (allstopmarker >= userIndex.length)
             allstopmarker = 0;
         // The distributor's topuplimit (for owner this is ignored)
-        uint256 distlimit = getTopUpLimit(UserType.UserDistributor, msg.sender);
+        uint256 distlimit = getTopUpLimit(UserType.Distributor, msg.sender);
         uint256 i = allstopmarker;
-        while (++i != allstopmarker)
+        // just a round number
+        while (gasleft()>=32768)
         {
+            i++;
             // If we get to the end of the list, loop back to the start of it
             if (i >= userIndex.length)
                 i = 0;
             UserEntry memory entry = userIndex[i];
             // make sure we skip deleted entries
-            if (entry.deleted)
-                continue;
             // We only handle Beneficiaries
-            if (entry.userType != UserType.UserBeneficiary)
-                continue;
-            //
-            uint256 topuplimit;
-            if (msg.sender == owner || entry.topUpLimit <= distlimit)
-                topuplimit = entry.topUpLimit;
-            else
-                topuplimit = distlimit;
-            // Does the user actually need to get topped up?
-            if (topuplimit > entry.addr.balance)
-                continue;
-            // What's the difference?
-            uint256 amount = topuplimit - entry.addr.balance;
-            replenish(entry.addr, amount);
-            // Do we have enough ether to send?
-            if (address(this).balance < amount)
-                continue;
-            // Do the transfer and emit an event
-            address payable addrpayable = address(uint160(entry.addr));
-            addrpayable.transfer(amount);
-            emit replenished(msg.sender, entry.addr, amount);
+            if (!entry.deleted && entry.userType == UserType.Beneficiary)
+            {
+                uint256 topuplimit = distlimit;
+                if (msg.sender == owner || entry.topUpLimit <= distlimit)
+                    topuplimit = entry.topUpLimit;
+                // Fill up if he is below 75% of his topuplimit
+                if (entry.addr.balance/100*75 < topuplimit)
+                {
+                    // What's the difference?
+                    uint256 amount = topuplimit - entry.addr.balance;
+                    // Do we have enough ether to send?
+                    if (amount > address(this).balance)
+                        amount = address(this).balance;
+                    // Do the transfer and emit an event
+                    address payable addrpayable = address(uint160(entry.addr));
+                    addrpayable.transfer(amount);
+                    emit replenished(msg.sender, entry.addr, amount);
+                }
+            }
+            // Only run through the list once
+            if ( i == allstopmarker )
+                break;
+            if (address(this).balance == 0)
+                break;
         }
-        return true;
+        return;
     }
 
     function getDistributorLimit(address addr) public view returns(uint256)
     {
-        return getTopUpLimit(UserType.UserDistributor, addr);
+        return getTopUpLimit(UserType.Distributor, addr);
     }
 
     function getBeneficiaryLimit(address addr) public view returns(uint256)
     {
-        return getTopUpLimit(UserType.UserBeneficiary, addr);
+        return getTopUpLimit(UserType.Beneficiary, addr);
     }
 
     function getBeneficiariesCount() public view returns(uint256 count)
@@ -248,64 +238,60 @@ contract destileria2
         {
             if (userIndex[i].deleted)
                 continue;
-            if (userIndex[i].userType == UserType.UserBeneficiary)
+            if (userIndex[i].userType == UserType.Beneficiary)
                 count++;
         }
     }
 
+    function getUserIndexCount() public view returns(uint256)
+    {
+        return userIndex.length;
+    }
+
     function isBeneficiary(address addr) public view returns(bool)
     {
-        return contains(UserType.UserBeneficiary, addr);
+        return contains(UserType.Beneficiary, addr);
     }
 
     function isDistributor(address addr) public view returns(bool)
     {
-        return contains(UserType.UserDistributor, addr);
+        return contains(UserType.Distributor, addr);
     }
 
-    function insert(UserType victimtype, address addr, uint256 value) private returns(bool replaced)
+    function insert(UserType victimtype, address addr, uint256 value) private
     {
         uint256 pos = addressToUserEntryIndex[addr];
         if (pos > 0)
+            assert( userIndex[pos].addr != addr || userIndex[pos].deleted );
+        if (deletedEntries.length > 0)
         {
-            assert(userIndex[pos].addr == addr);
-            assert(!userIndex[pos].deleted);
-            replaced = true;
+            // recycle deleted entries, if possible
+            pos = deletedEntries[deletedEntries.length-1];
+            deletedEntries.pop();
         }
         else
         {
-            replaced = false;
-            if (deletedEntries.length > 0)
-            {
-                // recycle deleted entries, if possible
-                pos = deletedEntries[deletedEntries.length-1];
-                deletedEntries.pop();
-            }
-            else
-            {
-                pos = userIndex.length;
-                userIndex.push();
-            }
+            pos = userIndex.length;
+            userIndex.push();
         }
+        addressToUserEntryIndex[addr] = pos;
         userIndex[pos].addr = addr;
         userIndex[pos].userType = victimtype;
         userIndex[pos].topUpLimit = value;
         userIndex[pos].deleted = false;
-        if (!replaced)
-            addressToUserEntryIndex[addr] = pos;
     }
 
-    function remove(UserType victimtype, address addr) private returns(bool success)
+    function remove(UserType victimtype, address addr) private
     {
         uint256 pos = addressToUserEntryIndex[addr];
-        if (pos == 0)
-            return false;
-        if(victimtype != userIndex[pos].userType)
-            return false;
+        assert(pos>0);
+        assert(userIndex[pos].addr == addr);
+        assert(userIndex[pos].userType == victimtype);
+        assert(!userIndex[pos].deleted);
+        userIndex[pos].addr = address(0);
+        userIndex[pos].deleted = true;
         delete addressToUserEntryIndex[addr];
         deletedEntries.push(pos);
-        userIndex[pos].deleted = true;
-        return true;
     }
 
     function getEntry(address addr) private view returns(UserEntry memory)
@@ -318,7 +304,7 @@ contract destileria2
     function getUserType(address addr) public view returns(UserType)
     {
         uint256 pos = addressToUserEntryIndex[addr];
-        // no match will give the 0th userIndex entry which has UserNotFound as UserType
+        // no match will give the 0th userIndex entry which has NotFound as UserType
         return userIndex[pos].userType;
     }
 
@@ -337,4 +323,8 @@ contract destileria2
             return true;
         return false;
     }
+
+    function kill() public onlyOwner {
+        selfdestruct(msg.sender);
+    }
 }