contract ERC223Token is ERC223, StandardToken {
	using SafeMath for uint256;

	/**
	 * @dev Function that is called when a user or another contract wants to transfer funds .
	 * This is method where you can supply fallback function name and that function will be triggered.
	 * This method is added as part of ERC23 standard
	 *
	 * @param _to The address which will receive the tokens.
	 * @param _value Amount of tokens received.
	 * @param _data Data sent along with transfer request.
	 * @param _custom_fallback Name of the method which should be called after transfer happens. If this method does not exists on contract then transaction will fail
	 */
	function transfer(address _to, uint256 _value, bytes _data, string _custom_fallback) public returns (bool success) {
		// check if receiving is contract
		if(isContract(_to)) {
			// validate the address and balance
			require(_to != address(0));
			require(_value <= balances[msg.sender]);

			// SafeMath.sub will throw if there is not enough balance.
			balances[msg.sender] = balances[msg.sender].sub(_value);
			balances[_to] = balances[_to].add(_value);
	
			// invoke custom fallback function			
			assert(_to.call.value(0)(bytes4(keccak256(_custom_fallback)), msg.sender, _value, _data));
			Transfer(msg.sender, _to, _value, _data);
			return true;
		}
		else {
			// receiver is not a contract so perform normal transfer to address
			return transferToAddress(_to, _value, _data);
		}
	}
  

	/**
	 * @dev Function that is called when a user or another contract wants to transfer funds .
	 * You can pass extra data which can be tracked in event.
	 * This method is added as part of ERC23 standard
	 *
	 * @param _to The address which will receive the tokens.
	 * @param _value Amount of tokens received.
	 * @param _data Data sent along with transfer request.
	 */
	function transfer(address _to, uint256 _value, bytes _data) public returns (bool success) {
		// check if receiver is contract address
		if(isContract(_to)) {
			// invoke transfer request to contract
			return transferToContract(_to, _value, _data);
		}
		else {
			// invoke transfer request to normal user wallet address
			return transferToAddress(_to, _value, _data);
		}
	}
  
	/**
	 * @dev Standard function transfer similar to ERC20 transfer with no _data .
	 * Added due to backwards compatibility reasons .
	 *
	 * @param _to The address which will receive the tokens.
	 * @param _value Amount of tokens received.
	 */
	function transfer(address _to, uint256 _value) public returns (bool success) {
		//standard function transfer similar to ERC20 transfer with no _data
		//added due to backwards compatibility reasons
		bytes memory empty;

		// check if receiver is contract address
		if(isContract(_to)) {
			// invoke transfer request to contract
			return transferToContract(_to, _value, empty);
		}
		else {
			// invoke transfer request to normal user wallet address
			return transferToAddress(_to, _value, empty);
		}
	}

	/**
	 * @dev assemble the given address bytecode. If bytecode exists then the _addr is a contract.
	 *
	 * @param _addr The address which need to be checked if contract address or wallet address
	 */
	function isContract(address _addr) private view returns (bool is_contract) {
		uint256 length;
		assembly {
			//retrieve the size of the code on target address, this needs assembly
			length := extcodesize(_addr)
		}
		return (length > 0);
	}

	/**
	 * @dev Function that is called when transaction target is an address. This is private method.
	 *
	 * @param _to The address which will receive the tokens.
	 * @param _value Amount of tokens received.
	 * @param _data Data sent along with transfer request.
	 */
	function transferToAddress(address _to, uint256 _value, bytes _data) private returns (bool success) {
		// validate the address and balance
		require(_to != address(0));
		require(_value <= balances[msg.sender]);

		// SafeMath.sub will throw if there is not enough balance.
		balances[msg.sender] = balances[msg.sender].sub(_value);
		balances[_to] = balances[_to].add(_value);

		// Log the transfer event
		Transfer(msg.sender, _to, _value, _data);
		return true;
	}
  
	/**
	 * @dev Function that is called when transaction target is a contract. This is private method.
	 *
	 * @param _to The address which will receive the tokens.
	 * @param _value Amount of tokens received.
	 * @param _data Data sent along with transfer request.
	 */
	function transferToContract(address _to, uint256 _value, bytes _data) private returns (bool success) {
		// validate the address and balance
		require(_to != address(0));
		require(_value <= balances[msg.sender]);

		// SafeMath.sub will throw if there is not enough balance.
		balances[msg.sender] = balances[msg.sender].sub(_value);
		balances[_to] = balances[_to].add(_value);

		// call fallback function of contract
		ERC223Receiver receiver = ERC223Receiver(_to);
		receiver.tokenFallback(msg.sender, _value, _data);
		
		// Log the transfer event
		Transfer(msg.sender, _to, _value, _data);
		return true;
	}
}
/**
 * @title Standard ERC223Token token
 *
 * @dev Implementation of the ERC23 token.
 * @dev https://github.com/ethereum/EIPs/issues/223
 */
function transfer(address _to, uint256 _value) public returns (bool success) {
	//standard function transfer similar to ERC20 transfer with no _data
	//added due to backwards compatibility reasons
	bytes memory empty;

	// check if receiver is contract address
	if(isContract(_to)) {
		// invoke transfer request to contract
		return transferToContract(_to, _value, empty);
	}
	else {
		// invoke transfer request to normal user wallet address
		return transferToAddress(_to, _value, empty);
	}
}

/**
 	 * @dev Standard function transfer similar to ERC20 transfer with no _data .
 	 * Added due to backwards compatibility reasons .
 	 *
 	 * @param _to The address which will receive the tokens.
 	 * @param _value Amount of tokens received.
 	 */