anchor.diff:        if (avatarHandler != null) {
           avatarHandler.dragEnd(_currentDrag.startPosition, _currentDrag.position);
         }
  -      
  +
         // Dispatch internal drop event if drag was not cancelled.
         if (!cancelled && target != null) {
           _DragEventDispatcher.dispatchDrop(this, target);
         }
  -      
  +
         // Fire dragEnd event.
         if (_onDragEnd != null) {
  -        _onDragEnd.add(new DraggableEvent._(event, _currentDrag, 
  +        _onDragEnd.add(new DraggableEvent._(event, _currentDrag,
               cancelled: cancelled));
         }
  -      
  +
         // Prevent TouchEvent from emulating a click after touchEnd event.
         event.preventDefault();
  -      
  +
         if (event is MouseEvent) {
           // Prevent MouseEvent from firing a click after mouseUp event.
           _suppressClickEvent();
         }
  -      
  +
         // Remove the css classes.
         if (draggingClass != null) {
           _currentDrag.element.classes.remove(draggingClass);
  
positive.code:       // This is the case for InputElement with type 'file'.
      }
    }
    
    /// Determine the actual target that should receive the event because 
    /// mouse or touch event might have occurred on a drag avatar.
    /// 
    /// If a [target] is provided it is tested to see if is already the correct
    /// target or if it is the drag avatar and thus must be replaced by the 
    /// element underneath.
    EventTarget _getRealTarget(Point clientPosition, {EventTarget target}) {
      // If no target was provided get it.
      if (target == null) {
        target = document.elementFromPoint(clientPosition.x, clientPosition.y);
      }
      
      // Test if target is the drag avatar.
      if (avatarHandler != null && avatarHandler.avatar != null 
          && avatarHandler.avatar.contains(target)) {
        
        // Target is the drag avatar, get element underneath. 
        avatarHandler.avatar.style.visibility = 'hidden';
        target = document.elementFromPoint(clientPosition.x, clientPosition.y);
        avatarHandler.avatar.style.visibility = 'visible';
      }
      
      return target;
    }
    
    /// Tests if [target] is a valid place to start a drag. If [handle] is
    /// provided, drag can only start on the [handle]s. If [cancel] is 
    /// provided, drag cannot be started on those elements.
    bool _isValidDragStartTarget(EventTarget target) {
      // Test if a drag was started on a cancel element.
      if (cancel != null 
          && target is Element 
          && target.matchesWithAncestors(cancel)) {
       
        return false;
      }
    
      // If handle is specified, drag must start on handle or one of its children.
      if (handle != null) {
        if (target is Element) {
          // 1. The target must match the handle query String.
          if (!target.matchesWithAncestors(handle)) {
            return false; 
          }
         
          // 2. The target must be a child of the drag element(s).
          if (_elementOrElementList is ElementList) {
            for (Element el in _elementOrElementList) {
              if (el.contains(target)) {
                return true; 
              }
            }
          } else {
            if ((_elementOrElementList as Element).contains(target)) {
              return true; 
            }
          }
        }
       
        // Has a handle specified but we did not find a match.
        return false;
      }
      
      return true;
    }
  }
  
  
  /// Event used when a drag is detected.
  class DraggableEvent {
    /// The [Element] that is beeing dragged. 
    final Element draggableElement;
    
    /// The [AvatarHandler] or null if there is none.
    final AvatarHandler avatarHandler;
    
    /// The original event which is either ...
    /// * a [MouseEvent], 
    /// * a [TouchEvent], 
    /// * a [KeyboardEvent] when the user clicks the esc-key, or
    /// * a normal [Event] when the window loses focus (blur event).
    final Event originalEvent;
    
    /// Position where the drag started, relative to the whole document (page 
    /// position).
    final Point startPosition;
    
    /// The current mouse/touch position, relative to the whole document (page 
    /// position).
    final Point position;
    
    /// Indicates if this [DraggableEvent] was [cancelled]. This is currently 
    /// only used for [onDragEnd] events to indicate a drag end through a 
    /// cancelling oparation like `esc` key or windows loosing focus.
    final bool cancelled;
    
    /// Private constructor for [DraggableEvent].
    DraggableEvent._(this.originalEvent, _DragInfo dragInfo, {this.cancelled: false})
        : draggableElement = dragInfo.element,
  
negative.code:         document.body.classes.remove(draggingClassBody);
        }
      }
  
      // Reset.
      _resetCurrentDrag();
    }
  
    /// Makes sure that a potential click event is ignored. This is necessary for
    /// [MouseEvent]s. We have to wait for and cancel a potential click event
    /// happening after the mouseUp event.
    void _suppressClickEvent() {
      StreamSubscription clickPreventer = _elementOrElementList.onClick.listen((event) {
        event.stopPropagation();
        event.preventDefault();
      });
  
      // Wait until the end of event loop to see if a click event is fired.
      // Then cancel the listener.
      new Future(() {
  