code: package org.gridkit.jvmtool.codec.stacktrace;
  
  import java.lang.Thread.State;
  
  import org.gridkit.jvmtool.event.CommonEvent;
  import org.gridkit.jvmtool.event.Event;
  import org.gridkit.jvmtool.event.GenericEvent;
  import org.gridkit.jvmtool.event.TaggedEvent;
  import org.gridkit.jvmtool.jvmevents.JvmEvents;
  import org.gridkit.jvmtool.stacktrace.StackFrameList;
  import org.gridkit.jvmtool.stacktrace.ThreadSnapshot;
  
  public class ThreadSnapshotEventPojo extends GenericEvent implements ThreadSnapshotEvent {
  
      private long threadId = -1;
      private String threadName;
      private State threadState;
      private StackFrameList stackTrace;
  
      @Override
      public long threadId() {
          return threadId;
      }
  
      public void threadId(long threadId) {
          this.threadId = threadId;
      }
  
      @Override
      public String threadName() {
          return threadName;
      }
  
      public void threadName(String name) {
          this.threadName = name;
      }
  
      @Override
      public State threadState() {
          return threadState;
      }
  
      public void threadState(State state) {
          this.threadState = state;
      }
  
      @Override
      public StackFrameList stackTrace() {
          return stackTrace;
      }
  
      public void stackTrace(StackFrameList trace) {
          this.stackTrace = trace;
      }
  
      public void loadFrom(ThreadSnapshot event) {
          if (event instanceof ThreadSnapshotEvent) {
              loadFrom((ThreadSnapshotEvent)event);
          }
          else {
              timestamp(event.timestamp());
              threadId(event.threadId());
              threadName(event.threadName());
              threadState(event.threadState());
              counters().clear();;
              counters().setAll(event.counters());
              stackTrace(event.stackTrace());
              if (event instanceof TaggedEvent) {
                  tags().clear();
                  tags().putAll(((TaggedEvent) event).tags());
              }
          }
      }
  
      public void loadFrom(ThreadSnapshotEvent event) {
          copyCommonEventFrom(event);
          threadId(event.threadId());
          threadName(event.threadName());
          threadState(event.threadState());
          stackTrace(event.stackTrace());
      }
  
      public void loadFromRawEvent(Event event) {
          threadId(-1);
          threadName(null);
          threadState(null);
  
          if (event instanceof CommonEvent) {
              CommonEvent cevent = (CommonEvent) event;
              copyCommonEventFrom(cevent);
              if (cevent.counters().getValue(JvmEvents.THREAD_ID) >= 0) {
                  threadId(cevent.counters().getValue(JvmEvents.THREAD_ID));
              }
              threadName(cevent.tags().firstTagFor(JvmEvents.THREAD_NAME));
              threadState(state(cevent.tags().firstTagFor(JvmEvents.THREAD_STATE)));
          }
          if (event instanceof ThreadTraceEvent) {
              stackTrace(((ThreadTraceEvent) event).stackTrace());
          }
      }
  
      private State state(String state) {
          try {
              return state == null ? null : Thread.State.valueOf(state);
          } catch (Exception e) {
              return null;
          }
      }
  }
  