diff --git a/Makefile b/Makefile
index bf2a1e2..eec974f 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,8 @@
 	(cd src/killSwitch && \
 		protoc -I=. --js_out=import_style=commonjs_strict:. api_proto/*.proto && \
 		protoc -I. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. api_proto/*.proto)
+	(cd src/workflows && \
+		protoc -I=. --js_out=import_style=commonjs_strict:. proto/*.proto)
 
 node_deps:
 	npm ci --no-save
diff --git a/src/workflows/proto/main.proto b/src/workflows/proto/main.proto
new file mode 100644
index 0000000..0230ca6
--- /dev/null
+++ b/src/workflows/proto/main.proto
@@ -0,0 +1,92 @@
+syntax = "proto3";
+
+package workflows;
+
+message Thread {
+  int64 forum_id = 1;
+  int64 thread_id = 2;
+}
+
+message Action {
+  message ReplyAction {
+    string payload = 1;
+    bool subscribe = 2;
+    bool mark_as_answer = 3;
+  }
+
+  message MoveAction {
+    int64 forum_id = 1;
+    string category = 2;
+    string language = 3;
+    map<string, string> property = 4;
+  }
+
+  message MarkDuplicateAction {
+    Thread destination = 1;
+  }
+
+  message UnmarkDuplicateAction {}
+
+  message StarAction {
+    bool star = 1; // true stars, and false unstars.
+  }
+
+  message SubscribeAction {
+    bool subscribe = 1; // true subscribes, false unsubscribes.
+  }
+
+  message VoteAction {
+    enum Vote {
+      NONE = 0;
+      UP = 1;
+      DOWN = -1;
+    }
+    Vote vote = 1;
+  }
+
+  message AttributeAction {
+    enum AttributeAction {
+      AA_NONE = 0;
+      AA_LOCK = 1;
+      AA_UNLOCK = 2;
+      AA_PIN = 3;
+      AA_UNPIN = 4;
+      AA_NON_ISSUE = 5;
+      AA_OBSOLETE = 6;
+      AA_REVERT = 7;
+      AA_SET_TRENDING = 8;
+      AA_UNSET_TRENDING = 9;
+      AA_SET_ISSUE_RESOLVED = 10;
+      AA_UNSET_ISSUE_RESOLVED = 11;
+    }
+    AttributeAction attribute_action = 1;
+  }
+
+  message ReportAction {
+    enum ReportType {
+      RT_UNKNOWN = 0;
+      RT_OFF_TOPIC = 1;
+      RT_ABUSE = 2;
+    }
+    ReportType report_type = 1;
+  }
+
+  oneof action {
+    ReplyAction reply_action = 1;
+    MoveAction move_action = 2;
+    MarkDuplicateAction mark_duplicate_action = 3;
+    UnmarkDuplicateAction unmark_duplicate_action = 4;
+    AttributeAction attribute_action = 5;
+    StarAction star_action = 16;
+    SubscribeAction subscribe_action = 17;
+    VoteAction vote_action = 18;
+    ReportAction report_action = 19;
+  }
+}
+
+message Workflow {
+  string name = 1;
+  string description = 2;
+  int32 index = 3;
+  repeated Action actions = 4;
+}
diff --git a/src/workflows/proto/main_pb.js b/src/workflows/proto/main_pb.js
new file mode 100644
index 0000000..7fa4d98
--- /dev/null
+++ b/src/workflows/proto/main_pb.js
@@ -0,0 +1,2639 @@
+// source: proto/main.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('workflows.Action', null, proto);
+goog.exportSymbol('workflows.Action.ActionCase', null, proto);
+goog.exportSymbol('workflows.Action.AttributeAction', null, proto);
+goog.exportSymbol('workflows.Action.AttributeAction.AttributeAction', null, proto);
+goog.exportSymbol('workflows.Action.MarkDuplicateAction', null, proto);
+goog.exportSymbol('workflows.Action.MoveAction', null, proto);
+goog.exportSymbol('workflows.Action.ReplyAction', null, proto);
+goog.exportSymbol('workflows.Action.ReportAction', null, proto);
+goog.exportSymbol('workflows.Action.ReportAction.ReportType', null, proto);
+goog.exportSymbol('workflows.Action.StarAction', null, proto);
+goog.exportSymbol('workflows.Action.SubscribeAction', null, proto);
+goog.exportSymbol('workflows.Action.UnmarkDuplicateAction', null, proto);
+goog.exportSymbol('workflows.Action.VoteAction', null, proto);
+goog.exportSymbol('workflows.Action.VoteAction.Vote', null, proto);
+goog.exportSymbol('workflows.Thread', null, proto);
+goog.exportSymbol('workflows.Workflow', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Thread = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Thread, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Thread.displayName = 'proto.workflows.Thread';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.workflows.Action.oneofGroups_);
+};
+goog.inherits(proto.workflows.Action, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.displayName = 'proto.workflows.Action';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.ReplyAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.ReplyAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.ReplyAction.displayName = 'proto.workflows.Action.ReplyAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.MoveAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.MoveAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.MoveAction.displayName = 'proto.workflows.Action.MoveAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.MarkDuplicateAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.MarkDuplicateAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.MarkDuplicateAction.displayName = 'proto.workflows.Action.MarkDuplicateAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.UnmarkDuplicateAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.UnmarkDuplicateAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.UnmarkDuplicateAction.displayName = 'proto.workflows.Action.UnmarkDuplicateAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.StarAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.StarAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.StarAction.displayName = 'proto.workflows.Action.StarAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.SubscribeAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.SubscribeAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.SubscribeAction.displayName = 'proto.workflows.Action.SubscribeAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.VoteAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.VoteAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.VoteAction.displayName = 'proto.workflows.Action.VoteAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.AttributeAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.AttributeAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.AttributeAction.displayName = 'proto.workflows.Action.AttributeAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Action.ReportAction = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.workflows.Action.ReportAction, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Action.ReportAction.displayName = 'proto.workflows.Action.ReportAction';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.workflows.Workflow = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.workflows.Workflow.repeatedFields_, null);
+};
+goog.inherits(proto.workflows.Workflow, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.workflows.Workflow.displayName = 'proto.workflows.Workflow';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Thread.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Thread.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Thread} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Thread.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    forumId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    threadId: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Thread}
+ */
+proto.workflows.Thread.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Thread;
+  return proto.workflows.Thread.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Thread} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Thread}
+ */
+proto.workflows.Thread.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setForumId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setThreadId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Thread.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Thread.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Thread} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Thread.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getForumId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getThreadId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 forum_id = 1;
+ * @return {number}
+ */
+proto.workflows.Thread.prototype.getForumId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.workflows.Thread} returns this
+ */
+proto.workflows.Thread.prototype.setForumId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional int64 thread_id = 2;
+ * @return {number}
+ */
+proto.workflows.Thread.prototype.getThreadId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.workflows.Thread} returns this
+ */
+proto.workflows.Thread.prototype.setThreadId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.workflows.Action.oneofGroups_ = [[1,2,3,4,5,16,17,18,19]];
+
+/**
+ * @enum {number}
+ */
+proto.workflows.Action.ActionCase = {
+  ACTION_NOT_SET: 0,
+  REPLY_ACTION: 1,
+  MOVE_ACTION: 2,
+  MARK_DUPLICATE_ACTION: 3,
+  UNMARK_DUPLICATE_ACTION: 4,
+  ATTRIBUTE_ACTION: 5,
+  STAR_ACTION: 16,
+  SUBSCRIBE_ACTION: 17,
+  VOTE_ACTION: 18,
+  REPORT_ACTION: 19
+};
+
+/**
+ * @return {proto.workflows.Action.ActionCase}
+ */
+proto.workflows.Action.prototype.getActionCase = function() {
+  return /** @type {proto.workflows.Action.ActionCase} */(jspb.Message.computeOneofCase(this, proto.workflows.Action.oneofGroups_[0]));
+};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    replyAction: (f = msg.getReplyAction()) && proto.workflows.Action.ReplyAction.toObject(includeInstance, f),
+    moveAction: (f = msg.getMoveAction()) && proto.workflows.Action.MoveAction.toObject(includeInstance, f),
+    markDuplicateAction: (f = msg.getMarkDuplicateAction()) && proto.workflows.Action.MarkDuplicateAction.toObject(includeInstance, f),
+    unmarkDuplicateAction: (f = msg.getUnmarkDuplicateAction()) && proto.workflows.Action.UnmarkDuplicateAction.toObject(includeInstance, f),
+    attributeAction: (f = msg.getAttributeAction()) && proto.workflows.Action.AttributeAction.toObject(includeInstance, f),
+    starAction: (f = msg.getStarAction()) && proto.workflows.Action.StarAction.toObject(includeInstance, f),
+    subscribeAction: (f = msg.getSubscribeAction()) && proto.workflows.Action.SubscribeAction.toObject(includeInstance, f),
+    voteAction: (f = msg.getVoteAction()) && proto.workflows.Action.VoteAction.toObject(includeInstance, f),
+    reportAction: (f = msg.getReportAction()) && proto.workflows.Action.ReportAction.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action}
+ */
+proto.workflows.Action.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action;
+  return proto.workflows.Action.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action}
+ */
+proto.workflows.Action.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.workflows.Action.ReplyAction;
+      reader.readMessage(value,proto.workflows.Action.ReplyAction.deserializeBinaryFromReader);
+      msg.setReplyAction(value);
+      break;
+    case 2:
+      var value = new proto.workflows.Action.MoveAction;
+      reader.readMessage(value,proto.workflows.Action.MoveAction.deserializeBinaryFromReader);
+      msg.setMoveAction(value);
+      break;
+    case 3:
+      var value = new proto.workflows.Action.MarkDuplicateAction;
+      reader.readMessage(value,proto.workflows.Action.MarkDuplicateAction.deserializeBinaryFromReader);
+      msg.setMarkDuplicateAction(value);
+      break;
+    case 4:
+      var value = new proto.workflows.Action.UnmarkDuplicateAction;
+      reader.readMessage(value,proto.workflows.Action.UnmarkDuplicateAction.deserializeBinaryFromReader);
+      msg.setUnmarkDuplicateAction(value);
+      break;
+    case 5:
+      var value = new proto.workflows.Action.AttributeAction;
+      reader.readMessage(value,proto.workflows.Action.AttributeAction.deserializeBinaryFromReader);
+      msg.setAttributeAction(value);
+      break;
+    case 16:
+      var value = new proto.workflows.Action.StarAction;
+      reader.readMessage(value,proto.workflows.Action.StarAction.deserializeBinaryFromReader);
+      msg.setStarAction(value);
+      break;
+    case 17:
+      var value = new proto.workflows.Action.SubscribeAction;
+      reader.readMessage(value,proto.workflows.Action.SubscribeAction.deserializeBinaryFromReader);
+      msg.setSubscribeAction(value);
+      break;
+    case 18:
+      var value = new proto.workflows.Action.VoteAction;
+      reader.readMessage(value,proto.workflows.Action.VoteAction.deserializeBinaryFromReader);
+      msg.setVoteAction(value);
+      break;
+    case 19:
+      var value = new proto.workflows.Action.ReportAction;
+      reader.readMessage(value,proto.workflows.Action.ReportAction.deserializeBinaryFromReader);
+      msg.setReportAction(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getReplyAction();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.workflows.Action.ReplyAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getMoveAction();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.workflows.Action.MoveAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getMarkDuplicateAction();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.workflows.Action.MarkDuplicateAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getUnmarkDuplicateAction();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.workflows.Action.UnmarkDuplicateAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getAttributeAction();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.workflows.Action.AttributeAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getStarAction();
+  if (f != null) {
+    writer.writeMessage(
+      16,
+      f,
+      proto.workflows.Action.StarAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getSubscribeAction();
+  if (f != null) {
+    writer.writeMessage(
+      17,
+      f,
+      proto.workflows.Action.SubscribeAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getVoteAction();
+  if (f != null) {
+    writer.writeMessage(
+      18,
+      f,
+      proto.workflows.Action.VoteAction.serializeBinaryToWriter
+    );
+  }
+  f = message.getReportAction();
+  if (f != null) {
+    writer.writeMessage(
+      19,
+      f,
+      proto.workflows.Action.ReportAction.serializeBinaryToWriter
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.ReplyAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.ReplyAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.ReplyAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.ReplyAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    payload: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    subscribe: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
+    markAsAnswer: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.ReplyAction}
+ */
+proto.workflows.Action.ReplyAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.ReplyAction;
+  return proto.workflows.Action.ReplyAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.ReplyAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.ReplyAction}
+ */
+proto.workflows.Action.ReplyAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPayload(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setSubscribe(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setMarkAsAnswer(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.ReplyAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.ReplyAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.ReplyAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.ReplyAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPayload();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getSubscribe();
+  if (f) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = message.getMarkAsAnswer();
+  if (f) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string payload = 1;
+ * @return {string}
+ */
+proto.workflows.Action.ReplyAction.prototype.getPayload = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.workflows.Action.ReplyAction} returns this
+ */
+proto.workflows.Action.ReplyAction.prototype.setPayload = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional bool subscribe = 2;
+ * @return {boolean}
+ */
+proto.workflows.Action.ReplyAction.prototype.getSubscribe = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.workflows.Action.ReplyAction} returns this
+ */
+proto.workflows.Action.ReplyAction.prototype.setSubscribe = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 2, value);
+};
+
+
+/**
+ * optional bool mark_as_answer = 3;
+ * @return {boolean}
+ */
+proto.workflows.Action.ReplyAction.prototype.getMarkAsAnswer = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.workflows.Action.ReplyAction} returns this
+ */
+proto.workflows.Action.ReplyAction.prototype.setMarkAsAnswer = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.MoveAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.MoveAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.MoveAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.MoveAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    forumId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    category: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    language: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    propertyMap: (f = msg.getPropertyMap()) ? f.toObject(includeInstance, undefined) : []
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.MoveAction}
+ */
+proto.workflows.Action.MoveAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.MoveAction;
+  return proto.workflows.Action.MoveAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.MoveAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.MoveAction}
+ */
+proto.workflows.Action.MoveAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setForumId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCategory(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLanguage(value);
+      break;
+    case 4:
+      var value = msg.getPropertyMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
+         });
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.MoveAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.MoveAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.MoveAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.MoveAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getForumId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getCategory();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getLanguage();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPropertyMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(4, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
+  }
+};
+
+
+/**
+ * optional int64 forum_id = 1;
+ * @return {number}
+ */
+proto.workflows.Action.MoveAction.prototype.getForumId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.workflows.Action.MoveAction} returns this
+ */
+proto.workflows.Action.MoveAction.prototype.setForumId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string category = 2;
+ * @return {string}
+ */
+proto.workflows.Action.MoveAction.prototype.getCategory = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.workflows.Action.MoveAction} returns this
+ */
+proto.workflows.Action.MoveAction.prototype.setCategory = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string language = 3;
+ * @return {string}
+ */
+proto.workflows.Action.MoveAction.prototype.getLanguage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.workflows.Action.MoveAction} returns this
+ */
+proto.workflows.Action.MoveAction.prototype.setLanguage = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * map<string, string> property = 4;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,string>}
+ */
+proto.workflows.Action.MoveAction.prototype.getPropertyMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,string>} */ (
+      jspb.Message.getMapField(this, 4, opt_noLazyCreate,
+      null));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.workflows.Action.MoveAction} returns this
+ */
+proto.workflows.Action.MoveAction.prototype.clearPropertyMap = function() {
+  this.getPropertyMap().clear();
+  return this;};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.MarkDuplicateAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.MarkDuplicateAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.MarkDuplicateAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.MarkDuplicateAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    destination: (f = msg.getDestination()) && proto.workflows.Thread.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.MarkDuplicateAction}
+ */
+proto.workflows.Action.MarkDuplicateAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.MarkDuplicateAction;
+  return proto.workflows.Action.MarkDuplicateAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.MarkDuplicateAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.MarkDuplicateAction}
+ */
+proto.workflows.Action.MarkDuplicateAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.workflows.Thread;
+      reader.readMessage(value,proto.workflows.Thread.deserializeBinaryFromReader);
+      msg.setDestination(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.MarkDuplicateAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.MarkDuplicateAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.MarkDuplicateAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.MarkDuplicateAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getDestination();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.workflows.Thread.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional Thread destination = 1;
+ * @return {?proto.workflows.Thread}
+ */
+proto.workflows.Action.MarkDuplicateAction.prototype.getDestination = function() {
+  return /** @type{?proto.workflows.Thread} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Thread, 1));
+};
+
+
+/**
+ * @param {?proto.workflows.Thread|undefined} value
+ * @return {!proto.workflows.Action.MarkDuplicateAction} returns this
+*/
+proto.workflows.Action.MarkDuplicateAction.prototype.setDestination = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action.MarkDuplicateAction} returns this
+ */
+proto.workflows.Action.MarkDuplicateAction.prototype.clearDestination = function() {
+  return this.setDestination(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.MarkDuplicateAction.prototype.hasDestination = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.UnmarkDuplicateAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.UnmarkDuplicateAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.UnmarkDuplicateAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.UnmarkDuplicateAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.UnmarkDuplicateAction}
+ */
+proto.workflows.Action.UnmarkDuplicateAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.UnmarkDuplicateAction;
+  return proto.workflows.Action.UnmarkDuplicateAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.UnmarkDuplicateAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.UnmarkDuplicateAction}
+ */
+proto.workflows.Action.UnmarkDuplicateAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.UnmarkDuplicateAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.UnmarkDuplicateAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.UnmarkDuplicateAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.UnmarkDuplicateAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.StarAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.StarAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.StarAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.StarAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    star: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.StarAction}
+ */
+proto.workflows.Action.StarAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.StarAction;
+  return proto.workflows.Action.StarAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.StarAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.StarAction}
+ */
+proto.workflows.Action.StarAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStar(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.StarAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.StarAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.StarAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.StarAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStar();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool star = 1;
+ * @return {boolean}
+ */
+proto.workflows.Action.StarAction.prototype.getStar = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.workflows.Action.StarAction} returns this
+ */
+proto.workflows.Action.StarAction.prototype.setStar = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.SubscribeAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.SubscribeAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.SubscribeAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.SubscribeAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    subscribe: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.SubscribeAction}
+ */
+proto.workflows.Action.SubscribeAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.SubscribeAction;
+  return proto.workflows.Action.SubscribeAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.SubscribeAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.SubscribeAction}
+ */
+proto.workflows.Action.SubscribeAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setSubscribe(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.SubscribeAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.SubscribeAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.SubscribeAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.SubscribeAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSubscribe();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool subscribe = 1;
+ * @return {boolean}
+ */
+proto.workflows.Action.SubscribeAction.prototype.getSubscribe = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.workflows.Action.SubscribeAction} returns this
+ */
+proto.workflows.Action.SubscribeAction.prototype.setSubscribe = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.VoteAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.VoteAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.VoteAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.VoteAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    vote: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.VoteAction}
+ */
+proto.workflows.Action.VoteAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.VoteAction;
+  return proto.workflows.Action.VoteAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.VoteAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.VoteAction}
+ */
+proto.workflows.Action.VoteAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.workflows.Action.VoteAction.Vote} */ (reader.readEnum());
+      msg.setVote(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.VoteAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.VoteAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.VoteAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.VoteAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getVote();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.workflows.Action.VoteAction.Vote = {
+  NONE: 0,
+  UP: 1,
+  DOWN: -1
+};
+
+/**
+ * optional Vote vote = 1;
+ * @return {!proto.workflows.Action.VoteAction.Vote}
+ */
+proto.workflows.Action.VoteAction.prototype.getVote = function() {
+  return /** @type {!proto.workflows.Action.VoteAction.Vote} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.workflows.Action.VoteAction.Vote} value
+ * @return {!proto.workflows.Action.VoteAction} returns this
+ */
+proto.workflows.Action.VoteAction.prototype.setVote = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.AttributeAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.AttributeAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.AttributeAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.AttributeAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    attributeAction: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.AttributeAction}
+ */
+proto.workflows.Action.AttributeAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.AttributeAction;
+  return proto.workflows.Action.AttributeAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.AttributeAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.AttributeAction}
+ */
+proto.workflows.Action.AttributeAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.workflows.Action.AttributeAction.AttributeAction} */ (reader.readEnum());
+      msg.setAttributeAction(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.AttributeAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.AttributeAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.AttributeAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.AttributeAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAttributeAction();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.workflows.Action.AttributeAction.AttributeAction = {
+  AA_NONE: 0,
+  AA_LOCK: 1,
+  AA_UNLOCK: 2,
+  AA_PIN: 3,
+  AA_UNPIN: 4,
+  AA_NON_ISSUE: 5,
+  AA_OBSOLETE: 6,
+  AA_REVERT: 7,
+  AA_SET_TRENDING: 8,
+  AA_UNSET_TRENDING: 9,
+  AA_SET_ISSUE_RESOLVED: 10,
+  AA_UNSET_ISSUE_RESOLVED: 11
+};
+
+/**
+ * optional AttributeAction attribute_action = 1;
+ * @return {!proto.workflows.Action.AttributeAction.AttributeAction}
+ */
+proto.workflows.Action.AttributeAction.prototype.getAttributeAction = function() {
+  return /** @type {!proto.workflows.Action.AttributeAction.AttributeAction} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.workflows.Action.AttributeAction.AttributeAction} value
+ * @return {!proto.workflows.Action.AttributeAction} returns this
+ */
+proto.workflows.Action.AttributeAction.prototype.setAttributeAction = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Action.ReportAction.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Action.ReportAction.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Action.ReportAction} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.ReportAction.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    reportType: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Action.ReportAction}
+ */
+proto.workflows.Action.ReportAction.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Action.ReportAction;
+  return proto.workflows.Action.ReportAction.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Action.ReportAction} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Action.ReportAction}
+ */
+proto.workflows.Action.ReportAction.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.workflows.Action.ReportAction.ReportType} */ (reader.readEnum());
+      msg.setReportType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Action.ReportAction.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Action.ReportAction.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Action.ReportAction} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Action.ReportAction.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getReportType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.workflows.Action.ReportAction.ReportType = {
+  RT_UNKNOWN: 0,
+  RT_OFF_TOPIC: 1,
+  RT_ABUSE: 2
+};
+
+/**
+ * optional ReportType report_type = 1;
+ * @return {!proto.workflows.Action.ReportAction.ReportType}
+ */
+proto.workflows.Action.ReportAction.prototype.getReportType = function() {
+  return /** @type {!proto.workflows.Action.ReportAction.ReportType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.workflows.Action.ReportAction.ReportType} value
+ * @return {!proto.workflows.Action.ReportAction} returns this
+ */
+proto.workflows.Action.ReportAction.prototype.setReportType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional ReplyAction reply_action = 1;
+ * @return {?proto.workflows.Action.ReplyAction}
+ */
+proto.workflows.Action.prototype.getReplyAction = function() {
+  return /** @type{?proto.workflows.Action.ReplyAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.ReplyAction, 1));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.ReplyAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setReplyAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 1, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearReplyAction = function() {
+  return this.setReplyAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasReplyAction = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional MoveAction move_action = 2;
+ * @return {?proto.workflows.Action.MoveAction}
+ */
+proto.workflows.Action.prototype.getMoveAction = function() {
+  return /** @type{?proto.workflows.Action.MoveAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.MoveAction, 2));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.MoveAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setMoveAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 2, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearMoveAction = function() {
+  return this.setMoveAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasMoveAction = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional MarkDuplicateAction mark_duplicate_action = 3;
+ * @return {?proto.workflows.Action.MarkDuplicateAction}
+ */
+proto.workflows.Action.prototype.getMarkDuplicateAction = function() {
+  return /** @type{?proto.workflows.Action.MarkDuplicateAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.MarkDuplicateAction, 3));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.MarkDuplicateAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setMarkDuplicateAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 3, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearMarkDuplicateAction = function() {
+  return this.setMarkDuplicateAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasMarkDuplicateAction = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional UnmarkDuplicateAction unmark_duplicate_action = 4;
+ * @return {?proto.workflows.Action.UnmarkDuplicateAction}
+ */
+proto.workflows.Action.prototype.getUnmarkDuplicateAction = function() {
+  return /** @type{?proto.workflows.Action.UnmarkDuplicateAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.UnmarkDuplicateAction, 4));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.UnmarkDuplicateAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setUnmarkDuplicateAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 4, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearUnmarkDuplicateAction = function() {
+  return this.setUnmarkDuplicateAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasUnmarkDuplicateAction = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional AttributeAction attribute_action = 5;
+ * @return {?proto.workflows.Action.AttributeAction}
+ */
+proto.workflows.Action.prototype.getAttributeAction = function() {
+  return /** @type{?proto.workflows.Action.AttributeAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.AttributeAction, 5));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.AttributeAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setAttributeAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 5, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearAttributeAction = function() {
+  return this.setAttributeAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasAttributeAction = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional StarAction star_action = 16;
+ * @return {?proto.workflows.Action.StarAction}
+ */
+proto.workflows.Action.prototype.getStarAction = function() {
+  return /** @type{?proto.workflows.Action.StarAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.StarAction, 16));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.StarAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setStarAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 16, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearStarAction = function() {
+  return this.setStarAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasStarAction = function() {
+  return jspb.Message.getField(this, 16) != null;
+};
+
+
+/**
+ * optional SubscribeAction subscribe_action = 17;
+ * @return {?proto.workflows.Action.SubscribeAction}
+ */
+proto.workflows.Action.prototype.getSubscribeAction = function() {
+  return /** @type{?proto.workflows.Action.SubscribeAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.SubscribeAction, 17));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.SubscribeAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setSubscribeAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 17, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearSubscribeAction = function() {
+  return this.setSubscribeAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasSubscribeAction = function() {
+  return jspb.Message.getField(this, 17) != null;
+};
+
+
+/**
+ * optional VoteAction vote_action = 18;
+ * @return {?proto.workflows.Action.VoteAction}
+ */
+proto.workflows.Action.prototype.getVoteAction = function() {
+  return /** @type{?proto.workflows.Action.VoteAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.VoteAction, 18));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.VoteAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setVoteAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 18, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearVoteAction = function() {
+  return this.setVoteAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasVoteAction = function() {
+  return jspb.Message.getField(this, 18) != null;
+};
+
+
+/**
+ * optional ReportAction report_action = 19;
+ * @return {?proto.workflows.Action.ReportAction}
+ */
+proto.workflows.Action.prototype.getReportAction = function() {
+  return /** @type{?proto.workflows.Action.ReportAction} */ (
+    jspb.Message.getWrapperField(this, proto.workflows.Action.ReportAction, 19));
+};
+
+
+/**
+ * @param {?proto.workflows.Action.ReportAction|undefined} value
+ * @return {!proto.workflows.Action} returns this
+*/
+proto.workflows.Action.prototype.setReportAction = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 19, proto.workflows.Action.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.workflows.Action} returns this
+ */
+proto.workflows.Action.prototype.clearReportAction = function() {
+  return this.setReportAction(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.workflows.Action.prototype.hasReportAction = function() {
+  return jspb.Message.getField(this, 19) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.workflows.Workflow.repeatedFields_ = [4];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.workflows.Workflow.prototype.toObject = function(opt_includeInstance) {
+  return proto.workflows.Workflow.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.workflows.Workflow} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Workflow.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    index: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    actionsList: jspb.Message.toObjectList(msg.getActionsList(),
+    proto.workflows.Action.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.workflows.Workflow}
+ */
+proto.workflows.Workflow.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.workflows.Workflow;
+  return proto.workflows.Workflow.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.workflows.Workflow} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.workflows.Workflow}
+ */
+proto.workflows.Workflow.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setIndex(value);
+      break;
+    case 4:
+      var value = new proto.workflows.Action;
+      reader.readMessage(value,proto.workflows.Action.deserializeBinaryFromReader);
+      msg.addActions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.workflows.Workflow.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.workflows.Workflow.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.workflows.Workflow} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.workflows.Workflow.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getIndex();
+  if (f !== 0) {
+    writer.writeInt32(
+      3,
+      f
+    );
+  }
+  f = message.getActionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      4,
+      f,
+      proto.workflows.Action.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.workflows.Workflow.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.workflows.Workflow} returns this
+ */
+proto.workflows.Workflow.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.workflows.Workflow.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.workflows.Workflow} returns this
+ */
+proto.workflows.Workflow.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int32 index = 3;
+ * @return {number}
+ */
+proto.workflows.Workflow.prototype.getIndex = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.workflows.Workflow} returns this
+ */
+proto.workflows.Workflow.prototype.setIndex = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * repeated Action actions = 4;
+ * @return {!Array<!proto.workflows.Action>}
+ */
+proto.workflows.Workflow.prototype.getActionsList = function() {
+  return /** @type{!Array<!proto.workflows.Action>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.workflows.Action, 4));
+};
+
+
+/**
+ * @param {!Array<!proto.workflows.Action>} value
+ * @return {!proto.workflows.Workflow} returns this
+*/
+proto.workflows.Workflow.prototype.setActionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+};
+
+
+/**
+ * @param {!proto.workflows.Action=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.workflows.Action}
+ */
+proto.workflows.Workflow.prototype.addActions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.workflows.Action, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.workflows.Workflow} returns this
+ */
+proto.workflows.Workflow.prototype.clearActionsList = function() {
+  return this.setActionsList([]);
+};
+
+
+goog.object.extend(exports, proto);
