Generate a bond type code for a given atom. The bond code
can be quickly tested to count the number of single, double,
or 'other' bonds.

@param idx the atom idx
@return bond code
190882
private int getBondTypes(int idx) {
        int btypes = container.getAtom(idx).getImplicitHydrogenCount();
        for (int end : graph[idx]) {
            IBond bond = edgeToBond.get(idx, end);
            if (bond.getOrder() == SINGLE)
                btypes += 0x00_0001;
            else if (bond.getOrder() == DOUBLE)
                btypes += 0x00_0100;
            else // other bond types
                btypes += 0x01_0000;
        }
        return btypes;
    }
1051940
public IDescriptorResult getCachedDescriptorValue(IAtom atom) {
        if (cachedDescriptorValues == null) return null;
        return (IDescriptorResult) cachedDescriptorValues.get(atom);
    }
190830
private static int getDoubleBondNumber(IAtomContainer container) {
        int doubleNumber = 0;
        for (IBond bond : container.bonds()) {
            if (bond.getOrder().equals(IBond.Order.DOUBLE) || bond.getOrder().equals(IBond.Order.TRIPLE))
                doubleNumber++;
        }
        return doubleNumber;
    }
802872
@Override
    public List<IBond> getConnectedBondsList(IAtom atom) {
        List<IBond> bondsList = new ArrayList<IBond>();
        for (int i = 0; i < bondCount; i++) {
            if (bonds[i].contains(atom)) bondsList.add(bonds[i]);
        }
        return bondsList;
    }
1367916
@Override
    public DescriptorValue calculate(IBond bond, IAtomContainer atomContainer) {
        double value = 0;
        // FIXME: for now I'll cache a few modified atomic properties, and restore them at the end of this method
        String originalAtomtypeName1 = bond.getBegin().getAtomTypeName();
        Integer originalNeighborCount1 = bond.getBegin().getFormalNeighbourCount();
        IAtomType.Hybridization originalHybridization1 = bond.getBegin().getHybridization();
        Integer originalValency1 = bond.getBegin().getValency();
        String originalAtomtypeName2 = bond.getEnd().getAtomTypeName();
        Integer originalNeighborCount2 = bond.getEnd().getFormalNeighbourCount();
        IAtomType.Hybridization originalHybridization2 = bond.getEnd().getHybridization();
        Integer originalValency2 = bond.getEnd().getValency();
        Double originalBondOrderSum1 = bond.getBegin().getBondOrderSum();
        Order originalMaxBondOrder1 = bond.getBegin().getMaxBondOrder();
        Double originalBondOrderSum2 = bond.getEnd().getBondOrderSum();
        Order originalMaxBondOrder2 = bond.getEnd().getMaxBondOrder();

        if (!isCachedAtomContainer(atomContainer)) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(atomContainer);
                LonePairElectronChecker lpcheck = new LonePairElectronChecker();
                lpcheck.saturate(atomContainer);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }

        }
        if (!bond.getOrder().equals(IBond.Order.SINGLE)) {
            try {
                value = IonizationPotentialTool.predictIP(atomContainer, bond);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }
        bond.getBegin().setAtomTypeName(originalAtomtypeName1);
        bond.getBegin().setHybridization(originalHybridization1);
        bond.getBegin().setValency(originalValency1);
        bond.getBegin().setFormalNeighbourCount(originalNeighborCount1);
        bond.getEnd().setAtomTypeName(originalAtomtypeName2);
        bond.getEnd().setHybridization(originalHybridization2);
        bond.getEnd().setValency(originalValency2);
        bond.getEnd().setFormalNeighbourCount(originalNeighborCount2);
        bond.getBegin().setMaxBondOrder(originalMaxBondOrder1);
        bond.getBegin().setBondOrderSum(originalBondOrderSum1);
        bond.getEnd().setMaxBondOrder(originalMaxBondOrder2);
        bond.getEnd().setBondOrderSum(originalBondOrderSum2);

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(value),
                DESCRIPTOR_NAMES);
    }
