buildscript {
	ext {
		log4jVersion = '1.2.17'
		springBootVersion = '2.7.0'
		eclipsePersistenceVersion = '2.1.1'
		kryoVersion = '4.0.2'
		springCloudClusterVersion = '1.0.2.RELEASE'
		springShellVersion = '1.1.0.RELEASE'
		eclipseEmfXmiVersion = '2.11.1-v20150805-0538'
		eclipseUml2CommonVersion = '2.0.0-v20140602-0749'
		eclipseEmfCommonVersion = '2.11.0-v20150805-0538'
		eclipseUml2TypesVersion = '2.0.0-v20140602-0749'
		eclipseEmfEcoreVersion = '2.11.1-v20150805-0538'
		eclipseUml2UmlVersion = '5.0.0-v20140602-0749'
		curatorVersion = '2.11.1'
		springAsciidoctorBackends = '0.0.5'
		awaitilityVersion = '3.1.6'
		reactorBlockHoundVersion = '1.0.4.RELEASE'
	}
	repositories {
		gradlePluginPortal()
		maven { url 'https://repo.spring.io/plugins-release' }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
	}
}

plugins {
	id 'org.asciidoctor.jvm.convert' version '3.3.2'
	id 'org.asciidoctor.jvm.pdf' version '3.3.2'
}

ext {
	moduleProjects = subprojects.findAll {
		it.name.startsWith("spring-statemachine-") && !it.name.contains("samples") && !it.name.contains("-bom")  && !it.name.contains("-platform")
	}
	javaProjects = subprojects - project(":spring-statemachine-bom") - project(":spring-statemachine-platform")
	javaProjectsAndRoot = javaProjects + rootProject
}

def recipeProjects() {
	subprojects.findAll { project ->
		project.name.contains('spring-statemachine-recipes') && project.name != 'spring-statemachine-recipes-common'
	}
}

def sampleProjects() {
	subprojects.findAll { project ->
		project.name.contains('spring-statemachine-samples') && project.name != 'spring-statemachine-samples-common'
	}
}

def getResolvedVersionOf(dependency) {
	// used for resolving version to docs
	return configurations.compileClasspath.resolvedConfiguration.firstLevelModuleDependencies.findAll { it.moduleName == dependency }[0].moduleVersion
}

configure(javaProjectsAndRoot) {
	apply plugin: 'java-library'
	apply plugin: 'eclipse'
	apply plugin: 'idea'
	apply plugin: 'org.springframework.statemachine.optional-dependencies'

	tasks.withType(GenerateModuleMetadata) {
		enabled = false
	}

	compileJava {
		sourceCompatibility = 1.8
		targetCompatibility = 1.8
	}

	compileTestJava {
		sourceCompatibility = 1.8
		targetCompatibility = 1.8
	}

	group = 'org.springframework.statemachine'

	[compileJava, compileTestJava]*.options*.compilerArgs = ['-Xlint:deprecation']

	repositories {
		mavenCentral()
		maven { url 'https://repo.spring.io/libs-snapshot' }
		maven { url 'https://repo.spring.io/libs-release' }
		maven { url 'https://repo.spring.io/libs-milestone' }
	}

	configurations {
		dependencyManagement {
			canBeConsumed = false
			canBeResolved = false
			visible = false
		}
		matching { it.name.endsWith("Classpath") }.all { it.extendsFrom(dependencyManagement) }
	}

	dependencies {
		dependencyManagement(enforcedPlatform(dependencies.project(path: ":spring-statemachine-platform")))
	}

	task integrationTest(type: Test) {
		include '**/*IntegrationTests.*'
	}

	test {
		useJUnitPlatform {
			if (!project.hasProperty('statemachineIncludeTags') && !project.hasProperty('statemachineExcludeTags')) {
				excludeTags = ['smoke']
			} else {
				if (project.hasProperty('statemachineIncludeTags') && statemachineIncludeTags.size() > 0) {
						includeTags = statemachineIncludeTags.split(',')
				}
				if (project.hasProperty('statemachineExcludeTags') && statemachineExcludeTags.size() > 0) {
						excludeTags = statemachineExcludeTags.split(',')
				}
			}
		}
		exclude '**/*IntegrationTests.*'
		if (project.hasProperty('statemachineTestResults') && statemachineTestResults.toBoolean()) {
			afterSuite { desc, result ->
				if (!desc.parent) {
					def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
					def startItem = '|  ', endItem = '  |'
					def repeatLength = startItem.length() + output.length() + endItem.length()
					println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
				}
			}
		}
	}
}

