/**
   * Serialize a {@link IntermediaryResult}.
   *
   * @throws IllegalArgumentException If cannot be serialized
   */
  public static RIntermediateAggregationResult buildRIntermediateAggregationResult(
      IntermediaryResult input) throws IllegalArgumentException {
    if (whitelistedSerializableClassNames == null) initialize();

    RIntermediateAggregationResult res = new RIntermediateAggregationResult();
    res.setOutputColName(input.getOutputColName());
    if (input.getInputColumnType() != null) {
      switch (input.getInputColumnType()) {
        case STRING:
          res.setInputColumnType(RColumnType.STRING);
          break;
        case LONG:
          res.setInputColumnType(RColumnType.LONG);
          break;
        case DOUBLE:
          res.setInputColumnType(RColumnType.DOUBLE);
          break;
      }
    }

    List<RIntermediateAggregationResultValue> values = new ArrayList<>();
    IntermediaryResultValueIterator it = input.createValueIterator();
    while (it.hasNext()) {
      Object valueObject = it.next();

      RIntermediateAggregationResultValue resValue = new RIntermediateAggregationResultValue();

      RValue rvalue = RValueUtil.createRValue(valueObject);
      if (rvalue != null) {
        resValue.setValue(rvalue);
      } else {
        if (!whitelistedSerializableClassNames.contains(valueObject.getClass().getName()))
          // only a shallow check, but better than no check at all.
          throw new IllegalArgumentException(
              "Class " + valueObject.getClass().getName() + " is not whitelisted.");

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
          try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(valueObject);
          }

          resValue.setSerialized(baos.toByteArray());
        } catch (IOException e) {
          logger.error("Could not serialize intermediary result", e);
          throw new IllegalArgumentException("Could not serialize intermediary result", e);
        }
      }

      values.add(resValue);
    }
    res.setValues(values);

    return res;
  }