/**
   * @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;
  }
  /** @param args the command line arguments */
  public static void main(String[] args) throws IOException, CDKException {
    BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(output));
    int j = 0;

    File f;

    SmilesGenerator sg;
    f = new File(input);

    System.out.println(input);
    IteratingSDFReader reader =
        new IteratingSDFReader(new FileInputStream(f), DefaultChemObjectBuilder.getInstance());

    sg = SmilesGenerator.generic().aromatic();
    sg.setUseAromaticityFlag(true);

    // List<IAtomContainer> mols = new ArrayList<IAtomContainer>();

    IAtomContainer mol;

    long totalMemory = 0;

    while (reader.hasNext()) {
      mol = (IAtomContainer) reader.next();
      // mols.add(mol);
      j++;
      String smiles = sg.create(mol);
      if (!smiles.equals("")) {
        writer.write(sg.create(mol).getBytes());
        writer.write(";".getBytes());
        writer.write("https://www.ebi.ac.uk/chembl/compound/inspect/".getBytes());
        writer.write(((String) mol.getProperties().get("chembl_id")).getBytes());
        writer.write("\n".getBytes());
      } else {
        System.out.println("HUUUUGE");
      }
      System.out.println("done" + j);
    }

    // totalMemory = MemoryUtil.deepMemoryUsageOfAll(mols, MemoryUtil.VisibilityFilter.ALL);

    // System.out.println("Average memory: " + (totalMemory/j));

    /*a a = new a();
    a aa = new a();
    a.c = new c();
    aa.c = a.c;

    System.out.println("a " + MemoryUtil.deepMemoryUsageOf(a, MemoryUtil.VisibilityFilter.ALL));
    System.out.println("aa " + MemoryUtil.deepMemoryUsageOf(aa, MemoryUtil.VisibilityFilter.ALL));
    System.out.println("a.c " + MemoryUtil.deepMemoryUsageOf(a.c, MemoryUtil.VisibilityFilter.ALL));

    List<a> ll = new ArrayList<a>();

    ll.add(a);
    ll.add(aa);

    System.out.println(MemoryUtil.deepMemoryUsageOfAll(ll, MemoryUtil.VisibilityFilter.ALL));*/

    System.out.println("done" + j);
    writer.close();
  }