diff --git a/TTTAttributedLabel.h b/TTTAttributedLabel.h
new file mode 100755
index 0000000..e43315e
--- /dev/null
+++ b/TTTAttributedLabel.h
@@ -0,0 +1,330 @@
+// TTTAttributedLabel.h
+//
+// Copyright (c) 2011 Mattt Thompson (http://mattt.me)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <UIKit/UIKit.h>
+#import <CoreText/CoreText.h>
+
+/**
+ Vertical alignment for text in a label whose bounds are larger than its text bounds
+ */
+typedef enum {
+    TTTAttributedLabelVerticalAlignmentCenter   = 0,
+    TTTAttributedLabelVerticalAlignmentTop      = 1,
+    TTTAttributedLabelVerticalAlignmentBottom   = 2,
+} TTTAttributedLabelVerticalAlignment;
+
+/**
+ Determines whether the text to which this attribute applies has a strikeout drawn through itself.
+ */
+extern NSString * const kTTTStrikeOutAttributeName;
+
+/**
+ The background fill color. Value must be a `CGColorRef`. Default value is `nil` (no fill).
+ */
+extern NSString * const kTTTBackgroundFillColorAttributeName;
+
+/**
+ The background stroke color. Value must be a `CGColorRef`. Default value is `nil` (no stroke).
+ */
+extern NSString * const kTTTBackgroundStrokeColorAttributeName;
+
+/**
+ The background stroke line width. Value must be an `NSNumber`. Default value is `1.0f`.
+ */
+extern NSString * const kTTTBackgroundLineWidthAttributeName;
+
+/**
+ The background corner radius. Value must be an `NSNumber`. Default value is `5.0f`.
+ */
+extern NSString * const kTTTBackgroundCornerRadiusAttributeName;
+
+@protocol TTTAttributedLabelDelegate;
+
+// Override UILabel @property to accept both NSString and NSAttributedString
+@protocol TTTAttributedLabel <NSObject>
+@property (nonatomic, copy) id text;
+@end
+
+/**
+ `TTTAttributedLabel` is a drop-in replacement for `UILabel` that supports `NSAttributedString`, as well as automatically-detected and manually-added links to URLs, addresses, phone numbers, and dates.
+ 
+ # Differences Between `TTTAttributedLabel` and `UILabel`
+ 
+ For the most part, `TTTAttributedLabel` behaves just like `UILabel`. The following are notable exceptions, in which `TTTAttributedLabel` properties may act differently:
+ 
+ - `text` - This property now takes an `id` type argument, which can either be a kind of `NSString` or `NSAttributedString` (mutable or immutable in both cases)
+ - `lineBreakMode` - This property displays only the first line when the value is `UILineBreakModeHeadTruncation`, `UILineBreakModeTailTruncation`, or `UILineBreakModeMiddleTruncation`
+ - `adjustsFontsizeToFitWidth` - Supported in iOS 5 and greater, this property is effective for any value of `numberOfLines` greater than zero. In iOS 4, setting `numberOfLines` to a value greater than 1 with `adjustsFontSizeToFitWidth` set to `YES` may cause `sizeToFit` to execute indefinitely.
+ 
+ Any properties affecting text or paragraph styling, such as `shadowRadius` or `firstLineIndent` will only apply when text is set with an `NSString`. If the text is set with an `NSAttributedString`, these properties will not apply.
+ 
+ @warning Any properties changed on the label after setting the text will not be reflected until a subsequent call to `setText:` or `setText:afterInheritingLabelAttributesAndConfiguringWithBlock:`. This is to say, order of operations matters in this case. For example, if the label text color is originally black when the text is set, changing the text color to red will have no effect on the display of the label until the text is set once again.
+ */
+@interface TTTAttributedLabel : UILabel <TTTAttributedLabel, UIGestureRecognizerDelegate>
+
+///-----------------------------
+/// @name Accessing the Delegate
+///-----------------------------
+
+/**
+ The receiver's delegate.
+ 
+ @discussion A `TTTAttributedLabel` delegate responds to messages sent by tapping on links in the label. You can use the delegate to respond to links referencing a URL, address, phone number, date, or date with a specified time zone and duration.
+ */
+@property (nonatomic, unsafe_unretained) id <TTTAttributedLabelDelegate> delegate;
+
+///--------------------------------------------
+/// @name Detecting, Accessing, & Styling Links
+///--------------------------------------------
+
+/**
+ A bitmask of `UIDataDetectorTypes` which are used to automatically detect links in the label text. This is `UIDataDetectorTypeNone` by default.
+ 
+ @warning You must specify `dataDetectorTypes` before setting the `text`, with either `setText:` or `setText:afterInheritingLabelAttributesAndConfiguringWithBlock:`.
+ */
+@property (nonatomic, assign) UIDataDetectorTypes dataDetectorTypes;
+
+/**
+ An array of `NSTextCheckingResult` objects for links detected or manually added to the label text.
+ */
+@property (readonly, nonatomic, strong) NSArray *links;
+
+/**
+ A dictionary containing the `NSAttributedString` attributes to be applied to links detected or manually added to the label text. The default link style is blue and underlined.
+ 
+ @warning You must specify `linkAttributes` before setting autodecting or manually-adding links for these attributes to be applied.
+ */
+@property (nonatomic, strong) NSDictionary *linkAttributes;
+
+/**
+ A dictionary containing the `NSAttributedString` attributes to be applied to links when they are in the active state. Supply `nil` or an empty dictionary to opt out of active link styling. The default active link style is red and underlined.
+ */
+@property (nonatomic, strong) NSDictionary *activeLinkAttributes;
+
+///---------------------------------------
+/// @name Acccessing Text Style Attributes
+///---------------------------------------
+
+/**
+ The shadow blur radius for the label. A value of 0 indicates no blur, while larger values produce correspondingly larger blurring. This value must not be negative. The default value is 0. 
+ */
+@property (nonatomic, assign) CGFloat shadowRadius;
+
+///--------------------------------------------
+/// @name Acccessing Paragraph Style Attributes
+///--------------------------------------------
+
+/**
+ The distance, in points, from the leading margin of a frame to the beginning of the paragraph's first line. This value is always nonnegative, and is 0.0 by default. 
+ */
+@property (nonatomic, assign) CGFloat firstLineIndent;
+
+/**
+ The space in points added between lines within the paragraph. This value is always nonnegative and is 0.0 by default. 
+ */
+@property (nonatomic, assign) CGFloat leading;
+
+/**
+ The line height multiple. This value is 0.0 by default.
+ */
+@property (nonatomic, assign) CGFloat lineHeightMultiple;
+
+/**
+ The distance, in points, from the margin to the text container. This value is `UIEdgeInsetsZero` by default.
+ 
+ @discussion The `UIEdgeInset` members correspond to paragraph style properties rather than a particular geometry, and can change depending on the writing direction. 
+ 
+ ## `UIEdgeInset` Member Correspondence With `CTParagraphStyleSpecifier` Values:
+ 
+ - `top`: `kCTParagraphStyleSpecifierParagraphSpacingBefore`
+ - `left`: `kCTParagraphStyleSpecifierHeadIndent`
+ - `bottom`: `kCTParagraphStyleSpecifierParagraphSpacing`
+ - `right`: `kCTParagraphStyleSpecifierTailIndent`
+ 
+ */
+@property (nonatomic, assign) UIEdgeInsets textInsets;
+
+/**
+ The vertical text alignment for the label, for when the frame size is greater than the text rect size. The vertical alignment is `TTTAttributedLabelVerticalAlignmentCenter` by default.
+ */
+@property (nonatomic, assign) TTTAttributedLabelVerticalAlignment verticalAlignment;
+
+///----------------------------------
+/// @name Setting the Text Attributes
+///----------------------------------
+
+/**
+ Sets the text displayed by the label.
+ 
+ @param text An `NSString` or `NSAttributedString` object to be displayed by the label. If the specified text is an `NSString`, the label will display the text like a `UILabel`, inheriting the text styles of the label. If the specified text is an `NSAttributedString`, the label text styles will be overridden by the styles specified in the attributed string.
+  
+ @discussion This method overrides `UILabel -setText:` to accept both `NSString` and `NSAttributedString` objects. This string is `nil` by default.
+ */
+- (void)setText:(id)text;
+
+/**
+ Sets the text displayed by the label, after configuring an attributed string containing the text attributes inherited from the label in a block.
+ 
+ @param text An `NSString` or `NSAttributedString` object to be displayed by the label.
+ @param block A block object that returns an `NSMutableAttributedString` object and takes a single argument, which is an `NSMutableAttributedString` object with the text from the first parameter, and the text attributes inherited from the label text styles. For example, if you specified the `font` of the label to be `[UIFont boldSystemFontOfSize:14]` and `textColor` to be `[UIColor redColor]`, the `NSAttributedString` argument of the block would be contain the `NSAttributedString` attribute equivalents of those properties. In this block, you can set further attributes on particular ranges.
+ 
+ @discussion This string is `nil` by default.
+ */
+- (void)setText:(id)text afterInheritingLabelAttributesAndConfiguringWithBlock:(NSMutableAttributedString *(^)(NSMutableAttributedString *mutableAttributedString))block;
+
+///----------------------------------
+/// @name Accessing the Text Attributes
+///----------------------------------
+
+/**
+ A copy of the label's current attributedText. This returns `nil` if an attributed string has never been set on the label.
+ */
+@property (readwrite, nonatomic, copy) NSAttributedString *attributedText;
+
+///-------------------
+/// @name Adding Links
+///-------------------
+
+/**
+ Adds a link to an `NSTextCheckingResult`.
+ 
+ @param result An `NSTextCheckingResult` representing the link's location and type.
+ */
+- (void)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result;
+
+/**
+ Adds a link to an `NSTextCheckingResult`.
+ 
+ @param result An `NSTextCheckingResult` representing the link's location and type.
+ @param attributes The attributes to be added to the text in the range of the specified link. If `nil`, no attributes are added.
+ */
+- (void)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result attributes:(NSDictionary *)attributes;
+
+/**
+ Adds a link to a URL for a specified range in the label text.
+ 
+ @param url The url to be linked to
+ @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
+ */
+- (void)addLinkToURL:(NSURL *)url withRange:(NSRange)range;
+
+/**
+ Adds a link to an address for a specified range in the label text.
+ 
+ @param addressComponents A dictionary of address components for the address to be linked to
+ @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
+ 
+ @discussion The address component dictionary keys are described in `NSTextCheckingResult`'s "Keys for Address Components." 
+ */
+- (void)addLinkToAddress:(NSDictionary *)addressComponents withRange:(NSRange)range;
+
+/**
+ Adds a link to a phone number for a specified range in the label text.
+ 
+ @param phoneNumber The phone number to be linked to.
+ @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
+ */
+- (void)addLinkToPhoneNumber:(NSString *)phoneNumber withRange:(NSRange)range;
+
+/**
+ Adds a link to a date for a specified range in the label text.
+ 
+ @param date The date to be linked to.
+ @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
+ */
+- (void)addLinkToDate:(NSDate *)date withRange:(NSRange)range;
+
+/**
+ Adds a link to a date with a particular time zone and duration for a specified range in the label text.
+ 
+ @param date The date to be linked to.
+ @param timeZone The time zone of the specified date.
+ @param duration The duration, in seconds from the specified date.
+ @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
+ */
+- (void)addLinkToDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration withRange:(NSRange)range;
+
+@end
+
+/**
+ The `TTTAttributedLabelDelegate` protocol defines the messages sent to an attributed label delegate when links are tapped. All of the methods of this protocol are optional.
+ */
+@protocol TTTAttributedLabelDelegate <NSObject>
+
+///-----------------------------------
+/// @name Responding to Link Selection
+///-----------------------------------
+@optional
+
+/**
+ Tells the delegate that the user did select a link to a URL.
+ 
+ @param label The label whose link was selected.
+ @param url The URL for the selected link.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url;
+
+/**
+ Tells the delegate that the user did select a link to an address.
+ 
+ @param label The label whose link was selected.
+ @param addressComponents The components of the address for the selected link.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithAddress:(NSDictionary *)addressComponents;
+
+/**
+ Tells the delegate that the user did select a link to a phone number.
+ 
+ @param label The label whose link was selected.
+ @param phoneNumber The phone number for the selected link.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithPhoneNumber:(NSString *)phoneNumber;
+
+/**
+ Tells the delegate that the user did select a link to a date.
+ 
+ @param label The label whose link was selected.
+ @param date The datefor the selected link.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithDate:(NSDate *)date;
+
+/**
+ Tells the delegate that the user did select a link to a date with a time zone and duration.
+ 
+ @param label The label whose link was selected.
+ @param date The date for the selected link.
+ @param timeZone The time zone of the date for the selected link.
+ @param duration The duration, in seconds from the date for the selected link.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration;
+
+/**
+ Tells the delegate that the user did select a link to a text checking result.
+ 
+ @discussion This method is called if no other delegate method was called, which can occur by either now implementing the method in `TTTAttributedLabelDelegate` corresponding to a particular link, or the link was added by passing an instance of a custom `NSTextCheckingResult` subclass into `-addLinkWithTextCheckingResult:`.
+ 
+ @param label The label whose link was selected.
+ @param result The custom text checking result.
+ */
+- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTextCheckingResult:(NSTextCheckingResult *)result;
+
+@end
diff --git a/TTTAttributedLabel.m b/TTTAttributedLabel.m
new file mode 100755
index 0000000..d03b96d
--- /dev/null
+++ b/TTTAttributedLabel.m
@@ -0,0 +1,967 @@
+// TTTAttributedLabel.m
+//
+// Copyright (c) 2011 Mattt Thompson (http://mattt.me)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "TTTAttributedLabel.h"
+
+#define kTTTLineBreakWordWrapTextWidthScalingFactor (M_PI / M_E)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+NSString * const kTTTStrikeOutAttributeName = @"TTTStrikeOutAttribute";
+NSString * const kTTTBackgroundFillColorAttributeName = @"TTTBackgroundFillColor";
+NSString * const kTTTBackgroundStrokeColorAttributeName = @"TTTBackgroundStrokeColor";
+NSString * const kTTTBackgroundLineWidthAttributeName = @"TTTBackgroundLineWidth";
+NSString * const kTTTBackgroundCornerRadiusAttributeName = @"TTTBackgroundCornerRadius";
+
+static inline CTTextAlignment CTTextAlignmentFromUITextAlignment(UITextAlignment alignment) {
+	switch (alignment) {
+		case UITextAlignmentLeft: return kCTLeftTextAlignment;
+		case UITextAlignmentCenter: return kCTCenterTextAlignment;
+		case UITextAlignmentRight: return kCTRightTextAlignment;
+		default: return kCTNaturalTextAlignment;
+	}
+}
+
+static inline CTLineBreakMode CTLineBreakModeFromUILineBreakMode(UILineBreakMode lineBreakMode) {
+	switch (lineBreakMode) {
+		case UILineBreakModeWordWrap: return kCTLineBreakByWordWrapping;
+		case UILineBreakModeCharacterWrap: return kCTLineBreakByCharWrapping;
+		case UILineBreakModeClip: return kCTLineBreakByClipping;
+		case UILineBreakModeHeadTruncation: return kCTLineBreakByTruncatingHead;
+		case UILineBreakModeTailTruncation: return kCTLineBreakByTruncatingTail;
+		case UILineBreakModeMiddleTruncation: return kCTLineBreakByTruncatingMiddle;
+		default: return 0;
+	}
+}
+
+static inline NSTextCheckingType NSTextCheckingTypeFromUIDataDetectorType(UIDataDetectorTypes dataDetectorType) {
+    NSTextCheckingType textCheckingType = 0;
+    if (dataDetectorType & UIDataDetectorTypeAddress) {
+        textCheckingType |= NSTextCheckingTypeAddress;
+    }
+    
+    if (dataDetectorType & UIDataDetectorTypeCalendarEvent) {
+        textCheckingType |= NSTextCheckingTypeDate;
+    }
+    
+    if (dataDetectorType & UIDataDetectorTypeLink) {
+        textCheckingType |= NSTextCheckingTypeLink;
+    }
+    
+    if (dataDetectorType & UIDataDetectorTypePhoneNumber) {
+        textCheckingType |= NSTextCheckingTypePhoneNumber;
+    }
+    
+    return textCheckingType;
+}
+
+static inline NSDictionary * NSAttributedStringAttributesFromLabel(TTTAttributedLabel *label) {
+    NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionary]; 
+    
+    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)label.font.fontName, label.font.pointSize, NULL);
+    [mutableAttributes setObject:(__bridge id)font forKey:(NSString *)kCTFontAttributeName];
+    CFRelease(font);
+    
+    [mutableAttributes setObject:(id)[label.textColor CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
+    
+    CTTextAlignment alignment = CTTextAlignmentFromUITextAlignment(label.textAlignment);
+    CGFloat lineSpacing = label.leading;
+    CGFloat lineSpacingAdjustment = label.font.lineHeight - label.font.ascender + label.font.descender;
+    CGFloat lineHeightMultiple = label.lineHeightMultiple;
+    CGFloat topMargin = label.textInsets.top;
+    CGFloat bottomMargin = label.textInsets.bottom;
+    CGFloat leftMargin = label.textInsets.left;
+    CGFloat rightMargin = label.textInsets.right;
+    CGFloat firstLineIndent = label.firstLineIndent + leftMargin;
+
+    CTLineBreakMode lineBreakMode;
+    if (label.numberOfLines != 1) {
+        lineBreakMode = CTLineBreakModeFromUILineBreakMode(UILineBreakModeWordWrap);
+    } else {
+        lineBreakMode = CTLineBreakModeFromUILineBreakMode(label.lineBreakMode);
+    }
+	
+    CTParagraphStyleSetting paragraphStyles[10] = {
+		{.spec = kCTParagraphStyleSpecifierAlignment, .valueSize = sizeof(CTTextAlignment), .value = (const void *)&alignment},
+		{.spec = kCTParagraphStyleSpecifierLineBreakMode, .valueSize = sizeof(CTLineBreakMode), .value = (const void *)&lineBreakMode},
+        {.spec = kCTParagraphStyleSpecifierLineSpacing, .valueSize = sizeof(CGFloat), .value = (const void *)&lineSpacing},
+        {.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment, .valueSize = sizeof (CGFloat), .value = (const void *)&lineSpacingAdjustment},
+        {.spec = kCTParagraphStyleSpecifierLineHeightMultiple, .valueSize = sizeof(CGFloat), .value = (const void *)&lineHeightMultiple},
+        {.spec = kCTParagraphStyleSpecifierFirstLineHeadIndent, .valueSize = sizeof(CGFloat), .value = (const void *)&firstLineIndent},
+        {.spec = kCTParagraphStyleSpecifierParagraphSpacingBefore, .valueSize = sizeof(CGFloat), .value = (const void *)&topMargin},
+        {.spec = kCTParagraphStyleSpecifierParagraphSpacing, .valueSize = sizeof(CGFloat), .value = (const void *)&bottomMargin},
+        {.spec = kCTParagraphStyleSpecifierHeadIndent, .valueSize = sizeof(CGFloat), .value = (const void *)&leftMargin},
+        {.spec = kCTParagraphStyleSpecifierTailIndent, .valueSize = sizeof(CGFloat), .value = (const void *)&rightMargin}
+	};
+
+    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(paragraphStyles, 10);
+	[mutableAttributes setObject:(__bridge id)paragraphStyle forKey:(NSString *)kCTParagraphStyleAttributeName];
+	CFRelease(paragraphStyle);
+    
+    return [NSDictionary dictionaryWithDictionary:mutableAttributes];
+}
+
+static inline NSAttributedString * NSAttributedStringByScalingFontSize(NSAttributedString *attributedString, CGFloat scale, CGFloat minimumFontSize) {    
+    NSMutableAttributedString *mutableAttributedString = [attributedString mutableCopy];
+    [mutableAttributedString enumerateAttribute:(NSString *)kCTFontAttributeName inRange:NSMakeRange(0, [mutableAttributedString length]) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
+        CTFontRef font = (__bridge CTFontRef)value;
+        if (font) {
+            CGFloat scaledFontSize = floorf(CTFontGetSize(font) * scale);
+            CTFontRef scaledFont = CTFontCreateCopyWithAttributes(font, fmaxf(scaledFontSize, minimumFontSize), NULL, NULL);
+            CFAttributedStringSetAttribute((__bridge CFMutableAttributedStringRef)mutableAttributedString, CFRangeMake(range.location, range.length), kCTFontAttributeName, scaledFont);
+            CFRelease(scaledFont);
+        }
+    }];
+    
+    return mutableAttributedString;
+}
+
+static inline NSAttributedString * NSAttributedStringBySettingColorFromContext(NSAttributedString *attributedString, UIColor *color) {
+    if (!color) {
+        return attributedString;
+    }
+    
+    CGColorRef colorRef = color.CGColor;
+    NSMutableAttributedString *mutableAttributedString = [attributedString mutableCopy];    
+    [mutableAttributedString enumerateAttribute:(NSString *)kCTForegroundColorFromContextAttributeName inRange:NSMakeRange(0, [mutableAttributedString length]) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
+        CFBooleanRef usesColorFromContext = (__bridge CFBooleanRef)value;
+        if (usesColorFromContext && CFBooleanGetValue(usesColorFromContext)) {
+            CFRange updateRange = CFRangeMake(range.location, range.length);
+            CFAttributedStringSetAttribute((__bridge CFMutableAttributedStringRef)mutableAttributedString, updateRange, kCTForegroundColorAttributeName, colorRef);
+            CFAttributedStringRemoveAttribute((__bridge CFMutableAttributedStringRef)mutableAttributedString, updateRange, kCTForegroundColorFromContextAttributeName);
+        }
+    }];
+    
+    return mutableAttributedString;    
+}
+
+@interface TTTAttributedLabel ()
+@property (readwrite, nonatomic, copy) NSAttributedString *inactiveAttributedText;
+@property (readwrite, nonatomic, copy) NSAttributedString *renderedAttributedText;
+@property (readwrite, nonatomic, assign) CTFramesetterRef framesetter;
+@property (readwrite, nonatomic, assign) CTFramesetterRef highlightFramesetter;
+@property (readwrite, nonatomic, strong) NSDataDetector *dataDetector;
+@property (readwrite, nonatomic, strong) NSArray *links;
+@property (readwrite, nonatomic, strong) NSTextCheckingResult *activeLink;
+
+- (void)commonInit;
+- (void)setNeedsFramesetter;
+- (NSArray *)detectedLinksInString:(NSString *)string range:(NSRange)range error:(NSError **)error;
+- (NSTextCheckingResult *)linkAtCharacterIndex:(CFIndex)idx;
+- (NSTextCheckingResult *)linkAtPoint:(CGPoint)p;
+- (CFIndex)characterIndexAtPoint:(CGPoint)p;
+- (void)drawFramesetter:(CTFramesetterRef)framesetter textRange:(CFRange)textRange inRect:(CGRect)rect context:(CGContextRef)c;
+- (void)drawStrike:(CTFrameRef)frame inRect:(CGRect)rect context:(CGContextRef)c;
+@end
+
+@implementation TTTAttributedLabel {
+@private
+    BOOL _needsFramesetter;
+}
+
+@dynamic text;
+@synthesize attributedText = _attributedText;
+@synthesize inactiveAttributedText = _inactiveAttributedText;
+@synthesize renderedAttributedText = _renderedAttributedText;
+@synthesize framesetter = _framesetter;
+@synthesize highlightFramesetter = _highlightFramesetter;
+@synthesize delegate = _delegate;
+@synthesize dataDetectorTypes = _dataDetectorTypes;
+@synthesize dataDetector = _dataDetector;
+@synthesize links = _links;
+@synthesize linkAttributes = _linkAttributes;
+@synthesize activeLinkAttributes = _activeLinkAttributes;
+@synthesize shadowRadius = _shadowRadius;
+@synthesize leading = _leading;
+@synthesize lineHeightMultiple = _lineHeightMultiple;
+@synthesize firstLineIndent = _firstLineIndent;
+@synthesize textInsets = _textInsets;
+@synthesize verticalAlignment = _verticalAlignment;
+@synthesize activeLink = _activeLink;
+
+- (id)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (!self) {
+        return nil;
+    }
+    
+    [self commonInit];
+    
+    return self;
+}
+
+- (id)initWithCoder:(NSCoder *)coder {
+    self = [super initWithCoder:coder];
+    if (!self) {
+        return nil;
+    }
+    
+    [self commonInit];
+    
+    return self;
+}
+
+- (void)commonInit {
+    self.dataDetectorTypes = UIDataDetectorTypeNone;
+    self.links = [NSArray array];
+    
+    NSMutableDictionary *mutableLinkAttributes = [NSMutableDictionary dictionary];
+    [mutableLinkAttributes setValue:(id)[[UIColor blueColor] CGColor] forKey:(NSString*)kCTForegroundColorAttributeName];
+    [mutableLinkAttributes setValue:[NSNumber numberWithBool:YES] forKey:(NSString *)kCTUnderlineStyleAttributeName];
+    self.linkAttributes = [NSDictionary dictionaryWithDictionary:mutableLinkAttributes];
+    
+    NSMutableDictionary *mutableActiveLinkAttributes = [NSMutableDictionary dictionary];
+    [mutableActiveLinkAttributes setValue:(id)[[UIColor redColor] CGColor] forKey:(NSString*)kCTForegroundColorAttributeName];
+    [mutableActiveLinkAttributes setValue:[NSNumber numberWithBool:NO] forKey:(NSString *)kCTUnderlineStyleAttributeName];
+
+    self.activeLinkAttributes = [NSDictionary dictionaryWithDictionary:mutableActiveLinkAttributes];
+    
+    self.textInsets = UIEdgeInsetsZero;
+    
+    self.userInteractionEnabled = YES;
+    self.multipleTouchEnabled = NO;
+}
+
+- (void)dealloc {
+    if (_framesetter) CFRelease(_framesetter);
+    if (_highlightFramesetter) CFRelease(_highlightFramesetter);
+}
+
+#pragma mark -
+
+- (void)setAttributedText:(NSAttributedString *)text {
+    if ([text isEqualToAttributedString:_attributedText]) {
+        return;
+    }
+    
+    [self willChangeValueForKey:@"attributedText"];
+    _attributedText = [text copy];
+    [self didChangeValueForKey:@"attributedText"];
+    
+    [self setNeedsFramesetter];
+}
+
+- (void)setNeedsFramesetter {
+    // Reset the rendered attributed text so it has a chance to regenerate
+    self.renderedAttributedText = nil;
+
+    _needsFramesetter = YES;
+}
+
+- (CTFramesetterRef)framesetter {
+    if (_needsFramesetter) {
+        @synchronized(self) {
+            if (_framesetter) CFRelease(_framesetter);
+            if (_highlightFramesetter) CFRelease(_highlightFramesetter);
+            
+            self.framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.renderedAttributedText);
+            self.highlightFramesetter = nil;
+            _needsFramesetter = NO;
+        }
+    }
+    
+    return _framesetter;
+}
+
+- (NSAttributedString *)renderedAttributedText {
+    if (!_renderedAttributedText) {
+        self.renderedAttributedText = NSAttributedStringBySettingColorFromContext(self.attributedText, self.textColor);
+    }
+    
+    return _renderedAttributedText;
+}
+
+#pragma mark -
+
+- (void)setLinkActive:(BOOL)active withTextCheckingResult:(NSTextCheckingResult *)result {
+    if (result && [self.activeLinkAttributes count] > 0) {
+        if (active) {
+            if (!self.inactiveAttributedText) {
+                self.inactiveAttributedText = self.attributedText;
+            }
+            
+            NSMutableAttributedString *mutableAttributedString = [self.inactiveAttributedText mutableCopy];
+            [mutableAttributedString addAttributes:self.activeLinkAttributes range:result.range];
+            self.attributedText = mutableAttributedString;
+            
+            [self setNeedsDisplay];
+        } else {
+            if (self.inactiveAttributedText) {
+                self.attributedText = self.inactiveAttributedText;
+                self.inactiveAttributedText = nil;
+                
+                [self setNeedsDisplay];
+            }
+        }
+    }
+}
+
+#pragma mark -
+
+- (void)setDataDetectorTypes:(UIDataDetectorTypes)dataDetectorTypes {
+    [self willChangeValueForKey:@"dataDetectorTypes"];
+    _dataDetectorTypes = dataDetectorTypes;
+    [self didChangeValueForKey:@"dataDetectorTypes"];
+    
+    if (self.dataDetectorTypes != UIDataDetectorTypeNone) {
+        self.dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeFromUIDataDetectorType(self.dataDetectorTypes) error:nil];
+    }
+}
+
+- (NSArray *)detectedLinksInString:(NSString *)string range:(NSRange)range error:(NSError **)error {
+    if (!string || !self.dataDetector) {
+        return [NSArray array];
+    }
+    
+    return [self.dataDetector matchesInString:string options:0 range:range];
+}
+
+- (void)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result attributes:(NSDictionary *)attributes {
+    self.links = [self.links arrayByAddingObject:result];
+    
+    if (attributes) {
+        NSMutableAttributedString *mutableAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
+        [mutableAttributedString addAttributes:attributes range:result.range];
+        self.attributedText = mutableAttributedString;        
+    }
+}
+
+- (void)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result {
+    [self addLinkWithTextCheckingResult:result attributes:self.linkAttributes];
+}
+
+- (void)addLinkToURL:(NSURL *)url withRange:(NSRange)range {
+    [self addLinkWithTextCheckingResult:[NSTextCheckingResult linkCheckingResultWithRange:range URL:url]];
+}
+
+- (void)addLinkToAddress:(NSDictionary *)addressComponents withRange:(NSRange)range {
+    [self addLinkWithTextCheckingResult:[NSTextCheckingResult addressCheckingResultWithRange:range components:addressComponents]];
+}
+
+- (void)addLinkToPhoneNumber:(NSString *)phoneNumber withRange:(NSRange)range {
+    [self addLinkWithTextCheckingResult:[NSTextCheckingResult phoneNumberCheckingResultWithRange:range phoneNumber:phoneNumber]];
+}
+
+- (void)addLinkToDate:(NSDate *)date withRange:(NSRange)range {
+    [self addLinkWithTextCheckingResult:[NSTextCheckingResult dateCheckingResultWithRange:range date:date]];
+}
+
+- (void)addLinkToDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration withRange:(NSRange)range {
+    [self addLinkWithTextCheckingResult:[NSTextCheckingResult dateCheckingResultWithRange:range date:date timeZone:timeZone duration:duration]];
+}
+
+#pragma mark -
+
+- (NSTextCheckingResult *)linkAtCharacterIndex:(CFIndex)idx {
+    for (NSTextCheckingResult *result in self.links) {
+        NSRange range = result.range;
+        if ((CFIndex)range.location <= idx && idx <= (CFIndex)(range.location + range.length - 1)) {
+            return result;
+        }
+    }
+    
+    return nil;
+}
+
+- (NSTextCheckingResult *)linkAtPoint:(CGPoint)p {
+    CFIndex idx = [self characterIndexAtPoint:p];
+    return [self linkAtCharacterIndex:idx];
+}
+
+- (CFIndex)characterIndexAtPoint:(CGPoint)p {
+    if (!CGRectContainsPoint(self.bounds, p)) {
+        return NSNotFound;
+    }
+    
+    CGRect textRect = [self textRectForBounds:self.bounds limitedToNumberOfLines:self.numberOfLines];
+    if (!CGRectContainsPoint(textRect, p)) {
+        return NSNotFound;
+    }
+    
+    // Offset tap coordinates by textRect origin to make them relative to the origin of frame
+    p = CGPointMake(p.x - textRect.origin.x, p.y - textRect.origin.y);
+    // Convert tap coordinates (start at top left) to CT coordinates (start at bottom left)
+    p = CGPointMake(p.x, textRect.size.height - p.y);
+
+    CGMutablePathRef path = CGPathCreateMutable();
+    CGPathAddRect(path, NULL, textRect);
+    CTFrameRef frame = CTFramesetterCreateFrame(self.framesetter, CFRangeMake(0, [self.attributedText length]), path, NULL);
+    if (frame == NULL) {
+        CFRelease(path);
+        return NSNotFound;
+    }
+
+    CFArrayRef lines = CTFrameGetLines(frame);
+    NSInteger numberOfLines = self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);
+    if (numberOfLines == 0) {
+        CFRelease(frame);
+        CFRelease(path);
+        return NSNotFound;
+    }
+    
+    NSUInteger idx = NSNotFound;
+
+    CGPoint lineOrigins[numberOfLines];
+    CTFrameGetLineOrigins(frame, CFRangeMake(0, numberOfLines), lineOrigins);
+
+    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {
+        CGPoint lineOrigin = lineOrigins[lineIndex];
+        CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
+        
+        // Get bounding information of line
+        CGFloat ascent, descent, leading, width;
+        width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
+        CGFloat yMin = floor(lineOrigin.y - descent);
+        CGFloat yMax = ceil(lineOrigin.y + ascent);
+        
+        // Check if we've already passed the line
+        if (p.y > yMax) {
+            break;
+        }
+        // Check if the point is within this line vertically
+        if (p.y >= yMin) {
+            // Check if the point is within this line horizontally
+            if (p.x >= lineOrigin.x && p.x <= lineOrigin.x + width) {
+                // Convert CT coordinates to line-relative coordinates
+                CGPoint relativePoint = CGPointMake(p.x - lineOrigin.x, p.y - lineOrigin.y);
+                idx = CTLineGetStringIndexForPosition(line, relativePoint);
+                break;
+            }
+        }
+    }
+    
+    CFRelease(frame);
+    CFRelease(path);
+        
+    return idx;
+}
+
+- (void)drawFramesetter:(CTFramesetterRef)framesetter textRange:(CFRange)textRange inRect:(CGRect)rect context:(CGContextRef)c {
+    CGMutablePathRef path = CGPathCreateMutable();
+    CGPathAddRect(path, NULL, rect);
+    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, textRange, path, NULL);    
+    
+    [self drawBackground:frame inRect:rect context:c];
+    
+    CFArrayRef lines = CTFrameGetLines(frame);
+    NSInteger numberOfLines = self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);
+    BOOL truncateLastLine = (self.lineBreakMode == UILineBreakModeHeadTruncation || self.lineBreakMode == UILineBreakModeMiddleTruncation || self.lineBreakMode == UILineBreakModeTailTruncation);
+	
+    CGPoint lineOrigins[numberOfLines];
+    CTFrameGetLineOrigins(frame, CFRangeMake(0, numberOfLines), lineOrigins);
+        
+    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {
+        CGPoint lineOrigin = lineOrigins[lineIndex];
+        CGContextSetTextPosition(c, lineOrigin.x, lineOrigin.y);
+        CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
+        
+        if (lineIndex == numberOfLines - 1 && truncateLastLine) {
+            // Check if the range of text in the last line reaches the end of the full attributed string
+            CFRange lastLineRange = CTLineGetStringRange(line);
+            
+            if (!(lastLineRange.length == 0 && lastLineRange.location == 0) && lastLineRange.location + lastLineRange.length < textRange.location + textRange.length) {
+                // Get correct truncationType and attribute position
+                CTLineTruncationType truncationType;
+                NSUInteger truncationAttributePosition = lastLineRange.location;
+                UILineBreakMode lineBreakMode = self.lineBreakMode;
+                
+                // Multiple lines, only use UILineBreakModeTailTruncation
+                if (numberOfLines != 1) {
+                    lineBreakMode = UILineBreakModeTailTruncation;
+                }
+                
+                switch (lineBreakMode) {
+                    case UILineBreakModeHeadTruncation:
+                        truncationType = kCTLineTruncationStart;
+                        break;
+                    case UILineBreakModeMiddleTruncation:
+                        truncationType = kCTLineTruncationMiddle;
+                        truncationAttributePosition += (lastLineRange.length / 2);
+                        break;
+                    case UILineBreakModeTailTruncation:
+                    default:
+                        truncationType = kCTLineTruncationEnd;
+                        truncationAttributePosition += (lastLineRange.length - 1);
+                        break;
+                }
+                
+                // Get the attributes and use them to create the truncation token string
+                NSDictionary *tokenAttributes = [self.renderedAttributedText attributesAtIndex:truncationAttributePosition effectiveRange:NULL];
+                // \u2026 is the Unicode horizontal ellipsis character code
+                NSAttributedString *tokenString = [[NSAttributedString alloc] initWithString:@"\u2026" attributes:tokenAttributes];
+                CTLineRef truncationToken = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)tokenString);
+                
+                // Append truncationToken to the string
+                // because if string isn't too long, CT wont add the truncationToken on it's own
+                // There is no change of a double truncationToken because CT only add the token if it removes characters (and the one we add will go first)
+                NSMutableAttributedString *truncationString = [[self.renderedAttributedText attributedSubstringFromRange:NSMakeRange(lastLineRange.location, lastLineRange.length)] mutableCopy];
+                if (lastLineRange.length > 0) {
+                    // Remove any newline at the end (we don't want newline space between the text and the truncation token). There can only be one, because the second would be on the next line.
+                    unichar lastCharacter = [[truncationString string] characterAtIndex:lastLineRange.length - 1];
+                    if ([[NSCharacterSet newlineCharacterSet] characterIsMember:lastCharacter]) {
+                        [truncationString deleteCharactersInRange:NSMakeRange(lastLineRange.length - 1, 1)];
+                    }
+                }
+                [truncationString appendAttributedString:tokenString];
+                CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString);
+
+                // Truncate the line in case it is too long.
+                CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, rect.size.width, truncationType, truncationToken);
+                if (!truncatedLine) {
+                    // If the line is not as wide as the truncationToken, truncatedLine is NULL
+                    truncatedLine = CFRetain(truncationToken);
+                }
+                
+                CTLineDraw(truncatedLine, c);
+                
+                CFRelease(truncatedLine);
+                CFRelease(truncationLine);
+                CFRelease(truncationToken);
+            } else {
+                CTLineDraw(line, c);
+            }
+        } else {
+            CTLineDraw(line, c);
+        }
+    }
+    
+    [self drawStrike:frame inRect:rect context:c];
+        
+    CFRelease(frame);
+    CFRelease(path);    
+}
+
+- (void)drawBackground:(CTFrameRef)frame inRect:(CGRect)rect context:(CGContextRef)c {
+    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
+    CGPoint origins[[lines count]];
+    CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
+    
+    CFIndex lineIndex = 0;
+    for (id line in lines) {
+        CGRect lineBounds = CTLineGetImageBounds((__bridge CTLineRef)line, c);
+        lineBounds.origin.x = origins[lineIndex].x;
+        lineBounds.origin.y = origins[lineIndex].y;
+        
+        for (id glyphRun in (__bridge NSArray *)CTLineGetGlyphRuns((__bridge CTLineRef)line)) {
+            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes((__bridge CTRunRef) glyphRun);
+            CGColorRef strokeColor = (__bridge CGColorRef)[attributes objectForKey:kTTTBackgroundStrokeColorAttributeName];
+            CGColorRef fillColor = (__bridge CGColorRef)[attributes objectForKey:kTTTBackgroundFillColorAttributeName];
+            CGFloat cornerRadius = [[attributes objectForKey:kTTTBackgroundCornerRadiusAttributeName] floatValue];
+            CGFloat lineWidth = [[attributes objectForKey:kTTTBackgroundLineWidthAttributeName] floatValue];
+
+            if (strokeColor || fillColor) {
+                CGRect runBounds = CGRectZero;
+                CGFloat ascent = 0.0f;
+                CGFloat descent = 0.0f;
+                
+                runBounds.size.width = CTRunGetTypographicBounds((__bridge CTRunRef)glyphRun, CFRangeMake(0, 0), &ascent, &descent, NULL);
+                runBounds.size.height = ascent + descent;
+                
+                CGFloat xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, CTRunGetStringRange((__bridge CTRunRef)glyphRun).location, NULL);
+                runBounds.origin.x = origins[lineIndex].x + rect.origin.x + xOffset;
+                runBounds.origin.y = origins[lineIndex].y + rect.origin.y;
+                runBounds.origin.y -= descent;
+                
+                // Don't draw higlightedLinkBackground too far to the right
+                if (CGRectGetWidth(runBounds) > CGRectGetWidth(lineBounds)) {
+                    runBounds.size.width = CGRectGetWidth(lineBounds);
+                }
+                
+                CGRect rect = CGRectInset(CGRectInset(runBounds, -1.0f, -3.0f), lineWidth, lineWidth);
+                CGPathRef path = [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius] CGPath];
+                
+                CGContextSetLineJoin(c, kCGLineJoinRound);
+                
+                if (fillColor) {
+                    CGContextSetFillColorWithColor(c, fillColor);
+                    CGContextAddPath(c, path);
+                    CGContextFillPath(c);
+                }
+                
+                if (strokeColor) {
+                    CGContextSetStrokeColorWithColor(c, strokeColor);
+                    CGContextAddPath(c, path);
+                    CGContextStrokePath(c);
+                }
+            }
+        }
+        
+        lineIndex++;
+    }
+}
+
+- (void)drawStrike:(CTFrameRef)frame inRect:(CGRect)rect context:(CGContextRef)c {
+    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
+    CGPoint origins[[lines count]];
+    CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
+    
+    CFIndex lineIndex = 0;
+    for (id line in lines) {        
+        CGRect lineBounds = CTLineGetImageBounds((__bridge CTLineRef)line, c);
+        lineBounds.origin.x = origins[lineIndex].x;
+        lineBounds.origin.y = origins[lineIndex].y;
+        
+        for (id glyphRun in (__bridge NSArray *)CTLineGetGlyphRuns((__bridge CTLineRef)line)) {
+            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes((__bridge CTRunRef) glyphRun);
+            BOOL strikeOut = [[attributes objectForKey:kTTTStrikeOutAttributeName] boolValue];
+            NSInteger superscriptStyle = [[attributes objectForKey:(id)kCTSuperscriptAttributeName] integerValue];
+            
+            if (strikeOut) {
+                CGRect runBounds = CGRectZero;
+                CGFloat ascent = 0.0f;
+                CGFloat descent = 0.0f;
+                
+                runBounds.size.width = CTRunGetTypographicBounds((__bridge CTRunRef)glyphRun, CFRangeMake(0, 0), &ascent, &descent, NULL);
+                runBounds.size.height = ascent + descent;
+                
+                CGFloat xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, CTRunGetStringRange((__bridge CTRunRef)glyphRun).location, NULL);
+                runBounds.origin.x = origins[lineIndex].x + rect.origin.x + xOffset;
+                runBounds.origin.y = origins[lineIndex].y + rect.origin.y;
+                runBounds.origin.y -= descent;
+                
+                // Don't draw strikeout too far to the right
+                if (CGRectGetWidth(runBounds) > CGRectGetWidth(lineBounds)) {
+                    runBounds.size.width = CGRectGetWidth(lineBounds);
+                }
+                
+				switch (superscriptStyle) {
+					case 1:
+						runBounds.origin.y -= ascent * 0.47f;
+						break;
+					case -1:
+						runBounds.origin.y += ascent * 0.25f;
+						break;
+					default:
+						break;
+				}
+                
+                // Use text color, or default to black
+                id color = [attributes objectForKey:(id)kCTForegroundColorAttributeName];
+
+                if (color) {
+                    CGContextSetStrokeColorWithColor(c, (__bridge CGColorRef)color);
+                } else {
+                    CGContextSetGrayStrokeColor(c, 0.0f, 1.0);
+                }
+                
+                CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)self.font.fontName, self.font.pointSize, NULL);
+                CGContextSetLineWidth(c, CTFontGetUnderlineThickness(font));
+                CGFloat y = roundf(runBounds.origin.y + runBounds.size.height / 2.0f);
+                CGContextMoveToPoint(c, runBounds.origin.x, y);
+                CGContextAddLineToPoint(c, runBounds.origin.x + runBounds.size.width, y);
+                
+                CGContextStrokePath(c);
+            }
+        }
+        
+        lineIndex++;
+    }
+}
+
+#pragma mark - TTTAttributedLabel
+
+- (void)setText:(id)text {
+    if ([text isKindOfClass:[NSString class]]) {
+        [self setText:text afterInheritingLabelAttributesAndConfiguringWithBlock:nil];
+        return;
+    }
+    
+    self.attributedText = text;
+
+    self.links = [NSArray array];
+    if (self.dataDetectorTypes != UIDataDetectorTypeNone) {
+        for (NSTextCheckingResult *result in [self detectedLinksInString:[self.attributedText string] range:NSMakeRange(0, [text length]) error:nil]) {
+            [self addLinkWithTextCheckingResult:result];
+        }
+    }
+        
+    [super setText:[self.attributedText string]];
+}
+
+- (void)setText:(id)text afterInheritingLabelAttributesAndConfiguringWithBlock:(NSMutableAttributedString *(^)(NSMutableAttributedString *mutableAttributedString))block {    
+    NSMutableAttributedString *mutableAttributedString = nil;
+    if ([text isKindOfClass:[NSString class]]) {
+        mutableAttributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:NSAttributedStringAttributesFromLabel(self)];
+    } else {
+        mutableAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:text];
+        [mutableAttributedString addAttributes:NSAttributedStringAttributesFromLabel(self) range:NSMakeRange(0, [mutableAttributedString length])];
+    }
+    
+    if (block) {
+        mutableAttributedString = block(mutableAttributedString);
+    }
+    
+    [self setText:mutableAttributedString];
+}
+
+#pragma mark - UILabel
+
+- (void)setHighlighted:(BOOL)highlighted {
+    [super setHighlighted:highlighted];
+    [self setNeedsDisplay];
+}
+
+// Fixes crash when loading from a UIStoryboard
+- (UIColor *)textColor {
+	UIColor *color = [super textColor];
+	if (!color) {
+		color = [UIColor blackColor];
+	}
+	
+	return color;
+}
+
+- (void)setTextColor:(UIColor *)textColor {
+    UIColor *oldTextColor = self.textColor;
+    [super setTextColor:textColor];
+
+    // Redraw to allow any ColorFromContext attributes a chance to update
+    if (textColor != oldTextColor) {
+        [self setNeedsFramesetter];
+        [self setNeedsDisplay];
+    }
+}
+
+- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
+    if (!self.attributedText) {
+        return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
+    }
+        
+    CGRect textRect = bounds;
+    
+    // Adjust the text to be in the center vertically, if the text size is smaller than bounds
+    CGSize textSize = CTFramesetterSuggestFrameSizeWithConstraints(self.framesetter, CFRangeMake(0, [self.attributedText length]), NULL, bounds.size, NULL);
+    textSize = CGSizeMake(ceilf(textSize.width), ceilf(textSize.height)); // Fix for iOS 4, CTFramesetterSuggestFrameSizeWithConstraints sometimes returns fractional sizes
+    
+    if (textSize.height < textRect.size.height) {
+        CGFloat heightChange = (textRect.size.height - textSize.height);
+        CGFloat yOffset = 0.0f;
+        switch (self.verticalAlignment) {
+            case TTTAttributedLabelVerticalAlignmentTop:
+                heightChange = 0.0f;
+                break;
+            case TTTAttributedLabelVerticalAlignmentCenter:
+                yOffset = floorf((textRect.size.height - textSize.height) / 2.0f);
+                break;
+            case TTTAttributedLabelVerticalAlignmentBottom:
+                yOffset = textRect.size.height - textSize.height;
+                break;
+        }
+        
+        textRect.origin.y += yOffset;
+        textRect.size = CGSizeMake(textRect.size.width, textRect.size.height - heightChange + yOffset);
+    }
+    
+    return textRect;
+}
+
+- (void)drawTextInRect:(CGRect)rect {
+    if (!self.attributedText) {
+        [super drawTextInRect:rect];
+        return;
+    }
+        
+    NSAttributedString *originalAttributedText = nil;
+    
+    // Adjust the font size to fit width, if necessarry 
+    if (self.adjustsFontSizeToFitWidth && self.numberOfLines > 0) {
+        CGFloat textWidth = [self sizeThatFits:CGSizeZero].width;
+        CGFloat availableWidth = self.frame.size.width * self.numberOfLines;
+        if (self.numberOfLines > 1 && self.lineBreakMode == UILineBreakModeWordWrap) {
+            textWidth *= kTTTLineBreakWordWrapTextWidthScalingFactor;
+        }
+        
+        if (textWidth > availableWidth && textWidth > 0.0f) {
+            originalAttributedText = [self.attributedText copy];
+            self.text = NSAttributedStringByScalingFontSize(self.attributedText, availableWidth / textWidth, self.minimumFontSize);
+        }
+    }
+    
+    CGContextRef c = UIGraphicsGetCurrentContext();
+    CGContextSetTextMatrix(c, CGAffineTransformIdentity);
+
+    // Inverts the CTM to match iOS coordinates (otherwise text draws upside-down; Mac OS's system is different)
+    CGContextTranslateCTM(c, 0.0f, rect.size.height);
+    CGContextScaleCTM(c, 1.0f, -1.0f);
+    
+    CFRange textRange = CFRangeMake(0, [self.attributedText length]);
+
+    // First, get the text rect (which takes vertical centering into account)
+    CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines];
+
+    // CoreText draws it's text aligned to the bottom, so we move the CTM here to take our vertical offsets into account
+    CGContextTranslateCTM(c, 0.0f, rect.size.height - textRect.origin.y - textRect.size.height);
+
+    // Second, trace the shadow before the actual text, if we have one
+    if (self.shadowColor && !self.highlighted) {
+        CGContextSetShadowWithColor(c, self.shadowOffset, self.shadowRadius, [self.shadowColor CGColor]);
+    }
+    
+    // Finally, draw the text or highlighted text itself (on top of the shadow, if there is one)
+    if (self.highlightedTextColor && self.highlighted) {
+        if (!self.highlightFramesetter) {
+            NSMutableAttributedString *mutableAttributedString = [self.renderedAttributedText mutableCopy];
+            [mutableAttributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)[self.highlightedTextColor CGColor] range:NSMakeRange(0, mutableAttributedString.length)];
+            self.highlightFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)mutableAttributedString);
+        }
+        
+        [self drawFramesetter:self.highlightFramesetter textRange:textRange inRect:textRect context:c];
+    } else {
+        [self drawFramesetter:self.framesetter textRange:textRange inRect:textRect context:c];
+    }  
+    
+    // If we adjusted the font size, set it back to its original size
+    if (originalAttributedText) {
+        self.text = originalAttributedText;
+    }
+}
+
+#pragma mark - UIView
+
+- (CGSize)sizeThatFits:(CGSize)size {
+    if (!self.attributedText) {
+        return [super sizeThatFits:size];
+    }
+    
+    CFRange rangeToSize = CFRangeMake(0, [self.attributedText length]);
+    CGSize constraints = CGSizeMake(size.width, CGFLOAT_MAX);
+    
+    if (self.numberOfLines == 1) {
+        // If there is one line, the size that fits is the full width of the line
+        constraints = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
+    } else if (self.numberOfLines > 0) {
+        // If the line count of the label more than 1, limit the range to size to the number of lines that have been set
+        CGMutablePathRef path = CGPathCreateMutable();
+        CGPathAddRect(path, NULL, CGRectMake(0.0f, 0.0f, constraints.width, CGFLOAT_MAX));
+        CTFrameRef frame = CTFramesetterCreateFrame(self.framesetter, CFRangeMake(0, 0), path, NULL);
+        CFArrayRef lines = CTFrameGetLines(frame);
+        
+        if (CFArrayGetCount(lines) > 0) {
+            NSInteger lastVisibleLineIndex = MIN(self.numberOfLines, CFArrayGetCount(lines)) - 1;
+            CTLineRef lastVisibleLine = CFArrayGetValueAtIndex(lines, lastVisibleLineIndex);
+            
+            CFRange rangeToLayout = CTLineGetStringRange(lastVisibleLine);
+            rangeToSize = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length);
+        }
+        
+        CFRelease(frame);
+        CFRelease(path);
+    }
+    
+    CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(self.framesetter, rangeToSize, NULL, constraints, NULL);
+    
+    return CGSizeMake(ceilf(suggestedSize.width), ceilf(suggestedSize.height));
+}
+
+#pragma mark - UIResponder
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+    UITouch *touch = [touches anyObject];
+    
+    self.activeLink = [self linkAtPoint:[touch locationInView:self]];
+        
+    if (self.activeLink) {
+        [self setLinkActive:YES withTextCheckingResult:self.activeLink];
+    } else {
+        [super touchesBegan:touches withEvent:event];
+    }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {    
+    if (self.activeLink) {
+        UITouch *touch = [touches anyObject];
+        
+        if (self.activeLink != [self linkAtPoint:[touch locationInView:self]]) {
+            [self setLinkActive:NO withTextCheckingResult:self.activeLink];
+        } else {
+            [self setLinkActive:YES withTextCheckingResult:self.activeLink];
+        }
+    } else {
+        [super touchesMoved:touches withEvent:event];
+    }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+    if (self.activeLink) {
+        UITouch *touch = [touches anyObject];
+        if (self.activeLink == [self linkAtPoint:[touch locationInView:self]]) {
+            [self setLinkActive:NO withTextCheckingResult:self.activeLink];
+            
+            if (!self.delegate) {
+                return;
+            }
+            
+            NSTextCheckingResult *result = self.activeLink;
+            switch (result.resultType) {
+                case NSTextCheckingTypeLink:
+                    if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithURL:)]) {
+                        [self.delegate attributedLabel:self didSelectLinkWithURL:result.URL];
+                        return;
+                    }
+                    break;
+                case NSTextCheckingTypeAddress:
+                    if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithAddress:)]) {
+                        [self.delegate attributedLabel:self didSelectLinkWithAddress:result.addressComponents];
+                        return;
+                    }
+                    break;
+                case NSTextCheckingTypePhoneNumber:
+                    if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithPhoneNumber:)]) {
+                        [self.delegate attributedLabel:self didSelectLinkWithPhoneNumber:result.phoneNumber];
+                        return;
+                    }
+                    break;
+                case NSTextCheckingTypeDate:
+                    if (result.timeZone && [self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:timeZone:duration:)]) {
+                        [self.delegate attributedLabel:self didSelectLinkWithDate:result.date timeZone:result.timeZone duration:result.duration];
+                        return;
+                    } else if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:)]) {
+                        [self.delegate attributedLabel:self didSelectLinkWithDate:result.date];
+                        return;
+                    }
+                    break;
+                default:
+                    break;
+            }
+            
+            // Fallback to `attributedLabel:didSelectLinkWithTextCheckingResult:` if no other delegate method matched.
+            if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithTextCheckingResult:)]) {
+                [self.delegate attributedLabel:self didSelectLinkWithTextCheckingResult:result];
+            }
+        }
+    } else {
+        [super touchesEnded:touches withEvent:event];
+    }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+    if (self.activeLink) {
+        [self setLinkActive:NO withTextCheckingResult:self.activeLink];
+    } else {
+        [super touchesCancelled:touches withEvent:event];
+    }
+}
+
+@end
+
+#pragma clang diagnostic pop
