context: /* 
   * Copyright (C) 2003-2007  The Chemistry Development Kit (CDK) project
   *                    2014  Mark B Vine (orcid:0000-0002-7794-0426)
   *
   * Contact: cdk-devel@slists.sourceforge.net
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public License
   * as published by the Free Software Foundation; either version 2.1
   * of the License, or (at your option) any later version.
   * All we ask is that proper credit is given for our work, which includes
   * - but is not limited to - adding the above copyright notice to the beginning
   * of your source code files, and to any copyright notice that you may distribute
   * with programs based on this work.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT Any WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   */
  
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using Moq;
  using NCDK.Geometries;
  using NCDK.IO.Listener;
  using NCDK.Isomorphisms.Matchers;
  using NCDK.Sgroups;
  using NCDK.Tools.Manipulator;
  using System;
  using System.Collections.Generic;
  using System.Collections.Specialized;
  using System.Diagnostics;
  using System.IO;
  using System.Linq;
  using System.Text;
  
  namespace NCDK.IO
  {
      /// <summary>
      /// TestCase for the reading MDL mol files using one test file.
      /// A test case for SDF files is available as separate Class.
      /// </summary>
      /// <seealso cref="MDLV2000Reader"/>
      /// <seealso cref="SDFReaderTest"/>
      // @cdk.module test-io
      [TestClass()]
      public class MDLV2000ReaderTest : SimpleChemObjectReaderTest
      {
          private readonly IChemObjectBuilder builder = CDK.Builder;
          protected override string TestFile => "NCDK.Data.MDL.bug682233.mol";
          protected override Type ChemObjectIOToTestType => typeof(MDLV2000Reader);
  
          [TestMethod()]
          public void TestAccepts()
          {
              var reader = new MDLV2000Reader(new StringReader(""));
              Assert.IsTrue(reader.Accepts(typeof(IChemFile)));
              Assert.IsTrue(reader.Accepts(typeof(IChemModel)));
              Assert.IsTrue(reader.Accepts(typeof(IAtomContainer)));
          }
  
          // @cdk.bug 3084064
          [TestMethod()]
          public void TestBug3084064()
          {
              var filename = "NCDK.Data.MDL.weirdprops.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
  
              Assert.IsNotNull(chemFile);
  
              var mols = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(10, mols.Count);
  
              var mol = mols[0];
              var props = mol.GetProperties();
              Assert.IsNotNull(props);
              Assert.AreEqual(5, props.Count());
  
              string[] keys = { "DatabaseID", "cdk:Title", "PeaksExplained", "cdk:Remark", "Score" };
              foreach (var s in keys)
              {
                  bool found = false;
                  foreach (var key in props.Keys)
                  {
                      if (s.Equals(key))
                      {
                          found = true;
                          break;
                      }
                  }
                  Assert.IsTrue(found, s + " was not read from the file");
              }
          }
  
          // @cdk.bug 682233
          [TestMethod()]
          public void TestBug682233()
          {
              var filename = "NCDK.Data.MDL.bug682233.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
  
              Assert.IsNotNull(chemFile);
              Assert.AreEqual(1, chemFile.Count);
              var seq = chemFile[0];
              Assert.IsNotNull(seq);
              Assert.AreEqual(1, seq.Count);
              var model = seq[0];
              Assert.IsNotNull(model);
  
              var som = model.MoleculeSet;
              Assert.IsNotNull(som);
              Assert.AreEqual(1, som.Count);
              IAtomContainer m = som[0];
              Assert.IsNotNull(m);
              Assert.AreEqual(4, m.Atoms.Count);
              Assert.AreEqual(2, m.Bonds.Count);
  
              // test reading of formal charges
              IAtom a = m.Atoms[0];
              Assert.IsNotNull(a);
              Assert.AreEqual("Na", a.Symbol);
              Assert.AreEqual(1, a.FormalCharge.Value);
              a = m.Atoms[2];
              Assert.IsNotNull(a);
              Assert.AreEqual("O", a.Symbol);
              Assert.AreEqual(-1, a.FormalCharge.Value);
          }
  
          [TestMethod()]
          public void TestAPinene()
          {
              var filename = "NCDK.Data.MDL.a-pinene.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestReadingMISOLines()
          {
              var filename = "NCDK.Data.MDL.ChEBI_37340.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.AreEqual(210, containersList[0].Atoms[0].MassNumber.Value);
          }
  
          // @cdk.bug 2234820
          [TestMethod()]
          public void TestMassNumber()
          {
              var filename = "NCDK.Data.MDL.massnumber.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.AreEqual(3, containersList[0].Atoms.Count);
              Assert.AreEqual(2, containersList[0].Atoms[1].MassNumber.Value);
              Assert.AreEqual(3, containersList[0].Atoms[2].MassNumber.Value);
          }
  
          [TestMethod()]
          public void TestAlkane()
          {
              var filename = "NCDK.Data.MDL.shortest_path_test.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              IAtomContainer container = containersList[0];
              Assert.AreEqual(10, container.Atoms.Count);
              Assert.AreEqual(9, container.Bonds.Count);
              foreach (var atom in container.Atoms)
                  Assert.AreEqual("C", atom.Symbol);
              foreach (var bond in container.Bonds)
                  Assert.AreEqual(BondOrder.Single, bond.Order);
          }
  
          [TestMethod()]
          public void TestReadTitle()
          {
              var filename = "NCDK.Data.MDL.a-pinene.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.AreEqual("a-pinen.mol", mol.Title);
          }
  
          [TestMethod()]
          public void TestFourRing()
          {
              var filename = "NCDK.Data.MDL.four-ring-5x10.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestHydrozyamino()
          {
              var filename = "NCDK.Data.MDL.hydroxyamino.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestMethylBenzol()
          {
              var filename = "NCDK.Data.MDL.methylbenzol.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestPolycarpol()
          {
              var filename = "NCDK.Data.MDL.polycarpol.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestReserpine()
          {
              var filename = "NCDK.Data.MDL.reserpine.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestSixRing()
          {
              var filename = "NCDK.Data.MDL.six-ring-4x4.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestSuperspiro()
          {
              var filename = "NCDK.Data.MDL.superspiro.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestGhemicalOutput()
          {
              var filename = "NCDK.Data.MDL.butanoic_acid.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue(containersList[0].Atoms.Count > 0);
              Assert.IsTrue(containersList[0].Bonds.Count > 0);
          }
  
          [TestMethod()]
          public void TestUsesGivenMolecule()
          {
              var filename = "NCDK.Data.MDL.superspiro.mol"; // just a random file
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var superspiro = builder.NewAtomContainer();
              superspiro.Id = "superspiro";
              var result = reader.Read(superspiro);
              reader.Close();
              Assert.AreEqual(superspiro.Id, result.Id);
          }
  
          // @cdk.bug 835571
          [TestMethod()]
          public void TestReadFromStringReader()
          {
              var mdl = "cyclopropane.mol\n" + "\n" + "\n" + "  9  9  0  0  0                 1 V2000\n"
                      + "   -0.0073   -0.5272    0.9655 C   0  0  0  0  0\n"
                      + "   -0.6776   -0.7930   -0.3498 C   0  0  0  0  0\n"
                      + "    0.2103    0.4053   -0.1891 C   0  0  0  0  0\n"
                      + "    0.8019   -1.1711    1.2970 H   0  0  0  0  0\n"
                      + "   -0.6000   -0.2021    1.8155 H   0  0  0  0  0\n"
                      + "   -1.7511   -0.6586   -0.4435 H   0  0  0  0  0\n"
                      + "   -0.3492   -1.6277   -0.9620 H   0  0  0  0  0\n"
                      + "    1.1755    0.4303   -0.6860 H   0  0  0  0  0\n"
                      + "   -0.2264    1.3994   -0.1675 H   0  0  0  0  0\n" + "  1  2  1  6  0  0\n"
                      + "  1  3  1  6  0  0\n" + "  1  4  1  0  0  0\n" + "  1  5  1  1  0  0\n" + "  2  3  1  0  0  0\n"
                      + "  2  6  1  0  0  0\n" + "  2  7  1  6  0  0\n" + "  3  8  1  6  0  0\n" + "  3  9  1  0  0  0\n"
                      + "M  END\n";
              var reader = new MDLV2000Reader(new StringReader(mdl));
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              Assert.AreEqual(1, chemFile.Count);
              var seq = chemFile[0];
              Assert.IsNotNull(seq);
              Assert.AreEqual(1, seq.Count);
              var model = seq[0];
              Assert.IsNotNull(model);
  
              var som = model.MoleculeSet;
              Assert.IsNotNull(som);
              Assert.AreEqual(1, som.Count);
              IAtomContainer m = som[0];
              Assert.IsNotNull(m);
              Assert.AreEqual(9, m.Atoms.Count);
              Assert.AreEqual(9, m.Bonds.Count);
          }
  
          [TestMethod()]
          public void TestRGroup()
          {
              var filename = "NCDK.Data.MDL.SARGROUPTEST.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.AreEqual("R2", ((IPseudoAtom)mol.Atoms[19]).Label);
          }
  
          [TestMethod()]
          public void TestAliasPropertyGroup()
          {
              var filename = "NCDK.Data.MDL.AliasPropertyRGroup.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              IAtom atom = mol.Atoms[0];
              Assert.IsTrue(atom is IPseudoAtom);
              Assert.AreEqual("R\\1", ((IPseudoAtom)atom).Label);
          }
  
          // @cdk.bug 1587283
          [TestMethod()]
          public void TestBug1587283()
          {
              var filename = "NCDK.Data.MDL.bug1587283.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.AreEqual(15, containersList[0].Atoms.Count);
              Assert.AreEqual(16, containersList[0].Bonds.Count);
          }
  
          [TestMethod()]
          public void TestReadProton()
          {
              var mdl = "proton.mol\n" + "\n" + "\n" + "  1  0  0  0  0                 1 V2000\n"
                      + "   -0.0073   -0.5272    0.9655 H   0  0  0  0  0\n" + "M  CHG  1   1   1\n" + "M  END\n";
              var reader = new MDLV2000Reader(new StringReader(mdl));
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(1, mol.Atoms.Count);
              Assert.AreEqual(0, mol.Bonds.Count);
              Assert.AreEqual(1, AtomContainerManipulator.GetTotalFormalCharge(mol));
              IAtom atom = mol.Atoms[0];
              Assert.AreEqual(1, atom.FormalCharge.Value);
          }
  
          [TestMethod()]
          public void TestReadingCharges()
          {
              var filename = "NCDK.Data.MDL.withcharges.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              IAtomContainer container = chemFile[0][0].MoleculeSet[0];
              Assert.AreEqual(1, container.Atoms[6].FormalCharge.Value);
              Assert.AreEqual(-1, container.Atoms[8].FormalCharge.Value);
          }
  
          [TestMethod()]
          public void TestEmptyString()
          {
              var emptyString = "";
              var reader = new MDLV2000Reader(new StringReader(emptyString));
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNull(mol);
          }
  
          [TestMethod()]
          public void TestNoAtomCase()
          {
              var filename = "NCDK.Data.MDL.emptyStructure.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
  
              IAtomContainer container = containersList[0];
              Assert.IsNotNull(container);
              Assert.AreEqual(0, container.Atoms.Count);
              Assert.AreEqual(0, container.Bonds.Count);
  
              var props = container.GetProperties();
              var keys = props.Keys;
  
              Assert.IsTrue(keys.Contains("SubstanceType"));
              Assert.IsTrue(keys.Contains("TD50 Rat"));
              Assert.IsTrue(keys.Contains("ChemCount"));
          }
  
          // @cdk.bug 1732307
          [TestMethod()]
          public void TestZeroZCoordinates()
          {
              var filename = "NCDK.Data.MDL.nozcoord.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var prop = new NameValueCollection
              {
                  ["ForceReadAs3DCoordinates"] = "true"
              };
              PropertiesListener listener = new PropertiesListener(prop);
              reader.Listeners.Add(listener);
              reader.CustomizeJob();
  
              IAtomContainer mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(5, mol.Atoms.Count);
  
              bool has3d = GeometryUtil.Has3DCoordinates(mol);
              Assert.IsTrue(has3d);
          }
  
          // @cdk.bug 1732307 
          [TestMethod()]
          public void TestZeroZCoordinates3DMarked()
          {
              var filename = "NCDK.Data.MDL.nozcoord.sdf";
              Trace.TraceInformation("Testing: " + filename);
              var ins = this.GetType().Assembly.GetManifestResourceStream(filename);
              var reader = new MDLV2000Reader(ins);
              IAtomContainer mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(5, mol.Atoms.Count);
  
              bool has3d = GeometryUtil.Has3DCoordinates(mol);
              Assert.IsTrue(has3d);
          }
  
          // @cdk.bug 1826577
          [TestMethod()]
          public void TestHIsotopes_Strict()
          {
              var filename = "NCDK.Data.MDL.hisotopes.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              try
              {
                  var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
                  reader.Read(builder.NewChemFile());
                  reader.Close();
                  Assert.Fail("Expected a CDKException");
              }
              catch (CDKException)
              {
                  // OK, that's what's is supposed to happen
              }
              catch (IOException)
              {
                  // OK, that's what's is supposed to happen
              }
          }
  
          // @cdk.bug 1826577
          [TestMethod()]
          public void TestHIsotopes_Relaxed()
          {
              var filename = "NCDK.Data.MDL.hisotopes.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Relaxed);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.IsNotNull(containersList[0]);
              Assert.IsFalse((containersList[0]).Atoms[1] is IPseudoAtom);
              Assert.IsFalse((containersList[0]).Atoms[2] is IPseudoAtom);
          }
  
          [TestMethod()]
          public void TestReadRadical()
          {
              var filename = "NCDK.Data.MDL.332727182.radical.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              Assert.IsTrue((containersList[0]).Atoms.Count > 0);
              Assert.IsTrue((containersList[0]).Bonds.Count > 0);
              Assert.IsTrue((containersList[0]).SingleElectrons.Count > 0);
          }
  
          // @cdk.bug 2604888
          [TestMethod()]
          public void TestNoCoordinates()
          {
              var mdl = "cyclopropane.mol\n" + "\n" + "\n" + "  9  9  0  0  0 0 0 0 0 0 0 0 0 1 V2000\n"
                      + "    0.0000    0.0000    0.0000 C   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 C   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 C   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n"
                      + "    0.0000    0.0000    0.0000 H   0  0  0  0  0\n" + "  1  2  1  6  0  0\n"
                      + "  1  3  1  6  0  0\n" + "  1  4  1  0  0  0\n" + "  1  5  1  1  0  0\n" + "  2  3  1  0  0  0\n"
                      + "  2  6  1  0  0  0\n" + "  2  7  1  6  0  0\n" + "  3  8  1  6  0  0\n" + "  3  9  1  0  0  0\n"
                      + "M  END\n";
              var reader = new MDLV2000Reader(new StringReader(mdl));
              var molecule = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(molecule);
              Assert.AreEqual(9, molecule.Atoms.Count);
              Assert.AreEqual(9, molecule.Bonds.Count);
              foreach (var atom in molecule.Atoms)
              {
                  Assert.IsNull(atom.Point2D);
                  Assert.IsNull(atom.Point2D);
              }
          }
  
          [TestMethod()]
          public void TestUndefinedStereo()
          {
              var filename = "NCDK.Data.MDL.ChEBI_26120.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.AreEqual(BondStereo.EOrZ, mol.Bonds[1].Stereo);
              Assert.AreEqual(BondStereo.EOrZ, mol.Bonds[6].Stereo);
              Assert.AreEqual(BondStereo.EOrZ, mol.Bonds[7].Stereo);
              Assert.AreEqual(BondStereo.EOrZ, mol.Bonds[11].Stereo);
          }
  
          [TestMethod()]
          public void TestUndefinedStereo2()
          {
              var filename = "NCDK.Data.MDL.a-pinene-with-undefined-stereo.mol";
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.AreEqual(BondStereo.UpOrDown, mol.Bonds[1].Stereo);
          }
  
          /// <summary>
          /// Tests that the '0' read from the bond block for bond stereo
          /// is read is 'no stereochemistry involved'.
          /// </summary>
          [TestMethod()]
          public void TestStereoReadZeroDefault()
          {
              var filename = "NCDK.Data.MDL.withcharges.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              IAtomContainer container = containersList[0];
              Assert.AreEqual(BondStereo.None, container.Bonds[0].Stereo);
          }
  
          [TestMethod()]
          public void TestReadStereoBonds()
          {
              var mdl = "cyclopropane.mol\n" + "\n" + "\n" + "  9  9  0  0  0                 1 V2000\n"
                      + "   -0.0073   -0.5272    0.9655 C   0  0  0  0  0\n"
                      + "   -0.6776   -0.7930   -0.3498 C   0  0  0  0  0\n"
                      + "    0.2103    0.4053   -0.1891 C   0  0  0  0  0\n"
                      + "    0.8019   -1.1711    1.2970 H   0  0  0  0  0\n"
                      + "   -0.6000   -0.2021    1.8155 H   0  0  0  0  0\n"
                      + "   -1.7511   -0.6586   -0.4435 H   0  0  0  0  0\n"
                      + "   -0.3492   -1.6277   -0.9620 H   0  0  0  0  0\n"
                      + "    1.1755    0.4303   -0.6860 H   0  0  0  0  0\n"
                      + "   -0.2264    1.3994   -0.1675 H   0  0  0  0  0\n" + "  1  2  1  6  0  0\n"
                      + "  1  3  1  6  0  0\n" + "  1  4  1  0  0  0\n" + "  1  5  1  1  0  0\n" + "  2  3  1  0  0  0\n"
                      + "  2  6  1  0  0  0\n" + "  2  7  1  6  0  0\n" + "  3  8  1  6  0  0\n" + "  3  9  1  0  0  0\n"
                      + "M  END\n";
              var reader = new MDLV2000Reader(new StringReader(mdl));
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(9, mol.Atoms.Count);
              Assert.AreEqual(9, mol.Bonds.Count);
              Assert.AreEqual(BondStereo.Down, mol.Bonds[0].Stereo);
              Assert.AreEqual(BondStereo.Up, mol.Bonds[3].Stereo);
          }
  
          [TestMethod()]
          public void TestStereoDoubleBonds()
          {
              var filename = "NCDK.Data.MDL.butadiene.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              var chemFile = reader.Read(builder.NewChemFile());
              reader.Close();
              Assert.IsNotNull(chemFile);
              var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile).ToReadOnlyList();
              Assert.AreEqual(1, containersList.Count);
              IAtomContainer container = containersList[0];
              Assert.AreEqual(BondStereo.EZByCoordinates, container.Bonds[0].Stereo);
              Assert.AreEqual(BondStereo.EOrZ, container.Bonds[2].Stereo);
          }
  
          /// <summary>
          /// Tests numbering of R# elements according to RGP line.
          /// </summary>
          [TestMethod()]
          public void TestRGroupHashNumbering()
          {
              var filename = "NCDK.Data.MDL.rgroups.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              foreach (var bond in mol.Bonds)
              {
                  IPseudoAtom rGroup = null;
                  IAtom partner = null;
                  if (bond.Atoms[0] is IPseudoAtom)
                  {
                      rGroup = (IPseudoAtom)bond.Begin;
                      partner = bond.End;
                  }
                  else
                  {
                      partner = bond.Begin;
                      rGroup = (IPseudoAtom)bond.End;
                  }
                  if (partner.Symbol.Equals("N"))
                  {
                      Assert.AreEqual(rGroup.Label, "R4");
                  }
                  else if (partner.Symbol.Equals("P"))
                  {
                      Assert.AreEqual(rGroup.Label, "R1");
                  }
                  else if (partner.Symbol.Equals("As"))
                  {
                      Assert.AreEqual(rGroup.Label, "R4");
                  }
                  else if (partner.Symbol.Equals("Si"))
                  {
                      Assert.AreEqual(rGroup.Label, "R");
                  }
              }
          }
  
          /// <summary>
          /// Test for hard coded R-group numbers in the Atom block.
          /// Hard coding is accepted but should not be done really, instead use
          /// a hash (#) conform the CTFile spec.
          /// </summary>
          [TestMethod()]
          public void TestRGroupHardcodedNumbering()
          {
              var filename = "NCDK.Data.MDL.rgroupsNumbered.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              IAtomContainer mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              foreach (var bond in mol.Bonds)
              {
                  IPseudoAtom rGroup;
                  if (bond.Atoms[0] is IPseudoAtom)
                      rGroup = (IPseudoAtom)bond.Begin;
                  else
                      rGroup = (IPseudoAtom)bond.End;
  
                  if (bond.Order == BondOrder.Double)
                  {
                      Assert.AreEqual(rGroup.Label, "R32");
                  }
                  else if (bond.Stereo == BondStereo.Down)
                  {
                      Assert.AreEqual(rGroup.Label, "R2");
                  }
                  else if (bond.Stereo == BondStereo.Up)
                  {
                      Assert.AreEqual(rGroup.Label, "R20");
                  }
                  else
                      Assert.AreEqual(rGroup.Label, "R5");
              }
          }
  
          [TestMethod()]
          public void TestReadValence()
          {
              var filename = "NCDK.Data.MDL.a-pinene-with-valence.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
  
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(2, mol.Atoms[0].Valency.Value);
              Assert.AreEqual(3, mol.Atoms[1].Valency.Value);
              Assert.AreNotEqual(0, mol.Atoms[2].Valency);
              Assert.AreEqual(4, mol.Atoms[2].Valency);
              Assert.AreEqual(0, mol.Atoms[3].Valency.Value);
          }
  
          [TestMethod()]
          public void TestShortLines()
          {
              Trace.TraceInformation("Testing short lines ChemObjectReaderModes.Relaxed");
              TestShortLinesForMode(ChemObjectReaderMode.Relaxed);
              Trace.TraceInformation("Testing short lines ChemObjectReaderModes.Strict");
              TestShortLinesForMode(ChemObjectReaderMode.Strict);
          }
  
          private void TestShortLinesForMode(ChemObjectReaderMode mode)
          {
              var filename = "NCDK.Data.MDL.glycine-short-lines.mol";
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, mode);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(mol.Atoms.Count, 5);
              Assert.AreEqual(mol.Bonds.Count, 4);
          }
  
          [TestMethod()]
          public void TestReadAtomAtomMapping()
          {
              var filename = "NCDK.Data.MDL.a-pinene-with-atom-atom-mapping.mol";
              Trace.TraceInformation("Testing: " + filename);
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              var mol = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(mol);
              Assert.AreEqual(1, (int)mol.Atoms[0].GetProperty<int>(CDKPropertyName.AtomAtomMapping));
              Assert.AreEqual(15, (int)mol.Atoms[1].GetProperty<int>(CDKPropertyName.AtomAtomMapping));
              Assert.IsNull(mol.Atoms[2].GetProperty<int?>(CDKPropertyName.AtomAtomMapping));
          }
  
          // @cdk.bug 2936440
          [TestMethod()]
          public void TestHas2DCoordinates_With000()
          {
              var filenameMol = "NCDK.Data.MDL.with000coordinate.mol";
              var ins = ResourceLoader.GetAsStream(filenameMol);
              IAtomContainer molOne = null;
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict);
              molOne = reader.Read(builder.NewAtomContainer());
              reader.Close();
              Assert.IsNotNull(molOne.Atoms[0].Point2D);
              Assert.IsNotNull(molOne.Atoms[0].Point3D);
          }
  
          [TestMethod()]
          public void TestAtomValueLines()
          {
              var filename = "NCDK.Data.MDL.atomValueLines.mol";
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins);
              IAtomContainer testMolecule = builder.NewAtomContainer();
              IAtomContainer result = reader.Read(testMolecule);
              reader.Close();
              IAtom oxygen = result.Atoms[0];
              Assert.IsTrue(oxygen.Symbol.Equals("O"));
              Assert.AreEqual(oxygen.GetProperty<string>(CDKPropertyName.Comment), "Oxygen comment");
          }
  
          [TestMethod()]
          public void TestDeuterium()
          {
              var filename = "NCDK.Data.MDL.chemblMolregno5369.mol";
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Relaxed);
  
              var prop = new NameValueCollection
              {
                  ["InterpretHydrogenIsotopes"] = "true"
              };
              PropertiesListener listener = new PropertiesListener(prop);
              reader.Listeners.Add(listener);
              reader.CustomizeJob();
  
              var molecule = builder.NewAtomContainer();
              molecule = reader.Read(molecule);
              reader.Close();
              int deuteriumCount = 0;
              foreach (var atom in molecule.Atoms)
                  if (atom.Symbol.Equals("H") && atom.MassNumber != null && atom.MassNumber == 2)
                      deuteriumCount++;
              Assert.AreEqual(3, deuteriumCount);
          }
  
          [TestMethod()]
          public void TestDeuteriumProperties()
          {
              var filename = "NCDK.Data.MDL.chemblMolregno5369.mol";
              var ins = ResourceLoader.GetAsStream(filename);
              var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Relaxed);
              var molecule = builder.NewAtomContainer();
              molecule = reader.Read(molecule);
              reader.Close();
              IAtom deuterium = molecule.Atoms[molecule.Atoms.Count - 1];
              Assert.IsTrue(1 == deuterium.AtomicNumber);
              Assert.IsTrue(2 == deuterium.MassNumber);
          }
  
          [TestMethod()]
          public void TestTritium()
          {
              var filename = "NCDK.Data.MDL.chemblMolregno7039.mol";
              var ins = ResourceLoader.GetAsStream(filename);
  
gt:             var reader = new MDLV2000Reader(ins);