contract BasicToken is ERC20Basic {
    using SafeMath for uint256;

    uint256 totalSupply_;

    mapping(address => uint256) balances;
    mapping(address => uint256) lockedBalanceMap;    // locked balance: address => amount
    mapping(address => uint256) releaseTimeMap;      // release time: address => timestamp

    event BalanceLocked(address indexed _addr, uint256 _amount);


    /**
    * @dev total number of tokens in existence
    */
    function totalSupply() public view returns (uint256) {
        return totalSupply_;
    }

    /**
     * @dev function to make sure the balance is not locked
     * @param _addr address
     * @param _value uint256
     */
    function checkNotLocked(address _addr, uint256 _value) internal view returns (bool) {
        uint256 balance = balances[_addr].sub(_value);
        if (releaseTimeMap[_addr] > block.timestamp && balance < lockedBalanceMap[_addr]) {
            revert();
        }
        return true;
    }

    /**
     * @dev transfer token for a specified address
     * @param _to The address to transfer to.
     * @param _value The amount to be transferred.
     */
    function transfer(address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
        require(_value <= balances[msg.sender]);

        checkNotLocked(msg.sender, _value);

        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        emit Transfer(msg.sender, _to, _value);
        return true;
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param _owner The address to query the the balance of.
     * @return Amount.
     */
    function balanceOf(address _owner) public view returns (uint256) {
        return balances[_owner];
    }

    /**
     * @dev Gets the locked balance of the specified address.
     * @param _owner The address to query.
     * @return Amount.
     */
    function lockedBalanceOf(address _owner) public view returns (uint256) {
        return lockedBalanceMap[_owner];
    }

    /**
     * @dev Gets the release timestamp of the specified address if it has a locked balance.
     * @param _owner The address to query.
     * @return Timestamp.
     */
    function releaseTimeOf(address _owner) public view returns (uint256) {
        return releaseTimeMap[_owner];
    }
}
/**
 * @title Basic token, Lockable
 * @dev Basic version of StandardToken, with no allowances.
 */
function releaseTimeOf(address _owner) public view returns (uint256) {
    return releaseTimeMap[_owner];
}

/**
 * @dev Gets the release timestamp of the specified address if it has a locked balance.
 * @param _owner The address to query.
 * @return Timestamp.
 */