diff --git a/README.md b/README.md
index a0782d8d50f977dea99a3e00b38ff3752e809d24..e3ccd343d0390618587ec358ee6b45e2db5a6a35 100644
--- a/README.md
+++ b/README.md
@@ -47,14 +47,14 @@ request: **geth**
 
 Connects you to your running local geth.
 
-## create.contract
+## compile.and.deploy.contract
 requires: **geth**, **solc**, **jq**
 
 Compiles and deploys a contract to the blockchain. A local "node1" must already be running and synchronized.
 
 Argument 1 is the filename of the contract to compile.
 
-Example: `create.contract src/TimestampAuthority.sol`
+Example: `compile.and.deploy.contract src/TimestampAuthority.sol`
 
 ## tsa-insert.sh
 requires: **geth**
diff --git a/bin/create.contract b/bin/compile.and.deploy.contract
similarity index 100%
rename from bin/create.contract
rename to bin/compile.and.deploy.contract
diff --git a/src/Sealers.sol b/src/Sealers.sol
index 47ae489fe24a48ddaea4b76ad6316d1e142cac45..0d5391880c70287c2a6e8447c4413c79e1afbc72 100644
--- a/src/Sealers.sol
+++ b/src/Sealers.sol
@@ -1,89 +1,190 @@
-pragma solidity ^0.4.22;
+// vim:syntax:filetype=javascript:ai:sm
+
+pragma solidity ^0.4.24;
 
 // This contract is supposed to maintain the list of authorized sealers.
 // For this to work, a sealer must deploy the contract and then all sealers
