<commit_before><project name="buck" default="default">
  <property environment="env"/>

  <property name="src.dir" value="${basedir}/src" />
  <property name="aosp.src.dir" value="third-party/java/aosp/src" />
  <property name="test.dir" value="${basedir}/test" />
  <property name="third-party.dir" value="${basedir}/third-party" />
  <property name="build.dir" value="${basedir}/build" />
  <property name="aosp.classes.dir" value="${build.dir}/aosp/classes" />
  <property name="testrunner.classes.dir" value="${build.dir}/testrunner/classes" />
  <property name="bootstrapper.src.dir" value="com/facebook/buck/cli/bootstrapper/" />
  <property name="bootstrapper.classes.dir" value="${build.dir}/bootstrapper/classes" />
  <property name="bootstrapper.jar" value="${build.dir}/bootstrapper/bootstrapper.jar" />
  <property name="tracing-api.src.dir" value="com/facebook/buck/event/api/" />
  <property name="tracing-api.classes.dir" value="${build.dir}/tracing-api/classes" />
  <property name="tracing-api.jar" value="${build.dir}/tracing-api/tracing-api.jar"/>
  <property name="javac-tracing.src.dir" value="com/facebook/buck/jvm/java/tracing" />
  <property name="javac-tracing.classes.dir" value="${build.dir}/javac-tracing/classes" />
  <property name="javac-tracing.jar" value="${build.dir}/javac-tracing/javac-tracing-compiler-plugin.jar" />
  <property name="buck.path_to_pex" value="${basedir}/src/com/facebook/buck/python/make_pex.py" />
  <property name="buck.path_to_python_test_main" value="${basedir}/src/com/facebook/buck/python/__test_main__.py" />
  <property name="buck.path_to_sh_binary_template" value="${basedir}/src/com/facebook/buck/shell/sh_binary_template" />
  <property name="buck.logging_config_file" value="${basedir}/config/logging.properties" />
  <property name="buck.test_logging_config_file" value="${basedir}/config/logging.test.properties" />
  <property name="classes.dir" value="${build.dir}/classes" />
  <property name="testclasses.dir" value="${build.dir}/testclasses" />
  <property name="javadoc.dir" value="${build.dir}/javadoc" />
  <property name="javadoc-with-android.dir" value="${build.dir}/javadoc-with-android" />
  <property name="javadoc-all.dir" value="${build.dir}/javadoc-all" />
  <property name="test.class" value="Test" />
  <property name="test.debug_port" value="8787" />
  <property name="lint.outputpath" value="${build.dir}/lint.output" />

  <property name="dx.base.dir" value="${basedir}/third-party/java/dx" />
  <property name="dx.src.dir" value="${dx.base.dir}/src" />
  <property name="dx.test.dir" value="${dx.base.dir}/tests" />
  <property name="dx.etc.dir" value="${dx.base.dir}/etc" />
  <property name="dx.classes.dir" value="${build.dir}/dx_classes" />

  <property name="eclipse.dir" value="${basedir}/third-party/java/eclipse" />

  <property name="pathlib.dir" value="${third-party.dir}/py/pathlib" />
  <property name="unittest2.dir" value="${third-party.dir}/py/unittest2" />
  <property name="pywatchman.dir" value="${third-party.dir}/py/pywatchman" />
  <property name="nailgun.dir" value="${third-party.dir}/nailgun" />

  <property name="buck.pythonpath" value="${pathlib.dir}:${pywatchman.dir}:${nailgun.dir}" />

  <property name="immutables-value-standalone.jar" value="${third-party.dir}/java/immutables/value-2.0.21.jar" />
  <property name="immutables.gensrc.dir" value="${build.dir}/immutables" />
  <property name="immutables.gensrc.test.dir" value="${build.dir}/immutables-tests" />

  <property name="manual.gensrc.dir" value="${basedir}/src-gen" />
  <property name="manual.gensrc.classes.dir" value="${build.dir}/src-gen/classes" />

  <!-- Javadoc in 1.8 became stricter about parsing the docs. This disables some of those checks -->
  <available property="jdk1.8" classname="java.util.stream.Stream"/>
  <condition
          property="javadoc.doclint"
          value="-Xdoclint:-reference"
          else="">
    <and>
      <isset property="jdk1.8"/>
    </and>
  </condition>

  <fileset dir="${third-party.dir}/java" id="buck.jars">
    <include name="args4j/args4j-2.0.30.jar" />
    <include name="ddmlib/ddmlib-22.5.3.jar" />
    <include name="guava/guava-19.0.jar" />
    <include name="ini4j/ini4j-0.5.2.jar" />
    <include name="jackson/jackson-annotations-2.5.5.jar" />
    <include name="jackson/jackson-core-2.5.5.jar" />
    <include name="jackson/jackson-databind-2.5.5.jar" />
    <include name="jackson/jackson-datatype-jdk7-2.5.0.jar" />
    <include name="jackson-datatype-guava/jackson-datatype-guava-2.5.5.jar" />
    <include name="jsr/jsr305.jar" />
    <include name="android/sdklib.jar" />
    <include name="nailgun/nailgun-server-0.9.2-SNAPSHOT.jar" />
    <include name="jna/jna-4.2.0.jar" />
  </fileset>

  <fileset dir="${third-party.dir}/java" id="third-party.jars">
    <include name="ObjCBridge/ObjCBridge.jar" />
    <include name="android/sdk-common-24.2.3.jar" />
    <include name="android/common-24.2.3.jar" />
    <include name="android/layoutlib-api-24.2.3.jar" />
    <include name="aopalliance/aopalliance.jar" />
    <include name="asm/asm-debug-all-5.0.3.jar" />
    <include name="closure-templates/soy-excluding-deps.jar" />
    <include name="commons-compress/commons-compress-1.8.1.jar" />
    <include name="concurrent-locks/concurrent-locks-1.0.0.jar" />
    <include name="dd-plist/dd-plist.jar" />
    <include name="eclipse/org.eclipse.core.contenttype_3.4.200.v20140207-1251.jar"/>
    <include name="eclipse/org.eclipse.core.jobs_3.6.1.v20141014-1248.jar"/>
    <include name="eclipse/org.eclipse.core.resources_3.9.1.v20140825-1431.jar"/>
    <include name="eclipse/org.eclipse.core.runtime_3.10.0.v20140318-2214.jar"/>
    <include name="eclipse/org.eclipse.equinox.common_3.6.200.v20130402-1505.jar"/>
    <include name="eclipse/org.eclipse.equinox.preferences_3.5.200.v20140224-1527.jar"/>
    <include name="eclipse/org.eclipse.jdt.core_3.10.2.v20150120-1634.jar"/>
    <include name="eclipse/org.eclipse.osgi_3.10.2.v20150203-1939.jar"/>
    <include name="guice/guice-3.0.jar" />
    <include name="guice/guice-assistedinject-3.0.jar" />
    <include name="guice/guice-multibindings-3.0.jar" />
    <include name="gson/gson-2.2.4.jar" />
    <include name="icu4j/icu4j-54.1.1.jar" />
    <include name="immutables/value-2.0.21.jar" />
    <include name="infer-annotations/infer-annotations-1.5.jar" />
    <include name="nuprocess/nuprocess-1.0.5-SNAPSHOT.jar" />
    <include name="jacoco/org.jacoco.core-0.7.5.201505241946.jar" />
    <include name="jacoco/org.jacoco.report-0.7.5.201505241946.jar" />
    <include name="jetty/jetty-all-9.2.10.v20150310.jar" />
    <include name="jimfs/jimfs-1.0.jar" />
    <include name="jsr/javax.inject-1.jar" />
    <include name="okhttp/okhttp-2.7.4.jar" />
    <include name="okio/okio-1.6.0.jar" />
    <include name="servlet-api/javax.servlet-api-3.1.0.jar" />
    <include name="slf4j/slf4j-jdk14-1.7.5.jar" /><!-- redirect slf4j to java.util.logging -->
    <include name="stringtemplate/ST-4.0.8.jar" />
    <include name="thrift/libthrift-0.9.3.jar" />
    <include name="xz-java-1.3/xz-1.3.jar" />

    <!-- maven interop -->
    <include name="aether/aether-api-1.0.2.v20150114.jar" />
    <include name="aether/aether-connector-basic-1.0.2.v20150114.jar" />
    <include name="aether/aether-impl-1.0.0.v20140518.jar" />
    <include name="aether/aether-spi-1.0.2.v20150114.jar" />
    <include name="aether/aether-transport-http-1.0.2.v20150114.jar" />
    <include name="aether/aether-util-1.0.2.v20150114.jar" />
    <include name="httpcomponents/httpclient-4.2.6.jar" />
    <include name="httpcomponents/httpcore-4.2.5.jar" />
    <include name="maven/maven-aether-provider-3.2.5.jar" />
    <include name="maven/maven-model-3.2.5.jar" />
    <include name="maven/maven-model-builder-3.2.5.jar" />
    <include name="maven/maven-repository-metadata-3.2.5.jar" />
    <include name="plexus/plexus-utils-3.0.20.jar" />
    <include name="plexus/plexus-interpolation-1.21.jar" />
    <include name="slf4j/jcl-over-slf4j-1.6.2.jar" />
    <include name="slf4j/slf4j-api-1.7.5.jar" />
  </fileset>

  <path id="classpath-no-src-no-aosp">
    <fileset refid="buck.jars" />
    <fileset refid="third-party.jars" />
    <pathelement location="${classes.dir}" />
    <pathelement location="${dx.classes.dir}" />
    <pathelement location="${bootstrapper.jar}" />
    <pathelement location="${manual.gensrc.classes.dir}" />
  </path>

  <path id="classpath-no-src">
    <path refid="classpath-no-src-no-aosp" />
    <pathelement location="${aosp.classes.dir}" />
  </path>

  <path id="classpath">
    <path refid="classpath-no-src" />
    <pathelement location="${src.dir}" />
    <pathelement location="${immutables.gensrc.dir}" />
    <pathelement location="${manual.gensrc.dir}" />
  </path>

  <path id="classpath-generate-immutables">
    <fileset refid="buck.jars" />
    <fileset refid="third-party.jars" />
    <pathelement location="${aosp.classes.dir}" />
  </path>

  <path id="classpath-compile-manual-gen-src">
    <fileset refid="third-party.jars" />
  </path>

  <path id="junit">
    <pathelement location="${third-party.dir}/java/junit/junit-4.12.jar" />
    <pathelement location="${third-party.dir}/java/hamcrest/hamcrest-junit-2.0.0.0.jar" />
    <pathelement location="${third-party.dir}/java/hamcrest/java-hamcrest-2.0.0.0.jar" />
    <pathelement location="${third-party.dir}/java/testng/testng-6.8.jar" />
    <pathelement location="${third-party.dir}/java/ddmlib/ddmlib-22.5.3.jar" />
  </path>

  <target name="clean" description="remove all generated files">
    <delete dir="${build.dir}" />
  </target>

  <!-- Default target so that a command line build can
       do more than one thing. -->
  <target name="default" depends="compile, dx, javac-tracing, report-generator-jar" />

  <target name="checkversion">
    <!-- The nio Files class was only introduced in Java 7. -->
    <available property="jdk7" classname="java.nio.file.Files"/>
    <fail message="Require JDK 7 or higher" unless="jdk7"/>
  </target>

  <target name="python-get-prefix">
    <exec executable="python" failonerror="true" outputproperty="python.prefix" logError="true">
      <arg value="-c" />
      <arg value="import distutils.sysconfig; print(distutils.sysconfig.PREFIX)" />
    </exec>
  </target>

  <target name="compile-manual-gen-src" depends="checkversion">
    <mkdir dir="${manual.gensrc.classes.dir}" />
    <javac srcdir="${manual.gensrc.dir}"
           destdir="${manual.gensrc.classes.dir}"
           classpathref="classpath-compile-manual-gen-src"
           debug="on"
           includeAntRuntime="no"
            >
    </javac>
  </target>

  <target name="compile-testrunner" depends="checkversion">
    <mkdir dir="${testrunner.classes.dir}" />
    <javac srcdir="${src.dir}"
           includes="com/facebook/buck/log/AppendableLogRecord.java,com/facebook/buck/testrunner/**,com/facebook/buck/util/concurrent/MoreExecutors.java,com/facebook/buck/jvm/java/runner/**"
           destdir="${testrunner.classes.dir}"
           classpathref="junit"
           debug="on"
           includeAntRuntime="no"
           >
      <compilerarg value="-Xlint:rawtypes" />
      <compilerarg value="-Xlint:unchecked" />
      <compilerarg value="-Xlint:serial" />
    </javac>
  </target>

  <path id="bootstrapper-classpath">
    <!-- Do not add dependencies. The bootstrapper is intended to keep the system ClassLoader free
         of classes that might conflict with those used by compiler plugins and annotation
         processors. As such it cannot depend on third-party libraries, directly or indirectly. -->
  </path>

  <target name="bootstrapper" depends="checkversion, tracing-api">
    <mkdir dir="${bootstrapper.classes.dir}" />
    <ecj destdir="${bootstrapper.classes.dir}" classpathref="bootstrapper-classpath">
      <javac-params>
        <include name="${bootstrapper.src.dir}/**/*.java" />
        <include name="${javac-tracing.src.dir}/JavacPhaseTracer.java" />
        <include name="com/facebook/buck/util/exportedfiles/Nullable.java" />
        <include name="com/facebook/buck/util/exportedfiles/Preconditions.java" />
      </javac-params>
    </ecj>
    <jar destfile="${bootstrapper.jar}">
      <fileset dir="${bootstrapper.classes.dir}" />

      <!-- Be very careful what is added here, and leave comments justifying each addition. See the
      comment in bootstrapper-classpath above for more details on why. -->

      <!-- The Tracing API jar must be accessible to both Buck and compiler plugins, so we put it
      in the bootstrapper. Compiler plugins will have their own copy linked in, but the ClassLoaders
      will end up loading this one instead when they are run inside Buck. -->
      <zipfileset src="${tracing-api.jar}" />
    </jar>
  </target>

  <path id="tracing-api.classpath">
    <!-- The Tracing API is a very light JAR meant to be included in compiler plugins that may
    be run outside of Buck. As such, it can take no dependencies. -->
  </path>

  <target name="tracing-api" depends="checkversion">
    <mkdir dir="${tracing-api.classes.dir}" />
    <ecj destdir="${tracing-api.classes.dir}" classpathref="tracing-api.classpath">
      <javac-params>
        <include name="${tracing-api.src.dir}/**/*.java"/>
      </javac-params>
    </ecj>
    <jar destfile="${tracing-api.jar}">
      <fileset dir="${tracing-api.classes.dir}"/>
    </jar>
  </target>

  <path id="javac-tracing.classpath">
    <!-- This jar is loaded in each compiler class loader, which is unrelated to Buck's class
    loader. Do not take dependencies on Buck code outside of the bootstrapper here. Compiler
    code (tools.jar) and third-party libraries are OK, though keep in mind that every class included
    in the jar will be freshly loaded for each invocation of the compiler. -->
    <pathelement location="${third-party.dir}/java/jdk/stub-compiler-tree-api.jar" />
    <pathelement location="${bootstrapper.jar}" />
  </path>

  <target name="javac-tracing" depends="checkversion, tracing-api">
    <mkdir dir="${javac-tracing.classes.dir}" />
    <ecj destdir="${javac-tracing.classes.dir}" classpathref="javac-tracing.classpath">
      <javac-params>
        <include name="com/facebook/buck/util/exportedfiles/Nullable.java" />
        <include name="com/facebook/buck/util/exportedfiles/Preconditions.java" />
        <include name="${javac-tracing.src.dir}/TracingTaskListener.java" />
      </javac-params>
    </ecj>
    <jar destfile="${javac-tracing.jar}">
      <fileset dir="${javac-tracing.classes.dir}"/>
    </jar>

    <!-- Put the tracing jar in resources so it can be dynamically loaded at runtime. See
     TranslatingJavacPhaseTracer -->
    <copy file="${javac-tracing.jar}" todir="${classes.dir}/com/facebook/buck/jvm/java/tracing" />
  </target>

  <path id="immutables-classpath">
    <path refid="classpath" />
    <pathelement location="${immutables-value-standalone.jar}" />
    <pathelement location="${src.dir}" />
    <pathelement location="${aosp.classes.dir}" />
    <pathelement location="${manual.gensrc.dir}" />
  </path>

  <!-- The set of Immutables value type source files which have not
       yet been run through the javac annotation processor. -->
  <fileset dir="${src.dir}" id="immutables-srcs">
    <!-- Speed up the build by only running javac on files containing Immutables. -->
    <contains text="org.immutables" />
    <exclude name="com/facebook/buck/android/support/**" />
    <exclude name="com/facebook/buck/cli/quickstart/**" />
    <exclude name="com/facebook/buck/testrunner/**" />
    <!-- Only run javac on immutables files which have changed since the last build. -->
    <modified>
      <param name="cache.cachefile" value="${build.dir}/immutables.modified.properties" />
    </modified>
  </fileset>

  <target name="check-immutables">
    <!--
      javac rules don't support filesets, but they do support comma-separated lists of
      sources in the includes parameter.

      However, if the includes parameter is empty, the javac rule will build everything,
      which we don't want. So we have to skip the generate-immutables step entirely
      in that case.

      This sets ${immutables-srcs-flattened} to a comma-separated list of files to build,
      then sets ${generate-immutables-needed} to true iff that variable is non-empty.
    -->
    <pathconvert property="immutables-srcs-flattened" pathsep="," refid="immutables-srcs">
      <map from="${src.dir}/" to=""/>
    </pathconvert>
    <condition property="generate-immutables-needed">
      <length string="${immutables-srcs-flattened}" when="greater" length="0" />
    </condition>
  </target>

  <target name="compile-aosp" depends="checkversion">
    <mkdir dir="${aosp.classes.dir}" />
    <ecj srcdir="${aosp.src.dir}" destdir="${aosp.classes.dir}">
      <ecj-params>
        <!-- ManifestMerger.java has redundant null checks -->
        <compilerarg value="-err:-null" />
      </ecj-params>
    </ecj>
  </target>

  <target name="generate-immutables" depends="compile-aosp, check-immutables" if="${generate-immutables-needed}">
    <mkdir dir="${immutables.gensrc.dir}" />
    <javac srcdir="${src.dir}:${manual.gensrc.dir}:${immutables.gensrc.dir}"
           classpathref="classpath-generate-immutables"
           includeAntRuntime="no"
           includes="${immutables-srcs-flattened}">
      <compilerarg value="-Werror" />
      <compilerarg value="-processorpath" />
      <compilerarg value="${immutables-value-standalone.jar}" />
      <compilerarg value="-proc:only" />
      <compilerarg value="-s" />
      <compilerarg value="${immutables.gensrc.dir}" />
    </javac>
  </target>

  <macrodef name="ecj" description="Compile Java using the ecj compiler with strict checks.">
    <attribute name="srcdir" default="${src.dir}" />
    <attribute name="classpathref" default="classpath-no-src" />
    <attribute name="destdir" default="${classes.dir}" />
    <!--
      javac-params can contain any extra parameters to the javac ant command.

      include and exclude elements are automatically relative to ${src.dir}.

      According to http://ant.apache.org/manual/Tasks/javac.html, the only way
      to enumerate the .java inputs to javac in Ant is to set the sourcepath
      to the empty string, set the srcdir to something, and use include/exclude
      elements to filter things under the srcdir.
    -->
    <element name="javac-params" optional="true" />
    <!--
      ecj-params can contain any extra paramters to the Eclipse batch compiler.
    -->
    <element name="ecj-params" optional="true" />
    <sequential>
      <javac srcdir="@{srcdir}"
             sourcepath=""
             destdir="@{destdir}"
             classpathref="@{classpathref}"
             debug="on"
             deprecation="on"
             includeAntRuntime="no"
             compiler="org.eclipse.jdt.core.JDTCompilerAdapter"
             >
        <javac-params />
        <!--
          ecj does not appear to support -Werror. As suggested by
          http://stackoverflow.com/a/14927725/396304, we specify an Eclipse preferences
          file to ECJ with the rules we want to enforce set to error.

          To see the full list of compiler options available, read the Javadoc for JavaCore at:
          http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2FJavaCore.html
          Apparently Eclipse refuses to publish traditional Javadoc with manageable URLs.
        -->
        <compilerarg line="-properties ${eclipse.dir}/org.eclipse.jdt.core.prefs" />
        <compilerarg value="-Xlint:rawtypes" />
        <compilerarg value="-Xlint:unchecked" />
        <compilerarg value="-Xlint:serial" />
        <compilerarg value="-time" />
        <compilerclasspath>
          <pathelement location="${eclipse.dir}/org.eclipse.jdt.core_3.10.2.v20150120-1634.jar" />
          <pathelement location="${eclipse.dir}/jdtCompilerAdapter.jar" />
        </compilerclasspath>
        <ecj-params />
      </javac>
    </sequential>
  </macrodef>

  <target name="package-resources">
    <mkdir dir="${classes.dir}/com/facebook/buck/cli/quickstart/android"/>
    <zip basedir="src/com/facebook/buck/cli/quickstart/android"
         destfile="${classes.dir}/com/facebook/buck/cli/quickstart/android/android-template.zip"
         excludes="BUCK"
         defaultexcludes="no"/>

    <mkdir dir="${classes.dir}/com/facebook/buck/cli/quickstart/ios"/>
    <zip basedir="src/com/facebook/buck/cli/quickstart/ios"
         destfile="${classes.dir}/com/facebook/buck/cli/quickstart/ios/ios-template.zip"
         excludes="BUCK"
         defaultexcludes="no"/>
    <mkdir dir="${classes.dir}/com/facebook/buck/android"/>
    <copy file="${third-party.dir}/java/ddmlib/ddmlib-22.5.3.jar"
          tofile="${classes.dir}/com/facebook/buck/android/ddmlib.jar"/>
    <copy file="${third-party.dir}/java/kxml2/kxml2-2.3.0.jar"
          tofile="${classes.dir}/com/facebook/buck/android/kxml2.jar"/>
  </target>

  <target name="compile"
          depends="compile-testrunner, compile-aosp, compile-manual-gen-src, bootstrapper, package-resources, tracing-api, dx, generate-immutables"
          description="compile Java source code">
    <mkdir dir="${classes.dir}" />

    <!-- Copy in scripts we need at run time when using an unpacked buck -->
    <copy file="src/com/facebook/buck/json/buck.py" todir="${classes.dir}/com/facebook/buck/json"/>

    <ecj>
      <javac-params>
        <patternset>
          <!--
            These patterns are excluded because they are compiled elsewhere
            and are deliberately isolated from Buck's core.
          -->
          <exclude name="com/facebook/buck/android/support/**" />
          <exclude name="com/facebook/buck/cli/bootstrapper/**" />
          <exclude name="com/facebook/buck/cli/quickstart/**" />
          <exclude name="com/facebook/buck/event/api/**" />
          <exclude name="com/facebook/buck/intellij/plugin/**" />
          <exclude name="com/facebook/buck/testrunner/**" />
        </patternset>
        <or>
          <filename name="${javac-tracing.src.dir}/JavacPhaseEvent.java" />
          <filename name="${javac-tracing.src.dir}/JavacPhaseEventLogger.java" />
          <filename name="${javac-tracing.src.dir}/TranslatingJavacPhaseTracer.java" />
          <not>
            <filename name="${javac-tracing.src.dir}/**" />
          </not>
        </or>
        <src path="${immutables.gensrc.dir}" />
      </javac-params>
    </ecj>
  </target>

  <fileset dir="${third-party.dir}/java" id="dx.jars">
    <include name="guava/guava-19.0.jar" />
  </fileset>

  <path id="dx.classpath">
    <fileset refid="dx.jars" />
  </path>

  <target name="dx-check-build">
    <uptodate property="dx-build-not-required" targetfile="${build.dir}/dx.jar">
      <srcfiles dir="${dx.src.dir}" includes="**/*.java" />
      <srcfiles dir="${third-party.dir}/java/guava" includes="guava-*.jar" />
      <srcfiles dir="${third-party.dir}/java/junit" includes="junit-*.jar" />
    </uptodate>
  </target>

  <target name="dx" depends="dx-check-build" unless="dx-build-not-required">
    <mkdir dir="${dx.classes.dir}" />

    <javac destdir="${dx.classes.dir}"
           classpathref="dx.classpath"
           debug="on"
           deprecation="on"
           includeAntRuntime="no"
           >
      <src path="${dx.src.dir}" />
    </javac>

    <jar destfile="${build.dir}/dx.jar">
      <zipfileset includes="**/*.class" src="${third-party.dir}/java/guava/guava-19.0.jar"/>
      <zipfileset includes="**/*.class" src="${third-party.dir}/java/junit/junit-4.12.jar" />
      <fileset dir="${dx.classes.dir}" />
      <manifest>
        <attribute name="Main-Class" value="com.android.dx.command.Main" />
      </manifest>
    </jar>
  </target>

  <!--
       Note: two of the dx tests (the two tests for the merger) run the command
       "dalvik" and expect it to be a working dalvik virtual machine.
       Fulfilling this expectation is no easy task.  Here's how I did it.

       - Be on Linux (Dalvik doesn't build for Mac).
       - Check out Android (I used ICS because I had it lying around).
       - make -kj25 dalvik-host
       - If you built on a remote machine, rsync "out" to where you are
         developing Buck, inside of a dedicated directory called "android"
         or something.
       - Edit android/out/host/linux-x86/dalvik to change the log tags to
         "*:w", because a spurious info message was messing up the test.
       - Delete android/out/host/linux-x86/dx so the tests will use our dx.
       - Run this rule as
         ANDROID_BUILD_TOP=/path/to/android PATH=$PATH:$ANDROID_BUILD_TOP/out/host/linux-x86/bin ant dx-tests
       -->
  <target name="dx-tests" depends="dx">
    <exec
        failonerror="true"
        dir="${dx.test.dir}"
        executable="./run-all-tests">
      <env key="PATH" path="${env.PATH}:${dx.etc.dir}"/>
    </exec>
  </target>

  <target name="jar" depends="buck-jar, report-generator-jar"/>

  <target name="buck-jar"
          depends="compile"
          description="build buck.jar"
          >

    <jar destfile="${build.dir}/buck.jar" update="true">
      <zipfileset refid="buck.jars" />
      <zipfileset refid="third-party.jars" />
      <fileset dir="${src.dir}"
               excludes="**/*.java, **/BUCK"
               />
      <fileset dir="${classes.dir}" />
      <manifest>
        <attribute name="Main-Class" value="com.facebook.buck.cli.Main" />
      </manifest>
    </jar>
  </target>

  <target name="report-generator-jar" depends="compile">
    <jar destfile="${build.dir}/report-generator.jar">
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/jacoco/org.jacoco.core-0.7.5.201505241946.jar"/>
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/jacoco/org.jacoco.report-0.7.5.201505241946.jar"/>
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/asm/asm-debug-all-5.0.3.jar"/>
      <fileset dir="${classes.dir}">
          <include name="com/facebook/buck/jvm/java/coverage/ReportGenerator.class"/>
      </fileset>
      <manifest>
        <attribute name="Main-Class" value="com.facebook.buck.jvm.java.coverage.ReportGenerator" />
      </manifest>
    </jar>
  </target>

  <path id="tests.run.classpath">
    <path refid="classpath" />
    <fileset dir="${third-party.dir}/java">
      <include name="caliper/caliper-1.0-all.jar" />
      <include name="cglib/cglib-nodep-2.2.jar" />
      <include name="easymock/easymock-3.3.1.jar" />
      <include name="hamcrest/hamcrest-junit-2.0.0.0.jar" />
      <include name="hamcrest/java-hamcrest-2.0.0.0.jar" />
      <include name="junit/junit-4.12.jar" />
      <include name="objenesis/objenesis-1.2.jar" />
    </fileset>

    <pathelement location="${testclasses.dir}" />
    <pathelement location="${test.dir}" />
    <pathelement location="${testrunner.classes.dir}" />
    <pathelement location="${immutables.gensrc.dir}" />
    <pathelement location="${immutables.gensrc.test.dir}" />
  </path>

  <path id="tests.compile.classpath">
    <path refid="tests.run.classpath" />
    <pathelement location="${third-party.dir}/java/jdk/stub-compiler-tree-api.jar" />
  </path>

  <!-- The set of Immutables value type source files which have not
       yet been run through the javac annotation processor. -->
  <fileset dir="${test.dir}" id="immutables-test-srcs">
    <!-- Speed up the build by only running javac on files containing Immutables. -->
    <contains text="org.immutables" />
    <exclude name="**/testdata/**" />
    <!-- Only run javac on immutables files which have changed since the last build. -->
    <modified>
      <param name="cache.cachefile" value="${build.dir}/immutables.test.modified.properties" />
    </modified>
  </fileset>

  <target name="check-test-immutables">
    <!--
      javac rules don't support filesets, but they do support comma-separated lists of
      sources in the includes parameter.

      However, if the includes parameter is empty, the javac rule will build everything,
      which we don't want. So we have to skip the generate-immutables step entirely
      in that case.

      This sets ${immutables-test-srcs-flattened} to a comma-separated list of files to build,
      then sets ${generate-test-immutables-needed} to true iff that variable is non-empty.
    -->
    <pathconvert property="immutables-test-srcs-flattened" pathsep="," refid="immutables-test-srcs">
      <map from="${test.dir}/" to=""/>
    </pathconvert>
    <condition property="generate-test-immutables-needed">
      <length string="${immutables-test-srcs-flattened}" when="greater" length="0" />
    </condition>
  </target>

  <target name="generate-test-immutables" depends="compile, check-test-immutables" if="${generate-test-immutables-needed}">
    <mkdir dir="${immutables.gensrc.test.dir}" />
    <javac srcdir="${test.dir}:${immutables.gensrc.test.dir}"
           includes="${immutables-test-srcs-flattened}"
           classpathref="tests.compile.classpath"
           includeAntRuntime="no">
      <compilerarg value="-Werror" />
      <compilerarg value="-processorpath" />
      <compilerarg value="${immutables-value-standalone.jar}" />
      <compilerarg value="-proc:only" />
      <compilerarg value="-s" />
      <compilerarg value="${immutables.gensrc.test.dir}" />
    </javac>
  </target>

  <target name="compile-tests"
          depends="compile, generate-test-immutables"
          >
    <mkdir dir="${testclasses.dir}" />
    <mkdir dir="${immutables.gensrc.dir}" />
    <ecj srcdir="${test.dir}"
         destdir="${testclasses.dir}"
         classpathref="tests.compile.classpath"
         >
      <javac-params>
        <exclude name="**/testdata/**" />

        <!-- This test cannot build with the rest because it is testing TracingTaskListener,
        which lives in the javac-tracing-compiler-plugin.jar, which is loaded dynamically at
        runtime. This test is run in the Buck build, which is capable of more isolated testing
        than the Ant build is. -->
        <exclude name="com/facebook/buck/jvm/java/tracing/TracingTaskListenerCleanerTest.java" />
      </javac-params>
    </ecj>
  </target>

  <target name="java-test"
          depends="compile-tests"
          description="runs the Java tests"
          >
    <condition property="jvmArgs"
               value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${test.debug_port}"
               else="-ea">
      <istrue value="${debugTest}"/>
    </condition>

    <junit failureproperty="hasFailingTests"
           showoutput="true"
           forkmode="perBatch"
           haltonfailure="on"
           haltonerror="on">
      <sysproperty key="buck.path_to_pex" value="${buck.path_to_pex}" />
      <sysproperty key="buck.path_to_python_test_main" value="${buck.path_to_python_test_main}" />
      <sysproperty key="buck.logging_config_file" value="${buck.test_logging_config_file}" />
      <sysproperty key="java.util.logging.config.class" value="com.facebook.buck.log.LogConfig" />
      <sysproperty key="org.eclipse.jetty.util.log.class" value="org.eclipse.jetty.util.log.JavaUtilLog" />

      <!-- See DEFS for details on why this property is needed. -->
      <sysproperty key="sun.zip.disableMemoryMapping" value="true" />

      <jvmarg value="-Xmx512M" />
      <jvmarg value="${jvmArgs}" />

      <formatter type="plain" usefile="false" />

      <!-- Java and android -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/jvm/java/**/*${test.class}.java" />
          <include name="com/facebook/buck/android/**/*${test.class}.java" />
          <include name="com/facebook/buck/dalvik/**/*${test.class}.java" />

          <exclude name="com/facebook/buck/jvm/java/tracing/TracingTaskListenerCleanerTest.java" />
          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- iOS -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/apple/**/*${test.class}.java" />
          <include name="com/facebook/buck/ddplist/**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- C++ and it's ilk -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/cxx/**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- Catch-all test group -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <!--
          Do not exclude tests that start with "Abstract", as there are some tests for abstract
          classes.
          -->
          <include name="**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
          <exclude name="com/facebook/buck/jvm/java/**" />
          <exclude name="com/facebook/buck/android/**" />
          <exclude name="com/facebook/buck/dalvik/**" />
          <exclude name="com/facebook/buck/apple/**" />
          <exclude name="com/facebook/buck/ddplist/**" />
          <exclude name="com/facebook/buck/cxx/**" />
        </fileset>
      </batchtest>

      <classpath refid="tests.run.classpath" />
    </junit>
    <fail if="hasFailingTests" />
  </target>

  <target name="py-test" description="runs the Python tests" depends="buck-py-test, class-loader-py-test, pathlib-py-test, zip-munger-py-test, buck-tool-py-test" />

  <target name="buck-py-test" description="tests the BUCK parser">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${buck.pythonpath}" />
      <arg value="src/com/facebook/buck/json/buck_test.py" />
    </exec>
  </target>

  <target name="class-loader-py-test" description="tests BUCK's class loader setup">
      <exec executable="python" failonerror="true">
          <env key="PYTHONPATH" path="${buck.pythonpath}" />
          <arg value="test/com/facebook/buck/cli/bootstrapper/class_loader_test.py" />
      </exec>
  </target>

  <target name="pathlib-py-test" description="tests pathlib.py">
    <exec executable="python" failonerror="true" dir="${pathlib.dir}">
      <!-- Needed on Python 2.6. -->
      <env key="PYTHONPATH" path="${unittest2.dir}" />
      <arg value="test_pathlib.py" />
    </exec>
  </target>

  <target name="zip-munger-py-test" description="tests munger.py">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${basedir}" />
      <arg value="py/buck/zip/test_munger.py" />
    </exec>
  </target>

  <target name="buck-tool-py-test" description="tests buck_tool.py">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${buck.pythonpath}" />
      <arg value="programs/test_buck_tool.py" />
    </exec>
  </target>

  <path id="pmd-classpath">
    <fileset dir="${basedir}/pmd" includes="*.jar" />
    <pathelement location="${third-party.dir}/java/guava/guava-19.0.jar" />
  </path>

  <!--
  Runs pmd on the file(s) specified in the property "lint.files",
  separated by commas. Writes output to ${lint.outputpath}.
  -->
  <target name="pmd-files-xml" if="lint.files">
    <taskdef name="pmd"
             classpathref="pmd-classpath"
             classname="net.sourceforge.pmd.ant.PMDTask"
             />
    <pmd failOnRuleViolation="true" rulesetfiles="pmd/rules.xml">
      <ruleset>buck</ruleset>
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${basedir}" includes="${lint.files}">
        <exclude name="**/testdata/**"/>
      </fileset>
    </pmd>
  </target>

  <!--
  Runs pmd on all source and test files.
  -->
  <target name="pmd">
    <taskdef name="pmd"
             classpathref="pmd-classpath"
             classname="net.sourceforge.pmd.ant.PMDTask"
             />
    <pmd failOnRuleViolation="true" rulesetfiles="pmd/rules.xml">
      <ruleset>buck</ruleset>
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
    </pmd>
  </target>

  <path id="checkstyle-classpath">
    <fileset dir="${basedir}/third-party/java/checkstyle" includes="*.jar" />
  </path>

  <!--
  Runs checkstyle on the file(s) specified in the property "lint.files",
  separated by commas.
  -->
  <target name="checkstyle-files-xml" if="lint.files">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml">
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${basedir}" includes="${lint.files}">
        <exclude name="**/testdata/**"/>
      </fileset>
    </checkstyle>
  </target>

    <!--
  Runs checkstyle on the file(s) specified in the property "lint.files",
  separated by commas.
  -->
  <target name="checkstyle-xml">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml">
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
    </checkstyle>
  </target>

  <!--
  Runs checkstyle on all source and test files.
  -->
  <target name="checkstyle">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml" maxWarnings="0">
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
      <formatter type="plain"/>
    </checkstyle>
  </target>

  <taskdef name="forbiddenapis" classname="de.thetaphi.forbiddenapis.AntTask" classpath="third-party/java/forbiddenapis/forbiddenapis-1.8.jar"/>

  <target name="forbidden-checks" depends="compile">
    <forbiddenapis internalRuntimeForbidden="true" classpathref="classpath" dir="${classes.dir}" suppressAnnotation="**.SuppressForbidden">
      <bundledsignatures name="jdk-unsafe-1.7"/>
      <bundledsignatures name="jdk-deprecated-1.7"/>
      <signaturesFileset file="config/forbiddenapis.txt"/>
    </forbiddenapis>
  </target>

  <target name="forbidden-checks-tests" depends="compile-tests">
    <forbiddenapis internalRuntimeForbidden="true" classpathref="tests.compile.classpath" dir="${testclasses.dir}" suppressAnnotation="**.SuppressForbidden">
      <bundledsignatures name="jdk-unsafe-1.7"/>
      <bundledsignatures name="jdk-deprecated-1.7"/>
      <signaturesFileset file="config/forbiddenapis.txt"/>
    </forbiddenapis>
  </target>

  <target name="lint" depends="pmd, checkstyle" />

  <target name="test" depends="java-test, py-test" description="runs the unit tests" />

  <!--
    Apparently, Eclipse's annotation processor does not seem to work properly. If you use the
    built-in processor, the .java files in .apt_generated do not match the ones in
    build/immutables (some methods appear to be missing). To workaround this, we just generate the
    files using Ant instead.
  -->
  <target name="eclipse-project"
          description="Generates files for Eclipse project"
          depends="clean, generate-immutables, generate-test-immutables"
          />

  <macrodef name="buck-javadoc" description="generates HTML documentation for Java code">
    <attribute name="destdir" />
    <attribute name="classpathref" />
    <attribute name="access" default="protected" />
    <element name="additional-links" optional="true" />
    <sequential>
      <delete dir="@{destdir}" />
      <mkdir dir="@{destdir}" />
      <record name="@{destdir}/javadoc.log" action="start" />

      <javadoc destdir="@{destdir}"
               access="@{access}"
               classpathref="@{classpathref}"
               windowtitle="Buck"
               failonerror="true"
               additionalparam="${javadoc.doclint}"
               >
        <fileset dir="${src.dir}">
          <include name="**/*.java" />
          <exclude name="com/facebook/buck/cli/quickstart/**" />
          <exclude name="com/facebook/buck/android/support/exopackage/**" />
          <exclude name="com/facebook/buck/intellij/plugin/**" />
        </fileset>
        <fileset dir="${immutables.gensrc.dir}" />
        <link href="http://docs.oracle.com/javase/7/docs/api/"
              offline="true"
              packagelistloc="third-party/java/javase" />
        <link href="http://docs.guava-libraries.googlecode.com/git-history/v18.0/javadoc/"
              offline="true"
              packagelistloc="third-party/java/guava"/>
        <!-- The latest version of the javadocs is only for 4.12 --><commit_msg>Stop generating timestamps for every page of javadoc<commit_after><project name="buck" default="default">
  <property environment="env"/>

  <property name="src.dir" value="${basedir}/src" />
  <property name="aosp.src.dir" value="third-party/java/aosp/src" />
  <property name="test.dir" value="${basedir}/test" />
  <property name="third-party.dir" value="${basedir}/third-party" />
  <property name="build.dir" value="${basedir}/build" />
  <property name="aosp.classes.dir" value="${build.dir}/aosp/classes" />
  <property name="testrunner.classes.dir" value="${build.dir}/testrunner/classes" />
  <property name="bootstrapper.src.dir" value="com/facebook/buck/cli/bootstrapper/" />
  <property name="bootstrapper.classes.dir" value="${build.dir}/bootstrapper/classes" />
  <property name="bootstrapper.jar" value="${build.dir}/bootstrapper/bootstrapper.jar" />
  <property name="tracing-api.src.dir" value="com/facebook/buck/event/api/" />
  <property name="tracing-api.classes.dir" value="${build.dir}/tracing-api/classes" />
  <property name="tracing-api.jar" value="${build.dir}/tracing-api/tracing-api.jar"/>
  <property name="javac-tracing.src.dir" value="com/facebook/buck/jvm/java/tracing" />
  <property name="javac-tracing.classes.dir" value="${build.dir}/javac-tracing/classes" />
  <property name="javac-tracing.jar" value="${build.dir}/javac-tracing/javac-tracing-compiler-plugin.jar" />
  <property name="buck.path_to_pex" value="${basedir}/src/com/facebook/buck/python/make_pex.py" />
  <property name="buck.path_to_python_test_main" value="${basedir}/src/com/facebook/buck/python/__test_main__.py" />
  <property name="buck.path_to_sh_binary_template" value="${basedir}/src/com/facebook/buck/shell/sh_binary_template" />
  <property name="buck.logging_config_file" value="${basedir}/config/logging.properties" />
  <property name="buck.test_logging_config_file" value="${basedir}/config/logging.test.properties" />
  <property name="classes.dir" value="${build.dir}/classes" />
  <property name="testclasses.dir" value="${build.dir}/testclasses" />
  <property name="javadoc.dir" value="${build.dir}/javadoc" />
  <property name="javadoc-with-android.dir" value="${build.dir}/javadoc-with-android" />
  <property name="javadoc-all.dir" value="${build.dir}/javadoc-all" />
  <property name="test.class" value="Test" />
  <property name="test.debug_port" value="8787" />
  <property name="lint.outputpath" value="${build.dir}/lint.output" />

  <property name="dx.base.dir" value="${basedir}/third-party/java/dx" />
  <property name="dx.src.dir" value="${dx.base.dir}/src" />
  <property name="dx.test.dir" value="${dx.base.dir}/tests" />
  <property name="dx.etc.dir" value="${dx.base.dir}/etc" />
  <property name="dx.classes.dir" value="${build.dir}/dx_classes" />

  <property name="eclipse.dir" value="${basedir}/third-party/java/eclipse" />

  <property name="pathlib.dir" value="${third-party.dir}/py/pathlib" />
  <property name="unittest2.dir" value="${third-party.dir}/py/unittest2" />
  <property name="pywatchman.dir" value="${third-party.dir}/py/pywatchman" />
  <property name="nailgun.dir" value="${third-party.dir}/nailgun" />

  <property name="buck.pythonpath" value="${pathlib.dir}:${pywatchman.dir}:${nailgun.dir}" />

  <property name="immutables-value-standalone.jar" value="${third-party.dir}/java/immutables/value-2.0.21.jar" />
  <property name="immutables.gensrc.dir" value="${build.dir}/immutables" />
  <property name="immutables.gensrc.test.dir" value="${build.dir}/immutables-tests" />

  <property name="manual.gensrc.dir" value="${basedir}/src-gen" />
  <property name="manual.gensrc.classes.dir" value="${build.dir}/src-gen/classes" />

  <!-- Javadoc in 1.8 became stricter about parsing the docs. This disables some of those checks -->
  <available property="jdk1.8" classname="java.util.stream.Stream"/>
  <condition
          property="javadoc.doclint"
          value="-Xdoclint:-reference"
          else="">
    <and>
      <isset property="jdk1.8"/>
    </and>
  </condition>

  <fileset dir="${third-party.dir}/java" id="buck.jars">
    <include name="args4j/args4j-2.0.30.jar" />
    <include name="ddmlib/ddmlib-22.5.3.jar" />
    <include name="guava/guava-19.0.jar" />
    <include name="ini4j/ini4j-0.5.2.jar" />
    <include name="jackson/jackson-annotations-2.5.5.jar" />
    <include name="jackson/jackson-core-2.5.5.jar" />
    <include name="jackson/jackson-databind-2.5.5.jar" />
    <include name="jackson/jackson-datatype-jdk7-2.5.0.jar" />
    <include name="jackson-datatype-guava/jackson-datatype-guava-2.5.5.jar" />
    <include name="jsr/jsr305.jar" />
    <include name="android/sdklib.jar" />
    <include name="nailgun/nailgun-server-0.9.2-SNAPSHOT.jar" />
    <include name="jna/jna-4.2.0.jar" />
  </fileset>

  <fileset dir="${third-party.dir}/java" id="third-party.jars">
    <include name="ObjCBridge/ObjCBridge.jar" />
    <include name="android/sdk-common-24.2.3.jar" />
    <include name="android/common-24.2.3.jar" />
    <include name="android/layoutlib-api-24.2.3.jar" />
    <include name="aopalliance/aopalliance.jar" />
    <include name="asm/asm-debug-all-5.0.3.jar" />
    <include name="closure-templates/soy-excluding-deps.jar" />
    <include name="commons-compress/commons-compress-1.8.1.jar" />
    <include name="concurrent-locks/concurrent-locks-1.0.0.jar" />
    <include name="dd-plist/dd-plist.jar" />
    <include name="eclipse/org.eclipse.core.contenttype_3.4.200.v20140207-1251.jar"/>
    <include name="eclipse/org.eclipse.core.jobs_3.6.1.v20141014-1248.jar"/>
    <include name="eclipse/org.eclipse.core.resources_3.9.1.v20140825-1431.jar"/>
    <include name="eclipse/org.eclipse.core.runtime_3.10.0.v20140318-2214.jar"/>
    <include name="eclipse/org.eclipse.equinox.common_3.6.200.v20130402-1505.jar"/>
    <include name="eclipse/org.eclipse.equinox.preferences_3.5.200.v20140224-1527.jar"/>
    <include name="eclipse/org.eclipse.jdt.core_3.10.2.v20150120-1634.jar"/>
    <include name="eclipse/org.eclipse.osgi_3.10.2.v20150203-1939.jar"/>
    <include name="guice/guice-3.0.jar" />
    <include name="guice/guice-assistedinject-3.0.jar" />
    <include name="guice/guice-multibindings-3.0.jar" />
    <include name="gson/gson-2.2.4.jar" />
    <include name="icu4j/icu4j-54.1.1.jar" />
    <include name="immutables/value-2.0.21.jar" />
    <include name="infer-annotations/infer-annotations-1.5.jar" />
    <include name="nuprocess/nuprocess-1.0.5-SNAPSHOT.jar" />
    <include name="jacoco/org.jacoco.core-0.7.5.201505241946.jar" />
    <include name="jacoco/org.jacoco.report-0.7.5.201505241946.jar" />
    <include name="jetty/jetty-all-9.2.10.v20150310.jar" />
    <include name="jimfs/jimfs-1.0.jar" />
    <include name="jsr/javax.inject-1.jar" />
    <include name="okhttp/okhttp-2.7.4.jar" />
    <include name="okio/okio-1.6.0.jar" />
    <include name="servlet-api/javax.servlet-api-3.1.0.jar" />
    <include name="slf4j/slf4j-jdk14-1.7.5.jar" /><!-- redirect slf4j to java.util.logging -->
    <include name="stringtemplate/ST-4.0.8.jar" />
    <include name="thrift/libthrift-0.9.3.jar" />
    <include name="xz-java-1.3/xz-1.3.jar" />

    <!-- maven interop -->
    <include name="aether/aether-api-1.0.2.v20150114.jar" />
    <include name="aether/aether-connector-basic-1.0.2.v20150114.jar" />
    <include name="aether/aether-impl-1.0.0.v20140518.jar" />
    <include name="aether/aether-spi-1.0.2.v20150114.jar" />
    <include name="aether/aether-transport-http-1.0.2.v20150114.jar" />
    <include name="aether/aether-util-1.0.2.v20150114.jar" />
    <include name="httpcomponents/httpclient-4.2.6.jar" />
    <include name="httpcomponents/httpcore-4.2.5.jar" />
    <include name="maven/maven-aether-provider-3.2.5.jar" />
    <include name="maven/maven-model-3.2.5.jar" />
    <include name="maven/maven-model-builder-3.2.5.jar" />
    <include name="maven/maven-repository-metadata-3.2.5.jar" />
    <include name="plexus/plexus-utils-3.0.20.jar" />
    <include name="plexus/plexus-interpolation-1.21.jar" />
    <include name="slf4j/jcl-over-slf4j-1.6.2.jar" />
    <include name="slf4j/slf4j-api-1.7.5.jar" />
  </fileset>

  <path id="classpath-no-src-no-aosp">
    <fileset refid="buck.jars" />
    <fileset refid="third-party.jars" />
    <pathelement location="${classes.dir}" />
    <pathelement location="${dx.classes.dir}" />
    <pathelement location="${bootstrapper.jar}" />
    <pathelement location="${manual.gensrc.classes.dir}" />
  </path>

  <path id="classpath-no-src">
    <path refid="classpath-no-src-no-aosp" />
    <pathelement location="${aosp.classes.dir}" />
  </path>

  <path id="classpath">
    <path refid="classpath-no-src" />
    <pathelement location="${src.dir}" />
    <pathelement location="${immutables.gensrc.dir}" />
    <pathelement location="${manual.gensrc.dir}" />
  </path>

  <path id="classpath-generate-immutables">
    <fileset refid="buck.jars" />
    <fileset refid="third-party.jars" />
    <pathelement location="${aosp.classes.dir}" />
  </path>

  <path id="classpath-compile-manual-gen-src">
    <fileset refid="third-party.jars" />
  </path>

  <path id="junit">
    <pathelement location="${third-party.dir}/java/junit/junit-4.12.jar" />
    <pathelement location="${third-party.dir}/java/hamcrest/hamcrest-junit-2.0.0.0.jar" />
    <pathelement location="${third-party.dir}/java/hamcrest/java-hamcrest-2.0.0.0.jar" />
    <pathelement location="${third-party.dir}/java/testng/testng-6.8.jar" />
    <pathelement location="${third-party.dir}/java/ddmlib/ddmlib-22.5.3.jar" />
  </path>

  <target name="clean" description="remove all generated files">
    <delete dir="${build.dir}" />
  </target>

  <!-- Default target so that a command line build can
       do more than one thing. -->
  <target name="default" depends="compile, dx, javac-tracing, report-generator-jar" />

  <target name="checkversion">
    <!-- The nio Files class was only introduced in Java 7. -->
    <available property="jdk7" classname="java.nio.file.Files"/>
    <fail message="Require JDK 7 or higher" unless="jdk7"/>
  </target>

  <target name="python-get-prefix">
    <exec executable="python" failonerror="true" outputproperty="python.prefix" logError="true">
      <arg value="-c" />
      <arg value="import distutils.sysconfig; print(distutils.sysconfig.PREFIX)" />
    </exec>
  </target>

  <target name="compile-manual-gen-src" depends="checkversion">
    <mkdir dir="${manual.gensrc.classes.dir}" />
    <javac srcdir="${manual.gensrc.dir}"
           destdir="${manual.gensrc.classes.dir}"
           classpathref="classpath-compile-manual-gen-src"
           debug="on"
           includeAntRuntime="no"
            >
    </javac>
  </target>

  <target name="compile-testrunner" depends="checkversion">
    <mkdir dir="${testrunner.classes.dir}" />
    <javac srcdir="${src.dir}"
           includes="com/facebook/buck/log/AppendableLogRecord.java,com/facebook/buck/testrunner/**,com/facebook/buck/util/concurrent/MoreExecutors.java,com/facebook/buck/jvm/java/runner/**"
           destdir="${testrunner.classes.dir}"
           classpathref="junit"
           debug="on"
           includeAntRuntime="no"
           >
      <compilerarg value="-Xlint:rawtypes" />
      <compilerarg value="-Xlint:unchecked" />
      <compilerarg value="-Xlint:serial" />
    </javac>
  </target>

  <path id="bootstrapper-classpath">
    <!-- Do not add dependencies. The bootstrapper is intended to keep the system ClassLoader free
         of classes that might conflict with those used by compiler plugins and annotation
         processors. As such it cannot depend on third-party libraries, directly or indirectly. -->
  </path>

  <target name="bootstrapper" depends="checkversion, tracing-api">
    <mkdir dir="${bootstrapper.classes.dir}" />
    <ecj destdir="${bootstrapper.classes.dir}" classpathref="bootstrapper-classpath">
      <javac-params>
        <include name="${bootstrapper.src.dir}/**/*.java" />
        <include name="${javac-tracing.src.dir}/JavacPhaseTracer.java" />
        <include name="com/facebook/buck/util/exportedfiles/Nullable.java" />
        <include name="com/facebook/buck/util/exportedfiles/Preconditions.java" />
      </javac-params>
    </ecj>
    <jar destfile="${bootstrapper.jar}">
      <fileset dir="${bootstrapper.classes.dir}" />

      <!-- Be very careful what is added here, and leave comments justifying each addition. See the
      comment in bootstrapper-classpath above for more details on why. -->

      <!-- The Tracing API jar must be accessible to both Buck and compiler plugins, so we put it
      in the bootstrapper. Compiler plugins will have their own copy linked in, but the ClassLoaders
      will end up loading this one instead when they are run inside Buck. -->
      <zipfileset src="${tracing-api.jar}" />
    </jar>
  </target>

  <path id="tracing-api.classpath">
    <!-- The Tracing API is a very light JAR meant to be included in compiler plugins that may
    be run outside of Buck. As such, it can take no dependencies. -->
  </path>

  <target name="tracing-api" depends="checkversion">
    <mkdir dir="${tracing-api.classes.dir}" />
    <ecj destdir="${tracing-api.classes.dir}" classpathref="tracing-api.classpath">
      <javac-params>
        <include name="${tracing-api.src.dir}/**/*.java"/>
      </javac-params>
    </ecj>
    <jar destfile="${tracing-api.jar}">
      <fileset dir="${tracing-api.classes.dir}"/>
    </jar>
  </target>

  <path id="javac-tracing.classpath">
    <!-- This jar is loaded in each compiler class loader, which is unrelated to Buck's class
    loader. Do not take dependencies on Buck code outside of the bootstrapper here. Compiler
    code (tools.jar) and third-party libraries are OK, though keep in mind that every class included
    in the jar will be freshly loaded for each invocation of the compiler. -->
    <pathelement location="${third-party.dir}/java/jdk/stub-compiler-tree-api.jar" />
    <pathelement location="${bootstrapper.jar}" />
  </path>

  <target name="javac-tracing" depends="checkversion, tracing-api">
    <mkdir dir="${javac-tracing.classes.dir}" />
    <ecj destdir="${javac-tracing.classes.dir}" classpathref="javac-tracing.classpath">
      <javac-params>
        <include name="com/facebook/buck/util/exportedfiles/Nullable.java" />
        <include name="com/facebook/buck/util/exportedfiles/Preconditions.java" />
        <include name="${javac-tracing.src.dir}/TracingTaskListener.java" />
      </javac-params>
    </ecj>
    <jar destfile="${javac-tracing.jar}">
      <fileset dir="${javac-tracing.classes.dir}"/>
    </jar>

    <!-- Put the tracing jar in resources so it can be dynamically loaded at runtime. See
     TranslatingJavacPhaseTracer -->
    <copy file="${javac-tracing.jar}" todir="${classes.dir}/com/facebook/buck/jvm/java/tracing" />
  </target>

  <path id="immutables-classpath">
    <path refid="classpath" />
    <pathelement location="${immutables-value-standalone.jar}" />
    <pathelement location="${src.dir}" />
    <pathelement location="${aosp.classes.dir}" />
    <pathelement location="${manual.gensrc.dir}" />
  </path>

  <!-- The set of Immutables value type source files which have not
       yet been run through the javac annotation processor. -->
  <fileset dir="${src.dir}" id="immutables-srcs">
    <!-- Speed up the build by only running javac on files containing Immutables. -->
    <contains text="org.immutables" />
    <exclude name="com/facebook/buck/android/support/**" />
    <exclude name="com/facebook/buck/cli/quickstart/**" />
    <exclude name="com/facebook/buck/testrunner/**" />
    <!-- Only run javac on immutables files which have changed since the last build. -->
    <modified>
      <param name="cache.cachefile" value="${build.dir}/immutables.modified.properties" />
    </modified>
  </fileset>

  <target name="check-immutables">
    <!--
      javac rules don't support filesets, but they do support comma-separated lists of
      sources in the includes parameter.

      However, if the includes parameter is empty, the javac rule will build everything,
      which we don't want. So we have to skip the generate-immutables step entirely
      in that case.

      This sets ${immutables-srcs-flattened} to a comma-separated list of files to build,
      then sets ${generate-immutables-needed} to true iff that variable is non-empty.
    -->
    <pathconvert property="immutables-srcs-flattened" pathsep="," refid="immutables-srcs">
      <map from="${src.dir}/" to=""/>
    </pathconvert>
    <condition property="generate-immutables-needed">
      <length string="${immutables-srcs-flattened}" when="greater" length="0" />
    </condition>
  </target>

  <target name="compile-aosp" depends="checkversion">
    <mkdir dir="${aosp.classes.dir}" />
    <ecj srcdir="${aosp.src.dir}" destdir="${aosp.classes.dir}">
      <ecj-params>
        <!-- ManifestMerger.java has redundant null checks -->
        <compilerarg value="-err:-null" />
      </ecj-params>
    </ecj>
  </target>

  <target name="generate-immutables" depends="compile-aosp, check-immutables" if="${generate-immutables-needed}">
    <mkdir dir="${immutables.gensrc.dir}" />
    <javac srcdir="${src.dir}:${manual.gensrc.dir}:${immutables.gensrc.dir}"
           classpathref="classpath-generate-immutables"
           includeAntRuntime="no"
           includes="${immutables-srcs-flattened}">
      <compilerarg value="-Werror" />
      <compilerarg value="-processorpath" />
      <compilerarg value="${immutables-value-standalone.jar}" />
      <compilerarg value="-proc:only" />
      <compilerarg value="-s" />
      <compilerarg value="${immutables.gensrc.dir}" />
    </javac>
  </target>

  <macrodef name="ecj" description="Compile Java using the ecj compiler with strict checks.">
    <attribute name="srcdir" default="${src.dir}" />
    <attribute name="classpathref" default="classpath-no-src" />
    <attribute name="destdir" default="${classes.dir}" />
    <!--
      javac-params can contain any extra parameters to the javac ant command.

      include and exclude elements are automatically relative to ${src.dir}.

      According to http://ant.apache.org/manual/Tasks/javac.html, the only way
      to enumerate the .java inputs to javac in Ant is to set the sourcepath
      to the empty string, set the srcdir to something, and use include/exclude
      elements to filter things under the srcdir.
    -->
    <element name="javac-params" optional="true" />
    <!--
      ecj-params can contain any extra paramters to the Eclipse batch compiler.
    -->
    <element name="ecj-params" optional="true" />
    <sequential>
      <javac srcdir="@{srcdir}"
             sourcepath=""
             destdir="@{destdir}"
             classpathref="@{classpathref}"
             debug="on"
             deprecation="on"
             includeAntRuntime="no"
             compiler="org.eclipse.jdt.core.JDTCompilerAdapter"
             >
        <javac-params />
        <!--
          ecj does not appear to support -Werror. As suggested by
          http://stackoverflow.com/a/14927725/396304, we specify an Eclipse preferences
          file to ECJ with the rules we want to enforce set to error.

          To see the full list of compiler options available, read the Javadoc for JavaCore at:
          http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2FJavaCore.html
          Apparently Eclipse refuses to publish traditional Javadoc with manageable URLs.
        -->
        <compilerarg line="-properties ${eclipse.dir}/org.eclipse.jdt.core.prefs" />
        <compilerarg value="-Xlint:rawtypes" />
        <compilerarg value="-Xlint:unchecked" />
        <compilerarg value="-Xlint:serial" />
        <compilerarg value="-time" />
        <compilerclasspath>
          <pathelement location="${eclipse.dir}/org.eclipse.jdt.core_3.10.2.v20150120-1634.jar" />
          <pathelement location="${eclipse.dir}/jdtCompilerAdapter.jar" />
        </compilerclasspath>
        <ecj-params />
      </javac>
    </sequential>
  </macrodef>

  <target name="package-resources">
    <mkdir dir="${classes.dir}/com/facebook/buck/cli/quickstart/android"/>
    <zip basedir="src/com/facebook/buck/cli/quickstart/android"
         destfile="${classes.dir}/com/facebook/buck/cli/quickstart/android/android-template.zip"
         excludes="BUCK"
         defaultexcludes="no"/>

    <mkdir dir="${classes.dir}/com/facebook/buck/cli/quickstart/ios"/>
    <zip basedir="src/com/facebook/buck/cli/quickstart/ios"
         destfile="${classes.dir}/com/facebook/buck/cli/quickstart/ios/ios-template.zip"
         excludes="BUCK"
         defaultexcludes="no"/>
    <mkdir dir="${classes.dir}/com/facebook/buck/android"/>
    <copy file="${third-party.dir}/java/ddmlib/ddmlib-22.5.3.jar"
          tofile="${classes.dir}/com/facebook/buck/android/ddmlib.jar"/>
    <copy file="${third-party.dir}/java/kxml2/kxml2-2.3.0.jar"
          tofile="${classes.dir}/com/facebook/buck/android/kxml2.jar"/>
  </target>

  <target name="compile"
          depends="compile-testrunner, compile-aosp, compile-manual-gen-src, bootstrapper, package-resources, tracing-api, dx, generate-immutables"
          description="compile Java source code">
    <mkdir dir="${classes.dir}" />

    <!-- Copy in scripts we need at run time when using an unpacked buck -->
    <copy file="src/com/facebook/buck/json/buck.py" todir="${classes.dir}/com/facebook/buck/json"/>

    <ecj>
      <javac-params>
        <patternset>
          <!--
            These patterns are excluded because they are compiled elsewhere
            and are deliberately isolated from Buck's core.
          -->
          <exclude name="com/facebook/buck/android/support/**" />
          <exclude name="com/facebook/buck/cli/bootstrapper/**" />
          <exclude name="com/facebook/buck/cli/quickstart/**" />
          <exclude name="com/facebook/buck/event/api/**" />
          <exclude name="com/facebook/buck/intellij/plugin/**" />
          <exclude name="com/facebook/buck/testrunner/**" />
        </patternset>
        <or>
          <filename name="${javac-tracing.src.dir}/JavacPhaseEvent.java" />
          <filename name="${javac-tracing.src.dir}/JavacPhaseEventLogger.java" />
          <filename name="${javac-tracing.src.dir}/TranslatingJavacPhaseTracer.java" />
          <not>
            <filename name="${javac-tracing.src.dir}/**" />
          </not>
        </or>
        <src path="${immutables.gensrc.dir}" />
      </javac-params>
    </ecj>
  </target>

  <fileset dir="${third-party.dir}/java" id="dx.jars">
    <include name="guava/guava-19.0.jar" />
  </fileset>

  <path id="dx.classpath">
    <fileset refid="dx.jars" />
  </path>

  <target name="dx-check-build">
    <uptodate property="dx-build-not-required" targetfile="${build.dir}/dx.jar">
      <srcfiles dir="${dx.src.dir}" includes="**/*.java" />
      <srcfiles dir="${third-party.dir}/java/guava" includes="guava-*.jar" />
      <srcfiles dir="${third-party.dir}/java/junit" includes="junit-*.jar" />
    </uptodate>
  </target>

  <target name="dx" depends="dx-check-build" unless="dx-build-not-required">
    <mkdir dir="${dx.classes.dir}" />

    <javac destdir="${dx.classes.dir}"
           classpathref="dx.classpath"
           debug="on"
           deprecation="on"
           includeAntRuntime="no"
           >
      <src path="${dx.src.dir}" />
    </javac>

    <jar destfile="${build.dir}/dx.jar">
      <zipfileset includes="**/*.class" src="${third-party.dir}/java/guava/guava-19.0.jar"/>
      <zipfileset includes="**/*.class" src="${third-party.dir}/java/junit/junit-4.12.jar" />
      <fileset dir="${dx.classes.dir}" />
      <manifest>
        <attribute name="Main-Class" value="com.android.dx.command.Main" />
      </manifest>
    </jar>
  </target>

  <!--
       Note: two of the dx tests (the two tests for the merger) run the command
       "dalvik" and expect it to be a working dalvik virtual machine.
       Fulfilling this expectation is no easy task.  Here's how I did it.

       - Be on Linux (Dalvik doesn't build for Mac).
       - Check out Android (I used ICS because I had it lying around).
       - make -kj25 dalvik-host
       - If you built on a remote machine, rsync "out" to where you are
         developing Buck, inside of a dedicated directory called "android"
         or something.
       - Edit android/out/host/linux-x86/dalvik to change the log tags to
         "*:w", because a spurious info message was messing up the test.
       - Delete android/out/host/linux-x86/dx so the tests will use our dx.
       - Run this rule as
         ANDROID_BUILD_TOP=/path/to/android PATH=$PATH:$ANDROID_BUILD_TOP/out/host/linux-x86/bin ant dx-tests
       -->
  <target name="dx-tests" depends="dx">
    <exec
        failonerror="true"
        dir="${dx.test.dir}"
        executable="./run-all-tests">
      <env key="PATH" path="${env.PATH}:${dx.etc.dir}"/>
    </exec>
  </target>

  <target name="jar" depends="buck-jar, report-generator-jar"/>

  <target name="buck-jar"
          depends="compile"
          description="build buck.jar"
          >

    <jar destfile="${build.dir}/buck.jar" update="true">
      <zipfileset refid="buck.jars" />
      <zipfileset refid="third-party.jars" />
      <fileset dir="${src.dir}"
               excludes="**/*.java, **/BUCK"
               />
      <fileset dir="${classes.dir}" />
      <manifest>
        <attribute name="Main-Class" value="com.facebook.buck.cli.Main" />
      </manifest>
    </jar>
  </target>

  <target name="report-generator-jar" depends="compile">
    <jar destfile="${build.dir}/report-generator.jar">
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/jacoco/org.jacoco.core-0.7.5.201505241946.jar"/>
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/jacoco/org.jacoco.report-0.7.5.201505241946.jar"/>
      <zipfileset excludes="**/*SF **/*RSA" src="${third-party.dir}/java/asm/asm-debug-all-5.0.3.jar"/>
      <fileset dir="${classes.dir}">
          <include name="com/facebook/buck/jvm/java/coverage/ReportGenerator.class"/>
      </fileset>
      <manifest>
        <attribute name="Main-Class" value="com.facebook.buck.jvm.java.coverage.ReportGenerator" />
      </manifest>
    </jar>
  </target>

  <path id="tests.run.classpath">
    <path refid="classpath" />
    <fileset dir="${third-party.dir}/java">
      <include name="caliper/caliper-1.0-all.jar" />
      <include name="cglib/cglib-nodep-2.2.jar" />
      <include name="easymock/easymock-3.3.1.jar" />
      <include name="hamcrest/hamcrest-junit-2.0.0.0.jar" />
      <include name="hamcrest/java-hamcrest-2.0.0.0.jar" />
      <include name="junit/junit-4.12.jar" />
      <include name="objenesis/objenesis-1.2.jar" />
    </fileset>

    <pathelement location="${testclasses.dir}" />
    <pathelement location="${test.dir}" />
    <pathelement location="${testrunner.classes.dir}" />
    <pathelement location="${immutables.gensrc.dir}" />
    <pathelement location="${immutables.gensrc.test.dir}" />
  </path>

  <path id="tests.compile.classpath">
    <path refid="tests.run.classpath" />
    <pathelement location="${third-party.dir}/java/jdk/stub-compiler-tree-api.jar" />
  </path>

  <!-- The set of Immutables value type source files which have not
       yet been run through the javac annotation processor. -->
  <fileset dir="${test.dir}" id="immutables-test-srcs">
    <!-- Speed up the build by only running javac on files containing Immutables. -->
    <contains text="org.immutables" />
    <exclude name="**/testdata/**" />
    <!-- Only run javac on immutables files which have changed since the last build. -->
    <modified>
      <param name="cache.cachefile" value="${build.dir}/immutables.test.modified.properties" />
    </modified>
  </fileset>

  <target name="check-test-immutables">
    <!--
      javac rules don't support filesets, but they do support comma-separated lists of
      sources in the includes parameter.

      However, if the includes parameter is empty, the javac rule will build everything,
      which we don't want. So we have to skip the generate-immutables step entirely
      in that case.

      This sets ${immutables-test-srcs-flattened} to a comma-separated list of files to build,
      then sets ${generate-test-immutables-needed} to true iff that variable is non-empty.
    -->
    <pathconvert property="immutables-test-srcs-flattened" pathsep="," refid="immutables-test-srcs">
      <map from="${test.dir}/" to=""/>
    </pathconvert>
    <condition property="generate-test-immutables-needed">
      <length string="${immutables-test-srcs-flattened}" when="greater" length="0" />
    </condition>
  </target>

  <target name="generate-test-immutables" depends="compile, check-test-immutables" if="${generate-test-immutables-needed}">
    <mkdir dir="${immutables.gensrc.test.dir}" />
    <javac srcdir="${test.dir}:${immutables.gensrc.test.dir}"
           includes="${immutables-test-srcs-flattened}"
           classpathref="tests.compile.classpath"
           includeAntRuntime="no">
      <compilerarg value="-Werror" />
      <compilerarg value="-processorpath" />
      <compilerarg value="${immutables-value-standalone.jar}" />
      <compilerarg value="-proc:only" />
      <compilerarg value="-s" />
      <compilerarg value="${immutables.gensrc.test.dir}" />
    </javac>
  </target>

  <target name="compile-tests"
          depends="compile, generate-test-immutables"
          >
    <mkdir dir="${testclasses.dir}" />
    <mkdir dir="${immutables.gensrc.dir}" />
    <ecj srcdir="${test.dir}"
         destdir="${testclasses.dir}"
         classpathref="tests.compile.classpath"
         >
      <javac-params>
        <exclude name="**/testdata/**" />

        <!-- This test cannot build with the rest because it is testing TracingTaskListener,
        which lives in the javac-tracing-compiler-plugin.jar, which is loaded dynamically at
        runtime. This test is run in the Buck build, which is capable of more isolated testing
        than the Ant build is. -->
        <exclude name="com/facebook/buck/jvm/java/tracing/TracingTaskListenerCleanerTest.java" />
      </javac-params>
    </ecj>
  </target>

  <target name="java-test"
          depends="compile-tests"
          description="runs the Java tests"
          >
    <condition property="jvmArgs"
               value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${test.debug_port}"
               else="-ea">
      <istrue value="${debugTest}"/>
    </condition>

    <junit failureproperty="hasFailingTests"
           showoutput="true"
           forkmode="perBatch"
           haltonfailure="on"
           haltonerror="on">
      <sysproperty key="buck.path_to_pex" value="${buck.path_to_pex}" />
      <sysproperty key="buck.path_to_python_test_main" value="${buck.path_to_python_test_main}" />
      <sysproperty key="buck.logging_config_file" value="${buck.test_logging_config_file}" />
      <sysproperty key="java.util.logging.config.class" value="com.facebook.buck.log.LogConfig" />
      <sysproperty key="org.eclipse.jetty.util.log.class" value="org.eclipse.jetty.util.log.JavaUtilLog" />

      <!-- See DEFS for details on why this property is needed. -->
      <sysproperty key="sun.zip.disableMemoryMapping" value="true" />

      <jvmarg value="-Xmx512M" />
      <jvmarg value="${jvmArgs}" />

      <formatter type="plain" usefile="false" />

      <!-- Java and android -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/jvm/java/**/*${test.class}.java" />
          <include name="com/facebook/buck/android/**/*${test.class}.java" />
          <include name="com/facebook/buck/dalvik/**/*${test.class}.java" />

          <exclude name="com/facebook/buck/jvm/java/tracing/TracingTaskListenerCleanerTest.java" />
          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- iOS -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/apple/**/*${test.class}.java" />
          <include name="com/facebook/buck/ddplist/**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- C++ and it's ilk -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <include name="com/facebook/buck/cxx/**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
        </fileset>
      </batchtest>

      <!-- Catch-all test group -->
      <batchtest fork="yes">
        <fileset dir="${test.dir}">
          <!--
          Do not exclude tests that start with "Abstract", as there are some tests for abstract
          classes.
          -->
          <include name="**/*${test.class}.java" />

          <exclude name="**/testdata/**" />
          <exclude name="com/facebook/buck/jvm/java/**" />
          <exclude name="com/facebook/buck/android/**" />
          <exclude name="com/facebook/buck/dalvik/**" />
          <exclude name="com/facebook/buck/apple/**" />
          <exclude name="com/facebook/buck/ddplist/**" />
          <exclude name="com/facebook/buck/cxx/**" />
        </fileset>
      </batchtest>

      <classpath refid="tests.run.classpath" />
    </junit>
    <fail if="hasFailingTests" />
  </target>

  <target name="py-test" description="runs the Python tests" depends="buck-py-test, class-loader-py-test, pathlib-py-test, zip-munger-py-test, buck-tool-py-test" />

  <target name="buck-py-test" description="tests the BUCK parser">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${buck.pythonpath}" />
      <arg value="src/com/facebook/buck/json/buck_test.py" />
    </exec>
  </target>

  <target name="class-loader-py-test" description="tests BUCK's class loader setup">
      <exec executable="python" failonerror="true">
          <env key="PYTHONPATH" path="${buck.pythonpath}" />
          <arg value="test/com/facebook/buck/cli/bootstrapper/class_loader_test.py" />
      </exec>
  </target>

  <target name="pathlib-py-test" description="tests pathlib.py">
    <exec executable="python" failonerror="true" dir="${pathlib.dir}">
      <!-- Needed on Python 2.6. -->
      <env key="PYTHONPATH" path="${unittest2.dir}" />
      <arg value="test_pathlib.py" />
    </exec>
  </target>

  <target name="zip-munger-py-test" description="tests munger.py">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${basedir}" />
      <arg value="py/buck/zip/test_munger.py" />
    </exec>
  </target>

  <target name="buck-tool-py-test" description="tests buck_tool.py">
    <exec executable="python" failonerror="true">
      <env key="PYTHONPATH" path="${buck.pythonpath}" />
      <arg value="programs/test_buck_tool.py" />
    </exec>
  </target>

  <path id="pmd-classpath">
    <fileset dir="${basedir}/pmd" includes="*.jar" />
    <pathelement location="${third-party.dir}/java/guava/guava-19.0.jar" />
  </path>

  <!--
  Runs pmd on the file(s) specified in the property "lint.files",
  separated by commas. Writes output to ${lint.outputpath}.
  -->
  <target name="pmd-files-xml" if="lint.files">
    <taskdef name="pmd"
             classpathref="pmd-classpath"
             classname="net.sourceforge.pmd.ant.PMDTask"
             />
    <pmd failOnRuleViolation="true" rulesetfiles="pmd/rules.xml">
      <ruleset>buck</ruleset>
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${basedir}" includes="${lint.files}">
        <exclude name="**/testdata/**"/>
      </fileset>
    </pmd>
  </target>

  <!--
  Runs pmd on all source and test files.
  -->
  <target name="pmd">
    <taskdef name="pmd"
             classpathref="pmd-classpath"
             classname="net.sourceforge.pmd.ant.PMDTask"
             />
    <pmd failOnRuleViolation="true" rulesetfiles="pmd/rules.xml">
      <ruleset>buck</ruleset>
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
    </pmd>
  </target>

  <path id="checkstyle-classpath">
    <fileset dir="${basedir}/third-party/java/checkstyle" includes="*.jar" />
  </path>

  <!--
  Runs checkstyle on the file(s) specified in the property "lint.files",
  separated by commas.
  -->
  <target name="checkstyle-files-xml" if="lint.files">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml">
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${basedir}" includes="${lint.files}">
        <exclude name="**/testdata/**"/>
      </fileset>
    </checkstyle>
  </target>

    <!--
  Runs checkstyle on the file(s) specified in the property "lint.files",
  separated by commas.
  -->
  <target name="checkstyle-xml">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml">
      <formatter type="xml" toFile="${lint.outputpath}" />
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
    </checkstyle>
  </target>

  <!--
  Runs checkstyle on all source and test files.
  -->
  <target name="checkstyle">
    <taskdef resource="checkstyletask.properties"
           classpathref="checkstyle-classpath"/>
    <checkstyle config="checkstyle.xml" maxWarnings="0">
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
      <fileset dir="${test.dir}">
        <include name="**/*.java"/>
        <exclude name="**/testdata/**"/>
      </fileset>
      <formatter type="plain"/>
    </checkstyle>
  </target>

  <taskdef name="forbiddenapis" classname="de.thetaphi.forbiddenapis.AntTask" classpath="third-party/java/forbiddenapis/forbiddenapis-1.8.jar"/>

  <target name="forbidden-checks" depends="compile">
    <forbiddenapis internalRuntimeForbidden="true" classpathref="classpath" dir="${classes.dir}" suppressAnnotation="**.SuppressForbidden">
      <bundledsignatures name="jdk-unsafe-1.7"/>
      <bundledsignatures name="jdk-deprecated-1.7"/>
      <signaturesFileset file="config/forbiddenapis.txt"/>
    </forbiddenapis>
  </target>

  <target name="forbidden-checks-tests" depends="compile-tests">
    <forbiddenapis internalRuntimeForbidden="true" classpathref="tests.compile.classpath" dir="${testclasses.dir}" suppressAnnotation="**.SuppressForbidden">
      <bundledsignatures name="jdk-unsafe-1.7"/>
      <bundledsignatures name="jdk-deprecated-1.7"/>
      <signaturesFileset file="config/forbiddenapis.txt"/>
    </forbiddenapis>
  </target>

  <target name="lint" depends="pmd, checkstyle" />

  <target name="test" depends="java-test, py-test" description="runs the unit tests" />

  <!--
    Apparently, Eclipse's annotation processor does not seem to work properly. If you use the
    built-in processor, the .java files in .apt_generated do not match the ones in
    build/immutables (some methods appear to be missing). To workaround this, we just generate the
    files using Ant instead.
  -->
  <target name="eclipse-project"
          description="Generates files for Eclipse project"
          depends="clean, generate-immutables, generate-test-immutables"
          />

  <macrodef name="buck-javadoc" description="generates HTML documentation for Java code">
    <attribute name="destdir" />
    <attribute name="classpathref" />
    <attribute name="access" default="protected" />
    <element name="additional-links" optional="true" />
    <sequential>
      <delete dir="@{destdir}" />
      <mkdir dir="@{destdir}" />
      <record name="@{destdir}/javadoc.log" action="start" />

      <javadoc destdir="@{destdir}"
               access="@{access}"
               classpathref="@{classpathref}"
               windowtitle="Buck"
               failonerror="true"
               additionalparam="${javadoc.doclint}"
               >
        <arg value="-notimestamp"/>
        <fileset dir="${src.dir}">
          <include name="**/*.java" />
          <exclude name="com/facebook/buck/cli/quickstart/**" />
          <exclude name="com/facebook/buck/android/support/exopackage/**" />
          <exclude name="com/facebook/buck/intellij/plugin/**" />
        </fileset>
        <fileset dir="${immutables.gensrc.dir}" />
        <link href="http://docs.oracle.com/javase/7/docs/api/"
              offline="true"
              packagelistloc="third-party/java/javase" />
        <link href="http://docs.guava-libraries.googlecode.com/git-history/v18.0/javadoc/"
              offline="true"
              packagelistloc="third-party/java/guava"/>
        <!-- The latest version of the javadocs is only for 4.12 -->
{'fraction_non_alphanumeric': 0.1757762692928876, 'fraction_numerical': 0.013940667160499824, 'mean_word_length': 3.0470807941812463, 'pattern_counts': {'":': 0, '<': 1350, '<?xml version=': 0, '>': 1350, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 28}, 'pii_count': 16, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4770324', 'n_tokens_mistral': 27605, 'n_tokens_neox': 26486, 'n_words': 4767}