contract Carati is ERC20Detailed, ERC20Mintable, ERC20Burnable, Ownable {
    constructor (string _name, string _symbol, uint8 _decimals) public
        ERC20Detailed(_name, _symbol, _decimals)
    {}

    mapping (address => uint256) public balances;

    // Overridden transfer method with _data param for transaction data (ERC223 Specification)
    function transfer(address _to, uint _value, bytes _data) public {
        uint codeLength;

        assembly {
            codeLength := extcodesize(_to)
        }

        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        // Check to see if receiver is contract
        if(codeLength>0) {
            ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
            receiver.tokenFallback(msg.sender, _value, _data);
        }
        emit Transfer(msg.sender, _to, _value);
    }
    
    // Overridden Backwards compatible transfer method without _data param (ERC223 Specification)
    function transfer(address _to, uint _value) public returns (bool) {
        uint codeLength;
        bytes memory empty;

        assembly {
            codeLength := extcodesize(_to)
        }

        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        // Check to see if receiver is contract
        if(codeLength>0) {
            ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
            receiver.tokenFallback(msg.sender, _value, empty);
        }
        emit Transfer(msg.sender, _to, _value);
    }
}
//ERC223 compatible safe token
function transfer(address _to, uint _value, bytes _data) public {
    uint codeLength;

    assembly {
        codeLength := extcodesize(_to)
    }

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    // Check to see if receiver is contract
    if(codeLength>0) {
        ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
        receiver.tokenFallback(msg.sender, _value, _data);
    }
    emit Transfer(msg.sender, _to, _value);
}

// Overridden transfer method with _data param for transaction data (ERC223 Specification)