<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>4.1.0-RC1</version>
		<relativePath />
		<!-- lookup parent from repository -->
	</parent>

	<groupId>eu.solven.adhoc</groupId>
	<artifactId>aggregator-adhoc</artifactId>
	<version>0.1.0</version>

	<packaging>pom</packaging>

	<name>${project.groupId}:${project.artifactId}</name>
	<description>Formulas for OLAP</description>
	<url>https://github.com/solven-eu/adhoc</url>

	<licenses>
		<license>
			<name>MIT License</name>
			<url>http://www.opensource.org/licenses/mit-license.php</url>
		</license>
	</licenses>

	<developers>
		<developer>
			<id>blacelle</id>
			<name>Benoit Chatain Lacelle</name>
			<email>benoit at solven.eu</email>
			<roles>
				<role>Project lead</role>
			</roles>
		</developer>
	</developers>

	<modules>
		<module>model</module>
		<module>engine</module>
		<module>experimental</module>
		<module>calcite</module>
		<module>spring</module>
		<module>jmh</module>

		<module>libraries</module>

		<module>pivotable</module>

		<module>bom</module>

		<module>training</module>

		<module>aggregate</module>
	</modules>

	<scm>
		<!-- readonly -->
		<connection>scm:git:git@github.com:solven-eu/adhoc.git</connection>
		<!-- readwrite -->
		<developerConnection>scm:git:git@github.com:solven-eu/adhoc.git</developerConnection>
		<tag>v0.1.0</tag>
		<url>https://github.com/solven-eu/adhoc</url>
	</scm>

	<properties>
		<java.version>25</java.version>

		<lombok.version>1.18.46</lombok.version>
		<!-- Error Prone — enabled only under the `errorprone` profile. Kept here so Dependabot can bump a single version token. -->
		<errorprone.version>2.49.0</errorprone.version>
		<!-- NullAway — Error Prone plugin doing flow-sensitive nullness analysis driven by JSpecify @NullMarked. -->
		<nullaway.version>0.13.4</nullaway.version>

		<spring-boot.version>4.1.0-RC1</spring-boot.version>
		<pepper.version>5.7</pepper.version>

		<!-- Used by Adhoc as a library, and Pivotable -->
		<!-- If this version is enforced only in adhoc module, pivotablr will
		take SpringBoot default-->
		<jooq.version>3.21.4</jooq.version>

		<spotless.version>3.5.1</spotless.version>
		<cleanthat.version>2.24</cleanthat.version>

		<!-- Optional dependencies -->
		<!-- Typically not optional when referred by pivotable-server-->
		<evalex.ezylang.version>3.6.1</evalex.ezylang.version>
		<duckdb.version>1.5.3.0</duckdb.version>
		<guava.version>33.6.0-jre</guava.version>

		<arrow.version>19.0.0</arrow.version>
		<jgrapht.version>1.5.3</jgrapht.version>

		<!-- Jacoco requirements on a per-module basis-->
		<jacoco.branch.ratio>0.50</jacoco.branch.ratio>
		<jacoco.instruction.ratio>0.70</jacoco.instruction.ratio>

		<!-- By default (i.e. in local environments), check for code formatting
		AFTER trying automatic fixes. -->
		<!-- We suppose the developper would see the fixed and include them in
		his commit. -->
		<!-- In the CI, we check BEFORE automatic fixes as the CI should report
		early invalid code -->
		<staticChecks>process-sources</staticChecks>
		<!-- SpotBugs works on bytecode, hence require compilation to be done -->
		<!-- http://maven.apache.org/ref/3.8.1/maven-core/lifecycles.html -->
		<!-- https://github.com/spotbugs/spotbugs-maven-plugin/issues/75 -->
		<staticChecksOverBytecode>process-classes</staticChecksOverBytecode>

		<!-- By default, benchmarks are not executed -->
		<excludedGroups>adhoc-benchmark</excludedGroups>

		<!-- https://mvnrepository.com/artifact/com.github.spotbugs/spotbugs -->
		<spotbugs.version>4.9.3</spotbugs.version>
		<!--
		https://mvnrepository.com/artifact/com.github.spotbugs/spotbugs-maven-plugin -->
		<spotbugs-maven.version>4.9.8.3</spotbugs-maven.version>
		<!--
		https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-checkstyle-plugin -->
		<maven-checkstyle-plugin.version>3.6.0</maven-checkstyle-plugin.version>
		<!-- https://mvnrepository.com/artifact/com.puppycrawl.tools/checkstyle -->
		<checkstyle.version>13.4.2</checkstyle.version>
		<!--
		https://mvnrepository.com/artifact/info.novatec.ita/stereotype.check.plugin -->
		<stereotype.check.plugin.version>4.0.0</stereotype.check.plugin.version>
		<!--
		https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-pmd-plugin -->
		<maven-pmd-plugin.version>3.28.0</maven-pmd-plugin.version>
		<!-- https://mvnrepository.com/artifact/net.sourceforge.pmd/pmd -->
		<pmd.version>7.24.0</pmd.version>

		<!-- Netty is often involved in CVEs: it's version is managed specifically -->
		<netty.version>4.2.13.Final</netty.version>

		<!--
		https://stackoverflow.com/questions/13829538/maven-surefire-append-to-argline -->
		<customArgLine />

		<automatic.module.name />

		<!-- -Djol.magicFieldOffset=true helps JOL to measure Heap consumption on private fields-->
		<argLine><![CDATA[-Xmx512M -XX:+HeapDumpOnOutOfMemoryError -Djol.magicFieldOffset=true ${customArgLine}]]></argLine>
		<!-- Set to 'package' to skip trigger the tests jar (e.g. not to skip
		deployment) -->
		<testJarPhase>none</testJarPhase>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>com.github.spotbugs</groupId>
			<artifactId>spotbugs-annotations</artifactId>
			<version>4.9.8</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-jar-plugin</artifactId>
					<configuration>
						<archive>
							<manifestEntries>
								<Automatic-Module-Name>${automatic.module.name}</Automatic-Module-Name>
							</manifestEntries>
						</archive>
						<skipIfEmpty>true</skipIfEmpty>
					</configuration>
					<executions>
						<execution>
							<goals>
								<!-- Provides a classifier=tests jar, helpful
								for integration tests or benchmarks-->
								<goal>test-jar</goal>
							</goals>
							<!-- Set -DtestJarPhase=none to skip building and
							deploying the tests jar -->
							<phase>${testJarPhase}</phase>
							<configuration>
								<archive>
									<manifestEntries>
										<Automatic-Module-Name>${automatic.module.name}.tests</Automatic-Module-Name>
									</manifestEntries>
								</archive>
								<!-- Skip modules without test sources (e.g. the
								aggregator POM) -->
								<skipIfEmpty>true</skipIfEmpty>
								<!-- These files are auto-loaded by their respective frameworks
								whenever they appear on the classpath, which would force
								the consuming module to follow our test setup. Keep them
								in src/test/resources for our own tests, but strip them
								from the published tests-jar so downstream tests / benchmarks
								keep their own configuration:
								- `logback-test.xml`: Logback test logging config.
								- `junit-platform.properties`: JUnit Platform discovery /
								  parallelism settings (see model/src/test/resources). -->
								<excludes>
									<exclude>logback-test.xml</exclude>
									<exclude>junit-platform.properties</exclude>
								</excludes>
							</configuration>
						</execution>
					</executions>
				</plugin>

				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-surefire-plugin</artifactId>
					<configuration>
						<!--
						https://stackoverflow.com/questions/52110023/how-do-you-organize-tests-in-a-modular-java-project -->
						<!--
						https://stackoverflow.com/questions/46613214/java-9-maven-junit-does-test-code-need-module-info-java-of-its-own-and-wher -->
						<!--  allow to use unnamed modules -->
						<useModulePath>false</useModulePath>
					</configuration>
				</plugin>

				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<configuration>
						<annotationProcessorPaths>
							<!-- https://projectlombok.org/setup/maven -->
							<!--
							https://github.com/projectlombok/lombok/issues/3967 -->
							<path>
								<groupId>org.projectlombok</groupId>
								<artifactId>lombok</artifactId>
								<version>${lombok.version}</version>
							</path>
						</annotationProcessorPaths>
					</configuration>
				</plugin>

				<plugin>
					<!--
						Shared config for the git-commit-id plugin. Submodules that actually declare the plugin
						(`pivotable-infra` generates git.properties, `pivotable-js` substitutes @git.commit.id.abbrev@
						into index.html) inherit this managed configuration. Build contexts without a `.git/` directory
						— typically container builds on Render, Cloud Run, etc. where `.git` is excluded from the
						upload — must not fail; they fall back to empty/placeholder commit info. Pass the real SHA
						via `-Dgit.commit.id.abbrev=$CI_COMMIT_SHA` (or equivalent) from the CI if the `@…@` token
						in the served HTML needs to resolve.
					-->
					<groupId>io.github.git-commit-id</groupId>
					<artifactId>git-commit-id-maven-plugin</artifactId>
					<configuration>
						<failOnNoGitDirectory>false</failOnNoGitDirectory>
						<failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
					</configuration>
				</plugin>

				<plugin>
					<!-- We want to provide source jars -->
					<!-- https://maven.apache.org/plugins/maven-source-plugin/ -->
					<!-- Needed by Sonatype deployment-->
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-source-plugin</artifactId>
					<version>3.4.0</version>
					<executions>
						<execution>
							<id>attach-sources</id>
							<goals>
								<goal>jar-no-fork</goal>
							</goals>
						</execution>
					</executions>
				</plugin>
				<plugin>
					<!-- Needed by Sonatype deployment-->
					<!-- Out Javadoc is very weak-->
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-javadoc-plugin</artifactId>
					<version>3.12.0</version>
					<configuration>
						<!--
						https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8212233 -->
						<!-- <source>8</source>-->
						<defaultAuthor>Benoit Chatain Lacelle</defaultAuthor>
						<failOnError>false</failOnError>
						<!--
						https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html#additional-options-provided-by-the-standard-doclet -->
						<!--
						https://maven.apache.org/plugins/maven-javadoc-plugin/javadoc-mojo.html#doclint -->
						<doclint>-html,-syntax,-accessibility,-missing</doclint>
						<!--
						https://stackoverflow.com/questions/71784748/maven-javadoc-plugin-generates-warning-about-generating-every-file-why-what-is -->
						<quiet>true</quiet>
					</configuration>
					<executions>
						<execution>
							<id>attach-javadocs</id>
							<goals>
								<goal>jar</goal>
							</goals>
						</execution>
					</executions>
				</plugin>
				<plugin>
					<!-- Needed by Sonatype deployment-->
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-gpg-plugin</artifactId>
					<version>3.2.8</version>
					<executions>
						<execution>
							<id>sign-artifacts</id>
							<goals>
								<goal>sign</goal>
							</goals>
							<phase>verify</phase>
						</execution>
					</executions>
				</plugin>

				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-enforcer-plugin</artifactId>
					<version>3.6.3</version>
					<dependencies>
						<dependency>
							<!--
							https://www.mojohaus.org/extra-enforcer-rules/banDuplicateClasses.html -->
							<groupId>org.codehaus.mojo</groupId>
							<artifactId>extra-enforcer-rules</artifactId>
							<version>1.12.0</version>
						</dependency>
					</dependencies>
					<executions>
						<execution>
							<id>enforce</id>
							<goals>
								<goal>enforce</goal>
							</goals>
							<configuration>
								<failFast>true</failFast>
								<!--
								https://maven.apache.org/enforcer/enforcer-rules/index.html -->
								<rules>
									<!-- We have a local site used to upload
									report in circleci -->
									<!-- <banDistributionManagement /> -->
									<banDuplicatePomDependencyVersions />
									<!-- TODO Activate this rule requiring to
									force quite many dependencies -->
									<!-- <dependencyConvergence /> -->
									<!-- reactorModuleConvergence seems not to
									handle outer BOM (e.g. from SpringBoot) -->
									<!-- <reactorModuleConvergence /> -->
									<requireMavenVersion>
										<version>[3.9,)</version>
									</requireMavenVersion>
									<requireJavaVersion>
										<version>25.0</version>
									</requireJavaVersion>
									<!-- We leave some plugin versions to
									SpringBoot -->
									<!-- <requirePluginVersions /> -->
									<requireReleaseDeps>
										<onlyWhenRelease>true</onlyWhenRelease>
									</requireReleaseDeps>
									<bannedDependencies>
										<excludes>
											<!--
											<exclude>org.slf4j:slf4j-api:2</exclude>-->
											<!-- JUnit 4 — project is on JUnit 5 -->
											<exclude>junit:junit</exclude>
											<!-- Log4j v1 — CVE-prone,
											superseded by Logback/Log4j2 -->
											<exclude>log4j:log4j</exclude>
											<!-- commons-logging — use
											jcl-over-slf4j bridge instead -->
											<exclude>commons-logging:commons-logging</exclude>
											<!-- Old servlet API — use
											jakarta.servlet:jakarta.servlet-api -->
											<exclude>javax.servlet:servlet-api</exclude>
										</excludes>
									</bannedDependencies>
									<requireUpperBoundDeps>
										<excludes />
									</requireUpperBoundDeps>

									<!--
									https://www.mojohaus.org/extra-enforcer-rules/enforceBytecodeVersion.html -->
									<enforceBytecodeVersion>
										<maxJdkVersion>25</maxJdkVersion>
										<ignoredScopes>
											<ignoreScope>test</ignoreScope>
										</ignoredScopes>
									</enforceBytecodeVersion>

									<banCircularDependencies />

									<banDuplicateClasses>
										<!--
										https://www.mojohaus.org/extra-enforcer-rules/banDuplicateClasses.html -->
										<ignoreClasses>
											<!--
											com.github.stephenc.jcip:jcip-annotations -->
											<!-- net.jcip:jcip-annotations -->
											<!--
											com.google.code.findbugs:annotations -->
											<!--
											<ignoreClass>net.jcip.annotations.GuardedBy</ignoreClass>-->
										</ignoreClasses>
										<scopes>
											<scope>compile</scope>
											<scope>provided</scope>
										</scopes>
										<findAllDuplicates>true</findAllDuplicates>
										<ignoreWhenIdentical>true</ignoreWhenIdentical>
									</banDuplicateClasses>
								</rules>
							</configuration>
						</execution>
					</executions>
				</plugin>

				<plugin>
					<!--https://spotbugs.github.io/spotbugs-maven-plugin/index.html -->
					<!-- mvn compile
					com.github.spotbugs:spotbugs-maven-plugin:spotbugs -->
					<groupId>com.github.spotbugs</groupId>
					<artifactId>spotbugs-maven-plugin</artifactId>
					<version>${spotbugs-maven.version}</version>
					<configuration>
						<effort>Max</effort>
						<!-- TODO Switch to Medium then Low-->
						<threshold>High</threshold>

						<excludeFilterFile>${maven.multiModuleProjectDirectory}/.cleanthat/spotbugs.xml</excludeFilterFile>

						<!-- Default timeout is 10 minutes, but it is
						unnecessary large, while we sometimes encounter timeouts
						due to a bug in concurrent builds -->
						<timeout>60000</timeout>

						<!-- In the hope of going faster, no need to start a
						brand new JVM on each module -->
						<fork>false</fork>
						<plugins>
							<plugin>
								<!-- https://find-sec-bugs.github.io/ -->
								<!-- Security-centric rules -->
								<groupId>com.h3xstream.findsecbugs</groupId>
								<artifactId>findsecbugs-plugin</artifactId>
								<version>1.14.0</version>
							</plugin>

							<!-- Following plugin leads to ClassPath issues -->
							<!-- <plugin> -->
							<!-- https://github.com/mebigfatguy/fb-contrib -->
							<!-- Additional Java rules -->
							<!-- <groupId>com.mebigfatguy.fb-contrib</groupId> -->
							<!-- <artifactId>fb-contrib</artifactId> -->
							<!-- <version>7.4.7</version> -->
							<!-- </plugin> -->
						</plugins>
					</configuration>
					<executions>
						<execution>
							<id>check</id>
							<goals>
								<goal>check</goal>
							</goals>
							<!-- default phase is verify, which is after tests. -->
							<!-- We prefer to run static analysis before tests
							not to wait -->
							<phase>${staticChecksOverBytecode}</phase>
						</execution>
					</executions>
				</plugin>
				<plugin>
					<!-- https://github.com/CycloneDX/cyclonedx-maven-plugin -->
					<!-- Generates a CycloneDX SBOM at target/classes/META-INF/sbom/application.cdx.json (shipped inside the jar).
					     On the reactor root, this file is the project-wide aggregate scanned by .github/workflows/grype-sbom.yml.
						     Relies on the plugin's auto-bound makeAggregateBom (default) execution at phase `package`. -->
					<groupId>org.cyclonedx</groupId>
					<artifactId>cyclonedx-maven-plugin</artifactId>
					<configuration>
						<skipNotDeployed>false</skipNotDeployed>
					</configuration>
				</plugin>
				<plugin>
					<!--
					https://maven.apache.org/plugins/maven-checkstyle-plugin/ -->
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-checkstyle-plugin</artifactId>
					<version>${maven-checkstyle-plugin.version}</version>
					<!-- Make sure the configuration is not in execution blocks,
					so then are re-used by explicit invocation (vs lifecycle
					phase) -->
					<configuration>
						<excludes>**/generated/**,**/me/lemire/integercompression/**</excludes>

						<configLocation>${maven.multiModuleProjectDirectory}/.cleanthat/checkstyle.xml</configLocation>
						<!-- https://github.com/redisson/redisson/issues/2048 -->
						<propertyExpansion>checkstyle.config.path=${maven.multiModuleProjectDirectory}/.cleanthat/</propertyExpansion>

						<inputEncoding>UTF-8</inputEncoding>
						<consoleOutput>true</consoleOutput>
						<failsOnError>true</failsOnError>
						<!-- Prevent [WARNING] Unable to locate Source XRef to
						link to - DISABLED -->
						<!-- only with goal checkstyle-aggregate or checkstyle
						generating a report -->
						<!--<linkXRef>false</linkXRef> -->
					</configuration>
					<dependencies>
						<dependency>
							<!-- more recent than brought by maven plugin -->
							<groupId>com.puppycrawl.tools</groupId>
							<artifactId>checkstyle</artifactId>
							<version>${checkstyle.version}</version>
						</dependency>
						<dependency>
							<!-- https://github.com/spring-io/spring-javaformat -->
							<groupId>io.spring.javaformat</groupId>
							<artifactId>spring-javaformat-checkstyle</artifactId>
							<version>0.0.47</version>
						</dependency>
					</dependencies>
					<executions>
						<execution>
							<id>check</id>
							<goals>
								<goal>check</goal>
							</goals>
							<!-- default phase is verify, which is after tests. -->
							<!-- We prefer to run static analysis before tests
							not to wait -->
							<phase>${staticChecks}</phase>
						</execution>
					</executions>
				</plugin>
				<plugin>
					<!--https://maven.apache.org/plugins/maven-pmd-plugin/ -->
					<!-- Skip a row by adding '//NOPMD' at the end -->
					<!--
					https://pmd.github.io/pmd-6.6.0/pmd_userdocs_suppressing_warnings.html#nopmd-comment -->
					<!-- Trigger only pmd with 'mvn pmd:check' -->
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-pmd-plugin</artifactId>
					<version>${maven-pmd-plugin.version}</version>
					<configuration>
						<!-- <includeTests>true</includeTests> -->
						<indentSize>4</indentSize>
						<printFailingErrors>true</printFailingErrors>

						<!-- TODO Decrease to 4, then 3, until 1 -->
						<failurePriority>5</failurePriority>
						<!-- Prevent [WARNING] Unable to locate Source XRef to
						link to - DISABLED -->
						<linkXRef>false</linkXRef>
						<rulesets>
							<ruleset>${maven.multiModuleProjectDirectory}/.cleanthat/pmd.rulesets.xml</ruleset>
						</rulesets>
						<excludes>
							<exclude>**/generated/**</exclude>
							<exclude>**/me/lemire/integercompression/**</exclude>
						</excludes>
					</configuration>
					<dependencies>
						<dependency>
							<groupId>net.sourceforge.pmd</groupId>
							<artifactId>pmd-java</artifactId>
							<version>${pmd.version}</version>
						</dependency>
						<!-- maven-pmd-plugin relies by default on some version
						of PMD which -->
						<!-- may be incompatible with custom PMD versions -->
						<dependency>
							<groupId>net.sourceforge.pmd</groupId>
							<artifactId>pmd-core</artifactId>
							<version>${pmd.version}</version>
						</dependency>

						<!-- `javascript` and `jsp` are included b ydefault: we
						also need to ensure they have proper version -->
						<dependency>
							<groupId>net.sourceforge.pmd</groupId>
							<artifactId>pmd-javascript</artifactId>
							<version>${pmd.version}</version>
						</dependency>
						<dependency>
							<groupId>net.sourceforge.pmd</groupId>
							<artifactId>pmd-jsp</artifactId>
							<version>${pmd.version}</version>
						</dependency>
					</dependencies>
					<executions>
						<execution>
							<goals>
								<goal>check</goal>
								<goal>cpd-check</goal>
							</goals>
							<!-- Default phase is verify, which is after tests. -->
							<!-- We prefer to run static analysis before tests
							not to wait -->

							<!-- PMD should run after import auto-cleaning: done
							by using same phase but ordering plugins properly -->
							<!--
							https://stackoverflow.com/questions/8243912/changing-the-order-of-maven-plugin-execution -->

							<!-- Since PMD7, we need to run PMD analysis after
							compilation otherwise we get ambiguous resolutions -->
							<!--
							https://github.com/solven-eu/mitrust-datasharing/pull/13287#issuecomment-2127074525 -->
							<phase>${staticChecksOverBytecode}</phase>
						</execution>
					</executions>
				</plugin>

				<plugin>
					<!-- mvn com.diffplug.spotless:spotless-maven-plugin:apply -->
					<!-- mvn com.diffplug.spotless:spotless-maven-plugin:check -->
					<groupId>com.diffplug.spotless</groupId>
					<artifactId>spotless-maven-plugin</artifactId>
					<version>${spotless.version}</version>
					<configuration>
						<!-- optional: limit format enforcement to just the
						files changed by this feature branch -->
						<!--ratchetFrom>origin/master</ratchetFrom-->
						<formats>
							<!-- you can define as many formats as you want,
							each is independent -->
							<format>
								<!-- define the files to apply to -->
								<includes>
									<include>.gitignore</include>
								</includes>
								<!-- define the steps to apply to those files -->
								<trimTrailingWhitespace />
								<endWithNewline />
								<indent>
									<tabs>true</tabs>
									<spacesPerTab>4</spacesPerTab>
								</indent>
							</format>
						</formats>

						<pom>
							<includes>
								<include>pom.xml</include>
							</includes>

							<!--
							https://github.com/diffplug/spotless/tree/main/plugin-maven#sortpom -->
							<sortPom>
								<!-- We like empty elements, while plugin
								default configuration would expand them -->
								<expandEmptyElements>false</expandEmptyElements>

								<!-- https://github.com/Ekryd/sortpom/issues/75 -->
								<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>

								<!--
								https://github.com/Ekryd/sortpom/wiki/Parameters#for-both-the-sort-and-verify-goal -->
								<!-- -1 means '\t' -->
								<nrOfIndentSpace>-1</nrOfIndentSpace>
							</sortPom>
						</pom>

						<markdown>
							<excludes>
								<exclude>**/node_modules/**</exclude>
							</excludes>
							<endWithNewline />
							<indent>
								<tabs>true</tabs>
								<spacesPerTab>4</spacesPerTab>
							</indent>
							<includes>
								<include>**/*.md</include>
							</includes>

							<flexmark />
						</markdown>

						<!-- define a language-specific format -->
						<java>
							<excludes>
								<!-- TestCases needs to remains not
								formatted/cleaned -->
								<exclude>**/do_not_format_me/**</exclude>
								<exclude>**/me/lemire/integercompression/**</exclude>
								<exclude>**/TransitiveReductionV2.java</exclude>

								<!-- As there is no Javadoc, it would lead to a
								dangling Javadoc according to PMD-->
								<exclude>**/module-info.java</exclude>
							</excludes>

							<cleanthat>
								<sourceJdk>${maven.compiler.source}</sourceJdk>
								<version>${cleanthat.version}</version>
								<javaparserVersion>3.28.1</javaparserVersion>
								<mutators>
									<mutator>SafeAndConsensual</mutator>
									<mutator>SafeButNotConsensual</mutator>
								</mutators>
								<includeDraft>true</includeDraft>
								<excludedMutators>
									<!--
									https://github.com/javaparser/javaparser/issues/3930 -->
									<excludedMutator>LambdaReturnsSingleStatement</excludedMutator>
									<!-- Too much instable -->
									<excludedMutator>UseDiamondOperator</excludedMutator>
									<!-- PMD recommends not using `var` -->
									<excludedMutator>LocalVariableTypeInference</excludedMutator>
								</excludedMutators>
							</cleanthat>

							<removeUnusedImports>
								<engine>cleanthat-javaparser-unnecessaryimport</engine>
							</removeUnusedImports>
							<importOrder>
								<file>${maven.multiModuleProjectDirectory}/.cleanthat/eclipse.importorder</file>
								<!--order>java,javax,org,com</order-->
							</importOrder>

							<eclipse>
								<!-- matches the version of Eclipse IDE-->
								<!-- https://download.eclipse.org/eclipse/downloads/ -->
								<version>4.39</version>
								<file>${maven.multiModuleProjectDirectory}/.cleanthat/eclipse_java_code_formatter.xml</file>
							</eclipse>

							<licenseHeader>
								<!--
								https://github.com/diffplug/spotless/issues/1418 -->
								<delimiter>(package )|(import )</delimiter>
								<file>${maven.multiModuleProjectDirectory}/.cleanthat/spotless.license</file>
							</licenseHeader>
						</java>

						<json>
							<trimTrailingWhitespace />
							<endWithNewline />
							<indent>
								<tabs>true</tabs>
								<spacesPerTab>4</spacesPerTab>
							</indent>

							<includes>
								<!-- json files at root-->
								<include>*.json</include>
								<!-- json files in folders like `.cleanthat` -->
								<include>/.*/*.json</include>
								<!-- json files in src folder-->
								<include>src/**/*.json</include>
								<!-- Make sure the root modules does not process
								all json of all modules-->
							</includes>

							<excludes>
								<!-- Given file is the concatenation of multiple
								small JSONs, 1 JSON per line-->
								<exclude>/src/test/resources/zips-mini.json</exclude>
							</excludes>

							<gson />
						</json>

						<!-- yaml formatting is disabled as it drops comments -->

						<javascript>
							<includes>
								<!-- Do not include HTML and Vue files -->
								<!--
								https://biomejs.dev/internals/language-support/#html-super-languages-support -->
								<include>**/*.js</include>
							</includes>
							<excludes>
								<exclude>**/node_modules/**</exclude>
								<!-- exclude `target/site/jacoco/jacoco-resources/*.js` -->
								<exclude>**/target/**</exclude>
							</excludes>

							<!-- https://biomejs.dev/ -->
							<biome>
								<!-- Download Biome from the network if not
								already downloaded, see below for more info  -->
								<version>1.9.4</version>

								<!-- (optional) Path to the directory with the
								biome.json config file -->
								<configPath>${maven.multiModuleProjectDirectory}/.cleanthat/</configPath>

								<!-- (optional) Biome will auto detect the
								language based on the file extension. -->
								<!-- See below for possible values. -->
								<!--        <language>js</language>-->
							</biome>
						</javascript>
					</configuration>

					<executions>
						<execution>
							<id>applySpotless</id>
							<goals>
								<goal>apply</goal>
							</goals>
							<phase>process-sources</phase>
						</execution>
					</executions>
				</plugin>

				<!-- -Djacoco.skip=true -->
				<plugin>
					<groupId>org.jacoco</groupId>
					<artifactId>jacoco-maven-plugin</artifactId>
					<version>0.8.14</version>
					<configuration>
						<excludes>
							<!-- Vendored third-party sources, excluded from
							coverage -->
							<exclude>**/me/lemire/integercompression/**</exclude>
						</excludes>
					</configuration>
					<executions>
						<execution>
							<id>default-prepare-agent</id>
							<goals>
								<goal>prepare-agent</goal>
							</goals>
						</execution>
						<execution>
							<id>default-report</id>
							<goals>
								<goal>report</goal>
							</goals>
							<phase>prepare-package</phase>
						</execution>
						<execution>
							<id>default-check</id>
							<goals>
								<goal>check</goal>
							</goals>
							<configuration>
								<!-- https://github.com/jacoco/jacoco/issues/981 -->
								<skip>${skipTests}</skip>
								<rules>
									<rule implementation="org.jacoco.maven.RuleConfiguration">
										<!-- BUNDLE, PACKAGE, CLASS, SOURCEFILE
										or METHOD -->
										<element>BUNDLE</element>
										<limits>
											<limit implementation="org.jacoco.report.check.Limit">
												<!-- INSTRUCTION, LINE, BRANCH,
												COMPLEXITY, METHOD, CLASS -->
												<counter>BRANCH</counter>
												<!-- TOTALCOUNT, COVEREDCOUNT,
												MISSEDCOUNT, COVEREDRATIO,
												MISSEDRATIO -->
												<value>COVEREDRATIO</value>
												<minimum>${jacoco.branch.ratio}</minimum>
											</limit>
											<limit implementation="org.jacoco.report.check.Limit">
												<!-- INSTRUCTION, LINE, BRANCH,
												COMPLEXITY, METHOD, CLASS -->
												<counter>INSTRUCTION</counter>
												<!-- TOTALCOUNT, COVEREDCOUNT,
												MISSEDCOUNT, COVEREDRATIO,
												MISSEDRATIO -->
												<value>COVEREDRATIO</value>
												<minimum>${jacoco.instruction.ratio}</minimum>
											</limit>
										</limits>
									</rule>
								</rules>
							</configuration>
						</execution>
					</executions>
				</plugin>
			</plugins>
		</pluginManagement>

		<!-- It is useful to reference the plugins here, so that the
		pluginManagement configuration kicks in also when the plugin is
		requested directly (vs bound to a lifecycle phase)-->
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-source-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
			</plugin>
			<plugin>
				<!-- mvn spotless:apply -->
				<groupId>com.diffplug.spotless</groupId>
				<artifactId>spotless-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.jacoco</groupId>
				<artifactId>jacoco-maven-plugin</artifactId>
			</plugin>

			<!-- checkers after formatters -->
			<plugin>
				<!-- mvn checkstyle:check -->
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-checkstyle-plugin</artifactId>
			</plugin>
			<plugin>
				<!-- mvn pmd:check -->
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-pmd-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>com.github.spotbugs</groupId>
				<artifactId>spotbugs-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.cyclonedx</groupId>
				<artifactId>cyclonedx-maven-plugin</artifactId>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-release-plugin</artifactId>
				<version>3.3.1</version>
				<configuration>
					<!--
					https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#autoVersionSubmodules -->
					<autoVersionSubmodules>true</autoVersionSubmodules>
					<!--
					https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#signTag -->
					<signTag>true</signTag>
					<!--
					https://maven.apache.org/maven-release/maven-release-plugin/usage/prepare-release.html#overriding-the-default-tag-name-format -->
					<!--
					https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#tagNameFormat -->
					<tagNameFormat>v@{project.version}</tagNameFormat>

					<!-- http://central.sonatype.org/pages/apache-maven.html -->
					<!-- Sonatype profile is defined in pepper-metadata -->
					<releaseProfiles>sonatype,activeviam</releaseProfiles>

					<!-- On each release, push the jars to Maven Central -->
					<goals>deploy</goals>
					<!-- Temporarily ensure release:perform is fast, until
					release is stabilized -->
					<!-- Ensure Javadoc is not skipped -->
					<arguments>-Pfast</arguments>
				</configuration>
			</plugin>

			<!--
			https://central.sonatype.org/publish/publish-portal-maven/#automatic-publishing -->
			<plugin>
				<groupId>org.sonatype.central</groupId>
				<artifactId>central-publishing-maven-plugin</artifactId>
				<version>0.10.0</version>
				<extensions>true</extensions>
				<configuration>
					<publishingServerId>central</publishingServerId>
					<autoPublish>true</autoPublish>
					<!-- `published` state can take hours to be reached-->
					<waitUntil>validated</waitUntil>
				</configuration>
			</plugin>
		</plugins>

	</build>

	<profiles>
		<profile>
			<!-- mvn clean install -Pactiveviam -->
			<!-- This would require adding a private repository holding
			activeviam jars -->
			<!--
			https://docs.activeviam.com/products/atoti/server/6.1.1/docs/start/download/ -->
			<id>activeviam</id>
			<modules>
				<module>atoti</module>
			</modules>
		</profile>
		<profile>
			<!-- alias for activeviam -->
			<id>activepivot</id>
			<modules>
				<module>atoti</module>
			</modules>
		</profile>
		<profile>
			<!-- alias for activeviam -->
			<id>atoti</id>
			<modules>
				<module>atoti</module>
			</modules>
		</profile>

		<profile>
			<!--
			http://central.sonatype.org/pages/apache-maven.html#deploying-to-ossrh-with-apache-maven-introduction -->
			<id>sonatype</id>

			<!-- `ossrh` needs a server entry in settings.xml -->
			<distributionManagement>
				<repository>
					<id>ossrh</id>
					<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
				</repository>
				<snapshotRepository>
					<id>ossrh</id>
					<url>https://oss.sonatype.org/content/repositories/snapshots</url>
				</snapshotRepository>
			</distributionManagement>

			<build>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-javadoc-plugin</artifactId>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-gpg-plugin</artifactId>
					</plugin>
				</plugins>
			</build>
		</profile>

		<profile>
			<!-- Used to recompile quickly only the core components -->
			<id>fast</id>
			<properties>
				<!-- Code style -->
				<checkstyle.skip>true</checkstyle.skip>
				<pmd.skip>true</pmd.skip>
				<cpd.skip>true</cpd.skip>
				<spotbugs.skip>true</spotbugs.skip>
				<!--				<maven.javadoc.skip>true</maven.javadoc.skip>-->
				<license.skip>true</license.skip>
				<formatter.skip>true</formatter.skip>
				<impsort.skip>true</impsort.skip>
				<cleanthat.skip>true</cleanthat.skip>
				<skip.npm.style>true</skip.npm.style>
				<spotless.skip>true</spotless.skip>

				<!-- Dependency will be checked with style -->
				<enforcer.skip>true</enforcer.skip>

				<!-- SBOM generation is slow and not needed for fast recompiles -->
				<cyclonedx.skip>true</cyclonedx.skip>

				<skipTests>true</skipTests>
				<skipITs>true</skipITs>
				<jacoco.skip>true</jacoco.skip>
			</properties>
		</profile>
		<profile>
			<!-- Used to run tests but skipping quality checks -->
			<id>nostyle</id>
			<properties>
				<!-- Code style -->
				<checkstyle.skip>true</checkstyle.skip>
				<pmd.skip>true</pmd.skip>
				<cpd.skip>true</cpd.skip>
				<spotbugs.skip>true</spotbugs.skip>
				<!--				<maven.javadoc.skip>true</maven.javadoc.skip>-->
				<license.skip>true</license.skip>
				<formatter.skip>true</formatter.skip>
				<impsort.skip>true</impsort.skip>
				<cleanthat.skip>true</cleanthat.skip>
				<skip.npm.style>true</skip.npm.style>
				<spotless.skip>true</spotless.skip>

				<!-- Dependency will be checked with style -->
				<enforcer.skip>true</enforcer.skip>

				<!-- SBOM generation is slow and not needed when skipping style checks -->
				<cyclonedx.skip>true</cyclonedx.skip>
			</properties>
		</profile>

		<profile>
			<!--
				Error Prone static analysis (https://errorprone.info/). Opt-in so the default build stays
				unchanged while the integration settles. Usage:
					mvn compile -Perrorprone
				What this does: wires error_prone_core as an annotation-processor-path entry on
				maven-compiler-plugin, adds the `-Xplugin:ErrorProne` flag, and opens the `com.sun.tools.javac.*`
				JDK internals that Error Prone reads to walk the AST (javac forbids access by default since
				JEP 403 "Strongly Encapsulate JDK Internals"). Error Prone's default check set runs at WARNING
				severity; nothing fails the build yet — once the codebase is clean, promote individual checks
				to errors via `-Xep:<CheckName>:ERROR` or drop the profile in favour of default-on.
			-->
			<id>errorprone</id>
			<build>
				<pluginManagement>
					<plugins>
						<plugin>
							<groupId>org.apache.maven.plugins</groupId>
							<artifactId>maven-compiler-plugin</artifactId>
							<configuration>
								<!--
									Fork javac into a dedicated JVM so the `-J...` flags below are honoured.
									Without forking, javac runs inside Maven's own JVM and the `-J` prefix is
									ignored, leaving Error Prone unable to access the javac internals it walks
									(raises IllegalAccessError at plugin init time).
								-->
								<fork>true</fork>
								<annotationProcessorPaths combine.children="append">
									<path>
										<groupId>com.google.errorprone</groupId>
										<artifactId>error_prone_core</artifactId>
										<version>${errorprone.version}</version>
									</path>
									<path>
										<!--
											NullAway — flow-sensitive nullness analysis layered on top of Error Prone.
											Driven by JSpecify @NullMarked: only packages already annotated are checked
											(see `-XepOpt:NullAway:AnnotatedPackages` below), so unmigrated code stays
											silent until it is opted in.
										-->
										<groupId>com.uber.nullaway</groupId>
										<artifactId>nullaway</artifactId>
										<version>${nullaway.version}</version>
									</path>
								</annotationProcessorPaths>
								<compilerArgs combine.children="append">
									<arg>-XDcompilePolicy=simple</arg>
									<arg>--should-stop=ifError=FLOW</arg>
									<!--
										Default severity stands (Error Prone's own ERROR vs WARNING mapping). Two
										doc-only checks are demoted to WARNING because fixing them would mean
										retrofitting Javadoc across hundreds of Lombok-flavoured types — tracked
										separately. All other checks keep their default severity, so real-bug
										rules block the build.
										`FunctionalInterfaceMethodChanged` is disabled: the rule flags
										@FunctionalInterfaces whose `default` methods override an abstract method of
										a @FunctionalInterface superinterface (surprising lambda-widening semantics).
										In this codebase all such types are implemented by named classes — the risk
										is theoretical and the @FunctionalInterface annotation has documentation
										value we want to keep.
										Two checks are disabled because Error Prone 2.49.0 crashes internally on
										patterns present in this codebase — track / drop these overrides on the
										next EP bump:
										  - StringConcatToTextBlock: NoSuchElementException on some literals
										  - Immutable: throws on switch-expressions yielding method references
									-->
									<!--
										NullAway is opted-in per package via JSpecify `@NullMarked` (JSpecifyMode=true):
										only annotated packages are checked, so unmigrated code stays silent. As a single
										module's packages get marked, NullAway starts enforcing flow-sensitive nullness
										on them at ERROR severity. To temporarily downgrade while migrating a noisy
										module, set `-Xep:NullAway:WARN` instead of WARN→ERROR — do this in a profile,
										not by editing this line, so the default stays strict.
									-->
									<arg>-Xplugin:ErrorProne -Xep:EmptyBlockTag:WARN -Xep:MissingSummary:WARN -Xep:FunctionalInterfaceMethodChanged:OFF -Xep:StringConcatToTextBlock:OFF -Xep:Immutable:OFF -Xep:NullAway:ERROR -XepOpt:NullAway:JSpecifyMode=true -XepOpt:NullAway:OnlyNullMarked=true</arg>
									<!--
										JEP 403: javac internals are strongly encapsulated by default on JDK 16+.
										Error Prone inspects those internals to traverse the AST, so we re-open them
										through the javac `add-exports` mechanism. These flags are required verbatim by
										Error Prone's documentation (https://errorprone.info/docs/installation).
									-->
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
									<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
									<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
									<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
								</compilerArgs>
							</configuration>
						</plugin>
					</plugins>
				</pluginManagement>
			</build>
		</profile>
		<profile>
			<!-- Used to recompile quickly only the core components -->
			<id>benchmark-with</id>
			<properties>
				<!-- see
				eu.solven.adhoc.util.TestAdhocIntegrationTests.runIntegrationTests() -->
				<customArgLine>-Dadhoc.runIntegrationTests</customArgLine>
			</properties>
		</profile>
		<profile>
			<!-- Used to recompile quickly only the core components -->
			<id>benchmark-only</id>
			<properties>
				<!-- see
				eu.solven.adhoc.util.TestAdhocIntegrationTests.runIntegrationTests() -->
				<customArgLine>-Dadhoc.runIntegrationTests</customArgLine>
				<!--
				https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#groups -->
				<groups>adhoc-benchmark</groups>
				<excludedGroups />
			</properties>
		</profile>
	</profiles>
</project>