configure(javaProjects) { subproject ->
	apply from: "$rootDir/gradle/publications.gradle"

	dependencies {
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("io.projectreactor.tools:blockhound")
		testImplementation("org.springframework.boot:spring-boot-starter-test")
		testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
		if (project.hasProperty('statemachineBlockHound') && statemachineBlockHound.toBoolean()) {
			testRuntimeOnly("org.junit.platform:junit-platform-launcher")
			testRuntimeOnly("io.projectreactor.tools:blockhound-junit-platform")
		}
	}

	jar {
		manifest.attributes['Implementation-Title'] = subproject.name
		manifest.attributes['Implementation-Version'] = subproject.version

		from("${rootProject.projectDir}/src/dist") {
			include "license.txt"
			include "notice.txt"
			into "META-INF"
			expand(copyright: new Date().format('yyyy'), version: project.version)
		}
	}

	javadoc {
		// /config/configuration/StateMachineConfiguration.html...
		// java.lang.ClassCastException: com.sun.tools.javadoc.MethodDocImpl cannot be cast
		// to com.sun.tools.javadoc.AnnotationTypeElementDocImpl
		// @Bean(name = StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY)
		// vs.
		// @Bean

		enabled = false
		options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
		options.author = true
		options.header = project.name
		verbose = true
	}

	task sourcesJar(type: Jar, dependsOn:classes) {
		classifier = 'sources'
		from sourceSets.main.allJava
	}

	task javadocJar(type: Jar) {
		classifier = 'javadoc'
		from javadoc
	}

	publishing {
		publications {
			mavenJava(MavenPublication) {
				from components.java
				artifact sourcesJar
				artifact javadocJar
			}
		}
	}
}

project('spring-statemachine-core') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"
	description = 'Spring State Machine Core'

	dependencies {
		api 'org.springframework:spring-tx'
		api 'org.springframework:spring-messaging'
		api 'io.projectreactor:reactor-core'
		optional 'org.springframework.security:spring-security-core'

		testImplementation 'org.springframework:spring-test'
		testImplementation 'org.springframework:spring-web'
		testImplementation 'org.springframework:spring-webmvc'
		testImplementation 'io.projectreactor:reactor-test'
		testFixturesImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.apache.tomcat.embed:tomcat-embed-core'
		testImplementation('org.mockito:mockito-core') { dep ->
			exclude group: 'org.hamcrest'
		}
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
		testImplementation 'org.assertj:assertj-core'
		testFixturesImplementation 'org.assertj:assertj-core'
		testImplementation 'org.springframework.security:spring-security-config'
		testImplementation 'org.springframework.security:spring-security-test'
		testImplementation 'javax.servlet:javax.servlet-api'
		testImplementation 'org.awaitility:awaitility'
		testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
	}
}

project('spring-statemachine-autoconfigure') {
	description = 'Spring State Machine Boot Autoconfigure'

	dependencies {
		api project(':spring-statemachine-core')
		api 'org.springframework.boot:spring-boot-autoconfigure'
		api 'org.springframework.boot:spring-boot-actuator-autoconfigure'
		api 'org.springframework.boot:spring-boot-actuator'
		optional project(':spring-statemachine-data-common:spring-statemachine-data-jpa')
		optional project(':spring-statemachine-data-common:spring-statemachine-data-redis')
		optional project(':spring-statemachine-data-common:spring-statemachine-data-mongodb')
		optional 'org.springframework.boot:spring-boot-autoconfigure-processor'
		optional 'io.micrometer:micrometer-core'
		optional 'org.eclipse.persistence:javax.persistence'
		optional 'org.springframework.boot:spring-boot-starter-data-jpa'
		optional 'org.springframework.boot:spring-boot-starter-data-redis'
		optional 'org.springframework.boot:spring-boot-starter-data-mongodb'
		testRuntimeOnly 'com.h2database:h2'
		testImplementation 'org.springframework.boot:spring-boot-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
	}
}

