       (?:\+([\d\w\-]+))?    # build
       $/x
 
-    @spec parse_requirement(String.t) :: {:ok, Version.Requirement.t} | :error
+    @spec parse_requirement(String.t) :: {:ok, term} | :error
     def parse_requirement(source) do
       lexed = lexer(source, [])
       to_matchspec(lexed)

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

      {:orelse, {:'>', {{:'$1', :'$2', :'$3'}},
                       {:const, {major, minor, patch}}},
                {:andalso, {:'==', {{:'$1', :'$2', :'$3'}},
                                        {:const, {major, minor, patch}}},
                {:orelse, {:andalso, {:'==', {:length, :'$4'}, 0},
                                     {:'/=', length(pre), 0}},
                          {:andalso, {:'/=', length(pre), 0},
                                     {:orelse, {:'>', {:length, :'$4'}, length(pre)},
                                     {:andalso, {:'==', {:length, :'$4'}, length(pre)},
                                                {:'>', :'$4', {:const, pre}}}}}}}}
    end

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

        {:ok, version} -> version
        :error -> throw :invalid_matchspec
      end
    end

    defp main_condition(op, major, minor, patch) do
      {op, {{:'$1', :'$2', :'$3'}},
           {:const, {major, minor, patch}}}
    end

    defp pre_condition(:'>', pre) do
      length_pre = length(pre)

      {: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
      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}}}}}}
    end

    defp matchable_to_string({major, minor, patch, pre}) do
