Java Code Examples for java.util.LinkedList#removeLast()

The following examples show how to use java.util.LinkedList#removeLast() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: HiveSchemaConverter.java    From kite with Apache License 2.0 6 votes vote down vote up
private static Schema convert(LinkedList<String> path, String name,
                              StructTypeInfo type,
                              Collection<String[]> required) {
  List<String> names = type.getAllStructFieldNames();
  List<TypeInfo> types = type.getAllStructFieldTypeInfos();
  Preconditions.checkArgument(names.size() == types.size(),
      "Cannot convert struct: %s names != %s types",
      names.size(), types.size());

  List<Schema.Field> fields = Lists.newArrayList();
  for (int i = 0; i < names.size(); i += 1) {
    path.addLast(name);
    fields.add(convertField(path, names.get(i), types.get(i), required));
    path.removeLast();
  }

  Schema recordSchema = Schema.createRecord(name, doc(type), null, false);
  recordSchema.setFields(fields);

  return recordSchema;
}
 
Example 2
Source File: LowestCommonAncestorOfABinaryTree.java    From pengyifan-leetcode with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private boolean findPath(TreeNode root, TreeNode target, LinkedList<TreeNode> list) {
  if (root == null) {
    return false;
  }
  list.add(root);
  if (root == target) {
    return true;
  }
  boolean found = findPath(root.left, target, list);
  if (found) {
    return true;
  }
  found = findPath(root.right, target, list);
  if (found) {
    return true;
  }
  list.removeLast();
  return false;
}
 
Example 3
Source File: EventSupport.java    From jkes with Apache License 2.0 6 votes vote down vote up
private void save(Object entity, LinkedList<Object> context) {
    if(entity == null) return;

    context.addLast(entity);

    EventContainer.addEvent(new Event.SaveEvent(Event.EventType.SAVE, entity));

    Collection<Object> cascadeEntity = getCascadeEntity(entity, context);
    cascadeEntity.forEach((e) -> {
        if(e instanceof Iterable) {
            save((Iterable)e, context);
        }else {
            save(e, context);
        }
    });

    context.removeLast();
}
 
Example 4
Source File: IntExpressionParser.java    From combinatoricslib with GNU Lesser General Public License v3.0 6 votes vote down vote up
static public void processOperator(LinkedList<Integer> st, char op) {
  int r = st.removeLast();
  int l = st.removeLast();
  switch (op) {
    case '+':
      st.add(l + r);
      break;
    case '-':
      st.add(l - r);
      break;
    case '*':
      st.add(l * r);
      break;
    case '/':
      st.add(l / r);
      break;
    case '%':
      st.add(l % r);
      break;
  }
}
 
Example 5
Source File: IdentifierConverter.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
private static List<ClassWrapperNode> getReversePostOrderListIterative(List<ClassWrapperNode> roots) {
  List<ClassWrapperNode> res = new ArrayList<>();

  LinkedList<ClassWrapperNode> stackNode = new LinkedList<>();
  LinkedList<Integer> stackIndex = new LinkedList<>();

  Set<ClassWrapperNode> setVisited = new HashSet<>();

  for (ClassWrapperNode root : roots) {
    stackNode.add(root);
    stackIndex.add(0);
  }

  while (!stackNode.isEmpty()) {
    ClassWrapperNode node = stackNode.getLast();
    int index = stackIndex.removeLast();

    setVisited.add(node);

    List<ClassWrapperNode> lstSubs = node.getSubclasses();

    for (; index < lstSubs.size(); index++) {
      ClassWrapperNode sub = lstSubs.get(index);
      if (!setVisited.contains(sub)) {
        stackIndex.add(index + 1);
        stackNode.add(sub);
        stackIndex.add(0);
        break;
      }
    }

    if (index == lstSubs.size()) {
      res.add(0, node);
      stackNode.removeLast();
    }
  }

  return res;
}
 
Example 6
Source File: SimpleTable.java    From w2j-cli with MIT License 5 votes vote down vote up
public SimpleTable addLine(String line) {
    if (table.isEmpty()) {
        throw new IllegalStateException("Table is empty. Call nextRow() first");
    }
    LinkedList<Collection<String>> row = table.getLast();
    if (row.isEmpty()) {
        throw new IllegalStateException("Row is empty.  Call nextCell() first");
    }
    Collection<String> cell = row.removeLast();
    cell = Cell.append(cell, line);
    row.add(cell);
    return this;
}
 
