         
         return CGRectMake(x, y, width, height)
     }
-
-    private func labelFrame() -> CGRect {
-        var x: CGFloat = 0
-        var y: CGFloat = 0
-        var width: CGFloat = 0
-        var height: CGFloat = 0
+    
+    // MARK: size and frame calculation
+    public override func sizeThatFits(size: CGSize) -> CGSize {
+        let imageLocationAdjustment = imageLocationSizeAdjustment()
+        let labelSize = calculateLabelSize()
+        
+        let height = labelSize.height + config.contentInsets.topAndBottom + imageLocationAdjustment.height
+        let width = labelSize.width + config.contentInsets.leftAndRight + imageLocationAdjustment.width
+        
+        return CGSizeMake(width, height)
+    }
+    
+    private func calculateLabelSize() -> CGSize {
+        let imageLocationAdjustment = imageLocationSizeAdjustment()
+        let screenSize = UIScreen.mainScreen().bounds
+        let maxLabelWidth = screenSize.width - 2 * margin - config.contentInsets.leftAndRight - imageLocationAdjustment.width
+        let size = config.font.sizeFor(message, constrain: CGSizeMake(maxLabelWidth, 0))
+        
+        return CGSizeMake(ceil(size.width), ceil(size.height))
+    }
+    
+    private func imageLocationSizeAdjustment() -> CGSize {
+        var widthAdjustment: CGFloat = 0
+        var heightAdjustment: CGFloat = 0
         
         switch config.imageAlignment {
-        case .Left:
-            x = config.contentInsets.left + imageWithMarginsSize().width
-            y = config.contentInsets.top
-            width = frame.size.width - config.contentInsets.leftAndRight - imageWithMarginsSize().width
-            height = contentHeight()
-        case .Right:
-            x = config.contentInsets.left
-            y = config.contentInsets.top
-            width = frame.size.width - config.contentInsets.leftAndRight - imageWithMarginsSize().width
-            height = contentHeight()
-        case .Top:
-            x = config.contentInsets.left
-            y = config.contentInsets.top + config.imageMargins.topAndBottom + imageSize().height
-            width = frame.size.width - config.contentInsets.leftAndRight
-            height = frame.size.height - config.contentInsets.topAndBottom - config.imageMargins.topAndBottom - imageSize().height
-        case .Bottom:
-            x = config.contentInsets.left
-            y = config.contentInsets.top
-            width = frame.size.width - config.contentInsets.leftAndRight
-            height = frame.size.height - config.contentInsets.topAndBottom - config.imageMargins.topAndBottom - imageSize().height
-        }
-        
-        return CGRectMake(x, y, width, height)
+        case .Left, .Right:
+            widthAdjustment = imageWithMarginsSize().width
+        case .Top, .Bottom:
+            heightAdjustment = imageWithMarginsSize().height
+        }
+        
+        return CGSizeMake(widthAdjustment, heightAdjustment)
     }
     
     private func imageWithMarginsSize() -> CGSize {

        return imageView
    }
    
    // MARK: size and frame calculation
    public override func sizeThatFits(size: CGSize) -> CGSize {
        let imageLocationAdjustment = imageLocationSizeAdjustment()
        let labelSize = calculateLabelSize()
        
        let height = labelSize.height + config.contentInsets.topAndBottom + imageLocationAdjustment.height
        let width = labelSize.width + config.contentInsets.leftAndRight + imageLocationAdjustment.width
        
        return CGSizeMake(width, height)
    }
    
    private func calculateLabelSize() -> CGSize {
        let imageLocationAdjustment = imageLocationSizeAdjustment()
        let screenSize = UIScreen.mainScreen().bounds
        let maxLabelWidth = screenSize.width - 2 * margin - config.contentInsets.leftAndRight - imageLocationAdjustment.width
        let size = config.font.sizeFor(message, constrain: CGSizeMake(maxLabelWidth, 0))
        
        return CGSizeMake(ceil(size.width), ceil(size.height))
    }
    
    private func imageLocationSizeAdjustment() -> CGSize {
        var widthAdjustment: CGFloat = 0
        var heightAdjustment: CGFloat = 0
        
        switch config.imageAlignment {
        case .Left, .Right:
            widthAdjustment = imageWithMarginsSize().width
        case .Top, .Bottom:
            heightAdjustment = imageWithMarginsSize().height
        }
        
        return CGSizeMake(widthAdjustment, heightAdjustment)
    }
    
    private func imageViewFrame() -> CGRect {
        var x: CGFloat = 0
        var y: CGFloat = 0
        var width: CGFloat = 0
        var height: CGFloat = 0

        let allInsets = config.contentInsets + config.imageMargins
        
        switch config.imageAlignment {

            x = allInsets.left
            y = allInsets.top
            width = imageSize().width
            height = contentSize().height - config.imageMargins.topAndBottom
        case .Right:
            x = frame.width - allInsets.right - imageSize().width
            y = allInsets.top
            width = imageSize().width
            height = contentSize().height - config.imageMargins.topAndBottom
        case .Top:
            x = allInsets.left
            y = allInsets.top