612533
private void encodeExpr(int idx, int bprev, StringBuilder sb) {
        avisit[idx] = numVisit++;
        sb.append(aexpr[idx]);
        final int d = deg[idx];

        int remain = d;
        for (int j = 0; j < d; j++) {
            int nbr = atomAdj[idx][j];
            int bidx = bondAdj[idx][j];

            // ring open/close
            if (rbnds[bidx] < 0) {
                // open
                final int rnum = chooseRingNumber();
                if (rnum > 9) sb.append('%');
                sb.append(rnum);
                rbnds[bidx] = rnum;
            } else if (rbnds[bidx] > 0) {
                // close
                final int rnum = rbnds[bidx];
                releaseRingNumber(rnum);
                if (rnum > 9) sb.append('%');
                sb.append(rnum);
            }

            if (mode == MODE_EXACT && avisit[nbr] == 0 ||
                bidx == bprev ||
                rbnds[bidx] != 0)
                remain--;
        }

        for (int j = 0; j < d; j++) {
            int nbr = atomAdj[idx][j];
            int bidx = bondAdj[idx][j];
            if (mode == MODE_EXACT && avisit[nbr] == 0 ||
                bidx == bprev ||
                rbnds[bidx] != 0)
                continue; // ignored
            remain--;
            if (avisit[nbr] == 0) {
                // peripheral bond
                if (remain > 0) sb.append('(');
                sb.append(bexpr[bidx]);
                sb.append(mol.getAtom(nbr).isAromatic() ? 'a' : '*');
                if (remain > 0) sb.append(')');
            } else {
                if (remain > 0) sb.append('(');
                sb.append(bexpr[bidx]);
                encodeExpr(nbr, bidx, sb);
                if (remain > 0) sb.append(')');
            }
        }
    }
930693
public Timex2 getTimex2(int i) {
    if (Document_Type.featOkTst && ((Document_Type)jcasType).casFeat_timex2 == null)
      jcasType.jcas.throwFeatMissing("timex2", "de.julielab.jules.types.ace.Document");
    jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Document_Type)jcasType).casFeatCode_timex2), i);
    return (Timex2)(jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Document_Type)jcasType).casFeatCode_timex2), i)));}
86127
private static Atomix buildAtomix(Namespace namespace) {
    return Atomix.builder(createConfig(namespace)).withShutdownHookEnabled().build();
  }
941590
public static <K extends Enum<K> & MultiKeyed> EnumLookup<K, String> of(
    		final Class<K> enumClass, final int idx, final boolean caseSensitive) {
        return new EnumLookup<K, String>(enumClass, idx, caseSensitive);
    }
1230137
public static <E> double dotProduct(Counter<E> c, double[] a, Index<E> idx) {
    double dotProd = 0;
    for (Map.Entry<E, Double> entry : c.entrySet()) {
      int keyIdx = idx.indexOf(entry.getKey());
      if (keyIdx == -1) {
        continue;
      }
      dotProd += entry.getValue() * a[keyIdx];
    }
    return dotProd;
  }
