public ChemWizard() {
    smrkMan = new SMIRKSManager(SilentChemObjectBuilder.getInstance());
    smrkMan.setFlagProcessResultStructures(true);
    smrkMan.setFlagAddImplicitHAtomsOnResultProcess(true);

    LOGGER.setLevel(Level.FINEST);
  }
  /**
   * @return
   * @throws Exception
   */
  public int process() throws Exception {
    if (file == null) throw new Exception("File not assigned! Use -f command line option.");
    if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath());
    int records_read = 0;
    int records_processed = 0;
    int records_error = 0;

    InputStream in = new FileInputStream(file);
    /**
     * cdk-io module http://ambit.uni-plovdiv.bg:8083/nexus/index.html#nexus-
     * search;classname~IteratingMDLReader
     */
    IteratingSDFReader reader = null;

    SDFWriter writer = new SDFWriter(new OutputStreamWriter(System.out));

    try {

      reader = new IteratingSDFReader(in, DefaultChemObjectBuilder.getInstance());
      LOGGER.log(Level.INFO, String.format("Reading %s", file.getAbsoluteFile()));
      while (reader.hasNext()) {
        /** Note recent versions allow IAtomContainer molecule = reader.next(); */
        Object object = reader.next();
        IAtomContainer molecule = null;
        if (object instanceof IAtomContainer) molecule = (IAtomContainer) object;
        else break;

        records_read++;
        try {
          /** cdk-standard module */
          AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(molecule);
          // CDKHueckelAromaticityDetector.detectAromaticity(molecule);
          for (IAtom atom : molecule.atoms())
            if (atom.getImplicitHydrogenCount() == null) {
              LOGGER.fine(
                  atom.getSymbol()
                      + "\t"
                      + atom.getAtomTypeName()
                      + "\t"
                      + atom.getImplicitHydrogenCount());
              atom.setImplicitHydrogenCount(0);
            }

          molecule = AtomContainerManipulator.copyAndSuppressedHydrogens(molecule);

          /** Generate SMILES and assign as properties */
          assignSMILES(molecule);
          molecule.setProperty("REACTION", "REACTANT");
          molecule.setProperty("SMIRKS", "");
          /** Apply reactions */
          writer.write(molecule);
          for (int r = 0; r < smirks.length; r++) {
            if (reactions[r] == null) {
              reactions[r] = smrkMan.parse(smirks[r][1]);
            }
            IAtomContainer reactant = molecule.clone();
            if (smrkMan.applyTransformation(reactant, reactions[r])) {
              AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(reactant);
              reactant.setProperty("REACTION", "PRODUCT OF " + smirks[r][0]);
              reactant.setProperty("SMIRKS", smirks[r][1]);
              try {
                assignSMILES(reactant);
              } catch (Exception x) {
                LOGGER.log(Level.WARNING, x.getMessage());
              }
              writer.write(reactant);
            }
          }
          records_processed++;
          ;
        } catch (Exception x) {
          System.err.println("*");
          records_error++;
          LOGGER.log(
              Level.SEVERE,
              String.format("[Record %d] Error %s\n", records_read, file.getAbsoluteFile()),
              x);
        }
      }
    } catch (Exception x) {
      LOGGER.log(
          Level.SEVERE,
          String.format("[Record %d] Error %s\n", records_read, file.getAbsoluteFile()),
          x);
    } finally {
      try {
        reader.close();
      } catch (Exception x) {
      }
      try {
        writer.close();
      } catch (Exception x) {
      }
    }
    LOGGER.log(
        Level.INFO,
        String.format(
            "[Records read/processed/error %d/%d/%d] %s",
            records_read, records_processed, records_error, file.getAbsoluteFile()));
    return records_read;
  }