public byte[] getBytes() throws IOException {
    final KuraPayloadProto.KuraPayload.Builder protoMsg = KuraPayloadProto.KuraPayload.newBuilder();

    if (this.m_kuraPayload.getTimestamp() != null) {
      protoMsg.setTimestamp(this.m_kuraPayload.getTimestamp().getTime());
    }

    if (this.m_kuraPayload.getPosition() != null) {
      protoMsg.setPosition(this.buildPositionProtoBuf());
    }

    for (final String name : this.m_kuraPayload.metricNames()) {

      final Object value = this.m_kuraPayload.getMetric(name);
      try {
        final KuraPayloadProto.KuraPayload.KuraMetric.Builder metricB =
            KuraPayloadProto.KuraPayload.KuraMetric.newBuilder();
        metricB.setName(name);

        setProtoKuraMetricValue(metricB, value);
        metricB.build();

        protoMsg.addMetric(metricB);
      } catch (final Exception eihte) {
        try {
          s_logger.error(
              "During serialization, ignoring metric named: {}. Unrecognized value type: {}.",
              name,
              value.getClass().getName());
        } catch (final NullPointerException npe) {
          s_logger.error(
              "During serialization, ignoring metric named: {}. The value is null.", name);
        }
        throw new RuntimeException(eihte);
      }
    }

    if (this.m_kuraPayload.getBody() != null) {
      protoMsg.setBody(ByteString.copyFrom(this.m_kuraPayload.getBody()));
    }

    return protoMsg.build().toByteArray();
  }
  private static void setProtoKuraMetricValue(
      final KuraPayloadProto.KuraPayload.KuraMetric.Builder metric, final Object o)
      throws Exception {

    if (o instanceof String) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.STRING);
      metric.setStringValue((String) o);
    } else if (o instanceof Double) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.DOUBLE);
      metric.setDoubleValue((Double) o);
    } else if (o instanceof Integer) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.INT32);
      metric.setIntValue((Integer) o);
    } else if (o instanceof Float) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.FLOAT);
      metric.setFloatValue((Float) o);
    } else if (o instanceof Long) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.INT64);
      metric.setLongValue((Long) o);
    } else if (o instanceof Boolean) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.BOOL);
      metric.setBoolValue((Boolean) o);
    } else if (o instanceof byte[]) {
      metric.setType(KuraPayloadProto.KuraPayload.KuraMetric.ValueType.BYTES);
      metric.setBytesValue(ByteString.copyFrom((byte[]) o));
    } else if (o == null) {
      throw new Exception("null value");
    } else {
      throw new Exception(o.getClass().getName());
    }
  }