Obtain a subset of the vertices which can contribute {@code electrons}
and are allowed to be involved in an aromatic system.

@param electrons electron contribution
@return vertices which can be involved in an aromatic system
18274
private static int[] subset(final int[] electrons) {
        int[] vs = new int[electrons.length];
        int n = 0;

        for (int i = 0; i < electrons.length; i++)
            if (electrons[i] >= 0) vs[n++] = i;

        return Arrays.copyOf(vs, n);
    }
25356
def edges
      vertices.map { |vert| vert.successors.map { |succ| [vert, succ] }}.flatten 1
    end
527638
@Override
  public Set<EndpointPair<N>> edges() {
    return new AbstractSet<EndpointPair<N>>() {
      @Override
      public UnmodifiableIterator<EndpointPair<N>> iterator() {
        return EndpointPairIterator.of(AbstractGraph.this);
      }

      @Override
      public int size() {
        return Ints.saturatedCast(edgeCount());
      }

      @Override
      public boolean contains(@Nullable Object obj) {
        if (!(obj instanceof EndpointPair)) {
          return false;
        }
        EndpointPair<?> endpointPair = (EndpointPair<?>) obj;
        return isDirected() == endpointPair.isOrdered()
            && nodes().contains(endpointPair.nodeU())
            && successors(endpointPair.nodeU()).contains(endpointPair.nodeV());
      }
    };
  }
859580
public ConceptLattice asConceptLattice(final Graph graph) {
        ConceptLattice lattice = new ConceptLattice(graph, attributes.size());
        
        Iterator it = this.asCrossTable().iterator();
        while(it.hasNext()) {
            CrossTable.Row row = (CrossTable.Row) it.next();
            lattice.insert(row.asConcept(attributes.size()));
        }
        
        return lattice;
    }
1254626
private static CyclicVertexSearch makeSearcher(int[][] graph) {

        if (graph == null) throw new NullPointerException("graph[][] must not be null");

        // if the molecule has 64 or less atoms we can use single 64 bit long
        // values to represent our sets of vertices
        if (graph.length <= 64) {
            return new RegularCyclicVertexSearch(graph);
        } else {
            return new JumboCyclicVertexSearch(graph);
        }
    }
749202
private List<Pair<Integer, Integer>> doGenerateEdgesSimpler() {
        final int numberOfNodes = getConfiguration().getNumberOfNodes();
        final long numberOfEdges = getConfiguration().getNumberOfEdges();

        final Set<Pair<Integer, Integer>> edges = new HashSet<>();

        while (edges.size() < numberOfEdges) {
            int origin = random.nextInt(numberOfNodes);
            int target = random.nextInt(numberOfNodes);

            if (target == origin) {
                continue;
            }

            edges.add(Pair.of(origin, target));
        }

        return new LinkedList<>(edges);
    }
94072
private static void addGeometricConfiguration(IDoubleBondStereochemistry dbs, int flavour, GraphBuilder gb, Map<IAtom, Integer> indices) {

        IBond db = dbs.getStereoBond();
        IBond[] bs = dbs.getBonds();

        // don't try to set a configuration on aromatic bonds
        if (SmiFlavor.isSet(flavour, SmiFlavor.UseAromaticSymbols) && db.getFlag(CDKConstants.ISAROMATIC)) return;

        int u = indices.get(db.getBegin());
        int v = indices.get(db.getEnd());

        // is bs[0] always connected to db.atom(0)?
        int x = indices.get(bs[0].getOther(db.getBegin()));
        int y = indices.get(bs[1].getOther(db.getEnd()));

        if (dbs.getStereo() == TOGETHER) {
            gb.geometric(u, v).together(x, y);
        } else {
            gb.geometric(u, v).opposite(x, y);
        }
    }
1131363
public static <K, VV, EV> Graph<K, VV, EV> fromCollection(Collection<Vertex<K, VV>> vertices,
			Collection<Edge<K, EV>> edges, ExecutionEnvironment context) {

		return fromDataSet(context.fromCollection(vertices),
				context.fromCollection(edges), context);
	}
