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/contract.Sealers.sol b/src/Sealers.sol
similarity index 76%
rename from src/contract.Sealers.sol
rename to src/Sealers.sol
index 2f1b8118811f7b97bf9e4ea10a0b85b79b44e88c..0d5391880c70287c2a6e8447c4413c79e1afbc72 100644
--- a/src/contract.Sealers.sol
+++ b/src/Sealers.sol
@@ -19,7 +19,7 @@ contract Sealers {
     address[]           public  sealers;
     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
@@ -56,7 +56,7 @@ contract Sealers {
     // Beware that:
     // 0 = not found.
     // 1 = first position.
-    function    _findAddressInList( address[] haystack, address needle ) private view returns (uint)
+    function    _findAddressInList( address[] haystack, address needle ) private pure returns (uint)
     {
         uint    i   =   haystack.length;
         while ( i-- > 0 )
@@ -130,7 +130,8 @@ contract Sealers {
     // needs to be removed.
     function _trimProposals() private
     {
-        for ( uint i = sealerproposals.length-1; i>=0; i-- )
+        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 )
@@ -138,6 +139,41 @@ contract Sealers {
         }
     }
 
+    // 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.
@@ -181,14 +217,14 @@ 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 or is otherwise not allowed.");
         _trimProposals();
 
         // Send notification of the vote
-        emit vote( msg.sender, victim, promotion );
+        emit voteCast( msg.sender, victim, promotion );
 
         uint    proppos     =   promotionIdx( victim, promotion );
         if ( proppos == 0 )
@@ -202,23 +238,12 @@ contract Sealers {
         // Add our vote
         sealerproposals[proppos].voters.push( msg.sender );
 
-        // Stop here if we do not have enough votes to perform the actual promotion/demotion
-        if ( sealerproposals[proppos].voters.length < sealers.length/2+1 )
-            return;
-
-        // Remove the proposal because the voting is complete.
-        _remove_proposal( proppos );
-
-        // Is it a promotion or a demotion?
-        if ( promotion )
-            // Add victim to sealer list
-            sealers.push( victim );
-        else
-            // Remove victim from sealer list
-            _remove_sealer( victim );
+        // See if we're ready to promote/demote anyone, based on the proposals.
+        _promotedemote();
 
-        // 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 );
     }
 }