project('spring-statemachine-test') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"
	description = "Spring State Machine Test"

	dependencies {
		api 'org.springframework:spring-context'
		api project(':spring-statemachine-core')
		api 'org.springframework:spring-test'
		api 'org.hamcrest:hamcrest-core'
		api 'org.hamcrest:hamcrest-library'
		api 'org.assertj:assertj-core'
		optional 'junit:junit'
		optional 'org.junit.jupiter:junit-jupiter-api'
		optional 'org.junit.vintage:junit-vintage-engine'
		testImplementation('org.mockito:mockito-core') { dep ->
			exclude group: 'org.hamcrest'
		}
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
	}
}

project('spring-statemachine-kryo') {
	description = 'Spring State Machine Kryo'

	dependencies {
		api project(':spring-statemachine-core')
		api 'com.esotericsoftware:kryo-shaded'

		testImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
		testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
	}
}

project('spring-statemachine-zookeeper') {
	description = 'Spring State Machine Zookeeper'

	dependencies {
		api 'org.springframework:spring-context'
		api project(':spring-statemachine-core')
		api project(':spring-statemachine-kryo')
		api 'org.apache.curator:curator-recipes'
		// github.com/spring-gradle-plugins/dependency-management-plugin/issues/136
		compileOnly 'log4j:log4j'

		testImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testImplementation 'org.apache.curator:curator-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
		testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
	}
}

project('spring-statemachine-data-common') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"

	dependencies {
		api project(':spring-statemachine-core')
		api project(':spring-statemachine-kryo')
		api 'org.springframework.data:spring-data-commons'
		optional 'org.springframework.security:spring-security-core'
		api 'com.fasterxml.jackson.core:jackson-core'
		api 'com.fasterxml.jackson.core:jackson-databind'
		testImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testFixturesImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.springframework.boot:spring-boot-starter-test'
		testFixturesImplementation 'org.springframework.boot:spring-boot-starter-test'
		testRuntimeOnly 'org.springframework.boot:spring-boot-starter-web'
	}
}

project('spring-statemachine-cluster') {
	description = 'Spring State Machine Cluster'

	dependencies {
		api project(':spring-statemachine-zookeeper')
		api 'org.springframework.integration:spring-integration-zookeeper'

		testImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testImplementation 'org.apache.curator:curator-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
		testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
	}
}

project('spring-statemachine-uml') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"
	description = 'Spring State Machine Uml'

	dependencies {
		api project(':spring-statemachine-core')
		optional 'org.springframework.security:spring-security-core'

		// these eclipse maven deps are simply broken
		api('org.eclipse.uml2:uml') { dep ->
			exclude group: 'org.eclipse.core', module: 'runtime'
			exclude group: 'org.eclipse.emf', module: 'ecore'
			exclude group: 'org.eclipse.emf.ecore', module: 'xmi'
			exclude group: 'org.eclipse.emf.mapping', module: 'ecore2xml'
			exclude group: 'org.eclipse.uml2', module: 'common'
			exclude group: 'org.eclipse.uml2', module: 'types'
		}
		api('org.eclipse.uml2:types') { dep ->
			exclude group: 'org.eclipse.core', module: 'runtime'
			exclude group: 'org.eclipse.emf', module: 'ecore'
			exclude group: 'org.eclipse.uml2', module: 'common'
		}
		api('org.eclipse.uml2:common') { dep ->
			exclude group: 'org.eclipse.core', module: 'runtime'
			exclude group: 'org.eclipse.emf', module: 'ecore'
		}
		api 'org.eclipse.emf:org.eclipse.emf.ecore.xmi'
		api 'org.eclipse.emf:org.eclipse.emf.ecore'
		api 'org.eclipse.emf:org.eclipse.emf.common'
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
		testImplementation 'org.awaitility:awaitility'
		testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
	}
}

