public static Throwable throwable(@NotNull ValueIn valueIn, boolean appendCurrentStack) {
    Class type = valueIn.typePrefix();
    String preMessage = null;
    Throwable throwable = ObjectUtils.newInstance((Class<Throwable>) type);

    final String finalPreMessage = preMessage;
    final Throwable finalThrowable = throwable;
    final List<StackTraceElement> stes = new ArrayList<>();
    valueIn.marshallable(
        m -> {
          final String message = merge(finalPreMessage, m.read(() -> "message").text());

          if (message != null) {
            try {
              DETAILED_MESSAGE.set(finalThrowable, message);
            } catch (IllegalAccessException e) {
              throw Jvm.rethrow(e);
            }
          }
          m.read(() -> "stackTrace")
              .sequence(
                  stes,
                  (stes0, stackTrace) -> {
                    while (stackTrace.hasNextSequenceItem()) {
                      stackTrace.marshallable(
                          r -> {
                            final String declaringClass = r.read(() -> "class").text();
                            final String methodName = r.read(() -> "method").text();
                            final String fileName = r.read(() -> "file").text();
                            final int lineNumber = r.read(() -> "line").int32();

                            stes0.add(
                                new StackTraceElement(
                                    declaringClass, methodName, fileName, lineNumber));
                          });
                    }
                  });
        });

    if (appendCurrentStack) {
      stes.add(new StackTraceElement("~ remote", "tcp ~", "", 0));
      StackTraceElement[] stes2 = Thread.currentThread().getStackTrace();
      int first = 6;
      int last = Jvm.trimLast(first, stes2);
      //noinspection ManualArrayToCollectionCopy
      for (int i = first; i <= last; i++) stes.add(stes2[i]);
    }
    try {
      //noinspection ToArrayCallWithZeroLengthArrayArgument
      STACK_TRACE.set(finalThrowable, stes.toArray(NO_STE));
    } catch (IllegalAccessException e) {
      throw Jvm.rethrow(e);
    }
    return throwable;
  }
 public boolean equalsBytes(@NotNull Bytes b2, long remaining) {
   long i = 0;
   try {
     for (; i < remaining - 7; i++)
       if (readLong(readPosition() + i) != b2.readLong(b2.readPosition() + i)) return false;
     for (; i < remaining; i++)
       if (readByte(readPosition() + i) != b2.readByte(b2.readPosition() + i)) return false;
   } catch (BufferUnderflowException | IORuntimeException e) {
     throw Jvm.rethrow(e);
   }
   return true;
 }
  /**
   * because we have set System.setProperty("Throttler.maxEventsPreSecond", "1"); in the static
   * above, we will only get one event per second, this test also checks that the messages still
   * arrive in order.
   *
   * @throws IOException
   * @throws InterruptedException
   */
  @Test
  public void testReceivingThrottledEventsInOrder() throws IOException, InterruptedException {

    final BlockingQueue<String> eventsQueue = new LinkedBlockingDeque<>();

    YamlLogging.showServerWrites = true;
    YamlLogging.showServerReads = true;

    yamlLoggger(
        () -> {
          try {

            Subscriber<String> add = eventsQueue::add;
            assetTree.registerSubscriber(NAME, String.class, add);

            for (int i = 0; i < 10; i++) {
              map.put("Hello" + i, "World" + i);
            }

            final long start = System.currentTimeMillis();

            for (int i = 0; i < 10; i++) {
              String actual = eventsQueue.poll(5, SECONDS);
              Assert.assertNotNull(actual);
              Assert.assertEquals("Hello" + i, actual);
            }

            // because we are only sending 1 message per second this should take around 10
            // seconds, certainly longer than 5 seconds
            Assert.assertTrue(System.currentTimeMillis() > start + TimeUnit.SECONDS.toMillis(5));

          } catch (Exception e) {
            throw Jvm.rethrow(e);
          }
        });
  }
  @NotNull
  private ReadMarshallable wireInConsumer() {
    return (wire) -> {
      long startWritePosition = outWire.bytes().writePosition();

      // if true the next data message will be a system message
      isSystemMessage = wire.bytes().readRemaining() == 0;
      if (isSystemMessage) {
        if (LOG.isDebugEnabled()) LOG.debug("received system-meta-data");
        return;
      }

      try {
        readCsp(wire);
        readTid(wire);
      } catch (Throwable t) {
        Jvm.rethrow(t);
      }

      try {
        if (hasCspChanged(cspText)) {

          if (LOG.isDebugEnabled()) LOG.debug("received meta-data:\n" + wire.bytes().toHexString());

          requestContext = requestContextInterner.intern(cspText);
          viewType = requestContext.viewType();
          if (viewType == null) {
            if (LOG.isDebugEnabled()) LOG.debug("received system-meta-data");
            isSystemMessage = true;
            return;
          }

          view = this.assetTree.acquireView(requestContext);

          if (viewType == MapView.class
              || viewType == EntrySetView.class
              || viewType == ValuesCollection.class
              || viewType == KeySetView.class
              || viewType == ObjectKVSSubscription.class
              || viewType == TopicPublisher.class
              || viewType == Publisher.class
              || viewType == Reference.class
              || viewType == TopologySubscription.class
              || viewType == Replication.class
              || viewType == Heartbeat.class) {

            // default to string type if not provided
            final Class type =
                requestContext.keyType() == null ? String.class : requestContext.keyType();

            final Class type2 =
                requestContext.valueType() == null ? String.class : requestContext.valueType();

            wireAdapter = new GenericWireAdapter(type, type2);
          } else throw new UnsupportedOperationException("unsupported view type");
        }
      } catch (Throwable e) {
        LOG.error("", e);
        outWire.bytes().writePosition(startWritePosition);
        outWire.writeDocument(true, w -> w.writeEventName(CoreFields.tid).int64(tid));
        outWire.writeDocument(false, out -> out.writeEventName(() -> "exception").throwable(e));
        logYamlToStandardOut(outWire);
        rethrow(e);
      }
    };
  }
 @Override
 public void updateThrown(Throwable t, String update, Object... args) {
   throw Jvm.rethrow(t);
 }
 @Override
 public void queryThrown(Throwable t, String query, Object... args) {
   throw Jvm.rethrow(t);
 }