contract AbstractToken is Token {
    using SafeMath for uint;

    /**
     * Create new Abstract Token contract.
     */
    function AbstractToken () {
        // Do nothing
    }

    /**
     * Get number of tokens currently belonging to given owner.
     *
     * @param _owner address to get number of tokens currently belonging to the owner
     * @return number of tokens currently belonging to the owner of given address
     */
    function balanceOf (address _owner) view returns (uint256 balance) {
        return accounts[_owner];
    }

    /**
     * Transfer given number of tokens from message sender to given recipient.
     *
     * @param _to address to transfer tokens to the owner of
     * @param _value number of tokens to transfer to the owner of given address
     * @return true if tokens were transferred successfully, false otherwise
     */
    function transfer (address _to, uint256 _value) returns (bool success) {
        uint256 fromBalance = accounts[msg.sender];
        if (fromBalance < _value) return false;
        if (_value > 0 && msg.sender != _to) {
            accounts[msg.sender] = fromBalance.sub(_value);
            accounts[_to] = accounts[_to].add(_value);
            Transfer(msg.sender, _to, _value);
        }
        return true;
    }

    /**
     * Transfer given number of tokens from given owner to given recipient.
     *
     * @param _from address to transfer tokens from the owner of
     * @param _to address to transfer tokens to the owner of
     * @param _value number of tokens to transfer from given owner to given recipient
     * @return true if tokens were transferred successfully, false otherwise
     */
    function transferFrom (address _from, address _to, uint256 _value) returns (bool success) {
        uint256 spenderAllowance = allowances[_from][msg.sender];
        if (spenderAllowance < _value) return false;
        uint256 fromBalance = accounts[_from];
        if (fromBalance < _value) return false;

        allowances[_from][msg.sender] = spenderAllowance.sub(_value);

        if (_value > 0 && _from != _to) {
            accounts[_from] = fromBalance.sub(_value);
            accounts[_to] = accounts[_to].add(_value);
            Transfer(_from, _to, _value);
        }
        return true;
    }

    /**
     * Allow given spender to transfer given number of tokens from message sender.
     *
     * @param _spender address to allow the owner of to transfer tokens from
     *        message sender
     * @param _value number of tokens to allow to transfer
     * @return true if token transfer was successfully approved, false otherwise
     */
    function approve (address _spender, uint256 _value) returns (bool success) {
        allowances[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);

        return true;
    }

    /**
     * Tell how many tokens given spender is currently allowed to transfer from
     * given owner.
     *
     * @param _owner address to get number of tokens allowed to be transferred from the owner
     * @param _spender address to get number of tokens allowed to be transferred by the owner
     * @return number of tokens given spender is currently allowed to transfer from given owner
     */
    function allowance (address _owner, address _spender) view returns (uint256 remaining) {
        return allowances[_owner][_spender];
    }

    /**
     * Mapping from addresses of token holders to the numbers of tokens belonging
     * to these token holders.
     */
    mapping (address => uint256) accounts;

    /**
     * Mapping from addresses of token holders to the mapping of addresses of
     * spenders to the allowances set by these token holders to these spenders.
     */
    mapping (address => mapping (address => uint256)) private allowances;
}
/**
 * Abstract Token Smart Contract that could be used as a base contract for
 * ERC-20 token contracts.
 */
function approve (address _spender, uint256 _value) returns (bool success) {
    allowances[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);

    return true;
}

/**
 * Allow given spender to transfer given number of tokens from message sender.
 *
 * @param _spender address to allow the owner of to transfer tokens from
 *        message sender
 * @param _value number of tokens to allow to transfer
 * @return true if token transfer was successfully approved, false otherwise
 */