//  [java]
	public String createEmbedJavaScript(HttpServletRequest request)
			throws IOException
	{
		String sparam = request.getParameter("s");
		String dev = request.getParameter("dev");
		StringBuffer result = new StringBuffer("[");
		StringBuffer js = new StringBuffer("");

		// Processes each stencil only once
		HashSet<String> done = new HashSet<String>();

		// Processes each lib only once
		HashSet<String> libsLoaded = new HashSet<String>();

		if (sparam != null)
		{
			String[] names = sparam.split(";");

			for (int i = 0; i < names.length; i++)
			{
				if (names[i].indexOf("..") < 0 && !done.contains(names[i]))
				{
					if (names[i].equals("*"))
					{
						js.append(readXmlFile("/js/shapes-14-6-5.min.js", false));
						result.append(
								"'" + readXmlFile("/stencils.xml", true) + "'");
					}
					else
					{
						// Checks if any JS files are associated with the library
						// name and injects the JS into the page
						String[] libs = libraries.get(names[i]);

						if (libs != null)
						{
							for (int j = 0; j < libs.length; j++)
							{
								if (!libsLoaded.contains(libs[j]))
								{
									String tmp = stencils.get(libs[j]);
									libsLoaded.add(libs[j]);

									if (tmp == null)
									{
										try
										{
											tmp = readXmlFile(libs[j],
													!libs[j].toLowerCase()
															.endsWith(".js"));

											// Cache for later use
											if (tmp != null)
											{
												stencils.put(libs[j], tmp);
											}
										}
										catch (NullPointerException e)
										{
											// This seems possible according to access log so ignore stencil
										}
									}

									if (tmp != null)
									{
										// TODO: Add JS to Javascript code inline. This had to be done to quickly
										// add JS-based dynamic loading to the existing embed setup where everything
										// dynamic is passed via function call, so an indirection via eval must be
										// used even though the JS could be parsed directly by adding it to JS.
										if (libs[j].toLowerCase()
												.endsWith(".js"))
										{
											js.append(tmp);
										}
										else
										{
											if (result.length() > 1)
											{
												result.append(",");
											}

											result.append("'" + tmp + "'");
										}
									}
								}
							}
						}
						else
						{
							String tmp = stencils.get(names[i]);

							if (tmp == null)
							{
								try
								{
									tmp = readXmlFile(
											"/stencils/" + names[i] + ".xml",
											true);

									// Cache for later use
									if (tmp != null)
									{
										stencils.put(names[i], tmp);
									}
								}
								catch (NullPointerException e)
								{
									// This seems possible according to access log so ignore stencil
								}
							}

							if (tmp != null)
							{
								if (result.length() > 1)
								{
									result.append(",");
								}

								result.append("'" + tmp + "'");
							}
						}
					}

					done.add(names[i]);
				}
			}
		}

		result.append("]");

		// LATER: Detect protocol of request in dev
		// mode to avoid security errors
		String proto = "https://";

		String setCachedUrls = "";
		String[] urls = request.getParameterValues("fetch");

		if (urls != null)
		{
			HashSet<String> completed = new HashSet<String>();

			for (int i = 0; i < urls.length; i++)
			{
				try
				{
					// Checks if URL already fetched to avoid duplicates
					if (!completed.contains(urls[i]) && Utils.sanitizeUrl(urls[i]))
					{
						completed.add(urls[i]);
						URL url = new URL(urls[i]);
						URLConnection connection = url.openConnection();
						ByteArrayOutputStream stream = new ByteArrayOutputStream();
						Utils.copy(connection.getInputStream(), stream);
						setCachedUrls += "GraphViewer.cachedUrls['"
								+ StringEscapeUtils.escapeEcmaScript(urls[i])
								+ "'] = decodeURIComponent('"
								+ StringEscapeUtils.escapeEcmaScript(
										Utils.encodeURIComponent(
												stream.toString("UTF-8"),
												Utils.CHARSET_FOR_URL_ENCODING))
								+ "');";
					}
				}
				catch (Exception e)
				{
					// ignore
				}
			}
		}

		// Installs a callback to load the stencils after the viewer was injected
		return "window.onDrawioViewerLoad = function() {" + setCachedUrls
				+ "mxStencilRegistry.parseStencilSets(" + result.toString()
				+ ");" + js + "GraphViewer.processElements(); };"
				+ "var t = document.getElementsByTagName('script');"
				+ "if (t != null && t.length > 0) {"
				+ "var script = document.createElement('script');"
				+ "script.type = 'text/javascript';" + "script.src = '" + proto
				+ ((dev != null && dev.equals("1")) ? "test" : "www")
				+ ".draw.io/js/viewer-static.min.js';"
				+ "t[0].parentNode.appendChild(script);}";
	}