                                     */
                                     mapItem.openInMapsWithLaunchOptions(nil)
                                 }
-                            }
-
-                        }, collectionView: collectionView, indexPath: indexPath)
-
-                        cell.tapAvatarAction = { [weak self] user in
-                            self?.performSegueWithIdentifier("showProfile", sender: user)
-                        }
-
-                        return cell
+
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
 
                     default:
 
-                        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightTextCellIdentifier, forIndexPath: indexPath) as! ChatRightTextCell
-
-                        cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: { [weak self] in
-
-                            if message.sendState == MessageSendState.Failed.rawValue {
-
-                                YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
-
-                                    resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
-                                        defaultFailureHandler(reason, errorMessage)
-
-                                        YepAlert.alertSorry(message: NSLocalizedString("Failed to resend text!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
-
-                                    }, completion: { success in
-                                        println("resendText: \(success)")
+                        if let cell = cell as? ChatLeftTextCell {
+
+                            cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+                    }
+
+                } else { // from Me
+
+                    switch message.mediaType {
+
+                    case MessageMediaType.Image.rawValue:
+
+                        if let cell = cell as? ChatRightImageCell {
+
+                            cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in
+
+                                if message.sendState == MessageSendState.Failed.rawValue {
+
+                                    YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend image?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
+
+                                        resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
+                                            defaultFailureHandler(reason, errorMessage)
+
+                                            YepAlert.alertSorry(message: NSLocalizedString("Failed to resend image!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
+
+                                        }, completion: { success in
+                                            println("resendImage: \(success)")
+                                        })
+
+                                    }, cancelAction: {
                                     })
 
-                                }, cancelAction: {
-                                })
-                            }
-                        }, collectionView: collectionView, indexPath: indexPath)
-
-                        cell.longPressAction = { [weak self] in
-                            dispatch_async(dispatch_get_main_queue()) {
-                                if let strongSelf = self, realm = message.realm {
-
-                                    var sectionDateMessage: Message?
-
-                                    if let currentMessageIndex = strongSelf.messages.indexOf(message) {
-
-                                        let previousMessageIndex = currentMessageIndex - 1
-
-                                        if let previousMessage = strongSelf.messages[safe: previousMessageIndex] {
-
-                                            if previousMessage.mediaType == MessageMediaType.SectionDate.rawValue {
-                                                sectionDateMessage = previousMessage
+                                } else {
+                                    self?.performSegueWithIdentifier("showMessageMedia", sender: message)
+                                }
+
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+
+                    case MessageMediaType.Audio.rawValue:
+
+                        if let cell = cell as? ChatRightAudioCell {
+
+                            let audioPlayedDuration = audioPlayedDurationOfMessage(message)
+
+                            cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in
+
+                                if message.sendState == MessageSendState.Failed.rawValue {
+
+                                    YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend audio?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
+
+                                        resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
+                                            defaultFailureHandler(reason, errorMessage)
+
+                                            YepAlert.alertSorry(message: NSLocalizedString("Failed to resend audio!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
+
+                                        }, completion: { success in
+                                            println("resendAudio: \(success)")
+                                        })
+
+                                    }, cancelAction: {
+                                    })
+
+                                    return
+                                }
+
+                                self?.playMessageAudioWithMessage(message)
+
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+
+                    case MessageMediaType.Video.rawValue:
+
+                        if let cell = cell as? ChatRightVideoCell {
+
+                            cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in
+
+                                if message.sendState == MessageSendState.Failed.rawValue {
+
+                                    YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend video?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
+
+                                        resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
+                                            defaultFailureHandler(reason, errorMessage)
+
+                                            YepAlert.alertSorry(message: NSLocalizedString("Failed to resend video!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
+
+                                        }, completion: { success in
+                                            println("resendVideo: \(success)")
+                                        })
+
+                                    }, cancelAction: {
+                                    })
+
+                                } else {
+                                    self?.performSegueWithIdentifier("showMessageMedia", sender: message)
+                                }
+
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+
+                    case MessageMediaType.Location.rawValue:
+
+                        if let cell = cell as? ChatRightLocationCell {
+
+                            cell.configureWithMessage(message, mediaTapAction: { [weak self] in
+
+                                if message.sendState == MessageSendState.Failed.rawValue {
+
+                                    YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend location?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
+
+                                        resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
+                                            defaultFailureHandler(reason, errorMessage)
+
+                                            YepAlert.alertSorry(message: NSLocalizedString("Failed to resend location!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
+
+                                        }, completion: { success in
+                                            println("resendLocation: \(success)")
+                                        })
+
+                                    }, cancelAction: {
+                                    })
+
+                                } else {
+                                    if let coordinate = message.coordinate {
+                                        let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
+                                        let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil))
+                                        /*
+                                        let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
+                                        mapItem.openInMapsWithLaunchOptions(launchOptions)
+                                        */
+                                        mapItem.openInMapsWithLaunchOptions(nil)
+                                    }
+                                }
+
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+
+                    default:
+
+                        if let cell = cell as? ChatRightTextCell {
+
+                            cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: { [weak self] in
+
+                                if message.sendState == MessageSendState.Failed.rawValue {
+
+                                    YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
+
+                                        resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
+                                            defaultFailureHandler(reason, errorMessage)
+
+                                            YepAlert.alertSorry(message: NSLocalizedString("Failed to resend text!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
+
+                                        }, completion: { success in
+                                            println("resendText: \(success)")
+                                        })
+
+                                    }, cancelAction: {
+                                    })
+                                }
+                            }, collectionView: collectionView, indexPath: indexPath)
+
+                            cell.longPressAction = { [weak self] in
+                                dispatch_async(dispatch_get_main_queue()) {
+                                    if let strongSelf = self, realm = message.realm {
+
+                                        var sectionDateMessage: Message?
+
+                                        if let currentMessageIndex = strongSelf.messages.indexOf(message) {
+
+                                            let previousMessageIndex = currentMessageIndex - 1
+
+                                            if let previousMessage = strongSelf.messages[safe: previousMessageIndex] {
+
+                                                if previousMessage.mediaType == MessageMediaType.SectionDate.rawValue {
+                                                    sectionDateMessage = previousMessage
+                                                }
                                             }
                                         }
-                                    }
-
-                                    let currentIndexPath: NSIndexPath
-                                    if let index = strongSelf.messages.indexOf(message) {
-                                        currentIndexPath = NSIndexPath(forItem: index - strongSelf.displayedMessagesRange.location, inSection: indexPath.section)
-                                    } else {
-                                        currentIndexPath = indexPath
-                                    }
-
-                                    if let sectionDateMessage = sectionDateMessage {
-
-                                        var canDeleteTwoMessages = false // 考虑刚好的边界情况，例如消息为本束的最后一条，而 sectionDate 在上一束中
-                                        if strongSelf.displayedMessagesRange.length >= 2 {
-                                            strongSelf.displayedMessagesRange.length -= 2
-                                            canDeleteTwoMessages = true
-
+
+                                        let currentIndexPath: NSIndexPath
+                                        if let index = strongSelf.messages.indexOf(message) {
+                                            currentIndexPath = NSIndexPath(forItem: index - strongSelf.displayedMessagesRange.location, inSection: indexPath.section)
                                         } else {
-                                            if strongSelf.displayedMessagesRange.location >= 1 {
-                                                strongSelf.displayedMessagesRange.location -= 1
+                                            currentIndexPath = indexPath
+                                        }
+
+                                        if let sectionDateMessage = sectionDateMessage {
+
+                                            var canDeleteTwoMessages = false // 考虑刚好的边界情况，例如消息为本束的最后一条，而 sectionDate 在上一束中
+                                            if strongSelf.displayedMessagesRange.length >= 2 {
+                                                strongSelf.displayedMessagesRange.length -= 2
+                                                canDeleteTwoMessages = true
+
+                                            } else {
+                                                if strongSelf.displayedMessagesRange.location >= 1 {
+                                                    strongSelf.displayedMessagesRange.location -= 1
+                                                }
+                                                strongSelf.displayedMessagesRange.length -= 1
                                             }
+
+                                            realm.write {
+                                                if let mediaMetaData = sectionDateMessage.mediaMetaData {
+                                                    realm.delete(mediaMetaData)
+                                                }
+                                                if let mediaMetaData = message.mediaMetaData {
+                                                    realm.delete(mediaMetaData)
+                                                }
+                                                realm.delete(sectionDateMessage)
+                                                realm.delete(message)
+                                            }
+
+                                            if canDeleteTwoMessages {
+                                                let previousIndexPath = NSIndexPath(forItem: currentIndexPath.item - 1, inSection: currentIndexPath.section)
+                                                strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([previousIndexPath, currentIndexPath])
+                                            } else {
+                                                strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath])
+                                            }
+
+                                        } else {
                                             strongSelf.displayedMessagesRange.length -= 1
-                                        }
-
-                                        realm.write {
-                                            if let mediaMetaData = sectionDateMessage.mediaMetaData {
-                                                realm.delete(mediaMetaData)
+                                            realm.write {
+                                                if let mediaMetaData = message.mediaMetaData {
+                                                    realm.delete(mediaMetaData)
+                                                }
+                                                realm.delete(message)
                                             }
-                                            if let mediaMetaData = message.mediaMetaData {
-                                                realm.delete(mediaMetaData)
-                                            }
-                                            realm.delete(sectionDateMessage)
-                                            realm.delete(message)
-                                        }
-
-                                        if canDeleteTwoMessages {
-                                            let previousIndexPath = NSIndexPath(forItem: currentIndexPath.item - 1, inSection: currentIndexPath.section)
-                                            strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([previousIndexPath, currentIndexPath])
-                                        } else {
                                             strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath])
                                         }
 
-                                    } else {
-                                        strongSelf.displayedMessagesRange.length -= 1
-                                        realm.write {
-                                            if let mediaMetaData = message.mediaMetaData {
-                                                realm.delete(mediaMetaData)
-                                            }
-                                            realm.delete(message)
-                                        }
-                                        strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath])
+                                        // 必须更新，插入时需要
+                                        strongSelf.lastTimeMessagesCount = strongSelf.messages.count
                                     }
