// prepositional phrase
private void findActionVerbsAndArguments(TreeGraphNode node, 
			Map<Pair<Integer, Integer>, String> edge_rels,
			Map<TreeGraphNode, Set<TreeGraphNode>> node_to_deps,
			Map<TreeGraphNode, TreeGraphNode> dep_to_gov,
			String root_type,
			List<Tree> leaves,
			List<String> lemmas, List<Label> tags, List<HasWord> words,
			String recipe_name, int sentence_idx, int curr_sentence_char_offset, 
			String sentence_string, TreeMap<Integer, RecipeEvent> predicate_idx_to_event) {
		String node_string = node.nodeString();
		int index = node.index();
		Label tag = tags.get(index - 1);
		int hw_character_offset = charOffset(leaves.get(index - 1));
		// Find the no-space character offset of the predicate
		int no_space_character_offset = hw_character_offset;
		String sentence_prefix = sentence_string.substring(0, hw_character_offset);
		while (sentence_prefix.contains(" I would ")) {
			no_space_character_offset -= 9;
			sentence_prefix = sentence_prefix.replaceFirst(" I would ", "");
		}
		while (sentence_prefix.contains("I would ")) {
			no_space_character_offset -= 8;
			sentence_prefix = sentence_prefix.replaceFirst("I would ", "");
		}
		while (sentence_prefix.contains(" ")) {
			no_space_character_offset--;
			sentence_prefix = sentence_prefix.replaceFirst(" ", "");
		}
		if (tag.value().startsWith("V")) {
			Set<TreeGraphNode> deps = node_to_deps.get(node);
			if (deps == null) {
				System.out.println(node + " " + deps);
				// Create RecipeEvent
				RecipeEvent event = new RecipeEvent(node_string.toLowerCase(), recipe_name, sentence_idx, curr_sentence_char_offset + no_space_character_offset);
				predicate_idx_to_event.put(hw_character_offset, event);
				return;
			}
			// check for pcomp
			boolean has_pcomp = false;
			TreeGraphNode pcomp = null;
			for (TreeGraphNode dep3 : deps) {
				String rel_string2 = edge_rels.get(new Pair<Integer, Integer>(hw_character_offset, charOffset(dep3)));
				if (rel_string2.equals("pcomp")) {
					has_pcomp = true;
					pcomp = dep3;
					break;
				}
			}
			if (has_pcomp) {
				System.out.println("has pcomp");
				TreeGraphNode grandgov = dep_to_gov.get(node);
				if (grandgov != null) {
					int grandgov_index = grandgov.index();
					RecipeEvent grandevent = predicate_idx_to_event.get(grandgov_index);
					if (grandevent != null) {
						Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(node, node_to_deps, edge_rels, lemmas, tags, words, true);
						grandevent.addPrepositionalArgument(hw_character_offset, args.getFirst(), pcomp.nodeString());
					}
				}
				return;
			}
			// Create RecipeEvent
			RecipeEvent event = new RecipeEvent(node_string.toLowerCase(), recipe_name, sentence_idx, curr_sentence_char_offset + no_space_character_offset);
			boolean has_subj = false;
			TreeGraphNode subj = null;
			for (TreeGraphNode dep : deps) {
				String rel_string2 = edge_rels.get(new Pair<Integer, Integer>(hw_character_offset, charOffset(dep)));
				if (rel_string2.equals("nsubj") && !root_type.equals("SINV")) {
					has_subj = true;
					subj = dep;
					break;
				}
			}
			// If the verb has a subject other than "I", assume parse error and add the subject as an argument.
			if (has_subj && !root_type.equals("SINV")) {
				System.out.println(has_subj + " " + root_type);
				if (!subj.nodeString().equals("I")) {
					Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(node, node_to_deps, edge_rels, lemmas, tags, words, false);
					String arg_string = args.getFirst();
					Set<TreeGraphNode> verbs = args.getSecond();
					if (verbs.size() == 1) {
						TreeGraphNode verb = verbs.iterator().next();
						dep_to_gov.put(verb, node);
						findActionVerbsAndArguments(verb, edge_rels, node_to_deps, dep_to_gov, "", leaves, lemmas, tags, words, recipe_name, sentence_idx,
								curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
						RecipeEvent dep_event = predicate_idx_to_event.get(charOffset(leaves.get(verb.index() - 1)));
						if (dep_event != null) {
							String[] split = arg_string.split(" ");
							int found = -1;
							for (int i = 0; i < split.length; i++) {
								if (split[i].equals(node.nodeString())) {
									found = i;
									break;
								}
							}
							if (tags.get(index - found - 1).value().equals("IN")) {
								dep_event.addPrepositionalArgument(hw_character_offset, arg_string);
							} else {
								dep_event.addOtherArgument(hw_character_offset, arg_string);
							}
						}
					} else {
						// TODO(chloe): do something else in this case?
						for (TreeGraphNode verb : verbs) {
							dep_to_gov.put(verb, node);
							findActionVerbsAndArguments(verb, edge_rels, node_to_deps, dep_to_gov, "", leaves, lemmas, tags, words, recipe_name, sentence_idx,
									curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
						}
					}
					return;
				}
			}
			// Search through the dependents of the verb and add each expanded dependent as an argument.
			Set<TreeGraphNode> new_deps = new HashSet<TreeGraphNode>(deps);
			TreeGraphNode pobj = null;
			while (new_deps.size() != 0) {
				List<TreeGraphNode> deps_list = new ArrayList<TreeGraphNode>(new_deps);
				new_deps.clear();
				for (TreeGraphNode dep : deps_list) {
					TreeGraphNode gov = dep_to_gov.get(dep);
					if (gov == null) {
						gov = node;
					}
					int gov_index = index;
					int gov_hw_offset = hw_character_offset;
					String gov_string = node_string;
					if (gov != null) {
						gov_index = gov.index();
						gov_hw_offset = charOffset(leaves.get(gov_index - 1));
						gov_string = gov.nodeString();
					}
					int dep_index = dep.index();
					int dep_hw_offset = charOffset(leaves.get(dep_index - 1));
					String dep_string = dep.nodeString();
					if (dep.nodeString().equals("would")) {
						continue;
					}
					String rel_string = edge_rels.get(new Pair<Integer, Integer>(gov_hw_offset, dep_hw_offset));
					if (rel_string.startsWith("nsubj") && !root_type.equals("SINV") && (gov == node || dep.nodeString().equals("I"))) {
						// skip subjects
						continue;
					}
					if (rel_string.startsWith("pobj")) {
						// Store the prepositional object, but ignore for now. We will deal with it when the
						// prepositional phrase is found.
						pobj = dep;
						continue;
					}
					// For vmod and xcomp edges, create an argument for the current verb
					if (rel_string.equals("vmod") || rel_string.equals("xcomp")) {
						Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(dep, node_to_deps, edge_rels, lemmas, tags, words, true);
						String arg_string = args.getFirst();
						String[] split = arg_string.split(" ");
						int found = -1;
						for (int i = 0; i < split.length; i++) {
							if (split[i].equals(dep.nodeString())) {
								found = i;
								break;
							}
						}
						if (found != -1) {
							if (tags.get(dep_index - found - 1).value().equals("IN")) {
								event.addPrepositionalArgument(dep_hw_offset, arg_string);
							} else {
								event.addOtherArgument(dep_hw_offset, arg_string);
							}
						}
						continue;
					}
					// Deal with prepositional phrases and determining whether or not a dependent verb is a new verb or
					// part of the current verb. Uses heuristics to find out.
					boolean is_prep = rel_string.startsWith("prep") || tags.get(dep_index - 1).value().equals("IN");
					Label dep_tag = tags.get(dep_index - 1);
					if (dep_tag.value().startsWith("V") && !is_prep && !rel_string.equals("advcl")
							) {
						if (dep_index == index + 2 && rel_string.startsWith("conj")) {
							int underscore = rel_string.indexOf('_');
							String conj_string = rel_string.substring(underscore + 1);
							node_string += " " + conj_string + " " + dep_string;
							Set<TreeGraphNode> depdeps = node_to_deps.get(dep);
							if (depdeps != null) {
								new_deps.addAll(depdeps);
								for (TreeGraphNode depdep : depdeps) {
									dep_to_gov.put(depdep, dep);
								}
							}
							event.addVerbToPredicate(dep.nodeString(), conj_string, (dep.index() > gov_index));
						} else if (rel_string.startsWith("conj") || rel_string.equals("parataxis") || rel_string.equals("dep")) {
							Set<TreeGraphNode> depdeps = node_to_deps.get(dep);
							has_subj = false;
							if (depdeps != null) {
								for (TreeGraphNode depdep : depdeps) {
									String rel_string2 = edge_rels.get(new Pair<Integer, Integer>(dep_hw_offset, charOffset(leaves.get(depdep.index() - 1))));
									if (rel_string2.equals("nsubj")) {
										has_subj = true;
										break;
									}
								}
								if (has_subj) {
									Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(dep, node_to_deps, edge_rels, lemmas, tags, words, true);
									String arg_string = args.getFirst();
									String[] split = arg_string.split(" ");
									int found = -1;
									for (int i = 0; i < split.length; i++) {
										if (split[i].equals(dep.nodeString())) {
											found = i;
											break;
										}
									}
									if (found != -1) {
										if (tags.get(dep_index - found - 1).value().equals("IN")) {
											event.addPrepositionalArgument(dep_hw_offset, arg_string);
										} else {
											event.addOtherArgument(dep_hw_offset, arg_string);
										}
									}
								} else {
									findActionVerbsAndArguments(dep, edge_rels, node_to_deps, dep_to_gov, "", leaves, lemmas, tags, words, recipe_name, sentence_idx,
											curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
								}
							}
						} else {
							Set<TreeGraphNode> depdeps = node_to_deps.get(dep);
							if (depdeps != null) {
								new_deps.addAll(depdeps);
								for (TreeGraphNode depdep : depdeps) {
									dep_to_gov.put(depdep, dep);
								}
							}
							event.addVerbToPredicate(dep.nodeString(), "", (dep.index() > gov_index));
						}
					} else {  // prepositional phrase
						Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(dep, node_to_deps, edge_rels, lemmas, tags, words, is_prep || rel_string.equals("dobj"));
						String arg_string = args.getFirst();
						for (TreeGraphNode verb : args.getSecond()) {
							findActionVerbsAndArguments(verb, edge_rels, node_to_deps, dep_to_gov, "", leaves, lemmas, tags, words, recipe_name, sentence_idx,
									curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
						}
						if (is_prep) {
							String pobj_arg_string = null;
							if (pobj != null) {
								args = getTreeGraphString(pobj, node_to_deps, edge_rels, lemmas, tags, words, is_prep);
								pobj_arg_string = args.getFirst();
								for (TreeGraphNode verb : args.getSecond()) {
									findActionVerbsAndArguments(verb, edge_rels, node_to_deps, dep_to_gov, "" , leaves, lemmas, tags, words, recipe_name, sentence_idx,
											curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
								}
							} else {
								for (TreeGraphNode dep2 : deps_list) {
									TreeGraphNode gov2 = dep_to_gov.get(dep2);
									if (gov2 == null) {
										gov2 = gov;
									}
									String rel_string2 = edge_rels.get(new Pair<Integer, Integer>(charOffset(leaves.get(gov2.index() - 1)), charOffset(leaves.get(dep2.index() - 1))));
									if (rel_string2.equals("pobj")) {
										args = getTreeGraphString(dep2, node_to_deps, edge_rels, lemmas, tags, words, is_prep);
										pobj_arg_string = args.getFirst();
										for (TreeGraphNode verb : args.getSecond()) {
											findActionVerbsAndArguments(verb, edge_rels, node_to_deps, dep_to_gov, "", leaves, lemmas, tags, words, recipe_name, sentence_idx,
													curr_sentence_char_offset, sentence_string, predicate_idx_to_event);
										}
										break;
									}
								}
							}
							// Find the true preposition from the collapsed dependency relation
							int underscore = rel_string.indexOf('_');
							if (underscore != -1) {
								String prep_string = rel_string.substring(underscore + 1);
								prep_string = prep_string.replace('_', ' ');
								if (pobj_arg_string != null) {
									if (prep_string.contains(arg_string)) {
										arg_string = prep_string + " " + pobj_arg_string;
									} else {
										arg_string = prep_string + " " + arg_string + " " + pobj_arg_string;
									}
								} else {
									arg_string = prep_string + " " + arg_string;
								}
							}
							event.addPrepositionalArgument(dep_hw_offset, arg_string);
						} else if (rel_string.equals("dobj") || rel_string.equals("nsubj")) {
							//							event.setDirectObject(arg_string);
							String[] split = arg_string.split(" ");
							int found = -1;
							for (int i = 0; i < split.length; i++) {
								if (split[i].equals(dep.nodeString())) {
									found = i;
									break;
								}
							}
							if (found != -1) {
								System.out.println("DIRECTOBJECT " + arg_string);
								if (tags.get(dep_index - found - 1).value().equals("IN")) {
									event.addPrepositionalArgument(dep_hw_offset, arg_string);
								} else {
									if (arg_string.contains("minutes") || arg_string.contains("hours")) {
										event.addPrepositionalArgument(dep_hw_offset, arg_string, "for");
									} else {
										event.setDirectObject(arg_string);
									}
								}
							}
						} else {
							String[] split = arg_string.split(" ");
							int found = -1;
							for (int i = 0; i < split.length; i++) {
								if (split[i].equals(dep.nodeString())) {
									found = i;
									break;
								}
							}
							if (found != -1) {
								if (tags.get(dep_index - found - 1).value().equals("IN")) {
									System.out.println("prep");
									event.addPrepositionalArgument(dep_hw_offset, arg_string);
								} else {
									event.addOtherArgument(dep_hw_offset, arg_string);
								}
							}
						}
					}
				}
			}
			System.out.println(event);
			predicate_idx_to_event.put(index, event);
		} else {
			// This method should not be called if the node is not a verb.
			//
			// Not sure if this happens, so I will currently have it crash so I can investigate it.
			Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(node, node_to_deps, edge_rels, lemmas, tags, words, false);
			String arg_string = args.getFirst();
			Set<TreeGraphNode> verbs = args.getSecond();
			System.out.println(arg_string);
			System.out.println("getting args error");
			System.exit(1);
		}
	}
if (rel_string.startsWith("pobj")) {
// Store the prepositional object, but ignore for now. We will deal with it when the
// prepositional phrase is found.
pobj = dep;
continue;
if (dep.nodeString().equals("would")) {
continue;
}
String rel_string = edge_rels.get(new Pair<Integer, Integer>(gov_hw_offset, dep_hw_offset));
if (rel_string.startsWith("nsubj") && !root_type.equals("SINV") && (gov == node || dep.nodeString().equals("I"))) {
// skip subjects
continue;
}
if (rel_string.startsWith("pobj")) {
// Store the prepositional object, but ignore for now. We will deal with it when the
// prepositional phrase is found.
pobj = dep;
continue;
}
// For vmod and xcomp edges, create an argument for the current verb
if (rel_string.equals("vmod") || rel_string.equals("xcomp")) {
Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(dep, node_to_deps, edge_rels, lemmas, tags, words, true);
String arg_string = args.getFirst();
String[] split = arg_string.split(" ");
int found = -1;
for (int i = 0; i < split.length; i++) {
int gov_hw_offset = hw_character_offset;
String gov_string = node_string;
if (gov != null) {
gov_index = gov.index();
gov_hw_offset = charOffset(leaves.get(gov_index - 1));
gov_string = gov.nodeString();
}
int dep_index = dep.index();
int dep_hw_offset = charOffset(leaves.get(dep_index - 1));
String dep_string = dep.nodeString();
if (dep.nodeString().equals("would")) {
continue;
}
String rel_string = edge_rels.get(new Pair<Integer, Integer>(gov_hw_offset, dep_hw_offset));
if (rel_string.startsWith("nsubj") && !root_type.equals("SINV") && (gov == node || dep.nodeString().equals("I"))) {
// skip subjects
continue;
}
if (rel_string.startsWith("pobj")) {
// Store the prepositional object, but ignore for now. We will deal with it when the
// prepositional phrase is found.
pobj = dep;
continue;
}
// For vmod and xcomp edges, create an argument for the current verb
if (rel_string.equals("vmod") || rel_string.equals("xcomp")) {
Pair<String, Set<TreeGraphNode>> args = getTreeGraphString(dep, node_to_deps, edge_rels, lemmas, tags, words, true);
String arg_string = args.getFirst();
String[] split = arg_string.split(" ");
int found = -1;
for (int i = 0; i < split.length; i++) {
if (split[i].equals(dep.nodeString())) {
found = i;
break;
}
}
if (found != -1) {
if (tags.get(dep_index - found - 1).value().equals("IN")) {
event.addPrepositionalArgument(dep_hw_offset, arg_string);
} else {
event.addOtherArgument(dep_hw_offset, arg_string);