public void testStoreNoSolutionState() {

    Set<PairInt> points = getSet0();

    BitVectorRepresentation bvr = new BitVectorRepresentation(points);

    PairInt currentXY = points.iterator().next();
    Set<PairInt> availableMoves = new HashSet<PairInt>();

    for (int i = (currentXY.getX() - 1); i <= (currentXY.getX() + 1); ++i) {
      for (int j = (currentXY.getY() - 1); j <= (currentXY.getY() + 1); ++j) {
        PairInt p = new PairInt(i, j);
        if (p.equals(currentXY)) {
          continue;
        }
        availableMoves.add(p);
      }
    }
    Set<PairInt> visited = new HashSet<PairInt>();
    int nVisited = 10;
    for (PairInt p : points) {
      if (p.equals(currentXY) || availableMoves.contains(p)) {
        continue;
      }
      visited.add(p);
      if (visited.size() == nVisited) {
        break;
      }
    }

    VeryLongBitString totalVisitedBitVector = bvr.createBitstring(visited);

    PathStep step = new PathStep(currentXY, availableMoves, totalVisitedBitVector);

    LinkedList<PathStep> path = new LinkedList<PathStep>();
    path.add(step);

    PerimeterFinderMemo memo = new PerimeterFinderMemo();

    memo.storeNoSolutionState(path);

    PathStep stepCopy = step.copy();

    assertTrue(memo.isANoSolutionState(stepCopy));

    availableMoves.remove(availableMoves.iterator().next());
    PathStep step2 = new PathStep(currentXY, availableMoves, bvr.createBitstring(visited));
    assertFalse(memo.isANoSolutionState(step2));

    visited.remove(visited.iterator().next());
    step2 = new PathStep(currentXY, availableMoves, bvr.createBitstring(visited));
    assertFalse(memo.isANoSolutionState(step2));
  }
  /**
   * count the values in the image and return as a frequency map. useful for images where the total
   * number of numbers present is small and one doesn't want to lose number resolution by creating a
   * histogram.
   *
   * @param points
   * @param img
   * @return map with key = pixel value, and map value is count of pixels with the pixel value of
   *     the key
   */
  public static Map<Integer, Integer> createAFrequencyMap(Set<PairInt> points, GreyscaleImage img) {

    Map<Integer, Integer> freqMap = new HashMap<Integer, Integer>();

    for (PairInt p : points) {

      int x = p.getX();
      int y = p.getY();

      Integer v = Integer.valueOf(img.getValue(x, y));

      Integer c = freqMap.get(v);

      if (c == null) {
        freqMap.put(v, Integer.valueOf(1));
      } else {
        c = Integer.valueOf(c.intValue() + 1);
        freqMap.put(v, c);
      }
    }

    return freqMap;
  }
  @Override
  protected void calculateColors(
      final Set<PairInt> points, ImageExt colorImage, int xOffset, int yOffset) {

    super.calculateColors(points, colorImage, xOffset, yOffset);

    float n = points.size();

    float sumCIEX = 0;
    float sumCIEY = 0;

    float sumLuma = 0;

    int i = 0;

    for (PairInt p : points) {

      int x = p.getX() + xOffset;
      int y = p.getY() + yOffset;
      int idx = colorImage.getInternalIndex(x, y);

      sumCIEX += colorImage.getCIEX(idx);
      sumCIEY += colorImage.getCIEY(idx);

      sumLuma += colorImage.getLuma(idx);

      i++;
    }

    avgCIEX = sumCIEX / n;
    avgCIEY = sumCIEY / n;
    avgLuma = sumLuma / n;

    float sumContrast = 0;
    float[] contrast = new float[points.size()];

    double sumStdDevCIEX = 0;
    double sumStdDevCIEY = 0;
    double sumStdDevLuma = 0;

    i = 0;
    for (PairInt p : points) {

      int x = p.getX() + xOffset;
      int y = p.getY() + yOffset;
      int idx = colorImage.getInternalIndex(x, y);

      float cieX = colorImage.getCIEX(idx);
      float cieY = colorImage.getCIEY(idx);
      float luma = colorImage.getLuma(idx);

      float diffCIEX = cieX - avgCIEX;
      float diffCIEY = cieY - avgCIEY;
      float diffLuma = luma - avgLuma;
      sumStdDevCIEX += (diffCIEX * diffCIEX);
      sumStdDevCIEY += (diffCIEY * diffCIEY);
      sumStdDevLuma += (diffLuma * diffLuma);

      contrast[i] = (avgLuma - luma) / luma;
      sumContrast += contrast[i];

      i++;
    }

    avgContrast = sumContrast / n;

    stdDevCIEX = (n > 1) ? (float) Math.sqrt(sumStdDevCIEX / (n - 1)) : Float.POSITIVE_INFINITY;
    stdDevCIEY = (n > 1) ? (float) Math.sqrt(sumStdDevCIEY / (n - 1)) : Float.POSITIVE_INFINITY;

    stdDevLuma = (n > 1) ? (float) Math.sqrt(sumStdDevLuma / (n - 1)) : Float.POSITIVE_INFINITY;

    double sumStdDevContrast = 0;

    for (i = 0; i < points.size(); i++) {
      float diffContrast = contrast[i] - avgContrast;
      sumStdDevContrast += (diffContrast * diffContrast);
    }

    stdDevContrast =
        (n > 1) ? (float) Math.sqrt(sumStdDevContrast / (n - 1)) : Float.POSITIVE_INFINITY;
  }