class KrakenDtoUserTradeHolder extends HashMap<String, KrakenOwnTrade> {}

  @Override
  public Observable<Order> getOrderChanges(CurrencyPair currencyPair, Object... args) {
    try {
      if (!ownTradesObservableSet) {
        synchronized (this) {
          if (!ownTradesObservableSet) {
            String channelName = getChannelName(KrakenSubscriptionName.openOrders);
            ownTradesObservable =
                streamingService
                    .subscribeChannel(channelName)
                    .filter(JsonNode::isArray)
                    .filter(Objects::nonNull)
                    .map(jsonNode -> jsonNode.get(0))
                    .map(
                        jsonNode ->
                            StreamingObjectMapperHelper.getObjectMapper()
                                .treeToValue(jsonNode, KrakenDtoOrderHolder[].class))
                    .flatMapIterable(this::adaptKrakenOrders)
                    .share();

            ownTradesObservableSet = true;
          }
        }
      }
      return Observable.create(
          emit ->
              ownTradesObservable
                  .filter(
                      order ->
                          currencyPair == null
                              || order.getCurrencyPair() == null
                              || order.getCurrencyPair().compareTo(currencyPair) == 0)
                  .subscribe(emit::onNext, emit::onError, emit::onComplete));

    } catch (Exception e) {
      return Observable.error(e);
    }
  }

  private Iterable<Order> adaptKrakenOrders(KrakenDtoOrderHolder[] dtoList) {<FILL_FUNCTION_BODY>

    List<Order> result = new ArrayList<>();

    for (KrakenDtoOrderHolder dtoHolder : dtoList) {
      for (Map.Entry<String, KrakenOpenOrder> dtoOrderEntry : dtoHolder.entrySet()) {
        String orderId = dtoOrderEntry.getKey();
        KrakenOpenOrder dto = dtoOrderEntry.getValue();
        KrakenOpenOrder.KrakenDtoDescr descr = dto.descr;

        CurrencyPair pair = descr == null ? null : new CurrencyPair(descr.pair);
        Order.OrderType side =
            descr == null ? null : KrakenAdapters.adaptOrderType(KrakenType.fromString(descr.type));
        String orderType = (descr == null || descr.ordertype == null) ? null : descr.ordertype;

        Order.Builder builder;
        if ("limit".equals(orderType))
          builder = new LimitOrder.Builder(side, pair).limitPrice(descr.price);
        else if ("stop".equals(orderType))
          builder =
              new StopOrder.Builder(side, pair).limitPrice(descr.price).stopPrice(descr.price2);
        else if ("market".equals(orderType)) builder = new MarketOrder.Builder(side, pair);
        else // this is an order update (not the full order, it may only update one field)
        builder = new MarketOrder.Builder(side, pair);

        result.add(
            builder
                .id(orderId)
                .originalAmount(dto.vol)
                .cumulativeAmount(dto.vol_exec)
                .averagePrice(dto.avg_price)
                .orderStatus(
                    dto.status == null
                        ? null
                        : KrakenAdapters.adaptOrderStatus(KrakenOrderStatus.fromString(dto.status)))
                .timestamp(dto.opentm == null ? null : new Date((long) (dto.opentm * 1000L)))
                .fee(dto.fee)
                .flags(adaptFlags(dto.oflags))
                .userReference(dto.userref == null ? null : Integer.toString(dto.userref))
                .build());
      }
    }
    return result;
  
<no_super_class>