anchor.diff:  include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/buildSrc/src/main/java/org/example/ProcessTemplates.java[tag=task-arg-method]
   ----
   
  -[source.multi-language-sample,groovy]
  -.build.gradle
  -----
  -include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/build.gradle[tag=task-arg-method]
  -----
  -
   .Output of `gradle processTemplates2`
   ----
   > gradle processTemplates2
   include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/incrementalBuildCustomMethodsWithTaskArg.out[]
   ----
  +====
   
   This technique can make your custom task easier to use and result in cleaner build files.
   As an added benefit, our use of `getProject().getLayout().files()` means that our custom method can set up an inferred task dependency.
  
positive.code: 
  We have already seen how to define tasks using a keyword style in <<tutorial_using_tasks.adoc#tutorial_using_tasks,this chapter>>. There are a few variations on this style, which you may need to use in certain situations. For example, the keyword style does not work in expressions.
  
  === Example: Defining tasks
  
  [source.multi-language-sample,groovy]
  .build.gradle
  ----
  include::{samplesPath}/userguide/tasks/defineAsExpression/build.gradle[]
  ----
  
  You can also use strings for the task names:
  
  === Example: Defining tasks - using strings for task names
  
  [source.multi-language-sample,groovy]
  .build.gradle
  ----
  include::{samplesPath}/userguide/tasks/defineUsingStringTaskNames/build.gradle[]
  ----
  
  There is an alternative syntax for defining tasks, which you may prefer to use:
  
  === Example: Defining tasks with alternative syntax
  
  [source.multi-language-sample,groovy]
  .build.gradle
  ----
  include::{samplesPath}/userguide/tasks/addToTaskContainer/build.gradle[]
  ----
  
  Here we add tasks to the `tasks` collection. Have a look at link:{javadocPath}/org/gradle/api/tasks/TaskContainer.html[TaskContainer] for more variations of the `create()` method.
  
  
negative.code: 
  As an example, imagine you want to use the output of a Java compilation task - via the `destinationDir` property - as the input of a custom task that instruments a set of files containing Java bytecode. This custom task, which we’ll call `Instrument`, has a `classFiles` property annotated with `@InputFiles`. You might initially try to configure the task like so:
  
  .Failed attempt at setting up an inferred task dependency
  ====
  include::sample[dir="userguide/tasks/incrementalBuild/incrementalBuildAdvanced",files="build.gradle[tags=failed-inferred-task-dep]"]
  
  .Output of **`gradle clean badInstrumentClasses`**
  ----
  > gradle clean badInstrumentClasses
  include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/incrementalBuildBadInputFilesConfig.out[]
  ----
  ====
  
  There’s nothing obviously wrong with this code, but you can see from the console output that the compilation task is missing. In this case you would need to add an explicit task dependency between `instrumentClasses` and `compileJava` via `dependsOn`. The use of `fileTree()` means that Gradle can’t infer the task dependency itself.
  
  One solution is to use the `TaskOutputs.files` property, as demonstrated by the following example:
  
  .Setting up an inferred task dependency between output dir and input files
  ====
  include::sample[dir="userguide/tasks/incrementalBuild/incrementalBuildAdvanced",files="build.gradle[tags=inferred-task-dep]"]
  
  .Output of **`gradle clean instrumentClasses`**
  ----
  > gradle clean instrumentClasses
  include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/incrementalBuildInputFilesConfig.out[]
  ----
  ====
  
  Alternatively, you can get Gradle to access the appropriate property itself by using one of `project.files()`, `project.layout.files()` or `project.layout.configurableFiles()` in place of `project.fileTree()`:
  
  .Setting up an inferred task dependency with filesFor()
  ====
  include::sample[dir="userguide/tasks/incrementalBuild/incrementalBuildAdvanced",files="build.gradle[tags=inferred-task-dep-with-files]"]
  
  .Output of **`gradle clean instrumentClasses2`**
  ----
  > gradle clean instrumentClasses2
  include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/incrementalBuildInputFilesConfigUsingTask.out[]
  ----
  ====
  
  Remember that `files()`, `layout.files()` and `layout.configurableFiles()` can take tasks as arguments, whereas `fileTree()` cannot.
  
  The downside of this approach is that all file outputs of the source task become the input files of the target - `instrumentClasses` in this case. That’s fine as long as the source task only has a single file-based output, like the `JavaCompile` task. But if you have to link just one output property among several, then you need to explicitly tell Gradle which task generates the input files using the `builtBy` method:
  
  .Setting up an inferred task dependency with builtBy()
  ====
  include::sample[dir="userguide/tasks/incrementalBuild/incrementalBuildAdvanced",files="build.gradle[tags=inferred-task-dep-with-builtby]"]
  
  .Output of **`gradle clean instrumentClassesBuiltBy`**
  ----
  > gradle clean instrumentClassesBuiltBy
  include::{samplesPath}/userguide/tasks/incrementalBuild/incrementalBuildAdvanced/inferredTaskDependencyWithBuiltBy.out[]
  ----
  ====
  
  You can of course just add an explicit task dependency via `dependsOn`, but the above approach provides more semantic meaning, explaining why `compileJava` has to run beforehand.
  
  