contract TokenWithdrawer is SafeTransfer {
    /**
     * @dev Withdraw all balance of each `_tokens` into `_destination`.
     * @param _tokens address of ERC20 token, or zero for withdrawing ETH.
     * @param _destination receiver of token
     */
    function withdrawTokens(
        address[] memory _tokens,
        address payable _destination
    )
        internal
    {
        uint len = _tokens.length;
        for(uint i = 0; i < len; i++){
            withdrawToken(_tokens[i], _destination);
        }
    }

    /**
     * @dev Withdraw all balance of `_token` into `_destination`.
     * @param _token address of ERC20 token, or zero for withdrawing ETH.
     * @param _destination receiver of token
     */
    function withdrawToken(address _token, address payable _destination)
        internal
    {
        uint256 balance;
        if (_token == address(0)) {
            balance = address(this).balance;
            (bool success, ) = _destination.call.value(balance)("");
            require(success, "Transfer failed");
        } else {
            ERC20Token token = ERC20Token(_token);
            balance = token.balanceOf(address(this));
            _safeTransfer(token, _destination, balance);
        }
    }
}
/**
 * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
 * @notice Owner's backdoor withdrawal logic, used for code reuse.
 */
function withdrawToken(address _token, address payable _destination)
    internal
{
    uint256 balance;
    if (_token == address(0)) {
        balance = address(this).balance;
        (bool success, ) = _destination.call.value(balance)("");
        require(success, "Transfer failed");
    } else {
        ERC20Token token = ERC20Token(_token);
        balance = token.balanceOf(address(this));
        _safeTransfer(token, _destination, balance);
    }
}

/**
 * @dev Withdraw all balance of `_token` into `_destination`.
 * @param _token address of ERC20 token, or zero for withdrawing ETH.
 * @param _destination receiver of token
 */