contract TestToken {

    mapping (address => uint256) public balances;
    string private _nextTransferRevertReason;
    bytes private _nextTransferReturnData;

    /// @dev Just calls `raiseTokenTransfer()` on the caller.
    function transfer(address to, uint256 amount)
        external
        returns (bool)
    {
        TestEvents(msg.sender).raiseTokenTransfer(msg.sender, to, amount);
        if (bytes(_nextTransferRevertReason).length != 0) {
            revert(_nextTransferRevertReason);
        }
        bytes memory returnData = _nextTransferReturnData;
        assembly { return(add(returnData, 0x20), mload(returnData)) }
    }

    /// @dev Set the balance for `owner`.
    function setBalance(address owner, uint256 balance)
        external
    {
        balances[owner] = balance;
    }

    /// @dev Set the behavior of the `transfer()` call.
    function setTransferBehavior(
        string calldata revertReason,
        bytes calldata returnData
    )
        external
    {
        _nextTransferRevertReason = revertReason;
        _nextTransferReturnData = returnData;
    }

    /// @dev Just calls `raiseTokenApprove()` on the caller.
    function approve(address spender, uint256 allowance)
        external
        returns (bool)
    {
        TestEvents(msg.sender).raiseTokenApprove(spender, allowance);
        return true;
    }

    /// @dev Retrieve the balance for `owner`.
    function balanceOf(address owner)
        external
        view
        returns (uint256)
    {
        return balances[owner];
    }
}
/// @dev A minimalist ERC20 token.
function transfer(address to, uint256 amount)
    external
    returns (bool)
{
    TestEvents(msg.sender).raiseTokenTransfer(msg.sender, to, amount);
    if (bytes(_nextTransferRevertReason).length != 0) {
        revert(_nextTransferRevertReason);
    }
    bytes memory returnData = _nextTransferReturnData;
    assembly { return(add(returnData, 0x20), mload(returnData)) }
}

/// @dev Just calls `raiseTokenTransfer()` on the caller.