Example 7
Source File: Recycler.java    From CrossMobile with GNU Lesser General Public License v3.0 5 votes vote down vote up
public synchronized V get(C category) {
    LinkedList<V> cat = storage.get(category);
    if (cat == null || cat.isEmpty())
        return constructor == null ? null : constructor.invoke(category);
    V found = cat.removeLast();
    if (found != null)
        resurrect.invoke(found);
    return found;
}
 
Example 8
Source File: SocketIOWithTimeout.java    From big-c with Apache License 2.0 5 votes vote down vote up
/**
 * Takes one selector from end of LRU list of free selectors.
 * If there are no selectors awailable, it creates a new selector.
 * Also invokes trimIdleSelectors(). 
 * 
 * @param channel
 * @return 
 * @throws IOException
 */
private synchronized SelectorInfo get(SelectableChannel channel) 
                                                     throws IOException {
  SelectorInfo selInfo = null;
  
  SelectorProvider provider = channel.provider();
  
  // pick the list : rarely there is more than one provider in use.
  ProviderInfo pList = providerList;
  while (pList != null && pList.provider != provider) {
    pList = pList.next;
  }      
  if (pList == null) {
    //LOG.info("Creating new ProviderInfo : " + provider.toString());
    pList = new ProviderInfo();
    pList.provider = provider;
    pList.queue = new LinkedList<SelectorInfo>();
    pList.next = providerList;
    providerList = pList;
  }
  
  LinkedList<SelectorInfo> queue = pList.queue;
  
  if (queue.isEmpty()) {
    Selector selector = provider.openSelector();
    selInfo = new SelectorInfo();
    selInfo.selector = selector;
    selInfo.queue = queue;
  } else {
    selInfo = queue.removeLast();
  }
  
  trimIdleSelectors(Time.now());
  return selInfo;
}
 
Example 9
Source File: ApkToJarFormat.java    From ApkToJar with MIT License 5 votes vote down vote up
/**
 * 非递归方式删除文件夹
 */
public static boolean deleteDir(File dir, FileFilter filter) {
    if (dir.exists() && dir.isDirectory()) {
        LinkedList<File> linkedList = new LinkedList<File>();
        linkedList.addLast(dir);
        while (!linkedList.isEmpty()) {
            File dirTemp = linkedList.getLast();
            File[] files = dirTemp.listFiles(filter);
            if (files == null || files.length == 0) {
                System.out.println("[删除文件" + dirTemp + "]");
                if (dirTemp.delete()) {
                    linkedList.removeLast();
                }
            } else {
                for (File file : files) {
                    if (file.isDirectory()) {
                        linkedList.addLast(file);
                    } else {
                        System.out.println("[删除文件" + file + "]");
                        file.delete();
                    }
                }
            }
        }
    }
    return dir.exists();
}
 
Example 10
Source File: SimpleTable.java    From w2j-cli with MIT License 5 votes vote down vote up
public SimpleTable addLines(String...lines) {
    if (table.isEmpty()) {
        throw new IllegalStateException("Table is empty. Call nextRow() first");
    }
    LinkedList<Collection<String>> row = table.getLast();
    if (row.isEmpty()) {
        throw new IllegalStateException("Row is empty.  Call nextCell() first");
    }
    Collection<String> cell = row.removeLast();
    cell = Cell.append(cell, lines);
    row.add(cell);
    return this;
}
 
Example 11
Source File: SqlgSqlExecutor.java    From sqlg with MIT License 5 votes vote down vote up
public static void executeDropQuery(
        SqlgGraph sqlgGraph,
        SchemaTableTree rootSchemaTableTree,
        LinkedList<SchemaTableTree> distinctQueryStack) {

    sqlgGraph.getTopology().threadWriteLock();
    List<Triple<DROP_QUERY, String, Boolean>> sqls = rootSchemaTableTree.constructDropSql(distinctQueryStack);
    for (Triple<DROP_QUERY, String, Boolean> sqlPair : sqls) {
        DROP_QUERY dropQuery = sqlPair.getLeft();
        String sql = sqlPair.getMiddle();
        Boolean addAdditionalPartitionHasContainer = sqlPair.getRight();
        switch (dropQuery) {
            case ALTER:
            case TRUNCATE:
                executeDropQuery(sqlgGraph, sql, new LinkedList<>(), false);
                break;
            case EDGE:
                LinkedList<SchemaTableTree> tmp = new LinkedList<>(distinctQueryStack);
                tmp.removeLast();
                executeDropQuery(sqlgGraph, sql, tmp, false);
                break;
            case NORMAL:
                executeDropQuery(sqlgGraph, sql, distinctQueryStack, addAdditionalPartitionHasContainer);
                break;
            default:
                throw new IllegalStateException("Unknown DROP_QUERY " + dropQuery.toString());
        }
    }
}
 
