/**
   * @param idx Index.
   * @return Conflict TTL.
   */
  public long conflictTtl(int idx) {
    if (conflictTtls != null) {
      assert idx >= 0 && idx < conflictTtls.size();

      return conflictTtls.get(idx);
    }

    return CU.TTL_NOT_CHANGED;
  }
  /**
   * @param idx Index.
   * @return Conflict expire time.
   */
  public long conflictExpireTime(int idx) {
    if (conflictExpireTimes != null) {
      assert idx >= 0 && idx < conflictExpireTimes.size();

      return conflictExpireTimes.get(idx);
    }

    return CU.EXPIRE_TIME_CALCULATE;
  }
    /**
     * Add continuous entry.
     *
     * @param e Cache continuous query entry.
     * @return Collection entries which will be fired.
     */
    public CacheContinuousQueryEntry handle(CacheContinuousQueryEntry e) {
      assert e != null;

      if (e.isFiltered()) {
        Long last = buf.lastx();
        Long first = buf.firstx();

        if (last != null && first != null && last - first >= MAX_BUFF_SIZE) {
          NavigableSet<Long> prevHoles = buf.subSet(first, true, last, true);

          GridLongList filteredEvts = new GridLongList((int) (last - first));

          int size = 0;

          Long cntr;

          while ((cntr = prevHoles.pollFirst()) != null) {
            filteredEvts.add(cntr);

            ++size;
          }

          filteredEvts.truncate(size, true);

          e.filteredEvents(filteredEvts);

          return e;
        }

        if (lastFiredCntr.get() > e.updateCounter() || e.updateCounter() == 1) return e;
        else {
          buf.add(e.updateCounter());

          // Double check. If another thread sent a event with counter higher than this event.
          if (lastFiredCntr.get() > e.updateCounter() && buf.contains(e.updateCounter())) {
            buf.remove(e.updateCounter());

            return e;
          } else return null;
        }
      } else {
        long prevVal = updateFiredCounter(e.updateCounter());

        if (prevVal == -1) return e;
        else {
          NavigableSet<Long> prevHoles = buf.subSet(prevVal, true, e.updateCounter(), true);

          GridLongList filteredEvts = new GridLongList((int) (e.updateCounter() - prevVal));

          int size = 0;

          Long cntr;

          while ((cntr = prevHoles.pollFirst()) != null) {
            filteredEvts.add(cntr);

            ++size;
          }

          filteredEvts.truncate(size, true);

          e.filteredEvents(filteredEvts);

          return e;
        }
      }
    }
 /** @return previous filtered events. */
 long[] filteredEvents() {
   return filteredEvts == null ? null : filteredEvts.array();
 }
  /**
   * @param key Key to add.
   * @param val Optional update value.
   * @param conflictTtl Conflict TTL (optional).
   * @param conflictExpireTime Conflict expire time (optional).
   * @param conflictVer Conflict version (optional).
   * @param primary If given key is primary on this mapping.
   */
  public void addUpdateEntry(
      KeyCacheObject key,
      @Nullable Object val,
      long conflictTtl,
      long conflictExpireTime,
      @Nullable GridCacheVersion conflictVer,
      boolean primary) {
    EntryProcessor<Object, Object, Object> entryProcessor = null;

    if (op == TRANSFORM) {
      assert val instanceof EntryProcessor : val;

      entryProcessor = (EntryProcessor<Object, Object, Object>) val;
    }

    assert val != null || op == DELETE;

    keys.add(key);

    if (entryProcessor != null) {
      if (entryProcessors == null) entryProcessors = new ArrayList<>();

      entryProcessors.add(entryProcessor);
    } else if (val != null) {
      assert val instanceof CacheObject : val;

      if (vals == null) vals = new ArrayList<>();

      vals.add((CacheObject) val);
    }

    hasPrimary |= primary;

    // In case there is no conflict, do not create the list.
    if (conflictVer != null) {
      if (conflictVers == null) {
        conflictVers = new ArrayList<>();

        for (int i = 0; i < keys.size() - 1; i++) conflictVers.add(null);
      }

      conflictVers.add(conflictVer);
    } else if (conflictVers != null) conflictVers.add(null);

    if (conflictTtl >= 0) {
      if (conflictTtls == null) {
        conflictTtls = new GridLongList(keys.size());

        for (int i = 0; i < keys.size() - 1; i++) conflictTtls.add(CU.TTL_NOT_CHANGED);
      }

      conflictTtls.add(conflictTtl);
    }

    if (conflictExpireTime >= 0) {
      if (conflictExpireTimes == null) {
        conflictExpireTimes = new GridLongList(keys.size());

        for (int i = 0; i < keys.size() - 1; i++) conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE);
      }

      conflictExpireTimes.add(conflictExpireTime);
    }
  }