1149890
public <K, EV> Graph<K, NullValue, EV> edgeTypes(Class<K> vertexKey, Class<EV> edgeValue) {

		if (edgeReader == null) {
			throw new RuntimeException("The edge input file cannot be null!");
		}

		DataSet<Tuple3<K, K, EV>> edges = edgeReader
			.types(vertexKey, vertexKey, edgeValue)
				.name(GraphCsvReader.class.getName());

		return Graph.fromTupleDataSet(edges, executionContext);
	}
320410
public static IAtomContainerSet getAllMolecules(IReaction reaction) {
        IAtomContainerSet moleculeSet = reaction.getBuilder().newInstance(IAtomContainerSet.class);

        moleculeSet.add(getAllReactants(reaction));
        moleculeSet.add(getAllAgents(reaction));
        moleculeSet.add(getAllProducts(reaction));

        return moleculeSet;
    }
702984
public static IAtomContainerSet getAllProducts(IReaction reaction) {
        IAtomContainerSet moleculeSet = reaction.getBuilder().newInstance(IAtomContainerSet.class);
        IAtomContainerSet products = reaction.getProducts();
        for (int i = 0; i < products.getAtomContainerCount(); i++) {
            moleculeSet.addAtomContainer(products.getAtomContainer(i));
        }
        return moleculeSet;
    }
