final private boolean updateActiveLayer()
   {
      assert (update_list.size() == 0);
      
      //double total_change = 0;
      total_change = 0;
      num_updated = 0;
      
      final Iterator<BandElement> it = layers[ZERO_LAYER].iterator();
      while (it.hasNext())
      {
         final BandElement elem = it.next();
         final int x = elem.getX();
         final int y = elem.getY();
         final int z = elem.getZ();
         
         // get the delta Phi         
         final double delta_phi = getDeltaPhi(x, y, z);
                  
         // add absolute value of the net change of this voxel to the total change
         total_change += Math.abs(delta_phi);
         num_updated++;
         
         // Calculate Phi value of the voxel after an executed update
         final double temp_phi = phi.get(x, y, z) + delta_phi;
         
         if (temp_phi < INSIDE * PHI_THRESHOLD)
         {
            // Will move to the inside of the active set
            
            if (zeroLayerNeighbourMovement(x, y, z, ACTIVE_OUTSIDE))
            {
               //System.out.println("Called - zero layer neighbour movement");
               continue;
            }
            
            /* this node will move inside, so update outside neigbours as they will move
             into the zero set
             */
            updateZeroLayerNeighbours(x, y, z, ZERO_LAYER + OUTSIDE, temp_phi, update_list);
            
            it.remove();
            inside_list.add(elem);
            action.set(x, y, z, ACTIVE_INSIDE);
         }
         else if (temp_phi > OUTSIDE * PHI_THRESHOLD)
         {
            // Will move to the outside of the active set
            
            if (zeroLayerNeighbourMovement(x, y, z, ACTIVE_INSIDE))
            {
               //System.out.println("Called - zero layer neighbour movement");
               continue;
            }
            
            /* this node will move outside, so update inside neigbours as they will move
             into the zero set
             */
            updateZeroLayerNeighbours(x, y, z, ZERO_LAYER + INSIDE, temp_phi, update_list);
            
            it.remove();
            outside_list.add(elem);
            action.set(x, y, z, ACTIVE_OUTSIDE);
         }
         else
         {
            // stays in active set, schedule for update
            elem.setValue(temp_phi);
            update_list.add(elem);
         }
      }
      
      // All calculations are done, it is safe to do the updates now
      final Iterator<BandElement> it2 = update_list.iterator();
      while (it2.hasNext())
      {
         final BandElement elem = it2.next();
         // was queued more than once, only update one time so continue
         if (elem.getValue() == Double.MAX_VALUE) continue;
         
         // set the updated phi value
         phi.set(elem.getX(), elem.getY(), elem.getZ(), elem.getValue());         
         // tag the element so it is not updated again (would be expensive)
         elem.setValue(Double.MAX_VALUE);
      }
      
      // check for convergence
      if ( verbose > 0 ) 
    	  IJ.log("Debug: Convergence = " + (total_change / num_updated) + ", change=" + total_change + ", num_updated=" + num_updated);
//      if ((total_change / num_updated) < CONVERGENCE_FACTOR)
      if ((total_change / num_updated) < CONVERGENCE_WEIGHT)
      {
         return true;
      }
      else return false; 
   }