anchor.diff:        
         _handleDragEnd(event);
       }));
  -    
  -    // Install esc-key and blur listeners.
  -    _installEscAndBlurListeners();
  -    
  -    // Prevent default on mouseDown. Reasons:
  -    // * Disables image dragging handled by the browser.
  -    // * Disables text selection.
  -    // 
  -    // Note: We must NOT prevent default on form elements. Reasons:
  -    // * SelectElement would not show a dropdown.
  -    // * InputElement and TextAreaElement would not get focus.
  -    // * ButtonElement and OptionElement - don't know if this is needed??
  -    Element target = startEvent.target;
  -    if (!(target is SelectElement || target is InputElement || 
  -          target is TextAreaElement || target is ButtonElement || 
  -          target is OptionElement)) {
  -      startEvent.preventDefault();
  -    }
  -  }
  -  
  -  /**
  -   * 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)) {
  -      
  -      _log.fine('Drag started on a cancel element, canceling drag.');
  -      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)) {
  -          _log.fine('Drag not started on valid 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.
  -      _log.fine('Drag not started on valid handle.');
  -      return false;
  -    }
  -    
  -    return true;
     }
     
     /**
  
positive.code:     
      return target;
    }
  }
  
  /**
  
negative.code:     
      _log.fine('Initializing Draggable.');
      
      // Install listeners for touch. Ignore browsers without touch support.
      bool touchSupport = false;
      
      if (!disableTouch && TouchEvent.supported) {
        _installTouchStart();
      }
      
      // Install drag start listener for mouse.
      if (!disableMouse) {
        _installMouseStart();
      }
    }
    
    /**
     * Installs listener for the touchStart event.
     */
    void _installTouchStart() {
      _log.fine('Installing touchStart listener.');
      
      _startSubs.add(_elementOrElementList.onTouchStart.listen((TouchEvent startEvent) {
        // Ignore if drag is already beeing handled.
        if (_currentDrag != null) {
          return;
        }
        
        // Ignore multi-touch events.
        if (startEvent.touches.length > 1) {
          return;
        }
        
        // Ensure the drag started on a valid target (with respect to cancel and 
        // handle query Strings).
        if (!_isValidDragStartTarget(startEvent.touches[0].target)) {
          return; 
        }
        
        _log.fine('TouchStart event.');
        
        // Initialize the drag info. 
        // Note: the drag is not started on touchStart but after a first valid move.
        _currentDrag = new _DragInfo(id, startEvent.currentTarget, 
            startEvent.touches[0].page, avatarHandler: avatarHandler,
            horizontalOnly: horizontalOnly, verticalOnly: verticalOnly);
        
        // Install listeners to detect a drag move or a drag end.
        _installTouchMove();
        _installTouchEnd();
        _installEscAndBlurListeners();
      }));
    }
    
    /**
     * Installs listener for the mouseDown event.
     */
    void _installMouseStart() {
      _log.fine('Installing mouseDown listener.');
      
      _startSubs.add(_elementOrElementList.onMouseDown.listen((MouseEvent startEvent) {
        // Ignore if drag is already beeing handled.
        if (_currentDrag != null) {
          return;
        }
        
        // Only handle left clicks, ignore clicks from right or middle buttons.
        if (startEvent.button != 0) {
          return;
        }
        
        // Ensure the drag started on a valid target (with respect to cancel and 
        // handle query Strings).
        if (!_isValidDragStartTarget(startEvent.target)) {
          return; 
        }
        
        _log.fine('MouseDown event.');
        
        // Initialize the drag info. 
        // Note: the drag is not started on mouseDown but after a first valid move.
        _currentDrag = new _DragInfo(id, startEvent.currentTarget, startEvent.page, 
            avatarHandler: avatarHandler,
            horizontalOnly: horizontalOnly, verticalOnly: verticalOnly);
        
        // Install listeners to detect a drag move or a drag end.
        _installMouseMove();
        _installMouseEnd();
        _installEscAndBlurListeners();
        
        // Prevent default on mouseDown. Reasons:
        // * Disables image dragging handled by the browser.
        // * Disables text selection.
        // 
        // Note: We must NOT prevent default on form elements. Reasons:
        // * SelectElement would not show a dropdown.
        // * InputElement and TextAreaElement would not get focus.
        // * ButtonElement and OptionElement - don't know if this is needed??
        Element target = startEvent.target;
        if (!(target is SelectElement || target is InputElement || 
              target is TextAreaElement || target is ButtonElement || 
              target is OptionElement)) {
          startEvent.preventDefault();
        }
      }));
    }
    
    /**
     * Installs the touchMove listener.
     */
    void _installTouchMove() {
      _dragSubs.add(document.onTouchMove.listen((TouchEvent event) {
        // Set the current position.
        _currentDrag.position = event.changedTouches[0].page;
  