From 697e6857a5feb64e8c732a7ec4e111f62b1c8fcc Mon Sep 17 00:00:00 2001
From: Marc Giffing <MarcGiffing@users.noreply.github.com>
Date: Tue, 12 Nov 2024 21:57:57 +0100
Subject: [PATCH] Example project - minor improvements

---
 wicket-spring-boot-starter-example/pom.xml    | 709 +++++++++---------
 .../boot/example/WicketApplication.java       |   2 +-
 .../spring/boot/example/model/Customer.java   |  48 +-
 .../services/customer/CustomerRepository.java |  13 +-
 .../customer/filter/CustomerFilter.java       |  52 +-
 .../customer/filter/CustomerSort.java         |   2 +-
 .../customer/specs/CustomerSpecs.java         |   3 +
 .../CustomStylesCssRessourceReference.java    |  12 +
 ...ixBootstrapStylesCssResourceReference.java |  12 -
 .../web/assets/base/{fix.css => custom.css}   |   4 +
 .../web/general/action/panel/ActionPanel.html |   2 +-
 .../web/general/action/panel/ActionPanel.java |  26 +-
 .../panel/items/AbstractActionItemLink.html   |   2 +-
 .../panel/items/AbstractActionItemLink.java   |  13 +-
 .../panel/items/AbstrractActionItem.java      |   2 +-
 .../panel/items/links/ActionItemLink.html     |   2 +-
 .../panel/items/links/ActionItemLink.java     |   7 +-
 .../action/panel/items/yesno/YesNoLink.java   |   7 +-
 .../example/web/general/icons/IconType.java   |  24 -
 .../autocomplete/AutoCompleteTextField.java   |   4 -
 .../behavior/ValidationMsgBehavior.java       |   6 +-
 .../web/html/form/ValidationFormVisitor.java  |   4 +-
 .../web/html/form/focus/FocusBehaviour.java   |  16 +-
 .../example/web/html/modal/YesNoModal.java    |   2 +-
 .../example/web/html/panel/FeedbackPanel.java |   6 -
 .../web/pages/BaseAuthenticatedPage.java      |  32 +-
 .../boot/example/web/pages/BasePage.java      |  12 +-
 .../web/pages/customers/CustomerListPage.java | 204 ++---
 .../web/pages/customers/CustomerResource.java |  42 --
 .../customers/create/CustomerCreatePage.java  |  22 +-
 .../customers/edit/CustomerEditPage.java      |   2 +
 .../events/CustomerChangedEvent.java          |  20 +-
 .../events/CustomerDeletedEvent.java          |  20 +-
 .../customers/model/CustomerDataProvider.java |  17 +-
 .../model/UsernameSearchTextField.java        |   4 +-
 .../example/web/pages/login/LoginPage.java    |  12 +-
 .../example/web/pages/websocket/ChatPage.java |  78 +-
 .../web/pages/websocket/ChatParticipant.java  |  62 +-
 .../web/pages/websocket/ChatService.java      |  11 +-
 .../events/CustomerMessageEvent.java          |  18 +-
 .../pages/websocket/events/JoinChatEvent.java |  12 +-
 .../pages/websocket/events/LeftChatEvent.java |  11 +-
 .../dataprovider/DefaultDataProvider.java     |   9 +-
 .../app/WicketBootStandardWebApplication.java |   7 +-
 .../classscanner/ClassCandidateScanner.java   |  10 +-
 45 files changed, 660 insertions(+), 925 deletions(-)
 create mode 100644 wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/CustomStylesCssRessourceReference.java
 delete mode 100644 wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/FixBootstrapStylesCssResourceReference.java
 rename wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/{fix.css => custom.css} (53%)
 delete mode 100644 wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/icons/IconType.java
 delete mode 100644 wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerResource.java

diff --git a/wicket-spring-boot-starter-example/pom.xml b/wicket-spring-boot-starter-example/pom.xml
index 7c470263..42e94e53 100644
--- a/wicket-spring-boot-starter-example/pom.xml
+++ b/wicket-spring-boot-starter-example/pom.xml
@@ -1,369 +1,364 @@
-<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<artifactId>wicket-spring-boot-starter-example</artifactId>
+<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>wicket-spring-boot-starter-example</artifactId>
 
-	<parent>
-		<groupId>com.giffing.wicket.spring.boot.starter</groupId>
-		<artifactId>wicket-spring-boot-starter-parent</artifactId>
-		<version>4.0.0</version>
-		<relativePath>..</relativePath>
-	</parent>
+    <parent>
+        <groupId>com.giffing.wicket.spring.boot.starter</groupId>
+        <artifactId>wicket-spring-boot-starter-parent</artifactId>
+        <version>4.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
 
-	<name>Spring boot starter example</name>
-	<description>
-		An example project which uses the wicket-spring-boot-starter autoconfiguration project
-	</description>
+    <name>Spring boot starter example</name>
+    <description>
+        An example project which uses the wicket-spring-boot-starter autoconfiguration project
+    </description>
 
-	<properties>
-		<maven.deploy.skip>true</maven.deploy.skip>
-		<maven-processor-plugin.version>5.1-jdk8</maven-processor-plugin.version>
-		<maven.javadoc.skip>true</maven.javadoc.skip>
-		<wicket-bootstrap.version>7.0.8</wicket-bootstrap.version>
-	</properties>
+    <properties>
+        <maven.deploy.skip>true</maven.deploy.skip>
+        <maven.javadoc.skip>true</maven.javadoc.skip>
+        <wicket-bootstrap.version>7.0.8</wicket-bootstrap.version>
+        <hibernate-processor.version>7.0.0.Beta1</hibernate-processor.version>
+    </properties>
 
-	<dependencies>
-		<dependency>
-			<groupId>com.giffing.wicket.spring.boot.starter</groupId>
-			<artifactId>wicket-spring-boot-starter</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-security</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-actuator</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.session</groupId>
-			<artifactId>spring-session-jdbc</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.h2database</groupId>
-			<artifactId>h2</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.wicketstuff</groupId>
-			<artifactId>wicketstuff-annotation</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>de.agilecoders.wicket</groupId>
-			<artifactId>wicket-bootstrap-core</artifactId>
-			<version>${wicket-bootstrap.version}</version>
-		</dependency>
+    <dependencies>
+        <dependency>
+            <groupId>com.giffing.wicket.spring.boot.starter</groupId>
+            <artifactId>wicket-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wicketstuff</groupId>
+            <artifactId>wicketstuff-annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket</groupId>
+            <artifactId>wicket-bootstrap-core</artifactId>
+            <version>${wicket-bootstrap.version}</version>
+        </dependency>
 
-		<dependency>
-			<groupId>de.agilecoders.wicket</groupId>
-			<artifactId>wicket-bootstrap-extensions</artifactId>
-			<version>${wicket-bootstrap.version}</version>
-		</dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket</groupId>
+            <artifactId>wicket-bootstrap-extensions</artifactId>
+            <version>${wicket-bootstrap.version}</version>
+        </dependency>
 
-		<dependency>
-			<groupId>de.agilecoders.wicket</groupId>
-			<artifactId>wicket-bootstrap-sass</artifactId>
-			<version>${wicket-bootstrap.version}</version>
-		</dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket</groupId>
+            <artifactId>wicket-bootstrap-sass</artifactId>
+            <version>${wicket-bootstrap.version}</version>
+        </dependency>
 
