 
   defp validate_version(version) do
     ensure_present(:version, version)
+
     unless is_binary(version) and match?({:ok, _}, Version.parse(version)) do
       Mix.raise("Expected :version to be a SemVer version, got: #{inspect(version)}")
     end

  defp apps_from_prod_non_optional_deps(properties) do
    included_applications = Keyword.get(properties, :included_applications, [])

    for %{app: app, opts: opts, top_level: true} <- Mix.Dep.cached,
        Keyword.get(opts, :app, true),
        Keyword.get(opts, :runtime, true),
        not Keyword.get(opts, :optional, false),
        app not in included_applications,
        do: app
  end

  defp normalize_apps(apps, properties, config) do

  end

  defp validate_properties!(properties) do
    Enum.each(properties, fn
      {:description, value} ->
        unless is_list(value) do
          Mix.raise(
            "Application description (:description) is not a character list, got: #{
              inspect(value)
            }"
          )
        end

      {:id, value} ->
        unless is_list(value) do
          Mix.raise("Application id (:id) is not a character list, got: #{inspect(value)}")
        end

      {:vsn, value} ->
        unless is_list(value) do
          Mix.raise("Application vsn (:vsn) is not a character list, got: #{inspect(value)}")
        end

      {:maxT, value} ->
        unless value == :infinity or is_integer(value) do
          Mix.raise(
            "Application maximum time (:maxT) is not an integer or :infinity, got: " <>
              inspect(value)
          )
        end

      {:modules, value} ->
        unless is_list(value) and Enum.all?(value, &is_atom(&1)) do
          Mix.raise(
            "Application modules (:modules) should be a list of atoms, got: #{inspect(value)}"
          )
        end

      {:registered, value} ->
        unless is_list(value) and Enum.all?(value, &is_atom(&1)) do
          Mix.raise(
            "Application registered processes (:registered) should be a list of atoms, got: " <>
              inspect(value)
          )
        end

      {:included_applications, value} ->
        unless is_list(value) and Enum.all?(value, &is_atom(&1)) do
          Mix.raise(
            "Application included applications (:included_applications) should be a list of atoms, got: " <>
              inspect(value)
          )
        end

      {:extra_applications, value} ->
        unless is_list(value) and Enum.all?(value, &is_atom(&1)) do
          Mix.raise(
            "Application extra applications (:extra_applications) should be a list of atoms, got: " <>
              inspect(value)
          )
        end

      {:applications, value} ->
        unless is_list(value) and Enum.all?(value, &is_atom(&1)) do
          Mix.raise(
            "Application applications (:applications) should be a list of atoms, got: " <>
              inspect(value)
          )
        end

      {:env, value} ->
        unless Keyword.keyword?(value) do
          Mix.raise(
            "Application environment (:env) should be a keyword list, got: #{inspect(value)}"
          )
        end

      {:start_phases, value} ->
        unless Keyword.keyword?(value) do
          Mix.raise(
            "Application start phases (:start_phases) should be a keyword list, got: " <>
              inspect(value)
          )
        end

      {:mod, []} ->
        :ok

      {:mod, {module, _args}} when is_atom(module) ->
        :ok

      {:mod, value} ->
        Mix.raise(
          "Application callback module (:mod) should be either [] or {module, start_args}, got: " <>
            inspect(value)
        )

      _ ->
        :ok
    end)

    properties
  end