104383
private void addDoubleBondStereochemistry(Graph g, IAtomContainer ac) {

        for (final Edge e : g.edges()) {

            if (e.bond() != Bond.DOUBLE) continue;

            int u = e.either();
            int v = e.other(u);

            // find a directional bond for either end
            Edge first  = null;
            Edge second = null;

            // if either atom is not incident to a directional label there
            // is no configuration
            if ((first = findDirectionalEdge(g, u)) != null) {
                if ((second = findDirectionalEdge(g, v)) != null) {

                    // if the directions (relative to the double bond) are the
                    // same then they are on the same side - otherwise they
                    // are opposite
                    Conformation conformation = first.bond(u) == second.bond(v) ?
                                                Conformation.TOGETHER : Conformation.OPPOSITE;

                    // get the stereo bond and build up the ligands for the
                    // stereo-element - linear search could be improved with
                    // map or API change to double bond element
                    IBond db = ac.getBond(ac.getAtom(u), ac.getAtom(v));

                    IBond[] ligands = new IBond[]{
                        ac.getBond(ac.getAtom(u), ac.getAtom(first.other(u))),
                        ac.getBond(ac.getAtom(v), ac.getAtom(second.other(v)))};

                    ac.addStereoElement(new DoubleBondStereochemistry(db, ligands, conformation));
                } else if (g.degree(v) == 2) {
                    List<Edge> edges = new ArrayList<>();
                    edges.add(e);
                    Edge f = findCumulatedEdge(g, v, e);
                    while (f != null) {
                        edges.add(f);
                        v = f.other(v);
                        f = findCumulatedEdge(g, v, f);
                    }
                    // only odd number of cumulated bonds here, otherwise is
                    // extended tetrahedral
                    if ((edges.size() & 0x1) == 0)
                        continue;
                    second = findDirectionalEdge(g, v);
                    if (second != null) {
                        int   cfg        = first.bond(u) == second.bond(v)
                                           ? IStereoElement.TOGETHER
                                           : IStereoElement.OPPOSITE;
                        Edge  middleEdge = edges.get(edges.size()/2);
                        IBond middleBond = ac.getBond(ac.getAtom(middleEdge.either()),
                                                      ac.getAtom(middleEdge.other(middleEdge.either())));
                        IBond[] ligands = new IBond[]{
                            ac.getBond(ac.getAtom(u), ac.getAtom(first.other(u))),
                            ac.getBond(ac.getAtom(v), ac.getAtom(second.other(v)))};

                        ac.addStereoElement(new ExtendedCisTrans(middleBond, ligands, cfg));
                    }
                }
            }
            // extension F[C@]=[C@@]F
            else {
                Configuration uConf = g.configurationOf(u);
                Configuration vConf = g.configurationOf(v);
                if (uConf.type() == Configuration.Type.DoubleBond &&
                    vConf.type() == Configuration.Type.DoubleBond) {

                    int[] nbrs = new int[6];
                    int[] uNbrs = g.neighbors(u);
                    int[] vNbrs = g.neighbors(v);

                    if (uNbrs.length < 2 || uNbrs.length > 3)
                        continue;
                    if (vNbrs.length < 2 || vNbrs.length > 3)
                        continue;

                    int idx   = 0;
                    System.arraycopy(uNbrs, 0, nbrs, idx, uNbrs.length);
                    idx += uNbrs.length;
                    if (uNbrs.length == 2) nbrs[idx++] = u;
                    System.arraycopy(vNbrs, 0, nbrs, idx, vNbrs.length);
                    idx += vNbrs.length;
                    if (vNbrs.length == 2) nbrs[idx] = v;
                    Arrays.sort(nbrs, 0, 3);
                    Arrays.sort(nbrs, 3, 6);

                    int vPos = Arrays.binarySearch(nbrs, 0, 3, v);
                    int uPos = Arrays.binarySearch(nbrs, 3, 6, u);

                    int uhi = 0, ulo = 0;
                    int vhi = 0, vlo = 0;

                    uhi = nbrs[(vPos + 1) % 3];
                    ulo = nbrs[(vPos + 2) % 3];
                    vhi = nbrs[3 + ((uPos + 1) % 3)];
                    vlo = nbrs[3 + ((uPos + 2) % 3)];

                    if (uConf.shorthand() == Configuration.CLOCKWISE) {
                        int tmp = uhi;
                        uhi = ulo;
                        ulo = tmp;
                    }
                    if (vConf.shorthand() == Configuration.ANTI_CLOCKWISE) {
                        int tmp = vhi;
                        vhi = vlo;
                        vlo = tmp;
                    }

                    DoubleBondStereochemistry.Conformation conf = null;
                    IBond[] bonds = new IBond[2];

                    if (uhi != u) {
                        bonds[0] = ac.getBond(ac.getAtom(u), ac.getAtom(uhi));
                        if (vhi != v) {
                            // System.err.println(uhi + "\\=/" + vhi);
                            conf = Conformation.TOGETHER;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vhi));
                        } else if (vlo != v) {
                            // System.err.println(uhi + "\\=\\" + vlo);
                            conf = Conformation.OPPOSITE;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vlo));
                        }
                    } else if (ulo != u) {
                        bonds[0] = ac.getBond(ac.getAtom(u), ac.getAtom(ulo));
                        if (vhi != v) {
                            // System.err.println(ulo + "/=/" + vhi);
                            conf = Conformation.OPPOSITE;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vhi));
                        } else if (vlo != v) {
                            // System.err.println(ulo + "/=\\" + vlo);
                            conf = Conformation.TOGETHER;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vlo));
                        }
                    }

                    ac.addStereoElement(new DoubleBondStereochemistry(ac.getBond(ac.getAtom(u), ac.getAtom(v)),
                                                                      bonds,
                                                                      conf));
                }
            }
        }
    }
507586
public List<IntArrayList> findComponents() {
        int nodes = graph.getNodes();
        for (int start = 0; start < nodes; start++) {
            if (nodeIndex[start] == 0
                    && !ignoreSet.contains(start)
                    && !graph.isNodeRemoved(start))
                strongConnect(start);
        }

        return components;
    }
685600
private static <T> void addDependencies(final Vertex<T> vertex, final List<Vertex<T>> vertices)
    {
        if (!vertices.contains(vertex))
        {
            vertices.add(vertex);

            for (Vertex<T> v : vertex.getDependencies())
            {
                addDependencies(v, vertices);
            }
        }
    }
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;
    }
804495
@Override
    public Iterable<Vertex> vertices() {
        GraphCentricQuery query = constructQuery(ElementCategory.VERTEX);
        return Iterables.filter(new QueryProcessor<>(query, tx.elementProcessor), Vertex.class);
    }
915670
public boolean hasOutEdges() {
		final Set<ODocument> docs = document.field(OGraphDatabase.VERTEX_FIELD_OUT);
		return docs != null && !docs.isEmpty();
	}