class PubsubClient implements Closeable {

  protected static long extractTimestamp(
      @Nullable String timestampLabel,
      @Nullable String pubsubTimestamp,
      @Nullable Map<String, String> attributes) {
    Long timestampMsSinceEpoch;
    if (Strings.isNullOrEmpty(timestampLabel)) {
      timestampMsSinceEpoch = asMsSinceEpoch(pubsubTimestamp);
      checkArgument(timestampMsSinceEpoch != null,
                    "Cannot interpret PubSub publish timestamp: %s",
                    pubsubTimestamp);
    } else {
      String value = attributes == null ? null : attributes.get(timestampLabel);
      checkArgument(value != null,
                    "PubSub message is missing a value for timestamp label %s",
                    timestampLabel);
      timestampMsSinceEpoch = asMsSinceEpoch(value);
      checkArgument(timestampMsSinceEpoch != null,
                    "Cannot interpret value of label %s as timestamp: %s",
                    timestampLabel, value);
    }
    return timestampMsSinceEpoch;
  }

}