	/**
	 * Parses the XML document. As elements are loaded, if they match, they are sent to the listeners that match the
	 * element.
	 *
	 * @throws SAXException
	 * @throws IOException
	 */
	public void parse() throws SAXException, IOException {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser saxParser;
		try {
			saxParser = factory.newSAXParser();
		} catch (ParserConfigurationException | SAXException ex) {
			throw new RuntimeException(ex);
		}
		saxParser.parse(stream, new DefaultHandler() {
			Stack<String> nodeNames = new Stack<>();
			Stack<Map<String, AtomicInteger>> nodeCount = new Stack<>();
			String lastElement = "";
			Map<String, StringBuilder> contents = new HashMap<>();
			Stack<Attributes> attributeStack = new Stack<>();

			@Override
			public void startDocument() throws SAXException {
				nodeCount.push(new HashMap<>());
			}

			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
				nodeNames.push(qName);
				Map<String, AtomicInteger> c = nodeCount.peek();
				if(!c.containsKey(qName)) {
					c.put(qName, new AtomicInteger(1));
				} else {
					c.get(qName).incrementAndGet();
				}
				Map<String, AtomicInteger> counts = new HashMap<>();
				nodeCount.push(counts);
				if(!contents.isEmpty()) {
					StringBuilder b = new StringBuilder();
					b.append("<").append(qName).append("");
					for(int i = 0; i < attributes.getLength(); i++) {
						b.append(" ").append(attributes.getQName(i))
								.append("=\"").append(attributes.getValue(i).replace("\"", """)).append("\"");
					}
					b.append(">");
					appendAll(b.toString());
				}
				String path = pathFromMarkers(nodeNames, nodeCount);
				if(hasListener(path)) {
					contents.put(getListenerPath(path), new StringBuilder());
					attributeStack.push(attributes);
				}
			}

			@Override
			public void characters(char[] ch, int start, int length) throws SAXException {
				if(!contents.isEmpty()) {
					String s = fromChars(ch, start, length);
					appendAll(s);
				}
			}

			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				String path = pathFromMarkers(nodeNames, nodeCount);
				if(hasListener(path)) {
					String key = getListenerPath(path);
					StringBuilder b = contents.remove(key);
					Attributes attr = attributeStack.pop();
					Map<String, String> attributes = new LinkedHashMap<>();
					for(int i = 0; i < attr.getLength(); i++) {
						attributes.put(attr.getQName(i), attr.getValue(i));
					}
					notifyListeners(path, qName, attributes, b.toString());
				}
				if(!contents.isEmpty()) {
					appendAll("</" + qName + ">");
				}

				nodeNames.pop();
				nodeCount.pop();
			}

			private void appendAll(String s) {
				for(StringBuilder b : contents.values()) {
					b.append(s);
				}
			}

		});
	}

	/**
	 * Parses the XML document. As elements are loaded, if they match, they are sent to the listeners that match the
	 * element.
	 *
	 * @throws SAXException
	 * @throws IOException
	 */
	public void parse() throws SAXException, IOException {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser saxParser;
		try {
			saxParser = factory.newSAXParser();
		} catch (ParserConfigurationException | SAXException ex) {
			throw new RuntimeException(ex);
		}
		saxParser.parse(stream, new DefaultHandler() {
			Stack<String> nodeNames = new Stack<>();
			Stack<Map<String, AtomicInteger>> nodeCount = new Stack<>();
			String lastElement = "";
			Map<String, StringBuilder> contents = new HashMap<>();
			Stack<Attributes> attributeStack = new Stack<>();

			@Override
			public void startDocument() throws SAXException {
				nodeCount.push(new HashMap<String, AtomicInteger>());
			}

			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
				nodeNames.push(qName);
				Map<String, AtomicInteger> c = nodeCount.peek();
				if(!c.containsKey(qName)) {
					c.put(qName, new AtomicInteger(1));
				} else {
					c.get(qName).incrementAndGet();
				}
				Map<String, AtomicInteger> counts = new HashMap<>();
				nodeCount.push(counts);
				if(!contents.isEmpty()) {
					StringBuilder b = new StringBuilder();
					b.append("<").append(qName).append("");
					for(int i = 0; i < attributes.getLength(); i++) {
						b.append(" ").append(attributes.getQName(i))
								.append("=\"").append(attributes.getValue(i).replace("\"", """)).append("\"");
					}
					b.append(">");
					appendAll(b.toString());
				}
				String path = pathFromMarkers(nodeNames, nodeCount);
				if(hasListener(path)) {
					contents.put(getListenerPath(path), new StringBuilder());
					attributeStack.push(attributes);
				}
			}

			@Override
			public void characters(char[] ch, int start, int length) throws SAXException {
				if(!contents.isEmpty()) {
					String s = fromChars(ch, start, length);
					appendAll(s);
				}
			}

			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				String path = pathFromMarkers(nodeNames, nodeCount);
				if(hasListener(path)) {
					String key = getListenerPath(path);
					StringBuilder b = contents.remove(key);
					Attributes attr = attributeStack.pop();
					Map<String, String> attributes = new LinkedHashMap<>();
					for(int i = 0; i < attr.getLength(); i++) {
						attributes.put(attr.getQName(i), attr.getValue(i));
					}
					notifyListeners(path, qName, attributes, b.toString());
				}
				if(!contents.isEmpty()) {
					appendAll("</" + qName + ">");
				}

				nodeNames.pop();
				nodeCount.pop();
			}

			private void appendAll(String s) {
				for(StringBuilder b : contents.values()) {
					b.append(s);
				}
			}

		});
	}

