function AdfDragRecognizer() {
  if(this != window) {
    this.Init()
  }
}
AdfObject.createSubclass(AdfDragRecognizer);
AdfDragRecognizer.prototype.prepDrag = function(dndContext, dragSource, inputEvent) {
  AdfAssert.assertPrototype(dragSource, AdfDragSource);
  AdfAssert.assertPrototype(inputEvent, AdfUIInputEvent);
  if(!AdfAgent.AGENT.isDragPrepEvent(inputEvent)) {
    return null
  }
  if(!dragSource.isAvailable(dndContext, inputEvent)) {
    return null
  }
  AdfLogger.LOGGER.finer("prep drag[ source:", dragSource, " event:", inputEvent, "]");
  var prepContext = {triggerEvent:inputEvent.clone(), startPageX:inputEvent.getPageX(), startPageY:inputEvent.getPageY()};
  return prepContext
};
AdfDragRecognizer.prototype.abortPrep = function(prepContext, inputEvent) {
  AdfAssert.assertPrototype(inputEvent, AdfUIInputEvent);
  return inputEvent.getType() == AdfUIInputEvent.MOUSE_UP_EVENT_TYPE
};
AdfDragRecognizer.prototype.recognizeDrag = function(prepContext, inputEvent) {
  var newPageX = inputEvent.getPageX();
  var newPageY = inputEvent.getPageY();
  var agent = AdfAgent.AGENT;
  var isPrimarilyTouchDevice = agent.isTouchFirstDevice();
  if(inputEvent.getType() == AdfUIInputEvent.MOUSE_MOVE_EVENT_TYPE || inputEvent.getType() == AdfComponentTouchEvent.TOUCH_MOVE_EVENT_TYPE && inputEvent.getTouchCount() == 1) {
    AdfLogger.LOGGER.finer("recognizeDrag curr:", newPageX, ",", newPageY, " ", prepContext.startPageX, ",", prepContext.startPageY);
    var minDragOffset = isPrimarilyTouchDevice ? 10 : 3;
    if(Math.abs(prepContext.startPageX - newPageX) > minDragOffset || Math.abs(prepContext.startPageY - newPageY) > minDragOffset) {
      AdfLogger.LOGGER.fine("Drag recognized for:", inputEvent);
      return prepContext.triggerEvent
    }else {
      if(!isPrimarilyTouchDevice) {
        AdfAgent.AGENT.preventDefault(inputEvent.getNativeEvent())
      }
    }
  }
  return null
};