902444
protected void generateAtomContainerFromInchi(IChemObjectBuilder builder) throws CDKException {
        try {
            output = JniInchiWrapper.getStructureFromInchi(input);
        } catch (JniInchiException jie) {
            throw new CDKException("Failed to convert InChI to molecule: " + jie.getMessage(), jie);
        }

        //molecule = new AtomContainer();
        molecule = builder.newInstance(IAtomContainer.class);

        Map<JniInchiAtom, IAtom> inchiCdkAtomMap = new HashMap<JniInchiAtom, IAtom>();

        for (int i = 0; i < output.getNumAtoms(); i++) {
            JniInchiAtom iAt = output.getAtom(i);
            IAtom cAt = builder.newInstance(IAtom.class);

            inchiCdkAtomMap.put(iAt, cAt);

            cAt.setID("a" + i);
            cAt.setSymbol(iAt.getElementType());
            cAt.setAtomicNumber(PeriodicTable.getAtomicNumber(cAt.getSymbol()));

            // Ignore coordinates - all zero - unless aux info was given... but
            // the CDK doesn't have an API to provide that

            // InChI does not have unset properties so we set charge,
            // hydrogen count (implicit) and isotopic mass
            cAt.setFormalCharge(iAt.getCharge());
            cAt.setImplicitHydrogenCount(iAt.getImplicitH());
            int isotopicMass = iAt.getIsotopicMass();

            if (isotopicMass != 0) {
                if (ISOTOPIC_SHIFT_FLAG == (isotopicMass & ISOTOPIC_SHIFT_FLAG)) {
                    try {
                        int massNumber = Isotopes.getInstance().getMajorIsotope(cAt.getAtomicNumber()).getMassNumber();
                        cAt.setMassNumber(massNumber + (isotopicMass - ISOTOPIC_SHIFT_FLAG));
                    } catch (IOException e) {
                        throw new CDKException("Could not load Isotopes data", e);
                    }
                } else {
                    cAt.setMassNumber(isotopicMass);
                }
            }

            molecule.addAtom(cAt);
            cAt = molecule.getAtom(molecule.getAtomCount()-1);
            for (int j = 0; j < iAt.getImplicitDeuterium(); j++) {
                IAtom deut = builder.newInstance(IAtom.class);
                deut.setAtomicNumber(1);
                deut.setSymbol("H");
                deut.setMassNumber(2);
                deut.setImplicitHydrogenCount(0);
                molecule.addAtom(deut);
                deut = molecule.getAtom(molecule.getAtomCount()-1);
                IBond bond = builder.newInstance(IBond.class, cAt, deut, Order.SINGLE);
                molecule.addBond(bond);
            }
            for (int j = 0; j < iAt.getImplicitTritium(); j++) {
                IAtom trit = builder.newInstance(IAtom.class);
                trit.setAtomicNumber(1);
                trit.setSymbol("H");
                trit.setMassNumber(3);
                trit.setImplicitHydrogenCount(0);
                molecule.addAtom(trit);
                trit = molecule.getAtom(molecule.getAtomCount()-1);
                IBond bond = builder.newInstance(IBond.class, cAt, trit, Order.SINGLE);
                molecule.addBond(bond);
            }
        }

        for (int i = 0; i < output.getNumBonds(); i++) {
            JniInchiBond iBo = output.getBond(i);
            IBond cBo = builder.newInstance(IBond.class);

            IAtom atO = inchiCdkAtomMap.get(iBo.getOriginAtom());
            IAtom atT = inchiCdkAtomMap.get(iBo.getTargetAtom());
            IAtom[] atoms = new IAtom[2];
            atoms[0] = atO;
            atoms[1] = atT;
            cBo.setAtoms(atoms);

            INCHI_BOND_TYPE type = iBo.getBondType();
            if (type == INCHI_BOND_TYPE.SINGLE) {
                cBo.setOrder(Order.SINGLE);
            } else if (type == INCHI_BOND_TYPE.DOUBLE) {
                cBo.setOrder(Order.DOUBLE);
            } else if (type == INCHI_BOND_TYPE.TRIPLE) {
                cBo.setOrder(Order.TRIPLE);
            } else if (type == INCHI_BOND_TYPE.ALTERN) {
                cBo.setFlag(CDKConstants.ISAROMATIC, true);
            } else {
                throw new CDKException("Unknown bond type: " + type);
            }

            INCHI_BOND_STEREO stereo = iBo.getBondStereo();

            // No stereo definition
            if (stereo == INCHI_BOND_STEREO.NONE) {
                cBo.setStereo(IBond.Stereo.NONE);
            }
            // Bond ending (fat end of wedge) below the plane
            else if (stereo == INCHI_BOND_STEREO.SINGLE_1DOWN) {
                cBo.setStereo(IBond.Stereo.DOWN);
            }
            // Bond ending (fat end of wedge) above the plane
            else if (stereo == INCHI_BOND_STEREO.SINGLE_1UP) {
                cBo.setStereo(IBond.Stereo.UP);
            }
            // Bond starting (pointy end of wedge) below the plane
            else if (stereo == INCHI_BOND_STEREO.SINGLE_2DOWN) {
                cBo.setStereo(IBond.Stereo.DOWN_INVERTED);
            }
            // Bond starting (pointy end of wedge) above the plane
            else if (stereo == INCHI_BOND_STEREO.SINGLE_2UP) {
                cBo.setStereo(IBond.Stereo.UP_INVERTED);
            }
            // Bond with undefined stereochemistry
            else if (stereo == INCHI_BOND_STEREO.SINGLE_1EITHER || stereo == INCHI_BOND_STEREO.DOUBLE_EITHER) {
                cBo.setStereo((IBond.Stereo) CDKConstants.UNSET);
            }

            molecule.addBond(cBo);
        }

        for (int i = 0; i < output.getNumStereo0D(); i++) {
            JniInchiStereo0D stereo0d = output.getStereo0D(i);
            if (stereo0d.getStereoType() == INCHI_STEREOTYPE.TETRAHEDRAL
                    || stereo0d.getStereoType() == INCHI_STEREOTYPE.ALLENE) {
                JniInchiAtom central = stereo0d.getCentralAtom();
                JniInchiAtom[] neighbours = stereo0d.getNeighbors();

                IAtom focus = inchiCdkAtomMap.get(central);
                IAtom[] neighbors = new IAtom[]{inchiCdkAtomMap.get(neighbours[0]), inchiCdkAtomMap.get(neighbours[1]),
                        inchiCdkAtomMap.get(neighbours[2]), inchiCdkAtomMap.get(neighbours[3])};
                ITetrahedralChirality.Stereo stereo;

                // as per JNI InChI doc even is clockwise and odd is
                // anti-clockwise
                if (stereo0d.getParity() == INCHI_PARITY.ODD) {
                    stereo = ITetrahedralChirality.Stereo.ANTI_CLOCKWISE;
                } else if (stereo0d.getParity() == INCHI_PARITY.EVEN) {
                    stereo = ITetrahedralChirality.Stereo.CLOCKWISE;
                } else {
                    // CDK Only supports parities of + or -
                    continue;
                }

                IStereoElement stereoElement = null;

                if (stereo0d.getStereoType() == INCHI_STEREOTYPE.TETRAHEDRAL) {
                    stereoElement = builder.newInstance(ITetrahedralChirality.class, focus, neighbors, stereo);
                } else if (stereo0d.getStereoType() == INCHI_STEREOTYPE.ALLENE) {

                    // The periphals (p<i>) and terminals (t<i>) are refering to
                    // the following atoms. The focus (f) is also shown.
                    //
                    //   p0          p2
                    //    \          /
                    //     t0 = f = t1
                    //    /         \
                    //   p1         p3
                    IAtom[] peripherals = neighbors;
                    IAtom[] terminals = ExtendedTetrahedral.findTerminalAtoms(molecule, focus);

                    // InChI always provides the terminal atoms t0 and t1 as
                    // periphals, here we find where they are and then add in
                    // the other explicit atom. As the InChI create hydrogens
                    // for stereo elements, there will always we an explicit
                    // atom that can be found - it may be optionally suppressed
                    // later.

                    // not much documentation on this (at all) but they appear
                    // to always be the middle two atoms (index 1, 2) we therefore
                    // test these first - but handle the other indices just in
                    // case
                    for (IAtom terminal : terminals) {
                        if (peripherals[1].equals(terminal)) {
                            peripherals[1] = findOtherSinglyBonded(molecule, terminal, peripherals[0]);
                        } else if (peripherals[2].equals(terminal)) {
                            peripherals[2] = findOtherSinglyBonded(molecule, terminal, peripherals[3]);
                        } else if (peripherals[0].equals(terminal)) {
                            peripherals[0] = findOtherSinglyBonded(molecule, terminal, peripherals[1]);
                        } else if (peripherals[3].equals(terminal)) {
                            peripherals[3] = findOtherSinglyBonded(molecule, terminal, peripherals[2]);
                        }
                    }

                    stereoElement = new ExtendedTetrahedral(focus, peripherals, stereo);
                }

                assert stereoElement != null;
                molecule.addStereoElement(stereoElement);
            } else if (stereo0d.getStereoType() == INCHI_STEREOTYPE.DOUBLEBOND) {
                JniInchiAtom[] neighbors = stereo0d.getNeighbors();

                // from JNI InChI doc
                //                            neighbor[4]  : {#X,#A,#B,#Y} in this order
                // X                          central_atom : NO_ATOM
                //  \            X        Y   type         : INCHI_StereoType_DoubleBond
                //   A == B       \      /
                //         \       A == B
                //          Y
                IAtom x = inchiCdkAtomMap.get(neighbors[0]);
                IAtom a = inchiCdkAtomMap.get(neighbors[1]);
                IAtom b = inchiCdkAtomMap.get(neighbors[2]);
                IAtom y = inchiCdkAtomMap.get(neighbors[3]);

                // XXX: AtomContainer is doing slow lookup
                IBond stereoBond = molecule.getBond(a, b);
                stereoBond.setAtoms(new IAtom[]{a, b}); // ensure a is first atom

                Conformation conformation = null;

                switch (stereo0d.getParity()) {
                    case ODD:
                        conformation = Conformation.TOGETHER;
                        break;
                    case EVEN:
                        conformation = Conformation.OPPOSITE;
                        break;
                }

                // unspecified not stored
                if (conformation == null) continue;

                molecule.addStereoElement(new DoubleBondStereochemistry(stereoBond, new IBond[]{molecule.getBond(x, a),
                        molecule.getBond(b, y)}, conformation));
            } else {
                // TODO - other types of atom parity - double bond, etc
            }
        }
    }
