/**
   * copy thumb file.
   *
   * @param file file to copy.
   * @throws IOException when ioerror occurs
   */
  private void copyThumb(final FilePostParam file) throws IOException {
    File sourceThumbFile =
        new File(
            configuration.getThumbsPath() + File.separator + file.getType() + file.getFolder(),
            file.getName());
    File destThumbFile =
        new File(
            configuration.getThumbsPath() + File.separator + type + this.currentFolder,
            file.getName());

    if (sourceThumbFile.isFile() && sourceThumbFile.exists()) {
      FileUtils.copyFromSourceToDestFile(sourceThumbFile, destThumbFile, false, configuration);
    }
  }
  /**
   * copy files from request.
   *
   * @return error code
   * @throws IOException when ioexception in debug mode occurs
   */
  private int copyFiles() throws IOException {
    this.filesCopied = 0;
    this.addCopyNode = false;
    for (FilePostParam file : files) {

      if (!FileUtils.checkFileName(file.getName())) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }

      if (Pattern.compile(Constants.INVALID_PATH_REGEX).matcher(file.getFolder()).find()) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }
      if (configuration.getTypes().get(file.getType()) == null) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }
      if (file.getFolder() == null || file.getFolder().equals("")) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }
      if (FileUtils.checkFileExtension(file.getName(), this.configuration.getTypes().get(this.type))
          == 1) {
        creator.appendErrorNodeChild(
            Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION,
            file.getName(),
            file.getFolder(),
            file.getType());
        continue;
      }
      // check #4 (extension) - when moving to another resource type,
      // double check extension
      if (!this.type.equals(file.getType())) {
        if (FileUtils.checkFileExtension(
                file.getName(), this.configuration.getTypes().get(file.getType()))
            == 1) {
          creator.appendErrorNodeChild(
              Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION,
              file.getName(),
              file.getFolder(),
              file.getType());
          continue;
        }
      }
      if (FileUtils.checkIfDirIsHidden(file.getFolder(), this.configuration)) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }

      if (FileUtils.checkIfFileIsHidden(file.getName(), this.configuration)) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST;
      }

      if (!AccessControlUtil.getInstance(this.configuration)
          .checkFolderACL(
              file.getType(),
              file.getFolder(),
              this.userRole,
              AccessControlUtil.CKFINDER_CONNECTOR_ACL_FILE_VIEW)) {
        return Constants.Errors.CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED;
      }

      File sourceFile =
          new File(
              configuration.getTypes().get(file.getType()).getPath() + file.getFolder(),
              file.getName());
      File destFile =
          new File(
              configuration.getTypes().get(this.type).getPath() + this.currentFolder,
              file.getName());

      try {
        if (!sourceFile.exists() || !sourceFile.isFile()) {
          creator.appendErrorNodeChild(
              Constants.Errors.CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND,
              file.getName(),
              file.getFolder(),
              file.getType());
          continue;
        }
        if (!this.type.equals(file.getType())) {
          Long maxSize = configuration.getTypes().get(this.type).getMaxSize();
          if (maxSize != null && maxSize < sourceFile.length()) {
            creator.appendErrorNodeChild(
                Constants.Errors.CKFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG,
                file.getName(),
                file.getFolder(),
                file.getType());
            continue;
          }
        }
        if (sourceFile.equals(destFile)) {
          creator.appendErrorNodeChild(
              Constants.Errors.CKFINDER_CONNECTOR_ERROR_SOURCE_AND_TARGET_PATH_EQUAL,
              file.getName(),
              file.getFolder(),
              file.getType());
          continue;
        } else if (destFile.exists()) {
          if (file.getOptions() != null && file.getOptions().indexOf("overwrite") != -1) {
            if (!handleOverwrite(sourceFile, destFile)) {
              creator.appendErrorNodeChild(
                  Constants.Errors.CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED,
                  file.getName(),
                  file.getFolder(),
                  file.getType());
              continue;
            } else {
              this.filesCopied++;
            }
          } else if (file.getOptions() != null && file.getOptions().indexOf("autorename") != -1) {
            if (!handleAutoRename(sourceFile, destFile)) {
              creator.appendErrorNodeChild(
                  Constants.Errors.CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED,
                  file.getName(),
                  file.getFolder(),
                  file.getType());
              continue;
            } else {
              this.filesCopied++;
            }
          } else {
            creator.appendErrorNodeChild(
                Constants.Errors.CKFINDER_CONNECTOR_ERROR_ALREADY_EXIST,
                file.getName(),
                file.getFolder(),
                file.getType());
            continue;
          }
        } else {
          if (FileUtils.copyFromSourceToDestFile(sourceFile, destFile, false, configuration)) {
            this.filesCopied++;
            copyThumb(file);
          }
        }
      } catch (SecurityException e) {
        if (configuration.isDebugMode()) {
          throw e;
        } else {
          creator.appendErrorNodeChild(
              Constants.Errors.CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED,
              file.getName(),
              file.getFolder(),
              file.getType());
          continue;
        }
      } catch (IOException e) {
        if (configuration.isDebugMode()) {
          throw e;
        } else {
          creator.appendErrorNodeChild(
              Constants.Errors.CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED,
              file.getName(),
              file.getFolder(),
              file.getType());
          continue;
        }
      }
    }
    this.addCopyNode = true;
    if (creator.hasErrors()) {
      return Constants.Errors.CKFINDER_CONNECTOR_ERROR_COPY_FAILED;
    } else {
      return Constants.Errors.CKFINDER_CONNECTOR_ERROR_NONE;
    }
  }