// Contract: DelegationManagementContract
// Target function: function checkConsolidationStatus(address _wallet1, address _wallet2, address _collectionAddress) public view returns (bool)
w].delegationAddress;
                        allExpirations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].expiryDate;
                        allTokens[count2] = globalDelegationHashes[allGlobalHashes[y]][w].allTokens;
                        tokensIDs[count2] = globalDelegationHashes[allGlobalHashes[y]][w].tokens;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            return (allDelegationAddresses, allExpirations, allTokens, tokensIDs);
        } else {
            address[] memory allDelegations1 = new address[](0);
            uint256[] memory tokensIDs = new uint256[](0);
            bool[] memory allTokens = new bool[](0);
            uint256[] memory allExpirations = new uint256[](0);
            return (allDelegations1, allExpirations, allTokens, tokensIDs);
        }
    }

    /**
     * @notice Returns an array of all active delegation addresses on a certain date for a specific use case on a specific NFT collection given a delegation Address
     */

    function retrieveActiveDelegations(address _delegatorAddress, address _collectionAddress, uint256 _date, uint256 _useCase) public view returns (address[] memory) {
        address[] memory allDelegations = retrieveDelegationAddresses(_delegatorAddress, _collectionAddress, _useCase);
        bytes32 globalHash;
        bytes32[] memory allGlobalHashes = new bytes32[](allDelegations.length);
        uint256 count1 = 0;
        uint256 count2 = 0;
        uint256 count3 = 0;
        uint256 k = 0;
        if (allDelegations.length > 0) {
            for (uint256 i = 0; i < allDelegations.length; ) {
                globalHash = keccak256(abi.encodePacked(_delegatorAddress, _collectionAddress, allDelegations[i], _useCase));
                allGlobalHashes[count1] = globalHash;
                count1 = count1 + 1;

                unchecked {
                    ++i;
                }
            }
            //Remove duplicates
            for (uint256 i = 0; i < allGlobalHashes.length - 1; ) {
                for (uint256 j = i + 1; j < allGlobalHashes.length; ) {
                    if (allGlobalHashes[i] == allGlobalHashes[j]) {
                        delete allGlobalHashes[i];
                    }

                    unchecked {
                        ++j;
                    }
                }

                unchecked {
                    ++i;
                }
            }
            for (uint256 i = 0; i < allGlobalHashes.length; ) {
                k = globalDelegationHashes[allGlobalHashes[i]].length + k;

                unchecked {
                    ++i;
                }
            }
            //Declare local arrays
            address[] memory allDelegationAddresses = new address[](k);
            uint256[] memory allExpirations = new uint256[](k);
            for (uint256 y = 0; y < k; ) {
                if (globalDelegationHashes[allGlobalHashes[y]].length > 0) {
                    for (uint256 w = 0; w < globalDelegationHashes[allGlobalHashes[y]].length; ) {
                        allDelegationAddresses[count2] = globalDelegationHashes[allGlobalHashes[y]][w].delegationAddress;
                        allExpirations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].expiryDate;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            address[] memory allActive = new address[](allExpirations.length);
            for (uint256 y = 0; y < k; ) {
                if (allExpirations[y] > _date) {
                    allActive[count3] = allDelegationAddresses[y];
                    count3 = count3 + 1;
                }

                unchecked {
                    ++y;
                }
            }
            return (allActive);
        } else {
            address[] memory allActive = new address[](0);
            return (allActive);
        }
    }

    /**
     * @notice Returns the most recent delegation address delegated for a specific use case on a specific NFT collection
     */

    function retrieveMostRecentDelegation(address _delegatorAddress, address _collectionAddress, uint256 _useCase) public view returns (address) {
        address[] memory allDelegations = retrieveDelegationAddresses(_delegatorAddress, _collectionAddress, _useCase);
        bytes32 globalHash;
        bytes32[] memory allGlobalHashes = new bytes32[](allDelegations.length);
        uint256 count1 = 0;
        uint256 count2 = 0;
        uint256 k = 0;
        if (allDelegations.length > 0) {
            for (uint256 i = 0; i < allDelegations.length; ) {
                globalHash = keccak256(abi.encodePacked(_delegatorAddress, _collectionAddress, allDelegations[i], _useCase));
                allGlobalHashes[count1] = globalHash;
                count1 = count1 + 1;

                unchecked {
                    ++i;
                }
            }
            //Removes duplicates
            for (uint256 i = 0; i < allGlobalHashes.length - 1; ) {
                for (uint256 j = i + 1; j < allGlobalHashes.length; ) {
                    if (allGlobalHashes[i] == allGlobalHashes[j]) {
                        delete allGlobalHashes[i];
                    }

                    unchecked {
                        ++j;
                    }
                }

                unchecked {
                    ++i;
                }
            }
            for (uint256 i = 0; i < allGlobalHashes.length; ) {
                k = globalDelegationHashes[allGlobalHashes[i]].length + k;

                unchecked {
                    ++i;
                }
            }
            //Declare local arrays
            address[] memory allDelegationAddresses = new address[](k);
            uint256[] memory allRegistrations = new uint256[](k);
            for (uint256 y = 0; y < k; ) {
                if (globalDelegationHashes[allGlobalHashes[y]].length > 0) {
                    for (uint256 w = 0; w < globalDelegationHashes[allGlobalHashes[y]].length; ) {
                        allDelegationAddresses[count2] = globalDelegationHashes[allGlobalHashes[y]][w].delegationAddress;
                        allRegistrations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].registeredDate;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            address recentDelegationAddress = allDelegationAddresses[0];
            uint256 time = allRegistrations[0];
            for (uint256 i = 0; i < allDelegationAddresses.length; ) {
                if (allRegistrations[i] >= time) {
                    time = allRegistrations[i];
                    recentDelegationAddress = allDelegationAddresses[i];
                }

                unchecked {
                    ++i;
                }
            }
            return (recentDelegationAddress);
        } else {
            return (0x0000000000000000000000000000000000000000);
        }
    }

    // Retrieve Delegators delegated to a hot wallet
    // This set of functions is used to retrieve info for a hot wallet

    /**
     * @notice Returns an array of all token ids delegated by a Delegator for a specific usecase on specific collection given a delegation Address
     */

    function retrieveDelegatorsTokensIDsandExpiredDates(address _delegationAddress, address _collectionAddress, uint256 _useCase) public view returns (address[] memory, uint256[] memory, bool[] memory, uint256[] memory) {
        address[] memory allDelegators = retrieveDelegators(_delegationAddress, _collectionAddress, _useCase);
        bytes32 globalHash;
        bytes32[] memory allGlobalHashes = new bytes32[](allDelegators.length);
        uint256 count1 = 0;
        uint256 count2 = 0;
        uint256 k = 0;
        if (allDelegators.length > 0) {
            for (uint256 i = 0; i < allDelegators.length; ) {
                globalHash = keccak256(abi.encodePacked(allDelegators[i], _collectionAddress, _delegationAddress, _useCase));
                allGlobalHashes[count1] = globalHash;
                count1 = count1 + 1;

                unchecked {
                    ++i;
                }
            }
            //Removes duplicates
            for (uint256 i = 0; i < allGlobalHashes.length - 1; ) {
                for (uint256 j = i + 1; j < allGlobalHashes.length; ) {
                    if (allGlobalHashes[i] == allGlobalHashes[j]) {
                        delete allGlobalHashes[i];
                    }

                    unchecked {
                        ++j;
                    }
                }

                unchecked {
                    ++i;
                }
            }
            for (uint256 i = 0; i < allGlobalHashes.length; ) {
                k = globalDelegationHashes[allGlobalHashes[i]].length + k;

                unchecked {
                    ++i;
                }
            }
            //Declare local arrays
            address[] memory allDelegatorsAddresses = new address[](k);
            uint256[] memory tokensIDs = new uint256[](k);
            bool[] memory allTokens = new bool[](k);
            uint256[] memory allExpirations = new uint256[](k);
            for (uint256 y = 0; y < k; ) {
                if (globalDelegationHashes[allGlobalHashes[y]].length > 0) {
                    for (uint256 w = 0; w < globalDelegationHashes[allGlobalHashes[y]].length; ) {
                        allDelegatorsAddresses[count2] = globalDelegationHashes[allGlobalHashes[y]][w].delegatorAddress;
                        allExpirations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].expiryDate;
                        allTokens[count2] = globalDelegationHashes[allGlobalHashes[y]][w].allTokens;
                        tokensIDs[count2] = globalDelegationHashes[allGlobalHashes[y]][w].tokens;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            return (allDelegatorsAddresses, allExpirations, allTokens, tokensIDs);
        } else {
            address[] memory allDelegations1 = new address[](0);
            uint256[] memory tokensIDs = new uint256[](0);
            bool[] memory allTokens = new bool[](0);
            uint256[] memory allExpirations = new uint256[](0);
            return (allDelegations1, allExpirations, allTokens, tokensIDs);
        }
    }

    /**
     * @notice Returns an array of all active delegators on a certain date for a specific use case on a specific NFT collection given a delegation Address
     */

    function retrieveActiveDelegators(address _delegationAddress, address _collectionAddress, uint256 _date, uint256 _useCase) public view returns (address[] memory) {
        address[] memory allDelegators = retrieveDelegators(_delegationAddress, _collectionAddress, _useCase);
        bytes32 globalHash;
        bytes32[] memory allGlobalHashes = new bytes32[](allDelegators.length);
        uint256 count1 = 0;
        uint256 count2 = 0;
        uint256 count3 = 0;
        uint256 k = 0;
        if (allDelegators.length > 0) {
            for (uint256 i = 0; i < allDelegators.length; ) {
                globalHash = keccak256(abi.encodePacked(allDelegators[i], _collectionAddress, _delegationAddress, _useCase));
                allGlobalHashes[count1] = globalHash;
                count1 = count1 + 1;

                unchecked {
                    ++i;
                }
            }
            //Remove duplicates
            for (uint256 i = 0; i < allGlobalHashes.length - 1; ) {
                for (uint256 j = i + 1; j < allGlobalHashes.length; ) {
                    if (allGlobalHashes[i] == allGlobalHashes[j]) {
                        delete allGlobalHashes[i];
                    }

                    unchecked {
                        ++j;
                    }
                }

                unchecked {
                    ++i;
                }
            }
            for (uint256 i = 0; i < allGlobalHashes.length; ) {
                k = globalDelegationHashes[allGlobalHashes[i]].length + k;

                unchecked {
                    ++i;
                }
            }
            //Declare local arrays
            address[] memory allDelegatorsAddresses = new address[](k);
            uint256[] memory allExpirations = new uint256[](k);
            for (uint256 y = 0; y < k; ) {
                if (globalDelegationHashes[allGlobalHashes[y]].length > 0) {
                    for (uint256 w = 0; w < globalDelegationHashes[allGlobalHashes[y]].length; ) {
                        allDelegatorsAddresses[count2] = globalDelegationHashes[allGlobalHashes[y]][w].delegatorAddress;
                        allExpirations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].expiryDate;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            address[] memory allActive = new address[](allExpirations.length);
            for (uint256 y = 0; y < k; ) {
                if (allExpirations[y] > _date) {
                    allActive[count3] = allDelegatorsAddresses[y];
                    count3 = count3 + 1;
                }

                unchecked {
                    ++y;
                }
            }
            return (allActive);
        } else {
            address[] memory allActive = new address[](0);
            return (allActive);
        }
    }

    /**
     * @notice Returns the most recent delegator for a specific use case on a specific NFT collection given a delegation Address
     */

    function retrieveMostRecentDelegator(address _delegationAddress, address _collectionAddress, uint256 _useCase) public view returns (address) {
        address[] memory allDelegators = retrieveDelegators(_delegationAddress, _collectionAddress, _useCase);
        bytes32 globalHash;
        bytes32[] memory allGlobalHashes = new bytes32[](allDelegators.length);
        uint256 count1 = 0;
        uint256 count2 = 0;
        uint256 k = 0;
        if (allDelegators.length > 0) {
            for (uint256 i = 0; i < allDelegators.length; ) {
                globalHash = keccak256(abi.encodePacked(allDelegators[i], _collectionAddress, _delegationAddress, _useCase));
                allGlobalHashes[count1] = globalHash;
                count1 = count1 + 1;

                unchecked {
                    ++i;
                }
            }
            //Removes duplicates
            for (uint256 i = 0; i < allGlobalHashes.length - 1; ) {
                for (uint256 j = i + 1; j < allGlobalHashes.length; ) {
                    if (allGlobalHashes[i] == allGlobalHashes[j]) {
                        delete allGlobalHashes[i];
                    }

                    unchecked {
                        ++j;
                    }
                }

                unchecked {
                    ++i;
                }
            }
            for (uint256 i = 0; i < allGlobalHashes.length; ) {
                k = globalDelegationHashes[allGlobalHashes[i]].length + k;

                unchecked {
                    ++i;
                }
            }
            //Declare local arrays
            address[] memory allDelegatorsAddresses = new address[](k);
            uint256[] memory allRegistrations = new uint256[](k);
            for (uint256 y = 0; y < k; ) {
                if (globalDelegationHashes[allGlobalHashes[y]].length > 0) {
                    for (uint256 w = 0; w < globalDelegationHashes[allGlobalHashes[y]].length; ) {
                        allDelegatorsAddresses[count2] = globalDelegationHashes[allGlobalHashes[y]][w].delegatorAddress;
                        allRegistrations[count2] = globalDelegationHashes[allGlobalHashes[y]][w].registeredDate;
                        count2 = count2 + 1;

                        unchecked {
                            ++w;
                        }
                    }
                }

                unchecked {
                    ++y;
                }
            }
            address recentDelegatorAddress = allDelegatorsAddresses[0];
            uint256 time = allRegistrations[0];
            for (uint256 i = 0; i < allDelegatorsAddresses.length; ) {
                if (allRegistrations[i] >= time) {
                    time = allRegistrations[i];
                    recentDelegatorAddress = allDelegatorsAddresses[i];
                }

                unchecked {
                    ++i;
                }
            }
            return (recentDelegatorAddress);
        } else {
            return (0x0000000000000000000000000000000000000000);
        }
    }