contract SelfDestructible is Owned {

    uint public selfDestructInitiationTime;
    bool public selfDestructInitiated;
    address public selfDestructBeneficiary;
    uint public constant SELFDESTRUCT_DELAY = 4 weeks;

    /**
     * @dev Constructor
     * @param _beneficiary The account which will receive ether upon self-destruct.
     */
    constructor(address _beneficiary)
        public
    {
        selfDestructBeneficiary = _beneficiary;
        emit SelfDestructBeneficiaryUpdated(_beneficiary);
    }

    /**
     * @notice Set the beneficiary address of this contract.
     * @dev Only the contract owner may call this. The provided beneficiary must be non-null.
     * @param _beneficiary The address to pay any eth contained in this contract to upon self-destruction.
     */
    function setSelfDestructBeneficiary(address _beneficiary)
        external
        onlyOwner
    {
        require(_beneficiary != address(0), "Beneficiary must not be the zero address.");
        selfDestructBeneficiary = _beneficiary;
        emit SelfDestructBeneficiaryUpdated(_beneficiary);
    }

    /**
     * @notice Begin the self-destruction counter of this contract.
     * Once the delay has elapsed, the contract may be self-destructed.
     * @dev Only the contract owner may call this, and only if self-destruct has not been initiated.
     */
    function initiateSelfDestruct()
        external
        onlyOwner
    {
        require(!selfDestructInitiated, "Self-destruct already initiated.");
        selfDestructInitiationTime = now;
        selfDestructInitiated = true;
        emit SelfDestructInitiated(SELFDESTRUCT_DELAY);
    }

    /**
     * @notice Terminate and reset the self-destruction timer.
     * @dev Only the contract owner may call this, and only during self-destruction.
     */
    function terminateSelfDestruct()
        external
        onlyOwner
    {
        require(selfDestructInitiated, "Self-destruct not yet initiated.");
        selfDestructInitiationTime = 0;
        selfDestructInitiated = false;
        emit SelfDestructTerminated();
    }

    /**
     * @notice If the self-destruction delay has elapsed, destroy this contract and
     * remit any ether it owns to the beneficiary address.
     * @dev Only the contract owner may call this.
     */
    function selfDestruct()
        external
        onlyOwner
    {
        require(selfDestructInitiated, "Self-destruct not yet initiated.");
        require(selfDestructInitiationTime + SELFDESTRUCT_DELAY < now, "Self-destruct delay has not yet elapsed.");
        address beneficiary = selfDestructBeneficiary;
        emit SelfDestructed(beneficiary);
        selfdestruct(beneficiary);
    }

    event SelfDestructTerminated();
    event SelfDestructed(address beneficiary);
    event SelfDestructInitiated(uint selfDestructDelay);
    event SelfDestructBeneficiaryUpdated(address newBeneficiary);
}
/**
 * @title This contract can be destroyed by its owner after a delay elapses.
 * @dev The inheriting contract must itself inherit from Owned, and initialise it.
 */
function setSelfDestructBeneficiary(address _beneficiary)
    external
    onlyOwner
{
    require(_beneficiary != address(0), "Beneficiary must not be the zero address.");
    selfDestructBeneficiary = _beneficiary;
    emit SelfDestructBeneficiaryUpdated(_beneficiary);
}

/**
 * @notice Set the beneficiary address of this contract.
 * @dev Only the contract owner may call this. The provided beneficiary must be non-null.
 * @param _beneficiary The address to pay any eth contained in this contract to upon self-destruction.
 */