@SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public void getContract(String apiOrganizationId, String apiId, String apiVersion, String apiKey, IAsyncResultHandler<ApiContract> handler) {
        String apiIndex = getApiIndex(apiOrganizationId, apiId, apiVersion);

        Future apiFuture = Future.future();
        Future clientFuture = Future.future();

        objectMap.get(apiIndex, apiFuture.completer());
        objectMap.get(apiKey, clientFuture.completer());

        CompositeFuture.all(apiFuture, clientFuture).setHandler(compositeResult -> {
            if (compositeResult.succeeded()) {
                Api api = (Api) apiFuture.result();
                Client client = (Client) clientFuture.result();

                if (api == null) {
                    Exception error = new ClientNotFoundException(Messages.i18n.format("InMemoryRegistry.NoClientForAPIKey", apiKey));
                    handler.handle(AsyncResultImpl.create(error, ApiContract.class));
                } else if (client == null) {
                    Exception error = new ApiRetiredException(Messages.i18n.format("InMemoryRegistry.ApiWasRetired",
                            apiId, apiOrganizationId));
                    handler.handle(AsyncResultImpl.create(error, ApiContract.class));
                } else {
                    Optional<Contract> matchedOpt = client.getContracts().stream()
                            .filter(contract -> contract.matches(apiOrganizationId, apiId, apiVersion))
                            .findFirst();

                    if (matchedOpt.isPresent()) {
                        Contract contract = matchedOpt.get();
                        ApiContract apiContract = new ApiContract(api, client, contract.getPlan(), contract.getPolicies());
                        handler.handle(AsyncResultImpl.create(apiContract));
                    } else {
                        Exception error = new NoContractFoundException(Messages.i18n.format("InMemoryRegistry.NoContractFound", //$NON-NLS-1$
                                client.getClientId(), api.getApiId()));
                        handler.handle(AsyncResultImpl.create(error, ApiContract.class));
                    }
                }
            } else {
                handler.handle(AsyncResultImpl.create(compositeResult.cause()));
            }
        });
    }
@author Marc Savy {@literal <marc@rhymewithgravy.com>}
gateway/engine/vertx-shareddata/src/main/java/io/apiman/gateway/engine/vertx/shareddata/SharedGlobalDataRegistry.java