-		<dependency>
-			<groupId>de.agilecoders.wicket</groupId>
-			<artifactId>wicket-bootstrap-themes</artifactId>
-			<version>${wicket-bootstrap.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.wicketstuff</groupId>
-			<artifactId>wicketstuff-htmlcompressor</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.yahoo.platform.yui</groupId>
-			<artifactId>yuicompressor</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.wicket</groupId>
-			<artifactId>wicket-extensions</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.wicket</groupId>
-			<artifactId>wicket-bean-validation</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-validation</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>de.agilecoders.wicket.webjars</groupId>
-			<artifactId>wicket-webjars</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>jakarta.xml.bind</groupId>
-			<artifactId>jakarta.xml.bind-api</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.wicketstuff</groupId>
-			<artifactId>wicketstuff-serializer-fast2</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>de.agilecoders.wicket</groupId>
-			<artifactId>jquery-selectors</artifactId>
-			<version>4.0.6</version>
-		</dependency>
-		<dependency>
-			<groupId>org.liquibase</groupId>
-			<artifactId>liquibase-core</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-lang3</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.wicketstuff</groupId>
-			<artifactId>wicketstuff-restannotations</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.wicketstuff</groupId>
-			<artifactId>wicketstuff-restannotations-json</artifactId>
-		</dependency>
-		<!-- Test dependencies -->
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.wicket</groupId>
-			<artifactId>wicket-tester</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<!-- To provide the annotation processor in the IDE's classpath -->
-		<dependency>
-			<groupId>org.hibernate.orm</groupId>
-			<artifactId>hibernate-jpamodelgen</artifactId>
-			<scope>provided</scope>
-		</dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket</groupId>
+            <artifactId>wicket-bootstrap-themes</artifactId>
+            <version>${wicket-bootstrap.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.wicketstuff</groupId>
+            <artifactId>wicketstuff-htmlcompressor</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.yahoo.platform.yui</groupId>
+            <artifactId>yuicompressor</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket-extensions</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket-bean-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket.webjars</groupId>
+            <artifactId>wicket-webjars</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wicketstuff</groupId>
+            <artifactId>wicketstuff-serializer-fast2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>de.agilecoders.wicket</groupId>
+            <artifactId>jquery-selectors</artifactId>
+            <version>4.0.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.liquibase</groupId>
+            <artifactId>liquibase-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wicketstuff</groupId>
+            <artifactId>wicketstuff-restannotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wicketstuff</groupId>
+            <artifactId>wicketstuff-restannotations-json</artifactId>
+        </dependency>
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket-tester</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate.orm</groupId>
+            <artifactId>hibernate-processor</artifactId>
+            <version>${hibernate-processor.version}</version>
+            <scope>provided</scope>
+        </dependency>
 
-		<dependency>
-			<groupId>org.apache.wicket</groupId>
-			<artifactId>wicket-native-websocket-javax</artifactId>
-		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket-native-websocket-javax</artifactId>
+        </dependency>
+    </dependencies>
 
-	<profiles>
-		<profile>
-			<id>release</id>
-		</profile>
-		<profile>
-			<id>development</id>
-			<activation>
-				<activeByDefault>true</activeByDefault>
-			</activation>
-			<properties>
-				<spring.profiles.active>development</spring.profiles.active>
-			</properties>
-			<dependencies>
-				<dependency>
-					<groupId>org.springframework.boot</groupId>
-					<artifactId>spring-boot-devtools</artifactId>
-				</dependency>
-				<dependency>
-					<groupId>org.apache.wicket</groupId>
-					<artifactId>wicket-devutils</artifactId>
-				</dependency>
-				<dependency>
-					<groupId>org.springframework.boot</groupId>
-					<artifactId>spring-boot-starter-web</artifactId>
-				</dependency>
-				<dependency>
-					<groupId>org.springframework.boot</groupId>
-					<artifactId>spring-boot-starter-actuator</artifactId>
-				</dependency>
-			</dependencies>
-		</profile>
-	</profiles>
+    <profiles>
+        <profile>
+            <id>release</id>
+        </profile>
+        <profile>
+            <id>development</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <properties>
+                <spring.profiles.active>development</spring.profiles.active>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-devtools</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.wicket</groupId>
+                    <artifactId>wicket-devutils</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-web</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-actuator</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
 
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-release-plugin</artifactId>
-				<executions>
-					<execution>
-						<phase>none</phase>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-deploy-plugin</artifactId>
-				<configuration>
-					<skip>true</skip>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-			<plugin>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<configuration>
-					<release>${java.version}</release>
-					<compilerArgument>-proc:none</compilerArgument>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.bsc.maven</groupId>
-				<artifactId>maven-processor-plugin</artifactId>
-				<version>${maven-processor-plugin.version}</version>
-				<executions>
-					<execution>
-						<id>process</id>
-						<goals>
-							<goal>process</goal>
-						</goals>
-						<phase>generate-sources</phase>
-						<configuration>
-							<processors>
-								<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
-							</processors>
-						</configuration>
-					</execution>
-				</executions>
-				<dependencies>
-					<dependency>
-						<groupId>org.hibernate.orm</groupId>
-						<artifactId>hibernate-jpamodelgen</artifactId>
-						<version>${hibernate.version}</version>
-					</dependency>
-				</dependencies>
-			</plugin>
-			<!-- Assist eclipse in recognizing the classes generated -->
-			<!-- by jpa-modelgen (via maven-processor-plugin) as source files -->
-			<plugin>
-				<groupId>org.codehaus.mojo</groupId>
-				<artifactId>build-helper-maven-plugin</artifactId>
-				<executions>
-					<execution>
-						<id>add-source</id>
-						<phase>generate-sources</phase>
-						<goals>
-							<goal>add-source</goal>
-						</goals>
-						<configuration>
-							<sources>
-								<source>target/generated-sources/apt</source>
-							</sources>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>org.asciidoctor</groupId>
-				<artifactId>asciidoctor-maven-plugin</artifactId>
-				<version>3.1.0</version>
-				<executions>
-					<execution>
-						<id>output-html</id>
-						<phase>generate-resources</phase>
-						<goals>
-							<goal>process-asciidoc</goal>
-						</goals>
-						<configuration>
-							<sourceDirectory>src/main/doc</sourceDirectory>
-							<outputDirectory>target/docs</outputDirectory>
-							<backend>html</backend>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<artifactId>maven-resources-plugin</artifactId>
-				<executions>
-					<execution>
-						<id>copy-asciidoc-resources</id>
-						<phase>generate-resources</phase>
-						<goals>
-							<goal>copy-resources</goal>
-						</goals>
-						<configuration>
-							<outputDirectory>${basedir}/src/main/resources/public/docs/</outputDirectory>
-							<resources>
-								<resource>
-									<directory>target/docs</directory>
-									<filtering>true</filtering>
-								</resource>
-							</resources>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-		</plugins>
-		<resources>
-			<resource>
-				<directory>src/main/resources</directory>
-			</resource>
-			<resource>
-				<directory>src/main/java</directory>
-				<includes>
-					<include>**</include>
-				</includes>
-				<excludes>
-					<exclude>**/*.java</exclude>
-				</excludes>
-			</resource>
-		</resources>
-		<pluginManagement>
-			<plugins>
-				<!--This plugin's configuration is used to store Eclipse m2e settings 
-					only. It has no influence on the Maven build itself. -->
-				<plugin>
-					<groupId>org.eclipse.m2e</groupId>
-					<artifactId>lifecycle-mapping</artifactId>
-					<version>1.0.0</version>
-					<configuration>
-						<lifecycleMappingMetadata>
-							<pluginExecutions>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>
-											org.asciidoctor
-										</groupId>
-										<artifactId>
-											asciidoctor-maven-plugin
-										</artifactId>
-										<versionRange>
-											[1.5.2,)
-										</versionRange>
-										<goals>
-											<goal>
-												process-asciidoc
-											</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore />
-									</action>
-								</pluginExecution>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.bsc.maven</groupId>
-										<artifactId>maven-processor-plugin</artifactId>
-										<versionRange>[${maven-processor-plugin.version},)</versionRange>
-										<goals>
-											<goal>process</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<execute />
-									</action>
-								</pluginExecution>
-							</pluginExecutions>
-						</lifecycleMappingMetadata>
-					</configuration>
-				</plugin>
-			</plugins>
-		</pluginManagement>
-	</build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>none</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.13.0</version>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                            <version>${lombok.version}</version>
+                        </path>
+                        <path>
+                            <groupId>org.hibernate.orm</groupId>
+                            <artifactId>hibernate-processor</artifactId>
+                            <version>${hibernate-processor.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+
+            <!-- Assist eclipse in recognizing the classes generated -->
+            <!-- by jpa-modelgen (via maven-processor-plugin) as source files -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>target/generated-sources/apt</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.asciidoctor</groupId>
+                <artifactId>asciidoctor-maven-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>output-html</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>process-asciidoc</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirectory>src/main/doc</sourceDirectory>
+                            <outputDirectory>target/docs</outputDirectory>
+                            <backend>html</backend>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-asciidoc-resources</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${basedir}/src/main/resources/public/docs/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>target/docs</directory>
+                                    <filtering>true</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**</include>
+                </includes>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
+        <pluginManagement>
+            <plugins>
+                <!--This plugin's configuration is used to store Eclipse m2e settings
+                    only. It has no influence on the Maven build itself. -->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>
+                                            org.asciidoctor
+                                        </groupId>
+                                        <artifactId>
+                                            asciidoctor-maven-plugin
+                                        </artifactId>
+                                        <versionRange>
+                                            [1.5.2,)
+                                        </versionRange>
+                                        <goals>
+                                            <goal>
+                                                process-asciidoc
+                                            </goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore/>
+                                    </action>
+                                </pluginExecution>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.bsc.maven</groupId>
+                                        <artifactId>maven-processor-plugin</artifactId>
+                                        <versionRange>[${maven-processor-plugin.version},)</versionRange>
+                                        <goals>
+                                            <goal>process</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <execute/>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
 
 </project>
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/WicketApplication.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/WicketApplication.java
index 4bc1c08b..d7b9e056 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/WicketApplication.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/WicketApplication.java
@@ -10,7 +10,7 @@
 @EnableJpaRepositories(basePackageClasses={DefaultRepositoryService.class})
 public class WicketApplication {
 
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) {
 		new SpringApplicationBuilder()
 			.sources(WicketApplication.class)
 			.run(args);
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/model/Customer.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/model/Customer.java
index 676cdb88..760499b5 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/model/Customer.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/model/Customer.java
@@ -8,8 +8,12 @@
 import jakarta.persistence.Id;
 
 import com.giffing.wicket.spring.boot.example.repository.Domain;
+import lombok.Getter;
+import lombok.Setter;
 
 @Entity
+@Getter
+@Setter
 public class Customer implements Domain<Long>, Serializable {
 
 	@Id
@@ -23,49 +27,5 @@ public class Customer implements Domain<Long>, Serializable {
 	private String lastname;
 	
 	private boolean active;
-	
-	@Override
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getFirstname() {
-		return firstname;
-	}
-
-	public void setFirstname(String firstname) {
-		this.firstname = firstname;
-	}
-
-	public String getLastname() {
-		return lastname;
-	}
 
-	public void setLastname(String lastname) {
-		this.lastname = lastname;
-	}
-
-	public boolean isActive() {
-		return active;
-	}
-
-	public void setActive(boolean active) {
-		this.active = active;
-	}
-
-	
-	
-	
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/CustomerRepository.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/CustomerRepository.java
index de33774f..a99df4d5 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/CustomerRepository.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/CustomerRepository.java
@@ -1,18 +1,11 @@
 package com.giffing.wicket.spring.boot.example.repository.services.customer;
 
-import java.util.List;
-
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.repository.CrudRepository;
-
 import com.giffing.wicket.spring.boot.example.model.Customer;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.ListCrudRepository;
 
-public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
+public interface CustomerRepository extends ListCrudRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
 	
-	@Override
-	List<Customer> findAll(Specification<Customer> specs);
-
 	int countByUsernameIgnoreCase(String username);
 
 	Customer findByUsernameIgnoreCase(String username);
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerFilter.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerFilter.java
index e4ef9c05..e9f99fb3 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerFilter.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerFilter.java
@@ -1,7 +1,11 @@
 package com.giffing.wicket.spring.boot.example.repository.services.customer.filter;
 
 import com.giffing.wicket.spring.boot.example.repository.DefaultFilter;
+import lombok.Getter;
+import lombok.Setter;
 
+@Getter
+@Setter
 public class CustomerFilter extends DefaultFilter {
 	
 	private Long id;
@@ -22,52 +26,4 @@ public class CustomerFilter extends DefaultFilter {
 	
 	private boolean active;
 
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getUsernameLike() {
-		return usernameLike;
-	}
-
-	public void setUsernameLike(String usernameLike) {
-		this.usernameLike = usernameLike;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getFirstnameLike() {
-		return firstnameLike;
-	}
-
-	public void setFirstnameLike(String firstnameLike) {
-		this.firstnameLike = firstnameLike;
-	}
-
-	public String getLastnameLike() {
-		return lastnameLike;
-	}
-
-	public void setLastnameLike(String lastnameLike) {
-		this.lastnameLike = lastnameLike;
-	}
-
-	public boolean isActive() {
-		return active;
-	}
-
-	public void setActive(boolean active) {
-		this.active = active;
-	}
-
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerSort.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerSort.java
index 1448ff48..a7142a7d 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerSort.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/filter/CustomerSort.java
@@ -9,7 +9,7 @@ public enum CustomerSort implements Sort {
 	LASTNAME("lastname"),
 	ACTIVE("active");
 
-	private String sortName;
+	private final String sortName;
 	
 	CustomerSort(String sortName){
 		this.sortName = sortName;
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/specs/CustomerSpecs.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/specs/CustomerSpecs.java
index 313d92e6..b2697261 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/specs/CustomerSpecs.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/repository/services/customer/specs/CustomerSpecs.java
@@ -1,10 +1,13 @@
 package com.giffing.wicket.spring.boot.example.repository.services.customer.specs;
 
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
 import org.springframework.data.jpa.domain.Specification;
 
 import com.giffing.wicket.spring.boot.example.model.Customer;
 import com.giffing.wicket.spring.boot.example.model.Customer_;
 
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class CustomerSpecs {
 
 	public static Specification<Customer> hasId(final Long id) {
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/CustomStylesCssRessourceReference.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/CustomStylesCssRessourceReference.java
new file mode 100644
index 00000000..55607ed2
--- /dev/null
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/CustomStylesCssRessourceReference.java
@@ -0,0 +1,12 @@
+package com.giffing.wicket.spring.boot.example.web.assets.base;
+
+import org.apache.wicket.request.resource.CssResourceReference;
+
+public class CustomStylesCssRessourceReference extends CssResourceReference {
+
+    public static final CustomStylesCssRessourceReference INSTANCE = new CustomStylesCssRessourceReference();
+
+    public CustomStylesCssRessourceReference() {
+        super(CustomStylesCssRessourceReference.class, "custom.css");
+    }
+}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/FixBootstrapStylesCssResourceReference.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/FixBootstrapStylesCssResourceReference.java
deleted file mode 100644
index 44ec0aab..00000000
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/FixBootstrapStylesCssResourceReference.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.giffing.wicket.spring.boot.example.web.assets.base;
-
-import org.apache.wicket.request.resource.CssResourceReference;
-
-public class FixBootstrapStylesCssResourceReference extends CssResourceReference {
-
-    public static final FixBootstrapStylesCssResourceReference INSTANCE = new FixBootstrapStylesCssResourceReference();
-
-    public FixBootstrapStylesCssResourceReference() {
-        super(FixBootstrapStylesCssResourceReference.class, "fix.css");
-    }
-}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/fix.css b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/custom.css
similarity index 53%
rename from wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/fix.css
rename to wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/custom.css
index 485a2ff7..de3fb268 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/fix.css
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/assets/base/custom.css
@@ -1,3 +1,7 @@
 .navbar {
     --bs-navbar-padding-x: 1;
+}
+
+.items {
+    padding-right: 5px;
 }
\ No newline at end of file
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.html b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.html
index 3ba385cc..5a9b28b6 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.html
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.html
@@ -1 +1 @@
-<wicket:panel><span wicket:id="items"><span wicket:id="item" /></span></wicket:panel>
\ No newline at end of file
+<wicket:panel><span wicket:id="items" class="items"><span wicket:id="item" /></span></wicket:panel>
\ No newline at end of file
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.java
index 7b9b64e9..58556509 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/ActionPanel.java
@@ -1,29 +1,25 @@
 package com.giffing.wicket.spring.boot.example.web.general.action.panel;
 
-import java.util.List;
-
+import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstrractActionItem;
+import de.agilecoders.wicket.core.markup.html.bootstrap.list.BootstrapListView;
 import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.Panel;
 
-import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstrractActionItem;
+import java.util.List;
 
 public class ActionPanel extends Panel {
-	
-	
+
 	public ActionPanel(String id, List<AbstrractActionItem> items) {
 		super(id);
-		ListView<AbstrractActionItem> listItems = new ListView<AbstrractActionItem>("items", items) {
+		add(new BootstrapListView<>("items", items) {
 
-			@Override
-			protected void populateItem(ListItem<AbstrractActionItem> item) {
-				item.add(item.getModel().getObject());
-			}
+            @Override
+            protected void populateItem(ListItem<AbstrractActionItem> item) {
+                item.add(item.getModel().getObject());
+            }
 
-
-		};
-		add(listItems);
+        });
 	}
-	
+
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.html b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.html
index ff99cf8d..3e6aa864 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.html
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.html
@@ -1,5 +1,5 @@
 <wicket:panel>
 <a wicket:id="link">
-	<span aria-hidden="true" wicket:id="icon-type"></span>
+	<span aria-hidden="true" wicket:id="icon"></span>
 </a>
 </wicket:panel>
\ No newline at end of file
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.java
index 32895302..9f524acc 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstractActionItemLink.java
@@ -1,16 +1,13 @@
 package com.giffing.wicket.spring.boot.example.web.general.action.panel.items;
 
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.behavior.AttributeAppender;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.model.IModel;
-
-import com.giffing.wicket.spring.boot.example.web.general.icons.IconType;
 
 public abstract class AbstractActionItemLink<T> extends AbstrractActionItem {
 	
-	public AbstractActionItemLink(IModel<T> label, IconType iconType){
+	protected AbstractActionItemLink(IconType iconType){
 		AjaxLink<T> link = new AjaxLink<T>("link") {
 
 			@Override
@@ -20,9 +17,7 @@ public void onClick(AjaxRequestTarget target) {
 			}
 		};
 		add(link);
-		WebMarkupContainer webMarkupContainer = new WebMarkupContainer("icon-type");
-		webMarkupContainer.add(new AttributeAppender("class", iconType.getCssName()));
-		link.add(webMarkupContainer);
+		link.add( new Icon("icon", iconType));
 	}
 	
 	public abstract void onClick(AjaxRequestTarget target);
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstrractActionItem.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstrractActionItem.java
index f4104921..95e51602 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstrractActionItem.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/AbstrractActionItem.java
@@ -4,7 +4,7 @@
 
 public abstract class AbstrractActionItem extends Panel {
 
-	public AbstrractActionItem() {
+	protected AbstrractActionItem() {
 		super("item");
 	}
 
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.html b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.html
index ff99cf8d..3e6aa864 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.html
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.html
@@ -1,5 +1,5 @@
 <wicket:panel>
 <a wicket:id="link">
-	<span aria-hidden="true" wicket:id="icon-type"></span>
+	<span aria-hidden="true" wicket:id="icon"></span>
 </a>
 </wicket:panel>
\ No newline at end of file
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.java
index 5166cdf0..19e800ac 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/links/ActionItemLink.java
@@ -1,20 +1,19 @@
 package com.giffing.wicket.spring.boot.example.web.general.action.panel.items.links;
 
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
 import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.link.AbstractLink;
 import org.apache.wicket.model.IModel;
 
 import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstrractActionItem;
-import com.giffing.wicket.spring.boot.example.web.general.icons.IconType;
 
 public class ActionItemLink extends AbstrractActionItem {
 	
 	public ActionItemLink(IModel<String> label, IconType iconType, AbstractLink link) {
 		add(link);
-		WebMarkupContainer webMarkupContainer = new WebMarkupContainer("icon-type");
-		webMarkupContainer.add(new AttributeAppender("class", "fa-solid fa-" + iconType.getCssName()));
-		link.add(webMarkupContainer);
+		link.add(new Icon("icon", iconType));
 	}
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/yesno/YesNoLink.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/yesno/YesNoLink.java
index b4062967..e42166ea 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/yesno/YesNoLink.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/action/panel/items/yesno/YesNoLink.java
@@ -1,18 +1,17 @@
 package com.giffing.wicket.spring.boot.example.web.general.action.panel.items.yesno;
 
 import com.giffing.wicket.spring.boot.example.web.pages.BasePage;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.panel.EmptyPanel;
-import org.apache.wicket.model.IModel;
 
 import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstractActionItemLink;
-import com.giffing.wicket.spring.boot.example.web.general.icons.IconType;
 import com.giffing.wicket.spring.boot.example.web.html.modal.YesNoModal;
 
 public abstract class YesNoLink<T> extends AbstractActionItemLink<T>{
 
-	public YesNoLink(IModel<T> label, IconType iconType) {
-		super(label, iconType);
+	public YesNoLink(IconType iconType) {
+		super(iconType);
 	}
 
 	@Override
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/icons/IconType.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/icons/IconType.java
deleted file mode 100644
index 5944837b..00000000
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/general/icons/IconType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.giffing.wicket.spring.boot.example.web.general.icons;
-
-import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome6IconType;
-
-public enum IconType {
-	CREATE(FontAwesome6IconType.plus_s.cssClassName()),
-	EDIT(FontAwesome6IconType.pen_s.cssClassName()),
-	DELETE(FontAwesome6IconType.minus_s.cssClassName());
-	
-	private String cssType;
-	
-	IconType(String cssType){
-		this.setCssType(cssType);
-	}
-
-	public String getCssName() {
-		return cssType;
-	}
-
-	public void setCssType(String cssType) {
-		this.cssType = cssType;
-	}
-	
-}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/autocomplete/AutoCompleteTextField.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/autocomplete/AutoCompleteTextField.java
index 683615fb..e9bc7127 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/autocomplete/AutoCompleteTextField.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/autocomplete/AutoCompleteTextField.java
@@ -13,10 +13,6 @@ public AutoCompleteTextField(String id, AutoCompleteSettings settings) {
 		super(id, settings);
 	}
 
-	public AutoCompleteTextField(String id, IModel<String> model) {
-		super(id, model);
-	}
-
 	public AutoCompleteTextField(String id, IModel<String> model, AutoCompleteSettings settings) {
 		super(id, model, settings);
 	}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/border/behavior/ValidationMsgBehavior.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/border/behavior/ValidationMsgBehavior.java
index 3d28418f..9870e5e6 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/border/behavior/ValidationMsgBehavior.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/border/behavior/ValidationMsgBehavior.java
@@ -12,8 +12,7 @@ public class ValidationMsgBehavior extends BorderBehavior {
 	
 	@Override
 	public void beforeRender(Component c) {
-		if (c instanceof FormComponent) {
-			FormComponent fc = (FormComponent) c;
+		if (c instanceof FormComponent fc) {
 			if (!fc.isValid()) {
 				super.beforeRender(c);
 				
@@ -24,8 +23,7 @@ public void beforeRender(Component c) {
 
 	@Override
 	public void afterRender(Component component) {
-		FormComponent fc = (FormComponent) component;
-		if (!fc.isValid()) {
+		if (component instanceof FormComponent<?> fc && !fc.isValid()) {
 			String error;
 			if (fc.hasFeedbackMessage()) {
 				FeedbackMessage first = fc.getFeedbackMessages().first();
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/ValidationFormVisitor.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/ValidationFormVisitor.java
index 80e24ebc..f477dc32 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/ValidationFormVisitor.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/ValidationFormVisitor.java
@@ -15,11 +15,11 @@ public class ValidationFormVisitor<R> implements IVisitor<Component, R>, ICluste
 
 	private static final long serialVersionUID = 1L;
 
-	Set<FormComponent> visited = new HashSet<>();
+	Set<FormComponent<?>> visited = new HashSet<>();
 
 	@Override
 	public void component(Component c, IVisit<R> visit) {
-		if(c instanceof FormComponent fc && !visited.contains(c)) {
+		if(c instanceof FormComponent<?> fc && !visited.contains(c)) {
 				c.add(new ValidationMsgBehavior());
 				visited.add(fc);
 			}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/focus/FocusBehaviour.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/focus/FocusBehaviour.java
index d6aa9209..6214b6ac 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/focus/FocusBehaviour.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/form/focus/FocusBehaviour.java
@@ -5,14 +5,14 @@
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 
-public class FocusBehaviour extends Behavior{
+public class FocusBehaviour extends Behavior {
 
-	@Override
-	public void renderHead(Component component, IHeaderResponse response) {
-		super.renderHead(component, response);
-		OnDomReadyHeaderItem focusComponentHeaderItem = OnDomReadyHeaderItem.forScript("document.getElementById('"
-				    + component.getMarkupId() + "').focus();");
-		response.render(focusComponentHeaderItem);
-	}
+    @Override
+    public void renderHead(Component component, IHeaderResponse response) {
+        super.renderHead(component, response);
+        OnDomReadyHeaderItem focusComponentHeaderItem = OnDomReadyHeaderItem
+				.forScript("document.getElementById('%s').focus();".formatted(component.getMarkupId()));
+        response.render(focusComponentHeaderItem);
+    }
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/modal/YesNoModal.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/modal/YesNoModal.java
index b6338483..f63759e8 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/modal/YesNoModal.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/modal/YesNoModal.java
@@ -8,7 +8,7 @@ public abstract class YesNoModal extends Modal<Panel> {
 
     public YesNoModal(String id) {
         super(id);
-        YesNoPanel yesNoPanel = new YesNoPanel("content") {
+        var yesNoPanel = new YesNoPanel("content") {
 
             @Override
             protected void yesClicked(AjaxRequestTarget target) {
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/panel/FeedbackPanel.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/panel/FeedbackPanel.java
index 99c2da79..981ac944 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/panel/FeedbackPanel.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/html/panel/FeedbackPanel.java
@@ -1,15 +1,9 @@
 package com.giffing.wicket.spring.boot.example.web.html.panel;
 
-import org.apache.wicket.feedback.IFeedbackMessageFilter;
-
 public class FeedbackPanel extends org.apache.wicket.markup.html.panel.FeedbackPanel {
 
 	public FeedbackPanel(String string) {
 		super(string);
 	}
 
-	public FeedbackPanel(String id, IFeedbackMessageFilter filter) {
-		super(id, filter);
-	}
-
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BaseAuthenticatedPage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BaseAuthenticatedPage.java
index 34e77cb5..ee7da97f 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BaseAuthenticatedPage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BaseAuthenticatedPage.java
@@ -34,21 +34,22 @@ public BaseAuthenticatedPage(final PageParameters parameters) {
     }
 
     protected Navbar newNavbar(String markupId) {
-        Navbar navbar = new Navbar(markupId)
+        var navbar = new Navbar(markupId)
                 .setPosition(Navbar.Position.TOP)
                 .setInverted(true)
                 .setBackgroundColor(BackgroundColorBehavior.Color.Dark);
 
         navbar.setBrandName(Model.of("Wicket"));
-        navbar.addComponents(NavbarComponents.transform(Navbar.ComponentPosition.LEFT,
-                        new NavbarButton<Void>(CustomerListPage.class, Model.of("Customers")).setIconType(FontAwesome6IconType.person_s),
-                        new NavbarButton<Void>(ChatPage.class, Model.of("Chat")).setIconType(FontAwesome6IconType.rocketchat),
-                        new NavbarExternalLink(Model.of("https://github.com/MarcGiffing/wicket-spring-boot"))
-                                .setLabel(Model.of("Github"))
-                                .setTarget(BootstrapExternalLink.Target.blank)
-                                .setIconType(FontAwesome6IconType.upload_s))
+        navbar.addComponents(NavbarComponents.transform(
+                Navbar.ComponentPosition.LEFT,
+                new NavbarButton<Void>(CustomerListPage.class, Model.of("Customers")).setIconType(FontAwesome6IconType.person_s),
+                new NavbarButton<Void>(ChatPage.class, Model.of("Chat")).setIconType(FontAwesome6IconType.rocketchat),
+                new NavbarExternalLink(Model.of("https://github.com/MarcGiffing/wicket-spring-boot"))
+                        .setLabel(Model.of("Github"))
+                        .setTarget(BootstrapExternalLink.Target.blank)
+                        .setIconType(FontAwesome6IconType.upload_s))
         );
-        DropDownButton dropdown = new NavbarDropDownButton(Model.of("Themes")) {
+        var dropdown = new NavbarDropDownButton(Model.of("Themes")) {
 
             @Override
             public boolean isActive(Component item) {
@@ -61,13 +62,12 @@ protected List<AbstractLink> newSubMenuButtons(final String buttonMarkupId) {
                 subMenu.add(new MenuHeader(Model.of("all available themes:")));
                 subMenu.add(new MenuDivider());
 
-                final IBootstrapSettings settings = Bootstrap.getSettings(getApplication());
-                final List<ITheme> themes = settings.getThemeProvider().available();
+                var settings = Bootstrap.getSettings(getApplication());
+                var themes = settings.getThemeProvider().available();
 
                 for (final ITheme theme : themes) {
-                    PageParameters params = new PageParameters();
+                    var params = new PageParameters();
                     params.set("theme", theme.name());
-
                     subMenu.add(new MenuBookmarkablePageLink<Void>(getPageClass(), params, Model.of(theme.name())));
                 }
 
@@ -80,10 +80,10 @@ protected List<AbstractLink> newSubMenuButtons(final String buttonMarkupId) {
     }
 
     private void configureTheme(PageParameters pageParameters) {
-        StringValue theme = pageParameters.get("theme");
+        var theme = pageParameters.get("theme");
 
         if (!theme.isEmpty()) {
-            IBootstrapSettings settings = Bootstrap.getSettings(getApplication());
+            var settings = Bootstrap.getSettings(getApplication());
             settings.getActiveThemeProvider().setActiveTheme(theme.toString(""));
         }
     }
@@ -99,7 +99,7 @@ protected boolean hasNavigation() {
     }
 
     private Component newNavigation(String markupId) {
-        WebMarkupContainer navigation = new WebMarkupContainer(markupId);
+        var navigation = new WebMarkupContainer(markupId);
         navigation.setVisible(hasNavigation());
         return navigation;
     }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BasePage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BasePage.java
index b7da8651..caf7ac61 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BasePage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/BasePage.java
@@ -1,6 +1,6 @@
 package com.giffing.wicket.spring.boot.example.web.pages;
 
-import com.giffing.wicket.spring.boot.example.web.assets.base.FixBootstrapStylesCssResourceReference;
+import com.giffing.wicket.spring.boot.example.web.assets.base.CustomStylesCssRessourceReference;
 import com.giffing.wicket.spring.boot.example.web.general.notify.NotyJSReference;
 import com.giffing.wicket.spring.boot.example.web.general.notify.NotyPackagedJSReference;
 import com.giffing.wicket.spring.boot.example.web.general.notify.NotyThemeBootstrapJSReference;
@@ -35,7 +35,6 @@ public BasePage(final PageParameters parameters) {
         defaultModal.setOutputMarkupId(true);
         queue(defaultModal);
 
-        //add(new HtmlTag("html", WebSession.get().getLocale()));
         MobileViewportMetaTag mvt = new MobileViewportMetaTag("viewport");
         mvt.setWidth("device-width");
         mvt.setInitialScale("1");
@@ -51,7 +50,7 @@ public BasePage(final PageParameters parameters) {
     public void renderHead(IHeaderResponse response) {
         super.renderHead(response);
 
-        response.render(CssHeaderItem.forReference(FixBootstrapStylesCssResourceReference.INSTANCE));
+        response.render(CssHeaderItem.forReference(CustomStylesCssRessourceReference.INSTANCE));
         response.render(CssHeaderItem.forReference(FontAwesome6CssReference.instance()));
         response.render(JavaScriptHeaderItem.forReference(NotyJSReference.INSTANCE));
         response.render(JavaScriptHeaderItem.forReference(NotyPackagedJSReference.INSTANCE));
@@ -62,10 +61,6 @@ public void renderHead(IHeaderResponse response) {
         }
     }
 
-    public MarkupContainer getDefaultModal() {
-        return defaultModal;
-    }
-
     public void replaceDefaultModal(MarkupContainer newModal, AjaxRequestTarget target) {
         newModal.setMarkupId(defaultModal.getMarkupId());
         newModal.setOutputMarkupId(true);
@@ -74,12 +69,11 @@ public void replaceDefaultModal(MarkupContainer newModal, AjaxRequestTarget targ
         defaultModal = newModal;
     }
 
-    protected FormGroup queueFormComponent(FormComponent formComponent) {
+    protected void queueFormComponent(FormComponent<?> formComponent) {
         var formGroup = new FormGroup(formComponent.getId() + "Border");
         formGroup.useFormComponentLabel(true);
         formGroup.add(formComponent);
         queue(formGroup);
-        return formGroup;
     }
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerListPage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerListPage.java
index 0757f56e..8c21a621 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerListPage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerListPage.java
@@ -4,6 +4,7 @@
 import java.util.List;
 
 import com.giffing.wicket.spring.boot.context.scan.WicketHomePage;
+import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstrractActionItem;
 import com.giffing.wicket.spring.boot.example.web.pages.BaseAuthenticatedPage;
 import com.giffing.wicket.spring.boot.example.web.pages.customers.events.CustomerDeletedEvent;
 import com.giffing.wicket.spring.boot.starter.web.servlet.websocket.WebSocketMessageBroadcaster;
@@ -45,10 +46,8 @@
 import com.giffing.wicket.spring.boot.example.repository.services.customer.filter.CustomerFilter;
 import com.giffing.wicket.spring.boot.example.repository.services.customer.filter.CustomerSort;
 import com.giffing.wicket.spring.boot.example.web.general.action.panel.ActionPanel;
-import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.AbstrractActionItem;
 import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.links.ActionItemLink;
 import com.giffing.wicket.spring.boot.example.web.general.action.panel.items.yesno.YesNoLink;
-import com.giffing.wicket.spring.boot.example.web.general.icons.IconType;
 import com.giffing.wicket.spring.boot.example.web.html.basic.YesNoLabel;
 import com.giffing.wicket.spring.boot.example.web.html.form.ValidationForm;
 import com.giffing.wicket.spring.boot.example.web.html.panel.FeedbackPanel;
@@ -83,21 +82,7 @@ public CustomerListPage() {
 		feedbackPanel.setOutputMarkupId(true);
 		add(feedbackPanel);
 		
-		add(new WebSocketBehavior() {
-
-			@Override
-			protected void onPush(WebSocketRequestHandler handler, IWebSocketPushMessage message) {
-				if (message instanceof CustomerChangedEvent event) {
-					info("Customer changed " + event.getCustomer().getFirstname() + " " + event.getCustomer().getLastname());
-					handler.add(feedbackPanel);
-				}
-				if (message instanceof CustomerDeletedEvent event) {
-					warn("Customer deleted: " + event.getCustomer().getFirstname() + " " + event.getCustomer().getLastname());
-					handler.add(feedbackPanel);
-				}
-			}
-
-		});
+		add(getWebSocketBehavior(feedbackPanel));
 		
 		customerFilterModel = new CompoundPropertyModel<>(new CustomerFilter());
 		CustomerDataProvider customerDataProvider = new CustomerDataProvider(customerFilterModel);
@@ -118,6 +103,24 @@ protected void onPush(WebSocketRequestHandler handler, IWebSocketPushMessage mes
 
 	}
 
+	private WebSocketBehavior getWebSocketBehavior(FeedbackPanel feedbackPanel) {
+		return new WebSocketBehavior() {
+
+			@Override
+			protected void onPush(WebSocketRequestHandler handler, IWebSocketPushMessage message) {
+				if (message instanceof CustomerChangedEvent event) {
+					info("Customer changed " + event.getCustomer().getFirstname() + " " + event.getCustomer().getLastname());
+					handler.add(feedbackPanel);
+				}
+				if (message instanceof CustomerDeletedEvent event) {
+					warn("Customer deleted: " + event.getCustomer().getFirstname() + " " + event.getCustomer().getLastname());
+					handler.add(feedbackPanel);
+				}
+			}
+
+		};
+	}
+
 	private Button cancelButton() {
 		Button cancelButton = new Button("cancel") {
 
@@ -146,7 +149,7 @@ private void customerDataTable(CustomerDataProvider customerDataProvider) {
 		columns.add(activeColumn());
 		columns.add(actionColumn());
 
-		dataTable = new AjaxFallbackDefaultDataTable<Customer, CustomerSort>("table", columns,
+		dataTable = new AjaxFallbackDefaultDataTable<>("table", columns,
 				customerDataProvider, 10);
 		dataTable.setOutputMarkupId(true);
 		FilterToolbar filterToolbar = new FilterToolbar(dataTable, filterForm);
@@ -161,112 +164,119 @@ private PropertyColumn<Customer, CustomerSort> idColumn() {
 	}
 	
 	private FilteredPropertyColumn<Customer, CustomerSort> usernameColumn() {
-		return new FilteredPropertyColumn<Customer, CustomerSort>(new ResourceModel("username"), CustomerSort.USERNAME,
-				CustomerSort.USERNAME.getFieldName()) {
+		return new FilteredPropertyColumn<>(new ResourceModel("username"), CustomerSort.USERNAME,
+                CustomerSort.USERNAME.getFieldName()) {
 
-			@Override
-			public Component getFilter(String componentId, FilterForm<?> form) {
-				return new AbstractTextFieldFilter<String>(componentId,
-						new PropertyModel<>(form.getModel(), "usernameLike"), form) {
+            @Override
+            public Component getFilter(String componentId, FilterForm<?> form) {
+                return new AbstractTextFieldFilter<String>(componentId,
+                        new PropertyModel<>(form.getModel(), "usernameLike"), form) {
 
-					@Override
-					public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
-						return new UsernameSearchTextField(componentId, model);
-					}
+                    @Override
+                    public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
+                        return new UsernameSearchTextField(componentId, model);
+                    }
 
-				};
-			}
+                };
+            }
 
-		};
+        };
 	}
 	
 	private FilteredPropertyColumn<Customer, CustomerSort> firstnameColumn() {
-		return new FilteredPropertyColumn<Customer, CustomerSort>(new ResourceModel("firstname"),
-				CustomerSort.FIRSTNAME, CustomerSort.FIRSTNAME.getFieldName()) {
+		return new FilteredPropertyColumn<>(new ResourceModel("firstname"),
+                CustomerSort.FIRSTNAME, CustomerSort.FIRSTNAME.getFieldName()) {
 
-			@Override
-			public Component getFilter(String componentId, FilterForm<?> form) {
-				return new AbstractTextFieldFilter<String>(componentId,
-						new PropertyModel<>(form.getModel(), "firstnameLike"), form) {
+            @Override
+            public Component getFilter(String componentId, FilterForm<?> form) {
+                return new AbstractTextFieldFilter<String>(componentId,
+                        new PropertyModel<>(form.getModel(), "firstnameLike"), form) {
 
-					@Override
-					public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
-						return new TextField<>(componentId, model);
-					}
+                    @Override
+                    public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
+                        return new TextField<>(componentId, model);
+                    }
 
-				};
-			}
+                };
+            }
 
-		};
+        };
 	}
 	
 	private FilteredPropertyColumn<Customer, CustomerSort> lastnameColumn() {
-		return new FilteredPropertyColumn<Customer, CustomerSort>(new ResourceModel("lastname"), CustomerSort.LASTNAME,
-				CustomerSort.LASTNAME.getFieldName()) {
+		return new FilteredPropertyColumn<>(new ResourceModel("lastname"), CustomerSort.LASTNAME,
+                CustomerSort.LASTNAME.getFieldName()) {
 
-			@Override
-			public Component getFilter(String componentId, FilterForm<?> form) {
-				return new AbstractTextFieldFilter<String>(componentId,
-						new PropertyModel<>(form.getModel(), "lastnameLike"), form) {
+            @Override
+            public Component getFilter(String componentId, FilterForm<?> form) {
+                return new AbstractTextFieldFilter<String>(componentId,
+                        new PropertyModel<>(form.getModel(), "lastnameLike"), form) {
 
-					@Override
-					public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
-						return new TextField<>(componentId, model);
-					}
+                    @Override
+                    public TextField<String> createTextFieldComponent(String componentId, IModel<String> model) {
+                        return new TextField<>(componentId, model);
+                    }
 
-				};
-			}
+                };
+            }
 
-		};
+        };
 	}
 
 	private FilteredPropertyColumn<Customer, CustomerSort> activeColumn() {
-		return new FilteredPropertyColumn<Customer, CustomerSort>(new ResourceModel("active"), CustomerSort.ACTIVE,
-				CustomerSort.ACTIVE.getFieldName()) {
+		return new FilteredPropertyColumn<>(new ResourceModel("active"), CustomerSort.ACTIVE,
+                CustomerSort.ACTIVE.getFieldName()) {
 
-			@Override
-			public Component getFilter(String componentId, FilterForm<?> form) {
-				return new AbstractCheckBoxFilter(componentId, new PropertyModel<>(form.getModel(), "active"), form);
-			}
+            @Override
+            public Component getFilter(String componentId, FilterForm<?> form) {
+                return new AbstractCheckBoxFilter(componentId, new PropertyModel<>(form.getModel(), "active"), form);
+            }
 
-			@Override
-			public void populateItem(Item<ICellPopulator<Customer>> item, String componentId,
-					IModel<Customer> rowModel) {
-				item.add(new YesNoLabel(componentId, (IModel<Boolean>) getDataModel(rowModel)));
-			}
+            @Override
+            public void populateItem(Item<ICellPopulator<Customer>> item, String componentId,
+                                     IModel<Customer> rowModel) {
+                item.add(new YesNoLabel(componentId, (IModel<Boolean>) getDataModel(rowModel)));
+            }
 
-		};
+        };
 	}
 	
 	private AbstractColumn<Customer, CustomerSort> actionColumn() {
-		return new AbstractColumn<Customer, CustomerSort>(Model.of("Action")) {
-
-			@Override
-			public void populateItem(Item<ICellPopulator<Customer>> cellItem, String componentId,
-					IModel<Customer> rowModel) {
-				List<AbstrractActionItem> abstractItems = new ArrayList<>();
-				
-				PageParameters params = new PageParameters();
-				params.add(CustomerEditPage.CUSTOMER_ID_PARAM, rowModel.getObject().getId());
-				params.add(CustomerEditPage.PAGE_REFERENCE_ID, getPageId());
-				abstractItems.add(new ActionItemLink(Model.of("edit"), IconType.EDIT,
-						new BookmarkablePageLink<Customer>("link", CustomerEditPage.class, params )));
-				
-				abstractItems.add(new YesNoLink<String>(Model.of("xx"), IconType.DELETE) {
-
-					@Override
-					protected void yesClicked(AjaxRequestTarget target) {
-						customerRepositoryService.delete(rowModel.getObject().getId());
-						webSocketMessageBroadcaster.sendToAll(new CustomerDeletedEvent(rowModel.getObject()));
-						target.add(dataTable);
-					}
-				});
-				
-				ActionPanel actionPanel = new ActionPanel(componentId, abstractItems);
-				cellItem.add(actionPanel);
-
-			}
-		};
+		return new AbstractColumn<>(Model.of("Action")) {
+
+            @Override
+            public void populateItem(Item<ICellPopulator<Customer>> cellItem, String componentId,
+                                     IModel<Customer> rowModel) {
+                List<AbstrractActionItem> abstractItems = new ArrayList<>();
+                var params = new PageParameters();
+                params.add(CustomerEditPage.CUSTOMER_ID_PARAM, rowModel.getObject().getId());
+                params.add(CustomerEditPage.PAGE_REFERENCE_ID, getPageId());
+
+                abstractItems.add(editActionItem(params));
+                abstractItems.add(deleteActionItem(rowModel));
+                cellItem.add(new ActionPanel(componentId, abstractItems));
+            }
+
+            private static ActionItemLink editActionItem(PageParameters params) {
+                return new ActionItemLink(
+                        Model.of("edit"),
+                        FontAwesome6IconType.pen_s,
+                        new BookmarkablePageLink<Customer>("link", CustomerEditPage.class, params)
+                );
+            }
+
+            private YesNoLink<Object> deleteActionItem(IModel<Customer> rowModel) {
+                return new YesNoLink<>(FontAwesome6IconType.trash_s) {
+
+                    @Override
+                    protected void yesClicked(AjaxRequestTarget target) {
+                        customerRepositoryService.delete(rowModel.getObject().getId());
+                        webSocketMessageBroadcaster.sendToAll(new CustomerDeletedEvent(rowModel.getObject()));
+                        target.add(dataTable);
+                    }
+                };
+            }
+        };
 	}
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerResource.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerResource.java
deleted file mode 100644
index 8eed0034..00000000
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerResource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.giffing.wicket.spring.boot.example.web.pages.customers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.wicketstuff.rest.annotations.MethodMapping;
-import org.wicketstuff.rest.annotations.ResourcePath;
-import org.wicketstuff.rest.contenthandling.json.objserialdeserial.JacksonObjectSerialDeserial;
-import org.wicketstuff.rest.contenthandling.json.webserialdeserial.JsonWebSerialDeserial;
-import org.wicketstuff.rest.resource.AbstractRestResource;
-
-import com.giffing.wicket.spring.boot.example.model.Customer;
-import com.giffing.wicket.spring.boot.example.repository.services.customer.CustomerRepositoryService;
-
-/**
- * TODO how to inject spring beans - {@link CustomerRepositoryService}...
- * 
- * @author Marc Giffing
- *
- */
-@ResourcePath("/rest")
-public class CustomerResource extends AbstractRestResource<JsonWebSerialDeserial>  {
-
-
-	public CustomerResource() {
-		super(new JsonWebSerialDeserial(new JacksonObjectSerialDeserial()));
-	}
-
-	
-	@MethodMapping("/customers")
-    public List<Customer> getAllCustomers() {
-		List<Customer> customers = new ArrayList<>();
-		Customer c = new Customer();
-		c.setId(1L);
-		c.setFirstname("firstname");
-		c.setLastname("lastname");
-		c.setUsername("username");
-		customers.add(c);
-		return customers;
-    }
-	
-}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/create/CustomerCreatePage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/create/CustomerCreatePage.java
index 085db326..616cbbf0 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/create/CustomerCreatePage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/create/CustomerCreatePage.java
@@ -8,8 +8,11 @@
 import com.giffing.wicket.spring.boot.example.web.pages.customers.events.CustomerChangedEvent;
 import com.giffing.wicket.spring.boot.example.web.pages.customers.model.UsernameTextField;
 import com.giffing.wicket.spring.boot.starter.web.servlet.websocket.WebSocketMessageBroadcaster;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.wicket.Component;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
 import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.CheckBox;
 import org.apache.wicket.markup.html.form.FormComponent;
@@ -20,6 +23,7 @@
 import org.wicketstuff.annotation.mount.MountPath;
 
 @MountPath("customers/create")
+@AuthorizeInstantiation("USER")
 public class CustomerCreatePage extends BaseAuthenticatedPage {
 
 	@SpringBean
@@ -28,8 +32,10 @@ public class CustomerCreatePage extends BaseAuthenticatedPage {
 	@SpringBean
 	private WebSocketMessageBroadcaster webSocketMessageBroadcaster;
 
-	CompoundPropertyModel<Customer> customerModel;
+	@Getter
+    CompoundPropertyModel<Customer> customerModel;
 
+	@Setter
 	private Integer pageReferenceId;
 
 	public CustomerCreatePage(Integer pageId){
@@ -68,7 +74,7 @@ private Component submitButton() {
 		return new Button("submit"){
 			@Override
 			public void onSubmit() {
-				Customer customer = customerModel.getObject();
+				var customer = customerModel.getObject();
 				service.save(customer);
 				webSocketMessageBroadcaster.sendToAll(new CustomerChangedEvent(customer));
 				if(pageReferenceId != null){
@@ -97,16 +103,4 @@ public void onSubmit() {
 		return cancelButton;
 	}
 
-	public CompoundPropertyModel<Customer> getCustomerModel() {
-		return customerModel;
-	}
-
-	public Integer getPageReferenceId() {
-		return pageReferenceId;
-	}
-
-	public void setPageReferenceId(Integer pageReferenceId) {
-		this.pageReferenceId = pageReferenceId;
-	}
-
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/edit/CustomerEditPage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/edit/CustomerEditPage.java
index f10cbd12..a3e3fd82 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/edit/CustomerEditPage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/edit/CustomerEditPage.java
@@ -3,6 +3,7 @@
 import java.text.MessageFormat;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.string.StringValue;
@@ -14,6 +15,7 @@
 import com.giffing.wicket.spring.boot.example.web.pages.customers.create.CustomerCreatePage;
 
 @MountPath("customers/edit/${" + CustomerEditPage.CUSTOMER_ID_PARAM + "}")
+@AuthorizeInstantiation("USER")
 public class CustomerEditPage extends CustomerCreatePage {
 	
 	public static final String CUSTOMER_ID_PARAM = "id";
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerChangedEvent.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerChangedEvent.java
index a20dd992..b7c7937c 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerChangedEvent.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerChangedEvent.java
@@ -1,23 +1,17 @@
 package com.giffing.wicket.spring.boot.example.web.pages.customers.events;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
 
 import com.giffing.wicket.spring.boot.example.model.Customer;
 
+@Getter
+@RequiredArgsConstructor
 public class CustomerChangedEvent implements IWebSocketPushMessage {
 
-	private Customer customer;
-
-	public CustomerChangedEvent(Customer customer) {
-		this.setCustomer(customer);
-	}
-
-	public Customer getCustomer() {
-		return customer;
-	}
-
-	public void setCustomer(Customer customer) {
-		this.customer = customer;
-	}
+	private final Customer customer;
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerDeletedEvent.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerDeletedEvent.java
index b40e835d..939eca54 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerDeletedEvent.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/events/CustomerDeletedEvent.java
@@ -1,22 +1,16 @@
 package com.giffing.wicket.spring.boot.example.web.pages.customers.events;
 
 import com.giffing.wicket.spring.boot.example.model.Customer;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
 
+@Getter
+@RequiredArgsConstructor
 public class CustomerDeletedEvent implements IWebSocketPushMessage {
 
-	private Customer customer;
-
-	public CustomerDeletedEvent(Customer customer) {
-		this.setCustomer(customer);
-	}
-
-	public Customer getCustomer() {
-		return customer;
-	}
-
-	public void setCustomer(Customer customer) {
-		this.customer = customer;
-	}
+	private final Customer customer;
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/CustomerDataProvider.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/CustomerDataProvider.java
index 45326aa1..809ed7d3 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/CustomerDataProvider.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/CustomerDataProvider.java
@@ -1,7 +1,8 @@
 package com.giffing.wicket.spring.boot.example.web.pages.customers.model;
 
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.wicket.injection.Injector;
-import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
@@ -11,27 +12,19 @@
 import com.giffing.wicket.spring.boot.example.repository.services.customer.filter.CustomerSort;
 import com.giffing.wicket.spring.boot.example.web.wicket.dataprovider.DefaultDataProvider;
 
+@Getter
+@Setter
 public class CustomerDataProvider extends DefaultDataProvider<Customer, Long, CustomerFilter, CustomerSort, CustomerRepositoryService>{
 	
 	@SpringBean
-	private CustomerRepositoryService customerRepositoryService;
+	private CustomerRepositoryService filterService;
 	
 	private IModel<CustomerFilter> customerFilterModel;
 
-	public CustomerDataProvider(){
-		customerFilterModel = new CompoundPropertyModel<>(new CustomerFilter());
-		Injector.get().inject(this);
-	}
-	
 	public CustomerDataProvider(IModel<CustomerFilter> customerFilterModel){
 		this.customerFilterModel = customerFilterModel;
 		Injector.get().inject(this);
 	}
-	
-	@Override
-	public CustomerRepositoryService getFilterService() {
-		return customerRepositoryService;
-	}
 
 	@Override
 	public CustomerFilter getFilter() {
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/UsernameSearchTextField.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/UsernameSearchTextField.java
index e0ca793a..bf77dd59 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/UsernameSearchTextField.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/model/UsernameSearchTextField.java
@@ -13,8 +13,8 @@
 import com.giffing.wicket.spring.boot.example.web.html.autocomplete.AutoCompleteTextField;
 
 public class UsernameSearchTextField extends AutoCompleteTextField {
-	
-	private final static Integer MINIMUM_INPUT_LENGTH = 3;
+
+	private static final Integer MINIMUM_INPUT_LENGTH = 3;
 	
 	@SpringBean
 	private CustomerRepositoryService service;
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/login/LoginPage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/login/LoginPage.java
index 64b0eed2..1f1f32c2 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/login/LoginPage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/login/LoginPage.java
@@ -1,5 +1,6 @@
 package com.giffing.wicket.spring.boot.example.web.pages.login;
 
+import com.giffing.wicket.spring.boot.example.web.html.form.focus.FocusBehaviour;
 import com.giffing.wicket.spring.boot.example.web.pages.BasePage;
 import com.giffing.wicket.spring.boot.example.web.pages.customers.CustomerListPage;
 import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
@@ -29,6 +30,7 @@ public LoginPage(PageParameters parameters) {
 
 		if (((AbstractAuthenticatedWebSession) getSession()).isSignedIn()) {
 			continueToOriginalDestination();
+			setResponsePage(CustomerListPage.class);
 		}
 		add(new LoginForm("loginForm"));
 	}
@@ -43,10 +45,18 @@ public LoginForm(String id) {
 			super(id);
 			setModel(new CompoundPropertyModel<>(this));
 			add(new FeedbackPanel("feedback"));
-			queueFormComponent(new RequiredTextField<String>("username"));
+
+			queueFormComponent(usernameField());
 			queueFormComponent(new PasswordTextField("password"));
 		}
 
+		private RequiredTextField<String> usernameField() {
+			var usernameField = new RequiredTextField<String>("username");
+			usernameField.setOutputMarkupId(true);
+			usernameField.add(new FocusBehaviour());
+			return usernameField;
+		}
+
 		@Override
 		protected void onSubmit() {
 			AuthenticatedWebSession session = AuthenticatedWebSession.get();
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatPage.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatPage.java
index 7e60e9bd..821aa0f0 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatPage.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatPage.java
@@ -7,10 +7,12 @@
 import com.giffing.wicket.spring.boot.example.web.pages.websocket.events.LeftChatEvent;
 import com.giffing.wicket.spring.boot.starter.web.servlet.websocket.WebSocketMessageBroadcaster;
 import de.agilecoders.wicket.jquery.JQuery;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
-import org.apache.wicket.markup.head.CssReferenceHeaderItem;
+import org.apache.wicket.markup.head.CssHeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
@@ -35,7 +37,6 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.UUID;
-import java.util.stream.Collectors;
 
 @MountPath("chat")
 @AuthorizeInstantiation("USER")
@@ -50,32 +51,28 @@ public class ChatPage extends BaseAuthenticatedPage {
     private WebMarkupContainer chatMessageContainer;
     private ListView<ChatMessage> messages;
 
-    RequiredTextField<String> messageInput;
+    private RequiredTextField<String> messageInput;
 
-    private DropDownChoice participantChoice;
+    private DropDownChoice<String> participantChoice;
 
     public ChatPage(PageParameters pageParameters) {
         super(pageParameters);
-        FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
-        feedbackPanel.setOutputMarkupId(true);
-        add(feedbackPanel);
+        add(new FeedbackPanel("feedback").setOutputMarkupId(true));
+        addWebsocketBehaviour();
         addChatForm();
-        addWebsocketBehaviour(feedbackPanel);
     }
 
     private void addChatForm() {
         IModel<String> to = Model.of("");
         IModel<String> message = Model.of("");
-        Form form = null;
-        add(form = new Form<>("form"));
-        form.add(participantChoice = new DropDownChoice<>("participants", to, () -> chatService
-                .getParticipants()
-                .stream().collect(Collectors.toList())));
+
+        var form = new Form<Void>("form");
+
+        participantChoice = new DropDownChoice<>("participants", to, () -> chatService.getParticipants().stream().toList());
         participantChoice.setOutputMarkupId(true);
+
         messageInput = new RequiredTextField<>("message", message);
         messageInput.setOutputMarkupId(true);
-
-        form.add(messageInput);
         AjaxButton submitButton = new AjaxButton("submit") {
 
             @Override
@@ -88,7 +85,7 @@ protected void onSubmit(AjaxRequestTarget target) {
 
         };
         form.setDefaultButton(submitButton);
-        form.add(submitButton);
+
 
         messages = new ListView<>("messages", new ArrayList<>()) {
 
@@ -101,15 +98,22 @@ protected void populateItem(ListItem<ChatMessage> item) {
             }
         };
         messages.setOutputMarkupId(true);
-        form.add(chatMessageContainer = new WebMarkupContainer("chatMessageContainer"));
+
+        chatMessageContainer = new WebMarkupContainer("chatMessageContainer");
         chatMessageContainer.setOutputMarkupId(true);
         chatMessageContainer.add(messages);
+
+        add(form);
+        form.add(submitButton);
+        form.add(participantChoice);
+        form.add(messageInput);
+        form.add(chatMessageContainer);
     }
 
-    private void addWebsocketBehaviour(FeedbackPanel feedbackPanel) {
-        String currentUsername = SecurityContextHolder.getContext().getAuthentication().getName();
-        String browserTabIdentifier = UUID.randomUUID().toString();
-        ChatParticipant chatParticipant = new ChatParticipant(browserTabIdentifier, currentUsername);
+    private void addWebsocketBehaviour() {
+        var currentUsername = SecurityContextHolder.getContext().getAuthentication().getName();
+        var browserTabIdentifier = UUID.randomUUID().toString();
+        var chatParticipant = new ChatParticipant(browserTabIdentifier, currentUsername);
         add(new WebSocketBehavior() {
 
             @Override
@@ -119,14 +123,14 @@ protected void onPush(WebSocketRequestHandler handler, IWebSocketPushMessage mes
                     handler.add(chatMessageContainer);
                 }
                 if (message instanceof JoinChatEvent event) {
-                    String notifyStatus = "success";
-                    String notifyMessage = event.getUsername() + " joined the chat";
+                    var notifyStatus = "success";
+                    var notifyMessage = "%s joined the chat".formatted(event.getUsername());
                     addNotifyMessage(handler, notifyStatus, notifyMessage);
                     handler.add(participantChoice);
                 }
                 if (message instanceof LeftChatEvent event) {
                     String notifyStatus = "warning";
-                    String notifyMessage = event.getUsername() + " left the chat";
+                    String notifyMessage = "%s left the chat".formatted(event.getUsername());
                     addNotifyMessage(handler, notifyStatus, notifyMessage);
                     handler.add(participantChoice);
                 }
@@ -134,14 +138,16 @@ protected void onPush(WebSocketRequestHandler handler, IWebSocketPushMessage mes
 
             private void addNotifyMessage(WebSocketRequestHandler handler, String notifyStatus, String notifyMessage) {
                 handler.appendJavaScript(JQuery
-                        .plain("noty({text: '" + notifyMessage + "', type: '" + notifyStatus
-                                + "', timeout: '5000', progressbar: true});"));
+                        .plain("noty({text: '%s', type: '%s', timeout: '5000', progressbar: true});"
+                                .formatted(notifyMessage, notifyStatus)));
             }
 
+            @Override
             protected void onConnect(ConnectedMessage message) {
                 chatService.join(chatParticipant);
             }
 
+            @Override
             protected void onClose(ClosedMessage message) {
                 chatService.leave(chatParticipant);
             }
@@ -149,29 +155,17 @@ protected void onClose(ClosedMessage message) {
         });
     }
 
+    @Getter
+    @RequiredArgsConstructor
     private static class ChatMessage implements Serializable {
         private final String from;
         private final String message;
-
-        public ChatMessage(String from, String message) {
-            this.from = from;
-            this.message = message;
-        }
-
-        public String getFrom() {
-            return from;
-        }
-
-        public String getMessage() {
-            return message;
-        }
-
-
     }
 
+    @Override
     public void renderHead(IHeaderResponse response) {
         super.renderHead(response);
-        response.render(CssReferenceHeaderItem.forReference(new PackageResourceReference(ChatPage.class, "ChatPage.css")));
+        response.render(CssHeaderItem.forReference(new PackageResourceReference(ChatPage.class, "ChatPage.css")));
     }
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatParticipant.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatParticipant.java
index 032ae7f1..a20ba100 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatParticipant.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatParticipant.java
@@ -1,5 +1,8 @@
 package com.giffing.wicket.spring.boot.example.web.pages.websocket;
 
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+
 import java.io.Serializable;
 
 /**
@@ -9,67 +12,16 @@
  * @author Marc Giffing
  *
  */
+@Data
+@RequiredArgsConstructor
 public class ChatParticipant implements Serializable {
 
-	private String username;
+	private final String username;
 
 	/**
 	 * The user can login to multiple browsers and tabs
 	 * This identifier is used to identify a single browser tab.
 	 */
-	private String browserTabIdentifier;
-	
-	public ChatParticipant(String browserTabIdentifier, String username) {
-		this.browserTabIdentifier = browserTabIdentifier;
-		this.username = username;
-	}
-
-	public String getBrowserTabIdentifier() {
-		return browserTabIdentifier;
-	}
-
-	public void setBrowserTabIdentifier(String browserTabIdentifier) {
-		this.browserTabIdentifier = browserTabIdentifier;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((browserTabIdentifier == null) ? 0 : browserTabIdentifier.hashCode());
-		result = prime * result + ((username == null) ? 0 : username.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		ChatParticipant other = (ChatParticipant) obj;
-		if (browserTabIdentifier == null) {
-			if (other.browserTabIdentifier != null)
-				return false;
-		} else if (!browserTabIdentifier.equals(other.browserTabIdentifier))
-			return false;
-		if (username == null) {
-			if (other.username != null)
-				return false;
-		} else if (!username.equals(other.username))
-			return false;
-		return true;
-	}
+	private final String browserTabIdentifier;
 
-	
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatService.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatService.java
index 1e290bea..f60a0536 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatService.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/ChatService.java
@@ -29,7 +29,7 @@ public ChatService(WebSocketMessageBroadcaster broadcaster) {
 	public Set<String> getParticipants() {
 		return participants
 				.stream()
-				.map(p -> p.getUsername())
+				.map(ChatParticipant::getUsername)
 				.collect(Collectors.toSet());
 	}
 	
@@ -38,7 +38,7 @@ public void join(ChatParticipant chatParticipant) {
 		List<ChatParticipant> existingUserSpecificParticipants = participants
 				.stream()
 				.filter(p -> p.getUsername().equalsIgnoreCase(chatParticipant.getUsername()))
-				.collect(Collectors.toList());
+				.toList();
 		participants.add(chatParticipant);
 		if(existingUserSpecificParticipants.isEmpty()) {
 			broadcaster.sendToAll(new JoinChatEvent(username));
@@ -51,13 +51,12 @@ public void leave(ChatParticipant chatParticipant) {
 			.stream()
 			.filter(p -> p.getBrowserTabIdentifier().equals(chatParticipant.getBrowserTabIdentifier()))
 			.findAny();
-		if(chatParticipateToDelete.isPresent()) {
-			participants.remove(chatParticipateToDelete.get());
-		}
+        chatParticipateToDelete.ifPresent(participant -> participants.remove(participant));
+
 		List<ChatParticipant> remainingUserSpecificParticipants = participants
 			.stream()
 			.filter(p -> p.getUsername().equalsIgnoreCase(chatParticipant.getUsername()))
-			.collect(Collectors.toList());
+			.toList();
 		if(remainingUserSpecificParticipants.isEmpty()) {
 			broadcaster.sendToAll(new LeftChatEvent(username));
 		}
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/CustomerMessageEvent.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/CustomerMessageEvent.java
index c07e3d44..a641d1bd 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/CustomerMessageEvent.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/CustomerMessageEvent.java
@@ -1,29 +1,19 @@
 package com.giffing.wicket.spring.boot.example.web.pages.websocket.events;
 
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
 
 /**
  * Used to send a message to a specific user
  */
+@Getter
+@RequiredArgsConstructor
 public class CustomerMessageEvent implements IWebSocketPushMessage {
 
-	private static final long serialVersionUID = 1L;
-
 	private final String sender;
 
 	private final String message;
 
-	public CustomerMessageEvent(String sender, String message) {
-		this.sender = sender;
-		this.message = message;
-	}
-
-	public String getMessage() {
-		return message;
-	}
-
-	public String getSender() {
-		return sender;
-	}
 
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/JoinChatEvent.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/JoinChatEvent.java
index c8791c2a..1a43f170 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/JoinChatEvent.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/JoinChatEvent.java
@@ -1,17 +1,13 @@
 package com.giffing.wicket.spring.boot.example.web.pages.websocket.events;
 
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
 
+@Getter
+@RequiredArgsConstructor
 public class JoinChatEvent implements IWebSocketPushMessage {
 
 	private final String username;
-	
-	public JoinChatEvent(String username) {
-		this.username = username;
-	}
 
-	public String getUsername() {
-		return username;
-	}
-	
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/LeftChatEvent.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/LeftChatEvent.java
index 30adcc83..b88e68d5 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/LeftChatEvent.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/websocket/events/LeftChatEvent.java
@@ -1,16 +1,13 @@
 package com.giffing.wicket.spring.boot.example.web.pages.websocket.events;
 
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
 
+@Getter
+@RequiredArgsConstructor
 public class LeftChatEvent implements IWebSocketPushMessage {
 
 	private final String username;
-	
-	public LeftChatEvent(String username) {
-		this.username = username;
-	}
 
-	public String getUsername() {
-		return username;
-	}
 }
diff --git a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/wicket/dataprovider/DefaultDataProvider.java b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/wicket/dataprovider/DefaultDataProvider.java
index 9ba2e361..98de541a 100644
--- a/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/wicket/dataprovider/DefaultDataProvider.java
+++ b/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/wicket/dataprovider/DefaultDataProvider.java
@@ -31,12 +31,8 @@ public abstract class DefaultDataProvider<MODEL extends Domain<ID>,
 	public abstract void setFilter(FILTER_MODEL filterModel);
 	
 	private SingleSortState<SORT> singleSortState = new SingleSortState<>();
-	
-	@Override
-	public void detach() {
-	}
 
-	@Override
+    @Override
 	public Iterator<? extends MODEL> iterator(long first, long count) {
 		if(singleSortState.getSort() != null){
 			Sort property = (Sort) singleSortState.getSort().getProperty();
@@ -45,8 +41,7 @@ public Iterator<? extends MODEL> iterator(long first, long count) {
 		}
 		//TODO quick and dirty check again 
 		long page = first / count;
-		List<MODEL> customers = getFilterService().findAll(page, count, this.getFilter());
-		return customers.iterator();
+		return getFilterService().findAll(page, count, this.getFilter()).iterator();
 	}
 
 	@Override
diff --git a/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/WicketBootStandardWebApplication.java b/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/WicketBootStandardWebApplication.java
index 1c3f3a48..a4ffd52d 100644
--- a/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/WicketBootStandardWebApplication.java
+++ b/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/WicketBootStandardWebApplication.java
@@ -87,7 +87,7 @@ public RuntimeConfigurationType getConfigurationType() {
 	@SuppressWarnings("unchecked")
 	@Override
 	public Class<? extends Page> getHomePage() {
-		if(classCandidates.getHomePageCandidates().size() <= 0){
+		if(classCandidates.getHomePageCandidates().isEmpty()){
 			throw new IllegalStateException("Couln't find home page - please annotate the home page with @" + WicketHomePage.class.getName());
 		}
 		if(classCandidates.getHomePageCandidates().size() > 1 ){
@@ -98,9 +98,8 @@ public Class<? extends Page> getHomePage() {
 			}
 			throw new IllegalStateException(message);
 		}
-		
-		Class<Page> next = classCandidates.getHomePageCandidates().iterator().next().getCandidate();
-		return next;
+
+		return classCandidates.getHomePageCandidates().iterator().next().getCandidate();
 	}
 
 	public ApplicationContext getApplicationContext() {
diff --git a/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/classscanner/ClassCandidateScanner.java b/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/classscanner/ClassCandidateScanner.java
index acb53e95..60a28b7e 100644
--- a/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/classscanner/ClassCandidateScanner.java
+++ b/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/app/classscanner/ClassCandidateScanner.java
@@ -77,23 +77,23 @@ public void postConstruct() {
 					}
 					if (beanClass.isAnnotationPresent(WicketHomePage.class)) {
 						classCandidates.getHomePageCandidates()
-								.add(new WicketClassCandidate<Page>((Class<Page>) beanClass));
+								.add(new WicketClassCandidate<>((Class<Page>) beanClass));
 					}
 					if (beanClass.isAnnotationPresent(WicketSignInPage.class)) {
 						classCandidates.getSignInPageCandidates()
-								.add(new WicketClassCandidate<WebPage>((Class<WebPage>) beanClass));
+								.add(new WicketClassCandidate<>((Class<WebPage>) beanClass));
 					}
 					if (beanClass.isAnnotationPresent(WicketAccessDeniedPage.class)) {
 						classCandidates.getAccessDeniedPageCandidates()
-								.add(new WicketClassCandidate<Page>((Class<Page>) beanClass));
+								.add(new WicketClassCandidate<>((Class<Page>) beanClass));
 					}
 					if (beanClass.isAnnotationPresent(WicketExpiredPage.class)) {
 						classCandidates.getExpiredPageCandidates()
-								.add(new WicketClassCandidate<Page>((Class<Page>) beanClass));
+								.add(new WicketClassCandidate<>((Class<Page>) beanClass));
 					}
 					if (beanClass.isAnnotationPresent(WicketInternalErrorPage.class)) {
 						classCandidates.getInternalErrorPageCandidates()
-								.add(new WicketClassCandidate<Page>((Class<Page>) beanClass));
+								.add(new WicketClassCandidate<>((Class<Page>) beanClass));
 					}
 					if (beanClass.isAnnotationPresent(SpringBootApplication.class)) {
 						classCandidates.setSpringBootMainClass(beanClass);