-// must occasionally (every 5 minutes) run the related SealerSync.js
+// must, say, every 5 minutes, run the related SealerSync.js
 
 contract Sealers {
 
     // This struct contains a list of votes and who has voted for each victim/beneficiary.
     // Votes taking longer than 30K blocks, will have to restart.
     struct Proposal {
-	address         victim;     // Whom are we voting about.
-        uint256         votestart;  // In which block did this vote begin?
-	bool		promotion;  // true=promotion, false=demotion
-	address[]	voters;     // List of voters.
+        address         victim;     // Whom are we voting about.
+        uint            votestart;  // In which block did this vote begin?
+        bool		    promotion;  // true=promotion, false=demotion
+        address[]	    voters;     // List of voters.
     }
     address[]           public  sealers;
-    Proposal[]          public	sealerproposals;
+    Proposal[]          public  sealerproposals;
 
-    event               vote( address voter, address victim, bool promotionOrDemotion );
+    event               voteCast( address voter, address victim, bool promotionOrDemotion );
     event               adminChange( address admin, bool promotionOrDemotion );
 
-    constructor() public {
-        sealers[0] = msg.sender;
+    constructor()   public
+    {
+        sealers.push( msg.sender );
     }
 
-    // Public utility, works on any list needle and haystack given.
-    //
-    // Returns an index to the position of the needle inside haystack.
-    // 0 is first position. -1 means not found.
-    function findAddressInList( address[] haystack, address needle ) public pure returns (int256) {
-        uint256 i   =   haystack.length;
-        while ( i-- > 0 )
-            if ( needle == haystack[i] )
-                return int256(i & 0x7fffffffffffffffffffffffffffffff);
-        return -1;
-    }
-    function sealerIdx( address needle ) public view returns (int256) {
-        return findAddressInList( sealers, needle );
-    }
-    // This function is to be used to know how many sealers are in the sealers list.
-    function sealerLength() public view returns (uint256) {
+    // This function is used to know how many sealers are in the sealers list.
+    function    sealerLength() public view returns (uint)
+    {
         return sealers.length;
     }
+
     // This function is to be used to get the address from a specific position in the sealers list.
     // Remember first position is 0.
     // Last position is sealers.length-1.
-    function sealerPosition( uint256 idx ) public view returns (address) {
+    function    sealerPosition( uint idx ) public view returns (address)
+    {
         require( idx < sealers.length, "There are not that many sealers registered in the list." );
         return sealers[idx];
     }
-    function isSealer( address subject ) public view returns (bool) {
-        return ( sealerIdx(subject) > -1 ); 
+
+    function    isSealer( address subject ) public view returns (bool)
+    {
+        return ( _findAddressInList( sealers, subject ) > 0 );
     }
-    function requireSealer( address subject ) public view {
+
+    function    requireSealer( address subject ) public view
+    {
         require( isSealer(subject), "Not sealer" );
     }
 
-    function _remove_entry( uint256 idx, list alist ) private returns (list) {
-        uint256 pos     =   idx;
+    // Returns an index to the position of the needle inside haystack.
+    // Beware that:
+    // 0 = not found.
+    // 1 = first position.
+    function    _findAddressInList( address[] haystack, address needle ) private pure returns (uint)
+    {
+        uint    i   =   haystack.length;
+        while ( i-- > 0 )
+            if ( needle == haystack[i] )
+                return i+1;
+        return 0;
+    }
+
+    function    _remove_proposal( uint idx ) private
+    {
         // Move all items in the list (after idx) one step closer to the
         // front of the list.
-        while ( ++pos < list.length )
-            alist[pos-1] = alist[pos];
+        uint    max     =   sealerproposals.length;
+        while ( ++idx < max )
+            sealerproposals[idx-1] = sealerproposals[idx];
         // "pop" the end of the list, making the list shorter.
-        alist.length--;
-        return alist;
+        sealerproposals.length--;
+    }
+
+    function _del_votes( address victim ) private
+    {
+        uint    i_max   =   sealerproposals.length;
+        uint    i       =   i_max;
+        // check all proposals
+        while ( i-- > 0 )
+        {
+            // check all voters for every proposal
+            uint    j_max   =   sealerproposals[i].voters.length;
+            uint    j       =   j_max;
+            while ( j-- > 0 )
+                if ( sealerproposals[i].voters[j] == victim )
+                {
+                    // Found the victim as voter, but since he is about
+                    // to be deleted, we will remove him from the list.
+                    uint    k   =   j;
+                    while ( ++k < j_max )
+                        sealerproposals[i].voters[k-1] = sealerproposals[i].voters[k];
+                    sealerproposals[i].voters.length--;
+                    j_max--;
+                    if ( sealerproposals[i].voters.length == 0 )
+                    {
+                        _remove_proposal( i );
+                        i_max--;
+                    }
+                }
+        }
+    }
+
+    function    _remove_sealer( address victim ) private
+    {
+        // Remove votes that the victim has already cast.
+        _del_votes( victim );
+        // Move all items in the list (after match) one step closer to the
+        // front of the list.
+        uint    max         =   sealers.length;
+        uint    i           =   max;
+        while ( i-- > 0 )
+            if ( sealers[i] == victim )
+            {
+                // We could have recycled 'i' here, but for clarity, we don't.
+                uint    j   =   i;
+                while ( ++j < max )
+                    sealers[j-1] = sealers[j];
+                // "pop" the end of the list, making the list shorter.
+                sealers.length--;
+                return;
+            }
     }
 
     // This function sees if any proposals have overstayed their welcome and thus
     // needs to be removed.
-    function _trimProposals() private {
-        for ( uint256 i = sealerproposals.length-1; i>=0; i-- )
+    function _trimProposals() private
+    {
+        uint    i           =   sealerproposals.length;
+        while ( i-- > 0 )
         {
             // If a proposal is more than 30K blocks old, then remove it from the list.
             if ( sealerproposals[i].votestart + 30000 <= block.number )
-                sealerproposals = _remove_entry( i, sealerproposals );
+                _remove_proposal( i );
         }
     }
 
-    function    promotionIdx( address victim, bool promotion ) public view return (int256) {
-	uint256	idx     =   sealerproposals.length;
-	while ( idx-- > 0)
-            if ( sealerproposals[idx].victim == victim && sealerproposals[idx].promotion == promotion )
-                return idx;
-        return -1;
+    // We run through the entire list of proposals, checking if they fulfill the
+    // requirements. Why the whole list? Because if a sealer is removed, whom has
+    // not yet voted for a proposal, that proposal may now have achieved majority.
+    function _promotedemote() private
+    {
+        uint    prevlength  =   0;
+        // Keep looping over the list until the number of proposals stops changing.
+        while ( prevlength != sealerproposals.length )
+        {
+            uint    i           =   sealerproposals.length;
+            prevlength          =   i;
+            uint    majority    =   sealers.length / 2 + 1;
+            // Loop over all proposals
+            while ( i-- > 0 )
+            {
+                // If we have enough votes to perform the actual promotion/demotion
+                if ( sealerproposals[i].voters.length >= majority )
+                {
+                    // Is it a promotion or a demotion?
+                    if (                sealerproposals[i].promotion )
+                        // Add victim to sealer list
+                        sealers.push(   sealerproposals[i].victim );
+                    else
+                        // Remove victim from sealer list
+                        _remove_sealer( sealerproposals[i].victim );
+    
+                    // Send notification
+                    emit adminChange(   sealerproposals[i].victim,
+                                        sealerproposals[i].promotion );
+                    // Remove the proposal because the voting is complete.
+                    _remove_proposal( i );
+                }
+            }
+        }
+    }
+    // Returns an index to the position of the proposal inside matching the [victim,promotion] tuple
+    // Beware that:
+    // 0 = not found.
+    // 1 = first position.
+    function    promotionIdx( address victim, bool promotion ) public view returns (uint)
+    {
+	uint   	i       =   sealerproposals.length;
+	while ( i-- > 0)
+            if ( sealerproposals[i].victim == victim && sealerproposals[i].promotion == promotion )
+                return i+1;
+        return 0;
     }
 
     // You can call this for free and know if your promote call
@@ -104,9 +205,9 @@ contract Sealers {
         if ( !isSealer(victim) && !promotion )
             return false;
 
-        // See if the voter is already in the list of voters for this [victim,promotion] tupple
-        int256  proppos     =   promotionIdx( victim, promotion );
-        if ( proppos > -1 && findAddressInList( sealerproposals[proppos].voters, voter ) > -1 )
+        // See if the voter is already in the list of voters for this [victim,promotion] tuple
+        uint    proppos     =   promotionIdx( victim, promotion );
+        if ( proppos > 0 && _findAddressInList( sealerproposals[proppos-1].voters, voter ) > 0 )
             return false;
         return true;
     }
@@ -116,48 +217,33 @@ contract Sealers {
     // As per usual, this requires n/2+1 votes.
     // The boolean must be true if you want to add a sealer
     // and false if you want to remove one.
-    function promote( address victim, bool promotion ) public {
+    function vote( address victim, bool promotion ) public
+    {
         if ( ! mayVote(msg.sender, victim, promotion))
-            revert("That seems redundant.");
+            revert("That seems redundant or is otherwise not allowed.");
         _trimProposals();
 
         // Send notification of the vote
-        emit vote( msg.sender, victim, promotion );
+        emit voteCast( msg.sender, victim, promotion );
 
-        // signed as opposed to unsigned (int)
-        int256  signedretval    =   promotionIdx( victim, promotion );
-        uint    proppos;
-        if ( signedretval == -1 )
+        uint    proppos     =   promotionIdx( victim, promotion );
+        if ( proppos == 0 )
         {
             // This is a new proposal, so we will add it, so we can vote on it.
             address[] memory emptyAddressList;
 	    proppos = sealerproposals.push( Proposal(victim, block.number, promotion, emptyAddressList ) );
         }
-        else
-            proppos = uint256( signedretval & 0x7fffffffffffffffffffffffffffffff );
-
-        // Make things a bit more easy to read by using a shorter variable name
-        Proposal memory prop = sealerproposals[proppos];
+        proppos--;
 
         // Add our vote
-        prop.voters.push( msg.sender );
-
-        // Stop here if we do not have enough votes to perform the actual promotion/demotion
-        if ( prop.voters.length < sealers.length/2+1 )
-            return;
+        sealerproposals[proppos].voters.push( msg.sender );
 
-        // Remove the proposal because the voting is complete.
-        sealerproposals =   _remove_entry( proppos, sealerproposals );
+        // See if we're ready to promote/demote anyone, based on the proposals.
+        _promotedemote();
 
-        // Is it a promotion or a demotion?
-        if ( promotion )
-            // Add victim to sealer list
-            sealers.push( victim );
-        else
-            // Remove victim from sealer list
-            sealers     =   _remove_entry( sealerIdx(victim), sealers );
-
-        // Send notification
-        emit adminChange( victim, promotion );
+        // If we have no more sealers, we have no reason to live.
+        if ( sealers.length == 0 )
+            selfdestruct( msg.sender );
     }
 }
+