     return ArbiterRequirementSatisfiedBy(pointer, version.pointer)
   }
 }
+
+public class RequirementPredicateBase
+{
+  private init ()
+  {}
+
+  private func satisfiedBy (selectedVersion: COpaquePointer) -> Bool
+  {
+    preconditionFailure("Must be overridden by subclasses")
+  }
+}
+
+public final class RequirementPredicate<VersionMetadata: ArbiterValue> : RequirementPredicateBase
+{
+  public typealias Predicate = SelectedVersion<VersionMetadata> -> Bool
+
+  private let closure: Predicate
+
+  public init (_ closure: Predicate)
+  {
+    self.closure = closure
+  }
+
+  private override func satisfiedBy (selectedVersion: COpaquePointer) -> Bool
+  {
+    return closure(SelectedVersion<VersionMetadata>(selectedVersion))
+  }
+}

  case CompatibleWith(SemanticVersion, ArbiterRequirementStrictness)
  case Exactly(SemanticVersion)
  case Unversioned(ArbiterUserValue)
  // TODO: Custom
  indirect case Compound([Specifier])
}


    case let .Unversioned(metadata):
      ptr = ArbiterCreateRequirementUnversioned(metadata)

    case let .Custom(predicate):
      ptr = ArbiterCreateRequirementCustom({ selectedVersion, context in
        let predicate: RequirementPredicateBase = fromUserContext(context)
        return predicate.satisfiedBy(selectedVersion)
      }, toUserContext(predicate))

    case let .Compound(specifiers):
      let requirements = specifiers.map { s in Requirement(s) }
      let requirementPtrs = requirements.map { $0.pointer }
