/**
   * Choose any possible quadruple of the set of atoms in ac and establish all of the possible
   * bonding schemes according to Faulon's equations.
   */
  public static List sample(IMolecule ac) {
    logger.debug("RandomGenerator->mutate() Start");
    List structures = new ArrayList();

    int nrOfAtoms = ac.getAtomCount();
    double a11 = 0, a12 = 0, a22 = 0, a21 = 0;
    double b11 = 0, lowerborder = 0, upperborder = 0;
    double b12 = 0;
    double b21 = 0;
    double b22 = 0;
    double[] cmax = new double[4];
    double[] cmin = new double[4];
    IAtomContainer newAc = null;

    IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null;
    IBond b1 = null, b2 = null, b3 = null, b4 = null;
    // int[] choices = new int[3];
    /* We need at least two non-zero bonds in order to be successful */
    int nonZeroBondsCounter = 0;
    for (int x1 = 0; x1 < nrOfAtoms; x1++) {
      for (int x2 = x1 + 1; x2 < nrOfAtoms; x2++) {
        for (int y1 = x2 + 1; y1 < nrOfAtoms; y1++) {
          for (int y2 = y1 + 1; y2 < nrOfAtoms; y2++) {
            nonZeroBondsCounter = 0;
            ax1 = ac.getAtom(x1);
            ay1 = ac.getAtom(y1);
            ax2 = ac.getAtom(x2);
            ay2 = ac.getAtom(y2);

            /* Get four bonds for these four atoms */

            b1 = ac.getBond(ax1, ay1);
            if (b1 != null) {
              a11 = BondManipulator.destroyBondOrder(b1.getOrder());
              nonZeroBondsCounter++;
            } else {
              a11 = 0;
            }

            b2 = ac.getBond(ax1, ay2);
            if (b2 != null) {
              a12 = BondManipulator.destroyBondOrder(b2.getOrder());
              nonZeroBondsCounter++;
            } else {
              a12 = 0;
            }

            b3 = ac.getBond(ax2, ay1);
            if (b3 != null) {
              a21 = BondManipulator.destroyBondOrder(b3.getOrder());
              nonZeroBondsCounter++;
            } else {
              a21 = 0;
            }

            b4 = ac.getBond(ax2, ay2);
            if (b4 != null) {
              a22 = BondManipulator.destroyBondOrder(b4.getOrder());
              nonZeroBondsCounter++;
            } else {
              a22 = 0;
            }
            if (nonZeroBondsCounter > 1) {
              /* Compute the range for b11 (see Faulons formulae for details) */

              cmax[0] = 0;
              cmax[1] = a11 - a22;
              cmax[2] = a11 + a12 - 3;
              cmax[3] = a11 + a21 - 3;
              cmin[0] = 3;
              cmin[1] = a11 + a12;
              cmin[2] = a11 + a21;
              cmin[3] = a11 - a22 + 3;
              lowerborder = MathTools.max(cmax);
              upperborder = MathTools.min(cmin);
              for (b11 = lowerborder; b11 <= upperborder; b11++) {
                if (b11 != a11) {

                  b12 = a11 + a12 - b11;
                  b21 = a11 + a21 - b11;
                  b22 = a22 - a11 + b11;
                  logger.debug("Trying atom combination : " + x1 + ":" + x2 + ":" + y1 + ":" + y2);
                  try {
                    newAc = (IAtomContainer) ac.clone();
                    change(newAc, x1, y1, x2, y2, b11, b12, b21, b22);
                    if (ConnectivityChecker.isConnected(newAc)) {
                      structures.add(newAc);
                    } else {
                      logger.debug("not connected");
                    }
                  } catch (CloneNotSupportedException e) {
                    logger.error("Cloning exception: " + e.getMessage());
                    logger.debug(e);
                  }
                }
              }
            }
          }
        }
      }
    }
    return structures;
  }