Project import
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..56cda91
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,19 @@
+**Copyright (c) 2012 - 2014, GitHub, Inc.**
+**All rights reserved.**
+
+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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c919c15
--- /dev/null
+++ b/README.md
@@ -0,0 +1,562 @@
+# ReactiveCocoa
+
+ReactiveCocoa (RAC) is an Objective-C framework for [Functional Reactive
+Programming][]. It provides APIs for **composing and transforming streams of
+values**.
+
+If you're already familiar with functional reactive programming or know the basic
+premise of ReactiveCocoa, check out the [Documentation][] folder for a framework
+overview and more in-depth information about how it all works in practice.
+
+## New to ReactiveCocoa?
+
+ReactiveCocoa is documented like crazy, and there's a wealth of introductory
+material available to explain what RAC is and how you can use it.
+
+If you want to learn more, we recommend these resources, roughly in order:
+
+ 1. [Introduction](#introduction)
+ 1. [When to use ReactiveCocoa](#when-to-use-reactivecocoa)
+ 1. [Framework Overview][]
+ 1. [Basic Operators][]
+ 1. [Header documentation](ReactiveCocoaFramework/ReactiveCocoa)
+ 1. Previously answered [Stack Overflow](https://github.com/ReactiveCocoa/ReactiveCocoa/wiki)
+    questions and [GitHub issues](https://github.com/ReactiveCocoa/ReactiveCocoa/issues?labels=question&state=closed)
+ 1. The rest of the [Documentation][] folder
+ 1. [Functional Reactive Programming on iOS](https://leanpub.com/iosfrp/) 
+    (eBook)
+ 
+If you have any further questions, please feel free to [file an issue](https://github.com/ReactiveCocoa/ReactiveCocoa/issues/new). 
+
+## Introduction
+
+ReactiveCocoa is an implementation of [functional reactive
+programming](http://blog.maybeapps.com/post/42894317939/input-and-output).
+Rather than using mutable variables which are replaced and modified in-place,
+RAC provides signals (represented by `RACSignal`) that capture present and
+future values.
+
+By chaining, combining, and reacting to signals, software can be written
+declaratively, without the need for code that continually observes and updates
+values.
+
+For example, a text field can be bound to the latest time, even as it changes,
+instead of using additional code that watches the clock and updates the
+text field every second.  It works much like KVO, but with blocks instead of
+overriding `-observeValueForKeyPath:ofObject:change:context:`.
+
+Signals can also represent asynchronous operations, much like [futures and
+promises][]. This greatly simplifies asynchronous software, including networking
+code.
+
+One of the major advantages of RAC is that it provides a single, unified
+approach to dealing with asynchronous behaviors, including delegate methods,
+callback blocks, target-action mechanisms, notifications, and KVO.
+
+Here's a simple example:
+
+```objc
+// When self.username changes, log the new name to the console.
+//
+// RACObserve(self, username) creates a new RACSignal that sends the current
+// value of self.username, then the new value whenever it changes.
+// -subscribeNext: will execute the block whenever the signal sends a value.
+[RACObserve(self, username) subscribeNext:^(NSString *newName) {
+	NSLog(@"%@", newName);
+}];
+```
+
+But unlike KVO notifications, signals can be chained together and operated on:
+
+```objc
+// Only log names that start with "j".
+//
+// -filter returns a new RACSignal that only sends a new value when its block
+// returns YES.
+[[RACObserve(self, username)
+	filter:^(NSString *newName) {
+		return [newName hasPrefix:@"j"];
+	}]
+	subscribeNext:^(NSString *newName) {
+		NSLog(@"%@", newName);
+	}];
+```
+
+Signals can also be used to derive state. Instead of observing properties and
+setting other properties in response to the new values, RAC makes it possible to
+express properties in terms of signals and operations:
+
+```objc
+// Create a one-way binding so that self.createEnabled will be
+// true whenever self.password and self.passwordConfirmation
+// are equal.
+//
+// RAC() is a macro that makes the binding look nicer.
+// 
+// +combineLatest:reduce: takes an array of signals, executes the block with the
+// latest value from each signal whenever any of them changes, and returns a new
+// RACSignal that sends the return value of that block as values.
+RAC(self, createEnabled) = [RACSignal 
+	combineLatest:@[ RACObserve(self, password), RACObserve(self, passwordConfirmation) ] 
+	reduce:^(NSString *password, NSString *passwordConfirm) {
+		return @([passwordConfirm isEqualToString:password]);
+	}];
+```
+
+Signals can be built on any stream of values over time, not just KVO. For
+example, they can also represent button presses:
+
+```objc
+// Log a message whenever the button is pressed.
+//
+// RACCommand creates signals to represent UI actions. Each signal can
+// represent a button press, for example, and have additional work associated
+// with it.
+//
+// -rac_command is an addition to NSButton. The button will send itself on that
+// command whenever it's pressed.
+self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id _) {
+	NSLog(@"button was pressed!");
+	return [RACSignal empty];
+}]
+```
+
+Or asynchronous network operations:
+
+```objc
+// Hook up a "Log in" button to log in over the network.
+//
+// This block will be run whenever the login command is executed, starting
+// the login process.
+self.loginCommand = [[RACCommand alloc] initWithSignalBlock:^(id sender) {
+	// The hypothetical -logIn method returns a signal that sends a value when
+	// the network request finishes.
+	return [client logIn];
+}];
+
+// -executionSignals returns a signal that includes the signals returned from
+// the above block, one for each time the command is executed.
+[self.loginCommand.executionSignals subscribeNext:^(RACSignal *loginSignal) {
+	// Log a message whenever we log in successfully.
+	[loginSignal subscribeCompleted:^ {
+		NSLog(@"Logged in successfully!");
+	}];
+}];
+
+// Execute the login command when the button is pressed.
+self.loginButton.rac_command = self.loginCommand;
+```
+
+Signals can also represent timers, other UI events, or anything else that
+changes over time.
+
+Using signals for asynchronous operations makes it possible to build up more
+complex behavior by chaining and transforming those signals. Work can easily be
+trigged after a group of operations completes:
+
+```objc
+// Perform 2 network operations and log a message to the console when they are
+// both completed.
+//
+// +merge: takes an array of signals and returns a new RACSignal that passes
+// through the values of all of the signals and completes when all of the
+// signals complete.
+//
+// -subscribeCompleted: will execute the block when the signal completes.
+[[RACSignal 
+	merge:@[ [client fetchUserRepos], [client fetchOrgRepos] ]] 
+	subscribeCompleted:^{
+		NSLog(@"They're both done!");
+	}];
+```
+
+Signals can be chained to sequentially execute asynchronous operations, instead
+of nesting callbacks with blocks. This is similar to how [futures and promises][]
+are usually used:
+
+```objc
+// Log in the user, then load any cached messages, then fetch the remaining
+// messages from the server. After that's all done, log a message to the
+// console.
+//
+// The hypothetical -logInUser methods returns a signal that completes after
+// logging in.
+//
+// -flattenMap: will execute its block whenever the signal sends a value, and
+// return a new RACSignal that merges all of the signals returned from the block
+// into a single signal.
+[[[[client 
+	logInUser] 
+	flattenMap:^(User *user) {
+		// Return a signal that loads cached messages for the user.
+		return [client loadCachedMessagesForUser:user];
+	}]
+	flattenMap:^(NSArray *messages) {
+		// Return a signal that fetches any remaining messages.
+		return [client fetchMessagesAfterMessage:messages.lastObject];
+	}]
+	subscribeNext:^(NSArray *newMessages) {
+		NSLog(@"New messages: %@", newMessages);
+	} completed:^{
+		NSLog(@"Fetched all messages.");
+	}];
+```
+
+RAC even makes it easy to bind to the result of an asynchronous operation:
+
+```objc
+// Create a one-way binding so that self.imageView.image will be set the user's
+// avatar as soon as it's downloaded.
+//
+// The hypothetical -fetchUserWithUsername: method returns a signal which sends
+// the user.
+//
+// -deliverOn: creates new signals that will do their work on other queues. In
+// this example, it's used to move work to a background queue and then back to the main thread.
+//
+// -map: calls its block with each user that's fetched and returns a new
+// RACSignal that sends values returned from the block.
+RAC(self.imageView, image) = [[[[client 
+	fetchUserWithUsername:@"joshaber"]
+	deliverOn:[RACScheduler scheduler]]
+	map:^(User *user) {
+		// Download the avatar (this is done on a background queue).
+		return [[NSImage alloc] initWithContentsOfURL:user.avatarURL];
+	}]
+	// Now the assignment will be done on the main thread.
+	deliverOn:RACScheduler.mainThreadScheduler];
+```
+
+That demonstrates some of what RAC can do, but it doesn't demonstrate why RAC is
+so powerful. It's hard to appreciate RAC from README-sized examples, but it
+makes it possible to write code with less state, less boilerplate, better code
+locality, and better expression of intent.
+
+For more sample code, check out [C-41][] or [GroceryList][], which are real iOS
+apps written using ReactiveCocoa. Additional information about RAC can be found
+in the [Documentation][] folder.
+
+## When to use ReactiveCocoa
+
+Upon first glance, ReactiveCocoa is very abstract, and it can be difficult to
+understand how to apply it to concrete problems.
+
+Here are some of the use cases that RAC excels at.
+
+### Handling asynchronous or event-driven data sources
+
+Much of Cocoa programming is focused on reacting to user events or changes in
+application state. Code that deals with such events can quickly become very
+complex and spaghetti-like, with lots of callbacks and state variables to handle
+ordering issues.
+
+Patterns that seem superficially different, like UI callbacks, network
+responses, and KVO notifications, actually have a lot in common. [RACSignal][]
+unifies all these different APIs so that they can be composed together and
+manipulated in the same way.
+
+For example, the following code:
+
+```objc
+
+static void *ObservationContext = &ObservationContext;
+
+- (void)viewDidLoad {
+	[super viewDidLoad];
+
+	[LoginManager.sharedManager addObserver:self forKeyPath:@"loggingIn" options:NSKeyValueObservingOptionInitial context:&ObservationContext];
+	[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(loggedOut:) name:UserDidLogOutNotification object:LoginManager.sharedManager];
+
+	[self.usernameTextField addTarget:self action:@selector(updateLogInButton) forControlEvents:UIControlEventEditingChanged];
+	[self.passwordTextField addTarget:self action:@selector(updateLogInButton) forControlEvents:UIControlEventEditingChanged];
+	[self.logInButton addTarget:self action:@selector(logInPressed:) forControlEvents:UIControlEventTouchUpInside];
+}
+
+- (void)dealloc {
+	[LoginManager.sharedManager removeObserver:self forKeyPath:@"loggingIn" context:ObservationContext];
+	[NSNotificationCenter.defaultCenter removeObserver:self];
+}
+
+- (void)updateLogInButton {
+	BOOL textFieldsNonEmpty = self.usernameTextField.text.length > 0 && self.passwordTextField.text.length > 0;
+	BOOL readyToLogIn = !LoginManager.sharedManager.isLoggingIn && !self.loggedIn;
+	self.logInButton.enabled = textFieldsNonEmpty && readyToLogIn;
+}
+
+- (IBAction)logInPressed:(UIButton *)sender {
+	[[LoginManager sharedManager]
+		logInWithUsername:self.usernameTextField.text
+		password:self.passwordTextField.text
+		success:^{
+			self.loggedIn = YES;
+		} failure:^(NSError *error) {
+			[self presentError:error];
+		}];
+}
+
+- (void)loggedOut:(NSNotification *)notification {
+	self.loggedIn = NO;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+	if (context == ObservationContext) {
+		[self updateLogInButton];
+	} else {
+		[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+	}
+}
+```
+
+… could be expressed in RAC like so:
+
+```objc
+- (void)viewDidLoad {
+	[super viewDidLoad];
+
+	@weakify(self);
+
+	RAC(self.logInButton, enabled) = [RACSignal
+		combineLatest:@[
+			self.usernameTextField.rac_textSignal,
+			self.passwordTextField.rac_textSignal,
+			RACObserve(LoginManager.sharedManager, loggingIn),
+			RACObserve(self, loggedIn)
+		] reduce:^(NSString *username, NSString *password, NSNumber *loggingIn, NSNumber *loggedIn) {
+			return @(username.length > 0 && password.length > 0 && !loggingIn.boolValue && !loggedIn.boolValue);
+		}];
+
+	[[self.logInButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton *sender) {
+		@strongify(self);
+
+		RACSignal *loginSignal = [LoginManager.sharedManager
+			logInWithUsername:self.usernameTextField.text
+			password:self.passwordTextField.text];
+
+			[loginSignal subscribeError:^(NSError *error) {
+				@strongify(self);
+				[self presentError:error];
+			} completed:^{
+				@strongify(self);
+				self.loggedIn = YES;
+			}];
+	}];
+
+	RAC(self, loggedIn) = [[NSNotificationCenter.defaultCenter
+		rac_addObserverForName:UserDidLogOutNotification object:nil]
+		mapReplace:@NO];
+}
+```
+
+### Chaining dependent operations
+
+Dependencies are most often found in network requests, where a previous request
+to the server needs to complete before the next one can be constructed, and so
+on:
+
+```objc
+[client logInWithSuccess:^{
+	[client loadCachedMessagesWithSuccess:^(NSArray *messages) {
+		[client fetchMessagesAfterMessage:messages.lastObject success:^(NSArray *nextMessages) {
+			NSLog(@"Fetched all messages.");
+		} failure:^(NSError *error) {
+			[self presentError:error];
+		}];
+	} failure:^(NSError *error) {
+		[self presentError:error];
+	}];
+} failure:^(NSError *error) {
+	[self presentError:error];
+}];
+```
+
+ReactiveCocoa makes this pattern particularly easy:
+
+```objc
+[[[[client logIn]
+	then:^{
+		return [client loadCachedMessages];
+	}]
+	flattenMap:^(NSArray *messages) {
+		return [client fetchMessagesAfterMessage:messages.lastObject];
+	}]
+	subscribeError:^(NSError *error) {
+		[self presentError:error];
+	} completed:^{
+		NSLog(@"Fetched all messages.");
+	}];
+```
+
+### Parallelizing independent work
+
+Working with independent data sets in parallel and then combining them into
+a final result is non-trivial in Cocoa, and often involves a lot of
+synchronization:
+
+```objc
+__block NSArray *databaseObjects;
+__block NSArray *fileContents;
+ 
+NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
+NSBlockOperation *databaseOperation = [NSBlockOperation blockOperationWithBlock:^{
+	databaseObjects = [databaseClient fetchObjectsMatchingPredicate:predicate];
+}];
+
+NSBlockOperation *filesOperation = [NSBlockOperation blockOperationWithBlock:^{
+	NSMutableArray *filesInProgress = [NSMutableArray array];
+	for (NSString *path in files) {
+		[filesInProgress addObject:[NSData dataWithContentsOfFile:path]];
+	}
+
+	fileContents = [filesInProgress copy];
+}];
+ 
+NSBlockOperation *finishOperation = [NSBlockOperation blockOperationWithBlock:^{
+	[self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
+	NSLog(@"Done processing");
+}];
+ 
+[finishOperation addDependency:databaseOperation];
+[finishOperation addDependency:filesOperation];
+[backgroundQueue addOperation:databaseOperation];
+[backgroundQueue addOperation:filesOperation];
+[backgroundQueue addOperation:finishOperation];
+```
+
+The above code can be cleaned up and optimized by simply composing signals:
+
+```objc
+RACSignal *databaseSignal = [[databaseClient
+	fetchObjectsMatchingPredicate:predicate]
+	subscribeOn:[RACScheduler scheduler]];
+
+RACSignal *fileSignal = [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(id<RACSubscriber> subscriber) {
+	NSMutableArray *filesInProgress = [NSMutableArray array];
+	for (NSString *path in files) {
+		[filesInProgress addObject:[NSData dataWithContentsOfFile:path]];
+	}
+
+	[subscriber sendNext:[filesInProgress copy]];
+	[subscriber sendCompleted];
+}];
+
+[[RACSignal
+	combineLatest:@[ databaseSignal, fileSignal ]
+	reduce:^ id (NSArray *databaseObjects, NSArray *fileContents) {
+		[self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
+		return nil;
+	}]
+	subscribeCompleted:^{
+		NSLog(@"Done processing");
+	}];
+```
+
+### Simplifying collection transformations
+
+Higher-order functions like `map`, `filter`, `fold`/`reduce` are sorely missing
+from Foundation, leading to loop-focused code like this:
+
+```objc
+NSMutableArray *results = [NSMutableArray array];
+for (NSString *str in strings) {
+	if (str.length < 2) {
+		continue;
+	}
+
+	NSString *newString = [str stringByAppendingString:@"foobar"];
+	[results addObject:newString];
+}
+```
+
+[RACSequence][] allows any Cocoa collection to be manipulated in a uniform and
+declarative way:
+
+```objc
+RACSequence *results = [[strings.rac_sequence
+	filter:^ BOOL (NSString *str) {
+		return str.length >= 2;
+	}]
+	map:^(NSString *str) {
+		return [str stringByAppendingString:@"foobar"];
+	}];
+```
+
+## System Requirements
+
+ReactiveCocoa supports OS X 10.7+ and iOS 5.0+.
+
+## Importing ReactiveCocoa
+
+To add RAC to your application:
+
+ 1. Add the ReactiveCocoa repository as a submodule of your application's
+    repository.
+ 1. Run `script/bootstrap` from within the ReactiveCocoa folder.
+ 1. Drag and drop `ReactiveCocoaFramework/ReactiveCocoa.xcodeproj` into your
+    application's Xcode project or workspace.
+ 1. On the "Build Phases" tab of your application target, add RAC to the "Link
+    Binary With Libraries" phase.
+    * **On iOS**, add `libReactiveCocoa-iOS.a`.
+    * **On OS X**, add `ReactiveCocoa.framework`. RAC must also be added to any
+      "Copy Frameworks" build phase. If you don't already have one, simply add
+      a "Copy Files" build phase and target the "Frameworks" destination.
+ 1. Add `"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include"
+    $(inherited)` to the "Header Search Paths" build setting (this is only
+    necessary for archive builds, but it has no negative effect otherwise).
+ 1. **For iOS targets**, add `-ObjC` to the "Other Linker Flags" build setting.
+ 1. **If you added RAC to a project (not a workspace)**, you will also need to
+    add the appropriate RAC target to the "Target Dependencies" of your
+    application.
+
+If you would prefer to use [CocoaPods](http://cocoapods.org), there are some
+[ReactiveCocoa
+podspecs](https://github.com/CocoaPods/Specs/tree/master/ReactiveCocoa) that
+have been generously contributed by third parties.
+
+To see a project already set up with RAC, check out [C-41][] or [GroceryList][],
+which are real iOS apps written using ReactiveCocoa.
+
+## Standalone Development
+
+If you’re working on RAC in isolation instead of integrating it into another project, you’ll want to open `ReactiveCocoaFramework/ReactiveCocoa.xcworkspace` and not the `.xcodeproj`.
+
+## More Info
+
+ReactiveCocoa is based on .NET's [Reactive
+Extensions](http://msdn.microsoft.com/en-us/data/gg577609) (Rx). Most of the
+principles of Rx apply to RAC as well. There are some really good Rx resources
+out there:
+
+* [Reactive Extensions MSDN entry](http://msdn.microsoft.com/en-us/library/hh242985.aspx)
+* [Reactive Extensions for .NET Introduction](http://leecampbell.blogspot.com/2010/08/reactive-extensions-for-net.html)
+* [Rx - Channel 9 videos](http://channel9.msdn.com/tags/Rx/)
+* [Reactive Extensions wiki](http://rxwiki.wikidot.com/)
+* [101 Rx Samples](http://rxwiki.wikidot.com/101samples)
+* [Programming Reactive Extensions and LINQ](http://www.amazon.com/Programming-Reactive-Extensions-Jesse-Liberty/dp/1430237473)
+
+RAC and Rx are both implementations of functional reactive programming. Here are
+some more resources for learning about FRP:
+
+* [What is FRP? - Elm Language](http://elm-lang.org/learn/What-is-FRP.elm)
+* [What is Functional Reactive Programming - Stack Overflow](http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming/1030631#1030631)
+* [Escape from Callback Hell](http://elm-lang.org/learn/Escape-from-Callback-Hell.elm)
+* [Principles of Reactive Programming on Coursera](https://www.coursera.org/course/reactive)
+
+[Basic Operators]: Documentation/BasicOperators.md
+[Documentation]: Documentation
+[Framework Overview]: Documentation/FrameworkOverview.md
+[Functional Reactive Programming]: http://en.wikipedia.org/wiki/Functional_reactive_programming
+[GroceryList]:  https://github.com/jspahrsummers/GroceryList
+[Memory Management]: Documentation/MemoryManagement.md
+[NSObject+RACLifting]: ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.h
+[RACDisposable]: ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.h
+[RACEvent]: ReactiveCocoaFramework/ReactiveCocoa/RACEvent.h
+[RACMulticastConnection]: ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.h
+[RACScheduler]: ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.h
+[RACSequence]: ReactiveCocoaFramework/ReactiveCocoa/RACSequence.h
+[RACSignal+Operations]: ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.h
+[RACSignal]: ReactiveCocoaFramework/ReactiveCocoa/RACSignal.h
+[RACStream]: ReactiveCocoaFramework/ReactiveCocoa/RACStream.h
+[RACSubscriber]: ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.h
+[RAC]: ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h
+[futures and promises]: http://en.wikipedia.org/wiki/Futures_and_promises
+[C-41]: https://github.com/AshFurrow/C-41
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.h
new file mode 100644
index 0000000..d2d0b3f
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.h
@@ -0,0 +1,20 @@
+//
+//  NSArray+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSArray (RACSequenceAdditions)
+
+/// Creates and returns a sequence corresponding to the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.m
new file mode 100644
index 0000000..ca2b951
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSArray+RACSequenceAdditions.m
@@ -0,0 +1,18 @@
+//
+//  NSArray+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSArray+RACSequenceAdditions.h"
+#import "RACArraySequence.h"
+
+@implementation NSArray (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	return [RACArraySequence sequenceWithArray:self offset:0];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.h
new file mode 100644
index 0000000..42198a6
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.h
@@ -0,0 +1,22 @@
+//
+//  NSData+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+@class RACScheduler;
+
+@interface NSData (RACSupport)
+
+// Read the data at the URL using -[NSData initWithContentsOfURL:options:error:].
+// Sends the data or the error.
+//
+// scheduler - cannot be nil.
++ (RACSignal *)rac_readContentsOfURL:(NSURL *)URL options:(NSDataReadingOptions)options scheduler:(RACScheduler *)scheduler;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.m
new file mode 100644
index 0000000..227eb4d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSData+RACSupport.m
@@ -0,0 +1,35 @@
+//
+//  NSData+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "NSData+RACSupport.h"
+#import "RACReplaySubject.h"
+#import "RACScheduler.h"
+
+@implementation NSData (RACSupport)
+
++ (RACSignal *)rac_readContentsOfURL:(NSURL *)URL options:(NSDataReadingOptions)options scheduler:(RACScheduler *)scheduler {
+	NSCParameterAssert(scheduler != nil);
+	
+	RACReplaySubject *subject = [RACReplaySubject subject];
+	[subject setNameWithFormat:@"+rac_readContentsOfURL: %@ options: %lu scheduler: %@", URL, (unsigned long)options, scheduler];
+	
+	[scheduler schedule:^{
+		NSError *error = nil;
+		NSData *data = [[NSData alloc] initWithContentsOfURL:URL options:options error:&error];
+		if(data == nil) {
+			[subject sendError:error];
+		} else {
+			[subject sendNext:data];
+			[subject sendCompleted];
+		}
+	}];
+	
+	return subject;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.h
new file mode 100644
index 0000000..4871fe7
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.h
@@ -0,0 +1,31 @@
+//
+//  NSDictionary+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSDictionary (RACSequenceAdditions)
+
+/// Creates and returns a sequence of RACTuple key/value pairs. The key will be
+/// the first element in the tuple, and the value will be the second.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+/// Creates and returns a sequence corresponding to the keys in the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_keySequence;
+
+/// Creates and returns a sequence corresponding to the values in the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_valueSequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.m
new file mode 100644
index 0000000..192e6fd
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSDictionary+RACSequenceAdditions.m
@@ -0,0 +1,34 @@
+//
+//  NSDictionary+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSDictionary+RACSequenceAdditions.h"
+#import "NSArray+RACSequenceAdditions.h"
+#import "RACSequence.h"
+#import "RACTuple.h"
+
+@implementation NSDictionary (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	NSDictionary *immutableDict = [self copy];
+
+	// TODO: First class support for dictionary sequences.
+	return [immutableDict.allKeys.rac_sequence map:^(id key) {
+		id value = immutableDict[key];
+		return [RACTuple tupleWithObjects:key, value, nil];
+	}];
+}
+
+- (RACSequence *)rac_keySequence {
+	return self.allKeys.rac_sequence;
+}
+
+- (RACSequence *)rac_valueSequence {
+	return self.allValues.rac_sequence;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h
new file mode 100644
index 0000000..1d8fc84
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h
@@ -0,0 +1,20 @@
+//
+//  NSEnumerator+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 07/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSEnumerator (RACSequenceAdditions)
+
+/// Creates and returns a sequence corresponding to the receiver.
+///
+/// The receiver is exhausted lazily as the sequence is enumerated.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m
new file mode 100644
index 0000000..aa56eaa
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m
@@ -0,0 +1,22 @@
+//
+//  NSEnumerator+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 07/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSEnumerator+RACSequenceAdditions.h"
+#import "RACSequence.h"
+
+@implementation NSEnumerator (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	return [RACSequence sequenceWithHeadBlock:^{
+		return [self nextObject];
+	} tailBlock:^{
+		return self.rac_sequence;
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.h
new file mode 100644
index 0000000..985398d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.h
@@ -0,0 +1,19 @@
+//
+//  NSFileHandle+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/10/12.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+@interface NSFileHandle (RACSupport)
+
+// Read any available data in the background and send it. Completes when data
+// length is <= 0.
+- (RACSignal *)rac_readInBackground;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.m
new file mode 100644
index 0000000..a258789
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSFileHandle+RACSupport.m
@@ -0,0 +1,39 @@
+//
+//  NSFileHandle+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/10/12.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSFileHandle+RACSupport.h"
+#import "NSNotificationCenter+RACSupport.h"
+#import "RACReplaySubject.h"
+#import "RACDisposable.h"
+
+@implementation NSFileHandle (RACSupport)
+
+- (RACSignal *)rac_readInBackground {
+	RACReplaySubject *subject = [RACReplaySubject subject];
+	[subject setNameWithFormat:@"%@ -rac_readInBackground", self];
+
+	RACSignal *dataNotification = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:NSFileHandleReadCompletionNotification object:self] map:^(NSNotification *note) {
+		return [note.userInfo objectForKey:NSFileHandleNotificationDataItem];
+	}];
+	
+	__block RACDisposable *subscription = [dataNotification subscribeNext:^(NSData *data) {
+		if(data.length > 0) {
+			[subject sendNext:data];
+			[self readInBackgroundAndNotify];
+		} else {
+			[subject sendCompleted];
+			[subscription dispose];
+		}
+	}];
+	
+	[self readInBackgroundAndNotify];
+	
+	return subject;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.h
new file mode 100644
index 0000000..b2066e4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.h
@@ -0,0 +1,20 @@
+//
+//  NSIndexSet+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Sergey Gavrilyuk on 12/17/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACSequence.h"
+
+@interface NSIndexSet (RACSequenceAdditions)
+
+/// Creates and returns a sequence of indexes (as `NSNumber`s) corresponding to
+/// the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.m
new file mode 100644
index 0000000..b3557e6
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSIndexSet+RACSequenceAdditions.m
@@ -0,0 +1,18 @@
+//
+//  NSIndexSet+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Sergey Gavrilyuk on 12/17/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSIndexSet+RACSequenceAdditions.h"
+#import "RACIndexSetSequence.h"
+
+@implementation NSIndexSet (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	return [RACIndexSetSequence sequenceWithIndexSet:self];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.h b/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.h
new file mode 100644
index 0000000..d1e72bf
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.h
@@ -0,0 +1,56 @@
+//
+//  NSInvocation+RACTypeParsing.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACTuple;
+
+// A private category of methods to handle wrapping and unwrapping of values.
+@interface NSInvocation (RACTypeParsing)
+
+// Sets the argument for the invocation at the given index by unboxing the given
+// object based on the type signature of the argument.
+//
+// This does not support C arrays or unions.
+//
+// Note that calling this on a char * or const char * argument can cause all
+// arguments to be retained.
+//
+// object - The object to unbox and set as the argument.
+// index  - The index of the argument to set.
+- (void)rac_setArgument:(id)object atIndex:(NSUInteger)index;
+
+// Gets the argument for the invocation at the given index based on the
+// invocation's method signature. The value is then wrapped in the appropriate
+// object type.
+//
+// This does not support C arrays or unions.
+//
+// index  - The index of the argument to get.
+//
+// Returns the argument of the invocation, wrapped in an object.
+- (id)rac_argumentAtIndex:(NSUInteger)index;
+
+// Arguments tuple for the invocation.
+//
+// The arguments tuple excludes implicit variables `self` and `_cmd`.
+//
+// See -rac_argumentAtIndex: and -rac_setArgumentAtIndex: for further
+// description of the underlying behavior.
+@property (nonatomic, copy) RACTuple *rac_argumentsTuple;
+
+// Gets the return value from the invocation based on the invocation's method
+// signature. The value is then wrapped in the appropriate object type.
+//
+// This does not support C arrays or unions.
+//
+// Returns the return value of the invocation, wrapped in an object. Voids are
+// returned as `RACUnit.defaultUnit`.
+- (id)rac_returnValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.m b/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.m
new file mode 100644
index 0000000..a5318e7
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSInvocation+RACTypeParsing.m
@@ -0,0 +1,232 @@
+//
+//  NSInvocation+RACTypeParsing.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "NSInvocation+RACTypeParsing.h"
+#import "RACTuple.h"
+#import "RACUnit.h"
+#import <CoreGraphics/CoreGraphics.h>
+
+@implementation NSInvocation (RACTypeParsing)
+
+- (void)rac_setArgument:(id)object atIndex:(NSUInteger)index {
+#define PULL_AND_SET(type, selector) \
+	do { \
+		type val = [object selector]; \
+		[self setArgument:&val atIndex:(NSInteger)index]; \
+	} while(0)
+
+	const char *argType = [self.methodSignature getArgumentTypeAtIndex:index];
+	// Skip const type qualifier.
+	if (argType[0] == 'r') {
+		argType++;
+	}
+
+	if (strcmp(argType, @encode(id)) == 0 || strcmp(argType, @encode(Class)) == 0) {
+		[self setArgument:&object atIndex:(NSInteger)index];
+	} else if (strcmp(argType, @encode(char)) == 0) {
+		PULL_AND_SET(char, charValue);
+	} else if (strcmp(argType, @encode(int)) == 0) {
+		PULL_AND_SET(int, intValue);
+	} else if (strcmp(argType, @encode(short)) == 0) {
+		PULL_AND_SET(short, shortValue);
+	} else if (strcmp(argType, @encode(long)) == 0) {
+		PULL_AND_SET(long, longValue);
+	} else if (strcmp(argType, @encode(long long)) == 0) {
+		PULL_AND_SET(long long, longLongValue);
+	} else if (strcmp(argType, @encode(unsigned char)) == 0) {
+		PULL_AND_SET(unsigned char, unsignedCharValue);
+	} else if (strcmp(argType, @encode(unsigned int)) == 0) {
+		PULL_AND_SET(unsigned int, unsignedIntValue);
+	} else if (strcmp(argType, @encode(unsigned short)) == 0) {
+		PULL_AND_SET(unsigned short, unsignedShortValue);
+	} else if (strcmp(argType, @encode(unsigned long)) == 0) {
+		PULL_AND_SET(unsigned long, unsignedLongValue);
+	} else if (strcmp(argType, @encode(unsigned long long)) == 0) {
+		PULL_AND_SET(unsigned long long, unsignedLongLongValue);
+	} else if (strcmp(argType, @encode(float)) == 0) {
+		PULL_AND_SET(float, floatValue);
+	} else if (strcmp(argType, @encode(double)) == 0) {
+		PULL_AND_SET(double, doubleValue);
+	} else if (strcmp(argType, @encode(BOOL)) == 0) {
+		PULL_AND_SET(BOOL, boolValue);
+	} else if (strcmp(argType, @encode(char *)) == 0) {
+		const char *cString = [object UTF8String];
+		[self setArgument:&cString atIndex:(NSInteger)index];
+		[self retainArguments];
+	} else if (strcmp(argType, @encode(void (^)(void))) == 0) {
+		[self setArgument:&object atIndex:(NSInteger)index];
+	} else {
+		NSCParameterAssert([object isKindOfClass:NSValue.class]);
+
+		NSUInteger valueSize = 0;
+		NSGetSizeAndAlignment([object objCType], &valueSize, NULL);
+
+#if DEBUG
+		NSUInteger argSize = 0;
+		NSGetSizeAndAlignment(argType, &argSize, NULL);
+		NSCAssert(valueSize == argSize, @"Value size does not match argument size in -rac_setArgument: %@ atIndex: %lu", object, (unsigned long)index);
+#endif
+		
+		unsigned char valueBytes[valueSize];
+		[object getValue:valueBytes];
+
+		[self setArgument:valueBytes atIndex:(NSInteger)index];
+	}
+
+#undef PULL_AND_SET
+}
+
+- (id)rac_argumentAtIndex:(NSUInteger)index {
+#define WRAP_AND_RETURN(type) \
+	do { \
+		type val = 0; \
+		[self getArgument:&val atIndex:(NSInteger)index]; \
+		return @(val); \
+	} while (0)
+
+	const char *argType = [self.methodSignature getArgumentTypeAtIndex:index];
+	// Skip const type qualifier.
+	if (argType[0] == 'r') {
+		argType++;
+	}
+
+	if (strcmp(argType, @encode(id)) == 0 || strcmp(argType, @encode(Class)) == 0) {
+		__autoreleasing id returnObj;
+		[self getArgument:&returnObj atIndex:(NSInteger)index];
+		return returnObj;
+	} else if (strcmp(argType, @encode(char)) == 0) {
+		WRAP_AND_RETURN(char);
+	} else if (strcmp(argType, @encode(int)) == 0) {
+		WRAP_AND_RETURN(int);
+	} else if (strcmp(argType, @encode(short)) == 0) {
+		WRAP_AND_RETURN(short);
+	} else if (strcmp(argType, @encode(long)) == 0) {
+		WRAP_AND_RETURN(long);
+	} else if (strcmp(argType, @encode(long long)) == 0) {
+		WRAP_AND_RETURN(long long);
+	} else if (strcmp(argType, @encode(unsigned char)) == 0) {
+		WRAP_AND_RETURN(unsigned char);
+	} else if (strcmp(argType, @encode(unsigned int)) == 0) {
+		WRAP_AND_RETURN(unsigned int);
+	} else if (strcmp(argType, @encode(unsigned short)) == 0) {
+		WRAP_AND_RETURN(unsigned short);
+	} else if (strcmp(argType, @encode(unsigned long)) == 0) {
+		WRAP_AND_RETURN(unsigned long);
+	} else if (strcmp(argType, @encode(unsigned long long)) == 0) {
+		WRAP_AND_RETURN(unsigned long long);
+	} else if (strcmp(argType, @encode(float)) == 0) {
+		WRAP_AND_RETURN(float);
+	} else if (strcmp(argType, @encode(double)) == 0) {
+		WRAP_AND_RETURN(double);
+	} else if (strcmp(argType, @encode(BOOL)) == 0) {
+		WRAP_AND_RETURN(BOOL);
+	} else if (strcmp(argType, @encode(char *)) == 0) {
+		WRAP_AND_RETURN(const char *);
+	} else if (strcmp(argType, @encode(void (^)(void))) == 0) {
+		__unsafe_unretained id block = nil;
+		[self getArgument:&block atIndex:(NSInteger)index];
+		return [block copy];
+	} else {
+		NSUInteger valueSize = 0;
+		NSGetSizeAndAlignment(argType, &valueSize, NULL);
+
+		unsigned char valueBytes[valueSize];
+		[self getArgument:valueBytes atIndex:(NSInteger)index];
+		
+		return [NSValue valueWithBytes:valueBytes objCType:argType];
+	}
+
+	return nil;
+
+#undef WRAP_AND_RETURN
+}
+
+- (RACTuple *)rac_argumentsTuple {
+	NSUInteger numberOfArguments = self.methodSignature.numberOfArguments;
+	NSMutableArray *argumentsArray = [NSMutableArray arrayWithCapacity:numberOfArguments - 2];
+	for (NSUInteger index = 2; index < numberOfArguments; index++) {
+		[argumentsArray addObject:[self rac_argumentAtIndex:index] ?: RACTupleNil.tupleNil];
+	}
+
+	return [RACTuple tupleWithObjectsFromArray:argumentsArray];
+}
+
+- (void)setRac_argumentsTuple:(RACTuple *)arguments {
+	NSCAssert(arguments.count == self.methodSignature.numberOfArguments - 2, @"Number of supplied arguments (%lu), does not match the number expected by the signature (%lu)", (unsigned long)arguments.count, (unsigned long)self.methodSignature.numberOfArguments - 2);
+
+	NSUInteger index = 2;
+	for (id arg in arguments) {
+		[self rac_setArgument:(arg == RACTupleNil.tupleNil ? nil : arg) atIndex:index];
+		index++;
+	}
+}
+
+- (id)rac_returnValue {
+#define WRAP_AND_RETURN(type) \
+	do { \
+		type val = 0; \
+		[self getReturnValue:&val]; \
+		return @(val); \
+	} while (0)
+
+	const char *returnType = self.methodSignature.methodReturnType;
+	// Skip const type qualifier.
+	if (returnType[0] == 'r') {
+		returnType++;
+	}
+
+	if (strcmp(returnType, @encode(id)) == 0 || strcmp(returnType, @encode(Class)) == 0 || strcmp(returnType, @encode(void (^)(void))) == 0) {
+		__autoreleasing id returnObj;
+		[self getReturnValue:&returnObj];
+		return returnObj;
+	} else if (strcmp(returnType, @encode(char)) == 0) {
+		WRAP_AND_RETURN(char);
+	} else if (strcmp(returnType, @encode(int)) == 0) {
+		WRAP_AND_RETURN(int);
+	} else if (strcmp(returnType, @encode(short)) == 0) {
+		WRAP_AND_RETURN(short);
+	} else if (strcmp(returnType, @encode(long)) == 0) {
+		WRAP_AND_RETURN(long);
+	} else if (strcmp(returnType, @encode(long long)) == 0) {
+		WRAP_AND_RETURN(long long);
+	} else if (strcmp(returnType, @encode(unsigned char)) == 0) {
+		WRAP_AND_RETURN(unsigned char);
+	} else if (strcmp(returnType, @encode(unsigned int)) == 0) {
+		WRAP_AND_RETURN(unsigned int);
+	} else if (strcmp(returnType, @encode(unsigned short)) == 0) {
+		WRAP_AND_RETURN(unsigned short);
+	} else if (strcmp(returnType, @encode(unsigned long)) == 0) {
+		WRAP_AND_RETURN(unsigned long);
+	} else if (strcmp(returnType, @encode(unsigned long long)) == 0) {
+		WRAP_AND_RETURN(unsigned long long);
+	} else if (strcmp(returnType, @encode(float)) == 0) {
+		WRAP_AND_RETURN(float);
+	} else if (strcmp(returnType, @encode(double)) == 0) {
+		WRAP_AND_RETURN(double);
+	} else if (strcmp(returnType, @encode(BOOL)) == 0) {
+		WRAP_AND_RETURN(BOOL);
+	} else if (strcmp(returnType, @encode(char *)) == 0) {
+		WRAP_AND_RETURN(const char *);
+	} else if (strcmp(returnType, @encode(void)) == 0) {
+		return RACUnit.defaultUnit;
+	} else {
+		NSUInteger valueSize = 0;
+		NSGetSizeAndAlignment(returnType, &valueSize, NULL);
+
+		unsigned char valueBytes[valueSize];
+		[self getReturnValue:valueBytes];
+
+		return [NSValue valueWithBytes:valueBytes objCType:returnType];
+	}
+
+	return nil;
+
+#undef WRAP_AND_RETURN
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.h
new file mode 100644
index 0000000..ddb3954
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.h
@@ -0,0 +1,18 @@
+//
+//  NSNotificationCenter+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/10/12.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+@interface NSNotificationCenter (RACSupport)
+
+// Sends the NSNotification every time the notification is posted.
+- (RACSignal *)rac_addObserverForName:(NSString *)notificationName object:(id)object;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.m
new file mode 100644
index 0000000..4219ecd
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSNotificationCenter+RACSupport.m
@@ -0,0 +1,31 @@
+//
+//  NSNotificationCenter+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/10/12.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSNotificationCenter+RACSupport.h"
+#import "RACEXTScope.h"
+#import "RACSignal.h"
+#import "RACSubscriber.h"
+#import "RACDisposable.h"
+
+@implementation NSNotificationCenter (RACSupport)
+
+- (RACSignal *)rac_addObserverForName:(NSString *)notificationName object:(id)object {
+	@unsafeify(object);
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		@strongify(object);
+		id observer = [self addObserverForName:notificationName object:object queue:nil usingBlock:^(NSNotification *note) {
+			[subscriber sendNext:note];
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[self removeObserver:observer];
+		}];
+	}] setNameWithFormat:@"-rac_addObserverForName: %@ object: <%@: %p>", notificationName, [object class], object];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.h
new file mode 100644
index 0000000..1530eb4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.h
@@ -0,0 +1,34 @@
+//
+//  NSObject+RACDeallocating.h
+//  ReactiveCocoa
+//
+//  Created by Kazuo Koga on 2013/03/15.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACCompoundDisposable;
+@class RACDisposable;
+@class RACSignal;
+
+@interface NSObject (RACDeallocating)
+
+/// The compound disposable which will be disposed of when the receiver is
+/// deallocated.
+@property (atomic, readonly, strong) RACCompoundDisposable *rac_deallocDisposable;
+
+/// Returns a signal that will complete immediately before the receiver is fully
+/// deallocated. If already deallocated when the signal is subscribed to,
+/// a `completed` event will be sent immediately.
+- (RACSignal *)rac_willDeallocSignal;
+
+@end
+
+@interface NSObject (RACDeallocatingDeprecated)
+
+- (RACSignal *)rac_didDeallocSignal __attribute__((deprecated("Use -rac_willDeallocSignal")));
+
+- (void)rac_addDeallocDisposable:(RACDisposable *)disposable __attribute__((deprecated("Add disposables to -rac_deallocDisposable instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.m
new file mode 100644
index 0000000..a81d89c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDeallocating.m
@@ -0,0 +1,129 @@
+//
+//  NSObject+RACDeallocating.m
+//  ReactiveCocoa
+//
+//  Created by Kazuo Koga on 2013/03/15.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSObject+RACDeallocating.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACReplaySubject.h"
+#import <objc/message.h>
+#import <objc/runtime.h>
+
+static const void *RACObjectCompoundDisposable = &RACObjectCompoundDisposable;
+
+static NSMutableSet *swizzledClasses() {
+	static dispatch_once_t onceToken;
+	static NSMutableSet *swizzledClasses = nil;
+	dispatch_once(&onceToken, ^{
+		swizzledClasses = [[NSMutableSet alloc] init];
+	});
+	
+	return swizzledClasses;
+}
+
+static void swizzleDeallocIfNeeded(Class classToSwizzle) {
+	@synchronized (swizzledClasses()) {
+		NSString *className = NSStringFromClass(classToSwizzle);
+		if ([swizzledClasses() containsObject:className]) return;
+
+		SEL deallocSelector = sel_registerName("dealloc");
+
+		__block void (*originalDealloc)(__unsafe_unretained id, SEL) = NULL;
+
+		id newDealloc = ^(__unsafe_unretained id self) {
+			RACCompoundDisposable *compoundDisposable = objc_getAssociatedObject(self, RACObjectCompoundDisposable);
+			[compoundDisposable dispose];
+
+			if (originalDealloc == NULL) {
+				struct objc_super superInfo = {
+					.receiver = self,
+					.super_class = class_getSuperclass(classToSwizzle)
+				};
+
+				void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper;
+				msgSend(&superInfo, deallocSelector);
+			} else {
+				originalDealloc(self, deallocSelector);
+			}
+		};
+		
+		IMP newDeallocIMP = imp_implementationWithBlock(newDealloc);
+		
+		if (!class_addMethod(classToSwizzle, deallocSelector, newDeallocIMP, "v@:")) {
+			// The class already contains a method implementation.
+			Method deallocMethod = class_getInstanceMethod(classToSwizzle, deallocSelector);
+			
+			// We need to store original implementation before setting new implementation
+			// in case method is called at the time of setting.
+			originalDealloc = (__typeof__(originalDealloc))method_getImplementation(deallocMethod);
+			
+			// We need to store original implementation again, in case it just changed.
+			originalDealloc = (__typeof__(originalDealloc))method_setImplementation(deallocMethod, newDeallocIMP);
+		}
+
+		[swizzledClasses() addObject:className];
+	}
+}
+
+@implementation NSObject (RACDeallocating)
+
+- (RACSignal *)rac_willDeallocSignal {
+	RACSignal *signal = objc_getAssociatedObject(self, _cmd);
+	if (signal != nil) return signal;
+
+	RACReplaySubject *subject = [RACReplaySubject subject];
+
+	[self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+		[subject sendCompleted];
+	}]];
+
+	objc_setAssociatedObject(self, _cmd, subject, OBJC_ASSOCIATION_RETAIN);
+
+	return subject;
+}
+
+- (RACCompoundDisposable *)rac_deallocDisposable {
+	@synchronized (self) {
+		RACCompoundDisposable *compoundDisposable = objc_getAssociatedObject(self, RACObjectCompoundDisposable);
+		if (compoundDisposable != nil) return compoundDisposable;
+
+		swizzleDeallocIfNeeded(self.class);
+
+		compoundDisposable = [RACCompoundDisposable compoundDisposable];
+		objc_setAssociatedObject(self, RACObjectCompoundDisposable, compoundDisposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+		return compoundDisposable;
+	}
+}
+
+@end
+
+@implementation NSObject (RACDeallocatingDeprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (RACSignal *)rac_didDeallocSignal {
+	RACSubject *subject = [RACSubject subject];
+
+	RACScopedDisposable *disposable = [[RACDisposable
+		disposableWithBlock:^{
+			[subject sendCompleted];
+		}]
+		asScopedDisposable];
+	
+	objc_setAssociatedObject(self, (__bridge void *)disposable, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	return subject;
+}
+
+- (void)rac_addDeallocDisposable:(RACDisposable *)disposable {
+	[self.rac_deallocDisposable addDisposable:disposable];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.h
new file mode 100644
index 0000000..41e3d8a
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.h
@@ -0,0 +1,21 @@
+//
+//  NSObject+RACDescription.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// A private category providing a terser but faster alternative to -description.
+@interface NSObject (RACDescription)
+
+// A simplified description of the receiver, which does not invoke -description
+// (and thus should be much faster in many cases).
+//
+// This is for debugging purposes only, and will return a constant string
+// unless the RAC_DEBUG_SIGNAL_NAMES environment variable is set.
+- (NSString *)rac_description;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.m
new file mode 100644
index 0000000..0088880
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACDescription.m
@@ -0,0 +1,46 @@
+//
+//  NSObject+RACDescription.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSObject+RACDescription.h"
+#import "RACTuple.h"
+
+@implementation NSObject (RACDescription)
+
+- (NSString *)rac_description {
+	if (getenv("RAC_DEBUG_SIGNAL_NAMES") != NULL) {
+		return [[NSString alloc] initWithFormat:@"<%@: %p>", self.class, self];
+	} else {
+		return @"(description skipped)";
+	}
+}
+
+@end
+
+@implementation NSValue (RACDescription)
+
+- (NSString *)rac_description {
+	return self.description;
+}
+
+@end
+
+@implementation NSString (RACDescription)
+
+- (NSString *)rac_description {
+	return self.description;
+}
+
+@end
+
+@implementation RACTuple (RACDescription)
+
+- (NSString *)rac_description {
+	return self.allObjects.description;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.h
new file mode 100644
index 0000000..3b9ff2f
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.h
@@ -0,0 +1,56 @@
+//
+//  NSObject+RACKVOWrapper.h
+//  GitHub
+//
+//  Created by Josh Abernathy on 10/11/11.
+//  Copyright (c) 2011 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+// RAC-specific KVO change dictionary key: Will be @YES if the change was caused
+// by the value at the key path or an intermediate value deallocating, @NO
+// otherwise.
+extern NSString * const RACKeyValueChangeCausedByDeallocationKey;
+
+// RAC-specific KVO change dictionary key: Will be @YES if the change only
+// affected the value of the last key path component leaving the values of the
+// intermediate key path components unaltered, @NO otherwise.
+extern NSString * const RACKeyValueChangeAffectedOnlyLastComponentKey;
+
+@class RACDisposable, RACKVOTrampoline;
+
+// A private category providing a block based interface to KVO.
+@interface NSObject (RACKVOWrapper)
+
+// Adds the given block as the callbacks for when the key path changes.
+//
+// Unlike direct KVO observation, this handles deallocation of `weak` properties
+// by generating an appropriate notification. This will only occur if there is
+// an `@property` declaration visible in the observed class, with the `weak`
+// memory management attribute.
+//
+// The observation does not need to be explicitly removed. It will be removed
+// when the observer or the receiver deallocate.
+//
+// keyPath  - The key path to observe. Must not be nil.
+// options  - The KVO observation options.
+// observer - The object that requested the observation. May be nil.
+// block    - The block called when the value at the key path changes. It is
+//            passed the current value of the key path and the extended KVO
+//            change dictionary including RAC-specific keys and values. Must not
+//            be nil.
+//
+// Returns a disposable that can be used to stop the observation.
+- (RACDisposable *)rac_observeKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer block:(void (^)(id value, NSDictionary *change))block;
+
+@end
+
+typedef void (^RACKVOBlock)(id target, id observer, NSDictionary *change);
+
+@interface NSObject (RACKVOWrapperDeprecated)
+
+- (RACKVOTrampoline *)rac_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(RACKVOBlock)block __attribute((deprecated("Use rac_observeKeyPath:options:observer:block: instead.")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.m
new file mode 100644
index 0000000..03f5375
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACKVOWrapper.m
@@ -0,0 +1,237 @@
+//
+//  NSObject+RACKVOWrapper.m
+//  GitHub
+//
+//  Created by Josh Abernathy on 10/11/11.
+//  Copyright (c) 2011 GitHub. All rights reserved.
+//
+
+#import "NSObject+RACKVOWrapper.h"
+#import "RACEXTRuntimeExtensions.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSString+RACKeyPathUtilities.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACKVOTrampoline.h"
+#import "RACSerialDisposable.h"
+
+NSString * const RACKeyValueChangeCausedByDeallocationKey = @"RACKeyValueChangeCausedByDeallocationKey";
+NSString * const RACKeyValueChangeAffectedOnlyLastComponentKey = @"RACKeyValueChangeAffectedOnlyLastComponentKey";
+
+@implementation NSObject (RACKVOWrapper)
+
+- (RACDisposable *)rac_observeKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer block:(void (^)(id, NSDictionary *))block {
+	NSCParameterAssert(block != nil);
+	NSCParameterAssert(keyPath.rac_keyPathComponents.count > 0);
+
+	keyPath = [keyPath copy];
+
+	@unsafeify(observer);
+
+	NSArray *keyPathComponents = keyPath.rac_keyPathComponents;
+	BOOL keyPathHasOneComponent = (keyPathComponents.count == 1);
+	NSString *keyPathHead = keyPathComponents[0];
+	NSString *keyPathTail = keyPath.rac_keyPathByDeletingFirstKeyPathComponent;
+
+	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+	// The disposable that groups all disposal necessary to clean up the callbacks
+	// added to the value of the first key path component.
+	RACSerialDisposable *firstComponentSerialDisposable = [RACSerialDisposable serialDisposableWithDisposable:[RACCompoundDisposable compoundDisposable]];
+	RACCompoundDisposable * (^firstComponentDisposable)(void) = ^{
+		return (RACCompoundDisposable *)firstComponentSerialDisposable.disposable;
+	};
+
+	[disposable addDisposable:firstComponentSerialDisposable];
+
+	// Adds the callback block to the value's deallocation. Also adds the logic to
+	// clean up the callback to the firstComponentDisposable.
+	void (^addDeallocObserverToPropertyValue)(NSObject *, NSString *, NSObject *) = ^(NSObject *parent, NSString *propertyKey, NSObject *value) {
+		// If a key path value is the observer, commonly when a key path begins
+		// with "self", we prevent deallocation triggered callbacks for any such key
+		// path components. Thus, the observer's deallocation is not considered a
+		// change to the key path.
+		@strongify(observer);
+		if (value == observer) return;
+
+		objc_property_t property = class_getProperty(object_getClass(parent), propertyKey.UTF8String);
+		if (property == NULL) {
+			// If we can't find an Objective-C property for this key, we assume
+			// that we don't need to observe its deallocation (thus matching
+			// vanilla KVO behavior).
+			//
+			// Even if we wanted to, there's not enough type information on
+			// ivars to figure out its memory management.
+			return;
+		}
+
+		rac_propertyAttributes *attributes = rac_copyPropertyAttributes(property);
+		if (attributes == NULL) return;
+
+		@onExit {
+			free(attributes);
+		};
+
+		BOOL isNonObject = attributes->objectClass == nil && strstr(attributes->type, @encode(id)) != attributes->type;
+		BOOL isProtocol = attributes->objectClass == NSClassFromString(@"Protocol");
+		BOOL isBlock = strcmp(attributes->type, @encode(void(^)())) == 0;
+		if (isNonObject || isProtocol || isBlock) {
+			// If this property isn't actually an object (or is a Class object),
+			// no point in observing the deallocation of the wrapper returned by
+			// KVC.
+			return;
+		}
+
+		if (!attributes->weak) {
+			// If this property is an object, but not declared `weak`, we
+			// don't need to watch for it spontaneously being set to nil.
+			//
+			// Attempting to observe non-weak properties will result in
+			// broken behavior for dynamic getters, so don't even try.
+			return;
+		}
+
+		NSDictionary *change = @{
+			NSKeyValueChangeKindKey: @(NSKeyValueChangeSetting),
+			NSKeyValueChangeNewKey: NSNull.null,
+			RACKeyValueChangeCausedByDeallocationKey: @YES,
+			RACKeyValueChangeAffectedOnlyLastComponentKey: @(keyPathHasOneComponent)
+		};
+
+		RACCompoundDisposable *valueDisposable = value.rac_deallocDisposable;
+		RACDisposable *deallocDisposable = [RACDisposable disposableWithBlock:^{
+			block(nil, change);
+		}];
+
+		[valueDisposable addDisposable:deallocDisposable];
+		[firstComponentDisposable() addDisposable:[RACDisposable disposableWithBlock:^{
+			[valueDisposable removeDisposable:deallocDisposable];
+		}]];
+	};
+
+	// Adds the callback block to the remaining path components on the value. Also
+	// adds the logic to clean up the callbacks to the firstComponentDisposable.
+	void (^addObserverToValue)(NSObject *) = ^(NSObject *value) {
+		@strongify(observer);
+		RACDisposable *observerDisposable = [value rac_observeKeyPath:keyPathTail options:(options & ~NSKeyValueObservingOptionInitial) observer:observer block:block];
+		[firstComponentDisposable() addDisposable:observerDisposable];
+	};
+
+	// Observe only the first key path component, when the value changes clean up
+	// the callbacks on the old value, add callbacks to the new value and call the
+	// callback block as needed.
+	//
+	// Note this does not use NSKeyValueObservingOptionInitial so this only
+	// handles changes to the value, callbacks to the initial value must be added
+	// separately.
+	NSKeyValueObservingOptions trampolineOptions = (options | NSKeyValueObservingOptionPrior) & ~NSKeyValueObservingOptionInitial;
+	RACKVOTrampoline *trampoline = [[RACKVOTrampoline alloc] initWithTarget:self observer:observer keyPath:keyPathHead options:trampolineOptions block:^(id trampolineTarget, id trampolineObserver, NSDictionary *change) {
+		// Prepare the change dictionary by adding the RAC specific keys
+		{
+			NSMutableDictionary *newChange = [change mutableCopy];
+			newChange[RACKeyValueChangeCausedByDeallocationKey] = @NO;
+			newChange[RACKeyValueChangeAffectedOnlyLastComponentKey] = @(keyPathHasOneComponent);
+			change = newChange.copy;
+		}
+
+		// If this is a prior notification, clean up all the callbacks added to the
+		// previous value and call the callback block. Everything else is deferred
+		// until after we get the notification after the change.
+		if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) {
+			[firstComponentDisposable() dispose];
+
+			if ((options & NSKeyValueObservingOptionPrior) != 0) {
+				block([trampolineTarget valueForKeyPath:keyPath], change);
+			}
+
+			return;
+		}
+
+		// From here the notification is not prior.
+		NSObject *value = [trampolineTarget valueForKey:keyPathHead];
+
+		// If the value has changed but is nil, there is no need to add callbacks to
+		// it, just call the callback block.
+		if (value == nil) {
+			block(nil, change);
+			return;
+		}
+
+		// From here the notification is not prior and the value is not nil.
+
+		// Create a new firstComponentDisposable while getting rid of the old one at
+		// the same time, in case this is being called concurrently.
+		RACDisposable *oldFirstComponentDisposable = [firstComponentSerialDisposable swapInDisposable:[RACCompoundDisposable compoundDisposable]];
+		[oldFirstComponentDisposable dispose];
+
+		addDeallocObserverToPropertyValue(trampolineTarget, keyPathHead, value);
+
+		// If there are no further key path components, there is no need to add the
+		// other callbacks, just call the callback block with the value itself.
+		if (keyPathHasOneComponent) {
+			block(value, change);
+			return;
+		}
+
+		// The value has changed, is not nil, and there are more key path components
+		// to consider. Add the callbacks to the value for the remaining key path
+		// components and call the callback block with the current value of the full
+		// key path.
+		addObserverToValue(value);
+		block([value valueForKeyPath:keyPathTail], change);
+	}];
+
+	// Stop the KVO observation when this one is disposed of.
+	[disposable addDisposable:trampoline];
+
+	// Add the callbacks to the initial value if needed.
+	NSObject *value = [self valueForKey:keyPathHead];
+	if (value != nil) {
+		addDeallocObserverToPropertyValue(self, keyPathHead, value);
+
+		if (!keyPathHasOneComponent) {
+			addObserverToValue(value);
+		}
+	}
+
+	// Call the block with the initial value if needed.
+	if ((options & NSKeyValueObservingOptionInitial) != 0) {
+		id initialValue = [self valueForKeyPath:keyPath];
+		NSDictionary *initialChange = @{
+			NSKeyValueChangeKindKey: @(NSKeyValueChangeSetting),
+			NSKeyValueChangeNewKey: initialValue ?: NSNull.null,
+			RACKeyValueChangeCausedByDeallocationKey: @NO,
+			RACKeyValueChangeAffectedOnlyLastComponentKey: @(keyPathHasOneComponent)
+		};
+		block(initialValue, initialChange);
+	}
+
+
+	RACCompoundDisposable *observerDisposable = observer.rac_deallocDisposable;
+	RACCompoundDisposable *selfDisposable = self.rac_deallocDisposable;
+	// Dispose of this observation if the receiver or the observer deallocate.
+	[observerDisposable addDisposable:disposable];
+	[selfDisposable addDisposable:disposable];
+
+	return [RACDisposable disposableWithBlock:^{
+		[disposable dispose];
+		[observerDisposable removeDisposable:disposable];
+		[selfDisposable removeDisposable:disposable];
+	}];
+}
+
+@end
+
+@implementation NSObject (RACKVOWrapperDeprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (RACKVOTrampoline *)rac_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(RACKVOBlock)block {
+	return [[RACKVOTrampoline alloc] initWithTarget:self observer:observer keyPath:keyPath options:options block:block];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.h
new file mode 100644
index 0000000..0feb272
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.h
@@ -0,0 +1,55 @@
+//
+//  NSObject+RACLifting.h
+//  iOSDemo
+//
+//  Created by Josh Abernathy on 10/13/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+@class RACSignal;
+
+@interface NSObject (RACLifting)
+
+/// Lifts the selector on the receiver into the reactive world. The selector will
+/// be invoked whenever any signal argument sends a value, but only after each
+/// signal has sent an initial value.
+///
+/// It will replay the most recently sent value to new subscribers.
+///
+/// This does not support C arrays or unions.
+///
+/// selector    - The selector on self to invoke.
+/// firstSignal - The signal corresponding to the first method argument. This
+///               must not be nil.
+/// ...         - A list of RACSignals corresponding to the remaining arguments.
+///               There must be a non-nil signal for each method argument.
+///
+/// Examples
+///
+///   [button rac_liftSelector:@selector(setTitleColor:forState:) withSignals:textColorSignal, [RACSignal return:@(UIControlStateNormal)], nil];
+///
+/// Returns a signal which sends the return value from each invocation of the
+/// selector. If the selector returns void, it instead sends RACUnit.defaultUnit.
+/// It completes only after all the signal arguments complete.
+- (RACSignal *)rac_liftSelector:(SEL)selector withSignals:(RACSignal *)firstSignal, ... NS_REQUIRES_NIL_TERMINATION;
+
+/// Like -rac_liftSelector:withSignals:, but accepts an array instead of
+/// a variadic list of arguments.
+- (RACSignal *)rac_liftSelector:(SEL)selector withSignalsFromArray:(NSArray *)signals;
+
+@end
+
+@interface NSObject (RACLiftingDeprecated)
+
+- (RACSignal *)rac_liftSelector:(SEL)selector withObjects:(id)arg, ... __attribute__((deprecated("Use -rac_liftSelector:withSignals: instead")));
+- (RACSignal *)rac_liftSelector:(SEL)selector withObjectsFromArray:(NSArray *)args __attribute__((deprecated("Use -rac_liftSelector:withSignalsFromArray: instead")));
+- (RACSignal *)rac_liftBlock:(id)block withArguments:(id)arg, ... NS_REQUIRES_NIL_TERMINATION __attribute__((deprecated("Use +combineLatest:reduce: instead")));
+- (RACSignal *)rac_liftBlock:(id)block withArgumentsFromArray:(NSArray *)args __attribute__((deprecated("Use +combineLatest:reduce: instead")));
+
+@end
+
+@interface NSObject (RACLiftingUnavailable)
+
+- (instancetype)rac_lift __attribute__((unavailable("Use -rac_liftSelector:withSignals: instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.m
new file mode 100644
index 0000000..5fe9a00
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACLifting.m
@@ -0,0 +1,132 @@
+//
+//  NSObject+RACLifting.m
+//  iOSDemo
+//
+//  Created by Josh Abernathy on 10/13/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "NSObject+RACLifting.h"
+#import "RACEXTScope.h"
+#import "NSInvocation+RACTypeParsing.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACSignal+Operations.h"
+#import "RACTuple.h"
+#import "NSObject+RACDescription.h"
+
+@implementation NSObject (RACLifting)
+
+- (RACSignal *)rac_liftSelector:(SEL)selector withSignalsFromArray:(NSArray *)signals {
+	NSCParameterAssert(selector != NULL);
+	NSCParameterAssert(signals != nil);
+	NSCParameterAssert(signals.count > 0);
+
+	NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
+	NSCAssert(methodSignature != nil, @"%@ does not respond to %@", self, NSStringFromSelector(selector));
+
+	NSUInteger numberOfArguments __attribute__((unused)) = methodSignature.numberOfArguments - 2;
+	NSCAssert(numberOfArguments == signals.count, @"Wrong number of signals for %@ (expected %lu, got %lu)", NSStringFromSelector(selector), (unsigned long)numberOfArguments, (unsigned long)signals.count);
+
+	@unsafeify(self);
+
+	return [[[[[RACSignal
+		combineLatest:signals]
+		takeUntil:self.rac_willDeallocSignal]
+		map:^(RACTuple *arguments) {
+			@strongify(self);
+
+			NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
+			invocation.selector = selector;
+			invocation.rac_argumentsTuple = arguments;
+			[invocation invokeWithTarget:self];
+
+			return invocation.rac_returnValue;
+		}]
+		replayLast]
+		setNameWithFormat:@"%@ -rac_liftSelector: %s withSignalsFromArray: %@", [self rac_description], sel_getName(selector), signals];
+}
+
+- (RACSignal *)rac_liftSelector:(SEL)selector withSignals:(RACSignal *)firstSignal, ... {
+	NSCParameterAssert(firstSignal != nil);
+
+	NSMutableArray *signals = [NSMutableArray array];
+
+	va_list args;
+	va_start(args, firstSignal);
+	for (id currentSignal = firstSignal; currentSignal != nil; currentSignal = va_arg(args, id)) {
+		NSCAssert([currentSignal isKindOfClass:RACSignal.class], @"Argument %@ is not a RACSignal", currentSignal);
+
+		[signals addObject:currentSignal];
+	}
+	va_end(args);
+
+	return [[self
+		rac_liftSelector:selector withSignalsFromArray:signals]
+		setNameWithFormat:@"%@ -rac_liftSelector: %s withSignals: %@", [self rac_description], sel_getName(selector), signals];
+}
+
+@end
+
+@implementation NSObject (RACLiftingDeprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+static NSArray *RACMapArgumentsToSignals(NSArray *args) {
+	NSMutableArray *mappedArgs = [NSMutableArray array];
+	for (id arg in args) {
+		if ([arg isEqual:RACTupleNil.tupleNil]) {
+			[mappedArgs addObject:[RACSignal return:nil]];
+		} else if ([arg isKindOfClass:RACSignal.class]) {
+			[mappedArgs addObject:arg];
+		} else {
+			[mappedArgs addObject:[RACSignal return:arg]];
+		}
+	}
+
+	return mappedArgs;
+}
+
+- (RACSignal *)rac_liftSelector:(SEL)selector withObjects:(id)arg, ... {
+	NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
+	NSMutableArray *arguments = [NSMutableArray array];
+
+	va_list args;
+	va_start(args, arg);
+	for (NSUInteger i = 2; i < methodSignature.numberOfArguments; i++) {
+		id currentObject = (i == 2 ? arg : va_arg(args, id));
+		[arguments addObject:currentObject ?: RACTupleNil.tupleNil];
+	}
+
+	va_end(args);
+	return [self rac_liftSelector:selector withObjectsFromArray:arguments];
+}
+
+- (RACSignal *)rac_liftSelector:(SEL)selector withObjectsFromArray:(NSArray *)args {
+	return [self rac_liftSelector:selector withSignalsFromArray:RACMapArgumentsToSignals(args)];
+}
+
+- (RACSignal *)rac_liftBlock:(id)block withArguments:(id)arg, ... {
+	NSMutableArray *arguments = [NSMutableArray array];
+
+	va_list args;
+	va_start(args, arg);
+	for (id currentObject = arg; currentObject != nil; currentObject = va_arg(args, id)) {
+		[arguments addObject:currentObject];
+	}
+
+	va_end(args);
+	return [self rac_liftBlock:block withArgumentsFromArray:arguments];
+}
+
+- (RACSignal *)rac_liftBlock:(id)block withArgumentsFromArray:(NSArray *)args {
+	return [[[[RACSignal
+		combineLatest:RACMapArgumentsToSignals(args)]
+		reduceEach:block]
+		takeUntil:self.rac_willDeallocSignal]
+		replayLast];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.h
new file mode 100644
index 0000000..10bb68d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.h
@@ -0,0 +1,102 @@
+//
+//  NSObject+RACPropertySubscribing.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/2/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACEXTKeyPathCoding.h"
+#import "RACmetamacros.h"
+
+/// Creates a signal which observes `KEYPATH` on `TARGET` for changes.
+///
+/// In either case, the observation continues until `TARGET` _or self_ is
+/// deallocated. If any intermediate object is deallocated instead, it will be
+/// assumed to have been set to nil.
+///
+/// Make sure to `@strongify(self)` when using this macro within a block! The
+/// macro will _always_ reference `self`, which can silently introduce a retain
+/// cycle within a block. As a result, you should make sure that `self` is a weak
+/// reference (e.g., created by `@weakify` and `@strongify`) before the
+/// expression that uses `RACObserve`.
+///
+/// Examples
+///
+///    // Observes self, and doesn't stop until self is deallocated.
+///    RACSignal *selfSignal = RACObserve(self, arrayController.items);
+///
+///    // Observes the array controller, and stops when self _or_ the array
+///    // controller is deallocated.
+///    RACSignal *arrayControllerSignal = RACObserve(self.arrayController, items);
+///
+///    // Observes obj.arrayController, and stops when self _or_ the array
+///    // controller is deallocated.
+///    RACSignal *signal2 = RACObserve(obj.arrayController, items);
+///
+///    @weakify(self);
+///    RACSignal *signal3 = [anotherSignal flattenMap:^(NSArrayController *arrayController) {
+///        // Avoids a retain cycle because of RACObserve implicitly referencing
+///        // self.
+///        @strongify(self);
+///        return RACObserve(arrayController, items);
+///    }];
+///
+/// Returns a signal which sends the current value of the key path on
+/// subscription, then sends the new value every time it changes, and sends
+/// completed if self or observer is deallocated.
+#define RACObserve(TARGET, KEYPATH) \
+    [(id)(TARGET) rac_valuesForKeyPath:@keypath(TARGET, KEYPATH) observer:self]
+
+@class RACDisposable;
+@class RACSignal;
+
+@interface NSObject (RACPropertySubscribing)
+
+/// Creates a signal to observe the value at the given key path.
+///
+/// The initial value is sent on subscription, the subsequent values are sent
+/// from whichever thread the change occured on, even if it doesn't have a valid
+/// scheduler.
+///
+/// Returns a signal that immediately sends the receiver's current value at the
+/// given keypath, then any changes thereafter.
+- (RACSignal *)rac_valuesForKeyPath:(NSString *)keyPath observer:(NSObject *)observer;
+
+/// Creates a signal to observe the changes of the given key path.
+///
+/// The initial value is sent on subscription, the subsequent values are sent
+/// from whichever thread the change occured on, even if it doesn't have a valid
+/// scheduler.
+///
+/// Returns a signal that sends tuples containing the current value at the key
+/// path and the change dictionary for each KVO callback.
+- (RACSignal *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer;
+
+@end
+
+#define RACAble(...) \
+    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
+        (_RACAbleObject(self, __VA_ARGS__)) \
+        (_RACAbleObject(__VA_ARGS__))
+
+#define _RACAbleObject(object, property) [object rac_signalForKeyPath:@keypath(object, property) observer:self]
+
+#define RACAbleWithStart(...) \
+    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
+        (_RACAbleWithStartObject(self, __VA_ARGS__)) \
+        (_RACAbleWithStartObject(__VA_ARGS__))
+
+#define _RACAbleWithStartObject(object, property) [object rac_signalWithStartingValueForKeyPath:@keypath(object, property) observer:self]
+
+@interface NSObject (RACPropertySubscribingDeprecated)
+
++ (RACSignal *)rac_signalFor:(NSObject *)object keyPath:(NSString *)keyPath observer:(NSObject *)observer __attribute__((deprecated("Use -rac_valuesForKeyPath:observer: or RACObserve() instead.")));
++ (RACSignal *)rac_signalWithStartingValueFor:(NSObject *)object keyPath:(NSString *)keyPath observer:(NSObject *)observer __attribute__((deprecated("Use -rac_valuesForKeyPath:observer: or RACObserve() instead.")));
++ (RACSignal *)rac_signalWithChangesFor:(NSObject *)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer __attribute__((deprecated("Use -rac_valuesAndChangesForKeyPath:options:observer: instead.")));
+- (RACSignal *)rac_signalForKeyPath:(NSString *)keyPath observer:(NSObject *)observer __attribute__((deprecated("Use -rac_valuesForKeyPath:observer: or RACObserve() instead.")));
+- (RACSignal *)rac_signalWithStartingValueForKeyPath:(NSString *)keyPath observer:(NSObject *)observer __attribute__((deprecated("Use -rac_valuesForKeyPath:observer: or RACObserve() instead.")));
+- (RACDisposable *)rac_deriveProperty:(NSString *)keyPath from:(RACSignal *)signal __attribute__((deprecated("Use -[RACSignal setKeyPath:onObject:] instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.m
new file mode 100644
index 0000000..88d4683
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.m
@@ -0,0 +1,161 @@
+//
+//  NSObject+RACPropertySubscribing.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/2/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "NSObject+RACPropertySubscribing.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACKVOWrapper.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACKVOTrampoline.h"
+#import "RACSubscriber.h"
+#import "RACSignal+Operations.h"
+#import "RACTuple.h"
+#import <libkern/OSAtomic.h>
+
+@implementation NSObject (RACPropertySubscribing)
+
+- (RACSignal *)rac_valuesForKeyPath:(NSString *)keyPath observer:(NSObject *)observer {
+	return [[[self
+		rac_valuesAndChangesForKeyPath:keyPath options:NSKeyValueObservingOptionInitial observer:observer]
+		reduceEach:^(id value, NSDictionary *change) {
+			return value;
+		}]
+		setNameWithFormat:@"RACObserve(%@, %@)", self.rac_description, keyPath];
+}
+
+- (RACSignal *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer {
+	keyPath = [keyPath copy];
+
+	NSRecursiveLock *objectLock = [[NSRecursiveLock alloc] init];
+	objectLock.name = @"com.github.ReactiveCocoa.NSObjectRACPropertySubscribing";
+
+	__block __unsafe_unretained NSObject *unsafeSelf = self;
+	__block __unsafe_unretained NSObject *unsafeObserver = observer;
+
+	RACSignal *deallocSignal = [[RACSignal
+		zip:@[
+			self.rac_willDeallocSignal,
+			observer.rac_willDeallocSignal ?: [RACSignal never]
+		]]
+		doCompleted:^{
+			// Forces deallocation to wait if the object variables are currently
+			// being read on another thread.
+			[objectLock lock];
+			@onExit {
+				[objectLock unlock];
+			};
+
+			unsafeSelf = nil;
+			unsafeObserver = nil;
+		}];
+
+	return [[[RACSignal
+		createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {
+			// Hold onto the lock the whole time we're setting up the KVO
+			// observation, because any resurrection that might be caused by our
+			// retaining below must be balanced out by the time -dealloc returns
+			// (if another thread is waiting on the lock above).
+			[objectLock lock];
+			@onExit {
+				[objectLock unlock];
+			};
+
+			__strong NSObject *observer __attribute__((objc_precise_lifetime)) = unsafeObserver;
+			__strong NSObject *self __attribute__((objc_precise_lifetime)) = unsafeSelf;
+
+			if (self == nil) {
+				[subscriber sendCompleted];
+				return nil;
+			}
+
+			return [self rac_observeKeyPath:keyPath options:options observer:observer block:^(id value, NSDictionary *change) {
+				[subscriber sendNext:RACTuplePack(value, change)];
+			}];
+		}]
+		takeUntil:deallocSignal]
+		setNameWithFormat:@"%@ -rac_valueAndChangesForKeyPath: %@ options: %lu observer: %@", self.rac_description, keyPath, (unsigned long)options, observer.rac_description];
+}
+
+@end
+
+static RACSignal *signalWithoutChangesFor(Class class, NSObject *object, NSString *keyPath, NSKeyValueObservingOptions options, NSObject *observer) {
+	NSCParameterAssert(object != nil);
+	NSCParameterAssert(keyPath != nil);
+	NSCParameterAssert(observer != nil);
+
+	keyPath = [keyPath copy];
+
+	@unsafeify(object);
+
+	return [[class
+		rac_signalWithChangesFor:object keyPath:keyPath options:options observer:observer]
+		map:^(NSDictionary *change) {
+			@strongify(object);
+			return [object valueForKeyPath:keyPath];
+		}];
+}
+
+@implementation NSObject (RACPropertySubscribingDeprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
++ (RACSignal *)rac_signalFor:(NSObject *)object keyPath:(NSString *)keyPath observer:(NSObject *)observer {
+	return signalWithoutChangesFor(self, object, keyPath, 0, observer);
+}
+
++ (RACSignal *)rac_signalWithStartingValueFor:(NSObject *)object keyPath:(NSString *)keyPath observer:(NSObject *)observer {
+	return signalWithoutChangesFor(self, object, keyPath, NSKeyValueObservingOptionInitial, observer);
+}
+
++ (RACSignal *)rac_signalWithChangesFor:(NSObject *)object keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer {
+	@unsafeify(observer, object);
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+
+		@strongify(observer, object);
+		RACKVOTrampoline *KVOTrampoline = [object rac_addObserver:observer forKeyPath:keyPath options:options block:^(id target, id observer, NSDictionary *change) {
+			[subscriber sendNext:change];
+		}];
+
+		@weakify(subscriber);
+		RACDisposable *deallocDisposable = [RACDisposable disposableWithBlock:^{
+			@strongify(subscriber);
+			[KVOTrampoline dispose];
+			[subscriber sendCompleted];
+		}];
+
+		[observer.rac_deallocDisposable addDisposable:deallocDisposable];
+		[object.rac_deallocDisposable addDisposable:deallocDisposable];
+
+		RACCompoundDisposable *observerDisposable = observer.rac_deallocDisposable;
+		RACCompoundDisposable *objectDisposable = object.rac_deallocDisposable;
+		return [RACDisposable disposableWithBlock:^{
+			[observerDisposable removeDisposable:deallocDisposable];
+			[objectDisposable removeDisposable:deallocDisposable];
+			[KVOTrampoline dispose];
+		}];
+	}] setNameWithFormat:@"RACAble(%@, %@)", object.rac_description, keyPath];
+}
+
+- (RACSignal *)rac_signalForKeyPath:(NSString *)keyPath observer:(NSObject *)observer {
+	return [self.class rac_signalFor:self keyPath:keyPath observer:observer];
+}
+
+- (RACSignal *)rac_signalWithStartingValueForKeyPath:(NSString *)keyPath observer:(NSObject *)observer {
+	return [self.class rac_signalWithStartingValueFor:self keyPath:keyPath observer:observer];
+}
+
+- (RACDisposable *)rac_deriveProperty:(NSString *)keyPath from:(RACSignal *)signal {
+	return [signal setKeyPath:keyPath onObject:self];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.h
new file mode 100644
index 0000000..c6f3de5
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.h
@@ -0,0 +1,79 @@
+//
+//  NSObject+RACSelectorSignal.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/18/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+/// The domain for any errors originating from -rac_signalForSelector:.
+extern NSString * const RACSelectorSignalErrorDomain;
+
+/// -rac_signalForSelector: was going to add a new method implementation for
+/// `selector`, but another thread added an implementation before it was able to.
+///
+/// This will _not_ occur for cases where a method implementation exists before
+/// -rac_signalForSelector: is invoked.
+extern const NSInteger RACSelectorSignalErrorMethodSwizzlingRace;
+
+@interface NSObject (RACSelectorSignal)
+
+/// Creates a signal associated with the receiver, which will send a tuple of the
+/// method's arguments each time the given selector is invoked.
+///
+/// If the selector is already implemented on the receiver, the existing
+/// implementation will be invoked _before_ the signal fires.
+///
+/// If the selector is not yet implemented on the receiver, the injected
+/// implementation will have a `void` return type and accept only object
+/// arguments. Invoking the added implementation with non-object values, or
+/// expecting a return value, will result in undefined behavior.
+///
+/// This is useful for changing an event or delegate callback into a signal. For
+/// example, on an NSView:
+///
+///     [[view rac_signalForSelector:@selector(mouseDown:)] subscribeNext:^(RACTuple *args) {
+///         NSEvent *event = args.first;
+///         NSLog(@"mouse button pressed: %@", event);
+///     }];
+///
+/// selector - The selector for whose invocations are to be observed. If it
+///            doesn't exist, it will be implemented to accept object arguments
+///            and return void. This cannot have C arrays or unions as arguments
+///            or C arrays, unions, structs, complex or vector types as return
+///            type.
+///
+/// Returns a signal which will send a tuple of arguments upon each invocation of
+/// the selector, then completes when the receiver is deallocated. `next` events
+/// will be sent synchronously from the thread that invoked the method. If
+/// a runtime call fails, the signal will send an error in the
+/// RACSelectorSignalErrorDomain.
+- (RACSignal *)rac_signalForSelector:(SEL)selector;
+
+/// Behaves like -rac_signalForSelector:, but if the selector is not yet
+/// implemented on the receiver, its method signature is looked up within
+/// `protocol`, and may accept non-object arguments.
+///
+/// If the selector is not yet implemented and has a return value, the injected
+/// method will return all zero bits (equal to `nil`, `NULL`, 0, 0.0f, etc.).
+///
+/// selector - The selector for whose invocations are to be observed. If it
+///            doesn't exist, it will be implemented using information from
+///            `protocol`, and may accept non-object arguments and return
+///            a value. This cannot have C arrays or unions as arguments or
+///            return type.
+/// protocol - The protocol in which `selector` is declared. This will be used
+///            for type information if the selector is not already implemented on
+///            the receiver. This must not be `NULL`, and `selector` must exist
+///            in this protocol.
+///
+/// Returns a signal which will send a tuple of arguments on each invocation of
+/// the selector, or an error in RACSelectorSignalErrorDomain if a runtime
+/// call fails.
+- (RACSignal *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.m
new file mode 100644
index 0000000..b7085c0
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACSelectorSignal.m
@@ -0,0 +1,322 @@
+//
+//  NSObject+RACSelectorSignal.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/18/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSObject+RACSelectorSignal.h"
+#import "RACEXTRuntimeExtensions.h"
+#import "NSInvocation+RACTypeParsing.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACObjCRuntime.h"
+#import "RACSubject.h"
+#import "RACTuple.h"
+#import "NSObject+RACDescription.h"
+#import <objc/message.h>
+#import <objc/runtime.h>
+
+NSString * const RACSelectorSignalErrorDomain = @"RACSelectorSignalErrorDomain";
+const NSInteger RACSelectorSignalErrorMethodSwizzlingRace = 1;
+
+static NSString * const RACSignalForSelectorAliasPrefix = @"rac_alias_";
+static NSString * const RACSubclassSuffix = @"_RACSelectorSignal";
+
+static NSMutableSet *swizzledClasses() {
+	static NSMutableSet *set;
+	static dispatch_once_t pred;
+	
+	dispatch_once(&pred, ^{
+		set = [[NSMutableSet alloc] init];
+	});
+
+	return set;
+}
+
+@implementation NSObject (RACSelectorSignal)
+
+static BOOL RACForwardInvocation(id self, NSInvocation *invocation) {
+	SEL aliasSelector = RACAliasForSelector(invocation.selector);
+	RACSubject *subject = objc_getAssociatedObject(self, aliasSelector);
+
+	Class class = object_getClass(invocation.target);
+	BOOL respondsToAlias = [class instancesRespondToSelector:aliasSelector];
+	if (respondsToAlias) {
+		invocation.selector = aliasSelector;
+		[invocation invoke];
+	}
+
+	if (subject == nil) return respondsToAlias;
+
+	[subject sendNext:invocation.rac_argumentsTuple];
+	return YES;
+}
+
+static void RACSwizzleForwardInvocation(Class class) {
+	SEL forwardInvocationSEL = @selector(forwardInvocation:);
+	Method forwardInvocationMethod = class_getInstanceMethod(class, forwardInvocationSEL);
+
+	// Preserve any existing implementation of -forwardInvocation:.
+	void (*originalForwardInvocation)(id, SEL, NSInvocation *) = NULL;
+	if (forwardInvocationMethod != NULL) {
+		originalForwardInvocation = (__typeof__(originalForwardInvocation))method_getImplementation(forwardInvocationMethod);
+	}
+
+	// Set up a new version of -forwardInvocation:.
+	//
+	// If the selector has been passed to -rac_signalForSelector:, invoke
+	// the aliased method, and forward the arguments to any attached signals.
+	//
+	// If the selector has not been passed to -rac_signalForSelector:,
+	// invoke any existing implementation of -forwardInvocation:. If there
+	// was no existing implementation, throw an unrecognized selector
+	// exception.
+	id newForwardInvocation = ^(id self, NSInvocation *invocation) {
+		BOOL matched = RACForwardInvocation(self, invocation);
+		if (matched) return;
+
+		if (originalForwardInvocation == NULL) {
+			[self doesNotRecognizeSelector:invocation.selector];
+		} else {
+			originalForwardInvocation(self, forwardInvocationSEL, invocation);
+		}
+	};
+
+	class_replaceMethod(class, forwardInvocationSEL, imp_implementationWithBlock(newForwardInvocation), "v@:@");
+}
+
+static void RACSwizzleRespondsToSelector(Class class) {
+	SEL respondsToSelectorSEL = @selector(respondsToSelector:);
+
+	// Preserve existing implementation of -respondsToSelector:.
+	Method respondsToSelectorMethod = class_getInstanceMethod(class, respondsToSelectorSEL);
+	BOOL (*originalRespondsToSelector)(id, SEL, SEL) = (__typeof__(originalRespondsToSelector))method_getImplementation(respondsToSelectorMethod);
+
+	// Set up a new version of -respondsToSelector: that returns YES for methods
+	// added by -rac_signalForSelector:.
+	//
+	// If the selector has a method defined on the receiver's actual class, and
+	// if that method's implementation is _objc_msgForward, then returns whether
+	// the instance has a signal for the selector.
+	// Otherwise, call the original -respondsToSelector:.
+	id newRespondsToSelector = ^ BOOL (id self, SEL selector) {
+		Method method = rac_getImmediateInstanceMethod(object_getClass(self), selector);
+
+		if (method != NULL && method_getImplementation(method) == _objc_msgForward) {
+			SEL aliasSelector = RACAliasForSelector(selector);
+			return objc_getAssociatedObject(self, aliasSelector) != nil;
+		}
+
+		return originalRespondsToSelector(self, respondsToSelectorSEL, selector);
+	};
+
+	class_replaceMethod(class, respondsToSelectorSEL, imp_implementationWithBlock(newRespondsToSelector), method_getTypeEncoding(respondsToSelectorMethod));
+}
+
+static void RACSwizzleGetClass(Class class, Class statedClass) {
+	SEL selector = @selector(class);
+	Method method = class_getInstanceMethod(class, selector);
+	IMP newIMP = imp_implementationWithBlock(^(id self) {
+		return statedClass;
+	});
+	class_replaceMethod(class, selector, newIMP, method_getTypeEncoding(method));
+}
+
+static void RACSwizzleMethodSignatureForSelector(Class class) {
+	IMP newIMP = imp_implementationWithBlock(^(id self, SEL selector) {
+		// Don't send the -class message to the receiver because we've changed
+		// that to return the original class.
+		Class actualClass = object_getClass(self);
+		Method method = class_getInstanceMethod(actualClass, selector);
+		if (method == NULL) {
+			// Messages that the original class dynamically implements fall
+			// here.
+			//
+			// Call the original class' -methodSignatureForSelector:.
+			struct objc_super target = {
+				.super_class = class_getSuperclass(class),
+				.receiver = self,
+			};
+			NSMethodSignature * (*messageSend)(struct objc_super *, SEL, SEL) = (__typeof__(messageSend))objc_msgSendSuper;
+			return messageSend(&target, @selector(methodSignatureForSelector:), selector);
+		}
+
+		char const *encoding = method_getTypeEncoding(method);
+		return [NSMethodSignature signatureWithObjCTypes:encoding];
+	});
+
+	SEL selector = @selector(methodSignatureForSelector:);
+	Method methodSignatureForSelectorMethod = class_getInstanceMethod(class, selector);
+	class_replaceMethod(class, selector, newIMP, method_getTypeEncoding(methodSignatureForSelectorMethod));
+}
+
+// It's hard to tell which struct return types use _objc_msgForward, and
+// which use _objc_msgForward_stret instead, so just exclude all struct, array,
+// union, complex and vector return types.
+static void RACCheckTypeEncoding(const char *typeEncoding) {
+#if !NS_BLOCK_ASSERTIONS
+	// Some types, including vector types, are not encoded. In these cases the
+	// signature starts with the size of the argument frame.
+	NSCAssert(*typeEncoding < '1' || *typeEncoding > '9', @"unknown method return type not supported in type encoding: %s", typeEncoding);
+	NSCAssert(strstr(typeEncoding, "(") != typeEncoding, @"union method return type not supported");
+	NSCAssert(strstr(typeEncoding, "{") != typeEncoding, @"struct method return type not supported");
+	NSCAssert(strstr(typeEncoding, "[") != typeEncoding, @"array method return type not supported");
+	NSCAssert(strstr(typeEncoding, @encode(_Complex float)) != typeEncoding, @"complex float method return type not supported");
+	NSCAssert(strstr(typeEncoding, @encode(_Complex double)) != typeEncoding, @"complex double method return type not supported");
+	NSCAssert(strstr(typeEncoding, @encode(_Complex long double)) != typeEncoding, @"complex long double method return type not supported");
+
+#endif // !NS_BLOCK_ASSERTIONS
+}
+
+static RACSignal *NSObjectRACSignalForSelector(NSObject *self, SEL selector, Protocol *protocol) {
+	SEL aliasSelector = RACAliasForSelector(selector);
+
+	@synchronized (self) {
+		RACSubject *subject = objc_getAssociatedObject(self, aliasSelector);
+		if (subject != nil) return subject;
+
+		Class class = RACSwizzleClass(self);
+		NSCAssert(class != nil, @"Could not swizzle class of %@", self);
+
+		subject = [[RACSubject subject] setNameWithFormat:@"%@ -rac_signalForSelector: %s", self.rac_description, sel_getName(selector)];
+		objc_setAssociatedObject(self, aliasSelector, subject, OBJC_ASSOCIATION_RETAIN);
+
+		[self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+			[subject sendCompleted];
+		}]];
+
+		Method targetMethod = class_getInstanceMethod(class, selector);
+		if (targetMethod == NULL) {
+			const char *typeEncoding;
+			if (protocol == NULL) {
+				typeEncoding = RACSignatureForUndefinedSelector(selector);
+			} else {
+				// Look for the selector as an optional instance method.
+				struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES);
+
+				if (methodDescription.name == NULL) {
+					// Then fall back to looking for a required instance
+					// method.
+					methodDescription = protocol_getMethodDescription(protocol, selector, YES, YES);
+					NSCAssert(methodDescription.name != NULL, @"Selector %@ does not exist in <%s>", NSStringFromSelector(selector), protocol_getName(protocol));
+				}
+
+				typeEncoding = methodDescription.types;
+			}
+
+			RACCheckTypeEncoding(typeEncoding);
+
+			// Define the selector to call -forwardInvocation:.
+			if (!class_addMethod(class, selector, _objc_msgForward, typeEncoding)) {
+				NSDictionary *userInfo = @{
+					NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedString(@"A race condition occurred implementing %@ on class %@", nil), NSStringFromSelector(selector), class],
+					NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Invoke -rac_signalForSelector: again to override the implementation.", nil)
+				};
+
+				return [RACSignal error:[NSError errorWithDomain:RACSelectorSignalErrorDomain code:RACSelectorSignalErrorMethodSwizzlingRace userInfo:userInfo]];
+			}
+		} else if (method_getImplementation(targetMethod) != _objc_msgForward) {
+			// Make a method alias for the existing method implementation.
+			const char *typeEncoding = method_getTypeEncoding(targetMethod);
+
+			RACCheckTypeEncoding(typeEncoding);
+
+			BOOL addedAlias __attribute__((unused)) = class_addMethod(class, aliasSelector, method_getImplementation(targetMethod), typeEncoding);
+			NSCAssert(addedAlias, @"Original implementation for %@ is already copied to %@ on %@", NSStringFromSelector(selector), NSStringFromSelector(aliasSelector), class);
+
+			// Redefine the selector to call -forwardInvocation:.
+			class_replaceMethod(class, selector, _objc_msgForward, method_getTypeEncoding(targetMethod));
+		}
+
+		return subject;
+	}
+}
+
+static SEL RACAliasForSelector(SEL originalSelector) {
+	NSString *selectorName = NSStringFromSelector(originalSelector);
+	return NSSelectorFromString([RACSignalForSelectorAliasPrefix stringByAppendingString:selectorName]);
+}
+
+static const char *RACSignatureForUndefinedSelector(SEL selector) {
+	const char *name = sel_getName(selector);
+	NSMutableString *signature = [NSMutableString stringWithString:@"v@:"];
+
+	while ((name = strchr(name, ':')) != NULL) {
+		[signature appendString:@"@"];
+		name++;
+	}
+
+	return signature.UTF8String;
+}
+
+static Class RACSwizzleClass(NSObject *self) {
+	Class statedClass = self.class;
+	Class baseClass = object_getClass(self);
+	NSString *className = NSStringFromClass(baseClass);
+
+	if ([className hasSuffix:RACSubclassSuffix]) {
+		return baseClass;
+	} else if (statedClass != baseClass) {
+		// If the class is already lying about what it is, it's probably a KVO
+		// dynamic subclass or something else that we shouldn't subclass
+		// ourselves.
+		//
+		// Just swizzle -forwardInvocation: in-place. Since the object's class
+		// was almost certainly dynamically changed, we shouldn't see another of
+		// these classes in the hierarchy.
+		//
+		// Additionally, swizzle -respondsToSelector: because the default
+		// implementation may be ignorant of methods added to this class.
+		@synchronized (swizzledClasses()) {
+			if (![swizzledClasses() containsObject:className]) {
+				RACSwizzleForwardInvocation(baseClass);
+				RACSwizzleRespondsToSelector(baseClass);
+				RACSwizzleGetClass(baseClass, statedClass);
+				RACSwizzleGetClass(object_getClass(baseClass), statedClass);
+				RACSwizzleMethodSignatureForSelector(baseClass);
+				[swizzledClasses() addObject:className];
+			}
+		}
+
+		return baseClass;
+	}
+
+	const char *subclassName = [className stringByAppendingString:RACSubclassSuffix].UTF8String;
+	Class subclass = objc_getClass(subclassName);
+
+	if (subclass == nil) {
+		subclass = [RACObjCRuntime createClass:subclassName inheritingFromClass:baseClass];
+		if (subclass == nil) return nil;
+
+		RACSwizzleForwardInvocation(subclass);
+		RACSwizzleRespondsToSelector(subclass);
+
+		RACSwizzleGetClass(subclass, statedClass);
+		RACSwizzleGetClass(object_getClass(subclass), statedClass);
+
+		RACSwizzleMethodSignatureForSelector(subclass);
+
+		objc_registerClassPair(subclass);
+	}
+
+	object_setClass(self, subclass);
+	return subclass;
+}
+
+- (RACSignal *)rac_signalForSelector:(SEL)selector {
+	NSCParameterAssert(selector != NULL);
+
+	return NSObjectRACSignalForSelector(self, selector, NULL);
+}
+
+- (RACSignal *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol {
+	NSCParameterAssert(selector != NULL);
+	NSCParameterAssert(protocol != NULL);
+
+	return NSObjectRACSignalForSelector(self, selector, protocol);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.h
new file mode 100644
index 0000000..8bea2db
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.h
@@ -0,0 +1,20 @@
+//
+//  NSOrderedSet+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSOrderedSet (RACSequenceAdditions)
+
+/// Creates and returns a sequence corresponding to the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.m
new file mode 100644
index 0000000..55dfd0b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSOrderedSet+RACSequenceAdditions.m
@@ -0,0 +1,19 @@
+//
+//  NSOrderedSet+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSOrderedSet+RACSequenceAdditions.h"
+#import "NSArray+RACSequenceAdditions.h"
+
+@implementation NSOrderedSet (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	// TODO: First class support for ordered set sequences.
+	return self.array.rac_sequence;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.h
new file mode 100644
index 0000000..6665501
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.h
@@ -0,0 +1,20 @@
+//
+//  NSSet+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSSet (RACSequenceAdditions)
+
+/// Creates and returns a sequence corresponding to the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.m
new file mode 100644
index 0000000..cc07f75
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSSet+RACSequenceAdditions.m
@@ -0,0 +1,19 @@
+//
+//  NSSet+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSSet+RACSequenceAdditions.h"
+#import "NSArray+RACSequenceAdditions.h"
+
+@implementation NSSet (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	// TODO: First class support for set sequences.
+	return self.allObjects.rac_sequence;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.h b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.h
new file mode 100644
index 0000000..d56cf59
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.h
@@ -0,0 +1,34 @@
+//
+//  NSString+RACKeyPathUtilities.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 05/05/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// A private category of methods to extract parts of a key path.
+@interface NSString (RACKeyPathUtilities)
+
+// Returns an array of the components of the receiver.
+//
+// Calling this method on a string that isn't a key path is considered undefined
+// behavior.
+- (NSArray *)rac_keyPathComponents;
+
+// Returns a key path with all the components of the receiver except for the
+// last one.
+//
+// Calling this method on a string that isn't a key path is considered undefined
+// behavior.
+- (NSString *)rac_keyPathByDeletingLastKeyPathComponent;
+
+// Returns a key path with all the components of the receiver expect for the
+// first one.
+//
+// Calling this method on a string that isn't a key path is considered undefined
+// behavior.
+- (NSString *)rac_keyPathByDeletingFirstKeyPathComponent;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.m b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.m
new file mode 100644
index 0000000..63a100c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACKeyPathUtilities.m
@@ -0,0 +1,36 @@
+//
+//  NSString+RACKeyPathUtilities.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 05/05/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSString+RACKeyPathUtilities.h"
+
+@implementation NSString (RACKeyPathUtilities)
+
+- (NSArray *)rac_keyPathComponents {
+	if (self.length == 0) {
+		return nil;
+	}
+	return [self componentsSeparatedByString:@"."];
+}
+
+- (NSString *)rac_keyPathByDeletingLastKeyPathComponent {
+	NSUInteger lastDotIndex = [self rangeOfString:@"." options:NSBackwardsSearch].location;
+	if (lastDotIndex == NSNotFound) {
+		return nil;
+	}
+	return [self substringToIndex:lastDotIndex];
+}
+
+- (NSString *)rac_keyPathByDeletingFirstKeyPathComponent {
+	NSUInteger firstDotIndex = [self rangeOfString:@"."].location;
+	if (firstDotIndex == NSNotFound) {
+		return nil;
+	}
+	return [self substringFromIndex:firstDotIndex + 1];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.h b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.h
new file mode 100644
index 0000000..0116231
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.h
@@ -0,0 +1,21 @@
+//
+//  NSString+RACSequenceAdditions.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSequence;
+
+@interface NSString (RACSequenceAdditions)
+
+/// Creates and returns a sequence containing strings corresponding to each
+/// composed character sequence in the receiver.
+///
+/// Mutating the receiver will not affect the sequence after it's been created.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.m b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.m
new file mode 100644
index 0000000..eb6a76e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSequenceAdditions.m
@@ -0,0 +1,18 @@
+//
+//  NSString+RACSequenceAdditions.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "NSString+RACSequenceAdditions.h"
+#import "RACStringSequence.h"
+
+@implementation NSString (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	return [RACStringSequence sequenceWithString:self offset:0];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.h
new file mode 100644
index 0000000..d904a4c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.h
@@ -0,0 +1,22 @@
+//
+//  NSString+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+@class RACScheduler;
+
+@interface NSString (RACSupport)
+
+// Reads in the contents of the file using +[NSString stringWithContentsOfURL:usedEncoding:error:].
+// Note that encoding won't be valid until the signal completes successfully.
+//
+// scheduler - cannot be nil.
++ (RACSignal *)rac_readContentsOfURL:(NSURL *)URL usedEncoding:(NSStringEncoding *)encoding scheduler:(RACScheduler *)scheduler;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.m
new file mode 100644
index 0000000..c6ebe0b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSString+RACSupport.m
@@ -0,0 +1,35 @@
+//
+//  NSString+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "NSString+RACSupport.h"
+#import "RACReplaySubject.h"
+#import "RACScheduler.h"
+
+@implementation NSString (RACSupport)
+
++ (RACSignal *)rac_readContentsOfURL:(NSURL *)URL usedEncoding:(NSStringEncoding *)encoding scheduler:(RACScheduler *)scheduler {
+	NSCParameterAssert(scheduler != nil);
+	
+	RACReplaySubject *subject = [RACReplaySubject subject];
+	[subject setNameWithFormat:@"+rac_readContentsOfURL: %@ usedEncoding:scheduler: %@", URL, scheduler];
+	
+	[scheduler schedule:^{
+		NSError *error = nil;
+		NSString *string = [NSString stringWithContentsOfURL:URL usedEncoding:encoding error:&error];
+		if(string == nil) {
+			[subject sendError:error];
+		} else {
+			[subject sendNext:string];
+			[subject sendCompleted];
+		}
+	}];
+	
+	return subject;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.h
new file mode 100644
index 0000000..e9bf04f
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.h
@@ -0,0 +1,25 @@
+//
+//  NSURLConnection+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+@interface NSURLConnection (RACSupport)
+
+// Lazily loads data for the given request in the background.
+//
+// request - The URL request to load. This must not be nil.
+//
+// Returns a signal which will begin loading the request upon each subscription,
+// then send a `RACTuple` of the received `NSURLResponse` and downloaded
+// `NSData`, and complete on a background thread. If any errors occur, the
+// returned signal will error out.
++ (RACSignal *)rac_sendAsynchronousRequest:(NSURLRequest *)request;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.m
new file mode 100644
index 0000000..3eaa2c3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSURLConnection+RACSupport.m
@@ -0,0 +1,53 @@
+//
+//  NSURLConnection+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSURLConnection+RACSupport.h"
+#import "RACDisposable.h"
+#import "RACSignal.h"
+#import "RACSignal+Operations.h"
+#import "RACSubscriber.h"
+#import "RACTuple.h"
+
+@implementation NSURLConnection (RACSupport)
+
++ (RACSignal *)rac_sendAsynchronousRequest:(NSURLRequest *)request {
+	NSCParameterAssert(request != nil);
+
+	return [[RACSignal
+		createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {
+			NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+			queue.name = @"com.github.ReactiveCocoa.NSURLConnectionRACSupport";
+
+			[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
+				// The docs say that `nil` data means an error occurred, but
+				// `nil` responses can also occur in practice (circumstances
+				// unknown). Consider either to be an error.
+				//
+				// Note that _empty_ data is not necessarily erroneous, as there
+				// may be headers but no HTTP body.
+				if (response == nil || data == nil) {
+					[subscriber sendError:error];
+				} else {
+					[subscriber sendNext:RACTuplePack(response, data)];
+					[subscriber sendCompleted];
+				}
+			}];
+
+			return [RACDisposable disposableWithBlock:^{
+				// It's not clear if this will actually cancel the connection,
+				// but we can at least prevent _some_ unnecessary work --
+				// without writing all the code for a proper delegate, which
+				// doesn't really belong in RAC.
+				queue.suspended = YES;
+				[queue cancelAllOperations];
+			}];
+		}]
+		setNameWithFormat:@"+rac_sendAsynchronousRequest: %@", request];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.h
new file mode 100644
index 0000000..8482fb3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.h
@@ -0,0 +1,27 @@
+//
+//  NSUserDefaults+RACSupport.h
+//  ReactiveCocoa
+//
+//  Created by Matt Diephouse on 12/19/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACChannelTerminal;
+
+@interface NSUserDefaults (RACSupport)
+
+/// Creates and returns a terminal for binding the user defaults key.
+///
+/// **Note:** The value in the user defaults is *asynchronously* updated with
+/// values sent to the channel.
+///
+/// key - The user defaults key to create the channel terminal for.
+///
+/// Returns a channel terminal that sends the value of the user defaults key
+/// upon subscription, sends an updated value whenever the default changes, and
+/// updates the default asynchronously with values it receives.
+- (RACChannelTerminal *)rac_channelTerminalForKey:(NSString *)key;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.m
new file mode 100644
index 0000000..eaef5a6
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/NSUserDefaults+RACSupport.m
@@ -0,0 +1,58 @@
+//
+//  NSUserDefaults+RACSupport.m
+//  ReactiveCocoa
+//
+//  Created by Matt Diephouse on 12/19/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "NSUserDefaults+RACSupport.h"
+
+#import "RACEXTScope.h"
+#import "RACChannel.h"
+#import "RACScheduler.h"
+#import "RACSignal+Operations.h"
+#import "NSNotificationCenter+RACSupport.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACLifting.h"
+
+@implementation NSUserDefaults (RACSupport)
+
+- (RACChannelTerminal *)rac_channelTerminalForKey:(NSString *)key {
+	RACChannel *channel = [RACChannel new];
+	
+	RACScheduler *scheduler = [RACScheduler scheduler];
+	__block BOOL ignoreNextValue = NO;
+	
+	@weakify(self);
+	[[[[[[[NSNotificationCenter.defaultCenter
+		rac_addObserverForName:NSUserDefaultsDidChangeNotification object:self]
+		map:^(id _) {
+			@strongify(self);
+			return [self objectForKey:key];
+		}]
+		startWith:[self objectForKey:key]]
+		// Don't send values that were set on the other side of the terminal.
+		filter:^ BOOL (id _) {
+			if (RACScheduler.currentScheduler == scheduler && ignoreNextValue) {
+				ignoreNextValue = NO;
+				return NO;
+			}
+			return YES;
+		}]
+		distinctUntilChanged]
+		takeUntil:self.rac_willDeallocSignal]
+		subscribe:channel.leadingTerminal];
+	
+	[[channel.leadingTerminal
+		deliverOn:scheduler]
+		subscribeNext:^(id value) {
+			@strongify(self);
+			ignoreNextValue = YES;
+			[self setObject:value forKey:key];
+		}];
+	
+	return channel.followingTerminal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.h
new file mode 100644
index 0000000..e9d948e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.h
@@ -0,0 +1,18 @@
+//
+//  RACArraySequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class that adapts an array to the RACSequence interface.
+@interface RACArraySequence : RACSequence
+
+// Returns a sequence for enumerating over the given array, starting from the
+// given offset. The array will be copied to prevent mutation.
++ (instancetype)sequenceWithArray:(NSArray *)array offset:(NSUInteger)offset;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.m
new file mode 100644
index 0000000..f7ca69d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACArraySequence.m
@@ -0,0 +1,125 @@
+//
+//  RACArraySequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACArraySequence.h"
+
+@interface RACArraySequence ()
+
+// Redeclared from the superclass and marked deprecated to prevent using `array`
+// where `backingArray` is intended.
+@property (nonatomic, copy, readonly) NSArray *array __attribute__((deprecated));
+
+// The array being sequenced.
+@property (nonatomic, copy, readonly) NSArray *backingArray;
+
+// The index in the array from which the sequence starts.
+@property (nonatomic, assign, readonly) NSUInteger offset;
+
+@end
+
+@implementation RACArraySequence
+
+#pragma mark Lifecycle
+
++ (instancetype)sequenceWithArray:(NSArray *)array offset:(NSUInteger)offset {
+	NSCParameterAssert(offset <= array.count);
+
+	if (offset == array.count) return self.empty;
+
+	RACArraySequence *seq = [[self alloc] init];
+	seq->_backingArray = [array copy];
+	seq->_offset = offset;
+	return seq;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	return [self.backingArray objectAtIndex:self.offset];
+}
+
+- (RACSequence *)tail {
+	RACSequence *sequence = [self.class sequenceWithArray:self.backingArray offset:self.offset + 1];
+	sequence.name = self.name;
+	return sequence;
+}
+
+#pragma mark NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id[])stackbuf count:(NSUInteger)len {
+	NSCParameterAssert(len > 0);
+
+	if (state->state >= self.backingArray.count) {
+		// Enumeration has completed.
+		return 0;
+	}
+
+	if (state->state == 0) {
+		state->state = self.offset;
+
+		// Since a sequence doesn't mutate, this just needs to be set to
+		// something non-NULL.
+		state->mutationsPtr = state->extra;
+	}
+
+	state->itemsPtr = stackbuf;
+
+	NSUInteger startIndex = state->state;
+	NSUInteger index = 0;
+
+	for (id value in self.backingArray) {
+		// Constructing an index set for -enumerateObjectsAtIndexes: can actually be
+		// slower than just skipping the items we don't care about.
+		if (index < startIndex) {
+			++index;
+			continue;
+		}
+
+		stackbuf[index - startIndex] = value;
+
+		++index;
+		if (index - startIndex >= len) break;
+	}
+
+	NSCAssert(index > startIndex, @"Final index (%lu) should be greater than start index (%lu)", (unsigned long)index, (unsigned long)startIndex);
+
+	state->state = index;
+	return index - startIndex;
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+- (NSArray *)array {
+	return [self.backingArray subarrayWithRange:NSMakeRange(self.offset, self.backingArray.count - self.offset)];
+}
+#pragma clang diagnostic pop
+
+#pragma mark NSCoding
+
+- (id)initWithCoder:(NSCoder *)coder {
+	self = [super initWithCoder:coder];
+	if (self == nil) return nil;
+
+	_backingArray = [coder decodeObjectForKey:@"array"];
+	_offset = 0;
+
+	return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+	// Encoding is handled in RACSequence.
+	[super encodeWithCoder:coder];
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, array = %@ }", self.class, self, self.name, self.backingArray];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.h b/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.h
new file mode 100644
index 0000000..8588c80
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.h
@@ -0,0 +1,70 @@
+//
+//  RACBacktrace.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-08-20.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#ifdef DEBUG
+
+extern void rac_dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+extern void rac_dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
+extern void rac_dispatch_after(dispatch_time_t time, dispatch_queue_t queue, dispatch_block_t block);
+extern void rac_dispatch_async_f(dispatch_queue_t queue, void *context, dispatch_function_t function);
+extern void rac_dispatch_barrier_async_f(dispatch_queue_t queue, void *context, dispatch_function_t function);
+extern void rac_dispatch_after_f(dispatch_time_t time, dispatch_queue_t queue, void *context, dispatch_function_t function);
+
+#define dispatch_async rac_dispatch_async
+#define dispatch_barrier_async rac_dispatch_barrier_async
+#define dispatch_after rac_dispatch_after
+#define dispatch_async_f rac_dispatch_async_f
+#define dispatch_barrier_async_f rac_dispatch_barrier_async_f
+#define dispatch_after_f rac_dispatch_after_f
+
+/// Preserves backtraces across asynchronous calls.
+///
+/// On OS X, you can enable the automatic capturing of asynchronous backtraces
+/// (in Debug builds) by setting the `DYLD_INSERT_LIBRARIES` environment variable
+/// to `@executable_path/../Frameworks/ReactiveCocoa.framework/ReactiveCocoa` in
+/// your scheme's Run action settings.
+///
+/// On iOS, your project and RAC will automatically use the `rac_` GCD functions
+/// (declared above) for asynchronous work. Unfortunately, unlike OS X, it's
+/// impossible to capture backtraces inside NSOperationQueue or other code
+/// outside of your project.
+///
+/// Once backtraces are being captured, you can `po [RACBacktrace backtrace]` in
+/// the debugger to print them out at any time. You can even set up an alias in
+/// ~/.lldbinit to do so:
+///
+///    command alias racbt po [RACBacktrace backtrace]
+/// 
+@interface RACBacktrace : NSObject
+
+/// The backtrace from any previous thread.
+@property (nonatomic, strong, readonly) RACBacktrace *previousThreadBacktrace;
+
+/// The call stack of this backtrace's thread.
+@property (nonatomic, copy, readonly) NSArray *callStackSymbols;
+
+/// Captures the current thread's backtrace, appending it to any backtrace from
+/// a previous thread.
++ (instancetype)backtrace;
+
+/// Same as +backtrace, but omits the specified number of frames at the
+/// top of the stack (in addition to this method itself).
++ (instancetype)backtraceIgnoringFrames:(NSUInteger)ignoreCount;
+
+@end
+
+#else
+
+#define rac_dispatch_async dispatch_async
+#define rac_dispatch_barrier_async dispatch_barrier_async
+#define rac_dispatch_after dispatch_after
+#define rac_dispatch_async_f dispatch_async_f
+#define rac_dispatch_barrier_async_f dispatch_barrier_async_f
+#define rac_dispatch_after_f dispatch_after_f
+
+#endif
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.m b/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.m
new file mode 100644
index 0000000..c2724d4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBacktrace.m
@@ -0,0 +1,249 @@
+//
+//  RACBacktrace.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-08-16.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <execinfo.h>
+#import <pthread.h>
+#import "RACBacktrace.h"
+
+#define RAC_BACKTRACE_MAX_CALL_STACK_FRAMES 128
+
+#ifdef DEBUG
+
+// Undefine the macros that hide the real GCD functions.
+#undef dispatch_async
+#undef dispatch_barrier_async
+#undef dispatch_after
+#undef dispatch_async_f
+#undef dispatch_barrier_async_f
+#undef dispatch_after_f
+
+@interface RACBacktrace () {
+	void *_callStackAddresses[RAC_BACKTRACE_MAX_CALL_STACK_FRAMES];
+	int _callStackSize;
+}
+
+@property (nonatomic, strong, readwrite) RACBacktrace *previousThreadBacktrace;
+@end
+
+@interface RACDispatchInfo : NSObject
+
+// The recorded backtrace.
+@property (nonatomic, strong, readonly) RACBacktrace *backtrace;
+
+// The information for the original dispatch.
+@property (nonatomic, readonly) dispatch_function_t function;
+@property (nonatomic, readonly) void *context;
+@property (nonatomic, readonly) dispatch_queue_t queue;
+
+- (id)initWithQueue:(dispatch_queue_t)queue function:(dispatch_function_t)function context:(void *)context;
+
+@end
+
+// Function for use with dispatch_async_f and friends, which will save the
+// backtrace onto the current queue, then call through to the original dispatch.
+static void RACTraceDispatch (void *ptr) {
+	// Balance out the retain necessary for async calls.
+	RACDispatchInfo *info __attribute__((objc_precise_lifetime)) = CFBridgingRelease(ptr);
+
+	dispatch_queue_set_specific(info.queue, (void *)pthread_self(), (__bridge void *)info.backtrace, NULL);
+	info.function(info.context);
+	dispatch_queue_set_specific(info.queue, (void *)pthread_self(), NULL, NULL);
+}
+
+// Always inline this function, for consistency in backtraces.
+__attribute__((always_inline))
+static dispatch_block_t RACBacktraceBlock (dispatch_queue_t queue, dispatch_block_t block) {
+	RACBacktrace *backtrace = [RACBacktrace backtrace];
+
+	return [^{
+		RACBacktrace *backtraceKeptAlive __attribute__((objc_precise_lifetime)) = backtrace;
+
+		dispatch_queue_set_specific(queue, (void *)pthread_self(), (__bridge void *)backtraceKeptAlive, NULL);
+		block();
+		dispatch_queue_set_specific(queue, (void *)pthread_self(), NULL, NULL);
+	} copy];
+}
+
+void rac_dispatch_async(dispatch_queue_t queue, dispatch_block_t block) {
+	dispatch_async(queue, RACBacktraceBlock(queue, block));
+}
+
+void rac_dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block) {
+	dispatch_barrier_async(queue, RACBacktraceBlock(queue, block));
+}
+
+void rac_dispatch_after(dispatch_time_t time, dispatch_queue_t queue, dispatch_block_t block) {
+	dispatch_after(time, queue, RACBacktraceBlock(queue, block));
+}
+
+void rac_dispatch_async_f(dispatch_queue_t queue, void *context, dispatch_function_t function) {
+	RACDispatchInfo *info = [[RACDispatchInfo alloc] initWithQueue:queue function:function context:context];
+	dispatch_async_f(queue, (void *)CFBridgingRetain(info), &RACTraceDispatch);
+}
+
+void rac_dispatch_barrier_async_f(dispatch_queue_t queue, void *context, dispatch_function_t function) {
+	RACDispatchInfo *info = [[RACDispatchInfo alloc] initWithQueue:queue function:function context:context];
+	dispatch_barrier_async_f(queue, (void *)CFBridgingRetain(info), &RACTraceDispatch);
+}
+
+void rac_dispatch_after_f(dispatch_time_t time, dispatch_queue_t queue, void *context, dispatch_function_t function) {
+	RACDispatchInfo *info = [[RACDispatchInfo alloc] initWithQueue:queue function:function context:context];
+	dispatch_after_f(time, queue, (void *)CFBridgingRetain(info), &RACTraceDispatch);
+}
+
+// This is what actually performs the injection.
+//
+// The DYLD_INSERT_LIBRARIES environment variable must include the RAC dynamic
+// library in order for this to work.
+__attribute__((used)) static struct { const void *replacement; const void *replacee; } interposers[] __attribute__((section("__DATA,__interpose"))) = {
+	{ (const void *)&rac_dispatch_async, (const void *)&dispatch_async },
+	{ (const void *)&rac_dispatch_barrier_async, (const void *)&dispatch_barrier_async },
+	{ (const void *)&rac_dispatch_after, (const void *)&dispatch_after },
+	{ (const void *)&rac_dispatch_async_f, (const void *)&dispatch_async_f },
+	{ (const void *)&rac_dispatch_barrier_async_f, (const void *)&dispatch_barrier_async_f },
+	{ (const void *)&rac_dispatch_after_f, (const void *)&dispatch_after_f },
+};
+
+static void RACSignalHandler (int sig) {
+	NSLog(@"Backtrace: %@", [RACBacktrace backtrace]);
+	fflush(stdout);
+
+	// Restore the default action and raise the signal again.
+	signal(sig, SIG_DFL);
+	raise(sig);
+}
+
+static void RACExceptionHandler (NSException *ex) {
+	NSLog(@"Uncaught exception %@", ex);
+	NSLog(@"Backtrace: %@", [RACBacktrace backtrace]);
+	fflush(stdout);
+}
+
+@implementation RACBacktrace
+
+#pragma mark Properties
+
+- (NSArray *)callStackSymbols {
+	if (_callStackSize == 0) return @[];
+
+	char **symbols = backtrace_symbols(_callStackAddresses, _callStackSize);
+	NSMutableArray *array = [NSMutableArray arrayWithCapacity:(NSUInteger)_callStackSize];
+
+	for (int i = 0; i < _callStackSize; i++) {
+		NSString *str = @(symbols[i]);
+		[array addObject:str];
+	}
+
+	free(symbols);
+	return array;
+}
+
+#pragma mark Lifecycle
+
++ (void)load {
+	@autoreleasepool {
+		NSString *libraries = [[[NSProcessInfo processInfo] environment] objectForKey:@"DYLD_INSERT_LIBRARIES"];
+
+		// Don't install our handlers if we're not actually intercepting function
+		// calls.
+		if ([libraries rangeOfString:@"ReactiveCocoa"].length == 0) return;
+
+		NSLog(@"*** Enabling asynchronous backtraces");
+
+		NSSetUncaughtExceptionHandler(&RACExceptionHandler);
+	}
+
+	signal(SIGILL, &RACSignalHandler);
+	signal(SIGTRAP, &RACSignalHandler);
+	signal(SIGABRT, &RACSignalHandler);
+	signal(SIGFPE, &RACSignalHandler);
+	signal(SIGBUS, &RACSignalHandler);
+	signal(SIGSEGV, &RACSignalHandler);
+	signal(SIGSYS, &RACSignalHandler);
+	signal(SIGPIPE, &RACSignalHandler);
+}
+
+- (void)dealloc {
+	__autoreleasing RACBacktrace *previous __attribute__((unused)) = self.previousThreadBacktrace;
+	self.previousThreadBacktrace = nil;
+}
+
+#pragma mark Backtraces
+
++ (instancetype)backtrace {
+	return [self backtraceIgnoringFrames:1];
+}
+
++ (instancetype)backtraceIgnoringFrames:(NSUInteger)ignoreCount {
+	@autoreleasepool {
+		RACBacktrace *oldBacktrace = (__bridge id)dispatch_get_specific((void *)pthread_self());
+
+		RACBacktrace *newBacktrace = [[RACBacktrace alloc] init];
+		newBacktrace.previousThreadBacktrace = oldBacktrace;
+
+		int size = backtrace(newBacktrace->_callStackAddresses, RAC_BACKTRACE_MAX_CALL_STACK_FRAMES);
+
+		// Omit this method plus however many others from the backtrace.
+		++ignoreCount;
+		if ((NSUInteger)size > ignoreCount) {
+			memmove(newBacktrace->_callStackAddresses, newBacktrace->_callStackAddresses + ignoreCount, ((NSUInteger)size - ignoreCount) * sizeof(char *));
+			size -= (int)ignoreCount;
+		}
+
+		newBacktrace->_callStackSize = size;
+		return newBacktrace;
+	}
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	NSString *str = [NSString stringWithFormat:@"%@", self.callStackSymbols];
+	if (self.previousThreadBacktrace != nil) {
+		str = [str stringByAppendingFormat:@"\n\n... asynchronously invoked from: %@", self.previousThreadBacktrace];
+	}
+
+	return str;
+}
+
+@end
+
+@implementation RACDispatchInfo
+
+#pragma mark Lifecycle
+
+- (id)initWithQueue:(dispatch_queue_t)queue function:(dispatch_function_t)function context:(void *)context {
+	@autoreleasepool {
+		NSCParameterAssert(queue != NULL);
+		NSCParameterAssert(function != NULL);
+
+		self = [super init];
+		if (self == nil) return nil;
+
+		_backtrace = [RACBacktrace backtraceIgnoringFrames:1];
+
+		dispatch_retain(queue);
+		_queue = queue;
+
+		_function = function;
+		_context = context;
+
+		return self;
+	}
+}
+
+- (void)dealloc {
+	if (_queue != NULL) {
+		dispatch_release(_queue);
+		_queue = NULL;
+	}
+}
+
+@end
+
+#endif
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.h b/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.h
new file mode 100644
index 0000000..2f9e0db
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.h
@@ -0,0 +1,19 @@
+//
+//  RACBehaviorSubject.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubject.h"
+
+
+/// A behavior subject sends the last value it received when it is subscribed to.
+@interface RACBehaviorSubject : RACSubject
+
+/// Creates a new behavior subject with a default value. If it hasn't received
+/// any values when it gets subscribed to, it sends the default value.
++ (instancetype)behaviorSubjectWithDefaultValue:(id)value;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.m b/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.m
new file mode 100644
index 0000000..dfda2ac
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBehaviorSubject.m
@@ -0,0 +1,56 @@
+//
+//  RACBehaviorSubject.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACBehaviorSubject.h"
+#import "RACDisposable.h"
+#import "RACScheduler+Private.h"
+
+@interface RACBehaviorSubject ()
+
+// This property should only be used while synchronized on self.
+@property (nonatomic, strong) id currentValue;
+
+@end
+
+@implementation RACBehaviorSubject
+
+#pragma mark Lifecycle
+
++ (instancetype)behaviorSubjectWithDefaultValue:(id)value {
+	RACBehaviorSubject *subject = [self subject];
+	subject.currentValue = value;
+	return subject;
+}
+
+#pragma mark RACSignal
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	RACDisposable *subscriptionDisposable = [super subscribe:subscriber];
+
+	RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
+		@synchronized (self) {
+			[subscriber sendNext:self.currentValue];
+		}
+	}];
+	
+	return [RACDisposable disposableWithBlock:^{
+		[subscriptionDisposable dispose];
+		[schedulingDisposable dispose];
+	}];
+}
+
+#pragma mark RACSubscriber
+
+- (void)sendNext:(id)value {
+	@synchronized (self) {
+		self.currentValue = value;
+		[super sendNext:value];
+	}
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.h b/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.h
new file mode 100644
index 0000000..3857d7c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.h
@@ -0,0 +1,30 @@
+//
+//  RACBlockTrampoline.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 10/21/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACTuple;
+
+// A private class that allows a limited type of dynamic block invocation.
+@interface RACBlockTrampoline : NSObject
+
+// Invokes the given block with the given arguments. All of the block's
+// argument types must be objects and it must be typed to return an object.
+//
+// At this time, it only supports blocks that take up to 15 arguments. Any more
+// is just cray.
+//
+// block     - The block to invoke. Must accept as many arguments as are given in
+//             the arguments array. Cannot be nil.
+// arguments - The arguments with which to invoke the block. `RACTupleNil`s will
+//             be passed as nils.
+//
+// Returns the return value of invoking the block.
++ (id)invokeBlock:(id)block withArguments:(RACTuple *)arguments;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.m b/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.m
new file mode 100644
index 0000000..07903dd
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACBlockTrampoline.m
@@ -0,0 +1,156 @@
+//
+//  RACBlockTrampoline.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 10/21/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACBlockTrampoline.h"
+#import "RACTuple.h"
+
+@interface RACBlockTrampoline ()
+@property (nonatomic, readonly, copy) id block;
+@end
+
+@implementation RACBlockTrampoline
+
+#pragma mark API
+
+- (id)initWithBlock:(id)block {
+	self = [super init];
+	if (self == nil) return nil;
+
+	_block = [block copy];
+
+	return self;
+}
+
++ (id)invokeBlock:(id)block withArguments:(RACTuple *)arguments {
+	NSCParameterAssert(block != NULL);
+
+	RACBlockTrampoline *trampoline = [[self alloc] initWithBlock:block];
+	return [trampoline invokeWithArguments:arguments];
+}
+
+- (id)invokeWithArguments:(RACTuple *)arguments {
+	SEL selector = [self selectorForArgumentCount:arguments.count];
+	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
+	invocation.selector = selector;
+	invocation.target = self;
+
+	for (NSUInteger i = 0; i < arguments.count; i++) {
+		id arg = arguments[i];
+		NSInteger argIndex = (NSInteger)(i + 2);
+		[invocation setArgument:&arg atIndex:argIndex];
+	}
+
+	[invocation invoke];
+	
+	__unsafe_unretained id returnVal;
+	[invocation getReturnValue:&returnVal];
+	return returnVal;
+}
+
+- (SEL)selectorForArgumentCount:(NSUInteger)count {
+	NSCParameterAssert(count > 0);
+
+	switch (count) {
+		case 0: return NULL;
+		case 1: return @selector(performWith:);
+		case 2: return @selector(performWith::);
+		case 3: return @selector(performWith:::);
+		case 4: return @selector(performWith::::);
+		case 5: return @selector(performWith:::::);
+		case 6: return @selector(performWith::::::);
+		case 7: return @selector(performWith:::::::);
+		case 8: return @selector(performWith::::::::);
+		case 9: return @selector(performWith:::::::::);
+		case 10: return @selector(performWith::::::::::);
+		case 11: return @selector(performWith:::::::::::);
+		case 12: return @selector(performWith::::::::::::);
+		case 13: return @selector(performWith:::::::::::::);
+		case 14: return @selector(performWith::::::::::::::);
+		case 15: return @selector(performWith:::::::::::::::);
+	}
+
+	NSCAssert(NO, @"The argument count is too damn high! Only blocks of up to 15 arguments are currently supported.");
+	return NULL;
+}
+
+- (id)performWith:(id)obj1 {
+	id (^block)(id) = self.block;
+	return block(obj1);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 {
+	id (^block)(id, id) = self.block;
+	return block(obj1, obj2);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 {
+	id (^block)(id, id, id) = self.block;
+	return block(obj1, obj2, obj3);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 {
+	id (^block)(id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 {
+	id (^block)(id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 {
+	id (^block)(id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 {
+	id (^block)(id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 {
+	id (^block)(id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 {
+	id (^block)(id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 :(id)obj14 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13, obj14);
+}
+
+- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 :(id)obj14 :(id)obj15 {
+	id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
+	return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13, obj14, obj15);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.h b/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.h
new file mode 100644
index 0000000..ef1d6f1
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.h
@@ -0,0 +1,70 @@
+//
+//  RACChannel.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 01/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+#import "RACSubscriber.h"
+
+@class RACChannelTerminal;
+
+/// A two-way channel.
+///
+/// Conceptually, RACChannel can be thought of as a bidirectional connection,
+/// composed of two controllable signals that work in parallel.
+///
+/// For example, when connecting between a view and a model:
+///
+///        Model                      View
+///  `leadingTerminal` ------> `followingTerminal`
+///  `leadingTerminal` <------ `followingTerminal`
+///
+/// The initial value of the model and all future changes to it are _sent on_ the
+/// `leadingTerminal`, and _received by_ subscribers of the `followingTerminal`.
+///
+/// Likewise, whenever the user changes the value of the view, that value is sent
+/// on the `followingTerminal`, and received in the model from the
+/// `leadingTerminal`. However, the initial value of the view is not received
+/// from the `leadingTerminal` (only future changes).
+@interface RACChannel : NSObject
+
+/// The terminal which "leads" the channel, by sending its latest value
+/// immediately to new subscribers of the `followingTerminal`.
+///
+/// New subscribers to this terminal will not receive a starting value, but will
+/// receive all future values that are sent to the `followingTerminal`.
+@property (nonatomic, strong, readonly) RACChannelTerminal *leadingTerminal;
+
+/// The terminal which "follows" the lead of the other terminal, only sending
+/// _future_ values to the subscribers of the `leadingTerminal`.
+///
+/// The latest value sent to the `leadingTerminal` (if any) will be sent
+/// immediately to new subscribers of this terminal, and then all future values
+/// as well.
+@property (nonatomic, strong, readonly) RACChannelTerminal *followingTerminal;
+
+@end
+
+/// Represents one end of a RACChannel.
+///
+/// An terminal is similar to a socket or pipe -- it represents one end of
+/// a connection (the RACChannel, in this case). Values sent to this terminal
+/// will _not_ be received by its subscribers. Instead, the values will be sent
+/// to the subscribers of the RACChannel's _other_ terminal.
+///
+/// For example, when using the `followingTerminal`, _sent_ values can only be
+/// _received_ from the `leadingTerminal`, and vice versa.
+///
+/// To make it easy to terminate a RACChannel, `error` and `completed` events
+/// sent to either terminal will be received by the subscribers of _both_
+/// terminals.
+///
+/// Do not instantiate this class directly. Create a RACChannel instead.
+@interface RACChannelTerminal : RACSignal <RACSubscriber>
+
+- (id)init __attribute__((unavailable("Instantiate a RACChannel instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.m b/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.m
new file mode 100644
index 0000000..7222858
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACChannel.m
@@ -0,0 +1,91 @@
+//
+//  RACChannel.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 01/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACChannel.h"
+#import "RACDisposable.h"
+#import "RACReplaySubject.h"
+#import "RACSignal+Operations.h"
+#import "RACUnit.h"
+
+@interface RACChannelTerminal ()
+
+// The values for this terminal.
+@property (nonatomic, strong, readonly) RACSignal *values;
+
+// A subscriber will will send values to the other terminal.
+@property (nonatomic, strong, readonly) id<RACSubscriber> otherTerminal;
+
+- (id)initWithValues:(RACSignal *)values otherTerminal:(id<RACSubscriber>)otherTerminal;
+
+@end
+
+@implementation RACChannel
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	// We don't want any starting value from the leadingSubject, but we do want
+	// error and completion to be replayed.
+	RACReplaySubject *leadingSubject = [[RACReplaySubject replaySubjectWithCapacity:0] setNameWithFormat:@"leadingSubject"];
+	RACReplaySubject *followingSubject = [[RACReplaySubject replaySubjectWithCapacity:1] setNameWithFormat:@"followingSubject"];
+
+	// Propagate errors and completion to everything.
+	[[leadingSubject ignoreValues] subscribe:followingSubject];
+	[[followingSubject ignoreValues] subscribe:leadingSubject];
+
+	_leadingTerminal = [[[RACChannelTerminal alloc] initWithValues:leadingSubject otherTerminal:followingSubject] setNameWithFormat:@"leadingTerminal"];
+	_followingTerminal = [[[RACChannelTerminal alloc] initWithValues:followingSubject otherTerminal:leadingSubject] setNameWithFormat:@"followingTerminal"];
+
+	return self;
+}
+
+@end
+
+@implementation RACChannelTerminal
+
+#pragma mark Lifecycle
+
+- (id)initWithValues:(RACSignal *)values otherTerminal:(id<RACSubscriber>)otherTerminal {
+	NSCParameterAssert(values != nil);
+	NSCParameterAssert(otherTerminal != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_values = values;
+	_otherTerminal = otherTerminal;
+
+	return self;
+}
+
+#pragma mark RACSignal
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	return [self.values subscribe:subscriber];
+}
+
+#pragma mark <RACSubscriber>
+
+- (void)sendNext:(id)value {
+	[self.otherTerminal sendNext:value];
+}
+
+- (void)sendError:(NSError *)error {
+	[self.otherTerminal sendError:error];
+}
+
+- (void)sendCompleted {
+	[self.otherTerminal sendCompleted];
+}
+
+- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable {
+	[self.otherTerminal didSubscribeWithDisposable:disposable];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.h b/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.h
new file mode 100644
index 0000000..653d46b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.h
@@ -0,0 +1,123 @@
+//
+//  RACCommand.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/3/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+/// The domain for errors originating within `RACCommand`.
+extern NSString * const RACCommandErrorDomain;
+
+/// -execute: was invoked while the command was disabled.
+extern const NSInteger RACCommandErrorNotEnabled;
+
+/// A `userInfo` key for an error, associated with the `RACCommand` that the
+/// error originated from.
+///
+/// This is included only when the error code is `RACCommandErrorNotEnabled`.
+extern NSString * const RACUnderlyingCommandErrorKey;
+
+/// A command is a signal triggered in response to some action, typically
+/// UI-related.
+@interface RACCommand : NSObject
+
+/// A signal of the signals returned by successful invocations of -execute:
+/// (i.e., while the receiver is `enabled`).
+///
+/// Errors will be automatically caught upon the inner signals, and sent upon
+/// `errors` instead. If you _want_ to receive inner errors, use -execute: or
+/// -[RACSignal materialize].
+/// 
+/// Only executions that begin _after_ subscription will be sent upon this
+/// signal. All inner signals will arrive upon the main thread.
+@property (nonatomic, strong, readonly) RACSignal *executionSignals;
+
+/// A signal of whether this command is currently executing.
+///
+/// This will send YES whenever -execute: is invoked and the created signal has
+/// not yet terminated. Once all executions have terminated, `executing` will
+/// send NO.
+///
+/// This signal will send its current value upon subscription, and then all
+/// future values on the main thread.
+@property (nonatomic, strong, readonly) RACSignal *executing;
+
+/// A signal of whether this command is able to execute.
+///
+/// This will send NO if:
+///
+///  - The command was created with an `enabledSignal`, and NO is sent upon that
+///    signal, or
+///  - `allowsConcurrentExecution` is NO and the command has started executing.
+///
+/// Once the above conditions are no longer met, the signal will send YES.
+///
+/// This signal will send its current value upon subscription, and then all
+/// future values on the main thread.
+@property (nonatomic, strong, readonly) RACSignal *enabled;
+
+/// Forwards any errors that occur within signals returned by -execute:.
+///
+/// When an error occurs on a signal returned from -execute:, this signal will
+/// send the associated NSError value as a `next` event (since an `error` event
+/// would terminate the stream).
+///
+/// After subscription, this signal will send all future errors on the main
+/// thread.
+@property (nonatomic, strong, readonly) RACSignal *errors;
+
+/// Whether the command allows multiple executions to proceed concurrently.
+///
+/// The default value for this property is NO.
+@property (atomic, assign) BOOL allowsConcurrentExecution;
+
+/// Invokes -initWithEnabled:signalBlock: with a nil `enabledSignal`.
+- (id)initWithSignalBlock:(RACSignal * (^)(id input))signalBlock;
+
+/// Initializes a command that is conditionally enabled.
+///
+/// This is the designated initializer for this class.
+///
+/// enabledSignal - A signal of BOOLs which indicate whether the command should
+///                 be enabled. `enabled` will be based on the latest value sent
+///                 from this signal. Before any values are sent, `enabled` will
+///                 default to YES. This argument may be nil.
+/// signalBlock   - A block which will map each input value (passed to -execute:)
+///                 to a signal of work. The returned signal will be multicasted
+///                 to a replay subject, sent on `executionSignals`, then
+///                 subscribed to synchronously. Neither the block nor the
+///                 returned signal may be nil.
+- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock;
+
+/// If the receiver is enabled, this method will:
+///
+///  1. Invoke the `signalBlock` given at the time of initialization.
+///  2. Multicast the returned signal to a RACReplaySubject.
+///  3. Send the multicasted signal on `executionSignals`.
+///  4. Subscribe (connect) to the original signal on the main thread.
+///
+/// input - The input value to pass to the receiver's `signalBlock`. This may be
+///         nil.
+///
+/// Returns the multicasted signal, after subscription. If the receiver is not
+/// enabled, returns a signal that will send an error with code
+/// RACCommandErrorNotEnabled.
+- (RACSignal *)execute:(id)input;
+
+@end
+
+@interface RACCommand (Unavailable)
+
+@property (atomic, readonly) BOOL canExecute __attribute__((unavailable("Use the 'enabled' signal instead")));
+
++ (instancetype)command __attribute__((unavailable("Use -initWithSignalBlock: instead")));
++ (instancetype)commandWithCanExecuteSignal:(RACSignal *)canExecuteSignal __attribute__((unavailable("Use -initWithEnabled:signalBlock: instead")));
+- (id)initWithCanExecuteSignal:(RACSignal *)canExecuteSignal __attribute__((unavailable("Use -initWithEnabled:signalBlock: instead")));
+- (RACSignal *)addSignalBlock:(RACSignal * (^)(id value))signalBlock __attribute__((unavailable("Pass the signalBlock to -initWithSignalBlock: instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.m b/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.m
new file mode 100644
index 0000000..1431fcb
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.m
@@ -0,0 +1,268 @@
+//
+//  RACCommand.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/3/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACCommand.h"
+#import "RACEXTScope.h"
+#import "NSArray+RACSequenceAdditions.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACPropertySubscribing.h"
+#import "RACMulticastConnection.h"
+#import "RACReplaySubject.h"
+#import "RACScheduler.h"
+#import "RACSequence.h"
+#import "RACSerialDisposable.h"
+#import "RACSignal+Operations.h"
+#import <libkern/OSAtomic.h>
+
+NSString * const RACCommandErrorDomain = @"RACCommandErrorDomain";
+NSString * const RACUnderlyingCommandErrorKey = @"RACUnderlyingCommandErrorKey";
+
+const NSInteger RACCommandErrorNotEnabled = 1;
+
+@interface RACCommand () {
+	// The mutable array backing `activeExecutionSignals`.
+	//
+	// This should only be used while synchronized on `self`.
+	NSMutableArray *_activeExecutionSignals;
+
+	// Atomic backing variable for `allowsConcurrentExecution`.
+	volatile uint32_t _allowsConcurrentExecution;
+}
+
+// An array of signals representing in-flight executions, in the order they
+// began.
+//
+// This property is KVO-compliant.
+@property (atomic, copy, readonly) NSArray *activeExecutionSignals;
+
+// `enabled`, but without a hop to the main thread.
+//
+// Values from this signal may arrive on any thread.
+@property (nonatomic, strong, readonly) RACSignal *immediateEnabled;
+
+// The signal block that the receiver was initialized with.
+@property (nonatomic, copy, readonly) RACSignal * (^signalBlock)(id input);
+
+// Adds a signal to `activeExecutionSignals` and generates a KVO notification.
+- (void)addActiveExecutionSignal:(RACSignal *)signal;
+
+// Removes a signal from `activeExecutionSignals` and generates a KVO
+// notification.
+- (void)removeActiveExecutionSignal:(RACSignal *)signal;
+
+@end
+
+@implementation RACCommand
+
+#pragma mark Properties
+
+- (BOOL)allowsConcurrentExecution {
+	return _allowsConcurrentExecution != 0;
+}
+
+- (void)setAllowsConcurrentExecution:(BOOL)allowed {
+	[self willChangeValueForKey:@keypath(self.allowsConcurrentExecution)];
+
+	if (allowed) {
+		OSAtomicOr32Barrier(1, &_allowsConcurrentExecution);
+	} else {
+		OSAtomicAnd32Barrier(0, &_allowsConcurrentExecution);
+	}
+
+	[self didChangeValueForKey:@keypath(self.allowsConcurrentExecution)];
+}
+
+- (NSArray *)activeExecutionSignals {
+	@synchronized (self) {
+		return [_activeExecutionSignals copy];
+	}
+}
+
+- (void)addActiveExecutionSignal:(RACSignal *)signal {
+	NSCParameterAssert([signal isKindOfClass:RACSignal.class]);
+
+	@synchronized (self) {
+		// The KVO notification has to be generated while synchronized, because
+		// it depends on the index remaining consistent.
+		NSIndexSet *indexes = [NSIndexSet indexSetWithIndex:_activeExecutionSignals.count];
+		[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@keypath(self.activeExecutionSignals)];
+		[_activeExecutionSignals addObject:signal];
+		[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@keypath(self.activeExecutionSignals)];
+	}
+}
+
+- (void)removeActiveExecutionSignal:(RACSignal *)signal {
+	NSCParameterAssert([signal isKindOfClass:RACSignal.class]);
+
+	@synchronized (self) {
+		// The indexes have to be calculated and the notification generated
+		// while synchronized, because they depend on the indexes remaining
+		// consistent.
+		NSIndexSet *indexes = [_activeExecutionSignals indexesOfObjectsPassingTest:^ BOOL (RACSignal *obj, NSUInteger index, BOOL *stop) {
+			return obj == signal;
+		}];
+
+		if (indexes.count == 0) return;
+
+		[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:@keypath(self.activeExecutionSignals)];
+		[_activeExecutionSignals removeObjectsAtIndexes:indexes];
+		[self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:@keypath(self.activeExecutionSignals)];
+	}
+}
+
+#pragma mark Lifecycle
+
+- (id)init {
+	NSCAssert(NO, @"Use -initWithSignalBlock: instead");
+	return nil;
+}
+
+- (id)initWithSignalBlock:(RACSignal * (^)(id input))signalBlock {
+	return [self initWithEnabled:nil signalBlock:signalBlock];
+}
+
+- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock {
+	NSCParameterAssert(signalBlock != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_activeExecutionSignals = [[NSMutableArray alloc] init];
+	_signalBlock = [signalBlock copy];
+
+	// A signal of additions to `activeExecutionSignals`.
+	RACSignal *newActiveExecutionSignals = [[[[[self
+		rac_valuesAndChangesForKeyPath:@keypath(self.activeExecutionSignals) options:NSKeyValueObservingOptionNew observer:nil]
+		reduceEach:^(id _, NSDictionary *change) {
+			NSArray *signals = change[NSKeyValueChangeNewKey];
+			if (signals == nil) return [RACSignal empty];
+
+			return [signals.rac_sequence signalWithScheduler:RACScheduler.immediateScheduler];
+		}]
+		concat]
+		publish]
+		autoconnect];
+
+	_executionSignals = [[[newActiveExecutionSignals
+		map:^(RACSignal *signal) {
+			return [signal catchTo:[RACSignal empty]];
+		}]
+		deliverOn:RACScheduler.mainThreadScheduler]
+		setNameWithFormat:@"%@ -executionSignals", self];
+	
+	// `errors` needs to be multicasted so that it picks up all
+	// `activeExecutionSignals` that are added.
+	//
+	// In other words, if someone subscribes to `errors` _after_ an execution
+	// has started, it should still receive any error from that execution.
+	RACMulticastConnection *errorsConnection = [[[newActiveExecutionSignals
+		flattenMap:^(RACSignal *signal) {
+			return [[signal
+				ignoreValues]
+				catch:^(NSError *error) {
+					return [RACSignal return:error];
+				}];
+		}]
+		deliverOn:RACScheduler.mainThreadScheduler]
+		publish];
+	
+	_errors = [errorsConnection.signal setNameWithFormat:@"%@ -errors", self];
+	[errorsConnection connect];
+
+	RACSignal *immediateExecuting = [RACObserve(self, activeExecutionSignals) map:^(NSArray *activeSignals) {
+		return @(activeSignals.count > 0);
+	}];
+
+	_executing = [[[[[immediateExecuting
+		deliverOn:RACScheduler.mainThreadScheduler]
+		// This is useful before the first value arrives on the main thread.
+		startWith:@NO]
+		distinctUntilChanged]
+		replayLast]
+		setNameWithFormat:@"%@ -executing", self];
+
+	RACSignal *moreExecutionsAllowed = [RACSignal
+		if:RACObserve(self, allowsConcurrentExecution)
+		then:[RACSignal return:@YES]
+		else:[immediateExecuting not]];
+	
+	if (enabledSignal == nil) {
+		enabledSignal = [RACSignal return:@YES];
+	} else {
+		enabledSignal = [[[enabledSignal
+			startWith:@YES]
+			takeUntil:self.rac_willDeallocSignal]
+			replayLast];
+	}
+	
+	_immediateEnabled = [[RACSignal
+		combineLatest:@[ enabledSignal, moreExecutionsAllowed ]]
+		and];
+	
+	_enabled = [[[[[self.immediateEnabled
+		take:1]
+		concat:[[self.immediateEnabled skip:1] deliverOn:RACScheduler.mainThreadScheduler]]
+		distinctUntilChanged]
+		replayLast]
+		setNameWithFormat:@"%@ -enabled", self];
+
+	return self;
+}
+
+#pragma mark Execution
+
+- (RACSignal *)execute:(id)input {
+	// `immediateEnabled` is guaranteed to send a value upon subscription, so
+	// -first is acceptable here.
+	BOOL enabled = [[self.immediateEnabled first] boolValue];
+	if (!enabled) {
+		NSError *error = [NSError errorWithDomain:RACCommandErrorDomain code:RACCommandErrorNotEnabled userInfo:@{
+			NSLocalizedDescriptionKey: NSLocalizedString(@"The command is disabled and cannot be executed", nil),
+			RACUnderlyingCommandErrorKey: self
+		}];
+
+		return [RACSignal error:error];
+	}
+
+	RACSignal *signal = self.signalBlock(input);
+	NSCAssert(signal != nil, @"nil signal returned from signal block for value: %@", input);
+
+	// We subscribe to the signal on the main thread so that it occurs _after_
+	// -addActiveExecutionSignal: completes below.
+	//
+	// This means that `executing` and `enabled` will send updated values before
+	// the signal actually starts performing work.
+	RACMulticastConnection *connection = [[signal
+		subscribeOn:RACScheduler.mainThreadScheduler]
+		multicast:[RACReplaySubject subject]];
+	
+	@weakify(self);
+
+	[self addActiveExecutionSignal:connection.signal];
+	[connection.signal subscribeError:^(NSError *error) {
+		@strongify(self);
+		[self removeActiveExecutionSignal:connection.signal];
+	} completed:^{
+		@strongify(self);
+		[self removeActiveExecutionSignal:connection.signal];
+	}];
+
+	[connection connect];
+	return [connection.signal setNameWithFormat:@"%@ -execute: %@", self, [input rac_description]];
+}
+
+#pragma mark NSKeyValueObserving
+
++ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
+	// Generate all KVO notifications manually to avoid the performance impact
+	// of unnecessary swizzling.
+	return NO;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.h b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.h
new file mode 100644
index 0000000..bb25f7d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.h
@@ -0,0 +1,48 @@
+//
+//  RACCompoundDisposable.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDisposable.h"
+
+/// A disposable of disposables. When it is disposed, it disposes of all its
+/// contained disposables.
+///
+/// If -addDisposable: is called after the compound disposable has been disposed
+/// of, the given disposable is immediately disposed. This allows a compound
+/// disposable to act as a stand-in for a disposable that will be delivered
+/// asynchronously.
+@interface RACCompoundDisposable : RACDisposable
+
+/// Creates and returns a new compound disposable.
++ (instancetype)compoundDisposable;
+
+/// Creates and returns a new compound disposable containing the given
+/// disposables.
++ (instancetype)compoundDisposableWithDisposables:(NSArray *)disposables;
+
+/// Adds the given disposable. If the receiving disposable has already been
+/// disposed of, the given disposable is disposed immediately.
+///
+/// This method is thread-safe.
+///
+/// disposable - The disposable to add. This may be nil, in which case nothing
+///              happens.
+- (void)addDisposable:(RACDisposable *)disposable;
+
+/// Removes the specified disposable from the compound disposable (regardless of
+/// its disposed status), or does nothing if it's not in the compound disposable.
+///
+/// This is mainly useful for limiting the memory usage of the compound
+/// disposable for long-running operations.
+///
+/// This method is thread-safe.
+///
+/// disposable - The disposable to remove. This argument may be nil (to make the
+///              use of weak references easier).
+- (void)removeDisposable:(RACDisposable *)disposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.m b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.m
new file mode 100644
index 0000000..3b0471c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposable.m
@@ -0,0 +1,239 @@
+//
+//  RACCompoundDisposable.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACCompoundDisposable.h"
+#import "RACCompoundDisposableProvider.h"
+#import <libkern/OSAtomic.h>
+
+// The number of child disposables for which space will be reserved directly in
+// `RACCompoundDisposable`.
+//
+// This number has been empirically determined to provide a good tradeoff
+// between performance, memory usage, and `RACCompoundDisposable` instance size
+// in a moderately complex GUI application.
+//
+// Profile any change!
+#define RACCompoundDisposableInlineCount 2
+
+static CFMutableArrayRef RACCreateDisposablesArray(void) {
+	// Compare values using only pointer equality.
+	CFArrayCallBacks callbacks = kCFTypeArrayCallBacks;
+	callbacks.equal = NULL;
+
+	return CFArrayCreateMutable(NULL, 0, &callbacks);
+}
+
+@interface RACCompoundDisposable () {
+	// Used for synchronization.
+	OSSpinLock _spinLock;
+
+	#if RACCompoundDisposableInlineCount
+	// A fast array to the first N of the receiver's disposables.
+	//
+	// Once this is full, `_disposables` will be created and used for additional
+	// disposables.
+	//
+	// This array should only be manipulated while _spinLock is held.
+	RACDisposable *_inlineDisposables[RACCompoundDisposableInlineCount];
+	#endif
+
+	// Contains the receiver's disposables.
+	//
+	// This array should only be manipulated while _spinLock is held. If
+	// `_disposed` is YES, this may be NULL.
+	CFMutableArrayRef _disposables;
+
+	// Whether the receiver has already been disposed.
+	//
+	// This ivar should only be accessed while _spinLock is held.
+	BOOL _disposed;
+}
+
+@end
+
+@implementation RACCompoundDisposable
+
+#pragma mark Properties
+
+- (BOOL)isDisposed {
+	OSSpinLockLock(&_spinLock);
+	BOOL disposed = _disposed;
+	OSSpinLockUnlock(&_spinLock);
+
+	return disposed;
+}
+
+#pragma mark Lifecycle
+
++ (instancetype)compoundDisposable {
+	return [[self alloc] initWithDisposables:nil];
+}
+
++ (instancetype)compoundDisposableWithDisposables:(NSArray *)disposables {
+	return [[self alloc] initWithDisposables:disposables];
+}
+
+- (id)initWithDisposables:(NSArray *)otherDisposables {
+	self = [self init];
+	if (self == nil) return nil;
+
+	#if RACCompoundDisposableInlineCount
+	[otherDisposables enumerateObjectsUsingBlock:^(RACDisposable *disposable, NSUInteger index, BOOL *stop) {
+		_inlineDisposables[index] = disposable;
+
+		// Stop after this iteration if we've reached the end of the inlined
+		// array.
+		if (index == RACCompoundDisposableInlineCount - 1) *stop = YES;
+	}];
+	#endif
+
+	if (otherDisposables.count > RACCompoundDisposableInlineCount) {
+		_disposables = RACCreateDisposablesArray();
+
+		CFRange range = CFRangeMake(RACCompoundDisposableInlineCount, (CFIndex)otherDisposables.count - RACCompoundDisposableInlineCount);
+		CFArrayAppendArray(_disposables, (__bridge CFArrayRef)otherDisposables, range);
+	}
+
+	return self;
+}
+
+- (id)initWithBlock:(void (^)(void))block {
+	RACDisposable *disposable = [RACDisposable disposableWithBlock:block];
+	return [self initWithDisposables:@[ disposable ]];
+}
+
+- (void)dealloc {
+	#if RACCompoundDisposableInlineCount
+	for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
+		_inlineDisposables[i] = nil;
+	}
+	#endif
+
+	if (_disposables != NULL) {
+		CFRelease(_disposables);
+		_disposables = NULL;
+	}
+}
+
+#pragma mark Addition and Removal
+
+- (void)addDisposable:(RACDisposable *)disposable {
+	NSCParameterAssert(disposable != self);
+	if (disposable == nil) return;
+
+	BOOL shouldDispose = NO;
+
+	OSSpinLockLock(&_spinLock);
+	{
+		if (_disposed) {
+			shouldDispose = YES;
+		} else {
+			#if RACCompoundDisposableInlineCount
+			for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
+				if (_inlineDisposables[i] == nil) {
+					_inlineDisposables[i] = disposable;
+					goto foundSlot;
+				}
+			}
+			#endif
+
+			if (_disposables == NULL) _disposables = RACCreateDisposablesArray();
+			CFArrayAppendValue(_disposables, (__bridge void *)disposable);
+
+			if (RACCOMPOUNDDISPOSABLE_ADDED_ENABLED()) {
+				RACCOMPOUNDDISPOSABLE_ADDED(self.description.UTF8String, disposable.description.UTF8String, CFArrayGetCount(_disposables) + RACCompoundDisposableInlineCount);
+			}
+
+		#if RACCompoundDisposableInlineCount
+		foundSlot:;
+		#endif
+		}
+	}
+	OSSpinLockUnlock(&_spinLock);
+
+	// Performed outside of the lock in case the compound disposable is used
+	// recursively.
+	if (shouldDispose) [disposable dispose];
+}
+
+- (void)removeDisposable:(RACDisposable *)disposable {
+	if (disposable == nil) return;
+
+	OSSpinLockLock(&_spinLock);
+	{
+		if (!_disposed) {
+			#if RACCompoundDisposableInlineCount
+			for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
+				if (_inlineDisposables[i] == disposable) _inlineDisposables[i] = nil;
+			}
+			#endif
+
+			if (_disposables != NULL) {
+				CFIndex count = CFArrayGetCount(_disposables);
+				for (CFIndex i = count - 1; i >= 0; i--) {
+					const void *item = CFArrayGetValueAtIndex(_disposables, i);
+					if (item == (__bridge void *)disposable) {
+						CFArrayRemoveValueAtIndex(_disposables, i);
+					}
+				}
+
+				if (RACCOMPOUNDDISPOSABLE_REMOVED_ENABLED()) {
+					RACCOMPOUNDDISPOSABLE_REMOVED(self.description.UTF8String, disposable.description.UTF8String, CFArrayGetCount(_disposables) + RACCompoundDisposableInlineCount);
+				}
+			}
+		}
+	}
+	OSSpinLockUnlock(&_spinLock);
+}
+
+#pragma mark RACDisposable
+
+static void disposeEach(const void *value, void *context) {
+	RACDisposable *disposable = (__bridge id)value;
+	[disposable dispose];
+}
+
+- (void)dispose {
+	#if RACCompoundDisposableInlineCount
+	RACDisposable *inlineCopy[RACCompoundDisposableInlineCount];
+	#endif
+
+	CFArrayRef remainingDisposables = NULL;
+
+	OSSpinLockLock(&_spinLock);
+	{
+		_disposed = YES;
+
+		#if RACCompoundDisposableInlineCount
+		for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
+			inlineCopy[i] = _inlineDisposables[i];
+			_inlineDisposables[i] = nil;
+		}
+		#endif
+
+		remainingDisposables = _disposables;
+		_disposables = NULL;
+	}
+	OSSpinLockUnlock(&_spinLock);
+
+	#if RACCompoundDisposableInlineCount
+	// Dispose outside of the lock in case the compound disposable is used
+	// recursively.
+	for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
+		[inlineCopy[i] dispose];
+	}
+	#endif
+
+	if (remainingDisposables == NULL) return;
+
+	CFIndex count = CFArrayGetCount(remainingDisposables);
+	CFArrayApplyFunction(remainingDisposables, CFRangeMake(0, count), &disposeEach, NULL);
+	CFRelease(remainingDisposables);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposableProvider.d b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposableProvider.d
new file mode 100644
index 0000000..847db19
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACCompoundDisposableProvider.d
@@ -0,0 +1,4 @@
+provider RACCompoundDisposable {
+    probe added(char *compoundDisposable, char *disposable, long newTotal);
+    probe removed(char *compoundDisposable, char *disposable, long newTotal);
+};
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.h b/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.h
new file mode 100644
index 0000000..9ec96bd
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.h
@@ -0,0 +1,28 @@
+//
+//  RACDelegateProxy.h
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/19/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACSignal;
+
+// A private delegate object suitable for using
+// -rac_signalForSelector:fromProtocol: upon.
+@interface RACDelegateProxy : NSObject
+
+// The delegate to which messages should be forwarded if not handled by
+// any -signalForSelector: applications.
+@property (nonatomic, unsafe_unretained) id rac_proxiedDelegate;
+
+// Creates a delegate proxy capable of responding to selectors from `protocol`.
+- (instancetype)initWithProtocol:(Protocol *)protocol;
+
+// Calls -rac_signalForSelector:fromProtocol: using the `protocol` specified
+// during initialization.
+- (RACSignal *)signalForSelector:(SEL)selector;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.m b/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.m
new file mode 100644
index 0000000..1d4fcbc
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDelegateProxy.m
@@ -0,0 +1,78 @@
+//
+//  RACDelegateProxy.m
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/19/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDelegateProxy.h"
+#import "RACSignal+Operations.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "NSObject+RACDeallocating.h"
+#import <objc/runtime.h>
+
+@interface RACDelegateProxy () {
+	// Declared as an ivar to avoid method naming conflicts.
+	Protocol *_protocol;
+}
+
+@end
+
+@implementation RACDelegateProxy
+
+#pragma mark Lifecycle
+
+- (instancetype)initWithProtocol:(Protocol *)protocol {
+	NSCParameterAssert(protocol != NULL);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	class_addProtocol(self.class, protocol);
+
+	_protocol = protocol;
+
+	return self;
+}
+
+#pragma mark API
+
+- (RACSignal *)signalForSelector:(SEL)selector {
+	return [self rac_signalForSelector:selector fromProtocol:_protocol];
+}
+
+#pragma mark NSObject
+
+- (BOOL)isProxy {
+	return YES;
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation {
+	[invocation invokeWithTarget:self.rac_proxiedDelegate];
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
+	// Look for the selector as an optional instance method.
+	struct objc_method_description methodDescription = protocol_getMethodDescription(_protocol, selector, NO, YES);
+
+	if (methodDescription.name == NULL) {
+		// Then fall back to looking for a required instance
+		// method.
+		methodDescription = protocol_getMethodDescription(_protocol, selector, YES, YES);
+		if (methodDescription.name == NULL) return [super methodSignatureForSelector:selector];
+	}
+
+	return [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
+}
+
+- (BOOL)respondsToSelector:(SEL)selector {
+	// Add the delegate to the autorelease pool, so it doesn't get deallocated
+	// between this method call and -forwardInvocation:.
+	__autoreleasing id delegate = self.rac_proxiedDelegate;
+	if ([delegate respondsToSelector:selector]) return YES;
+    
+	return [super respondsToSelector:selector];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.h b/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.h
new file mode 100644
index 0000000..1267d44
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.h
@@ -0,0 +1,36 @@
+//
+//  RACDisposable.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACScopedDisposable;
+
+
+/// A disposable encapsulates the work necessary to tear down and cleanup a
+/// subscription.
+@interface RACDisposable : NSObject
+
+/// Whether the receiver has been disposed.
+///
+/// Use of this property is discouraged, since it may be set to `YES`
+/// concurrently at any time.
+///
+/// This property is not KVO-compliant.
+@property (atomic, assign, getter = isDisposed, readonly) BOOL disposed;
+
++ (instancetype)disposableWithBlock:(void (^)(void))block;
+
+/// Performs the disposal work. Can be called multiple times, though subsequent
+/// calls won't do anything.
+- (void)dispose;
+
+/// Returns a new disposable which will dispose of this disposable when it gets
+/// dealloc'd.
+- (RACScopedDisposable *)asScopedDisposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.m b/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.m
new file mode 100644
index 0000000..08eceb2
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDisposable.m
@@ -0,0 +1,92 @@
+//
+//  RACDisposable.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDisposable.h"
+#import "RACScopedDisposable.h"
+#import <libkern/OSAtomic.h>
+
+@interface RACDisposable () {
+	// A copied block of type void (^)(void) containing the logic for disposal,
+	// a pointer to `self` if no logic should be performed upon disposal, or
+	// NULL if the receiver is already disposed.
+	//
+	// This should only be used atomically.
+	void * volatile _disposeBlock;
+}
+
+@end
+
+@implementation RACDisposable
+
+#pragma mark Properties
+
+- (BOOL)isDisposed {
+	return _disposeBlock == NULL;
+}
+
+#pragma mark Lifecycle
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	_disposeBlock = (__bridge void *)self;
+	OSMemoryBarrier();
+
+	return self;
+}
+
+- (id)initWithBlock:(void (^)(void))block {
+	NSCParameterAssert(block != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_disposeBlock = (void *)CFBridgingRetain([block copy]); 
+	OSMemoryBarrier();
+
+	return self;
+}
+
++ (instancetype)disposableWithBlock:(void (^)(void))block {
+	return [[self alloc] initWithBlock:block];
+}
+
+- (void)dealloc {
+	if (_disposeBlock == NULL || _disposeBlock == (__bridge void *)self) return;
+
+	CFRelease(_disposeBlock);
+	_disposeBlock = NULL;
+}
+
+#pragma mark Disposal
+
+- (void)dispose {
+	void (^disposeBlock)(void) = NULL;
+
+	while (YES) {
+		void *blockPtr = _disposeBlock;
+		if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
+			if (blockPtr != (__bridge void *)self) {
+				disposeBlock = CFBridgingRelease(blockPtr);
+			}
+
+			break;
+		}
+	}
+
+	if (disposeBlock != nil) disposeBlock();
+}
+
+#pragma mark Scoped Disposables
+
+- (RACScopedDisposable *)asScopedDisposable {
+	return [RACScopedDisposable scopedDisposableWithDisposable:self];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.h
new file mode 100644
index 0000000..1e103e3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.h
@@ -0,0 +1,20 @@
+//
+//  RACDynamicSequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class that implements a sequence dynamically using blocks.
+@interface RACDynamicSequence : RACSequence
+
+// Returns a sequence which evaluates `dependencyBlock` only once, the first
+// time either `headBlock` or `tailBlock` is evaluated. The result of
+// `dependencyBlock` will be passed into `headBlock` and `tailBlock` when
+// invoked.
++ (RACSequence *)sequenceWithLazyDependency:(id (^)(void))dependencyBlock headBlock:(id (^)(id dependency))headBlock tailBlock:(RACSequence *(^)(id dependency))tailBlock;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.m
new file mode 100644
index 0000000..48a977b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSequence.m
@@ -0,0 +1,197 @@
+//
+//  RACDynamicSequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACDynamicSequence.h"
+#import <libkern/OSAtomic.h>
+
+// Determines how RACDynamicSequences will be deallocated before the next one is
+// shifted onto the autorelease pool.
+//
+// This avoids stack overflows when deallocating long chains of dynamic
+// sequences.
+#define DEALLOC_OVERFLOW_GUARD 100
+
+@interface RACDynamicSequence () {
+	// The value for the "head" property, if it's been evaluated already.
+	//
+	// Because it's legal for head to be nil, this ivar is valid any time
+	// headBlock is nil.
+	//
+	// This ivar should only be accessed while synchronized on self.
+	id _head;
+
+	// The value for the "tail" property, if it's been evaluated already.
+	//
+	// Because it's legal for tail to be nil, this ivar is valid any time
+	// tailBlock is nil.
+	//
+	// This ivar should only be accessed while synchronized on self.
+	RACSequence *_tail;
+
+	// The result of an evaluated `dependencyBlock`.
+	//
+	// This ivar is valid any time `hasDependency` is YES and `dependencyBlock`
+	// is nil.
+	//
+	// This ivar should only be accessed while synchronized on self.
+	id _dependency;
+}
+
+// A block used to evaluate head. This should be set to nil after `_head` has been
+// initialized.
+//
+// This is marked `strong` instead of `copy` because of some bizarre block
+// copying bug. See https://github.com/ReactiveCocoa/ReactiveCocoa/pull/506.
+//
+// The signature of this block varies based on the value of `hasDependency`:
+//
+//  - If YES, this block is of type `id (^)(id)`.
+//  - If NO, this block is of type `id (^)(void)`.
+//
+// This property should only be accessed while synchronized on self.
+@property (nonatomic, strong) id headBlock;
+
+// A block used to evaluate tail. This should be set to nil after `_tail` has been
+// initialized.
+//
+// This is marked `strong` instead of `copy` because of some bizarre block
+// copying bug. See https://github.com/ReactiveCocoa/ReactiveCocoa/pull/506.
+//
+// The signature of this block varies based on the value of `hasDependency`:
+//
+//  - If YES, this block is of type `RACSequence * (^)(id)`.
+//  - If NO, this block is of type `RACSequence * (^)(void)`.
+//
+// This property should only be accessed while synchronized on self.
+@property (nonatomic, strong) id tailBlock;
+
+// Whether the receiver was initialized with a `dependencyBlock`.
+//
+// This property should only be accessed while synchronized on self.
+@property (nonatomic, assign) BOOL hasDependency;
+
+// A dependency which must be evaluated before `headBlock` and `tailBlock`. This
+// should be set to nil after `_dependency` and `dependencyBlockExecuted` have
+// been set.
+//
+// This is marked `strong` instead of `copy` because of some bizarre block
+// copying bug. See https://github.com/ReactiveCocoa/ReactiveCocoa/pull/506.
+//
+// This property should only be accessed while synchronized on self.
+@property (nonatomic, strong) id (^dependencyBlock)(void);
+
+@end
+
+@implementation RACDynamicSequence
+
+#pragma mark Lifecycle
+
++ (RACSequence *)sequenceWithHeadBlock:(id (^)(void))headBlock tailBlock:(RACSequence *(^)(void))tailBlock {
+	NSCParameterAssert(headBlock != nil);
+
+	RACDynamicSequence *seq = [[RACDynamicSequence alloc] init];
+	seq.headBlock = [headBlock copy];
+	seq.tailBlock = [tailBlock copy];
+	seq.hasDependency = NO;
+	return seq;
+}
+
++ (RACSequence *)sequenceWithLazyDependency:(id (^)(void))dependencyBlock headBlock:(id (^)(id dependency))headBlock tailBlock:(RACSequence *(^)(id dependency))tailBlock {
+	NSCParameterAssert(dependencyBlock != nil);
+	NSCParameterAssert(headBlock != nil);
+
+	RACDynamicSequence *seq = [[RACDynamicSequence alloc] init];
+	seq.headBlock = [headBlock copy];
+	seq.tailBlock = [tailBlock copy];
+	seq.dependencyBlock = [dependencyBlock copy];
+	seq.hasDependency = YES;
+	return seq;
+}
+
+- (void)dealloc {
+	static volatile int32_t directDeallocCount = 0;
+
+	if (OSAtomicIncrement32(&directDeallocCount) >= DEALLOC_OVERFLOW_GUARD) {
+		OSAtomicAdd32(-DEALLOC_OVERFLOW_GUARD, &directDeallocCount);
+
+		// Put this sequence's tail onto the autorelease pool so we stop
+		// recursing.
+		__autoreleasing RACSequence *tail __attribute__((unused)) = _tail;
+	}
+	
+	_tail = nil;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	@synchronized (self) {
+		id untypedHeadBlock = self.headBlock;
+		if (untypedHeadBlock == nil) return _head;
+
+		if (self.hasDependency) {
+			if (self.dependencyBlock != nil) {
+				_dependency = self.dependencyBlock();
+				self.dependencyBlock = nil;
+			}
+
+			id (^headBlock)(id) = untypedHeadBlock;
+			_head = headBlock(_dependency);
+		} else {
+			id (^headBlock)(void) = untypedHeadBlock;
+			_head = headBlock();
+		}
+
+		self.headBlock = nil;
+		return _head;
+	}
+}
+
+- (RACSequence *)tail {
+	@synchronized (self) {
+		id untypedTailBlock = self.tailBlock;
+		if (untypedTailBlock == nil) return _tail;
+
+		if (self.hasDependency) {
+			if (self.dependencyBlock != nil) {
+				_dependency = self.dependencyBlock();
+				self.dependencyBlock = nil;
+			}
+
+			RACSequence * (^tailBlock)(id) = untypedTailBlock;
+			_tail = tailBlock(_dependency);
+		} else {
+			RACSequence * (^tailBlock)(void) = untypedTailBlock;
+			_tail = tailBlock();
+		}
+
+		if (_tail.name == nil) _tail.name = self.name;
+
+		self.tailBlock = nil;
+		return _tail;
+	}
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	id head = @"(unresolved)";
+	id tail = @"(unresolved)";
+
+	@synchronized (self) {
+		if (self.headBlock == nil) head = _head;
+		if (self.tailBlock == nil) {
+			tail = _tail;
+			if (tail == self) tail = @"(self)";
+		}
+	}
+
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, head = %@, tail = %@ }", self.class, self, self.name, head, tail];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.h
new file mode 100644
index 0000000..81ac6db
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.h
@@ -0,0 +1,17 @@
+//
+//  RACDynamicSignal.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+
+// A private `RACSignal` subclasses that implements its subscription behavior
+// using a block.
+@interface RACDynamicSignal : RACSignal
+
++ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.m
new file mode 100644
index 0000000..7af1e12
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACDynamicSignal.m
@@ -0,0 +1,189 @@
+//
+//  RACDynamicSignal.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDynamicSignal.h"
+#import "RACEXTScope.h"
+#import "RACPassthroughSubscriber.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriber.h"
+#import "RACCompoundDisposable.h"
+#import <libkern/OSAtomic.h>
+
+// Retains dynamic signals while they wait for subscriptions.
+//
+// This set must only be used on the main thread.
+static CFMutableSetRef RACActiveSignals = nil;
+
+// A linked list of RACDynamicSignals, used in RACActiveSignalsToCheck.
+typedef struct RACSignalList {
+	CFTypeRef retainedSignal;
+	struct RACSignalList * restrict next;
+} RACSignalList;
+
+// An atomic queue of signals to check for subscribers. If any signals with zero
+// subscribers are found in this queue, they are removed from RACActiveSignals.
+static OSQueueHead RACActiveSignalsToCheck = OS_ATOMIC_QUEUE_INIT;
+
+// Whether RACActiveSignalsToCheck will be enumerated on the next iteration on
+// the main run loop.
+static volatile uint32_t RACWillCheckActiveSignals = 0;
+
+@interface RACDynamicSignal () {
+	// Contains all subscribers to the receiver.
+	//
+	// All access to this array must be synchronized using `_subscribersLock`.
+	NSMutableArray *_subscribers;
+
+	// Synchronizes access to `_subscribers`.
+	OSSpinLock _subscribersLock;
+}
+
+// The block to invoke for each subscriber.
+@property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
+
+@end
+
+@implementation RACDynamicSignal
+
+#pragma mark Lifecycle
+
++ (void)initialize {
+	if (self != RACDynamicSignal.class) return;
+
+	CFSetCallBacks callbacks = kCFTypeSetCallBacks;
+
+	// Use pointer equality and hashes for membership testing.
+	callbacks.equal = NULL;
+	callbacks.hash = NULL;
+
+	RACActiveSignals = CFSetCreateMutable(NULL, 0, &callbacks);
+}
+
++ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
+	RACDynamicSignal *signal = [[self alloc] init];
+	signal->_didSubscribe = [didSubscribe copy];
+	return [signal setNameWithFormat:@"+createSignal:"];
+}
+
+- (instancetype)init {
+	self = [super init];
+	if (self == nil) return nil;
+	
+	// As soon as we're created we're already trying to be released. Such is life.
+	[self invalidateGlobalRefIfNoNewSubscribersShowUp];
+	
+	return self;
+}
+
+static void RACCheckActiveSignals(void) {
+	// Clear this flag now, so another thread can re-dispatch to the main queue
+	// as needed.
+	OSAtomicAnd32Barrier(0, &RACWillCheckActiveSignals);
+
+	RACSignalList * restrict elem;
+
+	while ((elem = OSAtomicDequeue(&RACActiveSignalsToCheck, offsetof(RACSignalList, next))) != NULL) {
+		RACDynamicSignal *signal = CFBridgingRelease(elem->retainedSignal);
+		free(elem);
+
+		if (signal.hasSubscribers) {
+			// We want to keep the signal around until all its subscribers are done
+			CFSetAddValue(RACActiveSignals, (__bridge void *)signal);
+		} else {
+			CFSetRemoveValue(RACActiveSignals, (__bridge void *)signal);
+		}
+	}
+}
+
+- (void)invalidateGlobalRefIfNoNewSubscribersShowUp {
+	// If no one subscribes in one pass of the main run loop, then we're free to
+	// go. It's up to the caller to keep us alive if they still want us.
+	RACSignalList *elem = malloc(sizeof(*elem));
+
+	// This also serves to retain the signal until the next pass.
+	elem->retainedSignal = CFBridgingRetain(self);
+	OSAtomicEnqueue(&RACActiveSignalsToCheck, elem, offsetof(RACSignalList, next));
+
+	// Not using a barrier because duplicate scheduling isn't erroneous, just
+	// less optimized.
+	int32_t willCheck = OSAtomicOr32Orig(1, &RACWillCheckActiveSignals);
+
+	// Only schedule a check if RACWillCheckActiveSignals was 0 before.
+	if (willCheck == 0) {
+		dispatch_async(dispatch_get_main_queue(), ^{
+			RACCheckActiveSignals();
+		});
+	}
+}
+
+#pragma mark Managing Subscribers
+
+- (BOOL)hasSubscribers {
+	OSSpinLockLock(&_subscribersLock);
+	BOOL hasSubscribers = _subscribers.count > 0;
+	OSSpinLockUnlock(&_subscribersLock);
+
+	return hasSubscribers;
+}
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCParameterAssert(subscriber != nil);
+
+	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+	subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
+
+	OSSpinLockLock(&_subscribersLock);
+	if (_subscribers == nil) {
+		_subscribers = [NSMutableArray arrayWithObject:subscriber];
+	} else {
+		[_subscribers addObject:subscriber];
+	}
+	OSSpinLockUnlock(&_subscribersLock);
+	
+	@weakify(self);
+	RACDisposable *defaultDisposable = [RACDisposable disposableWithBlock:^{
+		@strongify(self);
+		if (self == nil) return;
+
+		BOOL stillHasSubscribers = YES;
+
+		OSSpinLockLock(&_subscribersLock);
+		{
+			// Since newer subscribers are generally shorter-lived, search
+			// starting from the end of the list.
+			NSUInteger index = [_subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
+				return obj == subscriber;
+			}];
+
+			if (index != NSNotFound) {
+				[_subscribers removeObjectAtIndex:index];
+				stillHasSubscribers = _subscribers.count > 0;
+			}
+		}
+		OSSpinLockUnlock(&_subscribersLock);
+		
+		if (!stillHasSubscribers) {
+			[self invalidateGlobalRefIfNoNewSubscribersShowUp];
+		}
+	}];
+
+	[disposable addDisposable:defaultDisposable];
+
+	if (self.didSubscribe != NULL) {
+		RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
+			RACDisposable *innerDisposable = self.didSubscribe(subscriber);
+			[disposable addDisposable:innerDisposable];
+		}];
+
+		[disposable addDisposable:schedulingDisposable];
+	}
+	
+	return disposable;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.h
new file mode 100644
index 0000000..ab5aa9f
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.h
@@ -0,0 +1,14 @@
+//
+//  RACEagerSequence.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 02/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACArraySequence.h"
+
+// Private class that implements an eager sequence.
+@interface RACEagerSequence : RACArraySequence
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.m
new file mode 100644
index 0000000..f12fbe9
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEagerSequence.m
@@ -0,0 +1,66 @@
+//
+//  RACEagerSequence.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 02/01/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACEagerSequence.h"
+#import "NSObject+RACDescription.h"
+#import "RACArraySequence.h"
+
+@implementation RACEagerSequence
+
+#pragma mark RACStream
+
++ (instancetype)return:(id)value {
+	return [[self sequenceWithArray:@[ value ] offset:0] setNameWithFormat:@"+return: %@", [value rac_description]];
+}
+
+- (instancetype)bind:(RACStreamBindBlock (^)(void))block {
+	NSCParameterAssert(block != nil);
+	RACStreamBindBlock bindBlock = block();
+	NSArray *currentArray = self.array;
+	NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:currentArray.count];
+	
+	for (id value in currentArray) {
+		BOOL stop = NO;
+		RACSequence *boundValue = (id)bindBlock(value, &stop);
+		if (boundValue == nil) break;
+
+		for (id x in boundValue) {
+			[resultArray addObject:x];
+		}
+
+		if (stop) break;
+	}
+	
+	return [[self.class sequenceWithArray:resultArray offset:0] setNameWithFormat:@"[%@] -bind:", self.name];
+}
+
+- (instancetype)concat:(RACSequence *)sequence {
+	NSCParameterAssert(sequence != nil);
+	NSCParameterAssert([sequence isKindOfClass:RACSequence.class]);
+
+	NSArray *array = [self.array arrayByAddingObjectsFromArray:sequence.array];
+	return [[self.class sequenceWithArray:array offset:0] setNameWithFormat:@"[%@] -concat: %@", self.name, sequence];
+}
+
+#pragma mark Extended methods
+
+- (RACSequence *)eagerSequence {
+	return self;
+}
+
+- (RACSequence *)lazySequence {
+	return [RACArraySequence sequenceWithArray:self.array offset:0];
+}
+
+- (id)foldRightWithStart:(id)start reduce:(id (^)(id, RACSequence *rest))reduce {
+	return [super foldRightWithStart:start reduce:^(id first, RACSequence *rest) {
+		return reduce(first, rest.eagerSequence);
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.h
new file mode 100644
index 0000000..140c78b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.h
@@ -0,0 +1,14 @@
+//
+//  RACEmptySequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class representing an empty sequence.
+@interface RACEmptySequence : RACSequence
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.m
new file mode 100644
index 0000000..e4df150
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySequence.m
@@ -0,0 +1,71 @@
+//
+//  RACEmptySequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACEmptySequence.h"
+
+@implementation RACEmptySequence
+
+#pragma mark Lifecycle
+
++ (instancetype)empty {
+	static id singleton;
+	static dispatch_once_t pred;
+
+	dispatch_once(&pred, ^{
+		singleton = [[self alloc] init];
+	});
+
+	return singleton;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	return nil;
+}
+
+- (RACSequence *)tail {
+	return nil;
+}
+
+- (RACSequence *)bind:(RACStreamBindBlock)bindBlock passingThroughValuesFromSequence:(RACSequence *)passthroughSequence {
+	return passthroughSequence ?: self;
+}
+
+#pragma mark NSCoding
+
+- (Class)classForCoder {
+	// Empty sequences should be encoded as themselves, not array sequences.
+	return self.class;
+}
+
+- (id)initWithCoder:(NSCoder *)coder {
+	// Return the singleton.
+	return self.class.empty;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@ }", self.class, self, self.name];
+}
+
+- (NSUInteger)hash {
+	// This hash isn't ideal, but it's better than -[RACSequence hash], which
+	// would just be zero because we have no head.
+	return (NSUInteger)(__bridge void *)self;
+}
+
+- (BOOL)isEqual:(RACSequence *)seq {
+	return (self == seq);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.h
new file mode 100644
index 0000000..90b4f00
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.h
@@ -0,0 +1,17 @@
+//
+//  RACEmptySignal.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+
+// A private `RACSignal` subclasses that synchronously sends completed to any
+// subscribers.
+@interface RACEmptySignal : RACSignal
+
++ (RACSignal *)empty;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.m
new file mode 100644
index 0000000..8bc8f41
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEmptySignal.m
@@ -0,0 +1,62 @@
+//
+//  RACEmptySignal.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACEmptySignal.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriber.h"
+
+@implementation RACEmptySignal
+
+#pragma mark Properties
+
+// Only allow this signal's name to be customized in DEBUG, since it's
+// a singleton in release builds (see +empty).
+- (void)setName:(NSString *)name {
+#ifdef DEBUG
+	[super setName:name];
+#endif
+}
+
+- (NSString *)name {
+#ifdef DEBUG
+	return super.name;
+#else
+	return @"+empty";
+#endif
+}
+
+#pragma mark Lifecycle
+
++ (RACSignal *)empty {
+#ifdef DEBUG
+	// Create multiple instances of this class in DEBUG so users can set custom
+	// names on each.
+	return [[[self alloc] init] setNameWithFormat:@"+empty"];
+#else
+	static id singleton;
+	static dispatch_once_t pred;
+
+	dispatch_once(&pred, ^{
+		singleton = [[self alloc] init];
+	});
+
+	return singleton;
+#endif
+}
+
+#pragma mark Subscription
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCParameterAssert(subscriber != nil);
+
+	return [RACScheduler.subscriptionScheduler schedule:^{
+		[subscriber sendCompleted];
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.h
new file mode 100644
index 0000000..c942f9e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.h
@@ -0,0 +1,17 @@
+//
+//  RACErrorSignal.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+
+// A private `RACSignal` subclasses that synchronously sends an error to any
+// subscribers.
+@interface RACErrorSignal : RACSignal
+
++ (RACSignal *)error:(NSError *)error;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.m
new file mode 100644
index 0000000..fd6778c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACErrorSignal.m
@@ -0,0 +1,47 @@
+//
+//  RACErrorSignal.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACErrorSignal.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriber.h"
+
+@interface RACErrorSignal ()
+
+// The error to send upon subscription.
+@property (nonatomic, strong, readonly) NSError *error;
+
+@end
+
+@implementation RACErrorSignal
+
+#pragma mark Lifecycle
+
++ (RACSignal *)error:(NSError *)error {
+	RACErrorSignal *signal = [[self alloc] init];
+	signal->_error = error;
+
+#ifdef DEBUG
+	[signal setNameWithFormat:@"+error: %@", error];
+#else
+	signal.name = @"+error:";
+#endif
+
+	return signal;
+}
+
+#pragma mark Subscription
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCParameterAssert(subscriber != nil);
+
+	return [RACScheduler.subscriptionScheduler schedule:^{
+		[subscriber sendError:self.error];
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.h b/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.h
new file mode 100644
index 0000000..9e64e5a
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.h
@@ -0,0 +1,51 @@
+//
+//  RACEvent.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-01-07.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/// Describes the type of a RACEvent.
+///
+/// RACEventTypeCompleted - A `completed` event.
+/// RACEventTypeError     - An `error` event.
+/// RACEventTypeNext      - A `next` event.
+typedef enum : NSUInteger {
+    RACEventTypeCompleted,
+    RACEventTypeError,
+    RACEventTypeNext
+} RACEventType;
+
+/// Represents an event sent by a RACSignal.
+///
+/// This corresponds to the `Notification` class in Rx.
+@interface RACEvent : NSObject <NSCopying>
+
+/// Returns a singleton RACEvent representing the `completed` event.
++ (instancetype)completedEvent;
+
+/// Returns a new event of type RACEventTypeError, containing the given error.
++ (instancetype)eventWithError:(NSError *)error;
+
+/// Returns a new event of type RACEventTypeNext, containing the given value.
++ (instancetype)eventWithValue:(id)value;
+
+/// The type of event represented by the receiver.
+@property (nonatomic, assign, readonly) RACEventType eventType;
+
+/// Returns whether the receiver is of type RACEventTypeCompleted or
+/// RACEventTypeError.
+@property (nonatomic, getter = isFinished, assign, readonly) BOOL finished;
+
+/// The error associated with an event of type RACEventTypeError. This will be
+/// nil for all other event types.
+@property (nonatomic, strong, readonly) NSError *error;
+
+/// The value associated with an event of type RACEventTypeNext. This will be
+/// nil for all other event types.
+@property (nonatomic, strong, readonly) id value;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.m b/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.m
new file mode 100644
index 0000000..270a95d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACEvent.m
@@ -0,0 +1,113 @@
+//
+//  RACEvent.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-01-07.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACEvent.h"
+
+@interface RACEvent ()
+
+// An object associated with this event. This will be used for the error and
+// value properties.
+@property (nonatomic, strong, readonly) id object;
+
+// Initializes the receiver with the given type and object.
+- (id)initWithEventType:(RACEventType)type object:(id)object;
+
+@end
+
+@implementation RACEvent
+
+#pragma mark Properties
+
+- (BOOL)isFinished {
+	return self.eventType == RACEventTypeCompleted || self.eventType == RACEventTypeError;
+}
+
+- (NSError *)error {
+	return (self.eventType == RACEventTypeError ? self.object : nil);
+}
+
+- (id)value {
+	return (self.eventType == RACEventTypeNext ? self.object : nil);
+}
+
+#pragma mark Lifecycle
+
++ (instancetype)completedEvent {
+	static dispatch_once_t pred;
+	static id singleton;
+
+	dispatch_once(&pred, ^{
+		singleton = [[self alloc] initWithEventType:RACEventTypeCompleted object:nil];
+	});
+
+	return singleton;
+}
+
++ (instancetype)eventWithError:(NSError *)error {
+	return [[self alloc] initWithEventType:RACEventTypeError object:error];
+}
+
++ (instancetype)eventWithValue:(id)value {
+	return [[self alloc] initWithEventType:RACEventTypeNext object:value];
+}
+
+- (id)initWithEventType:(RACEventType)type object:(id)object {
+	self = [super init];
+	if (self == nil) return nil;
+
+	_eventType = type;
+	_object = object;
+
+	return self;
+}
+
+#pragma mark NSCopying
+
+- (id)copyWithZone:(NSZone *)zone {
+	return self;
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	NSString *eventDescription = nil;
+
+	switch (self.eventType) {
+		case RACEventTypeCompleted:
+			eventDescription = @"completed";
+			break;
+
+		case RACEventTypeError:
+			eventDescription = [NSString stringWithFormat:@"error = %@", self.object];
+			break;
+
+		case RACEventTypeNext:
+			eventDescription = [NSString stringWithFormat:@"next = %@", self.object];
+			break;
+
+		default:
+			NSCAssert(NO, @"Unrecognized event type: %i", (int)self.eventType);
+	}
+
+	return [NSString stringWithFormat:@"<%@: %p>{ %@ }", self.class, self, eventDescription];
+}
+
+- (NSUInteger)hash {
+	return self.eventType ^ [self.object hash];
+}
+
+- (BOOL)isEqual:(id)event {
+	if (event == self) return YES;
+	if (![event isKindOfClass:RACEvent.class]) return NO;
+	if (self.eventType != [event eventType]) return NO;
+
+	// Catches the nil case too.
+	return self.object == [event object] || [self.object isEqual:[event object]];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.h
new file mode 100644
index 0000000..697d922
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.h
@@ -0,0 +1,20 @@
+//
+//  RACGroupedSignal.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/2/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubject.h"
+
+
+/// A grouped signal is used by -[RACSignal groupBy:transform:].
+@interface RACGroupedSignal : RACSubject
+
+/// The key shared by the group.
+@property (nonatomic, readonly, copy) id<NSCopying> key;
+
++ (instancetype)signalWithKey:(id<NSCopying>)key;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.m
new file mode 100644
index 0000000..00e0378
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACGroupedSignal.m
@@ -0,0 +1,25 @@
+//
+//  RACGroupedSignal.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 5/2/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACGroupedSignal.h"
+
+@interface RACGroupedSignal ()
+@property (nonatomic, copy) id<NSCopying> key;
+@end
+
+@implementation RACGroupedSignal
+
+#pragma mark API
+
++ (instancetype)signalWithKey:(id<NSCopying>)key {
+	RACGroupedSignal *subject = [self subject];
+	subject.key = key;
+	return subject;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.h
new file mode 100644
index 0000000..76b5b50
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.h
@@ -0,0 +1,14 @@
+//
+//  RACImmediateScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+
+// A private scheduler which immediately executes its scheduled blocks.
+@interface RACImmediateScheduler : RACScheduler
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.m
new file mode 100644
index 0000000..f32eda3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACImmediateScheduler.m
@@ -0,0 +1,44 @@
+//
+//  RACImmediateScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACImmediateScheduler.h"
+#import "RACScheduler+Private.h"
+
+@implementation RACImmediateScheduler
+
+#pragma mark Lifecycle
+
+- (id)init {
+	return [super initWithName:@"com.ReactiveCocoa.RACScheduler.immediateScheduler"];
+}
+
+#pragma mark RACScheduler
+
+- (RACDisposable *)schedule:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	block();
+	return nil;
+}
+
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(block != NULL);
+
+	[NSThread sleepUntilDate:date];
+	block();
+
+	return nil;
+}
+
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
+	NSCAssert(NO, @"+[RACScheduler immediateScheduler] does not support %@.", NSStringFromSelector(_cmd));
+	return nil;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.h
new file mode 100644
index 0000000..eab84a3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.h
@@ -0,0 +1,16 @@
+//
+//  RACIndexSetSequence.h
+//  ReactiveCocoa
+//
+//  Created by Sergey Gavrilyuk on 12/18/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class that adapts an array to the RACSequence interface.
+@interface RACIndexSetSequence : RACSequence
+
++ (instancetype)sequenceWithIndexSet:(NSIndexSet *)indexSet;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.m
new file mode 100644
index 0000000..7ac8f53
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACIndexSetSequence.m
@@ -0,0 +1,108 @@
+//
+//  RACIndexSetSequence.m
+//  ReactiveCocoa
+//
+//  Created by Sergey Gavrilyuk on 12/18/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACIndexSetSequence.h"
+
+@interface RACIndexSetSequence ()
+
+// A buffer holding the `NSUInteger` values to enumerate over.
+//
+// This is mostly used for memory management. Most access should go through
+// `indexes` instead.
+@property (nonatomic, strong, readonly) NSData *data;
+
+// The indexes that this sequence should enumerate.
+@property (nonatomic, readonly) const NSUInteger *indexes;
+
+// The number of indexes to enumerate.
+@property (nonatomic, readonly) NSUInteger count;
+
+@end
+
+@implementation RACIndexSetSequence
+
+#pragma mark Lifecycle
+
++ (instancetype)sequenceWithIndexSet:(NSIndexSet *)indexSet {
+	NSUInteger count = indexSet.count;
+	NSUInteger sizeInBytes = sizeof(NSUInteger) * count;
+
+	NSMutableData *data = [[NSMutableData alloc] initWithCapacity:sizeInBytes];
+	[indexSet getIndexes:data.mutableBytes maxCount:count inIndexRange:NULL];
+
+	RACIndexSetSequence *seq = [[self alloc] init];
+	seq->_data = data;
+	seq->_indexes = data.bytes;
+	seq->_count = count;
+	return seq;
+}
+
++ (instancetype)sequenceWithIndexSetSequence:(RACIndexSetSequence *)indexSetSequence offset:(NSUInteger)offset {
+	NSCParameterAssert(offset < indexSetSequence.count);
+
+	RACIndexSetSequence *seq = [[self alloc] init];
+	seq->_data = indexSetSequence.data;
+	seq->_indexes = indexSetSequence.indexes + offset;
+	seq->_count = indexSetSequence.count - offset;
+	return seq;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	return @(self.indexes[0]);
+}
+
+- (RACSequence *)tail {
+	if (self.count <= 1) return [RACSequence empty];
+
+	return [self.class sequenceWithIndexSetSequence:self offset:1];
+}
+
+#pragma mark NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id[])stackbuf count:(NSUInteger)len {
+	NSCParameterAssert(len > 0);
+
+	if (state->state >= self.count) {
+		// Enumeration has completed.
+		return 0;
+	}
+	
+	if (state->state == 0) {
+		// Enumeration begun, mark the mutation flag.
+		state->mutationsPtr = state->extra;
+	}
+	
+	state->itemsPtr = stackbuf;
+	
+	unsigned long index = 0;
+	while (index < MIN(self.count - state->state, len)) {
+		stackbuf[index] = @(self.indexes[index + state->state]);
+		++index;
+	}
+	
+	state->state += index;
+	return index;
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	NSMutableString *indexesStr = [NSMutableString string];
+
+	for (unsigned int i = 0; i < self.count; ++i) {
+		if (i > 0) [indexesStr appendString:@", "];
+
+		[indexesStr appendFormat:@"%lu", (unsigned long)self.indexes[i]];
+	}
+
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, indexes = %@ }", self.class, self, self.name, indexesStr];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.h b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.h
new file mode 100644
index 0000000..060a4cc
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.h
@@ -0,0 +1,97 @@
+//
+//  RACKVOChannel.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 27/12/2012.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACChannel.h"
+#import "RACEXTKeyPathCoding.h"
+#import "RACmetamacros.h"
+
+/// Creates a RACKVOChannel to the given key path. When the targeted object
+/// deallocates, the channel will complete.
+///
+/// If RACChannelTo() is used as an expression, it returns a RACChannelTerminal that
+/// can be used to watch the specified property for changes, and set new values
+/// for it. The terminal will start with the property's current value upon
+/// subscription.
+///
+/// If RACChannelTo() is used on the left-hand side of an assignment, there must a
+/// RACChannelTerminal on the right-hand side of the assignment. The two will be
+/// subscribed to one another: the property's value is immediately set to the
+/// value of the channel terminal on the right-hand side, and subsequent changes
+/// to either terminal will be reflected on the other.
+///
+/// There are two different versions of this macro:
+///
+///  - RACChannelTo(TARGET, KEYPATH, NILVALUE) will create a channel to the `KEYPATH`
+///    of `TARGET`. If the terminal is ever sent a `nil` value, the property will
+///    be set to `NILVALUE` instead. `NILVALUE` may itself be `nil` for object
+///    properties, but an NSValue should be used for primitive properties, to
+///    avoid an exception if `nil` is sent (which might occur if an intermediate
+///    object is set to `nil`).
+///  - RACChannelTo(TARGET, KEYPATH) is the same as the above, but `NILVALUE` defaults to
+///    `nil`.
+///
+/// Examples
+///
+///  RACChannelTerminal *integerChannel = RACChannelTo(self, integerProperty, @42);
+///
+///  // Sets self.integerProperty to 5.
+///  [integerChannel sendNext:@5];
+///
+///  // Logs the current value of self.integerProperty, and all future changes.
+///  [integerChannel subscribeNext:^(id value) {
+///      NSLog(@"value: %@", value);
+///  }];
+///
+///  // Binds properties to each other, taking the initial value from the right
+///  side.
+///  RACChannelTo(view, objectProperty) = RACChannelTo(model, objectProperty);
+///  RACChannelTo(view, integerProperty, @2) = RACChannelTo(model, integerProperty, @10);
+#define RACChannelTo(TARGET, ...) \
+    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
+        (RACChannelTo_(TARGET, __VA_ARGS__, nil)) \
+        (RACChannelTo_(TARGET, __VA_ARGS__))
+
+/// Do not use this directly. Use the RACChannelTo macro above.
+#define RACChannelTo_(TARGET, KEYPATH, NILVALUE) \
+    [[RACKVOChannel alloc] initWithTarget:(TARGET) keyPath:@keypath(TARGET, KEYPATH) nilValue:(NILVALUE)][@keypath(RACKVOChannel.new, followingTerminal)]
+
+/// A RACChannel that observes a KVO-compliant key path for changes.
+@interface RACKVOChannel : RACChannel
+
+/// Initializes a channel that will observe the given object and key path.
+///
+/// The current value of the key path, and future KVO notifications for the given
+/// key path, will be sent to subscribers of the channel's `followingTerminal`.
+/// Values sent to the `followingTerminal` will be set at the given key path using
+/// key-value coding.
+///
+/// When the target object deallocates, the channel will complete. Signal errors
+/// are considered undefined behavior.
+///
+/// This is the designated initializer for this class.
+///
+/// target   - The object to bind to.
+/// keyPath  - The key path to observe and set the value of.
+/// nilValue - The value to set at the key path whenever a `nil` value is
+///            received. This may be nil when connecting to object properties, but
+///            an NSValue should be used for primitive properties, to avoid an
+///            exception if `nil` is received (which might occur if an intermediate
+///            object is set to `nil`).
+- (id)initWithTarget:(NSObject *)target keyPath:(NSString *)keyPath nilValue:(id)nilValue;
+
+- (id)init __attribute__((unavailable("Use -initWithTarget:keyPath:nilValue: instead")));
+
+@end
+
+/// Methods needed for the convenience macro. Do not call explicitly.
+@interface RACKVOChannel (RACChannelTo)
+
+- (RACChannelTerminal *)objectForKeyedSubscript:(NSString *)key;
+- (void)setObject:(RACChannelTerminal *)otherTerminal forKeyedSubscript:(NSString *)key;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.m b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.m
new file mode 100644
index 0000000..e0d1a82
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOChannel.m
@@ -0,0 +1,206 @@
+//
+//  RACKVOChannel.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 27/12/2012.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACKVOChannel.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACKVOWrapper.h"
+#import "NSObject+RACPropertySubscribing.h"
+#import "NSString+RACKeyPathUtilities.h"
+#import "RACChannel.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACReplaySubject.h"
+#import "RACSignal+Operations.h"
+#import "RACSubscriber+Private.h"
+#import "RACSubject.h"
+
+// Key for the array of RACKVOChannel's additional thread local
+// data in the thread dictionary.
+static NSString * const RACKVOChannelDataDictionaryKey = @"RACKVOChannelKey";
+
+// Wrapper class for additional thread local data.
+@interface RACKVOChannelData : NSObject
+
+// The flag used to ignore updates the channel itself has triggered.
+@property (nonatomic, assign) BOOL ignoreNextUpdate;
+
+// A pointer to the owner of the data. Only use this for pointer comparison,
+// never as an object reference.
+@property (nonatomic, assign) void *owner;
+
++ (instancetype)dataForChannel:(RACKVOChannel *)channel;
+
+@end
+
+@interface RACKVOChannel ()
+
+// The object whose key path the channel is wrapping.
+@property (atomic, unsafe_unretained) NSObject *target;
+
+// The key path the channel is wrapping.
+@property (nonatomic, copy, readonly) NSString *keyPath;
+
+// Returns the existing thread local data container or nil if none exists.
+@property (nonatomic, strong, readonly) RACKVOChannelData *currentThreadData;
+
+// Creates the thread local data container for the channel.
+- (void)createCurrentThreadData;
+
+// Destroy the thread local data container for the channel.
+- (void)destroyCurrentThreadData;
+
+@end
+
+@implementation RACKVOChannel
+
+#pragma mark Properties
+
+- (RACKVOChannelData *)currentThreadData {
+	NSMutableArray *dataArray = NSThread.currentThread.threadDictionary[RACKVOChannelDataDictionaryKey];
+
+	for (RACKVOChannelData *data in dataArray) {
+		if (data.owner == (__bridge void *)self) return data;
+	}
+
+	return nil;
+}
+
+#pragma mark Lifecycle
+
+- (id)initWithTarget:(NSObject *)target keyPath:(NSString *)keyPath nilValue:(id)nilValue {
+	NSCParameterAssert(keyPath.rac_keyPathComponents.count > 0);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_target = target;
+	_keyPath = [keyPath copy];
+
+	[self.leadingTerminal setNameWithFormat:@"[-initWithTarget: %@ keyPath: %@ nilValue: %@] -leadingTerminal", target, keyPath, nilValue];
+	[self.followingTerminal setNameWithFormat:@"[-initWithTarget: %@ keyPath: %@ nilValue: %@] -followingTerminal", target, keyPath, nilValue];
+
+	// Observe the key path on target for changes and forward the changes to the
+	// terminal.
+	//
+	// Intentionally capturing `self` strongly in the blocks below, so the
+	// channel object stays alive while observing.
+	RACDisposable *observationDisposable = [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionInitial observer:nil block:^(id value, NSDictionary *change) {
+		// If the change wasn't triggered by deallocation, only affects the last
+		// path component, and ignoreNextUpdate is set, then it was triggered by
+		// this channel and should not be forwarded.
+		if (![change[RACKeyValueChangeCausedByDeallocationKey] boolValue] && [change[RACKeyValueChangeAffectedOnlyLastComponentKey] boolValue] && self.currentThreadData.ignoreNextUpdate) {
+			[self destroyCurrentThreadData];
+			return;
+		}
+
+		[self.leadingTerminal sendNext:value];
+	}];
+	
+	NSString *keyPathByDeletingLastKeyPathComponent = keyPath.rac_keyPathByDeletingLastKeyPathComponent;
+	NSArray *keyPathComponents = keyPath.rac_keyPathComponents;
+	NSUInteger keyPathComponentsCount = keyPathComponents.count;
+	NSString *lastKeyPathComponent = keyPathComponents.lastObject;
+
+	// Update the value of the property with the values received.
+	[[self.leadingTerminal
+		finally:^{
+			[observationDisposable dispose];
+		}]
+		subscribeNext:^(id x) {
+			// Check the value of the second to last key path component. Since the
+			// channel can only update the value of a property on an object, and not
+			// update intermediate objects, it can only update the value of the whole
+			// key path if this object is not nil.
+			NSObject *object = (keyPathComponentsCount > 1 ? [self.target valueForKeyPath:keyPathByDeletingLastKeyPathComponent] : self.target);
+			if (object == nil) return;
+
+			// Set the ignoreNextUpdate flag before setting the value so this channel
+			// ignores the value in the subsequent -didChangeValueForKey: callback.
+			[self createCurrentThreadData];
+			self.currentThreadData.ignoreNextUpdate = YES;
+
+			[object setValue:x ?: nilValue forKey:lastKeyPathComponent];
+		} error:^(NSError *error) {
+			NSCAssert(NO, @"Received error in %@: %@", self, error);
+			
+			// Log the error if we're running with assertions disabled.
+			NSLog(@"Received error in %@: %@", self, error);
+		}];
+	
+	// Capture `self` weakly for the target's deallocation disposable, so we can
+	// freely deallocate if we complete before then.
+	@weakify(self);
+	
+	[target.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+		@strongify(self);
+		[self.leadingTerminal sendCompleted];
+		self.target = nil;
+	}]];
+	
+	return self;
+}
+
+- (void)createCurrentThreadData {
+	NSMutableArray *dataArray = NSThread.currentThread.threadDictionary[RACKVOChannelDataDictionaryKey];
+	if (dataArray == nil) {
+		dataArray = [NSMutableArray array];
+		NSThread.currentThread.threadDictionary[RACKVOChannelDataDictionaryKey] = dataArray;
+		[dataArray addObject:[RACKVOChannelData dataForChannel:self]];
+		return;
+	}
+
+	for (RACKVOChannelData *data in dataArray) {
+		if (data.owner == (__bridge void *)self) return;
+	}
+
+	[dataArray addObject:[RACKVOChannelData dataForChannel:self]];
+}
+
+- (void)destroyCurrentThreadData {
+	NSMutableArray *dataArray = NSThread.currentThread.threadDictionary[RACKVOChannelDataDictionaryKey];
+	NSUInteger index = [dataArray indexOfObjectPassingTest:^ BOOL (RACKVOChannelData *data, NSUInteger idx, BOOL *stop) {
+		return data.owner == (__bridge void *)self;
+	}];
+
+	if (index != NSNotFound) [dataArray removeObjectAtIndex:index];
+}
+
+@end
+
+@implementation RACKVOChannel (RACChannelTo)
+
+- (RACChannelTerminal *)objectForKeyedSubscript:(NSString *)key {
+	NSCParameterAssert(key != nil);
+
+	RACChannelTerminal *terminal = [self valueForKey:key];
+	NSCAssert([terminal isKindOfClass:RACChannelTerminal.class], @"Key \"%@\" does not identify a channel terminal", key);
+	
+	return terminal;
+}
+
+- (void)setObject:(RACChannelTerminal *)otherTerminal forKeyedSubscript:(NSString *)key {
+	NSCParameterAssert(otherTerminal != nil);
+
+	RACChannelTerminal *selfTerminal = [self objectForKeyedSubscript:key];
+	[otherTerminal subscribe:selfTerminal];
+	[[selfTerminal skip:1] subscribe:otherTerminal];
+}
+
+@end
+
+@implementation RACKVOChannelData
+
++ (instancetype)dataForChannel:(RACKVOChannel *)channel {
+	RACKVOChannelData *data = [[self alloc] init];
+	data->_owner = (__bridge void *)channel;
+	return data;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.h b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.h
new file mode 100644
index 0000000..5701486
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.h
@@ -0,0 +1,31 @@
+//
+//  RACKVOTrampoline.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 1/15/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "NSObject+RACKVOWrapper.h"
+#import "RACDisposable.h"
+
+// A private trampoline object that represents a KVO observation.
+//
+// Disposing of the trampoline will stop observation.
+@interface RACKVOTrampoline : RACDisposable
+
+// Initializes the receiver with the given parameters.
+//
+// target   - The object whose key path should be observed. Cannot be nil.
+// observer - The object that gets notified when the value at the key path
+//            changes. Can be nil.
+// keyPath  - The key path on `target` to observe. Cannot be nil.
+// options  - Any key value observing options to use in the observation.
+// block    - The block to call when the value at the observed key path changes.
+//            Cannot be nil.
+//
+// Returns the initialized object.
+- (id)initWithTarget:(NSObject *)target observer:(NSObject *)observer keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(RACKVOBlock)block;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.m b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.m
new file mode 100644
index 0000000..1e4feae
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACKVOTrampoline.m
@@ -0,0 +1,100 @@
+//
+//  RACKVOTrampoline.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 1/15/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACKVOTrampoline.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACCompoundDisposable.h"
+
+static void *RACKVOWrapperContext = &RACKVOWrapperContext;
+
+@interface RACKVOTrampoline ()
+
+// The keypath which the trampoline is observing.
+@property (nonatomic, readonly, copy) NSString *keyPath;
+
+// These properties should only be manipulated while synchronized on the
+// receiver.
+@property (nonatomic, readonly, copy) RACKVOBlock block;
+@property (nonatomic, readonly, unsafe_unretained) NSObject *target;
+@property (nonatomic, readonly, unsafe_unretained) NSObject *observer;
+
+@end
+
+@implementation RACKVOTrampoline
+
+#pragma mark Lifecycle
+
+- (id)initWithTarget:(NSObject *)target observer:(NSObject *)observer keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(RACKVOBlock)block {
+	NSCParameterAssert(target != nil);
+	NSCParameterAssert(keyPath != nil);
+	NSCParameterAssert(block != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_keyPath = [keyPath copy];
+
+	_block = [block copy];
+	_target = target;
+	_observer = observer;
+
+	[self.target addObserver:self forKeyPath:self.keyPath options:options context:&RACKVOWrapperContext];
+	[self.target.rac_deallocDisposable addDisposable:self];
+	[self.observer.rac_deallocDisposable addDisposable:self];
+
+	return self;
+}
+
+- (void)dealloc {
+	[self dispose];
+}
+
+#pragma mark Observation
+
+- (void)dispose {
+	NSObject *target;
+	NSObject *observer;
+
+	@synchronized (self) {
+		_block = nil;
+
+		target = self.target;
+		observer = self.observer;
+
+		_target = nil;
+		_observer = nil;
+	}
+
+	[target.rac_deallocDisposable removeDisposable:self];
+	[observer.rac_deallocDisposable removeDisposable:self];
+
+	[target removeObserver:self forKeyPath:self.keyPath context:&RACKVOWrapperContext];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+	if (context != &RACKVOWrapperContext) {
+		[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+		return;
+	}
+
+	RACKVOBlock block;
+	id observer;
+	id target;
+
+	@synchronized (self) {
+		block = self.block;
+		observer = self.observer;
+		target = self.target;
+	}
+
+	if (block == nil) return;
+
+	block(target, observer, change);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection+Private.h b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection+Private.h
new file mode 100644
index 0000000..43931f8
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection+Private.h
@@ -0,0 +1,17 @@
+//
+//  RACMulticastConnection+Private.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACMulticastConnection.h"
+
+@class RACSubject;
+
+@interface RACMulticastConnection ()
+
+- (id)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)subject;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.h b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.h
new file mode 100644
index 0000000..5361f5d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.h
@@ -0,0 +1,46 @@
+//
+//  RACMulticastConnection.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+@class RACSignal;
+@class RACDisposable;
+
+/// A multicast connection encapsulates the idea of sharing one subscription to a
+/// signal to many subscribers. This is most often needed if the subscription to
+/// the underlying signal involves side-effects or shouldn't be called more than
+/// once.
+///
+/// The multicasted signal is only subscribed to when
+/// -[RACMulticastConnection connect] is called. Until that happens, no values
+/// will be sent on `signal`. See -[RACMulticastConnection autoconnect] for how
+/// -[RACMulticastConnection connect] can be called automatically.
+///
+/// Note that you shouldn't create RACMulticastConnection manually. Instead use
+/// -[RACSignal publish] or -[RACSignal multicast:].
+@interface RACMulticastConnection : NSObject
+
+/// The multicasted signal.
+@property (nonatomic, strong, readonly) RACSignal *signal;
+
+/// Connect to the underlying signal by subscribing to it. Calling this multiple
+/// times does nothing but return the existing connection's disposable.
+///
+/// Returns the disposable for the subscription to the multicasted signal.
+- (RACDisposable *)connect;
+
+/// Connects to the underlying signal when the returned signal is first
+/// subscribed to, and disposes of the subscription to the multicasted signal
+/// when the returned signal has no subscribers.
+///
+/// If new subscribers show up after being disposed, they'll subscribe and then
+/// be immediately disposed of. The returned signal will never re-connect to the
+/// multicasted signal.
+///
+/// Returns the autoconnecting signal.
+- (RACSignal *)autoconnect;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.m b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.m
new file mode 100644
index 0000000..1534d96
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACMulticastConnection.m
@@ -0,0 +1,85 @@
+//
+//  RACMulticastConnection.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/11/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACMulticastConnection.h"
+#import "RACMulticastConnection+Private.h"
+#import "RACDisposable.h"
+#import "RACSerialDisposable.h"
+#import "RACSubject.h"
+#import <libkern/OSAtomic.h>
+
+@interface RACMulticastConnection () {
+	RACSubject *_signal;
+
+	// When connecting, a caller should attempt to atomically swap the value of this
+	// from `0` to `1`.
+	//
+	// If the swap is successful the caller is resposible for subscribing `_signal`
+	// to `sourceSignal` and storing the returned disposable in `serialDisposable`.
+	//
+	// If the swap is unsuccessful it means that `_sourceSignal` has already been
+	// connected and the caller has no action to take.
+	int32_t volatile _hasConnected;
+}
+
+@property (nonatomic, readonly, strong) RACSignal *sourceSignal;
+@property (strong) RACSerialDisposable *serialDisposable;
+@end
+
+@implementation RACMulticastConnection
+
+#pragma mark Lifecycle
+
+- (id)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)subject {
+	NSCParameterAssert(source != nil);
+	NSCParameterAssert(subject != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_sourceSignal = source;
+	_serialDisposable = [[RACSerialDisposable alloc] init];
+	_signal = subject;
+	
+	return self;
+}
+
+#pragma mark Connecting
+
+- (RACDisposable *)connect {
+	BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);
+
+	if (shouldConnect) {
+		self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
+	}
+
+	return self.serialDisposable;
+}
+
+- (RACSignal *)autoconnect {
+	__block volatile int32_t subscriberCount = 0;
+
+	return [[RACSignal
+		createSignal:^(id<RACSubscriber> subscriber) {
+			OSAtomicIncrement32Barrier(&subscriberCount);
+
+			RACDisposable *subscriptionDisposable = [self.signal subscribe:subscriber];
+			RACDisposable *connectionDisposable = [self connect];
+
+			return [RACDisposable disposableWithBlock:^{
+				[subscriptionDisposable dispose];
+
+				if (OSAtomicDecrement32Barrier(&subscriberCount) == 0) {
+					[connectionDisposable dispose];
+				}
+			}];
+		}]
+		setNameWithFormat:@"[%@] -autoconnect", self.signal.name];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.h b/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.h
new file mode 100644
index 0000000..fbec61c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.h
@@ -0,0 +1,17 @@
+//
+//  RACObjCRuntime.h
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/19/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// A private class containing wrappers to runtime functions.
+@interface RACObjCRuntime : NSObject
+
+// Invokes objc_allocateClassPair(). Can be called from ARC code.
++ (Class)createClass:(const char *)className inheritingFromClass:(Class)superclass;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.m b/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.m
new file mode 100644
index 0000000..43cfc19
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACObjCRuntime.m
@@ -0,0 +1,22 @@
+//
+//  RACObjCRuntime.m
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/19/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACObjCRuntime.h"
+#import <objc/runtime.h>
+
+#if __has_feature(objc_arc)
+#error "This file must be compiled without ARC."
+#endif
+
+@implementation RACObjCRuntime
+
++ (Class)createClass:(const char *)className inheritingFromClass:(Class)superclass {
+	return objc_allocateClassPair(superclass, className, 0);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.h b/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.h
new file mode 100644
index 0000000..9ae547b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.h
@@ -0,0 +1,29 @@
+//
+//  RACPassthroughSubscriber.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-06-13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACSubscriber.h"
+
+@class RACCompoundDisposable;
+@class RACSignal;
+
+// A private subscriber that passes through all events to another subscriber
+// while not disposed.
+@interface RACPassthroughSubscriber : NSObject <RACSubscriber>
+
+// Initializes the receiver to pass through events until disposed.
+//
+// subscriber - The subscriber to forward events to. This must not be nil.
+// signal     - The signal that will be sending events to the receiver.
+// disposable - When this disposable is disposed, no more events will be
+//              forwarded. This must not be nil.
+//
+// Returns an initialized passthrough subscriber.
+- (instancetype)initWithSubscriber:(id<RACSubscriber>)subscriber signal:(RACSignal *)signal disposable:(RACCompoundDisposable *)disposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.m b/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.m
new file mode 100644
index 0000000..614d7d5
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACPassthroughSubscriber.m
@@ -0,0 +1,103 @@
+//
+//  RACPassthroughSubscriber.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-06-13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACPassthroughSubscriber.h"
+#import "RACCompoundDisposable.h"
+#import "RACSignal.h"
+#import "RACSignalProvider.h"
+
+static const char *cleanedDTraceString(NSString *original) {
+	return [original stringByReplacingOccurrencesOfString:@"\\s+" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, original.length)].UTF8String;
+}
+
+static const char *cleanedSignalDescription(RACSignal *signal) {
+	NSString *desc = signal.description;
+
+	NSRange range = [desc rangeOfString:@" name:"];
+	if (range.location != NSNotFound) {
+		desc = [desc stringByReplacingCharactersInRange:range withString:@""];
+	}
+
+	return cleanedDTraceString(desc);
+}
+
+@interface RACPassthroughSubscriber ()
+
+// The subscriber to which events should be forwarded.
+@property (nonatomic, strong, readonly) id<RACSubscriber> innerSubscriber;
+
+// The signal sending events to this subscriber.
+//
+// This property isn't `weak` because it's only used for DTrace probes, so
+// a zeroing weak reference would incur an unnecessary performance penalty in
+// normal usage.
+@property (nonatomic, unsafe_unretained, readonly) RACSignal *signal;
+
+// A disposable representing the subscription. When disposed, no further events
+// should be sent to the `innerSubscriber`.
+@property (nonatomic, strong, readonly) RACCompoundDisposable *disposable;
+
+@end
+
+@implementation RACPassthroughSubscriber
+
+#pragma mark Lifecycle
+
+- (instancetype)initWithSubscriber:(id<RACSubscriber>)subscriber signal:(RACSignal *)signal disposable:(RACCompoundDisposable *)disposable {
+	NSCParameterAssert(subscriber != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_innerSubscriber = subscriber;
+	_signal = signal;
+	_disposable = disposable;
+
+	[self.innerSubscriber didSubscribeWithDisposable:self.disposable];
+	return self;
+}
+
+#pragma mark RACSubscriber
+
+- (void)sendNext:(id)value {
+	if (self.disposable.disposed) return;
+
+	if (RACSIGNAL_NEXT_ENABLED()) {
+		RACSIGNAL_NEXT(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString([value description]));
+	}
+
+	[self.innerSubscriber sendNext:value];
+}
+
+- (void)sendError:(NSError *)error {
+	if (self.disposable.disposed) return;
+
+	if (RACSIGNAL_ERROR_ENABLED()) {
+		RACSIGNAL_ERROR(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString(error.description));
+	}
+
+	[self.innerSubscriber sendError:error];
+}
+
+- (void)sendCompleted {
+	if (self.disposable.disposed) return;
+
+	if (RACSIGNAL_COMPLETED_ENABLED()) {
+		RACSIGNAL_COMPLETED(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description));
+	}
+
+	[self.innerSubscriber sendCompleted];
+}
+
+- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable {
+	if (disposable != self.disposable) {
+		[self.disposable addDisposable:disposable];
+	}
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler+Subclass.h b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler+Subclass.h
new file mode 100644
index 0000000..48ef636
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler+Subclass.h
@@ -0,0 +1,46 @@
+//
+//  RACQueueScheduler+Subclass.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 6/6/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACQueueScheduler.h"
+
+/// An interface for use by subclasses.
+///
+/// Subclasses should use `-performAsCurrentScheduler:` to do the actual block
+/// invocation so that +[RACScheduler currentScheduler] behaves as expected.
+///
+/// **Note that RACSchedulers are expected to be serial**. Subclasses must honor
+/// that contract. See `RACTargetQueueScheduler` for a queue-based scheduler
+/// which will enforce the serialization guarantee.
+@interface RACQueueScheduler ()
+
+/// The queue on which blocks are enqueued.
+@property (nonatomic, readonly) dispatch_queue_t queue;
+
+/// Initializes the receiver with the name of the scheduler and the queue which
+/// the scheduler should use.
+///
+/// name  - The name of the scheduler. If nil, a default name will be used.
+/// queue - The queue upon which the receiver should enqueue scheduled blocks.
+///         This argument must not be NULL.
+///
+/// Returns the initialized object.
+- (id)initWithName:(NSString *)name queue:(dispatch_queue_t)queue;
+
+/// Performs the given block with the receiver as the current scheduler for
+/// `queue`. This should only be called by subclasses to perform scheduled blocks
+/// on their queue.
+///
+/// block - The block to execute. Cannot be NULL.
+- (void)performAsCurrentScheduler:(void (^)(void))block;
+
+/// Converts a date into a GCD time using dispatch_walltime().
+///
+/// date - The date to convert. This must not be nil.
++ (dispatch_time_t)wallTimeWithDate:(NSDate *)date;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.h
new file mode 100644
index 0000000..ef42512
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.h
@@ -0,0 +1,18 @@
+//
+//  RACQueueScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+
+/// An abstract scheduler which asynchronously enqueues all its work to a Grand
+/// Central Dispatch queue.
+///
+/// Because RACQueueScheduler is abstract, it should not be instantiated
+/// directly. Create a subclass using the `RACQueueScheduler+Subclass.h`
+/// interface and use that instead.
+@interface RACQueueScheduler : RACScheduler
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.m
new file mode 100644
index 0000000..7ae8202
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACQueueScheduler.m
@@ -0,0 +1,120 @@
+//
+//  RACQueueScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACQueueScheduler.h"
+#import "RACBacktrace.h"
+#import "RACDisposable.h"
+#import "RACQueueScheduler+Subclass.h"
+#import "RACScheduler+Private.h"
+
+@implementation RACQueueScheduler
+
+#pragma mark Lifecycle
+
+- (void)dealloc {
+	dispatch_release(_queue);
+}
+
+- (id)initWithName:(NSString *)name queue:(dispatch_queue_t)queue {
+	NSCParameterAssert(queue != NULL);
+
+	self = [super initWithName:name];
+	if (self == nil) return nil;
+
+	dispatch_retain(queue);
+	_queue = queue;
+
+	return self;
+}
+
+#pragma mark Date Conversions
+
++ (dispatch_time_t)wallTimeWithDate:(NSDate *)date {
+	NSCParameterAssert(date != nil);
+
+	double seconds = 0;
+	double frac = modf(date.timeIntervalSince1970, &seconds);
+
+	struct timespec walltime = {
+		.tv_sec = (time_t)fmin(fmax(seconds, LONG_MIN), LONG_MAX),
+		.tv_nsec = (long)fmin(fmax(frac * NSEC_PER_SEC, LONG_MIN), LONG_MAX)
+	};
+
+	return dispatch_walltime(&walltime, 0);
+}
+
+#pragma mark RACScheduler
+
+- (RACDisposable *)schedule:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	RACDisposable *disposable = [[RACDisposable alloc] init];
+
+	dispatch_async(self.queue, ^{
+		if (disposable.disposed) return;
+		[self performAsCurrentScheduler:block];
+	});
+
+	return disposable;
+}
+
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(block != NULL);
+
+	RACDisposable *disposable = [[RACDisposable alloc] init];
+
+	dispatch_after([self.class wallTimeWithDate:date], self.queue, ^{
+		if (disposable.disposed) return;
+		[self performAsCurrentScheduler:block];
+	});
+
+	return disposable;
+}
+
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(interval > 0.0 && interval < INT64_MAX / NSEC_PER_SEC);
+	NSCParameterAssert(leeway >= 0.0 && leeway < INT64_MAX / NSEC_PER_SEC);
+	NSCParameterAssert(block != NULL);
+
+	uint64_t intervalInNanoSecs = (uint64_t)(interval * NSEC_PER_SEC);
+	uint64_t leewayInNanoSecs = (uint64_t)(leeway * NSEC_PER_SEC);
+
+	dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
+	dispatch_source_set_timer(timer, [self.class wallTimeWithDate:date], intervalInNanoSecs, leewayInNanoSecs);
+	dispatch_source_set_event_handler(timer, block);
+	dispatch_resume(timer);
+
+	return [RACDisposable disposableWithBlock:^{
+		dispatch_source_cancel(timer);
+		dispatch_release(timer);
+	}];
+}
+
+- (void)performAsCurrentScheduler:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	// If we're using a concurrent queue, we could end up in here concurrently,
+	// in which case we *don't* want to clear the current scheduler immediately
+	// after our block is done executing, but only *after* all our concurrent
+	// invocations are done.
+
+	RACScheduler *previousScheduler = RACScheduler.currentScheduler;
+	NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = self;
+
+	block();
+
+	if (previousScheduler != nil) {
+		NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = previousScheduler;
+	} else {
+		[NSThread.currentThread.threadDictionary removeObjectForKey:RACSchedulerCurrentSchedulerKey];
+	}
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.h b/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.h
new file mode 100644
index 0000000..cd6f2ec
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.h
@@ -0,0 +1,23 @@
+//
+//  RACReplaySubject.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/14/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubject.h"
+
+extern const NSUInteger RACReplaySubjectUnlimitedCapacity;
+
+
+/// A replay subject saves the values it is sent (up to its defined capacity)
+/// and resends those to new subscribers. It will also replay an error or
+/// completion.
+@interface RACReplaySubject : RACSubject
+
+/// Creates a new replay subject with the given capacity. A capacity of
+/// RACReplaySubjectUnlimitedCapacity means values are never trimmed.
++ (instancetype)replaySubjectWithCapacity:(NSUInteger)capacity;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.m b/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.m
new file mode 100644
index 0000000..bca008e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACReplaySubject.m
@@ -0,0 +1,112 @@
+//
+//  RACReplaySubject.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/14/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACReplaySubject.h"
+#import "RACDisposable.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriber.h"
+#import "RACTuple.h"
+#import "RACCompoundDisposable.h"
+
+const NSUInteger RACReplaySubjectUnlimitedCapacity = NSUIntegerMax;
+
+@interface RACReplaySubject ()
+
+@property (nonatomic, assign, readonly) NSUInteger capacity;
+
+// These properties should only be modified while synchronized on self.
+@property (nonatomic, strong, readonly) NSMutableArray *valuesReceived;
+@property (nonatomic, assign) BOOL hasCompleted;
+@property (nonatomic, assign) BOOL hasError;
+@property (nonatomic, strong) NSError *error;
+
+@end
+
+
+@implementation RACReplaySubject
+
+#pragma mark Lifecycle
+
++ (instancetype)replaySubjectWithCapacity:(NSUInteger)capacity {
+	return [[self alloc] initWithCapacity:capacity];
+}
+
+- (instancetype)init {
+	return [self initWithCapacity:RACReplaySubjectUnlimitedCapacity];
+}
+
+- (instancetype)initWithCapacity:(NSUInteger)capacity {
+	self = [super init];
+	if (self == nil) return nil;
+	
+	_capacity = capacity;
+	_valuesReceived = (capacity == RACReplaySubjectUnlimitedCapacity ? [NSMutableArray array] : [NSMutableArray arrayWithCapacity:capacity]);
+	
+	return self;
+}
+
+#pragma mark RACSignal
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
+
+	RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
+		@synchronized (self) {
+			for (id value in self.valuesReceived) {
+				if (compoundDisposable.disposed) return;
+
+				[subscriber sendNext:([value isKindOfClass:RACTupleNil.class] ? nil : value)];
+			}
+
+			if (compoundDisposable.disposed) return;
+
+			if (self.hasCompleted) {
+				[subscriber sendCompleted];
+			} else if (self.hasError) {
+				[subscriber sendError:self.error];
+			} else {
+				RACDisposable *subscriptionDisposable = [super subscribe:subscriber];
+				[compoundDisposable addDisposable:subscriptionDisposable];
+			}
+		}
+	}];
+
+	[compoundDisposable addDisposable:schedulingDisposable];
+
+	return compoundDisposable;
+}
+
+#pragma mark RACSubscriber
+
+- (void)sendNext:(id)value {
+	@synchronized (self) {
+		[self.valuesReceived addObject:value ?: RACTupleNil.tupleNil];
+		[super sendNext:value];
+		
+		if (self.capacity != RACReplaySubjectUnlimitedCapacity && self.valuesReceived.count > self.capacity) {
+			[self.valuesReceived removeObjectsInRange:NSMakeRange(0, self.valuesReceived.count - self.capacity)];
+		}
+	}
+}
+
+- (void)sendCompleted {
+	@synchronized (self) {
+		self.hasCompleted = YES;
+		[super sendCompleted];
+	}
+}
+
+- (void)sendError:(NSError *)e {
+	@synchronized (self) {
+		self.hasError = YES;
+		self.error = e;
+		[super sendError:e];
+	}
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.h
new file mode 100644
index 0000000..73e5674
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.h
@@ -0,0 +1,17 @@
+//
+//  RACReturnSignal.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+
+// A private `RACSignal` subclasses that synchronously sends a value to any
+// subscribers, then completes.
+@interface RACReturnSignal : RACSignal
+
++ (RACSignal *)return:(id)value;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.m
new file mode 100644
index 0000000..3006634
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACReturnSignal.m
@@ -0,0 +1,90 @@
+//
+//  RACReturnSignal.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-10-10.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACReturnSignal.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriber.h"
+#import "RACUnit.h"
+
+@interface RACReturnSignal ()
+
+// The value to send upon subscription.
+@property (nonatomic, strong, readonly) id value;
+
+@end
+
+@implementation RACReturnSignal
+
+#pragma mark Properties
+
+// Only allow this signal's name to be customized in DEBUG, since it's
+// potentially a singleton in release builds (see +return:).
+- (void)setName:(NSString *)name {
+#ifdef DEBUG
+	[super setName:name];
+#endif
+}
+
+- (NSString *)name {
+#ifdef DEBUG
+	return super.name;
+#else
+	return @"+return:";
+#endif
+}
+
+#pragma mark Lifecycle
+
++ (RACSignal *)return:(id)value {
+#ifndef DEBUG
+	// In release builds, use singletons for two very common cases.
+	if (value == RACUnit.defaultUnit) {
+		static RACReturnSignal *unitSingleton;
+		static dispatch_once_t unitPred;
+
+		dispatch_once(&unitPred, ^{
+			unitSingleton = [[self alloc] init];
+			unitSingleton->_value = RACUnit.defaultUnit;
+		});
+
+		return unitSingleton;
+	} else if (value == nil) {
+		static RACReturnSignal *nilSingleton;
+		static dispatch_once_t nilPred;
+
+		dispatch_once(&nilPred, ^{
+			nilSingleton = [[self alloc] init];
+			nilSingleton->_value = nil;
+		});
+
+		return nilSingleton;
+	}
+#endif
+
+	RACReturnSignal *signal = [[self alloc] init];
+	signal->_value = value;
+
+#ifdef DEBUG
+	[signal setNameWithFormat:@"+return: %@", value];
+#endif
+
+	return signal;
+}
+
+#pragma mark Subscription
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCParameterAssert(subscriber != nil);
+
+	return [RACScheduler.subscriptionScheduler schedule:^{
+		[subscriber sendNext:self.value];
+		[subscriber sendCompleted];
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler+Private.h b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler+Private.h
new file mode 100644
index 0000000..2c91e66
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler+Private.h
@@ -0,0 +1,34 @@
+//
+//  RACScheduler+Private.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/29/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+
+// The thread-specific current scheduler key.
+extern NSString * const RACSchedulerCurrentSchedulerKey;
+
+// A private interface for internal RAC use only.
+@interface RACScheduler ()
+
+// A dedicated scheduler that fills two requirements:
+//
+//   1. By the time subscription happens, we need a valid +currentScheduler.
+//   2. Subscription should happen as soon as possible.
+//
+// To fulfill those two, if we already have a valid +currentScheduler, it
+// immediately executes scheduled blocks. If we don't, it will execute scheduled
+// blocks with a private background scheduler.
++ (instancetype)subscriptionScheduler;
+
+// Initializes the receiver with the given name.
+//
+// name - The name of the scheduler. If nil, a default name will be used.
+//
+// Returns the initialized object.
+- (id)initWithName:(NSString *)name;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.h
new file mode 100644
index 0000000..ce1ee32
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.h
@@ -0,0 +1,148 @@
+//
+//  RACScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/// The priority for the scheduler.
+///
+/// RACSchedulerPriorityHigh       - High priority.
+/// RACSchedulerPriorityDefault    - Default priority.
+/// RACSchedulerPriorityLow        - Low priority.
+/// RACSchedulerPriorityBackground - Background priority.
+typedef enum : long {
+	RACSchedulerPriorityHigh = DISPATCH_QUEUE_PRIORITY_HIGH,
+	RACSchedulerPriorityDefault = DISPATCH_QUEUE_PRIORITY_DEFAULT,
+	RACSchedulerPriorityLow = DISPATCH_QUEUE_PRIORITY_LOW,
+	RACSchedulerPriorityBackground = DISPATCH_QUEUE_PRIORITY_BACKGROUND,
+} RACSchedulerPriority;
+
+/// Scheduled with -scheduleRecursiveBlock:, this type of block is passed a block
+/// with which it can call itself recursively.
+typedef void (^RACSchedulerRecursiveBlock)(void (^reschedule)(void));
+
+@class RACDisposable;
+
+/// Schedulers are used to control when and where work is performed.
+@interface RACScheduler : NSObject
+
+/// A singleton scheduler that immediately executes the blocks it is given.
+///
+/// **Note:** Unlike most other schedulers, this does not set the current
+/// scheduler. There may still be a valid +currentScheduler if this is used
+/// within a block scheduled on a different scheduler.
++ (RACScheduler *)immediateScheduler;
+
+/// A singleton scheduler that executes blocks in the main thread.
++ (RACScheduler *)mainThreadScheduler;
+
+/// Creates and returns a new background scheduler with the given priority and
+/// name. The name is for debug and instrumentation purposes only.
+///
+/// Scheduler creation is cheap. It's unnecessary to save the result of this
+/// method call unless you want to serialize some actions on the same background
+/// scheduler.
++ (RACScheduler *)schedulerWithPriority:(RACSchedulerPriority)priority name:(NSString *)name;
+
+/// Invokes +schedulerWithPriority:name: with a default name.
++ (RACScheduler *)schedulerWithPriority:(RACSchedulerPriority)priority;
+
+/// Invokes +schedulerWithPriority: with RACSchedulerPriorityDefault.
++ (RACScheduler *)scheduler;
+
+/// The current scheduler. This will only be valid when used from within a
+/// -[RACScheduler schedule:] block or when on the main thread.
++ (RACScheduler *)currentScheduler;
+
+/// Schedule the given block for execution on the scheduler.
+///
+/// Scheduled blocks will be executed in the order in which they were scheduled.
+///
+/// block - The block to schedule for execution. Cannot be nil.
+///
+/// Returns a disposable which can be used to cancel the scheduled block before
+/// it begins executing, or nil if cancellation is not supported.
+- (RACDisposable *)schedule:(void (^)(void))block;
+
+/// Schedule the given block for execution on the scheduler at or after
+/// a specific time.
+///
+/// Note that blocks scheduled for a certain time will not preempt any other
+/// scheduled work that is executing at the time.
+///
+/// When invoked on the +immediateScheduler, the calling thread **will block**
+/// until the specified time.
+///
+/// date  - The earliest time at which `block` should begin executing. The block
+///         may not execute immediately at this time, whether due to system load
+///         or another block on the scheduler currently being run. Cannot be nil.
+/// block - The block to schedule for execution. Cannot be nil.
+///
+/// Returns a disposable which can be used to cancel the scheduled block before
+/// it begins executing, or nil if cancellation is not supported.
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block;
+
+/// Schedule the given block for execution on the scheduler after the delay.
+///
+/// Converts the delay into an NSDate, then invokes `-after:schedule:`.
+- (RACDisposable *)afterDelay:(NSTimeInterval)delay schedule:(void (^)(void))block;
+
+/// Reschedule the given block at a particular interval, starting at a specific
+/// time, and with a given leeway for deferral.
+///
+/// Note that blocks scheduled for a certain time will not preempt any other
+/// scheduled work that is executing at the time.
+///
+/// Regardless of the value of `leeway`, the given block may not execute exactly
+/// at `when` or exactly on successive intervals, whether due to system load or
+/// because another block is currently being run on the scheduler.
+///
+/// It is considered undefined behavior to invoke this method on the
+/// +immediateScheduler.
+///
+/// date     - The earliest time at which `block` should begin executing. The
+///            block may not execute immediately at this time, whether due to
+///            system load or another block on the scheduler currently being
+///            run. Cannot be nil.
+/// interval - The interval at which the block should be rescheduled, starting
+///            from `date`. This will use the system wall clock, to avoid
+///            skew when the computer goes to sleep.
+/// leeway   - A hint to the system indicating the number of seconds that each
+///            scheduling can be deferred. Note that this is just a hint, and
+///            there may be some additional latency no matter what.
+/// block    - The block to repeatedly schedule for execution. Cannot be nil.
+///
+/// Returns a disposable which can be used to cancel the automatic scheduling and
+/// rescheduling, or nil if cancellation is not supported.
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block;
+
+/// Schedule the given recursive block for execution on the scheduler. The
+/// scheduler will automatically flatten any recursive scheduling into iteration
+/// instead, so this can be used without issue for blocks that may keep invoking
+/// themselves forever.
+///
+/// Scheduled blocks will be executed in the order in which they were scheduled.
+///
+/// recursiveBlock - The block to schedule for execution. When invoked, the
+///                  recursive block will be passed a `void (^)(void)` block
+///                  which will reschedule the recursive block at the end of the
+///                  receiver's queue. This passed-in block will automatically
+///                  skip scheduling if the scheduling of the `recursiveBlock`
+///                  was disposed in the meantime.
+///
+/// Returns a disposable which can be used to cancel the scheduled block before
+/// it begins executing, or to stop it from rescheduling if it's already begun
+/// execution.
+- (RACDisposable *)scheduleRecursiveBlock:(RACSchedulerRecursiveBlock)recursiveBlock;
+
+@end
+
+@interface RACScheduler (Deprecated)
+
++ (RACScheduler *)schedulerWithQueue:(dispatch_queue_t)queue name:(NSString *)name __attribute__((deprecated("Use -[RACScheduler initWithName:targetQueue:] instead.")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.m
new file mode 100644
index 0000000..c829896
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACScheduler.m
@@ -0,0 +1,206 @@
+//
+//  RACScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/16/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+#import "RACBacktrace.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACImmediateScheduler.h"
+#import "RACScheduler+Private.h"
+#import "RACSubscriptionScheduler.h"
+#import "RACTargetQueueScheduler.h"
+
+// The key for the thread-specific current scheduler.
+NSString * const RACSchedulerCurrentSchedulerKey = @"RACSchedulerCurrentSchedulerKey";
+
+@interface RACScheduler ()
+@property (nonatomic, readonly, copy) NSString *name;
+@end
+
+@implementation RACScheduler
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, self.name];
+}
+
+#pragma mark Initializers
+
+- (id)initWithName:(NSString *)name {
+	self = [super init];
+	if (self == nil) return nil;
+
+	if (name == nil) {
+		_name = [NSString stringWithFormat:@"com.ReactiveCocoa.%@.anonymousScheduler", self.class];
+	} else {
+		_name = [name copy];
+	}
+
+	return self;
+}
+
+#pragma mark Schedulers
+
++ (instancetype)immediateScheduler {
+	static dispatch_once_t onceToken;
+	static RACScheduler *immediateScheduler;
+	dispatch_once(&onceToken, ^{
+		immediateScheduler = [[RACImmediateScheduler alloc] init];
+	});
+	
+	return immediateScheduler;
+}
+
++ (instancetype)mainThreadScheduler {
+	static dispatch_once_t onceToken;
+	static RACScheduler *mainThreadScheduler;
+	dispatch_once(&onceToken, ^{
+		mainThreadScheduler = [[RACTargetQueueScheduler alloc] initWithName:@"com.ReactiveCocoa.RACScheduler.mainThreadScheduler" targetQueue:dispatch_get_main_queue()];
+	});
+	
+	return mainThreadScheduler;
+}
+
++ (instancetype)schedulerWithPriority:(RACSchedulerPriority)priority name:(NSString *)name {
+	return [[RACTargetQueueScheduler alloc] initWithName:name targetQueue:dispatch_get_global_queue(priority, 0)];
+}
+
++ (instancetype)schedulerWithPriority:(RACSchedulerPriority)priority {
+	return [self schedulerWithPriority:priority name:@"com.ReactiveCocoa.RACScheduler.backgroundScheduler"];
+}
+
++ (instancetype)scheduler {
+	return [self schedulerWithPriority:RACSchedulerPriorityDefault];
+}
+
++ (instancetype)subscriptionScheduler {
+	static dispatch_once_t onceToken;
+	static RACScheduler *subscriptionScheduler;
+	dispatch_once(&onceToken, ^{
+		subscriptionScheduler = [[RACSubscriptionScheduler alloc] init];
+	});
+
+	return subscriptionScheduler;
+}
+
++ (BOOL)isOnMainThread {
+	return [NSOperationQueue.currentQueue isEqual:NSOperationQueue.mainQueue] || [NSThread isMainThread];
+}
+
++ (instancetype)currentScheduler {
+	RACScheduler *scheduler = NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey];
+	if (scheduler != nil) return scheduler;
+	if ([self.class isOnMainThread]) return RACScheduler.mainThreadScheduler;
+
+	return nil;
+}
+
+#pragma mark Scheduling
+
+- (RACDisposable *)schedule:(void (^)(void))block {
+	NSCAssert(NO, @"%@ must be implemented by subclasses.", NSStringFromSelector(_cmd));
+	return nil;
+}
+
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
+	NSCAssert(NO, @"%@ must be implemented by subclasses.", NSStringFromSelector(_cmd));
+	return nil;
+}
+
+- (RACDisposable *)afterDelay:(NSTimeInterval)delay schedule:(void (^)(void))block {
+	return [self after:[NSDate dateWithTimeIntervalSinceNow:delay] schedule:block];
+}
+
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
+	NSCAssert(NO, @"%@ must be implemented by subclasses.", NSStringFromSelector(_cmd));
+	return nil;
+}
+
+- (RACDisposable *)scheduleRecursiveBlock:(RACSchedulerRecursiveBlock)recursiveBlock {
+	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+	[self scheduleRecursiveBlock:[recursiveBlock copy] addingToDisposable:disposable];
+	return disposable;
+}
+
+- (void)scheduleRecursiveBlock:(RACSchedulerRecursiveBlock)recursiveBlock addingToDisposable:(RACCompoundDisposable *)disposable {
+	@autoreleasepool {
+		RACCompoundDisposable *selfDisposable = [RACCompoundDisposable compoundDisposable];
+		[disposable addDisposable:selfDisposable];
+
+		__weak RACDisposable *weakSelfDisposable = selfDisposable;
+
+		RACDisposable *schedulingDisposable = [self schedule:^{
+			@autoreleasepool {
+				// At this point, we've been invoked, so our disposable is now useless.
+				[disposable removeDisposable:weakSelfDisposable];
+			}
+
+			if (disposable.disposed) return;
+
+			void (^reallyReschedule)(void) = ^{
+				if (disposable.disposed) return;
+				[self scheduleRecursiveBlock:recursiveBlock addingToDisposable:disposable];
+			};
+
+			// Protects the variables below.
+			//
+			// This doesn't actually need to be __block qualified, but Clang
+			// complains otherwise. :C
+			__block NSLock *lock = [[NSLock alloc] init];
+			lock.name = [NSString stringWithFormat:@"%@ %s", self, sel_getName(_cmd)];
+
+			__block NSUInteger rescheduleCount = 0;
+
+			// Set to YES once synchronous execution has finished. Further
+			// rescheduling should occur immediately (rather than being
+			// flattened).
+			__block BOOL rescheduleImmediately = NO;
+
+			@autoreleasepool {
+				recursiveBlock(^{
+					[lock lock];
+					BOOL immediate = rescheduleImmediately;
+					if (!immediate) ++rescheduleCount;
+					[lock unlock];
+
+					if (immediate) reallyReschedule();
+				});
+			}
+
+			[lock lock];
+			NSUInteger synchronousCount = rescheduleCount;
+			rescheduleImmediately = YES;
+			[lock unlock];
+
+			for (NSUInteger i = 0; i < synchronousCount; i++) {
+				reallyReschedule();
+			}
+		}];
+
+		[selfDisposable addDisposable:schedulingDisposable];
+	}
+}
+
+@end
+
+@implementation RACScheduler (Deprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
++ (instancetype)schedulerWithQueue:(dispatch_queue_t)queue name:(NSString *)name {
+	NSCParameterAssert(queue != NULL);
+
+	return [[RACTargetQueueScheduler alloc] initWithName:name targetQueue:queue];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.h b/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.h
new file mode 100644
index 0000000..03da6a2
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.h
@@ -0,0 +1,19 @@
+//
+//  RACScopedDisposable.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/28/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDisposable.h"
+
+
+/// A disposable that calls its own -dispose when it is dealloc'd.
+@interface RACScopedDisposable : RACDisposable
+
+/// Creates a new scoped disposable that will also dispose of the given
+/// disposable when it is dealloc'd.
++ (instancetype)scopedDisposableWithDisposable:(RACDisposable *)disposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.m b/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.m
new file mode 100644
index 0000000..91115be
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACScopedDisposable.m
@@ -0,0 +1,32 @@
+//
+//  RACScopedDisposable.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/28/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScopedDisposable.h"
+
+@implementation RACScopedDisposable
+
+#pragma mark Lifecycle
+
++ (instancetype)scopedDisposableWithDisposable:(RACDisposable *)disposable {
+	return [self disposableWithBlock:^{
+		[disposable dispose];
+	}];
+}
+
+- (void)dealloc {
+	[self dispose];
+}
+
+#pragma mark RACDisposable
+
+- (RACScopedDisposable *)asScopedDisposable {
+	// totally already are
+	return self;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.h
new file mode 100644
index 0000000..a39f840
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.h
@@ -0,0 +1,154 @@
+//
+//  RACSequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACStream.h"
+
+@class RACScheduler;
+@class RACSignal;
+
+/// Represents an immutable sequence of values. Unless otherwise specified, the
+/// sequences' values are evaluated lazily on demand. Like Cocoa collections,
+/// sequences cannot contain nil.
+///
+/// Most inherited RACStream methods that accept a block will execute the block
+/// _at most_ once for each value that is evaluated in the returned sequence.
+/// Side effects are subject to the behavior described in
+/// +sequenceWithHeadBlock:tailBlock:.
+///
+/// Implemented as a class cluster. A minimal implementation for a subclass
+/// consists simply of -head and -tail.
+@interface RACSequence : RACStream <NSCoding, NSCopying, NSFastEnumeration>
+
+/// The first object in the sequence, or nil if the sequence is empty.
+///
+/// Subclasses must provide an implementation of this method.
+@property (nonatomic, strong, readonly) id head;
+
+/// All but the first object in the sequence, or nil if the sequence is empty.
+///
+/// Subclasses must provide an implementation of this method.
+@property (nonatomic, strong, readonly) RACSequence *tail;
+
+/// Evaluates the full sequence to produce an equivalently-sized array.
+@property (nonatomic, copy, readonly) NSArray *array;
+
+/// Returns an enumerator of all objects in the sequence.
+@property (nonatomic, copy, readonly) NSEnumerator *objectEnumerator;
+
+/// Converts a sequence into an eager sequence.
+///
+/// An eager sequence fully evaluates all of its values immediately. Sequences
+/// derived from an eager sequence will also be eager.
+///
+/// Returns a new eager sequence, or the receiver if the sequence is already
+/// eager.
+@property (nonatomic, copy, readonly) RACSequence *eagerSequence;
+
+/// Converts a sequence into a lazy sequence.
+///
+/// A lazy sequence evaluates its values on demand, as they are accessed.
+/// Sequences derived from a lazy sequence will also be lazy.
+///
+/// Returns a new lazy sequence, or the receiver if the sequence is already lazy.
+@property (nonatomic, copy, readonly) RACSequence *lazySequence;
+
+/// Invokes -signalWithScheduler: with a new RACScheduler.
+- (RACSignal *)signal;
+
+/// Evaluates the full sequence on the given scheduler.
+///
+/// Each item is evaluated in its own scheduled block, such that control of the
+/// scheduler is yielded between each value.
+///
+/// Returns a signal which sends the receiver's values on the given scheduler as
+/// they're evaluated.
+- (RACSignal *)signalWithScheduler:(RACScheduler *)scheduler;
+
+/// Applies a left fold to the sequence.
+///
+/// This is the same as iterating the sequence along with a provided start value.
+/// This uses a constant amount of memory. A left fold is left-associative so in
+/// the sequence [1,2,3] the block would applied in the following order:
+///  reduce(reduce(reduce(start, 1), 2), 3)
+///
+/// start  - The starting value for the fold. Used as `accumulator` for the
+///          first fold.
+/// reduce - The block used to combine the accumulated value and the next value.
+///          Cannot be nil.
+///
+/// Returns a reduced value.
+- (id)foldLeftWithStart:(id)start reduce:(id (^)(id accumulator, id value))reduce;
+
+/// Applies a right fold to the sequence.
+///
+/// A right fold is equivalent to recursion on the list. The block is evaluated
+/// from the right to the left in list. It is right associative so it's applied
+/// to the rightmost elements first. For example, in the sequence [1,2,3] the
+/// block is applied in the order:
+///   reduce(1, reduce(2, reduce(3, start)))
+///
+/// start  - The starting value for the fold.
+/// reduce - The block used to combine the accumulated value and the next head.
+///          The block is given the accumulated value and the value of the rest
+///          of the computation (result of the recursion). This is computed when
+///          you retrieve its value using `rest.head`. This allows you to
+///          prevent unnecessary computation by not accessing `rest.head` if you
+///          don't need to.
+///
+/// Returns a reduced value.
+- (id)foldRightWithStart:(id)start reduce:(id (^)(id first, RACSequence *rest))reduce;
+
+/// Check if any value in sequence passes the block.
+///
+/// block - The block predicate used to check each item. Cannot be nil.
+///
+/// Returns a boolean indiciating if any value in the sequence passed.
+- (BOOL)any:(BOOL (^)(id value))block;
+
+/// Check if all values in the sequence pass the block.
+///
+/// block - The block predicate used to check each item. Cannot be nil.
+///
+/// Returns a boolean indicating if all values in the sequence passed.
+- (BOOL)all:(BOOL (^)(id value))block;
+
+/// Returns the first object that passes the block.
+///
+/// block - The block predicate used to check each item. Cannot be nil.
+///
+/// Returns an object that passes the block or nil if no objects passed.
+- (id)objectPassingTest:(BOOL (^)(id value))block;
+
+/// Creates a sequence that dynamically generates its values.
+///
+/// headBlock - Invoked the first time -head is accessed.
+/// tailBlock - Invoked the first time -tail is accessed.
+///
+/// The results from each block are memoized, so each block will be invoked at
+/// most once, no matter how many times the head and tail properties of the
+/// sequence are accessed.
+///
+/// Any side effects in `headBlock` or `tailBlock` should be thread-safe, since
+/// the sequence may be evaluated at any time from any thread. Not only that, but
+/// -tail may be accessed before -head, or both may be accessed simultaneously.
+/// As noted above, side effects will only be triggered the _first_ time -head or
+/// -tail is invoked.
+///
+/// Returns a sequence that lazily invokes the given blocks to provide head and
+/// tail. `headBlock` must not be nil.
++ (RACSequence *)sequenceWithHeadBlock:(id (^)(void))headBlock tailBlock:(RACSequence *(^)(void))tailBlock;
+
+@end
+
+@interface RACSequence (Deprecated)
+
+- (id)foldLeftWithStart:(id)start combine:(id (^)(id accumulator, id value))combine __attribute__((deprecated("Renamed to -foldLeftWithStart:reduce:")));
+- (id)foldRightWithStart:(id)start combine:(id (^)(id first, RACSequence *rest))combine __attribute__((deprecated("Renamed to -foldRightWithStart:reduce:")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.m
new file mode 100644
index 0000000..9567ea8
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSequence.m
@@ -0,0 +1,384 @@
+//
+//  RACSequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACSequence.h"
+#import "RACArraySequence.h"
+#import "RACDynamicSequence.h"
+#import "RACEagerSequence.h"
+#import "RACEmptySequence.h"
+#import "RACScheduler.h"
+#import "RACSignal.h"
+#import "RACSubscriber.h"
+#import "RACTuple.h"
+#import "RACUnarySequence.h"
+
+// An enumerator over sequences.
+@interface RACSequenceEnumerator : NSEnumerator
+
+// The sequence the enumerator is enumerating.
+//
+// This will change as the enumerator is exhausted. This property should only be
+// accessed while synchronized on self.
+@property (nonatomic, strong) RACSequence *sequence;
+
+@end
+
+@interface RACSequence ()
+
+// Performs one iteration of lazy binding, passing through values from `current`
+// until the sequence is exhausted, then recursively binding the remaining
+// values in the receiver.
+//
+// Returns a new sequence which contains `current`, followed by the combined
+// result of all applications of `block` to the remaining values in the receiver.
+- (instancetype)bind:(RACStreamBindBlock)block passingThroughValuesFromSequence:(RACSequence *)current;
+
+@end
+
+@implementation RACSequenceEnumerator
+
+- (id)nextObject {
+	id object = nil;
+	
+	@synchronized (self) {
+		object = self.sequence.head;
+		self.sequence = self.sequence.tail;
+	}
+	
+	return object;
+}
+
+@end
+
+@implementation RACSequence
+
+#pragma mark Lifecycle
+
++ (RACSequence *)sequenceWithHeadBlock:(id (^)(void))headBlock tailBlock:(RACSequence *(^)(void))tailBlock {
+	return [[RACDynamicSequence sequenceWithHeadBlock:headBlock tailBlock:tailBlock] setNameWithFormat:@"+sequenceWithHeadBlock:tailBlock:"];
+}
+
+#pragma mark Class cluster primitives
+
+- (id)head {
+	NSCAssert(NO, @"%s must be overridden by subclasses", __func__);
+	return nil;
+}
+
+- (RACSequence *)tail {
+	NSCAssert(NO, @"%s must be overridden by subclasses", __func__);
+	return nil;
+}
+
+#pragma mark RACStream
+
++ (instancetype)empty {
+	return RACEmptySequence.empty;
+}
+
++ (instancetype)return:(id)value {
+	return [RACUnarySequence return:value];
+}
+
+- (instancetype)bind:(RACStreamBindBlock (^)(void))block {
+	RACStreamBindBlock bindBlock = block();
+	return [[self bind:bindBlock passingThroughValuesFromSequence:nil] setNameWithFormat:@"[%@] -bind:", self.name];
+}
+
+- (instancetype)bind:(RACStreamBindBlock)bindBlock passingThroughValuesFromSequence:(RACSequence *)passthroughSequence {
+	// Store values calculated in the dependency here instead, avoiding any kind
+	// of temporary collection and boxing.
+	//
+	// This relies on the implementation of RACDynamicSequence synchronizing
+	// access to its head, tail, and dependency, and we're only doing it because
+	// we really need the performance.
+	__block RACSequence *valuesSeq = self;
+	__block RACSequence *current = passthroughSequence;
+	__block BOOL stop = NO;
+
+	RACSequence *sequence = [RACDynamicSequence sequenceWithLazyDependency:^ id {
+		while (current.head == nil) {
+			if (stop) return nil;
+
+			// We've exhausted the current sequence, create a sequence from the
+			// next value.
+			id value = valuesSeq.head;
+
+			if (value == nil) {
+				// We've exhausted all the sequences.
+				stop = YES;
+				return nil;
+			}
+
+			current = (id)bindBlock(value, &stop);
+			if (current == nil) {
+				stop = YES;
+				return nil;
+			}
+
+			valuesSeq = valuesSeq.tail;
+		}
+
+		NSCAssert([current isKindOfClass:RACSequence.class], @"-bind: block returned an object that is not a sequence: %@", current);
+		return nil;
+	} headBlock:^(id _) {
+		return current.head;
+	} tailBlock:^ id (id _) {
+		if (stop) return nil;
+
+		return [valuesSeq bind:bindBlock passingThroughValuesFromSequence:current.tail];
+	}];
+
+	sequence.name = self.name;
+	return sequence;
+}
+
+- (instancetype)concat:(RACStream *)stream {
+	NSCParameterAssert(stream != nil);
+
+	return [[[RACArraySequence sequenceWithArray:@[ self, stream ] offset:0]
+		flatten]
+		setNameWithFormat:@"[%@] -concat: %@", self.name, stream];
+}
+
+- (instancetype)zipWith:(RACSequence *)sequence {
+	NSCParameterAssert(sequence != nil);
+
+	return [[RACSequence
+		sequenceWithHeadBlock:^ id {
+			if (self.head == nil || sequence.head == nil) return nil;
+			return RACTuplePack(self.head, sequence.head);
+		} tailBlock:^ id {
+			if (self.tail == nil || [[RACSequence empty] isEqual:self.tail]) return nil;
+			if (sequence.tail == nil || [[RACSequence empty] isEqual:sequence.tail]) return nil;
+
+			return [self.tail zipWith:sequence.tail];
+		}]
+		setNameWithFormat:@"[%@] -zipWith: %@", self.name, sequence];
+}
+
+#pragma mark Extended methods
+
+- (NSArray *)array {
+	NSMutableArray *array = [NSMutableArray array];
+	for (id obj in self) {
+		[array addObject:obj];
+	}
+
+	return [array copy];
+}
+
+- (NSEnumerator *)objectEnumerator {
+	RACSequenceEnumerator *enumerator = [[RACSequenceEnumerator alloc] init];
+	enumerator.sequence = self;
+	return enumerator;
+}
+
+- (RACSignal *)signal {
+	return [[self signalWithScheduler:[RACScheduler scheduler]] setNameWithFormat:@"[%@] -signal", self.name];
+}
+
+- (RACSignal *)signalWithScheduler:(RACScheduler *)scheduler {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		__block RACSequence *sequence = self;
+
+		return [scheduler scheduleRecursiveBlock:^(void (^reschedule)(void)) {
+			if (sequence.head == nil) {
+				[subscriber sendCompleted];
+				return;
+			}
+
+			[subscriber sendNext:sequence.head];
+
+			sequence = sequence.tail;
+			reschedule();
+		}];
+	}] setNameWithFormat:@"[%@] -signalWithScheduler:", self.name];
+}
+
+- (id)foldLeftWithStart:(id)start reduce:(id (^)(id, id))reduce {
+	NSCParameterAssert(reduce != NULL);
+
+	if (self.head == nil) return start;
+	
+	for (id value in self) {
+		start = reduce(start, value);
+	}
+	
+	return start;
+}
+
+- (id)foldRightWithStart:(id)start reduce:(id (^)(id, RACSequence *))reduce {
+	NSCParameterAssert(reduce != NULL);
+
+	if (self.head == nil) return start;
+	
+	RACSequence *rest = [RACSequence sequenceWithHeadBlock:^{
+		return [self.tail foldRightWithStart:start reduce:reduce];
+	} tailBlock:nil];
+	
+	return reduce(self.head, rest);
+}
+
+- (BOOL)any:(BOOL (^)(id))block {
+	NSCParameterAssert(block != NULL);
+
+	return [self objectPassingTest:block] != nil;
+}
+
+- (BOOL)all:(BOOL (^)(id))block {
+	NSCParameterAssert(block != NULL);
+	
+	NSNumber *result = [self foldLeftWithStart:@YES reduce:^(NSNumber *accumulator, id value) {
+		return @(accumulator.boolValue && block(value));
+	}];
+	
+	return result.boolValue;
+}
+
+- (id)objectPassingTest:(BOOL (^)(id))block {
+	NSCParameterAssert(block != NULL);
+
+	return [self filter:block].head;
+}
+
+- (RACSequence *)eagerSequence {
+	return [RACEagerSequence sequenceWithArray:self.array offset:0];
+}
+
+- (RACSequence *)lazySequence {
+	return self;
+}
+
+#pragma mark NSCopying
+
+- (id)copyWithZone:(NSZone *)zone {
+	return self;
+}
+
+#pragma mark NSCoding
+
+- (Class)classForCoder {
+	// Most sequences should be archived as RACArraySequences.
+	return RACArraySequence.class;
+}
+
+- (id)initWithCoder:(NSCoder *)coder {
+	if (![self isKindOfClass:RACArraySequence.class]) return [[RACArraySequence alloc] initWithCoder:coder];
+
+	// Decoding is handled in RACArraySequence.
+	return [super init];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+	[coder encodeObject:self.array forKey:@"array"];
+}
+
+#pragma mark NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id *)stackbuf count:(NSUInteger)len {
+	if (state->state == ULONG_MAX) {
+		// Enumeration has completed.
+		return 0;
+	}
+
+	// We need to traverse the sequence itself on repeated calls to this
+	// method, so use the 'state' field to track the current head.
+	RACSequence *(^getSequence)(void) = ^{
+		return (__bridge RACSequence *)(void *)state->state;
+	};
+
+	void (^setSequence)(RACSequence *) = ^(RACSequence *sequence) {
+		// Release the old sequence and retain the new one.
+		CFBridgingRelease((void *)state->state);
+
+		state->state = (unsigned long)CFBridgingRetain(sequence);
+	};
+
+	void (^complete)(void) = ^{
+		// Release any stored sequence.
+		setSequence(nil);
+		state->state = ULONG_MAX;
+	};
+
+	if (state->state == 0) {
+		// Since a sequence doesn't mutate, this just needs to be set to
+		// something non-NULL.
+		state->mutationsPtr = state->extra;
+
+		setSequence(self);
+	}
+
+	state->itemsPtr = stackbuf;
+
+	NSUInteger enumeratedCount = 0;
+	while (enumeratedCount < len) {
+		RACSequence *seq = getSequence();
+
+		// Because the objects in a sequence may be generated lazily, we want to
+		// prevent them from being released until the enumerator's used them.
+		__autoreleasing id obj = seq.head;
+		if (obj == nil) {
+			complete();
+			break;
+		}
+
+		stackbuf[enumeratedCount++] = obj;
+
+		if (seq.tail == nil) {
+			complete();
+			break;
+		}
+
+		setSequence(seq.tail);
+	}
+
+	return enumeratedCount;
+}
+
+#pragma mark NSObject
+
+- (NSUInteger)hash {
+	return [self.head hash];
+}
+
+- (BOOL)isEqual:(RACSequence *)seq {
+	if (self == seq) return YES;
+	if (![seq isKindOfClass:RACSequence.class]) return NO;
+
+	for (id<NSObject> selfObj in self) {
+		id<NSObject> seqObj = seq.head;
+
+		// Handles the nil case too.
+		if (![seqObj isEqual:selfObj]) return NO;
+
+		seq = seq.tail;
+	}
+
+	// self is now depleted -- the argument should be too.
+	return (seq.head == nil);
+}
+
+@end
+
+@implementation RACSequence (Deprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (id)foldLeftWithStart:(id)start combine:(id (^)(id accumulator, id value))combine {
+	return [self foldLeftWithStart:start reduce:combine];
+}
+
+- (id)foldRightWithStart:(id)start combine:(id (^)(id first, RACSequence *rest))combine {
+	return [self foldRightWithStart:start reduce:combine];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.h
new file mode 100644
index 0000000..a3fc1d4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.h
@@ -0,0 +1,43 @@
+//
+//  RACSerialDisposable.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACDisposable.h"
+
+/// A disposable that contains exactly one other disposable and allows it to be
+/// swapped out atomically.
+@interface RACSerialDisposable : RACDisposable
+
+/// The inner disposable managed by the serial disposable.
+///
+/// This property is thread-safe for reading and writing. However, if you want to
+/// read the current value _and_ write a new one atomically, use
+/// -swapInDisposable: instead.
+///
+/// Disposing of the receiver will also dispose of the current disposable set for
+/// this property, then set the property to nil. If any new disposable is set
+/// after the receiver is disposed, it will be disposed immediately and this
+/// property will remain set to nil.
+@property (atomic, strong) RACDisposable *disposable;
+
+/// Creates a serial disposable which will wrap the given disposable.
+///
+/// disposable - The value to set for `disposable`. This may be nil.
+///
+/// Returns a RACSerialDisposable, or nil if an error occurs.
++ (instancetype)serialDisposableWithDisposable:(RACDisposable *)disposable;
+
+/// Atomically swaps the receiver's `disposable` for `newDisposable`.
+///
+/// newDisposable - The new value for `disposable`. If the receiver has already
+///                 been disposed, this disposable will be too, and `disposable`
+///                 will remain set to nil. This argument may be nil.
+///
+/// Returns the previous value for the `disposable` property.
+- (RACDisposable *)swapInDisposable:(RACDisposable *)newDisposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.m
new file mode 100644
index 0000000..975afbf
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSerialDisposable.m
@@ -0,0 +1,133 @@
+//
+//  RACSerialDisposable.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSerialDisposable.h"
+#import <libkern/OSAtomic.h>
+
+@interface RACSerialDisposable () {
+	// A reference to the receiver's `disposable`. This variable must only be
+	// modified atomically.
+	//
+	// If this is `self`, no `disposable` has been set, but the receiver has not
+	// been disposed of yet. `self` is never stored retained.
+	//
+	// If this is `nil`, the receiver has been disposed.
+	//
+	// Otherwise, this is a retained reference to the inner disposable and the
+	// receiver has not been disposed of yet.
+	void * volatile _disposablePtr;
+}
+
+@end
+
+@implementation RACSerialDisposable
+
+#pragma mark Properties
+
+- (BOOL)isDisposed {
+	return _disposablePtr == nil;
+}
+
+- (RACDisposable *)disposable {
+	RACDisposable *disposable = (__bridge id)_disposablePtr;
+	return (disposable == self ? nil : disposable);
+}
+
+- (void)setDisposable:(RACDisposable *)disposable {
+	[self swapInDisposable:disposable];
+}
+
+#pragma mark Lifecycle
+
++ (instancetype)serialDisposableWithDisposable:(RACDisposable *)disposable {
+	RACSerialDisposable *serialDisposable = [[self alloc] init];
+	serialDisposable.disposable = disposable;
+	return serialDisposable;
+}
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	_disposablePtr = (__bridge void *)self;
+	OSMemoryBarrier();
+
+	return self;
+}
+
+- (id)initWithBlock:(void (^)(void))block {
+	self = [self init];
+	if (self == nil) return nil;
+
+	self.disposable = [RACDisposable disposableWithBlock:block];
+
+	return self;
+}
+
+- (void)dealloc {
+	self.disposable = nil;
+}
+
+#pragma mark Inner Disposable
+
+- (RACDisposable *)swapInDisposable:(RACDisposable *)newDisposable {
+	void * const selfPtr = (__bridge void *)self;
+
+	// Only retain the new disposable if it's not `self`.
+	// Take ownership before attempting the swap so that a subsequent swap
+	// receives an owned reference.
+	void *newDisposablePtr = selfPtr;
+	if (newDisposable != nil) {
+		newDisposablePtr = (void *)CFBridgingRetain(newDisposable);
+	}
+
+	void *existingDisposablePtr;
+	// Keep trying while we're not disposed.
+	while ((existingDisposablePtr = _disposablePtr) != NULL) {
+		if (!OSAtomicCompareAndSwapPtrBarrier(existingDisposablePtr, newDisposablePtr, &_disposablePtr)) {
+			continue;
+		}
+
+		// Return nil if _disposablePtr was set to self. Otherwise, release
+		// the old value and return it as an object.
+		if (existingDisposablePtr == selfPtr) {
+			return nil;
+		} else {
+			return CFBridgingRelease(existingDisposablePtr);
+		}
+	}
+
+	// At this point, we've found out that we were already disposed.
+	[newDisposable dispose];
+
+	// Failed to swap, clean up the ownership we took prior to the swap.
+	if (newDisposable != nil) {
+		CFRelease(newDisposablePtr);
+	}
+
+	return nil;
+}
+
+#pragma mark Disposal
+
+- (void)dispose {
+	void *existingDisposablePtr;
+
+	while ((existingDisposablePtr = _disposablePtr) != NULL) {
+		if (OSAtomicCompareAndSwapPtrBarrier(existingDisposablePtr, NULL, &_disposablePtr)) {
+			if (existingDisposablePtr != (__bridge void *)self) {
+				RACDisposable *existingDisposable = CFBridgingRelease(existingDisposablePtr);
+				[existingDisposable dispose];
+			}
+
+			break;
+		}
+	}
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.h
new file mode 100644
index 0000000..53b10d6
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.h
@@ -0,0 +1,625 @@
+//
+//  RACSignal+Operations.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-09-06.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACSignal.h"
+
+/// The domain for errors originating in RACSignal operations.
+extern NSString * const RACSignalErrorDomain;
+
+/// The error code used with -timeout:.
+extern const NSInteger RACSignalErrorTimedOut;
+
+/// The error code used when a value passed into +switch:cases:default: does not
+/// match any of the cases, and no default was given.
+extern const NSInteger RACSignalErrorNoMatchingCase;
+
+@class RACMulticastConnection;
+@class RACDisposable;
+@class RACScheduler;
+@class RACSequence;
+@class RACSubject;
+@class RACTuple;
+@class RACCommand;
+@protocol RACSubscriber;
+
+@interface RACSignal (Operations)
+
+/// Do the given block on `next`. This should be used to inject side effects into
+/// the signal.
+- (RACSignal *)doNext:(void (^)(id x))block;
+
+/// Do the given block on `error`. This should be used to inject side effects
+/// into the signal.
+- (RACSignal *)doError:(void (^)(NSError *error))block;
+
+/// Do the given block on `completed`. This should be used to inject side effects
+/// into the signal.
+- (RACSignal *)doCompleted:(void (^)(void))block;
+
+/// Send `next`s only if we don't receive another `next` in `interval` seconds.
+///
+/// If a `next` is received, and then another `next` is received before
+/// `interval` seconds have passed, the first value is discarded.
+///
+/// After `interval` seconds have passed since the most recent `next` was sent,
+/// the most recent `next` is forwarded on the scheduler that the value was
+/// originally received on. If +[RACScheduler currentScheduler] was nil at the
+/// time, a private background scheduler is used.
+///
+/// Returns a signal which sends throttled and delayed `next` events. Completion
+/// and errors are always forwarded immediately.
+- (RACSignal *)throttle:(NSTimeInterval)interval;
+
+/// Throttles `next`s for which `predicate` returns YES.
+///
+/// When `predicate` returns YES for a `next`:
+///
+///  1. If another `next` is received before `interval` seconds have passed, the
+///     prior value is discarded. This happens regardless of whether the new
+///     value will be throttled.
+///  2. After `interval` seconds have passed since the value was originally
+///     received, it will be forwarded on the scheduler that it was received
+///     upon. If +[RACScheduler currentScheduler] was nil at the time, a private
+///     background scheduler is used.
+///
+/// When `predicate` returns NO for a `next`, it is forwarded immediately,
+/// without any throttling.
+///
+/// interval  - The number of seconds for which to buffer the latest value that
+///             passes `predicate`.
+/// predicate - Passed each `next` from the receiver, this block returns
+///             whether the given value should be throttled. This argument must
+///             not be nil.
+///
+/// Returns a signal which sends `next` events, throttled when `predicate`
+/// returns YES. Completion and errors are always forwarded immediately.
+- (RACSignal *)throttle:(NSTimeInterval)interval valuesPassingTest:(BOOL (^)(id next))predicate;
+
+/// Forwards `next` and `completed` events after delaying for `interval` seconds
+/// on the current scheduler (on which the events were delivered).
+///
+/// If +[RACScheduler currentScheduler] is nil when `next` or `completed` is
+/// received, a private background scheduler is used.
+///
+/// Returns a signal which sends delayed `next` and `completed` events. Errors
+/// are always forwarded immediately.
+- (RACSignal *)delay:(NSTimeInterval)interval;
+
+/// Resubscribes when the signal completes.
+- (RACSignal *)repeat;
+
+/// Execute the given block each time a subscription is created.
+///
+/// block - A block which defines the subscription side effects. Cannot be `nil`.
+///
+/// Example:
+///
+///   // Write new file, with backup.
+///   [[[[fileManager
+///       rac_createFileAtPath:path contents:data]
+///       initially:^{
+///           // 2. Second, backup current file
+///           [fileManager moveItemAtPath:path toPath:backupPath error:nil];
+///       }]
+///       initially:^{
+///           // 1. First, acquire write lock.
+///           [writeLock lock];
+///       }]
+///       finally:^{
+///           [writeLock unlock];
+///       }];
+///
+/// Returns a signal that passes through all events of the receiver, plus
+/// introduces side effects which occur prior to any subscription side effects
+/// of the receiver.
+- (RACSignal *)initially:(void (^)(void))block;
+
+/// Execute the given block when the signal completes or errors.
+- (RACSignal *)finally:(void (^)(void))block;
+
+/// Divides the receiver's `next`s into buffers which deliver every `interval`
+/// seconds.
+///
+/// interval  - The interval in which values are grouped into one buffer.
+/// scheduler - The scheduler upon which the returned signal will deliver its
+///             values. This must not be nil or +[RACScheduler
+///             immediateScheduler].
+///
+/// Returns a signal which sends RACTuples of the buffered values at each
+/// interval on `scheduler`. When the receiver completes, any currently-buffered
+/// values will be sent immediately.
+- (RACSignal *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
+
+/// Collect all receiver's `next`s into a NSArray. nil values will be converted
+/// to NSNull.
+///
+/// This corresponds to the `ToArray` method in Rx.
+///
+/// Returns a signal which sends a single NSArray when the receiver completes
+/// successfully.
+- (RACSignal *)collect;
+
+/// Takes the last `count` `next`s after the receiving signal completes.
+- (RACSignal *)takeLast:(NSUInteger)count;
+
+/// Combines the latest values from the receiver and the given signal into
+/// RACTuples, once both have sent at least one `next`.
+///
+/// Any additional `next`s will result in a new RACTuple with the latest values
+/// from both signals.
+///
+/// signal - The signal to combine with. This argument must not be nil.
+///
+/// Returns a signal which sends RACTuples of the combined values, forwards any
+/// `error` events, and completes when both input signals complete.
+- (RACSignal *)combineLatestWith:(RACSignal *)signal;
+
+/// Combines the latest values from the given signals into RACTuples, once all
+/// the signals have sent at least one `next`.
+///
+/// Any additional `next`s will result in a new RACTuple with the latest values
+/// from all signals.
+///
+/// signals - The signals to combine. If this collection is empty, the returned
+///           signal will immediately complete upon subscription.
+///
+/// Returns a signal which sends RACTuples of the combined values, forwards any
+/// `error` events, and completes when all input signals complete.
++ (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals;
+
+/// Combines signals using +combineLatest:, then reduces the resulting tuples
+/// into a single value using -reduceEach:.
+///
+/// signals     - The signals to combine. If this collection is empty, the
+///               returned signal will immediately complete upon subscription.
+/// reduceBlock - The block which reduces the latest values from all the
+///               signals into one value. It must take as many arguments as the
+///               number of signals given. Each argument will be an object
+///               argument. The return value must be an object. This argument
+///               must not be nil.
+///
+/// Example:
+///
+///   [RACSignal combineLatest:@[ stringSignal, intSignal ] reduce:^(NSString *string, NSNumber *number) {
+///       return [NSString stringWithFormat:@"%@: %@", string, number];
+///   }];
+///
+/// Returns a signal which sends the results from each invocation of
+/// `reduceBlock`.
++ (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock;
+
+/// Merges the receiver and the given signal with `+merge:` and returns the
+/// resulting signal.
+- (RACSignal *)merge:(RACSignal *)signal;
+
+/// Sends the latest `next` from any of the signals.
+///
+/// Returns a signal that passes through values from each of the given signals,
+/// and sends `completed` when all of them complete. If any signal sends an error,
+/// the returned signal sends `error` immediately.
++ (RACSignal *)merge:(id<NSFastEnumeration>)signals;
+
+/// Merges the signals sent by the receiver into a flattened signal, but only
+/// subscribes to `maxConcurrent` number of signals at a time. New signals are
+/// queued and subscribed to as other signals complete.
+///
+/// If an error occurs on any of the signals, it is sent on the returned signal.
+/// It completes only after the receiver and all sent signals have completed.
+///
+/// This corresponds to `Merge<TSource>(IObservable<IObservable<TSource>>, Int32)`
+/// in Rx.
+///
+/// maxConcurrent - the maximum number of signals to subscribe to at a
+///                 time. If 0, it subscribes to an unlimited number of
+///                 signals.
+- (RACSignal *)flatten:(NSUInteger)maxConcurrent;
+
+/// Ignores all `next`s from the receiver, waits for the receiver to complete,
+/// then subscribes to a new signal.
+///
+/// block - A block which will create or obtain a new signal to subscribe to,
+///         executed only after the receiver completes. This block must not be
+///         nil, and it must not return a nil signal.
+///
+/// Returns a signal which will pass through the events of the signal created in
+/// `block`. If the receiver errors out, the returned signal will error as well.
+- (RACSignal *)then:(RACSignal * (^)(void))block;
+
+/// Concats the inner signals of a signal of signals.
+- (RACSignal *)concat;
+
+/// Aggregate `next`s with the given start and combination.
+- (RACSignal *)aggregateWithStart:(id)start reduce:(id (^)(id running, id next))reduceBlock;
+
+/// Aggregate `next`s with the given start and combination. The start factory 
+/// block is called to get a new start object for each subscription.
+- (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory reduce:(id (^)(id running, id next))reduceBlock;
+
+/// Invokes -setKeyPath:onObject:nilValue: with `nil` for the nil value.
+///
+/// WARNING: Under certain conditions, this method is known to be thread-unsafe.
+///          See the description in -setKeyPath:onObject:nilValue:.
+- (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object;
+
+/// Binds the receiver to an object, automatically setting the given key path on
+/// every `next`. When the signal completes, the binding is automatically
+/// disposed of.
+///
+/// WARNING: Under certain conditions, this method is known to be thread-unsafe.
+///          A crash can result if `object` is deallocated concurrently on
+///          another thread within a window of time between a value being sent
+///          on this signal and immediately prior to the invocation of
+///          -setValue:forKeyPath:, which sets the property. To prevent this,
+///          ensure `object` is deallocated on the same thread the receiver
+///          sends on, or ensure that the returned disposable is disposed of
+///          before `object` deallocates.
+///          See https://github.com/ReactiveCocoa/ReactiveCocoa/pull/1184
+///
+/// Sending an error on the signal is considered undefined behavior, and will
+/// generate an assertion failure in Debug builds.
+///
+/// A given key on an object should only have one active signal bound to it at any
+/// given time. Binding more than one signal to the same property is considered
+/// undefined behavior.
+///
+/// keyPath  - The key path to update with `next`s from the receiver.
+/// object   - The object that `keyPath` is relative to.
+/// nilValue - The value to set at the key path whenever `nil` is sent by the
+///            receiver. This may be nil when binding to object properties, but
+///            an NSValue should be used for primitive properties, to avoid an
+///            exception if `nil` is sent (which might occur if an intermediate
+///            object is set to `nil`).
+///
+/// Returns a disposable which can be used to terminate the binding.
+- (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object nilValue:(id)nilValue;
+
+/// Sends NSDate.date every `interval` seconds.
+///
+/// interval  - The time interval in seconds at which the current time is sent.
+/// scheduler - The scheduler upon which the current NSDate should be sent. This
+///             must not be nil or +[RACScheduler immediateScheduler].
+///
+/// Returns a signal that sends the current date/time every `interval` on
+/// `scheduler`.
++ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
+
+/// Sends NSDate.date at intervals of at least `interval` seconds, up to
+/// approximately `interval` + `leeway` seconds.
+///
+/// The created signal will defer sending each `next` for at least `interval`
+/// seconds, and for an additional amount of time up to `leeway` seconds in the
+/// interest of performance or power consumption. Note that some additional
+/// latency is to be expected, even when specifying a `leeway` of 0.
+///
+/// interval  - The base interval between `next`s.
+/// scheduler - The scheduler upon which the current NSDate should be sent. This
+///             must not be nil or +[RACScheduler immediateScheduler].
+/// leeway    - The maximum amount of additional time the `next` can be deferred.
+///
+/// Returns a signal that sends the current date/time at intervals of at least
+/// `interval seconds` up to approximately `interval` + `leeway` seconds on
+/// `scheduler`.
++ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway;
+
+/// Take `next`s until the `signalTrigger` sends `next` or `completed`.
+///
+/// Returns a signal which passes through all events from the receiver until
+/// `signalTrigger` sends `next` or `completed`, at which point the returned signal
+/// will send `completed`.
+- (RACSignal *)takeUntil:(RACSignal *)signalTrigger;
+
+/// Take `next`s until the `replacement` sends an event.
+///
+/// replacement - The signal which replaces the receiver as soon as it sends an
+///               event.
+///
+/// Returns a signal which passes through `next`s and `error` from the receiver
+/// until `replacement` sends an event, at which point the returned signal will
+/// send that event and switch to passing through events from `replacement`
+/// instead, regardless of whether the receiver has sent events already.
+- (RACSignal *)takeUntilReplacement:(RACSignal *)replacement;
+
+/// Subscribe to the returned signal when an error occurs.
+- (RACSignal *)catch:(RACSignal * (^)(NSError *error))catchBlock;
+
+/// Subscribe to the given signal when an error occurs.
+- (RACSignal *)catchTo:(RACSignal *)signal;
+
+/// Runs `tryBlock` against each of the receiver's values, passing values
+/// until `tryBlock` returns NO, or the receiver completes.
+///
+/// tryBlock - An action to run against each of the receiver's values.
+///            The block should return YES to indicate that the action was
+///            successful. This block must not be nil.
+///
+/// Example:
+///
+///   // The returned signal will send an error if data values cannot be
+///   // written to `someFileURL`.
+///   [signal try:^(NSData *data, NSError **errorPtr) {
+///       return [data writeToURL:someFileURL options:NSDataWritingAtomic error:errorPtr];
+///   }];
+///
+/// Returns a signal which passes through all the values of the receiver. If
+/// `tryBlock` fails for any value, the returned signal will error using the
+/// `NSError` passed out from the block.
+- (RACSignal *)try:(BOOL (^)(id value, NSError **errorPtr))tryBlock;
+
+/// Runs `mapBlock` against each of the receiver's values, mapping values until
+/// `mapBlock` returns nil, or the receiver completes.
+///
+/// mapBlock - An action to map each of the receiver's values. The block should
+///            return a non-nil value to indicate that the action was successful.
+///            This block must not be nil.
+///
+/// Example:
+///
+///   // The returned signal will send an error if data cannot be read from
+///   // `fileURL`.
+///   [signal tryMap:^(NSURL *fileURL, NSError **errorPtr) {
+///       return [NSData dataWithContentsOfURL:fileURL options:0 error:errorPtr];
+///   }];
+///
+/// Returns a signal which transforms all the values of the receiver. If
+/// `mapBlock` returns nil for any value, the returned signal will error using
+/// the `NSError` passed out from the block.
+- (RACSignal *)tryMap:(id (^)(id value, NSError **errorPtr))mapBlock;
+
+/// Returns the first `next`. Note that this is a blocking call.
+- (id)first;
+
+/// Returns the first `next` or `defaultValue` if the signal completes or errors
+/// without sending a `next`. Note that this is a blocking call.
+- (id)firstOrDefault:(id)defaultValue;
+
+/// Returns the first `next` or `defaultValue` if the signal completes or errors
+/// without sending a `next`. If an error occurs success will be NO and error
+/// will be populated. Note that this is a blocking call.
+///
+/// Both success and error may be NULL.
+- (id)firstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error;
+
+/// Blocks the caller and waits for the signal to complete.
+///
+/// error - If not NULL, set to any error that occurs.
+///
+/// Returns whether the signal completed successfully. If NO, `error` will be set
+/// to the error that occurred.
+- (BOOL)waitUntilCompleted:(NSError **)error;
+
+/// Defer creation of a signal until the signal's actually subscribed to.
+///
+/// This can be used to effectively turn a hot signal into a cold signal.
++ (RACSignal *)defer:(RACSignal * (^)(void))block;
+
+/// Every time the receiver sends a new RACSignal, subscribes and sends `next`s and
+/// `error`s only for that signal.
+///
+/// The receiver must be a signal of signals.
+///
+/// Returns a signal which passes through `next`s and `error`s from the latest
+/// signal sent by the receiver, and sends `completed` when both the receiver and
+/// the last sent signal complete.
+- (RACSignal *)switchToLatest;
+
+/// Switches between the signals in `cases` as well as `defaultSignal` based on
+/// the latest value sent by `signal`.
+///
+/// signal        - A signal of objects used as keys in the `cases` dictionary.
+///                 This argument must not be nil.
+/// cases         - A dictionary that has signals as values. This argument must
+///                 not be nil. A RACTupleNil key in this dictionary will match
+///                 nil `next` events that are received on `signal`.
+/// defaultSignal - The signal to pass through after `signal` sends a value for
+///                 which `cases` does not contain a signal. If nil, any
+///                 unmatched values will result in
+///                 a RACSignalErrorNoMatchingCase error.
+///
+/// Returns a signal which passes through `next`s and `error`s from one of the
+/// the signals in `cases` or `defaultSignal`, and sends `completed` when both
+/// `signal` and the last used signal complete. If no `defaultSignal` is given,
+/// an unmatched `next` will result in an error on the returned signal.
++ (RACSignal *)switch:(RACSignal *)signal cases:(NSDictionary *)cases default:(RACSignal *)defaultSignal;
+
+/// Switches between `trueSignal` and `falseSignal` based on the latest value
+/// sent by `boolSignal`.
+///
+/// boolSignal  - A signal of BOOLs determining whether `trueSignal` or
+///               `falseSignal` should be active. This argument must not be nil.
+/// trueSignal  - The signal to pass through after `boolSignal` has sent YES.
+///               This argument must not be nil.
+/// falseSignal - The signal to pass through after `boolSignal` has sent NO. This
+///               argument must not be nil.
+///
+/// Returns a signal which passes through `next`s and `error`s from `trueSignal`
+/// and/or `falseSignal`, and sends `completed` when both `boolSignal` and the
+/// last switched signal complete.
++ (RACSignal *)if:(RACSignal *)boolSignal then:(RACSignal *)trueSignal else:(RACSignal *)falseSignal;
+
+/// Add every `next` to an array. Nils are represented by NSNulls. Note that this
+/// is a blocking call.
+///
+/// **This is not the same as the `ToArray` method in Rx.** See -collect for
+/// that behavior instead.
+///
+/// Returns the array of `next` values, or nil if an error occurs.
+- (NSArray *)toArray;
+
+/// Add every `next` to a sequence. Nils are represented by NSNulls.
+///
+/// This corresponds to the `ToEnumerable` method in Rx.
+///
+/// Returns a sequence which provides values from the signal as they're sent.
+/// Trying to retrieve a value from the sequence which has not yet been sent will
+/// block.
+@property (nonatomic, strong, readonly) RACSequence *sequence;
+
+/// Creates and returns a multicast connection. This allows you to share a single
+/// subscription to the underlying signal.
+- (RACMulticastConnection *)publish;
+
+/// Creates and returns a multicast connection that pushes values into the given
+/// subject. This allows you to share a single subscription to the underlying
+/// signal.
+- (RACMulticastConnection *)multicast:(RACSubject *)subject;
+
+/// Multicasts the signal to a RACReplaySubject of unlimited capacity, and
+/// immediately connects to the resulting RACMulticastConnection.
+///
+/// Returns the connected, multicasted signal.
+- (RACSignal *)replay;
+
+/// Multicasts the signal to a RACReplaySubject of capacity 1, and immediately
+/// connects to the resulting RACMulticastConnection.
+///
+/// Returns the connected, multicasted signal.
+- (RACSignal *)replayLast;
+
+/// Multicasts the signal to a RACReplaySubject of unlimited capacity, and
+/// lazily connects to the resulting RACMulticastConnection.
+///
+/// This means the returned signal will subscribe to the multicasted signal only
+/// when the former receives its first subscription.
+///
+/// Returns the lazily connected, multicasted signal.
+- (RACSignal *)replayLazily;
+
+/// Sends an error after `interval` seconds if the source doesn't complete
+/// before then.
+///
+/// The error will be in the RACSignalErrorDomain and have a code of
+/// RACSignalErrorTimedOut.
+///
+/// interval  - The number of seconds after which the signal should error out.
+/// scheduler - The scheduler upon which any timeout error should be sent. This
+///             must not be nil or +[RACScheduler immediateScheduler].
+///
+/// Returns a signal that passes through the receiver's events, until the stream
+/// finishes or times out, at which point an error will be sent on `scheduler`.
+- (RACSignal *)timeout:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
+
+/// Creates and returns a signal that delivers its events on the given scheduler.
+/// Any side effects of the receiver will still be performed on the original
+/// thread.
+///
+/// This is ideal when the signal already performs its work on the desired
+/// thread, but you want to handle its events elsewhere.
+///
+/// This corresponds to the `ObserveOn` method in Rx.
+- (RACSignal *)deliverOn:(RACScheduler *)scheduler;
+
+/// Creates and returns a signal that executes its side effects and delivers its
+/// events on the given scheduler.
+///
+/// Use of this operator should be avoided whenever possible, because the
+/// receiver's side effects may not be safe to run on another thread. If you just
+/// want to receive the signal's events on `scheduler`, use -deliverOn: instead.
+- (RACSignal *)subscribeOn:(RACScheduler *)scheduler;
+
+/// Groups each received object into a group, as determined by calling `keyBlock`
+/// with that object. The object sent is transformed by calling `transformBlock`
+/// with the object. If `transformBlock` is nil, it sends the original object.
+///
+/// The returned signal is a signal of RACGroupedSignal.
+- (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock transform:(id (^)(id object))transformBlock;
+
+/// Calls -[RACSignal groupBy:keyBlock transform:nil].
+- (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock;
+
+/// Sends an [NSNumber numberWithBool:YES] if the receiving signal sends any
+/// objects.
+- (RACSignal *)any;
+
+/// Sends an [NSNumber numberWithBool:YES] if the receiving signal sends any
+/// objects that pass `predicateBlock`.
+///
+/// predicateBlock - cannot be nil.
+- (RACSignal *)any:(BOOL (^)(id object))predicateBlock;
+
+/// Sends an [NSNumber numberWithBool:YES] if all the objects the receiving 
+/// signal sends pass `predicateBlock`.
+///
+/// predicateBlock - cannot be nil.
+- (RACSignal *)all:(BOOL (^)(id object))predicateBlock;
+
+/// Resubscribes to the receiving signal if an error occurs, up until it has
+/// retried the given number of times.
+///
+/// retryCount - if 0, it keeps retrying until it completes.
+- (RACSignal *)retry:(NSInteger)retryCount;
+
+/// Resubscribes to the receiving signal if an error occurs.
+- (RACSignal *)retry;
+
+/// Sends the latest value from the receiver only when `sampler` sends a value.
+/// The returned signal could repeat values if `sampler` fires more often than
+/// the receiver. Values from `sampler` are ignored before the receiver sends
+/// its first value.
+///
+/// sampler - The signal that controls when the latest value from the receiver
+///           is sent. Cannot be nil.
+- (RACSignal *)sample:(RACSignal *)sampler;
+
+/// Ignores all `next`s from the receiver.
+///
+/// Returns a signal which only passes through `error` or `completed` events from
+/// the receiver.
+- (RACSignal *)ignoreValues;
+
+/// Converts each of the receiver's events into a RACEvent object.
+///
+/// Returns a signal which sends the receiver's events as RACEvents, and
+/// completes after the receiver sends `completed` or `error`.
+- (RACSignal *)materialize;
+
+/// Converts each RACEvent in the receiver back into "real" RACSignal events.
+///
+/// Returns a signal which sends `next` for each value RACEvent, `error` for each
+/// error RACEvent, and `completed` for each completed RACEvent.
+- (RACSignal *)dematerialize;
+
+/// Inverts each NSNumber-wrapped BOOL sent by the receiver. It will assert if
+/// the receiver sends anything other than NSNumbers.
+///
+/// Returns a signal of inverted NSNumber-wrapped BOOLs.
+- (RACSignal *)not;
+
+/// Performs a boolean AND on all of the RACTuple of NSNumbers in sent by the receiver.
+///
+/// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers.
+///
+/// Returns a signal that applies AND to each NSNumber in the tuple.
+- (RACSignal *)and;
+
+/// Performs a boolean OR on all of the RACTuple of NSNumbers in sent by the receiver.
+///
+/// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers.
+/// 
+/// Returns a signal that applies OR to each NSNumber in the tuple.
+- (RACSignal *)or;
+
+@end
+
+@interface RACSignal (OperationsDeprecated)
+
+- (RACSignal *)windowWithStart:(RACSignal *)openSignal close:(RACSignal * (^)(RACSignal *start))closeBlock __attribute__((deprecated("See https://github.com/ReactiveCocoa/ReactiveCocoa/issues/587")));
+- (RACSignal *)buffer:(NSUInteger)bufferCount __attribute__((deprecated("See https://github.com/ReactiveCocoa/ReactiveCocoa/issues/587")));
+- (RACSignal *)let:(RACSignal * (^)(RACSignal *sharedSignal))letBlock __attribute__((deprecated("Use -publish instead")));
++ (RACSignal *)interval:(NSTimeInterval)interval __attribute__((deprecated("Use +interval:onScheduler: instead")));
++ (RACSignal *)interval:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway __attribute__((deprecated("Use +interval:onScheduler:withLeeway: instead")));
+- (RACSignal *)bufferWithTime:(NSTimeInterval)interval __attribute__((deprecated("Use -bufferWithTime:onScheduler: instead")));
+- (RACSignal *)timeout:(NSTimeInterval)interval __attribute__((deprecated("Use -timeout:onScheduler: instead")));
+- (RACDisposable *)toProperty:(NSString *)keyPath onObject:(NSObject *)object __attribute__((deprecated("Renamed to -setKeyPath:onObject:")));
+- (RACSignal *)ignoreElements __attribute__((deprecated("Renamed to -ignoreValues")));
+- (RACSignal *)sequenceNext:(RACSignal * (^)(void))block __attribute__((deprecated("Renamed to -then:")));
+- (RACSignal *)aggregateWithStart:(id)start combine:(id (^)(id running, id next))combineBlock __attribute__((deprecated("Renamed to -aggregateWithStart:reduce:")));
+- (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory combine:(id (^)(id running, id next))combineBlock __attribute__((deprecated("Renamed to -aggregateWithStartFactory:reduce:")));
+- (RACDisposable *)executeCommand:(RACCommand *)command __attribute__((deprecated("Use -flattenMap: or -subscribeNext: instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.m
new file mode 100644
index 0000000..6e36dd6
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.m
@@ -0,0 +1,1436 @@
+//
+//  RACSignal+Operations.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-09-06.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal+Operations.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "RACCommand.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACEvent.h"
+#import "RACGroupedSignal.h"
+#import "RACMulticastConnection+Private.h"
+#import "RACReplaySubject.h"
+#import "RACScheduler+Private.h"
+#import "RACScheduler.h"
+#import "RACSerialDisposable.h"
+#import "RACSignalSequence.h"
+#import "RACStream+Private.h"
+#import "RACSubject.h"
+#import "RACSubscriber+Private.h"
+#import "RACSubscriber.h"
+#import "RACTuple.h"
+#import "RACUnit.h"
+#import <libkern/OSAtomic.h>
+#import <objc/runtime.h>
+
+NSString * const RACSignalErrorDomain = @"RACSignalErrorDomain";
+
+const NSInteger RACSignalErrorTimedOut = 1;
+const NSInteger RACSignalErrorNoMatchingCase = 2;
+
+// Subscribes to the given signal with the given blocks.
+//
+// If the signal errors or completes, the corresponding block is invoked. If the
+// disposable passed to the block is _not_ disposed, then the signal is
+// subscribed to again.
+static RACDisposable *subscribeForever (RACSignal *signal, void (^next)(id), void (^error)(NSError *, RACDisposable *), void (^completed)(RACDisposable *)) {
+	next = [next copy];
+	error = [error copy];
+	completed = [completed copy];
+
+	RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
+
+	RACSchedulerRecursiveBlock recursiveBlock = ^(void (^recurse)(void)) {
+		RACCompoundDisposable *selfDisposable = [RACCompoundDisposable compoundDisposable];
+		[compoundDisposable addDisposable:selfDisposable];
+
+		__weak RACDisposable *weakSelfDisposable = selfDisposable;
+
+		RACDisposable *subscriptionDisposable = [signal subscribeNext:next error:^(NSError *e) {
+			@autoreleasepool {
+				error(e, compoundDisposable);
+				[compoundDisposable removeDisposable:weakSelfDisposable];
+			}
+
+			recurse();
+		} completed:^{
+			@autoreleasepool {
+				completed(compoundDisposable);
+				[compoundDisposable removeDisposable:weakSelfDisposable];
+			}
+
+			recurse();
+		}];
+
+		[selfDisposable addDisposable:subscriptionDisposable];
+	};
+	
+	// Subscribe once immediately, and then use recursive scheduling for any
+	// further resubscriptions.
+	recursiveBlock(^{
+		RACScheduler *recursiveScheduler = RACScheduler.currentScheduler ?: [RACScheduler scheduler];
+
+		RACDisposable *schedulingDisposable = [recursiveScheduler scheduleRecursiveBlock:recursiveBlock];
+		[compoundDisposable addDisposable:schedulingDisposable];
+	});
+
+	return compoundDisposable;
+}
+
+@implementation RACSignal (Operations)
+
+- (RACSignal *)doNext:(void (^)(id x))block {
+	NSCParameterAssert(block != NULL);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [self subscribeNext:^(id x) {
+			block(x);
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -doNext:", self.name];
+}
+
+- (RACSignal *)doError:(void (^)(NSError *error))block {
+	NSCParameterAssert(block != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [self subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			block(error);
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -doError:", self.name];
+}
+
+- (RACSignal *)doCompleted:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [self subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			block();
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -doCompleted:", self.name];
+}
+
+- (RACSignal *)throttle:(NSTimeInterval)interval {
+	return [[self throttle:interval valuesPassingTest:^(id _) {
+		return YES;
+	}] setNameWithFormat:@"[%@] -throttle: %f", self.name, (double)interval];
+}
+
+- (RACSignal *)throttle:(NSTimeInterval)interval valuesPassingTest:(BOOL (^)(id next))predicate {
+	NSCParameterAssert(interval >= 0);
+	NSCParameterAssert(predicate != nil);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
+
+		// We may never use this scheduler, but we need to set it up ahead of
+		// time so that our scheduled blocks are run serially if we do.
+		RACScheduler *scheduler = [RACScheduler scheduler];
+
+		// Information about any currently-buffered `next` event.
+		__block id nextValue = nil;
+		__block BOOL hasNextValue = NO;
+		RACSerialDisposable *nextDisposable = [[RACSerialDisposable alloc] init];
+
+		void (^flushNext)(BOOL send) = ^(BOOL send) {
+			@synchronized (compoundDisposable) {
+				[nextDisposable.disposable dispose];
+
+				if (!hasNextValue) return;
+				if (send) [subscriber sendNext:nextValue];
+
+				nextValue = nil;
+				hasNextValue = NO;
+			}
+		};
+
+		RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+			RACScheduler *delayScheduler = RACScheduler.currentScheduler ?: scheduler;
+			BOOL shouldThrottle = predicate(x);
+
+			@synchronized (compoundDisposable) {
+				flushNext(NO);
+				if (!shouldThrottle) {
+					[subscriber sendNext:x];
+					return;
+				}
+
+				nextValue = x;
+				hasNextValue = YES;
+				nextDisposable.disposable = [delayScheduler afterDelay:interval schedule:^{
+					flushNext(YES);
+				}];
+			}
+		} error:^(NSError *error) {
+			[compoundDisposable dispose];
+			[subscriber sendError:error];
+		} completed:^{
+			flushNext(YES);
+			[subscriber sendCompleted];
+		}];
+
+		[compoundDisposable addDisposable:subscriptionDisposable];
+		return compoundDisposable;
+	}] setNameWithFormat:@"[%@] -throttle: %f valuesPassingTest:", self.name, (double)interval];
+}
+
+- (RACSignal *)delay:(NSTimeInterval)interval {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+		// We may never use this scheduler, but we need to set it up ahead of
+		// time so that our scheduled blocks are run serially if we do.
+		RACScheduler *scheduler = [RACScheduler scheduler];
+
+		void (^schedule)(dispatch_block_t) = ^(dispatch_block_t block) {
+			RACScheduler *delayScheduler = RACScheduler.currentScheduler ?: scheduler;
+			RACDisposable *schedulerDisposable = [delayScheduler afterDelay:interval schedule:block];
+			[disposable addDisposable:schedulerDisposable];
+		};
+
+		RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+			schedule(^{
+				[subscriber sendNext:x];
+			});
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			schedule(^{
+				[subscriber sendCompleted];
+			});
+		}];
+
+		[disposable addDisposable:subscriptionDisposable];
+		return disposable;
+	}] setNameWithFormat:@"[%@] -delay: %f", self.name, (double)interval];
+}
+
+- (RACSignal *)repeat {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return subscribeForever(self,
+			^(id x) {
+				[subscriber sendNext:x];
+			},
+			^(NSError *error, RACDisposable *disposable) {
+				[disposable dispose];
+				[subscriber sendError:error];
+			},
+			^(RACDisposable *disposable) {
+				// Resubscribe.
+			});
+	}] setNameWithFormat:@"[%@] -repeat", self.name];
+}
+
+- (RACSignal *)catch:(RACSignal * (^)(NSError *error))catchBlock {
+	NSCParameterAssert(catchBlock != NULL);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACSerialDisposable *catchDisposable = [[RACSerialDisposable alloc] init];
+
+		RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			RACSignal *signal = catchBlock(error);
+			NSCAssert(signal != nil, @"Expected non-nil signal from catch block on %@", self);
+			catchDisposable.disposable = [signal subscribe:subscriber];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[catchDisposable dispose];
+			[subscriptionDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -catch:", self.name];
+}
+
+- (RACSignal *)catchTo:(RACSignal *)signal {
+	return [[self catch:^(NSError *error) {
+		return signal;
+	}] setNameWithFormat:@"[%@] -catchTo: %@", self.name, signal];
+}
+
+- (RACSignal *)try:(BOOL (^)(id value, NSError **errorPtr))tryBlock {
+	NSCParameterAssert(tryBlock != NULL);
+	
+	return [[self flattenMap:^(id value) {
+		NSError *error = nil;
+		BOOL passed = tryBlock(value, &error);
+		return (passed ? [RACSignal return:value] : [RACSignal error:error]);
+	}] setNameWithFormat:@"[%@] -try:", self.name];
+}
+
+- (RACSignal *)tryMap:(id (^)(id value, NSError **errorPtr))mapBlock {
+	NSCParameterAssert(mapBlock != NULL);
+	
+	return [[self flattenMap:^(id value) {
+		NSError *error = nil;
+		id mappedValue = mapBlock(value, &error);
+		return (mappedValue == nil ? [RACSignal error:error] : [RACSignal return:mappedValue]);
+	}] setNameWithFormat:@"[%@] -tryMap:", self.name];
+}
+
+- (RACSignal *)initially:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	return [[RACSignal defer:^{
+		block();
+		return self;
+	}] setNameWithFormat:@"[%@] -initially:", self.name];
+}
+
+- (RACSignal *)finally:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+	
+	return [[[self
+		doError:^(NSError *error) {
+			block();
+		}]
+		doCompleted:^{
+			block();
+		}]
+		setNameWithFormat:@"[%@] -finally:", self.name];
+}
+
+- (RACSignal *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler {
+	NSCParameterAssert(scheduler != nil);
+	NSCParameterAssert(scheduler != RACScheduler.immediateScheduler);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACSerialDisposable *timerDisposable = [[RACSerialDisposable alloc] init];
+		NSMutableArray *values = [NSMutableArray array];
+
+		void (^flushValues)() = ^{
+			@synchronized (values) {
+				[timerDisposable.disposable dispose];
+
+				if (values.count == 0) return;
+
+				RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:values convertNullsToNils:NO];
+				[values removeAllObjects];
+				[subscriber sendNext:tuple];
+			}
+		};
+
+		RACDisposable *selfDisposable = [self subscribeNext:^(id x) {
+			@synchronized (values) {
+				if (values.count == 0) {
+					timerDisposable.disposable = [scheduler afterDelay:interval schedule:flushValues];
+				}
+
+				[values addObject:x ?: RACTupleNil.tupleNil];
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			flushValues();
+			[subscriber sendCompleted];
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[selfDisposable dispose];
+			[timerDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -bufferWithTime: %f", self.name, (double)interval];
+}
+
+- (RACSignal *)collect {
+	return [[self aggregateWithStartFactory:^{
+		return [[NSMutableArray alloc] init];
+	} reduce:^(NSMutableArray *collectedValues, id x) {
+		[collectedValues addObject:(x ?: NSNull.null)];
+		return collectedValues;
+	}] setNameWithFormat:@"[%@] -collect", self.name];
+}
+
+- (RACSignal *)takeLast:(NSUInteger)count {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {		
+		NSMutableArray *valuesTaken = [NSMutableArray arrayWithCapacity:count];
+		return [self subscribeNext:^(id x) {
+			[valuesTaken addObject:x ? : [RACTupleNil tupleNil]];
+			
+			while(valuesTaken.count > count) {
+				[valuesTaken removeObjectAtIndex:0];
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			for(id value in valuesTaken) {
+				[subscriber sendNext:[value isKindOfClass:[RACTupleNil class]] ? nil : value];
+			}
+			
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -takeLast: %lu", self.name, (unsigned long)count];
+}
+
+- (RACSignal *)combineLatestWith:(RACSignal *)signal {
+	NSCParameterAssert(signal != nil);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+		__block id lastSelfValue = nil;
+		__block BOOL selfCompleted = NO;
+
+		__block id lastOtherValue = nil;
+		__block BOOL otherCompleted = NO;
+
+		void (^sendNext)(void) = ^{
+			@synchronized (disposable) {
+				if (lastSelfValue == nil || lastOtherValue == nil) return;
+				[subscriber sendNext:[RACTuple tupleWithObjects:lastSelfValue, lastOtherValue, nil]];
+			}
+		};
+
+		RACDisposable *selfDisposable = [self subscribeNext:^(id x) {
+			@synchronized (disposable) {
+				lastSelfValue = x ?: RACTupleNil.tupleNil;
+				sendNext();
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			@synchronized (disposable) {
+				selfCompleted = YES;
+				if (otherCompleted) [subscriber sendCompleted];
+			}
+		}];
+
+		[disposable addDisposable:selfDisposable];
+
+		RACDisposable *otherDisposable = [signal subscribeNext:^(id x) {
+			@synchronized (disposable) {
+				lastOtherValue = x ?: RACTupleNil.tupleNil;
+				sendNext();
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			@synchronized (disposable) {
+				otherCompleted = YES;
+				if (selfCompleted) [subscriber sendCompleted];
+			}
+		}];
+
+		[disposable addDisposable:otherDisposable];
+
+		return disposable;
+	}] setNameWithFormat:@"[%@] -combineLatestWith: %@", self.name, signal];
+}
+
++ (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals {
+	return [[self join:signals block:^(RACSignal *left, RACSignal *right) {
+		return [left combineLatestWith:right];
+	}] setNameWithFormat:@"+combineLatest: %@", signals];
+}
+
++ (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock {
+	NSCParameterAssert(reduceBlock != nil);
+
+	RACSignal *result = [self combineLatest:signals];
+
+	// Although we assert this condition above, older versions of this method
+	// supported this argument being nil. Avoid crashing Release builds of
+	// apps that depended on that.
+	if (reduceBlock != nil) result = [result reduceEach:reduceBlock];
+
+	return [result setNameWithFormat:@"+combineLatest: %@ reduce:", signals];
+}
+
+- (RACSignal *)merge:(RACSignal *)signal {
+	return [[RACSignal
+		merge:@[ self, signal ]]
+		setNameWithFormat:@"[%@] -merge: %@", self.name, signal];
+}
+
++ (RACSignal *)merge:(id<NSFastEnumeration>)signals {
+	NSMutableArray *copiedSignals = [[NSMutableArray alloc] init];
+	for (RACSignal *signal in signals) {
+		[copiedSignals addObject:signal];
+	}
+
+	return [[[RACSignal
+		createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {
+			for (RACSignal *signal in copiedSignals) {
+				[subscriber sendNext:signal];
+			}
+
+			[subscriber sendCompleted];
+			return nil;
+		}]
+		flatten]
+		setNameWithFormat:@"+merge: %@", copiedSignals];
+}
+
+- (RACSignal *)flatten:(NSUInteger)maxConcurrent {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *compoundDisposable = [[RACCompoundDisposable alloc] init];
+
+		// Contains disposables for the currently active subscriptions.
+		//
+		// This should only be used while synchronized on `subscriber`.
+		NSMutableArray *activeDisposables = [[NSMutableArray alloc] initWithCapacity:maxConcurrent];
+
+		// Whether the signal-of-signals has completed yet.
+		//
+		// This should only be used while synchronized on `subscriber`.
+		__block BOOL selfCompleted = NO;
+
+		// Subscribes to the given signal.
+		//
+		// This will be set to nil once all signals have completed (to break
+		// a retain cycle in the recursive block).
+		__block void (^subscribeToSignal)(RACSignal *);
+
+		// Sends completed to the subscriber if all signals are finished.
+		//
+		// This should only be used while synchronized on `subscriber`.
+		void (^completeIfAllowed)(void) = ^{
+			if (selfCompleted && activeDisposables.count == 0) {
+				[subscriber sendCompleted];
+				subscribeToSignal = nil;
+			}
+		};
+
+		// The signals waiting to be started.
+		//
+		// This array should only be used while synchronized on `subscriber`.
+		NSMutableArray *queuedSignals = [NSMutableArray array];
+
+		subscribeToSignal = ^(RACSignal *signal) {
+			RACSerialDisposable *serialDisposable = [[RACSerialDisposable alloc] init];
+
+			@synchronized (subscriber) {
+				[compoundDisposable addDisposable:serialDisposable];
+				[activeDisposables addObject:serialDisposable];
+			}
+
+			serialDisposable.disposable = [signal subscribeNext:^(id x) {
+				[subscriber sendNext:x];
+			} error:^(NSError *error) {
+				[subscriber sendError:error];
+			} completed:^{
+				RACSignal *nextSignal;
+
+				@synchronized (subscriber) {
+					[compoundDisposable removeDisposable:serialDisposable];
+					[activeDisposables removeObjectIdenticalTo:serialDisposable];
+
+					if (queuedSignals.count == 0) {
+						completeIfAllowed();
+						return;
+					}
+
+					nextSignal = queuedSignals[0];
+					[queuedSignals removeObjectAtIndex:0];
+				}
+
+				#pragma clang diagnostic push
+				#pragma clang diagnostic ignored "-Warc-retain-cycles"
+				// This retain cycle is broken in `completeIfAllowed`.
+				subscribeToSignal(nextSignal);
+				#pragma clang diagnostic pop
+			}];
+		};
+
+		[compoundDisposable addDisposable:[self subscribeNext:^(RACSignal *signal) {
+			if (signal == nil) return;
+
+			NSCAssert([signal isKindOfClass:RACSignal.class], @"Expected a RACSignal, got %@", signal);
+
+			@synchronized (subscriber) {
+				if (maxConcurrent > 0 && activeDisposables.count >= maxConcurrent) {
+					[queuedSignals addObject:signal];
+
+					// If we need to wait, skip subscribing to this
+					// signal.
+					return;
+				}
+			}
+
+			subscribeToSignal(signal);
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			@synchronized (subscriber) {
+				selfCompleted = YES;
+				completeIfAllowed();
+			}
+		}]];
+
+		return compoundDisposable;
+	}] setNameWithFormat:@"[%@] -flatten: %lu", self.name, (unsigned long)maxConcurrent];
+}
+
+- (RACSignal *)then:(RACSignal * (^)(void))block {
+	NSCParameterAssert(block != nil);
+
+	return [[[self
+		ignoreValues]
+		concat:[RACSignal defer:block]]
+		setNameWithFormat:@"[%@] -then:", self.name];
+}
+
+- (RACSignal *)concat {
+	return [[self flatten:1] setNameWithFormat:@"[%@] -concat", self.name];
+}
+
+- (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory reduce:(id (^)(id running, id next))reduceBlock {
+	NSCParameterAssert(startFactory != NULL);
+	NSCParameterAssert(reduceBlock != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		__block id runningValue = startFactory();
+		return [self subscribeNext:^(id x) {
+			runningValue = reduceBlock(runningValue, x);
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendNext:runningValue];
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -aggregateWithStartFactory:reduce:", self.name];
+}
+
+- (RACSignal *)aggregateWithStart:(id)start reduce:(id (^)(id running, id next))reduceBlock {
+	RACSignal *signal = [self aggregateWithStartFactory:^{
+		return start;
+	} reduce:reduceBlock];
+
+	return [signal setNameWithFormat:@"[%@] -aggregateWithStart: %@ reduce:", self.name, [start rac_description]];
+}
+
+- (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object {
+	return [self setKeyPath:keyPath onObject:object nilValue:nil];
+}
+
+- (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object nilValue:(id)nilValue {
+	NSCParameterAssert(keyPath != nil);
+	NSCParameterAssert(object != nil);
+
+	keyPath = [keyPath copy];
+
+	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+	// Purposely not retaining 'object', since we want to tear down the binding
+	// when it deallocates normally.
+	__block void * volatile objectPtr = (__bridge void *)object;
+
+	RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+		// Possibly spec, possibly compiler bug, but this __bridge cast does not
+		// result in a retain here, effectively an invisible __unsafe_unretained
+		// qualifier. Using objc_precise_lifetime gives the __strong reference
+		// desired. The explicit use of __strong is strictly defensive.
+		__strong NSObject *object __attribute__((objc_precise_lifetime)) = (__bridge __strong id)objectPtr;
+		[object setValue:x ?: nilValue forKeyPath:keyPath];
+	} error:^(NSError *error) {
+		__strong NSObject *object __attribute__((objc_precise_lifetime)) = (__bridge __strong id)objectPtr;
+
+		NSCAssert(NO, @"Received error from %@ in binding for key path \"%@\" on %@: %@", self, keyPath, object, error);
+
+		// Log the error if we're running with assertions disabled.
+		NSLog(@"Received error from %@ in binding for key path \"%@\" on %@: %@", self, keyPath, object, error);
+
+		[disposable dispose];
+	} completed:^{
+		[disposable dispose];
+	}];
+
+	[disposable addDisposable:subscriptionDisposable];
+
+	#if DEBUG
+	static void *bindingsKey = &bindingsKey;
+	NSMutableDictionary *bindings;
+
+	@synchronized (object) {
+		bindings = objc_getAssociatedObject(object, bindingsKey);
+		if (bindings == nil) {
+			bindings = [NSMutableDictionary dictionary];
+			objc_setAssociatedObject(object, bindingsKey, bindings, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+		}
+	}
+
+	@synchronized (bindings) {
+		NSCAssert(bindings[keyPath] == nil, @"Signal %@ is already bound to key path \"%@\" on object %@, adding signal %@ is undefined behavior", [bindings[keyPath] nonretainedObjectValue], keyPath, object, self);
+
+		bindings[keyPath] = [NSValue valueWithNonretainedObject:self];
+	}
+	#endif
+
+	RACDisposable *clearPointerDisposable = [RACDisposable disposableWithBlock:^{
+		#if DEBUG
+		@synchronized (bindings) {
+			[bindings removeObjectForKey:keyPath];
+		}
+		#endif
+
+		while (YES) {
+			void *ptr = objectPtr;
+			if (OSAtomicCompareAndSwapPtrBarrier(ptr, NULL, &objectPtr)) {
+				break;
+			}
+		}
+	}];
+
+	[disposable addDisposable:clearPointerDisposable];
+
+	[object.rac_deallocDisposable addDisposable:disposable];
+	
+	RACCompoundDisposable *objectDisposable = object.rac_deallocDisposable;
+	return [RACDisposable disposableWithBlock:^{
+		[objectDisposable removeDisposable:disposable];
+		[disposable dispose];
+	}];
+}
+
++ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler {
+	return [[RACSignal interval:interval onScheduler:scheduler withLeeway:0.0] setNameWithFormat:@"+interval: %f onScheduler: %@", (double)interval, scheduler];
+}
+
++ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway {
+	NSCParameterAssert(scheduler != nil);
+	NSCParameterAssert(scheduler != RACScheduler.immediateScheduler);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [scheduler after:[NSDate dateWithTimeIntervalSinceNow:interval] repeatingEvery:interval withLeeway:leeway schedule:^{
+			[subscriber sendNext:[NSDate date]];
+		}];
+	}] setNameWithFormat:@"+interval: %f onScheduler: %@ withLeeway: %f", (double)interval, scheduler, (double)leeway];
+}
+
+- (RACSignal *)takeUntil:(RACSignal *)signalTrigger {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+		void (^triggerCompletion)(void) = ^{
+			[disposable dispose];
+			[subscriber sendCompleted];
+		};
+
+		RACDisposable *triggerDisposable = [signalTrigger subscribeNext:^(id _) {
+			triggerCompletion();
+		} completed:^{
+			triggerCompletion();
+		}];
+
+		[disposable addDisposable:triggerDisposable];
+
+		if (!disposable.disposed) {
+			RACDisposable *selfDisposable = [self subscribeNext:^(id x) {
+				[subscriber sendNext:x];
+			} error:^(NSError *error) {
+				[subscriber sendError:error];
+			} completed:^{
+				[disposable dispose];
+				[subscriber sendCompleted];
+			}];
+
+			[disposable addDisposable:selfDisposable];
+		}
+
+		return disposable;
+	}] setNameWithFormat:@"[%@] -takeUntil: %@", self.name, signalTrigger];
+}
+
+- (RACSignal *)takeUntilReplacement:(RACSignal *)replacement {
+	return [RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
+
+		RACDisposable *replacementDisposable = [replacement subscribeNext:^(id x) {
+			[selfDisposable dispose];
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[selfDisposable dispose];
+			[subscriber sendError:error];
+		} completed:^{
+			[selfDisposable dispose];
+			[subscriber sendCompleted];
+		}];
+
+		if (!selfDisposable.disposed) {
+			selfDisposable.disposable = [[self
+				concat:[RACSignal never]]
+				subscribe:subscriber];
+		}
+
+		return [RACDisposable disposableWithBlock:^{
+			[selfDisposable dispose];
+			[replacementDisposable dispose];
+		}];
+	}];
+}
+
+- (RACSignal *)switchToLatest {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACMulticastConnection *connection = [self publish];
+
+		RACDisposable *subscriptionDisposable = [[connection.signal
+			flattenMap:^(RACSignal *x) {
+				NSCAssert(x == nil || [x isKindOfClass:RACSignal.class], @"-switchToLatest requires that the source signal (%@) send signals. Instead we got: %@", self, x);
+
+				// -concat:[RACSignal never] prevents completion of the receiver from
+				// prematurely terminating the inner signal.
+				return [x takeUntil:[connection.signal concat:[RACSignal never]]];
+			}]
+			subscribe:subscriber];
+
+		RACDisposable *connectionDisposable = [connection connect];
+		return [RACDisposable disposableWithBlock:^{
+			[subscriptionDisposable dispose];
+			[connectionDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -switchToLatest", self.name];
+}
+
++ (RACSignal *)switch:(RACSignal *)signal cases:(NSDictionary *)cases default:(RACSignal *)defaultSignal {
+	NSCParameterAssert(signal != nil);
+	NSCParameterAssert(cases != nil);
+
+	for (id key in cases) {
+		id value __attribute__((unused)) = cases[key];
+		NSCAssert([value isKindOfClass:RACSignal.class], @"Expected all cases to be RACSignals, %@ isn't", value);
+	}
+
+	NSDictionary *copy = [cases copy];
+
+	return [[[signal
+		map:^(id key) {
+			if (key == nil) key = RACTupleNil.tupleNil;
+
+			RACSignal *signal = copy[key] ?: defaultSignal;
+			if (signal == nil) {
+				NSString *description = [NSString stringWithFormat:NSLocalizedString(@"No matching signal found for value %@", @""), key];
+				return [RACSignal error:[NSError errorWithDomain:RACSignalErrorDomain code:RACSignalErrorNoMatchingCase userInfo:@{ NSLocalizedDescriptionKey: description }]];
+			}
+
+			return signal;
+		}]
+		switchToLatest]
+		setNameWithFormat:@"+switch: %@ cases: %@ default: %@", signal, cases, defaultSignal];
+}
+
++ (RACSignal *)if:(RACSignal *)boolSignal then:(RACSignal *)trueSignal else:(RACSignal *)falseSignal {
+	NSCParameterAssert(boolSignal != nil);
+	NSCParameterAssert(trueSignal != nil);
+	NSCParameterAssert(falseSignal != nil);
+
+	return [[[boolSignal
+		map:^(NSNumber *value) {
+			NSCAssert([value isKindOfClass:NSNumber.class], @"Expected %@ to send BOOLs, not %@", boolSignal, value);
+			
+			return (value.boolValue ? trueSignal : falseSignal);
+		}]
+		switchToLatest]
+		setNameWithFormat:@"+if: %@ then: %@ else: %@", boolSignal, trueSignal, falseSignal];
+}
+
+- (id)first {
+	return [self firstOrDefault:nil];
+}
+
+- (id)firstOrDefault:(id)defaultValue {
+	return [self firstOrDefault:defaultValue success:NULL error:NULL];
+}
+
+- (id)firstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error {
+	NSCondition *condition = [[NSCondition alloc] init];
+	condition.name = [NSString stringWithFormat:@"[%@] -firstOrDefault: %@ success:error:", self.name, defaultValue];
+
+	__block id value = defaultValue;
+	__block BOOL done = NO;
+
+	// Ensures that we don't pass values across thread boundaries by reference.
+	__block NSError *localError;
+	__block BOOL localSuccess;
+
+	[[self take:1] subscribeNext:^(id x) {
+		[condition lock];
+
+		value = x;
+		localSuccess = YES;
+		
+		done = YES;
+		[condition broadcast];
+		[condition unlock];
+	} error:^(NSError *e) {
+		[condition lock];
+
+		if (!done) {
+			localSuccess = NO;
+			localError = e;
+
+			done = YES;
+			[condition broadcast];
+		}
+
+		[condition unlock];
+	} completed:^{
+		[condition lock];
+
+		localSuccess = YES;
+
+		done = YES;
+		[condition broadcast];
+		[condition unlock];
+	}];
+
+	[condition lock];
+	while (!done) {
+		[condition wait];
+	}
+
+	if (success != NULL) *success = localSuccess;
+	if (error != NULL) *error = localError;
+
+	[condition unlock];
+	return value;
+}
+
+- (BOOL)waitUntilCompleted:(NSError **)error {
+	BOOL success = NO;
+
+	[[[self
+		ignoreValues]
+		setNameWithFormat:@"[%@] -waitUntilCompleted:", self.name]
+		firstOrDefault:nil success:&success error:error];
+	
+	return success;
+}
+
++ (RACSignal *)defer:(RACSignal * (^)(void))block {
+	NSCParameterAssert(block != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [block() subscribe:subscriber];
+	}] setNameWithFormat:@"+defer:"];
+}
+
+- (NSArray *)toArray {
+	return [[[self collect] first] copy];
+}
+
+- (RACSequence *)sequence {
+	return [[RACSignalSequence sequenceWithSignal:self] setNameWithFormat:@"[%@] -sequence", self.name];
+}
+
+- (RACMulticastConnection *)publish {
+	RACSubject *subject = [[RACSubject subject] setNameWithFormat:@"[%@] -publish", self.name];
+	RACMulticastConnection *connection = [self multicast:subject];
+	return connection;
+}
+
+- (RACMulticastConnection *)multicast:(RACSubject *)subject {
+	[subject setNameWithFormat:@"[%@] -multicast: %@", self.name, subject.name];
+	RACMulticastConnection *connection = [[RACMulticastConnection alloc] initWithSourceSignal:self subject:subject];
+	return connection;
+}
+
+- (RACSignal *)replay {
+	RACReplaySubject *subject = [[RACReplaySubject subject] setNameWithFormat:@"[%@] -replay", self.name];
+
+	RACMulticastConnection *connection = [self multicast:subject];
+	[connection connect];
+
+	return connection.signal;
+}
+
+- (RACSignal *)replayLast {
+	RACReplaySubject *subject = [[RACReplaySubject replaySubjectWithCapacity:1] setNameWithFormat:@"[%@] -replayLast", self.name];
+
+	RACMulticastConnection *connection = [self multicast:subject];
+	[connection connect];
+
+	return connection.signal;
+}
+
+- (RACSignal *)replayLazily {
+	RACMulticastConnection *connection = [self multicast:[RACReplaySubject subject]];
+	return [[RACSignal
+		defer:^{
+			[connection connect];
+			return connection.signal;
+		}]
+		setNameWithFormat:@"[%@] -replayLazily", self.name];
+}
+
+- (RACSignal *)timeout:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler {
+	NSCParameterAssert(scheduler != nil);
+	NSCParameterAssert(scheduler != RACScheduler.immediateScheduler);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+		RACDisposable *timeoutDisposable = [scheduler afterDelay:interval schedule:^{
+			[disposable dispose];
+			[subscriber sendError:[NSError errorWithDomain:RACSignalErrorDomain code:RACSignalErrorTimedOut userInfo:nil]];
+		}];
+
+		[disposable addDisposable:timeoutDisposable];
+
+		RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[disposable dispose];
+			[subscriber sendError:error];
+		} completed:^{
+			[disposable dispose];
+			[subscriber sendCompleted];
+		}];
+
+		[disposable addDisposable:subscriptionDisposable];
+		return disposable;
+	}] setNameWithFormat:@"[%@] -timeout: %f", self.name, (double)interval];
+}
+
+- (RACSignal *)deliverOn:(RACScheduler *)scheduler {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [self subscribeNext:^(id x) {
+			[scheduler schedule:^{
+				[subscriber sendNext:x];
+			}];
+		} error:^(NSError *error) {
+			[scheduler schedule:^{
+				[subscriber sendError:error];
+			}];
+		} completed:^{
+			[scheduler schedule:^{
+				[subscriber sendCompleted];
+			}];
+		}];
+	}] setNameWithFormat:@"[%@] -deliverOn: %@", self.name, scheduler];
+}
+
+- (RACSignal *)subscribeOn:(RACScheduler *)scheduler {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+
+		RACDisposable *schedulingDisposable = [scheduler schedule:^{
+			RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
+				[subscriber sendNext:x];
+			} error:^(NSError *error) {
+				[subscriber sendError:error];
+			} completed:^{
+				[subscriber sendCompleted];
+			}];
+
+			[disposable addDisposable:subscriptionDisposable];
+		}];
+		
+		[disposable addDisposable:schedulingDisposable];
+		return disposable;
+	}] setNameWithFormat:@"[%@] -subscribeOn: %@", self.name, scheduler];
+}
+
+- (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock transform:(id (^)(id object))transformBlock {
+	NSCParameterAssert(keyBlock != NULL);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		NSMutableDictionary *groups = [NSMutableDictionary dictionary];
+
+		return [self subscribeNext:^(id x) {
+			id<NSCopying> key = keyBlock(x);
+			RACGroupedSignal *groupSubject = nil;
+			@synchronized(groups) {
+				groupSubject = [groups objectForKey:key];
+				if(groupSubject == nil) {
+					groupSubject = [RACGroupedSignal signalWithKey:key];
+					[groups setObject:groupSubject forKey:key];
+					[subscriber sendNext:groupSubject];
+				}
+			}
+
+			[groupSubject sendNext:transformBlock != NULL ? transformBlock(x) : x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+
+			[groups.allValues makeObjectsPerformSelector:@selector(sendError:) withObject:error];
+		} completed:^{
+			[subscriber sendCompleted];
+
+			[groups.allValues makeObjectsPerformSelector:@selector(sendCompleted)];
+		}];
+	}] setNameWithFormat:@"[%@] -groupBy:transform:", self.name];
+}
+
+- (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock {
+	return [[self groupBy:keyBlock transform:nil] setNameWithFormat:@"[%@] -groupBy:", self.name];
+}
+
+- (RACSignal *)any {	
+	return [[self any:^(id x) {
+		return YES;
+	}] setNameWithFormat:@"[%@] -any", self.name];
+}
+
+- (RACSignal *)any:(BOOL (^)(id object))predicateBlock {
+	NSCParameterAssert(predicateBlock != NULL);
+	
+	return [[[self materialize] bind:^{
+		return ^(RACEvent *event, BOOL *stop) {
+			if (event.finished) {
+				*stop = YES;
+				return [RACSignal return:@NO];
+			}
+			
+			if (predicateBlock(event.value)) {
+				*stop = YES;
+				return [RACSignal return:@YES];
+			}
+
+			return [RACSignal empty];
+		};
+	}] setNameWithFormat:@"[%@] -any:", self.name];
+}
+
+- (RACSignal *)all:(BOOL (^)(id object))predicateBlock {
+	NSCParameterAssert(predicateBlock != NULL);
+	
+	return [[[self materialize] bind:^{
+		return ^(RACEvent *event, BOOL *stop) {
+			if (event.eventType == RACEventTypeCompleted) {
+				*stop = YES;
+				return [RACSignal return:@YES];
+			}
+			
+			if (event.eventType == RACEventTypeError || !predicateBlock(event.value)) {
+				*stop = YES;
+				return [RACSignal return:@NO];
+			}
+
+			return [RACSignal empty];
+		};
+	}] setNameWithFormat:@"[%@] -all:", self.name];
+}
+
+- (RACSignal *)retry:(NSInteger)retryCount {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		__block NSInteger currentRetryCount = 0;
+		return subscribeForever(self,
+			^(id x) {
+				[subscriber sendNext:x];
+			},
+			^(NSError *error, RACDisposable *disposable) {
+				if (retryCount == 0 || currentRetryCount < retryCount) {
+					// Resubscribe.
+					currentRetryCount++;
+					return;
+				}
+
+				[disposable dispose];
+				[subscriber sendError:error];
+			},
+			^(RACDisposable *disposable) {
+				[disposable dispose];
+				[subscriber sendCompleted];
+			});
+	}] setNameWithFormat:@"[%@] -retry: %lu", self.name, (unsigned long)retryCount];
+}
+
+- (RACSignal *)retry {
+	return [[self retry:0] setNameWithFormat:@"[%@] -retry", self.name];
+}
+
+- (RACSignal *)sample:(RACSignal *)sampler {
+	NSCParameterAssert(sampler != nil);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		NSLock *lock = [[NSLock alloc] init];
+		__block id lastValue;
+		__block BOOL hasValue = NO;
+
+		RACSerialDisposable *samplerDisposable = [[RACSerialDisposable alloc] init];
+		RACDisposable *sourceDisposable = [self subscribeNext:^(id x) {
+			[lock lock];
+			hasValue = YES;
+			lastValue = x;
+			[lock unlock];
+		} error:^(NSError *error) {
+			[samplerDisposable dispose];
+			[subscriber sendError:error];
+		} completed:^{
+			[samplerDisposable dispose];
+			[subscriber sendCompleted];
+		}];
+
+		samplerDisposable.disposable = [sampler subscribeNext:^(id _) {
+			BOOL shouldSend = NO;
+			id value;
+			[lock lock];
+			shouldSend = hasValue;
+			value = lastValue;
+			[lock unlock];
+
+			if (shouldSend) {
+				[subscriber sendNext:value];
+			}
+		} error:^(NSError *error) {
+			[sourceDisposable dispose];
+			[subscriber sendError:error];
+		} completed:^{
+			[sourceDisposable dispose];
+			[subscriber sendCompleted];
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[samplerDisposable dispose];
+			[sourceDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -sample: %@", self.name, sampler];
+}
+
+- (RACSignal *)ignoreValues {
+	return [[self filter:^(id _) {
+		return NO;
+	}] setNameWithFormat:@"[%@] -ignoreValues", self.name];
+}
+
+- (RACSignal *)materialize {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		return [self subscribeNext:^(id x) {
+			[subscriber sendNext:[RACEvent eventWithValue:x]];
+		} error:^(NSError *error) {
+			[subscriber sendNext:[RACEvent eventWithError:error]];
+			[subscriber sendCompleted];
+		} completed:^{
+			[subscriber sendNext:RACEvent.completedEvent];
+			[subscriber sendCompleted];
+		}];
+	}] setNameWithFormat:@"[%@] -materialize", self.name];
+}
+
+- (RACSignal *)dematerialize {
+	return [[self bind:^{
+		return ^(RACEvent *event, BOOL *stop) {
+			switch (event.eventType) {
+				case RACEventTypeCompleted:
+					*stop = YES;
+					return [RACSignal empty];
+
+				case RACEventTypeError:
+					*stop = YES;
+					return [RACSignal error:event.error];
+
+				case RACEventTypeNext:
+					return [RACSignal return:event.value];
+			}
+		};
+	}] setNameWithFormat:@"[%@] -dematerialize", self.name];
+}
+
+- (RACSignal *)not {
+	return [[self map:^(NSNumber *value) {
+		NSCAssert([value isKindOfClass:NSNumber.class], @"-not must only be used on a signal of NSNumbers. Instead, got: %@", value);
+
+		return @(!value.boolValue);
+	}] setNameWithFormat:@"[%@] -not", self.name];
+}
+
+- (RACSignal *)and {
+	return [[self map:^(RACTuple *tuple) {
+		NSCAssert([tuple isKindOfClass:RACTuple.class], @"-and must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple);
+		NSCAssert(tuple.count > 0, @"-and must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple");
+		
+		return @([tuple.rac_sequence all:^(NSNumber *number) {
+			NSCAssert([number isKindOfClass:NSNumber.class], @"-and must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple);
+			
+			return number.boolValue;
+		}]);
+	}] setNameWithFormat:@"[%@] -and", self.name];
+}
+
+- (RACSignal *)or {
+	return [[self map:^(RACTuple *tuple) {
+		NSCAssert([tuple isKindOfClass:RACTuple.class], @"-or must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple);
+		NSCAssert(tuple.count > 0, @"-or must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple");
+		
+		return @([tuple.rac_sequence any:^(NSNumber *number) {
+			NSCAssert([number isKindOfClass:NSNumber.class], @"-or must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple);
+			
+			return number.boolValue;
+		}]);
+	}] setNameWithFormat:@"[%@] -or", self.name];
+}
+
+@end
+
+@implementation RACSignal (OperationsDeprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (RACSignal *)windowWithStart:(RACSignal *)openSignal close:(RACSignal * (^)(RACSignal *start))closeBlock {
+	NSCParameterAssert(openSignal != nil);
+	NSCParameterAssert(closeBlock != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		__block RACSubject *currentWindow = nil;
+		__block RACSignal *currentCloseWindow = nil;
+		__block RACDisposable *closeObserverDisposable = NULL;
+		
+		void (^closeCurrentWindow)(void) = ^{
+			[currentWindow sendCompleted];
+			currentWindow = nil;
+			currentCloseWindow = nil;
+			[closeObserverDisposable dispose], closeObserverDisposable = nil;
+		};
+		
+		RACDisposable *openObserverDisposable = [openSignal subscribe:[RACSubscriber subscriberWithNext:^(id x) {
+			if(currentWindow == nil) {
+				currentWindow = [RACSubject subject];
+				[subscriber sendNext:currentWindow];
+				
+				currentCloseWindow = closeBlock(currentWindow);
+				closeObserverDisposable = [currentCloseWindow subscribe:[RACSubscriber subscriberWithNext:^(id x) {
+					closeCurrentWindow();
+				} error:^(NSError *error) {
+					closeCurrentWindow();
+				} completed:^{
+					closeCurrentWindow();
+				}]];
+			}
+		} error:^(NSError *error) {
+			
+		} completed:^{
+			
+		}]];
+				
+		RACDisposable *selfObserverDisposable = [self subscribeNext:^(id x) {
+			[currentWindow sendNext:x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+				
+		return [RACDisposable disposableWithBlock:^{
+			[closeObserverDisposable dispose];
+			[openObserverDisposable dispose];
+			[selfObserverDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -windowWithStart: %@ close:", self.name, openSignal];
+}
+
+- (RACSignal *)buffer:(NSUInteger)bufferCount {
+	NSCParameterAssert(bufferCount > 0);
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		NSMutableArray *values = [NSMutableArray arrayWithCapacity:bufferCount];
+		RACSubject *windowCloseSubject = [RACSubject subject];
+		
+		RACDisposable *closeDisposable = [windowCloseSubject subscribeNext:^(id x) {
+			[subscriber sendNext:[RACTuple tupleWithObjectsFromArray:values convertNullsToNils:NO]];
+			[values removeAllObjects];
+		}];
+
+		__block RACDisposable *innerDisposable = nil;
+		RACDisposable *outerDisposable = [[self windowWithStart:self close:^(RACSignal *start) {
+			return windowCloseSubject;
+		}] subscribeNext:^(id x) {		
+			innerDisposable = [x subscribeNext:^(id x) {
+				[values addObject:x ? : [RACTupleNil tupleNil]];
+				if(values.count % bufferCount == 0) {
+					[windowCloseSubject sendNext:[RACUnit defaultUnit]];
+				}
+			}];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[innerDisposable dispose];
+			[outerDisposable dispose];
+			[closeDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -buffer: %lu", self.name, (unsigned long)bufferCount];
+}
+
+- (RACSignal *)let:(RACSignal * (^)(RACSignal *sharedSignal))letBlock {
+	NSCParameterAssert(letBlock != NULL);
+	
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACMulticastConnection *connection = [self publish];
+		RACDisposable *finalDisposable = [letBlock(connection.signal) subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			[subscriber sendCompleted];
+		}];
+		
+		RACDisposable *connectionDisposable = [connection connect];
+		
+		return [RACDisposable disposableWithBlock:^{
+			[connectionDisposable dispose];
+			[finalDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -let:", self.name];
+}
+
++ (RACSignal *)interval:(NSTimeInterval)interval {
+	return [RACSignal interval:interval onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityHigh]];
+}
+
++ (RACSignal *)interval:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway {
+	return [RACSignal interval:interval onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityHigh] withLeeway:leeway];
+}
+
+- (RACSignal *)timeout:(NSTimeInterval)interval {
+	return [self timeout:interval onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityHigh]];
+}
+
+- (RACSignal *)bufferWithTime:(NSTimeInterval)interval {
+	return [self bufferWithTime:interval onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityHigh]];
+}
+
+- (RACDisposable *)toProperty:(NSString *)keyPath onObject:(NSObject *)object {
+	return [self setKeyPath:keyPath onObject:object];
+}
+
+- (RACSignal *)ignoreElements {
+	return [self ignoreValues];
+}
+
+- (RACSignal *)sequenceNext:(RACSignal * (^)(void))block {
+	return [self then:block];
+}
+
+- (RACSignal *)aggregateWithStart:(id)start combine:(id (^)(id running, id next))combineBlock {
+	return [self aggregateWithStart:start reduce:combineBlock];
+}
+
+- (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory combine:(id (^)(id running, id next))combineBlock {
+	return [self aggregateWithStartFactory:startFactory reduce:combineBlock];
+}
+
+- (RACDisposable *)executeCommand:(RACCommand *)command {
+	NSCParameterAssert(command != nil);
+
+	return [self subscribeNext:^(id x) {
+		[command execute:x];
+	}];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.h
new file mode 100644
index 0000000..ed644cf
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.h
@@ -0,0 +1,219 @@
+//
+//  RACSignal.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/1/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACStream.h"
+
+@class RACDisposable;
+@class RACScheduler;
+@class RACSubject;
+@protocol RACSubscriber;
+
+@interface RACSignal : RACStream
+
+/// Creates a new signal. This is the preferred way to create a new signal
+/// operation or behavior.
+///
+/// Events can be sent to new subscribers immediately in the `didSubscribe`
+/// block, but the subscriber will not be able to dispose of the signal until
+/// a RACDisposable is returned from `didSubscribe`. In the case of infinite
+/// signals, this won't _ever_ happen if events are sent immediately.
+///
+/// To ensure that the signal is disposable, events can be scheduled on the
+/// +[RACScheduler currentScheduler] (so that they're deferred, not sent
+/// immediately), or they can be sent in the background. The RACDisposable
+/// returned by the `didSubscribe` block should cancel any such scheduling or
+/// asynchronous work.
+///
+/// didSubscribe - Called when the signal is subscribed to. The new subscriber is
+///                passed in. You can then manually control the <RACSubscriber> by
+///                sending it -sendNext:, -sendError:, and -sendCompleted,
+///                as defined by the operation you're implementing. This block
+///                should return a RACDisposable which cancels any ongoing work
+///                triggered by the subscription, and cleans up any resources or
+///                disposables created as part of it. When the disposable is
+///                disposed of, the signal must not send any more events to the
+///                `subscriber`. If no cleanup is necessary, return nil.
+///
+/// **Note:** The `didSubscribe` block is called every time a new subscriber
+/// subscribes. Any side effects within the block will thus execute once for each
+/// subscription, not necessarily on one thread, and possibly even
+/// simultaneously!
++ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe;
+
+/// Returns a signal that immediately sends the given error.
++ (RACSignal *)error:(NSError *)error;
+
+/// Returns a signal that never completes.
++ (RACSignal *)never;
+
+/// Immediately schedules the given block on the given scheduler. The block is
+/// given a subscriber to which it can send events.
+///
+/// scheduler - The scheduler on which `block` will be scheduled and results
+///             delivered. Cannot be nil.
+/// block     - The block to invoke. Cannot be NULL.
+///
+/// Returns a signal which will send all events sent on the subscriber given to
+/// `block`. All events will be sent on `scheduler` and it will replay any missed
+/// events to new subscribers.
++ (RACSignal *)startEagerlyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block;
+
+/// Invokes the given block only on the first subscription. The block is given a
+/// subscriber to which it can send events.
+///
+/// Note that disposing of the subscription to the returned signal will *not*
+/// dispose of the underlying subscription. If you need that behavior, see
+/// -[RACMulticastConnection autoconnect]. The underlying subscription will never
+/// be disposed of. Because of this, `block` should never return an infinite
+/// signal since there would be no way of ending it.
+///
+/// scheduler - The scheduler on which the block should be scheduled. Note that 
+///             if given +[RACScheduler immediateScheduler], the block will be
+///             invoked synchronously on the first subscription. Cannot be nil.
+/// block     - The block to invoke on the first subscription. Cannot be NULL.
+///
+/// Returns a signal which will pass through the events sent to the subscriber
+/// given to `block` and replay any missed events to new subscribers.
++ (RACSignal *)startLazilyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block;
+
+@end
+
+@interface RACSignal (RACStream)
+
+/// Returns a signal that immediately sends the given value and then completes.
++ (RACSignal *)return:(id)value;
+
+/// Returns a signal that immediately completes.
++ (RACSignal *)empty;
+
+/// Subscribes to `signal` when the source signal completes.
+- (RACSignal *)concat:(RACSignal *)signal;
+
+/// Zips the values in the receiver with those of the given signal to create
+/// RACTuples.
+///
+/// The first `next` of each stream will be combined, then the second `next`, and
+/// so forth, until either signal completes or errors.
+///
+/// signal - The signal to zip with. This must not be `nil`.
+///
+/// Returns a new signal of RACTuples, representing the combined values of the
+/// two signals. Any error from one of the original signals will be forwarded on
+/// the returned signal.
+- (RACSignal *)zipWith:(RACSignal *)signal;
+
+@end
+
+@interface RACSignal (Subscription)
+
+/// Subscribes `subscriber` to changes on the receiver. The receiver defines which
+/// events it actually sends and in what situations the events are sent.
+///
+/// Subscription will always happen on a valid RACScheduler. If the
+/// +[RACScheduler currentScheduler] cannot be determined at the time of
+/// subscription (e.g., because the calling code is running on a GCD queue or
+/// NSOperationQueue), subscription will occur on a private background scheduler.
+/// On the main thread, subscriptions will always occur immediately, with a
+/// +[RACScheduler currentScheduler] of +[RACScheduler mainThreadScheduler].
+///
+/// This method must be overridden by any subclasses.
+///
+/// Returns nil or a disposable. You can call -[RACDisposable dispose] if you
+/// need to end your subscription before it would "naturally" end, either by
+/// completing or erroring. Once the disposable has been disposed, the subscriber
+/// won't receive any more events from the subscription.
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber;
+
+/// Convenience method to subscribe to the `next` event.
+///
+/// This corresponds to `IObserver<T>.OnNext` in Rx.
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock;
+
+/// Convenience method to subscribe to the `next` and `completed` events.
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock completed:(void (^)(void))completedBlock;
+
+/// Convenience method to subscribe to the `next`, `completed`, and `error` events.
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock error:(void (^)(NSError *error))errorBlock completed:(void (^)(void))completedBlock;
+
+/// Convenience method to subscribe to `error` events.
+///
+/// This corresponds to the `IObserver<T>.OnError` in Rx.
+- (RACDisposable *)subscribeError:(void (^)(NSError *error))errorBlock;
+
+/// Convenience method to subscribe to `completed` events.
+///
+/// This corresponds to the `IObserver<T>.OnCompleted` in Rx.
+- (RACDisposable *)subscribeCompleted:(void (^)(void))completedBlock;
+
+/// Convenience method to subscribe to `next` and `error` events.
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock error:(void (^)(NSError *error))errorBlock;
+
+/// Convenience method to subscribe to `error` and `completed` events.
+- (RACDisposable *)subscribeError:(void (^)(NSError *error))errorBlock completed:(void (^)(void))completedBlock;
+
+@end
+
+/// Additional methods to assist with debugging.
+@interface RACSignal (Debugging)
+
+/// Logs all events that the receiver sends.
+- (RACSignal *)logAll;
+
+/// Logs each `next` that the receiver sends.
+- (RACSignal *)logNext;
+
+/// Logs any error that the receiver sends.
+- (RACSignal *)logError;
+
+/// Logs any `completed` event that the receiver sends.
+- (RACSignal *)logCompleted;
+
+@end
+
+/// Additional methods to assist with unit testing.
+///
+/// **These methods should never ship in production code.**
+@interface RACSignal (Testing)
+
+/// Spins the main run loop for a short while, waiting for the receiver to send a `next`.
+///
+/// **Because this method executes the run loop recursively, it should only be used
+/// on the main thread, and only from a unit test.**
+///
+/// defaultValue - Returned if the receiver completes or errors before sending
+///                a `next`, or if the method times out. This argument may be
+///                nil.
+/// success      - If not NULL, set to whether the receiver completed
+///                successfully.
+/// error        - If not NULL, set to any error that occurred.
+///
+/// Returns the first value received, or `defaultValue` if no value is received
+/// before the signal finishes or the method times out.
+- (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error;
+
+/// Spins the main run loop for a short while, waiting for the receiver to complete.
+///
+/// **Because this method executes the run loop recursively, it should only be used
+/// on the main thread, and only from a unit test.**
+///
+/// error - If not NULL, set to any error that occurs.
+///
+/// Returns whether the signal completed successfully before timing out. If NO,
+/// `error` will be set to any error that occurred.
+- (BOOL)asynchronouslyWaitUntilCompleted:(NSError **)error;
+
+@end
+
+@interface RACSignal (Deprecated)
+
++ (RACSignal *)start:(id (^)(BOOL *success, NSError **error))block __attribute__((deprecated("Use +startEagerlyWithScheduler:block: instead")));
++ (RACSignal *)startWithScheduler:(RACScheduler *)scheduler subjectBlock:(void (^)(RACSubject *subject))block __attribute__((deprecated("Use +startEagerlyWithScheduler:block: instead")));
++ (RACSignal *)startWithScheduler:(RACScheduler *)scheduler block:(id (^)(BOOL *success, NSError **error))block __attribute__((deprecated("Use +startEagerlyWithScheduler:block: instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.m
new file mode 100644
index 0000000..69d9700
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignal.m
@@ -0,0 +1,447 @@
+//
+//  RACSignal.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/15/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACDynamicSignal.h"
+#import "RACEmptySignal.h"
+#import "RACErrorSignal.h"
+#import "RACMulticastConnection.h"
+#import "RACReplaySubject.h"
+#import "RACReturnSignal.h"
+#import "RACScheduler.h"
+#import "RACSerialDisposable.h"
+#import "RACSignal+Operations.h"
+#import "RACSubject.h"
+#import "RACSubscriber+Private.h"
+#import "RACTuple.h"
+
+@implementation RACSignal
+
+#pragma mark Lifecycle
+
++ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
+	return [RACDynamicSignal createSignal:didSubscribe];
+}
+
++ (RACSignal *)error:(NSError *)error {
+	return [RACErrorSignal error:error];
+}
+
++ (RACSignal *)never {
+	return [[self createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {
+		return nil;
+	}] setNameWithFormat:@"+never"];
+}
+
++ (RACSignal *)startEagerlyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block {
+	NSCParameterAssert(scheduler != nil);
+	NSCParameterAssert(block != NULL);
+
+	RACSignal *signal = [self startLazilyWithScheduler:scheduler block:block];
+	// Subscribe to force the lazy signal to call its block.
+	[[signal publish] connect];
+	return [signal setNameWithFormat:@"+startEagerlyWithScheduler:%@ block:", scheduler];
+}
+
++ (RACSignal *)startLazilyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block {
+	NSCParameterAssert(scheduler != nil);
+	NSCParameterAssert(block != NULL);
+
+	RACMulticastConnection *connection = [[RACSignal
+		createSignal:^ id (id<RACSubscriber> subscriber) {
+			block(subscriber);
+			return nil;
+		}]
+		multicast:[RACReplaySubject subject]];
+	
+	return [[[RACSignal
+		createSignal:^ id (id<RACSubscriber> subscriber) {
+			[connection.signal subscribe:subscriber];
+			[connection connect];
+			return nil;
+		}]
+		subscribeOn:scheduler]
+		setNameWithFormat:@"+startLazilyWithScheduler:%@ block:", scheduler];
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p> name: %@", self.class, self, self.name];
+}
+
+@end
+
+@implementation RACSignal (RACStream)
+
++ (RACSignal *)empty {
+	return [RACEmptySignal empty];
+}
+
++ (RACSignal *)return:(id)value {
+	return [RACReturnSignal return:value];
+}
+
+- (RACSignal *)bind:(RACStreamBindBlock (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	/*
+	 * -bind: should:
+	 * 
+	 * 1. Subscribe to the original signal of values.
+	 * 2. Any time the original signal sends a value, transform it using the binding block.
+	 * 3. If the binding block returns a signal, subscribe to it, and pass all of its values through to the subscriber as they're received.
+	 * 4. If the binding block asks the bind to terminate, complete the _original_ signal.
+	 * 5. When _all_ signals complete, send completed to the subscriber.
+	 * 
+	 * If any signal sends an error at any point, send that to the subscriber.
+	 */
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACStreamBindBlock bindingBlock = block();
+
+		NSMutableArray *signals = [NSMutableArray arrayWithObject:self];
+
+		RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
+
+		void (^completeSignal)(RACSignal *, RACDisposable *) = ^(RACSignal *signal, RACDisposable *finishedDisposable) {
+			BOOL removeDisposable = NO;
+
+			@synchronized (signals) {
+				[signals removeObject:signal];
+
+				if (signals.count == 0) {
+					[subscriber sendCompleted];
+					[compoundDisposable dispose];
+				} else {
+					removeDisposable = YES;
+				}
+			}
+
+			if (removeDisposable) [compoundDisposable removeDisposable:finishedDisposable];
+		};
+
+		void (^addSignal)(RACSignal *) = ^(RACSignal *signal) {
+			@synchronized (signals) {
+				[signals addObject:signal];
+			}
+
+			RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
+			[compoundDisposable addDisposable:selfDisposable];
+
+			RACDisposable *disposable = [signal subscribeNext:^(id x) {
+				[subscriber sendNext:x];
+			} error:^(NSError *error) {
+				[compoundDisposable dispose];
+				[subscriber sendError:error];
+			} completed:^{
+				@autoreleasepool {
+					completeSignal(signal, selfDisposable);
+				}
+			}];
+
+			selfDisposable.disposable = disposable;
+		};
+
+		@autoreleasepool {
+			RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
+			[compoundDisposable addDisposable:selfDisposable];
+
+			RACDisposable *bindingDisposable = [self subscribeNext:^(id x) {
+				BOOL stop = NO;
+				id signal = bindingBlock(x, &stop);
+
+				@autoreleasepool {
+					if (signal != nil) addSignal(signal);
+					if (signal == nil || stop) {
+						[selfDisposable dispose];
+						completeSignal(self, selfDisposable);
+					}
+				}
+			} error:^(NSError *error) {
+				[compoundDisposable dispose];
+				[subscriber sendError:error];
+			} completed:^{
+				@autoreleasepool {
+					completeSignal(self, selfDisposable);
+				}
+			}];
+
+			selfDisposable.disposable = bindingDisposable;
+		}
+
+		return compoundDisposable;
+	}] setNameWithFormat:@"[%@] -bind:", self.name];
+}
+
+- (RACSignal *)concat:(RACSignal *)signal {
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		RACSerialDisposable *serialDisposable = [[RACSerialDisposable alloc] init];
+
+		RACDisposable *sourceDisposable = [self subscribeNext:^(id x) {
+			[subscriber sendNext:x];
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			RACDisposable *concattedDisposable = [signal subscribe:subscriber];
+			serialDisposable.disposable = concattedDisposable;
+		}];
+
+		serialDisposable.disposable = sourceDisposable;
+		return serialDisposable;
+	}] setNameWithFormat:@"[%@] -concat: %@", self.name, signal];
+}
+
+- (RACSignal *)zipWith:(RACSignal *)signal {
+	NSCParameterAssert(signal != nil);
+
+	return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
+		__block BOOL selfCompleted = NO;
+		NSMutableArray *selfValues = [NSMutableArray array];
+
+		__block BOOL otherCompleted = NO;
+		NSMutableArray *otherValues = [NSMutableArray array];
+
+		void (^sendCompletedIfNecessary)(void) = ^{
+			@synchronized (selfValues) {
+				BOOL selfEmpty = (selfCompleted && selfValues.count == 0);
+				BOOL otherEmpty = (otherCompleted && otherValues.count == 0);
+				if (selfEmpty || otherEmpty) [subscriber sendCompleted];
+			}
+		};
+
+		void (^sendNext)(void) = ^{
+			@synchronized (selfValues) {
+				if (selfValues.count == 0) return;
+				if (otherValues.count == 0) return;
+
+				RACTuple *tuple = [RACTuple tupleWithObjects:selfValues[0], otherValues[0], nil];
+				[selfValues removeObjectAtIndex:0];
+				[otherValues removeObjectAtIndex:0];
+
+				[subscriber sendNext:tuple];
+				sendCompletedIfNecessary();
+			}
+		};
+
+		RACDisposable *selfDisposable = [self subscribeNext:^(id x) {
+			@synchronized (selfValues) {
+				[selfValues addObject:x ?: RACTupleNil.tupleNil];
+				sendNext();
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			@synchronized (selfValues) {
+				selfCompleted = YES;
+				sendCompletedIfNecessary();
+			}
+		}];
+
+		RACDisposable *otherDisposable = [signal subscribeNext:^(id x) {
+			@synchronized (selfValues) {
+				[otherValues addObject:x ?: RACTupleNil.tupleNil];
+				sendNext();
+			}
+		} error:^(NSError *error) {
+			[subscriber sendError:error];
+		} completed:^{
+			@synchronized (selfValues) {
+				otherCompleted = YES;
+				sendCompletedIfNecessary();
+			}
+		}];
+
+		return [RACDisposable disposableWithBlock:^{
+			[selfDisposable dispose];
+			[otherDisposable dispose];
+		}];
+	}] setNameWithFormat:@"[%@] -zipWith: %@", self.name, signal];
+}
+
+@end
+
+@implementation RACSignal (Subscription)
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCAssert(NO, @"This method must be overridden by subclasses");
+	return nil;
+}
+
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
+	NSCParameterAssert(nextBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock completed:(void (^)(void))completedBlock {
+	NSCParameterAssert(nextBlock != NULL);
+	NSCParameterAssert(completedBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:completedBlock];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock error:(void (^)(NSError *error))errorBlock completed:(void (^)(void))completedBlock {
+	NSCParameterAssert(nextBlock != NULL);
+	NSCParameterAssert(errorBlock != NULL);
+	NSCParameterAssert(completedBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:errorBlock completed:completedBlock];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeError:(void (^)(NSError *error))errorBlock {
+	NSCParameterAssert(errorBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:NULL error:errorBlock completed:NULL];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeCompleted:(void (^)(void))completedBlock {
+	NSCParameterAssert(completedBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:NULL error:NULL completed:completedBlock];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock error:(void (^)(NSError *error))errorBlock {
+	NSCParameterAssert(nextBlock != NULL);
+	NSCParameterAssert(errorBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:errorBlock completed:NULL];
+	return [self subscribe:o];
+}
+
+- (RACDisposable *)subscribeError:(void (^)(NSError *))errorBlock completed:(void (^)(void))completedBlock {
+	NSCParameterAssert(completedBlock != NULL);
+	NSCParameterAssert(errorBlock != NULL);
+	
+	RACSubscriber *o = [RACSubscriber subscriberWithNext:NULL error:errorBlock completed:completedBlock];
+	return [self subscribe:o];
+}
+
+@end
+
+@implementation RACSignal (Debugging)
+
+- (RACSignal *)logAll {
+	return [[[self logNext] logError] logCompleted];
+}
+
+- (RACSignal *)logNext {
+	return [[self doNext:^(id x) {
+		NSLog(@"%@ next: %@", self, x);
+	}] setNameWithFormat:@"%@", self.name];
+}
+
+- (RACSignal *)logError {
+	return [[self doError:^(NSError *error) {
+		NSLog(@"%@ error: %@", self, error);
+	}] setNameWithFormat:@"%@", self.name];
+}
+
+- (RACSignal *)logCompleted {
+	return [[self doCompleted:^{
+		NSLog(@"%@ completed", self);
+	}] setNameWithFormat:@"%@", self.name];
+}
+
+@end
+
+@implementation RACSignal (Testing)
+
+static const NSTimeInterval RACSignalAsynchronousWaitTimeout = 10;
+
+- (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error {
+	NSCAssert([NSThread isMainThread], @"%s should only be used from the main thread", __func__);
+
+	__block id result = defaultValue;
+	__block BOOL done = NO;
+
+	// Ensures that we don't pass values across thread boundaries by reference.
+	__block NSError *localError;
+	__block BOOL localSuccess = YES;
+
+	[[[[self
+		take:1]
+		timeout:RACSignalAsynchronousWaitTimeout onScheduler:[RACScheduler scheduler]]
+		deliverOn:RACScheduler.mainThreadScheduler]
+		subscribeNext:^(id x) {
+			result = x;
+			done = YES;
+		} error:^(NSError *e) {
+			if (!done) {
+				localSuccess = NO;
+				localError = e;
+				done = YES;
+			}
+		} completed:^{
+			done = YES;
+		}];
+	
+	do {
+		[NSRunLoop.mainRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+	} while (!done);
+
+	if (success != NULL) *success = localSuccess;
+	if (error != NULL) *error = localError;
+
+	return result;
+}
+
+- (BOOL)asynchronouslyWaitUntilCompleted:(NSError **)error {
+	BOOL success = NO;
+	[[self ignoreValues] asynchronousFirstOrDefault:nil success:&success error:error];
+	return success;
+}
+
+@end
+
+@implementation RACSignal (Deprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
++ (RACSignal *)startWithScheduler:(RACScheduler *)scheduler subjectBlock:(void (^)(RACSubject *subject))block {
+	NSCParameterAssert(block != NULL);
+
+	RACReplaySubject *subject = [[RACReplaySubject subject] setNameWithFormat:@"+startWithScheduler:subjectBlock:"];
+
+	[scheduler schedule:^{
+		block(subject);
+	}];
+
+	return subject;
+}
+
++ (RACSignal *)start:(id (^)(BOOL *success, NSError **error))block {
+	return [[self startWithScheduler:[RACScheduler scheduler] block:block] setNameWithFormat:@"+start:"];
+}
+
++ (RACSignal *)startWithScheduler:(RACScheduler *)scheduler block:(id (^)(BOOL *success, NSError **error))block {
+	return [[self startWithScheduler:scheduler subjectBlock:^(id<RACSubscriber> subscriber) {
+		BOOL success = YES;
+		NSError *error = nil;
+		id returned = block(&success, &error);
+
+		if (!success) {
+			[subscriber sendError:error];
+		} else {
+			[subscriber sendNext:returned];
+			[subscriber sendCompleted];
+		}
+	}] setNameWithFormat:@"+startWithScheduler:block:"];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignalProvider.d b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalProvider.d
new file mode 100644
index 0000000..8add9a1
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalProvider.d
@@ -0,0 +1,5 @@
+provider RACSignal {
+    probe next(char *signal, char *subscriber, char *valueDescription);
+    probe completed(char *signal, char *subscriber);
+    probe error(char *signal, char *subscriber, char *errorDescription);
+};
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.h
new file mode 100644
index 0000000..e3ab77d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.h
@@ -0,0 +1,19 @@
+//
+//  RACSignalSequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-11-09.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+@class RACSignal;
+
+// Private class that adapts a RACSignal to the RACSequence interface.
+@interface RACSignalSequence : RACSequence
+
+// Returns a sequence for enumerating over the given signal.
++ (RACSequence *)sequenceWithSignal:(RACSignal *)signal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.m
new file mode 100644
index 0000000..52ea1b9
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSignalSequence.m
@@ -0,0 +1,79 @@
+//
+//  RACSignalSequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-11-09.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignalSequence.h"
+#import "RACDisposable.h"
+#import "RACReplaySubject.h"
+#import "RACSignal+Operations.h"
+
+@interface RACSignalSequence ()
+
+// Replays the signal given on initialization.
+@property (nonatomic, strong, readonly) RACReplaySubject *subject;
+
+@end
+
+@implementation RACSignalSequence
+
+#pragma mark Lifecycle
+
++ (RACSequence *)sequenceWithSignal:(RACSignal *)signal {
+	RACSignalSequence *seq = [[self alloc] init];
+
+	RACReplaySubject *subject = [RACReplaySubject subject];
+	[signal subscribeNext:^(id value) {
+		[subject sendNext:value];
+	} error:^(NSError *error) {
+		[subject sendError:error];
+	} completed:^{
+		[subject sendCompleted];
+	}];
+
+	seq->_subject = subject;
+	return seq;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	id value = [self.subject firstOrDefault:self];
+
+	if (value == self) {
+		return nil;
+	} else {
+		return value ?: NSNull.null;
+	}
+}
+
+- (RACSequence *)tail {
+	RACSequence *sequence = [self.class sequenceWithSignal:[self.subject skip:1]];
+	sequence.name = self.name;
+	return sequence;
+}
+
+- (NSArray *)array {
+	return self.subject.toArray;
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	// Synchronously accumulate the values that have been sent so far.
+	NSMutableArray *values = [NSMutableArray array];
+	RACDisposable *disposable = [self.subject subscribeNext:^(id value) {
+		@synchronized (values) {
+			[values addObject:value ?: NSNull.null];
+		}
+	}];
+
+	[disposable dispose];
+
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, values = %@ … }", self.class, self, self.name, values];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACStream+Private.h b/ReactiveCocoaFramework/ReactiveCocoa/RACStream+Private.h
new file mode 100644
index 0000000..f6c0407
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACStream+Private.h
@@ -0,0 +1,23 @@
+//
+//  RACStream+Private.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACStream.h"
+
+@interface RACStream ()
+
+// Combines a list of streams using the logic of the given block.
+//
+// streams - The streams to combine.
+// block   - An operator that combines two streams and returns a new one. The
+//           returned stream should contain 2-tuples of the streams' combined
+//           values.
+//
+// Returns a combined stream.
++ (instancetype)join:(id<NSFastEnumeration>)streams block:(RACStream * (^)(id, id))block;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACStream.h b/ReactiveCocoaFramework/ReactiveCocoa/RACStream.h
new file mode 100644
index 0000000..8853ffe
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACStream.h
@@ -0,0 +1,321 @@
+//
+//  RACStream.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-31.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACStream;
+
+/// A block which accepts a value from a RACStream and returns a new instance
+/// of the same stream class.
+///
+/// Setting `stop` to `YES` will cause the bind to terminate after the returned
+/// value. Returning `nil` will result in immediate termination.
+typedef RACStream * (^RACStreamBindBlock)(id value, BOOL *stop);
+
+/// An abstract class representing any stream of values.
+///
+/// This class represents a monad, upon which many stream-based operations can
+/// be built.
+///
+/// When subclassing RACStream, only the methods in the main @interface body need
+/// to be overridden.
+@interface RACStream : NSObject
+
+/// Returns an empty stream.
++ (instancetype)empty;
+
+/// Lifts `value` into the stream monad.
+///
+/// Returns a stream containing only the given value.
++ (instancetype)return:(id)value;
+
+/// Lazily binds a block to the values in the receiver.
+///
+/// This should only be used if you need to terminate the bind early, or close
+/// over some state. -flattenMap: is more appropriate for all other cases.
+///
+/// block - A block returning a RACStreamBindBlock. This block will be invoked
+///         each time the bound stream is re-evaluated. This block must not be
+///         nil or return nil.
+///
+/// Returns a new stream which represents the combined result of all lazy
+/// applications of `block`.
+- (instancetype)bind:(RACStreamBindBlock (^)(void))block;
+
+/// Appends the values of `stream` to the values in the receiver.
+///
+/// stream - A stream to concatenate. This must be an instance of the same
+///          concrete class as the receiver, and should not be `nil`.
+///
+/// Returns a new stream representing the receiver followed by `stream`.
+- (instancetype)concat:(RACStream *)stream;
+
+/// Zips the values in the receiver with those of the given stream to create
+/// RACTuples.
+///
+/// The first value of each stream will be combined, then the second value, and
+/// so forth, until at least one of the streams is exhausted.
+///
+/// stream - The stream to zip with. This must be an instance of the same
+///          concrete class as the receiver, and should not be `nil`.
+///
+/// Returns a new stream of RACTuples, representing the zipped values of the
+/// two streams.
+- (instancetype)zipWith:(RACStream *)stream;
+
+@end
+
+/// This extension contains functionality to support naming streams for
+/// debugging.
+///
+/// Subclasses do not need to override the methods here.
+@interface RACStream ()
+
+/// The name of the stream. This is for debugging/human purposes only.
+@property (copy) NSString *name;
+
+/// Sets the name of the receiver to the given format string.
+///
+/// This is for debugging purposes only, and won't do anything unless the
+/// RAC_DEBUG_SIGNAL_NAMES environment variable is set.
+///
+/// Returns the receiver, for easy method chaining.
+- (instancetype)setNameWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2);
+
+@end
+
+/// Operations built on the RACStream primitives.
+///
+/// These methods do not need to be overridden, although subclasses may
+/// occasionally gain better performance from doing so.
+@interface RACStream (Operations)
+
+/// Maps `block` across the values in the receiver and flattens the result.
+///
+/// Note that operators applied _after_ -flattenMap: behave differently from
+/// operators _within_ -flattenMap:. See the Examples section below.
+///
+/// This corresponds to the `SelectMany` method in Rx.
+///
+/// block - A block which accepts the values in the receiver and returns a new
+///         instance of the receiver's class. Returning `nil` from this block is
+///         equivalent to returning an empty signal.
+///
+/// Examples
+///
+///   [signal flattenMap:^(id x) {
+///       // Logs each time a returned signal completes.
+///       return [[RACSignal return:x] logCompleted];
+///   }];
+///
+///   [[signal
+///       flattenMap:^(id x) {
+///           return [RACSignal return:x];
+///       }]
+///       // Logs only once, when all of the signals complete.
+///       logCompleted];
+///
+/// Returns a new stream which represents the combined streams resulting from
+/// mapping `block`.
+- (instancetype)flattenMap:(RACStream * (^)(id value))block;
+
+/// Flattens a stream of streams.
+///
+/// This corresponds to the `Merge` method in Rx.
+///
+/// Returns a stream consisting of the combined streams obtained from the
+/// receiver.
+- (instancetype)flatten;
+
+/// Maps `block` across the values in the receiver.
+///
+/// This corresponds to the `Select` method in Rx.
+///
+/// Returns a new stream with the mapped values.
+- (instancetype)map:(id (^)(id value))block;
+
+/// Replace each value in the receiver with the given object.
+///
+/// Returns a new stream which includes the given object once for each value in
+/// the receiver.
+- (instancetype)mapReplace:(id)object;
+
+/// Filters out values in the receiver that don't pass the given test.
+///
+/// This corresponds to the `Where` method in Rx.
+///
+/// Returns a new stream with only those values that passed.
+- (instancetype)filter:(BOOL (^)(id value))block;
+
+/// Filters out values in the receiver that equal (via -isEqual:) the provided value.
+///
+/// value - The value can be `nil`, in which case it ignores `nil` values.
+///
+/// Returns a new stream containing only the values which did not compare equal
+/// to `value`.
+- (instancetype)ignore:(id)value;
+
+/// Unpacks each RACTuple in the receiver and maps the values to a new value.
+///
+/// reduceBlock - The block which reduces each RACTuple's values into one value.
+///               It must take as many arguments as the number of tuple elements
+///               to process. Each argument will be an object argument. The
+///               return value must be an object. This argument cannot be nil.
+///
+/// Returns a new stream of reduced tuple values.
+- (instancetype)reduceEach:(id (^)())reduceBlock;
+
+/// Returns a stream consisting of `value`, followed by the values in the
+/// receiver.
+- (instancetype)startWith:(id)value;
+
+/// Skips the first `skipCount` values in the receiver.
+///
+/// Returns the receiver after skipping the first `skipCount` values. If
+/// `skipCount` is greater than the number of values in the stream, an empty
+/// stream is returned.
+- (instancetype)skip:(NSUInteger)skipCount;
+
+/// Returns a stream of the first `count` values in the receiver. If `count` is
+/// greater than or equal to the number of values in the stream, a stream
+/// equivalent to the receiver is returned.
+- (instancetype)take:(NSUInteger)count;
+
+/// Zips the values in the given streams to create RACTuples.
+///
+/// The first value of each stream will be combined, then the second value, and
+/// so forth, until at least one of the streams is exhausted.
+///
+/// streams - The streams to combine. These must all be instances of the same
+///           concrete class implementing the protocol. If this collection is
+///           empty, the returned stream will be empty.
+///
+/// Returns a new stream containing RACTuples of the zipped values from the
+/// streams.
++ (instancetype)zip:(id<NSFastEnumeration>)streams;
+
+/// Zips streams using +zip:, then reduces the resulting tuples into a single
+/// value using -reduceEach:
+///
+/// streams     - The streams to combine. These must all be instances of the
+///               same concrete class implementing the protocol. If this
+///               collection is empty, the returned stream will be empty.
+/// reduceBlock - The block which reduces the values from all the streams
+///               into one value. It must take as many arguments as the
+///               number of streams given. Each argument will be an object
+///               argument. The return value must be an object. This argument
+///               must not be nil.
+///
+/// Example:
+///
+///   [RACStream zip:@[ stringSignal, intSignal ] reduce:^(NSString *string, NSNumber *number) {
+///       return [NSString stringWithFormat:@"%@: %@", string, number];
+///   }];
+///
+/// Returns a new stream containing the results from each invocation of
+/// `reduceBlock`.
++ (instancetype)zip:(id<NSFastEnumeration>)streams reduce:(id (^)())reduceBlock;
+
+/// Returns a stream obtained by concatenating `streams` in order.
++ (instancetype)concat:(id<NSFastEnumeration>)streams;
+
+/// Combines values in the receiver from left to right using the given block.
+///
+/// The algorithm proceeds as follows:
+///
+///  1. `startingValue` is passed into the block as the `running` value, and the
+///  first element of the receiver is passed into the block as the `next` value.
+///  2. The result of the invocation is added to the returned stream.
+///  3. The result of the invocation (`running`) and the next element of the
+///  receiver (`next`) is passed into `block`.
+///  4. Steps 2 and 3 are repeated until all values have been processed.
+///
+/// startingValue - The value to be combined with the first element of the
+///                 receiver. This value may be `nil`.
+/// block         - A block that describes how to combine values of the
+///                 receiver. If the receiver is empty, this block will never be
+///                 invoked.
+///
+/// Examples
+///
+///      RACSequence *numbers = @[ @1, @2, @3, @4 ].rac_sequence;
+///
+///      // Contains 1, 3, 6, 10
+///      RACSequence *sums = [numbers scanWithStart:@0 reduce:^(NSNumber *sum, NSNumber *next) {
+///          return @(sum.integerValue + next.integerValue);
+///      }];
+///
+/// Returns a new stream that consists of each application of `block`. If the
+/// receiver is empty, an empty stream is returned.
+- (instancetype)scanWithStart:(id)startingValue reduce:(id (^)(id running, id next))block;
+
+/// Combines each previous and current value into one object.
+///
+/// This method is similar to -scanWithStart:reduce:, but only ever operates on
+/// the previous and current values (instead of the whole stream), and does not
+/// pass the return value of `reduceBlock` into the next invocation of it.
+///
+/// start       - The value passed into `reduceBlock` as `previous` for the
+///               first value.
+/// reduceBlock - The block that combines the previous value and the current
+///               value to create the reduced value. Cannot be nil.
+///
+/// Examples
+///
+///      RACSequence *numbers = @[ @1, @2, @3, @4 ].rac_sequence;
+///
+///      // Contains 1, 3, 5, 7
+///      RACSequence *sums = [numbers combinePreviousWithStart:@0 reduce:^(NSNumber *previous, NSNumber *next) {
+///          return @(previous.integerValue + next.integerValue);
+///      }];
+///
+/// Returns a new stream consisting of the return values from each application of
+/// `reduceBlock`.
+- (instancetype)combinePreviousWithStart:(id)start reduce:(id (^)(id previous, id current))reduceBlock;
+
+/// Takes values until the given block returns `YES`.
+///
+/// Returns a stream of the initial values in the receiver that fail `predicate`.
+/// If `predicate` never returns `YES`, a stream equivalent to the receiver is
+/// returned.
+- (instancetype)takeUntilBlock:(BOOL (^)(id x))predicate;
+
+/// Takes values until the given block returns `NO`.
+///
+/// Returns a stream of the initial values in the receiver that pass `predicate`.
+/// If `predicate` never returns `NO`, a stream equivalent to the receiver is
+/// returned.
+- (instancetype)takeWhileBlock:(BOOL (^)(id x))predicate;
+
+/// Skips values until the given block returns `YES`.
+///
+/// Returns a stream containing the values of the receiver that follow any
+/// initial values failing `predicate`. If `predicate` never returns `YES`,
+/// an empty stream is returned.
+- (instancetype)skipUntilBlock:(BOOL (^)(id x))predicate;
+
+/// Skips values until the given block returns `NO`.
+///
+/// Returns a stream containing the values of the receiver that follow any
+/// initial values passing `predicate`. If `predicate` never returns `NO`, an
+/// empty stream is returned.
+- (instancetype)skipWhileBlock:(BOOL (^)(id x))predicate;
+
+/// Returns a stream of values for which -isEqual: returns NO when compared to the
+/// previous value.
+- (instancetype)distinctUntilChanged;
+
+@end
+
+@interface RACStream (Deprecated)
+
+- (instancetype)sequenceMany:(RACStream * (^)(void))block __attribute__((deprecated("Use -flattenMap: instead")));
+- (instancetype)scanWithStart:(id)startingValue combine:(id (^)(id running, id next))block __attribute__((deprecated("Renamed to -scanWithStart:reduce:")));
+- (instancetype)mapPreviousWithStart:(id)start reduce:(id (^)(id previous, id current))combineBlock __attribute__((deprecated("Renamed to -combinePreviousWithStart:reduce:")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACStream.m b/ReactiveCocoaFramework/ReactiveCocoa/RACStream.m
new file mode 100644
index 0000000..7c37c69
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACStream.m
@@ -0,0 +1,362 @@
+//
+//  RACStream.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-31.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACStream.h"
+#import "NSObject+RACDescription.h"
+#import "RACBlockTrampoline.h"
+#import "RACTuple.h"
+
+@implementation RACStream
+
+#pragma mark Lifecycle
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	self.name = @"";
+	return self;
+}
+
+#pragma mark Abstract methods
+
++ (instancetype)empty {
+	return nil;
+}
+
+- (instancetype)bind:(RACStreamBindBlock (^)(void))block {
+	return nil;
+}
+
++ (instancetype)return:(id)value {
+	return nil;
+}
+
+- (instancetype)concat:(RACStream *)stream {
+	return nil;
+}
+
+- (instancetype)zipWith:(RACStream *)stream {
+	return nil;
+}
+
+#pragma mark Naming
+
+- (instancetype)setNameWithFormat:(NSString *)format, ... {
+	if (getenv("RAC_DEBUG_SIGNAL_NAMES") == NULL) return self;
+
+	NSCParameterAssert(format != nil);
+
+	va_list args;
+	va_start(args, format);
+
+	NSString *str = [[NSString alloc] initWithFormat:format arguments:args];
+	va_end(args);
+
+	self.name = str;
+	return self;
+}
+
+@end
+
+@implementation RACStream (Operations)
+
+- (instancetype)flattenMap:(RACStream * (^)(id value))block {
+	Class class = self.class;
+
+	return [[self bind:^{
+		return ^(id value, BOOL *stop) {
+			id stream = block(value) ?: [class empty];
+			NSCAssert([stream isKindOfClass:RACStream.class], @"Value returned from -flattenMap: is not a stream: %@", stream);
+
+			return stream;
+		};
+	}] setNameWithFormat:@"[%@] -flattenMap:", self.name];
+}
+
+- (instancetype)flatten {
+	__weak RACStream *stream __attribute__((unused)) = self;
+	return [[self flattenMap:^(id value) {
+		return value;
+	}] setNameWithFormat:@"[%@] -flatten", self.name];
+}
+
+- (instancetype)map:(id (^)(id value))block {
+	NSCParameterAssert(block != nil);
+
+	Class class = self.class;
+	
+	return [[self flattenMap:^(id value) {
+		return [class return:block(value)];
+	}] setNameWithFormat:@"[%@] -map:", self.name];
+}
+
+- (instancetype)mapReplace:(id)object {
+	return [[self map:^(id _) {
+		return object;
+	}] setNameWithFormat:@"[%@] -mapReplace: %@", self.name, [object rac_description]];
+}
+
+- (instancetype)combinePreviousWithStart:(id)start reduce:(id (^)(id previous, id next))reduceBlock {
+	NSCParameterAssert(reduceBlock != NULL);
+	return [[[self
+		scanWithStart:[RACTuple tupleWithObjects:start, nil]
+		reduce:^(RACTuple *previousTuple, id next) {
+			id value = reduceBlock(previousTuple[0], next);
+			return [RACTuple tupleWithObjects:next ?: RACTupleNil.tupleNil, value ?: RACTupleNil.tupleNil, nil];
+		}]
+		map:^(RACTuple *tuple) {
+			return tuple[1];
+		}]
+		setNameWithFormat:@"[%@] -combinePreviousWithStart: %@ reduce:", self.name, [start rac_description]];
+}
+
+- (instancetype)filter:(BOOL (^)(id value))block {
+	NSCParameterAssert(block != nil);
+
+	Class class = self.class;
+	
+	return [[self flattenMap:^ id (id value) {
+		if (block(value)) {
+			return [class return:value];
+		} else {
+			return class.empty;
+		}
+	}] setNameWithFormat:@"[%@] -filter:", self.name];
+}
+
+- (instancetype)ignore:(id)value {
+	return [[self filter:^ BOOL (id innerValue) {
+		return innerValue != value && ![innerValue isEqual:value];
+	}] setNameWithFormat:@"[%@] -ignore: %@", self.name, [value rac_description]];
+}
+
+- (instancetype)reduceEach:(id (^)())reduceBlock {
+	NSCParameterAssert(reduceBlock != nil);
+
+	__weak RACStream *stream __attribute__((unused)) = self;
+	return [[self map:^(RACTuple *t) {
+		NSCAssert([t isKindOfClass:RACTuple.class], @"Value from stream %@ is not a tuple: %@", stream, t);
+		return [RACBlockTrampoline invokeBlock:reduceBlock withArguments:t];
+	}] setNameWithFormat:@"[%@] -reduceEach:", self.name];
+}
+
+- (instancetype)startWith:(id)value {
+	return [[[self.class return:value]
+		concat:self]
+		setNameWithFormat:@"[%@] -startWith: %@", self.name, [value rac_description]];
+}
+
+- (instancetype)skip:(NSUInteger)skipCount {
+	Class class = self.class;
+	
+	return [[self bind:^{
+		__block NSUInteger skipped = 0;
+
+		return ^(id value, BOOL *stop) {
+			if (skipped >= skipCount) return [class return:value];
+
+			skipped++;
+			return class.empty;
+		};
+	}] setNameWithFormat:@"[%@] -skip: %lu", self.name, (unsigned long)skipCount];
+}
+
+- (instancetype)take:(NSUInteger)count {
+	Class class = self.class;
+	
+	return [[self bind:^{
+		__block NSUInteger taken = 0;
+
+		return ^ id (id value, BOOL *stop) {
+			RACStream *result = class.empty;
+
+			if (taken < count) result = [class return:value];
+			if (++taken >= count) *stop = YES;
+
+			return result;
+		};
+	}] setNameWithFormat:@"[%@] -take: %lu", self.name, (unsigned long)count];
+}
+
++ (instancetype)join:(id<NSFastEnumeration>)streams block:(RACStream * (^)(id, id))block {
+	RACStream *current = nil;
+
+	// Creates streams of successively larger tuples by combining the input
+	// streams one-by-one.
+	for (RACStream *stream in streams) {
+		// For the first stream, just wrap its values in a RACTuple. That way,
+		// if only one stream is given, the result is still a stream of tuples.
+		if (current == nil) {
+			current = [stream map:^(id x) {
+				return RACTuplePack(x);
+			}];
+
+			continue;
+		}
+
+		current = block(current, stream);
+	}
+
+	if (current == nil) return [self empty];
+
+	return [current map:^(RACTuple *xs) {
+		// Right now, each value is contained in its own tuple, sorta like:
+		//
+		// (((1), 2), 3)
+		//
+		// We need to unwrap all the layers and create a tuple out of the result.
+		NSMutableArray *values = [[NSMutableArray alloc] init];
+
+		while (xs != nil) {
+			[values insertObject:xs.last ?: RACTupleNil.tupleNil atIndex:0];
+			xs = (xs.count > 1 ? xs.first : nil);
+		}
+
+		return [RACTuple tupleWithObjectsFromArray:values];
+	}];
+}
+
++ (instancetype)zip:(id<NSFastEnumeration>)streams {
+	return [[self join:streams block:^(RACStream *left, RACStream *right) {
+		return [left zipWith:right];
+	}] setNameWithFormat:@"+zip: %@", streams];
+}
+
++ (instancetype)zip:(id<NSFastEnumeration>)streams reduce:(id (^)())reduceBlock {
+	NSCParameterAssert(reduceBlock != nil);
+
+	RACStream *result = [self zip:streams];
+
+	// Although we assert this condition above, older versions of this method
+	// supported this argument being nil. Avoid crashing Release builds of
+	// apps that depended on that.
+	if (reduceBlock != nil) result = [result reduceEach:reduceBlock];
+
+	return [result setNameWithFormat:@"+zip: %@ reduce:", streams];
+}
+
++ (instancetype)concat:(id<NSFastEnumeration>)streams {
+	RACStream *result = self.empty;
+	for (RACStream *stream in streams) {
+		result = [result concat:stream];
+	}
+
+	return [result setNameWithFormat:@"+concat: %@", streams];
+}
+
+- (instancetype)scanWithStart:(id)startingValue reduce:(id (^)(id running, id next))block {
+	NSCParameterAssert(block != nil);
+
+	Class class = self.class;
+	
+	return [[self bind:^{
+		__block id running = startingValue;
+
+		return ^(id value, BOOL *stop) {
+			running = block(running, value);
+			return [class return:running];
+		};
+	}] setNameWithFormat:@"[%@] -scanWithStart: %@ reduce:", self.name, [startingValue rac_description]];
+}
+
+- (instancetype)takeUntilBlock:(BOOL (^)(id x))predicate {
+	NSCParameterAssert(predicate != nil);
+
+	Class class = self.class;
+	
+	return [[self bind:^{
+		return ^ id (id value, BOOL *stop) {
+			if (predicate(value)) return nil;
+
+			return [class return:value];
+		};
+	}] setNameWithFormat:@"[%@] -takeUntilBlock:", self.name];
+}
+
+- (instancetype)takeWhileBlock:(BOOL (^)(id x))predicate {
+	NSCParameterAssert(predicate != nil);
+
+	return [[self takeUntilBlock:^ BOOL (id x) {
+		return !predicate(x);
+	}] setNameWithFormat:@"[%@] -takeWhileBlock:", self.name];
+}
+
+- (instancetype)skipUntilBlock:(BOOL (^)(id x))predicate {
+	NSCParameterAssert(predicate != nil);
+
+	Class class = self.class;
+	
+	return [[self bind:^{
+		__block BOOL skipping = YES;
+
+		return ^ id (id value, BOOL *stop) {
+			if (skipping) {
+				if (predicate(value)) {
+					skipping = NO;
+				} else {
+					return class.empty;
+				}
+			}
+
+			return [class return:value];
+		};
+	}] setNameWithFormat:@"[%@] -skipUntilBlock:", self.name];
+}
+
+- (instancetype)skipWhileBlock:(BOOL (^)(id x))predicate {
+	NSCParameterAssert(predicate != nil);
+
+	return [[self skipUntilBlock:^ BOOL (id x) {
+		return !predicate(x);
+	}] setNameWithFormat:@"[%@] -skipUntilBlock:", self.name];
+}
+
+- (instancetype)distinctUntilChanged {
+	Class class = self.class;
+
+	return [[self bind:^{
+		__block id lastValue = nil;
+		__block BOOL initial = YES;
+
+		return ^(id x, BOOL *stop) {
+			if (!initial && (lastValue == x || [x isEqual:lastValue])) return [class empty];
+
+			initial = NO;
+			lastValue = x;
+			return [class return:x];
+		};
+	}] setNameWithFormat:@"[%@] -distinctUntilChanged", self.name];
+}
+
+@end
+
+@implementation RACStream (Deprecated)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (instancetype)sequenceMany:(RACStream * (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	return [[self flattenMap:^(id _) {
+		return block();
+	}] setNameWithFormat:@"[%@] -sequenceMany:", self.name];
+}
+
+- (instancetype)scanWithStart:(id)startingValue combine:(id (^)(id running, id next))block {
+	return [self scanWithStart:startingValue reduce:block];
+}
+
+- (instancetype)mapPreviousWithStart:(id)start reduce:(id (^)(id previous, id current))combineBlock {
+	return [self combinePreviousWithStart:start reduce:combineBlock];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.h
new file mode 100644
index 0000000..b37ddea
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.h
@@ -0,0 +1,18 @@
+//
+//  RACStringSequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class that adapts a string to the RACSequence interface.
+@interface RACStringSequence : RACSequence
+
+// Returns a sequence for enumerating over the given string, starting from the
+// given character offset. The string will be copied to prevent mutation.
++ (RACSequence *)sequenceWithString:(NSString *)string offset:(NSUInteger)offset;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.m
new file mode 100644
index 0000000..dd10f3c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACStringSequence.m
@@ -0,0 +1,65 @@
+//
+//  RACStringSequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2012-10-29.
+//  Copyright (c) 2012 GitHub. All rights reserved.
+//
+
+#import "RACStringSequence.h"
+
+@interface RACStringSequence ()
+
+// The string being sequenced.
+@property (nonatomic, copy, readonly) NSString *string;
+
+// The index in the string from which the sequence starts.
+@property (nonatomic, assign, readonly) NSUInteger offset;
+
+@end
+
+@implementation RACStringSequence
+
+#pragma mark Lifecycle
+
++ (RACSequence *)sequenceWithString:(NSString *)string offset:(NSUInteger)offset {
+	NSCParameterAssert(offset <= string.length);
+
+	if (offset == string.length) return self.empty;
+
+	RACStringSequence *seq = [[self alloc] init];
+	seq->_string = [string copy];
+	seq->_offset = offset;
+	return seq;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	return [self.string substringWithRange:NSMakeRange(self.offset, 1)];
+}
+
+- (RACSequence *)tail {
+	RACSequence *sequence = [self.class sequenceWithString:self.string offset:self.offset + 1];
+	sequence.name = self.name;
+	return sequence;
+}
+
+- (NSArray *)array {
+	NSUInteger substringLength = self.string.length - self.offset;
+	NSMutableArray *array = [NSMutableArray arrayWithCapacity:substringLength];
+
+	[self.string enumerateSubstringsInRange:NSMakeRange(self.offset, substringLength) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
+		[array addObject:substring];
+	}];
+
+	return [array copy];
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, string = %@ }", self.class, self, self.name, [self.string substringFromIndex:self.offset]];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.h
new file mode 100644
index 0000000..30c100b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.h
@@ -0,0 +1,22 @@
+//
+//  RACSubject.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/9/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSignal.h"
+#import "RACSubscriber.h"
+
+/// A subject can be thought of as a signal that you can manually control by
+/// sending next, completed, and error.
+///
+/// They're most helpful in bridging the non-RAC world to RAC, since they let you
+/// manually control the sending of events.
+@interface RACSubject : RACSignal <RACSubscriber>
+
+/// Returns a new subject.
++ (instancetype)subject;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.m
new file mode 100644
index 0000000..3c155ab
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubject.m
@@ -0,0 +1,124 @@
+//
+//  RACSubject.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/9/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubject.h"
+#import "RACEXTScope.h"
+#import "RACCompoundDisposable.h"
+#import "RACPassthroughSubscriber.h"
+
+@interface RACSubject ()
+
+// Contains all current subscribers to the receiver.
+//
+// This should only be used while synchronized on `self`.
+@property (nonatomic, strong, readonly) NSMutableArray *subscribers;
+
+// Contains all of the receiver's subscriptions to other signals.
+@property (nonatomic, strong, readonly) RACCompoundDisposable *disposable;
+
+// Enumerates over each of the receiver's `subscribers` and invokes `block` for
+// each.
+- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block;
+
+@end
+
+@implementation RACSubject
+
+#pragma mark Lifecycle
+
++ (instancetype)subject {
+	return [[self alloc] init];
+}
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	_disposable = [RACCompoundDisposable compoundDisposable];
+	_subscribers = [[NSMutableArray alloc] initWithCapacity:1];
+	
+	return self;
+}
+
+- (void)dealloc {
+	[self.disposable dispose];
+}
+
+#pragma mark Subscription
+
+- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
+	NSCParameterAssert(subscriber != nil);
+
+	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
+	subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
+
+	NSMutableArray *subscribers = self.subscribers;
+	@synchronized (subscribers) {
+		[subscribers addObject:subscriber];
+	}
+	
+	return [RACDisposable disposableWithBlock:^{
+		@synchronized (subscribers) {
+			// Since newer subscribers are generally shorter-lived, search
+			// starting from the end of the list.
+			NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
+				return obj == subscriber;
+			}];
+
+			if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
+		}
+	}];
+}
+
+- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block {
+	NSArray *subscribers;
+	@synchronized (self.subscribers) {
+		subscribers = [self.subscribers copy];
+	}
+
+	for (id<RACSubscriber> subscriber in subscribers) {
+		block(subscriber);
+	}
+}
+
+#pragma mark RACSubscriber
+
+- (void)sendNext:(id)value {
+	[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
+		[subscriber sendNext:value];
+	}];
+}
+
+- (void)sendError:(NSError *)error {
+	[self.disposable dispose];
+	
+	[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
+		[subscriber sendError:error];
+	}];
+}
+
+- (void)sendCompleted {
+	[self.disposable dispose];
+	
+	[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
+		[subscriber sendCompleted];
+	}];
+}
+
+- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)d {
+	if (d.disposed) return;
+	[self.disposable addDisposable:d];
+
+	@weakify(self, d);
+	[d addDisposable:[RACDisposable disposableWithBlock:^{
+		@strongify(self, d);
+		[self.disposable removeDisposable:d];
+	}]];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber+Private.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber+Private.h
new file mode 100644
index 0000000..0ad81d2
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber+Private.h
@@ -0,0 +1,17 @@
+//
+//  RACSubscriber+Private.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-06-13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubscriber.h"
+
+// A simple block-based subscriber.
+@interface RACSubscriber : NSObject <RACSubscriber>
+
+// Creates a new subscriber with the given blocks.
++ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.h
new file mode 100644
index 0000000..173e6dc
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.h
@@ -0,0 +1,51 @@
+//
+//  RACSubscriber.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/1/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class RACCompoundDisposable;
+
+/// Represents any object which can directly receive values from a RACSignal.
+///
+/// You generally shouldn't need to implement this protocol. +[RACSignal
+/// createSignal:], RACSignal's subscription methods, or RACSubject should work
+/// for most uses.
+///
+/// Implementors of this protocol may receive messages and values from multiple
+/// threads simultaneously, and so should be thread-safe. Subscribers will also
+/// be weakly referenced so implementations must allow that.
+@protocol RACSubscriber <NSObject>
+@required
+
+/// Send the next value to subscribers.
+///
+/// value - The value to send. This can be `nil`.
+- (void)sendNext:(id)value;
+
+/// Send the error to subscribers.
+///
+/// error - The error to send. This can be `nil`.
+///
+/// This terminates the subscription, and invalidates the subscriber (such that
+/// it cannot subscribe to anything else in the future).
+- (void)sendError:(NSError *)error;
+
+/// Send completed to subscribers.
+///
+/// This terminates the subscription, and invalidates the subscriber (such that
+/// it cannot subscribe to anything else in the future).
+- (void)sendCompleted;
+
+/// Sends the subscriber a disposable that represents one of its subscriptions.
+///
+/// A subscriber may receive multiple disposables if it gets subscribed to
+/// multiple signals; however, any error or completed events must terminate _all_
+/// subscriptions.
+- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.m
new file mode 100644
index 0000000..1237077
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriber.m
@@ -0,0 +1,108 @@
+//
+//  RACSubscriber.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/1/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubscriber.h"
+#import "RACSubscriber+Private.h"
+#import "RACEXTScope.h"
+#import "RACCompoundDisposable.h"
+
+@interface RACSubscriber ()
+
+// These callbacks should only be accessed while synchronized on self.
+@property (nonatomic, copy) void (^next)(id value);
+@property (nonatomic, copy) void (^error)(NSError *error);
+@property (nonatomic, copy) void (^completed)(void);
+
+@property (nonatomic, strong, readonly) RACCompoundDisposable *disposable;
+
+@end
+
+@implementation RACSubscriber
+
+#pragma mark Lifecycle
+
++ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {
+	RACSubscriber *subscriber = [[self alloc] init];
+
+	subscriber->_next = [next copy];
+	subscriber->_error = [error copy];
+	subscriber->_completed = [completed copy];
+
+	return subscriber;
+}
+
+- (id)init {
+	self = [super init];
+	if (self == nil) return nil;
+
+	@weakify(self);
+
+	RACDisposable *selfDisposable = [RACDisposable disposableWithBlock:^{
+		@strongify(self);
+		if (self == nil) return;
+
+		@synchronized (self) {
+			self.next = nil;
+			self.error = nil;
+			self.completed = nil;
+		}
+	}];
+
+	_disposable = [RACCompoundDisposable compoundDisposable];
+	[_disposable addDisposable:selfDisposable];
+	
+	return self;
+}
+
+- (void)dealloc {
+	[self.disposable dispose];
+}
+
+#pragma mark RACSubscriber
+
+- (void)sendNext:(id)value {
+	@synchronized (self) {
+		void (^nextBlock)(id) = [self.next copy];
+		if (nextBlock == nil) return;
+
+		nextBlock(value);
+	}
+}
+
+- (void)sendError:(NSError *)e {
+	@synchronized (self) {
+		void (^errorBlock)(NSError *) = [self.error copy];
+		[self.disposable dispose];
+
+		if (errorBlock == nil) return;
+		errorBlock(e);
+	}
+}
+
+- (void)sendCompleted {
+	@synchronized (self) {
+		void (^completedBlock)(void) = [self.completed copy];
+		[self.disposable dispose];
+
+		if (completedBlock == nil) return;
+		completedBlock();
+	}
+}
+
+- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)d {
+	if (d.disposed) return;
+	[self.disposable addDisposable:d];
+
+	@weakify(self, d);
+	[d addDisposable:[RACDisposable disposableWithBlock:^{
+		@strongify(self, d);
+		[self.disposable removeDisposable:d];
+	}]];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h
new file mode 100644
index 0000000..a95b496
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h
@@ -0,0 +1,54 @@
+//
+//  RACSubscriptingAssignmentTrampoline.h
+//  iOSDemo
+//
+//  Created by Josh Abernathy on 9/24/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACEXTKeyPathCoding.h"
+
+@class RACSignal;
+
+/// Assigns a signal to an object property, automatically setting the given key
+/// path on every `next`. When the signal completes, the binding is automatically
+/// disposed of.
+///
+/// There are two different versions of this macro:
+///
+///  - RAC(TARGET, KEYPATH, NILVALUE) will bind the `KEYPATH` of `TARGET` to the
+///    given signal. If the signal ever sends a `nil` value, the property will be
+///    set to `NILVALUE` instead. `NILVALUE` may itself be `nil` for object
+///    properties, but an NSValue should be used for primitive properties, to
+///    avoid an exception if `nil` is sent (which might occur if an intermediate
+///    object is set to `nil`).
+///  - RAC(TARGET, KEYPATH) is the same as the above, but `NILVALUE` defaults to
+///    `nil`.
+///
+/// See -[RACSignal setKeyPath:onObject:nilValue:] for more information about the
+/// binding's semantics.
+///
+/// Examples
+///
+///  RAC(self, objectProperty) = objectSignal;
+///  RAC(self, stringProperty, @"foobar") = stringSignal;
+///  RAC(self, integerProperty, @42) = integerSignal;
+///
+/// WARNING: Under certain conditions, use of this macro can be thread-unsafe.
+///          See the documentation of -setKeyPath:onObject:nilValue:.
+#define RAC(TARGET, ...) \
+    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
+        (RAC_(TARGET, __VA_ARGS__, nil)) \
+        (RAC_(TARGET, __VA_ARGS__))
+
+/// Do not use this directly. Use the RAC macro above.
+#define RAC_(TARGET, KEYPATH, NILVALUE) \
+    [[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(TARGET) nilValue:(NILVALUE)][@keypath(TARGET, KEYPATH)]
+
+@interface RACSubscriptingAssignmentTrampoline : NSObject
+
+- (id)initWithTarget:(id)target nilValue:(id)nilValue;
+- (void)setObject:(RACSignal *)signal forKeyedSubscript:(NSString *)keyPath;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.m
new file mode 100644
index 0000000..2ab8cd3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptingAssignmentTrampoline.m
@@ -0,0 +1,42 @@
+//
+//  RACSubscriptingAssignmentTrampoline.m
+//  iOSDemo
+//
+//  Created by Josh Abernathy on 9/24/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubscriptingAssignmentTrampoline.h"
+#import "RACSignal+Operations.h"
+
+@interface RACSubscriptingAssignmentTrampoline ()
+
+// The object to bind to.
+@property (nonatomic, strong, readonly) id target;
+
+// A value to use when `nil` is sent on the bound signal.
+@property (nonatomic, strong, readonly) id nilValue;
+
+@end
+
+@implementation RACSubscriptingAssignmentTrampoline
+
+- (id)initWithTarget:(id)target nilValue:(id)nilValue {
+	// This is often a programmer error, but this prevents crashes if the target
+	// object has unexpectedly deallocated.
+	if (target == nil) return nil;
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_target = target;
+	_nilValue = nilValue;
+
+	return self;
+}
+
+- (void)setObject:(RACSignal *)signal forKeyedSubscript:(NSString *)keyPath {
+	[signal setKeyPath:keyPath onObject:self.target nilValue:self.nilValue];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.h
new file mode 100644
index 0000000..34f5dc5
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.h
@@ -0,0 +1,15 @@
+//
+//  RACSubscriptionScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+
+// A private scheduler used only for subscriptions. See the private
+// +[RACScheduler subscriptionScheduler] method for more information.
+@interface RACSubscriptionScheduler : RACScheduler
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.m
new file mode 100644
index 0000000..2aab9c3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACSubscriptionScheduler.m
@@ -0,0 +1,54 @@
+//
+//  RACSubscriptionScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 11/30/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSubscriptionScheduler.h"
+#import "RACScheduler+Private.h"
+
+@interface RACSubscriptionScheduler ()
+
+// A private background scheduler on which to subscribe if the +currentScheduler
+// is unknown.
+@property (nonatomic, strong, readonly) RACScheduler *backgroundScheduler;
+
+@end
+
+@implementation RACSubscriptionScheduler
+
+#pragma mark Lifecycle
+
+- (id)init {
+	self = [super initWithName:@"com.ReactiveCocoa.RACScheduler.subscriptionScheduler"];
+	if (self == nil) return nil;
+
+	_backgroundScheduler = [RACScheduler scheduler];
+
+	return self;
+}
+
+#pragma mark RACScheduler
+
+- (RACDisposable *)schedule:(void (^)(void))block {
+	NSCParameterAssert(block != NULL);
+
+	if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];
+
+	block();
+	return nil;
+}
+
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
+	RACScheduler *scheduler = RACScheduler.currentScheduler ?: self.backgroundScheduler;
+	return [scheduler after:date schedule:block];
+}
+
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
+	RACScheduler *scheduler = RACScheduler.currentScheduler ?: self.backgroundScheduler;
+	return [scheduler after:date repeatingEvery:interval withLeeway:leeway schedule:block];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.h
new file mode 100644
index 0000000..429e595
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.h
@@ -0,0 +1,24 @@
+//
+//  RACTargetQueueScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 6/6/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACQueueScheduler.h"
+
+/// A scheduler that enqueues blocks on a private serial queue, targeting an
+/// arbitrary GCD queue.
+@interface RACTargetQueueScheduler : RACQueueScheduler
+
+/// Initializes the receiver with a serial queue that will target the given
+/// `targetQueue`.
+///
+/// name        - The name of the scheduler. If nil, a default name will be used.
+/// targetQueue - The queue to target. Cannot be NULL.
+///
+/// Returns the initialized object.
+- (id)initWithName:(NSString *)name targetQueue:(dispatch_queue_t)targetQueue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.m
new file mode 100644
index 0000000..65114d3
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTargetQueueScheduler.m
@@ -0,0 +1,37 @@
+//
+//  RACTargetQueueScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 6/6/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACTargetQueueScheduler.h"
+#import "RACBacktrace.h"
+#import "RACQueueScheduler+Subclass.h"
+
+@implementation RACTargetQueueScheduler
+
+#pragma mark Lifecycle
+
+- (id)initWithName:(NSString *)name targetQueue:(dispatch_queue_t)targetQueue {
+	NSCParameterAssert(targetQueue != NULL);
+
+	if (name == nil) {
+		name = [NSString stringWithFormat:@"com.ReactiveCocoa.RACTargetQueueScheduler(%s)", dispatch_queue_get_label(targetQueue)];
+	}
+
+	dispatch_queue_t queue = dispatch_queue_create(name.UTF8String, DISPATCH_QUEUE_SERIAL);
+	if (queue == NULL) return nil;
+
+	dispatch_set_target_queue(queue, targetQueue);
+
+	self = [super initWithName:name queue:queue];
+	if (self == nil) return nil;
+
+	dispatch_release(queue);
+
+	return self;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.h b/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.h
new file mode 100644
index 0000000..a790f5b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.h
@@ -0,0 +1,42 @@
+//
+//  RACTestScheduler.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-06.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACScheduler.h"
+
+/// A special kind of scheduler that steps through virtualized time.
+///
+/// This scheduler class can be used in unit tests to verify asynchronous
+/// behaviors without spending significant time waiting.
+///
+/// This class can be used from multiple threads, but only one thread can `step`
+/// through the enqueued actions at a time. Other threads will wait while the
+/// scheduled blocks are being executed.
+@interface RACTestScheduler : RACScheduler
+
+/// Initializes a new test scheduler.
+- (instancetype)init;
+
+/// Executes the next scheduled block, if any.
+///
+/// This method will block until the scheduled action has completed.
+- (void)step;
+
+/// Executes up to the next `ticks` scheduled blocks.
+///
+/// This method will block until the scheduled actions have completed.
+///
+/// ticks - The number of scheduled blocks to execute. If there aren't this many
+///         blocks enqueued, all scheduled blocks are executed.
+- (void)step:(NSUInteger)ticks;
+
+/// Executes all of the scheduled blocks on the receiver.
+///
+/// This method will block until the scheduled actions have completed.
+- (void)stepAll;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.m b/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.m
new file mode 100644
index 0000000..374fbe2
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTestScheduler.m
@@ -0,0 +1,223 @@
+//
+//  RACTestScheduler.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-06.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACTestScheduler.h"
+#import "RACEXTScope.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACScheduler+Private.h"
+
+@interface RACTestSchedulerAction : NSObject
+
+// The date at which the action should be executed.
+//
+// This absolute time will not actually be honored. This date is only used for
+// comparison, to determine which block should be run _next_.
+@property (nonatomic, copy, readonly) NSDate *date;
+
+// The scheduled block.
+@property (nonatomic, copy, readonly) void (^block)(void);
+
+// A disposable for this action.
+//
+// When disposed, the action should not start executing if it hasn't already.
+@property (nonatomic, strong, readonly) RACDisposable *disposable;
+
+// Initializes a new scheduler action.
+- (id)initWithDate:(NSDate *)date block:(void (^)(void))block;
+
+@end
+
+static CFComparisonResult RACCompareScheduledActions(const void *ptr1, const void *ptr2, void *info) {
+	RACTestSchedulerAction *action1 = (__bridge id)ptr1;
+	RACTestSchedulerAction *action2 = (__bridge id)ptr2;
+	return CFDateCompare((__bridge CFDateRef)action1.date, (__bridge CFDateRef)action2.date, NULL);
+}
+
+static const void *RACRetainScheduledAction(CFAllocatorRef allocator, const void *ptr) {
+	return CFRetain(ptr);
+}
+
+static void RACReleaseScheduledAction(CFAllocatorRef allocator, const void *ptr) {
+	CFRelease(ptr);
+}
+
+@interface RACTestScheduler ()
+
+// All of the RACTestSchedulerActions that have been enqueued and not yet
+// executed.
+//
+// The minimum value in the heap represents the action to execute next.
+//
+// This property should only be used while synchronized on self.
+@property (nonatomic, assign, readonly) CFBinaryHeapRef scheduledActions;
+
+// The number of blocks that have been directly enqueued with -schedule: so
+// far.
+//
+// This is used to ensure unique dates when two blocks are enqueued
+// simultaneously.
+//
+// This property should only be used while synchronized on self.
+@property (nonatomic, assign) NSUInteger numberOfDirectlyScheduledBlocks;
+
+@end
+
+@implementation RACTestScheduler
+
+#pragma mark Lifecycle
+
+- (instancetype)init {
+	self = [super initWithName:@"com.github.ReactiveCocoa.RACTestScheduler"];
+	if (self == nil) return nil;
+
+	CFBinaryHeapCallBacks callbacks = (CFBinaryHeapCallBacks){
+		.version = 0,
+		.retain = &RACRetainScheduledAction,
+		.release = &RACReleaseScheduledAction,
+		.copyDescription = &CFCopyDescription,
+		.compare = &RACCompareScheduledActions
+	};
+
+	_scheduledActions = CFBinaryHeapCreate(NULL, 0, &callbacks, NULL);
+	return self;
+}
+
+- (void)dealloc {
+	[self stepAll];
+
+	if (_scheduledActions != NULL) {
+		CFRelease(_scheduledActions);
+		_scheduledActions = NULL;
+	}
+}
+
+#pragma mark Execution
+
+- (void)step {
+	[self step:1];
+}
+
+- (void)step:(NSUInteger)ticks {
+	@synchronized (self) {
+		for (NSUInteger i = 0; i < ticks; i++) {
+			const void *actionPtr = NULL;
+			if (!CFBinaryHeapGetMinimumIfPresent(self.scheduledActions, &actionPtr)) break;
+
+			RACTestSchedulerAction *action = (__bridge id)actionPtr;
+			CFBinaryHeapRemoveMinimumValue(self.scheduledActions);
+
+			if (action.disposable.disposed) continue;
+			
+			RACScheduler *previousScheduler = RACScheduler.currentScheduler;
+			NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = self;
+
+			action.block();
+
+			if (previousScheduler != nil) {
+				NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = previousScheduler;
+			} else {
+				[NSThread.currentThread.threadDictionary removeObjectForKey:RACSchedulerCurrentSchedulerKey];
+			}
+		}
+	}
+}
+
+- (void)stepAll {
+	[self step:NSUIntegerMax];
+}
+
+#pragma mark RACScheduler
+
+- (RACDisposable *)schedule:(void (^)(void))block {
+	NSCParameterAssert(block != nil);
+
+	@synchronized (self) {
+		NSDate *uniqueDate = [NSDate dateWithTimeIntervalSinceReferenceDate:self.numberOfDirectlyScheduledBlocks];
+		self.numberOfDirectlyScheduledBlocks++;
+
+		RACTestSchedulerAction *action = [[RACTestSchedulerAction alloc] initWithDate:uniqueDate block:block];
+		CFBinaryHeapAddValue(self.scheduledActions, (__bridge void *)action);
+
+		return action.disposable;
+	}
+}
+
+- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(block != nil);
+
+	@synchronized (self) {
+		RACTestSchedulerAction *action = [[RACTestSchedulerAction alloc] initWithDate:date block:block];
+		CFBinaryHeapAddValue(self.scheduledActions, (__bridge void *)action);
+
+		return action.disposable;
+	}
+}
+
+- (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(block != nil);
+	NSCParameterAssert(interval >= 0);
+	NSCParameterAssert(leeway >= 0);
+
+	RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
+
+	@weakify(self);
+	@synchronized (self) {
+		__block RACDisposable *thisDisposable = nil;
+
+		void (^reschedulingBlock)(void) = ^{
+			@strongify(self);
+
+			[compoundDisposable removeDisposable:thisDisposable];
+
+			// Schedule the next interval.
+			RACDisposable *schedulingDisposable = [self after:[date dateByAddingTimeInterval:interval] repeatingEvery:interval withLeeway:leeway schedule:block];
+			[compoundDisposable addDisposable:schedulingDisposable];
+		
+			block();
+		};
+
+		RACTestSchedulerAction *action = [[RACTestSchedulerAction alloc] initWithDate:date block:reschedulingBlock];
+		CFBinaryHeapAddValue(self.scheduledActions, (__bridge void *)action);
+
+		thisDisposable = action.disposable;
+		[compoundDisposable addDisposable:thisDisposable];
+	}
+
+	return compoundDisposable;
+}
+
+@end
+
+@implementation RACTestSchedulerAction
+
+#pragma mark Lifecycle
+
+- (id)initWithDate:(NSDate *)date block:(void (^)(void))block {
+	NSCParameterAssert(date != nil);
+	NSCParameterAssert(block != nil);
+
+	self = [super init];
+	if (self == nil) return nil;
+
+	_date = [date copy];
+	_block = [block copy];
+	_disposable = [[RACDisposable alloc] init];
+
+	return self;
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ date: %@ }", self.class, self, self.date];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.h b/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.h
new file mode 100644
index 0000000..c364630
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.h
@@ -0,0 +1,159 @@
+//
+//  RACTuple.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/12/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACmetamacros.h"
+
+@class RACSequence;
+
+/// Creates a new tuple with the given values. At least one value must be given.
+/// Values can be nil.
+#define RACTuplePack(...) \
+    RACTuplePack_(__VA_ARGS__)
+
+/// Declares new object variables and unpacks a RACTuple into them.
+///
+/// This macro should be used on the left side of an assignment, with the
+/// tuple on the right side. Nothing else should appear on the same line, and the
+/// macro should not be the only statement in a conditional or loop body.
+///
+/// If the tuple has more values than there are variables listed, the excess
+/// values are ignored.
+///
+/// If the tuple has fewer values than there are variables listed, the excess
+/// variables are initialized to nil.
+///
+/// Examples
+///
+///   RACTupleUnpack(NSString *string, NSNumber *num) = [RACTuple tupleWithObjects:@"foo", @5, nil];
+///   NSLog(@"string: %@", string);
+///   NSLog(@"num: %@", num);
+///
+///   /* The above is equivalent to: */
+///   RACTuple *t = [RACTuple tupleWithObjects:@"foo", @5, nil];
+///   NSString *string = t[0];
+///   NSNumber *num = t[1];
+///   NSLog(@"string: %@", string);
+///   NSLog(@"num: %@", num);
+#define RACTupleUnpack(...) \
+        RACTupleUnpack_(__VA_ARGS__)
+
+/// A sentinel object that represents nils in the tuple.
+///
+/// It should never be necessary to create a tuple nil yourself. Just use
+/// +tupleNil.
+@interface RACTupleNil : NSObject <NSCopying, NSCoding>
+/// A singleton instance.
++ (RACTupleNil *)tupleNil;
+@end
+
+
+/// A tuple is an ordered collection of objects. It may contain nils, represented
+/// by RACTupleNil.
+@interface RACTuple : NSObject <NSCoding, NSCopying, NSFastEnumeration>
+
+@property (nonatomic, readonly) NSUInteger count;
+
+/// These properties all return the object at that index or nil if the number of 
+/// objects is less than the index.
+@property (nonatomic, readonly) id first;
+@property (nonatomic, readonly) id second;
+@property (nonatomic, readonly) id third;
+@property (nonatomic, readonly) id fourth;
+@property (nonatomic, readonly) id fifth;
+@property (nonatomic, readonly) id last;
+
+/// Creates a new tuple out of the array. Does not convert nulls to nils.
++ (instancetype)tupleWithObjectsFromArray:(NSArray *)array;
+
+/// Creates a new tuple out of the array. If `convert` is YES, it also converts
+/// every NSNull to RACTupleNil.
++ (instancetype)tupleWithObjectsFromArray:(NSArray *)array convertNullsToNils:(BOOL)convert;
+
+/// Creates a new tuple with the given objects. Use RACTupleNil to represent
+/// nils.
++ (instancetype)tupleWithObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;
+
+/// Returns the object at `index` or nil if the object is a RACTupleNil. Unlike
+/// NSArray and friends, it's perfectly fine to ask for the object at an index
+/// past the tuple's count - 1. It will simply return nil.
+- (id)objectAtIndex:(NSUInteger)index;
+
+/// Returns an array of all the objects. RACTupleNils are converted to NSNulls.
+- (NSArray *)allObjects;
+
+/// Appends `obj` to the receiver.
+///
+/// obj - The object to add to the tuple. This argument may be nil.
+///
+/// Returns a new tuple.
+- (instancetype)tupleByAddingObject:(id)obj;
+
+@end
+
+@interface RACTuple (RACSequenceAdditions)
+
+/// Returns a sequence of all the objects. RACTupleNils are converted to NSNulls.
+@property (nonatomic, copy, readonly) RACSequence *rac_sequence;
+
+@end
+
+@interface RACTuple (ObjectSubscripting)
+/// Returns the object at that index or nil if the number of objects is less
+/// than the index.
+- (id)objectAtIndexedSubscript:(NSUInteger)idx; 
+@end
+
+/// This and everything below is for internal use only.
+///
+/// See RACTuplePack() and RACTupleUnpack() instead.
+#define RACTuplePack_(...) \
+    ([RACTuple tupleWithObjectsFromArray:@[ metamacro_foreach(RACTuplePack_object_or_ractuplenil,, __VA_ARGS__) ]])
+
+#define RACTuplePack_object_or_ractuplenil(INDEX, ARG) \
+    (ARG) ?: RACTupleNil.tupleNil,
+
+#define RACTupleUnpack_(...) \
+    metamacro_foreach(RACTupleUnpack_decl,, __VA_ARGS__) \
+    \
+    int RACTupleUnpack_state = 0; \
+    \
+    RACTupleUnpack_after: \
+        ; \
+        metamacro_foreach(RACTupleUnpack_assign,, __VA_ARGS__) \
+        if (RACTupleUnpack_state != 0) RACTupleUnpack_state = 2; \
+        \
+        while (RACTupleUnpack_state != 2) \
+            if (RACTupleUnpack_state == 1) { \
+                goto RACTupleUnpack_after; \
+            } else \
+                for (; RACTupleUnpack_state != 1; RACTupleUnpack_state = 1) \
+                    [RACTupleUnpackingTrampoline trampoline][ @[ metamacro_foreach(RACTupleUnpack_value,, __VA_ARGS__) ] ]
+
+#define RACTupleUnpack_state metamacro_concat(RACTupleUnpack_state, __LINE__)
+#define RACTupleUnpack_after metamacro_concat(RACTupleUnpack_after, __LINE__)
+#define RACTupleUnpack_loop metamacro_concat(RACTupleUnpack_loop, __LINE__)
+
+#define RACTupleUnpack_decl_name(INDEX) \
+    metamacro_concat(metamacro_concat(RACTupleUnpack, __LINE__), metamacro_concat(_var, INDEX))
+
+#define RACTupleUnpack_decl(INDEX, ARG) \
+    __strong id RACTupleUnpack_decl_name(INDEX);
+
+#define RACTupleUnpack_assign(INDEX, ARG) \
+    __strong ARG = RACTupleUnpack_decl_name(INDEX);
+
+#define RACTupleUnpack_value(INDEX, ARG) \
+    [NSValue valueWithPointer:&RACTupleUnpack_decl_name(INDEX)],
+
+@interface RACTupleUnpackingTrampoline : NSObject
+
++ (instancetype)trampoline;
+- (void)setObject:(RACTuple *)tuple forKeyedSubscript:(NSArray *)variables;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.m b/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.m
new file mode 100644
index 0000000..c3e979c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTuple.m
@@ -0,0 +1,252 @@
+//
+//  RACTuple.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/12/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACTuple.h"
+#import "RACEXTKeyPathCoding.h"
+#import "RACTupleSequence.h"
+
+@implementation RACTupleNil
+
++ (RACTupleNil *)tupleNil {
+	static dispatch_once_t onceToken;
+	static RACTupleNil *tupleNil = nil;
+	dispatch_once(&onceToken, ^{
+		tupleNil = [[self alloc] init];
+	});
+	
+	return tupleNil;
+}
+
+#pragma mark NSCopying
+
+- (id)copyWithZone:(NSZone *)zone {
+	return self;
+}
+
+#pragma mark NSCoding
+
+- (id)initWithCoder:(NSCoder *)coder {
+	// Always return the singleton.
+	return self.class.tupleNil;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+}
+
+@end
+
+
+@interface RACTuple ()
+@property (nonatomic, strong) NSArray *backingArray;
+@end
+
+
+@implementation RACTuple
+
+- (instancetype)init {
+	self = [super init];
+	if (self == nil) return nil;
+	
+	self.backingArray = [NSArray array];
+	
+	return self;
+}
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, self.allObjects];
+}
+
+- (BOOL)isEqual:(RACTuple *)object {
+	if (object == self) return YES;
+	if (![object isKindOfClass:self.class]) return NO;
+	
+	return [self.backingArray isEqual:object.backingArray];
+}
+
+- (NSUInteger)hash {
+	return self.backingArray.hash;
+}
+
+
+#pragma mark NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len {
+	return [self.backingArray countByEnumeratingWithState:state objects:buffer count:len];
+}
+
+
+#pragma mark NSCopying
+
+- (instancetype)copyWithZone:(NSZone *)zone {
+	// we're immutable, bitches!
+	return self;
+}
+
+
+#pragma mark NSCoding
+
+- (id)initWithCoder:(NSCoder *)coder {
+	self = [self init];
+	if (self == nil) return nil;
+	
+	self.backingArray = [coder decodeObjectForKey:@keypath(self.backingArray)];
+	return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+	if (self.backingArray != nil) [coder encodeObject:self.backingArray forKey:@keypath(self.backingArray)];
+}
+
+
+#pragma mark API
+
++ (instancetype)tupleWithObjectsFromArray:(NSArray *)array {
+	return [self tupleWithObjectsFromArray:array convertNullsToNils:NO];
+}
+
++ (instancetype)tupleWithObjectsFromArray:(NSArray *)array convertNullsToNils:(BOOL)convert {
+	RACTuple *tuple = [[self alloc] init];
+	
+	if (convert) {
+		NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:array.count];
+		for (id object in array) {
+			[newArray addObject:(object == NSNull.null ? RACTupleNil.tupleNil : object)];
+		}
+		
+		tuple.backingArray = newArray;
+	} else {
+		tuple.backingArray = [array copy];
+	}
+	
+	return tuple;
+}
+
++ (instancetype)tupleWithObjects:(id)object, ... {
+	RACTuple *tuple = [[self alloc] init];
+
+	va_list args;
+	va_start(args, object);
+
+	NSUInteger count = 0;
+	for (id currentObject = object; currentObject != nil; currentObject = va_arg(args, id)) {
+		++count;
+	}
+
+	va_end(args);
+
+	if (count == 0) {
+		tuple.backingArray = @[];
+		return tuple;
+	}
+	
+	NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:count];
+	
+	va_start(args, object);
+	for (id currentObject = object; currentObject != nil; currentObject = va_arg(args, id)) {
+		[objects addObject:currentObject];
+	}
+
+	va_end(args);
+	
+	tuple.backingArray = objects;
+	return tuple;
+}
+
+- (id)objectAtIndex:(NSUInteger)index {
+	if (index >= self.count) return nil;
+	
+	id object = [self.backingArray objectAtIndex:index];
+	return (object == RACTupleNil.tupleNil ? nil : object);
+}
+
+- (NSArray *)allObjects {
+	NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:self.backingArray.count];
+	for (id object in self.backingArray) {
+		[newArray addObject:(object == RACTupleNil.tupleNil ? NSNull.null : object)];
+	}
+	
+	return newArray;
+}
+
+- (instancetype)tupleByAddingObject:(id)obj {
+	NSArray *newArray = [self.backingArray arrayByAddingObject:obj ?: RACTupleNil.tupleNil];
+	return [self.class tupleWithObjectsFromArray:newArray convertNullsToNils:NO];
+}
+
+- (NSUInteger)count {
+	return self.backingArray.count;
+}
+
+- (id)first {
+	return [self objectAtIndex:0];
+}
+
+- (id)second {
+	return [self objectAtIndex:1];
+}
+
+- (id)third {
+	return [self objectAtIndex:2];
+}
+
+- (id)fourth {
+	return [self objectAtIndex:3];
+}
+
+- (id)fifth {
+	return [self objectAtIndex:4];
+}
+
+- (id)last {
+	return [self objectAtIndex:self.count - 1];
+}
+
+@end
+
+
+@implementation RACTuple (RACSequenceAdditions)
+
+- (RACSequence *)rac_sequence {
+	return [RACTupleSequence sequenceWithTupleBackingArray:self.backingArray offset:0];
+}
+
+@end
+
+@implementation RACTuple (ObjectSubscripting)
+
+- (id)objectAtIndexedSubscript:(NSUInteger)idx {
+	return [self objectAtIndex:idx];
+}
+
+@end
+
+
+@implementation RACTupleUnpackingTrampoline
+
+#pragma mark Lifecycle
+
++ (instancetype)trampoline {
+	static dispatch_once_t onceToken;
+	static id trampoline = nil;
+	dispatch_once(&onceToken, ^{
+		trampoline = [[self alloc] init];
+	});
+	
+	return trampoline;
+}
+
+- (void)setObject:(RACTuple *)tuple forKeyedSubscript:(NSArray *)variables {
+	NSCParameterAssert(variables != nil);
+	
+	[variables enumerateObjectsUsingBlock:^(NSValue *value, NSUInteger index, BOOL *stop) {
+		__strong id *ptr = (__strong id *)value.pointerValue;
+		*ptr = tuple[index];
+	}];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.h
new file mode 100644
index 0000000..f6cd021
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.h
@@ -0,0 +1,18 @@
+//
+//  RACTupleSequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class that adapts a RACTuple to the RACSequence interface.
+@interface RACTupleSequence : RACSequence
+
+// Returns a sequence for enumerating over the given backing array (from a
+// RACTuple), starting from the given offset.
++ (instancetype)sequenceWithTupleBackingArray:(NSArray *)backingArray offset:(NSUInteger)offset;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.m
new file mode 100644
index 0000000..ba268f5
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACTupleSequence.m
@@ -0,0 +1,68 @@
+//
+//  RACTupleSequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACTupleSequence.h"
+#import "RACTuple.h"
+
+@interface RACTupleSequence ()
+
+// The array being sequenced, as taken from RACTuple.backingArray.
+@property (nonatomic, strong, readonly) NSArray *tupleBackingArray;
+
+// The index in the array from which the sequence starts.
+@property (nonatomic, assign, readonly) NSUInteger offset;
+
+@end
+
+@implementation RACTupleSequence
+
+#pragma mark Lifecycle
+
++ (instancetype)sequenceWithTupleBackingArray:(NSArray *)backingArray offset:(NSUInteger)offset {
+	NSCParameterAssert(offset <= backingArray.count);
+
+	if (offset == backingArray.count) return self.empty;
+
+	RACTupleSequence *seq = [[self alloc] init];
+	seq->_tupleBackingArray = backingArray;
+	seq->_offset = offset;
+	return seq;
+}
+
+#pragma mark RACSequence
+
+- (id)head {
+	id object = [self.tupleBackingArray objectAtIndex:self.offset];
+	return (object == RACTupleNil.tupleNil ? NSNull.null : object);
+}
+
+- (RACSequence *)tail {
+	RACSequence *sequence = [self.class sequenceWithTupleBackingArray:self.tupleBackingArray offset:self.offset + 1];
+	sequence.name = self.name;
+	return sequence;
+}
+
+- (NSArray *)array {
+	NSRange range = NSMakeRange(self.offset, self.tupleBackingArray.count - self.offset);
+	NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:range.length];
+
+	[self.tupleBackingArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] options:0 usingBlock:^(id object, NSUInteger index, BOOL *stop) {
+		id mappedObject = (object == RACTupleNil.tupleNil ? NSNull.null : object);
+		[array addObject:mappedObject];
+	}];
+
+	return array;
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, tuple = %@ }", self.class, self, self.name, self.tupleBackingArray];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.h b/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.h
new file mode 100644
index 0000000..86a514b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.h
@@ -0,0 +1,14 @@
+//
+//  RACUnarySequence.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACSequence.h"
+
+// Private class representing a sequence of exactly one value.
+@interface RACUnarySequence : RACSequence
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.m b/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.m
new file mode 100644
index 0000000..fefca84
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACUnarySequence.m
@@ -0,0 +1,81 @@
+//
+//  RACUnarySequence.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-05-01.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "RACUnarySequence.h"
+#import "RACEXTKeyPathCoding.h"
+#import "NSObject+RACDescription.h"
+
+@interface RACUnarySequence ()
+
+// The single value stored in this sequence.
+@property (nonatomic, strong, readwrite) id head;
+
+@end
+
+@implementation RACUnarySequence
+
+#pragma mark Properties
+
+@synthesize head = _head;
+
+#pragma mark Lifecycle
+
++ (instancetype)return:(id)value {
+	RACUnarySequence *sequence = [[self alloc] init];
+	sequence.head = value;
+	return [sequence setNameWithFormat:@"+return: %@", [value rac_description]];
+}
+
+#pragma mark RACSequence
+
+- (RACSequence *)tail {
+	return nil;
+}
+
+- (instancetype)bind:(RACStreamBindBlock (^)(void))block {
+	RACStreamBindBlock bindBlock = block();
+	BOOL stop = NO;
+
+	RACSequence *result = (id)[bindBlock(self.head, &stop) setNameWithFormat:@"[%@] -bind:", self.name];
+	return result ?: self.class.empty;
+}
+
+#pragma mark NSCoding
+
+- (Class)classForCoder {
+	// Unary sequences should be encoded as themselves, not array sequences.
+	return self.class;
+}
+
+- (id)initWithCoder:(NSCoder *)coder {
+	id value = [coder decodeObjectForKey:@keypath(self.head)];
+	return [self.class return:value];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+	if (self.head != nil) [coder encodeObject:self.head forKey:@keypath(self.head)];
+}
+
+#pragma mark NSObject
+
+- (NSString *)description {
+	return [NSString stringWithFormat:@"<%@: %p>{ name = %@, head = %@ }", self.class, self, self.name, self.head];
+}
+
+- (NSUInteger)hash {
+	return [self.head hash];
+}
+
+- (BOOL)isEqual:(RACUnarySequence *)seq {
+	if (self == seq) return YES;
+	if (![seq isKindOfClass:RACUnarySequence.class]) return NO;
+
+	return self.head == seq.head || [(NSObject *)self.head isEqual:seq.head];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.h b/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.h
new file mode 100644
index 0000000..7713e1d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.h
@@ -0,0 +1,20 @@
+//
+//  RACUnit.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/27/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+/// A unit represents an empty value.
+///
+/// It should never be necessary to create a unit yourself. Just use +defaultUnit.
+@interface RACUnit : NSObject
+
+/// A singleton instance.
++ (RACUnit *)defaultUnit;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.m b/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.m
new file mode 100644
index 0000000..76b8425
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACUnit.m
@@ -0,0 +1,27 @@
+//
+//  RACUnit.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/27/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACUnit.h"
+
+
+@implementation RACUnit
+
+
+#pragma mark API
+
++ (RACUnit *)defaultUnit {
+	static dispatch_once_t onceToken;
+	static RACUnit *defaultUnit = nil;
+	dispatch_once(&onceToken, ^{
+		defaultUnit = [[self alloc] init];
+	});
+	
+	return defaultUnit;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.h b/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.h
new file mode 100644
index 0000000..740b861
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.h
@@ -0,0 +1,16 @@
+//
+//  RACValueTransformer.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/6/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// A private block based transformer.
+@interface RACValueTransformer : NSValueTransformer
+
++ (instancetype)transformerWithBlock:(id (^)(id value))block;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.m b/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.m
new file mode 100644
index 0000000..ccec07d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/RACValueTransformer.m
@@ -0,0 +1,42 @@
+//
+//  RACValueTransformer.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/6/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACValueTransformer.h"
+
+@interface RACValueTransformer ()
+@property (nonatomic, copy) id (^transformBlock)(id value);
+@end
+
+
+@implementation RACValueTransformer
+
+
+#pragma mark NSValueTransformer
+
++ (BOOL)allowsReverseTransformation {
+	return NO;
+}
+
+- (id)transformedValue:(id)value {
+    return self.transformBlock(value);
+}
+
+
+#pragma mark API
+
+@synthesize transformBlock;
+
++ (instancetype)transformerWithBlock:(id (^)(id value))block {
+	NSCParameterAssert(block != NULL);
+	
+	RACValueTransformer *transformer = [[self alloc] init];
+	transformer.transformBlock = block;
+	return transformer;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/ReactiveCocoa.h b/ReactiveCocoaFramework/ReactiveCocoa/ReactiveCocoa.h
new file mode 100644
index 0000000..7c1441d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/ReactiveCocoa.h
@@ -0,0 +1,74 @@
+//
+//  ReactiveCocoa.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 3/5/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "RACEXTKeyPathCoding.h"
+#import "NSArray+RACSequenceAdditions.h"
+#import "NSData+RACSupport.h"
+#import "NSDictionary+RACSequenceAdditions.h"
+#import "NSEnumerator+RACSequenceAdditions.h"
+#import "NSFileHandle+RACSupport.h"
+#import "NSNotificationCenter+RACSupport.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACLifting.h"
+#import "NSObject+RACPropertySubscribing.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "NSOrderedSet+RACSequenceAdditions.h"
+#import "NSSet+RACSequenceAdditions.h"
+#import "NSString+RACSequenceAdditions.h"
+#import "NSString+RACSupport.h"
+#import "NSIndexSet+RACSequenceAdditions.h"
+#import "NSURLConnection+RACSupport.h"
+#import "NSUserDefaults+RACSupport.h"
+#import "RACBehaviorSubject.h"
+#import "RACChannel.h"
+#import "RACCommand.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACEvent.h"
+#import "RACGroupedSignal.h"
+#import "RACKVOChannel.h"
+#import "RACMulticastConnection.h"
+#import "RACQueueScheduler.h"
+#import "RACReplaySubject.h"
+#import "RACScheduler.h"
+#import "RACScopedDisposable.h"
+#import "RACSequence.h"
+#import "RACSerialDisposable.h"
+#import "RACSignal+Operations.h"
+#import "RACSignal.h"
+#import "RACStream.h"
+#import "RACSubject.h"
+#import "RACSubscriber.h"
+#import "RACSubscriptingAssignmentTrampoline.h"
+#import "RACTargetQueueScheduler.h"
+#import "RACTestScheduler.h"
+#import "RACTuple.h"
+#import "RACUnit.h"
+
+#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
+	#import "UIActionSheet+RACSignalSupport.h"
+	#import "UIAlertView+RACSignalSupport.h"
+	#import "UIBarButtonItem+RACCommandSupport.h"
+	#import "UIButton+RACCommandSupport.h"
+	#import "UICollectionReusableView+RACSignalSupport.h"
+	#import "UIControl+RACSignalSupport.h"
+	#import "UIDatePicker+RACSignalSupport.h"
+	#import "UIGestureRecognizer+RACSignalSupport.h"
+	#import "UISegmentedControl+RACSignalSupport.h"
+	#import "UISlider+RACSignalSupport.h"
+	#import "UIStepper+RACSignalSupport.h"
+	#import "UISwitch+RACSignalSupport.h"
+	#import "UITableViewCell+RACSignalSupport.h"
+	#import "UITextField+RACSignalSupport.h"
+	#import "UITextView+RACSignalSupport.h"
+#elif TARGET_OS_MAC
+	#import "NSControl+RACCommandSupport.h"
+	#import "NSControl+RACTextSignalSupport.h"
+	#import "NSObject+RACAppKitBindings.h"
+	#import "NSText+RACSignalSupport.h"
+#endif
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.h
new file mode 100644
index 0000000..3d667e9
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.h
@@ -0,0 +1,32 @@
+//
+//  UIActionSheet+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Dave Lee on 2013-06-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACDelegateProxy;
+@class RACSignal;
+
+@interface UIActionSheet (RACSignalSupport)
+
+/// A delegate proxy which will be set as the receiver's delegate when any of the
+/// methods in this category are used.
+@property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy;
+
+/// Creates a signal for button clicks on the receiver.
+///
+/// When this method is invoked, the `rac_delegateProxy` will become the
+/// receiver's delegate. Any previous delegate will become the -[RACDelegateProxy
+/// rac_proxiedDelegate], so that it receives any messages that the proxy doesn't
+/// know how to handle. Setting the receiver's `delegate` afterward is
+/// considered undefined behavior.
+///
+/// Returns a signal which will send the index of the specific button clicked.
+/// The signal will complete when the receiver is deallocated.
+- (RACSignal *)rac_buttonClickedSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.m
new file mode 100644
index 0000000..6198797
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIActionSheet+RACSignalSupport.m
@@ -0,0 +1,50 @@
+//
+//  UIActionSheet+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Dave Lee on 2013-06-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIActionSheet+RACSignalSupport.h"
+#import "RACDelegateProxy.h"
+#import "RACSignal+Operations.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACTuple.h"
+#import "NSObject+RACDescription.h"
+#import <objc/runtime.h>
+
+@implementation UIActionSheet (RACSignalSupport)
+
+static void RACUseDelegateProxy(UIActionSheet *self) {
+    if (self.delegate == self.rac_delegateProxy) return;
+
+    self.rac_delegateProxy.rac_proxiedDelegate = self.delegate;
+    self.delegate = (id)self.rac_delegateProxy;
+}
+
+- (RACDelegateProxy *)rac_delegateProxy {
+	RACDelegateProxy *proxy = objc_getAssociatedObject(self, _cmd);
+	if (proxy == nil) {
+		proxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UIActionSheetDelegate)];
+		objc_setAssociatedObject(self, _cmd, proxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	}
+
+	return proxy;
+}
+
+- (RACSignal *)rac_buttonClickedSignal {
+	RACSignal *signal = [[[[self.rac_delegateProxy
+		signalForSelector:@selector(actionSheet:clickedButtonAtIndex:)]
+		reduceEach:^(UIActionSheet *actionSheet, NSNumber *buttonIndex) {
+			return buttonIndex;
+		}]
+		takeUntil:self.rac_willDeallocSignal]
+		setNameWithFormat:@"%@ -rac_buttonClickedSignal", [self rac_description]];
+
+	RACUseDelegateProxy(self);
+
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.h
new file mode 100644
index 0000000..4586460
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.h
@@ -0,0 +1,32 @@
+//
+//  UIAlertView+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Henrik Hodne on 6/16/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACDelegateProxy;
+@class RACSignal;
+
+@interface UIAlertView (RACSignalSupport)
+
+/// A delegate proxy which will be set as the receiver's delegate when any of the
+/// methods in this category are used.
+@property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy;
+
+/// Creates a signal for button clicks on the receiver.
+///
+/// When this method is invoked, the `rac_delegateProxy` will become the
+/// receiver's delegate. Any previous delegate will become the -[RACDelegateProxy
+/// rac_proxiedDelegate], so that it receives any messages that the proxy doesn't
+/// know how to handle. Setting the receiver's `delegate` afterward is considered
+/// undefined behavior.
+///
+/// Returns a signal which will send the index of the specific button clicked.
+/// The signal will complete itself when the receiver is deallocated.
+- (RACSignal *)rac_buttonClickedSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.m
new file mode 100644
index 0000000..bf15b27
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIAlertView+RACSignalSupport.m
@@ -0,0 +1,50 @@
+//
+//  UIAlertView+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Henrik Hodne on 6/16/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIAlertView+RACSignalSupport.h"
+#import "RACDelegateProxy.h"
+#import "RACSignal+Operations.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "RACTuple.h"
+#import <objc/runtime.h>
+
+@implementation UIAlertView (RACSignalSupport)
+
+static void RACUseDelegateProxy(UIAlertView *self) {
+	if (self.delegate == self.rac_delegateProxy) return;
+
+	self.rac_delegateProxy.rac_proxiedDelegate = self.delegate;
+	self.delegate = (id)self.rac_delegateProxy;
+}
+
+- (RACDelegateProxy *)rac_delegateProxy {
+	RACDelegateProxy *proxy = objc_getAssociatedObject(self, _cmd);
+	if (proxy == nil) {
+		proxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UIAlertViewDelegate)];
+		objc_setAssociatedObject(self, _cmd, proxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	}
+
+	return proxy;
+}
+
+- (RACSignal *)rac_buttonClickedSignal {
+	RACSignal *signal = [[[[self.rac_delegateProxy
+		signalForSelector:@selector(alertView:clickedButtonAtIndex:)]
+		reduceEach:^(UIAlertView *alertView, NSNumber *buttonIndex) {
+			return buttonIndex;
+		}]
+		takeUntil:self.rac_willDeallocSignal]
+		setNameWithFormat:@"%@ -rac_buttonClickedSignal", [self rac_description]];
+
+	RACUseDelegateProxy(self);
+
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h
new file mode 100644
index 0000000..c04648a
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h
@@ -0,0 +1,22 @@
+//
+//  UIBarButtonItem+RACCommandSupport.h
+//  ReactiveCocoa
+//
+//  Created by Kyle LeNeau on 3/27/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACCommand;
+
+@interface UIBarButtonItem (RACCommandSupport)
+
+/// Sets the control's command. When the control is clicked, the command is
+/// executed with the sender of the event. The control's enabledness is bound
+/// to the command's `canExecute`.
+///
+/// Note: this will reset the control's target and action.
+@property (nonatomic, strong) RACCommand *rac_command;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m
new file mode 100644
index 0000000..7370af2
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m
@@ -0,0 +1,55 @@
+//
+//  UIBarButtonItem+RACCommandSupport.m
+//  ReactiveCocoa
+//
+//  Created by Kyle LeNeau on 3/27/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIBarButtonItem+RACCommandSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "NSObject+RACPropertySubscribing.h"
+#import "RACCommand.h"
+#import "RACDisposable.h"
+#import "RACSignal+Operations.h"
+#import <objc/runtime.h>
+
+static void *UIControlRACCommandKey = &UIControlRACCommandKey;
+static void *UIControlEnabledDisposableKey = &UIControlEnabledDisposableKey;
+
+@implementation UIBarButtonItem (RACCommandSupport)
+
+- (RACCommand *)rac_command {
+	return objc_getAssociatedObject(self, UIControlRACCommandKey);
+}
+
+- (void)setRac_command:(RACCommand *)command {
+	objc_setAssociatedObject(self, UIControlRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	
+	// Check for stored signal in order to remove it and add a new one
+	RACDisposable *disposable = objc_getAssociatedObject(self, UIControlEnabledDisposableKey);
+	[disposable dispose];
+	
+	if (command == nil) return;
+	
+	disposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
+	objc_setAssociatedObject(self, UIControlEnabledDisposableKey, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	
+	[self rac_hijackActionAndTargetIfNeeded];
+}
+
+- (void)rac_hijackActionAndTargetIfNeeded {
+	SEL hijackSelector = @selector(rac_commandPerformAction:);
+	if (self.target == self && self.action == hijackSelector) return;
+	
+	if (self.target != nil) NSLog(@"WARNING: UIBarButtonItem.rac_command hijacks the control's existing target and action.");
+	
+	self.target = self;
+	self.action = hijackSelector;
+}
+
+- (void)rac_commandPerformAction:(id)sender {
+	[self.rac_command execute:sender];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.h
new file mode 100644
index 0000000..642ba8e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.h
@@ -0,0 +1,20 @@
+//
+//  UIButton+RACCommandSupport.h
+//  ReactiveCocoa
+//
+//  Created by Ash Furrow on 2013-06-06.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACCommand;
+
+@interface UIButton (RACCommandSupport)
+
+/// Sets the button's command. When the button is clicked, the command is
+/// executed with the sender of the event. The button's enabledness is bound
+/// to the command's `canExecute`.
+@property (nonatomic, strong) RACCommand *rac_command;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.m
new file mode 100644
index 0000000..38fd470
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIButton+RACCommandSupport.m
@@ -0,0 +1,57 @@
+//
+//  UIButton+RACCommandSupport.m
+//  ReactiveCocoa
+//
+//  Created by Ash Furrow on 2013-06-06.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIButton+RACCommandSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "NSObject+RACPropertySubscribing.h"
+#import "RACCommand.h"
+#import "RACDisposable.h"
+#import "RACSignal+Operations.h"
+#import <objc/runtime.h>
+
+static void *UIButtonRACCommandKey = &UIButtonRACCommandKey;
+static void *UIButtonEnabledDisposableKey = &UIButtonEnabledDisposableKey;
+
+@implementation UIButton (RACCommandSupport)
+
+- (RACCommand *)rac_command {
+	return objc_getAssociatedObject(self, UIButtonRACCommandKey);
+}
+
+- (void)setRac_command:(RACCommand *)command {
+	objc_setAssociatedObject(self, UIButtonRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	
+	// Check for stored signal in order to remove it and add a new one
+	RACDisposable *disposable = objc_getAssociatedObject(self, UIButtonEnabledDisposableKey);
+	[disposable dispose];
+	
+	if (command == nil) return;
+	
+	disposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
+	objc_setAssociatedObject(self, UIButtonEnabledDisposableKey, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	
+	[self rac_hijackActionAndTargetIfNeeded];
+}
+
+- (void)rac_hijackActionAndTargetIfNeeded {
+	SEL hijackSelector = @selector(rac_commandPerformAction:);
+	
+	for (NSString *selector in [self actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
+		if (hijackSelector == NSSelectorFromString(selector)) {
+			return;
+		}
+	}
+	
+	[self addTarget:self action:hijackSelector forControlEvents:UIControlEventTouchUpInside];
+}
+
+- (void)rac_commandPerformAction:(id)sender {
+	[self.rac_command execute:sender];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.h
new file mode 100644
index 0000000..96b3dfe
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.h
@@ -0,0 +1,29 @@
+//
+//  UICollectionReusableView+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Kent Wong on 2013-10-04.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal;
+
+// This category is only applicable to iOS >= 6.0.
+@interface UICollectionReusableView (RACSignalSupport)
+
+/// A signal which will send a RACUnit whenever -prepareForReuse is invoked upon
+/// the receiver.
+///
+/// Examples
+///
+///  [[[self.cancelButton
+///     rac_signalForControlEvents:UIControlEventTouchUpInside]
+///     takeUntil:self.rac_prepareForReuseSignal]
+///     subscribeNext:^(UIButton *x) {
+///         // do other things
+///     }];
+@property (nonatomic, strong, readonly) RACSignal *rac_prepareForReuseSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.m
new file mode 100644
index 0000000..7e8680c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UICollectionReusableView+RACSignalSupport.m
@@ -0,0 +1,31 @@
+//
+//  UICollectionReusableView+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Kent Wong on 2013-10-04.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UICollectionReusableView+RACSignalSupport.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "RACSignal+Operations.h"
+#import "RACUnit.h"
+#import <objc/runtime.h>
+
+@implementation UICollectionReusableView (RACSignalSupport)
+
+- (RACSignal *)rac_prepareForReuseSignal {
+	RACSignal *signal = objc_getAssociatedObject(self, _cmd);
+	if (signal != nil) return signal;
+	
+	signal = [[[self
+		rac_signalForSelector:@selector(prepareForReuse)]
+		mapReplace:RACUnit.defaultUnit]
+		setNameWithFormat:@"%@ -rac_prepareForReuseSignal", self.rac_description];
+	
+	objc_setAssociatedObject(self, _cmd, signal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.h
new file mode 100644
index 0000000..2de86cf
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.h
@@ -0,0 +1,19 @@
+//
+//  UIControl+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal;
+
+@interface UIControl (RACSignalSupport)
+
+/// Creates and returns a signal that sends the sender of the control event
+/// whenever one of the control events is triggered.
+- (RACSignal *)rac_signalForControlEvents:(UIControlEvents)controlEvents;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.m
new file mode 100644
index 0000000..3cc503e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupport.m
@@ -0,0 +1,41 @@
+//
+//  UIControl+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "UIControl+RACSignalSupport.h"
+#import "RACEXTScope.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACSignal.h"
+#import "RACSignal+Operations.h"
+#import "RACSubscriber+Private.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+
+@implementation UIControl (RACSignalSupport)
+
+- (RACSignal *)rac_signalForControlEvents:(UIControlEvents)controlEvents {
+	@weakify(self);
+
+	return [[RACSignal
+		createSignal:^(id<RACSubscriber> subscriber) {
+			@strongify(self);
+
+			[self addTarget:subscriber action:@selector(sendNext:) forControlEvents:controlEvents];
+			[self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+				[subscriber sendCompleted];
+			}]];
+
+			return [RACDisposable disposableWithBlock:^{
+				@strongify(self);
+				[self removeTarget:subscriber action:@selector(sendNext:) forControlEvents:controlEvents];
+			}];
+		}]
+		setNameWithFormat:@"%@ -rac_signalForControlEvents: %lx", [self rac_description], (unsigned long)controlEvents];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.h b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.h
new file mode 100644
index 0000000..7f778a4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.h
@@ -0,0 +1,29 @@
+//
+//  UIControl+RACSignalSupportPrivate.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 06/08/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UIControl (RACSignalSupportPrivate)
+
+// Adds a RACChannel-based interface to the receiver for the given
+// UIControlEvents and exposes it.
+//
+// controlEvents - A mask of UIControlEvents on which to send new values.
+// key           - The key whose value should be read and set when a control
+//                 event fires and when a value is sent to the
+//                 RACChannelTerminal respectively.
+// nilValue      - The value to be assigned to the key when `nil` is sent to the
+//                 RACChannelTerminal.
+//
+// Returns a RACChannelTerminal which will send future values from the receiver,
+// and update the receiver when values are sent to the terminal.
+- (RACChannelTerminal *)rac_channelForControlEvents:(UIControlEvents)controlEvents key:(NSString *)key nilValue:(id)nilValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.m b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.m
new file mode 100644
index 0000000..df5c505
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIControl+RACSignalSupportPrivate.m
@@ -0,0 +1,50 @@
+//
+//  UIControl+RACSignalSupportPrivate.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 06/08/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIControl+RACSignalSupportPrivate.h"
+#import "RACEXTScope.h"
+#import "NSInvocation+RACTypeParsing.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACLifting.h"
+#import "RACChannel.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACSignal+Operations.h"
+#import "UIControl+RACSignalSupport.h"
+
+@implementation UIControl (RACSignalSupportPrivate)
+
+- (RACChannelTerminal *)rac_channelForControlEvents:(UIControlEvents)controlEvents key:(NSString *)key nilValue:(id)nilValue {
+	NSCParameterAssert(key.length > 0);
+	key = [key copy];
+	RACChannel *channel = [[RACChannel alloc] init];
+
+	[self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+		[channel.followingTerminal sendCompleted];
+	}]];
+
+	RACSignal *eventSignal = [[[self
+		rac_signalForControlEvents:controlEvents]
+		mapReplace:key]
+		takeUntil:[[channel.followingTerminal
+			ignoreValues]
+			catchTo:RACSignal.empty]];
+	[[self
+		rac_liftSelector:@selector(valueForKey:) withSignals:eventSignal, nil]
+		subscribe:channel.followingTerminal];
+
+	RACSignal *valuesSignal = [channel.followingTerminal
+		map:^(id value) {
+			return value ?: nilValue;
+		}];
+	[self rac_liftSelector:@selector(setValue:forKey:) withSignals:valuesSignal, [RACSignal return:key], nil];
+
+	return channel.leadingTerminal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.h
new file mode 100644
index 0000000..e620dfc
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.h
@@ -0,0 +1,24 @@
+//
+//  UIDatePicker+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UIDatePicker (RACSignalSupport)
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// nilValue - The date to set when the terminal receives `nil`.
+///
+/// Returns a RACChannelTerminal that sends the receiver's date whenever the
+/// UIControlEventValueChanged control event is fired, and sets the date to the
+/// values it receives.
+- (RACChannelTerminal *)rac_newDateChannelWithNilValue:(NSDate *)nilValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.m
new file mode 100644
index 0000000..1c11066
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIDatePicker+RACSignalSupport.m
@@ -0,0 +1,20 @@
+//
+//  UIDatePicker+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIDatePicker+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UIDatePicker (RACSignalSupport)
+
+- (RACChannelTerminal *)rac_newDateChannelWithNilValue:(NSDate *)nilValue {
+	return [self rac_channelForControlEvents:UIControlEventValueChanged key:@keypath(self.date) nilValue:nilValue];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.h
new file mode 100644
index 0000000..ee774fe
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.h
@@ -0,0 +1,18 @@
+//
+//  UIGestureRecognizer+RACSignalSupport.h
+//  Talks
+//
+//  Created by Josh Vera on 5/5/13.
+//  Copyright (c) 2013 GitHub. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal;
+
+@interface UIGestureRecognizer (RACSignalSupport)
+
+/// Returns a signal that sends the receiver when its gesture occurs.
+- (RACSignal *)rac_gestureSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.m
new file mode 100644
index 0000000..510d3ba
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIGestureRecognizer+RACSignalSupport.m
@@ -0,0 +1,40 @@
+//
+//  UIGestureRecognizer+RACSignalSupport.m
+//  Talks
+//
+//  Created by Josh Vera on 5/5/13.
+//  Copyright (c) 2013 GitHub. All rights reserved.
+//
+
+#import "UIGestureRecognizer+RACSignalSupport.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACCompoundDisposable.h"
+#import "RACDisposable.h"
+#import "RACSignal.h"
+#import "RACSubscriber.h"
+#import "NSObject+RACDescription.h"
+
+@implementation UIGestureRecognizer (RACSignalSupport)
+
+- (RACSignal *)rac_gestureSignal {
+	@weakify(self);
+
+	return [[RACSignal
+		createSignal:^(id<RACSubscriber> subscriber) {
+			@strongify(self);
+
+			[self addTarget:subscriber action:@selector(sendNext:)];
+			[self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
+				[subscriber sendCompleted];
+			}]];
+
+			return [RACDisposable disposableWithBlock:^{
+				@strongify(self);
+				[self removeTarget:subscriber action:@selector(sendNext:)];
+			}];
+		}]
+		setNameWithFormat:@"%@ -rac_gestureSignal", [self rac_description]];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.h
new file mode 100644
index 0000000..0bd1bf1
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.h
@@ -0,0 +1,22 @@
+//
+//  UIRefreshControl+RACCommandSupport.h
+//  ReactiveCocoa
+//
+//  Created by Dave Lee on 2013-10-17.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACCommand;
+
+@interface UIRefreshControl (RACCommandSupport)
+
+/// Manipulate the RACCommand property associated with this refresh control.
+///
+/// When this refresh control is activated by the user, the command will be
+/// executed. Upon completion or error of the execution signal, -endRefreshing
+/// will be invoked.
+@property (nonatomic, strong) RACCommand *rac_command;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.m
new file mode 100644
index 0000000..2b7d7a4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIRefreshControl+RACCommandSupport.m
@@ -0,0 +1,59 @@
+//
+//  UIRefreshControl+RACCommandSupport.m
+//  ReactiveCocoa
+//
+//  Created by Dave Lee on 2013-10-17.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIRefreshControl+RACCommandSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "RACDisposable.h"
+#import "RACCommand.h"
+#import "RACCompoundDisposable.h"
+#import "RACSignal.h"
+#import "RACSignal+Operations.h"
+#import "UIControl+RACSignalSupport.h"
+#import <objc/runtime.h>
+
+static void *UIRefreshControlRACCommandKey = &UIRefreshControlRACCommandKey;
+static void *UIRefreshControlDisposableKey = &UIRefreshControlDisposableKey;
+
+@implementation UIRefreshControl (RACCommandSupport)
+
+- (RACCommand *)rac_command {
+	return objc_getAssociatedObject(self, UIRefreshControlRACCommandKey);
+}
+
+- (void)setRac_command:(RACCommand *)command {
+	objc_setAssociatedObject(self, UIRefreshControlRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+	// Dispose of any active command associations.
+	[objc_getAssociatedObject(self, UIRefreshControlDisposableKey) dispose];
+
+	if (command == nil) return;
+
+	// Like RAC(self, enabled) = command.enabled; but with access to disposable.
+	RACDisposable *enabledDisposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
+
+	RACDisposable *executionDisposable = [[[[self
+		rac_signalForControlEvents:UIControlEventValueChanged]
+		map:^(UIRefreshControl *x) {
+			return [[[command
+				execute:x]
+				catchTo:[RACSignal empty]]
+				then:^{
+					return [RACSignal return:x];
+				}];
+		}]
+		concat]
+		subscribeNext:^(UIRefreshControl *x) {
+			[x endRefreshing];
+		}];
+
+	RACDisposable *commandDisposable = [RACCompoundDisposable compoundDisposableWithDisposables:@[ enabledDisposable, executionDisposable ]];
+	objc_setAssociatedObject(self, UIRefreshControlDisposableKey, commandDisposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.h
new file mode 100644
index 0000000..2d3c3e7
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.h
@@ -0,0 +1,24 @@
+//
+//  UISegmentedControl+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UISegmentedControl (RACSignalSupport)
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// nilValue - The segment to select when the terminal receives `nil`.
+///
+/// Returns a RACChannelTerminal that sends the receiver's currently selected
+/// segment's index whenever the UIControlEventValueChanged control event is
+/// fired, and sets the selected segment index to the values it receives.
+- (RACChannelTerminal *)rac_newSelectedSegmentIndexChannelWithNilValue:(NSNumber *)nilValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.m
new file mode 100644
index 0000000..96ea556
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISegmentedControl+RACSignalSupport.m
@@ -0,0 +1,20 @@
+//
+//  UISegmentedControl+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UISegmentedControl+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UISegmentedControl (RACSignalSupport)
+
+- (RACChannelTerminal *)rac_newSelectedSegmentIndexChannelWithNilValue:(NSNumber *)nilValue {
+	return [self rac_channelForControlEvents:UIControlEventValueChanged key:@keypath(self.selectedSegmentIndex) nilValue:nilValue];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.h
new file mode 100644
index 0000000..75626ad
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.h
@@ -0,0 +1,24 @@
+//
+//  UISlider+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UISlider (RACSignalSupport)
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// nilValue - The value to set when the terminal receives `nil`.
+///
+/// Returns a RACChannelTerminal that sends the receiver's value whenever the
+/// UIControlEventValueChanged control event is fired, and sets the value to the
+/// values it receives.
+- (RACChannelTerminal *)rac_newValueChannelWithNilValue:(NSNumber *)nilValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.m
new file mode 100644
index 0000000..1643f46
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISlider+RACSignalSupport.m
@@ -0,0 +1,20 @@
+//
+//  UISlider+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UISlider+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UISlider (RACSignalSupport)
+
+- (RACChannelTerminal *)rac_newValueChannelWithNilValue:(NSNumber *)nilValue {
+	return [self rac_channelForControlEvents:UIControlEventValueChanged key:@keypath(self.value) nilValue:nilValue];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.h
new file mode 100644
index 0000000..da6d97b
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.h
@@ -0,0 +1,24 @@
+//
+//  UIStepper+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UIStepper (RACSignalSupport)
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// nilValue - The value to set when the terminal receives `nil`.
+///
+/// Returns a RACChannelTerminal that sends the receiver's value whenever the
+/// UIControlEventValueChanged control event is fired, and sets the value to the
+/// values it receives.
+- (RACChannelTerminal *)rac_newValueChannelWithNilValue:(NSNumber *)nilValue;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.m
new file mode 100644
index 0000000..c7dc6ea
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UIStepper+RACSignalSupport.m
@@ -0,0 +1,20 @@
+//
+//  UIStepper+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIStepper+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UIStepper (RACSignalSupport)
+
+- (RACChannelTerminal *)rac_newValueChannelWithNilValue:(NSNumber *)nilValue {
+	return [self rac_channelForControlEvents:UIControlEventValueChanged key:@keypath(self.value) nilValue:nilValue];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.h
new file mode 100644
index 0000000..1313a2c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.h
@@ -0,0 +1,22 @@
+//
+//  UISwitch+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACChannelTerminal;
+
+@interface UISwitch (RACSignalSupport)
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// Returns a RACChannelTerminal that sends whether the receiver is on whenever
+/// the UIControlEventValueChanged control event is fired, and sets it on or off
+/// when it receives @YES or @NO respectively.
+- (RACChannelTerminal *)rac_newOnChannel;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.m
new file mode 100644
index 0000000..8146507
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UISwitch+RACSignalSupport.m
@@ -0,0 +1,20 @@
+//
+//  UISwitch+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Uri Baghin on 20/07/2013.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UISwitch+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UISwitch (RACSignalSupport)
+
+- (RACChannelTerminal *)rac_newOnChannel {
+	return [self rac_channelForControlEvents:UIControlEventValueChanged key:@keypath(self.on) nilValue:@NO];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.h
new file mode 100644
index 0000000..c29d47c
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.h
@@ -0,0 +1,28 @@
+//
+//  UITableViewCell+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal;
+
+@interface UITableViewCell (RACSignalSupport)
+
+/// A signal which will send a RACUnit whenever -prepareForReuse is invoked upon
+/// the receiver.
+///
+/// Examples
+///
+///  [[[self.cancelButton
+///     rac_signalForControlEvents:UIControlEventTouchUpInside]
+///     takeUntil:self.rac_prepareForReuseSignal]
+///     subscribeNext:^(UIButton *x) {
+///         // do other things
+///     }];
+@property (nonatomic, strong, readonly) RACSignal *rac_prepareForReuseSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.m
new file mode 100644
index 0000000..8a81c30
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewCell+RACSignalSupport.m
@@ -0,0 +1,31 @@
+//
+//  UITableViewCell+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Justin Spahr-Summers on 2013-07-22.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UITableViewCell+RACSignalSupport.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "RACSignal+Operations.h"
+#import "RACUnit.h"
+#import <objc/runtime.h>
+
+@implementation UITableViewCell (RACSignalSupport)
+
+- (RACSignal *)rac_prepareForReuseSignal {
+	RACSignal *signal = objc_getAssociatedObject(self, _cmd);
+	if (signal != nil) return signal;
+
+	signal = [[[self
+		rac_signalForSelector:@selector(prepareForReuse)]
+		mapReplace:RACUnit.defaultUnit]
+		setNameWithFormat:@"%@ -rac_prepareForReuseSignal", self.rac_description];
+	
+	objc_setAssociatedObject(self, _cmd, signal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.h
new file mode 100644
index 0000000..6c5d6b8
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.h
@@ -0,0 +1,29 @@
+//
+//  UITableViewHeaderFooterView+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Syo Ikeda on 12/30/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal;
+
+// This category is only applicable to iOS >= 6.0.
+@interface UITableViewHeaderFooterView (RACSignalSupport)
+
+/// A signal which will send a RACUnit whenever -prepareForReuse is invoked upon
+/// the receiver.
+///
+/// Examples
+///
+///  [[[self.cancelButton
+///     rac_signalForControlEvents:UIControlEventTouchUpInside]
+///     takeUntil:self.rac_prepareForReuseSignal]
+///     subscribeNext:^(UIButton *x) {
+///         // do other things
+///     }];
+@property (nonatomic, strong, readonly) RACSignal *rac_prepareForReuseSignal;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.m
new file mode 100644
index 0000000..0ecfc37
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITableViewHeaderFooterView+RACSignalSupport.m
@@ -0,0 +1,31 @@
+//
+//  UITableViewHeaderFooterView+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Syo Ikeda on 12/30/13.
+//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UITableViewHeaderFooterView+RACSignalSupport.h"
+#import "NSObject+RACDescription.h"
+#import "NSObject+RACSelectorSignal.h"
+#import "RACSignal+Operations.h"
+#import "RACUnit.h"
+#import <objc/runtime.h>
+
+@implementation UITableViewHeaderFooterView (RACSignalSupport)
+
+- (RACSignal *)rac_prepareForReuseSignal {
+	RACSignal *signal = objc_getAssociatedObject(self, _cmd);
+	if (signal != nil) return signal;
+
+	signal = [[[self
+		rac_signalForSelector:@selector(prepareForReuse)]
+		mapReplace:RACUnit.defaultUnit]
+		setNameWithFormat:@"%@ -rac_prepareForReuseSignal", self.rac_description];
+
+	objc_setAssociatedObject(self, _cmd, signal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.h
new file mode 100644
index 0000000..4ff6ee4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.h
@@ -0,0 +1,27 @@
+//
+//  UITextField+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACSignal, RACChannelTerminal;
+
+@interface UITextField (RACSignalSupport)
+
+/// Creates and returns a signal for the text of the field. It always starts with
+/// the current text. The signal sends next when the UIControlEventEditingChanged
+/// or UIControlEventEditingDidBegin control event is fired on the control.
+- (RACSignal *)rac_textSignal;
+
+/// Creates a new RACChannel-based binding to the receiver.
+///
+/// Returns a RACChannelTerminal that sends the receiver's text whenever the
+/// UIControlEventEditingChanged or UIControlEventEditingDidBegin control event 
+/// is fired, and sets the text to the values it receives.
+- (RACChannelTerminal *)rac_newTextChannel;
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.m
new file mode 100644
index 0000000..6e6d523
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITextField+RACSignalSupport.m
@@ -0,0 +1,39 @@
+//
+//  UITextField+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Josh Abernathy on 4/17/12.
+//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
+//
+
+#import "UITextField+RACSignalSupport.h"
+#import "RACEXTKeyPathCoding.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "NSObject+RACDescription.h"
+#import "RACSignal+Operations.h"
+#import "UIControl+RACSignalSupport.h"
+#import "UIControl+RACSignalSupportPrivate.h"
+
+@implementation UITextField (RACSignalSupport)
+
+- (RACSignal *)rac_textSignal {
+	@weakify(self);
+	return [[[[[RACSignal
+		defer:^{
+			@strongify(self);
+			return [RACSignal return:self];
+		}]
+		concat:[self rac_signalForControlEvents:UIControlEventEditingChanged | UIControlEventEditingDidBegin]]
+		map:^(UITextField *x) {
+			return x.text;
+		}]
+		takeUntil:self.rac_willDeallocSignal]
+		setNameWithFormat:@"%@ -rac_textSignal", [self rac_description]];
+}
+
+- (RACChannelTerminal *)rac_newTextChannel {
+	return [self rac_channelForControlEvents:UIControlEventEditingChanged | UIControlEventEditingDidBegin key:@keypath(self.text) nilValue:@""];
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.h b/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.h
new file mode 100644
index 0000000..174b1ba
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.h
@@ -0,0 +1,39 @@
+//
+//  UITextView+RACSignalSupport.h
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/18/12.
+//  Copyright (c) 2012 Cody Krieger. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACDelegateProxy;
+@class RACSignal;
+
+@interface UITextView (RACSignalSupport)
+
+/// A delegate proxy which will be set as the receiver's delegate when any of the
+/// methods in this category are used.
+@property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy;
+
+/// Creates a signal for the text of the receiver.
+///
+/// When this method is invoked, the `rac_delegateProxy` will become the
+/// receiver's delegate. Any previous delegate will become the -[RACDelegateProxy
+/// rac_proxiedDelegate], so that it receives any messages that the proxy doesn't
+/// know how to handle. Setting the receiver's `delegate` afterward is
+/// considered undefined behavior.
+///
+/// Returns a signal which will send the current text upon subscription, then
+/// again whenever the receiver's text is changed. The signal will complete when
+/// the receiver is deallocated.
+- (RACSignal *)rac_textSignal;
+
+@end
+
+@interface UITextView (RACSignalSupportUnavailable)
+
+- (RACSignal *)rac_signalForDelegateMethod:(SEL)method __attribute__((unavailable("Use -rac_signalForSelector:fromProtocol: instead")));
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.m b/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.m
new file mode 100644
index 0000000..7208698
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/UITextView+RACSignalSupport.m
@@ -0,0 +1,56 @@
+//
+//  UITextView+RACSignalSupport.m
+//  ReactiveCocoa
+//
+//  Created by Cody Krieger on 5/18/12.
+//  Copyright (c) 2012 Cody Krieger. All rights reserved.
+//
+
+#import "UITextView+RACSignalSupport.h"
+#import "RACEXTScope.h"
+#import "NSObject+RACDeallocating.h"
+#import "RACDelegateProxy.h"
+#import "RACSignal+Operations.h"
+#import "RACTuple.h"
+#import "NSObject+RACDescription.h"
+#import <objc/runtime.h>
+
+@implementation UITextView (RACSignalSupport)
+
+static void RACUseDelegateProxy(UITextView *self) {
+    if (self.delegate == self.rac_delegateProxy) return;
+
+    self.rac_delegateProxy.rac_proxiedDelegate = self.delegate;
+    self.delegate = (id)self.rac_delegateProxy;
+}
+
+- (RACDelegateProxy *)rac_delegateProxy {
+	RACDelegateProxy *proxy = objc_getAssociatedObject(self, _cmd);
+	if (proxy == nil) {
+		proxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UITextViewDelegate)];
+		objc_setAssociatedObject(self, _cmd, proxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+	}
+
+	return proxy;
+}
+
+- (RACSignal *)rac_textSignal {
+	@weakify(self);
+	RACSignal *signal = [[[[[RACSignal
+		defer:^{
+			@strongify(self);
+			return [RACSignal return:RACTuplePack(self)];
+		}]
+		concat:[self.rac_delegateProxy signalForSelector:@selector(textViewDidChange:)]]
+		reduceEach:^(UITextView *x) {
+			return x.text;
+		}]
+		takeUntil:self.rac_willDeallocSignal]
+		setNameWithFormat:@"%@ -rac_textSignal", [self rac_description]];
+
+	RACUseDelegateProxy(self);
+
+	return signal;
+}
+
+@end
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTKeyPathCoding.h b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTKeyPathCoding.h
new file mode 100644
index 0000000..0106319
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTKeyPathCoding.h
@@ -0,0 +1,68 @@
+//
+//  EXTKeyPathCoding.h
+//  extobjc
+//
+//  Created by Justin Spahr-Summers on 19.06.12.
+//  Copyright (C) 2012 Justin Spahr-Summers.
+//  Released under the MIT license.
+//
+
+#import <Foundation/Foundation.h>
+#import "RACmetamacros.h"
+
+/**
+ * \@keypath allows compile-time verification of key paths. Given a real object
+ * receiver and key path:
+ *
+ * @code
+
+NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String);
+// => @"lowercaseString.UTF8String"
+
+NSString *versionPath = @keypath(NSObject, version);
+// => @"version"
+
+NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString);
+// => @"lowercaseString"
+
+ * @endcode
+ *
+ * ... the macro returns an \c NSString containing all but the first path
+ * component or argument (e.g., @"lowercaseString.UTF8String", @"version").
+ *
+ * In addition to simply creating a key path, this macro ensures that the key
+ * path is valid at compile-time (causing a syntax error if not), and supports
+ * refactoring, such that changing the name of the property will also update any
+ * uses of \@keypath.
+ */
+#define keypath(...) \
+    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__))
+
+#define keypath1(PATH) \
+    (((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1))
+
+#define keypath2(OBJ, PATH) \
+    (((void)(NO && ((void)OBJ.PATH, NO)), # PATH))
+
+/**
+ * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object
+ * receiver, collection object receiver and related keypaths:
+ *
+ * @code
+ 
+ NSString *employessFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName)
+ // => @"employees.firstName"
+ 
+ NSString *employessFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName)
+ // => @"employees.firstName"
+
+ * @endcode
+ *
+ */
+#define collectionKeypath(...) \
+    metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__))
+
+#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String])
+
+#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(OBJ, PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String])
+
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.h b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.h
new file mode 100644
index 0000000..ab4e11d
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.h
@@ -0,0 +1,122 @@
+//
+//  EXTRuntimeExtensions.h
+//  extobjc
+//
+//  Created by Justin Spahr-Summers on 2011-03-05.
+//  Copyright (C) 2012 Justin Spahr-Summers.
+//  Released under the MIT license.
+//
+
+#import <objc/runtime.h>
+
+/**
+ * Describes the memory management policy of a property.
+ */
+typedef enum {
+    /**
+     * The value is assigned.
+     */
+    rac_propertyMemoryManagementPolicyAssign = 0,
+
+    /**
+     * The value is retained.
+     */
+    rac_propertyMemoryManagementPolicyRetain,
+
+    /**
+     * The value is copied.
+     */
+    rac_propertyMemoryManagementPolicyCopy
+} rac_propertyMemoryManagementPolicy;
+
+/**
+ * Describes the attributes and type information of a property.
+ */
+typedef struct {
+    /**
+     * Whether this property was declared with the \c readonly attribute.
+     */
+    BOOL readonly;
+
+    /**
+     * Whether this property was declared with the \c nonatomic attribute.
+     */
+    BOOL nonatomic;
+
+    /**
+     * Whether the property is a weak reference.
+     */
+    BOOL weak;
+
+    /**
+     * Whether the property is eligible for garbage collection.
+     */
+    BOOL canBeCollected;
+
+    /**
+     * Whether this property is defined with \c \@dynamic.
+     */
+    BOOL dynamic;
+
+    /**
+     * The memory management policy for this property. This will always be
+     * #rac_propertyMemoryManagementPolicyAssign if #readonly is \c YES.
+     */
+    rac_propertyMemoryManagementPolicy memoryManagementPolicy;
+
+    /**
+     * The selector for the getter of this property. This will reflect any
+     * custom \c getter= attribute provided in the property declaration, or the
+     * inferred getter name otherwise.
+     */
+    SEL getter;
+
+    /**
+     * The selector for the setter of this property. This will reflect any
+     * custom \c setter= attribute provided in the property declaration, or the
+     * inferred setter name otherwise.
+     *
+     * @note If #readonly is \c YES, this value will represent what the setter
+     * \e would be, if the property were writable.
+     */
+    SEL setter;
+
+    /**
+     * The backing instance variable for this property, or \c NULL if \c
+     * \c @synthesize was not used, and therefore no instance variable exists. This
+     * would also be the case if the property is implemented dynamically.
+     */
+    const char *ivar;
+
+    /**
+     * If this property is defined as being an instance of a specific class,
+     * this will be the class object representing it.
+     *
+     * This will be \c nil if the property was defined as type \c id, if the
+     * property is not of an object type, or if the class could not be found at
+     * runtime.
+     */
+    Class objectClass;
+
+    /**
+     * The type encoding for the value of this property. This is the type as it
+     * would be returned by the \c \@encode() directive.
+     */
+    char type[];
+} rac_propertyAttributes;
+
+/**
+ * Finds the instance method named \a aSelector on \a aClass and returns it, or
+ * returns \c NULL if no such instance method exists. Unlike \c
+ * class_getInstanceMethod(), this does not search superclasses.
+ *
+ * @note To get class methods in this manner, use a metaclass for \a aClass.
+ */
+Method rac_getImmediateInstanceMethod (Class aClass, SEL aSelector);
+
+/**
+ * Returns a pointer to a structure containing information about \a property.
+ * You must \c free() the returned pointer. Returns \c NULL if there is an error
+ * obtaining information from \a property.
+ */
+rac_propertyAttributes *rac_copyPropertyAttributes (objc_property_t property);
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.m b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.m
new file mode 100644
index 0000000..2d2010e
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTRuntimeExtensions.m
@@ -0,0 +1,232 @@
+//
+//  EXTRuntimeExtensions.m
+//  extobjc
+//
+//  Created by Justin Spahr-Summers on 2011-03-05.
+//  Copyright (C) 2012 Justin Spahr-Summers.
+//  Released under the MIT license.
+//
+
+#import "RACEXTRuntimeExtensions.h"
+#import <ctype.h>
+#import <libkern/OSAtomic.h>
+#import <objc/message.h>
+#import <pthread.h>
+#import <stdio.h>
+#import <stdlib.h>
+#import <string.h>
+
+rac_propertyAttributes *rac_copyPropertyAttributes (objc_property_t property) {
+    const char * const attrString = property_getAttributes(property);
+    if (!attrString) {
+        fprintf(stderr, "ERROR: Could not get attribute string from property %s\n", property_getName(property));
+        return NULL;
+    }
+
+    if (attrString[0] != 'T') {
+        fprintf(stderr, "ERROR: Expected attribute string \"%s\" for property %s to start with 'T'\n", attrString, property_getName(property));
+        return NULL;
+    }
+
+    const char *typeString = attrString + 1;
+    const char *next = NSGetSizeAndAlignment(typeString, NULL, NULL);
+    if (!next) {
+        fprintf(stderr, "ERROR: Could not read past type in attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+        return NULL;
+    }
+
+    size_t typeLength = (size_t)(next - typeString);
+    if (!typeLength) {
+        fprintf(stderr, "ERROR: Invalid type in attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+        return NULL;
+    }
+
+    // allocate enough space for the structure and the type string (plus a NUL)
+    rac_propertyAttributes *attributes = calloc(1, sizeof(rac_propertyAttributes) + typeLength + 1);
+    if (!attributes) {
+        fprintf(stderr, "ERROR: Could not allocate rac_propertyAttributes structure for attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+        return NULL;
+    }
+
+    // copy the type string
+    strncpy(attributes->type, typeString, typeLength);
+    attributes->type[typeLength] = '\0';
+
+    // if this is an object type, and immediately followed by a quoted string...
+    if (typeString[0] == *(@encode(id)) && typeString[1] == '"') {
+        // we should be able to extract a class name
+        const char *className = typeString + 2;
+        next = strchr(className, '"');
+
+        if (!next) {
+            fprintf(stderr, "ERROR: Could not read class name in attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+            return NULL;
+        }
+
+        if (className != next) {
+            size_t classNameLength = (size_t)(next - className);
+            char trimmedName[classNameLength + 1];
+
+            strncpy(trimmedName, className, classNameLength);
+            trimmedName[classNameLength] = '\0';
+
+            // attempt to look up the class in the runtime
+            attributes->objectClass = objc_getClass(trimmedName);
+        }
+    }
+
+    if (*next != '\0') {
+        // skip past any junk before the first flag
+        next = strchr(next, ',');
+    }
+
+    while (next && *next == ',') {
+        char flag = next[1];
+        next += 2;
+
+        switch (flag) {
+        case '\0':
+            break;
+
+        case 'R':
+            attributes->readonly = YES;
+            break;
+
+        case 'C':
+            attributes->memoryManagementPolicy = rac_propertyMemoryManagementPolicyCopy;
+            break;
+
+        case '&':
+            attributes->memoryManagementPolicy = rac_propertyMemoryManagementPolicyRetain;
+            break;
+
+        case 'N':
+            attributes->nonatomic = YES;
+            break;
+
+        case 'G':
+        case 'S':
+            {
+                const char *nextFlag = strchr(next, ',');
+                SEL name = NULL;
+
+                if (!nextFlag) {
+                    // assume that the rest of the string is the selector
+                    const char *selectorString = next;
+                    next = "";
+
+                    name = sel_registerName(selectorString);
+                } else {
+                    size_t selectorLength = (size_t)(nextFlag - next);
+                    if (!selectorLength) {
+                        fprintf(stderr, "ERROR: Found zero length selector name in attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+                        goto errorOut;
+                    }
+
+                    char selectorString[selectorLength + 1];
+
+                    strncpy(selectorString, next, selectorLength);
+                    selectorString[selectorLength] = '\0';
+
+                    name = sel_registerName(selectorString);
+                    next = nextFlag;
+                }
+
+                if (flag == 'G')
+                    attributes->getter = name;
+                else
+                    attributes->setter = name;
+            }
+
+            break;
+
+        case 'D':
+            attributes->dynamic = YES;
+            attributes->ivar = NULL;
+            break;
+
+        case 'V':
+            // assume that the rest of the string (if present) is the ivar name
+            if (*next == '\0') {
+                // if there's nothing there, let's assume this is dynamic
+                attributes->ivar = NULL;
+            } else {
+                attributes->ivar = next;
+                next = "";
+            }
+
+            break;
+
+        case 'W':
+            attributes->weak = YES;
+            break;
+
+        case 'P':
+            attributes->canBeCollected = YES;
+            break;
+
+        case 't':
+            fprintf(stderr, "ERROR: Old-style type encoding is unsupported in attribute string \"%s\" for property %s\n", attrString, property_getName(property));
+
+            // skip over this type encoding
+            while (*next != ',' && *next != '\0')
+                ++next;
+
+            break;
+
+        default:
+            fprintf(stderr, "ERROR: Unrecognized attribute string flag '%c' in attribute string \"%s\" for property %s\n", flag, attrString, property_getName(property));
+        }
+    }
+
+    if (next && *next != '\0') {
+        fprintf(stderr, "Warning: Unparsed data \"%s\" in attribute string \"%s\" for property %s\n", next, attrString, property_getName(property));
+    }
+
+    if (!attributes->getter) {
+        // use the property name as the getter by default
+        attributes->getter = sel_registerName(property_getName(property));
+    }
+
+    if (!attributes->setter) {
+        const char *propertyName = property_getName(property);
+        size_t propertyNameLength = strlen(propertyName);
+
+        // we want to transform the name to setProperty: style
+        size_t setterLength = propertyNameLength + 4;
+
+        char setterName[setterLength + 1];
+        strncpy(setterName, "set", 3);
+        strncpy(setterName + 3, propertyName, propertyNameLength);
+
+        // capitalize property name for the setter
+        setterName[3] = (char)toupper(setterName[3]);
+
+        setterName[setterLength - 1] = ':';
+        setterName[setterLength] = '\0';
+
+        attributes->setter = sel_registerName(setterName);
+    }
+
+    return attributes;
+
+errorOut:
+    free(attributes);
+    return NULL;
+}
+
+Method rac_getImmediateInstanceMethod (Class aClass, SEL aSelector) {
+    unsigned methodCount = 0;
+    Method *methods = class_copyMethodList(aClass, &methodCount);
+    Method foundMethod = NULL;
+
+    for (unsigned methodIndex = 0;methodIndex < methodCount;++methodIndex) {
+        if (method_getName(methods[methodIndex]) == aSelector) {
+            foundMethod = methods[methodIndex];
+            break;
+        }
+    }
+
+    free(methods);
+    return foundMethod;
+}
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTScope.h b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTScope.h
new file mode 100644
index 0000000..029e0c4
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACEXTScope.h
@@ -0,0 +1,101 @@
+//
+//  EXTScope.h
+//  extobjc
+//
+//  Created by Justin Spahr-Summers on 2011-05-04.
+//  Copyright (C) 2012 Justin Spahr-Summers.
+//  Released under the MIT license.
+//
+
+#import "RACmetamacros.h"
+
+/**
+ * \@onExit defines some code to be executed when the current scope exits. The
+ * code must be enclosed in braces and terminated with a semicolon, and will be
+ * executed regardless of how the scope is exited, including from exceptions,
+ * \c goto, \c return, \c break, and \c continue.
+ *
+ * Provided code will go into a block to be executed later. Keep this in mind as
+ * it pertains to memory management, restrictions on assignment, etc. Because
+ * the code is used within a block, \c return is a legal (though perhaps
+ * confusing) way to exit the cleanup block early.
+ *
+ * Multiple \@onExit statements in the same scope are executed in reverse
+ * lexical order. This helps when pairing resource acquisition with \@onExit
+ * statements, as it guarantees teardown in the opposite order of acquisition.
+ *
+ * @note This statement cannot be used within scopes defined without braces
+ * (like a one line \c if). In practice, this is not an issue, since \@onExit is
+ * a useless construct in such a case anyways.
+ */
+#define onExit \
+    autoreleasepool {} \
+    __strong rac_cleanupBlock_t metamacro_concat(rac_exitBlock_, __LINE__) __attribute__((cleanup(rac_executeCleanupBlock), unused)) = ^
+
+/**
+ * Creates \c __weak shadow variables for each of the variables provided as
+ * arguments, which can later be made strong again with #strongify.
+ *
+ * This is typically used to weakly reference variables in a block, but then
+ * ensure that the variables stay alive during the actual execution of the block
+ * (if they were live upon entry).
+ *
+ * See #strongify for an example of usage.
+ */
+#define weakify(...) \
+    autoreleasepool {} \
+    metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
+
+/**
+ * Like #weakify, but uses \c __unsafe_unretained instead, for targets or
+ * classes that do not support weak references.
+ */
+#define unsafeify(...) \
+    autoreleasepool {} \
+    metamacro_foreach_cxt(rac_weakify_,, __unsafe_unretained, __VA_ARGS__)
+
+/**
+ * Strongly references each of the variables provided as arguments, which must
+ * have previously been passed to #weakify.
+ *
+ * The strong references created will shadow the original variable names, such
+ * that the original names can be used without issue (and a significantly
+ * reduced risk of retain cycles) in the current scope.
+ *
+ * @code
+
+    id foo = [[NSObject alloc] init];
+    id bar = [[NSObject alloc] init];
+
+    @weakify(foo, bar);
+
+    // this block will not keep 'foo' or 'bar' alive
+    BOOL (^matchesFooOrBar)(id) = ^ BOOL (id obj){
+        // but now, upon entry, 'foo' and 'bar' will stay alive until the block has
+        // finished executing
+        @strongify(foo, bar);
+
+        return [foo isEqual:obj] || [bar isEqual:obj];
+    };
+
+ * @endcode
+ */
+#define strongify(...) \
+    try {} @finally {} \
+    _Pragma("clang diagnostic push") \
+    _Pragma("clang diagnostic ignored \"-Wshadow\"") \
+    metamacro_foreach(rac_strongify_,, __VA_ARGS__) \
+    _Pragma("clang diagnostic pop")
+
+/*** implementation details follow ***/
+typedef void (^rac_cleanupBlock_t)();
+
+static inline void rac_executeCleanupBlock (__strong rac_cleanupBlock_t *block) {
+    (*block)();
+}
+
+#define rac_weakify_(INDEX, CONTEXT, VAR) \
+    CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
+
+#define rac_strongify_(INDEX, VAR) \
+    __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
diff --git a/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACmetamacros.h b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACmetamacros.h
new file mode 100644
index 0000000..77a77b5
--- /dev/null
+++ b/ReactiveCocoaFramework/ReactiveCocoa/extobjc/RACmetamacros.h
@@ -0,0 +1,666 @@
+/**
+ * Macros for metaprogramming
+ * ExtendedC
+ *
+ * Copyright (C) 2012 Justin Spahr-Summers
+ * Released under the MIT license
+ */
+
+#ifndef EXTC_METAMACROS_H
+#define EXTC_METAMACROS_H
+
+/**
+ * Executes one or more expressions (which may have a void type, such as a call
+ * to a function that returns no value) and always returns true.
+ */
+#define metamacro_exprify(...) \
+    ((__VA_ARGS__), true)
+
+/**
+ * Returns a string representation of VALUE after full macro expansion.
+ */
+#define metamacro_stringify(VALUE) \
+        metamacro_stringify_(VALUE)
+
+/**
+ * Returns A and B concatenated after full macro expansion.
+ */
+#define metamacro_concat(A, B) \
+        metamacro_concat_(A, B)
+
+/**
+ * Returns the Nth variadic argument (starting from zero). At least
+ * N + 1 variadic arguments must be given. N must be between zero and twenty,
+ * inclusive.
+ */
+#define metamacro_at(N, ...) \
+        metamacro_concat(metamacro_at, N)(__VA_ARGS__)
+
+/**
+ * Returns the number of arguments (up to twenty) provided to the macro. At
+ * least one argument must be provided.
+ *
+ * Inspired by P99: http://p99.gforge.inria.fr
+ */
+#define metamacro_argcount(...) \
+        metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+
+/**
+ * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is
+ * given. Only the index and current argument will thus be passed to MACRO.
+ */
+#define metamacro_foreach(MACRO, SEP, ...) \
+        metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
+
+/**
+ * For each consecutive variadic argument (up to twenty), MACRO is passed the
+ * zero-based index of the current argument, CONTEXT, and then the argument
+ * itself. The results of adjoining invocations of MACRO are then separated by
+ * SEP.
+ *
+ * Inspired by P99: http://p99.gforge.inria.fr
+ */
+#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
+        metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
+
+/**
+ * Identical to #metamacro_foreach_cxt. This can be used when the former would
+ * fail due to recursive macro expansion.
+ */
+#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \
+        metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
+
+/**
+ * In consecutive order, appends each variadic argument (up to twenty) onto
+ * BASE. The resulting concatenations are then separated by SEP.
+ *
+ * This is primarily useful to manipulate a list of macro invocations into instead
+ * invoking a different, possibly related macro.
+ */
+#define metamacro_foreach_concat(BASE, SEP, ...) \
+        metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)
+
+/**
+ * Iterates COUNT times, each time invoking MACRO with the current index
+ * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO
+ * are then separated by SEP.
+ *
+ * COUNT must be an integer between zero and twenty, inclusive.
+ */
+#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \
+        metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)
+
+/**
+ * Returns the first argument given. At least one argument must be provided.
+ *
+ * This is useful when implementing a variadic macro, where you may have only
+ * one variadic argument, but no way to retrieve it (for example, because \c ...
+ * always needs to match at least one argument).
+ *
+ * @code
+
+#define varmacro(...) \
+    metamacro_head(__VA_ARGS__)
+
+ * @endcode
+ */
+#define metamacro_head(...) \
+        metamacro_head_(__VA_ARGS__, 0)
+
+/**
+ * Returns every argument except the first. At least two arguments must be
+ * provided.
+ */
+#define metamacro_tail(...) \
+        metamacro_tail_(__VA_ARGS__)
+
+/**
+ * Returns the first N (up to twenty) variadic arguments as a new argument list.
+ * At least N variadic arguments must be provided.
+ */
+#define metamacro_take(N, ...) \
+        metamacro_concat(metamacro_take, N)(__VA_ARGS__)
+
+/**
+ * Removes the first N (up to twenty) variadic arguments from the given argument
+ * list. At least N variadic arguments must be provided.
+ */
+#define metamacro_drop(N, ...) \
+        metamacro_concat(metamacro_drop, N)(__VA_ARGS__)
+
+/**
+ * Decrements VAL, which must be a number between zero and twenty, inclusive.
+ *
+ * This is primarily useful when dealing with indexes and counts in
+ * metaprogramming.
+ */
+#define metamacro_dec(VAL) \
+        metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
+
+/**
+ * Increments VAL, which must be a number between zero and twenty, inclusive.
+ *
+ * This is primarily useful when dealing with indexes and counts in
+ * metaprogramming.
+ */
+#define metamacro_inc(VAL) \
+        metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
+
+/**
+ * If A is equal to B, the next argument list is expanded; otherwise, the
+ * argument list after that is expanded. A and B must be numbers between zero
+ * and twenty, inclusive. Additionally, B must be greater than or equal to A.
+ *
+ * @code
+
+// expands to true
+metamacro_if_eq(0, 0)(true)(false)
+
+// expands to false
+metamacro_if_eq(0, 1)(true)(false)
+
+ * @endcode
+ *
+ * This is primarily useful when dealing with indexes and counts in
+ * metaprogramming.
+ */
+#define metamacro_if_eq(A, B) \
+        metamacro_concat(metamacro_if_eq, A)(B)
+
+/**
+ * Identical to #metamacro_if_eq. This can be used when the former would fail
+ * due to recursive macro expansion.
+ */
+#define metamacro_if_eq_recursive(A, B) \
+        metamacro_concat(metamacro_if_eq_recursive, A)(B)
+
+/**
+ * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and
+ * twenty, inclusive.
+ *
+ * For the purposes of this test, zero is considered even.
+ */
+#define metamacro_is_even(N) \
+        metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
+
+/**
+ * Returns the logical NOT of B, which must be the number zero or one.
+ */
+#define metamacro_not(B) \
+        metamacro_at(B, 1, 0)
+
+// IMPLEMENTATION DETAILS FOLLOW!
+// Do not write code that depends on anything below this line.
+#define metamacro_stringify_(VALUE) # VALUE
+#define metamacro_concat_(A, B) A ## B
+#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
+#define metamacro_head_(FIRST, ...) FIRST
+#define metamacro_tail_(FIRST, ...) __VA_ARGS__
+#define metamacro_consume_(...)
+#define metamacro_expand_(...) __VA_ARGS__
+
+// implemented from scratch so that metamacro_concat() doesn't end up nesting
+#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)
+#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG
+
+// metamacro_at expansions
+#define metamacro_at0(...) metamacro_head(__VA_ARGS__)
+#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__)
+#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)
+
+// metamacro_foreach_cxt expansions
+#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
+#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
+
+#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
+    metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \
+    SEP \
+    MACRO(1, CONTEXT, _1)
+
+#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
+    metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
+    SEP \
+    MACRO(2, CONTEXT, _2)
+
+#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
+    metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
+    SEP \
+    MACRO(3, CONTEXT, _3)
+
+#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
+    metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
+    SEP \
+    MACRO(4, CONTEXT, _4)
+
+#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
+    metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
+    SEP \
+    MACRO(5, CONTEXT, _5)
+
+#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
+    metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
+    SEP \
+    MACRO(6, CONTEXT, _6)
+
+#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
+    metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
+    SEP \
+    MACRO(7, CONTEXT, _7)
+
+#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
+    metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
+    SEP \
+    MACRO(8, CONTEXT, _8)
+
+#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
+    metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
+    SEP \
+    MACRO(9, CONTEXT, _9)
+
+#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
+    metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
+    SEP \
+    MACRO(10, CONTEXT, _10)
+
+#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
+    metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
+    SEP \
+    MACRO(11, CONTEXT, _11)
+
+#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
+    metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
+    SEP \
+    MACRO(12, CONTEXT, _12)
+
+#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
+    metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
+    SEP \
+    MACRO(13, CONTEXT, _13)
+
+#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
+    metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
+    SEP \
+    MACRO(14, CONTEXT, _14)
+
+#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
+    metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
+    SEP \
+    MACRO(15, CONTEXT, _15)
+
+#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+    metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
+    SEP \
+    MACRO(16, CONTEXT, _16)
+
+#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
+    metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+    SEP \
+    MACRO(17, CONTEXT, _17)
+
+#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
+    metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
+    SEP \
+    MACRO(18, CONTEXT, _18)
+
+#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
+    metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
+    SEP \
+    MACRO(19, CONTEXT, _19)
+
+// metamacro_foreach_cxt_recursive expansions
+#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)
+#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
+
+#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
+    metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \
+    SEP \
+    MACRO(1, CONTEXT, _1)
+
+#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
+    metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
+    SEP \
+    MACRO(2, CONTEXT, _2)
+
+#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
+    metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
+    SEP \
+    MACRO(3, CONTEXT, _3)
+
+#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
+    metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
+    SEP \
+    MACRO(4, CONTEXT, _4)
+
+#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
+    metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
+    SEP \
+    MACRO(5, CONTEXT, _5)
+
+#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
+    metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
+    SEP \
+    MACRO(6, CONTEXT, _6)
+
+#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
+    metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
+    SEP \
+    MACRO(7, CONTEXT, _7)
+
+#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
+    metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
+    SEP \
+    MACRO(8, CONTEXT, _8)
+
+#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
+    metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
+    SEP \
+    MACRO(9, CONTEXT, _9)
+
+#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
+    metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
+    SEP \
+    MACRO(10, CONTEXT, _10)
+
+#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
+    metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
+    SEP \
+    MACRO(11, CONTEXT, _11)
+
+#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
+    metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
+    SEP \
+    MACRO(12, CONTEXT, _12)
+
+#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
+    metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
+    SEP \
+    MACRO(13, CONTEXT, _13)
+
+#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
+    metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
+    SEP \
+    MACRO(14, CONTEXT, _14)
+
+#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
+    metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
+    SEP \
+    MACRO(15, CONTEXT, _15)
+
+#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+    metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
+    SEP \
+    MACRO(16, CONTEXT, _16)
+
+#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
+    metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
+    SEP \
+    MACRO(17, CONTEXT, _17)
+
+#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
+    metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
+    SEP \
+    MACRO(18, CONTEXT, _18)
+
+#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
+    metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
+    SEP \
+    MACRO(19, CONTEXT, _19)
+
+// metamacro_for_cxt expansions
+#define metamacro_for_cxt0(MACRO, SEP, CONTEXT)
+#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)
+
+#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt1(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(1, CONTEXT)
+
+#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(2, CONTEXT)
+
+#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(3, CONTEXT)
+
+#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(4, CONTEXT)
+
+#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(5, CONTEXT)
+
+#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(6, CONTEXT)
+
+#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(7, CONTEXT)
+
+#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(8, CONTEXT)
+
+#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(9, CONTEXT)
+
+#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(10, CONTEXT)
+
+#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(11, CONTEXT)
+
+#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(12, CONTEXT)
+
+#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(13, CONTEXT)
+
+#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(14, CONTEXT)
+
+#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(15, CONTEXT)
+
+#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(16, CONTEXT)
+
+#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(17, CONTEXT)
+
+#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(18, CONTEXT)
+
+#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \
+    metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
+    SEP \
+    MACRO(19, CONTEXT)
+
+// metamacro_if_eq expansions
+#define metamacro_if_eq0(VALUE) \
+    metamacro_concat(metamacro_if_eq0_, VALUE)
+
+#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
+#define metamacro_if_eq0_1(...) metamacro_expand_
+#define metamacro_if_eq0_2(...) metamacro_expand_
+#define metamacro_if_eq0_3(...) metamacro_expand_
+#define metamacro_if_eq0_4(...) metamacro_expand_
+#define metamacro_if_eq0_5(...) metamacro_expand_
+#define metamacro_if_eq0_6(...) metamacro_expand_
+#define metamacro_if_eq0_7(...) metamacro_expand_
+#define metamacro_if_eq0_8(...) metamacro_expand_
+#define metamacro_if_eq0_9(...) metamacro_expand_
+#define metamacro_if_eq0_10(...) metamacro_expand_
+#define metamacro_if_eq0_11(...) metamacro_expand_
+#define metamacro_if_eq0_12(...) metamacro_expand_
+#define metamacro_if_eq0_13(...) metamacro_expand_
+#define metamacro_if_eq0_14(...) metamacro_expand_
+#define metamacro_if_eq0_15(...) metamacro_expand_
+#define metamacro_if_eq0_16(...) metamacro_expand_
+#define metamacro_if_eq0_17(...) metamacro_expand_
+#define metamacro_if_eq0_18(...) metamacro_expand_
+#define metamacro_if_eq0_19(...) metamacro_expand_
+#define metamacro_if_eq0_20(...) metamacro_expand_
+
+#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
+#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
+#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
+#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
+#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
+#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
+#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
+#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
+#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
+#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
+#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
+#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
+#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
+#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
+#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
+#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
+#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
+#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
+#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
+#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
+
+// metamacro_if_eq_recursive expansions
+#define metamacro_if_eq_recursive0(VALUE) \
+    metamacro_concat(metamacro_if_eq_recursive0_, VALUE)
+
+#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_
+#define metamacro_if_eq_recursive0_1(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_2(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_3(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_4(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_5(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_6(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_7(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_8(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_9(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_10(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_11(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_12(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_13(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_14(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_15(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_16(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_17(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_18(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_19(...) metamacro_expand_
+#define metamacro_if_eq_recursive0_20(...) metamacro_expand_
+
+#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))
+#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))
+
+// metamacro_take expansions
+#define metamacro_take0(...)
+#define metamacro_take1(...) metamacro_head(__VA_ARGS__)
+#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))
+#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))
+#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))
+#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))
+#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))
+#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))
+#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))
+#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))
+#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))
+#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))
+#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))
+#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))
+#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))
+#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))
+#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))
+#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))
+#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))
+#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))
+#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))
+
+// metamacro_drop expansions
+#define metamacro_drop0(...) __VA_ARGS__
+#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)
+#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))
+#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))
+
+#endif