   /**
    * This method is only needed if the function implements HasHandles. It allows the
    * user to adjust the function parameters by dragging on handles on the function itself.
    * This is not so easy to implement in general, so should only be attempted by advanced
    * users! The values passed in are the current ranges on the X and Y axes, so that 
    * appropriate initial positions can be chosen for the handles.
    */
    public Handle[] getHandles(double xLow, double xHigh, double yLow, double yHigh)
   {
      Handle[] result = new Handle[2];
      // We choose the number of cycles so that the minimu will be in the visible region
      // of the plot.
      final int cycles = (int) Math.floor(xLow-offset/period)+1;
      // handle at first minimum
      // used to adjust offset      
      result[0] = new Handle()
      {
         public void moveTo(double x, double y)
         {
            offset = x - cycles * period;
            clearFit();
            setChanged();
         }
         public double getX()
         {
            return cycles*period + offset;
         }
         public double getY()
         {
            return 0;
         }
      };
      // handle at first maximum
      // used to adjust offset and period
      result[1] = new Handle()
      {
         public void moveTo(double x, double y)
         {
            double old = cycles*period + offset; 
            amplitude = y;
            period = 4*(x - old);
            offset = old - cycles*period; 
            clearFit();
            setChanged();
         }
         public double getY()
         {
            return amplitude;
         }
         public double getX()
         {
            return cycles * period + offset + period/4;
         }
      };
      return result;
   }