-
-                                    // 必须更新，插入时需要
-                                    strongSelf.lastTimeMessagesCount = strongSelf.messages.count
                                 }
                             }
-                        }
-
-                        cell.tapAvatarAction = { [weak self] user in
-                            self?.performSegueWithIdentifier("showProfile", sender: user)
-                        }
-
-                        return cell
-                    }
-                }
-            }
-        }
-
-        println("🐌 Conversation: Should not be there")
-
-        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatSectionDateCellIdentifier, forIndexPath: indexPath) as! ChatSectionDateCell
-
-        cell.sectionDateLabel.text = "🐌"
-
-        return cell
-
+
+                            cell.tapAvatarAction = { [weak self] user in
+                                self?.performSegueWithIdentifier("showProfile", sender: user)
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {


                        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftImageCellIdentifier, forIndexPath: indexPath) as! ChatLeftImageCell

                        cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in

                            if message.downloadState == MessageDownloadState.Downloaded.rawValue {
                                self?.performSegueWithIdentifier("showMessageMedia", sender: message)

                            } else {
                                YepAlert.alertSorry(message: NSLocalizedString("Please wait while the image is not dready!", comment: ""), inViewController: self)
                            }

                        }, collectionView: collectionView, indexPath: indexPath)

                        cell.tapAvatarAction = { [weak self] user in
                            self?.performSegueWithIdentifier("showProfile", sender: user)
                        }
                        
                        return cell

                    case MessageMediaType.Audio.rawValue:

                        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftAudioCellIdentifier, forIndexPath: indexPath) as! ChatLeftAudioCell

                        let audioPlayedDuration = audioPlayedDurationOfMessage(message)

                        cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in

                            if message.downloadState == MessageDownloadState.Downloaded.rawValue {
                                self?.playMessageAudioWithMessage(message)

                            } else {
                                YepAlert.alertSorry(message: NSLocalizedString("Please wait while the audio is not dready!", comment: ""), inViewController: self)
                            }

                        }, collectionView: collectionView, indexPath: indexPath)

                        cell.tapAvatarAction = { [weak self] user in
                            self?.performSegueWithIdentifier("showProfile", sender: user)
                        }

                        return cell

                    case MessageMediaType.Video.rawValue:

                        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftVideoCellIdentifier, forIndexPath: indexPath) as! ChatLeftVideoCell

                        cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in

                            if message.downloadState == MessageDownloadState.Downloaded.rawValue {
                                self?.performSegueWithIdentifier("showMessageMedia", sender: message)

                            } else {
                                YepAlert.alertSorry(message: NSLocalizedString("Please wait while the video is not dready!", comment: ""), inViewController: self)
                            }

                        }, collectionView: collectionView, indexPath: indexPath)

                        cell.tapAvatarAction = { [weak self] user in
                            self?.performSegueWithIdentifier("showProfile", sender: user)
                        }

                        return cell

                    case MessageMediaType.Location.rawValue:

                        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftLocationCellIdentifier, forIndexPath: indexPath) as! ChatLeftLocationCell

                        cell.configureWithMessage(message, mediaTapAction: { [weak self] in
                            if let coordinate = message.coordinate {
                                let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
                                let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil))
                                /*
                                let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
                                mapItem.openInMapsWithLaunchOptions(launchOptions)
                                */
                                mapItem.openInMapsWithLaunchOptions(nil)
                            }

                        }, collectionView: collectionView, indexPath: indexPath)

                        cell.tapAvatarAction = { [weak self] user in
                            self?.performSegueWithIdentifier("showProfile", sender: user)
                        }

                        return cell

                    default:


                let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatSectionDateCellIdentifier, forIndexPath: indexPath) as! ChatSectionDateCell

                return cell
            }