project('spring-statemachine-build-tests') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"
	description = 'Spring State Machine Build Tests'

	dependencies {
		testImplementation project(':spring-statemachine-uml')
		testImplementation project(':spring-statemachine-test')
		testImplementation project(':spring-statemachine-data-common:spring-statemachine-data-jpa')
		testImplementation project(':spring-statemachine-data-common:spring-statemachine-data-redis')
		testImplementation project(':spring-statemachine-data-common:spring-statemachine-data-mongodb')
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.apache.commons:commons-pool2'
		testRuntimeOnly 'org.springframework.boot:spring-boot-starter-data-mongodb'
		testRuntimeOnly 'org.springframework.boot:spring-boot-starter-data-redis'
		testRuntimeOnly 'redis.clients:jedis'
		testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa'
		testImplementation 'com.h2database:h2'
		testImplementation 'org.springframework.boot:spring-boot-starter'
		testImplementation 'org.springframework:spring-test'
	}
}

configure(recipeProjects()) {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"

	dependencies {
		api project(':spring-statemachine-recipes-common')
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
	}
}

project('spring-statemachine-recipes-common') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"

	dependencies {
		api 'org.springframework:spring-context'
		api project(':spring-statemachine-core')
		testImplementation(testFixtures(project(":spring-statemachine-core")))
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
	}
}

project('spring-statemachine-bom') {
	apply plugin: 'java-platform'
	apply from: "$rootDir/gradle/publications.gradle"
	description = 'Spring Statemachine (Bill of Materials)'
	group = 'org.springframework.statemachine'

	tasks.withType(GenerateModuleMetadata) {
		enabled = false
	}

	dependencies {
		constraints {
			parent.moduleProjects.sort { "$it.name" }.each {
				api it
			}
		}
	}

	publishing {
		publications {
			mavenJava(MavenPublication) {
				artifactId = 'spring-statemachine-bom'
				from components.javaPlatform
			}
		}
	}

}

project('spring-statemachine-starter') {
	description = 'Spring Statemachine Starter'
	dependencies {
		api project(':spring-statemachine-autoconfigure')
		api 'org.springframework.boot:spring-boot-starter'
	}
}

configure(sampleProjects()) {
	apply plugin: 'org.springframework.boot'
	compileJava {
		sourceCompatibility = 1.8
		targetCompatibility = 1.8
	}
	dependencies {
		api project(':spring-statemachine-core')
		api 'org.springframework:spring-context-support'
		testImplementation('org.mockito:mockito-core') { dep ->
			exclude group: 'org.hamcrest'
		}
		testImplementation (project(':spring-statemachine-test')) { dep ->
			exclude group: 'junit', module: 'junit'
			exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
		}
		testImplementation 'org.springframework.boot:spring-boot-test'
		testImplementation 'org.springframework:spring-test'
		testImplementation("org.junit.jupiter:junit-jupiter-api")
		testImplementation("org.junit.jupiter:junit-jupiter-engine")
	}
	build.dependsOn bootJar

	artifacts {
		archives bootJar
	}
}

project('spring-statemachine-samples-common') {
	apply from: "$rootDir/gradle/java-test-fixtures.gradle"

	dependencies {
		api project(':spring-statemachine-core')
		api 'org.springframework.shell:spring-shell'
		api 'org.springframework.boot:spring-boot-starter'
		testImplementation(testFixtures(project(":spring-statemachine-core")))
	}
}

