contract DonationDoubler is Escapable, SafeMath {
    Campaign public beneficiary; // expected to be a Giveth campaign

    /// @notice The Constructor assigns the `beneficiary`, the
    ///  `escapeHatchDestination` and the `escapeHatchCaller` as well as deploys
    ///  the contract to the blockchain (obviously)
    /// @param _beneficiary The address of the CAMPAIGN CONTROLLER for the Campaign
    ///  that is to receive donations
    /// @param _escapeHatchDestination The address of a safe location (usually a
    ///  Multisig) to send the ether held in this contract
    /// @param _escapeHatchCaller The address of a trusted account or contract
    ///  to call `escapeHatch()` to send the ether in this contract to the 
    ///  `escapeHatchDestination` it would be ideal that `escapeHatchCaller`
    ///  cannot move funds out of `escapeHatchDestination`
    function DonationDoubler(
            Campaign _beneficiary,
            // person or legal entity that receives money or other benefits from a benefactor
            address _escapeHatchCaller,
            address _escapeHatchDestination
        )
        Escapable(_escapeHatchCaller, _escapeHatchDestination)
    {
        beneficiary = _beneficiary;
    }

    /// @notice Simple function to deposit more ETH to Double Donations
    function depositETH() payable {
        DonationDeposited4Doubling(msg.sender, msg.value);
    }

    /// @notice Donate ETH to the `beneficiary`, and if there is enough in the 
    ///  contract double it. The `msg.sender` is rewarded with Campaign tokens
    // depending on how one calls into this fallback function, i.e. with .send ( hard limit of 2300 gas ) vs .value (provides fallback with all the available gas of the caller), it may throw
    function () payable {
        uint amount;

        // When there is enough ETH in the contract to double the ETH sent
        if (this.balance >= multiply(msg.value, 2)){
            amount = multiply(msg.value, 2); // do it two it!
            // Send the ETH to the beneficiary so that they receive Campaign tokens
            if (!beneficiary.proxyPayment.value(amount)(msg.sender))
                throw;
            DonationDoubled(msg.sender, amount);
        } else {
            amount = this.balance;
            // Send the ETH to the beneficiary so that they receive Campaign tokens
            if (!beneficiary.proxyPayment.value(amount)(msg.sender))
                throw;
            DonationSentButNotDoubled(msg.sender, amount);
        }
    }

    event DonationDeposited4Doubling(address indexed sender, uint amount);
    event DonationDoubled(address indexed sender, uint amount);
    event DonationSentButNotDoubled(address indexed sender, uint amount);
}
/// @dev Finally! The main contract which doubles the amount donated.
function () payable {
    uint amount;

    // When there is enough ETH in the contract to double the ETH sent
    if (this.balance >= multiply(msg.value, 2)){
        amount = multiply(msg.value, 2); // do it two it!
        // Send the ETH to the beneficiary so that they receive Campaign tokens
        if (!beneficiary.proxyPayment.value(amount)(msg.sender))
            throw;
        DonationDoubled(msg.sender, amount);
    } else {
        amount = this.balance;
        // Send the ETH to the beneficiary so that they receive Campaign tokens
        if (!beneficiary.proxyPayment.value(amount)(msg.sender))
            throw;
        DonationSentButNotDoubled(msg.sender, amount);
    }
}

// depending on how one calls into this fallback function, i.e. with .send ( hard limit of 2300 gas ) vs .value (provides fallback with all the available gas of the caller), it may throw