 
   defp custom_validator(_, _), do: :ok
 
-  # Returns a map containing only keys that `map_1` and `map_2` have in common.
-  # Values for the returned map are taken from `map_2`.
-  @spec intersection(map, map) :: map
-  defp intersection(map_1, map_2) when is_map(map_1) and is_map(map_2),
-    do:
-      for(
-        key <- Map.keys(map_1),
-        true == Map.has_key?(map_2, key),
-        into: %{},
-        do: {key, Map.get(map_2, key)}
-      )
+  defp delete_properties(map, %{properties: nil}), do: map
+
+  defp delete_properties(map, %{properties: properties}) do
+    map
+    |> Enum.filter(fn {key, _value} -> !Map.has_key?(properties, key) end)
+    |> Enum.into(%{})
+  end
+
+  defp delete_patterns(map, %{pattern_properties: nil}), do: map
+
+  defp delete_patterns(map, %{pattern_properties: patterns}) do
+    patterns = Map.keys(patterns)
+
+    map
+    |> Enum.filter(fn {key, _value} -> !match_any?(patterns, key) end)
+    |> Enum.into(%{})
+  end
+
+  defp match_any?(patterns, pattern) when is_atom(pattern) do
+    match_any?(patterns, Atom.to_string(pattern))
+  end
+
+  defp match_any?(patterns, pattern) when is_binary(pattern) do
+    Enum.any?(patterns, fn regex -> Regex.match?(regex, pattern) end)
+  end
+
+  defp collect(results) do
+    Enum.reduce(results, :ok, fn
+      :ok, :ok ->
+        :ok
+
+      {:error, reason}, :ok ->
+        {:error, [reason]}
+
+      :ok, {:error, _} = error ->
+        error
+
+      {:error, reason}, {:error, reasons} ->
+        {:error, [reason | reasons]}
+    end)
+  end
 end

    end
  end

  defp additionals(_schema, _map, _opts), do: :ok

  @spec dependencies(Schema.t(), map, keyword) :: result
  defp dependencies(%{dependencies: nil}, _map, _opts), do: :ok


        do_properties(props, map, errors, opts)

      {:error, reason} ->
        updated_errors = Map.put(errors, prop, reason)
        do_properties(props, map, updated_errors, opts)
    end
  end

