@Override
  Tuple8<A, B, C, D, E, F, G, H> decodeFromRawInternal(Object o) {
    if (LOGGER.isTraceEnabled()) {
      LOGGER.trace(format("Decode '%s' tuple8 raw object %s", fieldName, o));
    }

    Validator.validateTrue(
        TupleValue.class.isAssignableFrom(o.getClass()),
        "The class of object %s to decode should be %s",
        o,
        TupleValue.class.getCanonicalName());
    final List<DataType> types = tupleType.getComponentTypes();
    return new Tuple8<>(
        aProperty.decodeFromRaw(extractType((TupleValue) o, types.get(0), aProperty, 0)),
        bProperty.decodeFromRaw(extractType((TupleValue) o, types.get(1), bProperty, 1)),
        cProperty.decodeFromRaw(extractType((TupleValue) o, types.get(2), cProperty, 2)),
        dProperty.decodeFromRaw(extractType((TupleValue) o, types.get(3), dProperty, 3)),
        eProperty.decodeFromRaw(extractType((TupleValue) o, types.get(4), eProperty, 4)),
        fProperty.decodeFromRaw(extractType((TupleValue) o, types.get(5), fProperty, 5)),
        gProperty.decodeFromRaw(extractType((TupleValue) o, types.get(6), gProperty, 6)),
        hProperty.decodeFromRaw(extractType((TupleValue) o, types.get(7), hProperty, 7)));
  }