// Path: src/com/metamolecular/mx/model/Molecule.java
// public interface Molecule
// {
//   public int countAtoms();
//   
//   public int countBonds();
// 
//   public int countSuperatoms();
// 
//   public Atom getAtom(int index);
//   
//   public Bond getBond(int index);
//   
//   public Bond getBond(Atom source, Atom target);
// 
//   public Superatom getSuperatom(int index);
// 
//   public Superatom addSuperatom();
// 
//   public Atom addAtom(String symbol, double x, double y, double z);
//   
//   public Atom addAtom(String symbol);
//   
//   public void removeAtom(Atom atom);
//   
//   public Bond connect(Atom source, Atom target, int type, int stereo);
//   
//   public Bond connect(Atom source, Atom target, int type);
//                                      
//   public void removeBond(Bond bond);
//   
//   public void disconnect(Atom source, Atom target);
// 
//   public void removeSuperatom(Superatom substructure);
//   
//   public void clear();
//   
//   public void beginModify();
//   
//   public void endModify();
// 
//   public void addChangeListener(ChangeListener listener);
// 
//   public void removeChangeListener(ChangeListener listener);
//   
//   public Molecule copy();
//   
//   public void copy(Molecule molecule);
// }
// 
// Path: src/com/metamolecular/mx/model/MoleculeKit.java
// public class MoleculeKit
// {
//   private static MolfileReader reader;
//   private static MolfileWriter writer;
//   private static VirtualHydrogenCounter hydrogenCounter;
//   private static String hydrogen = "H";
//   private static MassCalculator massCalculator;
//   
//   static
//   {
//     reader = new MolfileReader();
//     writer = new MolfileWriter();
//     massCalculator = new MassCalculator();
//     hydrogenCounter = new VirtualHydrogenCounter();
//   }
//   
//   /**
//    * 
//    */
//   private MoleculeKit()
//   {
//     
//   }
//   
//   public static double getMass(Molecule molecule)
//   {
//     return massCalculator.findAveragedMass(molecule);
//   }
// 
//   public static Molecule readMolfile(String molfile)
//   {
//     Molecule result = new DefaultMolecule();
//     
//     reader.read(result, molfile.replaceAll("\\\\n", "\n"));
//     
//     return result;
//   }
//   
//   public static Molecule readMolfile(String molfile, boolean virtualizeHydrogens)
//   {
//     Molecule mol = readMolfile(molfile);
//     
//     if (virtualizeHydrogens)
//     {
//       virtualizeHydrogens(mol);
//     }
//     
//     return mol;
//   }
//   
//   public static String writeMolfile(Molecule molecule)
//   {
//     return writer.write(molecule);
//   }
//   
//   public static void virtualizeHydrogens(Molecule molecule)
//   {
//     List toStrip = new ArrayList();
//     
//     for (int i = 0; i < molecule.countAtoms(); i++)
//     {
//       Atom atom = molecule.getAtom(i);
//       
//       recordVirtualizableHydrogens(atom, toStrip);
//     }
//     
//     if (toStrip.isEmpty()) return;
//     
//     molecule.beginModify();
//     
//     for (int i = 0; i < toStrip.size(); i++)
//     {
//       Atom atom = (Atom) toStrip.get(i);
//       
//       molecule.removeAtom(atom);
//     }
//     
//     molecule.endModify();
//   }
//   
//   public static boolean isVirtualizableHydrogen(Atom atom)
//   {
//     if (!hydrogen.equals(atom.getSymbol()))
//     {
//       return false;
//     }
//     
//     if (atom.hasSingleIsotope() || atom.countNeighbors() != 1)
//     {
//       return false;
//     }
//     
//     Bond[] bonds = atom.getBonds();
//     
//     return bonds[0].getStereo() == 0 && bonds[0].getType() == 1;
//   }
//   
//   public static boolean isVirtualizableHydrogenBond(Bond bond)
//   {
//     if (!(hydrogen.equals(bond.getSource().getSymbol()) || hydrogen.equals(bond.getTarget().getSymbol())))
//     {
//       return false;
//     }
//     
//     if (hydrogen.equals(bond.getSource().getSymbol()) && hydrogen.equals(bond.getTarget().getSymbol()))
//     {
//       return false;
//     }
//     
//     return bond.getStereo() == 0 && bond.getType() == 1;
//   }
//   
//   private static void recordVirtualizableHydrogens(Atom atom, List toStrip)
//   {
//     if (!hydrogenCounter.isVirtualizableHeavyAtom(atom)) return;
//     
//     Bond[] bonds = atom.getBonds();
//     
//     for (int i = 0; i < bonds.length; i++)
//     {
//       Bond bond = bonds[i];
//       Atom neighbor = bond.getMate(atom);
//       
//       if (hydrogen.equals(neighbor.getSymbol()))
//       {
//         if (neighbor.hasSingleIsotope()) continue;
//         if (bond.getStereo() != 0) continue;
//         
//         toStrip.add(neighbor);
//       }
//     }
//   }
// }