Example 12
Source File: StorageManager.java    From blueflood with Apache License 2.0 5 votes vote down vote up
public StorageManager() throws IOException {
    this.maxBufferAge = config.getIntegerProperty(CloudfilesConfig.CLOUDFILES_MAX_BUFFER_AGE);
    this.maxBufferSize = config.getIntegerProperty(CloudfilesConfig.CLOUDFILES_MAX_BUFFER_SIZE);
    this.bufferDir = new File(config.getStringProperty(CloudfilesConfig.CLOUDFILES_BUFFER_DIR));
    this.uploadQueueDepthGauge = new Gauge<Integer>() {
        @Override
        public Integer getValue() {
            return done.size();
        }
    };

    Metrics.getRegistry().register(MetricRegistry.name(StorageManager.class, "Upload Queue Depth"), this.uploadQueueDepthGauge);

    if (!bufferDir.isDirectory()) {
        throw new IOException("Specified BUFFER_DIR is not a directory: " + bufferDir.getAbsolutePath());
    }

    File[] bufferFiles = bufferDir.listFiles(RollupFile.fileFilter);
    LinkedList<RollupFile> rollupFileList = new LinkedList<RollupFile>();

    // Build a list of all buffer files in the directory
    for (File bufferFile : bufferFiles) {
        rollupFileList.add(new RollupFile(bufferFile));
    }

    Collections.sort(rollupFileList);

    // Take the newest metric file as the "current" one, or make a new one if there are none
    if (!rollupFileList.isEmpty()) {
        current = rollupFileList.removeLast();
    } else {
        current = RollupFile.buildRollupFile(bufferDir);
    }

    // Queue the rest for upload
    done.addAll(rollupFileList);
}
 
Example 13
Source File: diff_match_patch.java    From webdsl with Apache License 2.0 4 votes vote down vote up
/**
 * Do a quick line-level diff on both strings, then rediff the parts for
 * greater accuracy.
 * This speedup can produce non-minimal diffs.
 * @param text1 Old string to be diffed.
 * @param text2 New string to be diffed.
 * @param deadline Time when the diff should be complete by.
 * @return Linked List of Diff objects.
 */
private LinkedList<Diff> diff_lineMode(String text1, String text2,
                                       long deadline) {
  // Scan the text on a line-by-line basis first.
  LinesToCharsResult b = diff_linesToChars(text1, text2);
  text1 = b.chars1;
  text2 = b.chars2;
  List<String> linearray = b.lineArray;

  LinkedList<Diff> diffs = diff_main(text1, text2, false, deadline);

  // Convert the diff back to original text.
  diff_charsToLines(diffs, linearray);
  // Eliminate freak matches (e.g. blank lines)
  diff_cleanupSemantic(diffs);

  // Rediff any replacement blocks, this time character-by-character.
  // Add a dummy entry at the end.
  diffs.add(new Diff(Operation.EQUAL, ""));
  int count_delete = 0;
  int count_insert = 0;
  String text_delete = "";
  String text_insert = "";
  ListIterator<Diff> pointer = diffs.listIterator();
  Diff thisDiff = pointer.next();
  while (thisDiff != null) {
    switch (thisDiff.operation) {
    case INSERT:
      count_insert++;
      text_insert += thisDiff.text;
      break;
    case DELETE:
      count_delete++;
      text_delete += thisDiff.text;
      break;
    case EQUAL:
      // Upon reaching an equality, check for prior redundancies.
      if (count_delete >= 1 && count_insert >= 1) {
        // Delete the offending records and add the merged ones.
        pointer.previous();
        for (int j = 0; j < count_delete + count_insert; j++) {
          pointer.previous();
          pointer.remove();
        }
        for (Diff newDiff : diff_main(text_delete, text_insert, false,
            deadline)) {
          pointer.add(newDiff);
        }
      }
      count_insert = 0;
      count_delete = 0;
      text_delete = "";
      text_insert = "";
      break;
    }
    thisDiff = pointer.hasNext() ? pointer.next() : null;
  }
  diffs.removeLast();  // Remove the dummy entry at the end.

  return diffs;
}
 
