diff --git a/src/Ballot.sol b/src/Ballot.sol
index a451841f6f40dddcf13d4b056f46a22d45170103..07690f21a9a2241201e20efc71f479c97efc8c70 100644
--- a/src/Ballot.sol
+++ b/src/Ballot.sol
@@ -1,70 +1,66 @@
 // Basado en https://soliditycookbook.com/voting
 // vim:syntax:filetype=javascript:ai:sm
 // vim:expandtab:backspace=indent,eol,start:softtabstop=4
+
 pragma solidity ^0.4.25;
 
-/// @title Voting with delegation.
-contract            Ballot      {
-    // This declares a new complex type which will
-    // be used for variables later.
-    // It will represent a single voter.
-    struct          Voter       {
+/// @title A single ballot contract which allows certain
+/// @title accounts to vote (one single vote).
+/// @author soliditycookbook.com & Robert Martin-Legene
+/// @notice A Chairman will deploy the contract, setting up initial
+/// @notice conditions. Before the voting period starts the Chairman
+/// @notice must also tell the contract who is allowed to vote.
+contract            Ballot
+{
+    /// @dev This is a struct for a single voter.
+    /// @dev Voter.vote is the index of the voted proposal or -1 if
+    /// @dev the account has not voted yet.
+    struct          Voter
+    {
         address     voter;
-        int         vote;       // index of the voted proposal or -1 if not voted
-    }
-    // This is a type for a single proposal.
-    struct          Proposal    {
-        bytes32     name;       // short name (up to 32 bytes)
-        uint        voteCount;  // number of accumulated votes
-    }
-    struct          Votingrules  {
-        string      title;
-        address     chairman;
-        uint        voteStarts;
-        uint        voteBefore;
-        // A NOTE ON PERCENTAGES
-        // At present floats do not exist. Since we merely use
-        // our floats to later present to the outside world,
-        // and then let them handle the math, this scenario will
-        // be used:
-        //
-        // A percentage will be multiplied with one million. Thus:
-        // 100% is represented as 100 million. I.e. "100000000".
-        // 2/3 is represented as "67777778" (see note later on
-        // two-thirds
-
-        // Which percentage of the registered voters must
-        // vote in order for the vote to be considered valid.
-        // e.g. 0
-        uint        percentOfRegisteredVotersReqToBeValid;
-        // Which percentage of the cast votes are required
-        // for the motion/title to pass?
-        // MAJORITY VOTE:
-        //   specify 50000001
-        // TWO-THIRDS:
-        //   specify 67777777
-        uint        percentOfVotesCastToWin;
-        // Counting registered voters who do not vote as blank
-        // votes, has the effect that it is more difficult
-        // to acquire the desired votes.
-        bool        countNonvotesAsBlanks;
+        uint[]      votedProposals;
+        uint        votesLeft;
     }
+    string      public      ballotTitle;
+    address     public      ballotChairman;
+    uint        public      ballotVoteStarts;
+    uint        public      ballotVoteBefore;
+    uint        public      ballotPercentOfRegisteredVotersReqToBeValid;
+    uint        public      ballotPercentOfVotesCastToWin;
+    /// @dev Counting registered voters who do not vote as blank
+    /// @dev votes, has the effect that it is more difficult
+    /// @dev to acquire the desired votes.
+    bool        public      ballotCountNonvotesAsBlanks;
+    uint        public      ballotMaxVotesPerVoter;
+    uint        public      ballotMaxVotesPerProposal;
+    /// @dev The votermap points to the index(number) that the struct of the
+    /// @dev account can be found.
+    mapping( address => uint )
+                public      voterMap;
+    Voter[]     public      voterList;
+    /// @dev Short name (up to 32 bytes)
+    bytes32[]   public      proposalList;
+    uint[]      private     emptyuintlist;
 
-    Votingrules                     public  rules;
-    mapping( address => uint )      public  voterMap;
-    Voter[]                         public  voterList;
-    uint                            public  numvoters;
-    Proposal[]                      public  proposalList;
-    uint                            public  numproposals;
-
-    /// Create a new ballot to choose one of `proposalNames`.
+    /// @notice When the SC is being deployed, you must define initial conditions. When specifying percentages they are to have been multiplied with 100 million (5% is written as 5 million, since 5% is actially 0.05).
+    /// @param title Name of the things being voted for.
+    /// @param voteStarts Time in seconds (since Unix Epoch) when the voting starts (note that voters must be defined before voting starts).
+    /// @param voteBefore Time in seconds (since Unix Epoch) at/after which it is too late to vote. After this point, the Ballot is effectively readonly.
+    /// @param percentOfRegisteredVotersReqToBeValid How many of the registered voters must vote before the result of the Ballot can be considered valid. E.g. if 50% is set and only 40% votes, then the result of the Ballot can not be used.
+    /// @param percentOfVotesCastToWin How many of the votes that are cast are required to win. This is often 50.000001% ("more than half"), 67.777778% ("two thirds") or 0% (proposal with most votes - e.g. voting for most popular fruit).
+    /// @param countNonvotesAsBlanks Whether or not to count voters whom did not vote, as having voted blank.
+    /// @param maxVotesPerVoter How many votes can a voter cast. Often this is 1 (one).
+    /// @param maxVotesPerProposal How many votes one voter can cast on each proposal. I.e. can (s)he vote use all his votes on one proposal?
+    /// @param proposalNames 32 char "strings" listing all the options available to vote for.
     constructor(
-        string      ballotTitle,
+        string      title,
         uint        voteStarts,
         uint        voteBefore,
         uint        percentOfRegisteredVotersReqToBeValid,
         uint        percentOfVotesCastToWin,
         bool        countNonvotesAsBlanks,
+        uint        maxVotesPerVoter,
+        uint        maxVotesPerProposal,
         bytes32[]   proposalNames
     )
         public
@@ -72,61 +68,63 @@ contract            Ballot      {
         require( voteBefore > now );
         require( percentOfRegisteredVotersReqToBeValid <= 100000000 );
         require( percentOfVotesCastToWin               <= 100000000 );
-        // chairman can not automatically vote. Chairman must
-        // giveRightToVote to himself if he wants to vote.
-        rules.chairman                                  =   msg.sender;
-        rules.title                                     =   ballotTitle;
-        rules.voteStarts                                =   voteStarts;
-        rules.voteBefore                                =   voteBefore;
-        rules.percentOfRegisteredVotersReqToBeValid     =   percentOfRegisteredVotersReqToBeValid;
-        rules.percentOfVotesCastToWin                   =   percentOfVotesCastToWin;
-        rules.countNonvotesAsBlanks                     =   countNonvotesAsBlanks;
-
-        // For each of the provided proposal names,
-        // create a new proposal object and add it
-        // to the end of the array.
-        numproposals                        =   proposalNames.length;
+        // chairman can not automatically vote.
+        // Chairman must giveRightToVote to himself if
+        // he wants to vote.
+        ballotChairman                                  =   msg.sender;
+        ballotTitle                                     =   title;
+        ballotVoteStarts                                =   voteStarts;
+        ballotVoteBefore                                =   voteBefore;
+        ballotPercentOfRegisteredVotersReqToBeValid     =   percentOfRegisteredVotersReqToBeValid;
+        ballotPercentOfVotesCastToWin                   =   percentOfVotesCastToWin;
+        ballotCountNonvotesAsBlanks                     =   countNonvotesAsBlanks;
+        ballotMaxVotesPerVoter                          =   maxVotesPerVoter;
+        ballotMaxVotesPerProposal                       =   maxVotesPerProposal;
+        /// @dev For each of the provided proposal names,
+        /// @dev add it to the end of the proposalList
+        uint        incoming                =   proposalNames.length;
         uint        i                       =   0;
-        while ( i < numproposals )
+        while ( i < incoming )
         {
-            proposalList.push(
-                Proposal(
-                    {
-                        name:                   proposalNames[i],
-                        voteCount:              0
-                    }
-                )
-            );
+            proposalList.push( proposalNames[i] );
             i++;
         }
     }
 
-    // Give `voter` the right to vote on this ballot.
-    function giveRightToVote( address voter )
+    /// @notice Give 'voters' the right to vote on this ballot.
+    /// @param voters The list of voters to add to the list of allowed voters.
+    function giveRightToVote( address[] voters )
         public
     {
         // May only be called by chairman.
-        require( msg.sender == rules.chairman   );
-        require( rules.voteBefore < now         );
-        uint        idx                     =   voterMap[voter];
-        // Can't add voters more than once.
-        require( idx == 0 );
-        // Not even the voter listed in [0].
-        if ( voterList.length > 0 )
-            require( voterList[0].voter != voter );
-        // If the voter's address doesn't match, it is because
-        // he doesn't exist (and then we always have idx=0).
-        // So we push him onto the voterList.
-        idx                                 =   voterList.push(
-            Voter(
-                {
-                    voter:                      voter,
-                    vote:                       -1
-                }
-            )
-        ) - 1;
-        voterMap[voter]                     =   idx;
-        numvoters++;
+        require( msg.sender == ballotChairman   );
+        require( ballotVoteBefore < now         );
+        uint        len                     =   voters.length;
+        uint        i                       =   0;
+        while ( i < len )
+        {
+            address voter                   =   voters[i];
+            uint    idx                     =   voterMap[voter];
+            /// @dev Can't add any voters more than once.
+            require( idx == 0 );
+            /// @dev Not even the voter listed in [0] can vote more than once.
+            if ( voterList.length > 0 )
+                require( voterList[0].voter != voter );
+            /// @dev If the voter's address doesn't match, it is because
+            /// @dev he doesn't exist (and then we always have idx=0).
+            /// @dev So we push him onto the voterList.
+            idx                             =   voterList.push(
+                Voter(
+                    {
+                        voter:                  voter,
+                        votedProposals:         emptyuintlist,
+                        votesLeft:              ballotMaxVotesPerVoter
+                    }
+                )
+            ) - 1;
+            voterMap[voter]                 =   idx;
+            i++;
+        }
     }
 
     function getVoterIdx( address voter )
@@ -142,24 +140,26 @@ contract            Ballot      {
         return -1;
     }
 
-    /// Give your vote to proposal `proposals[proposal].name`.
     function vote( uint proposal )
         public
     {
-        require( proposal < numproposals        );
-        require( rules.voteStarts  >= now       );
-        require( rules.voteBefore < now         );
+        require( proposal < proposalList.length );
+        require( ballotVoteStarts >= now        );
+        require( ballotVoteBefore <  now        );
         int         idx                     =   getVoterIdx( msg.sender );
         require( idx > -1 );
         uint        uidx                    =   uint( idx );
-        int         formervote              =   voterList[uidx].vote;
-        require( formervote != int(proposal) );
-        if ( formervote > -1 )
+        require( voterList[uidx].votesLeft > 0 );
+        uint        proposalCounter         =   0;
+        uint        i                       =   voterList[uidx].votedProposals.length;
+        while ( i > 0 )
         {
-            // He changed his vote - this is normal for politicians, too.
-            proposalList[ uint(formervote) ].voteCount--;
+            i--;
+            if ( voterList[uidx].votedProposals[i] == proposal )
+                proposalCounter++;
         }
-        proposalList[ proposal ].voteCount++;
-        voterList[ uidx ].vote              =   int(proposal);
+        require( proposalCounter < ballotMaxVotesPerProposal );
+        voterList[uidx].votesLeft--;
+        voterList[uidx].votedProposals.push( proposal );
     }
 }