class ChiPathDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor {

    @Override
    public DescriptorValue calculate(IAtomContainer container) {
        if (sp == null) sp = new SmilesParser(container.getBuilder());

        IAtomContainer localAtomContainer = AtomContainerManipulator.removeHydrogens(container);
        CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(container.getBuilder());
        Iterator<IAtom> atoms = localAtomContainer.atoms().iterator();
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            IAtomType type;
            try {
                type = matcher.findMatchingAtomType(localAtomContainer, atom);
                AtomTypeManipulator.configure(atom, type);
            } catch (Exception e) {
                return getDummyDescriptorValue(new CDKException("Error in atom typing: " + e.getMessage()));
            }
        }
        CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(container.getBuilder());
        try {
            hAdder.addImplicitHydrogens(localAtomContainer);
        } catch (CDKException e) {
            return getDummyDescriptorValue(new CDKException("Error in hydrogen addition: " + e.getMessage()));
        }

        try {
            List<List<Integer>> subgraph0 = order0(localAtomContainer);
            List<List<Integer>> subgraph1 = order1(localAtomContainer);
            List<List<Integer>> subgraph2 = order2(localAtomContainer);
            List<List<Integer>> subgraph3 = order3(localAtomContainer);
            List<List<Integer>> subgraph4 = order4(localAtomContainer);
            List<List<Integer>> subgraph5 = order5(localAtomContainer);
            List<List<Integer>> subgraph6 = order6(localAtomContainer);
            List<List<Integer>> subgraph7 = order7(localAtomContainer);

            double order0s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph0);
            double order1s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph1);
            double order2s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph2);
            double order3s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph3);
            double order4s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph4);
            double order5s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph5);
            double order6s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph6);
            double order7s = ChiIndexUtils.evalSimpleIndex(localAtomContainer, subgraph7);

            double order0v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph0);
            double order1v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph1);
            double order2v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph2);
            double order3v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph3);
            double order4v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph4);
            double order5v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph5);
            double order6v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph6);
            double order7v = ChiIndexUtils.evalValenceIndex(localAtomContainer, subgraph7);

            DoubleArrayResult retval = new DoubleArrayResult();
            retval.add(order0s);
            retval.add(order1s);
            retval.add(order2s);
            retval.add(order3s);
            retval.add(order4s);
            retval.add(order5s);
            retval.add(order6s);
            retval.add(order7s);

            retval.add(order0v);
            retval.add(order1v);
            retval.add(order2v);
            retval.add(order3v);
            retval.add(order4v);
            retval.add(order5v);
            retval.add(order6v);
            retval.add(order7v);

            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval,
                    getDescriptorNames());
        } catch (CDKException e) {
            return getDummyDescriptorValue(new CDKException(e.getMessage()));
        }

    }

    public  ChiPathDescriptor();

}