abstract contract ERC677Token is ERC677 {
    /**
    * @dev transfer token to a contract address with additional data if the recipient is a contact.
    * @param _to The address to transfer to.
    * @param _value The amount to be transferred.
    * @param _data The extra data to be passed to the receiving contract.
    */
    function transferAndCall(address _to, uint _value, bytes memory _data)
        public
        override
        returns (bool success)
    {
        transfer(_to, _value);
        // emit Transfer(msg.sender, _to, _value, _data);
        if (isContract(_to)) {
            contractFallback(_to, _value, _data);
        }
        return true;
    }

    function contractFallback(address _to, uint _value, bytes memory _data)
        private
    {
        ERC677Receiver receiver = ERC677Receiver(_to);
        receiver.onTokenTransfer(msg.sender, _value, _data);
    }

    function isContract(address _addr)
        private
        view
        returns (bool hasCode)
    {
        uint length;
        // solhint-disable-next-line no-inline-assembly
        assembly { length := extcodesize(_addr) }
        return length > 0;
    }
}
function transferAndCall(address _to, uint _value, bytes memory _data)
    public
    override
    returns (bool success)
{
    transfer(_to, _value);
    // emit Transfer(msg.sender, _to, _value, _data);
    if (isContract(_to)) {
        contractFallback(_to, _value, _data);
    }
    return true;
}

/**
 * @dev transfer token to a contract address with additional data if the recipient is a contact.
 * @param _to The address to transfer to.
 * @param _value The amount to be transferred.
 * @param _data The extra data to be passed to the receiving contract.
 */