 //
 
 import Foundation
+import ReactiveCocoa
 
-/// The domain for all errors originating within Carthage.
-public let CarthageErrorDomain: NSString = "org.carthage.Carthage"
-
-/// Possible error codes with `CarthageErrorDomain`.
-public enum CarthageErrorCode: Int {
-	case InvalidArgument
-	case MissingBuildSetting
-	case IncompatibleRequirements
-	case TaggedVersionNotFound
-	case RequiredVersionNotFound
-	case RepositoryCheckoutFailed
-	case ReadFailed
-	case WriteFailed
-	case ParseError
-	case InvalidArchitectures
-	case MissingEnvironmentVariable
-	case NoSharedSchemes
-	case DuplicateDependencies
-
-	func error(userInfo: [NSObject: AnyObject]?) -> NSError {
-		return NSError(domain: CarthageErrorDomain, code: self.rawValue, userInfo: userInfo)
-	}
-}
-
-/// Possible errors within `CarthageErrorDomain`.
+/// Possible errors that can originate from Carthage.
 public enum CarthageError {
 	/// One or more arguments was invalid.
 	case InvalidArgument(description: String)

				.reduce("") { (acc, dep) in
					"\(acc)\n\t\(dep)"
				}
			return CarthageErrorCode.DuplicateDependencies.error([
				NSLocalizedDescriptionKey: "The following dependencies are duplicates:\(deps)"
			])
		}
	}
}


	/// A cartfile contains duplicate dependencies, either in itself or across
	/// other cartfiles.
	case DuplicateDependencies([DuplicateDependency])
}

extension CarthageError: Printable {
	public var description: String {
		switch self {
		case let .InvalidArgument(description):
			return description

		case let .MissingBuildSetting(setting):
			return "xcodebuild did not return a value for build setting \(setting)"

		case let .ReadFailed(fileURL):
			return "Failed to read file or folder at \(fileURL.path!)"

		case let .IncompatibleRequirements(dependency, first, second):
			return "Could not pick a version for \(dependency), due to mutually incompatible requirements:\n\t\(first)\n\t\(second)"

		case let .TaggedVersionNotFound(dependency):
			return "No tagged versions found for \(dependency)"

		case let .RequiredVersionNotFound(dependency, specifier):
			return "No available version for \(dependency) satisfies the requirement: \(specifier)"

		case let .RepositoryCheckoutFailed(workingDirectoryURL, reason):
			return "Failed to check out repository into \(workingDirectoryURL.path!): \(reason)"

		case let .WriteFailed(fileURL):
			return "Failed to create \(fileURL.path!)"

		case let .ParseError(description):
			return "Parse error: \(description)"

		case let .InvalidArchitectures(description):
			return "Invalid architecture: \(description)"

		case let .MissingEnvironmentVariable(variable):
			return "Environment variable not set: \(variable)"

		case let .NoSharedSchemes(project):
			return "Project \"\(project)\" has no shared schemes"

		case let .DuplicateDependencies(duplicateDeps):
			let deps = duplicateDeps