563174
private static int nStereoBonds(List<IBond> bonds) {
        int count = 0;
        for (IBond bond : bonds) {
            IBond.Stereo stereo = bond.getStereo();
            switch (stereo) {
            // query bonds... no configuration possible
                case E_OR_Z:
                case UP_OR_DOWN:
                case UP_OR_DOWN_INVERTED:
                    return -1;
                case UP:
                case DOWN:
                case UP_INVERTED:
                case DOWN_INVERTED:
                    count++;
                    break;
            }
        }
        return count;
    }
360034
public double[] prepareNode(IAtomContainer atomContainer) {
        double nodeSequence[] = new double[atomContainer.getAtomCount()];
        int i = 0;
        for (IAtom atom : atomContainer.atoms()) {
            String symbol = atom.getSymbol();

            List<IBond> bonds = atomContainer.getConnectedBondsList(atom);
            if (bonds.size() == 1) {
                IBond bond0 = bonds.get(0);
                IBond.Order order = bond0.getOrder();
                if (symbol.equals("C")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 1;// CH3-
                    else if (order == IBond.Order.DOUBLE)
                        nodeSequence[i] = 3;// CH2=
                    else if (order == IBond.Order.TRIPLE) nodeSequence[i] = 6;// CH#
                } else if (symbol.equals("O")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 14;// HO-
                    else if (order == IBond.Order.DOUBLE) nodeSequence[i] = 16;// O=
                    // missing the case of an aromatic double bond
                } else if (symbol.equals("N")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 18;// NH2-
                    else if (order == IBond.Order.DOUBLE) {
                        if (atom.getCharge() == -1.0)
                            nodeSequence[i] = 27;// N= contains -1 charge
                        else
                            nodeSequence[i] = 20;// NH=
                    } else if (order == IBond.Order.TRIPLE) nodeSequence[i] = 23;// N#
                } else if (symbol.equals("S")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 31;// HS-
                    else if (order == IBond.Order.DOUBLE) nodeSequence[i] = 33;// S=
                } else if (symbol.equals("P"))
                    nodeSequence[i] = 38;// PH2-
                else if (symbol.equals("F"))
                    nodeSequence[i] = 42;// F-
                else if (symbol.equals("Cl"))
                    nodeSequence[i] = 43;// Cl-
                else if (symbol.equals("Br"))
                    nodeSequence[i] = 44;// Br-
                else if (symbol.equals("I"))
                    nodeSequence[i] = 45;// I-
                else {
                    logger.debug("in case of a new node, please " + "report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 2) {
                IBond bond0 = (IBond) bonds.get(0);
                IBond bond1 = (IBond) bonds.get(1);
                IBond.Order order0 = bond0.getOrder();
                IBond.Order order1 = bond1.getOrder();
                if (symbol.equals("C")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 2;// -CH2-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 10;// =C=
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE))
                        nodeSequence[i] = 5;// -CH=
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.TRIPLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 9;// -C#
                    // case 3 would not allow to reach this statement as there
                    // is no aromatic bond order
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 11;// ArCH
                } else if (symbol.equals("N")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 19;// -NH-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 28;// =N= with charge=-1
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE))
                        nodeSequence[i] = 22;// -N=
                    else if ((order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 26;// =N#
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 29;// -N# with charge=+1
                    // case 3 would not allow to reach this statement as there
                    // is no aromatic bond order
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 30;// ArN
                    // there is no way to distinguish between ArNH and ArN as
                    // bonds to protons are not considered
                } else if (symbol.equals("O")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 15;// -O-
                    else if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 17;// ArO
                } else if (symbol.equals("S")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 32;// -S-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 35;// =S=
                    else if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 37;// ArS
                } else if (symbol.equals("P")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE) nodeSequence[i] = 39;// -PH-
                } else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 3) {
                IBond bond0 = (IBond) bonds.get(0);
                IBond bond1 = (IBond) bonds.get(1);
                IBond bond2 = (IBond) bonds.get(2);
                IBond.Order order0 = bond0.getOrder();
                IBond.Order order1 = bond1.getOrder();
                IBond.Order order2 = bond2.getOrder();

                if (symbol.equals("C")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 4;// >C-
                    else if (order0 == IBond.Order.DOUBLE || order1 == IBond.Order.DOUBLE
                            || order2 == IBond.Order.DOUBLE) nodeSequence[i] = 8;// >C=
                    // case 2 would not allow to reach this statement because
                    // there is always a double bond (pi system) around an
                    // aromatic atom
                    if ((bond0.getFlag(CDKConstants.ISAROMATIC) || bond1.getFlag(CDKConstants.ISAROMATIC) || bond2
                            .getFlag(CDKConstants.ISAROMATIC))
                            && (order0 == IBond.Order.SINGLE || order1 == IBond.Order.SINGLE || bond2.getOrder() == IBond.Order.SINGLE))
                        nodeSequence[i] = 12;// ArC-
                    // case 3 would not allow to reach this statement
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC)
                            && bond2.getFlag(CDKConstants.ISAROMATIC)) nodeSequence[i] = 13;// ArC
                } else if (symbol.equals("N")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 21;// >N-
                    else if (order0 == IBond.Order.SINGLE || order1 == IBond.Order.SINGLE
                            || order2 == IBond.Order.SINGLE) nodeSequence[i] = 25;// -N(=)=
                } else if (symbol.equals("S")) {
                    if (order0 == IBond.Order.DOUBLE || order1 == IBond.Order.DOUBLE || order2 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 34;// >S=
                } else if (symbol.equals("P")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 40;// >P-
                } else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 4) {
                if (atom.getSymbol().equals("C"))
                    nodeSequence[i] = 7;// >C<
                else if (atom.getSymbol().equals("N"))
                    nodeSequence[i] = 24;// >N(=)-
                else if (atom.getSymbol().equals("S"))
                    nodeSequence[i] = 36;// >S(=)=
                else if (atom.getSymbol().equals("P"))
                    nodeSequence[i] = 41;// =P<-
                else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            }
            i++;
        }
        return nodeSequence;
    }