Example 14
Source File: Warlight2.java    From warlight2-engine with Apache License 2.0 4 votes vote down vote up
/**
 * Turns the game that is stored in the processor to a nice string for the visualization
 * @param winner : winner
 * @param gameView : type of view
 * @return : string that the visualizer can read
 */
private String getPlayedGame(Player winner, String gameView)
{
	StringBuilder out = new StringBuilder();		

	LinkedList<MoveResult> playedGame;
	if(gameView.equals("player1"))
		playedGame = this.processor.getPlayer1PlayedGame();
	else if(gameView.equals("player2"))
		playedGame = this.processor.getPlayer2PlayedGame();
	else
		playedGame = this.processor.getFullPlayedGame();
		
	playedGame.removeLast();
	int roundNr = 0;
	for(MoveResult moveResult : playedGame)
	{
		if(moveResult != null)
		{
			if(moveResult.getMove() != null)
			{
				try {
					PlaceArmiesMove plm = (PlaceArmiesMove) moveResult.getMove();
					out.append(plm.getString() + "\n");
				}
				catch(Exception e) {
					AttackTransferMove atm = (AttackTransferMove) moveResult.getMove();
					out.append(atm.getString() + "\n");
				}
				
			}
			out.append("map " + moveResult.getMap().getMapString() + "\n");
		}
		else
		{
			out.append("round " + roundNr + "\n");
			roundNr++;
		}
	}
	
	if(winner != null)
		out.append(winner.getName() + " won\n");
	else
		out.append("Nobody won\n");

	return out.toString();
}
 
Example 15
Source File: TextDiffMatcher.java    From translationstudio8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Do a quick line-level diff on both strings, then rediff the parts for
 * greater accuracy.
 * This speedup can produce non-minimal diffs.
 * @param text1 Old string to be diffed.
 * @param text2 New string to be diffed.
 * @param deadline Time when the diff should be complete by.
 * @return Linked List of Diff objects.
 */
private LinkedList<Diff> diff_lineMode(String text1, String text2,
                                       long deadline) {
  // Scan the text on a line-by-line basis first.
  LinesToCharsResult b = diff_linesToChars(text1, text2);
  text1 = b.chars1;
  text2 = b.chars2;
  List<String> linearray = b.lineArray;

  LinkedList<Diff> diffs = diff_main(text1, text2, false, deadline);

  // Convert the diff back to original text.
  diff_charsToLines(diffs, linearray);
  // Eliminate freak matches (e.g. blank lines)
  diff_cleanupSemantic(diffs);

  // Rediff any replacement blocks, this time character-by-character.
  // Add a dummy entry at the end.
  diffs.add(new Diff(Operation.EQUAL, ""));
  int count_delete = 0;
  int count_insert = 0;
  String text_delete = "";
  String text_insert = "";
  ListIterator<Diff> pointer = diffs.listIterator();
  Diff thisDiff = pointer.next();
  while (thisDiff != null) {
    switch (thisDiff.operation) {
    case INSERT:
      count_insert++;
      text_insert += thisDiff.text;
      break;
    case DELETE:
      count_delete++;
      text_delete += thisDiff.text;
      break;
    case EQUAL:
      // Upon reaching an equality, check for prior redundancies.
      if (count_delete >= 1 && count_insert >= 1) {
        // Delete the offending records and add the merged ones.
        pointer.previous();
        for (int j = 0; j < count_delete + count_insert; j++) {
          pointer.previous();
          pointer.remove();
        }
        for (Diff newDiff : diff_main(text_delete, text_insert, false,
            deadline)) {
          pointer.add(newDiff);
        }
      }
      count_insert = 0;
      count_delete = 0;
      text_delete = "";
      text_insert = "";
      break;
    }
    thisDiff = pointer.hasNext() ? pointer.next() : null;
  }
  diffs.removeLast();  // Remove the dummy entry at the end.

  return diffs;
}
 
Example 16
Source File: TextDiff.java    From JDeodorant with MIT License 4 votes vote down vote up
/**
 * Do a quick line-level ca.concordia.jdeodorant.eclipse.commandline.diff on both strings, then rediff the parts for
 * greater accuracy.
 * This speedup can produce non-minimal diffs.
 * @param text1 Old string to be diffed.
 * @param text2 New string to be diffed.
 * @param deadline Time when the ca.concordia.jdeodorant.eclipse.commandline.diff should be complete by.
 * @return Linked List of Diff objects.
 */
