contract SafeWinner is Ownable {
    using SafeMath for uint256;

    mapping(address => uint) public pendingPayments;
    address[] public pendingWinners;
    uint public totalPendingPayments;

    event WinnerWithdrew(address indexed winner, uint amount, uint block);

    /// @dev records the winner so that a transfer or withdraw can occur at 
    /// a later date.
    function addPendingWinner(address winner, uint amount) internal {
        pendingPayments[winner] = pendingPayments[winner].add(amount);
        totalPendingPayments = totalPendingPayments.add(amount);
        pendingWinners.push(winner);
    }

    /// @dev allows a winner to withdraw their rightful jackpot.
    function withdrawWinnings() public {
        address winner = msg.sender;
        uint payment = pendingPayments[winner];

        require(payment > 0);
        require(this.balance >= payment);

        transferPending(winner, payment);
    }

    /// @dev Retries all pending winners
    function retryWinners() public onlyOwner {
        for (uint i = 0; i < pendingWinners.length; i++) {
            retryWinner(i);
        }

        pendingWinners.length = 0;
    }

    function retryWinner(uint index) public onlyOwner {
        address winner = pendingWinners[index];
        uint payment = pendingPayments[winner];
        require(this.balance >= payment);
        if (payment != 0) {
            transferPending(winner, payment);
        }
    }

    function transferPending(address winner, uint256 payment) internal {
        totalPendingPayments = totalPendingPayments.sub(payment);
        pendingPayments[winner] = 0;
        winner.transfer(payment);        
        WinnerWithdrew(winner, payment, block.number);
    }
}
function retryWinners() public onlyOwner {
    for (uint i = 0; i < pendingWinners.length; i++) {
        retryWinner(i);
    }

    pendingWinners.length = 0;
}

/// @dev Retries all pending winners