            {:const, version}}
     end
 
-    defp pre_condition(:'>', pre) do
+    defp pre_condition(:>, pre) do
       length_pre = length(pre)
 
-      {:orelse, {:andalso, {:'==', {:length, :'$4'}, 0},
+      {:orelse, {:andalso, {:==, {:length, :'$4'}, 0},
                            {:const, length_pre != 0}},
                 {:andalso, {:const, length_pre != 0},
-                           {:orelse, {:'>', {:length, :'$4'}, length_pre},
-                                     {:andalso, {:'==', {:length, :'$4'}, length_pre},
-                                                {:'>', :'$4', {:const, pre}}}}}}
-    end
-
-    defp pre_condition(:'<', pre) do
+                           {:orelse, {:>, {:length, :'$4'}, length_pre},
+                                     {:andalso, {:==, {:length, :'$4'}, length_pre},
+                                                {:>, :'$4', {:const, pre}}}}}}
+    end
+
+    defp pre_condition(:<, pre) do
       length_pre = length(pre)
 
       {:orelse, {:andalso, {:'/=', {:length, :'$4'}, 0},
                            {:const, length_pre == 0}},
                 {:andalso, {:'/=', {:length, :'$4'}, 0},
-                           {:orelse, {:'<', {:length, :'$4'}, length_pre},
-                                     {:andalso, {:'==', {:length, :'$4'}, length_pre},
-                                                {:'<', :'$4', {:const, pre}}}}}}
+                           {:orelse, {:<, {:length, :'$4'}, length_pre},
+                                     {:andalso, {:==, {:length, :'$4'}, length_pre},
+                                                {:<, :'$4', {:const, pre}}}}}}
     end
 
     defp no_pre_condition(pre) do

        is_binary h ->
          [h <> x | acc]

        h in [:'||', :'&&'] ->
          [x, :'==', h | acc]

        true ->
          [x, h | acc]

      :invalid_matchspec -> :error
    end

    defp to_condition([:==, version | _]) do
      matchable = parse_condition(version)
      main_condition(:==, matchable)
    end

    defp to_condition([:!=, version | _]) do
      matchable = parse_condition(version)
      main_condition(:'/=', matchable)
    end

    defp to_condition([:~>, version | _]) do
      from = parse_condition(version, true)
      to   = approximate_upper(from)

      {:andalso, to_condition([:>=, matchable_to_string(from)]),
                 to_condition([:<, matchable_to_string(to)])}
    end

    defp to_condition([:>, version | _]) do
      {major, minor, patch, pre} = parse_condition(version)

      {:orelse, main_condition(:>, {major, minor, patch}),
                {:andalso, main_condition(:==, {major, minor, patch}),
                           {:andalso, no_pre_condition(pre),
                                      pre_condition(:>, pre)}}}
    end

    defp to_condition([:>=, version | _]) do
      matchable = parse_condition(version)

      {:orelse, main_condition(:==, matchable),
                to_condition([:>, version])}
    end

    defp to_condition([:<, version | _]) do
      {major, minor, patch, pre} = parse_condition(version)

      {:orelse, main_condition(:<, {major, minor, patch}),
                {:andalso, main_condition(:==, {major, minor, patch}),
                           {:andalso, no_pre_condition(pre),
                                      pre_condition(:<, pre)}}}
    end

    defp to_condition([:<=, version | _]) do
      matchable = parse_condition(version)

      {:orelse, main_condition(:==, matchable),
                to_condition([:<, version])}
    end

    defp to_condition(current, []) do
      current
    end

    defp to_condition(current, [:&&, operator, version | rest]) do
      to_condition({:andalso, current, to_condition([operator, version])}, rest)
    end

    defp to_condition(current, [:||, operator, version | rest]) do
      to_condition({:orelse, current, to_condition([operator, version])}, rest)
    end

