+ *
+ * @param pos
+ * int -1, 0-length of visible region, or greater to append new ops
+ * (with insertions in between)
+ * @param op
+ * char
+ * @param range
+ * int public void addOperationAt(int pos, char op, int range) { int
+ * cursor = -1; // mark the position for the current operation being
+ * edited. int o = 0; boolean last_d = false; // previous op was a
+ * deletion. if (pos < -1) throw new
+ * Error("pos<-1 is not supported."); while (o<length) { if
+ * (operation[o] != D) { if ( (cursor + this.range[o]) < pos) {
+ * cursor += this.range[o]; o++; last_d=false; } else { break; } }
+ * else { last_d=true; o++; } } if (o==length) { // must insert more
+ * operations before pos if (pos-cursor>0) addInsertion(pos-cursor);
+ * // then just add the new operation. Regardless of what it is.
+ * addOperation(op, range); } else { int diff = pos - cursor;
+ *
+ * int e_length = length-o; // new edit operation array length. //
+ * diff<0 - can only happen before first insertion or match. -
+ * affects op and all following // dif==0 - only when at first
+ * position of existing op - // diff>0 - must preserve some existing
+ * operations int[] e_range = new int[e_length];
+ * System.arraycopy(this.range, o, e_range, 0, e_length); char[] e_op
+ * = new char[e_length]; System.arraycopy(this.operation, o, e_op, 0,
+ * e_length); length = o; // can now use add_operation to extend
+ * list. int e_o=0; // current operation being edited. switch (op) {
+ * case M: switch (e_op[e_o]) { case M: if (last_d && diff <= 0) { //
+ * reduce D's, if possible if (range<=this.range[o-1]) { this.range[o
+ * - 1] -= range; } else { this.range[o-1]=0; } if
+ * (this.range[o-1]==0) o--; // lose this op. } e_range[e_o] +=
+ * range; // just add more matched residues break; case I: // change
+ * from insertion to match if (last_d && diff<=0) { // reduce D's, if
+ * possible if (range<=this.range[o-1]) { this.range[o - 1] -= range;
+ * } else { this.range[o-1]=0; } if (this.range[o-1]==0) o--; // lose
+ * this op. } e_range[e_o] break; default: throw new Inp }
+ *
+ * break; case I: break; case D: } break; default: throw new
+ * Error("Implementation Error: Unknown operation in addOperation!");
+ * } // finally, add remaining ops. while (e_o<e_length) {
+ * addOperation(e_op[e_o], e_range[e_o]); e_o++; } } }
+ */
+ /**
+ * Mark residues from start to end (inclusive) as deleted from the alignment,
+ * and removes any insertions.
+ *
+ * @param start
+ * int
+ * @param end
+ * int
+ * @return deleted int - number of symbols marked as deleted