 				@addComment(op, metadata)
 			else
 				throw new Error("unknown op type")
-			
+
+		applyOps: (ops, metadata = {}) ->
+			for op in ops
+				@applyOp(op, metadata)
+
 		addComment: (op, metadata) ->
 			# TODO: Don't allow overlapping comments?
 			@comments.push comment = {

					t: op.t
				metadata
			}
			@emit "comment:added", comment
			return comment
		
		applyInsertToComments: (op) ->
			for comment in @comments
				if op.p <= comment.op.p
					comment.op.p += op.i.length
					@emit "comment:moved", comment
				else if op.p < comment.op.p + comment.op.c.length
					offset = op.p - comment.op.p
					comment.op.c = comment.op.c[0..(offset-1)] + op.i + comment.op.c[offset...]
					@emit "comment:moved", comment

		applyDeleteToComments: (op) ->
			op_start = op.p

		#     middle of a previous insert by the first user, the original insert will be split into two.
		constructor: (@changes = [], @comments = []) ->
			@setIdSeed(RangesTracker.generateIdSeed())
			@resetDirtyState()

		getIdSeed: () ->
			return @id_seed
