Helper method determines if a bond is defined (not null) and whether it
is a sigma (single) bond with no stereo attribute (wedge/hatch).

@param bond the bond to test
@return the bond is a planar sigma bond
188885
private static boolean isPlanarSigmaBond(IBond bond) {
        return bond != null &&
                IBond.Order.SINGLE.equals(bond.getOrder()) &&
                IBond.Stereo.NONE.equals(bond.getStereo());
    }
1011874
public boolean newSaturate(IBond[] bonds, IAtomContainer atomContainer) throws CDKException {
        logger.debug("Saturating bond set of size: " + bonds.length);
        boolean bondsAreFullySaturated = true;
        if (bonds.length > 0) {
            IBond bond = bonds[0];

            // determine bonds left
            int leftBondCount = bonds.length - 1;
            IBond[] leftBonds = new IBond[leftBondCount];
            System.arraycopy(bonds, 1, leftBonds, 0, leftBondCount);

            // examine this bond
            if (isUnsaturated(bond, atomContainer)) {
                // either this bonds should be saturated or not

                // try to leave this bond unsaturated and saturate the left bondssaturate this bond
                if (leftBondCount > 0) {
                    logger.debug("Recursing with unsaturated bond with #bonds: " + leftBondCount);
                    bondsAreFullySaturated = newSaturate(leftBonds, atomContainer)
                            && !isUnsaturated(bond, atomContainer);
                } else {
                    bondsAreFullySaturated = false;
                }

                // ok, did it work? if not, saturate this bond, and recurse
                if (!bondsAreFullySaturated) {
                    logger.debug("First try did not work...");
                    // ok, revert saturating this bond, and recurse again
                    boolean couldSaturate = newSaturate(bond, atomContainer);
                    if (couldSaturate) {
                        if (leftBondCount > 0) {
                            logger.debug("Recursing with saturated bond with #bonds: " + leftBondCount);
                            bondsAreFullySaturated = newSaturate(leftBonds, atomContainer);
                        } else {
                            bondsAreFullySaturated = true;
                        }
                    } else {
                        bondsAreFullySaturated = false;
                        // no need to recurse, because we already know that this bond
                        // unsaturated does not work
                    }
                }
            } else if (isSaturated(bond, atomContainer)) {
                logger.debug("This bond is already saturated.");
                if (leftBondCount > 0) {
                    logger.debug("Recursing with #bonds: " + leftBondCount);
                    bondsAreFullySaturated = newSaturate(leftBonds, atomContainer);
                } else {
                    bondsAreFullySaturated = true;
                }
            } else {
                logger.debug("Cannot saturate this bond");
                // but, still recurse (if possible)
                if (leftBondCount > 0) {
                    logger.debug("Recursing with saturated bond with #bonds: " + leftBondCount);
                    bondsAreFullySaturated = newSaturate(leftBonds, atomContainer)
                            && !isUnsaturated(bond, atomContainer);
                } else {
                    bondsAreFullySaturated = !isUnsaturated(bond, atomContainer);
                }
            }
        }
        logger.debug("Is bond set fully saturated?: " + bondsAreFullySaturated);
        logger.debug("Returning to level: " + (bonds.length + 1));
        return bondsAreFullySaturated;
    }
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;
    }
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;
    }
737546
private List<Integer[]> getAtomNoPairsForRingGroup(IAtomContainer molecule, List<Integer> bondsToCheck) {
        List<Integer[]> aptc = new ArrayList<Integer[]>();
        for (Integer i : bondsToCheck) {
            Integer[] aps = new Integer[2];
            aps[0] = molecule.indexOf(molecule.getBond(i).getBegin());
            aps[1] = molecule.indexOf(molecule.getBond(i).getEnd());
            aptc.add(aps);
        }
        return aptc;
    }
235831
private static String getCommonSymbol(IBond bondA, IBond bondB) {
        String symbol = "";

        if (bondA.contains(bondB.getBegin())) {
            symbol = bondB.getBegin().getSymbol();
        } else if (bondA.contains(bondB.getEnd())) {
            symbol = bondB.getEnd().getSymbol();
        }

        return symbol;
    }