1005835
public IDescriptorResult getCachedDescriptorValue(IBond bond) {
        if (cachedDescriptorValues == null) return null;
        return (IDescriptorResult) cachedDescriptorValues.get(bond);
    }
827816
static IAtomContainer apply(IAtomContainer container) {

        int n = container.getAtomCount();

        int[] valences = new int[n];

        Map<IAtom, Integer> atomToIndex = Maps.newHashMapWithExpectedSize(n);
        for (IAtom atom : container.atoms())
            atomToIndex.put(atom, atomToIndex.size());

        // compute the bond order sums
        for (IBond bond : container.bonds()) {
            int u = atomToIndex.get(bond.getBegin());
            int v = atomToIndex.get(bond.getEnd());

            int bondOrder = bond.getOrder().numeric();

            valences[u] += bondOrder;
            valences[v] += bondOrder;
        }

        for (int i = 0; i < n; i++) {

            IAtom atom = container.getAtom(i);
            Integer charge = atom.getFormalCharge();
            Integer element = atom.getAtomicNumber();

            if (element == null) continue;

            // unset = 0 in this case
            charge = charge == null ? 0 : charge;

            int explicit = valences[i];

            // if there was a valence read from the mol file use that otherwise
            // use the default value from the valence model to set the correct
            // number of implied hydrogens
            if (atom.getValency() != null) {
                atom.setImplicitHydrogenCount(atom.getValency() - explicit);
            } else {
                int implicit = implicitValence(element, charge, valences[i]);
                atom.setImplicitHydrogenCount(implicit - explicit);
                atom.setValency(implicit);
            }
        }

        return container;
    }
