interface CollectionNotificationI is IERC165 {
    /*
     *     Calculate the interface ID for ERC 165:
     *
     *     bytes4(keccak256('onContractAdded(bool)')) == 0xdaf96bfb
     *     bytes4(keccak256('onContractRemoved()')) == 0x4664c35c
     *     bytes4(keccak256('onAssetAdded(address,uint256,uint8)')) == 0x60dec1cc
     *     bytes4(keccak256('onAssetRemoved(address,uint256,uint8)')) == 0xb5ed6ea2
     *
     *     => 0xdaf96bfb ^ 0x4664c35c ^ 0x60dec1cc ^ 0xb5ed6ea2 == 0x49ae07c9
     */

    enum TokenType {
        ERC721,
        ERC1155
    }

    /**
     * @notice Notify about being added as a notification contract on the Collection
     * @dev The Collection smart contract calls this function when adding this contract
     * as a notification contract. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onContractAdded.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the Collection contract address is always the message sender.
     * @param initial This is being called in the initial constructor of the Collection
     * @return bytes4 `bytes4(keccak256("onContractAdded(bool)"))`
     */
    function onContractAdded(bool initial)
    external returns (bytes4);

    /**
     * @notice Notify about being removed as a notification contract on the Collection
     * @dev The Collection smart contract calls this function when removing this contract
     * as a notification contract. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onContractRemoved.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the Collection contract address is always the message sender.
     * @return bytes4 `bytes4(keccak256("onContractRemoved()"))`
     */
    function onContractRemoved()
    external returns (bytes4);

    /**
     * @notice Notify about adding an asset to the Collection
     * @dev The Collection smart contract calls this function when adding any asset to
     * its internal tracking of assets. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onAssetAdded.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the Collection contract address is always the message sender.
     * @param tokenAddress The address of the token contract
     * @param tokenId The token identifier which is being transferred
     * @param tokenType The type of token this asset represents (can be ERC721 or ERC1155)
     * @return bytes4 `bytes4(keccak256("onAssetAdded(address,uint256,uint8)"))`
     */
    function onAssetAdded(address tokenAddress, uint256 tokenId, TokenType tokenType)
    external returns (bytes4);

    /**
     * @notice Notify about removing an asset from the Collection
     * @dev The Collection smart contract calls this function when removing any asset from
     * its internal tracking of assets. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onAssetAdded.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the Collection contract address is always the message sender.
     * @param tokenAddress The address of the token contract
     * @param tokenId The token identifier which is being transferred
     * @param tokenType The type of token this asset represents (can be ERC721 or ERC1155)
     * @return bytes4 `bytes4(keccak256("onAssetRemoved(address,uint256,uint8)"))`
     */
    function onAssetRemoved(address tokenAddress, uint256 tokenId, TokenType tokenType)
    external returns (bytes4);
}
function onContractRemoved()
external returns (bytes4);

/**
 * @notice Notify about being removed as a notification contract on the Collection
 * @dev The Collection smart contract calls this function when removing this contract
 * as a notification contract. This function MUST return the function selector,
 * otherwise the caller will revert the transaction. The selector to be
 * returned can be obtained as `this.onContractRemoved.selector`. This
 * function MAY throw to revert and reject the transfer.
 * Note: the Collection contract address is always the message sender.
 * @return bytes4 `bytes4(keccak256("onContractRemoved()"))`
 */