configure(rootProject) {
	apply from: "$rootDir/gradle/publications.gradle"
	description = 'Spring State Machine'

	pluginManager.withPlugin('com.jfrog.artifactory') {
		artifactory {
		    publish {
		        defaults {
					properties {
						archives '*:*:*:*@zip', 'zip.deployed': false, 'zip.name': 'spring-statemachine', 'zip.displayname': 'Spring Statemachine'
						archives '*:*:*:docs@zip', 'zip.type': 'docs'
						archives '*:*:*:dist@zip', 'zip.type': 'dist'
					}
		        }
		    }
		}
	}

	dependencies {
		// just used to get version into docs
		api 'org.springframework:spring-core'
		api 'org.springframework.boot:spring-boot'
	}

	// don't publish the default jar for the root project
	configurations.archives.artifacts.clear()

	afterEvaluate {
		tasks.findAll { it.name.startsWith('reference') }.each{ it.dependsOn.add('asciidoctor') }
	}

	configurations {
		docs
	}

	task prepareAsciidocBuild(type: Sync) {
		// and doc sources
		from 'docs/src/reference/asciidoc/'
		// to a build directory of your choice
		into "$buildDir/asciidoc/assemble"
	}

	asciidoctorj {
		version = '2.4.3'
	}

	asciidoctor {
		configurations "docs"
		dependsOn 'prepareAsciidocBuild'
		dependsOn 'copyDocsSamples'
		baseDirFollowsSourceFile()
		sourceDir "$buildDir/asciidoc/assemble"
		sources {
			include 'index.adoc'
		}
		resources {
			from(sourceDir) {
				include 'images/*', 'css/**', 'js/**', 'samples/**'
			}
		}
		outputOptions {
			backends "spring-html"
		}
		options doctype: 'book', eruby: 'erubis'
		attributes \
			'docinfo': 'shared',
			'toc': 'left',
			'toc-levels': '4',
			'stylesdir': "css/",
			'stylesheet': 'spring.css',
			'linkcss': true,
			'icons': 'font',
			'sectanchors': '',
			'idprefix': '',
			'idseparator': '-',
			'spring-statemachine-version' : project.version,
			'spring-version' : getResolvedVersionOf("spring-core"),
			'spring-boot-version' : getResolvedVersionOf("spring-boot"),
			'revnumber' : project.version
	}

	asciidoctorPdf {
		dependsOn 'copyDocsSamples'
		baseDirFollowsSourceFile()
		sourceDir "$buildDir/asciidoc/assemble"
		sources {
			include 'index.adoc'
		}
		options doctype: 'book', eruby: 'erubis'
		attributes \
			'spring-statemachine-version' : project.version,
			'spring-version' : getResolvedVersionOf("spring-core"),
			'spring-boot-version' : getResolvedVersionOf("spring-boot"),
			'revnumber' : project.version
	}

	dependencies { // for integration tests
		docs "io.spring.asciidoctor.backends:spring-asciidoctor-backends:${springAsciidoctorBackends}"
	}

	task copyDocsSamples(type: Copy) {
		from 'spring-statemachine-core/src/test/java/org/springframework/statemachine/docs'
		from 'spring-statemachine-test/src/test/java/org/springframework/statemachine/test/docs'
		from 'spring-statemachine-recipes/src/test/java/org/springframework/statemachine/recipes/docs'
		from 'spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/docs'
		from 'spring-statemachine-uml/src/test/java/org/springframework/statemachine/uml/docs'
		from 'spring-statemachine-uml/src/test/resources/org/springframework/statemachine/uml/docs'
		from 'spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/docs'
		from 'spring-statemachine-data/redis/src/test/java/org/springframework/statemachine/data/redis/docs'
		from 'spring-statemachine-data/mongodb/src/test/java/org/springframework/statemachine/data/mongodb/docs'
		from 'spring-statemachine-samples/src/main/java/'
		from 'spring-statemachine-samples/washer/src/main/java/'
		from 'spring-statemachine-samples/tasks/src/main/java/'
		from 'spring-statemachine-samples/turnstile/src/main/java/'
		from 'spring-statemachine-samples/turnstilereactive/src/main/java/'
		from 'spring-statemachine-samples/showcase/src/main/java/'
		from 'spring-statemachine-samples/cdplayer/src/main/java/'
		from 'spring-statemachine-samples/persist/src/main/java/'
		from 'spring-statemachine-samples/zookeeper/src/main/java/'
		from 'spring-statemachine-samples/security/src/main/java/'
		from 'spring-statemachine-samples/eventservice/src/main/java/'
		from 'spring-statemachine-samples/datajpa/src/main/java/'
		from 'spring-statemachine-samples/datajpa/src/main/resources/'
		from 'spring-statemachine-samples/datajpamultipersist/src/main/java/'
		from 'spring-statemachine-samples/datajpamultipersist/src/main/resources/'
		from 'spring-statemachine-samples/datapersist/src/main/java/'
		from 'spring-statemachine-samples/monitoring/src/main/java/'
		include '**/*.java'
		include '**/*.uml'
		include '**/*.json'
		into 'docs/src/reference/asciidoc/samples'
	}

	task api(type: Javadoc) {
		group = 'Documentation'
		description = 'Generates aggregated Javadoc API documentation.'
		title = "${rootProject.description} ${version} API"
		options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
		options.author = true
		options.header = rootProject.description
		options.links(
			'https://docs.jboss.org/jbossas/javadoc/4.0.5/connector'
		)

		// disable javadocs for samples
		source javaProjects
		.findAll { project ->
			!project.name.contains('samples')
		}
		.collect { project ->
			project.sourceSets.main.allJava
		}

		destinationDir = new File(buildDir, "api")
		classpath = files(javaProjects.collect { project ->
			project.sourceSets.main.compileClasspath
		})
		maxMemory = '1024m'
	}

	task docsZip(type: Zip) {
		group = 'Distribution'
		classifier = 'docs'
		description = "Builds -${classifier} archive containing api and reference for deployment."
		from('src/dist') {
			include 'changelog.txt'
		}
		from (api) {
			into 'api'
		}
		from (asciidoctorPdf) {
			into 'reference'
			include 'index.pdf'
		}
		from (asciidoctor) {
			into 'reference'
			include 'index.html'
			include 'js/**'
			include 'css/**'
			include 'images/**'
			include 'samples/**'
		}
	}

	task distZip(type: Zip, dependsOn: [docsZip]) {
		group = 'Distribution'
		classifier = 'dist'
		description = "Builds -${classifier} archive, containing all jars and docs, " +
			"suitable for community download page."

		ext.baseDir = "${project.name}-${project.version}";

		from('src/dist') {
			include 'readme.txt'
			include 'license.txt'
			include 'notice.txt'
			into "${baseDir}"
			expand(copyright: new Date().format('yyyy'), version: project.version)
		}

		from(zipTree(docsZip.archivePath)) {
			into "${baseDir}/docs"
		}

		javaProjects.each { subproject ->
			into ("${baseDir}/libs") {
				from subproject.jar
				if (subproject.tasks.findByPath('sourcesJar')) {
					from subproject.sourcesJar
				}
				if (subproject.tasks.findByPath('javadocJar')) {
					from subproject.javadocJar
				}
			}
		}
	}

	task nextVersion {
		doLast{
			def properties = new Properties()
			def file = new File('gradle.properties')
			properties.load(file.newDataInputStream())
			def currentVersion = properties.getProperty('version')
			if (currentVersion.indexOf('-SNAPSHOT') < 0) {
				throw new GradleException('Version is a non SNAPSHOT version')
			} else {
				def (major, minor, patch) = version.tokenize('.')
				patch = patch.replace('-SNAPSHOT', '')
				patch = String.valueOf(patch.toInteger() + 1)
				def nextVersion = major + '.' + minor + '.' + patch + '-SNAPSHOT'
				properties.setProperty('version', nextVersion)
				properties.store(file.newWriter(), null)
			}
		}
	}

	task milestoneVersion {
		doLast{
			def postfix = project.getProperty('statemachineMilestone')
			if (!(postfix ==~ /(?:M|RC)\d+/)) {
				throw new GradleException('Illegal milestone version')
			}
			def properties = new Properties()
			def file = new File('gradle.properties')
			properties.load(file.newDataInputStream())
			def currentVersion = properties.getProperty('version')
			if (currentVersion.indexOf('-SNAPSHOT') > 0) {
				def nextVersion = currentVersion - '-SNAPSHOT' + '-' + postfix
				properties.setProperty('version', nextVersion)
				properties.store(file.newWriter(), null)
			} else {
				throw new GradleException('Version is not a SNAPSHOT version')
			}
		}
	}

	task releaseVersion {
		doLast{
			def properties = new Properties()
			def file = new File('gradle.properties')
			properties.load(file.newDataInputStream())
			def currentVersion = properties.getProperty('version')
			if (currentVersion.indexOf('-SNAPSHOT') > 0) {
				def nextVersion = currentVersion - '-SNAPSHOT'
				properties.setProperty('version', nextVersion)
				properties.store(file.newWriter(), null)
			} else {
				throw new GradleException('Version is not a SNAPSHOT version')
			}
		}
	}

	publishing {
		publications {
			mavenJava(MavenPublication) {
				artifact docsZip
				artifact distZip
			}
		}
	}

}