1371333
private static BitSet available(int[][] graph, IAtom[] atoms, EdgeToBondMap bonds) {

        final BitSet available = new BitSet();

        // for all atoms, select those that require a double-bond
        ATOMS: for (int i = 0; i < atoms.length; i++) {

            final IAtom atom = atoms[i];

            // preconditions
            if (atom.getAtomicNumber() == null)
                throw new IllegalArgumentException("atom " + (i + 1) + " had unset atomic number");
            if (atom.getFormalCharge() == null)
                throw new IllegalArgumentException("atom " + (i + 1) + " had unset formal charge");
            if (atom.getImplicitHydrogenCount() == null)
                throw new IllegalArgumentException("atom " + (i + 1) + " had unset implicit hydrogen count");

            if (!atom.getFlag(ISAROMATIC)) continue;

            // count preexisting pi-bonds, a higher bond order causes a skip
            int nPiBonds = 0;
            for (final int w : graph[i]) {
                IBond.Order order = bonds.get(i, w).getOrder();
                if (order == DOUBLE) {
                    nPiBonds++;
                } else if (order.numeric() > 2) {
                    continue ATOMS;
                }
            }

            // check if a pi bond can be assigned
            final int element = atom.getAtomicNumber();
            final int charge = atom.getFormalCharge();
            final int valence = graph[i].length + atom.getImplicitHydrogenCount() + nPiBonds;

            if (available(element, charge, valence)) {
                available.set(i);
            }
        }

        return available;
    }
1191855
private int getDoubleBondedOxygenCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        IBond bond;
        int odbcounter = 0;
        boolean chargeFlag = false;
        if (atom.getFormalCharge() >= 1) {
            chargeFlag = true;
        }
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("O")) {
                bond = ac.getBond(neighbour, atom);
                if (chargeFlag && neighbour.getFormalCharge() == -1 && bond.getOrder() == IBond.Order.SINGLE) {
                    odbcounter += 1;
                }
                if (!neighbour.getFlag(CDKConstants.ISAROMATIC)) {
                    if (bond.getOrder() == IBond.Order.DOUBLE) {
                        odbcounter += 1;
                    }
                }
            }
        }
        return odbcounter;
    }