972305
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        int hBondAcceptors = 0;

        IAtomContainer ac;
        try {
            ac = (IAtomContainer) atomContainer.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(e);
        }

        // aromaticity is detected prior to descriptor calculation if the respective parameter is set to true

        if (checkAromaticity) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(ac);
                Aromaticity.cdkLegacy().apply(ac);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }

        //org.openscience.cdk.interfaces.IAtom[] atoms = ac.getAtoms();
        // labelled for loop to allow for labelled continue statements within the loop
        atomloop: for (IAtom atom : ac.atoms()) {
            // looking for suitable nitrogen atoms
            if (atom.getSymbol().equals("N") && atom.getFormalCharge() <= 0) {

                // excluding nitrogens that are adjacent to an oxygen
                List<IBond> bonds = ac.getConnectedBondsList(atom);
                int nPiBonds = 0;
                for (IBond bond : bonds) {
                    if (bond.getOther(atom).getSymbol().equals("O")) continue atomloop;
                    if (IBond.Order.DOUBLE.equals(bond.getOrder())) nPiBonds++;
                }

                // if the nitrogen is aromatic and there are no pi bonds then it's
                // lone pair cannot accept any hydrogen bonds
                if (atom.getFlag(CDKConstants.ISAROMATIC) && nPiBonds == 0) continue;

                hBondAcceptors++;
            }
            // looking for suitable oxygen atoms
            else if (atom.getSymbol().equals("O") && atom.getFormalCharge() <= 0) {
                //excluding oxygens that are adjacent to a nitrogen or to an aromatic carbon
                List<IBond> neighbours = ac.getConnectedBondsList(atom);
                for (IBond bond : neighbours) {
                    IAtom neighbor = bond.getOther(atom);
                    if (neighbor.getSymbol().equals("N") ||
                        (neighbor.getSymbol().equals("C") &&
                         neighbor.isAromatic() &&
                         bond.getOrder() != IBond.Order.DOUBLE))
                        continue atomloop;;
                }
                hBondAcceptors++;
            }
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                hBondAcceptors), getDescriptorNames());
    }
43900
@Override
    public boolean isSaturated(IAtom atom, IAtomContainer ac) throws CDKException {
        IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol());
        if (atomTypes.length == 0) return true;
        double bondOrderSum = ac.getBondOrderSum(atom);
        IBond.Order maxBondOrder = ac.getMaximumBondOrder(atom);
        Integer hcount = atom.getImplicitHydrogenCount() == CDKConstants.UNSET ? 0 : atom.getImplicitHydrogenCount();
        Integer charge = atom.getFormalCharge() == CDKConstants.UNSET ? 0 : atom.getFormalCharge();
        try {
            logger.debug("*** Checking saturation of atom ", atom.getSymbol(), "" + ac.indexOf(atom) + " ***");
            logger.debug("bondOrderSum: " + bondOrderSum);
            logger.debug("maxBondOrder: " + maxBondOrder);
            logger.debug("hcount: " + hcount);
        } catch (Exception exc) {
            logger.debug(exc);
        }
        for (int f = 0; f < atomTypes.length; f++) {
            if (bondOrderSum - charge + hcount == atomTypes[f].getBondOrderSum()
                    && !BondManipulator.isHigherOrder(maxBondOrder, atomTypes[f].getMaxBondOrder())) {
                logger.debug("*** Good ! ***");
                return true;
            }
        }
        logger.debug("*** Bad ! ***");
        return false;
    }
342346
public static IBond deref(IBond bond) {
        while (bond instanceof BondRef)
            bond = ((BondRef) bond).deref();
        return bond;
    }
710816
@Override
    public boolean matches(IBond bond) {
        if (bond.isAromatic() ^ isAromatic()) return false;

        // we check for both bonds being aromatic - but the query will
        // never come in as aromatic (since there is a separate aromatic
        // query bond). But no harm in checking
        return bond.isAromatic() || bond.getOrder() == getOrder();
    }
