@SuppressWarnings("boxing")
  @Override
  public <T> Subscription<T> open(
      Class<T> clazz, final long id, final SubscriptionConnectionOptions options, String database)
      throws SubscriptionException {
    if (options == null) {
      throw new IllegalArgumentException("Cannot open a subscription if options are null");
    }

    if (options.getBatchOptions() == null) {
      throw new IllegalArgumentException("Cannot open a subscription if batch options are null");
    }

    if (options.getBatchOptions().getMaxSize() != null
        && options.getBatchOptions().getMaxSize() < 16 * 1024) {
      throw new IllegalArgumentException(
          "Max size value of batch options cannot be lower than that 16 KB");
    }

    final IDatabaseCommands commands =
        database == null
            ? documentStore.getDatabaseCommands()
            : documentStore.getDatabaseCommands().forDatabase(database);

    boolean open = true;
    try {

      sendOpenSubscriptionRequest(commands, id, options);
    } catch (SubscriptionException subscriptionException) {
      if (options.getStrategy() != SubscriptionOpeningStrategy.WAIT_FOR_FREE
          || !(subscriptionException instanceof SubscriptionInUseException)) {
        throw subscriptionException;
      }
      open = false;
    }

    Subscription<T> subscription =
        new Subscription<>(
            clazz,
            id,
            Lang.coalesce(database, MultiDatabase.getDatabaseName(documentStore.getUrl())),
            options,
            commands,
            documentStore.changes(database),
            documentStore.getConventions(),
            open,
            new Action0() {
              @SuppressWarnings("synthetic-access")
              @Override
              public void apply() {
                sendOpenSubscriptionRequest(
                    commands, id,
                    options); // to ensure that subscription is open try to call it with the same
                              // connection id
              }
            });

    subscriptions.add(subscription);
    return subscription;
  }
 @SuppressWarnings("boxing")
 private static void sendOpenSubscriptionRequest(
     IDatabaseCommands commands, long id, SubscriptionConnectionOptions options)
     throws SubscriptionException {
   try (HttpJsonRequest request =
       commands.createRequest(
           HttpMethods.POST,
           String.format(
               "/subscriptions/open?id=%d&connection=%s", id, options.getConnectionId()))) {
     request.write(options.toRavenObject().toString());
     request.executeRequest();
   } catch (Exception e) {
     SubscriptionException subscriptionException = tryGetSubscriptionException(e);
     if (subscriptionException != null) {
       throw subscriptionException;
     }
     throw e;
   }
 }