 }
 
 
-func validateIPv4(_ context: Context, _ value: Any) -> AnySequence<ValidationError> {
-  if let ipv4 = value as? String {
-    if let expression = try? NSRegularExpression(pattern: "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", options: NSRegularExpression.Options(rawValue: 0)) {
-      if expression.matches(in: ipv4, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, ipv4.count)).count == 1 {
+func validateIPv4(_ context: Context, _ value: String) -> AnySequence<ValidationError> {
+  if let expression = try? NSRegularExpression(pattern: "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", options: NSRegularExpression.Options(rawValue: 0)) {
+    if expression.matches(in: value, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, value.utf16.count)).count == 1 {
+      return AnySequence(EmptyCollection())
+    }
+  }
+
+  return AnySequence([
+    ValidationError(
+      "'\(value)' is not a IPv4 address.",
+      instanceLocation: context.instanceLocation,
+      keywordLocation: context.keywordLocation
+    )
+  ])
+}
+
+
+func validateIPv6(_ context: Context, _ value: String) -> AnySequence<ValidationError> {
+  if !value.contains("%") {
+    var buf = UnsafeMutablePointer<Int8>.allocate(capacity: Int(INET6_ADDRSTRLEN))
+    if inet_pton(AF_INET6, value, &buf) == 1 {
+      return AnySequence(EmptyCollection())
+    }
+  }
+
+  return AnySequence([
+    ValidationError(
+      "'\(value)' is not a value address.",
+      instanceLocation: context.instanceLocation,
+      keywordLocation: context.keywordLocation
+    )
+  ])
+}
+
+
+func validateURI(_ context: Context, _ value: String) -> AnySequence<ValidationError> {
+  // Using the regex from http://blog.dieweltistgarnichtso.net/constructing-a-regular-expression-that-matches-uris
+
+  if let expression = try? NSRegularExpression(pattern: "((?<=\\()[A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+(?=\\)))|([A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+)", options: NSRegularExpression.Options(rawValue: 0)) {
+    let result = expression.matches(in: value, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, value.utf16.count))
+    if result.count == 1 {
+      let foundRange = result[0].range
+      if foundRange.location == 0 && foundRange.length == value.utf16.count {
         return AnySequence(EmptyCollection())
       }
     }
+  }
 
+  return AnySequence([
+    ValidationError(
+      "'\(value)' is not a valid uri.",
+      instanceLocation: context.instanceLocation,
+      keywordLocation: context.keywordLocation
+    )
+  ])
+}
+
+
+func validateUUID(_ context: Context, _ value: String) -> AnySequence<ValidationError> {
+  if UUID(uuidString: value) == nil {
     return AnySequence([
       ValidationError(
-        "'\(ipv4)' is not a IPv4 address.",
+        "'\(value)' is not a valid uuid.",
         instanceLocation: context.instanceLocation,
         keywordLocation: context.keywordLocation
       )

}


func validateURI(_ context: Context, _ value: Any) -> AnySequence<ValidationError> {
  if let uri = value as? String {
    // Using the regex from http://blog.dieweltistgarnichtso.net/constructing-a-regular-expression-that-matches-uris

    if let expression = try? NSRegularExpression(pattern: "((?<=\\()[A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+(?=\\)))|([A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+)", options: NSRegularExpression.Options(rawValue: 0)) {
      let result = expression.matches(in: uri, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, uri.count))
      if result.count == 1 {
        let foundRange = result[0].range
        if foundRange.location == 0 && foundRange.length == uri.count {
          return AnySequence(EmptyCollection())
        }
      }
    }

    return AnySequence([
      ValidationError(
        "'\(uri)' is not a valid uri.",
        instanceLocation: context.instanceLocation,
        keywordLocation: context.keywordLocation
      )


  return AnySequence(EmptyCollection())
}