import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.metamolecular.mx.model.Molecule;
import com.metamolecular.mx.model.MoleculeKit;
import java.io.BufferedReader;
import java.io.FileReader;
  }

  public String getData(String key)
  {
    assertRecordLoaded();

    Pattern pattern = keyPatterns.get(key);

    if (pattern == null)
    {
      pattern = Pattern.compile(".*^> *?<" + key + ">$(.*?)$^$.*", Pattern.MULTILINE | Pattern.DOTALL);

      keyPatterns.put(key, pattern);
    }

    Matcher matcher = pattern.matcher(record);

    return matcher.matches() ? matcher.group(1).trim() : "";
  }

  public Molecule getMolecule()
  {
    assertRecordLoaded();

    Matcher matcher = molfilePattern.matcher(record);

    matcher.find();

    String molfile = matcher.group(1);

// Path: src/com/metamolecular/mx/model/Molecule.java
// public interface Molecule
// {
//   public int countAtoms();
//   
//   public int countBonds();
// 
//   public int countSuperatoms();
// 
//   public Atom getAtom(int index);
//   
//   public Bond getBond(int index);
//   
//   public Bond getBond(Atom source, Atom target);
// 
//   public Superatom getSuperatom(int index);
// 
//   public Superatom addSuperatom();
// 
//   public Atom addAtom(String symbol, double x, double y, double z);
//   
//   public Atom addAtom(String symbol);
//   
//   public void removeAtom(Atom atom);
//   
//   public Bond connect(Atom source, Atom target, int type, int stereo);
//   
//   public Bond connect(Atom source, Atom target, int type);
//                                      
//   public void removeBond(Bond bond);
//   
//   public void disconnect(Atom source, Atom target);
// 
//   public void removeSuperatom(Superatom substructure);
//   
//   public void clear();
//   
//   public void beginModify();
//   
//   public void endModify();
// 
//   public void addChangeListener(ChangeListener listener);
// 
//   public void removeChangeListener(ChangeListener listener);
//   
//   public Molecule copy();
//   
//   public void copy(Molecule molecule);
// }
// 
// Path: src/com/metamolecular/mx/model/MoleculeKit.java
// public class MoleculeKit
// {
//   private static MolfileReader reader;
//   private static MolfileWriter writer;
//   private static VirtualHydrogenCounter hydrogenCounter;
//   private static String hydrogen = "H";
//   private static MassCalculator massCalculator;
//   
//   static
//   {
//     reader = new MolfileReader();
//     writer = new MolfileWriter();
//     massCalculator = new MassCalculator();
//     hydrogenCounter = new VirtualHydrogenCounter();
//   }
//   
//   /**
//    * 
//    */
//   private MoleculeKit()
//   {
//     
//   }
//   
//   public static double getMass(Molecule molecule)
//   {
//     return massCalculator.findAveragedMass(molecule);
//   }
// 
//   public static Molecule readMolfile(String molfile)
//   {
//     Molecule result = new DefaultMolecule();
//     
//     reader.read(result, molfile.replaceAll("\\\\n", "\n"));
//     
//     return result;
//   }
//   
//   public static Molecule readMolfile(String molfile, boolean virtualizeHydrogens)
//   {
//     Molecule mol = readMolfile(molfile);
//     
//     if (virtualizeHydrogens)
//     {
//       virtualizeHydrogens(mol);
//     }
//     
//     return mol;
//   }
//   
//   public static String writeMolfile(Molecule molecule)
//   {
//     return writer.write(molecule);
//   }
//   
//   public static void virtualizeHydrogens(Molecule molecule)
//   {
//     List toStrip = new ArrayList();
//     
//     for (int i = 0; i < molecule.countAtoms(); i++)
//     {
//       Atom atom = molecule.getAtom(i);
//       
//       recordVirtualizableHydrogens(atom, toStrip);
//     }
//     
//     if (toStrip.isEmpty()) return;
//     
//     molecule.beginModify();
//     
//     for (int i = 0; i < toStrip.size(); i++)
//     {
//       Atom atom = (Atom) toStrip.get(i);
//       
//       molecule.removeAtom(atom);
//     }
//     
//     molecule.endModify();
//   }
//   
//   public static boolean isVirtualizableHydrogen(Atom atom)
//   {
//     if (!hydrogen.equals(atom.getSymbol()))
//     {
//       return false;
//     }
//     
//     if (atom.hasSingleIsotope() || atom.countNeighbors() != 1)
//     {
//       return false;
//     }
//     
//     Bond[] bonds = atom.getBonds();
//     
//     return bonds[0].getStereo() == 0 && bonds[0].getType() == 1;
//   }
//   
//   public static boolean isVirtualizableHydrogenBond(Bond bond)
//   {
//     if (!(hydrogen.equals(bond.getSource().getSymbol()) || hydrogen.equals(bond.getTarget().getSymbol())))
//     {
//       return false;
//     }
//     
//     if (hydrogen.equals(bond.getSource().getSymbol()) && hydrogen.equals(bond.getTarget().getSymbol()))
//     {
//       return false;
//     }
//     
//     return bond.getStereo() == 0 && bond.getType() == 1;
//   }
//   
//   private static void recordVirtualizableHydrogens(Atom atom, List toStrip)
//   {
//     if (!hydrogenCounter.isVirtualizableHeavyAtom(atom)) return;
//     
//     Bond[] bonds = atom.getBonds();
//     
//     for (int i = 0; i < bonds.length; i++)
//     {
//       Bond bond = bonds[i];
//       Atom neighbor = bond.getMate(atom);
//       
//       if (hydrogen.equals(neighbor.getSymbol()))
//       {
//         if (neighbor.hasSingleIsotope()) continue;
//         if (bond.getStereo() != 0) continue;
//         
//         toStrip.add(neighbor);
//       }
//     }
//   }
// }


// Path: src/com/metamolecular/mx/io/mdl/SDFileReader.java
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.metamolecular.mx.model.Molecule;
import com.metamolecular.mx.model.MoleculeKit;
import java.io.BufferedReader;
import java.io.FileReader;

  }

  public String getData(String key)
  {
    assertRecordLoaded();

    Pattern pattern = keyPatterns.get(key);

    if (pattern == null)
    {
      pattern = Pattern.compile(".*^> *?<" + key + ">$(.*?)$^$.*", Pattern.MULTILINE | Pattern.DOTALL);

      keyPatterns.put(key, pattern);
    }

    Matcher matcher = pattern.matcher(record);

    return matcher.matches() ? matcher.group(1).trim() : "";
  }

  public Molecule getMolecule()
  {
    assertRecordLoaded();

    Matcher matcher = molfilePattern.matcher(record);

    matcher.find();

    String molfile = matcher.group(1);

    return MoleculeKit.readMolfile(molfile);