private LinkedList<Diff> diff_lineMode(String text1, String text2,
                                       long deadline) {
  // Scan the text on a line-by-line basis first.
  LinesToCharsResult b = diff_linesToChars(text1, text2);
  text1 = b.chars1;
  text2 = b.chars2;
  List<String> linearray = b.lineArray;

  LinkedList<Diff> diffs = diff_main(text1, text2, false, deadline);

  // Convert the ca.concordia.jdeodorant.eclipse.commandline.diff back to original text.
  diff_charsToLines(diffs, linearray);
  // Eliminate freak matches (e.g. blank lines)
  diff_cleanupSemantic(diffs);

  // Rediff any replacement blocks, this time character-by-character.
  // Add a dummy entry at the end.
  diffs.add(new Diff(Operation.EQUAL, ""));
  int count_delete = 0;
  int count_insert = 0;
  String text_delete = "";
  String text_insert = "";
  ListIterator<Diff> pointer = diffs.listIterator();
  Diff thisDiff = pointer.next();
  while (thisDiff != null) {
    switch (thisDiff.operation) {
    case INSERT:
      count_insert++;
      text_insert += thisDiff.text;
      break;
    case DELETE:
      count_delete++;
      text_delete += thisDiff.text;
      break;
    case EQUAL:
      // Upon reaching an equality, check for prior redundancies.
      if (count_delete >= 1 && count_insert >= 1) {
        // Delete the offending records and add the merged ones.
        pointer.previous();
        for (int j = 0; j < count_delete + count_insert; j++) {
          pointer.previous();
          pointer.remove();
        }
        for (Diff newDiff : diff_main(text_delete, text_insert, false,
            deadline)) {
          pointer.add(newDiff);
        }
      }
      count_insert = 0;
      count_delete = 0;
      text_delete = "";
      text_insert = "";
      break;
    }
    thisDiff = pointer.hasNext() ? pointer.next() : null;
  }
  diffs.removeLast();  // Remove the dummy entry at the end.

  return diffs;
}
 
Example 17
Source File: NetworkPacket.java    From sdn-wise-java with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Returns a NetworkPacket given a BufferedInputStream. It supports
 * streams where there could be bytes not belonging to a packet or
 * malformed packets.
 *
 * @param bis the BufferedInputStream
 */
public NetworkPacket(final BufferedInputStream bis) throws IOException {
    data = new byte[MAX_PACKET_LENGTH];
    boolean startFlag = false;
    boolean idFlag = false;
    boolean found = false;
    int expected = 0;
    int b;
    byte a;
    final LinkedList<Byte> receivedBytes = new LinkedList<>();
    final LinkedList<Byte> packet = new LinkedList<>();
    byte startByte = 0x7A;
    byte stopByte = 0x7E;


    while (!found && (b = bis.read()) != -1) {
        receivedBytes.add((byte) b);
        while (!receivedBytes.isEmpty()) {
            a = receivedBytes.poll();
            if (!startFlag && a == startByte) {
                startFlag = true;
                packet.add(a);
            } else if (startFlag && !idFlag) {
                packet.add(a);
                idFlag = true;
            } else if (startFlag && idFlag && expected == 0) {
                expected = Byte.toUnsignedInt(a);
                packet.add(a);
            } else if (startFlag && idFlag && expected > 0
                    && packet.size() < expected + 1) {
                packet.add(a);
            } else if (startFlag && idFlag && expected > 0
                    && packet.size() == expected + 1) {
                packet.add(a);
                if (a == stopByte) {
                    packet.removeFirst();
                    packet.removeLast();
                    byte[] tmpData = new byte[packet.size()];
                    for (int i = 0; i < tmpData.length; i++) {
                        tmpData[i] = packet.poll();
                    }
                    setArray(tmpData);
                    found = true;
                    break;
                } else {
                    while (!packet.isEmpty()) {
                        receivedBytes.addFirst(packet.removeLast());
                    }
                    receivedBytes.poll();
                }
                startFlag = false;
                idFlag = false;
                expected = 0;
            }
        }
    }
}
 
