private byte[] synchronousRequest(
      ConnectorSession session, ConnectorProducer producer, ConnectorMessage m)
      throws BCSAPIException {
    ConnectorTemporaryQueue answerQueue = null;
    try {
      answerQueue = session.createTemporaryQueue();
      m.setReplyTo(answerQueue);

      try (ConnectorConsumer consumer = session.createConsumer(answerQueue)) {
        producer.send(m);
        ConnectorMessage reply = consumer.receive(clientSettings.getTimeout());
        if (reply == null) {
          throw new BCSAPIException("timeout");
        }
        return reply.getPayload();
      }
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    } finally {
      try {
        if (answerQueue != null) {
          answerQueue.delete();
        }
      } catch (ConnectorException e) {
      }
    }
  }
  @Override
  public void spendingTransactions(List<TID> tids, final TransactionListener listener)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer scanAccountProducer =
          session.createProducer(session.createQueue("spendingTransactions"));
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      for (TID tid : tids) {
        builder.addHash(ByteString.copyFrom(tid.unsafeGetArray()));
      }
      m.setPayload(builder.build().toByteArray());

      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for spendingt ransactions request", e);
            }
          });

      scanAccountProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }
  private void scanRequest(
      Collection<Script> match, final TransactionListener listener, String requestQueue)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer exactMatchProducer =
          session.createProducer(session.createQueue(requestQueue));
      BCSAPIMessage.ExactMatchRequest.Builder builder =
          BCSAPIMessage.ExactMatchRequest.newBuilder();
      for (Script d : match) {
        builder.addMatch(ByteString.copyFrom(d.toByteArray()));
      }
      m.setPayload(builder.build().toByteArray());
      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for scan matching transactions", e);
            }
          });

      exactMatchProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }
  private void scanRequest(
      MasterPublicKey master, int lookAhead, final TransactionListener listener, String request)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer scanAccountProducer = session.createProducer(session.createQueue(request));
      BCSAPIMessage.AccountRequest.Builder builder = BCSAPIMessage.AccountRequest.newBuilder();
      builder.setPublicKey(master.serialize(true));
      builder.setLookAhead(lookAhead);
      m.setPayload(builder.build().toByteArray());

      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for account scan transactions", e);
            }
          });

      scanAccountProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }