private final ZSamplePoint<TZ> closeSample(int x, int y) {
   ZSamplePoint<TZ> A = sampleGrid.getOrCreate(x, y);
   A.setZ(
       metric.closeSample(
           A.up() != null ? A.up().getZ() : null,
           A.down() != null ? A.down().getZ() : null,
           A.right() != null ? A.right().getZ() : null,
           A.left() != null ? A.left().getZ() : null));
   return A;
 }
 /** Surround all existing samples on the edge by a layer of closing samples. */
 public final void close() {
   if (closed) return;
   closed = true;
   List<ZSamplePoint<TZ>> processList = new ArrayList<ZSamplePoint<TZ>>(sampleGrid.size());
   for (ZSamplePoint<TZ> A : sampleGrid) {
     processList.add(A);
   }
   int n = 0;
   for (int i = 0; i < 2; i++) {
     List<ZSamplePoint<TZ>> newProcessList = new ArrayList<ZSamplePoint<TZ>>(processList.size());
     for (ZSamplePoint<TZ> A : processList) {
       if (A.right() == null) {
         newProcessList.add(closeSample(A.getX() + 1, A.getY()));
         n++;
       }
       if (A.left() == null) {
         newProcessList.add(closeSample(A.getX() - 1, A.getY()));
         n++;
       }
       if (A.up() == null) {
         newProcessList.add(closeSample(A.getX(), A.getY() + 1));
         n++;
       }
       if (A.down() == null) {
         newProcessList.add(closeSample(A.getX(), A.getY() - 1));
         n++;
       }
     }
     processList = newProcessList;
   }
   LOG.info("Added {} closing samples to get a total of {}.", n, sampleGrid.size());
 }