diff --git a/bin/compile.and.deploy.contract b/bin/compile.and.deploy.contract
new file mode 100755
index 0000000000000000000000000000000000000000..f7a36c0ff88ab9452775a3aa6278b2b18678fe59
--- /dev/null
+++ b/bin/compile.and.deploy.contract
@@ -0,0 +1,70 @@
+#!/bin/bash
+# 20180618 Robert Martin-Legene <robert@nic.ar>
+
+if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi
+source ${BFAHOME}/bin/libbfa.sh || exit 1
+
+function	create
+{
+    workdir=$(  mktemp -p . -d )
+    cleanup     "$workdir"
+    json=$(	solc --optimize --combined-json abi,bin $filename	); test $? = 0
+    prefix=$(   echo "$json"    | jq -M  '.contracts | keys | .[0]'     );
+    abi=$(	echo "$json"	| jq -rM ".contracts.${prefix}.abi"	); test $? = 0
+    bin=$(	echo "$json"	| jq -rM ".contracts.${prefix}.bin"	); test $? = 0
+    # Save abi for future use
+    echo $abi > ${workdir}/abi
+    # We could save the bin, but we don't actually use it later, plus
+    # it gets stored in the blockchain
+    #echo $bin > ${workdir}/bin
+    js=$(       mktemp )
+    cleanup     "$js"
+    cat > $js <<EOT
+var mycontract  = eth.contract($abi)
+var transaction = mycontract.new( { from: eth.accounts[0], data: "0x${bin}", gas: 1000000 } )
+var rcpt
+while ( !rcpt )
+{
+  admin.sleepBlocks( 1 )
+  rcpt = eth.getTransactionReceipt( transaction.transactionHash )
+}
+var address = rcpt.contractAddress
+var pubcontract = mycontract.at(address)
+console.log( pubcontract.address )
+EOT
+    echo '*** Creating contract. This will take at least 16 seconds.'
+    outfile=$( mktemp )
+    cleanup "$outfile"
+    geth_exec_file $js > $outfile
+    if [ ` wc -l < $outfile ` = 2 -a `tail -1 < $outfile` = "true" ]
+    then
+        addr=` head -1 < $outfile `
+        mkdir -p ${BFANETWORKDIR}/contracts
+        mv ${workdir} ${BFANETWORKDIR}/contracts/${addr}
+        echo Your new contract can be found in ${BFANETWORKDIR}/contracts/${addr}
+ 	ln -snf ${addr} ${BFANETWORKDIR}/contracts/${contractname}
+    else
+        echo 
+        echo ' *** INPUT ***'
+        echo 
+        cat $js
+        echo
+        echo ' *** OUTPUT ***'
+        echo
+        cat $outfile
+    fi
+}
+
+filename="$1"
+if [ -z "$filename" -o ! -r "$filename" ]
+then
+    echo "Specify a filename of a contract you wish to compile."
+    false
+fi
+contractname=${filename%%.sol}
+contractname=${contractname##*/}
+contractname=${contractname##contract.}
+contractname=${contractname%.*}
+bfaconfig max
+prereq jq solc geth
+create
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 );
     }
 }