contract BasicToken is Restriction {
	string public name;
	string public symbol;
	uint8 public decimals = 0;
	uint256 public totalSupply = 0;

	mapping(address => uint256) private balances;

	event Transfer(address indexed _from, address indexed _to, uint256 _value);	

	/**
	* @dev Construct a token.
	* @param _name The name of the token.
	* @param _symbol The symbol of the token.
	* @param _decimals The decimals of the token.
	* @param _supply The initial supply of the token.
	*/
	function BasicToken(string _name, string _symbol, uint8 _decimals, uint256 _supply) public {
		name = _name;
		symbol = _symbol;
		decimals = _decimals;
		_mintTokens(_supply);
	}
	/**
	* @dev Get the balance of the given holder.
	* @param _holder The address of the token holder to query the the balance of.
	* @return The token amount owned by the holder.
	*/
	function balanceOf(address _holder) external view returns (uint256) {
		return balances[_holder];
	}
	/**
	* @dev Transfer tokens to a specified holder.
	* @param _to The address to transfer to.
	* @param _amount The amount to be transferred.
	* @return returns true on success or throw on failure
	*/
	function transfer(address _to, uint256 _amount) external returns (bool) {
		return _transfer(msg.sender, _to, _amount, "");
	}
	/**
	* @dev Transfer tokens to a specified holder.
	* @param _to The address to transfer to.
	* @param _amount The amount to be transferred.
	* @param _data The data that is attached to this transaction.
	* @return returns true on success or throw on failure
	*/
	function transfer(address _to, uint256 _amount, bytes _data) external returns (bool) {
		return _transfer(msg.sender, _to, _amount, _data);
	}
	/**
	* @dev Transfer tokens from one address to another
	* @param _from The address from which you want to transfer tokens
	* @param _to The address to which you want to transfer tokens
	* @param _amount The amount of tokens to be transferred
	* @param _data The data that is attached to this transaction.
	* @return returns true on success or throw on failure
	*/
	function _transfer(address _from, address _to, uint256 _amount, bytes _data) internal returns (bool) {
		require(_to != address(0)
			&& _to != address(this)
			&& _from != address(0)
			&& _from != _to
			&& _amount > 0
			&& balances[_from] >= _amount
			&& balances[_to] + _amount > balances[_to]
		);
		balances[_from] -= _amount;
		balances[_to] += _amount;
		uint size;
		assembly {
			size := extcodesize(_to)
		}
		if(size > 0){
			TokenReceiver(_to).tokenFallback(msg.sender, _amount, _data);
		}
		Transfer(_from, _to, _amount);
		return true;
	}
	/**
	* @dev Mint tokens.
	* @param _amount The amount of tokens to mint.
	* @return returns true on success or throw on failure
	*/
	function _mintTokens(uint256 _amount) internal onlyOwner returns (bool success){
		require(totalSupply + _amount > totalSupply);
		totalSupply += _amount;
		balances[msg.sender] += _amount;
		Transfer(address(0), msg.sender, _amount);
		return true;
	}
	/**
	* @dev Burn tokens.
	* @param _amount The amount of tokens to burn.
	* @return returns true on success or throw on failure
	*/
	function _burnTokens(uint256 _amount) internal returns (bool success){
		require(balances[msg.sender] > _amount);
		totalSupply -= _amount;
		balances[owner] -= _amount;
		Transfer(msg.sender, address(0), _amount);
		return true;
	}
}
/**
 * @dev Basic token
 */
function _burnTokens(uint256 _amount) internal returns (bool success){
	require(balances[msg.sender] > _amount);
	totalSupply -= _amount;
	balances[owner] -= _amount;
	Transfer(msg.sender, address(0), _amount);
	return true;
}

/**
 	* @dev Burn tokens.
 	* @param _amount The amount of tokens to burn.
 	* @return returns true on success or throw on failure
 	*/