@Override
    protected Object doInBackground() throws Exception {

      BusyIndicator.showAt(CreateBagsPanel.this);

      try {
        int total = getCreateBagsParams().getDirectories().size();
        int totalSuccess = 0;

        for (int i = 0; i < getCreateBagsParams().getDirectories().size(); i++) {

          File inputDir = getCreateBagsParams().getDirectories().get(i);
          File out = new File(getCreateBagsParams().getOutputDir().get(0), inputDir.getName());
          ArrayList<String> errors = new ArrayList<String>();
          int percent =
              (int)
                  Math.floor(
                      ((i + 1) / ((float) getCreateBagsParams().getDirectories().size())) * 100);

          // regular check
          if (isCancelled()) {
            reportStatistics(total, totalSuccess);
            break;
          }

          String error = null;
          String errorTitle = null;

          try {
            // -> input check

            try {
              // leesbaar? bestaat?
              FUtils.checkFile(inputDir, true);
            } catch (FileNotWritableException e) {
              log.debug(e.getMessage());
              // doe niets
            }

            // bestandsnamen cross platform overdraagbaar?
            FUtils.checkSafeFiles(inputDir);

            // lege map verboden
            if (inputDir.isDirectory()) {
              File[] children = inputDir.listFiles();
              if (children == null || children.length == 0) {
                throw new FileEmptyDirectoryException(inputDir);
              }
            }

            /*
             *  Lege bag:
             *      rootDir: null, want map bestaat nog niet (opgeven File die nog niet bestaat geef IOException)
             */
            MetsBag metsBag = new MetsBag(null, getCreateBagsParams().getVersion());
            metsBag.setFile(out);
            metsBag.setBagItMets(new DefaultBagItMets());
            Mets mets = new Mets();
            metsBag.setMets(mets);

            // voeg payloads toe
            File[] listPayloads = inputDir.listFiles();
            if (listPayloads != null) {
              for (File file : listPayloads) {
                metsBag.addFileToPayload(file);
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // zoek metadata bestanden (todo: haal die uit payload lijst)
            for (String metadataPath : getCreateBagsParams().getMetadata()) {
              File metadataFile = new File(inputDir, metadataPath);
              if (metadataFile.exists() && metadataFile.isFile()) {
                // voeg toe aan mets

                if (metadataFile.getAbsolutePath().endsWith(".xml")) {
                  MdSec mdSec = MetsUtils.createMdSec(metadataFile);
                  mets.getDmdSec().add(mdSec);
                }

                // haal uit payload lijst
                if (!getCreateBagsParams().isKeepMetadata()) {
                  String path = "data/" + metadataPath;
                  metsBag.removeBagFile(path);
                }
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // voeg dc toe indien nodig, en mogelijk
            if (getCreateBagsParams().isAddDC()) {
              Document dcDoc = MetsUtils.generateDCDoc(mets);
              if (dcDoc != null) {
                mets.getDmdSec().add(MetsUtils.createMdSec(dcDoc));
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // schrijf naar bag-info
            if (getCreateBagsParams().isWriteToBagInfo()) {

              ArrayList<Element> dcElements = new ArrayList<Element>();
              ArrayList<Element> dcCandidates = new ArrayList<Element>();
              MetsUtils.findDC(mets, dcElements, dcCandidates);

              Document dcDoc = null;
              if (dcElements.size() > 0) {
                Document doc = XML.createDocument();
                Node node = doc.importNode(dcElements.get(0), true);
                doc.appendChild(node);
                dcDoc = doc;
              } else {
                dcDoc = MetsUtils.generateDCDoc(dcElements, dcCandidates);
              }

              if (dcDoc != null) {

                ByteArrayInputStream baginfoIn =
                    new ByteArrayInputStream(MetsUtils.DCToBagInfo(dcDoc));
                NameValueReaderImpl reader =
                    new NameValueReaderImpl("UTF-8", baginfoIn, "bagInfoTxt");
                while (reader.hasNext()) {
                  NameValueReader.NameValue pair = reader.next();
                  BagInfoField field = new BagInfoField();
                  field.setName(pair.getName());
                  field.setLabel(pair.getName());
                  field.setValue(pair.getValue());
                  field.setComponentType(BagInfoField.TEXTFIELD_COMPONENT);
                  metsBag.addField(field);
                }
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // save!
            Writer writer = new FileSystemWriter(new BagFactory());
            boolean saveOk = metsBag.write(writer);

            // save ok!
            if (saveOk) {
              totalSuccess++;
            }

          } catch (FileNotReadableException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.FileNotReadableException",
                    new Object[] {e.getFile()});

          } catch (FileNotFoundException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.FileNotFoundException", new Object[] {inputDir});

          } catch (FileNameNotPortableException e) {

            // één of meerdere bestandsnamen zijn niet portabel
            if (inputDir.isDirectory()) {
              error =
                  Context.getMessage(
                      "CreateBagsPanel.NewBagsWorker.FileNameNotPortableException.directory",
                      new Object[] {inputDir, e.getFile()});
            } else {
              error =
                  Context.getMessage(
                      "CreateBagsPanel.NewBagsWorker.FileNameNotPortableException.file",
                      new Object[] {inputDir});
            }

          } catch (FileEmptyDirectoryException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.FileEmptyDirectoryException",
                    new Object[] {inputDir});

          } catch (IOException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.IOException", new Object[] {e.getMessage()});

          } catch (SAXException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.SAXException", new Object[] {e.getMessage()});

          } catch (ParserConfigurationException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.ParserConfigurationException",
                    new Object[] {e.getMessage()});

          } catch (IllegalNamespaceException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.IllegalNamespaceException",
                    new Object[] {e.getNamespace()});

          } catch (NoNamespaceException e) {
            error = Context.getMessage("CreateBagsPanel.NewBagsWorker.NoNamespaceException");

          } catch (DtdNoFixFoundException e) {
            error = Context.getMessage("CreateBagsPanel.NewBagsWorker.DtdNoFixFoundException");

          } catch (Exception e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsWorker.Exception", new Object[] {e.getMessage()});
          }

          // rapport
          if (error != null) {
            errors.add(error);
            SwingUtils.ShowError(errorTitle, error);
            log.error(error);
          }
          reportStatistics(total, totalSuccess);
          addCreateBagResult(new CreateBagResult(inputDir, out, errors.toArray(new String[] {})));
          if (!isDone()) {
            setProgress(percent);
          }
        }

      } catch (Exception e) {
        log.error(e.getMessage());
      }

      BusyIndicator.clearAt(CreateBagsPanel.this);

      return null;
    }
    @Override
    protected Object doInBackground() throws Exception {
      BusyIndicator.showAt(CreateBagsPanel.this);

      try {
        int totalSuccess = 0;
        int total = getCreateBagsParams().getDirectories().size();

        for (int i = 0; i < getCreateBagsParams().getDirectories().size(); i++) {

          File file = getCreateBagsParams().getDirectories().get(i);

          int percent =
              (int)
                  Math.floor(
                      ((i + 1) / ((float) getCreateBagsParams().getDirectories().size())) * 100);
          ArrayList<String> errors = new ArrayList<String>();

          String error = null;
          String errorTitle = null;

          // regular check
          if (isCancelled()) {
            reportStatistics(total, totalSuccess);
            break;
          }

          try {
            // bestaat? leesbaar? schrijfbaar?
            FUtils.checkFile(file, true);

            // bestandsnamen cross platform overdraagbaar?
            FUtils.checkSafeFiles(file);

            // creëer bag in place
            MetsBag metsBag = new MetsBag(null, null);
            metsBag.setBagItMets(new DefaultBagItMets());
            metsBag.setFile(file);
            Mets mets = new Mets();
            metsBag.setMets(mets);

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // zoek metadata bestanden (todo: haal die uit payload lijst)
            for (String metadataPath : getCreateBagsParams().getMetadata()) {
              File metadataFile = new File(file, metadataPath);
              if (metadataFile.exists() && metadataFile.isFile()) {
                if (metadataFile.getAbsolutePath().endsWith(".xml")) {
                  MdSec mdSec = MetsUtils.createMdSec(metadataFile);
                  mets.getDmdSec().add(mdSec);
                }
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // voeg dc toe indien nodig, en mogelijk
            if (getCreateBagsParams().isAddDC()) {
              Document dcDoc = MetsUtils.generateDCDoc(mets);
              if (dcDoc != null) {
                mets.getDmdSec().add(MetsUtils.createMdSec(dcDoc));
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            // schrijf naar bag-info
            if (getCreateBagsParams().isWriteToBagInfo()) {
              ArrayList<Element> dcElements = new ArrayList<Element>();
              ArrayList<Element> dcCandidates = new ArrayList<Element>();
              MetsUtils.findDC(mets, dcElements, dcCandidates);

              Document dcDoc = null;
              if (dcElements.size() > 0) {
                Document doc = XML.createDocument();
                Node node = doc.importNode(dcElements.get(0), true);
                doc.appendChild(node);
                dcDoc = doc;
              } else {
                dcDoc = MetsUtils.generateDCDoc(dcElements, dcCandidates);
              }

              if (dcDoc != null) {
                ByteArrayInputStream baginfoIn =
                    new ByteArrayInputStream(MetsUtils.DCToBagInfo(dcDoc));
                NameValueReaderImpl reader =
                    new NameValueReaderImpl("UTF-8", baginfoIn, "bagInfoTxt");
                while (reader.hasNext()) {
                  NameValueReader.NameValue pair = reader.next();
                  BagInfoField field = new BagInfoField();
                  field.setName(pair.getName());
                  field.setLabel(pair.getName());
                  field.setValue(pair.getValue());
                  field.setComponentType(BagInfoField.TEXTFIELD_COMPONENT);
                  metsBag.addField(field);
                }
              }
            }

            // regular check
            if (isCancelled()) {
              reportStatistics(total, totalSuccess);
              break;
            }

            String[] ignoreFiles =
                getCreateBagsParams().isKeepMetadata()
                    ? new String[] {}
                    : getCreateBagsParams().getMetadata();

            if (getCreateBagsParams().isKeepEmptyDirectories()) {
              metsBag.createPreBagAddKeepFilesToEmptyFolders(
                  file, getCreateBagsParams().getVersion(), ignoreFiles);
            } else {
              metsBag.createPreBag(file, getCreateBagsParams().getVersion(), ignoreFiles);
            }

          } catch (FileNotWritableException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.FileNotWritableException",
                    new Object[] {e.getFile()});

          } catch (FileNotReadableException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.FileNotReadableException",
                    new Object[] {e.getFile()});

          } catch (FileNotFoundException e) {

            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.FileNotFoundException",
                    new Object[] {file});

          } catch (FileNameNotPortableException e) {

            // één of meerdere bestandsnamen zijn niet portabel
            if (file.isDirectory()) {
              error =
                  Context.getMessage(
                      "CreateBagsPanel.NewBagsInPlaceWorker.FileNameNotPortableException.directory",
                      new Object[] {file, e.getFile()});
            } else {
              error =
                  Context.getMessage(
                      "CreateBagsPanel.NewBagsInPlaceWorker.FileNameNotPortableException.file",
                      new Object[] {file});
            }

          } catch (IOException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.IOException",
                    new Object[] {e.getMessage()});

          } catch (SAXException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.SAXException",
                    new Object[] {e.getMessage()});

          } catch (ParserConfigurationException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.ParserConfigurationException",
                    new Object[] {e.getMessage()});

          } catch (IllegalNamespaceException e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.IllegalNamespaceException",
                    new Object[] {e.getNamespace()});

          } catch (NoNamespaceException e) {
            error = Context.getMessage("CreateBagsPanel.NewBagsInPlaceWorker.NoNamespaceException");

          } catch (DtdNoFixFoundException e) {
            error =
                Context.getMessage("CreateBagsPanel.NewBagsInPlaceWorker.DtdNoFixFoundException");

          } catch (Exception e) {
            error =
                Context.getMessage(
                    "CreateBagsPanel.NewBagsInPlaceWorker.Exception",
                    new Object[] {e.getMessage()});
          }

          // rapport
          if (error != null) {
            errors.add(error);
            log.error(error);
            SwingUtils.ShowError(errorTitle, error);
          }
          reportStatistics(total, totalSuccess);
          addCreateBagResult(new CreateBagResult(file, file, errors.toArray(new String[] {})));
          if (!isDone()) {
            setProgress(percent);
          }

          // regular check
          if (isCancelled()) {
            reportStatistics(total, totalSuccess);
            break;
          }
        }

      } catch (Exception e) {
        log.error(e.getMessage());
      }

      BusyIndicator.clearAt(CreateBagsPanel.this);
      return null;
    }