	public int decryptWithAd(byte[] ad, byte[] ciphertext,
			int ciphertextOffset, byte[] plaintext, int plaintextOffset,
			int length) throws ShortBufferException, BadPaddingException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (length > space)
			throw new ShortBufferException();
		if (plaintextOffset > plaintext.length)
			space = 0;
		else
			space = plaintext.length - plaintextOffset;
		if (!haskey) {
			// The key is not set yet - return the ciphertext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(ciphertext, ciphertextOffset, plaintext, plaintextOffset, length);
			return length;
		}
		if (length < 16)
			Noise.throwBadTagException();
		int dataLen = length - 16;
		if (dataLen > space)
			throw new ShortBufferException();
		setup(ad);
		ghash.update(ciphertext, ciphertextOffset, dataLen);
		ghash.pad(ad != null ? ad.length : 0, dataLen);
		ghash.finish(enciv, 0, 16);
		int temp = 0;
		for (int index = 0; index < 16; ++index)
			temp |= (hashKey[index] ^ enciv[index] ^ ciphertext[ciphertextOffset + dataLen + index]);
		if ((temp & 0xFF) != 0)
			Noise.throwBadTagException();
		encryptCTR(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
		return dataLen;
	}


	private String getTitleQTI12(QuestionItemImpl item) {
		try {
			VFSLeaf leaf = qpoolService.getRootLeaf(item);
			Item xmlItem = QTIEditHelper.readItemXml(leaf);
			return xmlItem.getTitle();
		} catch (NullPointerException e) {
			log.warn("Cannot read files from dir: " + item.getDirectory());
		}
		return null;
	}


	public PlayerBinary(String code, ISkinParam skinParam, TimingRuler ruler, boolean compact) {
		super(code, skinParam, ruler, compact);
		this.style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder());
		this.suggestedHeight = 30;
	}


    DefaultResetPasswordRequestResponse(UserReference reference, InternetAddress userEmail, String verificationCode)
    {
        this.userReference = reference;
        this.userEmail = userEmail;
        this.verificationCode = verificationCode;
    }


	public Map<String, FileEntry> generatorCode(TableDetails tableDetails, String tablePrefix,
			Map<String, String> customProperties, List<TemplateFile> templateFiles) {

		Map<String, FileEntry> map = new HashMap<>(templateFiles.size());

		// 模板渲染
		Map<String, Object> context = GenUtils.getContext(tableDetails, tablePrefix, customProperties);

		for (TemplateFile templateFile : templateFiles) {
			FileEntry fileEntry = new FileEntry();
			fileEntry.setType(templateFile.getType());

			// 替换路径中的占位符
			String filename = StrUtil.format(templateFile.getFilename(), context);
			fileEntry.setFilename(filename);

			String parentFilePath = GenUtils.evaluateRealPath(templateFile.getParentFilePath(), context);
			fileEntry.setParentFilePath(parentFilePath);

			// 如果是文件
			if (TemplateEntryTypeEnum.FILE.getType().equals(fileEntry.getType())) {
				fileEntry.setFilePath(GenUtils.concatFilePath(parentFilePath, filename));
				// 文件内容渲染
				TemplateEngineTypeEnum engineTypeEnum = TemplateEngineTypeEnum.of(templateFile.getEngineType());
				String content = templateEngineDelegator.render(engineTypeEnum, templateFile.getContent(), context);
				fileEntry.setContent(content);
			}
			else {
				String currentPath = GenUtils.evaluateRealPath(templateFile.getFilename(), context);
				fileEntry.setFilePath(GenUtils.concatFilePath(parentFilePath, currentPath));
			}

			map.put(fileEntry.getFilePath(), fileEntry);
		}

		return map;
	}


    void validSaveNewTranslation() throws Exception
    {
        when(mockForm.getLanguage()).thenReturn("fr");
        when(mockClonedDocument.getTranslatedDocument("fr", this.context)).thenReturn(mockClonedDocument);
        when(mockClonedDocument.getDocumentReference()).thenReturn(new DocumentReference("xwiki", "My", "Page"));
        when(mockClonedDocument.getStore()).thenReturn(this.oldcore.getMockStore());
        when(xWiki.getStore()).thenReturn(this.oldcore.getMockStore());
        context.put("ajax", true);
        when(xWiki.isMultiLingual(this.context)).thenReturn(true);
        when(mockRequest.getParameter("previousVersion")).thenReturn("1.1");
        when(mockRequest.getParameter("isNew")).thenReturn("true");
        assertFalse(saveAction.save(this.context));
        assertEquals(new Version("1.1"), this.context.get("SaveAction.savedObjectVersion"));
        verify(this.xWiki).checkSavingDocument(eq(USER_REFERENCE), any(XWikiDocument.class), eq(""),
            eq(false), eq(this.context));
        verify(this.xWiki).saveDocument(any(XWikiDocument.class), eq(""), eq(false), eq(this.context));
    }


	public boolean loginValidate(String userName, String password) {

		String sql = "select * from admin_table where admin_name=? and password=?";
		try {
			ps=DbUtil.getConnection().prepareStatement(sql);
			ps.setString(1, userName);
			ps.setString(2,password);
			ResultSet rs =ps.executeQuery();
			if (rs.next()) {
				return true;
			}
		} catch (SQLException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}


	protected String getCorsDomain(String referer, String userAgent)
	{
		String dom = null;

		if (referer != null && referer.toLowerCase()
				.matches("https?://([a-z0-9,-]+[.])*draw[.]io/.*"))
		{
			dom = referer.toLowerCase().substring(0,
					referer.indexOf(".draw.io/") + 8);
		}
		else if (referer != null && referer.toLowerCase()
				.matches("https?://([a-z0-9,-]+[.])*diagrams[.]net/.*"))
		{
			dom = referer.toLowerCase().substring(0,
					referer.indexOf(".diagrams.net/") + 13);
		}
		else if (referer != null && referer.toLowerCase()
				.matches("https?://([a-z0-9,-]+[.])*quipelements[.]com/.*"))
		{
			dom = referer.toLowerCase().substring(0,
					referer.indexOf(".quipelements.com/") + 17);
		}
		// Enables Confluence/Jira proxy via referer or hardcoded user-agent (for old versions)
		// UA refers to old FF on macOS so low risk and fixes requests from existing servers
		else if ((referer != null
				&& referer.equals("draw.io Proxy Confluence Server"))
				|| (userAgent != null && userAgent.equals(
						"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0")))
		{
			dom = "";
		}

		return dom;
	}


    public void testSetNullHeaderValue() {
        final HttpHeadersBase headers = newEmptyHeaders();
        headers.set("test", (String) null);
    }


	public static AlgorithmMode resolveAlgorithmMode(final JWEAlgorithm alg)
		throws JOSEException {

		if (alg.equals(JWEAlgorithm.ECDH_ES)) {

			return AlgorithmMode.DIRECT;

		} else if (alg.equals(JWEAlgorithm.ECDH_ES_A128KW) ||
			alg.equals(JWEAlgorithm.ECDH_ES_A192KW) ||
			alg.equals(JWEAlgorithm.ECDH_ES_A256KW)) {

			return AlgorithmMode.KW;
		} else {

			throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(
				alg,
				ECDHCryptoProvider.SUPPORTED_ALGORITHMS));
		}
	}


    public void install(
            String displayName, String description, String[] dependencies,
            String account, String password, String config) throws URISyntaxException {

        String javaHome = System.getProperty("java.home");
        String javaBinary = javaHome + "\\bin\\java.exe";

        File jar = new File(WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI());
        String command = javaBinary
                + " -Duser.dir=\"" + jar.getParentFile().getAbsolutePath() + "\""
                + " -jar \"" + jar.getAbsolutePath() + "\""
                + " --service \"" + config + "\"";

        StringBuilder dep = new StringBuilder();

        if (dependencies != null) {
            for (String s : dependencies) {
                dep.append(s);
                dep.append("\0");
            }
        }
        dep.append("\0");

        SERVICE_DESCRIPTION desc = new SERVICE_DESCRIPTION();
        desc.lpDescription = description;

        SC_HANDLE serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS);

        if (serviceManager != null) {
            SC_HANDLE service = ADVAPI_32.CreateService(serviceManager, serviceName, displayName,
                    Winsvc.SERVICE_ALL_ACCESS, WinNT.SERVICE_WIN32_OWN_PROCESS, WinNT.SERVICE_AUTO_START,
                    WinNT.SERVICE_ERROR_NORMAL,
                    command,
                    null, null, dep.toString(), account, password);

            if (service != null) {
                ADVAPI_32.ChangeServiceConfig2(service, Winsvc.SERVICE_CONFIG_DESCRIPTION, desc);
                ADVAPI_32.CloseServiceHandle(service);
            }
            ADVAPI_32.CloseServiceHandle(serviceManager);
        }
    }


  public RechnungCostEditTablePanel(final String id)
  {
    super(id);
    feedbackPanel = new FeedbackPanel("feedback");
    ajaxComponents.register(feedbackPanel);
    add(feedbackPanel);
    this.form = new Form<AbstractRechnungsPositionDO>("form");
    add(form);
    rows = new RepeatingView("rows");
    form.add(rows);
  }


    public boolean isValid(Integer value, ConstraintValidatorContext context) {
      if (proxyManager.get(value) != null) {
        return true;
      }

      String errorMessage = String.format("No proxy server found for specified port %d", value);
      LOG.warn(errorMessage);

      context.buildConstraintViolationWithTemplate(errorMessage).addPropertyNode(PARAM_NAME).addConstraintViolation();
      return false;
    }


    public void translate(MapInfoRequestPacket packet, GeyserSession session) {
        long mapId = packet.getUniqueMapId();

        ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapId);
        if (mapPacket != null) {
            // Delay the packet 100ms to prevent the client from ignoring the packet
            GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(mapPacket),
                    100, TimeUnit.MILLISECONDS);
        }
    }


    void relative() {
        assertThat(PathAndQuery.parse("foo")).isNull();
    }


    protected SAXContentHandler createContentHandler(XMLReader reader) {
        return new SAXContentHandler(getDocumentFactory(), dispatchHandler);
    }


    public void testSetSelfIsNoOp() {
        final HttpHeadersBase headers = newEmptyHeaders();
        headers.add("name", "value");
        headers.set(headers);
        assertThat(headers.size()).isEqualTo(1);
    }


    public void testGetBytesAndSetBytesWithFileChannel() throws IOException {
        File file = File.createTempFile("file-channel", ".tmp");
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile(file, "rw");
            FileChannel channel = randomAccessFile.getChannel();
            // channelPosition should never be changed
            long channelPosition = channel.position();

            byte[] bytes = {'a', 'b', 'c', 'd'};
            int len = bytes.length;
            ByteBuf buffer = newBuffer(len);
            buffer.resetReaderIndex();
            buffer.resetWriterIndex();
            buffer.writeBytes(bytes);

            int oldReaderIndex = buffer.readerIndex();
            assertEquals(len, buffer.getBytes(oldReaderIndex, channel, 10, len));
            assertEquals(oldReaderIndex, buffer.readerIndex());
            assertEquals(channelPosition, channel.position());

            ByteBuf buffer2 = newBuffer(len);
            buffer2.resetReaderIndex();
            buffer2.resetWriterIndex();
            int oldWriterIndex = buffer2.writerIndex();
            assertEquals(buffer2.setBytes(oldWriterIndex, channel, 10, len), len);
            assertEquals(channelPosition, channel.position());

            assertEquals(oldWriterIndex, buffer2.writerIndex());
            assertEquals('a', buffer2.getByte(oldWriterIndex));
            assertEquals('b', buffer2.getByte(oldWriterIndex + 1));
            assertEquals('c', buffer2.getByte(oldWriterIndex + 2));
            assertEquals('d', buffer2.getByte(oldWriterIndex + 3));

            buffer.release();
            buffer2.release();
        } finally {
            if (randomAccessFile != null) {
                randomAccessFile.close();
            }
            file.delete();
        }
    }


   protected void traceLdapEnv(Properties env)
   {
      if (trace)
      {
         Properties tmp = new Properties();
         tmp.putAll(env);
         String credentials = tmp.getProperty(Context.SECURITY_CREDENTIALS);
         String bindCredential = tmp.getProperty(BIND_CREDENTIAL);
         if (credentials != null && credentials.length() > 0)
            tmp.setProperty(Context.SECURITY_CREDENTIALS, "***");

         if (bindCredential != null && bindCredential.length() > 0)
             tmp.setProperty(BIND_CREDENTIAL, "***");

         log.trace("Logging into LDAP server, env=" + tmp.toString());
      }
   }


    private void initAndSaveDocument(XWikiContext context, XWikiDocument newDocument, String title, String template,
        String parent) throws XWikiException
    {
        XWiki xwiki = context.getWiki();

        // Set the locale and default locale, considering that we're creating the original version of the document
        // (not a translation).
        newDocument.setLocale(Locale.ROOT);
        if (newDocument.getDefaultLocale() == Locale.ROOT) {
            newDocument.setDefaultLocale(xwiki.getLocalePreference(context));
        }

        // Copy the template.
        readFromTemplate(newDocument, template, context);

        // Set the parent field.
        if (!StringUtils.isEmpty(parent)) {
            DocumentReference parentReference = this.currentmixedReferenceResolver.resolve(parent);
            newDocument.setParentReference(parentReference);
        }

        // Set the document title
        if (title != null) {
            newDocument.setTitle(title);
        }

        // Set the author and creator.
        DocumentReference currentUserReference = context.getUserReference();
        newDocument.setAuthorReference(currentUserReference);
        newDocument.setCreatorReference(currentUserReference);

        // Make sure the user is allowed to make this modification
        xwiki.checkSavingDocument(currentUserReference, newDocument, context);

        xwiki.saveDocument(newDocument, context);
    }


    public void setSetContentFromFileExceptionally() throws Exception {
        final long maxSize = 4;
        DiskFileUpload f1 = new DiskFileUpload("file5", "file5", "application/json", null, null, 0);
        f1.setMaxSize(maxSize);
        try {
            f1.setContent(Unpooled.wrappedBuffer(new byte[(int) maxSize]));
            File originalFile = f1.getFile();
            assertNotNull(originalFile);
            assertEquals(maxSize, originalFile.length());
            assertEquals(maxSize, f1.length());
            byte[] bytes = new byte[8];
            PlatformDependent.threadLocalRandom().nextBytes(bytes);
            File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
            tmpFile.deleteOnExit();
            FileOutputStream fos = new FileOutputStream(tmpFile);
            try {
                fos.write(bytes);
                fos.flush();
            } finally {
                fos.close();
            }
            try {
                f1.setContent(tmpFile);
                fail("should not reach here!");
            } catch (IOException e) {
                assertNotNull(f1.getFile());
                assertEquals(originalFile, f1.getFile());
                assertEquals(maxSize, f1.length());
            }
        } finally {
            f1.delete();
        }
    }


  private CallbackHandler getCallbackHandler(
      @UnderInitialization(WrappedFactory.class) LibPQFactory this,
      Properties info) throws PSQLException {
    // Determine the callback handler
    CallbackHandler cbh;
    String sslpasswordcallback = PGProperty.SSL_PASSWORD_CALLBACK.get(info);
    if (sslpasswordcallback != null) {
      try {
        cbh = (CallbackHandler) ObjectFactory.instantiate(sslpasswordcallback, info, false, null);
      } catch (Exception e) {
        throw new PSQLException(
          GT.tr("The password callback class provided {0} could not be instantiated.",
            sslpasswordcallback),
          PSQLState.CONNECTION_FAILURE, e);
      }
    } else {
      cbh = new ConsoleCallbackHandler(PGProperty.SSL_PASSWORD.get(info));
    }
    return cbh;
  }


	public static boolean isAbsolute(String url)
	{
		if (url.startsWith("//"))  // //www.domain.com/start
		{
			return true;
		}

		if (url.startsWith("/")) // /somePage.html
		{
			return false;
		}

		boolean result = false;

		try
		{
			URI uri = new URI(url);
			result = uri.isAbsolute();
		}
		catch (URISyntaxException e) {} //Ignore

		return result;
	}


	protected void runTeardown() {
		Assert.assertTrue("HTTP connection is not allowed", messagedAccessDenied);
	}


    public void setXMLReader(XMLReader reader) {
        this.xmlReader = reader;
    }


    public String findFilter( String url_suffix )
    {
        if( url_suffix == null )
        {
            throw new IllegalArgumentException( "The url_suffix must not be null." );
        }

        CaptureType type = em.find( CaptureType.class, url_suffix );

        if( type != null )
        {
            return type.getCaptureFilter();
        }

        return null;
    }


    default boolean contains(String name) {
        return get(name, Object.class).isPresent();
    }


        public int getPosition()
        {
            if ( realPos == -1 )
            {
                realPos = ( getExecutable() == null ? 0 : 1 );
                for ( int i = 0; i < position; i++ )
                {
                    Arg arg = (Arg) arguments.elementAt( i );
                    realPos += arg.getParts().length;
                }
            }
            return realPos;
        }


    private String tryRewrite(String s) throws IOException, InvalidKeyException {
        if (s.length()<24)
            return s;   // Encrypting "" in Secret produces 24-letter characters, so this must be the minimum length
        if (!isBase64(s))
            return s;   // decode throws IOException if the input is not base64, and this is also a very quick way to filter

        byte[] in;
        try {
            in = Base64.decode(s.toCharArray());
        } catch (IOException e) {
            return s;   // not a valid base64
        }
        cipher.init(Cipher.DECRYPT_MODE, key);
        Secret sec = Secret.tryDecrypt(cipher, in);
        if(sec!=null) // matched
            return sec.getEncryptedValue(); // replace by the new encrypted value
        else // not encrypted with the legacy key. leave it unmodified
            return s;
    }


    public void translate(ServerEntityAttachPacket packet, GeyserSession session) {

        Entity holderId;
        if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
            holderId = session.getPlayerEntity();
        } else {
            holderId = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
            if (holderId == null) {
                return;
            }
        }

        Entity attachedToId;
        if (packet.getAttachedToId() == session.getPlayerEntity().getEntityId()) {
            attachedToId = session.getPlayerEntity();
        } else {
            attachedToId = session.getEntityCache().getEntityByJavaId(packet.getAttachedToId());
            if ((attachedToId == null || packet.getAttachedToId() == 0)) {
                // Is not being leashed
                holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, false);
                holderId.getMetadata().put(EntityData.LEASH_HOLDER_EID, -1L);
                holderId.updateBedrockMetadata(session);
                EntityEventPacket eventPacket = new EntityEventPacket();
                eventPacket.setRuntimeEntityId(holderId.getGeyserId());
                eventPacket.setType(EntityEventType.REMOVE_LEASH);
                eventPacket.setData(0);
                session.sendUpstreamPacket(eventPacket);
                return;
            }
        }

        holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, true);
        holderId.getMetadata().put(EntityData.LEASH_HOLDER_EID, attachedToId.getGeyserId());
        holderId.updateBedrockMetadata(session);
    }


    protected TestPolicy(Policy.ParseContext parseContext) throws PolicyException {
        super(parseContext);
    }


    private ModelAndView renameGroup(HttpServletRequest request, HttpServletResponse response) throws Exception {

        String oldName = request.getParameter("groupName");
        String newName = request.getParameter("newName");

        if (StringUtils.hasText(oldName) && StringUtils.hasText(newName)) {
            m_groupRepository.renameGroup(oldName, newName);
        }

        return listGroups(request, response);
    }


	public static ResourceEvaluation evaluate(File file, String filename) {
		ResourceEvaluation eval = new ResourceEvaluation();
		try {
			ImsManifestFileFilter visitor = new ImsManifestFileFilter();
			Path fPath = PathUtils.visit(file, filename, visitor);
			if(visitor.hasManifest()) {
				Path realManifestPath = visitor.getManifestPath();
				Path manifestPath = fPath.resolve(realManifestPath);

				RootSearcher rootSearcher = new RootSearcher();
				Files.walkFileTree(fPath, rootSearcher);
				if(rootSearcher.foundRoot()) {
					manifestPath = rootSearcher.getRoot().resolve(IMS_MANIFEST);
				} else {
					manifestPath = fPath.resolve(IMS_MANIFEST);
				}

				Document doc = IMSLoader.loadIMSDocument(manifestPath);
				if(validateImsManifest(doc)) {
					if(visitor.hasEditorTreeModel()) {
						XMLScanner scanner = new XMLScanner();
						scanner.scan(visitor.getEditorTreeModelPath());
						eval.setValid(!scanner.hasEditorTreeModelMarkup());
					} else {
						eval.setValid(true);
					}
				} else {
					eval.setValid(false);
				}
			} else {
				eval.setValid(false);
			}
			PathUtils.closeSubsequentFS(fPath);
		} catch (IOException | IllegalArgumentException e) {
			log.error("", e);
			eval.setValid(false);
		}
		return eval;
	}


  private byte[] decodeAndInflate(String encodedRequest) throws SAMLException {
    byte[] bytes = Base64.getMimeDecoder().decode(encodedRequest);
    Inflater inflater = new Inflater(true);
    inflater.setInput(bytes);
    inflater.finished();

    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte[] result = new byte[bytes.length];
      while (!inflater.finished()) {
        int length = inflater.inflate(result);
        if (length > 0) {
          baos.write(result, 0, length);
        }
      }

      return baos.toByteArray();
    } catch (DataFormatException e) {
      throw new SAMLException("Invalid AuthnRequest. Inflating the bytes failed.", e);
    }
  }


    public void testOfCharSequence() {
        // Should produce a lower-cased AsciiString.
        assertThat((Object) HttpHeaderNames.of("Foo")).isEqualTo(AsciiString.of("foo"));

        // Should reuse known header name instances.
        assertThat((Object) HttpHeaderNames.of("date")).isSameAs(HttpHeaderNames.DATE);
    }


        public User getUser() {
            return user;
        }


    public boolean isAvailable() {
        try {
            GeoTools.getInitialContext();
            return true;
        } catch (Exception e) {
            return false;
        }
    }


	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
	throws IOException {
		Path relativeDir = source.relativize(dir);
        final Path dirToCreate = Paths.get(destDir.toString(), relativeDir.toString());
        if(!dirToCreate.toFile().exists()) {
        	Files.createDirectory(dirToCreate);
        }
        return FileVisitResult.CONTINUE;
	}


    public Document read(Reader reader, String systemId)
            throws DocumentException {
        InputSource source = new InputSource(reader);
        source.setSystemId(systemId);
        if (this.encoding != null) {
            source.setEncoding(this.encoding);
        }

        return read(source);
    }


	public Controller execute(FolderComponent fc, UserRequest ureq, WindowControl wContr, Translator trans) {
		this.translator = trans;
		this.folderComponent = fc;
		this.fileSelection = new FileSelection(ureq, fc.getCurrentContainerPath());

		VFSContainer currentContainer = folderComponent.getCurrentContainer();
		List<String> lockedFiles = hasLockedFiles(currentContainer, fileSelection);
		if (lockedFiles.isEmpty()) {
			String msg = trans.translate("del.confirm") + "<p>" + fileSelection.renderAsHtml() + "</p>";
			// create dialog controller
			dialogCtr = activateYesNoDialog(ureq, trans.translate("del.header"), msg, dialogCtr);
		} else {
			String msg = FolderCommandHelper.renderLockedMessageAsHtml(trans, lockedFiles);
			List<String> buttonLabels = Collections.singletonList(trans.translate("ok"));
			lockedFiledCtr = activateGenericDialog(ureq, trans.translate("lock.title"), msg, buttonLabels, lockedFiledCtr);
		}
		return this;
	}


  public DropFileContainer(final String id, final String mimeType) {
    super(id);
    this.mimeType = mimeType;
    main = new WebMarkupContainer("main");
    add(main);
  }


    private <P extends T> void translate0(GeyserSession session, PacketTranslator<P> translator, P packet) {
        if (session.isClosed()) {
            return;
        }

        try {
            translator.translate(packet, session);
        } catch (Throwable ex) {
            GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
            ex.printStackTrace();
        }
    }


	public static boolean isAbsolute(String url)
	{
		if (url.startsWith("//"))  // //www.domain.com/start
		{
			return true;
		}

		if (url.startsWith("/")) // /somePage.html
		{
			return false;
		}

		boolean result = false;

		try
		{
			URI uri = new URI(url);
			result = uri.isAbsolute();
		}
		catch (URISyntaxException e) {} //Ignore

		return result;
	}


    public void encodeByteArrayDeepInJson() throws JSONException {
        JSONObject data = new JSONObject("{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}");
        data.getJSONObject("b").put("why", new byte[3]);
        data.getJSONObject("c").getJSONObject("b").put("a", new byte[6]);

        Packet<JSONObject> packet = new Packet<>(Parser.BINARY_EVENT);
        packet.data = data;
        packet.id = 999;
        packet.nsp = "/deep";
        Helpers.testBin(packet);
    }


	public Controller execute(FolderComponent folderComponent, UserRequest ureq, WindowControl wControl, Translator trans) {
		VFSContainer currentContainer = folderComponent.getCurrentContainer();

		status = FolderCommandHelper.sanityCheck(wControl, folderComponent);
		if(status == FolderCommandStatus.STATUS_FAILED) {
			return null;
		}

		FileSelection selection = new FileSelection(ureq, folderComponent.getCurrentContainerPath());
		status = FolderCommandHelper.sanityCheck3(wControl, folderComponent, selection);
		if(status == FolderCommandStatus.STATUS_FAILED) {
			return null;
		}

		if(selection.getFiles().isEmpty()) {
			status = FolderCommandStatus.STATUS_FAILED;
			wControl.setWarning(trans.translate("warning.file.selection.empty"));
			return null;
		}

		MediaResource mr = new ZipMediaResource(currentContainer, selection);
		ureq.getDispatchResult().setResultingMediaResource(mr);
		return null;
	}


    public void setShouldOverWritePreviousValue() {
        final HttpHeadersBase headers = newEmptyHeaders();
        headers.set("name", "value1");
        headers.set("name", "value2");
        assertThat(headers.size()).isEqualTo(1);
        assertThat(headers.getAll("name").size()).isEqualTo(1);
        assertThat(headers.getAll("name").get(0)).isEqualTo("value2");
        assertThat(headers.get("name")).isEqualTo("value2");
    }


    public UploadFileResponse getCloudUrl(String contextPath, String uri, String finalFilePath, HttpServletRequest request) {
        UploadFileResponse uploadFileResponse = new UploadFileResponse();
        // try push to cloud
        Map<String, String[]> map = new HashMap<>();
        map.put("fileInfo", new String[]{finalFilePath + "," + uri});
        map.put("name", new String[]{"uploadService"});
        String url;
        try {
            List<Map> urls = HttpUtil.getInstance().sendGetRequest(Constants.pluginServer + "/service", map
                    , new HttpJsonArrayHandle<Map>(), PluginHelper.genHeaderMapByRequest(request)).getT();
            if (urls != null && !urls.isEmpty()) {
                url = (String) urls.get(0).get("url");
                if (!url.startsWith("https://") && !url.startsWith("http://")) {
                    String tUrl = url;
                    if (!url.startsWith("/")) {
                        tUrl = "/" + url;
                    }
                    url = contextPath + tUrl;
                }
            } else {
                url = contextPath + uri;
            }
        } catch (Exception e) {
            url = contextPath + uri;
            LOGGER.error(e);
        }
        uploadFileResponse.setUrl(url);
        return uploadFileResponse;
    }


	public int decryptWithAd(byte[] ad, byte[] ciphertext,
			int ciphertextOffset, byte[] plaintext, int plaintextOffset,
			int length) throws ShortBufferException, BadPaddingException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (length > space)
			throw new ShortBufferException();
		if (plaintextOffset > plaintext.length)
			space = 0;
		else
			space = plaintext.length - plaintextOffset;
		if (!haskey) {
			// The key is not set yet - return the ciphertext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(ciphertext, ciphertextOffset, plaintext, plaintextOffset, length);
			return length;
		}
		if (length < 16)
			Noise.throwBadTagException();
		int dataLen = length - 16;
		if (dataLen > space)
			throw new ShortBufferException();
		setup(ad);
		poly.update(ciphertext, ciphertextOffset, dataLen);
		finish(ad, dataLen);
		int temp = 0;
		for (int index = 0; index < 16; ++index)
			temp |= (polyKey[index] ^ ciphertext[ciphertextOffset + dataLen + index]);
		if ((temp & 0xFF) != 0)
			Noise.throwBadTagException();
		encrypt(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
		return dataLen;
	}


    public void testQuoteWorkingDirectoryAndExecutable_WDPathWithSingleQuotes()
    {
        Shell sh = newShell();

        sh.setWorkingDirectory( "/usr/local/'something else'" );
        sh.setExecutable( "chmod" );

        String executable = StringUtils.join( sh.getShellCommandLine( new String[]{} ).iterator(), " " );

        assertEquals( "/bin/sh -c cd \"/usr/local/\'something else\'\" && chmod", executable );
    }


  private static String bytesToHex(byte[] bytes, int length) {
    String out = "";
    for (int j = 0; j < length; j++) {
      int v = bytes[j] & 0xFF;
      out += hexArray[v >>> 4];
      out += hexArray[v & 0x0F];
      out += " ";
    }
    return out;
  }


    public void translate(ServerEntityRotationPacket packet, GeyserSession session) {
        Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
        if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
            entity = session.getPlayerEntity();
        }
        if (entity == null) return;

        entity.updateRotation(session, packet.getYaw(), packet.getPitch(), packet.isOnGround());
    }


    protected XMLReader installXMLFilter(XMLReader reader) {
        XMLFilter filter = getXMLFilter();

        if (filter != null) {
            // find the root XMLFilter
            XMLFilter root = filter;

            while (true) {
                XMLReader parent = root.getParent();

                if (parent instanceof XMLFilter) {
                    root = (XMLFilter) parent;
                } else {
                    break;
                }
            }

            root.setParent(reader);

            return filter;
        }

        return reader;
    }


    public static void zipFolderAPKTool(String srcFolder, String destZipFile) throws Exception {
        try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
            addFolderToZipAPKTool("", srcFolder, zip);
            zip.flush();
        }
    }


    private static boolean nameContainsForbiddenSequence(String name) {
        boolean result = false;
        if (name != null) {
            name = name.toLowerCase();

            result = name.startsWith(".") ||
                     name.contains("../") ||
                     name.contains("..\\") ||
                     name.startsWith("/") ||
                     name.startsWith("\\") ||
                     name.endsWith("/") ||

                     name.contains("..%2f") ||
                     name.contains("..%5c") ||
                     name.startsWith("%2f") ||
                     name.startsWith("%5c") ||
                     name.endsWith("%2f") ||

                     name.contains("..\\u002f") ||
                     name.contains("..\\u005c") ||
                     name.startsWith("\\u002f") ||
                     name.startsWith("\\u005c") ||
                     name.endsWith("\\u002f")

                    ;
        }

        return result;
    }


	public void privateMsgInMuc(Conversation conversation, String nick) {
		switchToConversation(conversation, null, false, nick, true);
	}


    public void delete(String databaseType) {
        Path path = Paths.get(driverFilePath(driverBaseDirectory, databaseType));
        try {
            Files.deleteIfExists(path);
        } catch (IOException e) {
            log.error("delete driver error " + databaseType, e);
        }
    }


	private void saveToFile(VFSLeaf glossaryFile, List<GlossaryItem> glossaryItemArr) {
		// cdata-tags should be used instead of strings, overwrite writer.
		glossaryItemArr = removeEmptyGlossaryItems(glossaryItemArr);
		XStreamHelper.writeObject(xstreamWriter, glossaryFile, glossaryItemArr);
	}


    public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
        if (javaVersion() >= 7) {
            if (directory == null) {
                return Files.createTempFile(prefix, suffix).toFile();
            }
            return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
        }
        if (directory == null) {
            return File.createTempFile(prefix, suffix);
        }
        File file = File.createTempFile(prefix, suffix, directory);
        // Try to adjust the perms, if this fails there is not much else we can do...
        file.setReadable(false, false);
        file.setReadable(true, true);
        return file;
    }


    public void translate(ServerSetSlotPacket packet, GeyserSession session) {
        if (packet.getWindowId() == 255) { //cursor
            GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
            session.getPlayerInventory().setCursor(newItem, session);
            InventoryUtils.updateCursor(session);
            return;
        }

        //TODO: support window id -2, should update player inventory
        Inventory inventory = InventoryUtils.getInventory(session, packet.getWindowId());
        if (inventory == null)
            return;

        inventory.setStateId(packet.getStateId());

        InventoryTranslator translator = session.getInventoryTranslator();
        if (translator != null) {
            if (session.getCraftingGridFuture() != null) {
                session.getCraftingGridFuture().cancel(false);
            }
            session.setCraftingGridFuture(session.scheduleInEventLoop(() -> updateCraftingGrid(session, packet, inventory, translator), 150, TimeUnit.MILLISECONDS));

            GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
            if (packet.getWindowId() == 0 && !(translator instanceof PlayerInventoryTranslator)) {
                // In rare cases, the window ID can still be 0 but Java treats it as valid
                session.getPlayerInventory().setItem(packet.getSlot(), newItem, session);
                InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, session.getPlayerInventory(), packet.getSlot());
            } else {
                inventory.setItem(packet.getSlot(), newItem, session);
                translator.updateSlot(session, inventory, packet.getSlot());
            }
        }
    }


    public void accessDenied() {
        expect(backend.isRemoteAccessAllowed("localhost","127.0.0.1")).andReturn(false);
        replay(backend);

        handler.checkClientIPAccess("localhost","127.0.0.1");
    }


    public void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
    {
        // new document = xwiki:X.Y
        DocumentReference documentReference =
            new DocumentReference("Y", new SpaceReference("X", new WikiReference("xwiki")));
        XWikiDocument document = mock(XWikiDocument.class);
        when(document.getDocumentReference()).thenReturn(documentReference);
        when(document.isNew()).thenReturn(true);
        when(document.getLocalReferenceMaxLength()).thenReturn(255);
        context.setDoc(document);

        // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
        String templateProviderFullName = "XWiki.MyTemplateProvider";
        when(mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);

        // Mock 1 existing template provider
        mockExistingTemplateProviders(templateProviderFullName,
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"),
            Arrays.asList("AnythingButX"));

        // Run the action
        String result = action.render(context);

        // The tests are below this line!

        // Verify that the create template is rendered, so the UI is displayed for the user to see the error.
        assertEquals("create", result);

        // Check that the exception is properly set in the context for the UI to display.
        XWikiException exception = (XWikiException) this.oldcore.getScriptContext().getAttribute("createException");
        assertNotNull(exception);
        assertEquals(XWikiException.ERROR_XWIKI_APP_TEMPLATE_NOT_AVAILABLE, exception.getCode());

        // We should not get this far so no redirect should be done, just the template will be rendered.
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    }


    public void translate(PositionTrackingDBClientRequestPacket packet, GeyserSession session) {
        PositionTrackingDBServerBroadcastPacket broadcastPacket = new PositionTrackingDBServerBroadcastPacket();
        broadcastPacket.setTrackingId(packet.getTrackingId());

        // Fetch the stored Loadstone
        LoadstoneTracker.LoadstonePos pos = LoadstoneTracker.getPos(packet.getTrackingId());

        // If we don't have data for that ID tell the client its not found
        if (pos == null) {
            broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.NOT_FOUND);
            session.sendUpstreamPacket(broadcastPacket);
            return;
        }

        broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.UPDATE);

        // Build the nbt data for the update
        NbtMapBuilder builder = NbtMap.builder();
        builder.putInt("dim", DimensionUtils.javaToBedrock(pos.getDimension()));
        builder.putString("id", String.format("%08X", packet.getTrackingId()));

        builder.putByte("version", (byte) 1); // Not sure what this is for
        builder.putByte("status", (byte) 0); // Not sure what this is for

        // Build the position for the update
        IntList posList = new IntArrayList();
        posList.add(pos.getX());
        posList.add(pos.getY());
        posList.add(pos.getZ());
        builder.putList("pos", NbtType.INT, posList);
        broadcastPacket.setTag(builder.build());

        session.sendUpstreamPacket(broadcastPacket);
    }


	public static void copyDb(
	    String jdbcDriverSource,
	    String usernameSource,
	    String passwordSource,
	    String jdbcUrlSource,
	    String jdbcDriverTarget,
	    String usernameTarget,
	    String passwordTarget,
	    String jdbcUrlTarget,
	    List<String> includeDbObjects,
	    List<String> excludeDbObjects,
	    List<String> valuePatterns,
	    List<String> valueReplacements,
	    PrintStream out
	) throws ServiceException {
		{
			DBOBJECTS.clear();
			List<String> tableNames = new ArrayList<String>();
			try {
				tableNames = DbSchemaUtils.getTableNames();
			} catch (Exception e) {
				new ServiceException(e).log();
			}
			for(String tableName : tableNames) {
				if(
					tableName.indexOf("_") > 0 &&
					tableName.indexOf("_TOBJ_") < 0 &&
					tableName.indexOf("_JOIN_") < 0 &&
					!tableName.endsWith("_")
				) {
					DBOBJECTS.add(tableName);
				}
			}
		}
		try {
			// Source connection
			Class.forName(jdbcDriverSource);
			Properties props = new Properties();
			props.put("user", usernameSource);
			props.put("password", passwordSource);
			Connection connSource = DriverManager.getConnection(jdbcUrlSource, props);
			connSource.setAutoCommit(true);
			// Target connection
			Class.forName(jdbcDriverTarget);
			props = new Properties();
			props.put("user", usernameTarget);
			props.put("password", passwordTarget);
			Connection connTarget = DriverManager.getConnection(jdbcUrlTarget, props);
			connTarget.setAutoCommit(true);
			CopyDb.copyNamespace(
				connSource,
				connTarget,
				filterDbObjects(
					DBOBJECTS,
					includeDbObjects,
					excludeDbObjects
				),
			    valuePatterns,
			    valueReplacements,
			    out
			);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		out.println();
		out.println("!!! DONE !!!");
	}


	protected StyleSignatureBasic getStyleSignature() {
		if (type == TimingStyle.CONCISE)
			return StyleSignatureBasic.of(SName.root, SName.element, SName.timingDiagram, SName.concise);
		if (type == TimingStyle.ROBUST)
			return StyleSignatureBasic.of(SName.root, SName.element, SName.timingDiagram, SName.robust);
		throw new IllegalStateException();
	}


    public void translate(NetworkStackLatencyPacket packet, GeyserSession session) {
        long pingId;
        // so apparently, as of 1.16.200
        // PS4 divides the network stack latency timestamp FOR US!!!
        // WTF
        if (session.getClientData().getDeviceOs().equals(DeviceOs.PS4)) {
            pingId = packet.getTimestamp();
        } else {
            pingId = packet.getTimestamp() / 1000;
        }

        // negative timestamps are used as hack to fix the url image loading bug
        if (packet.getTimestamp() > 0) {
            if (session.getConnector().getConfig().isForwardPlayerPing()) {
                ClientKeepAlivePacket keepAlivePacket = new ClientKeepAlivePacket(pingId);
                session.sendDownstreamPacket(keepAlivePacket);
            }
            return;
        }

        // Hack to fix the url image loading bug
        UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
        attributesPacket.setRuntimeEntityId(session.getPlayerEntity().getGeyserId());

        AttributeData attribute = session.getPlayerEntity().getAttributes().get(GeyserAttributeType.EXPERIENCE_LEVEL);
        if (attribute != null) {
            attributesPacket.setAttributes(Collections.singletonList(attribute));
        } else {
            attributesPacket.setAttributes(Collections.singletonList(GeyserAttributeType.EXPERIENCE_LEVEL.getAttribute(0)));
        }

        session.getConnector().getGeneralThreadPool().schedule(
                () -> session.sendUpstreamPacket(attributesPacket),
                500, TimeUnit.MILLISECONDS);
    }


	public SymbolContext getContext(ISkinParam skinParam, Style style) {
		return new SymbolContext(getBackColor(skinParam, style), getLineColor(skinParam, style))
				.withStroke(new UStroke(1.5));
	}


    public BCXMSSMTPrivateKey(PrivateKeyInfo keyInfo)
        throws IOException
    {
        XMSSMTKeyParams keyParams = XMSSMTKeyParams.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
        this.treeDigest = keyParams.getTreeDigest().getAlgorithm();

        XMSSPrivateKey xmssMtPrivateKey = XMSSPrivateKey.getInstance(keyInfo.parsePrivateKey());

        try
        {
            XMSSMTPrivateKeyParameters.Builder keyBuilder = new XMSSMTPrivateKeyParameters
                .Builder(new XMSSMTParameters(keyParams.getHeight(), keyParams.getLayers(), DigestUtil.getDigest(treeDigest)))
                .withIndex(xmssMtPrivateKey.getIndex())
                .withSecretKeySeed(xmssMtPrivateKey.getSecretKeySeed())
                .withSecretKeyPRF(xmssMtPrivateKey.getSecretKeyPRF())
                .withPublicSeed(xmssMtPrivateKey.getPublicSeed())
                .withRoot(xmssMtPrivateKey.getRoot());

            if (xmssMtPrivateKey.getBdsState() != null)
            {
                keyBuilder.withBDSState((BDSStateMap)XMSSUtil.deserialize(xmssMtPrivateKey.getBdsState()));
            }

            this.keyParams = keyBuilder.build();
        }
        catch (ClassNotFoundException e)
        {
            throw new IOException("ClassNotFoundException processing BDS state: " + e.getMessage());
        }
    }


    public void testCreateHttpUrlConnection() {
        HttpURLConnection conn;
        // Test without proxy
        conn = createHttpUrlConnection(convertToUrl(TEST_URL), "", 0, "", "");
        Assert.assertNotNull(conn);
        // Test with the proxy
        conn = createHttpUrlConnection(convertToUrl(TEST_URL), "http://localhost", 9090, "testUser", "testPassword");
        Assert.assertNotNull(conn);
    }


    public void failingExample() throws Exception {
        assertThat(ConstraintViolations.format(validator.validate(new FailingExample())))
            .containsExactlyInAnyOrder(FAILED_RESULT);
        assertThat(TestLoggerFactory.getAllLoggingEvents())
            .isEmpty();
    }


    private void checkParams()
        throws Exception
    {
        if (vi == null)
        {
            throw new Exception("no layers defined.");
        }
        if (vi.length > 1)
        {
            for (int i = 0; i < vi.length - 1; i++)
            {
                if (vi[i] >= vi[i + 1])
                {
                    throw new Exception(
                        "v[i] has to be smaller than v[i+1]");
                }
            }
        }
        else
        {
            throw new Exception(
                "Rainbow needs at least 1 layer, such that v1 < v2.");
        }
    }


	public int encryptWithAd(byte[] ad, byte[] plaintext, int plaintextOffset,
			byte[] ciphertext, int ciphertextOffset, int length)
			throws ShortBufferException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (!haskey) {
			// The key is not set yet - return the plaintext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(plaintext, plaintextOffset, ciphertext, ciphertextOffset, length);
			return length;
		}
		if (space < 16 || length > (space - 16))
			throw new ShortBufferException();
		setup(ad);
		encryptCTR(plaintext, plaintextOffset, ciphertext, ciphertextOffset, length);
		ghash.update(ciphertext, ciphertextOffset, length);
		ghash.pad(ad != null ? ad.length : 0, length);
		ghash.finish(ciphertext, ciphertextOffset + length, 16);
		for (int index = 0; index < 16; ++index)
			ciphertext[ciphertextOffset + length + index] ^= hashKey[index];
		return length + 16;
	}


    default Optional<String> findFirst(CharSequence name) {
        return getFirst(name, String.class);
    }


    public static void beforeClass() throws IOException {
        final Random r = new Random();
        for (int i = 0; i < BYTES.length; i++) {
            BYTES[i] = (byte) r.nextInt(255);
        }

        tmp = File.createTempFile("netty-traffic", ".tmp");
        tmp.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(tmp);
            out.write(BYTES);
            out.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
    }


	public static int version() {
		return 1202204;
	}


	public int decryptWithAd(byte[] ad, byte[] ciphertext,
			int ciphertextOffset, byte[] plaintext, int plaintextOffset,
			int length) throws ShortBufferException, BadPaddingException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (length > space)
			throw new ShortBufferException();
		if (plaintextOffset > plaintext.length)
			space = 0;
		else
			space = plaintext.length - plaintextOffset;
		if (keySpec == null) {
			// The key is not set yet - return the ciphertext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(ciphertext, ciphertextOffset, plaintext, plaintextOffset, length);
			return length;
		}
		if (length < 16)
			Noise.throwBadTagException();
		int dataLen = length - 16;
		if (dataLen > space)
			throw new ShortBufferException();
		try {
			setup(ad);
		} catch (InvalidKeyException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		} catch (InvalidAlgorithmParameterException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		}
		ghash.update(ciphertext, ciphertextOffset, dataLen);
		ghash.pad(ad != null ? ad.length : 0, dataLen);
		ghash.finish(iv, 0, 16);
		int temp = 0;
		for (int index = 0; index < 16; ++index)
			temp |= (hashKey[index] ^ iv[index] ^ ciphertext[ciphertextOffset + dataLen + index]);
		if ((temp & 0xFF) != 0)
			Noise.throwBadTagException();
		try {
			int result = cipher.update(ciphertext, ciphertextOffset, dataLen, plaintext, plaintextOffset);
			cipher.doFinal(plaintext, plaintextOffset + result);
		} catch (IllegalBlockSizeException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		} catch (BadPaddingException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		}
		return dataLen;
	}


    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof ClassPathResource) {
            ClassPathResource otherRes = (ClassPathResource) obj;

            ClassLoader thisLoader = this.classLoader;
            ClassLoader otherLoader = otherRes.classLoader;

            return (this.path.equals(otherRes.path) &&
                thisLoader.equals(otherLoader) &&
                this.clazz.equals(otherRes.clazz));
        }
        return false;
    }


	public ProductServletConfigurator(ServerConfig serverConfig, ShiroFilter shiroFilter, GitFilter gitFilter,
			GitPreReceiveCallback preReceiveServlet, GitPostReceiveCallback postReceiveServlet,
			WicketServlet wicketServlet, WebSocketManager webSocketManager,
			AttachmentUploadServlet attachmentUploadServlet, ServletContainer jerseyServlet) {
		this.serverConfig = serverConfig;
		this.shiroFilter = shiroFilter;
        this.gitFilter = gitFilter;
		this.preReceiveServlet = preReceiveServlet;
		this.postReceiveServlet = postReceiveServlet;
		this.wicketServlet = wicketServlet;
		this.webSocketManager = webSocketManager;
		this.jerseyServlet = jerseyServlet;
		this.attachmentUploadServlet = attachmentUploadServlet;
	}


    void colon() {
        assertThat(PathAndQuery.parse("/:")).isNotNull();
        assertThat(PathAndQuery.parse("/:/")).isNotNull();
        assertThat(PathAndQuery.parse("/a/:")).isNotNull();
        assertThat(PathAndQuery.parse("/a/:/")).isNotNull();
    }


    public void testPseudoHeadersWithRemovePreservesPseudoIterationOrder() {
        final HttpHeadersBase headers = newHttp2Headers();
        final HttpHeadersBase nonPseudoHeaders = newEmptyHeaders();
        for (Map.Entry<AsciiString, String> entry : headers) {
            if (entry.getKey().isEmpty() ||
                entry.getKey().charAt(0) != ':' && !nonPseudoHeaders.contains(entry.getKey())) {
                nonPseudoHeaders.add(entry.getKey(), entry.getValue());
            }
        }

        assertThat(nonPseudoHeaders.isEmpty()).isFalse();

        // Remove all the non-pseudo headers and verify
        for (Map.Entry<AsciiString, String> nonPseudoHeaderEntry : nonPseudoHeaders) {
            assertThat(headers.remove(nonPseudoHeaderEntry.getKey())).isTrue();
            verifyPseudoHeadersFirst(headers);
            verifyAllPseudoHeadersPresent(headers);
        }

        // Add back all non-pseudo headers
        for (Map.Entry<AsciiString, String> nonPseudoHeaderEntry : nonPseudoHeaders) {
            headers.add(nonPseudoHeaderEntry.getKey(), "goo");
            verifyPseudoHeadersFirst(headers);
            verifyAllPseudoHeadersPresent(headers);
        }
    }


	public String getSHA(String password) {

		try {
			// Static getInstance method is called with hashing SHA
			MessageDigest md = MessageDigest.getInstance("SHA-256");

			// digest() method called
			// to calculate message digest of an input
			// and return array of byte
			byte[] messageDigest = md.digest(password.getBytes());

			// Convert byte array into signum representation
			BigInteger no = new BigInteger(1, messageDigest);

			// Convert message digest into hex value
			String hashPass = no.toString(16);

			while (hashPass.length() < 32) {
				hashPass = "0" + hashPass;
			}
			return hashPass;

			// For specifying wrong message digest algorithms
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}
	}


    public SAXReader(XMLReader xmlReader) {
        this.xmlReader = xmlReader;
    }


    protected void onStart() {
        super.onStart();
        Intent intent = getIntent();
        intent.putExtra(
                SettingsActivity.SP_FEED_LIST_LAYOUT,
                mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0")
        );
        setResult(RESULT_OK,intent);
    }


  public ExitCode runWithoutHelp(CommandRunnerParams params)
      throws IOException, InterruptedException {

    if (saveFilename != null && loadFilename != null) {
      params.getConsole().printErrorText("Can't use both --load and --save");
      return ExitCode.COMMANDLINE_ERROR;
    }

    if (saveFilename != null) {
      invalidateChanges(params);
      RemoteDaemonicParserState state = params.getParser().storeParserState(params.getCell());
      try (FileOutputStream fos = new FileOutputStream(saveFilename);
          ZipOutputStream zipos = new ZipOutputStream(fos)) {
        zipos.putNextEntry(new ZipEntry("parser_data"));
        try (ObjectOutputStream oos = new ObjectOutputStream(zipos)) {
          oos.writeObject(state);
        }
      }
    } else if (loadFilename != null) {
      try (FileInputStream fis = new FileInputStream(loadFilename);
          ZipInputStream zipis = new ZipInputStream(fis)) {
        ZipEntry entry = zipis.getNextEntry();
        Preconditions.checkState(entry.getName().equals("parser_data"));
        try (ObjectInputStream ois = new ObjectInputStream(zipis)) {
          RemoteDaemonicParserState state;
          try {
            state = (RemoteDaemonicParserState) ois.readObject();
          } catch (ClassNotFoundException e) {
            params.getConsole().printErrorText("Invalid file format");
            return ExitCode.COMMANDLINE_ERROR;
          }
          params.getParser().restoreParserState(state, params.getCell());
        }
      }
      invalidateChanges(params);

      ParserConfig configView = params.getBuckConfig().getView(ParserConfig.class);
      if (configView.isParserCacheMutationWarningEnabled()) {
        params
            .getConsole()
            .printErrorText(
                params
                    .getConsole()
                    .getAnsi()
                    .asWarningText(
                        "WARNING: Buck injected a parser state that may not match the local state."));
      }
    }

    return ExitCode.SUCCESS;
  }


	final protected SymbolContext getContext() {
		if (UseStyle.useBetaStyle() == false)
			return getContextLegacy();

		final Style style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder());
		final HColor lineColor = style.value(PName.LineColor).asColor(skinParam.getThemeStyle(),
				skinParam.getIHtmlColorSet());
		final HColor backgroundColor = style.value(PName.BackGroundColor).asColor(skinParam.getThemeStyle(),
				skinParam.getIHtmlColorSet());

		return new SymbolContext(backgroundColor, lineColor).withStroke(getStroke());
	}


	public String render(String templateContent, Map<String, Object> context) {
		VelocityContext velocityContext = new VelocityContext(context);
		try (StringWriter sw = new StringWriter()) {
			Velocity.evaluate(velocityContext, sw, "velocityTemplateEngine", templateContent);
			return sw.toString();
		}
		catch (Exception ex) {
			throw new TemplateRenderException(ex);
		}
	}


    public String list(Model model, // TODO model should no longer be injected
                       @RequestParam(required = false, defaultValue = "FILENAME") SortBy sortBy,
                       @RequestParam(required = false, defaultValue = "false") boolean desc,
                       @RequestParam(required = false) String base) throws IOException, TemplateException {
        securityCheck(base);

        Path currentFolder = loggingPath(base);

        List<FileEntry> files = getFileProvider(currentFolder).getFileEntries(currentFolder);
        List<FileEntry> sortedFiles = sortFiles(files, sortBy, desc);

        model.addAttribute("sortBy", sortBy);
        model.addAttribute("desc", desc);
        model.addAttribute("files", sortedFiles);
        model.addAttribute("currentFolder", currentFolder.toAbsolutePath().toString());
        model.addAttribute("base", base != null ? URLEncoder.encode(base, "UTF-8") : "");
        model.addAttribute("parent", getParent(currentFolder));
        model.addAttribute("stylesheets", stylesheets);

        return FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfig.getTemplate("logview.ftl"), model);
    }


	private final void servlet31(HttpServletRequest request) {
		try {
			for(Part part:request.getParts()) {
				if(part.getContentType() != null && (StringHelper.containsNonWhitespace(part.getSubmittedFileName()) || !part.getContentType().startsWith("text/plain"))) {
					contentType = part.getContentType();
					filename = part.getSubmittedFileName();
					if(filename != null) {
						filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;
					} else {
						filename = "upload-" + UUID.randomUUID().toString().replace("-", "");
					}
					file = new File(WebappHelper.getTmpDir(), filename);
					part.write(file.getAbsolutePath());
					file = new File(WebappHelper.getTmpDir(), filename);
				} else {
					String value = IOUtils.toString(part.getInputStream(), request.getCharacterEncoding());
					fields.put(part.getName(), value);
				}

				try {
					part.delete();
				} catch (Exception e) {
					//we try (tomcat doesn't send exception but undertow)
				}
			}
		} catch (IOException | ServletException e) {
			log.error("", e);
		}
	}


	public void saveCustomConfigAndCompileCSS(Map<String, Map<String, Object>> customConfig, CourseEnvironment courseEnvironment){
		VFSContainer themeBase = null;
		VFSContainer base = null;
		base = (VFSContainer) courseEnvironment.getCourseBaseContainer().resolve(CourseLayoutHelper.LAYOUT_COURSE_SUBFOLDER);
		if (base == null) {
			base = courseEnvironment.getCourseBaseContainer().createChildContainer(CourseLayoutHelper.LAYOUT_COURSE_SUBFOLDER);
		}
		themeBase = (VFSContainer) base.resolve("/" + CourseLayoutHelper.CONFIG_KEY_CUSTOM);
		if (themeBase == null) {
			themeBase = base.createChildContainer(CourseLayoutHelper.CONFIG_KEY_CUSTOM);
		}
		VFSLeaf configTarget = (VFSLeaf) themeBase.resolve(CUSTOM_CONFIG_XML);
		if (configTarget == null) {
			configTarget = themeBase.createChildLeaf(CUSTOM_CONFIG_XML);
		}

		XStream xStream = XStreamHelper.createXStreamInstance();
		xStream.toXML(customConfig, configTarget.getOutputStream(false));

		// compile the css-files
		StringBuilder sbMain = new StringBuilder();
		StringBuilder sbIFrame = new StringBuilder();
		for (Entry<String, Map<String, Object>> iterator : customConfig.entrySet()) {
			String type = iterator.getKey();
			Map<String, Object> elementConfig = iterator.getValue();
		  AbstractLayoutElement configuredLayEl = createLayoutElementByType(type, elementConfig);
			sbIFrame.append(configuredLayEl.getCSSForIFrame());
			sbMain.append(configuredLayEl.getCSSForMain());
		}

		// attach line for logo, if there is any to cssForMain:
		appendLogoPart(sbMain, themeBase);

		VFSLeaf mainFile = (VFSLeaf) themeBase.resolve(MAIN_CSS);
		if (mainFile == null) mainFile = themeBase.createChildLeaf(MAIN_CSS);
		VFSLeaf iFrameFile = (VFSLeaf) themeBase.resolve(IFRAME_CSS);
		if (iFrameFile == null) iFrameFile = themeBase.createChildLeaf(IFRAME_CSS);
		FileUtils.save(mainFile.getOutputStream(false), sbMain.toString(), "utf-8");
		FileUtils.save(iFrameFile.getOutputStream(false), sbIFrame.toString(), "utf-8");
	}


        public UserCause(User user, String message) {
            super(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(
                    user!=null ? user.getId() : Jenkins.ANONYMOUS.getName(),
                    message != null ? " : " + message : ""
            ));
            this.user = user;
        }


    default Optional<MediaType> contentType() {
        return getFirst(HttpHeaders.CONTENT_TYPE, MediaType.class);
    }


    public void setEntityResolver(EntityResolver entityResolver) {
        this.entityResolver = entityResolver;
    }


    private void processExtras(Bundle extras) {
        final String downloadUuid = extras.getString(ConversationsActivity.EXTRA_DOWNLOAD_UUID);
        final String text = extras.getString(Intent.EXTRA_TEXT);
        final String nick = extras.getString(ConversationsActivity.EXTRA_NICK);
        final boolean asQuote = extras.getBoolean(ConversationsActivity.EXTRA_AS_QUOTE);
        final boolean pm = extras.getBoolean(ConversationsActivity.EXTRA_IS_PRIVATE_MESSAGE, false);
        final List<Uri> uris = extractUris(extras);
        if (uris != null && uris.size() > 0) {
            final List<Uri> cleanedUris = cleanUris(new ArrayList<>(uris));
            mediaPreviewAdapter.addMediaPreviews(Attachment.of(getActivity(), cleanedUris));
            toggleInputMethod();
            return;
        }
        if (nick != null) {
            if (pm) {
                Jid jid = conversation.getJid();
                try {
                    Jid next = Jid.of(jid.getLocal(), jid.getDomain(), nick);
                    privateMessageWith(next);
                } catch (final IllegalArgumentException ignored) {
                    //do nothing
                }
            } else {
                final MucOptions mucOptions = conversation.getMucOptions();
                if (mucOptions.participating() || conversation.getNextCounterpart() != null) {
                    highlightInConference(nick);
                }
            }
        } else {
            if (text != null && asQuote) {
                quoteText(text);
            } else {
                appendText(text);
            }
        }
        final Message message = downloadUuid == null ? null : conversation.findMessageWithFileAndUuid(downloadUuid);
        if (message != null) {
            startDownloadable(message);
        }
    }


    public void view(@RequestParam String filename,
                     @RequestParam(required = false) String base,
                     @RequestParam(required = false) Integer tailLines,
                     HttpServletResponse response) throws IOException {
        securityCheck(filename);
        response.setContentType(MediaType.TEXT_PLAIN_VALUE);

        Path path = loggingPath(base);
        FileProvider fileProvider = getFileProvider(path);
        if (tailLines != null) {
            fileProvider.tailContent(path, filename, response.getOutputStream(), tailLines);
        }
        else {
            fileProvider.streamContent(path, filename, response.getOutputStream());
        }
    }


    public void toScientificString(StringBuilder result) {
        assert(!isApproximate);
        if (isNegative()) {
            result.append('-');
        }
        if (precision == 0) {
            result.append("0E+0");
            return;
        }
        // NOTE: It is not safe to add to lOptPos (aka maxInt) or subtract from
        // rOptPos (aka -maxFrac) due to overflow.
        int upperPos = Math.min(precision + scale, lOptPos) - scale - 1;
        int lowerPos = Math.max(scale, rOptPos) - scale;
        int p = upperPos;
        result.append((char) ('0' + getDigitPos(p)));
        if ((--p) >= lowerPos) {
            result.append('.');
            for (; p >= lowerPos; p--) {
                result.append((char) ('0' + getDigitPos(p)));
            }
        }
        result.append('E');
        int _scale = upperPos + scale;
        if (_scale < 0) {
            _scale *= -1;
            result.append('-');
        } else {
            result.append('+');
        }
        if (_scale == 0) {
            result.append('0');
        }
        int insertIndex = result.length();
        while (_scale > 0) {
            int quot = _scale / 10;
            int rem = _scale % 10;
            result.insert(insertIndex, (char) ('0' + rem));
            _scale = quot;
        }
    }


    public void translate(ServerPlayerAbilitiesPacket packet, GeyserSession session) {
        session.setCanFly(packet.isCanFly());
        session.setFlying(packet.isFlying());
        session.sendAdventureSettings();
    }


    protected List<PropertySource> readPropertySourceListFromFiles(String files) {
        List<PropertySource> propertySources = new ArrayList<>();
        Collection<PropertySourceLoader> propertySourceLoaders = getPropertySourceLoaders();
        Optional<Collection<String>> filePathList = Optional.ofNullable(files)
            .filter(value -> !value.isEmpty())
            .map(value -> value.split(FILE_SEPARATOR))
            .map(Arrays::asList)
            .map(Collections::unmodifiableList);

        filePathList.ifPresent(list -> {
            if (!list.isEmpty()) {
                int order = AbstractPropertySourceLoader.DEFAULT_POSITION + 50;
                for (String filePath: list) {
                    if (!propertySourceLoaders.isEmpty()) {
                        String extension = NameUtils.extension(filePath);
                        String fileName = NameUtils.filename(filePath);
                        Optional<PropertySourceLoader> propertySourceLoader = Optional.ofNullable(loaderByFormatMap.get(extension));
                        if (propertySourceLoader.isPresent()) {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("Reading property sources from loader: {}", propertySourceLoader);
                            }
                            Optional<Map<String, Object>> properties = readPropertiesFromLoader(fileName, filePath, propertySourceLoader.get());
                            if (properties.isPresent()) {
                                propertySources.add(PropertySource.of(filePath, properties.get(), order));
                            }
                            order++;
                        } else {
                            throw new ConfigurationException("Unsupported properties file format: " + fileName);
                        }
                    }
                }
            }
        });
        return propertySources;
    }


  public TMap readMapBegin() throws TException {
    return new TMap(readByte(), readByte(), readI32());
  }


	private void parse(UserRequest ureq) {
		String[] sFiles = ureq.getHttpReq().getParameterValues(FORM_ID);
		if (sFiles == null || sFiles.length == 0) return;
		files = Arrays.asList(sFiles);
	}


        public void validateFail(ViolationCollector col) {
        }


  private Document parseFromBytes(byte[] bytes) throws SAMLException {
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    try {
      DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
      return builder.parse(new ByteArrayInputStream(bytes));
    } catch (ParserConfigurationException | SAXException | IOException e) {
      throw new SAMLException("Unable to parse SAML v2.0 authentication response", e);
    }
  }


    public void testGetShellCommandLineBash_WithWorkingDirectory()
        throws Exception
    {
        Commandline cmd = new Commandline( new BourneShell() );
        cmd.setExecutable( "/bin/echo" );
        cmd.addArguments( new String[] {
            "hello world"
        } );
        File root = File.listRoots()[0];
        File workingDirectory = new File( root, "path with spaces" );
        cmd.setWorkingDirectory( workingDirectory );

        String[] shellCommandline = cmd.getShellCommandline();

        assertEquals( "Command line size", 3, shellCommandline.length );

        assertEquals( "/bin/sh", shellCommandline[0] );
        assertEquals( "-c", shellCommandline[1] );
        String expectedShellCmd = "cd \"" + root.getAbsolutePath()
                                  + "path with spaces\" && /bin/echo \'hello world\'";
        if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
        {
            expectedShellCmd = "cd \"" + root.getAbsolutePath()
                               + "path with spaces\" && \\bin\\echo \'hello world\'";
        }
        assertEquals( expectedShellCmd, shellCommandline[2] );
    }


	public void testLoadMapper_serializade() {
		//create a mapper
		String mapperId = UUID.randomUUID().toString();
		String sessionId = UUID.randomUUID().toString().substring(0, 32);
		PersistentMapper sMapper = new PersistentMapper("mapper-to-persist");
		PersistedMapper pMapper = mapperDao.persistMapper(sessionId, mapperId, sMapper, -1);
		Assert.assertNotNull(pMapper);
		dbInstance.commitAndCloseSession();

		//load the mapper
		PersistedMapper loadedMapper = mapperDao.loadByMapperId(mapperId);
		Assert.assertNotNull(loadedMapper);
		Assert.assertEquals(pMapper, loadedMapper);
		Assert.assertEquals(mapperId, loadedMapper.getMapperId());

		Object objReloaded = XStreamHelper.createXStreamInstance().fromXML(pMapper.getXmlConfiguration());
		Assert.assertTrue(objReloaded instanceof PersistentMapper);
		PersistentMapper sMapperReloaded = (PersistentMapper)objReloaded;
		Assert.assertEquals("mapper-to-persist", sMapperReloaded.getKey());
	}


    public void encodeByteArray() {
        Packet<byte[]> packet = new Packet<>(Parser.BINARY_EVENT);
        packet.data = "abc".getBytes(Charset.forName("UTF-8"));
        packet.id = 23;
        packet.nsp = "/cool";
        Helpers.testBin(packet);
    }


  public static boolean isPermitted(
      final Optional<AuthenticationService> authenticationService,
      final Optional<User> optionalUser,
      final JsonRpcMethod jsonRpcMethod) {

    AtomicBoolean foundMatchingPermission = new AtomicBoolean();

    if (authenticationService.isPresent()) {
      if (optionalUser.isPresent()) {
        User user = optionalUser.get();
        for (String perm : jsonRpcMethod.getPermissions()) {
          user.isAuthorized(
              perm,
              (authed) -> {
                if (authed.result()) {
                  LOG.trace(
                      "user {} authorized : {} via permission {}",
                      user,
                      jsonRpcMethod.getName(),
                      perm);
                  foundMatchingPermission.set(true);
                }
              });
        }
      }
    } else {
      // no auth provider configured thus anything is permitted
      foundMatchingPermission.set(true);
    }

    if (!foundMatchingPermission.get()) {
      LOG.trace("user NOT authorized : {}", jsonRpcMethod.getName());
    }
    return foundMatchingPermission.get();
  }


	public int decryptWithAd(byte[] ad, byte[] ciphertext,
			int ciphertextOffset, byte[] plaintext, int plaintextOffset,
			int length) throws ShortBufferException, BadPaddingException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (length > space)
			throw new ShortBufferException();
		if (plaintextOffset > plaintext.length)
			space = 0;
		else
			space = plaintext.length - plaintextOffset;
		if (!haskey) {
			// The key is not set yet - return the ciphertext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(ciphertext, ciphertextOffset, plaintext, plaintextOffset, length);
			return length;
		}
		if (length < 16)
			Noise.throwBadTagException();
		int dataLen = length - 16;
		if (dataLen > space)
			throw new ShortBufferException();
		setup(ad);
		ghash.update(ciphertext, ciphertextOffset, dataLen);
		ghash.pad(ad != null ? ad.length : 0, dataLen);
		ghash.finish(enciv, 0, 16);
		int temp = 0;
		for (int index = 0; index < 16; ++index)
			temp |= (hashKey[index] ^ enciv[index] ^ ciphertext[ciphertextOffset + dataLen + index]);
		if ((temp & 0xFF) != 0)
			Noise.throwBadTagException();
		encryptCTR(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
		return dataLen;
	}


    public void existingDocumentFromUITemplateProviderSpecified() throws Exception
    {
        // current document = xwiki:Main.WebHome
        DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
        XWikiDocument document = mock(XWikiDocument.class);
        when(document.getDocumentReference()).thenReturn(documentReference);
        when(document.isNew()).thenReturn(false);
        when(document.getLocalReferenceMaxLength()).thenReturn(255);
        context.setDoc(document);

        // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
        String templateProviderFullName = "XWiki.MyTemplateProvider";
        when(mockRequest.getParameter("spaceReference")).thenReturn("X");
        when(mockRequest.getParameter("name")).thenReturn("Y");
        when(mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);

        // Mock 1 existing template provider
        mockExistingTemplateProviders(templateProviderFullName,
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST);

        // Run the action
        String result = action.render(context);

        // The tests are below this line!

        // Verify null is returned (this means the response has been returned)
        assertNull(result);

        // Note: We are creating X.Y and using the template extracted from the template provider.
        verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y", null, "xwiki", context);
    }


	public int encryptWithAd(byte[] ad, byte[] plaintext, int plaintextOffset,
			byte[] ciphertext, int ciphertextOffset, int length)
			throws ShortBufferException {
		int space;
		if (ciphertextOffset > ciphertext.length)
			space = 0;
		else
			space = ciphertext.length - ciphertextOffset;
		if (keySpec == null) {
			// The key is not set yet - return the plaintext as-is.
			if (length > space)
				throw new ShortBufferException();
			if (plaintext != ciphertext || plaintextOffset != ciphertextOffset)
				System.arraycopy(plaintext, plaintextOffset, ciphertext, ciphertextOffset, length);
			return length;
		}
		if (space < 16 || length > (space - 16))
			throw new ShortBufferException();
		try {
			setup(ad);
			int result = cipher.update(plaintext, plaintextOffset, length, ciphertext, ciphertextOffset);
			cipher.doFinal(ciphertext, ciphertextOffset + result);
		} catch (InvalidKeyException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		} catch (InvalidAlgorithmParameterException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		} catch (IllegalBlockSizeException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		} catch (BadPaddingException e) {
			// Shouldn't happen.
			throw new IllegalStateException(e);
		}
		ghash.update(ciphertext, ciphertextOffset, length);
		ghash.pad(ad != null ? ad.length : 0, length);
		ghash.finish(ciphertext, ciphertextOffset + length, 16);
		for (int index = 0; index < 16; ++index)
			ciphertext[ciphertextOffset + length + index] ^= hashKey[index];
		return length + 16;
	}


	private void processReturnFiles(VFSLeaf target, List<BulkAssessmentRow> rows) {
		Map<String, BulkAssessmentRow> assessedIdToRow = new HashMap<>();
		for(BulkAssessmentRow row:rows) {
			assessedIdToRow.put(row.getAssessedId(), row);
		}

		if(target.exists()) {
			File parentTarget = ((LocalImpl)target).getBasefile().getParentFile();

			ZipEntry entry;
			try(InputStream is = target.getInputStream();
					ZipInputStream zis = new ZipInputStream(is)) {
				byte[] b = new byte[FileUtils.BSIZE];
				while ((entry = zis.getNextEntry()) != null) {
					if(!entry.isDirectory()) {
						while (zis.read(b) > 0) {
							//continue
						}

						Path op = new File(parentTarget, entry.getName()).toPath();
						if(!Files.isHidden(op) && !op.toFile().isDirectory()) {
							Path parentDir = op.getParent();
							String assessedId = parentDir.getFileName().toString();
							String filename = op.getFileName().toString();

							BulkAssessmentRow row;
							if(assessedIdToRow.containsKey(assessedId)) {
								row = assessedIdToRow.get(assessedId);
							} else {
								row = new BulkAssessmentRow();
								row.setAssessedId(assessedId);
								assessedIdToRow.put(assessedId, row);
								rows.add(row);
							}

							if(row.getReturnFiles() == null) {
								row.setReturnFiles(new ArrayList<String>(2));
							}
							row.getReturnFiles().add(filename);
						}
					}
				}
			} catch(Exception e) {
				logError("", e);
			}
		}
	}


    public void testBourneShellQuotingCharacters()
        throws Exception
    {
        // { ' ', '$', ';', '&', '|', '<', '>', '*', '?', '(', ')' };
        // test with values http://steve-parker.org/sh/bourne.shtml Appendix B - Meta-characters and Reserved Words
        Commandline commandline = new Commandline( newShell() );
        commandline.setExecutable( "chmod" );
        commandline.getShell().setQuotedArgumentsEnabled( true );
        commandline.createArg().setValue( " " );
        commandline.createArg().setValue( "|" );
        commandline.createArg().setValue( "&&" );
        commandline.createArg().setValue( "||" );
        commandline.createArg().setValue( ";" );
        commandline.createArg().setValue( ";;" );
        commandline.createArg().setValue( "&" );
        commandline.createArg().setValue( "()" );
        commandline.createArg().setValue( "<" );
        commandline.createArg().setValue( "<<" );
        commandline.createArg().setValue( ">" );
        commandline.createArg().setValue( ">>" );
        commandline.createArg().setValue( "*" );
        commandline.createArg().setValue( "?" );
        commandline.createArg().setValue( "[" );
        commandline.createArg().setValue( "]" );
        commandline.createArg().setValue( "{" );
        commandline.createArg().setValue( "}" );
        commandline.createArg().setValue( "`" );

        String[] lines = commandline.getShellCommandline();
        System.out.println( Arrays.asList( lines ) );

        assertEquals( "/bin/sh", lines[0] );
        assertEquals( "-c", lines[1] );
        assertEquals( "chmod ' ' '|' '&&' '||' ';' ';;' '&' '()' '<' '<<' '>' '>>' '*' '?' '[' ']' '{' '}' '`'",
                      lines[2] );

    }


    public void setErrorHandler(ErrorHandler errorHandler) {
        this.errorHandler = errorHandler;
    }


    public void sendError(int sc, String msg) throws IOException {
        if (isIncluding()) {
            Logger.log(Logger.ERROR, Launcher.RESOURCES, "IncludeResponse.Error",
                    new String[] { "" + sc, msg });
            return;
        }

        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
                "WinstoneResponse.SendingError", new String[] { "" + sc, msg });

        if ((this.webAppConfig != null) && (this.req != null)) {

            RequestDispatcher rd = this.webAppConfig
                    .getErrorDispatcherByCode(req.getRequestURI(), sc, msg, null);
            if (rd != null) {
                try {
                    rd.forward(this.req, this);
                    return;
                } catch (IllegalStateException err) {
                    throw err;
                } catch (IOException err) {
                    throw err;
                } catch (Throwable err) {
                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
                            "WinstoneResponse.ErrorInErrorPage", new String[] {
                                    rd.getName(), sc + "" }, err);
                    return;
                }
            }
        }
        // If we are here there was no webapp and/or no request object, so
        // show the default error page
        if (this.errorStatusCode == null) {
            this.statusCode = sc;
        }
        String output = Launcher.RESOURCES.getString("WinstoneResponse.ErrorPage",
                new String[] { sc + "", (msg == null ? "" : msg), "",
                        Launcher.RESOURCES.getString("ServerVersion"),
                        "" + new Date() });
        setContentLength(output.getBytes(getCharacterEncoding()).length);
        Writer out = getWriter();
        out.write(output);
        out.flush();
    }


    public URL createURL(String spaces, String name, String queryString, String anchor, String wikiId,
        XWikiContext context, FilesystemExportContext exportContext) throws Exception
    {
        // Check if the current user has the right to view the SX file. We do this since this is what would happen
        // in XE when a SX action is called (check done in XWikiAction).
        // Note that we cannot just open an HTTP connection to the SX action here since we wouldn't be authenticated...
        // Thus we have to simulate the same behavior as the SX action...

        List<String> spaceNames = this.legacySpaceResolve.resolve(spaces);
        DocumentReference sxDocumentReference = new DocumentReference(wikiId, spaceNames, name);
        this.authorizationManager.checkAccess(Right.VIEW, sxDocumentReference);

        // Set the SX document as the current document in the XWiki Context since unfortunately the SxSource code
        // uses the current document in the context instead of accepting it as a parameter...
        XWikiDocument sxDocument = context.getWiki().getDocument(sxDocumentReference, context);

        Map<String, Object> backup = new HashMap<>();
        XWikiDocument.backupContext(backup, context);
        try {
            sxDocument.setAsContextDoc(context);
            return processSx(spaceNames, name, queryString, context, exportContext);
        } finally {
            XWikiDocument.restoreContext(backup, context);
        }
    }


    private static boolean validateChainData(JsonNode data) throws Exception {
        ECPublicKey lastKey = null;
        boolean validChain = false;
        for (JsonNode node : data) {
            JWSObject jwt = JWSObject.parse(node.asText());

            if (!validChain) {
                validChain = EncryptionUtils.verifyJwt(jwt, EncryptionUtils.getMojangPublicKey());
            }

            if (lastKey != null) {
                if (!EncryptionUtils.verifyJwt(jwt, lastKey)) return false;
            }

            JsonNode payloadNode = JSON_MAPPER.readTree(jwt.getPayload().toString());
            JsonNode ipkNode = payloadNode.get("identityPublicKey");
            Preconditions.checkState(ipkNode != null && ipkNode.getNodeType() == JsonNodeType.STRING, "identityPublicKey node is missing in chain");
            lastKey = EncryptionUtils.generateKey(ipkNode.asText());
        }
        return validChain;
    }


  public Operation.OperationResult executeFixedCostOperation(
      final MessageFrame frame, final EVM evm) {
    Bytes shiftAmount = frame.popStackItem();
    if (shiftAmount.size() > 4 && (shiftAmount = shiftAmount.trimLeadingZeros()).size() > 4) {
      frame.popStackItem();
      frame.pushStackItem(UInt256.ZERO);
    } else {
      final int shiftAmountInt = shiftAmount.toInt();
      final Bytes value = leftPad(frame.popStackItem());

      if (shiftAmountInt >= 256) {
        frame.pushStackItem(UInt256.ZERO);
      } else {
        frame.pushStackItem(value.shiftLeft(shiftAmountInt));
      }
    }
    return successResponse;
  }


    public void translate(LoginDisconnectPacket packet, GeyserSession session) {
        // The client doesn't manually get disconnected so we have to do it ourselves
        session.disconnect(MessageTranslator.convertMessage(packet.getReason(), session.getLocale()));
    }


    public void translate(EntityEventPacket packet, GeyserSession session) {
        switch (packet.getType()) {
            case EATING_ITEM:
                // Resend the packet so we get the eating sounds
                session.sendUpstreamPacket(packet);
                return;
            case COMPLETE_TRADE:
                ClientSelectTradePacket selectTradePacket = new ClientSelectTradePacket(packet.getData());
                session.sendDownstreamPacket(selectTradePacket);

                session.scheduleInEventLoop(() -> {
                    Entity villager = session.getPlayerEntity();
                    Inventory openInventory = session.getOpenInventory();
                    if (openInventory instanceof MerchantContainer) {
                        MerchantContainer merchantInventory = (MerchantContainer) openInventory;
                        VillagerTrade[] trades = merchantInventory.getVillagerTrades();
                        if (trades != null && packet.getData() >= 0 && packet.getData() < trades.length) {
                            VillagerTrade trade = merchantInventory.getVillagerTrades()[packet.getData()];
                            openInventory.setItem(2, GeyserItemStack.from(trade.getOutput()), session);
                            villager.getMetadata().put(EntityData.TRADE_XP, trade.getXp() + villager.getMetadata().getInt(EntityData.TRADE_XP));
                            villager.updateBedrockMetadata(session);
                        }
                    }
                }, 100, TimeUnit.MILLISECONDS);
                return;
        }
        session.getConnector().getLogger().debug("Did not translate incoming EntityEventPacket: " + packet.toString());
    }


    private void sendStreamingResponse(HttpExchange pExchange, ParsedUri pParsedUri, JSONStreamAware pJson) throws IOException {
        Headers headers = pExchange.getResponseHeaders();
        if (pJson != null) {
            headers.set("Content-Type", getMimeType(pParsedUri) + "; charset=utf-8");
            String callback = pParsedUri.getParameter(ConfigKey.CALLBACK.getKeyValue());
            pExchange.sendResponseHeaders(200, 0);
            Writer writer = new OutputStreamWriter(pExchange.getResponseBody(), "UTF-8");
            IoUtil.streamResponseAndClose(writer, pJson, callback);
        } else {
            headers.set("Content-Type", "text/plain");
            pExchange.sendResponseHeaders(200,-1);
        }
    }


    final void set(CharSequence name, String... values) {
        final AsciiString normalizedName = normalizeName(name);
        requireNonNull(values, "values");

        final int h = normalizedName.hashCode();
        final int i = index(h);

        remove0(h, i, normalizedName);
        for (String v : values) {
            requireNonNullElement(values, v);
            add0(h, i, normalizedName, v);
        }
    }


    public void translate(LoginSuccessPacket packet, GeyserSession session) {
        PlayerEntity playerEntity = session.getPlayerEntity();
        AuthType remoteAuthType = session.getRemoteAuthType();

        // Required, or else Floodgate players break with Spigot chunk caching
        GameProfile profile = packet.getProfile();
        playerEntity.setUsername(profile.getName());
        playerEntity.setUuid(profile.getId());

        // Check if they are not using a linked account
        if (remoteAuthType == AuthType.OFFLINE || playerEntity.getUuid().getMostSignificantBits() == 0) {
            SkinManager.handleBedrockSkin(playerEntity, session.getClientData());
        }

        if (remoteAuthType == AuthType.FLOODGATE) {
            // We'll send the skin upload a bit after the handshake packet (aka this packet),
            // because otherwise the global server returns the data too fast.
            session.getAuthData().upload(session.getConnector());
        }
    }


    public void translate(ServerSpawnPlayerPacket packet, GeyserSession session) {
        Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
        Vector3f rotation = Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getYaw());

        PlayerEntity entity;
        if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
            // Server is sending a fake version of the current player
            entity = new PlayerEntity(session.getPlayerEntity().getProfile(), packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), position, Vector3f.ZERO, rotation);
        } else {
            entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
            if (entity == null) {
                GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid()));
                return;
            }

            entity.setEntityId(packet.getEntityId());
            entity.setPosition(position);
            entity.setRotation(rotation);
        }
        session.getEntityCache().cacheEntity(entity);

        entity.sendPlayer(session);
        SkinManager.requestAndHandleSkinAndCape(entity, session, null);
    }


	public static SecretKey decryptCEK(final PrivateKey priv,
		                           final byte[] encryptedCEK,
		                           final int keyLength,
		                           final Provider provider)
		throws JOSEException {

		try {
			Cipher cipher = CipherHelper.getInstance("RSA/ECB/PKCS1Padding", provider);
			cipher.init(Cipher.DECRYPT_MODE, priv);
			byte[] secretKeyBytes = cipher.doFinal(encryptedCEK);

			if (ByteUtils.bitLength(secretKeyBytes) != keyLength) {
				// CEK key length mismatch
				return null;
			}

			return new SecretKeySpec(secretKeyBytes, "AES");

		} catch (Exception e) {

			// java.security.NoSuchAlgorithmException
			// java.security.InvalidKeyException
			// javax.crypto.IllegalBlockSizeException
			// javax.crypto.BadPaddingException
			throw new JOSEException("Couldn't decrypt Content Encryption Key (CEK): " + e.getMessage(), e);
		}
	}


  public void getPermissions() {
    List<String> permissions = method.getPermissions();
    assertThat(permissions).containsExactlyInAnyOrder("net:*", "net:listening", "*:*");
  }


    private File createTemporaryFolderIn(File parentFolder) throws IOException {
        File createdFolder = null;
        for (int i = 0; i < TEMP_DIR_ATTEMPTS; ++i) {
            // Use createTempFile to get a suitable folder name.
            String suffix = ".tmp";
            File tmpFile = File.createTempFile(TMP_PREFIX, suffix, parentFolder);
            String tmpName = tmpFile.toString();
            // Discard .tmp suffix of tmpName.
            String folderName = tmpName.substring(0, tmpName.length() - suffix.length());
            createdFolder = new File(folderName);
            if (createdFolder.mkdir()) {
                tmpFile.delete();
                return createdFolder;
            }
            tmpFile.delete();
        }
        throw new IOException("Unable to create temporary directory in: "
            + parentFolder.toString() + ". Tried " + TEMP_DIR_ATTEMPTS + " times. "
            + "Last attempted to create: " + createdFolder.toString());
    }


    private static String encodeToPercents(Bytes value, boolean isPath) {
        final BitSet allowedChars = isPath ? ALLOWED_PATH_CHARS : ALLOWED_QUERY_CHARS;
        final int length = value.length;
        boolean needsEncoding = false;
        for (int i = 0; i < length; i++) {
            if (!allowedChars.get(value.data[i] & 0xFF)) {
                needsEncoding = true;
                break;
            }
        }

        if (!needsEncoding) {
            // Deprecated, but it fits perfect for our use case.
            // noinspection deprecation
            return new String(value.data, 0, 0, length);
        }

        final StringBuilder buf = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            final int b = value.data[i] & 0xFF;

            if (b == PERCENT_ENCODING_MARKER && (i + 1) < length) {
                final int marker = value.data[i + 1] & 0xFF;
                final String percentEncodedChar = MARKER_TO_PERCENT_ENCODED_CHAR[marker];
                if (percentEncodedChar != null) {
                    buf.append(percentEncodedChar);
                    i++;
                    continue;
                }
            }

            if (allowedChars.get(b)) {
                buf.append((char) b);
            } else if (b == ' ') {
                if (isPath) {
                    buf.append("%20");
                } else {
                    buf.append('+');
                }
            } else {
                buf.append('%');
                appendHexNibble(buf, b >>> 4);
                appendHexNibble(buf, b & 0xF);
            }
        }

        return buf.toString();
    }


    public void translate(ServerChatPacket packet, GeyserSession session) {
        TextPacket textPacket = new TextPacket();
        textPacket.setPlatformChatId("");
        textPacket.setSourceName("");
        textPacket.setXuid(session.getAuthData().getXboxUUID());
        switch (packet.getType()) {
            case CHAT:
                textPacket.setType(TextPacket.Type.CHAT);
                break;
            case SYSTEM:
                textPacket.setType(TextPacket.Type.SYSTEM);
                break;
            case NOTIFICATION:
                textPacket.setType(TextPacket.Type.TIP);
                break;
            default:
                textPacket.setType(TextPacket.Type.RAW);
                break;
        }

        textPacket.setNeedsTranslation(false);
        textPacket.setMessage(MessageTranslator.convertMessage(packet.getMessage(), session.getLocale()));

        session.sendUpstreamPacket(textPacket);
    }


    void equal() {
        final PathAndQuery res = PathAndQuery.parse("/=?a=b=1");
        assertThat(res).isNotNull();
        assertThat(res.path()).isEqualTo("/=");
        assertThat(res.query()).isEqualTo("a=b=1");

        // '%3D' in a query string should never be decoded into '='.
        final PathAndQuery res2 = PathAndQuery.parse("/%3D?a%3db=1");
        assertThat(res2).isNotNull();
        assertThat(res2.path()).isEqualTo("/=");
        assertThat(res2.query()).isEqualTo("a%3Db=1");
    }


    public void existingDocumentFromUINoName() throws Exception
    {
        // current document = xwiki:Main.WebHome
        DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
        XWikiDocument document = mock(XWikiDocument.class);
        when(document.getDocumentReference()).thenReturn(documentReference);
        when(document.isNew()).thenReturn(false);
        when(document.getLocalReferenceMaxLength()).thenReturn(255);
        context.setDoc(document);

        // Just landed on the create page or submitted with no values (no name) specified.

        // Run the action
        String result = action.render(context);

        // The tests are below this line!

        // Verify that the create template is rendered, so the UI is displayed for the user to enter the missing values.
        assertEquals("create", result);

        // We should not get this far so no redirect should be done, just the template will be rendered.
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    }


    public void translate(AnimatePacket packet, GeyserSession session) {
        // Stop the player sending animations before they have fully spawned into the server
        if (!session.isSpawned()) {
            return;
        }

        switch (packet.getAction()) {
            case SWING_ARM:
                // Delay so entity damage can be processed first
                session.scheduleInEventLoop(() ->
                        session.sendDownstreamPacket(new ClientPlayerSwingArmPacket(Hand.MAIN_HAND)),
                        25,
                        TimeUnit.MILLISECONDS
                );
                break;
            // These two might need to be flipped, but my recommendation is getting moving working first
            case ROW_LEFT:
                // Packet value is a float of how long one has been rowing, so we convert that into a boolean
                session.setSteeringLeft(packet.getRowingTime() > 0.0);
                ClientSteerBoatPacket steerLeftPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
                session.sendDownstreamPacket(steerLeftPacket);
                break;
            case ROW_RIGHT:
                session.setSteeringRight(packet.getRowingTime() > 0.0);
                ClientSteerBoatPacket steerRightPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
                session.sendDownstreamPacket(steerRightPacket);
                break;
        }
    }