static void Apply( GenericImage<P>& image, const LocalHistogramEqualizationInstance& instance )
   {
      if ( image.IsColor() )
      {
         Image L;
         image.GetLightness( L );
         L.Status() = image.Status();
         Apply( L, instance );
         image.Status() = L.Status();
         image.SetLightness( L );
         return;
      }

      // create copy of the luminance to evaluate histogram from
      GenericImage<P> imageCopy( image );
      imageCopy.EnsureUnique(); // really not necessary, but we'll be safer if this is done

      size_type N = image.NumberOfPixels();

      int numberOfThreads = Thread::NumberOfThreads( image.Height(), 1 );
      int rowsPerThread = image.Height()/numberOfThreads;

      image.Status().Initialize( "CLAHE", N );

      AbstractImage::ThreadData data( image, N );

      // create processing threads
      ReferenceArray<LocalHistogramEqualizationThread<P> > threads;
      for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j )
         threads.Add( new LocalHistogramEqualizationThread<P>( data,
                                 instance,
                                 image,
                                 imageCopy,
                                 i*rowsPerThread,
                                 (j < numberOfThreads) ? j*rowsPerThread : image.Height() ) );

      AbstractImage::RunThreads( threads, data );

      threads.Destroy();

      image.Status() = data.status;
   }