docs: public static <I extends ImageGray<I>, D extends ImageGray<D>>
  	void gradient( DerivativeType type , I input , D derivX , D derivY , BorderType borderType ) {
  
  		ImageBorder<I> border = BorderType.SKIP == borderType ? null : FactoryImageBorder.wrap(borderType, input);
  
  		switch( type ) {
  			case PREWITT:
  				if( input instanceof GrayF32) {
  					GradientPrewitt.process((GrayF32)input,(GrayF32)derivX,(GrayF32)derivY,(ImageBorder_F32)border);
  				} else if( input instanceof GrayU8) {
  					GradientPrewitt.process((GrayU8)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else if( input instanceof GrayS16) {
  					GradientPrewitt.process((GrayS16)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else {
  					throw new IllegalArgumentException("Unknown input image type: "+input.getClass().getSimpleName());
  				}
  				break;
  			case SOBEL:
  				if( input instanceof GrayF32) {
  					GradientSobel.process((GrayF32)input,(GrayF32)derivX,(GrayF32)derivY,(ImageBorder_F32)border);
  				} else if( input instanceof GrayU8) {
  					GradientSobel.process((GrayU8)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else if( input instanceof GrayS16) {
  					GradientSobel.process((GrayS16)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else {
  					throw new IllegalArgumentException("Unknown input image type: "+input.getClass().getSimpleName());
  				}
  				break;
  			case THREE:
  				if( input instanceof GrayF32) {
  					GradientThree.process((GrayF32)input,(GrayF32)derivX,(GrayF32)derivY,(ImageBorder_F32)border);
  				} else if( input instanceof GrayU8) {
  					GradientThree.process((GrayU8)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else if( input instanceof GrayS16) {
  					GradientThree.process((GrayS16)input,(GrayS16)derivX,(GrayS16)derivY,(ImageBorder_S32)border);
  				} else {
  					throw new IllegalArgumentException("Unknown input image type: "+input.getClass().getSimpleName());
  				}
  				break;
  			case TWO_0:
  				if( input instanceof GrayF32) {
  					GradientTwo0.process((GrayF32) input, (GrayF32) derivX, (GrayF32) derivY, (ImageBorder_F32) border);
  				} else if( input instanceof GrayU8) {
  					GradientTwo0.process((GrayU8) input, (GrayS16) derivX, (GrayS16) derivY, (ImageBorder_S32) border);
  				} else if( input instanceof GrayS16) {
  					GradientTwo0.process((GrayS16) input, (GrayS16) derivX, (GrayS16) derivY, (ImageBorder_S32) border);
  				} else {
  					throw new IllegalArgumentException("Unknown input image type: "+input.getClass().getSimpleName());
  				}
  				break;
  			case TWO_1:
  				if( input instanceof GrayF32) {
  					GradientTwo1.process((GrayF32) input, (GrayF32) derivX, (GrayF32) derivY, (ImageBorder_F32) border);
  				} else if( input instanceof GrayU8) {
  					GradientTwo1.process((GrayU8) input, (GrayS16) derivX, (GrayS16) derivY, (ImageBorder_S32) border);
  				} else if( input instanceof GrayS16) {
  					GradientTwo1.process((GrayS16) input, (GrayS16) derivX, (GrayS16) derivY, (ImageBorder_S32) border);
  				} else {
  					throw new IllegalArgumentException("Unknown input image type: "+input.getClass().getSimpleName());
  				}
  				break;
  
  			default:
  				throw new IllegalArgumentException("Unknown type: "+type);
  		}
  	}