You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2016/12/17 10:28:26 UTC

[50/81] [abbrv] [partial] zest-java git commit: ZEST-195 ; Replace all "zest" with "polygene"

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index ebd7b5d..4147856 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,9 +15,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-import org.apache.zest.gradle.AllProjectsPlugin
-import org.apache.zest.gradle.RootProjectPlugin
-import org.apache.zest.gradle.dependencies.DependenciesDeclarationPlugin
+import org.apache.polygene.gradle.AllProjectsPlugin
+import org.apache.polygene.gradle.RootProjectPlugin
+import org.apache.polygene.gradle.dependencies.DependenciesDeclarationPlugin
 
 apply plugin: DependenciesDeclarationPlugin
 apply from: 'dependencies.gradle'

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/AllProjectsPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/AllProjectsPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/AllProjectsPlugin.groovy
new file mode 100644
index 0000000..6c9a2c0
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/AllProjectsPlugin.groovy
@@ -0,0 +1,208 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle
+
+import groovy.transform.CompileStatic
+import org.apache.polygene.gradle.dependencies.DependenciesPlugin
+import org.apache.polygene.gradle.publish.PublishingPlugin
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.api.tasks.testing.Test
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+import org.nosphere.honker.gradle.HonkerExtension
+import org.nosphere.honker.gradle.HonkerGenDependenciesTask
+import org.nosphere.honker.gradle.HonkerGenLicenseTask
+import org.nosphere.honker.gradle.HonkerGenNoticeTask
+import org.nosphere.honker.gradle.HonkerLicenseOverrideCandidate
+
+@CompileStatic
+class AllProjectsPlugin implements Plugin<Project>
+{
+  @Override
+  void apply( final Project project )
+  {
+    project.defaultTasks = [ 'classes', 'test' ]
+    project.group = project.name == 'org.apache.polygene' ?
+                    'org.apache.polygene' :
+                    project.name.substring( 0, project.name.lastIndexOf( '.' ) )
+
+    applyDefaultVersion( project )
+    applyPolygeneExtension( project )
+
+    configureJava( project )
+    project.plugins.apply DependenciesPlugin
+    configureJavadoc( project )
+    configureTest( project )
+    if( CodeProjectsPlugin.isCodeProject( project ) )
+    {
+      project.plugins.apply CodeProjectsPlugin
+    }
+    configureDependencyReport( project )
+    configureHonker( project )
+    project.plugins.apply PublishingPlugin
+  }
+
+  private static void applyDefaultVersion( Project project )
+  {
+    if( project.version == 'unspecified' )
+    {
+      project.version = System.properties.version ?: '0'
+    }
+  }
+
+  private static void applyPolygeneExtension( Project project )
+  {
+    project.extensions.create( "polygene", PolygeneExtension, project )
+  }
+
+  private static void configureJava( Project project )
+  {
+    project.plugins.apply 'java'
+    def javaConvention = project.convention.getPlugin( JavaPluginConvention )
+    javaConvention.targetCompatibility = JavaVersion.VERSION_1_8
+    javaConvention.sourceCompatibility = JavaVersion.VERSION_1_8
+    project.tasks.withType( JavaCompile ) { JavaCompile task ->
+      task.options.encoding = 'UTF-8'
+      // Deprecation warnings for all compilations
+      task.options.compilerArgs << "-Xlint:deprecation"
+      // Unchecked warnings for non-test core compilations
+      if( 'org.apache.polygene.core' == project.group && !task.name.toLowerCase( Locale.US ).contains( 'test' ) )
+      {
+        task.options.compilerArgs << "-Xlint:unchecked"
+      }
+    }
+  }
+
+  private static void configureJavadoc( Project project )
+  {
+    project.tasks.withType( Javadoc ) { Javadoc task ->
+      def options = task.options as StandardJavadocDocletOptions
+      options.encoding = 'UTF-8'
+      options.docEncoding = 'UTF-8'
+      options.charSet = 'UTF-8'
+      options.noTimestamp = true
+      options.links = [
+        'http://docs.oracle.com/javase/8/docs/api/',
+        'https://stleary.github.io/JSON-java/',
+        'http://junit.org/junit4/javadoc/latest/'
+      ]
+      // exclude '**/internal/**'
+    }
+  }
+
+  private static void configureTest( Project project )
+  {
+    // Match --max-workers and Test maxParallelForks, use 1 if parallel is disabled
+    def parallel = project.gradle.startParameter.parallelProjectExecutionEnabled
+    def maxTestWorkers = ( parallel ? project.gradle.startParameter.maxWorkerCount : 1 ) as int
+    // The space in the directory name is intentional
+    def allTestsDir = project.file( "$project.buildDir/tmp/test files" )
+    project.tasks.withType( Test ) { Test testTask ->
+      testTask.onlyIf { !project.hasProperty( 'skipTests' ) }
+      testTask.testLogging.info.exceptionFormat = TestExceptionFormat.FULL
+      testTask.maxHeapSize = '1g'
+      testTask.maxParallelForks = maxTestWorkers
+      testTask.systemProperties = [ 'proxySet' : System.properties[ 'proxySet' ],
+                                    'proxyHost': System.properties[ 'proxyHost' ],
+                                    'proxyPort': System.properties[ 'proxyPort' ] ]
+      testTask.reports.html.enabled = true
+      def testDir = new File( allTestsDir, testTask.name )
+      def workDir = new File( testDir, 'work' )
+      def tmpDir = new File( testDir, 'tmp' )
+      def homeDir = new File( testDir, 'home' )
+      testTask.workingDir = workDir
+      testTask.systemProperties << ( [
+        'user.dir'      : workDir.absolutePath,
+        'java.io.tmpdir': tmpDir.absolutePath,
+        'home.dir'      : homeDir.absolutePath
+      ] as Map<String, Object> )
+      testTask.environment << ( [
+        'HOME'       : homeDir.absolutePath,
+        'USERPROFILE': homeDir.absolutePath
+      ] as Map<String, Object> )
+      testTask.doFirst { Test task ->
+        [ workDir, tmpDir, homeDir ]*.mkdirs()
+      }
+      testTask.doLast { Test task ->
+        if( !task.state.failure )
+        {
+          project.delete testDir
+        }
+      }
+    }
+  }
+
+  // Dependency Report generate only the runtime configuration
+  // The report is packaged in the SDK distributions
+  private static void configureDependencyReport( Project project )
+  {
+    project.plugins.apply 'project-report'
+    // TODO Fails with no task found
+    // def dependencyReport = project.tasks.getByName( 'dependencyReport' ) as DependencyReportTask
+    // dependencyReport.configurations = [ project.configurations.getByName( 'runtime' ) ] as Set
+  }
+
+  private static void configureHonker( Project project )
+  {
+    project.plugins.apply 'org.nosphere.honker'
+    def honkerGenDependencies = project.tasks.getByName( 'honkerGenDependencies' ) as HonkerGenDependenciesTask
+    def honkerGenLicense = project.tasks.getByName( 'honkerGenLicense' ) as HonkerGenLicenseTask
+    def honkerGenNotice = project.tasks.getByName( 'honkerGenNotice' ) as HonkerGenNoticeTask
+    def javaConvention = project.convention.getPlugin( JavaPluginConvention )
+    def mainSourceSet = javaConvention.sourceSets.getByName( 'main' )
+    mainSourceSet.output.dir( [ builtBy: honkerGenDependencies ] as Map<String, Object>,
+                              honkerGenDependencies.outputDir )
+    mainSourceSet.output.dir( [ builtBy: honkerGenLicense ] as Map<String, Object>,
+                              honkerGenLicense.outputDir )
+    mainSourceSet.output.dir( [ builtBy: honkerGenNotice ] as Map<String, Object>,
+                              honkerGenNotice.outputDir )
+    def honker = project.extensions.getByType( HonkerExtension )
+    // Project License, applied to all submodules
+    honker.license 'Apache 2'
+    // Dependencies (transitive or not) with no license information, overriding them
+    honker.licenseOverride { HonkerLicenseOverrideCandidate candidate ->
+      if( candidate.group == 'asm' || candidate.module == 'prefuse-core' )
+      {
+        candidate.license = 'BSD 3-Clause'
+      }
+      if( candidate.group == 'javax.websocket'
+        || candidate.group == 'javax.xml.bind' )
+      {
+        candidate.license = 'CDDL'
+      }
+      if( candidate.group == 'org.apache.httpcomponents'
+        || candidate.group == 'net.java.dev.jna'
+        || candidate.group == 'lucene'
+        || candidate.group == 'jdbm'
+        || candidate.group == 'org.osgi'
+        || candidate.group.startsWith( 'org.restlet' ) )
+      {
+        candidate.license = 'Apache 2'
+      }
+    }
+    honkerGenNotice.header = 'Apache Polygene'
+    honkerGenNotice.footer = 'This product includes software developed at\n' +
+                             'The Apache Software Foundation (http://www.apache.org/).\n'
+    project.tasks.getByName( 'check' ).dependsOn project.tasks.getByName( 'honkerCheck' )
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/CodeProjectsPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/CodeProjectsPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/CodeProjectsPlugin.groovy
new file mode 100644
index 0000000..6aa345b
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/CodeProjectsPlugin.groovy
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle
+
+import groovy.transform.CompileStatic
+import org.apache.polygene.gradle.dependencies.DependenciesDeclarationExtension
+import org.apache.polygene.gradle.doc.AsciidocBuildInfoPlugin
+import org.apache.polygene.gradle.version.VersionClassPlugin
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.plugins.osgi.OsgiManifest
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.jvm.tasks.Jar
+import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
+import org.gradle.testing.jacoco.tasks.JacocoReport
+
+@CompileStatic
+class CodeProjectsPlugin implements Plugin<Project>
+{
+  static boolean isCodeProject( Project project )
+  {
+    [ 'src/main/java', 'src/test/java',
+      'src/main/groovy', 'src/test/groovy' ].collect { path ->
+      new File( "$project.projectDir/$path" )
+    }.any { dir -> dir.isDirectory() }
+  }
+
+  @Override
+  void apply( final Project project )
+  {
+    project.plugins.apply VersionClassPlugin
+    project.plugins.apply AsciidocBuildInfoPlugin
+
+    configureJar( project )
+    configureSupplementaryArchives( project )
+
+    configureJacoco( project )
+    configureCheckstyle( project )
+  }
+
+  private static void configureJar( Project project )
+  {
+    project.plugins.apply 'osgi'
+    def jar = project.tasks.getByName( 'jar' ) as Jar
+    def manifest = jar.manifest as OsgiManifest
+    manifest.attributes( [
+      license    : 'http://www.apache.org/licenses/LICENSE-2.0.txt',
+      docURL     : 'https://polygene.apache.org/',
+      description: project.description ?:
+                   'Apache Polygene\u2122 (Java Edition) is a platform for Composite Oriented Programming',
+      vendor     : 'The Apache Software Foundation, https://www.apache.org',
+    ] )
+    manifest.instruction '-debug', 'true'
+  }
+
+  private static void configureSupplementaryArchives( Project project )
+  {
+    def javaConvention = project.convention.getPlugin( JavaPluginConvention )
+    def sourceJar = project.tasks.create( 'sourceJar', Jar ) { Jar task ->
+      task.description = 'Builds -sources.jar'
+      task.classifier = 'sources'
+      task.from javaConvention.sourceSets.getByName( 'main' ).allSource
+    }
+    def testSourceJar = project.tasks.create( 'testSourceJar', Jar ) { Jar task ->
+      task.description = 'Builds -testsources.jar'
+      task.classifier = 'testsources'
+      task.from javaConvention.sourceSets.getByName( 'test' ).allSource
+    }
+    def javadoc = project.tasks.getByName( 'javadoc' ) as Javadoc
+    def javadocJar = project.tasks.create( 'javadocJar', Jar ) { Jar task ->
+      task.description = 'Builds -javadoc.jar'
+      task.classifier = 'javadoc'
+      task.from javadoc.destinationDir
+      task.dependsOn javadoc
+    }
+    project.artifacts.add( 'archives', sourceJar )
+    project.artifacts.add( 'archives', testSourceJar )
+    project.artifacts.add( 'archives', javadocJar )
+  }
+
+  private static void configureJacoco( Project project )
+  {
+    def dependencies = project.rootProject.extensions.getByType( DependenciesDeclarationExtension )
+    project.plugins.apply 'jacoco'
+    def jacoco = project.extensions.getByType( JacocoPluginExtension )
+    jacoco.toolVersion = dependencies.buildToolsVersions.jacoco
+    project.tasks.withType( JacocoReport ) { JacocoReport task ->
+      task.group = TaskGroups.VERIFICATION
+      task.description = 'Generates test coverage report.'
+    }
+  }
+
+  private static void configureCheckstyle( Project project )
+  {
+    // project.plugins.apply 'checkstyle'
+    //    if( name == "org.apache.polygene.core.runtime" )
+    //    {
+    //      checkstyleMain {
+    //        configFile = new File( "$rootProject.projectDir.absolutePath/etc/polygene-runtime-checkstyle.xml" )
+    //        ignoreFailures = true
+    //      }
+    //    }
+    //    else
+    //    {
+    //      checkstyleMain {
+    //        configFile = new File( rootProject.projectDir.absolutePath.toString() + '/etc/polygene-api-checkstyle.xml' )
+    //        ignoreFailures = true
+    //        reporting.baseDir = "$rootProject.reporting.baseDir/checkstyle"
+    //      }
+    //    }
+    //    checkstyleTest {
+    //      configFile = new File( "$rootProject.projectDir.absolutePath/etc/polygene-tests-checkstyle.xml" )
+    //      ignoreFailures = true
+    //    }
+    //
+    //    checkstyleVersion {
+    //      configFile = new File( "$rootProject.projectDir.absolutePath/etc/polygene-tests-checkstyle.xml" )
+    //      ignoreFailures = true
+    //    }
+    //    // Create checkstyle report
+    //    task checkstyleReport( type: XsltTask, dependsOn: check ) {
+    //      source project.checkstyle.reportsDir
+    //      include '*.xml'
+    //      destDir = file( "build/reports/checkstyle/" )
+    //      extension = 'html'
+    //      stylesheetFile = file( "$rootProject.projectDir/etc/checkstyle-noframes.xsl" )
+    //    }
+    //
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/RootProjectPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/RootProjectPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/RootProjectPlugin.groovy
new file mode 100644
index 0000000..c05a584
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/RootProjectPlugin.groovy
@@ -0,0 +1,262 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle
+
+import groovy.transform.CompileStatic
+import org.apache.rat.gradle.RatTask
+import org.apache.polygene.gradle.dependencies.DependenciesDeclarationExtension
+import org.apache.polygene.gradle.dist.DistributionPlugin
+import org.apache.polygene.gradle.release.ReleaseSpecExtension
+import org.apache.polygene.gradle.release.ReleaseSpecPlugin
+import org.apache.polygene.gradle.test.AggregatedJacocoReportTask
+import org.gradle.api.GradleException
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.tasks.Copy
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.api.tasks.testing.Test
+import org.gradle.api.tasks.testing.TestReport
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+
+@CompileStatic
+class RootProjectPlugin implements Plugin<Project>
+{
+  static final String PROJECT_TITLE = 'Apache Polygene\u2122 (Java Edition) SDK'
+  static final String PROJECT_DESCRIPTION = 'Apache Polygene\u2122 (Java Edition) is a framework for domain centric ' +
+                                            'application development, including evolved concepts from AOP, DI and DDD.'
+
+  static class TaskNames
+  {
+    static final String GO_OFFLINE = 'goOffline'
+    static final String GLOBAL_TEST_REPORT = 'globalTestReport'
+    static final String JAVADOCS = 'javadocs'
+    static final String ARCHIVE_JAVADOCS = 'archiveJavadocs'
+    static final String BUILD_ALL = 'buildAll'
+  }
+
+  @Override
+  void apply( Project project )
+  {
+    project.plugins.apply ReleaseSpecPlugin
+
+    applyProjectMetadata( project )
+    applyHelperTasks( project )
+    applyPlugins( project )
+
+    configureJacoco( project )
+    configureTestReport( project )
+    configureJavadocs( project )
+    configureRat( project )
+
+    project.plugins.apply DistributionPlugin
+    configureReleaseTask( project )
+  }
+
+  private static void applyProjectMetadata( Project project )
+  {
+    def extraProperties = project.extensions.extraProperties
+    extraProperties.set 'title', PROJECT_TITLE
+    extraProperties.set 'description', PROJECT_DESCRIPTION
+  }
+
+  private static void applyHelperTasks( Project project )
+  {
+    project.tasks.create( TaskNames.GO_OFFLINE ) { Task task ->
+      task.group = TaskGroups.HELP
+      task.description = 'Resolves all dependencies configuration'
+      task.doLast {
+        def allConfigurations = project.allprojects.collect { Project each ->
+          each.configurations
+        }.flatten() as Set<Configuration>
+        allConfigurations*.resolvedConfiguration
+      }
+    }
+    def buildAll = project.tasks.create( TaskNames.BUILD_ALL )
+    buildAll.group = TaskGroups.BUILD
+    buildAll.description = 'Builds all'
+    buildAll.dependsOn 'javadocs', 'check', 'jar',
+                       project.subprojects.collect { p -> p.tasks.getByName( 'dependencyReport' ) },
+                       project.subprojects.collect { p -> p.tasks.getByName( 'assemble' ) },
+                       ':org.apache.polygene.manual:website'
+  }
+
+  private static void applyPlugins( Project project )
+  {
+    project.plugins.apply 'org.nosphere.apache.rat'
+  }
+
+  private static void configureJacoco( Project project )
+  {
+    def dependencies = project.rootProject.extensions.getByType( DependenciesDeclarationExtension )
+    project.configurations.create( 'jacoco' )
+    project.dependencies.add( 'jacoco', "org.jacoco:org.jacoco.ant:${ dependencies.buildToolsVersions.jacoco }" )
+    def task = project.tasks.create( 'coverageReport', AggregatedJacocoReportTask ) { AggregatedJacocoReportTask task ->
+      task.group = TaskGroups.VERIFICATION
+      task.description = 'Generates global coverage report'
+      task.dependsOn project.subprojects.collect( { Project p -> p.tasks.getByName( 'test' ) } )
+    }
+    project.tasks.getByName( 'check' ).dependsOn task
+  }
+
+  private static void configureTestReport( Project project )
+  {
+    project.tasks.create( TaskNames.GLOBAL_TEST_REPORT, TestReport ) { TestReport task ->
+      task.group = TaskGroups.VERIFICATION
+      task.description = 'Generates global test report'
+      task.destinationDir = project.file( "$project.buildDir/reports/tests" )
+      task.reportOn project.subprojects.collect { it.tasks.getByName( 'test' ) }
+    }
+    def test = project.tasks.getByName( 'test' ) as Test
+    test.dependsOn project.subprojects.collect { it.tasks.getByName( 'test' ) }
+    test.dependsOn project.tasks.getByName( TaskNames.GLOBAL_TEST_REPORT )
+    test.reports.html.enabled = false
+  }
+
+  private static void configureJavadocs( Project project )
+  {
+    def zest = project.extensions.getByType( PolygeneExtension )
+    def releaseSpec = project.extensions.getByType( ReleaseSpecExtension )
+    project.tasks.create( TaskNames.JAVADOCS, Javadoc ) { Javadoc task ->
+      task.group = TaskGroups.DOCUMENTATION
+      task.description = 'Builds the whole SDK public Javadoc'
+      task.dependsOn ReleaseSpecPlugin.TaskNames.RELEASE_APPROVED_PROJECTS
+      def options = task.options as StandardJavadocDocletOptions
+      options.docFilesSubDirs = true
+      options.encoding = "UTF-8"
+      options.overview = "${ project.projectDir }/src/javadoc/overview.html"
+      task.title = "${ PROJECT_TITLE } ${ project.version }"
+      def apiSources = releaseSpec.approvedProjects.findAll { approved ->
+        ( approved.name.startsWith( 'org.apache.polygene.core' ) &&
+          !approved.name.startsWith( 'org.apache.polygene.core.runtime' ) ) ||
+        approved.name.startsWith( 'org.apache.polygene.library' ) ||
+        approved.name.startsWith( 'org.apache.polygene.extension' ) ||
+        approved.name.startsWith( 'org.apache.polygene.tool' )
+      }
+      task.source apiSources.collect { each ->
+        each.convention.getPlugin( JavaPluginConvention ).sourceSets.getByName( 'main' ).allJava
+      }
+      task.destinationDir = project.file( "${ project.convention.getPlugin( JavaPluginConvention ).docsDir }/javadocs" )
+      task.classpath = project.files( apiSources.collect { apiProject ->
+        apiProject.convention.getPlugin( JavaPluginConvention ).sourceSets.getByName( 'main' ).compileClasspath
+      } )
+      options.group( [
+        "Core API"      : [ "org.apache.polygene.api",
+                            "org.apache.polygene.api.*" ],
+        "Core Bootstrap": [ "org.apache.polygene.bootstrap",
+                            "org.apache.polygene.bootstrap.*" ],
+        "Core SPI"      : [ "org.apache.polygene.spi",
+                            "org.apache.polygene.spi.*" ],
+        "Libraries"     : [ "org.apache.polygene.library.*" ],
+        "Extensions"    : [ "org.apache.polygene.valueserialization.*",
+                            "org.apache.polygene.entitystore.*",
+                            "org.apache.polygene.index.*",
+                            "org.apache.polygene.metrics.*",
+                            "org.apache.polygene.cache.*",
+                            "org.apache.polygene.migration",
+                            "org.apache.polygene.migration.*" ],
+        "Tools"         : [ "org.apache.polygene.tools.*",
+                            "org.apache.polygene.envisage",
+                            "org.apache.polygene.envisage.*" ],
+        "Test Support"  : [ "org.apache.polygene.test",
+                            "org.apache.polygene.test.*" ]
+      ] )
+    }
+    project.tasks.create( TaskNames.ARCHIVE_JAVADOCS, Copy ) { Copy task ->
+      task.group = TaskGroups.DOCUMENTATION
+      task.description = 'Copy SDK public Javadoc to ../polygene-web'
+      task.dependsOn TaskNames.JAVADOCS
+      task.from 'build/docs/javadoc/'
+      if( zest.developmentVersion )
+      {
+        task.into( "$project.projectDir/../polygene-web/site/content/java/develop/javadocs/" )
+      }
+      else
+      {
+        task.into( "$project.projectDir/../polygene-web/site/content/java/$project.version/javadocs/" )
+      }
+    }
+  }
+
+  private static void configureRat( Project project )
+  {
+    def rat = project.tasks.getByName( 'rat' ) as RatTask
+    rat.group = TaskGroups.VERIFICATION
+    rat.onlyIf { project.version != '0' }
+    rat.excludes = [
+      '**/.DS_Store/**', '**/._*',
+      // Git Files
+      '**/.git/**', '**/.gitignore',
+      // Gradle Files
+      'gradle/wrapper/**', '**/gradlew', '**/gradlew.bat', '**/.gradle/**',
+      // Build Output
+      '**/build/**', '**/derby.log', 'out/**',
+      // IDE Files
+      '**/.idea/**', '**/*.iml', '**/*.ipr', '**/*.iws',
+      '**/.settings/**', '**/.classpath', '**/.project',
+      '**/.gradletasknamecache', '**/private/cache/**',
+      '**/.nb-gradle-properties', '**/.nb-gradle/**',
+      // JSON files are not allowed to have comments, according to http://www.json.org/ and http://www.ietf.org/rfc/rfc4627.txt
+      '**/*.json',
+      // Various Text Resources
+      '**/README.*', '**/README*.*', '**/TODO',
+      '**/src/main/resources/**/*.txt',
+      '**/src/test/resources/**/*.txt',
+      'libraries/rest-server/src/main/resources/**/*.htm',
+      'libraries/rest-server/src/main/resources/**/*.atom',
+      'tools/qidea/src/main/resources/**/*.ft',
+      'tools/qidea/src/main/resources/**/*.template',
+      // Graphic Resources
+      '**/*.svg', '**/*.gif', '**/*.png', '**/*.jpg', '**/*.psd',
+      // Keystores
+      '**/*.jceks',
+      // Syntax Highlighter - MIT
+      'manual/**/sh*.css', 'manual/**/sh*.js',
+      // jQuery & plugins - MIT
+      'manual/**/jquery*.js',
+      // W3C XML Schemas - W3C Software License
+      'samples/rental/src/main/resources/*.xsd',
+      // Polygene Generator Heroes Templates - MIT
+      'tools/generator-polygene/app/templates/Heroes/**',
+      // templates that will become the user's source files, should not have license headers
+      'tools/shell/src/dist/etc/templates/**',
+    ]
+  }
+
+  private static void configureReleaseTask( Project project )
+  {
+    def zest = project.extensions.getByType( PolygeneExtension )
+    def release = project.tasks.create( 'release' )
+    release.description = 'Builds, tests and uploads the release artifacts'
+    release.group = TaskGroups.RELEASE
+    release.doFirst {
+      if( zest.developmentVersion )
+      {
+        throw new GradleException( "Cannot release development version $project.version, use '-Dversion=X.Y.Z'" )
+      }
+    }
+    release.dependsOn 'checkReleaseSpec',
+                      'rat',
+                      'archiveJavadocs',
+                      ':org.apache.polygene.manual:copyWebsite',
+                      project.allprojects.collect { it.tasks.getByName( 'uploadArchives' ) },
+                      'dist'
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/TaskGroups.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/TaskGroups.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/TaskGroups.groovy
new file mode 100644
index 0000000..61d3d0d
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/TaskGroups.groovy
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle
+
+import org.gradle.api.plugins.ApplicationPlugin
+import org.gradle.api.plugins.BasePlugin
+import org.gradle.api.plugins.HelpTasksPlugin
+import org.gradle.api.plugins.JavaBasePlugin
+import org.gradle.language.base.plugins.LifecycleBasePlugin
+
+class TaskGroups
+{
+  static final String HELP = HelpTasksPlugin.HELP_GROUP
+  static final String BUILD = LifecycleBasePlugin.BUILD_GROUP
+  static final String VERIFICATION = LifecycleBasePlugin.VERIFICATION_GROUP
+  static final String DOCUMENTATION = JavaBasePlugin.DOCUMENTATION_GROUP
+  static final String DISTRIBUTION = ApplicationPlugin.APPLICATION_GROUP
+  static final String DISTRIBUTION_VERIFICATION = 'distribution verification'
+  static final String PERFORMANCE = 'performance'
+  static final String PERFORMANCE_VERIFICATION = 'performance verification'
+  static final String RELEASE = 'release'
+  static final String RELEASE_VERIFICATION = 'release verification'
+  static final String UPLOAD = BasePlugin.UPLOAD_GROUP
+  static final String SAMPLES = 'samples'
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/ZestExtension.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/ZestExtension.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/ZestExtension.groovy
new file mode 100644
index 0000000..41e472a
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/ZestExtension.groovy
@@ -0,0 +1,79 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle
+
+import groovy.transform.CompileStatic
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Dependency
+
+@CompileStatic
+class PolygeneExtension
+{
+  private final Project project
+  final Core core
+
+  PolygeneExtension( Project project )
+  {
+    this.project = project
+    this.core = new Core()
+  }
+
+  boolean isDevelopmentVersion()
+  {
+    return project.version == '0' || project.version.toString().contains( 'SNAPSHOT' )
+  }
+
+  boolean isReleaseVersion()
+  {
+    return !isDevelopmentVersion()
+  }
+
+  class Core
+  {
+    Dependency api = core( 'api' )
+    Dependency spi = core( 'spi' )
+    Dependency runtime = core( 'runtime' )
+    Dependency bootstrap = core( 'bootstrap' )
+    Dependency testsupport = core( 'testsupport' )
+  }
+
+  private Dependency core( String name )
+  {
+    return dependency( 'org.apache.polygene.core', "org.apache.polygene.core.$name" )
+  }
+
+  Dependency library( String name )
+  {
+    return dependency( 'org.apache.polygene.libraries', "org.apache.polygene.library.$name" )
+  }
+
+  Dependency extension( String name )
+  {
+    return dependency( 'org.apache.polygene.extensions', "org.apache.polygene.extension.$name" )
+  }
+
+  Dependency tool( String name )
+  {
+    return dependency( 'org.apache.polygene.tools', "org.apache.polygene.tool.$name" )
+  }
+
+  private Dependency dependency( String group, String name )
+  {
+    project.dependencies.project( path: ":$group:$name" )
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationExtension.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationExtension.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationExtension.groovy
new file mode 100644
index 0000000..c91f0b2
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationExtension.groovy
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.dependencies
+
+import groovy.transform.CompileStatic
+import org.gradle.api.artifacts.DependencySubstitution
+import org.gradle.api.artifacts.component.ModuleComponentSelector
+import org.gradle.internal.BiAction
+
+@CompileStatic
+class DependenciesDeclarationExtension
+{
+  final Map<String, String> repositoriesUrls = [ : ]
+  final Map<String, Object> libraries = [ : ]
+  final Map<String, List<Object>> defaultDependencies = [ : ]
+  BiAction<DependencySubstitution, ModuleComponentSelector> dependencySubstitutionSpec
+  final Map<String, String> buildToolsVersions = [ : ]
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationPlugin.groovy
new file mode 100644
index 0000000..cb90182
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesDeclarationPlugin.groovy
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.dependencies
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class DependenciesDeclarationPlugin implements Plugin<Project>
+{
+  @Override
+  void apply( Project project )
+  {
+    project.extensions.create( 'dependenciesDeclaration', DependenciesDeclarationExtension )
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesPlugin.groovy
new file mode 100644
index 0000000..660406d
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dependencies/DependenciesPlugin.groovy
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.dependencies
+
+import groovy.transform.CompileStatic
+import org.gradle.api.Action
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.DependencySubstitution
+import org.gradle.api.artifacts.component.ModuleComponentSelector
+import org.gradle.api.artifacts.repositories.MavenArtifactRepository
+
+@CompileStatic
+class DependenciesPlugin implements Plugin<Project>
+{
+  @Override
+  void apply( final Project project )
+  {
+    def dependenciesDeclaration = project.rootProject.extensions.getByType( DependenciesDeclarationExtension )
+    applyRepositories( project, dependenciesDeclaration )
+    applyLibraries( project, dependenciesDeclaration )
+    applyDependencyResolutionRules( project, dependenciesDeclaration )
+    applyDefaultDependencies( project, dependenciesDeclaration )
+  }
+
+  private static void applyRepositories( Project project, DependenciesDeclarationExtension declaration )
+  {
+    declaration.repositoriesUrls.each { name, url ->
+      project.repositories.maven { MavenArtifactRepository repo ->
+        repo.name = name
+        repo.url = url
+      }
+    }
+  }
+
+  private static void applyLibraries( Project project, DependenciesDeclarationExtension declaration )
+  {
+    project.extensions.extraProperties.set 'libraries', declaration.libraries
+  }
+
+  private static void applyDependencyResolutionRules( Project project, DependenciesDeclarationExtension declaration )
+  {
+    project.configurations.all(
+      { Configuration configuration ->
+        configuration.resolutionStrategy.dependencySubstitution.all(
+          { DependencySubstitution dep ->
+            if( dep.requested instanceof ModuleComponentSelector )
+            {
+              def selector = dep.requested as ModuleComponentSelector
+              declaration.dependencySubstitutionSpec.execute dep, selector
+            }
+          } as Action<DependencySubstitution> )
+      } as Action<Configuration> )
+  }
+
+  private static void applyDefaultDependencies( Project project, DependenciesDeclarationExtension declaration )
+  {
+    declaration.defaultDependencies.each { String configuration, List<Object> dependencies ->
+      dependencies.each { dependency ->
+        if( dependency instanceof Collection )
+        {
+          dependency.each { subdep ->
+            project.dependencies.add( configuration, subdep )
+          }
+        }
+        else
+        {
+          project.dependencies.add( configuration, dependency )
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/DistributionPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/DistributionPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/DistributionPlugin.groovy
new file mode 100644
index 0000000..0a4a49b
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/DistributionPlugin.groovy
@@ -0,0 +1,387 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.dist
+
+import groovy.transform.CompileStatic
+import groovy.transform.TypeCheckingMode
+import org.apache.rat.gradle.RatTask
+import org.apache.tools.ant.filters.ReplaceTokens
+import org.apache.polygene.gradle.RootProjectPlugin
+import org.apache.polygene.gradle.TaskGroups
+import org.apache.polygene.gradle.dependencies.DependenciesDeclarationExtension
+import org.apache.polygene.gradle.release.ReleaseSpecExtension
+import org.apache.polygene.gradle.release.ReleaseSpecPlugin
+import org.gradle.api.Action
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.file.CopySpec
+import org.gradle.api.file.FileCopyDetails
+import org.gradle.api.tasks.Copy
+import org.gradle.api.tasks.GradleBuild
+import org.gradle.api.tasks.bundling.Compression
+import org.gradle.api.tasks.bundling.Tar
+import org.gradle.api.tasks.bundling.Zip
+
+@CompileStatic
+class DistributionPlugin implements Plugin<Project>
+{
+  static class TaskNames
+  {
+    static final String UNPACK_SOURCE_DIST = 'unpackSrcDist'
+    static final String UNPACK_BINARY_DIST = 'unpackBinDist'
+    static final String CHECK_SOURCE_DIST = 'checkSrcDist'
+    static final String CHECK_BINARY_DIST = 'checkBinDist'
+    static final String CHECK_BINARY_DIST_RAT = 'checkBinDist_rat'
+    static final String GENERATE_MAVEN_OFFLINE_HELPERS = 'generateMavenGoOfflineHelpers'
+    static final String GENERATE_GRADLE_OFFLINE_HELPERS = 'generateGradleGoOfflineHelpers'
+    static final String CHECK_MAVEN_OFFLINE_HELPERS = 'checkMavenGoOfflineHelpers'
+    static final String CHECK_GRADLE_OFFLINE_HELPERS = 'checkGradleGoOfflineHelpers'
+  }
+
+  @Override
+  void apply( final Project project )
+  {
+    configureSourceDistribution( project )
+    configureBinaryDistribution( project )
+    configureDistributionChecksums( project )
+    configureHelperTasks( project )
+  }
+
+  private static void configureSourceDistribution( Project project )
+  {
+    def releaseSpec = project.extensions.getByType( ReleaseSpecExtension )
+    def srcDistFilesCopySpec = project.copySpec { CopySpec spec ->
+      spec.from '.'
+      spec.include '*.txt'
+      spec.include 'doap.rdf'
+      spec.include '*.gradle'
+      spec.include 'gradlew*'
+      spec.include 'gradle/**'
+      spec.include 'etc/**'
+      spec.include 'buildSrc/**'
+      spec.include 'src/**'
+      releaseSpec.approvedProjects.each { p ->
+        def relPath = new File( project.projectDir.toURI().relativize( p.projectDir.toURI() ).toString() )
+        spec.include "$relPath/**"
+      }
+      spec.include 'manual/**'
+      spec.include 'samples/**'
+      spec.include 'tests/**'
+      spec.include 'tutorials/**'
+      spec.include 'tools/shell/**'
+      // Filtered, see below
+      spec.exclude 'settings.gradle'
+      spec.exclude 'gradle.properties'
+      // Excludes
+      spec.exclude '**/build/**'             // Build output
+      spec.exclude 'derby.log'               // Derby test garbage
+      spec.exclude '**/*.iml'                // IDEA files
+      spec.exclude '**/*.ipr'                // IDEA files
+      spec.exclude '**/*.iws'                // IDEA files
+      spec.exclude '**/.idea'                // IDEA files
+      spec.exclude '**/out/**'               // IDEA build output
+      spec.exclude '**/.classpath'           // Eclipse files
+      spec.exclude '**/.project'             // Eclipse files
+      spec.exclude '**/.settings'            // Eclipse files
+      spec.exclude '**/.nb-gradle/**'        // Netbeans files
+      spec.exclude '**/.nb-gradle*'          // Netbeans files
+      spec.exclude '**/.git/**'              // Git directories
+      spec.exclude '**/.git*'                // Git files
+      spec.exclude '**/.gradle/**'           // Gradle management files
+      spec.exclude '**/.gradletasknamecache' // Gradle cache
+      spec.into '.'
+    }
+    def srcDistFilteredFilesTask = project.tasks.create( 'srcDistFilteredFiles' )
+    srcDistFilteredFilesTask.description = 'Apply release specification to source distribution build scripts'
+    // Generates various files for the source distribution
+    // - settings.gradle
+    // - gradle.properties to set version !
+    def filteredDir = new File( "$project.buildDir/tmp/srcDistFilteredFiles" )
+    srcDistFilteredFilesTask.outputs.file filteredDir
+    srcDistFilteredFilesTask.doLast {
+      // Settings
+      def settingsFile = new File( filteredDir, 'settings.gradle' )
+      settingsFile.parentFile.mkdirs()
+      def filteredSettings = ''
+      project.file( 'settings.gradle' ).readLines().each { line ->
+        if( line.contains( '\'libraries:' ) || line.contains( '\'extensions:' ) || line.contains( '\'tools:' ) )
+        {
+          def accepted = false
+          releaseSpec.approvedProjects.collect { it.projectDir }.each { acceptedProjectDir ->
+            if( line.contains( "'${ acceptedProjectDir.parentFile.name }:${ acceptedProjectDir.name }'" ) )
+            {
+              accepted = true
+            }
+          }
+          if( accepted )
+          {
+            filteredSettings += "$line\n"
+          }
+        }
+        else
+        {
+          filteredSettings += "$line\n"
+        }
+      }
+      settingsFile.text = filteredSettings
+      // gradle.properties
+      def gradlePropsFile = new File( filteredDir, 'gradle.properties' )
+      gradlePropsFile.parentFile.mkdirs()
+      gradlePropsFile.text = project.file( 'gradle.properties' ).text +
+                             "\nskipSigning=true\nskipAsciidocIfAbsent=true\n\nversion=$project.version\n"
+    }
+    def srcDistFilteredFilesCopySpec = project.copySpec { CopySpec spec ->
+      spec.from srcDistFilteredFilesTask
+      spec.into '.'
+    }
+    def srcDistCopySpec = project.copySpec { CopySpec spec ->
+      spec.into "apache-polygene-java-$project.version-src"
+      spec.with srcDistFilesCopySpec
+      spec.with srcDistFilteredFilesCopySpec
+    }
+
+    def zipSources = project.tasks.create( 'zipSources', Zip ) { Zip task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = 'Assemble .zip source distribution'
+      task.baseName = 'apache-polygene-java'
+      task.with srcDistCopySpec
+      task.classifier = 'src'
+    }
+    def tarSources = project.tasks.create( 'tarSources', Tar ) { Tar task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = 'Assemble .tar.gz source distribution'
+      task.baseName = 'apache-polygene-java'
+      task.with srcDistCopySpec
+      task.compression = Compression.GZIP
+      task.classifier = 'src'
+    }
+    project.artifacts.add( 'archives', zipSources )
+    project.artifacts.add( 'archives', tarSources )
+
+    project.tasks.create( TaskNames.UNPACK_SOURCE_DIST, Copy ) { Copy task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = "Unpack source distribution"
+      task.with srcDistCopySpec
+      task.into 'build/unpacked-distributions/src'
+    }
+
+    def unpackedSrcDistDir = project.file( "build/unpacked-distributions/src/apache-polygene-java-$project.version-src" )
+    project.tasks.create( TaskNames.CHECK_SOURCE_DIST, GradleBuild.class, { GradleBuild task ->
+      task.group = TaskGroups.DISTRIBUTION_VERIFICATION
+      task.description = "Check the source distribution by running the 'check' and 'assemble' tasks inside"
+      task.dependsOn TaskNames.UNPACK_SOURCE_DIST
+      task.buildFile = "$unpackedSrcDistDir/build.gradle"
+      task.tasks = [ 'check', 'assemble' ]
+    } as Action<GradleBuild> )
+  }
+
+  private static void configureBinaryDistribution( Project project )
+  {
+    configureGoOfflineHelpers( project )
+
+    def releaseSpec = project.extensions.getByType( ReleaseSpecExtension )
+    def reportsDistCopySpec = project.copySpec { CopySpec spec ->
+      spec.from "$project.buildDir/reports"
+      spec.into 'docs/reports'
+    }
+    def docsCopySpec = project.copySpec { CopySpec spec ->
+      spec.from 'build/docs'
+      spec.from 'manual/build/docs/website'
+      spec.into 'docs'
+    }
+    def runtimeDependenciesListCopySpec = project.copySpec { CopySpec spec ->
+      releaseSpec.approvedProjects.collect { p ->
+        spec.into( 'libs/' ) { CopySpec sub ->
+          sub.from "$p.buildDir/reports/project/dependencies.txt"
+          sub.rename 'dependencies.txt', "${ p.name }-${ p.version }-runtime-deps.txt"
+        }
+      }
+      spec.into( '.' ) { CopySpec sub ->
+        sub.from project.tasks.getByName( TaskNames.GENERATE_MAVEN_OFFLINE_HELPERS ).outputs
+        sub.from project.tasks.getByName( TaskNames.GENERATE_GRADLE_OFFLINE_HELPERS ).outputs
+      }
+    }
+    def libsCopySpec = project.copySpec { CopySpec spec ->
+      releaseSpec.approvedProjects.collect { proj ->
+        spec.into( 'libs/' ) { CopySpec sub ->
+          sub.from proj.configurations.getByName( 'archives' ).artifacts.files
+          sub.exclude '**-testsources.jar'
+          sub.exclude '**/*.asc'
+        }
+      }
+    }
+    def extraDistTextCopySpec = project.copySpec { CopySpec spec ->
+      releaseSpec.approvedProjects.collect { p ->
+        spec.from project.fileTree( dir: "$p.projectDir/src/dist/", include: '**', exclude: "**/*.jar*" )
+        spec.eachFile { FileCopyDetails fcd ->
+          fcd.filter( ReplaceTokens, tokens: [ version: project.version ] )
+        }
+      }
+      spec.into '.'
+    }
+    def extraDistBinCopySpec = project.copySpec { CopySpec spec ->
+      releaseSpec.approvedProjects.collect { p ->
+        spec.from "$p.projectDir/src/dist/"
+        spec.include '**/*.jar'
+        spec.include '**/*.jar_'
+      }
+      spec.into '.'
+    }
+    def binDistNoticesCopySpec = project.copySpec { CopySpec spec ->
+      spec.from "$project.projectDir/LICENSE.txt"
+      spec.from "$project.projectDir/src/bin-dist"
+      spec.into '.'
+    }
+    def binDistImage = project.copySpec { CopySpec spec ->
+      spec.into "apache-polygene-java-$project.version-bin"
+      spec.with binDistNoticesCopySpec
+      spec.with docsCopySpec
+      spec.with reportsDistCopySpec
+      spec.with runtimeDependenciesListCopySpec
+      spec.with extraDistTextCopySpec
+      spec.with extraDistBinCopySpec
+      spec.with libsCopySpec
+    }
+
+    def zipBinaries = project.tasks.create( 'zipBinaries', Zip ) { Zip task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = 'Assemble .zip binary distribution'
+      task.dependsOn project.tasks.getByName( RootProjectPlugin.TaskNames.BUILD_ALL )
+      task.baseName = 'apache-polygene-java'
+      task.classifier = 'bin'
+      task.with binDistImage
+    }
+    def tarBinaries = project.tasks.create( 'tarBinaries', Tar ) { Tar task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = 'Assemble .tar.gz binary distribution'
+      task.dependsOn project.tasks.getByName( RootProjectPlugin.TaskNames.BUILD_ALL )
+      task.baseName = 'apache-polygene-java'
+      task.classifier = 'bin'
+      task.compression = Compression.GZIP
+      task.with binDistImage
+    }
+    project.artifacts.add( 'archives', zipBinaries )
+    project.artifacts.add( 'archives', tarBinaries )
+
+    project.tasks.create( TaskNames.UNPACK_BINARY_DIST, Copy ) { Copy task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = "Unpack binary distribution"
+      task.with binDistImage
+      task.into 'build/unpacked-distributions/bin'
+    }
+
+    configureBinaryDistributionCheck( project )
+  }
+
+  private static void configureGoOfflineHelpers( Project project )
+  {
+    def externalRepos = project.rootProject.extensions.getByType( DependenciesDeclarationExtension ).repositoriesUrls
+    def approvedProjectsTask = project.tasks.getByName( ReleaseSpecPlugin.TaskNames.RELEASE_APPROVED_PROJECTS )
+    def genOfflineMaven = project.tasks.create( TaskNames.GENERATE_MAVEN_OFFLINE_HELPERS,
+                                                GoOfflineHelpersTasks.GenerateMaven )
+    def genOfflineGradle = project.tasks.create( TaskNames.GENERATE_GRADLE_OFFLINE_HELPERS,
+                                                 GoOfflineHelpersTasks.GenerateGradle )
+    genOfflineMaven.repositories = externalRepos
+    genOfflineGradle.repositories = externalRepos
+    [ genOfflineMaven, genOfflineGradle ].each { task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.dependsOn approvedProjectsTask
+    }
+    def checkOfflineMaven = project.tasks.create( TaskNames.CHECK_MAVEN_OFFLINE_HELPERS,
+                                                  GoOfflineHelpersTasks.CheckMaven )
+    checkOfflineMaven.group = TaskGroups.DISTRIBUTION_VERIFICATION
+    checkOfflineMaven.description = 'Check binary distribution Maven dependencies download helper'
+    checkOfflineMaven.dependsOn genOfflineMaven
+    def checkOfflineGradle = project.tasks.create( TaskNames.CHECK_GRADLE_OFFLINE_HELPERS,
+                                                   GoOfflineHelpersTasks.CheckGradle )
+    checkOfflineGradle.group = TaskGroups.DISTRIBUTION_VERIFICATION
+    checkOfflineGradle.description = 'Check binary distribution Gradle dependencies download helper'
+    checkOfflineGradle.dependsOn genOfflineGradle
+    [ checkOfflineMaven, checkOfflineGradle ].each { task ->
+      task.group = TaskGroups.DISTRIBUTION_VERIFICATION
+      task.dependsOn TaskNames.UNPACK_BINARY_DIST
+    }
+  }
+
+  private static void configureBinaryDistributionCheck( Project project )
+  {
+    def unpackedBinDistDir = project.file( "build/unpacked-distributions/bin/apache-polygene-java-$project.version-bin" )
+    project.tasks.create( TaskNames.CHECK_BINARY_DIST_RAT, RatTask, { RatTask task ->
+      task.group = TaskGroups.DISTRIBUTION_VERIFICATION
+      task.description = "Checks binary distribution using Apache RAT"
+      task.dependsOn TaskNames.UNPACK_BINARY_DIST
+      task.inputDir = unpackedBinDistDir.absolutePath
+      task.reportDir = project.file( 'build/reports/rat-bin-dist' )
+      task.excludes = [
+        '.gradle/**',
+        'docs/reports/**',
+        'docs/javadocs/**',
+        'etc/templates/**',
+        'libs/**'
+      ]
+    } as Action<RatTask> )
+    project.tasks.getByName( TaskNames.CHECK_MAVEN_OFFLINE_HELPERS ) { GoOfflineHelpersTasks.CheckMaven task ->
+      task.directory = unpackedBinDistDir
+    }
+    project.tasks.getByName( TaskNames.CHECK_GRADLE_OFFLINE_HELPERS ) { GoOfflineHelpersTasks.CheckGradle task ->
+      task.directory = unpackedBinDistDir
+      task.mustRunAfter TaskNames.CHECK_MAVEN_OFFLINE_HELPERS
+    }
+    project.tasks.create( TaskNames.CHECK_BINARY_DIST ) { Task task ->
+      task.group = TaskGroups.DISTRIBUTION_VERIFICATION
+      task.description = 'Checks binary distribution'
+      task.dependsOn TaskNames.CHECK_BINARY_DIST_RAT
+      task.dependsOn TaskNames.CHECK_MAVEN_OFFLINE_HELPERS
+      task.dependsOn TaskNames.CHECK_GRADLE_OFFLINE_HELPERS
+    }
+  }
+
+  @CompileStatic( TypeCheckingMode.SKIP )
+  private static void configureDistributionChecksums( Project project )
+  {
+    project.tasks.withType( Zip ) { Zip task ->
+      task.doLast {
+        project.ant.checksum file: task.archivePath, algorithm: 'MD5'
+        project.ant.checksum file: task.archivePath, algorithm: 'SHA-512'
+      }
+    }
+    project.tasks.withType( Tar ) { Tar task ->
+      task.doLast {
+        project.ant.checksum file: task.archivePath, algorithm: 'MD5'
+        project.ant.checksum file: task.archivePath, algorithm: 'SHA-512'
+      }
+    }
+  }
+
+  private static void configureHelperTasks( Project project )
+  {
+    project.tasks.create( 'dist', Copy ) { Copy task ->
+      task.group = TaskGroups.DISTRIBUTION
+      task.description = "Assembles source and binary distributions"
+      task.dependsOn 'install'
+      task.from project.tasks.getByName( 'unpackBinDist' )
+      task.into "$project.buildDir/dist"
+    }
+    project.tasks.create( 'checkDists' ) { Task task ->
+      task.group = TaskGroups.DISTRIBUTION_VERIFICATION
+      task.description = "Checks source and binary distributions"
+      task.dependsOn TaskNames.CHECK_SOURCE_DIST, TaskNames.CHECK_BINARY_DIST
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/GoOfflineHelpersTasks.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/GoOfflineHelpersTasks.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/GoOfflineHelpersTasks.groovy
new file mode 100644
index 0000000..415a0bb
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/dist/GoOfflineHelpersTasks.groovy
@@ -0,0 +1,345 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.dist
+
+import groovy.transform.CompileStatic
+import org.apache.polygene.gradle.release.ReleaseSpecExtension
+import org.apache.polygene.gradle.tasks.ExecLogged
+import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.artifacts.ProjectDependency
+import org.gradle.api.artifacts.result.ResolvedComponentResult
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.process.ExecSpec
+
+/**
+ * Tasks to generate and check go-offline maven and gradle helpers bundled with the binary distribution.
+ */
+@CompileStatic
+interface GoOfflineHelpersTasks
+{
+  class GenerateMaven extends DefaultTask
+  {
+    static final String POM_FILENAME = 'go-offline.pom'
+
+    @Input
+    Map<String, String> repositories = [ : ]
+
+    @Internal
+    File outputDir = new File( project.buildDir, 'go-offline-helpers' )
+
+    @OutputFile
+    File getMavenGoOfflineHelper()
+    {
+      return new File( outputDir, POM_FILENAME )
+    }
+
+    GenerateMaven()
+    {
+      super();
+      outputs.upToDateWhen { false }
+    }
+
+    @TaskAction
+    void generate()
+    {
+      outputDir.mkdirs()
+      def components = Utils.resolveAllRuntimeComponents( project )
+      def maven = generateMaven( components )
+      mavenGoOfflineHelper.text = maven
+    }
+
+    private String generateMaven( Set<ResolvedComponentResult> components )
+    {
+      def pom = Utils.licenseHeader( project.file( 'etc/header.txt' ).text, 'xml' )
+      pom += '<project>\n  <modelVersion>4.0.0</modelVersion>\n'
+      pom +=
+        "  <groupId>org.apache.polygene</groupId>\n  <artifactId>go-offline-helper</artifactId>\n  <version>$project.version</version>\n"
+      pom += '  <packaging>pom</packaging>\n'
+      pom +=
+        '  <!--\n  This pom has the sole purpose of downloading all dependencies in a directory relative to this file named \'dependencies\'.\n'
+      pom += "  Use the following command:\n\n  mvn -f $POM_FILENAME validate\n  -->\n  <repositories>\n"
+      repositories.entrySet().each { repo ->
+        pom += "    <repository><id>go-offline-repo-$repo.key</id><url>${ repo.value }</url></repository>\n"
+      }
+      pom += '  </repositories>\n  <dependencies>\n'
+      components.each { comp ->
+        pom += '    <dependency>\n'
+        pom += "      <groupId>$comp.moduleVersion.group</groupId>\n"
+        pom += "      <artifactId>$comp.moduleVersion.name</artifactId>\n"
+        pom += "      <version>$comp.moduleVersion.version</version>\n"
+        pom += '    </dependency>\n'
+      }
+      pom += """  </dependencies>\n  <build><plugins><plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-dependency-plugin</artifactId>
+    <version>2.10</version>
+    <executions>
+      <execution>
+        <id>go-offline-jars</id><phase>validate</phase>
+        <goals><goal>copy-dependencies</goal></goals>
+        <configuration>
+          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
+          <excludeTransitive>true</excludeTransitive>
+        </configuration>
+      </execution>
+      <execution>
+        <id>go-offline-sources</id><phase>validate</phase>
+        <goals><goal>copy-dependencies</goal></goals>
+        <configuration>
+          <classifier>sources</classifier><failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
+          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
+          <excludeTransitive>true</excludeTransitive>
+        </configuration>
+      </execution>
+      <execution>
+        <id>go-offline-javadocs</id><phase>validate</phase>
+        <goals><goal>copy-dependencies</goal></goals>
+        <configuration>
+          <classifier>javadoc</classifier><failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
+          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
+          <excludeTransitive>true</excludeTransitive>
+        </configuration>
+      </execution>
+    </executions>
+  </plugin></plugins></build>
+</project>
+"""
+      return pom
+    }
+  }
+
+  class GenerateGradle extends DefaultTask
+  {
+    static final String BUILD_SCRIPT_FILENAME = 'go-offline.gradle'
+
+    @Input
+    Map<String, String> repositories = [ : ]
+
+    @Internal
+    File outputDir = new File( project.buildDir, 'go-offline-helpers' )
+
+    @OutputFile
+    File getGradleGoOfflineHelper()
+    {
+      return new File( outputDir, BUILD_SCRIPT_FILENAME )
+    }
+
+    GenerateGradle()
+    {
+      super();
+      outputs.upToDateWhen { false }
+    }
+
+    @TaskAction
+    void generate()
+    {
+      outputDir.mkdirs()
+      def components = Utils.resolveAllRuntimeComponents( project )
+      def gradle = generateGradle( components )
+      gradleGoOfflineHelper.text = gradle
+    }
+
+    private String generateGradle( Set<ResolvedComponentResult> components )
+    {
+      def build = Utils.licenseHeader( project.file( 'etc/header.txt' ).text, 'java' )
+      build += '// This gradle build file has the sole purpose of downloading all dependencies in a directory\n'
+      build += '// relative to this file named \'dependencies\'.\n'
+      build += "// Use the following command: gradle -b $BUILD_SCRIPT_FILENAME download\n"
+      build += 'apply plugin: \'java\'\nconfigurations { download }\nrepositories {\n'
+      repositories.entrySet().each { repo ->
+        build += "  maven { url '${ repo.value }' }\n"
+      }
+      build += '}\ndependencies {\n'
+      components.each { comp ->
+        def depCoords = "${ comp.moduleVersion.group }:${ comp.moduleVersion.name }:${ comp.moduleVersion.version }"
+        build += "  download( '$depCoords' ) { transitive = false }\n"
+      }
+      build += """}
+task download( type: Copy ) {
+  outputs.upToDateWhen { false }
+  def sources = configurations.download.resolvedConfiguration.resolvedArtifacts.collect { artifact ->
+    project.dependencies.create( [ group: artifact.moduleVersion.id.group, name: artifact.moduleVersion.id.name, version: artifact.moduleVersion.id.version, classifier: 'sources' ] )
+  }
+  def javadocs = configurations.download.resolvedConfiguration.resolvedArtifacts.collect { artifact ->
+    project.dependencies.create( [ group: artifact.moduleVersion.id.group, name: artifact.moduleVersion.id.name, version: artifact.moduleVersion.id.version, classifier: 'javadoc' ] )
+  }
+  from configurations.download
+  from configurations.detachedConfiguration( sources as Dependency[] ).resolvedConfiguration.lenientConfiguration.getFiles( Specs.SATISFIES_ALL )
+  from configurations.detachedConfiguration( javadocs as Dependency[] ).resolvedConfiguration.lenientConfiguration.getFiles( Specs.SATISFIES_ALL )
+  into file( 'dependencies/' )
+}
+"""
+      return build
+    }
+  }
+
+  class CheckMaven extends DefaultTask
+  {
+    @Internal
+    File directory
+
+    @InputFile
+    File getMavenGoOfflineHelper()
+    {
+      return new File( directory, GenerateMaven.POM_FILENAME )
+    }
+
+    CheckMaven()
+    {
+      super();
+      description = 'Check the binary distribution Maven go-offline helper'
+      outputs.upToDateWhen { false }
+      onlyIf { Utils.isMvnInstalled() }
+    }
+
+    @TaskAction
+    void check()
+    {
+      def dependenciesDir = new File( directory, 'dependencies' )
+      project.delete dependenciesDir
+      def outLog = project.file( "$project.buildDir/tmp/$name/stdout.log" )
+      def errLog = project.file( "$project.buildDir/tmp/$name/stderr.log" )
+      def command = [ 'mvn', '-e', '-f', GenerateMaven.POM_FILENAME, 'validate' ] as Object[]
+      ExecLogged.execLogged( project, outLog, errLog ) { ExecSpec spec ->
+        spec.workingDir directory
+        spec.commandLine command
+      }
+      Utils.checkAllJarsArePresent( project, dependenciesDir, GenerateMaven.POM_FILENAME )
+    }
+  }
+
+  class CheckGradle extends DefaultTask
+  {
+    @Internal
+    File directory
+
+    @InputFile
+    File getGradleGoOfflineHelper()
+    {
+      return new File( directory, GenerateGradle.BUILD_SCRIPT_FILENAME )
+    }
+
+    CheckGradle()
+    {
+      super();
+      description = 'Check the binary distribution Gradle go-offline helper'
+      outputs.upToDateWhen { false }
+    }
+
+    @TaskAction
+    void check()
+    {
+      def buildScript = new File( directory, GenerateGradle.BUILD_SCRIPT_FILENAME )
+      def dependenciesDir = new File( directory, 'dependencies' )
+      project.delete dependenciesDir
+      def outLog = project.file( "$project.buildDir/tmp/$name/stdout.log" )
+      def errLog = project.file( "$project.buildDir/tmp/$name/stderr.log" )
+      ExecLogged.execLogged( project, outLog, errLog ) { ExecSpec spec ->
+        spec.workingDir project.projectDir
+        spec.commandLine './gradlew', '-u', '-s', '-b', buildScript.absolutePath, 'download'
+      }
+      Utils.checkAllJarsArePresent( project, dependenciesDir, GenerateGradle.BUILD_SCRIPT_FILENAME )
+    }
+  }
+
+  static class Utils
+  {
+    // Do the global dependency resolution here so there won't be any surprise when using the helpers
+    // This also allow to apply the resolution strategy defined in libraries.gradle
+    // WARN some of our modules depends on != versions of some artifacts, this resolution flatten this using the most up to date
+    private static Set<ResolvedComponentResult> resolveAllRuntimeComponents( Project rootProject )
+    {
+      def allRuntimeDeps = getAllRuntimeDependencies( rootProject )
+      def configuration = rootProject.configurations.findByName( 'goOfflineHelpers' )
+      if( !configuration )
+      {
+        configuration = rootProject.configurations.create( 'goOfflineHelpers' )
+        allRuntimeDeps.each { set -> rootProject.dependencies.add( configuration.name, set ) }
+      }
+      return configuration.incoming.resolutionResult.allComponents.findAll { ResolvedComponentResult comp ->
+        !comp.moduleVersion.group.startsWith( 'org.apache.polygene' )
+      } as Set<ResolvedComponentResult>
+    }
+
+    private static List<Dependency> getAllRuntimeDependencies( Project rootProject )
+    {
+      def releaseSpec = rootProject.extensions.getByType( ReleaseSpecExtension )
+      def allDependencies = releaseSpec.approvedProjects.collect { project ->
+        project.configurations.getByName( 'runtime' ).allDependencies
+      }.flatten() as List<Dependency>
+      return allDependencies.findAll { Dependency dep ->
+        !( dep instanceof ProjectDependency ) && dep.name != null && !dep.group.startsWith( 'org.apache.polygene' )
+      }
+    }
+
+    private static void checkAllJarsArePresent( Project rootProject, File dependenciesDir, String helper )
+    {
+      def allDependencies = getAllRuntimeDependencies( rootProject )
+      allDependencies.each { Dependency dep ->
+        def jarName = "${ dep.name }-${ dep.version }.jar"
+        def jarFile = new File( dependenciesDir, jarName )
+        if( !jarFile.exists() )
+        {
+          throw new GradleException( "Binary distribution $helper failed!\n" +
+                                     "\tMissing: $dep\n" +
+                                     "\tin $jarFile" );
+        }
+      }
+    }
+
+    private static boolean isMvnInstalled()
+    {
+      def pathDirs = System.getenv( 'PATH' ).split( File.pathSeparator )
+      def flattened = pathDirs.collect( { String pathDir -> new File( pathDir, 'mvn' ) } ).flatten() as List<File>
+      return flattened.find( { File pathDir -> pathDir.isFile() } ) != null
+    }
+
+    // Generate license headers with comment styles
+    private static String licenseHeader( String base, String flavour )
+    {
+      def header
+      switch( flavour )
+      {
+        case 'java': case 'groovy': case 'js':
+          header = licenseHeader_wrap( base, '/*', ' * ', ' */' ); break
+        case 'xml': case 'html':
+          header = licenseHeader_wrap( base, '<!--', '  ', '-->' ); break
+        case 'txt': case 'shell': case 'python': case 'ruby':
+          header = licenseHeader_wrap( base, null, '# ', null ); break
+        case 'adoc': case 'asciidoc':
+          header = licenseHeader_wrap( base, null, '// ', null ); break
+        default:
+          header = base
+      }
+      header
+    }
+
+    private static String licenseHeader_wrap( String base, String top, String left, String bottom )
+    {
+      ( top ? "$top\n" : '' ) + base.readLines().collect { "${ left }${ it }" }.join( '\n' ) + '\n' +
+      ( bottom ? "$bottom\n" : '' )
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/AsciidocBuildInfoPlugin.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/AsciidocBuildInfoPlugin.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/AsciidocBuildInfoPlugin.groovy
new file mode 100644
index 0000000..f8edcfb
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/AsciidocBuildInfoPlugin.groovy
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.doc
+
+import groovy.transform.CompileStatic
+import org.apache.polygene.gradle.TaskGroups
+import org.gradle.api.Project
+import org.gradle.api.Plugin
+
+@CompileStatic
+class AsciidocBuildInfoPlugin implements Plugin<Project>
+{
+  final static String TASK_NAME = 'makeAsciidocBuildInfo'
+
+  def void apply( Project project )
+  {
+    def buildInfoDir = new File( project.buildDir, "docs/buildinfo" );
+
+    def makeAsciidocBuildInfoTask = project.tasks.create( TASK_NAME )
+    makeAsciidocBuildInfoTask.group = TaskGroups.DOCUMENTATION
+    makeAsciidocBuildInfoTask.description = 'Generates asciidoc artifact snippet'
+    makeAsciidocBuildInfoTask.doLast {
+      buildInfoDir.mkdirs()
+
+      // GroupID, ArtifactID, Version table in artifact.txt
+      def artifactTableFile = new File( buildInfoDir, "artifact.txt" )
+      def artifactTable = """
+        |.Artifact
+        |[role="artifact", options="header,autowidth"]
+        ||===================================================
+        ||Group ID|Artifact ID|Version
+        ||${ project.group }|${ project.name }|${ project.version }
+        ||===================================================
+        """.stripMargin()
+      artifactTableFile.withWriter { out -> out.println( artifactTable ) }
+    }
+
+    // Declare inputs/outputs
+    if( project.getBuildFile() != null && project.getBuildFile().exists() )
+    {
+      makeAsciidocBuildInfoTask.getInputs().file( project.getBuildFile() )
+    }
+    makeAsciidocBuildInfoTask.getOutputs().file( buildInfoDir )
+  }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/DocumentationTask.groovy
----------------------------------------------------------------------
diff --git a/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/DocumentationTask.groovy b/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/DocumentationTask.groovy
new file mode 100644
index 0000000..a043aa0
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/polygene/gradle/doc/DocumentationTask.groovy
@@ -0,0 +1,292 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.gradle.doc
+
+import groovy.io.FileType
+import groovy.transform.CompileStatic
+import groovy.transform.TypeCheckingMode
+import java.security.MessageDigest
+import org.apache.polygene.gradle.PolygeneExtension
+import org.apache.polygene.gradle.release.ReleaseSpecExtension
+import org.apache.polygene.gradle.tasks.ExecLogged
+import org.gradle.api.Action;
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.CopySpec
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.process.ExecSpec
+
+// TODO: try to use dependencies for FOP and execute within the same JVM.
+// TODO: move the bulk of resources into this plugin, instead of sitting in the project.
+@CompileStatic
+class DocumentationTask extends DefaultTask
+{
+  @Input def String docName
+  @Input def String docType
+
+  @InputDirectory def File getCommonResourcesDir() { project.file( 'src/resources' ) }
+  @InputDirectory def File getConfigDir() { project.file( 'src/conf' ) }
+  @InputDirectory def File getDocsDir() { project.file( 'src/docs' ) }
+  @InputDirectory def File getSrcMainDir() { project.file( 'src/main' ) }
+  @InputDirectory def File getXslDir() { project.file( 'src/xsl' ) }
+  @InputDirectory def File getBuildSrcDir() { project.rootProject.file( 'buildSrc/src' ) }
+
+  @InputFiles def getSubProjectsDocsDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/docs' ) } }
+  @InputFiles def getSubProjectsTestDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/test' ) } }
+
+  @OutputDirectory def File getOutputDir() { project.file( "${ project.buildDir }/docs/${ docName }/" ) }
+
+  @Internal def File getTempAsciidocDir() { project.file( "${ project.buildDir }/tmp-asciidoc" ) }
+  @Internal def File getTempDir() { project.file( "${ project.buildDir }/tmp/docs/${ docName }" ) }
+
+  @TaskAction
+  def void generate()
+  {
+    installAsciidocFilters()
+
+    [ outputDir, tempAsciidocDir, tempDir ].each { it.deleteDir() }
+    [ outputDir, tempAsciidocDir, tempDir ].each { it.mkdirs() }
+
+    copySubProjectsDocsResources()
+    generateAsciidocAccordingToReleaseSpecification()
+    generateXDoc()
+    generateChunkedHtml()
+    // generateSingleHtml()
+    // generatePdf()
+  }
+
+  def void installAsciidocFilters()
+  {
+    def digester = MessageDigest.getInstance( 'SHA' )
+    def filtersDir = project.rootProject.file( 'buildSrc/src/asciidoc/filters' )
+    def userHome = new File( System.getProperty( 'user.home' ) )
+    def dotAsciidocFiltersDir = new File( userHome, '.asciidoc/filters' )
+    def installSnippets = false
+    filtersDir.eachFileRecurse( FileType.FILES ) { originalFile ->
+      def targetFile = new File( dotAsciidocFiltersDir,
+                                 ( originalFile.toURI() as String ) - ( filtersDir.toURI() as String ) )
+      if( !targetFile.exists() )
+      {
+        installSnippets = true
+      }
+      else
+      {
+        def originalDigest = digester.digest( originalFile.bytes )
+        def targetDigest = digester.digest( targetFile.bytes )
+        if( originalDigest != targetDigest )
+        {
+          installSnippets = true
+        }
+      }
+    }
+    if( installSnippets )
+    {
+      dotAsciidocFiltersDir.mkdirs()
+      project.rootProject.copy { CopySpec spec ->
+        spec.from filtersDir
+        spec.into dotAsciidocFiltersDir
+      }
+      dotAsciidocFiltersDir.eachFileRecurse( FileType.FILES ) { file ->
+        if( file.name.endsWith( '.py' ) )
+        {
+          chmod( file, '755' )
+        }
+      }
+      println "Polygene Asciidoc Filters Installed!"
+    }
+  }
+
+  @CompileStatic( TypeCheckingMode.SKIP )
+  def void chmod( File file, String permissions )
+  {
+    ant.chmod( file: file.absolutePath, perm: permissions )
+  }
+
+  def void copySubProjectsDocsResources()
+  {
+    project.rootProject.subprojects.each { p ->
+      p.copy { CopySpec spec ->
+        spec.from p.file( 'src/docs/resources' )
+        spec.into outputDir
+        spec.include '**'
+      }
+    }
+  }
+
+  def void generateAsciidocAccordingToReleaseSpecification()
+  {
+    def zest = project.extensions.getByType( PolygeneExtension )
+    project.copy { CopySpec spec ->
+      spec.from docsDir
+      spec.into tempAsciidocDir
+      spec.include '**'
+    }
+    if( zest.releaseVersion )
+    {
+      def licenseFile = new File( tempAsciidocDir, 'userguide/libraries.txt' )
+      def extensionsFile = new File( tempAsciidocDir, 'userguide/extensions.txt' )
+      def toolsFile = new File( tempAsciidocDir, 'userguide/tools.txt' )
+      [ licenseFile, extensionsFile, toolsFile ].each { asciidocFile ->
+        def filteredFileContent = ''
+        asciidocFile.readLines().each { line ->
+          if( line.startsWith( 'include::' ) )
+          {
+            def approved = false
+            def releaseApprovedProjects = project.rootProject.extensions.
+              getByType( ReleaseSpecExtension ).approvedProjects
+            releaseApprovedProjects.collect { it.projectDir }.each { approvedProjectDir ->
+              if( line.contains( "${ approvedProjectDir.parentFile.name }/${ approvedProjectDir.name }" ) )
+              {
+                approved = true
+              }
+            }
+            if( approved )
+            {
+              filteredFileContent += "$line\n"
+            }
+          }
+          else
+          {
+            filteredFileContent += "$line\n"
+          }
+        }
+        asciidocFile.text = filteredFileContent
+      }
+    }
+  }
+
+  def void generateXDoc()
+  {
+    def outLog = getLogFile( 'adoc-2-docbook', 'stdout' )
+    def errLog = getLogFile( 'adoc-2-docbook', 'stderr' )
+    ExecLogged.execLogged( project, outLog, errLog, { ExecSpec spec ->
+      spec.executable = 'asciidoc'
+      spec.workingDir = '..'
+      def commonResourcesPath = relativePath( project.rootDir, commonResourcesDir )
+      def asciidocConfigPath = relativePath( project.rootDir, new File( configDir, 'asciidoc.conf' ) )
+      def docbookConfigPath = relativePath( project.rootDir, new File( configDir, 'docbook45.conf' ) )
+      def linkimagesConfigPath = relativePath( project.rootDir, new File( configDir, 'linkedimages.conf' ) )
+      def xdocOutputPath = relativePath( project.rootDir, new File( tempDir, 'xdoc-temp.xml' ) )
+      def asciidocIndexPath = relativePath( project.rootDir, new File( tempAsciidocDir, "$docName/index.txt" ) )
+      spec.args = [
+        '--attribute', 'revnumber=' + project.version,
+        '--attribute', 'level1=' + ( docType == 'article' ? 1 : 0 ),
+        '--attribute', 'level2=' + ( docType == 'article' ? 2 : 1 ),
+        '--attribute', 'level3=' + ( docType == 'article' ? 3 : 2 ),
+        '--attribute', 'level4=' + ( docType == 'article' ? 4 : 3 ),
+        '--attribute', 'importdir=' + commonResourcesPath,
+        '--backend', 'docbook',
+        '--attribute', 'docinfo1',
+        '--doctype', docType,
+        '--conf-file=' + asciidocConfigPath,
+        '--conf-file=' + docbookConfigPath,
+        '--conf-file=' + linkimagesConfigPath,
+        '--out-file', xdocOutputPath,
+        asciidocIndexPath
+      ]
+    } as Action<? super ExecSpec> )
+  }
+
+  def void generateChunkedHtml()
+  {
+    project.copy { CopySpec spec ->
+      spec.from commonResourcesDir
+      spec.into outputDir
+      spec.include '**'
+    }
+    project.copy { CopySpec spec ->
+      spec.from "$docsDir/$docName/resources"
+      spec.into outputDir
+      spec.include '**'
+    }
+    def outLog = getLogFile( 'docbook-2-chunked-html', 'stdout' )
+    def errLog = getLogFile( 'docbook-2-chunked-html', 'stderr' )
+    ExecLogged.execLogged( project, outLog, errLog, { ExecSpec spec ->
+      def xsltFile = "$docsDir/$docName/xsl/chunked.xsl"
+      def outputPath = relativePath( project.projectDir, outputDir ) + '/'
+      spec.executable = 'xsltproc'
+      spec.args = [
+        '--nonet',
+        '--noout',
+        '--output', outputPath,
+        xsltFile,
+        "$tempDir/xdoc-temp.xml"
+      ]
+    } as Action<? super ExecSpec> )
+  }
+
+  def void generateSingleHtml()
+  {
+    def outLog = getLogFile( 'docbook-2-html', 'stdout' )
+    def errLog = getLogFile( 'docbook-2-html', 'stderr' )
+    ExecLogged.execLogged( project, outLog, errLog, { ExecSpec spec ->
+      // XML_CATALOG_FILES=
+      String xsltFile = "$xslDir/xhtml.xsl"
+      spec.executable = 'xsltproc'
+      spec.args = [
+        '--nonet',
+        '--noout',
+        '--output', "$outputDir/${ docName }.html",
+        xsltFile,
+        "$tempDir/xdoc-temp.xml"
+      ]
+    } as Action<? super ExecSpec> )
+  }
+
+  def void generatePdf()
+  {
+    // $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo
+    def outLog = getLogFile( 'docbook-2-fo', 'stdout' )
+    def errLog = getLogFile( 'docbook-2-fo', 'stderr' )
+    ExecLogged.execLogged( project, outLog, errLog, { ExecSpec spec ->
+      String xsltFile = "$xslDir/fo.xsl"
+      spec.executable = 'xsltproc'
+      spec.args = [
+        '--nonet',
+        '--output', "$tempDir/${ docName }.fo",
+        xsltFile,
+        "$tempDir/xdoc-temp.xml"
+      ]
+    } as Action<? super ExecSpec> )
+
+    // $ fop article.fo article.pdf
+    outLog = getLogFile( 'fo-2-pdf', 'stdout' )
+    errLog = getLogFile( 'fo-2-pdf', 'stderr' )
+    ExecLogged.execLogged( project, outLog, errLog, { ExecSpec spec ->
+      spec.executable = 'fop'
+      spec.args = [
+        "$tempDir/${ docName }.fo",
+        "$outputDir/${ docName }.pdf"
+      ]
+    } as Action<? super ExecSpec> )
+  }
+
+  private File getLogFile( String step, String stream )
+  {
+    return project.file( "${ project.buildDir }/tmp/${ name }/${ step }-${ stream }.log" )
+  }
+
+  private static String relativePath( File root, File target )
+  {
+    new File( root.toURI().relativize( target.toURI() ).toString() ).path
+  }
+}