Replace Generic With Diamond HashMap<String,AtomicInteger> with HashMap<> in method public parse() : void from class com.laytonsmith.PureUtilities.SAXDocument


	/**
	 * Writes an arbitrary stream to a file on the remote.
	 *
	 * @param contents The input stream to write
	 * @param toLocation The location to write to
	 */
	private void writeFromStream(final InputStream contents, final String toLocation) {
		uploadQueue.submit(() -> {
			try {
				writeStatus("Currently uploading " + toLocation);
				// Read the contents only once
				byte[] c = StreamUtils.GetBytes(contents);
				contents.close();
				boolean skipUpload = false;
				String hash = null;
				if(pn != null) {
					if(notificationAboutLocalCache) {
						hash = getLocalMD5(new ByteArrayInputStream(c));
						try {
							if(lc.containsKey(deploymentMethod.getID() + toLocation)) {
								if(useLocalCache) {
									String cacheHash = lc.get(deploymentMethod.getID() + toLocation);
									if(cacheHash.equals(hash)) {
										skipUpload = true;
									}
								}
							}
						} catch (IllegalArgumentException ex) {
							writeLog("Could not use local cache", ex);
							notificationAboutLocalCache = false;
						}
					}
				}
				if(!skipUpload && deploymentMethod.deploy(new ByteArrayInputStream(c), toLocation, overrideIdRsa)) {
					filesChanged.add(toLocation);
				}
				if(pn != null && notificationAboutLocalCache && hash != null) {
					try {
						lc.put(deploymentMethod.getID() + toLocation, hash);
						pn.set(dm, new String[]{"site_deploy", "local_cache"}, JSONValue.toJSONString(lc));
					} catch (DataSourceException | ReadOnlyException | IllegalArgumentException ex) {
						writeLog(null, ex);
						notificationAboutLocalCache = false;
					}
				}
				currentUploadTask.addAndGet(1);
				writeStatus("");
			} catch (Throwable ex) {
				writeLog("Failed while uploading " + toLocation, ex);
				generateQueue.shutdownNow();
				uploadQueue.shutdownNow();
			}
		});
		totalUploadTasks.addAndGet(1);
	}

	/**
	 * Writes an arbitrary stream to a file on the remote.
	 *
	 * @param contents The input stream to write
	 * @param toLocation The location to write to
	 */
	private void writeFromStream(final InputStream contents, final String toLocation) {
		uploadQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					writeStatus("Currently uploading " + toLocation);
					// Read the contents only once
					byte[] c = StreamUtils.GetBytes(contents);
					contents.close();
					boolean skipUpload = false;
					String hash = null;
					if(pn != null) {
						if(notificationAboutLocalCache) {
							hash = getLocalMD5(new ByteArrayInputStream(c));
							try {
								if(lc.containsKey(deploymentMethod.getID() + toLocation)) {
									if(useLocalCache) {
										String cacheHash = lc.get(deploymentMethod.getID() + toLocation);
										if(cacheHash.equals(hash)) {
											skipUpload = true;
										}
									}
								}
							} catch (IllegalArgumentException ex) {
								writeLog("Could not use local cache", ex);
								notificationAboutLocalCache = false;
							}
						}
					}
					if(!skipUpload && deploymentMethod.deploy(new ByteArrayInputStream(c), toLocation, overrideIdRsa)) {
						filesChanged.add(toLocation);
					}
					if(pn != null && notificationAboutLocalCache && hash != null) {
						try {
							lc.put(deploymentMethod.getID() + toLocation, hash);
							pn.set(dm, new String[]{"site_deploy", "local_cache"}, JSONValue.toJSONString(lc));
						} catch (DataSourceException | ReadOnlyException | IllegalArgumentException ex) {
							writeLog(null, ex);
							notificationAboutLocalCache = false;
						}
					}
					currentUploadTask.addAndGet(1);
					writeStatus("");
				} catch (Throwable ex) {
					writeLog("Failed while uploading " + toLocation, ex);
					generateQueue.shutdownNow();
					uploadQueue.shutdownNow();
				}
			}
		});
		totalUploadTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.writeFromStream.submit.new Runnable with () -> {trywriteStatus("Currently uploading " + toLocation); in method private writeFromStream(contents InputStream, toLocation String) : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


/**
	 * Most pages should use this method instead of the other methods. This takes care of all the steps, including
	 * substituting the body into the frame, and handling all the other connections.
	 *
	 * @param body The content body
	 * @param title The title of the page
	 * @param toLocation the location on the remote server
	 * @param keywords A list of keywords to be added to the meta tag on the page
	 * @param description A description of the page's content
	 */
	private void writePage(final String title, final String body, final String toLocation,
			List<String> keywords, final String description) {
		if(keywords == null) {
			keywords = new ArrayList<>();
		}
		final List<String> kw = keywords;
		generateQueue.submit(() -> {
			try {
				String bW = body;
				if(!bW.contains(EDIT_THIS_PAGE_PREAMBLE)) {
					bW += "
"
							+ EDIT_THIS_PAGE_PREAMBLE
							+ String.format(githubBaseUrl, "java/" + SiteDeploy.class.getName().replace(".", "/"))
							+ ".java"
							+ EDIT_THIS_PAGE_POSTAMBLE
							+ "
";
				}
				try {
					writeStatus("Currently generating " + toLocation);
					// First, substitute the templates in the body
					final String b;
					try {
						Map<String, Generator> standard = getStandardGenerators();
						standard.putAll(DocGenTemplates.GetGenerators());
						b = DocGenTemplates.DoTemplateReplacement(bW, standard);
					} catch (Exception ex) {
						if(ex instanceof GenerateException) {
							writeLog("Failed to substitute template"
									+ " while trying to upload resource to " + toLocation, ex);
						} else {
							writeLog(null, ex);
						}
						reader.flush();
						generateQueue.shutdownNow();
						uploadQueue.shutdownNow();
						return;
					}
					// Second, add the template %%body%% and replace that in the frame
					final Map<String, Generator> g = new HashMap<>();
					g.put("body", (Generator) (String... args) -> b);
					g.put("bodyEscaped", (Generator) (String... args) -> {
						String s = b.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'")
								.replaceAll("\r", "").replaceAll("\n", "\\\\n");
						s = s.replaceAll("", "");
						return s;
					});
					g.put("title", (Generator) (String... args) -> title);
					g.put("useHttps", (Generator) (String... args)
							-> SiteDeploy.this.siteBase.startsWith("https") ? "true" : "false");
					g.put("keywords", (Generator) (String... args) -> {
						List<String> k = new ArrayList<>(kw);
						k.add(Implementation.GetServerType().getBranding());
						return StringUtils.Join(k, ", ");
					});
					g.put("description", (Generator) (String... args) -> description);
					g.putAll(getStandardGenerators());
					g.putAll(DocGenTemplates.GetGenerators());
					String frame = StreamUtils.GetString(SiteDeploy.class
							.getResourceAsStream("/siteDeploy/frame.html"));
					final String bb = DocGenTemplates.DoTemplateReplacement(frame, g);
					// Write out using writeFromString
					uploadedPages.put(toLocation, bb);
					writeFromString(bb, toLocation);
					currentGenerateTask.addAndGet(1);
					writeStatus("");
				} catch (Exception ex) {
					writeLog("While writing " + toLocation + " the following error occured:", ex);
				}
			} catch (Throwable t) {
				writeLog("Failure!", t);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

/**
	 * Most pages should use this method instead of the other methods. This takes care of all the steps, including
	 * substituting the body into the frame, and handling all the other connections.
	 *
	 * @param body The content body
	 * @param title The title of the page
	 * @param toLocation the location on the remote server
	 * @param keywords A list of keywords to be added to the meta tag on the page
	 * @param description A description of the page's content
	 */
	private void writePage(final String title, final String body, final String toLocation,
			List<String> keywords, final String description) {
		if(keywords == null) {
			keywords = new ArrayList<>();
		}
		final List<String> kw = keywords;
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					String bW = body;
					if(!bW.contains(EDIT_THIS_PAGE_PREAMBLE)) {
						bW += "
"
								+ EDIT_THIS_PAGE_PREAMBLE
								+ String.format(githubBaseUrl, "java/" + SiteDeploy.class.getName().replace(".", "/")) + ".java"
								+ EDIT_THIS_PAGE_POSTAMBLE
								+ "
";
					}
					try {
						writeStatus("Currently generating " + toLocation);
						// First, substitute the templates in the body
						final String b;
						try {
							Map<String, Generator> standard = getStandardGenerators();
							standard.putAll(DocGenTemplates.GetGenerators());
							b = DocGenTemplates.DoTemplateReplacement(bW, standard);
						} catch (Exception ex) {
							if(ex instanceof GenerateException) {
								writeLog("Failed to substitute template"
										+ " while trying to upload resource to " + toLocation, ex);
							} else {
								writeLog(null, ex);
							}
							reader.flush();
							generateQueue.shutdownNow();
							uploadQueue.shutdownNow();
							return;
						}
						// Second, add the template %%body%% and replace that in the frame
						final Map<String, Generator> g = new HashMap<>();
						g.put("body", new Generator() {
							@Override
							public String generate(String... args) {
								return b;
							}
						});
						g.put("bodyEscaped", new Generator() {
							@Override
							public String generate(String... args) {
								String s = b.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'")
										.replaceAll("\r", "").replaceAll("\n", "\\\\n");
								s = s.replaceAll("", "");
								return s;
							}
						});
						g.put("title", new Generator() {
							@Override
							public String generate(String... args) {
								return title;
							}
						});
						g.put("useHttps", new Generator() {
							@Override
							public String generate(String... args) {
								return SiteDeploy.this.siteBase.startsWith("https") ? "true" : "false";
							}
						});
						g.put("keywords", new Generator() {
							@Override
							public String generate(String... args) throws GenerateException {
								List<String> k = new ArrayList<>(kw);
								k.add(Implementation.GetServerType().getBranding());
								return StringUtils.Join(k, ", ");
							}
						});
						g.put("description", new Generator() {
							@Override
							public String generate(String... args) throws GenerateException {
								return description;
							}
						});
						g.putAll(getStandardGenerators());
						g.putAll(DocGenTemplates.GetGenerators());
						String frame = StreamUtils.GetString(SiteDeploy.class.getResourceAsStream("/siteDeploy/frame.html"));
						final String bb = DocGenTemplates.DoTemplateReplacement(frame, g);
						// Write out using writeFromString
						uploadedPages.put(toLocation, bb);
						writeFromString(bb, toLocation);
						currentGenerateTask.addAndGet(1);
						writeStatus("");
					} catch (Exception ex) {
						writeLog("While writing " + toLocation + " the following error occured:", ex);
					}
				} catch (Throwable t) {
					writeLog("Failure!", t);
				}
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.writePage.submit.new Runnable with () -> {tryString bW=body; in method private writePage(title String, body String, toLocation String, keywords List<String>, description String) : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


	/**
	 * Pages deployed: All pages under the siteDeploy/resources folder. They are transferred as is, including
	 * recursively looking through the folder structure. Binary files are also supported. index.js (after template
	 * replacement)
	 */
	private void deployResources() {
		generateQueue.submit(() -> {
			try {
				writeStatus("Generating resources");
				File root = new File(SiteDeploy.class.getResource("/siteDeploy/resources").toExternalForm());
				ZipReader reader1 = new ZipReader(root);
				Queue<File> q = new LinkedList<>();
				q.addAll(Arrays.asList(reader1.listFiles()));
				while(q.peek() != null) {
					ZipReader r = new ZipReader(q.poll());
					if(r.isDirectory()) {
						q.addAll(Arrays.asList(r.listFiles()));
					} else {
						String fileName = r.getFile().getAbsolutePath().replaceFirst(Pattern.quote(reader1.getFile()
								.getAbsolutePath()), "");
						writeStatus("Generating " + fileName);
						writeFromStream(r.getInputStream(), "resources" + fileName);
					}
				}
			} catch (IOException ex) {
				writeLog(null, ex);
			}
			String indexJs = StreamUtils.GetString(SiteDeploy.class.getResourceAsStream("/siteDeploy/index.js"));
			try {
				writeFromString(DocGenTemplates.DoTemplateReplacement(indexJs, getStandardGenerators()),
						"resources/js/index.js");
			} catch (Generator.GenerateException ex) {
				writeLog("GenerateException in /siteDeploy/index.js", ex);
			}
			currentGenerateTask.addAndGet(1);
		});
		totalGenerateTasks.addAndGet(1);
	}

	/**
	 * Pages deployed: All pages under the siteDeploy/resources folder. They are transferred as is, including
	 * recursively looking through the folder structure. Binary files are also supported. index.js (after template
	 * replacement)
	 */
	private void deployResources() {
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					writeStatus("Generating resources");
					File root = new File(SiteDeploy.class.getResource("/siteDeploy/resources").toExternalForm());
					ZipReader reader = new ZipReader(root);
					Queue<File> q = new LinkedList<>();
					q.addAll(Arrays.asList(reader.listFiles()));
					while(q.peek() != null) {
						ZipReader r = new ZipReader(q.poll());
						if(r.isDirectory()) {
							q.addAll(Arrays.asList(r.listFiles()));
						} else {
							String fileName = r.getFile().getAbsolutePath().replaceFirst(Pattern.quote(reader.getFile().getAbsolutePath()), "");
							writeStatus("Generating " + fileName);
							writeFromStream(r.getInputStream(), "resources" + fileName);
						}
					}
				} catch (IOException ex) {
					writeLog(null, ex);
				}
				String indexJs = StreamUtils.GetString(SiteDeploy.class.getResourceAsStream("/siteDeploy/index.js"));
				try {
					writeFromString(DocGenTemplates.DoTemplateReplacement(indexJs, getStandardGenerators()), "resources/js/index.js");
				} catch (Generator.GenerateException ex) {
					writeLog("GenerateException in /siteDeploy/index.js", ex);
				}
				currentGenerateTask.addAndGet(1);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployResources.submit.new Runnable with () -> {trywriteStatus("Generating resources"); in method private deployResources() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


	/**
	 * Pages deployed: All files from /docs/*
	 */
	private void deployLearningTrail() {
		generateQueue.submit(() -> {
			try {
				File root = new File(SiteDeploy.class.getResource("/docs").toExternalForm());
				ZipReader zReader = new ZipReader(root);
				String path = Pattern.quote(zReader.getFile().getAbsolutePath());
				for(File r : zReader.listFiles()) {
					String filename = r.getAbsolutePath().replaceFirst(path, "");
					writePageFromResource(r.getName(), "/docs" + filename, r.getName() + ".html",
							Arrays.asList(new String[]{r.getName().replace("_", " ")}), "Learning trail page for "
									+ r.getName().replace("_", " "));
				}
			} catch (IOException ex) {
				writeLog(null, ex);
			}
			currentGenerateTask.addAndGet(1);
		});
		totalGenerateTasks.addAndGet(1);
	}

	/**
	 * Pages deployed: All files from /docs/*
	 */
	private void deployLearningTrail() {
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					File root = new File(SiteDeploy.class.getResource("/docs").toExternalForm());
					ZipReader zReader = new ZipReader(root);
					String path = Pattern.quote(zReader.getFile().getAbsolutePath());
					for(File r : zReader.listFiles()) {
						String filename = r.getAbsolutePath().replaceFirst(path, "");
						writePageFromResource(r.getName(), "/docs" + filename, r.getName() + ".html",
								Arrays.asList(new String[]{r.getName().replace("_", " ")}), "Learning trail page for " + r.getName().replace("_", " "));
					}
				} catch (IOException ex) {
					writeLog(null, ex);
				}
				currentGenerateTask.addAndGet(1);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployLearningTrail.submit.new Runnable with () -> {tryFile root=new File(SiteDeploy.class.getResource("/docs").toExternalForm()); in method private deployLearningTrail() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


private void deployAPI() {
		generateQueue.submit(() -> {
			try {
				Set<Class<? extends Function>> functionClasses = new TreeSet<>(
						(Class<? extends Function> o1, Class<? extends Function> o2) -> {
					Function f1 = ReflectionUtils.instantiateUnsafe(o1);
					Function f2 = ReflectionUtils.instantiateUnsafe(o2);
					return f1.getName().compareTo(f2.getName());
				});
				functionClasses.addAll(ClassDiscovery.getDefaultInstance()
						.loadClassesWithAnnotationThatExtend(api.class, Function.class));
				// A map of where it maps the enclosing class to the list of function rows, which contains a list of
				// table cells.
				Map<Class<?>, List<List<String>>> data = new TreeMap<>((Class<?> o1, Class<?> o2)
						-> o1.getCanonicalName().compareTo(o2.getCanonicalName()));
				List<String> hiddenFunctions = new ArrayList<>();
				for(Class<? extends Function> functionClass : functionClasses) {
					try {
						if(!data.containsKey(functionClass.getEnclosingClass())) {
							data.put(functionClass.getEnclosingClass(), new ArrayList<>());
						}
						List<List<String>> d = data.get(functionClass.getEnclosingClass());
						List<String> c = new ArrayList<>();
						// function name, returns, arguments, throws, description, restricted
						final Function f;
						try {
							f = ReflectionUtils.instantiateUnsafe(functionClass);
						} catch (ReflectionUtils.ReflectionException ex) {
							throw new RuntimeException("While trying to construct " + functionClass
									+ ", got the following", ex);
						}
						final DocGen.DocInfo di = new DocGen.DocInfo(f.docs());
						// If the function is hidden, we don't want to put it on the main page by default. Regardless,
						// we do want to generate the function page, it will just remain unlinked.
						generateQueue.submit(() -> {
							try {
								generateFunctionDocs(f, di);
							} catch (Throwable ex) {
								ex.printStackTrace(System.err);
							}
						});
						if(f.since().equals(MSVersion.V0_0_0)) {
							// Don't add these
							continue;
						}
						if(f.getClass().getAnnotation(hide.class) != null) {
							hiddenFunctions.add(f.getName());
						}
						c.add("[[API/functions/" + f.getName() + "|" + f.getName() + "]]()");
						c.add(di.ret);
						c.add(di.args);
						List<String> exc = new ArrayList<>();
						if(f.thrown() != null) {
							for(Class<? extends CREThrowable> e : f.thrown()) {
								CREThrowable ct = ReflectionUtils.instantiateUnsafe(e);
								exc.add("{{object|" + ct.getName() + "}}");
							}
						}
						c.add(StringUtils.Join(exc, "
"));
						StringBuilder desc = new StringBuilder();
						desc.append(HTMLUtils.escapeHTML(di.desc));
						if(di.extendedDesc != null) {
							desc.append(" [[API/functions/").append(f.getName()).append("|See more...]]
\n");
						}
						try {
							if(f.examples() != null && f.examples().length > 0) {
								desc.append("
([[API/functions/").append(f.getName())
										.append("#Examples|Examples...]])\n");
							}
						} catch (ConfigCompileException | NoClassDefFoundError ex) {
							writeLog(null, ex);
						}
						c.add(desc.toString());
						c.add(""
								+ (f.isRestricted() ? "Yes" : "No")
								+ "");
						d.add(c);
					} catch (Throwable t) {
						writeLog("Failure while generating " + functionClass, t);
					}
				}
				//					System.out.println("Functions to be deployed: " + data + "\n\n");
				// data is now constructed.
				StringBuilder b = new StringBuilder();
				b.append("
");
				for(Class<?> clazz : data.keySet()) {
					b.append("
").append(clazz.getSimpleName()).append("
");
				}
				b.append("
\n");
				for(Map.Entry<Class<?>, List<List<String>>> e : data.entrySet()) {
					Class<?> clazz = e.getKey();
					List<List<String>> clazzData = e.getValue();
					if(clazzData.isEmpty()) {
						// If there are no functions in the class, don't display it. This is most likely to happen
						// if all the class's functions are hidden with @hide.
						continue;
					}
					try {
						b.append("== ").append(clazz.getSimpleName()).append(" ==\n");
						String docs = (String) ReflectionUtils.invokeMethod(clazz, null, "docs");
						b.append("
").append(docs).append("
\n\n");
						b.append("{|\n|-\n");
						b.append("! scope=\"col\" width=\"6%\" | Function Name\n"
								+ "! scope=\"col\" width=\"5%\" | Returns\n"
								+ "! scope=\"col\" width=\"10%\" | Arguments\n"
								+ "! scope=\"col\" width=\"10%\" | Throws\n"
								+ "! scope=\"col\" width=\"64%\" | Description\n"
								+ "! scope=\"col\" width=\"5%\" |"
								+ " Res\n");
						for(List<String> row : clazzData) {
							b.append("|-");
							if(hiddenFunctions.contains(row.get(0))) {
								b.append(" class=\"hiddenFunction\"");
							}
							b.append("\n");
							for(String cell : row) {
								b.append("| ").append(cell).append("\n");
							}

						}
						b.append("|}\n");
						b.append("
Back to top
\n");
					} catch (Error ex) {
						writeLog("While processing " + clazz + " got:", ex);
					}
				}
				b.append("
Show hidden
");
				b.append("");
				writePage("API", b.toString(), "API.html",
						Arrays.asList(new String[]{"API", "functions"}),
						"A list of all " + Implementation.GetServerType().getBranding() + " functions");
				currentGenerateTask.addAndGet(1);
			} catch (Throwable ex) {
				ex.printStackTrace(System.err);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

private void deployAPI() {
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					Set<Class<? extends Function>> functionClasses
							= new TreeSet<>(new Comparator<Class<? extends Function>>() {
								@Override
								public int compare(Class<? extends Function> o1, Class<? extends Function> o2) {
									Function f1 = ReflectionUtils.instantiateUnsafe(o1);
									Function f2 = ReflectionUtils.instantiateUnsafe(o2);
									return f1.getName().compareTo(f2.getName());
								}
							});
					functionClasses.addAll(ClassDiscovery.getDefaultInstance().loadClassesWithAnnotationThatExtend(api.class, Function.class));
					// A map of where it maps the enclosing class to the list of function rows, which contains a list of
					// table cells.
					Map<Class<?>, List<List<String>>> data = new TreeMap<>(new Comparator<Class<?>>() {
						@Override
						public int compare(Class<?> o1, Class<?> o2) {
							return o1.getCanonicalName().compareTo(o2.getCanonicalName());
						}
					});
					List<String> hiddenFunctions = new ArrayList<>();
					for(Class<? extends Function> functionClass : functionClasses) {
						try {
							if(!data.containsKey(functionClass.getEnclosingClass())) {
								data.put(functionClass.getEnclosingClass(), new ArrayList<>());
							}
							List<List<String>> d = data.get(functionClass.getEnclosingClass());
							List<String> c = new ArrayList<>();
							// function name, returns, arguments, throws, description, restricted
							final Function f;
							try {
								f = ReflectionUtils.instantiateUnsafe(functionClass);
							} catch (ReflectionUtils.ReflectionException ex) {
								throw new RuntimeException("While trying to construct " + functionClass + ", got the following", ex);
							}
							final DocGen.DocInfo di = new DocGen.DocInfo(f.docs());
							// If the function is hidden, we don't want to put it on the main page by default. Regardless,
							// we do want to generate the function page, it will just remain unlinked.
							generateQueue.submit(new Runnable() {
								@Override
								public void run() {
									try {
										generateFunctionDocs(f, di);
									} catch (Throwable ex) {
										ex.printStackTrace(System.err);
									}
								}
							});
							if(f.since().equals(MSVersion.V0_0_0)) {
								// Don't add these
								continue;
							}
							if(f.getClass().getAnnotation(hide.class) != null) {
								hiddenFunctions.add(f.getName());
							}
							c.add("[[API/functions/" + f.getName() + "|" + f.getName() + "]]()");
							c.add(di.ret);
							c.add(di.args);
							List<String> exc = new ArrayList<>();
							if(f.thrown() != null) {
								for(Class<? extends CREThrowable> e : f.thrown()) {
									CREThrowable ct = ReflectionUtils.instantiateUnsafe(e);
									exc.add("{{object|" + ct.getName() + "}}");
								}
							}
							c.add(StringUtils.Join(exc, "
"));
							StringBuilder desc = new StringBuilder();
							desc.append(HTMLUtils.escapeHTML(di.desc));
							if(di.extendedDesc != null) {
								desc.append(" [[API/functions/").append(f.getName()).append("|See more...]]
\n");
							}
							try {
								if(f.examples() != null && f.examples().length > 0) {
									desc.append("
([[API/functions/").append(f.getName()).append("#Examples|Examples...]])\n");
								}
							} catch (ConfigCompileException | NoClassDefFoundError ex) {
								writeLog(null, ex);
							}
							c.add(desc.toString());
							c.add("" + (f.isRestricted() ? "Yes" : "No")
									+ "");
							d.add(c);
						} catch (Throwable t) {
							writeLog("Failure while generating " + functionClass, t);
						}
					}
//					System.out.println("Functions to be deployed: " + data + "\n\n");
					// data is now constructed.
					StringBuilder b = new StringBuilder();
					b.append("
");
					for(Class<?> clazz : data.keySet()) {
						b.append("
").append(clazz.getSimpleName()).append("
");
					}
					b.append("
\n");
					for(Map.Entry<Class<?>, List<List<String>>> e : data.entrySet()) {
						Class<?> clazz = e.getKey();
						List<List<String>> clazzData = e.getValue();
						if(clazzData.isEmpty()) {
							// If there are no functions in the class, don't display it. This is most likely to happen
							// if all the class's functions are hidden with @hide.
							continue;
						}
						try {
							b.append("== ").append(clazz.getSimpleName()).append(" ==\n");
							String docs = (String) ReflectionUtils.invokeMethod(clazz, null, "docs");
							b.append("
").append(docs).append("
\n\n");
							b.append("{|\n|-\n");
							b.append("! scope=\"col\" width=\"6%\" | Function Name\n"
									+ "! scope=\"col\" width=\"5%\" | Returns\n"
									+ "! scope=\"col\" width=\"10%\" | Arguments\n"
									+ "! scope=\"col\" width=\"10%\" | Throws\n"
									+ "! scope=\"col\" width=\"64%\" | Description\n"
									+ "! scope=\"col\" width=\"5%\" | Res\n");
							for(List<String> row : clazzData) {
								b.append("|-");
								if(hiddenFunctions.contains(row.get(0))) {
									b.append(" class=\"hiddenFunction\"");
								}
								b.append("\n");
								for(String cell : row) {
									b.append("| ").append(cell).append("\n");
								}

							}
							b.append("|}\n");
							b.append("
Back to top
\n");
						} catch (Error ex) {
							writeLog("While processing " + clazz + " got:", ex);
						}
					}

					b.append("
Show hidden
");
					b.append("");

					writePage("API", b.toString(), "API.html",
							Arrays.asList(new String[]{"API", "functions"}),
							"A list of all " + Implementation.GetServerType().getBranding() + " functions");
					currentGenerateTask.addAndGet(1);
				} catch (Throwable ex) {
					ex.printStackTrace(System.err);
				}
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployAPI.submit.new Runnable with () -> {trySet<Class<? extends Function>> functionClasses=new TreeSet<>((Class<? extends Function> o1,Class<? extends Function> o2) -> { in method private deployAPI() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


private void deployEventAPI() {
		generateQueue.submit(() -> {
			try {
				Set<Class<? extends Event>> eventClasses = new TreeSet<>(
						(Class<? extends Event> o1, Class<? extends Event> o2) -> {
					Event f1 = ReflectionUtils.instantiateUnsafe(o1);
					Event f2 = ReflectionUtils.instantiateUnsafe(o2);
					return f1.getName().compareTo(f2.getName());
				});
				eventClasses.addAll(ClassDiscovery.getDefaultInstance()
						.loadClassesWithAnnotationThatExtend(api.class, Event.class));
				// A map of where it maps the enclosing class to the list of event rows,
				// which contains a list of table cells.
				Map<Class<?>, List<List<String>>> data = new TreeMap<>((Class<?> o1, Class<?> o2)
						-> o1.getCanonicalName().compareTo(o2.getCanonicalName()));
				for(Class<? extends Event> eventClass : eventClasses) {
					if(!data.containsKey(eventClass.getEnclosingClass())) {
						data.put(eventClass.getEnclosingClass(), new ArrayList<>());
					}
					List<List<String>> d = data.get(eventClass.getEnclosingClass());
					List<String> c = new ArrayList<>();
					// event name, description, prefilters, data, mutable
					final Event e;
					try {
						e = ReflectionUtils.instantiateUnsafe(eventClass);
					} catch (ReflectionUtils.ReflectionException ex) {
						throw new RuntimeException("While trying to construct " + eventClass
								+ ", got the following", ex);
					}
					final DocGen.EventDocInfo edi = new DocGen.EventDocInfo(e.docs(), e.getName());
					if(e.since().equals(MSVersion.V0_0_0)) {
						// Don't add these
						continue;
					}
					c.add(e.getName());
					c.add(edi.description);
					List<String> pre = new ArrayList<>();
					if(!edi.prefilter.isEmpty()) {
						for(DocGen.EventDocInfo.PrefilterData pdata : edi.prefilter) {
							pre.add("
" + pdata.name + ": "
									+ pdata.formatDescription(DocGen.MarkupType.HTML) + "
");
						}
					}
					c.add(StringUtils.Join(pre, ""));
					List<String> ed = new ArrayList<>();
					if(!edi.eventData.isEmpty()) {
						for(DocGen.EventDocInfo.EventData edata : edi.eventData) {
							ed.add("
" + edata.name + ""
									+ (!edata.description.isEmpty() ? ": " + edata.description : "") + "
");
						}
					}
					c.add(StringUtils.Join(ed, ""));
					List<String> mut = new ArrayList<>();
					if(!edi.mutability.isEmpty()) {
						for(DocGen.EventDocInfo.MutabilityData mdata : edi.mutability) {
							mut.add("
" + mdata.name + ""
									+ (!mdata.description.isEmpty() ? ": " + mdata.description : "") + "
");
						}
					}
					c.add(StringUtils.Join(mut, ""));
					d.add(c);
				}
				// data is now constructed.
				StringBuilder b = new StringBuilder();
				b.append("
");
				for(Class<?> clazz : data.keySet()) {
					b.append("
").append(clazz.getSimpleName()).append("
");
				}
				b.append("
\n");
				for(Map.Entry<Class<?>, List<List<String>>> e : data.entrySet()) {
					Class<?> clazz = e.getKey();
					List<List<String>> clazzData = e.getValue();
					if(clazzData.isEmpty()) {
						// If there are no events in the class, don't display it.
						continue;
					}
					try {
						b.append("== ").append(clazz.getSimpleName()).append(" ==\n");
						String docs = (String) ReflectionUtils.invokeMethod(clazz, null, "docs");
						b.append("
").append(docs).append("
\n\n");
						b.append("{|\n|-\n");
						b.append("! scope=\"col\" width=\"7%\" | Event Name\n"
								+ "! scope=\"col\" width=\"30%\" | Description\n"
								+ "! scope=\"col\" width=\"20%\" | Prefilters\n"
								+ "! scope=\"col\" width=\"25%\" | Event Data\n"
								+ "! scope=\"col\" width=\"18%\" | Mutable Fields\n");
						for(List<String> row : clazzData) {
							b.append("|-");
							b.append("\n");
							for(String cell : row) {
								b.append("| ").append(cell).append("\n");
							}
						}
						b.append("|}\n");
						b.append("
Back to top
\n");
					} catch (Error ex) {
						writeLog("While processing " + clazz + " got:", ex);
					}
				}
				writePage("Event API", b.toString(), "Event_API.html",
						Arrays.asList(new String[]{"API", "events"}),
						"A list of all " + Implementation.GetServerType().getBranding() + " events");
				currentGenerateTask.addAndGet(1);
			} catch (Error ex) {
				ex.printStackTrace(System.err);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

private void deployEventAPI() {
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					Set<Class<? extends Event>> eventClasses
							= new TreeSet<>(new Comparator<Class<? extends Event>>() {
								@Override
								public int compare(Class<? extends Event> o1, Class<? extends Event> o2) {
									Event f1 = ReflectionUtils.instantiateUnsafe(o1);
									Event f2 = ReflectionUtils.instantiateUnsafe(o2);
									return f1.getName().compareTo(f2.getName());
								}
							});
					eventClasses.addAll(ClassDiscovery.getDefaultInstance().loadClassesWithAnnotationThatExtend(api.class, Event.class));
					// A map of where it maps the enclosing class to the list of event rows, which contains a list of table cells.
					Map<Class<?>, List<List<String>>> data = new TreeMap<>(new Comparator<Class<?>>() {
						@Override
						public int compare(Class<?> o1, Class<?> o2) {
							return o1.getCanonicalName().compareTo(o2.getCanonicalName());
						}
					});
					for(Class<? extends Event> eventClass : eventClasses) {
						if(!data.containsKey(eventClass.getEnclosingClass())) {
							data.put(eventClass.getEnclosingClass(), new ArrayList<>());
						}
						List<List<String>> d = data.get(eventClass.getEnclosingClass());
						List<String> c = new ArrayList<>();
						// event name, description, prefilters, data, mutable
						final Event e;
						try {
							e = ReflectionUtils.instantiateUnsafe(eventClass);
						} catch (ReflectionUtils.ReflectionException ex) {
							throw new RuntimeException("While trying to construct " + eventClass + ", got the following", ex);
						}
						final DocGen.EventDocInfo edi = new DocGen.EventDocInfo(e.docs(), e.getName());
						if(e.since().equals(MSVersion.V0_0_0)) {
							// Don't add these
							continue;
						}
						c.add(e.getName());
						c.add(edi.description);
						List<String> pre = new ArrayList<>();
						if(!edi.prefilter.isEmpty()) {
							for(DocGen.EventDocInfo.PrefilterData pdata : edi.prefilter) {
								pre.add("
" + pdata.name + ": " + pdata.formatDescription(DocGen.MarkupType.HTML) + "
");
							}
						}
						c.add(StringUtils.Join(pre, ""));
						List<String> ed = new ArrayList<>();
						if(!edi.eventData.isEmpty()) {
							for(DocGen.EventDocInfo.EventData edata : edi.eventData) {
								ed.add("
" + edata.name + ""
										+ (!edata.description.isEmpty() ? ": " + edata.description : "") + "
");
							}
						}
						c.add(StringUtils.Join(ed, ""));
						List<String> mut = new ArrayList<>();
						if(!edi.mutability.isEmpty()) {
							for(DocGen.EventDocInfo.MutabilityData mdata : edi.mutability) {
								mut.add("
" + mdata.name + ""
										+ (!mdata.description.isEmpty() ? ": " + mdata.description : "") + "
");
							}
						}
						c.add(StringUtils.Join(mut, ""));
						d.add(c);
					}
					// data is now constructed.
					StringBuilder b = new StringBuilder();
					b.append("
");
					for(Class<?> clazz : data.keySet()) {
						b.append("
").append(clazz.getSimpleName()).append("
");
					}
					b.append("
\n");
					for(Map.Entry<Class<?>, List<List<String>>> e : data.entrySet()) {
						Class<?> clazz = e.getKey();
						List<List<String>> clazzData = e.getValue();
						if(clazzData.isEmpty()) {
							// If there are no events in the class, don't display it.
							continue;
						}
						try {
							b.append("== ").append(clazz.getSimpleName()).append(" ==\n");
							String docs = (String) ReflectionUtils.invokeMethod(clazz, null, "docs");
							b.append("
").append(docs).append("
\n\n");
							b.append("{|\n|-\n");
							b.append("! scope=\"col\" width=\"7%\" | Event Name\n"
									+ "! scope=\"col\" width=\"30%\" | Description\n"
									+ "! scope=\"col\" width=\"20%\" | Prefilters\n"
									+ "! scope=\"col\" width=\"25%\" | Event Data\n"
									+ "! scope=\"col\" width=\"18%\" | Mutable Fields\n");
							for(List<String> row : clazzData) {
								b.append("|-");
								b.append("\n");
								for(String cell : row) {
									b.append("| ").append(cell).append("\n");
								}
							}
							b.append("|}\n");
							b.append("
Back to top
\n");
						} catch (Error ex) {
							writeLog("While processing " + clazz + " got:", ex);
						}
					}
					writePage("Event API", b.toString(), "Event_API.html",
							Arrays.asList(new String[]{"API", "events"}),
							"A list of all " + Implementation.GetServerType().getBranding() + " events");
					currentGenerateTask.addAndGet(1);
				} catch (Error ex) {
					ex.printStackTrace(System.err);
				}
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployEventAPI.submit.new Runnable with () -> {trySet<Class<? extends Event>> eventClasses=new TreeSet<>((Class<? extends Event> o1,Class<? extends Event> o2) -> { in method private deployEventAPI() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


	/**
	 * Pages deployed: api.json - This page is the json version of the api
	 */
	private void deployAPIJSON() {
		generateQueue.submit(() -> {
			try {
				writeFromString(apiJson, "api.json");
				currentGenerateTask.addAndGet(1);
			} catch (Throwable t) {
				writeLog("Failure!", t);
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

	/**
	 * Pages deployed: api.json - This page is the json version of the api
	 */
	private void deployAPIJSON() {
		generateQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					writeFromString(apiJson, "api.json");
					currentGenerateTask.addAndGet(1);
				} catch (Throwable t) {
					writeLog("Failure!", t);
				}
			}
		});
		totalGenerateTasks.addAndGet(1);
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployAPIJSON.submit.new Runnable with () -> {trywriteFromString(apiJson,"api.json"); in method private deployAPIJSON() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


	private void deployJar() {
		uploadQueue.submit(() -> {
			try {
				writeFromStream(ClassDiscovery.GetClassContainer(SiteDeploy.class).openStream(),
						"MethodScript.jar");
				// It goes in two places, so the latest release is always available no matter the last
				// build this version was built with.
				writeFromStream(ClassDiscovery.GetClassContainer(SiteDeploy.class).openStream(),
						"../../MethodScript.jar");

			} catch (Throwable e) {
				e.printStackTrace(System.err);
			}
		});
	}

	private void deployJar() {
		uploadQueue.submit(new Runnable() {
			@Override
			public void run() {
				try {
					writeFromStream(ClassDiscovery.GetClassContainer(SiteDeploy.class).openStream(),
							"MethodScript.jar");
					// It goes in two places, so the latest release is always available no matter the last
					// build this version was built with.
					writeFromStream(ClassDiscovery.GetClassContainer(SiteDeploy.class).openStream(),
							"../../MethodScript.jar");

				} catch (Throwable e) {
					e.printStackTrace(System.err);
				}
			}
		});
	}

Replace Anonymous With Lambda com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy.deployJar.submit.new Runnable with () -> {trywriteFromStream(ClassDiscovery.GetClassContainer(SiteDeploy.class).openStream(),"MethodScript.jar"); in method private deployJar() : void from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			long time = Static.getInt(args[0], t);
			int offset = 0;
			long delay = time;
			if(args.length == 3) {
				offset = 1;
				delay = Static.getInt(args[1], t);
			}
			if(!(args[1 + offset].isInstanceOf(CClosure.class))) {
				throw new CRECastException(getName() + " expects a closure to be sent as the second argument", t);
			}
			final CClosure c = (CClosure) args[1 + offset];
			final AtomicInteger ret = new AtomicInteger(-1);

			ret.set(StaticLayer.SetFutureRepeater(environment.getEnv(GlobalEnv.class).GetDaemonManager(), time, delay, () -> {
				c.getEnv().getEnv(GlobalEnv.class).SetCustom("timeout-id", ret.get());
				try {
					ProfilePoint p = environment.getEnv(GlobalEnv.class).GetProfiler().start("Executing timeout"
							+ " with id " + ret.get() + " (defined at " + t.toString() + ")", LogLevel.ERROR);
					try {
						c.executeCallable();
					} finally {
						p.stop();
					}
				} catch (ConfigRuntimeException e) {
					ConfigRuntimeException.HandleUncaughtException(e, environment);
				} catch (CancelCommandException e) {
					//Ok
				} catch (ProgramFlowManipulationException e) {
					ConfigRuntimeException.DoWarning("Using a program flow manipulation construct improperly! " + e.getClass().getSimpleName());
				}
			}));
			return new CInt(ret.get(), t);
		}

		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			long time = Static.getInt(args[0], t);
			int offset = 0;
			long delay = time;
			if(args.length == 3) {
				offset = 1;
				delay = Static.getInt(args[1], t);
			}
			if(!(args[1 + offset].isInstanceOf(CClosure.class))) {
				throw new CRECastException(getName() + " expects a closure to be sent as the second argument", t);
			}
			final CClosure c = (CClosure) args[1 + offset];
			final AtomicInteger ret = new AtomicInteger(-1);

			ret.set(StaticLayer.SetFutureRepeater(environment.getEnv(GlobalEnv.class).GetDaemonManager(), time, delay, new Runnable() {
				@Override
				public void run() {
					c.getEnv().getEnv(GlobalEnv.class).SetCustom("timeout-id", ret.get());
					try {
						ProfilePoint p = environment.getEnv(GlobalEnv.class).GetProfiler().start("Executing timeout"
								+ " with id " + ret.get() + " (defined at " + t.toString() + ")", LogLevel.ERROR);
						try {
							c.executeCallable();
						} finally {
							p.stop();
						}
					} catch (ConfigRuntimeException e) {
						ConfigRuntimeException.HandleUncaughtException(e, environment);
					} catch (CancelCommandException e) {
						//Ok
					} catch (ProgramFlowManipulationException e) {
						ConfigRuntimeException.DoWarning("Using a program flow manipulation construct improperly! " + e.getClass().getSimpleName());
					}
				}
			}));
			return new CInt(ret.get(), t);
		}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Scheduling.set_interval.exec.set.SetFutureRepeater.new Runnable with () -> {c.getEnv().getEnv(GlobalEnv.class).SetCustom("timeout-id",ret.get()); in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Scheduling.set_interval


		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			final TaskManager taskManager = environment.getEnv(GlobalEnv.class).GetTaskManager();
			long time = Static.getInt(args[0], t);
			if(!(args[1].isInstanceOf(CClosure.class))) {
				throw new CRECastException(getName() + " expects a closure to be sent as the second argument", t);
			}
			final CClosure c = (CClosure) args[1];
			final AtomicInteger ret = new AtomicInteger(-1);
			final AtomicBoolean isRunning = new AtomicBoolean(false);
			ret.set(StaticLayer.SetFutureRunnable(environment.getEnv(GlobalEnv.class).GetDaemonManager(), time, () -> {
				isRunning.set(true);
				c.getEnv().getEnv(GlobalEnv.class).SetCustom("timeout-id", ret.get());
				taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.RUNNING);
				try {
					ProfilePoint p = environment.getEnv(GlobalEnv.class).GetProfiler().start("Executing timeout"
							+ " with id " + ret.get() + " (defined at " + t.toString() + ")", LogLevel.ERROR);
					try {
						c.executeCallable();
					} finally {
						p.stop();
					}
				} catch (ConfigRuntimeException e) {
					ConfigRuntimeException.HandleUncaughtException(e, environment);
				} catch (CancelCommandException e) {
					//Ok
				} catch (ProgramFlowManipulationException e) {
					ConfigRuntimeException.DoWarning("Using a program flow manipulation construct improperly! " + e.getClass().getSimpleName());
				} finally {
					taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.FINISHED);
					environment.getEnv(GlobalEnv.class).SetInterrupt(false);
				}
			}));
			taskManager.addTask(new TimeoutTaskHandler(ret.get(), t, () -> {
				if(isRunning.get()) {
					new clear_task().exec(t, environment, new CInt(ret.get(), t));
					environment.getEnv(GlobalEnv.class).SetInterrupt(true);
					taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.KILLED);
				}
			}));
			taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.IDLE);
			return new CInt(ret.get(), t);
		}

		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			final TaskManager taskManager = environment.getEnv(GlobalEnv.class).GetTaskManager();
			long time = Static.getInt(args[0], t);
			if(!(args[1].isInstanceOf(CClosure.class))) {
				throw new CRECastException(getName() + " expects a closure to be sent as the second argument", t);
			}
			final CClosure c = (CClosure) args[1];
			final AtomicInteger ret = new AtomicInteger(-1);
			final AtomicBoolean isRunning = new AtomicBoolean(false);
			ret.set(StaticLayer.SetFutureRunnable(environment.getEnv(GlobalEnv.class).GetDaemonManager(), time, new Runnable() {
				@Override
				public void run() {
					isRunning.set(true);
					c.getEnv().getEnv(GlobalEnv.class).SetCustom("timeout-id", ret.get());
					taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.RUNNING);
					try {
						ProfilePoint p = environment.getEnv(GlobalEnv.class).GetProfiler().start("Executing timeout"
								+ " with id " + ret.get() + " (defined at " + t.toString() + ")", LogLevel.ERROR);
						try {
							c.executeCallable();
						} finally {
							p.stop();
						}
					} catch (ConfigRuntimeException e) {
						ConfigRuntimeException.HandleUncaughtException(e, environment);
					} catch (CancelCommandException e) {
						//Ok
					} catch (ProgramFlowManipulationException e) {
						ConfigRuntimeException.DoWarning("Using a program flow manipulation construct improperly! " + e.getClass().getSimpleName());
					} finally {
						taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.FINISHED);
						environment.getEnv(GlobalEnv.class).SetInterrupt(false);
					}
				}
			}));
			taskManager.addTask(new TimeoutTaskHandler(ret.get(), t, new Runnable() {

				@Override
				public void run() {
					if(isRunning.get()) {
						new clear_task().exec(t, environment, new CInt(ret.get(), t));
						environment.getEnv(GlobalEnv.class).SetInterrupt(true);
						taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.KILLED);
					}
				}
			}));
			taskManager.getTask(CoreTaskType.TIMEOUT, ret.get()).changeState(TaskState.IDLE);
			return new CInt(ret.get(), t);
		}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Scheduling.set_timeout.exec.set.SetFutureRunnable.new Runnable with () -> {isRunning.set(true); in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Scheduling.set_timeout


		@Override
		public String docs() {
			Map<String, DocGenTemplates.Generator> map = new HashMap<>();
			map.put("timezoneValues", (DocGenTemplates.Generator) (String... args) -> {
				String[] timezones = ArrayUtils.EMPTY_STRING_ARRAY;
				try {
					timezones = TimeZone.getAvailableIDs();
				} catch (NullPointerException e) {
					//This is due to a JDK bug. As you can see, the code above
					//should never NPE due to our mistake, so it would only occur
					//during an internal error. The solution that worked for me is here:
					//https://bugs.launchpad.net/ubuntu/+source/tzdata/+bug/1053160
					//however, this appears to be an issue in Open JDK, so performance on
					//other systems may vary. We will handle this error by reporting that
					//list could not be retrieved, using the Join method's empty parameter.
				}
				//Let's sort the timezones
				List<String> tz = new ArrayList<>(Arrays.asList(timezones));
				Collections.sort(tz);
				return StringUtils.Join(tz, ", ", " or ", " or ", "Couldn't retrieve the list of timezones!");
			});
			try {
				return getBundledDocs(map);
			} catch (DocGenTemplates.Generator.GenerateException ex) {
				Logger.getLogger(Scheduling.class.getName()).log(Level.SEVERE, null, ex);
				return getBundledDocs();
			}
		}

		@Override
		public String docs() {
			Map<String, DocGenTemplates.Generator> map = new HashMap<String, DocGenTemplates.Generator>();
			map.put("timezoneValues", new DocGenTemplates.Generator() {

				@Override
				public String generate(String... args) {
					String[] timezones = ArrayUtils.EMPTY_STRING_ARRAY;
					try {
						timezones = TimeZone.getAvailableIDs();
					} catch (NullPointerException e) {
						//This is due to a JDK bug. As you can see, the code above
						//should never NPE due to our mistake, so it would only occur
						//during an internal error. The solution that worked for me is here:
						//https://bugs.launchpad.net/ubuntu/+source/tzdata/+bug/1053160
						//however, this appears to be an issue in Open JDK, so performance on
						//other systems may vary. We will handle this error by reporting that
						//list could not be retrieved, using the Join method's empty parameter.
					}
					//Let's sort the timezones
					List<String> tz = new ArrayList<String>(Arrays.asList(timezones));
					Collections.sort(tz);
					return StringUtils.Join(tz, ", ", " or ", " or ", "Couldn't retrieve the list of timezones!");
				}
			});
			try {
				return getBundledDocs(map);
			} catch (DocGenTemplates.Generator.GenerateException ex) {
				Logger.getLogger(Scheduling.class.getName()).log(Level.SEVERE, null, ex);
				return getBundledDocs();
			}
		}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Scheduling.simple_date.docs.put.new DocGenTemplates.Generator with (args) -> {String[] timezones=ArrayUtils.EMPTY_STRING_ARRAY; in method public docs() : String from class com.laytonsmith.core.functions.Scheduling.simple_date


		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			//First things first, check the format of the arguments.
			if(!(args[0].isInstanceOf(CString.class))) {
				throw new CRECastException("Expected string for argument 1 in " + getName(), t);
			}
			if(!(args[1].isInstanceOf(CClosure.class))) {
				throw new CRECastException("Expected closure for argument 2 in " + getName(), t);
			}
			CronFormat format = validateFormat(args[0].val(), t);
			format.job = ((CClosure) args[1]);
			//At this point, the format is complete. We need to start up the cron thread if it's not running, and
			//then register this job, as well as inform clear_task of this id.
			synchronized(CRON_THREAD_LOCK) {
				if(cronThread == null) {
					final DaemonManager dm = environment.getEnv(GlobalEnv.class).GetDaemonManager();
					final MutableObject<Boolean> stopCron = new MutableObject<>(false);
					StaticLayer.GetConvertor().addShutdownHook(() -> {
						cronThread = null;
						stopCron.setObject(true);
						synchronized(CRON_JOBS) {
							CRON_JOBS.clear();
						}
						synchronized(CRON_THREAD_LOCK) {
							CRON_THREAD_LOCK.notifyAll();
						}
					});
					cronThread = new Thread(() -> {
						long lastMinute = 0;
						while(!stopCron.getObject()) {
							//We want to check to make sure that we only run once per minute, even though the
							//checks happen every second. This ensures that we have a fast enough sampling
							//period, while ensuring that we don't repeat tasks within the same minute.
							if((System.currentTimeMillis() / 1000 / 60) > lastMinute) {
								//Set the lastMinute value to now
								lastMinute = System.currentTimeMillis() / 1000 / 60;
								//Activate
								synchronized(CRON_JOBS) {
									Calendar c = Calendar.getInstance();
									for(final CronFormat f : CRON_JOBS.values()) {
										//Check to see if it is currently time to run each job
										if(f.min.contains(c.get(Calendar.MINUTE))
												&& f.hour.contains(c.get(Calendar.HOUR_OF_DAY))
												&& f.day.contains(c.get(Calendar.DAY_OF_MONTH))
												&& f.month.contains(c.get(Calendar.MONTH) + 1)
												&& f.dayOfWeek.contains(c.get(Calendar.DAY_OF_WEEK) - 1)) {
											//All the fields match, so let's trigger this job
											StaticLayer.GetConvertor().runOnMainThreadLater(dm, () -> {
												try {
													f.job.executeCallable();
												} catch (ConfigRuntimeException ex) {
													ConfigRuntimeException.HandleUncaughtException(ex, f.job.getEnv());
												}
											});
										}
									}
								}
							} //else continue, we'll wait another second.
							synchronized(CRON_THREAD_LOCK) {
								try {
									CRON_THREAD_LOCK.wait(1000);
								} catch (InterruptedException ex) {
									//Continue
								}
							}
						}
						dm.deactivateThread(cronThread);
					}, Implementation.GetServerType().getBranding() + "-CronDaemon");
					dm.activateThread(cronThread);
					cronThread.start();
				}
			}
			int jobID = JOB_IDS.getAndIncrement();
			synchronized(CRON_JOBS) {
				CRON_JOBS.put(jobID, format);
				format.job.getEnv().getEnv(GlobalEnv.class).SetCustom("cron-task-id", jobID);
			}
			return new CInt(jobID, t);
		}

		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			//First things first, check the format of the arguments.
			if(!(args[0].isInstanceOf(CString.class))) {
				throw new CRECastException("Expected string for argument 1 in " + getName(), t);
			}
			if(!(args[1].isInstanceOf(CClosure.class))) {
				throw new CRECastException("Expected closure for argument 2 in " + getName(), t);
			}
			CronFormat format = validateFormat(args[0].val(), t);
			format.job = ((CClosure) args[1]);
			//At this point, the format is complete. We need to start up the cron thread if it's not running, and
			//then register this job, as well as inform clear_task of this id.
			synchronized(CRON_THREAD_LOCK) {
				if(cronThread == null) {
					final DaemonManager dm = environment.getEnv(GlobalEnv.class).GetDaemonManager();
					final MutableObject<Boolean> stopCron = new MutableObject<>(false);
					StaticLayer.GetConvertor().addShutdownHook(new Runnable() {

						@Override
						public void run() {
							cronThread = null;
							stopCron.setObject(true);
							synchronized(CRON_JOBS) {
								CRON_JOBS.clear();
							}
							synchronized(CRON_THREAD_LOCK) {
								CRON_THREAD_LOCK.notifyAll();
							}
						}
					});
					cronThread = new Thread(new Runnable() {

						@Override
						public void run() {
							long lastMinute = 0;
							while(!stopCron.getObject()) {
								//We want to check to make sure that we only run once per minute, even though the
								//checks happen every second. This ensures that we have a fast enough sampling
								//period, while ensuring that we don't repeat tasks within the same minute.
								if((System.currentTimeMillis() / 1000 / 60) > lastMinute) {
									//Set the lastMinute value to now
									lastMinute = System.currentTimeMillis() / 1000 / 60;
									//Activate
									synchronized(CRON_JOBS) {
										Calendar c = Calendar.getInstance();
										for(final CronFormat f : CRON_JOBS.values()) {
											//Check to see if it is currently time to run each job
											if(f.min.contains(c.get(Calendar.MINUTE))
													&& f.hour.contains(c.get(Calendar.HOUR_OF_DAY))
													&& f.day.contains(c.get(Calendar.DAY_OF_MONTH))
													&& f.month.contains(c.get(Calendar.MONTH) + 1)
													&& f.dayOfWeek.contains(c.get(Calendar.DAY_OF_WEEK) - 1)) {
												//All the fields match, so let's trigger this job
												StaticLayer.GetConvertor().runOnMainThreadLater(dm, new Runnable() {

													@Override
													public void run() {
														try {
															f.job.executeCallable();
														} catch (ConfigRuntimeException ex) {
															ConfigRuntimeException.HandleUncaughtException(ex, f.job.getEnv());
														}
													}
												});
											}
										}
									}
								} //else continue, we'll wait another second.
								synchronized(CRON_THREAD_LOCK) {
									try {
										CRON_THREAD_LOCK.wait(1000);
									} catch (InterruptedException ex) {
										//Continue
									}
								}
							}
							dm.deactivateThread(cronThread);
						}
					}, Implementation.GetServerType().getBranding() + "-CronDaemon");
					dm.activateThread(cronThread);
					cronThread.start();
				}
			}
			int jobID = JOB_IDS.getAndIncrement();
			synchronized(CRON_JOBS) {
				CRON_JOBS.put(jobID, format);
				format.job.getEnv().getEnv(GlobalEnv.class).SetCustom("cron-task-id", jobID);
			}
			return new CInt(jobID, t);
		}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Scheduling.set_cron.exec.new Thread.new Runnable with () -> {long lastMinute=0; in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Scheduling.set_cron


	@SuppressWarnings("unchecked")
	private SiteDeploy(String siteBase, String docsBase, boolean useLocalCache,
			DeploymentMethod deploymentMethod, boolean doValidation, boolean showTemplateCredit,
			String githubBaseUrl, String validatorUrl, File finalizerScript, boolean clearProgressBar,
			String overrideIdRsa)
			throws IOException {
		this.siteBase = siteBase;
		this.docsBase = docsBase;
		this.resourceBase = docsBase + "resources/";
		this.finalizerScript = finalizerScript;
		this.reader = new jline.console.ConsoleReader();
		this.generateQueue = new ThreadPoolExecutor(1, 1,
				0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<>(),
				new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				return new Thread(r, "generateQueue");
			}
		});
		this.uploadQueue = new ThreadPoolExecutor(1, 1,
				0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<>(),
				new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				return new Thread(r, "uploadQueue");
			}
		});
		this.useLocalCache = useLocalCache;
		this.deploymentMethod = deploymentMethod;
		this.doValidation = doValidation;
		this.showTemplateCredit = showTemplateCredit;
		this.validatorUrl = validatorUrl;
		if(githubBaseUrl.isEmpty()) {
			githubBaseUrl = DEFAULT_GITHUB_BASE_URL;
		}
		this.githubBaseUrl = githubBaseUrl;
		this.clearProgressBar = clearProgressBar;
		pn = getPersistenceNetwork();
		if(pn != null) {
			try {
				String localCache = pn.get(new String[]{"site_deploy", "local_cache"});
				if(localCache == null) {
					localCache = "{}";
				}
				lc = (Map<String, String>) JSONValue.parse(localCache);
			} catch (DataSourceException | IllegalArgumentException ex) {
				writeLog("Could not read in local cache", ex);
				notificationAboutLocalCache = false;
			}
		}
		this.overrideIdRsa = overrideIdRsa;
	}

	@SuppressWarnings("unchecked")
	private SiteDeploy(String siteBase, String docsBase, boolean useLocalCache,
			DeploymentMethod deploymentMethod, boolean doValidation, boolean showTemplateCredit,
			String githubBaseUrl, String validatorUrl, File finalizerScript, boolean clearProgressBar,
			String overrideIdRsa)
			throws IOException {
		this.siteBase = siteBase;
		this.docsBase = docsBase;
		this.resourceBase = docsBase + "resources/";
		this.finalizerScript = finalizerScript;
		this.reader = new jline.console.ConsoleReader();
		this.generateQueue = new ThreadPoolExecutor(1, 1,
				0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<Runnable>(),
				new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				return new Thread(r, "generateQueue");
			}
		});
		this.uploadQueue = new ThreadPoolExecutor(1, 1,
				0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<Runnable>(),
				new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				return new Thread(r, "uploadQueue");
			}
		});
		this.useLocalCache = useLocalCache;
		this.deploymentMethod = deploymentMethod;
		this.doValidation = doValidation;
		this.showTemplateCredit = showTemplateCredit;
		this.validatorUrl = validatorUrl;
		if(githubBaseUrl.isEmpty()) {
			githubBaseUrl = DEFAULT_GITHUB_BASE_URL;
		}
		this.githubBaseUrl = githubBaseUrl;
		this.clearProgressBar = clearProgressBar;
		pn = getPersistenceNetwork();
		if(pn != null) {
			try {
				String localCache = pn.get(new String[]{"site_deploy", "local_cache"});
				if(localCache == null) {
					localCache = "{}";
				}
				lc = (Map<String, String>) JSONValue.parse(localCache);
			} catch (DataSourceException | IllegalArgumentException ex) {
				writeLog("Could not read in local cache", ex);
				notificationAboutLocalCache = false;
			}
		}
		this.overrideIdRsa = overrideIdRsa;
	}

Replace Generic With Diamond ThreadPoolExecutor with ThreadPoolExecutor in method private SiteDeploy(siteBase String, docsBase String, useLocalCache boolean, deploymentMethod DeploymentMethod, doValidation boolean, showTemplateCredit boolean, githubBaseUrl String, validatorUrl String, finalizerScript File, clearProgressBar boolean, overrideIdRsa String) from class com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy


	@Override
	public IVariableList clone() {
		IVariableList clone = new IVariableList();
		clone.varList = new HashMap<>(varList);
		return clone;
	}

	@Override
	public IVariableList clone() {
		IVariableList clone = new IVariableList();
		clone.varList = new HashMap<String, IVariable>(varList);
		return clone;
	}

Replace Generic With Diamond HashMap<String,IVariable> with HashMap<> in method public clone() : IVariableList from class com.laytonsmith.core.constructs.IVariableList


	@EventHandler(priority = EventPriority.LOWEST)
	public void onPlayerChat(final AsyncPlayerChatEvent event) {
		if(interpreterMode.contains(event.getPlayer().getName())) {
			final MCPlayer p = new BukkitMCPlayer(event.getPlayer());
			event.setCancelled(true);
			StaticLayer.SetFutureRunnable(null, 0, () -> textLine(p, event.getMessage()));
		}

	}

	@EventHandler(priority = EventPriority.LOWEST)
	public void onPlayerChat(final AsyncPlayerChatEvent event) {
		if(interpreterMode.contains(event.getPlayer().getName())) {
			final MCPlayer p = new BukkitMCPlayer(event.getPlayer());
			event.setCancelled(true);
			StaticLayer.SetFutureRunnable(null, 0, new Runnable() {

				@Override
				public void run() {
					textLine(p, event.getMessage());
				}
			});
		}

	}

Replace Anonymous With Lambda com.laytonsmith.commandhelper.CommandHelperInterpreterListener.onPlayerChat.SetFutureRunnable.new Runnable with () -> textLine(p,event.getMessage()) in method public onPlayerChat(event AsyncPlayerChatEvent) : void from class com.laytonsmith.commandhelper.CommandHelperInterpreterListener


	public void execute(String script, final MCPlayer p) throws ConfigCompileException, ConfigCompileGroupException {
		TokenStream stream = MethodScriptCompiler.lex(script, new File("Interpreter"), true);
		ParseTree tree = MethodScriptCompiler.compile(stream, null);
		interpreterMode.remove(p.getName());
		GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork,
				CommandHelperFileLocations.getDefault().getConfigDirectory(),
				plugin.profiles, new TaskManagerImpl());
		gEnv.SetDynamicScriptingMode(true);
		CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
		cEnv.SetPlayer(p);
		Environment env = Environment.createEnvironment(gEnv, cEnv);
		try {
			MethodScriptCompiler.registerAutoIncludes(env, null);
			MethodScriptCompiler.execute(tree, env, output -> {
				output = output.trim();
				if(output.isEmpty()) {
					Static.SendMessage(p, ":");
				} else {
					if(output.startsWith("/")) {
						//Run the command
						Static.SendMessage(p, ":" + MCChatColor.YELLOW + output);
						p.chat(output);
					} else {
						//output the results
						Static.SendMessage(p, ":" + MCChatColor.GREEN + output);
					}
				}
				interpreterMode.add(p.getName());
			}, null);
		} catch (CancelCommandException e) {
			interpreterMode.add(p.getName());
		} catch (ConfigRuntimeException e) {
			ConfigRuntimeException.HandleUncaughtException(e, env);
			Static.SendMessage(p, MCChatColor.RED + e.toString());
			interpreterMode.add(p.getName());
		} catch (Exception e) {
			Static.SendMessage(p, MCChatColor.RED + e.toString());
			Static.getLogger().log(Level.SEVERE, null, e);
			interpreterMode.add(p.getName());
		}
	}

	public void execute(String script, final MCPlayer p) throws ConfigCompileException, ConfigCompileGroupException {
		TokenStream stream = MethodScriptCompiler.lex(script, new File("Interpreter"), true);
		ParseTree tree = MethodScriptCompiler.compile(stream, null);
		interpreterMode.remove(p.getName());
		GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork,
				CommandHelperFileLocations.getDefault().getConfigDirectory(),
				plugin.profiles, new TaskManagerImpl());
		gEnv.SetDynamicScriptingMode(true);
		CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
		cEnv.SetPlayer(p);
		Environment env = Environment.createEnvironment(gEnv, cEnv);
		try {
			MethodScriptCompiler.registerAutoIncludes(env, null);
			MethodScriptCompiler.execute(tree, env, new MethodScriptComplete() {

				@Override
				public void done(String output) {
					output = output.trim();
					if(output.isEmpty()) {
						Static.SendMessage(p, ":");
					} else {
						if(output.startsWith("/")) {
							//Run the command
							Static.SendMessage(p, ":" + MCChatColor.YELLOW + output);
							p.chat(output);
						} else {
							//output the results
							Static.SendMessage(p, ":" + MCChatColor.GREEN + output);
						}
					}
					interpreterMode.add(p.getName());
				}
			}, null);
		} catch (CancelCommandException e) {
			interpreterMode.add(p.getName());
		} catch (ConfigRuntimeException e) {
			ConfigRuntimeException.HandleUncaughtException(e, env);
			Static.SendMessage(p, MCChatColor.RED + e.toString());
			interpreterMode.add(p.getName());
		} catch (Exception e) {
			Static.SendMessage(p, MCChatColor.RED + e.toString());
			Logger.getLogger(CommandHelperInterpreterListener.class.getName()).log(Level.SEVERE, null, e);
			interpreterMode.add(p.getName());
		}
	}

Replace Anonymous With Lambda com.laytonsmith.commandhelper.CommandHelperInterpreterListener.execute.execute.new MethodScriptComplete with output -> {output=output.trim(); in method public execute(script String, p MCPlayer) : void from class com.laytonsmith.commandhelper.CommandHelperInterpreterListener


		public List<FileInfo> getMSFiles() {
			return new ArrayList<>(ms);
		}

		public List<FileInfo> getMSFiles() {
			return new ArrayList<FileInfo>(ms);
		}

Replace Generic With Diamond ArrayList<FileInfo> with ArrayList<> in method public getMSFiles() : List<FileInfo> from class com.laytonsmith.core.AliasCore.LocalPackage


		public List<FileInfo> getMSAFiles() {
			return new ArrayList<>(msa);
		}

		public List<FileInfo> getMSAFiles() {
			return new ArrayList<FileInfo>(msa);
		}

Replace Generic With Diamond ArrayList<FileInfo> with ArrayList<> in method public getMSAFiles() : List<FileInfo> from class com.laytonsmith.core.AliasCore.LocalPackage


	public List<Script> getScripts() {
		return new ArrayList<>(scripts);
	}

	public List<Script> getScripts() {
		return new ArrayList<Script>(scripts);
	}

Replace Generic With Diamond ArrayList<Script> with ArrayList<> in method public getScripts() : List<Script> from class com.laytonsmith.core.AliasCore


		@SuppressWarnings({"BroadCatchBlock", "TooBroadCatch", "UseSpecificCatch"})
		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			//TODO: Make this more robust by having a local cache of the environment which we modify, and get_env returns from.
			Map<String, String> newenv = new HashMap<>(System.getenv());
			newenv.put(args[0].val(), args[1].val());
			boolean ret;
			try {
				Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
				Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
				theEnvironmentField.setAccessible(true);
				Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
				env.putAll(newenv);
				Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
				theCaseInsensitiveEnvironmentField.setAccessible(true);
				Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
				cienv.putAll(newenv);
				ret = true;
			} catch (NoSuchFieldException e) {
				try {
					Class[] classes = Collections.class.getDeclaredClasses();
					Map<String, String> env = System.getenv();
					for(Class cl : classes) {
						if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
							Field field = cl.getDeclaredField("m");
							field.setAccessible(true);
							Object obj = field.get(env);
							Map<String, String> map = (Map<String, String>) obj;
							map.clear();
							map.putAll(newenv);
						}
					}
					ret = true;
				} catch (Exception e2) {
					ret = false;
					if(Prefs.DebugMode()) {
						MSLog.GetLogger().e(MSLog.Tags.GENERAL, e2, t);
					}
				}
			} catch (Exception e1) {
				ret = false;
				if(Prefs.DebugMode()) {
					MSLog.GetLogger().e(MSLog.Tags.GENERAL, e1, t);
				}
			}
			return CBoolean.get(ret);
		}

		@SuppressWarnings({"BroadCatchBlock", "TooBroadCatch", "UseSpecificCatch"})
		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			//TODO: Make this more robust by having a local cache of the environment which we modify, and get_env returns from.
			Map<String, String> newenv = new HashMap<String, String>(System.getenv());
			newenv.put(args[0].val(), args[1].val());
			boolean ret;
			try {
				Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
				Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
				theEnvironmentField.setAccessible(true);
				Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
				env.putAll(newenv);
				Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
				theCaseInsensitiveEnvironmentField.setAccessible(true);
				Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
				cienv.putAll(newenv);
				ret = true;
			} catch (NoSuchFieldException e) {
				try {
					Class[] classes = Collections.class.getDeclaredClasses();
					Map<String, String> env = System.getenv();
					for(Class cl : classes) {
						if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
							Field field = cl.getDeclaredField("m");
							field.setAccessible(true);
							Object obj = field.get(env);
							Map<String, String> map = (Map<String, String>) obj;
							map.clear();
							map.putAll(newenv);
						}
					}
					ret = true;
				} catch (Exception e2) {
					ret = false;
					if(Prefs.DebugMode()) {
						MSLog.GetLogger().e(MSLog.Tags.GENERAL, e2, t);
					}
				}
			} catch (Exception e1) {
				ret = false;
				if(Prefs.DebugMode()) {
					MSLog.GetLogger().e(MSLog.Tags.GENERAL, e1, t);
				}
			}
			return CBoolean.get(ret);
		}

Replace Generic With Diamond HashMap<String,String> with HashMap<> in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Cmdline.set_env


		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment, true)) {
				throw new CREInsufficientPermissionException(getName() + " cannot be used outside of cmdline mode.", t);
			}
			boolean mask = true;
			if(args.length > 1) {
				mask = ArgumentValidation.getBoolean(args[1], t);
			}

			String prompt = args[0].val();
			Character cha = (char) 0;
			if(mask) {
				cha = '*';
			}
			try(jline.console.ConsoleReader reader = new jline.console.ConsoleReader()) {
				reader.setExpandEvents(false);
				return new CSecureString(reader.readLine(Static.MCToANSIColors(prompt), cha).toCharArray(), t);
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			}

		}

		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment)) {
				throw new CREInsufficientPermissionException(getName() + " cannot be used outside of cmdline mode.", t);
			}
			boolean mask = true;
			if(args.length > 1) {
				mask = ArgumentValidation.getBoolean(args[1], t);
			}

			String prompt = args[0].val();
			Character cha = new Character((char) 0);
			if(mask) {
				cha = new Character('*');
			}
			jline.console.ConsoleReader reader = null;
			try {
				reader = new jline.console.ConsoleReader();
				reader.setExpandEvents(false);
				return new CSecureString(reader.readLine(Static.MCToANSIColors(prompt), cha).toCharArray(), t);
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			} finally {
				if(reader != null) {
					reader.close();
				}
			}

		}

Try With Resources try(jline.console.ConsoleReader reader=new jline.console.ConsoleReader()) in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Cmdline.prompt_pass


		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment, true)) {
				throw new CREInsufficientPermissionException(getName() + " cannot be used outside of cmdline mode.", t);
			}

			String prompt = args[0].val();
			try(jline.console.ConsoleReader reader = new jline.console.ConsoleReader()) {
				reader.setExpandEvents(false);
				String line = reader.readLine(Static.MCToANSIColors(prompt));
				return new CString(line, t);
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			}

		}

		@Override
		public Mixed exec(Target t, Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment)) {
				throw new CREInsufficientPermissionException(getName() + " cannot be used outside of cmdline mode.", t);
			}

			String prompt = args[0].val();
			jline.console.ConsoleReader reader = null;
			try {
				reader = new jline.console.ConsoleReader();
				reader.setExpandEvents(false);
				String line = reader.readLine(Static.MCToANSIColors(prompt));
				return new CString(line, t);
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			} finally {
				if(reader != null) {
					reader.close();
				}
			}

		}

Try With Resources try(jline.console.ConsoleReader reader=new jline.console.ConsoleReader()) in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Cmdline.prompt_line


				@Override
				public void write(int b) throws IOException {
					if(stdout == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(() -> {
								stdout.executeCallable(new CString(sbout.getObject(), t));
								return null;
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sbout.setObject(new StringBuilder());
					} else {
						sbout.getObject().append(c);
					}
				}

				@Override
				public void write(int b) throws IOException {
					if(stdout == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {

								@Override
								public Object call() throws Exception {
									stdout.executeCallable(new CString(sbout.getObject(), t));
									return null;
								}
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sbout.setObject(new StringBuilder());
					} else {
						sbout.getObject().append(c);
					}
				}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Cmdline.shell_adv.exec.setSystemOut.new OutputStream.write.runOnMainThreadAndWait.new Callable<Object> with () -> {stdout.executeCallable(new CString(sbout.getObject(),t)); in method public write(b int) : void from class com.laytonsmith.core.functions.Cmdline.shell_adv.exec.setSystemOut.new OutputStream


				@Override
				public void write(int b) throws IOException {
					if(stderr == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(() -> {
								stderr.executeCallable(new CString(sberr.getObject(), t));
								return null;
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sberr.setObject(new StringBuilder());
					} else {
						sberr.getObject().append(c);
					}
				}

				@Override
				public void write(int b) throws IOException {
					if(stderr == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {

								@Override
								public Object call() throws Exception {
									stderr.executeCallable(new CString(sberr.getObject(), t));
									return null;
								}
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sberr.setObject(new StringBuilder());
					} else {
						sberr.getObject().append(c);
					}
				}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Cmdline.shell_adv.exec.setSystemErr.new OutputStream.write.runOnMainThreadAndWait.new Callable<Object> with () -> {stderr.executeCallable(new CString(sberr.getObject(),t)); in method public write(b int) : void from class com.laytonsmith.core.functions.Cmdline.shell_adv.exec.setSystemErr.new OutputStream


		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment, true)) {
				if(!Prefs.AllowShellCommands()) {
					throw new CREInsufficientPermissionException("Shell commands are not allowed. Enable them in preferences.ini.", t);
				}
				if(environment.getEnv(GlobalEnv.class).GetDynamicScriptingMode() && !Prefs.AllowDynamicShell()) {
					throw new CREInsufficientPermissionException("Shell commands are disabled from dynamic sources.", t);
				}
			}
			String[] command;
			File workingDir = null;
			final CClosure stdout;
			final CClosure stderr;
			final CClosure exit;
			final boolean subshell;
			if(args[0] instanceof CArray) {
				CArray array = (CArray) args[0];
				command = new String[(int) array.size()];
				for(int i = 0; i < array.size(); i++) {
					command[i] = array.get(i, t).val();
				}
			} else {
				command = StringUtils.ArgParser(args[0].val()).toArray(new String[0]);
			}
			if(args.length > 1) {
				CArray options = Static.getArray(args[1], t);
				if(options.containsKey("workingDir") && !(options.get("workingDir", t) instanceof CNull)) {
					workingDir = new File(options.get("workingDir", t).val());
					if(!workingDir.isAbsolute()) {
						workingDir = new File(t.file().getParentFile(), workingDir.getPath());
					}
				}
				stdout = (options.containsKey("stdout") && !(options.get("stdout", t) instanceof CNull)
						? Static.getObject(options.get("stdout", t), t, CClosure.class) : null);
				stderr = (options.containsKey("stderr") && !(options.get("stderr", t) instanceof CNull)
						? Static.getObject(options.get("stderr", t), t, CClosure.class) : null);
				exit = (options.containsKey("exit") && !(options.get("exit", t) instanceof CNull)
						? Static.getObject(options.get("exit", t), t, CClosure.class) : null);
				subshell = (options.containsKey("subshell")
						? ArgumentValidation.getBoolean(options.get("subshell", t), t) : false);
			} else {
				stdout = null;
				stderr = null;
				exit = null;
				subshell = false;
			}
			final CommandExecutor cmd = new CommandExecutor(command);
			cmd.setWorkingDir(workingDir);
			final MutableObject<StringBuilder> sbout = new MutableObject(new StringBuilder());
			final MutableObject<StringBuilder> sberr = new MutableObject(new StringBuilder());
			cmd.setSystemOut(new OutputStream() {
				@Override
				public void write(int b) throws IOException {
					if(stdout == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(() -> {
								stdout.executeCallable(new CString(sbout.getObject(), t));
								return null;
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sbout.setObject(new StringBuilder());
					} else {
						sbout.getObject().append(c);
					}
				}
			});
			cmd.setSystemErr(new OutputStream() {
				@Override
				public void write(int b) throws IOException {
					if(stderr == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(() -> {
								stderr.executeCallable(new CString(sberr.getObject(), t));
								return null;
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sberr.setObject(new StringBuilder());
					} else {
						sberr.getObject().append(c);
					}
				}
			});
			try {
				cmd.start();
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			}

			Runnable run = () -> {
				environment.getEnv(GlobalEnv.class).GetDaemonManager().activateThread(null);
				try {
					final int exitCode = cmd.waitFor();
					try {
						cmd.getSystemOut().flush();
						if(cmd.getSystemOut() != StreamUtils.GetSystemOut()) {
							cmd.getSystemOut().close();
						}
					} catch (IOException ex) {
						Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
					}
					try {
						cmd.getSystemErr().flush();
						if(cmd.getSystemErr() != StreamUtils.GetSystemErr()) {
							cmd.getSystemErr().close();
						}
					} catch (IOException ex) {
						Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
					}
					if(exit != null) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(() -> {
								exit.executeCallable(new CInt(exitCode, t));
								return null;
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
					}
				} catch (InterruptedException ex) {
					throw ConfigRuntimeException.CreateUncatchableException(ex.getMessage(), t);
				} finally {
					environment.getEnv(GlobalEnv.class).GetDaemonManager().deactivateThread(null);
				}
			};
			if(subshell) {
				new Thread(run, "shell-adv-subshell (" + StringUtils.Join(command, " ") + ")").start();
			} else {
				run.run();
			}
			return CVoid.VOID;
		}

		@Override
		public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException {
			if(!Static.InCmdLine(environment)) {
				if(!Prefs.AllowShellCommands()) {
					throw new CREInsufficientPermissionException("Shell commands are not allowed. Enable them in preferences.ini.", t);
				}
				if(environment.getEnv(GlobalEnv.class).GetDynamicScriptingMode() && !Prefs.AllowDynamicShell()) {
					throw new CREInsufficientPermissionException("Shell commands are disabled from dynamic sources.", t);
				}
			}
			String[] command;
			File workingDir = null;
			final CClosure stdout;
			final CClosure stderr;
			final CClosure exit;
			final boolean subshell;
			if(args[0] instanceof CArray) {
				CArray array = (CArray) args[0];
				command = new String[(int) array.size()];
				for(int i = 0; i < array.size(); i++) {
					command[i] = array.get(i, t).val();
				}
			} else {
				command = StringUtils.ArgParser(args[0].val()).toArray(new String[0]);
			}
			if(args.length > 1) {
				CArray options = Static.getArray(args[1], t);
				if(options.containsKey("workingDir") && !(options.get("workingDir", t) instanceof CNull)) {
					workingDir = new File(options.get("workingDir", t).val());
					if(!workingDir.isAbsolute()) {
						workingDir = new File(t.file().getParentFile(), workingDir.getPath());
					}
				}
				stdout = (options.containsKey("stdout") && !(options.get("stdout", t) instanceof CNull)
						? Static.getObject(options.get("stdout", t), t, CClosure.class) : null);
				stderr = (options.containsKey("stderr") && !(options.get("stderr", t) instanceof CNull)
						? Static.getObject(options.get("stderr", t), t, CClosure.class) : null);
				exit = (options.containsKey("exit") && !(options.get("exit", t) instanceof CNull)
						? Static.getObject(options.get("exit", t), t, CClosure.class) : null);
				subshell = (options.containsKey("subshell")
						? ArgumentValidation.getBoolean(options.get("subshell", t), t) : false);
			} else {
				stdout = null;
				stderr = null;
				exit = null;
				subshell = false;
			}
			final CommandExecutor cmd = new CommandExecutor(command);
			cmd.setWorkingDir(workingDir);
			final MutableObject<StringBuilder> sbout = new MutableObject(new StringBuilder());
			final MutableObject<StringBuilder> sberr = new MutableObject(new StringBuilder());
			cmd.setSystemOut(new OutputStream() {
				@Override
				public void write(int b) throws IOException {
					if(stdout == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {

								@Override
								public Object call() throws Exception {
									stdout.executeCallable(new CString(sbout.getObject(), t));
									return null;
								}
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sbout.setObject(new StringBuilder());
					} else {
						sbout.getObject().append(c);
					}
				}
			});
			cmd.setSystemErr(new OutputStream() {
				@Override
				public void write(int b) throws IOException {
					if(stderr == null) {
						return;
					}
					char c = (char) b;
					if(c == '\n' || b == -1) {
						try {
							StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {

								@Override
								public Object call() throws Exception {
									stderr.executeCallable(new CString(sberr.getObject(), t));
									return null;
								}
							});
						} catch (Exception ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						sberr.setObject(new StringBuilder());
					} else {
						sberr.getObject().append(c);
					}
				}
			});
			try {
				cmd.start();
			} catch (IOException ex) {
				throw new CREIOException(ex.getMessage(), t);
			}

			Runnable run = new Runnable() {

				@Override
				public void run() {
					environment.getEnv(GlobalEnv.class).GetDaemonManager().activateThread(null);
					try {
						final int exitCode = cmd.waitFor();
						try {
							cmd.getSystemOut().flush();
							if(cmd.getSystemOut() != StreamUtils.GetSystemOut()) {
								cmd.getSystemOut().close();
							}
						} catch (IOException ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						try {
							cmd.getSystemErr().flush();
							if(cmd.getSystemErr() != StreamUtils.GetSystemErr()) {
								cmd.getSystemErr().close();
							}
						} catch (IOException ex) {
							Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
						}
						if(exit != null) {
							try {
								StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable<Object>() {

									@Override
									public Object call() throws Exception {
										exit.executeCallable(new CInt(exitCode, t));
										return null;
									}
								});
							} catch (Exception ex) {
								Logger.getLogger(Cmdline.class.getName()).log(Level.SEVERE, null, ex);
							}
						}
					} catch (InterruptedException ex) {
						throw ConfigRuntimeException.CreateUncatchableException(ex.getMessage(), t);
					} finally {
						environment.getEnv(GlobalEnv.class).GetDaemonManager().deactivateThread(null);
					}
				}
			};
			if(subshell) {
				new Thread(run, "shell-adv-subshell (" + StringUtils.Join(command, " ") + ")").start();
			} else {
				run.run();
			}
			return CVoid.VOID;
		}

Replace Anonymous With Lambda com.laytonsmith.core.functions.Cmdline.shell_adv.exec.run.new Runnable with () -> {environment.getEnv(GlobalEnv.class).GetDaemonManager().activateThread(null); in method public exec(t Target, environment Environment, args Mixed...) : Mixed from class com.laytonsmith.core.functions.Cmdline.shell_adv