Recommendation for Custom Task Similar to Copy

In general, it seems to be recommended that custom tasks extend DefaultTask.
The syntax and semantics for specifying sources and targets of AbstractCopyTask is appealing.
What is the recommended way to obtain a similar syntax and semantic in a custom task?

Specifically, I am refering to the from, into, include, etc. properties.

If your task is copying things, it should be absolutely ok to extend AbstractCopyTask.

What I came up with…

@CacheableTask
abstract class FooTask : DefaultTask(), CopySourceSpec {
...

    @get:Input
    @get:Optional
    abstract val sourceEncoding: Property<EncodingType>
...

    override fun from(vararg sourcePaths: Any?): FooTask {
        this.sourceFiles.from(sourcePaths)
        return this
    }
    override fun from(sourcePath: Any, closure: Closure<*>): FooTask {
        this.sourceFiles.from(sourcePath, closure)
        return this
    }
    override fun from(sourcePath: Any, configureAction: Action<in CopySpec >): FooTask {
        this.sourceFiles.from(sourcePath, configureAction)
        return this
    }
...
}

This is used in a build.gradle.kts as…

...
tasks.register<FooTask >("fooize") {
        group = "fooize"
        from(srcDirectory.asFileTree.matching {
            include("**/*.foo")
        })
    }
...

I did a similar thing for into but, being lazy, I did not want to implement the entire interface.
Taken from org/gradle/api/file/CopyProcessingSpec.java

    open fun  into(destPath: Directory?): ProtobufHeaderTask? {
        this.targetDir.set(destPath)
        return this
    }

    open fun  into(destPath: Provider<Directory>?): ProtobufHeaderTask? {
        if (destPath != null) {
            this.targetDir.set(destPath.get())
        }
        return this
    }

The drawback to this implementation is that it seems like it would be a good candidate for Kotlin delegation, but I have not been able to get it to work.

@CacheableTask
abstract class FooTask : DefaultTask(), ConfigurableFileCollection by sourceFiles {
...
    @get:InputFiles
    @get:Optional
    @get:SkipWhenEmpty
    @get:IgnoreEmptyDirectories
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val sourceFiles: ConfigurableFileCollection
...

Here is the error I get.

e: <foopath>\FooTask.kt: (22, 82): Unresolved reference: sourceFiles.

Any guidance on getting Kotlin delegation working in a Gradle custom task?

It turns out what I wanted is less like copying than I imagined.
What I really want is to implement the CopySourceSpec and CopyProcessingSpec.
I noticed that CopySourceSpec behavior is largely implemented by ConfigurableFileCollection.
This suggests the delegation pattern.

Many tasks involve some bunch of input files and some bunch of output files.
This seems like from and into behavior.
I was expecting to find some AbstractTransformTask that provided just this behavior.
AbstractCopyTask seemed like a candidate but I was unable see how to make use of it.

I don’t think Kotlin delegation will work here. Afaik you can only delegate this way to a constructor parameter but not to a property. But I might be wrong of course.

I found some good examples:

The SourceTask provides what I was looking for.