         
         collectionView?.dataSource = self
         collectionView?.delegate = self
+        // add a tap gesture for colleciotnview
+        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap(messageCollectionView:)))
+        collectionView?.addGestureRecognizer(tapGesture)
         
         updateCollectionViewInsets(top: self.topLayoutGuide.length, bottom: CGRectGetMaxY(collectionView!.frame) - CGRectGetMinY(self.inputToolbar!.frame))
     }

    }
    
    
    // FIXME: for current controller can not be released due to unfound retain cycle, we remove notification in viewDidDisappear for temporary
    override public func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        clearForNotification()

    }
}

// MARK: DUMessageCollectionView
extension DUMessagesViewController {
    private func messageCollectionViewTapHandler(sender: UITapGestureRecognizer) {
        if let _ = self.collectionView {
            didTap(messageCollectionView: self.collectionView!)
        }
    }
    
    public func didTap(messageCollectionView view: DUMessageCollectionView) {
        print("Tapped messageCollectionView, please implemnt '\(#function)' to deal with this event.")
    }
}

// MARK: message data helper
public extension DUMessageData {
    var isOutgoingMessage: Bool {
