contract ERC721Recoverable is Ownable {
    /**
     * @dev Used to recover a stuck token.
     */
    function recoverERC721(address token, address recipient, uint256 tokenId) external onlyOwner {
        return IERC721(token).transferFrom(address(this), recipient, tokenId);
    }

    /**
     * @dev Used to recover a stuck token using the safe transfer function of ERC721.
     */
    function recoverERC721Safe(address token, address recipient, uint256 tokenId) external onlyOwner {
        return IERC721(token).safeTransferFrom(address(this), recipient, tokenId);
    }

    /**
     * @dev Used to approve the recovery of a stuck token.
     */
    function recoverERC721Approve(address token, address recipient, uint256 tokenId) external onlyOwner {
        return IERC721(token).approve(recipient, tokenId);
    }

    /**
     * @dev Used to approve the recovery of stuck token, also in future.
     */
    function recoverERC721ApproveAll(address token, address recipient, bool approved) external onlyOwner {
        return IERC721(token).setApprovalForAll(recipient, approved);
    }
}
/**
 * @dev Contract module that can be used to recover ERC721 compatible tokens stuck in the contract.
 */
function recoverERC721Approve(address token, address recipient, uint256 tokenId) external onlyOwner {
    return IERC721(token).approve(recipient, tokenId);
}

/**
 * @dev Used to approve the recovery of a stuck token.
 */