contract TrustedIssuersRegistry is ITrustedIssuersRegistry, Ownable {

    /// Array containing all TrustedIssuers identity contract address.
    IClaimIssuer[] private trustedIssuers;

    /// Mapping between a trusted issuer index and its corresponding claimTopics.
    mapping(address => uint[]) private trustedIssuerClaimTopics;

   /**
    *  @dev See {ITrustedIssuersRegistry-addTrustedIssuer}.
    */
    function addTrustedIssuer(IClaimIssuer _trustedIssuer, uint[] calldata _claimTopics) external override onlyOwner {
        require(trustedIssuerClaimTopics[address(_trustedIssuer)].length == 0, "trusted Issuer already exists");
        require(_claimTopics.length > 0, "trusted claim topics cannot be empty");
        trustedIssuers.push(_trustedIssuer);
        trustedIssuerClaimTopics[address(_trustedIssuer)] = _claimTopics;
        emit TrustedIssuerAdded(_trustedIssuer, _claimTopics);
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-removeTrustedIssuer}.
    */
    function removeTrustedIssuer(IClaimIssuer _trustedIssuer) external override onlyOwner {
        require(trustedIssuerClaimTopics[address(_trustedIssuer)].length != 0, "trusted Issuer doesn't exist");
        uint length = trustedIssuers.length;
        for (uint i = 0; i < length; i++) {
            if (trustedIssuers[i] == _trustedIssuer) {
                delete trustedIssuers[i];
                trustedIssuers[i] = trustedIssuers[length - 1];
                delete trustedIssuers[length - 1];
                trustedIssuers.pop();
                break;
            }
        }
        delete trustedIssuerClaimTopics[address(_trustedIssuer)];
        emit TrustedIssuerRemoved(_trustedIssuer);
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-updateIssuerClaimTopics}.
    */
    function updateIssuerClaimTopics(IClaimIssuer _trustedIssuer, uint[] calldata _claimTopics) external override onlyOwner {
        require(trustedIssuerClaimTopics[address(_trustedIssuer)].length != 0, "trusted Issuer doesn't exist");
        require(_claimTopics.length > 0, "claim topics cannot be empty");
        trustedIssuerClaimTopics[address(_trustedIssuer)] = _claimTopics;
        emit ClaimTopicsUpdated(_trustedIssuer, _claimTopics);
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-getTrustedIssuers}.
    */
    function getTrustedIssuers() external override view returns (IClaimIssuer[] memory) {
        return trustedIssuers;
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-isTrustedIssuer}.
    */
    function isTrustedIssuer(address _issuer) external override view returns (bool) {
        uint length = trustedIssuers.length;
        for (uint i = 0; i < length; i++) {
            if (address(trustedIssuers[i]) == _issuer) {
                return true;
            }
        }
        return false;
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-getTrustedIssuerClaimTopics}.
    */
    function getTrustedIssuerClaimTopics(IClaimIssuer _trustedIssuer) external override view returns (uint[] memory) {
        require(trustedIssuerClaimTopics[address(_trustedIssuer)].length != 0, "trusted Issuer doesn't exist");
        return trustedIssuerClaimTopics[address(_trustedIssuer)];
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-hasClaimTopic}.
    */
    function hasClaimTopic(address _issuer, uint _claimTopic) external override view returns (bool) {
        uint length = trustedIssuerClaimTopics[_issuer].length;
        uint[] memory claimTopics = trustedIssuerClaimTopics[_issuer];
        for (uint i = 0; i < length; i++) {
            if (claimTopics[i] == _claimTopic) {
                return true;
            }
        }
        return false;
    }

   /**
    *  @dev See {ITrustedIssuersRegistry-transferOwnershipOnIssuersRegistryContract}.
    */
    function transferOwnershipOnIssuersRegistryContract(address _newOwner) external override onlyOwner {
        transferOwnership(_newOwner);
    }
}
function isTrustedIssuer(address _issuer) external override view returns (bool) {
    uint length = trustedIssuers.length;
    for (uint i = 0; i < length; i++) {
        if (address(trustedIssuers[i]) == _issuer) {
            return true;
        }
    }
    return false;
}

/**
 *  @dev See {ITrustedIssuersRegistry-isTrustedIssuer}.
 */