<project default="sort"
         xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">

  <property name="dirname" value="work" />
  <property name="dir" location="${dirname}" />
  <property name="echolevel" value="debug" />

  <target name="tearDown">
    <delete dir="${dir}" />
    <delete file="${zip}" />
    <delete file="${jar}" deleteonexit="true" />
    <delete file="${file}" />
  </target>

  <target name="sortsetup" unless="sortsetup.done">
    <mkdir dir="${dir}" />

    <echo file="${dir}/b" message="yyy" />
    <echo file="${dir}/e" message="aaa" />
    <sleep seconds="2" />
    <echo file="${dir}/c" message="x" />
    <echo file="${dir}/d" message="x" />
    <sleep seconds="2" />
    <echo file="${dir}/a" message="zz" />
    <echo file="${dir}/f" message="zz" />

    <mkdir dir="${dir}/a.dir" />
    <mkdir dir="${dir}/b.dir" />
    <mkdir dir="${dir}/c.dir" />

    <macrodef name="mysort">
      <attribute name="property" />
      <attribute name="separator" default="," />
      <element name="cmp" optional="true" implicit="true" />
      <sequential>
        <pathconvert property="@{property}" pathsep="@{separator}">
          <sort>
            <fileset dir="${dir}" includes="a,b,c" />
            <cmp />
          </sort>
          <flattenmapper />
        </pathconvert>
        <echo level="${echolevel}">@{property}=${@{property}}</echo>
      </sequential>
    </macrodef>

    <property name="sortsetup.done" value="true" />
  </target>

  <target name="testsortdefault" depends="sortsetup">
    <mysort property="sortdf" />
    <fail>
      <condition>
        <not>
          <equals arg1="${sortdf}" arg2="a,b,c" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvdefault" depends="sortsetup">
    <mysort property="sortdf-rev">
      <rcmp:reverse />
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortdf-rev}" arg2="c,b,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testname" depends="sortsetup">
    <mysort property="sortnm">
      <rcmp:name />
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortnm}" arg2="a,b,c" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvname" depends="sortsetup">
    <mysort property="sortnm-rev">
      <rcmp:reverse>
        <rcmp:name />
      </rcmp:reverse>
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortnm-rev}" arg2="c,b,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testdate" depends="sortsetup">
    <mysort property="sortlm">
      <rcmp:date />
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortlm}" arg2="b,c,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvdate" depends="sortsetup">
    <mysort property="sortlm-rev">
      <rcmp:reverse>
        <rcmp:date />
      </rcmp:reverse>
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortlm-rev}" arg2="a,c,b" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testsize" depends="sortsetup">
    <mysort property="sortsz">
      <rcmp:size />
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortsz}" arg2="c,a,b" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvsize" depends="sortsetup">
    <mysort property="sortsz-rev">
      <rcmp:reverse>
        <rcmp:size />
      </rcmp:reverse>
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortsz-rev}" arg2="b,a,c" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testcontent" depends="sortsetup">
    <mysort property="sortct">
      <rcmp:content />
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortct}" arg2="c,b,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvcontent" depends="sortsetup">
    <mysort property="sortct-rev">
      <rcmp:reverse>
        <rcmp:content />
      </rcmp:reverse>
    </mysort>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortct-rev}" arg2="a,b,c" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testexists" depends="sortsetup">
    <pathconvert property="sortex" pathsep=",">
      <sort>
        <resources>
          <file file="${dir}/a" />
          <resource name="redherring" exists="false" />
        </resources>
        <rcmp:exists />
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortex}" arg2="redherring,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvexists" depends="sortsetup">
    <pathconvert property="sortex-rev" pathsep=",">
      <sort>
        <resources>
          <file file="${dir}/a" />
          <resource name="redherring" exists="false" />
        </resources>
        <rcmp:reverse>
          <rcmp:exists />
        </rcmp:reverse>
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortex-rev}" arg2="a,redherring" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testtype" depends="sortsetup">
    <pathconvert property="sorttp" pathsep=",">
      <sort>
        <resources>
          <file file="${dir}/a" />
          <file file="${dir}/a.dir" />
        </resources>
        <rcmp:type />
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sorttp}" arg2="a,a.dir" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testrvtype" depends="sortsetup">
    <pathconvert property="sorttp-rev" pathsep=",">
      <sort>
        <resources>
          <file file="${dir}/a" />
          <file file="${dir}/a.dir" />
        </resources>
        <rcmp:reverse>
          <rcmp:type />
        </rcmp:reverse>
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sorttp-rev}" arg2="a.dir,a" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="forwardsort"
    depends="testsortdefault,testname,testdate,testsize,testcontent,testexists,testtype" />

  <target name="reversesort"
    depends="testrvdefault,testrvname,testrvdate,testrvsize,testrvcontent,testrvexists,testrvtype" />

  <target name="testcompoundsort1" depends="sortsetup">
    <pathconvert property="sortcmp1" pathsep=",">
      <sort>
        <resources>
          <file file="${dir}/c" />
          <file file="${dir}/b.dir" />
          <file file="${dir}/a" />
          <file file="${dir}/c.dir" />
          <file file="${dir}/b" />
          <file file="${dir}/a.dir" />
        </resources>
        <rcmp:reverse>
          <rcmp:type />
        </rcmp:reverse>
        <rcmp:name />
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortcmp1}" arg2="a.dir,b.dir,c.dir,a,b,c" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="testcompoundsort2" depends="sortsetup">
    <pathconvert property="sortcmp2" pathsep=",">
      <sort>
        <files includes="${dir}/?" />
        <rcmp:size />
        <rcmp:content />
        <rcmp:reverse>
          <rcmp:name />
        </rcmp:reverse>
      </sort>
      <flattenmapper />
    </pathconvert>
    <fail>
      <condition>
        <not>
          <equals arg1="${sortcmp2}" arg2="d,c,f,a,e,b" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="compoundsort" depends="testcompoundsort1,testcompoundsort2" />

  <target name="sort" depends="forwardsort,reversesort,compoundsort" />

</project>