Example 18
Source File: ControlFlowGraph.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
private void setSubroutineEdges() {

        final Map<BasicBlock, BasicBlock> subroutines = new LinkedHashMap<>();

        for (BasicBlock block : blocks) {

            if (block.getSeq().getLastInstr().opcode == CodeConstants.opc_jsr) {

                LinkedList<BasicBlock> stack = new LinkedList<>();
                LinkedList<LinkedList<BasicBlock>> stackJsrStacks = new LinkedList<>();

                Set<BasicBlock> setVisited = new HashSet<>();

                stack.add(block);
                stackJsrStacks.add(new LinkedList<BasicBlock>());

                while (!stack.isEmpty()) {

                    BasicBlock node = stack.removeFirst();
                    LinkedList<BasicBlock> jsrstack = stackJsrStacks.removeFirst();

                    setVisited.add(node);

                    switch (node.getSeq().getLastInstr().opcode) {
                        case CodeConstants.opc_jsr:
                            jsrstack.add(node);
                            break;
                        case CodeConstants.opc_ret:
                            BasicBlock enter = jsrstack.getLast();
                            BasicBlock exit = blocks.getWithKey(enter.id + 1); // FIXME: find successor in a better way

                            if (exit != null) {
                                if (!node.isSuccessor(exit)) {
                                    node.addSuccessor(exit);
                                }
                                jsrstack.removeLast();
                                subroutines.put(enter, exit);
                            } else {
                                throw new RuntimeException("ERROR: last instruction jsr");
                            }
                    }

                    if (!jsrstack.isEmpty()) {
                        for (BasicBlock succ : node.getSuccs()) {
                            if (!setVisited.contains(succ)) {
                                stack.add(succ);
                                stackJsrStacks.add(new LinkedList<>(jsrstack));
                            }
                        }
                    }
                }
            }
        }

        this.subroutines = subroutines;
    }
 
Example 19
Source File: AbstractSecs2.java    From secs4java8 with Apache License 2.0 4 votes vote down vote up
@Override
public final float getFloat(int... indices) throws Secs2Exception {
	LinkedList<Integer> list = createLinkedList(indices);
	int lastIndex = list.removeLast();
	return get(list).getFloat(lastIndex);
}
 
Example 20
Source File: DiffMatchPatch.java    From titan-hotfix with Apache License 2.0 4 votes vote down vote up
/**
 * Do a quick line-level diff on both strings, then rediff the parts for
 * greater accuracy.
 * This speedup can produce non-minimal diffs.
 *
 * @param text1    Old string to be diffed.
 * @param text2    New string to be diffed.
 * @param deadline Time when the diff should be complete by.
 * @return Linked List of Diff objects.
 */
private LinkedList<Diff> diffLineMode(String text1, String text2,
                                      long deadline) {
    // Scan the text on a line-by-line basis first.
    LinesToCharsResult a = diffLinesToChars(text1, text2);
    text1 = a.chars1;
    text2 = a.chars2;
    List<String> linearray = a.lineArray;

    LinkedList<Diff> diffs = diffMain(text1, text2, false, deadline);

    // Convert the diff back to original text.
    diffCharsToLines(diffs, linearray);
    // Eliminate freak matches (e.g. blank lines)
    diffCleanupSemantic(diffs);

    // Rediff any replacement blocks, this time character-by-character.
    // Add a dummy entry at the end.
    diffs.add(new Diff(Operation.EQUAL, ""));
    int countDelete = 0;
    int countInsert = 0;
    String textDelete = "";
    String textInsert = "";
    ListIterator<Diff> pointer = diffs.listIterator();
    Diff thisDiff = pointer.next();
    while (thisDiff != null) {
        switch (thisDiff.operation) {
            case INSERT:
                countInsert++;
                textInsert += thisDiff.text;
                break;
            case DELETE:
                countDelete++;
                textDelete += thisDiff.text;
                break;
            case EQUAL:
                // Upon reaching an equality, check for prior redundancies.
                if (countDelete >= 1 && countInsert >= 1) {
                    // Delete the offending records and add the merged ones.
                    pointer.previous();
                    for (int j = 0; j < countDelete + countInsert; j++) {
                        pointer.previous();
                        pointer.remove();
                    }
                    for (Diff subDiff : diffMain(textDelete, textInsert, false,
                            deadline)) {
                        pointer.add(subDiff);
                    }
                }
                countInsert = 0;
                countDelete = 0;
                textDelete = "";
                textInsert = "";
                break;
            default:
                throw new RuntimeException();
        }
        thisDiff = pointer.hasNext() ? pointer.next() : null;
    }
    diffs.removeLast();  // Remove the dummy entry at the end.

    return diffs;
}