424360
def remove_bond(self, idx1, idx2):
        
        for obbond in ob.OBMolBondIter(self._obmol):
            if (obbond.GetBeginAtomIdx() == idx1 and obbond.GetEndAtomIdx() == idx2) or (obbond.GetBeginAtomIdx() == idx2 and obbond.GetEndAtomIdx() == idx1):
                self._obmol.DeleteBond(obbond)
341700
public IAtom getOtherBondAtom(IAtom atom, IBond bond) {
        if (!bond.contains(atom)) return null;
        if (bond.getBegin().equals(atom))
            return bond.getEnd();
        else
            return bond.getBegin();
    }
258605
private void addSelfToAtoms() {
		List<Bond> bonds = atomA.getBonds();
		if (bonds==null) {
			bonds = new ArrayList<Bond>(AtomImpl.BONDS_INITIAL_CAPACITY);
			atomA.setBonds(bonds);
		}

		boolean exists = false;
		for (Bond bond : bonds) {
			// TODO is it equals() what we want here, or is it == ? - JD 2016-03-02
			if (bond.getOther(atomA).equals(atomB)) {
				exists = true;
				break;
			}
		}
		if (!exists) {
			atomA.addBond(this);
			atomB.addBond(this);
		}
	}
985556
static public SimpleGraph getMoleculeGraph(IAtomContainer molecule) {
        SimpleGraph graph = new SimpleGraph();
        for (int i = 0; i < molecule.getAtomCount(); i++) {
            IAtom atom = molecule.getAtom(i);
            graph.addVertex(atom);
        }

        for (int i = 0; i < molecule.getBondCount(); i++) {
            IBond bond = molecule.getBond(i);

            /*
             * int order = (int) bond.getOrder(); for (int j=0; j<order; j++) {
             * graph.addEdge(bond.getAtoms()[0], bond.getAtoms()[1]); }
             */
            graph.addEdge(bond.getBegin(), bond.getEnd());
        }
        return graph;
    }
944229
private static boolean has3DCoordinates(List<IBond> bonds) {
        for (IBond bond : bonds) {
            if (bond.getBegin().getPoint3d() == null || bond.getEnd().getPoint3d() == null) return false;
        }
        return true;
    }
809629
private void bondAtom(IAtomContainer container, IAtom atom) {
        double myCovalentRadius = atom.getCovalentRadius();
        double searchRadius = myCovalentRadius + maxCovalentRadius + bondTolerance;
        Point tupleAtom = new Point(atom.getPoint3d().x, atom.getPoint3d().y, atom.getPoint3d().z);
        for (Bspt.EnumerateSphere e = bspt.enumHemiSphere(tupleAtom, searchRadius); e.hasMoreElements();) {
            IAtom atomNear = ((TupleAtom) e.nextElement()).getAtom();
            if (!atomNear.equals(atom) && container.getBond(atom, atomNear) == null) {
                boolean bonded = isBonded(myCovalentRadius, atomNear.getCovalentRadius(), e.foundDistance2());
                if (bonded) {
                    IBond bond = atom.getBuilder().newInstance(IBond.class, atom, atomNear, IBond.Order.SINGLE);
                    container.addBond(bond);
                }
            }
        }
    }
1070992
public static IBond.Stereo convertStereo(int stereoValue) {
        IBond.Stereo stereo = IBond.Stereo.NONE;
        if (stereoValue == 1) {
            // up bond
            stereo = IBond.Stereo.UP;
        } else if (stereoValue == 6) {
            // down bond
            stereo = IBond.Stereo.DOWN;
        } else if (stereoValue == 0) {
            // bond has no stereochemistry
            stereo = IBond.Stereo.NONE;
        } else if (stereoValue == 4) {
            //up or down bond
            stereo = IBond.Stereo.UP_OR_DOWN;
        } else if (stereoValue == 3) {
            //e or z undefined
            stereo = IBond.Stereo.E_OR_Z;
        }
        return stereo;
    }