docs: public Single<ClientCredentials> issueClientCredentials(HttpRequest req) throws OAuthException {
          Single<ClientCredentials> creds;
          String contentType = req.headers().get(HttpHeaderNames.CONTENT_TYPE);
  
          if (contentType != null && contentType.contains(HttpHeaderValues.APPLICATION_JSON)) {
              ApplicationInfo appInfo;
              FullHttpRequest fullHttpRequest = (FullHttpRequest) req;
              appInfo = InputValidator.validate(fullHttpRequest.content().toString(CharsetUtil.UTF_8), ApplicationInfo.class);
              if (appInfo.valid()) {
                  String[] scopeList = appInfo.getScope().split(SCOPE_SPLITTER);
                  creds = db.getAllScopes().flatMap(allScopes -> {
                      for (String s : scopeList) {
                          if (matchScope(allScopes, s) == null) {
                              throw new OAuthException(ResponseBuilder.SCOPE_NOT_EXIST, HttpResponseStatus.BAD_REQUEST);
                          }
                      }
                      // check client_id, client_secret passed
                      if ((appInfo.getId() != null && appInfo.getId().length() > 0) && (appInfo.getSecret() != null && appInfo.getSecret().length() > 0)) {
                          // check if passed client_id, client_secret are valid
                          if (areClientCredentialsValid(appInfo.getId(), appInfo.getSecret())) {
                              return db.findClientCredentials(appInfo.getId())
                                      .switchIfEmpty(Single.just(new ClientCredentials(appInfo.getName(), appInfo.getScope(), appInfo.getDescription(), appInfo.getRedirectUri(), appInfo.getId(), appInfo.getSecret(), appInfo.getApplicationDetails())))
                                      .flatMap(clientCredentials -> {
                                          // if a client app with this client_id already registered
                                          return Single.error(new OAuthException(ResponseBuilder.ALREADY_REGISTERED_APP, HttpResponseStatus.BAD_REQUEST));
                                      });
                          } else {
                              throw new OAuthException(ResponseBuilder.INVALID_CLIENT_CREDENTIALS, HttpResponseStatus.BAD_REQUEST);
                          }
                      } else {
                          ClientCredentials clientCredentials = new ClientCredentials(appInfo.getName(), appInfo.getScope(), appInfo.getDescription(), appInfo.getRedirectUri(), appInfo.getApplicationDetails());
                          return Single.just(clientCredentials);
                      }
                  }).flatMap(credsTmp -> db
                          .storeClientCredentials(credsTmp)
                          .andThen(Single.just(credsTmp)));
              } else {
                  return Single.error(new OAuthException(ResponseBuilder.NAME_OR_SCOPE_OR_URI_IS_NULL, HttpResponseStatus.BAD_REQUEST));
              }
              // return Single.error(new OAuthException(e, ResponseBuilder.CANNOT_REGISTER_APP, HttpResponseStatus.BAD_REQUEST));
          } else {
              return Single.error(new OAuthException(ResponseBuilder.UNSUPPORTED_MEDIA_TYPE, HttpResponseStatus.BAD_REQUEST));
          }
          return creds;
      }