public static IReadOnlyList <IAtomContainer> PartitionIntoMolecules(IAtomContainer container, int[] components) { int maxComponentIndex = 0; foreach (int component in components) { if (component > maxComponentIndex) { maxComponentIndex = component; } } var containers = new IAtomContainer[maxComponentIndex + 1]; var componentsMap = new Dictionary <IAtom, IAtomContainer>(2 * container.Atoms.Count); for (int i = 1; i < containers.Length; i++) { containers[i] = container.Builder.NewAtomContainer(); } for (int i = 0; i < container.Atoms.Count; i++) { componentsMap.Add(container.Atoms[i], containers[components[i]]); containers[components[i]].Atoms.Add(container.Atoms[i]); } foreach (var bond in container.Bonds) { var begComp = componentsMap[bond.Begin]; var endComp = componentsMap[bond.End]; if (begComp == endComp) { begComp.Bonds.Add(bond); } } foreach (var electron in container.SingleElectrons) { componentsMap[electron.Atom].SingleElectrons.Add(electron); } foreach (var lonePair in container.LonePairs) { componentsMap[lonePair.Atom].LonePairs.Add(lonePair); } foreach (var stereo in container.StereoElements) { var focus = stereo.Focus; switch (focus) { case IAtom atom: if (componentsMap.ContainsKey(atom)) { componentsMap[atom].StereoElements.Add(stereo); } break; case IBond bond: if (componentsMap.ContainsKey(bond.Begin)) { componentsMap[bond.Begin].StereoElements.Add(stereo); } break; default: throw new InvalidOperationException("New stereo element not using an atom/bond for focus?"); } } // do not return IEnumerable, containers are modified above. var containerSet = new List <IAtomContainer>(containers.Skip(1)); return(containerSet); }