Project import
diff --git a/LICENCE.txt b/LICENCE.txt
new file mode 100644
index 0000000..12b7844
--- /dev/null
+++ b/LICENCE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2011-2013, Tony Million.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4814e6d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,75 @@
+[![Reference Status](https://www.versioneye.com/objective-c/reachability/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/reachability/references)
+
+# Reachability
+
+This is a drop-in replacement for Apple's `Reachability` class. It is ARC-compatible, and it uses the new GCD methods to notify of network interface changes.
+
+In addition to the standard `NSNotification`, it supports the use of blocks for when the network becomes reachable and unreachable.
+
+Finally, you can specify whether a WWAN connection is considered "reachable".
+
+*DO NOT OPEN BUGS UNTIL YOU HAVE TESTED ON DEVICE*
+
+## Requirements
+
+Once you have added the `.h/m` files to your project, simply:
+
+* Go to the `Project->TARGETS->Build Phases->Link Binary With Libraries`.
+* Press the plus in the lower left of the list.
+* Add `SystemConfiguration.framework`.
+
+Boom, you're done.
+
+## Examples
+
+### Block Example
+
+This sample uses blocks to notify when the interface state has changed. The blocks will be called on a **BACKGROUND THREAD**, so you need to dispatch UI updates onto the main thread.
+
+	// Allocate a reachability object
+	Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];
+
+	// Set the blocks
+	reach.reachableBlock = ^(Reachability*reach)
+	{
+		// keep in mind this is called on a background thread
+		// and if you are updating the UI it needs to happen
+		// on the main thread, like this:
+
+		dispatch_async(dispatch_get_main_queue(), ^{
+		  NSLog(@"REACHABLE!");
+		});
+	};
+
+	reach.unreachableBlock = ^(Reachability*reach)
+	{
+		NSLog(@"UNREACHABLE!");
+	};
+
+	// Start the notifier, which will cause the reachability object to retain itself!
+	[reach startNotifier];
+
+### `NSNotification` Example
+
+This sample will use `NSNotification`s to notify when the interface has changed. They will be delivered on the **MAIN THREAD**, so you *can* do UI updates from within the function.
+
+In addition, it asks the `Reachability` object to consider the WWAN (3G/EDGE/CDMA) as a non-reachable connection (you might use this if you are writing a video streaming app, for example, to save the user's data plan).
+
+	// Allocate a reachability object
+	Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];
+
+	// Tell the reachability that we DON'T want to be reachable on 3G/EDGE/CDMA
+	reach.reachableOnWWAN = NO;
+
+	// Here we set up a NSNotification observer. The Reachability that caused the notification
+	// is passed in the object parameter
+	[[NSNotificationCenter defaultCenter] addObserver:self
+											 selector:@selector(reachabilityChanged:)
+												 name:kReachabilityChangedNotification
+											   object:nil];
+
+	[reach startNotifier];
+
+## Tell the world
+
+Head over to [Projects using Reachability](https://github.com/tonymillion/Reachability/wiki/Projects-using-Reachability) and add your project for "Maximum Wins!".
diff --git a/Reachability.h b/Reachability.h
new file mode 100644
index 0000000..c432152
--- /dev/null
+++ b/Reachability.h
@@ -0,0 +1,95 @@
+/*
+ Copyright (c) 2011, Tony Million.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+
+
+/** 
+ * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
+ *
+ * @see http://nshipster.com/ns_enum-ns_options/
+ **/
+#ifndef NS_ENUM
+#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#endif
+
+extern NSString *const kReachabilityChangedNotification;
+
+typedef NS_ENUM(NSInteger, NetworkStatus) {
+    // Apple NetworkStatus Compatible Names.
+    NotReachable = 0,
+    ReachableViaWiFi = 2,
+    ReachableViaWWAN = 1
+};
+
+@class Reachability;
+
+typedef void (^NetworkReachable)(Reachability * reachability);
+typedef void (^NetworkUnreachable)(Reachability * reachability);
+
+
+@interface Reachability : NSObject
+
+@property (nonatomic, copy) NetworkReachable    reachableBlock;
+@property (nonatomic, copy) NetworkUnreachable  unreachableBlock;
+
+@property (nonatomic, assign) BOOL reachableOnWWAN;
+
+
++(Reachability*)reachabilityWithHostname:(NSString*)hostname;
+// This is identical to the function above, but is here to maintain
+//compatibility with Apples original code. (see .m)
++(Reachability*)reachabilityWithHostName:(NSString*)hostname;
++(Reachability*)reachabilityForInternetConnection;
++(Reachability*)reachabilityWithAddress:(void *)hostAddress;
++(Reachability*)reachabilityForLocalWiFi;
+
+-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
+
+-(BOOL)startNotifier;
+-(void)stopNotifier;
+
+-(BOOL)isReachable;
+-(BOOL)isReachableViaWWAN;
+-(BOOL)isReachableViaWiFi;
+
+// WWAN may be available, but not active until a connection has been established.
+// WiFi may require a connection for VPN on Demand.
+-(BOOL)isConnectionRequired; // Identical DDG variant.
+-(BOOL)connectionRequired; // Apple's routine.
+// Dynamic, on demand connection?
+-(BOOL)isConnectionOnDemand;
+// Is user intervention required?
+-(BOOL)isInterventionRequired;
+
+-(NetworkStatus)currentReachabilityStatus;
+-(SCNetworkReachabilityFlags)reachabilityFlags;
+-(NSString*)currentReachabilityString;
+-(NSString*)currentReachabilityFlags;
+
+@end
diff --git a/Reachability.m b/Reachability.m
new file mode 100644
index 0000000..f2952d9
--- /dev/null
+++ b/Reachability.m
@@ -0,0 +1,469 @@
+/*
+ Copyright (c) 2011, Tony Million.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#import "Reachability.h"
+
+#import <sys/socket.h>
+#import <netinet/in.h>
+#import <netinet6/in6.h>
+#import <arpa/inet.h>
+#import <ifaddrs.h>
+#import <netdb.h>
+
+
+NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";
+
+
+@interface Reachability ()
+
+@property (nonatomic, assign) SCNetworkReachabilityRef  reachabilityRef;
+@property (nonatomic, strong) dispatch_queue_t          reachabilitySerialQueue;
+@property (nonatomic, strong) id                        reachabilityObject;
+
+-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
+-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;
+
+@end
+
+
+static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) 
+{
+    return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
+#if	TARGET_OS_IPHONE
+            (flags & kSCNetworkReachabilityFlagsIsWWAN)               ? 'W' : '-',
+#else
+            'X',
+#endif
+            (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
+            (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
+            (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
+            (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+            (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
+            (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
+            (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
+            (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-'];
+}
+
+// Start listening for reachability notifications on the current run loop
+static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) 
+{
+#pragma unused (target)
+
+    Reachability *reachability = ((__bridge Reachability*)info);
+
+    // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
+    // but what the heck eh?
+    @autoreleasepool 
+    {
+        [reachability reachabilityChanged:flags];
+    }
+}
+
+
+@implementation Reachability
+
+#pragma mark - Class Constructor Methods
+
++(Reachability*)reachabilityWithHostName:(NSString*)hostname
+{
+    return [Reachability reachabilityWithHostname:hostname];
+}
+
++(Reachability*)reachabilityWithHostname:(NSString*)hostname
+{
+    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
+    if (ref) 
+    {
+        id reachability = [[self alloc] initWithReachabilityRef:ref];
+
+        return reachability;
+    }
+    
+    return nil;
+}
+
++(Reachability *)reachabilityWithAddress:(void *)hostAddress
+{
+    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
+    if (ref) 
+    {
+        id reachability = [[self alloc] initWithReachabilityRef:ref];
+        
+        return reachability;
+    }
+    
+    return nil;
+}
+
++(Reachability *)reachabilityForInternetConnection 
+{   
+    struct sockaddr_in zeroAddress;
+    bzero(&zeroAddress, sizeof(zeroAddress));
+    zeroAddress.sin_len = sizeof(zeroAddress);
+    zeroAddress.sin_family = AF_INET;
+    
+    return [self reachabilityWithAddress:&zeroAddress];
+}
+
++(Reachability*)reachabilityForLocalWiFi
+{
+    struct sockaddr_in localWifiAddress;
+    bzero(&localWifiAddress, sizeof(localWifiAddress));
+    localWifiAddress.sin_len            = sizeof(localWifiAddress);
+    localWifiAddress.sin_family         = AF_INET;
+    // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
+    localWifiAddress.sin_addr.s_addr    = htonl(IN_LINKLOCALNETNUM);
+    
+    return [self reachabilityWithAddress:&localWifiAddress];
+}
+
+
+// Initialization methods
+
+-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref 
+{
+    self = [super init];
+    if (self != nil) 
+    {
+        self.reachableOnWWAN = YES;
+        self.reachabilityRef = ref;
+
+        // We need to create a serial queue.
+        // We allocate this once for the lifetime of the notifier.
+
+        self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
+    }
+    
+    return self;    
+}
+
+-(void)dealloc
+{
+    [self stopNotifier];
+
+    if(self.reachabilityRef)
+    {
+        CFRelease(self.reachabilityRef);
+        self.reachabilityRef = nil;
+    }
+
+	self.reachableBlock          = nil;
+	self.unreachableBlock        = nil;
+    self.reachabilitySerialQueue = nil;
+}
+
+#pragma mark - Notifier Methods
+
+// Notifier 
+// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
+// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
+//   INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)
+
+-(BOOL)startNotifier
+{
+    // allow start notifier to be called multiple times
+    if(self.reachabilityObject && (self.reachabilityObject == self))
+    {
+        return YES;
+    }
+
+
+    SCNetworkReachabilityContext    context = { 0, NULL, NULL, NULL, NULL };
+    context.info = (__bridge void *)self;
+
+    if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))
+    {
+        // Set it as our reachability queue, which will retain the queue
+        if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
+        {
+            // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
+            // woah
+            self.reachabilityObject = self;
+            return YES;
+        }
+        else
+        {
+#ifdef DEBUG
+            NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
+#endif
+
+            // UH OH - FAILURE - stop any callbacks!
+            SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
+        }
+    }
+    else
+    {
+#ifdef DEBUG
+        NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
+#endif
+    }
+
+    // if we get here we fail at the internet
+    self.reachabilityObject = nil;
+    return NO;
+}
+
+-(void)stopNotifier
+{
+    // First stop, any callbacks!
+    SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
+    
+    // Unregister target from the GCD serial dispatch queue.
+    SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);
+
+    self.reachabilityObject = nil;
+}
+
+#pragma mark - reachability tests
+
+// This is for the case where you flick the airplane mode;
+// you end up getting something like this:
+//Reachability: WR ct-----
+//Reachability: -- -------
+//Reachability: WR ct-----
+//Reachability: -- -------
+// We treat this as 4 UNREACHABLE triggers - really apple should do better than this
+
+#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
+
+-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
+{
+    BOOL connectionUP = YES;
+    
+    if(!(flags & kSCNetworkReachabilityFlagsReachable))
+        connectionUP = NO;
+    
+    if( (flags & testcase) == testcase )
+        connectionUP = NO;
+    
+#if	TARGET_OS_IPHONE
+    if(flags & kSCNetworkReachabilityFlagsIsWWAN)
+    {
+        // We're on 3G.
+        if(!self.reachableOnWWAN)
+        {
+            // We don't want to connect when on 3G.
+            connectionUP = NO;
+        }
+    }
+#endif
+    
+    return connectionUP;
+}
+
+-(BOOL)isReachable
+{
+    SCNetworkReachabilityFlags flags;  
+    
+    if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+        return NO;
+    
+    return [self isReachableWithFlags:flags];
+}
+
+-(BOOL)isReachableViaWWAN 
+{
+#if	TARGET_OS_IPHONE
+
+    SCNetworkReachabilityFlags flags = 0;
+    
+    if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+    {
+        // Check we're REACHABLE
+        if(flags & kSCNetworkReachabilityFlagsReachable)
+        {
+            // Now, check we're on WWAN
+            if(flags & kSCNetworkReachabilityFlagsIsWWAN)
+            {
+                return YES;
+            }
+        }
+    }
+#endif
+    
+    return NO;
+}
+
+-(BOOL)isReachableViaWiFi 
+{
+    SCNetworkReachabilityFlags flags = 0;
+    
+    if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+    {
+        // Check we're reachable
+        if((flags & kSCNetworkReachabilityFlagsReachable))
+        {
+#if	TARGET_OS_IPHONE
+            // Check we're NOT on WWAN
+            if((flags & kSCNetworkReachabilityFlagsIsWWAN))
+            {
+                return NO;
+            }
+#endif
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+
+// WWAN may be available, but not active until a connection has been established.
+// WiFi may require a connection for VPN on Demand.
+-(BOOL)isConnectionRequired
+{
+    return [self connectionRequired];
+}
+
+-(BOOL)connectionRequired
+{
+    SCNetworkReachabilityFlags flags;
+	
+	if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+    {
+		return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
+	}
+    
+    return NO;
+}
+
+// Dynamic, on demand connection?
+-(BOOL)isConnectionOnDemand
+{
+	SCNetworkReachabilityFlags flags;
+	
+	if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+    {
+		return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
+				(flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
+	}
+	
+	return NO;
+}
+
+// Is user intervention required?
+-(BOOL)isInterventionRequired
+{
+    SCNetworkReachabilityFlags flags;
+	
+	if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
+    {
+		return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
+				(flags & kSCNetworkReachabilityFlagsInterventionRequired));
+	}
+	
+	return NO;
+}
+
+
+#pragma mark - reachability status stuff
+
+-(NetworkStatus)currentReachabilityStatus
+{
+    if([self isReachable])
+    {
+        if([self isReachableViaWiFi])
+            return ReachableViaWiFi;
+        
+#if	TARGET_OS_IPHONE
+        return ReachableViaWWAN;
+#endif
+    }
+    
+    return NotReachable;
+}
+
+-(SCNetworkReachabilityFlags)reachabilityFlags
+{
+    SCNetworkReachabilityFlags flags = 0;
+    
+    if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 
+    {
+        return flags;
+    }
+    
+    return 0;
+}
+
+-(NSString*)currentReachabilityString
+{
+	NetworkStatus temp = [self currentReachabilityStatus];
+	
+	if(temp == ReachableViaWWAN)
+	{
+        // Updated for the fact that we have CDMA phones now!
+		return NSLocalizedString(@"Cellular", @"");
+	}
+	if (temp == ReachableViaWiFi) 
+	{
+		return NSLocalizedString(@"WiFi", @"");
+	}
+	
+	return NSLocalizedString(@"No Connection", @"");
+}
+
+-(NSString*)currentReachabilityFlags
+{
+    return reachabilityFlags([self reachabilityFlags]);
+}
+
+#pragma mark - Callback function calls this method
+
+-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
+{
+    if([self isReachableWithFlags:flags])
+    {
+        if(self.reachableBlock)
+        {
+            self.reachableBlock(self);
+        }
+    }
+    else
+    {
+        if(self.unreachableBlock)
+        {
+            self.unreachableBlock(self);
+        }
+    }
+    
+    // this makes sure the change notification happens on the MAIN THREAD
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification 
+                                                            object:self];
+    });
+}
+
+#pragma mark - Debug Description
+
+- (NSString *) description
+{
+    NSString *description = [NSString stringWithFormat:@"<%@: %#x (%@)>",
+                             NSStringFromClass([self class]), (unsigned int) self, [self currentReachabilityFlags]];
+    return description;
+}
+
+@end