You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ju...@apache.org on 2020/02/24 16:52:42 UTC

[jspwiki] branch master updated (cf23ad6 -> b03d0b5)

This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git.


    from cf23ad6  2.11.0-M7-git-08
     new 52d21f1  JSPWIKI-120: add adapt( Class< E > cls ) method to Engine
     new 205b397  JSPWIKI-120: rename + extract interface from AttachmentManager
     new 6039095  inherit javadoc
     new ae99ac7  apply format and fixes suggested by intellij
     new 380de2a  JSPWIKI-120: rename + extract interface from AuthenticationManager
     new 3e3810d  add @SuppressWarnings annotation to E Engine#adapt( Class< E > )
     new 1cceed4  JSPWIKI-120: promote DefaultAuthenticationManager#findConfigFile( Engine, String ) to Engine#findConfigFile( String ) as default method
     new f14bedc  remove old references to AuthenticationManager on Engine
     new 2e4934a  JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead
     new 1860484  JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead
     new 05eec06  add initialize( Engine, Properties ) to AuthenticationManager
     new df5e6db  WikiEngine -> Engine
     new ae43c07  class javadocs
     new f1b62ab  JSPWIKI-120: rename + extract interface from AuthorizationManager
     new 11a0ada  JSPWIKI-120: rename + extract interface from UserManager
     new 79af4e4  use Engine instead of WikiEngine
     new dc5168f  translate WatchDog changes to JSPs
     new dbee4c2  Use Engine instead of WikiEngine in SecurityVerifier + Extract DummyUserDatabase to its own class
     new 4344cfb  use Engine instead of WikiEngine on WikiPage
     new d03a5c7  promote a couple of methods more from DefaultAuthorizationManager to AuthorizationManager
     new d3710e0  JSPWIKI-120: use Engine instead of WikiEngine on Attachment, SessionMonitor, WikiContext and WikiSession
     new 43bf182  JSPWIKI-120: WikiProvider#initialize receives an Engine instead of a WikiEngine
     new db20d0e  JSPWIKI-120: make callback handlers use Engine instead of WikiEngine
     new bbac3d4  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (1)
     new 5ea8be0  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (2)
     new 25f87fd  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (3)
     new ab518d9  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (4)
     new 1433993  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (5)
     new e9f724f  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (6)
     new 8d2e5ee  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (7)
     new 25c9ed0  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (8)
     new f44500b  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (9)
     new 2d9a75b  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (10)
     new de7c770  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (11)
     new 6d6b17c  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (12)
     new 869dc56  JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (and 13)
     new 999c443  JSPWIKI-120: rename + extract interface from GroupManager
     new b03d0b5  2.11.0-M7-git-09

The 38 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ChangeLog.md                                       |  19 +-
 .../src/main/java/org/apache/wiki/Release.java     |   2 +-
 .../src/main/java/org/apache/wiki/WatchDog.java    | 150 ++---
 .../java/org/apache/wiki/WikiBackgroundThread.java |  11 +-
 .../src/main/java/org/apache/wiki/WikiContext.java |  62 +-
 .../src/main/java/org/apache/wiki/WikiEngine.java  |  17 +-
 .../src/main/java/org/apache/wiki/WikiPage.java    |  93 ++-
 .../main/java/org/apache/wiki/WikiProvider.java    |  11 +-
 .../src/main/java/org/apache/wiki/WikiSession.java |  31 +-
 .../main/java/org/apache/wiki/api/core/Engine.java | 103 ++-
 .../java/org/apache/wiki/api/engine/package.html   |   2 +-
 .../org/apache/wiki/attachment/Attachment.java     |   9 +-
 .../apache/wiki/attachment/AttachmentManager.java  | 505 ++-------------
 .../apache/wiki/attachment/AttachmentServlet.java  |  60 +-
 .../wiki/attachment/DefaultAttachmentManager.java  | 348 ++++++++++
 .../apache/wiki/auth/AuthenticationManager.java    | 674 +++----------------
 .../org/apache/wiki/auth/AuthorizationManager.java | 660 ++++---------------
 .../main/java/org/apache/wiki/auth/Authorizer.java |  54 +-
 .../wiki/auth/DefaultAuthenticationManager.java    | 428 +++++++++++++
 .../wiki/auth/DefaultAuthorizationManager.java     | 392 ++++++++++++
 .../org/apache/wiki/auth/DefaultUserManager.java   | 482 ++++++++++++++
 .../org/apache/wiki/auth/SecurityVerifier.java     | 403 +++++-------
 .../java/org/apache/wiki/auth/SessionMonitor.java  |  73 +--
 .../java/org/apache/wiki/auth/UserManager.java     | 712 ++-------------------
 .../apache/wiki/auth/acl/DefaultAclManager.java    |  14 +-
 .../wiki/auth/authorize/DefaultGroupManager.java   | 398 ++++++++++++
 .../apache/wiki/auth/authorize/GroupDatabase.java  |   4 +-
 .../apache/wiki/auth/authorize/GroupManager.java   | 678 +++-----------------
 .../wiki/auth/authorize/JDBCGroupDatabase.java     | 118 ++--
 .../apache/wiki/auth/authorize/WebAuthorizer.java  |  20 +-
 .../auth/authorize/WebContainerAuthorizer.java     |  92 ++-
 .../wiki/auth/authorize/XMLGroupDatabase.java      |  35 +-
 .../login/CookieAuthenticationLoginModule.java     | 292 ++++-----
 .../auth/login/WebContainerCallbackHandler.java    |  50 +-
 .../wiki/auth/login/WikiCallbackHandler.java       |  78 +--
 .../apache/wiki/auth/login/WikiEngineCallback.java |  25 +-
 .../wiki/auth/user/AbstractUserDatabase.java       | 169 ++---
 .../apache/wiki/auth/user/DummyUserDatabase.java   | 135 ++++
 .../apache/wiki/auth/user/JDBCUserDatabase.java    | 143 ++---
 .../org/apache/wiki/auth/user/UserDatabase.java    | 172 ++---
 .../org/apache/wiki/auth/user/XMLUserDatabase.java | 287 ++++-----
 .../apache/wiki/content/DefaultPageRenamer.java    |  64 +-
 .../apache/wiki/diff/ContextualDiffProvider.java   |  19 +-
 .../apache/wiki/diff/DefaultDifferenceManager.java |   9 +-
 .../java/org/apache/wiki/diff/DiffProvider.java    |   8 +-
 .../org/apache/wiki/diff/ExternalDiffProvider.java |  10 +-
 .../apache/wiki/diff/TraditionalDiffProvider.java  |  18 +-
 .../apache/wiki/filters/PingWeblogsComFilter.java  |  11 +-
 .../java/org/apache/wiki/filters/SpamFilter.java   | 211 +++---
 .../java/org/apache/wiki/forms/FormOutput.java     |  56 +-
 .../org/apache/wiki/pages/DefaultPageManager.java  |  30 +-
 .../apache/wiki/parser/JSPWikiMarkupParser.java    | 259 ++++----
 .../apache/wiki/parser/LinkParsingOperations.java  |   5 +-
 .../java/org/apache/wiki/parser/MarkupParser.java  |   4 +-
 .../java/org/apache/wiki/parser/PluginContent.java |  15 +-
 .../org/apache/wiki/parser/VariableContent.java    |   9 +-
 .../apache/wiki/plugin/AbstractReferralPlugin.java |  91 ++-
 .../org/apache/wiki/plugin/BugReportHandler.java   |  11 +-
 .../main/java/org/apache/wiki/plugin/Groups.java   |  12 +-
 .../main/java/org/apache/wiki/plugin/IfPlugin.java |  18 +-
 .../main/java/org/apache/wiki/plugin/Image.java    |  44 +-
 .../java/org/apache/wiki/plugin/IndexPlugin.java   |  64 +-
 .../java/org/apache/wiki/plugin/InsertPage.java    |  46 +-
 .../org/apache/wiki/plugin/ListLocksPlugin.java    |  48 +-
 .../src/main/java/org/apache/wiki/plugin/Note.java |  25 +-
 .../org/apache/wiki/plugin/PageViewPlugin.java     | 109 ++--
 .../apache/wiki/plugin/RecentChangesPlugin.java    |  14 +-
 .../apache/wiki/plugin/ReferredPagesPlugin.java    |  15 +-
 .../apache/wiki/plugin/ReferringPagesPlugin.java   |  13 +-
 .../wiki/plugin/ReferringUndefinedPagesPlugin.java |  24 +-
 .../main/java/org/apache/wiki/plugin/Search.java   |  38 +-
 .../org/apache/wiki/plugin/SessionsPlugin.java     |  34 +-
 .../org/apache/wiki/plugin/TableOfContents.java    |  36 +-
 .../apache/wiki/plugin/UndefinedPagesPlugin.java   |   4 +-
 .../org/apache/wiki/plugin/UnusedPagesPlugin.java  |  55 +-
 .../apache/wiki/plugin/WeblogArchivePlugin.java    | 127 ++--
 .../org/apache/wiki/plugin/WeblogEntryPlugin.java  |  20 +-
 .../java/org/apache/wiki/plugin/WeblogPlugin.java  |  36 +-
 .../org/apache/wiki/preferences/Preferences.java   |  70 +-
 .../wiki/providers/AbstractFileProvider.java       | 412 +++++-------
 .../wiki/providers/BasicAttachmentProvider.java    | 469 +++++---------
 .../wiki/providers/CachingAttachmentProvider.java  |  80 ++-
 .../org/apache/wiki/providers/CachingProvider.java | 135 ++--
 .../apache/wiki/providers/FileSystemProvider.java  | 179 ++----
 .../wiki/providers/VersioningFileProvider.java     | 255 +++-----
 .../wiki/providers/WikiAttachmentProvider.java     | 107 ++--
 .../apache/wiki/providers/WikiPageProvider.java    |  61 +-
 .../wiki/references/DefaultReferenceManager.java   |  39 +-
 .../wiki/render/DefaultRenderingManager.java       |   6 +-
 .../org/apache/wiki/rpc/atom/AtomAPIServlet.java   |  87 +--
 .../main/java/org/apache/wiki/rss/AtomFeed.java    |  11 +-
 .../src/main/java/org/apache/wiki/rss/Feed.java    |  31 +-
 .../main/java/org/apache/wiki/rss/RSS10Feed.java   |  36 +-
 .../main/java/org/apache/wiki/rss/RSS20Feed.java   |  48 +-
 .../java/org/apache/wiki/rss/RSSGenerator.java     |   8 +-
 .../main/java/org/apache/wiki/rss/RSSThread.java   |  25 +-
 .../apache/wiki/search/BasicSearchProvider.java    |  27 +-
 .../apache/wiki/search/LuceneSearchProvider.java   |  33 +-
 .../java/org/apache/wiki/search/SearchManager.java |   7 +-
 .../java/org/apache/wiki/search/SearchMatcher.java |  12 +-
 .../org/apache/wiki/tags/AdminBeanIteratorTag.java |  20 +-
 .../apache/wiki/tags/AttachmentsIteratorTag.java   |   9 +-
 .../main/java/org/apache/wiki/tags/AuthorTag.java  |   9 +-
 .../java/org/apache/wiki/tags/BreadcrumbsTag.java  |  97 ++-
 .../java/org/apache/wiki/tags/CalendarTag.java     |   9 +-
 .../java/org/apache/wiki/tags/CheckLockTag.java    |  70 +-
 .../java/org/apache/wiki/tags/CheckVersionTag.java |  12 +-
 .../org/apache/wiki/tags/ContentEncodingTag.java   |   7 +-
 .../main/java/org/apache/wiki/tags/ContentTag.java |  62 +-
 .../java/org/apache/wiki/tags/DiffLinkTag.java     |  15 +-
 .../java/org/apache/wiki/tags/EditLinkTag.java     |  78 +--
 .../org/apache/wiki/tags/EditorIteratorTag.java    |  15 +-
 .../main/java/org/apache/wiki/tags/EditorTag.java  |  61 +-
 .../org/apache/wiki/tags/FeedDiscoveryTag.java     |   8 +-
 .../org/apache/wiki/tags/HasAttachmentsTag.java    |  10 +-
 .../org/apache/wiki/tags/HistoryIteratorTag.java   |   9 +-
 .../main/java/org/apache/wiki/tags/IncludeTag.java |  56 +-
 .../java/org/apache/wiki/tags/InsertDiffTag.java   |  14 +-
 .../java/org/apache/wiki/tags/InsertPageTag.java   |  18 +-
 .../main/java/org/apache/wiki/tags/LinkTag.java    |  34 +-
 .../main/java/org/apache/wiki/tags/LinkToTag.java  |  31 +-
 .../java/org/apache/wiki/tags/NoSuchPageTag.java   |  13 +-
 .../java/org/apache/wiki/tags/PageInfoLinkTag.java |   9 +-
 .../java/org/apache/wiki/tags/PageNameTag.java     |   8 +-
 .../java/org/apache/wiki/tags/PageSizeTag.java     |  10 +-
 .../org/apache/wiki/tags/ParentPageNameTag.java    |   9 +-
 .../java/org/apache/wiki/tags/PermissionTag.java   |   5 +-
 .../main/java/org/apache/wiki/tags/PluginTag.java  |  35 +-
 .../java/org/apache/wiki/tags/RSSImageLinkTag.java |  50 +-
 .../apache/wiki/tags/SearchResultIteratorTag.java  |  48 +-
 .../java/org/apache/wiki/tags/TranslateTag.java    |   5 +-
 .../java/org/apache/wiki/tags/UserCheckTag.java    |   2 +-
 .../java/org/apache/wiki/tags/UserNameTag.java     |  43 +-
 .../java/org/apache/wiki/tags/UserProfileTag.java  | 181 ++----
 .../java/org/apache/wiki/tags/VariableTag.java     |  59 +-
 .../org/apache/wiki/tasks/DefaultTasksManager.java |  10 +-
 .../java/org/apache/wiki/tasks/TasksManager.java   |   4 +-
 .../wiki/tasks/auth/SaveUserProfileTask.java       |  18 +-
 .../wiki/tasks/pages/PreSaveWikiPageTask.java      |  27 +-
 .../apache/wiki/tasks/pages/SaveWikiPageTask.java  |  15 +-
 .../org/apache/wiki/ui/DefaultCommandResolver.java |   5 +-
 .../src/main/java/org/apache/wiki/ui/Editor.java   |   2 +-
 .../java/org/apache/wiki/ui/WikiJSPFilter.java     |  14 +-
 .../java/org/apache/wiki/ui/admin/AdminBean.java   |   4 +-
 .../org/apache/wiki/ui/admin/SimpleAdminBean.java  |  22 +-
 .../apache/wiki/ui/admin/WikiFormAdminBean.java    |  23 +-
 .../org/apache/wiki/ui/admin/beans/CoreBean.java   |  17 +-
 .../org/apache/wiki/ui/admin/beans/FilterBean.java |  24 +-
 .../org/apache/wiki/ui/admin/beans/ModuleBean.java |  30 +-
 .../wiki/ui/admin/beans/PlainEditorAdminBean.java  |  57 +-
 .../org/apache/wiki/ui/admin/beans/PluginBean.java |  24 +-
 .../wiki/ui/admin/beans/SearchManagerBean.java     |  81 +--
 .../org/apache/wiki/ui/admin/beans/UserBean.java   |  51 +-
 .../wiki/variables/DefaultVariableManager.java     |  17 +-
 .../wiki/workflow/DefaultWorkflowManager.java      |  19 +-
 .../org/apache/wiki/workflow/WorkflowBuilder.java  |  89 +--
 .../org/apache/wiki/workflow/WorkflowManager.java  |   4 +-
 .../org/apache/wiki/xmlrpc/AbstractRPCHandler.java |  13 +-
 .../org/apache/wiki/xmlrpc/MetaWeblogHandler.java  |  37 +-
 .../java/org/apache/wiki/xmlrpc/RPCHandler.java    |  34 +-
 .../org/apache/wiki/xmlrpc/RPCHandlerUTF8.java     |  34 +-
 .../src/main/resources/ini/classmappings.xml       |  10 +-
 .../test/java/org/apache/wiki/WikiEngineTest.java  |  22 +-
 .../wiki/attachment/AttachmentManagerTest.java     |  80 +--
 .../wiki/auth/AuthenticationManagerTest.java       | 103 ++-
 .../apache/wiki/auth/AuthorizationManagerTest.java | 151 ++---
 .../java/org/apache/wiki/auth/TestAuthorizer.java  |  42 +-
 .../java/org/apache/wiki/auth/UserManagerTest.java | 102 +--
 .../wiki/auth/acl/DefaultAclManagerTest.java       |  16 +-
 .../org/apache/wiki/content/PageRenamerTest.java   | 110 ++--
 .../apache/wiki/pages/DefaultPageManagerTest.java  |  78 +--
 .../wiki/parser/JSPWikiMarkupParserTest.java       | 546 ++++++++--------
 .../wiki/plugin/DefaultPluginManagerTest.java      |   5 +-
 .../java/org/apache/wiki/plugin/GroupsTest.java    |  11 +-
 .../java/org/apache/wiki/plugin/IfPluginTest.java  |  50 +-
 .../org/apache/wiki/plugin/InsertPageTest.java     |  31 +-
 .../org/apache/wiki/plugin/PageViewPluginTest.java |  77 +--
 .../apache/wiki/plugin/TableOfContentsTest.java    |  43 +-
 .../wiki/plugin/UndefinedPagesPluginTest.java      |   3 +-
 .../org/apache/wiki/plugin/WeblogPluginTest.java   |   3 +-
 .../apache/wiki/providers/CachingProviderTest.java |  27 +-
 .../org/apache/wiki/providers/CounterProvider.java |  56 +-
 .../wiki/providers/VersioningFileProviderTest.java | 184 +++---
 .../apache/wiki/providers/VerySimpleProvider.java  |  42 +-
 .../wiki/references/ReferenceManagerTest.java      |   4 +-
 .../apache/wiki/render/RenderingManagerTest.java   |  21 +-
 .../java/org/apache/wiki/rss/RSSGeneratorTest.java |  29 +-
 .../org/apache/wiki/search/SearchManagerTest.java  |   9 +-
 .../apache/wiki/stress/MassiveRepositoryTest.java  |  50 +-
 .../wiki/stress/StressTestVersioningProvider.java  |  27 +-
 .../org/apache/wiki/ui/CommandResolverTest.java    |   7 +-
 .../java/org/apache/wiki/ui/PageCommandTest.java   |   3 +-
 .../apache/wiki/workflow/ApprovalWorkflowTest.java |  85 +--
 .../org/apache/wiki/xmlrpc/RPCHandlerTest.java     |  47 +-
 .../LocalLinkAttributeProviderState.java           |   8 +-
 .../AccessRuleLinkNodePostProcessorState.java      |   6 +-
 .../LocalLinkNodePostProcessorState.java           |   3 +-
 .../MetadataLinkNodePostProcessorState.java        |   3 +-
 .../VariableLinkNodePostProcessorState.java        |   3 +-
 .../wiki/parser/markdown/MarkdownParser.java       |  35 +-
 .../apache/wiki/render/MarkdownRendererTest.java   |   5 +-
 .../wiki/search/tika/TikaSearchProvider.java       |  17 +-
 .../wiki/search/tika/TikaSearchProviderTest.java   |  15 +-
 .../main/java/org/apache/wiki/util/ClassUtil.java  | 197 +++---
 jspwiki-war/src/main/webapp/Diff.jsp               |   2 +-
 jspwiki-war/src/main/webapp/PageInfo.jsp           |   2 +-
 jspwiki-war/src/main/webapp/Wiki.jsp               |   2 +-
 jspwiki-war/src/main/webapp/rss.jsp                |   2 +-
 .../main/webapp/templates/210/AttachmentTab.jsp    |   2 +-
 .../main/webapp/templates/210/CommentContent.jsp   |   5 +-
 .../src/main/webapp/templates/210/DiffTab.jsp      |  12 +-
 .../src/main/webapp/templates/210/EditContent.jsp  |   5 +-
 .../src/main/webapp/templates/210/GroupTab.jsp     |   4 +-
 .../src/main/webapp/templates/210/InfoContent.jsp  |  12 +-
 .../src/main/webapp/templates/210/LoginContent.jsp |   2 +-
 .../src/main/webapp/templates/210/PageContent.jsp  |   4 +-
 .../src/main/webapp/templates/210/PageTab.jsp      |   3 +-
 .../main/webapp/templates/210/PreferencesTab.jsp   |   2 +-
 .../src/main/webapp/templates/210/ProfileTab.jsp   |   2 +-
 .../main/webapp/templates/210/UploadTemplate.jsp   |   5 +-
 .../main/webapp/templates/210/editors/CKeditor.jsp |  18 +-
 .../src/main/webapp/templates/210/editors/FCK.jsp  |  18 +-
 .../main/webapp/templates/210/editors/TinyMCE.jsp  |  20 +-
 .../main/webapp/templates/210/editors/plain.jsp    |  14 +-
 .../main/webapp/templates/210/editors/wysiwyg.jsp  |  14 +-
 .../webapp/templates/default/AttachmentTab.jsp     |   2 +-
 .../src/main/webapp/templates/default/DiffTab.jsp  |  12 +-
 .../src/main/webapp/templates/default/GroupTab.jsp |   5 +-
 .../main/webapp/templates/default/InfoContent.jsp  |   8 +-
 .../main/webapp/templates/default/LoginContent.jsp |   9 +-
 .../src/main/webapp/templates/default/Nav.jsp      |  11 +-
 .../src/main/webapp/templates/default/PageTab.jsp  |   6 +-
 .../webapp/templates/default/PreferencesTab.jsp    |  11 +-
 .../main/webapp/templates/default/ProfileTab.jsp   |   2 +-
 .../webapp/templates/default/editors/CKeditor.jsp  |  20 +-
 .../webapp/templates/default/editors/TinyMCE.jsp   |  20 +-
 .../webapp/templates/default/editors/plain.jsp     |  16 +-
 .../webapp/templates/default/editors/wysiwyg.jsp   |  20 +-
 238 files changed, 7587 insertions(+), 8628 deletions(-)
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/DefaultGroupManager.java
 create mode 100644 jspwiki-main/src/main/java/org/apache/wiki/auth/user/DummyUserDatabase.java


[jspwiki] 19/38: use Engine instead of WikiEngine on WikiPage

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 4344cfbd049de06934e8e71c84e791d8e9ec0eed
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 12:20:43 2020 +0100

    use Engine instead of WikiEngine on WikiPage
---
 .../src/main/java/org/apache/wiki/WikiPage.java    | 93 ++++++++++------------
 1 file changed, 43 insertions(+), 50 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiPage.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiPage.java
index 8cb19f9..b69b240 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiPage.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiPage.java
@@ -18,9 +18,11 @@
  */
 package org.apache.wiki;
 
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.acl.Acl;
 import org.apache.wiki.auth.acl.AclEntry;
 import org.apache.wiki.auth.acl.AclImpl;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 
 import java.util.Date;
@@ -29,8 +31,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 /**
- *  Simple wrapper class for the Wiki page attributes.  The Wiki page
- *  content is moved around in Strings, though.
+ *  Simple wrapper class for the Wiki page attributes.  The Wiki page content is moved around in Strings, though.
  */
 
 // FIXME: We need to rethink how metadata is being used - probably the 
@@ -40,7 +41,7 @@ import java.util.Map;
 public class WikiPage implements Cloneable, Comparable< WikiPage > {
 
     private       String     m_name;
-    private       WikiEngine m_engine;
+    private       Engine     m_engine;
     private       String     m_wiki;
     private Date             m_lastModified;
     private long             m_fileSize = -1;
@@ -76,8 +77,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @param engine The WikiEngine that owns this page.
      *  @param name   The name of the page.
      */
-    public WikiPage( WikiEngine engine, String name )
-    {
+    public WikiPage( final Engine engine, final String name ) {
         m_engine = engine;
         m_name = name;
         m_wiki = engine.getApplicationName();
@@ -103,9 +103,10 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @param key The key using which the attribute is fetched
      *  @return The attribute.  If the attribute has not been set, returns null.
      */
-    public < T > T getAttribute( String key )
+    @SuppressWarnings( "unchecked" )
+    public < T > T getAttribute( final String key )
     {
-        return (T)m_attributes.get( key );
+        return ( T )m_attributes.get( key );
     }
 
     /**
@@ -115,7 +116,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @param key The key for the attribute used to fetch the attribute later on.
      *  @param attribute The attribute value
      */
-    public void setAttribute( String key, Object attribute )
+    public void setAttribute( final String key, final Object attribute )
     {
         m_attributes.put( key, attribute );
     }
@@ -139,9 +140,10 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @return If the attribute existed, returns the object.
      *  @since 2.1.111
      */
-    public Object removeAttribute( String key )
+    @SuppressWarnings( "unchecked" )
+    public < T > T removeAttribute( final String key )
     {
-        return m_attributes.remove( key );
+        return ( T )m_attributes.remove( key );
     }
 
     /**
@@ -160,7 +162,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  
      *  @param date The date
      */
-    public void setLastModified( Date date )
+    public void setLastModified( final Date date )
     {
         m_lastModified = date;
     }
@@ -171,7 +173,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  
      *  @param version The version number
      */
-    public void setVersion( int version )
+    public void setVersion( final int version )
     {
         m_version = version;
     }
@@ -203,18 +205,16 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @param size The size of the page.
      *  @since 2.1.109
      */
-    public void setSize( long size )
+    public void setSize( final long size )
     {
         m_fileSize = size;
     }
 
     /**
-     *  Returns the Acl for this page.  May return <code>null</code>, 
-     *  in case there is no Acl defined, or it has not
-     *  yet been set by {@link #setAcl(Acl)}.
+     *  Returns the Acl for this page.  May return <code>null</code>, in case there is no Acl defined, or it has not yet been set by
+     *  {@link #setAcl(Acl)}.
      *  
-     *  @return The access control list.  May return null, if there is 
-     *          no acl.
+     *  @return The access control list.  May return null, if there is no acl.
      */
     public Acl getAcl()
     {
@@ -222,14 +222,13 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
     }
 
     /**
-     * Sets the Acl for this page. Note that method does <em>not</em>
-     * persist the Acl itself to back-end storage or in page markup;
-     * it merely sets the internal field that stores the Acl. To
-     * persist the Acl, callers should invoke 
+     * Sets the Acl for this page. Note that method does <em>not</em> persist the Acl itself to back-end storage or in page markup;
+     * it merely sets the internal field that stores the Acl. To persist the Acl, callers should invoke
      * {@link org.apache.wiki.auth.acl.AclManager#setPermissions(WikiPage, Acl)}.
+     *
      * @param acl The Acl to set
      */
-    public void setAcl( Acl acl )
+    public void setAcl( final Acl acl )
     {
         m_accessList = acl;
     }
@@ -239,7 +238,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  
      *  @param author The author name.
      */
-    public void setAuthor( String author )
+    public void setAuthor( final String author )
     {
         m_author = author;
     }
@@ -267,8 +266,7 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
     /**
      *  This method will remove all metadata from the page.
      */
-    public void invalidateMetadata()
-    {        
+    public void invalidateMetadata() {
         m_hasMetadata = false;
         setAcl( null );
         m_attributes.clear();
@@ -277,9 +275,8 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
     private boolean m_hasMetadata = false;
 
     /**
-     *  Returns <code>true</code> if the page has valid metadata; that is, it has been parsed.
-     *  Note that this method is a kludge to support our pre-3.0 metadata system, and as such
-     *  will go away with the new API.
+     *  Returns <code>true</code> if the page has valid metadata; that is, it has been parsed. Note that this method is a kludge to
+     *  support our pre-3.0 metadata system, and as such will go away with the new API.
      *  
      *  @return true, if the page has metadata.
      */
@@ -301,22 +298,21 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  
      *  @return A debug string.
      */
+    @Override
     public String toString()
     {
-        return "WikiPage ["+m_wiki+":"+m_name+",ver="+m_version+",mod="+m_lastModified+"]";
+        return "WikiPage [" + m_wiki + ":" + m_name + ",ver=" + m_version + ",mod=" + m_lastModified + "]";
     }
 
     /**
-     *  Creates a deep clone of a WikiPage.  Strings are not cloned, since
-     *  they're immutable.  Attributes are not cloned, only the internal
-     *  HashMap (so if you modify the contents of a value of an attribute,
-     *  these will reflect back to everyone).
+     *  Creates a deep clone of a WikiPage.  Strings are not cloned, since they're immutable.  Attributes are not cloned, only the internal
+     *  HashMap (so if you modify the contents of a value of an attribute, these will reflect back to everyone).
      *  
      *  @return A deep clone of the WikiPage
      */
-    public Object clone()
-    {
-        WikiPage p = new WikiPage( m_engine, m_name );
+    @Override
+    public Object clone() {
+        final WikiPage p = new WikiPage( m_engine, m_name );
        
         p.m_wiki         = m_wiki;
             
@@ -326,20 +322,14 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
 
         p.m_fileSize     = m_fileSize;
 
-        for( Map.Entry<String,Object> entry : m_attributes.entrySet() )
-        {
-            p.m_attributes.put( entry.getKey(), 
-                                entry.getValue() );
+        for( final Map.Entry< String, Object > entry : m_attributes.entrySet() ) {
+            p.m_attributes.put( entry.getKey(), entry.getValue() );
         }
 
-        if( m_accessList != null )
-        {
+        if( m_accessList != null ) {
             p.m_accessList = new AclImpl();
-            
-            for( Enumeration< AclEntry > entries = m_accessList.entries(); entries.hasMoreElements(); )
-            {
-                AclEntry e = entries.nextElement();
-            
+            for( final Enumeration< AclEntry > entries = m_accessList.entries(); entries.hasMoreElements(); ) {
+                final AclEntry e = entries.nextElement();
                 p.m_accessList.addEntry( e );
             }
         }
@@ -353,12 +343,13 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
      *  @param page The page to compare against
      *  @return -1, 0 or 1
      */
-    public int compareTo( WikiPage page ) {
+    @Override
+    public int compareTo( final WikiPage page ) {
         if( this == page ) {
             return 0; // the same object
         }
 
-        int res = m_engine.getPageManager().getPageSorter().compare( this.getName(), page.getName() );
+        int res = m_engine.getManager( PageManager.class ).getPageSorter().compare( this.getName(), page.getName() );
         if( res == 0 ) {
             res = this.getVersion() - page.getVersion();
         }
@@ -394,8 +385,10 @@ public class WikiPage implements Cloneable, Comparable< WikiPage > {
     /**
      *  {@inheritDoc}
      */
+    @Override
     public int hashCode()
     {
         return m_name.hashCode() * m_version;
     }
+
 }


[jspwiki] 09/38: JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 2e4934a6229df6952c5b638d7b91b4d01140fcd2
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:50:24 2020 +0100

    JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead
---
 .../src/main/java/org/apache/wiki/WatchDog.java    | 150 ++++++++++-----------
 .../java/org/apache/wiki/WikiBackgroundThread.java |  11 +-
 .../main/java/org/apache/wiki/api/core/Engine.java |   9 --
 .../main/java/org/apache/wiki/rss/RSSThread.java   |  25 ++--
 .../apache/wiki/search/LuceneSearchProvider.java   |   2 +-
 .../java/org/apache/wiki/ui/WikiJSPFilter.java     |  14 +-
 6 files changed, 97 insertions(+), 114 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WatchDog.java b/jspwiki-main/src/main/java/org/apache/wiki/WatchDog.java
index 94d236f..ad261bd 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WatchDog.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WatchDog.java
@@ -18,6 +18,9 @@
  */
 package org.apache.wiki;
 
+import org.apache.log4j.Logger;
+import org.apache.wiki.api.core.Engine;
+
 import java.lang.ref.WeakReference;
 import java.util.Iterator;
 import java.util.Map;
@@ -25,64 +28,53 @@ import java.util.Set;
 import java.util.Stack;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.log4j.Logger;
-
 
 /**
- *  WatchDog is a general system watchdog.  You can attach any Watchable or a
- *  Thread object to it, and it will notify you if a timeout has been exceeded.
+ *  WatchDog is a general system watchdog.  You can attach any Watchable or a Thread object to it, and it will notify you
+ *  if a timeout has been exceeded.
  *  <p>
- *  The notification of the timeouts is done from a separate WatchDog thread,
- *  of which there is one per watched thread.  This Thread is named 'WatchDog for
- *  XXX', where XXX is your Thread name.
+ *  The notification of the timeouts is done from a separate WatchDog thread, of which there is one per watched thread.
+ *  This Thread is named 'WatchDog for XXX', where XXX is your Thread name.
  *  <p>
- *  The suggested method of obtaining a WatchDog is via the static factory
- *  method, since it will return you the correct watchdog for the current
- *  thread.  However, we do not prevent you from creating your own watchdogs
- *  either.
+ *  The suggested method of obtaining a WatchDog is via the static factory method, since it will return you the correct
+ *  watchdog for the current thread.  However, we do not prevent you from creating your own watchdogs either.
  *  <p>
- *  If you create a WatchDog for a Thread, the WatchDog will figure out when
- *  the Thread is dead, and will stop itself accordingly.  However, this object
- *  is not automatically released, so you might want to check it out after a while.
+ *  If you create a WatchDog for a Thread, the WatchDog will figure out when the Thread is dead, and will stop itself
+ *  accordingly. However, this object is not automatically released, so you might want to check it out after a while.
  *
  *  @since  2.4.92
  */
 public final class WatchDog {
 
     private Watchable m_watchable;
-    private Stack< State > m_stateStack = new Stack< State >();
+    private final Stack< State > m_stateStack = new Stack<>();
     private boolean m_enabled = true;
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
     private static final Logger log = Logger.getLogger( WatchDog.class );
 
-    private static Map< Integer, WeakReference< WatchDog > > c_kennel = new ConcurrentHashMap< Integer, WeakReference< WatchDog > >();
-
+    private static Map< Integer, WeakReference< WatchDog > > c_kennel = new ConcurrentHashMap<>();
     private static WikiBackgroundThread c_watcherThread;
 
     /**
-     *  Returns the current watchdog for the current thread. This
-     *  is the preferred method of getting you a Watchdog, since it
-     *  keeps an internal list of Watchdogs for you so that there
-     *  won't be more than one watchdog per thread.
+     *  Returns the current watchdog for the current thread. This is the preferred method of getting you a Watchdog, since it
+     *  keeps an internal list of Watchdogs for you so that there won't be more than one watchdog per thread.
      *
      *  @param engine The WikiEngine to which the Watchdog should be bonded to.
      *  @return A usable WatchDog object.
      */
-    public static WatchDog getCurrentWatchDog( WikiEngine engine ) {
-        Thread t = Thread.currentThread();
-        WatchDog wd = null;
+    public static WatchDog getCurrentWatchDog( final Engine engine ) {
+        final Thread t = Thread.currentThread();
 
         WeakReference< WatchDog > w = c_kennel.get( t.hashCode() );
-
+        WatchDog wd = null;
         if( w != null ) {
         	wd = w.get();
         }
 
         if( w == null || wd == null ) {
             wd = new WatchDog( engine, t );
-            w = new WeakReference< WatchDog >( wd );
-
+            w = new WeakReference<>( wd );
             c_kennel.put( t.hashCode(), w );
         }
 
@@ -92,14 +84,14 @@ public final class WatchDog {
     /**
      *  Creates a new WatchDog for a Watchable.
      *
-     *  @param engine  The WikiEngine.
-     *  @param watch   A Watchable object.
+     *  @param engine The Engine.
+     *  @param watch A Watchable object.
      */
-    public WatchDog( WikiEngine engine, Watchable watch ) {
+    public WatchDog( final Engine engine, final Watchable watch ) {
         m_engine    = engine;
         m_watchable = watch;
 
-        synchronized( this.getClass() ) {
+        synchronized( WatchDog.class ) {
             if( c_watcherThread == null ) {
                 c_watcherThread = new WatchDogThread( engine );
                 c_watcherThread.start();
@@ -113,30 +105,24 @@ public final class WatchDog {
      *  @param engine The WikiEngine
      *  @param thread A Thread for watching.
      */
-    public WatchDog(WikiEngine engine, Thread thread) {
-        this( engine, new ThreadWrapper(thread) );
+    public WatchDog( final Engine engine, final Thread thread ) {
+        this( engine, new ThreadWrapper( thread ) );
     }
 
     /**
      *  Hopefully finalizes this properly.  This is rather untested for now...
      */
     private static void scrub() {
-        //
-        //  During finalization, the object may already be cleared (depending
-        //  on the finalization order).  Therefore, it's possible that this
-        //  method is called from another thread after the WatchDog itself
-        //  has been cleared.
-        //
+        //  During finalization, the object may already be cleared (depending on the finalization order). Therefore, it's
+        //  possible that this method is called from another thread after the WatchDog itself has been cleared.
         if( c_kennel == null ) {
         	return;
         }
 
-        for( Map.Entry< Integer, WeakReference< WatchDog > > e : c_kennel.entrySet() ) {
-            WeakReference< WatchDog > w = e.getValue();
+        for( final Map.Entry< Integer, WeakReference< WatchDog > > e : c_kennel.entrySet() ) {
+            final WeakReference< WatchDog > w = e.getValue();
 
-            //
             //  Remove expired as well
-            //
             if( w.get() == null ) {
                 c_kennel.remove( e.getKey() );
                 scrub();
@@ -149,7 +135,7 @@ public final class WatchDog {
      *  Can be used to enable the WatchDog.  Will cause a new Thread to be created, if none was existing previously.
      */
     public void enable() {
-        synchronized( this.getClass() ) {
+        synchronized( WatchDog.class ) {
             if( !m_enabled ) {
                 m_enabled = true;
                 c_watcherThread = new WatchDogThread( m_engine );
@@ -162,7 +148,7 @@ public final class WatchDog {
      *  Is used to disable a WatchDog.  The watchdog thread is shut down and resources released.
      */
     public void disable() {
-        synchronized( this.getClass() ) {
+        synchronized( WatchDog.class ) {
             if( m_enabled ) {
                 m_enabled = false;
                 c_watcherThread.shutdown();
@@ -177,7 +163,7 @@ public final class WatchDog {
      *
      *  @param state A free-form string description of your state.
      */
-    public void enterState( String state ) {
+    public void enterState( final String state ) {
         enterState( state, Integer.MAX_VALUE );
     }
 
@@ -197,14 +183,14 @@ public final class WatchDog {
      *  @param state A free-form string description of the state
      *  @param expectedCompletionTime The timeout in seconds.
      */
-    public void enterState( String state, int expectedCompletionTime ) {
+    public void enterState( final String state, final int expectedCompletionTime ) {
         if( log.isDebugEnabled() ){
         	log.debug( m_watchable.getName() + ": Entering state " + state +
         			                           ", expected completion in " + expectedCompletionTime + " s");
         }
 
         synchronized( m_stateStack ) {
-            State st = new State( state, expectedCompletionTime );
+            final State st = new State( state, expectedCompletionTime );
             m_stateStack.push( st );
         }
     }
@@ -223,10 +209,10 @@ public final class WatchDog {
      *
      *  @param state The state you wish to exit.
      */
-    public void exitState( String state ) {
+    public void exitState( final String state ) {
         if( !m_stateStack.empty() ) {
             synchronized( m_stateStack ) {
-                State st = m_stateStack.peek();
+                final State st = m_stateStack.peek();
                 if( state == null || st.getState().equals( state ) ) {
                     m_stateStack.pop();
 
@@ -249,7 +235,7 @@ public final class WatchDog {
      * @return {@code true} if not empty, {@code false} otherwise.
      */
     public boolean isStateStackNotEmpty() {
-		return m_stateStack != null && !m_stateStack.isEmpty();
+		return !m_stateStack.isEmpty();
 	}
 
     /**
@@ -268,8 +254,8 @@ public final class WatchDog {
 
         synchronized( m_stateStack ) {
             if( !m_stateStack.empty() ) {
-                State st = m_stateStack.peek();
-                long now = System.currentTimeMillis();
+                final State st = m_stateStack.peek();
+                final long now = System.currentTimeMillis();
 
                 if( now > st.getExpiryTime() ) {
                     log.info( "Watchable '" + m_watchable.getName() + "' exceeded timeout in state '" + st.getState() +
@@ -277,7 +263,7 @@ public final class WatchDog {
                     		 ( log.isDebugEnabled() ? "" : "Enable DEBUG-level logging to see stack traces." ) );
                     dumpStackTraceForWatchable();
 
-                    m_watchable.timeoutExceeded(st.getState());
+                    m_watchable.timeoutExceeded( st.getState() );
                 }
             } else {
             	log.warn( "Stack for " + m_watchable.getName() + " is empty!" );
@@ -293,22 +279,22 @@ public final class WatchDog {
         	return;
         }
 
-        Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
-        Set<Thread> threads = stackTraces.keySet();
-        Iterator<Thread> threadIterator = threads.iterator();
-        StringBuilder stacktrace = new StringBuilder();
+        final Map< Thread, StackTraceElement[] > stackTraces = Thread.getAllStackTraces();
+        final Set< Thread > threads = stackTraces.keySet();
+        final Iterator< Thread > threadIterator = threads.iterator();
+        final StringBuilder stacktrace = new StringBuilder();
 
         while ( threadIterator.hasNext() ) {
-            Thread t = threadIterator.next();
+            final Thread t = threadIterator.next();
             if( t.getName().equals( m_watchable.getName() ) ) {
                 if( t.getName().equals( m_watchable.getName() ) ) {
-                    stacktrace.append( "dumping stacktrace for too long running thread : " + t );
+                    stacktrace.append( "dumping stacktrace for too long running thread : " ).append( t );
                 } else {
-                    stacktrace.append( "dumping stacktrace for other running thread : " + t );
+                    stacktrace.append( "dumping stacktrace for other running thread : " ).append( t );
                 }
-                StackTraceElement[] ste = stackTraces.get( t );
-                for( int i = 0; i < ste.length; i++ ) {
-                    stacktrace.append( "\n" + ste[i] );
+                final StackTraceElement[] ste = stackTraces.get( t );
+                for( final StackTraceElement stackTraceElement : ste ) {
+                    stacktrace.append( "\n" ).append( stackTraceElement );
                 }
             }
         }
@@ -321,12 +307,13 @@ public final class WatchDog {
      *
      *  @return Random ramblings.
      */
+    @Override
     public String toString() {
         synchronized( m_stateStack ) {
             String state = "Idle";
 
             if( !m_stateStack.empty() ) {
-                State st = m_stateStack.peek();
+                final State st = m_stateStack.peek();
                 state = st.getState();
             }
             return "WatchDog state=" + state;
@@ -340,33 +327,34 @@ public final class WatchDog {
         /** How often the watchdog thread should wake up (in seconds) */
         private static final int CHECK_INTERVAL = 30;
 
-        public WatchDogThread( WikiEngine engine ) {
+        public WatchDogThread( final Engine engine ) {
             super( engine, CHECK_INTERVAL );
             setName( "WatchDog for '" + engine.getApplicationName() + "'" );
         }
 
+        @Override
         public void startupTask() {
         }
 
+        @Override
         public void shutdownTask() {
             WatchDog.scrub();
         }
 
         /**
-         *  Checks if the watchable is alive, and if it is, checks if
-         *  the stack is finished.
+         *  Checks if the watchable is alive, and if it is, checks if the stack is finished.
          *
-         *  If the watchable has been deleted in the mean time, will
-         *  simply shut down itself.
+         *  If the watchable has been deleted in the mean time, will simply shut down itself.
          */
-        public void backgroundTask() throws Exception {
+        @Override
+        public void backgroundTask() {
             if( c_kennel == null ) {
             	return;
             }
 
-            for( Map.Entry< Integer, WeakReference< WatchDog > > entry : c_kennel.entrySet() ) {
-                WeakReference< WatchDog > wr = entry.getValue();
-                WatchDog w = wr.get();
+            for( final Map.Entry< Integer, WeakReference< WatchDog > > entry : c_kennel.entrySet() ) {
+                final WeakReference< WatchDog > wr = entry.getValue();
+                final WatchDog w = wr.get();
                 if( w != null ) {
                     if( w.isWatchableAlive() && w.isStateStackNotEmpty() ) {
                         w.check();
@@ -391,10 +379,10 @@ public final class WatchDog {
         protected long   m_enterTime;
         protected long   m_expiryTime;
 
-        protected State( String state, int expiry ) {
+        protected State( final String state, final int expiry ) {
             m_state      = state;
             m_enterTime  = System.currentTimeMillis();
-            m_expiryTime = m_enterTime + (expiry * 1000L);
+            m_expiryTime = m_enterTime + ( expiry * 1_000L );
         }
 
         protected String getState() {
@@ -404,6 +392,7 @@ public final class WatchDog {
         protected long getExpiryTime() {
             return m_expiryTime;
         }
+
     }
 
     /**
@@ -412,18 +401,21 @@ public final class WatchDog {
     private static class ThreadWrapper implements Watchable {
         private Thread m_thread;
 
-        public ThreadWrapper( Thread thread ) {
+        public ThreadWrapper( final Thread thread ) {
             m_thread = thread;
         }
 
-        public void timeoutExceeded( String state ) {
+        @Override
+        public void timeoutExceeded( final String state ) {
             // TODO: Figure out something sane to do here.
         }
 
+        @Override
         public String getName() {
             return m_thread.getName();
         }
 
+        @Override
         public boolean isAlive() {
             return m_thread.isAlive();
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiBackgroundThread.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiBackgroundThread.java
index 18e48e3..8bda0fa 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiBackgroundThread.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiBackgroundThread.java
@@ -19,6 +19,7 @@
 package org.apache.wiki;
 
 import org.apache.log4j.Logger;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.event.WikiEngineEvent;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventListener;
@@ -34,7 +35,7 @@ public abstract class WikiBackgroundThread extends Thread implements WikiEventLi
 	
     private static final Logger LOG = Logger.getLogger( WikiBackgroundThread.class );
     private volatile boolean m_killMe = false;
-    private final WikiEngine m_engine;
+    private final Engine m_engine;
     private final int m_interval;
     private static final long POLLING_INTERVAL = 1_000L;
     
@@ -46,7 +47,7 @@ public abstract class WikiBackgroundThread extends Thread implements WikiEventLi
      * @param sleepInterval the interval between invocations of
      * the thread's {@link Thread#run()} method, in seconds
      */
-    public WikiBackgroundThread( final WikiEngine engine, final int sleepInterval ) {
+    public WikiBackgroundThread( final Engine engine, final int sleepInterval ) {
         super();
         m_engine = engine;
         m_interval = sleepInterval;
@@ -60,7 +61,7 @@ public abstract class WikiBackgroundThread extends Thread implements WikiEventLi
      * @param event {@inheritDoc}
      * @see org.apache.wiki.event.WikiEventListener#actionPerformed(org.apache.wiki.event.WikiEvent)
      */
-    public final void actionPerformed( final WikiEvent event ) {
+    @Override public final void actionPerformed( final WikiEvent event ) {
         if ( event instanceof WikiEngineEvent ) {
             if ( event.getType() == WikiEngineEvent.SHUTDOWN ) {
                 LOG.warn( "Detected wiki engine shutdown: killing " + getName() + "." );
@@ -81,7 +82,7 @@ public abstract class WikiBackgroundThread extends Thread implements WikiEventLi
      * 
      * @return the wiki engine
      */
-    public WikiEngine getEngine() {
+    public Engine getEngine() {
         return m_engine;
     }
     
@@ -103,7 +104,7 @@ public abstract class WikiBackgroundThread extends Thread implements WikiEventLi
      * 
      * @see java.lang.Thread#run()
      */
-    public final void run() {
+    @Override public final void run() {
         try {
             // Perform the initial startup task
             final String name = getName();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index f88eb88..bab095c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -19,7 +19,6 @@
 package org.apache.wiki.api.core;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WatchDog;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.event.WikiEventListener;
 
@@ -381,14 +380,6 @@ public interface Engine {
     < T > T removeAttribute( String key );
 
     /**
-     *  Returns a WatchDog for current thread.
-     *
-     *  @return The current thread WatchDog.
-     *  @since 2.4.92
-     */
-    WatchDog getCurrentWatchDog();
-
-    /**
      * Signals that the Engine will be shut down by the servlet container.
      */
     void shutdown();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSThread.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSThread.java
index 4d0d303..9707314 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSThread.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSThread.java
@@ -19,6 +19,12 @@
 package org.apache.wiki.rss;
 
 
+import org.apache.log4j.Logger;
+import org.apache.wiki.WatchDog;
+import org.apache.wiki.WikiBackgroundThread;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.util.FileUtil;
+
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -28,12 +34,6 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.io.Writer;
 
-import org.apache.log4j.Logger;
-import org.apache.wiki.WatchDog;
-import org.apache.wiki.WikiBackgroundThread;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.util.FileUtil;
-
 /**
  *  Runs the RSS generation thread.
  *  FIXME: MUST be somewhere else, this is not a good place.
@@ -54,7 +54,7 @@ public class RSSThread extends WikiBackgroundThread
      *  @param rssFile A File to write the RSS data to.
      *  @param rssInterval How often the RSS should be generated.
      */
-    public RSSThread( WikiEngine engine, File rssFile, int rssInterval )
+    public RSSThread( final WikiEngine engine, final File rssFile, final int rssInterval )
     {
         super( engine, rssInterval );
         m_generator = engine.getRSSGenerator();
@@ -68,9 +68,8 @@ public class RSSThread extends WikiBackgroundThread
      *  {@inheritDoc}
      */
     @Override
-    public void startupTask() throws Exception
-    {
-        m_watchdog = getEngine().getCurrentWatchDog();
+    public void startupTask() {
+        m_watchdog = WatchDog.getCurrentWatchDog( getEngine() );
     }
     
     /**
@@ -99,14 +98,14 @@ public class RSSThread extends WikiBackgroundThread
                 //
                 log.debug("Regenerating RSS feed to "+m_rssFile);
 
-                String feed = m_generator.generate();
+                final String feed = m_generator.generate();
 
                 in  = new StringReader(feed);
                 out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( m_rssFile ), "UTF-8") );
 
                 FileUtil.copyContents( in, out );
             }
-            catch( IOException e )
+            catch( final IOException e )
             {
                 log.error("Cannot generate RSS feed to "+m_rssFile.getAbsolutePath(), e );
                 m_generator.setEnabled( false );
@@ -118,7 +117,7 @@ public class RSSThread extends WikiBackgroundThread
                     if( in != null )  in.close();
                     if( out != null ) out.close();
                 }
-                catch( IOException e )
+                catch( final IOException e )
                 {
                     log.fatal("Could not close I/O for RSS", e );
                     m_generator.setEnabled( false );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
index 1cfcc30..c6ab12a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
@@ -564,7 +564,7 @@ public class LuceneSearchProvider implements SearchProvider {
 
         @Override
         public void startupTask() throws Exception {
-            m_watchdog = getEngine().getCurrentWatchDog();
+            m_watchdog = WatchDog.getCurrentWatchDog( getEngine() );
 
             // Sleep initially...
             try {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiJSPFilter.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiJSPFilter.java
index d7d1fe2..03e16cd 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiJSPFilter.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiJSPFilter.java
@@ -77,15 +77,15 @@ public class WikiJSPFilter extends WikiServletFilter {
     private boolean useEncoding;
 
     /** {@inheritDoc} */
-    public void init( final FilterConfig config ) throws ServletException {
+    @Override public void init( final FilterConfig config ) throws ServletException {
         super.init( config );
         m_wiki_encoding = m_engine.getWikiProperties().getProperty(WikiEngine.PROP_ENCODING);
 
         useEncoding = !( Boolean.valueOf( m_engine.getWikiProperties().getProperty( WikiEngine.PROP_NO_FILTER_ENCODING, "false" ).trim() ).booleanValue() );
     }
 
-    public void doFilter( final ServletRequest  request, final ServletResponse response, final FilterChain chain ) throws ServletException, IOException {
-        final WatchDog w = m_engine.getCurrentWatchDog();
+    @Override public void doFilter( final ServletRequest  request, final ServletResponse response, final FilterChain chain ) throws ServletException, IOException {
+        final WatchDog w = WatchDog.getCurrentWatchDog( m_engine );
         try {
             NDC.push( m_engine.getApplicationName()+":"+((HttpServletRequest)request).getRequestURI() );
             w.enterState("Filtering for URL "+((HttpServletRequest)request).getRequestURI(), 90 );
@@ -229,15 +229,15 @@ public class WikiJSPFilter extends WikiServletFilter {
         /**
          *  Returns a writer for output; this wraps the internal buffer into a PrintWriter.
          */
-        public PrintWriter getWriter() {
+        @Override public PrintWriter getWriter() {
             return m_writer;
         }
 
-        public ServletOutputStream getOutputStream() {
+        @Override public ServletOutputStream getOutputStream() {
             return m_servletOut;
         }
 
-        public void flushBuffer() throws IOException {
+        @Override public void flushBuffer() throws IOException {
             m_writer.flush();
             super.flushBuffer();
         }
@@ -272,7 +272,7 @@ public class WikiJSPFilter extends WikiServletFilter {
         }
 
         /** Returns whatever was written so far into the Writer. */
-        public String toString() {
+        @Override public String toString() {
             try {
 				flushBuffer();
 			} catch( final IOException e ) {


[jspwiki] 12/38: WikiEngine -> Engine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit df5e6db36104215384a5fd47db67c2247102d414
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:52:24 2020 +0100

    WikiEngine -> Engine
---
 jspwiki-main/src/main/java/org/apache/wiki/api/engine/package.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/engine/package.html b/jspwiki-main/src/main/java/org/apache/wiki/api/engine/package.html
index bd321bf..1b8998d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/engine/package.html
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/engine/package.html
@@ -26,7 +26,7 @@
 <body>
 JSPWiki's WikiEngine Managers package.
 
-This package holds all the Managers provided by WikiEngine and associated classes.
+This package holds all the Managers provided by the Engine and associated classes.
 
 <h3>Package Specification</h3>
 


[jspwiki] 18/38: Use Engine instead of WikiEngine in SecurityVerifier + Extract DummyUserDatabase to its own class

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit dbee4c25e3bbc8471737c731299a10bbded71e77
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 12:20:07 2020 +0100

    Use Engine instead of WikiEngine in SecurityVerifier + Extract DummyUserDatabase to its own class
---
 .../org/apache/wiki/auth/DefaultUserManager.java   | 111 +--------
 .../org/apache/wiki/auth/SecurityVerifier.java     | 265 ++++++++-------------
 .../apache/wiki/auth/user/DummyUserDatabase.java   | 135 +++++++++++
 3 files changed, 230 insertions(+), 281 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
index c2b13af..5037db3 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
@@ -32,7 +32,7 @@ import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.api.filters.PageFilter;
 import org.apache.wiki.auth.permissions.AllPermission;
 import org.apache.wiki.auth.permissions.WikiPermission;
-import org.apache.wiki.auth.user.AbstractUserDatabase;
+import org.apache.wiki.auth.user.DummyUserDatabase;
 import org.apache.wiki.auth.user.DuplicateUserException;
 import org.apache.wiki.auth.user.UserDatabase;
 import org.apache.wiki.auth.user.UserProfile;
@@ -402,115 +402,6 @@ public class DefaultUserManager implements UserManager {
         return getUserDatabase().getWikiNames();
     }
 
-    /**
-     * This is a database that gets used if nothing else is available. It does nothing of note - it just mostly throws
-     * NoSuchPrincipalExceptions if someone tries to log in.
-     */
-    public static class DummyUserDatabase extends AbstractUserDatabase {
-
-        /**
-         * No-op.
-         * @param loginName the login name to delete
-         */
-        @Override
-        public void deleteByLoginName( final String loginName ) {
-            // No operation
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByEmail(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByFullName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByLoginName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param uid the unique identifier to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByWikiName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op.
-         * @return a zero-length array
-         */
-        @Override
-        public Principal[] getWikiNames() {
-            return new Principal[0];
-        }
-
-        /**
-         * No-op.
-         *
-         * @param engine the wiki engine
-         * @param props the properties used to initialize the wiki engine
-         */
-        @Override
-        public void initialize( final Engine engine, final Properties props ) {
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param loginName the login name
-         * @param newName the proposed new login name
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op.
-         * @param profile the user profile
-         */
-        @Override
-        public void save( final UserProfile profile ) {
-        }
-
-    }
-
     // events processing .......................................................
 
     /**
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
index 6946732..fbe727d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
@@ -20,8 +20,8 @@ package org.apache.wiki.auth;
 
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.auth.authorize.Group;
 import org.apache.wiki.auth.authorize.GroupDatabase;
@@ -32,6 +32,7 @@ import org.apache.wiki.auth.permissions.AllPermission;
 import org.apache.wiki.auth.permissions.GroupPermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
 import org.apache.wiki.auth.permissions.WikiPermission;
+import org.apache.wiki.auth.user.DummyUserDatabase;
 import org.apache.wiki.auth.user.UserDatabase;
 import org.apache.wiki.auth.user.UserProfile;
 import org.freshcookies.security.policy.PolicyReader;
@@ -60,7 +61,7 @@ import java.util.Set;
  */
 public final class SecurityVerifier {
 
-    private WikiEngine            m_engine;
+    private Engine                m_engine;
 
     private boolean               m_isSecurityPolicyConfigured = false;
 
@@ -138,20 +139,15 @@ public final class SecurityVerifier {
      * @param engine the wiki engine
      * @param session the wiki session (typically, that of an administrator)
      */
-    public SecurityVerifier( final WikiEngine engine, final WikiSession session )
-    {
-        super();
+    public SecurityVerifier( final Engine engine, final WikiSession session ) {
         m_engine = engine;
         m_session = session;
         m_session.clearMessages();
         verifyJaas();
         verifyPolicy();
-        try
-        {
+        try {
             verifyPolicyAndContainerRoles();
-        }
-        catch ( final WikiException e )
-        {
+        } catch( final WikiException e ) {
             m_session.addMessage( ERROR_ROLES, e.getMessage() );
         }
         verifyGroupDatabase();
@@ -194,12 +190,9 @@ public final class SecurityVerifier {
 
         // Calculate column widths
         final String colWidth;
-        if ( pageActions.length > 0 && roles.length > 0 )
-        {
-            colWidth =  (67f / ( pageActions.length * roles.length )) + "%";
-        }
-        else
-        {
+        if( pageActions.length > 0 && roles.length > 0 ) {
+            colWidth = ( 67f / ( pageActions.length * roles.length ) ) + "%";
+        } else {
             colWidth = "67%";
         }
 
@@ -232,14 +225,11 @@ public final class SecurityVerifier {
         s.append( "  </tr>\n" );
 
         // Write page permission tests first
-        for( final String page : pages )
-        {
+        for( final String page : pages ) {
             s.append( "  <tr>\n" );
             s.append( "    <td>PagePermission \"" + wiki + ":" + page + "\"</td>\n" );
-            for( final Principal role : roles )
-            {
-                for( final String pageAction : pageActions )
-                {
+            for( final Principal role : roles ) {
+                for( final String pageAction : pageActions ) {
                     final Permission permission = PermissionFactory.getPagePermission( wiki + ":" + page, pageAction );
                     s.append( printPermissionTest( permission, role, 1 ) );
                 }
@@ -248,17 +238,13 @@ public final class SecurityVerifier {
         }
 
         // Now do the group tests
-        for( final String group : groups )
-        {
+        for( final String group : groups ) {
             s.append( "  <tr>\n" );
             s.append( "    <td>GroupPermission \"" + wiki + ":" + group + "\"</td>\n" );
-            for( final Principal role : roles )
-            {
-                for( final String groupAction : groupActions )
-                {
+            for( final Principal role : roles ) {
+                for( final String groupAction : groupActions ) {
                     Permission permission = null;
-                    if ( groupAction != null)
-                    {
+                    if( groupAction != null ) {
                         permission = new GroupPermission( wiki + ":" + group, groupAction );
                     }
                     s.append( printPermissionTest( permission, role, 1 ) );
@@ -269,14 +255,11 @@ public final class SecurityVerifier {
 
 
         // Now check the wiki-wide permissions
-        final String[] wikiPerms = new String[]
-        { "createGroups", "createPages", "login", "editPreferences", "editProfile" };
-        for( final String wikiPerm : wikiPerms )
-        {
+        final String[] wikiPerms = new String[] { "createGroups", "createPages", "login", "editPreferences", "editProfile" };
+        for( final String wikiPerm : wikiPerms ) {
             s.append( "  <tr>\n" );
             s.append( "    <td>WikiPermission \"" + wiki + "\",\"" + wikiPerm + "\"</td>\n" );
-            for( final Principal role : roles )
-            {
+            for( final Principal role : roles ) {
                 final Permission permission = new WikiPermission( wiki, wikiPerm );
                 s.append( printPermissionTest( permission, role, pageActions.length ) );
             }
@@ -304,16 +287,12 @@ public final class SecurityVerifier {
      * @param principal
      * @param cols
      */
-    private String printPermissionTest( final Permission permission, final Principal principal, final int cols )
-    {
+    private String printPermissionTest( final Permission permission, final Principal principal, final int cols ) {
     	final StringBuilder s = new StringBuilder();
-        if ( permission == null )
-        {
+        if( permission == null ) {
             s.append( "    <td colspan=\"" + cols + "\" align=\"center\" title=\"N/A\">" );
             s.append( "&nbsp;</td>\n" );
-        }
-        else
-        {
+        } else {
             final boolean allowed = verifyStaticPermission( principal, permission );
             s.append( "    <td colspan=\"" + cols + "\" align=\"center\" title=\"" );
             s.append( allowed ? "ALLOW: " : "DENY: " );
@@ -347,15 +326,12 @@ public final class SecurityVerifier {
      * @return the formatted HTML table containing the result of the tests
      * @throws WikiException if tests fail for unexpected reasons
      */
-    public String containerRoleTable() throws WikiException
-    {
-
-        final AuthorizationManager authorizationManager = m_engine.getAuthorizationManager();
+    public String containerRoleTable() throws WikiException {
+        final AuthorizationManager authorizationManager = m_engine.getManager( AuthorizationManager.class );
         final Authorizer authorizer = authorizationManager.getAuthorizer();
 
         // If authorizer not WebContainerAuthorizer, print error message
-        if ( !( authorizer instanceof WebContainerAuthorizer ) )
-        {
+        if ( !( authorizer instanceof WebContainerAuthorizer ) ) {
             throw new IllegalStateException( "Authorizer should be WebContainerAuthorizer" );
         }
 
@@ -373,8 +349,7 @@ public final class SecurityVerifier {
         s.append( "  </tr>\n" );
         s.append( "  <tr>\n" );
         s.append( "    <th>Anonymous</th>\n" );
-        for( final Principal role : roles )
-        {
+        for( final Principal role : roles ) {
             s.append( "    <th>" + role.getName() + "</th>\n" );
         }
         s.append( "</tr>\n" );
@@ -382,8 +357,7 @@ public final class SecurityVerifier {
         s.append( "<tbody>\n" );
 
         final WebContainerAuthorizer wca = (WebContainerAuthorizer) authorizer;
-        for( int i = 0; i < CONTAINER_ACTIONS.length; i++ )
-        {
+        for( int i = 0; i < CONTAINER_ACTIONS.length; i++ ) {
             final String action = CONTAINER_ACTIONS[i];
             final String jsp = CONTAINER_JSPS[i];
 
@@ -433,17 +407,15 @@ public final class SecurityVerifier {
     }
 
     /**
-     * If the active Authorizer is the WebContainerAuthorizer, returns the roles
-     * it knows about; otherwise, a zero-length array.
+     * If the active Authorizer is the WebContainerAuthorizer, returns the roles it knows about; otherwise, a zero-length array.
+     *
      * @return the roles parsed from <code>web.xml</code>, or a zero-length array
      * @throws WikiException if the web authorizer cannot obtain the list of roles
      */
-    public Principal[] webContainerRoles() throws WikiException
-    {
-        final Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
-        if ( authorizer instanceof WebContainerAuthorizer )
-        {
-            return ( (WebContainerAuthorizer) authorizer ).getRoles();
+    public Principal[] webContainerRoles() throws WikiException {
+        final Authorizer authorizer = m_engine.getManager( AuthorizationManager.class ).getAuthorizer();
+        if ( authorizer instanceof WebContainerAuthorizer ) {
+            return authorizer.getRoles();
         }
         return new Principal[0];
     }
@@ -455,7 +427,7 @@ public final class SecurityVerifier {
      */
     protected void verifyPolicyAndContainerRoles() throws WikiException
     {
-        final Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
+        final Authorizer authorizer = m_engine.getManager( AuthorizationManager.class ).getAuthorizer();
         final Principal[] containerRoles = authorizer.getRoles();
         boolean missing = false;
         for( final Principal principal : m_policyPrincipals )
@@ -483,29 +455,21 @@ public final class SecurityVerifier {
      */
     protected void verifyGroupDatabase()
     {
-        final GroupManager mgr = m_engine.getGroupManager();
+        final GroupManager mgr = m_engine.getManager( GroupManager.class );
         GroupDatabase db = null;
-        try
-        {
-            db = m_engine.getGroupManager().getGroupDatabase();
-        }
-        catch ( final WikiSecurityException e )
-        {
+        try {
+            db = m_engine.getManager( GroupManager.class ).getGroupDatabase();
+        } catch ( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_GROUPS, "Could not retrieve GroupManager: " + e.getMessage() );
         }
 
         // Check for obvious error conditions
-        if ( mgr == null || db == null )
-        {
-            if ( mgr == null )
-            {
-                m_session.addMessage( ERROR_GROUPS, "GroupManager is null; JSPWiki could not " +
-                        "initialize it. Check the error logs." );
+        if ( mgr == null || db == null ) {
+            if ( mgr == null ) {
+                m_session.addMessage( ERROR_GROUPS, "GroupManager is null; JSPWiki could not initialize it. Check the error logs." );
             }
-            if ( db == null )
-            {
-                m_session.addMessage( ERROR_GROUPS, "GroupDatabase is null; JSPWiki could not " +
-                        "initialize it. Check the error logs." );
+            if ( db == null ) {
+                m_session.addMessage( ERROR_GROUPS, "GroupDatabase is null; JSPWiki could not initialize it. Check the error logs." );
             }
             return;
         }
@@ -513,61 +477,49 @@ public final class SecurityVerifier {
         // Everything initialized OK...
 
         // Tell user what class of database this is.
-        m_session.addMessage( INFO_GROUPS, "GroupDatabase is of type '" + db.getClass().getName() +
-                "'. It appears to be initialized properly." );
+        m_session.addMessage( INFO_GROUPS, "GroupDatabase is of type '" + db.getClass().getName() + "'. It appears to be initialized properly." );
 
         // Now, see how many groups we have.
-        int oldGroupCount = 0;
-        try
-        {
+        final int oldGroupCount;
+        try {
             final Group[] groups = db.groups();
             oldGroupCount = groups.length;
             m_session.addMessage( INFO_GROUPS, "The group database contains " + oldGroupCount + " groups." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_GROUPS, "Could not obtain a list of current groups: " + e.getMessage() );
             return;
         }
 
         // Try adding a bogus group with random name
         final String name = "TestGroup" + System.currentTimeMillis();
-        Group group = null;
-        try
-        {
+        final Group group;
+        try {
             // Create dummy test group
             group = mgr.parseGroup( name, "", true );
             final Principal user = new WikiPrincipal( "TestUser" );
             group.add( user );
-            db.save( group, new WikiPrincipal("SecurityVerifier") );
+            db.save( group, new WikiPrincipal( "SecurityVerifier" ) );
 
             // Make sure the group saved successfully
-            if ( db.groups().length == oldGroupCount )
-            {
+            if( db.groups().length == oldGroupCount ) {
                 m_session.addMessage( ERROR_GROUPS, "Could not add a test group to the database." );
                 return;
             }
             m_session.addMessage( INFO_GROUPS, "The group database allows new groups to be created, as it should." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_GROUPS, "Could not add a group to the database: " + e.getMessage() );
             return;
         }
 
         // Now delete the group; should be back to old count
-        try
-        {
+        try {
             db.delete( group );
-            if ( db.groups().length != oldGroupCount )
-            {
+            if( db.groups().length != oldGroupCount ) {
                 m_session.addMessage( ERROR_GROUPS, "Could not delete a test group from the database." );
                 return;
             }
             m_session.addMessage( INFO_GROUPS, "The group database allows groups to be deleted, as it should." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_GROUPS, "Could not delete a test group from the database: " + e.getMessage() );
             return;
         }
@@ -581,42 +533,31 @@ public final class SecurityVerifier {
      * {@value org.apache.wiki.auth.AuthenticationManager#PROP_LOGIN_MODULE}
      * resolves to a valid class on the classpath.
      */
-    protected void verifyJaas()
-    {
+    protected void verifyJaas() {
         // Verify that the specified JAAS moduie corresponds to a class we can load successfully.
         final String jaasClass = m_engine.getWikiProperties().getProperty( AuthenticationManager.PROP_LOGIN_MODULE );
-        if ( jaasClass == null || jaasClass.length() == 0 )
-        {
-            m_session.addMessage( ERROR_JAAS, "The value of the '" + AuthenticationManager.PROP_LOGIN_MODULE +
-                    "' property was null or blank. This is a fatal error. This value should be set to a valid LoginModule implementation " +
-                    "on the classpath." );
+        if( jaasClass == null || jaasClass.length() == 0 ) {
+            m_session.addMessage( ERROR_JAAS, "The value of the '" + AuthenticationManager.PROP_LOGIN_MODULE
+                    + "' property was null or blank. This is a fatal error. This value should be set to a valid LoginModule implementation "
+                    + "on the classpath." );
             return;
         }
-        
+
         // See if we can find the LoginModule on the classpath
         Class< ? > c = null;
-        try
-        {
-            m_session.addMessage( INFO_JAAS, "The property '" + AuthenticationManager.PROP_LOGIN_MODULE +
-                                  "' specified the class '" + jaasClass + ".'" );
+        try {
+            m_session.addMessage( INFO_JAAS,
+                    "The property '" + AuthenticationManager.PROP_LOGIN_MODULE + "' specified the class '" + jaasClass + ".'" );
             c = Class.forName( jaasClass );
+        } catch( final ClassNotFoundException e ) {
+            m_session.addMessage( ERROR_JAAS, "We could not find the the class '" + jaasClass + "' on the " + "classpath. This is fatal error." );
         }
-        catch( final ClassNotFoundException e )
-        {
-            m_session.addMessage( ERROR_JAAS, "We could not find the the class '" + jaasClass + "' on the " +
-            "classpath. This is fatal error." );
-        }
-        
+
         // Is the specified class actually a LoginModule?
-        if ( LoginModule.class.isAssignableFrom( c ) )
-        {
-            m_session.addMessage( INFO_JAAS, "We found the the class '" + jaasClass + "' on the " +
-                    "classpath, and it is a LoginModule implementation. Good!" );
-        }
-        else
-        {
-            m_session.addMessage( ERROR_JAAS, "We found the the class '" + jaasClass + "' on the " +
-            "classpath, but it does not seem to be LoginModule implementation! This is fatal error." );
+        if( LoginModule.class.isAssignableFrom( c ) ) {
+            m_session.addMessage( INFO_JAAS, "We found the the class '" + jaasClass + "' on the classpath, and it is a LoginModule implementation. Good!" );
+        } else {
+            m_session.addMessage( ERROR_JAAS, "We found the the class '" + jaasClass + "' on the classpath, but it does not seem to be LoginModule implementation! This is fatal error." );
         }
     }
 
@@ -759,22 +700,15 @@ public final class SecurityVerifier {
     {
         final Subject subject = new Subject();
         subject.getPrincipals().add( principal );
-        final boolean allowedByGlobalPolicy = ((Boolean)
-            Subject.doAsPrivileged( subject, new PrivilegedAction<Object>()
-            {
-                @Override public Object run()
-                {
-                    try
-                    {
-                        AccessController.checkPermission( permission );
-                        return Boolean.TRUE;
-                    }
-                    catch ( final AccessControlException e )
-                    {
-                        return Boolean.FALSE;
-                    }
+        final boolean allowedByGlobalPolicy = (Boolean)
+            Subject.doAsPrivileged( subject, ( PrivilegedAction< Object > )() -> {
+                try {
+                    AccessController.checkPermission( permission );
+                    return Boolean.TRUE;
+                } catch( final AccessControlException e ) {
+                    return Boolean.FALSE;
                 }
-            }, null )).booleanValue();
+            }, null );
 
         if ( allowedByGlobalPolicy )
         {
@@ -783,7 +717,7 @@ public final class SecurityVerifier {
 
         // Check local policy
         final Principal[] principals = new Principal[]{ principal };
-        return m_engine.getAuthorizationManager().allowedByLocalPolicy( principals, permission );
+        return m_engine.getManager( AuthorizationManager.class ).allowedByLocalPolicy( principals, permission );
     }
 
     /**
@@ -792,7 +726,7 @@ public final class SecurityVerifier {
      */
     protected void verifyUserDatabase()
     {
-        final UserDatabase db = m_engine.getUserManager().getUserDatabase();
+        final UserDatabase db = m_engine.getManager( UserManager.class ).getUserDatabase();
 
         // Check for obvious error conditions
         if ( db == null )
@@ -802,7 +736,7 @@ public final class SecurityVerifier {
             return;
         }
 
-        if ( db instanceof UserManager.DummyUserDatabase )
+        if ( db instanceof DummyUserDatabase )
         {
             m_session.addMessage( ERROR_DB, "UserDatabase is DummyUserDatabase; JSPWiki " +
                     "may not have been able to initialize the database you supplied in " +
@@ -812,60 +746,49 @@ public final class SecurityVerifier {
 
         // Tell user what class of database this is.
         m_session.addMessage( INFO_DB, "UserDatabase is of type '" + db.getClass().getName() +
-                "'. It appears to be initialized properly." );
+                                       "'. It appears to be initialized properly." );
 
         // Now, see how many users we have.
-        int oldUserCount = 0;
-        try
-        {
+        final int oldUserCount;
+        try {
             final Principal[] users = db.getWikiNames();
             oldUserCount = users.length;
             m_session.addMessage( INFO_DB, "The user database contains " + oldUserCount + " users." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_DB, "Could not obtain a list of current users: " + e.getMessage() );
             return;
         }
 
         // Try adding a bogus user with random name
         final String loginName = "TestUser" + System.currentTimeMillis();
-        try
-        {
+        try {
             final UserProfile profile = db.newProfile();
             profile.setEmail( "jspwiki.tests@mailinator.com" );
             profile.setLoginName( loginName );
-            profile.setFullname( "FullName"+loginName );
+            profile.setFullname( "FullName" + loginName );
             profile.setPassword( "password" );
-            db.save(profile);
+            db.save( profile );
 
             // Make sure the profile saved successfully
-            if ( db.getWikiNames().length == oldUserCount )
-            {
+            if( db.getWikiNames().length == oldUserCount ) {
                 m_session.addMessage( ERROR_DB, "Could not add a test user to the database." );
                 return;
             }
             m_session.addMessage( INFO_DB, "The user database allows new users to be created, as it should." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_DB, "Could not add a test user to the database: " + e.getMessage() );
             return;
         }
 
         // Now delete the profile; should be back to old count
-        try
-        {
+        try {
             db.deleteByLoginName( loginName );
-            if ( db.getWikiNames().length != oldUserCount )
-            {
+            if( db.getWikiNames().length != oldUserCount ) {
                 m_session.addMessage( ERROR_DB, "Could not delete a test user from the database." );
                 return;
             }
             m_session.addMessage( INFO_DB, "The user database allows users to be deleted, as it should." );
-        }
-        catch ( final WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             m_session.addMessage( ERROR_DB, "Could not delete a test user to the database: " + e.getMessage() );
             return;
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/DummyUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/DummyUserDatabase.java
new file mode 100644
index 0000000..af4aea6
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/DummyUserDatabase.java
@@ -0,0 +1,135 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+package org.apache.wiki.auth.user;
+
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.auth.NoSuchPrincipalException;
+
+import java.security.Principal;
+import java.util.Properties;
+
+
+/**
+ * This is a database that gets used if nothing else is available. It does nothing of note - it just mostly throws
+ * NoSuchPrincipalExceptions if someone tries to log in.
+ */
+public class DummyUserDatabase extends AbstractUserDatabase {
+
+    /**
+     * No-op.
+     * @param loginName the login name to delete
+     */
+    @Override
+    public void deleteByLoginName( final String loginName ) {
+        // No operation
+    }
+
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param index the name to search for
+     * @return the user profile
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public UserProfile findByEmail(final String index) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param index the name to search for
+     * @return the user profile
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public UserProfile findByFullName(final String index) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param index the name to search for
+     * @return the user profile
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public UserProfile findByLoginName(final String index) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param uid the unique identifier to search for
+     * @return the user profile
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param index the name to search for
+     * @return the user profile
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public UserProfile findByWikiName(final String index) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+
+    /**
+     * No-op.
+     * @return a zero-length array
+     */
+    @Override
+    public Principal[] getWikiNames() {
+        return new Principal[0];
+    }
+
+    /**
+     * No-op.
+     *
+     * @param engine the wiki engine
+     * @param props the properties used to initialize the wiki engine
+     */
+    @Override
+    public void initialize( final Engine engine, final Properties props ) {
+    }
+
+    /**
+     * No-op; always throws <code>NoSuchPrincipalException</code>.
+     * @param loginName the login name
+     * @param newName the proposed new login name
+     * @throws NoSuchPrincipalException always...
+     */
+    @Override
+    public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException {
+        throw new NoSuchPrincipalException("No user profiles available");
+    }
+
+    /**
+     * No-op.
+     * @param profile the user profile
+     */
+    @Override
+    public void save( final UserProfile profile ) {
+    }
+
+}


[jspwiki] 14/38: JSPWIKI-120: rename + extract interface from AuthorizationManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit f1b62ab54488614ac209b26ffa727504df5cf81d
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 18:43:16 2020 +0100

    JSPWIKI-120: rename + extract interface from AuthorizationManager
---
 .../org/apache/wiki/auth/AuthorizationManager.java | 654 +++------------------
 .../main/java/org/apache/wiki/auth/Authorizer.java |  10 +-
 .../wiki/auth/DefaultAuthorizationManager.java     | 425 +++++++++++++
 .../apache/wiki/auth/authorize/GroupDatabase.java  |   4 +-
 .../apache/wiki/auth/authorize/GroupManager.java   | 141 +++--
 .../wiki/auth/authorize/JDBCGroupDatabase.java     | 118 ++--
 .../apache/wiki/auth/authorize/WebAuthorizer.java  |  20 +-
 .../auth/authorize/WebContainerAuthorizer.java     |  92 ++-
 .../wiki/auth/authorize/XMLGroupDatabase.java      |  35 +-
 .../src/main/resources/ini/classmappings.xml       |   2 +-
 .../wiki/auth/AuthenticationManagerTest.java       | 103 ++--
 .../java/org/apache/wiki/auth/TestAuthorizer.java  |  42 +-
 12 files changed, 774 insertions(+), 872 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
index 265cef2..a0ab560 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
@@ -18,382 +18,145 @@
  */
 package org.apache.wiki.auth;
 
-
-import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiSession;
-import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
-import org.apache.wiki.auth.acl.Acl;
-import org.apache.wiki.auth.acl.AclEntry;
-import org.apache.wiki.auth.acl.UnresolvedPrincipal;
 import org.apache.wiki.auth.authorize.Role;
-import org.apache.wiki.auth.permissions.AllPermission;
-import org.apache.wiki.auth.permissions.PagePermission;
-import org.apache.wiki.auth.user.UserDatabase;
-import org.apache.wiki.auth.user.UserProfile;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
-import org.apache.wiki.i18n.InternationalizationManager;
-import org.apache.wiki.preferences.Preferences;
-import org.apache.wiki.util.ClassUtil;
-import org.freshcookies.security.policy.LocalPolicy;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.File;
 import java.io.IOException;
-import java.net.URL;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Map;
 import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.WeakHashMap;
+
 
 /**
- * <p>Manages all access control and authorization; determines what authenticated
- * users are allowed to do.</p>
- * <p>Privileges in JSPWiki are expressed as Java-standard {@link java.security.Permission}
- * classes. There are two types of permissions:</p>
+ * <p>Manages all access control and authorization; determines what authenticated users are allowed to do.</p>
+ * <p>Privileges in JSPWiki are expressed as Java-standard {@link java.security.Permission} classes. There are two types of permissions:</p>
  * <ul>
- *   <li>{@link org.apache.wiki.auth.permissions.WikiPermission} - privileges that apply
- *   to an entire wiki instance: <em>e.g.,</em> editing user profiles, creating pages, creating groups</li>
- *   <li>{@link org.apache.wiki.auth.permissions.PagePermission} - privileges that apply
- *   to a single wiki page or range of pages: <em>e.g.,</em> reading, editing, renaming
+ *   <li>{@link org.apache.wiki.auth.permissions.WikiPermission} - privileges that apply to an entire wiki instance: <em>e.g.,</em>
+ *   editing user profiles, creating pages, creating groups</li>
+ *   <li>{@link org.apache.wiki.auth.permissions.PagePermission} - privileges that apply to a single wiki page or range of pages:
+ *   <em>e.g.,</em> reading, editing, renaming
  * </ul>
- * <p>Calling classes determine whether they are entitled to perform a particular action
- * by constructing the appropriate permission first, then passing it and the current
- * {@link org.apache.wiki.WikiSession} to the
- * {@link #checkPermission(WikiSession, Permission)} method. If the session's
- * Subject possesses the permission, the action is allowed.</p>
- * <p>For WikiPermissions, the decision criteria is relatively simple: the caller either
- * possesses the permission, as granted by the wiki security policy -- or not.</p>
- * <p>For PagePermissions, the logic is exactly the same if the page being checked
- * does not have an access control list. However, if the page does have an ACL, the
- * authorization decision is made based the <em>union</em> of the permissions
- * granted in the ACL and in the security policy. In other words, the user must
- * be named in the ACL (or belong to a group or role that is named in the ACL)
- * <em>and</em> be granted (at least) the same permission in the security policy. We
- * do this to prevent a user from gaining more permissions than they already
- * have, based on the security policy.</p>
- * <p>See the {@link #checkPermission(WikiSession, Permission)} and
- * {@link #hasRoleOrPrincipal(WikiSession, Principal)} methods for more information
- * on the authorization logic.</p>
+ * <p>Calling classes determine whether they are entitled to perform a particular action by constructing the appropriate permission first,
+ * then passing it and the current {@link org.apache.wiki.WikiSession} to the {@link #checkPermission(WikiSession, Permission)} method. If
+ * the session's Subject possesses the permission, the action is allowed.</p>
+ * <p>For WikiPermissions, the decision criteria is relatively simple: the caller either possesses the permission, as granted by the wiki
+ * security policy -- or not.</p>
+ * <p>For PagePermissions, the logic is exactly the same if the page being checked does not have an access control list. However, if the
+ * page does have an ACL, the authorization decision is made based the <em>union</em> of the permissions granted in the ACL and in the
+ * security policy. In other words, the user must be named in the ACL (or belong to a group or role that is named in the ACL) <em>and</em>
+ * be granted (at least) the same permission in the security policy. We do this to prevent a user from gaining more permissions than they
+ * already have, based on the security policy.</p>
+ * <p>See the implementation on {@link #checkPermission(WikiSession, Permission)} method for more information on the authorization logic.</p>
+ *
  * @since 2.3
  * @see AuthenticationManager
  */
-public class AuthorizationManager {
+public interface AuthorizationManager {
 
-    private static final Logger log = Logger.getLogger( AuthorizationManager.class );
-    /**
-     * The default external Authorizer is the {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer}
-     */
-    public static final String                DEFAULT_AUTHORIZER = "org.apache.wiki.auth.authorize.WebContainerAuthorizer";
+    /** The default external Authorizer is the {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer} */
+    String DEFAULT_AUTHORIZER = "org.apache.wiki.auth.authorize.WebContainerAuthorizer";
 
     /** Property that supplies the security policy file name, in WEB-INF. */
-    protected static final String             POLICY      = "jspwiki.policy.file";
+    String POLICY = "jspwiki.policy.file";
 
     /** Name of the default security policy file, in WEB-INF. */
-    protected static final String             DEFAULT_POLICY      = "jspwiki.policy";
-
-    /**
-     * The property name in jspwiki.properties for specifying the external {@link Authorizer}.
-     */
-    public static final String                PROP_AUTHORIZER   = "jspwiki.authorizer";
+    String DEFAULT_POLICY = "jspwiki.policy";
 
-    private Authorizer                        m_authorizer      = null;
-
-    /** Cache for storing ProtectionDomains used to evaluate the local policy. */
-    private Map<Principal, ProtectionDomain>                               m_cachedPds       = new WeakHashMap<>();
-
-    private WikiEngine                        m_engine          = null;
-
-    private LocalPolicy                       m_localPolicy     = null;
+    /** The property name in jspwiki.properties for specifying the external {@link Authorizer}. */
+    String PROP_AUTHORIZER = "jspwiki.authorizer";
 
     /**
-     * Constructs a new AuthorizationManager instance.
-     */
-    public AuthorizationManager()
-    {
-    }
-
-    /**
-     * Returns <code>true</code> or <code>false</code>, depending on
-     * whether a Permission is allowed for the Subject associated with
+     * Returns <code>true</code> or <code>false</code>, depending on whether a Permission is allowed for the Subject associated with
      * a supplied WikiSession. The access control algorithm works this way:
      * <ol>
      * <li>The {@link org.apache.wiki.auth.acl.Acl} for the page is obtained</li>
-     * <li>The Subject associated with the current
-     * {@link org.apache.wiki.WikiSession} is obtained</li>
-     * <li>If the Subject's Principal set includes the Role Principal that is
-     * the administrator group, always allow the Permission</li>
-     * <li>For all permissions, check to see if the Permission is allowed according
-     * to the default security policy. If it isn't, deny the permission and halt
-     * further processing.</li>
-     * <li>If there is an Acl, get the list of Principals assigned this
-     * Permission in the Acl: these will be role, group or user Principals, or
-     * {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}s (see below).
-     * Then iterate through the Subject's Principal set and determine whether
-     * the user (Subject) possesses any one of these specified Roles or
-     * Principals. The matching process delegates to
-     * {@link #hasRoleOrPrincipal(WikiSession, Principal)}.
+     * <li>The Subject associated with the current {@link org.apache.wiki.WikiSession} is obtained</li>
+     * <li>If the Subject's Principal set includes the Role Principal that is the administrator group, always allow the Permission</li>
+     * <li>For all permissions, check to see if the Permission is allowed according to the default security policy. If it isn't, deny
+     * the permission and halt further processing.</li>
+     * <li>If there is an Acl, get the list of Principals assigned this Permission in the Acl: these will be role, group or user Principals,
+     * or {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}s (see below). Then iterate through the Subject's Principal set and determine
+     * whether the user (Subject) possesses any one of these specified Roles or Principals.</li>
      * </ol>
      * <p>
-     * Note that when iterating through the Acl's list of authorized Principals,
-     * it is possible that one or more of the Acl's Principal entries are of
-     * type <code>UnresolvedPrincipal</code>. This means that the last time
-     * the ACL was read, the Principal (user, built-in Role, authorizer Role, or
-     * wiki Group) could not be resolved: the Role was not valid, the user
-     * wasn't found in the UserDatabase, or the Group wasn't known to (e.g.,
-     * cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is
-     * encountered, this method will attempt to resolve it first <em>before</em>
-     * checking to see if the Subject possesses this principal, by calling
-     * {@link #resolvePrincipal(String)}. If the (re-)resolution does not
-     * succeed, the access check for the principal will fail by definition (the
-     * Subject should never contain UnresolvedPrincipals).
+     * Note that when iterating through the Acl's list of authorized Principals, it is possible that one or more of the Acl's Principal
+     * entries are of type <code>UnresolvedPrincipal</code>. This means that the last time the ACL was read, the Principal (user, built-in
+     * Role, authorizer Role, or wiki Group) could not be resolved: the Role was not valid, the user wasn't found in the UserDatabase, or
+     * the Group wasn't known to (e.g., cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is encountered, this method
+     * will attempt to resolve it first <em>before</em> checking to see if the Subject possesses this principal, by calling
+     * {@link #resolvePrincipal(String)}. If the (re-)resolution does not succeed, the access check for the principal will fail by
+     * definition (the Subject should never contain UnresolvedPrincipals).
      * </p>
      * <p>
      * If security not set to JAAS, will return true.
      * </p>
+     *
      * @param session the current wiki session
      * @param permission the Permission being checked
-     * @see #hasRoleOrPrincipal(WikiSession, Principal)
      * @return the result of the Permission check
      */
-    public boolean checkPermission( final WikiSession session, final Permission permission )
-    {
-        //
-        //  A slight sanity check.
-        //
-        if ( session == null || permission == null )
-        {
-            fireEvent( WikiSecurityEvent.ACCESS_DENIED, null, permission );
-            return false;
-        }
-
-        final Principal user = session.getLoginPrincipal();
-
-        // Always allow the action if user has AllPermission
-        final Permission allPermission = new AllPermission( m_engine.getApplicationName() );
-        final boolean hasAllPermission = checkStaticPermission( session, allPermission );
-        if ( hasAllPermission )
-        {
-            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
-            return true;
-        }
-
-        // If the user doesn't have *at least* the permission
-        // granted by policy, return false.
-        final boolean hasPolicyPermission = checkStaticPermission( session, permission );
-        if ( !hasPolicyPermission )
-        {
-            fireEvent( WikiSecurityEvent.ACCESS_DENIED, user, permission );
-            return false;
-        }
-
-        // If this isn't a PagePermission, it's allowed
-        if ( ! ( permission instanceof PagePermission ) )
-        {
-            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
-            return true;
-        }
-
-        //
-        // If the page or ACL is null, it's allowed.
-        //
-        final String pageName = ((PagePermission)permission).getPage();
-        final WikiPage page = m_engine.getPageManager().getPage( pageName );
-        final Acl acl = ( page == null) ? null : m_engine.getAclManager().getPermissions( page );
-        if ( page == null ||  acl == null || acl.isEmpty() )
-        {
-            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
-            return true;
-        }
-
-        //
-        //  Next, iterate through the Principal objects assigned
-        //  this permission. If the context's subject possesses
-        //  any of these, the action is allowed.
-
-        final Principal[] aclPrincipals = acl.findPrincipals( permission );
-
-        log.debug( "Checking ACL entries..." );
-        log.debug( "Acl for this page is: " + acl );
-        log.debug( "Checking for principal: " + Arrays.toString( aclPrincipals ) );
-        log.debug( "Permission: " + permission );
-
-        for( Principal aclPrincipal : aclPrincipals )
-        {
-            // If the ACL principal we're looking at is unresolved,
-            // try to resolve it here & correct the Acl
-            if ( aclPrincipal instanceof UnresolvedPrincipal )
-            {
-                final AclEntry aclEntry = acl.getEntry( aclPrincipal );
-                aclPrincipal = resolvePrincipal( aclPrincipal.getName() );
-                if ( aclEntry != null && !( aclPrincipal instanceof UnresolvedPrincipal ) )
-                {
-                    aclEntry.setPrincipal( aclPrincipal );
-                }
-            }
-
-            if ( hasRoleOrPrincipal( session, aclPrincipal ) )
-            {
-                fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
-                return true;
-            }
-        }
-        fireEvent( WikiSecurityEvent.ACCESS_DENIED, user, permission );
-        return false;
-    }
+    boolean checkPermission( WikiSession session, Permission permission );
 
     /**
-     * <p>Determines if the Subject associated with a
-     * supplied WikiSession contains a desired Role or GroupPrincipal.
-     * The algorithm simply checks to see if the Subject possesses
-     * the Role or GroupPrincipal it in its Principal set. Note that
-     * any user (anonymous, asserted, authenticated) can possess
-     * a built-in role. But a user <em>must</em> be authenticated to
-     * possess a role other than one of the built-in ones.
-     * We do this to prevent privilege escalation.</p>
+     * <p>Determines if the Subject associated with a supplied WikiSession contains a desired Role or GroupPrincipal. The algorithm
+     * simply checks to see if the Subject possesses the Role or GroupPrincipal it in its Principal set. Note that any user (anonymous,
+     * asserted, authenticated) can possess a built-in role. But a user <em>must</em> be authenticated to possess a role other than one
+     * of the built-in ones. We do this to prevent privilege escalation.</p>
      * <p>For all other cases, this method returns <code>false</code>.</p>
-     * <p>Note that this method does <em>not</em> consult the external
-     * Authorizer or GroupManager; it relies on the Principals that
-     * have been injected into the user's Subject at login time, or
-     * after group creation/modification/deletion.</p>
-     * @param session the current wiki session, which must be non-null. If null,
-     *            the result of this method always returns <code>false</code>
-     * @param principal the Principal (role or group principal) to look
-     *            for, which must be non-<code>null</code>. If <code>null</code>,
-     *            the result of this method always returns <code>false</code>
-     * @return <code>true</code> if the Subject supplied with the WikiContext
-     *         posesses the Role or GroupPrincipal, <code>false</code> otherwise
+     * <p>Note that this method does <em>not</em> consult the external Authorizer or GroupManager; it relies on the Principals that
+     * have been injected into the user's Subject at login time, or after group creation/modification/deletion.</p>
+     *
+     * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
+     * @param principal the Principal (role or group principal) to look for, which must be non-<code>null</code>. If <code>null</code>,
+     *                  the result of this method always returns <code>false</code>
+     * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role or GroupPrincipal, <code>false</code> otherwise
      */
-    public boolean isUserInRole( final WikiSession session, final Principal principal )
-    {
-        if ( session == null || principal == null ||
-             AuthenticationManager.isUserPrincipal( principal ) )
-        {
+    default boolean isUserInRole( final WikiSession session, final Principal principal ) {
+        if ( session == null || principal == null || AuthenticationManager.isUserPrincipal( principal ) ) {
             return false;
         }
 
         // Any type of user can possess a built-in role
-        if ( principal instanceof Role && Role.isBuiltInRole( (Role)principal ) )
-        {
+        if ( principal instanceof Role && Role.isBuiltInRole( (Role)principal ) ) {
             return session.hasPrincipal( principal );
         }
 
         // Only authenticated users can possess groups or custom roles
-        if ( session.isAuthenticated() && AuthenticationManager.isRolePrincipal( principal ) )
-        {
+        if ( session.isAuthenticated() && AuthenticationManager.isRolePrincipal( principal ) ) {
             return session.hasPrincipal( principal );
         }
         return false;
     }
 
     /**
-     * Returns the current external {@link Authorizer} in use. This method
-     * is guaranteed to return a properly-initialized Authorizer, unless
-     * it could not be initialized. In that case, this method throws
-     * a {@link org.apache.wiki.auth.WikiSecurityException}.
-     * @throws org.apache.wiki.auth.WikiSecurityException if the Authorizer could
-     * not be initialized
+     * Returns the current external {@link Authorizer} in use. This method is guaranteed to return a properly-initialized Authorizer, unless
+     * it could not be initialized. In that case, this method throws a {@link org.apache.wiki.auth.WikiSecurityException}.
+     *
+     * @throws org.apache.wiki.auth.WikiSecurityException if the Authorizer could not be initialized
      * @return the current Authorizer
      */
-    public Authorizer getAuthorizer() throws WikiSecurityException
-    {
-        if ( m_authorizer != null )
-        {
-            return m_authorizer;
-        }
-        throw new WikiSecurityException( "Authorizer did not initialize properly. Check the logs." );
-    }
-
-    /**
-     * <p>Determines if the Subject associated with a supplied WikiSession contains
-     * a desired user Principal or built-in Role principal, OR is a member a
-     * Group or external Role. The rules are as follows:</p>
-     * <ol>
-     * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to
-     * {@link #isUserInRole(WikiSession, Principal)} and
-     * return the result.</li>
-     * <li>Otherwise, we're looking for a user Principal,
-     * so iterate through the Principal set and see if
-     * any share the same name as the one we are looking for.</li>
-     * </ol>
-     * <p><em>Note: if the Principal parameter is a user principal, the session
-     * must be authenticated in order for the user to "possess it". Anonymous
-     * or asserted sessions will never posseess a named user principal.</em></p>
-     * @param session the current wiki session, which must be non-null. If null,
-     *            the result of this method always returns <code>false</code>
-     * @param principal the Principal (role, group, or user principal) to look
-     *            for, which must be non-null. If null, the result of this
-     *            method always returns <code>false</code>
-     * @return <code>true</code> if the Subject supplied with the WikiContext
-     *         posesses the Role, GroupPrincipal or desired
-     *         user Principal, <code>false</code> otherwise
-     */
-    protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal )
-    {
-        // If either parameter is null, always deny
-        if( session == null || principal == null )
-        {
-            return false;
-        }
-
-        // If principal is role, delegate to isUserInRole
-        if( AuthenticationManager.isRolePrincipal( principal ) )
-        {
-            return isUserInRole( session, principal );
-        }
-
-        // We must be looking for a user principal, assuming that the user
-        // has been properly logged in.
-        // So just look for a name match.
-        if( session.isAuthenticated() && AuthenticationManager.isUserPrincipal( principal ) )
-        {
-            final String principalName = principal.getName();
-            final Principal[] userPrincipals = session.getPrincipals();
-            for( final Principal userPrincipal : userPrincipals )
-            {
-                if( userPrincipal.getName().equals( principalName ) )
-                {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
+    Authorizer getAuthorizer() throws WikiSecurityException;
 
     /**
-     * Checks whether the current user has access to the wiki context,
-     * by obtaining the required Permission ({@link WikiContext#requiredPermission()})
-     * and delegating the access check to {@link #checkPermission(WikiSession, Permission)}.
-     * If the user is allowed, this method returns <code>true</code>;
-     * <code>false</code> otherwise. If access is allowed,
-     * the wiki context will be added to the request as an attribute
-     * with the key name {@link org.apache.wiki.WikiContext#ATTR_CONTEXT}.
-     * Note that this method will automatically redirect the user to
-     * a login or error page, as appropriate, if access fails. This is
-     * NOT guaranteed to be default behavior in the future.
+     * Checks whether the current user has access to the wiki context, by obtaining the required Permission ({@link WikiContext#requiredPermission()})
+     * and delegating the access check to {@link #checkPermission(WikiSession, Permission)}. If the user is allowed, this method returns
+     * <code>true</code>; <code>false</code> otherwise. If access is allowed, the wiki context will be added to the request as an attribute
+     * with the key name {@link org.apache.wiki.WikiContext#ATTR_CONTEXT}. Note that this method will automatically redirect the user to
+     * a login or error page, as appropriate, if access fails. This is NOT guaranteed to be default behavior in the future.
      *
      * @param context wiki context to check if it is accesible
      * @param response the http response
      * @return the result of the access check
      * @throws IOException In case something goes wrong
      */
-    public boolean hasAccess( final WikiContext context, final HttpServletResponse response ) throws IOException
-    {
+    default boolean hasAccess( final WikiContext context, final HttpServletResponse response ) throws IOException {
         return hasAccess( context, response, true );
     }
 
@@ -411,294 +174,63 @@ public class AuthorizationManager {
      * @return the result of the access check
      * @throws IOException If something goes wrong
      */
-    public boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException {
-        final boolean allowed = checkPermission( context.getWikiSession(), context.requiredPermission() );
-        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-
-        // Stash the wiki context
-        if ( context.getHttpRequest() != null && context.getHttpRequest().getAttribute( WikiContext.ATTR_CONTEXT ) == null ) {
-            context.getHttpRequest().setAttribute( WikiContext.ATTR_CONTEXT, context );
-        }
-
-        // If access not allowed, redirect
-        if( !allowed && redirect ) {
-            final Principal currentUser  = context.getWikiSession().getUserPrincipal();
-            final String pageurl = context.getPage().getName();
-            if( context.getWikiSession().isAuthenticated() ) {
-                log.info("User "+currentUser.getName()+" has no access - forbidden (permission=" + context.requiredPermission() + ")" );
-                context.getWikiSession().addMessage( MessageFormat.format( rb.getString( "security.error.noaccess.logged" ),
-                                                     context.getName()) );
-            } else {
-                log.info("User "+currentUser.getName()+" has no access - redirecting (permission=" + context.requiredPermission() + ")");
-                context.getWikiSession().addMessage( MessageFormat.format( rb.getString("security.error.noaccess"), context.getName() ) );
-            }
-            response.sendRedirect( m_engine.getURL(WikiContext.LOGIN, pageurl, null ) );
-        }
-        return allowed;
-    }
+    boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException;
 
     /**
-     * Initializes AuthorizationManager with an engine and set of properties.
-     * Expects to find property 'jspwiki.authorizer' with a valid Authorizer
-     * implementation name to take care of role lookup operations.
+     * Initializes AuthorizationManager with an engine and set of properties. Expects to find property 'jspwiki.authorizer' with a valid
+     * Authorizer implementation name to take care of role lookup operations.
+     *
      * @param engine the wiki engine
      * @param properties the set of properties used to initialize the wiki engine
      * @throws WikiException if the AuthorizationManager cannot be initialized
      */
-    public void initialize( final WikiEngine engine, final Properties properties ) throws WikiException {
-        m_engine = engine;
-
-        //
-        //  JAAS authorization continues
-        //
-        m_authorizer = getAuthorizerImplementation( properties );
-        m_authorizer.initialize( engine, properties );
-
-        // Initialize local security policy
-        try {
-            final String policyFileName = properties.getProperty( POLICY, DEFAULT_POLICY );
-            final URL policyURL = engine.findConfigFile( policyFileName );
-
-            if (policyURL != null) {
-                final File policyFile = new File( policyURL.toURI().getPath() );
-                log.info("We found security policy URL: " + policyURL + " and transformed it to file " + policyFile.getAbsolutePath());
-                m_localPolicy = new LocalPolicy( policyFile, engine.getContentEncoding().displayName() );
-                m_localPolicy.refresh();
-                log.info( "Initialized default security policy: " + policyFile.getAbsolutePath() );
-            } else {
-                final String sb = "JSPWiki was unable to initialize the default security policy (WEB-INF/jspwiki.policy) file. " +
-                                  "Please ensure that the jspwiki.policy file exists in the default location. " +
-                		          "This file should exist regardless of the existance of a global policy file. " +
-                                  "The global policy file is identified by the java.security.policy variable. ";
-                final WikiSecurityException wse = new WikiSecurityException( sb );
-                log.fatal( sb, wse );
-                throw wse;
-            }
-        } catch ( final Exception e) {
-            log.error("Could not initialize local security policy: " + e.getMessage() );
-            throw new WikiException( "Could not initialize local security policy: " + e.getMessage(), e );
-        }
-    }
-
-    /**
-     * Attempts to locate and initialize a Authorizer to use with this manager.
-     * Throws a WikiException if no entry is found, or if one fails to
-     * initialize.
-     * @param props jspwiki.properties, containing a
-     *            'jspwiki.authorization.provider' class name
-     * @return a Authorizer used to get page authorization information
-     * @throws WikiException
-     */
-    private Authorizer getAuthorizerImplementation( final Properties props ) throws WikiException {
-        final String authClassName = props.getProperty( PROP_AUTHORIZER, DEFAULT_AUTHORIZER );
-        return ( Authorizer )locateImplementation( authClassName );
-    }
-
-    private Object locateImplementation( final String clazz ) throws WikiException {
-        if ( clazz != null ) {
-            try {
-                final Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
-                final Object impl = authClass.newInstance();
-                return impl;
-            } catch( final ClassNotFoundException e ) {
-                log.fatal( "Authorizer " + clazz + " cannot be found", e );
-                throw new WikiException( "Authorizer " + clazz + " cannot be found", e );
-            } catch( final InstantiationException e ) {
-                log.fatal( "Authorizer " + clazz + " cannot be created", e );
-                throw new WikiException( "Authorizer " + clazz + " cannot be created", e );
-            } catch( final IllegalAccessException e ) {
-                log.fatal( "You are not allowed to access this authorizer class", e );
-                throw new WikiException( "You are not allowed to access this authorizer class", e );
-            }
-        }
-
-        throw new NoRequiredPropertyException( "Unable to find a " + PROP_AUTHORIZER + " entry in the properties.",
-                                               PROP_AUTHORIZER );
-    }
-
-    /**
-     * Checks to see if the local security policy allows a particular static Permission.
-     * Do not use this method for normal permission checks; use
-     * {@link #checkPermission(WikiSession, Permission)} instead.
-     * @param principals the Principals to check
-     * @param permission the Permission
-     * @return the result
-     */
-    protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission )
-    {
-        for ( final Principal principal : principals )
-        {
-            // Get ProtectionDomain for this Principal from cache, or create new one
-            ProtectionDomain pd = m_cachedPds.get( principal );
-            if ( pd == null )
-            {
-                final ClassLoader cl = this.getClass().getClassLoader();
-                final CodeSource cs = new CodeSource( null, (Certificate[])null );
-                pd = new ProtectionDomain( cs, null, cl, new Principal[]{ principal } );
-                m_cachedPds.put( principal, pd );
-            }
-
-            // Consult the local policy and get the answer
-            if ( m_localPolicy.implies( pd, permission ) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
+    void initialize( final Engine engine, final Properties properties ) throws WikiException;
 
     /**
-     * Determines whether a Subject possesses a given "static" Permission as
-     * defined in the security policy file. This method uses standard Java 2
-     * security calls to do its work. Note that the current access control
-     * context's <code>codeBase</code> is effectively <em>this class</em>,
-     * not that of the caller. Therefore, this method will work best when what
-     * matters in the policy is <em>who</em> makes the permission check, not
-     * what the caller's code source is. Internally, this method works by
-     * executing <code>Subject.doAsPrivileged</code> with a privileged action
-     * that simply calls {@link java.security.AccessController#checkPermission(Permission)}.
-     * @see AccessController#checkPermission(java.security.Permission) . A
-     *       caught exception (or lack thereof) determines whether the privilege
-     *       is absent (or present).
-     * @param session the WikiSession whose permission status is being queried
-     * @param permission the Permission the Subject must possess
-     * @return <code>true</code> if the Subject possesses the permission,
-     *         <code>false</code> otherwise
-     */
-    protected boolean checkStaticPermission( final WikiSession session, final Permission permission )
-    {
-        final Boolean allowed = (Boolean) WikiSession.doPrivileged( session, new PrivilegedAction<Boolean>()
-        {
-            @Override public Boolean run()
-            {
-                try
-                {
-                    // Check the JVM-wide security policy first
-                    AccessController.checkPermission( permission );
-                    return Boolean.TRUE;
-                }
-                catch( final AccessControlException e )
-                {
-                    // Global policy denied the permission
-                }
-
-                // Try the local policy - check each Role/Group and User Principal
-                if ( allowedByLocalPolicy( session.getRoles(), permission ) ||
-                     allowedByLocalPolicy( session.getPrincipals(), permission ) )
-                {
-                    return Boolean.TRUE;
-                }
-                return Boolean.FALSE;
-            }
-        } );
-        return allowed.booleanValue();
-    }
-
-    /**
-     * <p>Given a supplied string representing a Principal's name from an Acl, this
-     * method resolves the correct type of Principal (role, group, or user).
-     * This method is guaranteed to always return a Principal.
-     * The algorithm is straightforward:</p>
+     * <p>Given a supplied string representing a Principal's name from an Acl, this method resolves the correct type of Principal (role,
+     * group, or user). This method is guaranteed to always return a Principal. The algorithm is straightforward:</p>
      * <ol>
-     * <li>If the name matches one of the built-in {@link org.apache.wiki.auth.authorize.Role} names,
-     * return that built-in Role</li>
-     * <li>If the name matches one supplied by the current
-     * {@link org.apache.wiki.auth.Authorizer}, return that Role</li>
-     * <li>If the name matches a group managed by the
-     * current {@link org.apache.wiki.auth.authorize.GroupManager}, return that Group</li>
-     * <li>Otherwise, assume that the name represents a user
-     * principal. Using the current {@link org.apache.wiki.auth.user.UserDatabase}, find the
-     * first user who matches the supplied name by calling
-     * {@link org.apache.wiki.auth.user.UserDatabase#find(String)}.</li>
-     * <li>Finally, if a user cannot be found, manufacture
-     * and return a generic {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}</li>
+     * <li>If the name matches one of the built-in {@link org.apache.wiki.auth.authorize.Role} names, return that built-in Role</li>
+     * <li>If the name matches one supplied by the current {@link org.apache.wiki.auth.Authorizer}, return that Role</li>
+     * <li>If the name matches a group managed by the current {@link org.apache.wiki.auth.authorize.GroupManager}, return that Group</li>
+     * <li>Otherwise, assume that the name represents a user principal. Using the current {@link org.apache.wiki.auth.user.UserDatabase},
+     * find the first user who matches the supplied name by calling {@link org.apache.wiki.auth.user.UserDatabase#find(String)}.</li>
+     * <li>Finally, if a user cannot be found, manufacture and return a generic {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}</li>
      * </ol>
+     *
      * @param name the name of the Principal to resolve
      * @return the fully-resolved Principal
      */
-    public Principal resolvePrincipal( final String name )
-    {
-        // Check built-in Roles first
-        final Role role = new Role(name);
-        if ( Role.isBuiltInRole( role ) )
-        {
-            return role;
-        }
-
-        // Check Authorizer Roles
-        Principal principal = m_authorizer.findRole( name );
-        if ( principal != null )
-        {
-            return principal;
-        }
-
-        // Check Groups
-        principal = m_engine.getGroupManager().findRole( name );
-        if ( principal != null )
-        {
-            return principal;
-        }
-
-        // Ok, no luck---this must be a user principal
-        Principal[] principals = null;
-        UserProfile profile = null;
-        final UserDatabase db = m_engine.getUserManager().getUserDatabase();
-        try
-        {
-            profile = db.find( name );
-            principals = db.getPrincipals( profile.getLoginName() );
-            for (int i = 0; i < principals.length; i++)
-            {
-                principal = principals[i];
-                if ( principal.getName().equals( name ) )
-                {
-                    return principal;
-                }
-            }
-        }
-        catch( final NoSuchPrincipalException e )
-        {
-            // We couldn't find the user...
-        }
-        // Ok, no luck---mark this as unresolved and move on
-        return new UnresolvedPrincipal( name );
-    }
+    Principal resolvePrincipal( final String name );
 
 
     // events processing .......................................................
 
     /**
      * Registers a WikiEventListener with this instance.
+     *
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( final WikiEventListener listener )
-    {
-        WikiEventManager.addWikiEventListener( this, listener );
-    }
+    void addWikiEventListener( WikiEventListener listener );
 
     /**
      * Un-registers a WikiEventListener with this instance.
+     *
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( final WikiEventListener listener )
-    {
-        WikiEventManager.removeWikiEventListener( this, listener );
-    }
+    void removeWikiEventListener( final WikiEventListener listener );
 
     /**
-     *  Fires a WikiSecurityEvent of the provided type, user,
-     *  and permission to all registered listeners.
+     * Fires a WikiSecurityEvent of the provided type, user, and permission to all registered listeners.
      *
      * @see org.apache.wiki.event.WikiSecurityEvent
      * @param type        the event type to be fired
      * @param user        the user associated with the event
      * @param permission  the permission the subject must possess
      */
-    protected void fireEvent( final int type, final Principal user, final Object permission )
-    {
-        if ( WikiEventManager.isListening(this) )
-        {
-            WikiEventManager.fireEvent(this,new WikiSecurityEvent(this,type,user,permission));
+    default void fireEvent( final int type, final Principal user, final Object permission ) {
+        if( WikiEventManager.isListening( this ) ) {
+            WikiEventManager.fireEvent( this, new WikiSecurityEvent( this, type, user, permission ) );
         }
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
index 36d44c2..13f82c2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
@@ -18,11 +18,12 @@
  */
 package org.apache.wiki.auth;
 
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+
 import java.security.Principal;
 import java.util.Properties;
 
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiSession;
 
 /**
  * Interface for service providers of authorization information. After a user
@@ -43,8 +44,7 @@ import org.apache.wiki.WikiSession;
  * 
  * @since 2.3
  */
-public interface Authorizer
-{
+public interface Authorizer {
 
     /**
      * Returns an array of role Principals this Authorizer knows about. This
@@ -74,7 +74,7 @@ public interface Authorizer
      * @param props the wiki engine initialization properties
      * @throws WikiSecurityException if the Authorizer could not be initialized
      */
-    void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException;
+    void initialize( Engine engine, Properties props ) throws WikiSecurityException;
 
     /**
      * Determines whether the Subject associated with a WikiSession is in a
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
new file mode 100644
index 0000000..a388a08
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
@@ -0,0 +1,425 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+package org.apache.wiki.auth;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.acl.Acl;
+import org.apache.wiki.auth.acl.AclEntry;
+import org.apache.wiki.auth.acl.AclManager;
+import org.apache.wiki.auth.acl.UnresolvedPrincipal;
+import org.apache.wiki.auth.authorize.GroupManager;
+import org.apache.wiki.auth.authorize.Role;
+import org.apache.wiki.auth.permissions.AllPermission;
+import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.auth.user.UserDatabase;
+import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.event.WikiEventListener;
+import org.apache.wiki.event.WikiEventManager;
+import org.apache.wiki.event.WikiSecurityEvent;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.util.ClassUtil;
+import org.freshcookies.security.policy.LocalPolicy;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.WeakHashMap;
+
+
+/**
+ * <p>Default implementation for {@link AuthorizationManager}</p>
+ * {@inheritDoc}
+ *
+ * <p>See the {@link #checkPermission(WikiSession, Permission)} and {@link #hasRoleOrPrincipal(WikiSession, Principal)} methods for more
+ * information on the authorization logic.</p>
+ * @since 2.3
+ * @see AuthenticationManager
+ */
+public class DefaultAuthorizationManager implements AuthorizationManager {
+
+    private static final Logger log = Logger.getLogger( DefaultAuthorizationManager.class );
+
+    private Authorizer m_authorizer = null;
+
+    /** Cache for storing ProtectionDomains used to evaluate the local policy. */
+    private Map< Principal, ProtectionDomain > m_cachedPds = new WeakHashMap<>();
+
+    private Engine m_engine = null;
+
+    private LocalPolicy m_localPolicy = null;
+
+    /**
+     * Constructs a new DefaultAuthorizationManager instance.
+     */
+    public DefaultAuthorizationManager() {
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean checkPermission( final WikiSession session, final Permission permission ) {
+        // A slight sanity check.
+        if( session == null || permission == null ) {
+            fireEvent( WikiSecurityEvent.ACCESS_DENIED, null, permission );
+            return false;
+        }
+
+        final Principal user = session.getLoginPrincipal();
+
+        // Always allow the action if user has AllPermission
+        final Permission allPermission = new AllPermission( m_engine.getApplicationName() );
+        final boolean hasAllPermission = checkStaticPermission( session, allPermission );
+        if( hasAllPermission ) {
+            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
+            return true;
+        }
+
+        // If the user doesn't have *at least* the permission granted by policy, return false.
+        final boolean hasPolicyPermission = checkStaticPermission( session, permission );
+        if( !hasPolicyPermission ) {
+            fireEvent( WikiSecurityEvent.ACCESS_DENIED, user, permission );
+            return false;
+        }
+
+        // If this isn't a PagePermission, it's allowed
+        if( !( permission instanceof PagePermission ) ) {
+            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
+            return true;
+        }
+
+        // If the page or ACL is null, it's allowed.
+        final String pageName = ((PagePermission)permission).getPage();
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pageName );
+        final Acl acl = ( page == null) ? null : m_engine.getManager( AclManager.class ).getPermissions( page );
+        if( page == null ||  acl == null || acl.isEmpty() ) {
+            fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
+            return true;
+        }
+
+        // Next, iterate through the Principal objects assigned this permission. If the context's subject possesses
+        // any of these, the action is allowed.
+        final Principal[] aclPrincipals = acl.findPrincipals( permission );
+
+        log.debug( "Checking ACL entries..." );
+        log.debug( "Acl for this page is: " + acl );
+        log.debug( "Checking for principal: " + Arrays.toString( aclPrincipals ) );
+        log.debug( "Permission: " + permission );
+
+        for( Principal aclPrincipal : aclPrincipals ) {
+            // If the ACL principal we're looking at is unresolved, try to resolve it here & correct the Acl
+            if ( aclPrincipal instanceof UnresolvedPrincipal ) {
+                final AclEntry aclEntry = acl.getEntry( aclPrincipal );
+                aclPrincipal = resolvePrincipal( aclPrincipal.getName() );
+                if ( aclEntry != null && !( aclPrincipal instanceof UnresolvedPrincipal ) ) {
+                    aclEntry.setPrincipal( aclPrincipal );
+                }
+            }
+
+            if ( hasRoleOrPrincipal( session, aclPrincipal ) ) {
+                fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
+                return true;
+            }
+        }
+        fireEvent( WikiSecurityEvent.ACCESS_DENIED, user, permission );
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Authorizer getAuthorizer() throws WikiSecurityException {
+        if ( m_authorizer != null ) {
+            return m_authorizer;
+        }
+        throw new WikiSecurityException( "Authorizer did not initialize properly. Check the logs." );
+    }
+
+    /**
+     * <p>Determines if the Subject associated with a supplied WikiSession contains a desired user Principal or built-in Role principal,
+     * OR is a member a Group or external Role. The rules are as follows:</p>
+     * <ol>
+     * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to {@link #isUserInRole(WikiSession, Principal)} and
+     * return the result.</li>
+     * <li>Otherwise, we're looking for a user Principal, so iterate through the Principal set and see if any share the same name as the
+     * one we are looking for.</li>
+     * </ol>
+     * <p><em>Note: if the Principal parameter is a user principal, the session must be authenticated in order for the user to "possess it".
+     * Anonymous or asserted sessions will never posseess a named user principal.</em></p>
+     *
+     * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
+     * @param principal the Principal (role, group, or user principal) to look for, which must be non-null. If null, the result of this
+     *                  method always returns <code>false</code>
+     * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role, GroupPrincipal or desired
+     *         user Principal, <code>false</code> otherwise
+     */
+    protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal ) {
+        // If either parameter is null, always deny
+        if( session == null || principal == null ) {
+            return false;
+        }
+
+        // If principal is role, delegate to isUserInRole
+        if( AuthenticationManager.isRolePrincipal( principal ) ) {
+            return isUserInRole( session, principal );
+        }
+
+        // We must be looking for a user principal, assuming that the user has been properly logged in. So just look for a name match.
+        if( session.isAuthenticated() && AuthenticationManager.isUserPrincipal( principal ) ) {
+            final String principalName = principal.getName();
+            final Principal[] userPrincipals = session.getPrincipals();
+            for( final Principal userPrincipal : userPrincipals ) {
+                if( userPrincipal.getName().equals( principalName ) ) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException {
+        final boolean allowed = checkPermission( context.getWikiSession(), context.requiredPermission() );
+        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
+
+        // Stash the wiki context
+        if ( context.getHttpRequest() != null && context.getHttpRequest().getAttribute( WikiContext.ATTR_CONTEXT ) == null ) {
+            context.getHttpRequest().setAttribute( WikiContext.ATTR_CONTEXT, context );
+        }
+
+        // If access not allowed, redirect
+        if( !allowed && redirect ) {
+            final Principal currentUser  = context.getWikiSession().getUserPrincipal();
+            final String pageurl = context.getPage().getName();
+            if( context.getWikiSession().isAuthenticated() ) {
+                log.info( "User " + currentUser.getName() + " has no access - forbidden (permission=" + context.requiredPermission() + ")" );
+                context.getWikiSession().addMessage( MessageFormat.format( rb.getString( "security.error.noaccess.logged" ),
+                                                     context.getName()) );
+            } else {
+                log.info( "User " + currentUser.getName() + " has no access - redirecting (permission=" + context.requiredPermission() + ")" );
+                context.getWikiSession().addMessage( MessageFormat.format( rb.getString("security.error.noaccess"), context.getName() ) );
+            }
+            response.sendRedirect( m_engine.getURL(WikiContext.LOGIN, pageurl, null ) );
+        }
+        return allowed;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void initialize( final Engine engine, final Properties properties ) throws WikiException {
+        m_engine = engine;
+
+        //  JAAS authorization continues
+        m_authorizer = getAuthorizerImplementation( properties );
+        m_authorizer.initialize( engine, properties );
+
+        // Initialize local security policy
+        try {
+            final String policyFileName = properties.getProperty( POLICY, DEFAULT_POLICY );
+            final URL policyURL = engine.findConfigFile( policyFileName );
+
+            if (policyURL != null) {
+                final File policyFile = new File( policyURL.toURI().getPath() );
+                log.info("We found security policy URL: " + policyURL + " and transformed it to file " + policyFile.getAbsolutePath());
+                m_localPolicy = new LocalPolicy( policyFile, engine.getContentEncoding().displayName() );
+                m_localPolicy.refresh();
+                log.info( "Initialized default security policy: " + policyFile.getAbsolutePath() );
+            } else {
+                final String sb = "JSPWiki was unable to initialize the default security policy (WEB-INF/jspwiki.policy) file. " +
+                                  "Please ensure that the jspwiki.policy file exists in the default location. " +
+                		          "This file should exist regardless of the existance of a global policy file. " +
+                                  "The global policy file is identified by the java.security.policy variable. ";
+                final WikiSecurityException wse = new WikiSecurityException( sb );
+                log.fatal( sb, wse );
+                throw wse;
+            }
+        } catch ( final Exception e) {
+            log.error("Could not initialize local security policy: " + e.getMessage() );
+            throw new WikiException( "Could not initialize local security policy: " + e.getMessage(), e );
+        }
+    }
+
+    /**
+     * Attempts to locate and initialize a Authorizer to use with this manager. Throws a WikiException if no entry is found, or if one
+     * fails to initialize.
+     *
+     * @param props jspwiki.properties, containing a 'jspwiki.authorization.provider' class name.
+     * @return a Authorizer used to get page authorization information.
+     * @throws WikiException if there are problems finding the authorizer implementation.
+     */
+    private Authorizer getAuthorizerImplementation( final Properties props ) throws WikiException {
+        final String authClassName = props.getProperty( PROP_AUTHORIZER, DEFAULT_AUTHORIZER );
+        return ( Authorizer )locateImplementation( authClassName );
+    }
+
+    private Object locateImplementation( final String clazz ) throws WikiException {
+        if ( clazz != null ) {
+            try {
+                final Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
+                return authClass.newInstance();
+            } catch( final ClassNotFoundException e ) {
+                log.fatal( "Authorizer " + clazz + " cannot be found", e );
+                throw new WikiException( "Authorizer " + clazz + " cannot be found", e );
+            } catch( final InstantiationException e ) {
+                log.fatal( "Authorizer " + clazz + " cannot be created", e );
+                throw new WikiException( "Authorizer " + clazz + " cannot be created", e );
+            } catch( final IllegalAccessException e ) {
+                log.fatal( "You are not allowed to access this authorizer class", e );
+                throw new WikiException( "You are not allowed to access this authorizer class", e );
+            }
+        }
+
+        throw new NoRequiredPropertyException( "Unable to find a " + PROP_AUTHORIZER + " entry in the properties.", PROP_AUTHORIZER );
+    }
+
+    /**
+     * Checks to see if the local security policy allows a particular static Permission.
+     * Do not use this method for normal permission checks; use {@link #checkPermission(WikiSession, Permission)} instead.
+     *
+     * @param principals the Principals to check
+     * @param permission the Permission
+     * @return the result
+     */
+    protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission ) {
+        for ( final Principal principal : principals ) {
+            // Get ProtectionDomain for this Principal from cache, or create new one
+            ProtectionDomain pd = m_cachedPds.get( principal );
+            if ( pd == null ) {
+                final ClassLoader cl = this.getClass().getClassLoader();
+                final CodeSource cs = new CodeSource( null, (Certificate[])null );
+                pd = new ProtectionDomain( cs, null, cl, new Principal[]{ principal } );
+                m_cachedPds.put( principal, pd );
+            }
+
+            // Consult the local policy and get the answer
+            if ( m_localPolicy.implies( pd, permission ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether a Subject possesses a given "static" Permission as defined in the security policy file. This method uses standard
+     * Java 2 security calls to do its work. Note that the current access control context's <code>codeBase</code> is effectively <em>this
+     * class</em>, not that of the caller. Therefore, this method will work best when what matters in the policy is <em>who</em> makes the
+     * permission check, not what the caller's code source is. Internally, this method works by executing <code>Subject.doAsPrivileged</code>
+     * with a privileged action that simply calls {@link AccessController#checkPermission(Permission)}.
+     *
+     * @see AccessController#checkPermission(Permission) . A caught exception (or lack thereof) determines whether the
+     *       privilege is absent (or present).
+     * @param session the WikiSession whose permission status is being queried
+     * @param permission the Permission the Subject must possess
+     * @return <code>true</code> if the Subject possesses the permission, <code>false</code> otherwise
+     */
+    protected boolean checkStaticPermission( final WikiSession session, final Permission permission ) {
+        return ( Boolean )WikiSession.doPrivileged( session, ( PrivilegedAction< Boolean > )() -> {
+            try {
+                // Check the JVM-wide security policy first
+                AccessController.checkPermission( permission );
+                return Boolean.TRUE;
+            } catch( final AccessControlException e ) {
+                // Global policy denied the permission
+            }
+
+            // Try the local policy - check each Role/Group and User Principal
+            if ( allowedByLocalPolicy( session.getRoles(), permission ) || allowedByLocalPolicy( session.getPrincipals(), permission ) ) {
+                return Boolean.TRUE;
+            }
+            return Boolean.FALSE;
+        } );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Principal resolvePrincipal( final String name ) {
+        // Check built-in Roles first
+        final Role role = new Role(name);
+        if ( Role.isBuiltInRole( role ) ) {
+            return role;
+        }
+
+        // Check Authorizer Roles
+        Principal principal = m_authorizer.findRole( name );
+        if ( principal != null ) {
+            return principal;
+        }
+
+        // Check Groups
+        principal = m_engine.getManager( GroupManager.class ).findRole( name );
+        if ( principal != null ) {
+            return principal;
+        }
+
+        // Ok, no luck---this must be a user principal
+        final Principal[] principals;
+        final UserProfile profile;
+        final UserDatabase db = m_engine.getManager( UserManager.class ).getUserDatabase();
+        try {
+            profile = db.find( name );
+            principals = db.getPrincipals( profile.getLoginName() );
+            for( final Principal value : principals ) {
+                principal = value;
+                if( principal.getName().equals( name ) ) {
+                    return principal;
+                }
+            }
+        } catch( final NoSuchPrincipalException e ) {
+            // We couldn't find the user...
+        }
+        // Ok, no luck---mark this as unresolved and move on
+        return new UnresolvedPrincipal( name );
+    }
+
+
+    // events processing .......................................................
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized void addWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.addWikiEventListener( this, listener );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.removeWikiEventListener( this, listener );
+    }
+
+}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
index ca03266..579036a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
@@ -18,7 +18,7 @@
  */
 package org.apache.wiki.auth.authorize;
 
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.WikiSecurityException;
 
@@ -50,7 +50,7 @@ public interface GroupDatabase {
      * @throws WikiSecurityException if the database could not be initialized successfully
      * @throws NoRequiredPropertyException if a required property is not present
      */
-    void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
+    void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
 
     /**
      * Saves a Group to the group database. Note that this method <em>must</em>
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
index 1f3bc60..37e3c33 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
@@ -21,14 +21,15 @@ package org.apache.wiki.auth.authorize;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.Authorizer;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.NoSuchPrincipalException;
+import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.auth.WikiSecurityException;
 import org.apache.wiki.auth.user.UserProfile;
@@ -67,38 +68,33 @@ import java.util.StringTokenizer;
 public class GroupManager implements Authorizer, WikiEventListener {
 
     /** Key used for adding UI messages to a user's WikiSession. */
-    public static final String  MESSAGES_KEY       = "group";
+    public static final String  MESSAGES_KEY = "group";
 
     private static final String PROP_GROUPDATABASE = "jspwiki.groupdatabase";
 
-    static final Logger         log                = Logger.getLogger( GroupManager.class );
+    private static final Logger log = Logger.getLogger( GroupManager.class );
 
-    protected WikiEngine        m_engine;
+    protected Engine m_engine;
 
     protected WikiEventListener m_groupListener;
 
     private GroupDatabase       m_groupDatabase    = null;
 
     /** Map with GroupPrincipals as keys, and Groups as values */
-    private final Map<Principal, Group>           m_groups           = new HashMap<Principal, Group>();
+    private final Map< Principal, Group > m_groups = new HashMap<>();
 
     /**
      * <p>
-     * Returns a GroupPrincipal matching a given name. If a group cannot be
-     * found, return <code>null</code>.
+     * Returns a GroupPrincipal matching a given name. If a group cannot be found, return <code>null</code>.
      * </p>
      * @param name Name of the group. This is case-sensitive.
      * @return A DefaultGroup instance.
      */
-    public Principal findRole( String name )
-    {
-        try
-        {
-            Group group = getGroup( name );
+    @Override public Principal findRole( final String name ) {
+        try {
+            final Group group = getGroup( name );
             return group.getPrincipal();
-        }
-        catch( NoSuchPrincipalException e )
-        {
+        } catch( final NoSuchPrincipalException e ) {
             return null;
         }
     }
@@ -110,9 +106,9 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @return the group
      * @throws NoSuchPrincipalException if the group cannot be found
      */
-    public Group getGroup( String name ) throws NoSuchPrincipalException
+    public Group getGroup( final String name ) throws NoSuchPrincipalException
     {
-        Group group = m_groups.get( new GroupPrincipal( name ) );
+        final Group group = m_groups.get( new GroupPrincipal( name ) );
         if ( group != null )
         {
             return group;
@@ -143,37 +139,37 @@ public class GroupManager implements Authorizer, WikiEventListener {
         Throwable cause = null;
         try
         {
-            Properties props = m_engine.getWikiProperties();
+            final Properties props = m_engine.getWikiProperties();
             dbClassName = props.getProperty( PROP_GROUPDATABASE );
             if ( dbClassName == null )
             {
                 dbClassName = XMLGroupDatabase.class.getName();
             }
             log.info( "Attempting to load group database class " + dbClassName );
-            Class<?> dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
+            final Class<?> dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
             m_groupDatabase = (GroupDatabase) dbClass.newInstance();
             m_groupDatabase.initialize( m_engine, m_engine.getWikiProperties() );
             log.info( "Group database initialized." );
         }
-        catch( ClassNotFoundException e )
+        catch( final ClassNotFoundException e )
         {
             log.error( "GroupDatabase class " + dbClassName + " cannot be found.", e );
             dbInstantiationError = "Failed to locate GroupDatabase class " + dbClassName;
             cause = e;
         }
-        catch( InstantiationException e )
+        catch( final InstantiationException e )
         {
             log.error( "GroupDatabase class " + dbClassName + " cannot be created.", e );
             dbInstantiationError = "Failed to create GroupDatabase class " + dbClassName;
             cause = e;
         }
-        catch( IllegalAccessException e )
+        catch( final IllegalAccessException e )
         {
             log.error( "You are not allowed to access group database class " + dbClassName + ".", e );
             dbInstantiationError = "Access GroupDatabase class " + dbClassName + " denied";
             cause = e;
         }
-        catch( NoRequiredPropertyException e )
+        catch( final NoRequiredPropertyException e )
         {
             log.error( "Missing property: " + e.getMessage() + "." );
             dbInstantiationError = "Missing property: " + e.getMessage();
@@ -195,7 +191,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * defensive copy of an internally stored hashmap.
      * @return an array of Principals representing the roles
      */
-    public Principal[] getRoles()
+    @Override public Principal[] getRoles()
     {
         return m_groups.keySet().toArray( new Principal[m_groups.size()] );
     }
@@ -205,12 +201,11 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * obtaining a list of all of the groups it stores.
      * @param engine the wiki engine
      * @param props the properties used to initialize the wiki engine
-     * @see GroupDatabase#initialize(org.apache.wiki.WikiEngine,
-     *      java.util.Properties)
+     * @see GroupDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      * @see GroupDatabase#groups()
      * @throws WikiSecurityException if GroupManager cannot be initialized
      */
-    public void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException
+    @Override public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException
     {
         m_engine = engine;
 
@@ -218,16 +213,16 @@ public class GroupManager implements Authorizer, WikiEventListener {
         {
             m_groupDatabase = getGroupDatabase();
         }
-        catch ( WikiException e )
+        catch ( final WikiException e )
         {
             throw new WikiSecurityException( e.getMessage(), e );
         }
 
         // Load all groups from the database into the cache
-        Group[] groups = m_groupDatabase.groups();
+        final Group[] groups = m_groupDatabase.groups();
         synchronized( m_groups )
         {
-            for( Group group : groups )
+            for( final Group group : groups )
             {
                 // Add new group to cache; fire GROUP_ADD event
                 m_groups.put( group.getPrincipal(), group );
@@ -236,7 +231,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
         }
 
         // Make the GroupManager listen for WikiEvents (WikiSecurityEvents for changed user profiles)
-        engine.getUserManager().addWikiEventListener( this );
+        engine.getManager( UserManager.class ).addWikiEventListener( this );
 
         // Success!
         log.info( "Authorizer GroupManager initialized successfully; loaded " + groups.length + " group(s)." );
@@ -264,7 +259,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @return <code>true</code> if the user is considered to be in the role,
      *         <code>false</code> otherwise
      */
-    public boolean isUserInRole( WikiSession session, Principal role )
+    @Override public boolean isUserInRole( final WikiSession session, final Principal role )
     {
         // Always return false if session/role is null, or if
         // role isn't a GroupPrincipal
@@ -274,14 +269,14 @@ public class GroupManager implements Authorizer, WikiEventListener {
         }
 
         // Get the group we're examining
-        Group group = m_groups.get( role );
+        final Group group = m_groups.get( role );
         if ( group == null )
         {
             return false;
         }
 
         // Check each user principal to see if it belongs to the group
-        for ( Principal principal : session.getPrincipals() )
+        for ( final Principal principal : session.getPrincipals() )
         {
             if ( AuthenticationManager.isUserPrincipal( principal ) && group.isMember( principal ) )
             {
@@ -321,7 +316,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * <code>create</code> is <code>false</code>
      * and the Group named <code>name</code> does not exist
      */
-    public Group parseGroup( String name, String memberLine, boolean create ) throws WikiSecurityException
+    public Group parseGroup( String name, String memberLine, final boolean create ) throws WikiSecurityException
     {
         // If null name parameter, it's because someone's creating a new group
         if ( name == null )
@@ -350,22 +345,22 @@ public class GroupManager implements Authorizer, WikiEventListener {
         memberLine = memberLine.trim();
 
         // Create or retrieve the group (may have been previously cached)
-        Group group = new Group( name, m_engine.getApplicationName() );
+        final Group group = new Group( name, m_engine.getApplicationName() );
         try
         {
-            Group existingGroup = getGroup( name );
+            final Group existingGroup = getGroup( name );
 
             // If existing, clone it
             group.setCreator( existingGroup.getCreator() );
             group.setCreated( existingGroup.getCreated() );
             group.setModifier( existingGroup.getModifier() );
             group.setLastModified( existingGroup.getLastModified() );
-            for( Principal existingMember : existingGroup.members() )
+            for( final Principal existingMember : existingGroup.members() )
             {
                 group.add( existingMember );
             }
         }
-        catch( NoSuchPrincipalException e )
+        catch( final NoSuchPrincipalException e )
         {
             // It's a new group.... throw error if we don't create new ones
             if ( !create )
@@ -375,11 +370,11 @@ public class GroupManager implements Authorizer, WikiEventListener {
         }
 
         // If passed members not empty, overwrite
-        String[] members = extractMembers( memberLine );
+        final String[] members = extractMembers( memberLine );
         if ( members.length > 0 )
         {
             group.clear();
-            for( String member : members )
+            for( final String member : members )
             {
                 group.add( new WikiPrincipal( member ) );
             }
@@ -416,16 +411,16 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * <code>create</code> is <code>false</code>
      * and the Group does not exist
      */
-    public Group parseGroup( WikiContext context, boolean create ) throws WikiSecurityException
+    public Group parseGroup( final WikiContext context, final boolean create ) throws WikiSecurityException
     {
         // Extract parameters
-        HttpServletRequest request = context.getHttpRequest();
-        String name = request.getParameter( "group" );
-        String memberLine = request.getParameter( "members" );
+        final HttpServletRequest request = context.getHttpRequest();
+        final String name = request.getParameter( "group" );
+        final String memberLine = request.getParameter( "members" );
 
         // Create the named group; we pass on any NoSuchPrincipalExceptions
         // that may be thrown if create == false, or WikiSecurityExceptions
-        Group group = parseGroup( name, memberLine, create );
+        final Group group = parseGroup( name, memberLine, create );
 
         // If no members, add the current user by default
         if ( group.members().length == 0 )
@@ -449,14 +444,14 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * the back-end
      * @see org.apache.wiki.auth.authorize.GroupDatabase#delete(Group)
      */
-    public void removeGroup( String index ) throws WikiSecurityException
+    public void removeGroup( final String index ) throws WikiSecurityException
     {
         if ( index == null )
         {
             throw new IllegalArgumentException( "Group cannot be null." );
         }
 
-        Group group = m_groups.get( new GroupPrincipal( index ) );
+        final Group group = m_groups.get( new GroupPrincipal( index ) );
         if ( group == null )
         {
             throw new NoSuchPrincipalException( "Group " + index + " not found" );
@@ -512,12 +507,12 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @param group the Group, which may not be <code>null</code>
      * @throws WikiSecurityException if the Group cannot be saved by the back-end
      */
-    public void setGroup( WikiSession session, Group group ) throws WikiSecurityException
+    public void setGroup( final WikiSession session, final Group group ) throws WikiSecurityException
     {
         // TODO: check for appropriate permissions
 
         // If group already exists, delete it; fire GROUP_REMOVE event
-        Group oldGroup = m_groups.get( group.getPrincipal() );
+        final Group oldGroup = m_groups.get( group.getPrincipal() );
         if ( oldGroup != null )
         {
             fireEvent( WikiSecurityEvent.GROUP_REMOVE, oldGroup );
@@ -552,7 +547,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
         }
 
         // We got an exception! Roll back...
-        catch( WikiSecurityException e )
+        catch( final WikiSecurityException e )
         {
             if ( oldGroup != null )
             {
@@ -577,22 +572,22 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @param context the current wiki context
      * @param group the supplied Group
      */
-    public void validateGroup( WikiContext context, Group group )
+    public void validateGroup( final WikiContext context, final Group group )
     {
-        InputValidator validator = new InputValidator( MESSAGES_KEY, context );
+        final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
 
         // Name cannot be null or one of the restricted names
         try
         {
             checkGroupName( context, group.getName() );
         }
-        catch( WikiSecurityException e )
+        catch( final WikiSecurityException e )
         {
 
         }
 
         // Member names must be "safe" strings
-        Principal[] members = group.members();
+        final Principal[] members = group.members();
         for( int i = 0; i < members.length; i++ )
         {
             validator.validateNotNull( members[i].getName(), "Full name", InputValidator.ID );
@@ -604,15 +599,15 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @param memberLine the list of members
      * @return the list of members
      */
-    protected String[] extractMembers( String memberLine )
+    protected String[] extractMembers( final String memberLine )
     {
-        Set<String> members = new HashSet<String>();
+        final Set<String> members = new HashSet<>();
         if ( memberLine != null )
         {
-            StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
+            final StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
             while( tok.hasMoreTokens() )
             {
-                String uid = tok.nextToken().trim();
+                final String uid = tok.nextToken().trim();
                 if ( uid != null && uid.length() > 0 )
                 {
                     members.add( uid );
@@ -631,12 +626,12 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * <code>null</code> or the Group name is illegal
      * @see Group#RESTRICTED_GROUPNAMES
      */
-    protected void checkGroupName( WikiContext context, String name ) throws WikiSecurityException
+    protected void checkGroupName( final WikiContext context, final String name ) throws WikiSecurityException
     {
         //TODO: groups cannot have the same name as a user
 
         // Name cannot be null
-        InputValidator validator = new InputValidator( MESSAGES_KEY, context );
+        final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
         validator.validateNotNull( name, "Group name" );
 
         // Name cannot be one of the restricted names either
@@ -654,7 +649,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * This is a convenience method.
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( WikiEventListener listener )
+    public synchronized void addWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.addWikiEventListener( this, listener );
     }
@@ -664,7 +659,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * This is a convenience method.
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( WikiEventListener listener )
+    public synchronized void removeWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.removeWikiEventListener( this, listener );
     }
@@ -677,7 +672,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * @param type       the event type to be fired
      * @param target     the changed Object, which may be <code>null</code>
      */
-    protected void fireEvent( int type, Object target )
+    protected void fireEvent( final int type, final Object target )
     {
         if ( WikiEventManager.isListening(this) )
         {
@@ -693,32 +688,32 @@ public class GroupManager implements Authorizer, WikiEventListener {
      * only the representations of the names within that are changing.
      * @param event the incoming event
      */
-    public void actionPerformed(WikiEvent event)
+    @Override public void actionPerformed( final WikiEvent event)
     {
         if (! ( event instanceof WikiSecurityEvent ) )
         {
             return;
         }
 
-        WikiSecurityEvent se = (WikiSecurityEvent)event;
+        final WikiSecurityEvent se = (WikiSecurityEvent)event;
         if ( se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED )
         {
-            WikiSession session = se.getSrc();
-            UserProfile[] profiles = (UserProfile[])se.getTarget();
-            Principal[] oldPrincipals = new Principal[] {
+            final WikiSession session = se.getSrc();
+            final UserProfile[] profiles = (UserProfile[])se.getTarget();
+            final Principal[] oldPrincipals = new Principal[] {
                 new WikiPrincipal( profiles[0].getLoginName() ),
                 new WikiPrincipal( profiles[0].getFullname() ),
                 new WikiPrincipal( profiles[0].getWikiName() ) };
-            Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() );
+            final Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() );
 
             // Examine each group
             int groupsChanged = 0;
             try
             {
-                for ( Group group : m_groupDatabase.groups() )
+                for ( final Group group : m_groupDatabase.groups() )
                 {
                     boolean groupChanged = false;
-                    for ( Principal oldPrincipal : oldPrincipals )
+                    for ( final Principal oldPrincipal : oldPrincipals )
                     {
                         if ( group.isMember( oldPrincipal ) )
                         {
@@ -734,7 +729,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
                     }
                 }
             }
-            catch ( WikiException e )
+            catch ( final WikiException e )
             {
                 // Oooo! This is really bad...
                 log.error( "Could not change user name in Group lists because of GroupDatabase error:" + e.getMessage() );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
index d5ac0d2..1f22cf6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
@@ -18,23 +18,29 @@
  */
 package org.apache.wiki.auth.authorize;
 
-import java.security.Principal;
-import java.sql.*;
-import java.util.*;
-import java.util.Date;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.auth.WikiSecurityException;
 
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
 /**
  * <p>
  * Implementation of GroupDatabase that persists {@link Group} objects to a JDBC
@@ -121,13 +127,8 @@ import org.apache.wiki.auth.WikiSecurityException;
  * </p>
  * <p>
  * JDBCGroupDatabase commits changes as transactions if the back-end database
- * supports them. If the database supports transactions, group changes are saved
- * to permanent storage only when the {@link #commit()} method is called. If the
- * database does <em>not</em> support transactions, then changes are made
- * immediately (during the {@link #save(Group, Principal)} method), and the
- * {@linkplain #commit()} method no-ops. Thus, callers should always call the
- * {@linkplain #commit()} method after saving a profile to guarantee that
- * changes are applied.
+ * supports them. Changes are made
+ * immediately (during the {@link #save(Group, Principal)} method).
  * </p>
  * 
  * @since 2.3
@@ -222,7 +223,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
 
     private boolean m_supportsCommits = false;
 
-    private WikiEngine m_engine = null;
+    private Engine m_engine = null;
 
     /**
      * Looks up and deletes a {@link Group} from the group database. If the
@@ -235,14 +236,14 @@ public class JDBCGroupDatabase implements GroupDatabase {
      *             supplied group (thrown as {@link NoSuchPrincipalException})
      *             or if the commit did not succeed
      */
-    public void delete( Group group ) throws WikiSecurityException
+    @Override public void delete( final Group group ) throws WikiSecurityException
     {
         if( !exists( group ) )
         {
             throw new NoSuchPrincipalException( "Not in database: " + group.getName() );
         }
 
-        String groupName = group.getName();
+        final String groupName = group.getName();
         Connection conn = null;
         PreparedStatement ps = null;
         try
@@ -269,7 +270,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 conn.commit();
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly( conn, ps, null );
             throw new WikiSecurityException( "Could not delete group " + groupName + ": " + e.getMessage(), e );
@@ -291,9 +292,9 @@ public class JDBCGroupDatabase implements GroupDatabase {
      * @throws WikiSecurityException if the groups cannot be returned by the
      *             back-end
      */
-    public Group[] groups() throws WikiSecurityException
+    @Override public Group[] groups() throws WikiSecurityException
     {
-        Set<Group> groups = new HashSet<Group>();
+        final Set<Group> groups = new HashSet<>();
         Connection conn = null;
         PreparedStatement ps = null;
         ResultSet rs = null;
@@ -306,14 +307,14 @@ public class JDBCGroupDatabase implements GroupDatabase {
             rs = ps.executeQuery();
             while ( rs.next() )
             {
-                String groupName = rs.getString( m_name );
+                final String groupName = rs.getString( m_name );
                 if( groupName == null )
                 {
                     log.warn( "Detected null group name in JDBCGroupDataBase. Check your group database." );
                 }
                 else
                 {
-                    Group group = new Group( groupName, m_engine.getApplicationName() );
+                    final Group group = new Group( groupName, m_engine.getApplicationName() );
                     group.setCreated( rs.getTimestamp( m_created ) );
                     group.setCreator( rs.getString( m_creator ) );
                     group.setLastModified( rs.getTimestamp( m_modified ) );
@@ -323,7 +324,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 }
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly( conn, ps, rs );
             throw new WikiSecurityException( e.getMessage(), e );
@@ -346,17 +347,16 @@ public class JDBCGroupDatabase implements GroupDatabase {
      * 
      * @param group the Group to save
      * @param modifier the user who saved the Group
-     * @throws WikiSecurityException if the Group could not be saved
-     *             successfully
+     * @throws WikiSecurityException if the Group could not be saved successfully
      */
-    public void save( Group group, Principal modifier ) throws WikiSecurityException
+    @Override public void save( final Group group, final Principal modifier ) throws WikiSecurityException
     {
         if( group == null || modifier == null )
         {
             throw new IllegalArgumentException( "Group or modifier cannot be null." );
         }
 
-        boolean exists = exists( group );
+        final boolean exists = exists( group );
         Connection conn = null;
         PreparedStatement ps = null;
         try
@@ -368,8 +368,8 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 conn.setAutoCommit( false );
             }
             
-            Timestamp ts = new Timestamp( System.currentTimeMillis() );
-            Date modDate = new Date( ts.getTime() );
+            final Timestamp ts = new Timestamp( System.currentTimeMillis() );
+            final Date modDate = new Date( ts.getTime() );
             if( !exists )
             {
                 // Group is new: insert new group record
@@ -410,10 +410,10 @@ public class JDBCGroupDatabase implements GroupDatabase {
 
             // Insert group member records
             ps = conn.prepareStatement( m_insertGroupMembers );
-            Principal[] members = group.members();
+            final Principal[] members = group.members();
             for( int i = 0; i < members.length; i++ )
             {
-                Principal member = members[i];
+                final Principal member = members[i];
                 ps.setString( 1, group.getName() );
                 ps.setString( 2, member.getName() );
                 ps.execute();
@@ -425,7 +425,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 conn.commit();
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly(conn, ps, null );
             throw new WikiSecurityException( e.getMessage(), e );
@@ -445,18 +445,18 @@ public class JDBCGroupDatabase implements GroupDatabase {
      *             successfully
      * @throws NoRequiredPropertyException if a required property is not present
      */
-    public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException
+    @Override public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException
     {
-        String table;
-        String memberTable;
+        final String table;
+        final String memberTable;
 
         m_engine = engine;
 
-        String jndiName = props.getProperty( PROP_GROUPDB_DATASOURCE, DEFAULT_GROUPDB_DATASOURCE );
+        final String jndiName = props.getProperty( PROP_GROUPDB_DATASOURCE, DEFAULT_GROUPDB_DATASOURCE );
         try
         {
-            Context initCtx = new InitialContext();
-            Context ctx = (Context) initCtx.lookup( "java:comp/env" );
+            final Context initCtx = new InitialContext();
+            final Context ctx = (Context) initCtx.lookup( "java:comp/env" );
             m_ds = (DataSource) ctx.lookup( jndiName );
 
             // Prepare the SQL selectors
@@ -485,7 +485,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
             m_deleteGroup = "DELETE FROM " + table + " WHERE " + m_name + "=?";
             m_deleteGroupMembers = "DELETE FROM " + memberTable + " WHERE " + m_name + "=?";
         }
-        catch( NamingException e )
+        catch( final NamingException e )
         {
             log.error( "JDBCGroupDatabase initialization error: " + e );
             throw new NoRequiredPropertyException( PROP_GROUPDB_DATASOURCE, "JDBCGroupDatabase initialization error: " + e);
@@ -501,7 +501,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
             ps.executeQuery();
             ps.close();
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly( conn, ps, null );
             log.error( "DB connectivity error: " + e.getMessage() );
@@ -517,7 +517,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
         try
         {
             conn = m_ds.getConnection();
-            DatabaseMetaData dmd = conn.getMetaData();
+            final DatabaseMetaData dmd = conn.getMetaData();
             if( dmd.supportsTransactions() )
             {
                 m_supportsCommits = true;
@@ -525,7 +525,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 log.info( "JDBCGroupDatabase supports transactions. Good; we will use them." );
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly( conn, null, null );
             log.warn( "JDBCGroupDatabase warning: user database doesn't seem to support transactions. Reason: " + e);
@@ -542,15 +542,15 @@ public class JDBCGroupDatabase implements GroupDatabase {
      * @param group the Group to look for
      * @return the result of the search
      */
-    private boolean exists( Group group )
+    private boolean exists( final Group group )
     {
-        String index = group.getName();
+        final String index = group.getName();
         try
         {
             findGroup( index );
             return true;
         }
-        catch( NoSuchPrincipalException e )
+        catch( final NoSuchPrincipalException e )
         {
             return false;
         }
@@ -565,7 +565,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
      * @throws NoSuchPrincipalException if the Group cannot be found
      * @throws SQLException if the database query returns an error
      */
-    private Group findGroup( String index ) throws NoSuchPrincipalException
+    private Group findGroup( final String index ) throws NoSuchPrincipalException
     {
         Group group = null;
         boolean found = false;
@@ -597,7 +597,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
                 found = true;
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
         	closeQuietly( conn, ps, rs );
             throw new NoSuchPrincipalException( e.getMessage() );
@@ -624,7 +624,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
      * @param group the group to populate
      * @return the populated Group
      */
-    private Group populateGroup( Group group )
+    private Group populateGroup( final Group group )
     {
     	ResultSet rs = null;
     	PreparedStatement ps = null;
@@ -639,15 +639,15 @@ public class JDBCGroupDatabase implements GroupDatabase {
             rs = ps.executeQuery();
             while ( rs.next() )
             {
-                String memberName = rs.getString( m_member );
+                final String memberName = rs.getString( m_member );
                 if( memberName != null )
                 {
-                    WikiPrincipal principal = new WikiPrincipal( memberName, WikiPrincipal.UNSPECIFIED );
+                    final WikiPrincipal principal = new WikiPrincipal( memberName, WikiPrincipal.UNSPECIFIED );
                     group.add( principal );
                 }
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
             // I guess that means there aren't any principals...
         }
@@ -658,23 +658,23 @@ public class JDBCGroupDatabase implements GroupDatabase {
         return group;
     }
     
-    void closeQuietly( Connection conn, PreparedStatement ps, ResultSet rs ) {
+    void closeQuietly( final Connection conn, final PreparedStatement ps, final ResultSet rs ) {
     	if( conn != null ) {
     		try {
     		    conn.close();
-    		} catch( Exception e ) {
+    		} catch( final Exception e ) {
     		}
     	}
 		if( ps != null )  {
 			try {
 			    ps.close();
-			} catch( Exception e ) {
+			} catch( final Exception e ) {
 			}
 		}
 		if( rs != null )  {
 			try {
 			    rs.close();
-			} catch( Exception e ) {
+			} catch( final Exception e ) {
 			}
 		}
 	}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
index d55569e..dd6cf08 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
@@ -18,29 +18,25 @@
  */
 package org.apache.wiki.auth.authorize;
 
-import java.security.Principal;
+import org.apache.wiki.auth.Authorizer;
 
 import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
 
-import org.apache.wiki.auth.Authorizer;
 
 /**
- * Extends the {@link org.apache.wiki.auth.Authorizer} interface by
- * including a delgate method for 
+ * Extends the {@link org.apache.wiki.auth.Authorizer} interface by including a delgate method for
  * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}.
  */
-public interface WebAuthorizer extends Authorizer
-{
+public interface WebAuthorizer extends Authorizer {
     
     /**
-     * Determines whether a user associated with an HTTP request possesses
-     * a particular role. This method simply delegates to 
-     * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}
-     * by converting the Principal's name to a String.
+     * Determines whether a user associated with an HTTP request possesses a particular role. This method simply delegates to
+     * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)} by converting the Principal's name to a String.
+     *
      * @param request the HTTP request
      * @param role the role to check
-     * @return <code>true</code> if the user is considered to be in the role,
-     *         <code>false</code> otherwise
+     * @return <code>true</code> if the user is considered to be in the role, <code>false</code> otherwise
      */
     boolean isUserInRole( HttpServletRequest request, Principal role );
     
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
index cfb78b3..a4c4968 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
@@ -20,8 +20,8 @@ package org.apache.wiki.auth.authorize;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.InternalWikiException;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.jdom2.Document;
 import org.jdom2.Element;
 import org.jdom2.JDOMException;
@@ -56,9 +56,9 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
 
     private static final String J2EE_SCHEMA_25_NAMESPACE = "http://xmlns.jcp.org/xml/ns/javaee";
 
-    protected static final Logger log                   = Logger.getLogger( WebContainerAuthorizer.class );
+    private static final Logger log = Logger.getLogger( WebContainerAuthorizer.class );
 
-    protected WikiEngine          m_engine;
+    protected Engine m_engine;
 
     /**
      * A lazily-initialized array of Roles that the container knows about. These
@@ -68,15 +68,15 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      * that we have no direct way of querying the web container about which
      * roles it manages.
      */
-    protected Role[]            m_containerRoles      = new Role[0];
+    protected Role[] m_containerRoles      = new Role[0];
 
     /**
      * Lazily-initialized boolean flag indicating whether the web container
      * protects JSPWiki resources.
      */
-    protected boolean           m_containerAuthorized = false;
+    protected boolean m_containerAuthorized = false;
 
-    private Document            m_webxml = null;
+    private Document m_webxml = null;
 
     /**
      * Constructs a new instance of the WebContainerAuthorizer class.
@@ -92,49 +92,36 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      * @param props the wiki engine initialization properties
      */
     @Override
-    public void initialize( WikiEngine engine, Properties props )
-    {
+    public void initialize( final Engine engine, final Properties props ) {
         m_engine = engine;
         m_containerAuthorized = false;
 
         // FIXME: Error handling here is not very verbose
-        try
-        {
+        try {
             m_webxml = getWebXml();
-            if ( m_webxml != null )
-            {
+            if( m_webxml != null ) {
                 // Add the J2EE 2.4 schema namespace
                 m_webxml.getRootElement().setNamespace( Namespace.getNamespace( J2EE_SCHEMA_25_NAMESPACE ) );
 
-                m_containerAuthorized = isConstrained( "/Delete.jsp", Role.ALL )
-                        && isConstrained( "/Login.jsp", Role.ALL );
+                m_containerAuthorized = isConstrained( "/Delete.jsp", Role.ALL ) && isConstrained( "/Login.jsp", Role.ALL );
             }
-            if ( m_containerAuthorized )
-            {
+            if( m_containerAuthorized ) {
                 m_containerRoles = getRoles( m_webxml );
                 log.info( "JSPWiki is using container-managed authentication." );
-            }
-            else
-            {
+            } else {
                 log.info( "JSPWiki is using custom authentication." );
             }
-        }
-        catch ( IOException e )
-        {
-            log.error("Initialization failed: ",e);
-            throw new InternalWikiException( e.getClass().getName()+": "+e.getMessage() , e);
-        }
-        catch ( JDOMException e )
-        {
-            log.error("Malformed XML in web.xml",e);
-            throw new InternalWikiException( e.getClass().getName()+": "+e.getMessage() , e);
+        } catch( final IOException e ) {
+            log.error( "Initialization failed: ", e );
+            throw new InternalWikiException( e.getClass().getName() + ": " + e.getMessage(), e );
+        } catch( final JDOMException e ) {
+            log.error( "Malformed XML in web.xml", e );
+            throw new InternalWikiException( e.getClass().getName() + ": " + e.getMessage(), e );
         }
 
-        if ( m_containerRoles.length > 0 )
-        {
+        if( m_containerRoles.length > 0 ) {
             String roles = "";
-            for( Role containerRole : m_containerRoles )
-            {
+            for( final Role containerRole : m_containerRoles ) {
                 roles = roles + containerRole + " ";
             }
             log.info( " JSPWiki determined the web container manages these roles: " + roles );
@@ -153,7 +140,7 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      *         <code>false</code> otherwise
      */
     @Override
-    public boolean isUserInRole( HttpServletRequest request, Principal role )
+    public boolean isUserInRole( final HttpServletRequest request, final Principal role )
     {
         return request.isUserInRole( role.getName() );
     }
@@ -182,10 +169,8 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      * @see org.apache.wiki.auth.Authorizer#isUserInRole(org.apache.wiki.WikiSession, java.security.Principal)
      */
     @Override
-    public boolean isUserInRole( WikiSession session, Principal role )
-    {
-        if ( session == null || role == null )
-        {
+    public boolean isUserInRole( final WikiSession session, final Principal role ) {
+        if ( session == null || role == null ) {
             return false;
         }
         return session.hasPrincipal( role );
@@ -197,15 +182,12 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      * initialization, this method returns <code>null</code>.
      * @param role the name of the Role to retrieve
      * @return a Role Principal, or <code>null</code>
-     * @see org.apache.wiki.auth.Authorizer#initialize(WikiEngine, Properties)
+     * @see org.apache.wiki.auth.Authorizer#initialize(Engine, Properties)
      */
     @Override
-    public Principal findRole( String role )
-    {
-        for( Role containerRole : m_containerRoles )
-        {
-            if ( containerRole.getName().equals( role ) )
-            {
+    public Principal findRole( final String role ) {
+        for( final Role containerRole : m_containerRoles ) {
+            if ( containerRole.getName().equals( role ) ) {
                 return containerRole;
             }
         }
@@ -266,9 +248,9 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
         }
 
         // If a constraint is contained in both lists, we must be constrained
-        for ( Iterator< Element > c = constraints.iterator(); c.hasNext(); ) {
+        for ( final Iterator< Element > c = constraints.iterator(); c.hasNext(); ) {
             final Element constraint = c.next();
-            for ( Iterator< Element > r = roles.iterator(); r.hasNext(); ) {
+            for ( final Iterator< Element > r = roles.iterator(); r.hasNext(); ) {
                 final Element roleConstraint = r.next();
                 if ( constraint.equals( roleConstraint ) ) {
                     return true;
@@ -362,14 +344,14 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
      */
     protected Document getWebXml() throws JDOMException, IOException
     {
-        URL url;
-        SAXBuilder builder = new SAXBuilder();
+        final URL url;
+        final SAXBuilder builder = new SAXBuilder();
         builder.setXMLReaderFactory( XMLReaders.NONVALIDATING );
         builder.setEntityResolver( new LocalEntityResolver() );
         Document doc = null;
         if ( m_engine.getServletContext() == null )
         {
-            ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
+            final ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
             url = cl.getResource( "WEB-INF/web.xml" );
             if( url != null )
                 log.info( "Examining " + url.toExternalForm() );
@@ -414,13 +396,13 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
          * @throws IOException if the resource cannot be opened
          */
         @Override
-        public InputSource resolveEntity( String publicId, String systemId ) throws SAXException, IOException
+        public InputSource resolveEntity( final String publicId, final String systemId ) throws SAXException, IOException
         {
-            String file = systemId.substring( systemId.lastIndexOf( '/' ) + 1 );
-            URL url;
+            final String file = systemId.substring( systemId.lastIndexOf( '/' ) + 1 );
+            final URL url;
             if ( m_engine.getServletContext() == null )
             {
-                ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
+                final ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
                 url = cl.getResource( "WEB-INF/dtd/" + file );
             }
             else
@@ -430,7 +412,7 @@ public class WebContainerAuthorizer implements WebAuthorizer  {
 
             if( url != null )
             {
-                InputSource is = new InputSource( url.openStream() );
+                final InputSource is = new InputSource( url.openStream() );
                 log.debug( "Resolved systemID=" + systemId + " using local file " + url );
                 return is;
             }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
index 153a2d6..6b0ec1d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
@@ -20,7 +20,7 @@ package org.apache.wiki.auth.authorize;
 
 import org.apache.commons.text.StringEscapeUtils;
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiPrincipal;
@@ -73,14 +73,11 @@ import java.util.concurrent.ConcurrentHashMap;
  * </code></blockquote>
  * @since 2.4.17
  */
-public class XMLGroupDatabase implements GroupDatabase
-{
-    protected static final Logger log              = Logger.getLogger( XMLGroupDatabase.class );
+public class XMLGroupDatabase implements GroupDatabase {
 
-    /**
-     * The jspwiki.properties property specifying the file system location of
-     * the group database.
-     */
+    private static final Logger log              = Logger.getLogger( XMLGroupDatabase.class );
+
+    /** The jspwiki.properties property specifying the file system location of the group database. */
     public static final String    PROP_DATABASE    = "jspwiki.xmlGroupDatabaseFile";
 
     private static final String   DEFAULT_DATABASE = "groupdatabase.xml";
@@ -109,7 +106,7 @@ public class XMLGroupDatabase implements GroupDatabase
 
     private File                  m_file           = null;
 
-    private WikiEngine            m_engine         = null;
+    private Engine                m_engine         = null;
 
     private Map<String, Group>    m_groups         = new ConcurrentHashMap<>();
 
@@ -124,10 +121,10 @@ public class XMLGroupDatabase implements GroupDatabase
      * the commit did not succeed
      */
     @Override
-    public void delete( Group group ) throws WikiSecurityException
+    public void delete( final Group group ) throws WikiSecurityException
     {
-        String index = group.getName();
-        boolean exists = m_groups.containsKey( index );
+        final String index = group.getName();
+        final boolean exists = m_groups.containsKey( index );
 
         if ( !exists )
         {
@@ -153,7 +150,7 @@ public class XMLGroupDatabase implements GroupDatabase
     public Group[] groups() throws WikiSecurityException
     {
         buildDOM();
-        Collection<Group> groups = m_groups.values();
+        final Collection<Group> groups = m_groups.values();
         return groups.toArray( new Group[groups.size()] );
     }
 
@@ -168,7 +165,7 @@ public class XMLGroupDatabase implements GroupDatabase
      * @throws WikiSecurityException if the database could not be initialized successfully
      */
     @Override
-    public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException
+    public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException
     {
         m_engine = engine;
 
@@ -184,7 +181,7 @@ public class XMLGroupDatabase implements GroupDatabase
         }
 
         // Get database file location
-        String file = TextUtil.getStringProperty(props, PROP_DATABASE , defaultFile.getAbsolutePath());
+        final String file = TextUtil.getStringProperty(props, PROP_DATABASE , defaultFile.getAbsolutePath());
         if ( file == null )
         {
             log.warn( "XML group database property " + PROP_DATABASE + " not found; trying " + defaultFile );
@@ -213,16 +210,16 @@ public class XMLGroupDatabase implements GroupDatabase
      * @throws WikiSecurityException if the Group could not be saved successfully
      */
     @Override
-    public void save( Group group, Principal modifier ) throws WikiSecurityException {
+    public void save( final Group group, final Principal modifier ) throws WikiSecurityException {
         if ( group == null || modifier == null ) {
             throw new IllegalArgumentException( "Group or modifier cannot be null." );
         }
 
         checkForRefresh();
 
-        String index = group.getName();
-        boolean isNew = !( m_groups.containsKey( index ) );
-        Date modDate = new Date( System.currentTimeMillis() );
+        final String index = group.getName();
+        final boolean isNew = !( m_groups.containsKey( index ) );
+        final Date modDate = new Date( System.currentTimeMillis() );
         if ( isNew )
         {
             // If new, set created info
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index ff4ad5a..b419955 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -73,7 +73,7 @@
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.AuthorizationManager</requestedClass>
-    <mappedClass>org.apache.wiki.auth.AuthorizationManager</mappedClass>
+    <mappedClass>org.apache.wiki.auth.DefaultAuthorizationManager</mappedClass>
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.UserManager</requestedClass>
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
index 803f1fd..0c1a106 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
@@ -17,16 +17,12 @@
     under the License.
  */
 package org.apache.wiki.auth;
-import java.security.Principal;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.servlet.http.HttpServletRequest;
 
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.WikiSessionTest;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.authorize.Group;
 import org.apache.wiki.auth.authorize.GroupManager;
 import org.apache.wiki.auth.authorize.Role;
@@ -36,45 +32,42 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
+import java.util.Map;
+import java.util.Properties;
+
 /**
  * Tests the AuthorizationManager class.
  *
  */
-public class AuthenticationManagerTest
-{
-    public static class DummyAuthorizer implements WebAuthorizer
-    {
+public class AuthenticationManagerTest {
+
+    public static class DummyAuthorizer implements WebAuthorizer {
         private static Principal[] m_roles = new Principal[] { new Role( "ContainerRole" ), new Role( "AuthorizerRole" ),
                                                               new Role( "DummyRole" ) };
 
-        public Principal findRole( String role )
-        {
-            for( Principal principal : m_roles )
-            {
-                if( principal.getName().equals( role ) )
-                {
+        @Override public Principal findRole( final String role ) {
+            for( final Principal principal : m_roles ) {
+                if( principal.getName().equals( role ) ) {
                     return principal;
                 }
             }
             return null;
         }
 
-        public Principal[] getRoles()
-        {
+        @Override public Principal[] getRoles() {
             return m_roles;
         }
 
-        public void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException
-        {
+        @Override public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException {
         }
 
-        public boolean isUserInRole( HttpServletRequest request, Principal role )
-        {
+        @Override public boolean isUserInRole( final HttpServletRequest request, final Principal role ) {
             return request != null && "ContainerRole".equals( role.getName() );
         }
 
-        public boolean isUserInRole( WikiSession session, Principal role )
-        {
+        @Override public boolean isUserInRole( final WikiSession session, final Principal role ) {
             return session != null && "AuthorizerRole".equals( role.getName() );
         }
     }
@@ -88,9 +81,8 @@ public class AuthenticationManagerTest
     private WikiSession m_session;
 
     @BeforeEach
-    public void setUp() throws Exception
-    {
-        Properties props = TestEngine.getTestProperties();
+    public void setUp() throws Exception {
+        final Properties props = TestEngine.getTestProperties();
         m_engine = new TestEngine( props );
         m_auth = m_engine.getAuthenticationManager();
         m_groupMgr = m_engine.getGroupManager();
@@ -98,15 +90,13 @@ public class AuthenticationManagerTest
     }
 
     /**
-     * Tests a dummy WebAuthorizer that is guaranteed to return true for one
-     * role for each of the two <code>isInRole</code> methods.
+     * Tests a dummy WebAuthorizer that is guaranteed to return true for one role for each of the two <code>isInRole</code> methods.
      *
      * @throws Exception
      */
     @Test
-    public void testCustomAuthorizer() throws Exception
-    {
-        Properties props = TestEngine.getTestProperties();
+    public void testCustomAuthorizer() throws Exception {
+        final Properties props = TestEngine.getTestProperties();
         props.put( AuthorizationManager.PROP_AUTHORIZER, "org.apache.wiki.auth.AuthenticationManagerTest$DummyAuthorizer" );
         m_engine = new TestEngine( props );
 
@@ -134,24 +124,22 @@ public class AuthenticationManagerTest
     }
 
     @Test
-    public void testCustomJAASLoginModule() throws Exception
-    {
-        Properties props = TestEngine.getTestProperties();
+    public void testCustomJAASLoginModule() throws Exception {
+        final Properties props = TestEngine.getTestProperties();
 
         // Supply a custom LoginModule class
         props.put( "jspwiki.loginModule.class", "org.apache.wiki.auth.login.CookieAssertionLoginModule" );
 
         // Init the engine and verify that we initialized with a custom auth
         // login module
-        WikiEngine engine = new TestEngine( props );
-        AuthenticationManager authMgr = engine.getAuthenticationManager();
+        final WikiEngine engine = new TestEngine( props );
+        final DefaultAuthenticationManager authMgr = ( DefaultAuthenticationManager )engine.getAuthenticationManager();
         Assertions.assertEquals( CookieAssertionLoginModule.class, authMgr.m_loginModuleClass );
     }
 
     @Test
-    public void testCustomJAASLoginModuleOptions() throws Exception
-    {
-        Properties props = TestEngine.getTestProperties();
+    public void testCustomJAASLoginModuleOptions() throws Exception {
+        final Properties props = TestEngine.getTestProperties();
 
         // Supply a custom LoginModule options
         props.put( "jspwiki.loginModule.options.key1", "value1" );
@@ -160,9 +148,9 @@ public class AuthenticationManagerTest
 
         // Init the engine and verify that we initialized with the correct
         // options
-        WikiEngine engine = new TestEngine( props );
-        AuthenticationManager authMgr = engine.getAuthenticationManager();
-        Map<String, String> options = authMgr.m_loginModuleOptions;
+        final WikiEngine engine = new TestEngine( props );
+        final DefaultAuthenticationManager authMgr = ( DefaultAuthenticationManager )engine.getAuthenticationManager();
+        final Map<String, String> options = authMgr.m_loginModuleOptions;
         Assertions.assertEquals( 3, options.size() );
         Assertions.assertTrue( options.containsKey( "key1" ) );
         Assertions.assertTrue( options.containsKey( "key2" ) );
@@ -173,8 +161,7 @@ public class AuthenticationManagerTest
     }
 
     @Test
-    public void testIsUserPrincipal()
-    {
+    public void testIsUserPrincipal() {
         Assertions.assertTrue( AuthenticationManager.isUserPrincipal( new WikiPrincipal( "Foo" ) ) );
         Assertions.assertFalse( AuthenticationManager.isUserPrincipal( new GroupPrincipal( "Group1" ) ) );
         Assertions.assertFalse( AuthenticationManager.isUserPrincipal( new Role( "Role1" ) ) );
@@ -182,9 +169,8 @@ public class AuthenticationManagerTest
     }
 
     @Test
-    public void testLoginCustom() throws Exception
-    {
-        WikiSession session = WikiSessionTest.authenticatedSession( m_engine, Users.JANNE, Users.JANNE_PASS );
+    public void testLoginCustom() throws Exception {
+        final WikiSession session = WikiSessionTest.authenticatedSession( m_engine, Users.JANNE, Users.JANNE_PASS );
         Assertions.assertTrue( session.hasPrincipal( Role.ALL ) );
         Assertions.assertTrue( session.hasPrincipal( Role.AUTHENTICATED ) );
         Assertions.assertTrue( session.hasPrincipal( new WikiPrincipal( Users.JANNE, WikiPrincipal.LOGIN_NAME ) ) );
@@ -193,43 +179,38 @@ public class AuthenticationManagerTest
     }
 
     @Test
-    public void testLoginCustomWithGroup() throws Exception
-    {
-        // Flush any pre-existing groups (left over from previous Assertions.failures,
-        // perhaps)
-        try
-        {
+    public void testLoginCustomWithGroup() throws Exception {
+        // Flush any pre-existing groups (left over from previous Assertions.failures, perhaps)
+        try {
             m_groupMgr.removeGroup( "Test1" );
             m_groupMgr.removeGroup( "Test2" );
-        }
-        catch( NoSuchPrincipalException e )
-        {
+        } catch( final NoSuchPrincipalException e ) {
 
         }
 
         // Log in 'janne' and verify there are 5 principals in the subject
         // (ALL, AUTHENTICATED, login, fullname, wikiname Principals)
-        WikiSession session = WikiSession.guestSession( m_engine );
+        final WikiSession session = WikiSession.guestSession( m_engine );
         m_auth.login( session, null, Users.JANNE, Users.JANNE_PASS );
         Assertions.assertEquals( 3, session.getPrincipals().length );
         Assertions.assertEquals( 2, session.getRoles().length );
         Assertions.assertTrue( session.hasPrincipal( new WikiPrincipal( "JanneJalkanen", WikiPrincipal.WIKI_NAME ) ) );
 
         // Listen for any manager group-add events
-        GroupManager manager = m_engine.getGroupManager();
-        SecurityEventTrap trap = new SecurityEventTrap();
+        final GroupManager manager = m_engine.getGroupManager();
+        final SecurityEventTrap trap = new SecurityEventTrap();
         manager.addWikiEventListener( trap );
 
         // Create two groups; one with Janne in it, and one without
         Group groupTest1 = m_groupMgr.parseGroup( "Test1", "JanneJalkanen \n Bob \n Charlie", true );
         m_groupMgr.setGroup( m_session, groupTest1 );
         groupTest1 = m_groupMgr.getGroup( "Test1" );
-        Principal principalTest1 = groupTest1.getPrincipal();
+        final Principal principalTest1 = groupTest1.getPrincipal();
 
         Group groupTest2 = m_groupMgr.parseGroup( "Test2", "Alice \n Bob \n Charlie", true );
         m_groupMgr.setGroup( m_session, groupTest2 );
         groupTest2 = m_groupMgr.getGroup( "Test2" );
-        Principal principalTest2 = groupTest2.getPrincipal();
+        final Principal principalTest2 = groupTest2.getPrincipal();
 
         // We should see two security events (one for each group create)
         // We should also see a GroupPrincipal for group Test1, but not Test2
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
index c0761e9..5b272e7 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
@@ -18,24 +18,23 @@
  */
 package org.apache.wiki.auth;
 
-import java.security.Principal;
-import java.util.Properties;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.authorize.Role;
 import org.apache.wiki.auth.authorize.WebAuthorizer;
 
+import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
+import java.util.Properties;
+
 /**
- * A very fast authorizer that does almost nothing. The WebContainerAuthorizer module
- * is very slow, as it parses the web.xml each time, so we use this for most of
- * the different tests.
+ * A very fast authorizer that does almost nothing. The WebContainerAuthorizer module is very slow, as it parses the web.xml each time,
+ * so we use this for most of the different tests.
+ *
  * @since 2.3
  */
-public class TestAuthorizer implements WebAuthorizer
-{
+public class TestAuthorizer implements WebAuthorizer {
+
     private Role[] m_roles = new Role[]{ 
             new Role( "Admin" ), 
             Role.AUTHENTICATED,
@@ -48,33 +47,28 @@ public class TestAuthorizer implements WebAuthorizer
         super();
     }
 
-    public Principal findRole( String role )
+    @Override public Principal findRole( final String role )
     {
         return null;
     }
 
-    public void initialize( WikiEngine engine, Properties props )
-    {
+    @Override public void initialize( final Engine engine, final Properties props ) {
     }
 
     /**
-     * Returns an array of Principal objects containing five elements:
-     * Role "Admin", Role.AUTHENTICATED, Role "IT", Role "Finance" and 
+     * Returns an array of Principal objects containing five elements: Role "Admin", Role.AUTHENTICATED, Role "IT", Role "Finance" and
      * Role "Engineering."
      */
-    public Principal[] getRoles()
+    @Override public Principal[] getRoles()
     {
         return m_roles;
     }
     
     /**
-     * Returns <code>true</code> if the WikiSession's Subject contains 
-     * a particular role principal.
+     * Returns <code>true</code> if the WikiSession's Subject contains a particular role principal.
      */
-    public boolean isUserInRole( WikiSession session, Principal role )
-    {
-        if ( session == null || role == null )
-        {
+    @Override public boolean isUserInRole( final WikiSession session, final Principal role ) {
+        if ( session == null || role == null ) {
             return false;
         }
         
@@ -87,7 +81,7 @@ public class TestAuthorizer implements WebAuthorizer
      * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}.
      * @see org.apache.wiki.auth.authorize.WebAuthorizer#isUserInRole(javax.servlet.http.HttpServletRequest, java.security.Principal)
      */
-    public boolean isUserInRole( HttpServletRequest request, Principal role )
+    @Override public boolean isUserInRole( final HttpServletRequest request, final Principal role )
     {
         return request.isUserInRole( role.getName() );
     }


[jspwiki] 10/38: JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 18604845ff3f3383a7a747eaf6129604f0123219
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:50:54 2020 +0100

    JSPWIKI-120: remove Engine#getCurrentWatchDog() use WatchDog.getCurrentWathDog( Engine ) instead
---
 jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
index 5b9d1c5..1afc4b1 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
@@ -1068,10 +1068,4 @@ public class WikiEngine implements Engine {
         return ( T )m_attributes.remove( key );
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public WatchDog getCurrentWatchDog() {
-        return WatchDog.getCurrentWatchDog( this );
-    }
-
 }


[jspwiki] 31/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (8)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 25c9ed0217ff9df195c18e6d7ccf89172f21ff6d
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:16:27 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (8)
---
 .../org/apache/wiki/rpc/atom/AtomAPIServlet.java   | 87 +++++++++++-----------
 .../java/org/apache/wiki/search/SearchManager.java |  7 +-
 .../wiki/tasks/pages/PreSaveWikiPageTask.java      | 27 ++++---
 .../apache/wiki/tasks/pages/SaveWikiPageTask.java  | 15 ++--
 4 files changed, 70 insertions(+), 66 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rpc/atom/AtomAPIServlet.java b/jspwiki-main/src/main/java/org/apache/wiki/rpc/atom/AtomAPIServlet.java
index 56dc601..084ecd2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rpc/atom/AtomAPIServlet.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rpc/atom/AtomAPIServlet.java
@@ -24,6 +24,7 @@ import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.plugin.WeblogEntryPlugin;
 import org.apache.wiki.plugin.WeblogPlugin;
 import org.apache.wiki.util.TextUtil;
@@ -65,7 +66,7 @@ public class AtomAPIServlet extends HttpServlet
     /**
      *  {@inheritDoc}
      */
-    public void init( ServletConfig config )
+    @Override public void init( final ServletConfig config )
         throws ServletException
     {
         m_engine = WikiEngine.getInstance( config );
@@ -76,7 +77,7 @@ public class AtomAPIServlet extends HttpServlet
      *  The initial slash is also removed.  If there is no page,
      *  returns null.
      */
-    private String getPageName( HttpServletRequest request )
+    private String getPageName( final HttpServletRequest request )
     {
         String name = request.getPathInfo();
 
@@ -107,16 +108,16 @@ public class AtomAPIServlet extends HttpServlet
      *  @param response {@inheritDoc}
      *  @throws ServletException {@inheritDoc}
      */
-    public void doPost( HttpServletRequest request, HttpServletResponse response )
+    @Override public void doPost( final HttpServletRequest request, final HttpServletResponse response )
         throws ServletException
     {
         log.debug("Received POST to AtomAPIServlet");
 
         try
         {
-            String blogid = getPageName( request );
+            final String blogid = getPageName( request );
 
-            WikiPage page    = m_engine.getPageManager().getPage( blogid );
+            final WikiPage page    = m_engine.getManager( PageManager.class ).getPage( blogid );
 
             if( page == null )
             {
@@ -124,39 +125,39 @@ public class AtomAPIServlet extends HttpServlet
             }
 
             //FIXME: Do authentication here
-            Entry entry = Sandler.unmarshallEntry( request.getInputStream() );
+            final Entry entry = Sandler.unmarshallEntry( request.getInputStream() );
 
             //
             //  Fetch the obligatory parts of the content.
             //
-            Content title   = entry.getTitle();
-            Content content = entry.getContent(0);
+            final Content title   = entry.getTitle();
+            final Content content = entry.getContent(0);
 
-            Person  author  = entry.getAuthor();
+            final Person  author  = entry.getAuthor();
 
             //FIXME: Sandler 0.5 does not support generator
 
             //
             //  Generate new blog entry.
             //
-            WeblogEntryPlugin plugin = new WeblogEntryPlugin();
+            final WeblogEntryPlugin plugin = new WeblogEntryPlugin();
 
-            String pageName = plugin.getNewEntryPage( m_engine, blogid );
-            String username = author.getName();
+            final String pageName = plugin.getNewEntryPage( m_engine, blogid );
+            final String username = author.getName();
 
-            WikiPage entryPage = new WikiPage( m_engine, pageName );
+            final WikiPage entryPage = new WikiPage( m_engine, pageName );
             entryPage.setAuthor( username );
 
-            WikiContext context = new WikiContext( m_engine, request, entryPage );
+            final WikiContext context = new WikiContext( m_engine, request, entryPage );
 
-            StringBuilder text = new StringBuilder();
+            final StringBuilder text = new StringBuilder();
             text.append( "!" + title.getBody() );
             text.append( "\n\n" );
             text.append( content.getBody() );
 
             log.debug("Writing entry: "+text);
 
-            m_engine.getPageManager().saveText( context, text.toString() );
+            m_engine.getManager( PageManager.class ).saveText( context, text.toString() );
 
         } catch( final FeedMarshallException e ) {
             log.error("Received faulty Atom entry",e);
@@ -176,12 +177,12 @@ public class AtomAPIServlet extends HttpServlet
      *  
      *  {@inheritDoc}
      */
-    public void doGet( HttpServletRequest request, HttpServletResponse response )
+    @Override public void doGet( final HttpServletRequest request, final HttpServletResponse response )
         throws ServletException
     {
         log.debug("Received HTTP GET to AtomAPIServlet");
 
-        String blogid = getPageName( request );
+        final String blogid = getPageName( request );
 
         log.debug("Requested page "+blogid);
 
@@ -189,7 +190,7 @@ public class AtomAPIServlet extends HttpServlet
         {
             if( blogid == null )
             {
-                Feed feed = listBlogs();
+                final Feed feed = listBlogs();
 
                 response.setContentType("application/x.atom+xml; charset=UTF-8");
                 response.getWriter().println( Sandler.marshallFeed(feed) );
@@ -198,7 +199,7 @@ public class AtomAPIServlet extends HttpServlet
             }
             else
             {
-                Entry entry = getBlogEntry( blogid );
+                final Entry entry = getBlogEntry( blogid );
 
                 response.setContentType("application/x.atom+xml; charset=UTF-8");
                 response.getWriter().println( Sandler.marshallEntry(entry) );
@@ -206,7 +207,7 @@ public class AtomAPIServlet extends HttpServlet
                 response.getWriter().flush();
             }
         }
-        catch( Exception e )
+        catch( final Exception e )
         {
             log.error("Unable to generate response",e);
             throw new ServletException("Internal problem - whack Janne on the head to get a better error report",e);
@@ -214,15 +215,15 @@ public class AtomAPIServlet extends HttpServlet
 
     }
 
-    private Entry getBlogEntry( String entryid ) {
-        WikiPage page = m_engine.getPageManager().getPage( entryid );
-        WikiPage firstVersion = m_engine.getPageManager().getPage( entryid, 1 );
+    private Entry getBlogEntry( final String entryid ) {
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( entryid );
+        final WikiPage firstVersion = m_engine.getManager( PageManager.class ).getPage( entryid, 1 );
 
-        Entry entry = SyndicationFactory.newSyndicationEntry();
+        final Entry entry = SyndicationFactory.newSyndicationEntry();
 
-        String pageText = m_engine.getPageManager().getText(page.getName());
+        final String pageText = m_engine.getManager( PageManager.class ).getText(page.getName());
         String title = "";
-        int firstLine = pageText.indexOf('\n');
+        final int firstLine = pageText.indexOf('\n');
 
         if( firstLine > 0 )
         {
@@ -250,15 +251,15 @@ public class AtomAPIServlet extends HttpServlet
      *  Creates and outputs a full list of all available blogs
      */
     private Feed listBlogs() throws ProviderException {
-        Collection< WikiPage > pages = m_engine.getPageManager().getAllPages();
+        final Collection< WikiPage > pages = m_engine.getManager( PageManager.class ).getAllPages();
 
-        Feed feed = SyndicationFactory.newSyndicationFeed();
+        final Feed feed = SyndicationFactory.newSyndicationFeed();
         feed.setTitle("List of blogs at this site");
         feed.setModified( new Date() );
 
-        for( Iterator< WikiPage > i = pages.iterator(); i.hasNext(); )
+        for( final Iterator< WikiPage > i = pages.iterator(); i.hasNext(); )
         {
-            WikiPage p = i.next();
+            final WikiPage p = i.next();
 
             //
             //  List only weblogs
@@ -273,21 +274,21 @@ public class AtomAPIServlet extends HttpServlet
                 continue;
             }
 
-            String encodedName = TextUtil.urlEncodeUTF8( p.getName() );
+            final String encodedName = TextUtil.urlEncodeUTF8( p.getName() );
 
-            WikiContext context = new WikiContext( m_engine, p );
+            final WikiContext context = new WikiContext( m_engine, p );
 
-            String title = TextUtil.replaceEntities(org.apache.wiki.rss.Feed.getSiteName(context));
+            final String title = TextUtil.replaceEntities(org.apache.wiki.rss.Feed.getSiteName(context));
 
-            Link postlink = createLink( "service.post",
+            final Link postlink = createLink( "service.post",
                                         m_engine.getBaseURL()+"atom/"+encodedName,
                                         title );
 
-            Link editlink = createLink( "service.edit",
+            final Link editlink = createLink( "service.edit",
                                         m_engine.getBaseURL()+"atom/"+encodedName,
                                         title );
 
-            Link feedlink = createLink( "service.feed",
+            final Link feedlink = createLink( "service.feed",
                                         m_engine.getBaseURL()+"atom.jsp?page="+encodedName,
                                         title );
 
@@ -300,11 +301,11 @@ public class AtomAPIServlet extends HttpServlet
         return feed;
     }
 
-    private Link createLink( String rel,
-                             String href,
-                             String title )
+    private Link createLink( final String rel,
+                             final String href,
+                             final String title )
     {
-        org.intabulas.sandler.elements.impl.LinkImpl link = new org.intabulas.sandler.elements.impl.LinkImpl();
+        final org.intabulas.sandler.elements.impl.LinkImpl link = new org.intabulas.sandler.elements.impl.LinkImpl();
 
         link.setRelationship( rel );
         link.setTitle( title );
@@ -317,14 +318,14 @@ public class AtomAPIServlet extends HttpServlet
     /**
      *  {@inheritDoc}
      */
-    public void doDelete( HttpServletRequest request, HttpServletResponse response ) {
+    @Override public void doDelete( final HttpServletRequest request, final HttpServletResponse response ) {
         log.debug("Received HTTP DELETE");
     }
 
     /**
      *  {@inheritDoc}
      */
-    public void doPut( HttpServletRequest request, HttpServletResponse response ) {
+    @Override public void doPut( final HttpServletRequest request, final HttpServletResponse response ) {
         log.debug("Received HTTP PUT");
     }
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java
index 2d975f4..53e1c5d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchManager.java
@@ -36,6 +36,7 @@ import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiPageEvent;
 import org.apache.wiki.modules.InternalModule;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.util.ClassUtil;
 
@@ -80,7 +81,7 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi
      */
     public SearchManager( final WikiEngine engine, final Properties properties ) throws FilterException {
         initialize( engine, properties );
-        WikiEventManager.getInstance().addWikiEventListener( m_engine.getPageManager(), this );
+        WikiEventManager.getInstance().addWikiEventListener( m_engine.getManager( PageManager.class ), this );
 
         //TODO: Replace with custom annotations. See JSPWIKI-566
         WikiAjaxDispatcherServlet.registerServlet( JSON_SEARCH, new JSONSearch() );
@@ -311,7 +312,7 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi
     @Override
     public void postSave( final WikiContext wikiContext, final String content ) {
         //  Makes sure that we're indexing the latest version of this page.
-        final WikiPage p = m_engine.getPageManager().getPage( wikiContext.getPage().getName() );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( wikiContext.getPage().getName() );
         reindexPage( p );
     }
 
@@ -335,7 +336,7 @@ public class SearchManager extends BasicPageFilter implements InternalModule, Wi
         if( event instanceof WikiPageEvent && event.getType() == WikiPageEvent.PAGE_DELETE_REQUEST ) {
             final String pageName = ( ( WikiPageEvent ) event ).getPageName();
 
-            final WikiPage p = m_engine.getPageManager().getPage( pageName );
+            final WikiPage p = m_engine.getManager( PageManager.class ).getPage( pageName );
             if( p != null ) {
                 pageRemoved( p );
             }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/PreSaveWikiPageTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/PreSaveWikiPageTask.java
index 1bd6b7c..006174e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/PreSaveWikiPageTask.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/PreSaveWikiPageTask.java
@@ -18,11 +18,10 @@
  */
 package org.apache.wiki.tasks.pages;
 
-import java.security.Principal;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.engine.FilterManager;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.tasks.TasksManager;
 import org.apache.wiki.workflow.Outcome;
@@ -30,6 +29,8 @@ import org.apache.wiki.workflow.Task;
 import org.apache.wiki.workflow.Workflow;
 import org.apache.wiki.workflow.WorkflowManager;
 
+import java.security.Principal;
+
 
 /**
  * Handles the page pre-save actions. If the proposed page text is the same as the current version, 
@@ -60,24 +61,22 @@ public class PreSaveWikiPageTask extends Task {
     @Override
     public Outcome execute() throws WikiException {
         // Retrieve attributes
-        WikiEngine engine = m_context.getEngine();
-        Workflow workflow = getWorkflow();
+        final Engine engine = m_context.getEngine();
+        final Workflow workflow = getWorkflow();
 
         // Get the wiki page
-        WikiPage page = m_context.getPage();
-
-        // Figure out who the author was. Prefer the author set programmatically; otherwise 
-        // get from the current logged in user
-        if (page.getAuthor() == null) {
-            Principal wup = m_context.getCurrentUser();
+        final WikiPage page = m_context.getPage();
 
-            if (wup != null) {
-                page.setAuthor(wup.getName());
+        // Figure out who the author was. Prefer the author set programmatically; otherwise get from the current logged in user
+        if( page.getAuthor() == null ) {
+            final Principal wup = m_context.getCurrentUser();
+            if( wup != null ) {
+                page.setAuthor( wup.getName() );
             }
         }
 
         // Run the pre-save filters. If any exceptions, add error to list, abort, and redirect
-        String saveText = engine.getFilterManager().doPreSaveFiltering(m_context, m_proposedText);
+        final String saveText = engine.getManager( FilterManager.class ).doPreSaveFiltering(m_context, m_proposedText);
 
         // Stash the wiki context, old and new text as workflow attributes
         workflow.setAttribute( WorkflowManager.WF_WP_SAVE_ATTR_PRESAVE_WIKI_CONTEXT, m_context );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/SaveWikiPageTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/SaveWikiPageTask.java
index e076fb8..7dcf18c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/SaveWikiPageTask.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/pages/SaveWikiPageTask.java
@@ -19,9 +19,12 @@
 package org.apache.wiki.tasks.pages;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.engine.FilterManager;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.tasks.TasksManager;
 import org.apache.wiki.workflow.Outcome;
 import org.apache.wiki.workflow.Task;
@@ -51,16 +54,16 @@ public class SaveWikiPageTask extends Task {
         final WikiContext context = ( WikiContext ) getWorkflow().getAttribute( WorkflowManager.WF_WP_SAVE_ATTR_PRESAVE_WIKI_CONTEXT );
         final String proposedText = (String) getWorkflow().getAttribute( WorkflowManager.WF_WP_SAVE_FACT_PROPOSED_TEXT );
 
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
         final WikiPage page = context.getPage();
 
         // Let the rest of the engine handle actual saving.
-        engine.getPageManager().putPageText( page, proposedText );
+        engine.getManager( PageManager.class ).putPageText( page, proposedText );
 
         // Refresh the context for post save filtering.
-        engine.getPageManager().getPage( page.getName() );
-        engine.getRenderingManager().textToHTML( context, proposedText );
-        engine.getFilterManager().doPostSaveFiltering( context, proposedText );
+        engine.getManager( PageManager.class ).getPage( page.getName() );
+        engine.getManager( RenderingManager.class ).textToHTML( context, proposedText );
+        engine.getManager( FilterManager.class ).doPostSaveFiltering( context, proposedText );
 
         return Outcome.STEP_COMPLETE;
     }


[jspwiki] 01/38: JSPWIKI-120: add adapt( Class< E > cls ) method to Engine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 52d21f1d4efd8931589399a7feba7e76ad63441e
Author: juanpablo <ju...@apache.org>
AuthorDate: Wed Feb 19 14:23:52 2020 +0100

    JSPWIKI-120: add adapt( Class< E > cls ) method to Engine
---
 .../src/main/java/org/apache/wiki/api/core/Engine.java        | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index 7cb1bf6..cc45798 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -82,6 +82,17 @@ public interface Engine {
     String PROP_ALLOW_CREATION_OF_EMPTY_PAGES = "jspwiki.allowCreationOfEmptyPages";
 
     /**
+     * Adapt Engine to a concrete type.
+     *
+     * @param cls class denoting the type to adapt to.
+     * @param <E> type to adapt to.
+     * @return engine instance adapted to the requested type. Might throw an unchecked exception if the instance cannot be adapted to requested type!
+     */
+    default < E extends Engine > E adapt( Class< E > cls ) {
+        return ( E )this;
+    }
+
+    /**
      * Retrieves the requested object instantiated by the Engine.
      *
      * @param manager requested object instantiated by the Engine.


[jspwiki] 17/38: translate WatchDog changes to JSPs

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit dc5168f2f47c1f4984a27a237a5603835066bca2
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 11:51:36 2020 +0100

    translate WatchDog changes to JSPs
---
 jspwiki-war/src/main/webapp/Diff.jsp     | 2 +-
 jspwiki-war/src/main/webapp/PageInfo.jsp | 2 +-
 jspwiki-war/src/main/webapp/Wiki.jsp     | 2 +-
 jspwiki-war/src/main/webapp/rss.jsp      | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/jspwiki-war/src/main/webapp/Diff.jsp b/jspwiki-war/src/main/webapp/Diff.jsp
index 1d2ede4..c9b8adf 100644
--- a/jspwiki-war/src/main/webapp/Diff.jsp
+++ b/jspwiki-war/src/main/webapp/Diff.jsp
@@ -41,7 +41,7 @@
     }
     String pagereq = wikiContext.getName();
 
-    WatchDog w = wiki.getCurrentWatchDog();
+    WatchDog w = WatchDog.getCurrentWatchDog( wiki );
     try
     {
     w.enterState("Generating INFO response",60);
diff --git a/jspwiki-war/src/main/webapp/PageInfo.jsp b/jspwiki-war/src/main/webapp/PageInfo.jsp
index fe5445c..ec7c848 100644
--- a/jspwiki-war/src/main/webapp/PageInfo.jsp
+++ b/jspwiki-war/src/main/webapp/PageInfo.jsp
@@ -39,7 +39,7 @@
     }
     String pagereq = wikiContext.getName();
 
-    WatchDog w = wiki.getCurrentWatchDog();
+    WatchDog w = WatchDog.getCurrentWatchDog( wiki );
     try {
     w.enterState("Generating INFO response",60);
 
diff --git a/jspwiki-war/src/main/webapp/Wiki.jsp b/jspwiki-war/src/main/webapp/Wiki.jsp
index 7dca137..b6fc66d 100644
--- a/jspwiki-war/src/main/webapp/Wiki.jsp
+++ b/jspwiki-war/src/main/webapp/Wiki.jsp
@@ -45,7 +45,7 @@
 
     StopWatch sw = new StopWatch();
     sw.start();
-    WatchDog w = wiki.getCurrentWatchDog();
+    WatchDog w = WatchDog.getCurrentWatchDog( wiki );
     try {
         w.enterState("Generating VIEW response for "+wikiContext.getPage(),60);
 
diff --git a/jspwiki-war/src/main/webapp/rss.jsp b/jspwiki-war/src/main/webapp/rss.jsp
index e528bb9..e60bd38 100644
--- a/jspwiki-war/src/main/webapp/rss.jsp
+++ b/jspwiki-war/src/main/webapp/rss.jsp
@@ -67,7 +67,7 @@
         return;
     }
 
-    WatchDog w = wiki.getCurrentWatchDog();
+    WatchDog w = WatchDog.getCurrentWatchDog( wiki );
     w.enterState("Generating RSS",60);
     
     // Set the mode and type for the feed


[jspwiki] 25/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (2)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 5ea8be0fc6358bf8367eacb90113e5d1767c1d85
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:11:26 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (2)
---
 .../org/apache/wiki/tags/AdminBeanIteratorTag.java |  20 +--
 .../apache/wiki/tags/AttachmentsIteratorTag.java   |   9 +-
 .../main/java/org/apache/wiki/tags/AuthorTag.java  |   9 +-
 .../java/org/apache/wiki/tags/BreadcrumbsTag.java  |  97 +++++------
 .../java/org/apache/wiki/tags/CalendarTag.java     |   9 +-
 .../java/org/apache/wiki/tags/CheckLockTag.java    |  70 +++-----
 .../java/org/apache/wiki/tags/CheckVersionTag.java |  12 +-
 .../org/apache/wiki/tags/ContentEncodingTag.java   |   7 +-
 .../main/java/org/apache/wiki/tags/ContentTag.java |  62 ++++---
 .../java/org/apache/wiki/tags/DiffLinkTag.java     |  15 +-
 .../java/org/apache/wiki/tags/EditLinkTag.java     |  78 ++++-----
 .../org/apache/wiki/tags/EditorIteratorTag.java    |  15 +-
 .../main/java/org/apache/wiki/tags/EditorTag.java  |  61 +++----
 .../org/apache/wiki/tags/FeedDiscoveryTag.java     |   8 +-
 .../org/apache/wiki/tags/HasAttachmentsTag.java    |  10 +-
 .../org/apache/wiki/tags/HistoryIteratorTag.java   |   9 +-
 .../main/java/org/apache/wiki/tags/IncludeTag.java |  56 +++----
 .../java/org/apache/wiki/tags/InsertDiffTag.java   |  14 +-
 .../java/org/apache/wiki/tags/InsertPageTag.java   |  18 +-
 .../main/java/org/apache/wiki/tags/LinkTag.java    |  34 ++--
 .../main/java/org/apache/wiki/tags/LinkToTag.java  |  31 ++--
 .../java/org/apache/wiki/tags/NoSuchPageTag.java   |  13 +-
 .../java/org/apache/wiki/tags/PageInfoLinkTag.java |   9 +-
 .../java/org/apache/wiki/tags/PageNameTag.java     |   8 +-
 .../java/org/apache/wiki/tags/PageSizeTag.java     |  10 +-
 .../org/apache/wiki/tags/ParentPageNameTag.java    |   9 +-
 .../java/org/apache/wiki/tags/PermissionTag.java   |   5 +-
 .../main/java/org/apache/wiki/tags/PluginTag.java  |  35 ++--
 .../java/org/apache/wiki/tags/RSSImageLinkTag.java |  50 +++---
 .../apache/wiki/tags/SearchResultIteratorTag.java  |  48 +++---
 .../java/org/apache/wiki/tags/TranslateTag.java    |   5 +-
 .../java/org/apache/wiki/tags/UserCheckTag.java    |   2 +-
 .../java/org/apache/wiki/tags/UserNameTag.java     |  43 +++--
 .../java/org/apache/wiki/tags/UserProfileTag.java  | 181 ++++++++-------------
 .../java/org/apache/wiki/tags/VariableTag.java     |  59 +++----
 35 files changed, 491 insertions(+), 630 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/AdminBeanIteratorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/AdminBeanIteratorTag.java
index 444dd73..49af855 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/AdminBeanIteratorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/AdminBeanIteratorTag.java
@@ -18,14 +18,13 @@
  */
 package org.apache.wiki.tags;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.engine.AdminBeanManager;
 import org.apache.wiki.ui.admin.AdminBean;
 
+import java.util.ArrayList;
+import java.util.Collection;
+
 /**
  *  Provides an iterator for all AdminBeans of a given type.
  *
@@ -41,11 +40,11 @@ public class AdminBeanIteratorTag extends IteratorTag {
      *  
      *  @param type Type to set
      */
-    public void setType( String type ) {
+    public void setType( final String type ) {
     	if (m_wikiContext == null) {
     		m_wikiContext = WikiContext.findContext(pageContext);
     	}
-        m_type = m_wikiContext.getEngine().getAdminBeanManager().getTypeFromString( type );
+        m_type = m_wikiContext.getEngine().getManager( AdminBeanManager.class ).getTypeFromString( type );
     }
 
     /**
@@ -53,11 +52,10 @@ public class AdminBeanIteratorTag extends IteratorTag {
      */
     @Override
     public void resetIterator() {
-        AdminBeanManager mgr = m_wikiContext.getEngine().getAdminBeanManager();
-        Collection< AdminBean > beans = mgr.getAllBeans();
-        ArrayList< AdminBean > typedBeans = new ArrayList< AdminBean >();
-        for( Iterator< AdminBean > i = beans.iterator(); i.hasNext(); ) {
-            AdminBean ab = i.next();
+        final AdminBeanManager mgr = m_wikiContext.getEngine().getManager( AdminBeanManager.class );
+        final Collection< AdminBean > beans = mgr.getAllBeans();
+        final ArrayList< AdminBean > typedBeans = new ArrayList<>();
+        for( final AdminBean ab : beans ) {
             if( ab.getType() == m_type ) {
                 typedBeans.add( ab );
             }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/AttachmentsIteratorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/AttachmentsIteratorTag.java
index 41f1c67..1825aca 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/AttachmentsIteratorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/AttachmentsIteratorTag.java
@@ -20,11 +20,12 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.PageContext;
@@ -54,8 +55,8 @@ public class AttachmentsIteratorTag extends IteratorTag {
     @Override
     public final int doStartTag()  {
         m_wikiContext = (WikiContext) pageContext.getAttribute( WikiContext.ATTR_CONTEXT, PageContext.REQUEST_SCOPE );
-        final WikiEngine engine = m_wikiContext.getEngine();
-        final AttachmentManager mgr = engine.getAttachmentManager();
+        final Engine engine = m_wikiContext.getEngine();
+        final AttachmentManager mgr = engine.getManager( AttachmentManager.class );
         final WikiPage page;
 
         page = m_wikiContext.getPage();
@@ -66,7 +67,7 @@ public class AttachmentsIteratorTag extends IteratorTag {
         }
 
         try {
-            if( page != null && engine.getPageManager().wikiPageExists(page) ) {
+            if( page != null && engine.getManager( PageManager.class ).wikiPageExists(page) ) {
                 final List< Attachment > atts = mgr.listAttachments( page );
 
                 if( atts == null ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/AuthorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/AuthorTag.java
index caac8e3..c278072 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/AuthorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/AuthorTag.java
@@ -18,9 +18,10 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.parser.WikiDocument;
 import org.apache.wiki.preferences.Preferences;
@@ -49,16 +50,16 @@ public class AuthorTag extends WikiTagBase {
      */
     @Override
     public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage   page   = m_wikiContext.getPage();
         String author = page.getAuthor();
 
         if( author != null && author.length() > 0 ) {
             author = TextUtil.replaceEntities(author);
 
-            if( engine.getPageManager().wikiPageExists(author) && !( "plain".equalsIgnoreCase( m_format ) ) ) {
+            if( engine.getManager( PageManager.class ).wikiPageExists(author) && !( "plain".equalsIgnoreCase( m_format ) ) ) {
                 // FIXME: It's very boring to have to do this.  Slow, too.
-                final RenderingManager mgr = engine.getRenderingManager();
+                final RenderingManager mgr = engine.getManager( RenderingManager.class );
                 final MarkupParser p = mgr.getParser( m_wikiContext, "["+author+"|"+author+"]" );
                 final WikiDocument d = p.parse();
                 author = mgr.getHTML( m_wikiContext, d );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/BreadcrumbsTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/BreadcrumbsTag.java
index 0ffa258..a6f44bc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/BreadcrumbsTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/BreadcrumbsTag.java
@@ -20,6 +20,7 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.util.TextUtil;
 
 import javax.servlet.http.HttpSession;
@@ -80,7 +81,7 @@ public class BreadcrumbsTag extends WikiTagBase
      *
      *  @param maxpages The amount.
      */
-    public void setMaxpages(int maxpages)
+    public void setMaxpages( final int maxpages)
     {
         m_maxQueueSize = maxpages + 1;
     }
@@ -100,7 +101,7 @@ public class BreadcrumbsTag extends WikiTagBase
      *
      *  @param separator A string which separates the page names.
      */
-    public void setSeparator(String separator)
+    public void setSeparator( final String separator)
     {
         m_separator = TextUtil.replaceEntities( separator );
     }
@@ -109,47 +110,34 @@ public class BreadcrumbsTag extends WikiTagBase
      *  {@inheritDoc}
      */
     @Override
-    public int doWikiStartTag() throws IOException
-    {
-        HttpSession session = pageContext.getSession();
-        FixedQueue  trail = (FixedQueue) session.getAttribute(BREADCRUMBTRAIL_KEY);
-
-        String page = m_wikiContext.getPage().getName();
+    public int doWikiStartTag() throws IOException {
+        final HttpSession session = pageContext.getSession();
+        FixedQueue trail = (FixedQueue) session.getAttribute(BREADCRUMBTRAIL_KEY);
+        final String page = m_wikiContext.getPage().getName();
 
-        if( trail == null )
-        {
+        if( trail == null ) {
             trail = new FixedQueue(m_maxQueueSize);
         } else {
             //  check if page still exists (could be deleted/renamed by another user)
             for (int i = 0;i<trail.size();i++) {
-                if (!m_wikiContext.getEngine().getPageManager().wikiPageExists(trail.get(i))) {
+                if( !m_wikiContext.getEngine().getManager( PageManager.class ).wikiPageExists( trail.get( i ) ) ) {
                     trail.remove(i);
                 }
             }
         }
 
-        if (m_wikiContext.getRequestContext().equals(WikiContext.VIEW))
-        {
-            if (m_wikiContext.getEngine().getPageManager().wikiPageExists(page))
-            {
-                if (trail.isEmpty())
-                {
-                    trail.pushItem(page);
-                }
-                else
-                {
-                    //
+        if( m_wikiContext.getRequestContext().equals( WikiContext.VIEW ) ) {
+            if( m_wikiContext.getEngine().getManager( PageManager.class ).wikiPageExists( page ) ) {
+                if( trail.isEmpty() ) {
+                    trail.pushItem( page );
+                } else {
                     // Don't add the page to the queue if the page was just refreshed
-                    //
-                    if (!trail.getLast().equals(page))
-                    {
-                        trail.pushItem(page);
+                    if( !trail.getLast().equals( page ) ) {
+                        trail.pushItem( page );
                     }
                 }
-            }
-            else
-            {
-                log.debug("didn't add page because it doesn't exist: " + page);
+            } else {
+                log.debug( "didn't add page because it doesn't exist: " + page );
             }
         }
 
@@ -162,22 +150,21 @@ public class BreadcrumbsTag extends WikiTagBase
         // FIXME: this code would be much simpler if we could just output the [pagename] and then use the
         // wiki engine to output the appropriate wikilink
 
-        JspWriter out     = pageContext.getOut();
-        int queueSize     = trail.size();
-        String linkclass  = "wikipage";
+        final JspWriter out     = pageContext.getOut();
+        final int queueSize     = trail.size();
+        final String linkclass  = "wikipage";
         String curPage    = null;
 
-        for( int i = 0; i < queueSize - 1; i++ )
-        {
+        for( int i = 0; i < queueSize - 1; i++ ) {
             curPage = trail.get(i);
 
             //FIXME: I can't figure out how to detect the appropriate jsp page to put here, so I hard coded Wiki.jsp
             //This breaks when you view an attachment metadata page
-            out.print("<a class=\"" + linkclass + "\" href=\"" + m_wikiContext.getViewURL(curPage)+ "\">"
-                        + TextUtil.replaceEntities( curPage ) + "</a>");
+            out.print( "<a class=\"" + linkclass + "\" href=\"" + m_wikiContext.getViewURL(curPage) + "\">" +
+                       TextUtil.replaceEntities( curPage ) +
+                       "</a>" );
 
-            if( i < queueSize - 2 )
-            {
+            if( i < queueSize - 2 ) {
                 out.print(m_separator);
             }
         }
@@ -188,23 +175,17 @@ public class BreadcrumbsTag extends WikiTagBase
     /**
      * Extends the LinkedList class to provide a fixed-size queue implementation
      */
-    public static class FixedQueue
-        extends LinkedList<String>
-        implements Serializable
-    {
+    public static class FixedQueue extends LinkedList< String > implements Serializable {
         private int m_size;
         private static final long serialVersionUID = 0L;
 
-        FixedQueue(int size)
-        {
+        FixedQueue( final int size ) {
             m_size = size;
         }
 
-        String pushItem(String o)
-        {
-            add(o);
-            if( size() > m_size )
-            {
+        String pushItem( final String o ) {
+            add( o );
+            if( size() > m_size ) {
                 return removeFirst();
             }
 
@@ -212,17 +193,13 @@ public class BreadcrumbsTag extends WikiTagBase
         }
 
         /**
-         * @param pageName
-         *            the page to be deleted from the breadcrumb
+         * @param pageName the page to be deleted from the breadcrumb
          */
-        public void removeItem(String pageName)
-        {
-            for (int i = 0; i < size(); i++)
-            {
-                String page = get(i);
-                if (page != null && page.equals(pageName))
-                {
-                    remove(page);
+        public void removeItem( final String pageName ) {
+            for( int i = 0; i < size(); i++ ) {
+                final String page = get( i );
+                if( page != null && page.equals( pageName ) ) {
+                    remove( page );
                 }
             }
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/CalendarTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/CalendarTag.java
index cbfd2f0..125e19c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/CalendarTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/CalendarTag.java
@@ -20,8 +20,9 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.util.HttpUtil;
 import org.apache.wiki.util.TextUtil;
 
@@ -138,13 +139,13 @@ public class CalendarTag extends WikiTagBase {
      *  Returns a link to the given day.
      */
     private String getDayLink( final Calendar day ) {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final String result;
 
         if( m_pageFormat != null ) {
             final String pagename = m_pageFormat.format( day.getTime() );
             
-            if( engine.getPageManager().wikiPageExists( pagename ) ) {
+            if( engine.getManager( PageManager.class ).wikiPageExists( pagename ) ) {
                 if( m_urlFormat != null ) {
                     final String url = m_urlFormat.format( day.getTime() );
                     result = "<td class=\"link\"><a href=\""+url+"\">"+day.get( Calendar.DATE )+"</a></td>";
@@ -240,7 +241,7 @@ public class CalendarTag extends WikiTagBase {
      */
     @Override
     public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final JspWriter out = pageContext.getOut();
         final Calendar cal = Calendar.getInstance();
         final Calendar prevCal = Calendar.getInstance();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckLockTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckLockTag.java
index 1dc4675..d6753c7 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckLockTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckLockTag.java
@@ -18,15 +18,14 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.pages.PageLock;
 import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.http.HttpSession;
+import java.io.IOException;
 
 /**
  *  Checks whether the page is locked for editing.  If the mode matches,
@@ -40,13 +39,11 @@ import javax.servlet.http.HttpSession;
  *  
  *  @since 2.0
  */
-public class CheckLockTag
-    extends WikiTagBase
-{
+public class CheckLockTag extends WikiTagBase {
+
     private static final long serialVersionUID = 1L;
     
-    private static enum LockState
-    {
+    private enum LockState {
         LOCKED, NOTLOCKED, OWNED
     }
 
@@ -56,8 +53,7 @@ public class CheckLockTag
      *  {@inheritDoc}
      */
     @Override
-    public void initTag()
-    {
+    public void initTag() {
         super.initTag();
         m_mode = LockState.NOTLOCKED;
     }
@@ -67,18 +63,12 @@ public class CheckLockTag
      *  
      *  @param arg A String for the mode.
      */
-    public void setMode( String arg )
-    {
-        if( "locked".equals(arg) )
-        {
+    public void setMode( final String arg ) {
+        if( "locked".equals( arg ) ) {
             m_mode = LockState.LOCKED;
-        }
-        else if("owned".equals(arg) )
-        {
+        } else if( "owned".equals( arg ) ) {
             m_mode = LockState.OWNED;
-        }
-        else
-        {
+        } else {
             m_mode = LockState.NOTLOCKED;
         }
     }
@@ -87,31 +77,21 @@ public class CheckLockTag
      *  {@inheritDoc}
      */
     @Override
-    public final int doWikiStartTag()
-        throws IOException,
-               ProviderException
-    {
-        WikiEngine engine = m_wikiContext.getEngine();
-        WikiPage   page   = m_wikiContext.getPage();
-
-        if( page != null )
-        {
-            PageManager mgr = engine.getPageManager();
-
-            PageLock lock = mgr.getCurrentLock( page );
-
-            HttpSession session = pageContext.getSession();
-
-            PageLock userLock = (PageLock) session.getAttribute("lock-"+page.getName());
-
-            if( (lock != null && m_mode == LockState.LOCKED && lock != userLock ) ||
-                (lock != null && m_mode == LockState.OWNED && lock == userLock ) ||
-                (lock == null && m_mode == LockState.NOTLOCKED) )
-            {
-                String tid = getId();
-
-                if( tid != null && lock != null )
-                {
+    public final int doWikiStartTag() throws IOException, ProviderException {
+        final Engine engine = m_wikiContext.getEngine();
+        final WikiPage page = m_wikiContext.getPage();
+
+        if( page != null ) {
+            final PageManager mgr = engine.getManager( PageManager.class );
+            final PageLock lock = mgr.getCurrentLock( page );
+            final HttpSession session = pageContext.getSession();
+            final PageLock userLock = ( PageLock )session.getAttribute( "lock-" + page.getName() );
+            if( ( lock != null && m_mode == LockState.LOCKED && lock != userLock ) ||
+                ( lock != null && m_mode == LockState.OWNED && lock == userLock )  ||
+                ( lock == null && m_mode == LockState.NOTLOCKED ) ) {
+
+                final String tid = getId();
+                if( tid != null && lock != null ) {
                     pageContext.setAttribute( tid, lock );
                 }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckVersionTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckVersionTag.java
index c51bf6f..58d4676 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckVersionTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/CheckVersionTag.java
@@ -19,8 +19,10 @@
 package org.apache.wiki.tags;
 
 import org.apache.wiki.InternalWikiException;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
+
 
 /**
  *  Does a version check on the page.  Mode is as follows:
@@ -75,13 +77,13 @@ public class CheckVersionTag extends WikiTagBase {
      */
     @Override
     public final int doWikiStartTag() {
-        final WikiEngine engine = m_wikiContext.getEngine();
-        final WikiPage   page   = m_wikiContext.getPage();
+        final Engine engine = m_wikiContext.getEngine();
+        final WikiPage page   = m_wikiContext.getPage();
 
-        if( page != null && engine.getPageManager().wikiPageExists(page.getName()) ) {
+        if( page != null && engine.getManager( PageManager.class ).wikiPageExists(page.getName()) ) {
             final int version = page.getVersion();
             final boolean include;
-            final WikiPage latest = engine.getPageManager().getPage( page.getName() );
+            final WikiPage latest = engine.getManager( PageManager.class ).getPage( page.getName() );
 
             switch( m_mode ) {
                 case LATEST    : include = (version < 0) || (latest.getVersion() == version); break;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentEncodingTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentEncodingTag.java
index a33a0d3..611e9c8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentEncodingTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentEncodingTag.java
@@ -18,7 +18,7 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 
 import java.io.IOException;
 
@@ -34,9 +34,10 @@ public class ContentEncodingTag extends WikiTagBase {
     /**
      *  {@inheritDoc}
      */
-    public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
         pageContext.getOut().print( engine.getContentEncoding() );
         return SKIP_BODY;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentTag.java
index 3e4b1f2..033d6d8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/ContentTag.java
@@ -18,16 +18,16 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.jsp.JspException;
-
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.ui.TemplateManager;
+
+import javax.servlet.ServletException;
+import javax.servlet.jsp.JspException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 
 /**
@@ -41,14 +41,14 @@ public class ContentTag extends WikiTagBase {
     private static final long serialVersionUID = 0L;
     private static final Logger log = Logger.getLogger( ContentTag.class );
     
-    private Map<String, String> m_mappings = new HashMap<String, String>();
+    private Map<String, String> m_mappings = new HashMap<>();
 
     /**
      *  Set the template for the VIEW context.
      *  
      *  @param s The template name.
      */
-    public void setView( String s )
+    public void setView( final String s )
     {
         m_mappings.put( WikiContext.VIEW, s );
     }
@@ -58,7 +58,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setDiff( String s )
+    public void setDiff( final String s )
     {
         m_mappings.put( WikiContext.DIFF, s );
     }
@@ -68,7 +68,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setInfo( String s )
+    public void setInfo( final String s )
     {
         m_mappings.put( WikiContext.INFO, s );
     }
@@ -78,7 +78,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setPreview( String s )
+    public void setPreview( final String s )
     {
         m_mappings.put( WikiContext.PREVIEW, s );
     }
@@ -88,7 +88,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setConflict( String s )
+    public void setConflict( final String s )
     {
         m_mappings.put( WikiContext.CONFLICT, s );
     }
@@ -98,7 +98,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setFind( String s )
+    public void setFind( final String s )
     {
         m_mappings.put( WikiContext.FIND, s );
     }
@@ -108,7 +108,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setPrefs( String s )
+    public void setPrefs( final String s )
     {
         m_mappings.put( WikiContext.PREFS, s );
     }
@@ -118,7 +118,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setError( String s )
+    public void setError( final String s )
     {
         m_mappings.put( WikiContext.ERROR, s );
     }
@@ -128,7 +128,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setEdit( String s )
+    public void setEdit( final String s )
     {
         m_mappings.put( WikiContext.EDIT, s );
     }
@@ -138,7 +138,7 @@ public class ContentTag extends WikiTagBase {
      *  
      *  @param s The template name.
      */
-    public void setComment( String s )
+    public void setComment( final String s )
     {
         m_mappings.put( WikiContext.COMMENT, s );
     }
@@ -146,7 +146,7 @@ public class ContentTag extends WikiTagBase {
     /**
      *  {@inheritDoc}
      */
-    public final int doWikiStartTag()
+    @Override public final int doWikiStartTag()
         throws IOException,
                ProviderException
     {
@@ -156,39 +156,37 @@ public class ContentTag extends WikiTagBase {
     /**
      *  {@inheritDoc}
      */
-    public final int doEndTag()
+    @Override public final int doEndTag()
         throws JspException
     {
         try
         {
             // Check the overridden templates first
-            String requestContext = m_wikiContext.getRequestContext();
+            final String requestContext = m_wikiContext.getRequestContext();
             String contentTemplate = m_mappings.get( requestContext );
 
             // If not found, use the defaults
-            if ( contentTemplate == null )
-            {
+            if( contentTemplate == null ) {
                 contentTemplate = m_wikiContext.getContentTemplate();
             }
-            
+
             // If still no, something fishy is going on
-            if( contentTemplate == null )
-            {
-                throw new JspException("This template uses <wiki:Content/> in an unsupported context: " + requestContext );
+            if( contentTemplate == null ) {
+                throw new JspException( "This template uses <wiki:Content/> in an unsupported context: " + requestContext );
             }
 
-            String page = m_wikiContext.getEngine().getTemplateManager().findJSP( pageContext,
-                                                                                  m_wikiContext.getTemplate(),
-                                                                                  contentTemplate );
+            final String page = m_wikiContext.getEngine().getManager( TemplateManager.class ).findJSP( pageContext,
+                                                                                                 m_wikiContext.getTemplate(),
+                                                                                                 contentTemplate );
             pageContext.include( page );
         }
-        catch( ServletException e )
+        catch( final ServletException e )
         {
             log.warn( "Including failed, got a servlet exception from sub-page. "+
                       "Rethrowing the exception to the JSP engine.", e );
             throw new JspException( e.getMessage() );
         }
-        catch( IOException e )
+        catch( final IOException e )
         {
             log.warn( "I/O exception - probably the connection was broken. "+
                       "Rethrowing the exception to the JSP engine.", e );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/DiffLinkTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/DiffLinkTag.java
index d660c46..d62f5f6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/DiffLinkTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/DiffLinkTag.java
@@ -19,9 +19,10 @@
 package org.apache.wiki.tags;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import java.io.IOException;
@@ -53,7 +54,7 @@ public class DiffLinkTag extends WikiLinkTag {
     private String m_version    = VER_LATEST;
     private String m_newVersion = VER_LATEST;
 
-    public void initTag()
+    @Override public void initTag()
     {
         super.initTag();
         m_version = m_newVersion = VER_LATEST;
@@ -79,8 +80,8 @@ public class DiffLinkTag extends WikiLinkTag {
         m_newVersion = arg;
     }
 
-    public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
         String pageName = m_pageName;
 
         if( m_pageName == null ) {
@@ -97,12 +98,12 @@ public class DiffLinkTag extends WikiLinkTag {
         int r2;
 
         //  In case the page does not exist, we fail silently.
-        if( !engine.getPageManager().wikiPageExists( pageName ) ) {
+        if( !engine.getManager( PageManager.class ).wikiPageExists( pageName ) ) {
             return SKIP_BODY;
         }
 
         if( VER_LATEST.equals(getVersion()) ) {
-            final WikiPage latest = engine.getPageManager().getPage( pageName, WikiProvider.LATEST_VERSION );
+            final WikiPage latest = engine.getManager( PageManager.class ).getPage( pageName, WikiProvider.LATEST_VERSION );
             if( latest == null ) {
                 // This may occur if matchEnglishPlurals is on, and we access the wrong page name
                 return SKIP_BODY;
@@ -118,7 +119,7 @@ public class DiffLinkTag extends WikiLinkTag {
         }
 
         if( VER_LATEST.equals( getNewVersion() ) ) {
-            final WikiPage latest = engine.getPageManager().getPage( pageName, WikiProvider.LATEST_VERSION );
+            final WikiPage latest = engine.getManager( PageManager.class ).getPage( pageName, WikiProvider.LATEST_VERSION );
             r2 = latest.getVersion();
         } else if( VER_PREVIOUS.equals( getNewVersion() ) ) {
             r2 = m_wikiContext.getPage().getVersion() - 1;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditLinkTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditLinkTag.java
index 8bbbd32..62622e1 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditLinkTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditLinkTag.java
@@ -19,8 +19,9 @@
 package org.apache.wiki.tags;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import java.io.IOException;
@@ -40,100 +41,82 @@ import java.io.IOException;
  *
  *  @since 2.0
  */
-public class EditLinkTag
-    extends WikiLinkTag
-{
+public class EditLinkTag extends WikiLinkTag {
+
     private static final long serialVersionUID = 0L;
     
     public String m_version = null;
     public String m_title = "";
     public String m_accesskey = "";
     
-    public void initTag()
-    {
+    @Override
+    public void initTag() {
         super.initTag();
         m_version = null;
     }
 
-    public void setVersion( String vers )
+    public void setVersion( final String vers )
     {
         m_version = vers;
     }
     
-    public void setTitle( String title )
+    public void setTitle( final String title )
     {
         m_title = title;
     }
 
-    public void setAccesskey( String access )
+    public void setAccesskey( final String access )
     {
         m_accesskey = access;
     }
 
-    public final int doWikiStartTag()
-        throws IOException
-    {
-        WikiEngine engine   = m_wikiContext.getEngine();
-        WikiPage   page     = null;
-        String     versionString = "";
-        String     pageName = null;
+    @Override
+    public final int doWikiStartTag() throws IOException {
+        final Engine engine   = m_wikiContext.getEngine();
+        WikiPage page = null;
+        String versionString = "";
+        final String pageName;
         
-        //
         //  Determine the page and the link.
-        //
-        if( m_pageName == null )
-        {
+        if( m_pageName == null ) {
             page = m_wikiContext.getPage();
-            if( page == null )
-            {
+            if( page == null ) {
                 // You can't call this on the page itself anyways.
                 return SKIP_BODY;
             }
 
             pageName = page.getName();
-        }
-        else
-        {
+        } else {
             pageName = m_pageName;
         }
 
         //
         //  Determine the latest version, if the version attribute is "this".
         //
-        if( m_version != null )
-        {
-            if( "this".equalsIgnoreCase(m_version) )
-            {
-                if( page == null )
-                {
+        if( m_version != null ) {
+            if( "this".equalsIgnoreCase( m_version ) ) {
+                if( page == null ) {
                     // No page, so go fetch according to page name.
-                    page = engine.getPageManager().getPage( m_pageName );
+                    page = engine.getManager( PageManager.class ).getPage( m_pageName );
                 }
-                
-                if( page != null )
-                {
-                    versionString = "version="+page.getVersion();
+
+                if( page != null ) {
+                    versionString = "version=" + page.getVersion();
                 }
-            }
-            else
-            {
-                versionString = "version="+m_version;
+            } else {
+                versionString = "version=" + m_version;
             }
         }
 
         //
-        //  Finally, print out the correct link, according to what
-        //  user commanded.
+        //  Finally, print out the correct link, according to what user commanded.
         //
-        JspWriter out = pageContext.getOut();
-
-        switch( m_format )
-        {
+        final JspWriter out = pageContext.getOut();
+        switch( m_format ) {
           case ANCHOR:
             out.print("<a href=\""+m_wikiContext.getURL(WikiContext.EDIT,pageName, versionString)
                      +"\" accesskey=\"" + m_accesskey + "\" title=\"" + m_title + "\">");
             break;
-
           case URL:
             out.print( m_wikiContext.getURL(WikiContext.EDIT,pageName,versionString) );
             break;
@@ -141,4 +124,5 @@ public class EditLinkTag
 
         return EVAL_BODY_INCLUDE;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorIteratorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorIteratorTag.java
index 690fe91..d1f6882 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorIteratorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorIteratorTag.java
@@ -18,9 +18,8 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.ui.Editor;
 import org.apache.wiki.ui.EditorManager;
 
@@ -36,20 +35,20 @@ import java.util.Collection;
 public class EditorIteratorTag extends IteratorTag  {
 
     private static final long serialVersionUID = 0L;
-    private static final Logger log = Logger.getLogger( EditorIteratorTag.class );
 
-    public final int doStartTag() {
+    @Override public final int doStartTag() {
         m_wikiContext = WikiContext.findContext(pageContext);
-        final WikiEngine engine = m_wikiContext.getEngine();
-        final EditorManager mgr = engine.getEditorManager();
+        final Engine engine = m_wikiContext.getEngine();
+        final EditorManager mgr = engine.getManager( EditorManager.class );
         final String[] editorList = mgr.getEditorList();
         final Collection< Editor > editors = new ArrayList<>();
 
-        for ( int i = 0; i < editorList.length; i++ ) {
-            editors.add( new Editor( m_wikiContext, editorList[ i ] ) );
+        for( final String editor : editorList ) {
+            editors.add( new Editor( m_wikiContext, editor ) );
         }
         setList( editors );
 
         return super.doStartTag();
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorTag.java
index 9866d32..095f847 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/EditorTag.java
@@ -18,14 +18,14 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
+import org.apache.log4j.Logger;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.ui.EditorManager;
+import org.apache.wiki.ui.TemplateManager;
 
 import javax.servlet.ServletException;
 import javax.servlet.jsp.JspException;
-
-import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.ui.EditorManager;
+import java.io.IOException;
 
 
 /**
@@ -42,45 +42,34 @@ public class EditorTag extends WikiBodyTag {
     private static final long serialVersionUID = 0L;
     private static final Logger log = Logger.getLogger( EditorTag.class );
     
-    public final int doWikiStartTag()
-        throws IOException
-    {
+    @Override
+    public final int doWikiStartTag() throws IOException {
         return SKIP_BODY;
     }
        
-    public int doEndTag() throws JspException
-    {
-        WikiEngine engine = m_wikiContext.getEngine();
-        EditorManager mgr = engine.getEditorManager();
-        
-        String editorPath = mgr.getEditorPath( m_wikiContext );
-        
-        try
-        {
-            String page = engine.getTemplateManager().findJSP( pageContext,
-                                                               m_wikiContext.getTemplate(),
-                                                               editorPath );
-            
-            if( page == null )
-            {
+    @Override
+    public int doEndTag() throws JspException {
+        final Engine engine = m_wikiContext.getEngine();
+        final EditorManager mgr = engine.getManager( EditorManager.class );
+        final String editorPath = mgr.getEditorPath( m_wikiContext );
+
+        try {
+            final String page = engine.getManager( TemplateManager.class ).findJSP( pageContext, m_wikiContext.getTemplate(), editorPath );
+
+            if( page == null ) {
                 //FIXME: should be I18N ...
-                pageContext.getOut().println("Unable to find editor '"+editorPath+"'");
-            }
-            else
-            {
+                pageContext.getOut().println( "Unable to find editor '" + editorPath + "'" );
+            } else {
                 pageContext.include( page );
             }
-        }
-        catch( ServletException e )
-        {
-            log.error("Failed to include editor",e);
-            throw new JspException("Failed to include editor: "+e.getMessage() );
-        }
-        catch( IOException e )
-        {
-            throw new JspException("Could not print Editor tag: "+e.getMessage() );
+        } catch( final ServletException e ) {
+            log.error( "Failed to include editor", e );
+            throw new JspException( "Failed to include editor: " + e.getMessage() );
+        } catch( final IOException e ) {
+            throw new JspException( "Could not print Editor tag: " + e.getMessage() );
         }
         
         return EVAL_PAGE;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/FeedDiscoveryTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/FeedDiscoveryTag.java
index 2acff88..3dd20a5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/FeedDiscoveryTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/FeedDiscoveryTag.java
@@ -19,8 +19,8 @@
 package org.apache.wiki.tags;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.plugin.WeblogPlugin;
 import org.apache.wiki.rss.Feed;
 import org.apache.wiki.util.TextUtil;
@@ -36,9 +36,9 @@ public class FeedDiscoveryTag extends WikiTagBase {
 
     private static final long serialVersionUID = 0L;
     
-    public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
-        final WikiPage   page   = m_wikiContext.getPage();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
+        final WikiPage page = m_wikiContext.getPage();
 
         final String encodedName = engine.encodeName( page.getName() );
         final String rssURL      = engine.getGlobalRSSURL();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/HasAttachmentsTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/HasAttachmentsTag.java
index 0192b7d..1d58bbd 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/HasAttachmentsTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/HasAttachmentsTag.java
@@ -19,10 +19,11 @@
 package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.AttachmentManager;
+import org.apache.wiki.pages.PageManager;
 
 
 /**
@@ -35,13 +36,14 @@ public class HasAttachmentsTag extends WikiTagBase {
     private static final long serialVersionUID = 0L;
     private static final Logger log = Logger.getLogger( HasAttachmentsTag.class );
     
+    @Override
     public final int doWikiStartTag() {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page = m_wikiContext.getPage();
-        final AttachmentManager mgr = engine.getAttachmentManager();
+        final AttachmentManager mgr = engine.getManager( AttachmentManager.class );
 
         try {
-            if( page != null && engine.getPageManager().wikiPageExists(page) && mgr.attachmentsEnabled() ) {
+            if( page != null && engine.getManager( PageManager.class ).wikiPageExists(page) && mgr.attachmentsEnabled() ) {
                 if( mgr.hasAttachments(page) ) {
                     return EVAL_BODY_INCLUDE;
                 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/HistoryIteratorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/HistoryIteratorTag.java
index 6686c54..0d674ae 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/HistoryIteratorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/HistoryIteratorTag.java
@@ -20,9 +20,10 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.PageContext;
@@ -48,12 +49,12 @@ public class HistoryIteratorTag extends IteratorTag  {
     @Override
     public final int doStartTag() {
         m_wikiContext = (WikiContext) pageContext.getAttribute( WikiContext.ATTR_CONTEXT, PageContext.REQUEST_SCOPE );
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page = m_wikiContext.getPage();
 
         try {
-            if( page != null && engine.getPageManager().wikiPageExists( page ) ) {
-                final List< WikiPage > versions = engine.getPageManager().getVersionHistory( page.getName() );
+            if( page != null && engine.getManager( PageManager.class ).wikiPageExists( page ) ) {
+                final List< WikiPage > versions = engine.getManager( PageManager.class ).getVersionHistory( page.getName() );
 
                 if( versions == null ) {
                     // There is no history
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/IncludeTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/IncludeTag.java
index 7abb30a..8332c63 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/IncludeTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/IncludeTag.java
@@ -18,15 +18,15 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.ServletException;
-
 import org.apache.log4j.Logger;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.ui.TemplateManager;
 import org.apache.wiki.util.TextUtil;
 
+import javax.servlet.ServletException;
+import javax.servlet.jsp.JspException;
+import java.io.IOException;
+
 /**
  *  Includes an another JSP page, making sure that we actually pass
  *  the WikiContext correctly.
@@ -41,13 +41,12 @@ public class IncludeTag extends WikiTagBase {
     
     protected String m_page;
 
-    public void initTag()
-    {
+    @Override public void initTag() {
         super.initTag();
         m_page = null;
     }
 
-    public void setPage( String page )
+    public void setPage( final String page )
     {
         m_page = page;
     }
@@ -57,7 +56,7 @@ public class IncludeTag extends WikiTagBase {
         return m_page;
     }
 
-    public final int doWikiStartTag()
+    @Override public final int doWikiStartTag()
         throws IOException,
                ProviderException
     {
@@ -66,37 +65,26 @@ public class IncludeTag extends WikiTagBase {
         return SKIP_BODY;
     }
 
-    public final int doEndTag()
-        throws JspException
-    {
-        try
-        {
-            String page = m_wikiContext.getEngine().getTemplateManager().findJSP( pageContext,
-                                                                                  m_wikiContext.getTemplate(),
-                                                                                  m_page );
-            
-            if( page == null )
-            {
-                pageContext.getOut().println("No template file called '"+TextUtil.replaceEntities(m_page)+"'");
-            }
-            else
-            {
+    @Override public final int doEndTag() throws JspException {
+        try {
+            final String page = m_wikiContext.getEngine().getManager( TemplateManager.class ).findJSP( pageContext,
+                                                                                                 m_wikiContext.getTemplate(),
+                                                                                                 m_page );
+
+            if( page == null ) {
+                pageContext.getOut().println( "No template file called '" + TextUtil.replaceEntities( m_page ) + "'" );
+            } else {
                 pageContext.include( page );
             }
-        }
-        catch( ServletException e )
-        {
-            log.warn( "Including failed, got a servlet exception from sub-page. "+
-                      "Rethrowing the exception to the JSP engine.", e );
+        } catch( final ServletException e ) {
+            log.warn( "Including failed, got a servlet exception from sub-page. Rethrowing the exception to the JSP engine.", e );
             throw new JspException( e.getMessage() );
-        }
-        catch( IOException e )
-        {
-            log.warn( "I/O exception - probably the connection was broken. "+
-                      "Rethrowing the exception to the JSP engine.", e );
+        } catch( final IOException e ) {
+            log.warn( "I/O exception - probably the connection was broken. Rethrowing the exception to the JSP engine.", e );
             throw new JspException( e.getMessage() );
         }
 
         return EVAL_PAGE;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertDiffTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertDiffTag.java
index 68152f6..7865639 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertDiffTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertDiffTag.java
@@ -20,7 +20,9 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.diff.DifferenceManager;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.PageContext;
@@ -51,7 +53,7 @@ public class InsertDiffTag extends WikiTagBase {
     protected String m_pageName;
 
     /** {@inheritDoc} */
-    public void initTag() {
+    @Override public void initTag() {
         super.initTag();
         m_pageName = null;
     }
@@ -75,15 +77,15 @@ public class InsertDiffTag extends WikiTagBase {
     }
 
     /** {@inheritDoc} */
-    public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
         final WikiContext ctx;
         
         if( m_pageName == null ) {
             ctx = m_wikiContext;
         } else {
             ctx = ( WikiContext )m_wikiContext.clone();
-            ctx.setPage( engine.getPageManager().getPage(m_pageName) );
+            ctx.setPage( engine.getManager( PageManager.class ).getPage(m_pageName) );
         }
 
         final Integer vernew = ( Integer )pageContext.getAttribute( ATTR_NEWVERSION, PageContext.REQUEST_SCOPE );
@@ -93,7 +95,7 @@ public class InsertDiffTag extends WikiTagBase {
 
         if( ctx.getPage() != null ) {
             final JspWriter out = pageContext.getOut();
-            final String diff = engine.getDifferenceManager().getDiff( ctx, vernew.intValue(), verold.intValue() );
+            final String diff = engine.getManager( DifferenceManager.class ).getDiff( ctx, vernew.intValue(), verold.intValue() );
 
             if( diff.length() == 0 ) {
                 return EVAL_BODY_INCLUDE;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertPageTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertPageTag.java
index e932cdd..1497f93 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertPageTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/InsertPageTag.java
@@ -19,9 +19,11 @@
 package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.render.RenderingManager;
 
 import javax.servlet.jsp.JspWriter;
 import java.io.IOException;
@@ -58,7 +60,7 @@ public class InsertPageTag extends WikiTagBase {
     protected String m_pageName = null;
     private   int    m_mode = HTML;
 
-    public void initTag() {
+    @Override public void initTag() {
         super.initTag();
         m_pageName = null;
         m_mode = HTML;
@@ -82,8 +84,8 @@ public class InsertPageTag extends WikiTagBase {
         }
     }
 
-    public final int doWikiStartTag() throws IOException, ProviderException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public final int doWikiStartTag() throws IOException, ProviderException {
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage insertedPage;
 
         //
@@ -94,9 +96,9 @@ public class InsertPageTag extends WikiTagBase {
 
         if( m_pageName == null ) {
             insertedPage = m_wikiContext.getPage();
-            if( !engine.getPageManager().wikiPageExists(insertedPage) ) return SKIP_BODY;
+            if( !engine.getManager( PageManager.class ).wikiPageExists(insertedPage) ) return SKIP_BODY;
         } else {
-            insertedPage = engine.getPageManager().getPage( m_pageName );
+            insertedPage = engine.getManager( PageManager.class ).getPage( m_pageName );
         }
 
         if( insertedPage != null ) {
@@ -109,8 +111,8 @@ public class InsertPageTag extends WikiTagBase {
             final WikiPage oldPage = m_wikiContext.setRealPage( insertedPage );
             
             switch( m_mode ) {
-              case HTML: out.print( engine.getRenderingManager().getHTML( m_wikiContext, insertedPage ) ); break;
-              case PLAIN: out.print( engine.getPageManager().getText( insertedPage ) ); break;
+              case HTML: out.print( engine.getManager( RenderingManager.class ).getHTML( m_wikiContext, insertedPage ) ); break;
+              case PLAIN: out.print( engine.getManager( PageManager.class ).getText( insertedPage ) ); break;
             }
             
             m_wikiContext.setRealPage( oldPage );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkTag.java
index e464f59..c4609ed 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkTag.java
@@ -20,11 +20,13 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.LinkParsingOperations;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.util.TextUtil;
@@ -67,7 +69,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
 
     private BodyContent m_bodyContent;
 
-    public void initTag() {
+    @Override public void initTag() {
         super.initTag();
         m_version = m_cssClass = m_style = m_title = m_target = m_compareToVersion = m_rel = m_jsp = m_ref = m_accesskey = m_templatefile = null;
         m_context = WikiContext.VIEW;
@@ -147,7 +149,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
     /**
      * Support for ParamTag supplied parameters in body.
      */
-    public void setContainedParameter( final String name, final String value ) {
+    @Override public void setContainedParameter( final String name, final String value ) {
         if( name != null ) {
             if( m_containedParams == null ) {
                 m_containedParams = new HashMap<>();
@@ -165,7 +167,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
      */
     private String figureOutURL() throws ProviderException {
         String url = null;
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
 
         if( m_pageName == null ) {
             final WikiPage page = m_wikiContext.getPage();
@@ -206,7 +208,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
                 //
                 //  Internal wiki link, but is it an attachment link?
                 //
-                final WikiPage p = engine.getPageManager().getPage( m_pageName );
+                final WikiPage p = engine.getManager( PageManager.class ).getPage( m_pageName );
 
                 if( p instanceof Attachment ) {
                     url = m_wikiContext.getURL( WikiContext.ATTACH, m_pageName );
@@ -233,7 +235,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
                 }
             }
         } else if( m_pageName != null && m_pageName.length() > 0 ) {
-            final WikiPage p = engine.getPageManager().getPage( m_pageName );
+            final WikiPage p = engine.getManager( PageManager.class ).getPage( m_pageName );
 
             String parms = (m_version != null) ? "version="+getVersion() : null;
 
@@ -286,14 +288,14 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
     }
 
     private String makeBasicURL( final String context, final String page, String parms ) {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
 
         if( context.equals( WikiContext.DIFF ) ) {
             int r1;
             int r2;
 
             if( DiffLinkTag.VER_LATEST.equals( getVersion() ) ) {
-                final WikiPage latest = engine.getPageManager().getPage( page, WikiProvider.LATEST_VERSION );
+                final WikiPage latest = engine.getManager( PageManager.class ).getPage( page, WikiProvider.LATEST_VERSION );
 
                 r1 = latest.getVersion();
             } else if( DiffLinkTag.VER_PREVIOUS.equals(getVersion()) ) {
@@ -306,7 +308,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
             }
 
             if( DiffLinkTag.VER_LATEST.equals(m_compareToVersion) ) {
-                final WikiPage latest = engine.getPageManager().getPage( page, WikiProvider.LATEST_VERSION );
+                final WikiPage latest = engine.getManager( PageManager.class ).getPage( page, WikiProvider.LATEST_VERSION );
 
                 r2 = latest.getVersion();
             } else if( DiffLinkTag.VER_PREVIOUS.equals(m_compareToVersion) ) {
@@ -324,13 +326,13 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
         return engine.getURL( m_context, m_pageName, parms );
     }
 
-    public int doWikiStartTag() throws Exception {
+    @Override public int doWikiStartTag() throws Exception {
         return EVAL_BODY_BUFFERED;
     }
 
-    public int doEndTag() {
+    @Override public int doEndTag() {
         try {
-            final WikiEngine engine = m_wikiContext.getEngine();
+            final Engine engine = m_wikiContext.getEngine();
             final JspWriter out = pageContext.getOut();
             final String url = figureOutURL();
 
@@ -344,8 +346,8 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
             sb.append( (m_accesskey != null) ? "accesskey=\""+m_accesskey+"\" " : "" );
             sb.append( (m_tabindex != null) ? "tabindex=\""+m_tabindex+"\" " : "" );
 
-            if( engine.getPageManager().getPage( m_pageName ) instanceof Attachment ) {
-                sb.append( engine.getAttachmentManager().forceDownload( m_pageName ) ? "download " : "" );
+            if( engine.getManager( PageManager.class ).getPage( m_pageName ) instanceof Attachment ) {
+                sb.append( engine.getManager( AttachmentManager.class ).forceDownload( m_pageName ) ? "download " : "" );
             }
 
             switch( m_format ) {
@@ -374,12 +376,12 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
         return EVAL_PAGE;
     }
 
-    public void setBodyContent( final BodyContent bc )
+    @Override public void setBodyContent( final BodyContent bc )
     {
         m_bodyContent = bc;
     }
 
-    public void doInitBody() {
+    @Override public void doInitBody() {
     }
 
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkToTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkToTag.java
index 8599189..8e48cbc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkToTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/LinkToTag.java
@@ -18,13 +18,14 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-
-import javax.servlet.jsp.JspWriter;
-
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
+
+import javax.servlet.jsp.JspWriter;
+import java.io.IOException;
+
 
 /**
  *  Writes a link to a Wiki page.  Body of the link becomes the actual text.
@@ -50,7 +51,7 @@ public class LinkToTag
     public String m_title = "";
     public String m_accesskey = "";
 
-    public void initTag()
+    @Override public void initTag()
     {
         super.initTag();
         m_version = null;
@@ -61,23 +62,23 @@ public class LinkToTag
         return m_version;
     }
 
-    public void setVersion( String arg )
+    public void setVersion( final String arg )
     {
         m_version = arg;
     }
 
-    public void setTitle( String title )
+    public void setTitle( final String title )
     {
         m_title = title;
     }
 
-    public void setAccesskey( String access )
+    public void setAccesskey( final String access )
     {
         m_accesskey = access;
     }
 
 
-    public int doWikiStartTag()
+    @Override public int doWikiStartTag()
         throws IOException
     {
         String     pageName = m_pageName;
@@ -85,7 +86,7 @@ public class LinkToTag
 
         if( m_pageName == null )
         {
-            WikiPage p = m_wikiContext.getPage();
+            final WikiPage p = m_wikiContext.getPage();
 
             if( p != null )
             {
@@ -99,9 +100,9 @@ public class LinkToTag
             }
         }
 
-        JspWriter out = pageContext.getOut();
-        String url;
-        String linkclass;
+        final JspWriter out = pageContext.getOut();
+        final String url;
+        final String linkclass;
         String forceDownload = "";
 
         if( isattachment )
@@ -110,7 +111,7 @@ public class LinkToTag
                                        (getVersion() != null) ? "version="+getVersion() : null );
             linkclass = "attachment";
 
-            if( m_wikiContext.getEngine().getAttachmentManager().forceDownload( pageName ) )
+            if( m_wikiContext.getEngine().getManager( AttachmentManager.class ).forceDownload( pageName ) )
             {
                 forceDownload = "download ";
             }
@@ -118,7 +119,7 @@ public class LinkToTag
         }
         else
         {
-        	StringBuilder params = new StringBuilder();
+        	final StringBuilder params = new StringBuilder();
             if( getVersion() != null ) params.append( "version="+getVersion() );
             if( getTemplate() != null ) params.append( (params.length()>0?"&amp;":"") + "skin="+getTemplate() );
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/NoSuchPageTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/NoSuchPageTag.java
index 40bfdb0..adbfacc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/NoSuchPageTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/NoSuchPageTag.java
@@ -18,9 +18,10 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
 
 import java.io.IOException;
 
@@ -35,7 +36,7 @@ public class NoSuchPageTag extends WikiTagBase {
     
     private String m_pageName;
 
-    public void initTag() {
+    @Override public void initTag() {
         super.initTag();
         m_pageName = null;
     }
@@ -50,17 +51,17 @@ public class NoSuchPageTag extends WikiTagBase {
         return m_pageName;
     }
 
-    public int doWikiStartTag() throws IOException, ProviderException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public int doWikiStartTag() throws IOException, ProviderException {
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page;
 
         if( m_pageName == null ) {
             page = m_wikiContext.getPage();
         } else {
-            page = engine.getPageManager().getPage( m_pageName );
+            page = engine.getManager( PageManager.class ).getPage( m_pageName );
         }
 
-        if( page != null && engine.getPageManager().wikiPageExists( page.getName(), page.getVersion() ) ) {
+        if( page != null && engine.getManager( PageManager.class ).wikiPageExists( page.getName(), page.getVersion() ) ) {
             return SKIP_BODY;
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageInfoLinkTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageInfoLinkTag.java
index bcc170b..1ecbd73 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageInfoLinkTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageInfoLinkTag.java
@@ -19,8 +19,9 @@
 package org.apache.wiki.tags;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 
 import javax.servlet.jsp.JspWriter;
 import java.io.IOException;
@@ -54,8 +55,8 @@ public class PageInfoLinkTag extends WikiLinkTag {
         m_accesskey = access;
     }
     
-    public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
         String     pageName = m_pageName;
 
         if( m_pageName == null ) {
@@ -67,7 +68,7 @@ public class PageInfoLinkTag extends WikiLinkTag {
             }
         }
 
-        if( engine.getPageManager().wikiPageExists(pageName) ) {
+        if( engine.getManager( PageManager.class ).wikiPageExists(pageName) ) {
             final JspWriter out = pageContext.getOut();
             final String url = m_wikiContext.getURL( WikiContext.INFO, pageName );
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageNameTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageNameTag.java
index 4372b04..7841a8c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageNameTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageNameTag.java
@@ -18,9 +18,10 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 
 import java.io.IOException;
@@ -34,15 +35,16 @@ public class PageNameTag extends WikiTagBase {
 
     private static final long serialVersionUID = 0L;
 
+    @Override
     public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page = m_wikiContext.getPage();
 
         if( page != null ) {
             if( page instanceof Attachment ) {
                 pageContext.getOut().print( TextUtil.replaceEntities( ((Attachment)page).getFileName() ) );
             } else {
-                pageContext.getOut().print( engine.getRenderingManager().beautifyTitle( m_wikiContext.getName() ) );
+                pageContext.getOut().print( engine.getManager( RenderingManager.class ).beautifyTitle( m_wikiContext.getName() ) );
             }
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageSizeTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageSizeTag.java
index 0e5764f..7dba42c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/PageSizeTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/PageSizeTag.java
@@ -19,9 +19,10 @@
 package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
 
 import java.io.IOException;
 
@@ -35,16 +36,17 @@ public class PageSizeTag extends WikiTagBase {
     private static final long serialVersionUID = 0L;
     private static final Logger log = Logger.getLogger( PageSizeTag.class );
     
+    @Override
     public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page = m_wikiContext.getPage();
 
         try {
             if( page != null ) {
                 long size = page.getSize();
 
-                if( size == -1 && engine.getPageManager().wikiPageExists( page ) ) { // should never happen with attachments
-                    size = engine.getPageManager().getPureText( page.getName(), page.getVersion() ).length();
+                if( size == -1 && engine.getManager( PageManager.class ).wikiPageExists( page ) ) { // should never happen with attachments
+                    size = engine.getManager( PageManager.class ).getPureText( page.getName(), page.getVersion() ).length();
                     page.setSize( size );
                 }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/ParentPageNameTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/ParentPageNameTag.java
index 6f32d83..44cd9d8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/ParentPageNameTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/ParentPageNameTag.java
@@ -18,9 +18,10 @@
  */
 package org.apache.wiki.tags;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.render.RenderingManager;
 
 import java.io.IOException;
 
@@ -38,12 +39,12 @@ public class ParentPageNameTag extends WikiTagBase {
      */
     @Override
     public final int doWikiStartTag() throws IOException {
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         final WikiPage page = m_wikiContext.getPage();
 
         if( page != null ) {
             if( page instanceof Attachment ) {
-                pageContext.getOut().print( engine.getRenderingManager().beautifyTitle( ((Attachment)page).getParentName()) );
+                pageContext.getOut().print( engine.getManager( RenderingManager.class ).beautifyTitle( ((Attachment)page).getParentName()) );
             } else {
                 String name = page.getName();
                 final int entrystart = name.indexOf("_blogentry_");
@@ -56,7 +57,7 @@ public class ParentPageNameTag extends WikiTagBase {
                     name = name.substring( 0, commentstart );
                 }
 
-                pageContext.getOut().print( engine.getRenderingManager().beautifyTitle(name) );
+                pageContext.getOut().print( engine.getManager( RenderingManager.class ).beautifyTitle(name) );
             }
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/PermissionTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/PermissionTag.java
index a6a246b..e3f6c3d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/PermissionTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/PermissionTag.java
@@ -28,6 +28,7 @@ import org.apache.wiki.auth.permissions.AllPermission;
 import org.apache.wiki.auth.permissions.GroupPermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
 import org.apache.wiki.auth.permissions.WikiPermission;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.ui.Command;
 import org.apache.wiki.ui.GroupCommand;
 
@@ -104,7 +105,7 @@ public class PermissionTag extends WikiTagBase {
     private boolean checkPermission( final String permission ) {
         final WikiSession session        = m_wikiContext.getWikiSession();
         final WikiPage    page           = m_wikiContext.getPage();
-        final AuthorizationManager mgr   = m_wikiContext.getEngine().getAuthorizationManager();
+        final AuthorizationManager mgr   = m_wikiContext.getEngine().getManager( AuthorizationManager.class );
         boolean gotPermission      = false;
         
         if ( CREATE_GROUPS.equals( permission ) || CREATE_PAGES.equals( permission ) || EDIT_PREFERENCES.equals( permission ) || EDIT_PROFILE.equals( permission ) || LOGIN.equals( permission ) ) {
@@ -130,7 +131,7 @@ public class PermissionTag extends WikiTagBase {
             //  Edit tag also checks that we're not trying to edit an old version: they cannot be edited.
             //
             if( EDIT.equals(permission) ) {
-                final WikiPage latest = m_wikiContext.getEngine().getPageManager().getPage( page.getName() );
+                final WikiPage latest = m_wikiContext.getEngine().getManager( PageManager.class ).getPage( page.getName() );
                 if( page.getVersion() != WikiProvider.LATEST_VERSION && latest.getVersion() != page.getVersion() ) {
                     return false;
                 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/PluginTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/PluginTag.java
index 55d560f..c971d71 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/PluginTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/PluginTag.java
@@ -18,17 +18,16 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-import java.util.Map;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.tagext.BodyContent;
-
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.engine.PluginManager;
 import org.apache.wiki.api.exceptions.PluginException;
 
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.BodyContent;
+import java.io.IOException;
+import java.util.Map;
+
 /**
  *  Inserts any Wiki plugin.  The body of the tag becomes then
  *  the body for the plugin.
@@ -67,7 +66,7 @@ public class PluginTag
      *  
      *  @param p Name of the plugin.
      */
-    public void setPlugin( String p )
+    public void setPlugin( final String p )
     {
         m_plugin = p;
     }
@@ -77,7 +76,7 @@ public class PluginTag
      *  
      *  @param a Arguments string.
      */
-    public void setArgs( String a )
+    public void setArgs( final String a )
     {
         m_args = a;
     }
@@ -92,22 +91,20 @@ public class PluginTag
         return EVAL_BODY_BUFFERED;
     }
 
-    private String executePlugin( String plugin, String args, String body )
-        throws PluginException, IOException
-    {
-        WikiEngine engine = m_wikiContext.getEngine();
-        PluginManager pm  = engine.getPluginManager();
+    private String executePlugin( final String plugin, final String args, final String body ) throws PluginException, IOException {
+        final Engine engine = m_wikiContext.getEngine();
+        final PluginManager pm  = engine.getManager( PluginManager.class );
 
         m_evaluated = true;
 
-        Map<String, String> argmap = pm.parseArgs( args );
+        final Map<String, String> argmap = pm.parseArgs( args );
         
         if( body != null ) 
         {
             argmap.put( "_body", body );
         }
 
-        String result = pm.execute( m_wikiContext, plugin, argmap );
+        final String result = pm.execute( m_wikiContext, plugin, argmap );
 
         return result;        
     }
@@ -125,7 +122,7 @@ public class PluginTag
             {
                 pageContext.getOut().write( executePlugin( m_plugin, m_args, null ) );
             }
-            catch( Exception e )
+            catch( final Exception e )
             {
                 log.error( "Failed to insert plugin", e );
                 throw new JspException( "Tag failed, check logs: "+e.getMessage() );
@@ -143,11 +140,11 @@ public class PluginTag
     {
         try
         {
-            BodyContent bc = getBodyContent();
+            final BodyContent bc = getBodyContent();
             
             getPreviousOut().write( executePlugin( m_plugin, m_args, (bc != null) ? bc.getString() : null) );
         }
-        catch( Exception e )
+        catch( final Exception e )
         {
             log.error( "Failed to insert plugin", e );
             throw new JspException( "Tag failed, check logs: "+e.getMessage() );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
index 3e35278..151a03c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
@@ -18,18 +18,17 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ResourceBundle;
-
-import javax.servlet.jsp.JspWriter;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.rss.RSSGenerator;
 
+import javax.servlet.jsp.JspWriter;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
 /**
  *  Writes an image link to a JSPWiki RSS file.  If RSS generation has
  *  been turned off in jspwiki.properties, returns an empty string.
@@ -62,12 +61,12 @@ public class RSSImageLinkTag
      *
      *  @param title A string for the title.
      */
-    public void setTitle( String title )
+    public void setTitle( final String title )
     {
         m_title = title;
     }
 
-    public void setMode( String mode )
+    public void setMode( final String mode )
     {
         m_mode = mode;
     }
@@ -87,31 +86,21 @@ public class RSSImageLinkTag
      *  {@inheritDoc}
      */
     @Override
-    public final int doWikiStartTag()
-        throws IOException
-    {
-        WikiEngine engine = m_wikiContext.getEngine();
-        JspWriter out = pageContext.getOut();
-        ResourceBundle rb = Preferences.getBundle( m_wikiContext, InternationalizationManager.CORE_BUNDLE );
-
-        if( engine.getRSSGenerator() != null && engine.getRSSGenerator().isEnabled() )
-        {
-            if( RSSGenerator.MODE_FULL.equals(m_mode) )
-            {
-                String rssURL = engine.getGlobalRSSURL();
-
-                if( rssURL != null )
-                {
+    public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
+        final JspWriter out = pageContext.getOut();
+        final ResourceBundle rb = Preferences.getBundle( m_wikiContext, InternationalizationManager.CORE_BUNDLE );
+        if( engine.getManager( RSSGenerator.class ) != null && engine.getManager( RSSGenerator.class ).isEnabled() ) {
+            if( RSSGenerator.MODE_FULL.equals(m_mode) ) {
+                final String rssURL = engine.getGlobalRSSURL();
+                if( rssURL != null ) {
                     out.print("<a class=\"feed\" href=\""+rssURL);
                     out.print( " title='"+rb.getString( "rss.title.full" )+"'>" );
                     out.print( "&nbsp;</a> ");
                 }
-            }
-            else
-            {
-                String page = m_pageName != null ? m_pageName : m_wikiContext.getPage().getName();
-
-                String params = "page="+page+"&mode="+m_mode;
+            } else {
+                final String page = m_pageName != null ? m_pageName : m_wikiContext.getPage().getName();
+                final String params = "page="+page+"&mode="+m_mode;
                 out.print( "<a href='"+m_wikiContext.getURL( WikiContext.NONE, "rss.jsp", params ));
                 out.print( "' class='feed'" );
                 out.print( " title='"+MessageFormat.format( rb.getString( "rss.title" ), page )+"'>" );
@@ -121,4 +110,5 @@ public class RSSImageLinkTag
 
         return SKIP_BODY;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/SearchResultIteratorTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/SearchResultIteratorTag.java
index f3f8ed2..a3da953 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/SearchResultIteratorTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/SearchResultIteratorTag.java
@@ -20,7 +20,7 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.search.SearchResult;
 import org.apache.wiki.ui.Command;
 import org.apache.wiki.ui.PageCommand;
@@ -41,11 +41,9 @@ import java.util.Collection;
  *
  *  @since 2.0
  */
-
 // FIXME: Shares MUCH too much in common with IteratorTag.  Must refactor.
-public class SearchResultIteratorTag
-    extends IteratorTag
-{
+public class SearchResultIteratorTag extends IteratorTag {
+
     private static final long serialVersionUID = 0L;
     
     private   int         m_maxItems;
@@ -54,30 +52,26 @@ public class SearchResultIteratorTag
     
     private static final Logger log = Logger.getLogger(SearchResultIteratorTag.class);
     
-    public void release()
+    @Override public void release()
     {
         super.release();
         m_maxItems = m_count = 0;
     }
 
-    public void setMaxItems( int arg )
+    public void setMaxItems( final int arg )
     {
         m_maxItems = arg;
     }
 
-    public void setStart( int arg )
+    public void setStart( final int arg )
     {
         m_start = arg;
     }
     
-    public final int doStartTag()
-    {
-        //
+    @Override public final int doStartTag() {
         //  Do lazy eval if the search results have not been set.
-        //
-        if( m_iterator == null )
-        {
-            Collection< ? > searchresults = (Collection< ? >)pageContext.getAttribute( "searchresults", PageContext.REQUEST_SCOPE );
+        if( m_iterator == null ) {
+            final Collection< ? > searchresults = (Collection< ? >)pageContext.getAttribute( "searchresults", PageContext.REQUEST_SCOPE );
             setList( searchresults );
             
             int skip = 0;
@@ -93,18 +87,16 @@ public class SearchResultIteratorTag
         return nextResult();
     }
 
-    private int nextResult()
-    {
-        if( m_iterator != null && m_iterator.hasNext() && m_count++ < m_maxItems )
-        {
-            SearchResult r = (SearchResult) m_iterator.next();
-            
+    private int nextResult() {
+        if( m_iterator != null && m_iterator.hasNext() && m_count++ < m_maxItems ) {
+            final SearchResult r = ( SearchResult )m_iterator.next();
+
             // Create a wiki context for the result
-            WikiEngine engine = m_wikiContext.getEngine();
-            HttpServletRequest request = m_wikiContext.getHttpRequest();
-            Command command = PageCommand.VIEW.targetedCommand( r.getPage() );
-            WikiContext context = new WikiContext( engine, request, command );
-            
+            final Engine engine = m_wikiContext.getEngine();
+            final HttpServletRequest request = m_wikiContext.getHttpRequest();
+            final Command command = PageCommand.VIEW.targetedCommand( r.getPage() );
+            final WikiContext context = new WikiContext( engine, request, command );
+
             // Stash it in the page context
             pageContext.setAttribute( WikiContext.ATTR_CONTEXT, context, PageContext.REQUEST_SCOPE );
             pageContext.setAttribute( getId(), r );
@@ -115,7 +107,7 @@ public class SearchResultIteratorTag
         return SKIP_BODY;
     }
 
-    public int doAfterBody() {
+    @Override public int doAfterBody() {
         if( bodyContent != null ) {
             try {
                 final JspWriter out = getPreviousOut();
@@ -130,7 +122,7 @@ public class SearchResultIteratorTag
         return nextResult();
     }
 
-    public int doEndTag() {
+    @Override public int doEndTag() {
         m_iterator = null;
         return super.doEndTag();
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/TranslateTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/TranslateTag.java
index f4355d2..48dec5e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/TranslateTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/TranslateTag.java
@@ -20,6 +20,7 @@ package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.render.RenderingManager;
 
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.PageContext;
@@ -38,7 +39,7 @@ public class TranslateTag
     
     private static final Logger log = Logger.getLogger( TranslateTag.class );
 
-    public final int doAfterBody() throws JspException {
+    @Override public final int doAfterBody() throws JspException {
         try {
             WikiContext context = (WikiContext) pageContext.getAttribute( WikiContext.ATTR_CONTEXT, PageContext.REQUEST_SCOPE );
 
@@ -52,7 +53,7 @@ public class TranslateTag
 
             if( wikiText != null ) {
                 wikiText = wikiText.trim();
-                final String result = context.getEngine().getRenderingManager().textToHTML( context, wikiText );
+                final String result = context.getEngine().getManager( RenderingManager.class ).textToHTML( context, wikiText );
                 getPreviousOut().write( result );
             }
         } catch( final Exception e ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserCheckTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserCheckTag.java
index 687d977..57fa5eb 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserCheckTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserCheckTag.java
@@ -112,7 +112,7 @@ public class UserCheckTag extends WikiTagBase {
     public final int doWikiStartTag() {
         final WikiSession session = m_wikiContext.getWikiSession();
         final String status = session.getStatus();
-        final AuthenticationManager mgr = m_wikiContext.getEngine().getAuthenticationManager();
+        final AuthenticationManager mgr = m_wikiContext.getEngine().getManager( AuthenticationManager.class );
         final boolean containerAuth = mgr.isContainerAuthenticated();
         final boolean cookieAssertions = mgr.allowsCookieAssertions();
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserNameTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserNameTag.java
index 3989c6c..9de5ee7 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserNameTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserNameTag.java
@@ -18,26 +18,25 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-import java.security.Principal;
-import java.util.regex.Pattern;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.util.TextUtil;
 
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.regex.Pattern;
+
+
 /**
- *  Returns the current user name, or empty, if the user has not been
- *  validated.
+ *  Returns the current user name, or empty, if the user has not been validated.
  *
  *  @since 2.0
  */
-public class UserNameTag extends WikiTagBase
-{
+public class UserNameTag extends WikiTagBase {
+
     private static final long serialVersionUID = 0L;
 
     private static String notStartWithBlankOrColon = "^[^( |:)]";
@@ -46,20 +45,15 @@ public class UserNameTag extends WikiTagBase
 
     private static final Pattern VALID_USER_NAME_PATTERN = Pattern.compile(notStartWithBlankOrColon + noColons);
 
-    public final int doWikiStartTag() throws IOException
-    {
-        WikiEngine engine = this.m_wikiContext.getEngine();
-        WikiSession wikiSession = WikiSession.getWikiSession(engine, (HttpServletRequest) pageContext.getRequest());
-        Principal user = wikiSession.getUserPrincipal();
+    @Override public final int doWikiStartTag() throws IOException {
+        final Engine engine = m_wikiContext.getEngine();
+        final WikiSession wikiSession = WikiSession.getWikiSession(engine, (HttpServletRequest) pageContext.getRequest());
+        final Principal user = wikiSession.getUserPrincipal();
 
-        if (user != null)
-        {
-            if (VALID_USER_NAME_PATTERN.matcher(user.getName()).matches())
-            {
-                pageContext.getOut().print(TextUtil.replaceEntities(user.getName()));
-            }
-            else
-            {
+        if( user != null ) {
+            if( VALID_USER_NAME_PATTERN.matcher( user.getName() ).matches() ) {
+                pageContext.getOut().print( TextUtil.replaceEntities( user.getName() ) );
+            } else {
                 pageContext.getOut().print( Preferences.getBundle( m_wikiContext, InternationalizationManager.CORE_BUNDLE )
                                                        .getString( "security.user.fullname.invalid" ) );
             }
@@ -67,4 +61,5 @@ public class UserNameTag extends WikiTagBase
 
         return SKIP_BODY;
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserProfileTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserProfileTag.java
index 5c6a75e..7d6fa86 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/UserProfileTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/UserProfileTag.java
@@ -18,17 +18,9 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ResourceBundle;
-
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.UserManager;
@@ -39,6 +31,13 @@ import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.util.TextUtil;
 
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
 /**
  * <p>
  * Returns user profile attributes, or empty strings if the user has not been
@@ -72,8 +71,8 @@ import org.apache.wiki.util.TextUtil;
  * negative condition (for example, <code>!exists</code>).</p>
  * @since 2.3
  */
-public class UserProfileTag extends WikiTagBase
-{
+public class UserProfileTag extends WikiTagBase {
+
     private static final long serialVersionUID = 3258410625431582003L;
 
     public  static final String BLANK = "(not set)";
@@ -112,99 +111,70 @@ public class UserProfileTag extends WikiTagBase
 
     private String             m_prop;
 
-    public void initTag()
-    {
+    @Override
+    public void initTag() {
         super.initTag();
         m_prop = null;
     }
 
-    public final int doWikiStartTag() throws IOException, WikiSecurityException
-    {
-        UserManager manager = m_wikiContext.getEngine().getUserManager();
-        UserProfile profile = manager.getUserProfile( m_wikiContext.getWikiSession() );
+    @Override
+    public final int doWikiStartTag() throws IOException, WikiSecurityException {
+        final UserManager manager = m_wikiContext.getEngine().getManager( UserManager.class );
+        final UserProfile profile = manager.getUserProfile( m_wikiContext.getWikiSession() );
         String result = null;
 
-        if ( EXISTS.equals( m_prop ) || NOT_NEW.equals( m_prop ) )
-        {
+        if( EXISTS.equals( m_prop ) || NOT_NEW.equals( m_prop ) ) {
             return profile.isNew() ? SKIP_BODY : EVAL_BODY_INCLUDE;
-        }
-        else if ( NEW.equals( m_prop ) || NOT_EXISTS.equals( m_prop ) )
-        {
+        } else if( NEW.equals( m_prop ) || NOT_EXISTS.equals( m_prop ) ) {
             return profile.isNew() ? EVAL_BODY_INCLUDE : SKIP_BODY;
-        }
-
-        else if ( CREATED.equals( m_prop ) && profile.getCreated() != null )
-        {
+        } else if( CREATED.equals( m_prop ) && profile.getCreated() != null ) {
             result = profile.getCreated().toString();
-        }
-        else if ( EMAIL.equals( m_prop ) )
-        {
+        } else if( EMAIL.equals( m_prop ) ) {
             result = profile.getEmail();
-        }
-        else if ( FULLNAME.equals( m_prop ) )
-        {
+        } else if( FULLNAME.equals( m_prop ) ) {
             result = profile.getFullname();
-        }
-        else if ( GROUPS.equals( m_prop ) )
-        {
+        } else if( GROUPS.equals( m_prop ) ) {
             result = printGroups( m_wikiContext );
-        }
-        else if ( LOGINNAME.equals( m_prop ) )
-        {
+        } else if( LOGINNAME.equals( m_prop ) ) {
             result = profile.getLoginName();
-        }
-        else if ( MODIFIED.equals( m_prop ) && profile.getLastModified() != null )
-        {
+        } else if( MODIFIED.equals( m_prop ) && profile.getLastModified() != null ) {
             result = profile.getLastModified().toString();
-        }
-        else if ( ROLES.equals( m_prop ) )
-        {
+        } else if( ROLES.equals( m_prop ) ) {
             result = printRoles( m_wikiContext );
-        }
-        else if ( WIKINAME.equals( m_prop ) )
-        {
+        } else if( WIKINAME.equals( m_prop ) ) {
             result = profile.getWikiName();
 
-            if( result == null )
-            {
+            if( result == null ) {
                 //
                 //  Default back to the declared user name
                 //
-                WikiEngine engine = this.m_wikiContext.getEngine();
-                WikiSession wikiSession = WikiSession.getWikiSession( engine, (HttpServletRequest)pageContext.getRequest() );
-                Principal user = wikiSession.getUserPrincipal();
+                final Engine engine = this.m_wikiContext.getEngine();
+                final WikiSession wikiSession = WikiSession.getWikiSession( engine, ( HttpServletRequest )pageContext.getRequest() );
+                final Principal user = wikiSession.getUserPrincipal();
 
-                if( user != null )
-                {
+                if( user != null ) {
                     result = user.getName();
                 }
             }
-        }
-        else if ( CHANGE_PASSWORD.equals( m_prop ) || CHANGE_LOGIN_NAME.equals( m_prop ) )
-        {
-            AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager();
-            if ( !authMgr.isContainerAuthenticated() )
-            {
+        } else if( CHANGE_PASSWORD.equals( m_prop ) || CHANGE_LOGIN_NAME.equals( m_prop ) ) {
+            final AuthenticationManager authMgr = m_wikiContext.getEngine().getManager( AuthenticationManager.class );
+            if( !authMgr.isContainerAuthenticated() ) {
                 return EVAL_BODY_INCLUDE;
             }
-        }
-        else if ( NOT_CHANGE_PASSWORD.equals( m_prop ) || NOT_CHANGE_LOGIN_NAME.equals( m_prop ) )
-        {
-            AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager();
-            if ( authMgr.isContainerAuthenticated() )
-            {
+        } else if( NOT_CHANGE_PASSWORD.equals( m_prop ) || NOT_CHANGE_LOGIN_NAME.equals( m_prop ) ) {
+            final AuthenticationManager authMgr = m_wikiContext.getEngine().getManager( AuthenticationManager.class );
+            if( authMgr.isContainerAuthenticated() ) {
                 return EVAL_BODY_INCLUDE;
             }
         }
 
-        if ( result != null )
-        {
-            pageContext.getOut().print( TextUtil.replaceEntities(result) );
+        if( result != null ) {
+            pageContext.getOut().print( TextUtil.replaceEntities( result ) );
         }
         return SKIP_BODY;
     }
 
-    public void setProperty( String property )
+    public void setProperty( final String property )
     {
         m_prop = property.toLowerCase().trim();
     }
@@ -216,34 +186,28 @@ public class UserProfileTag extends WikiTagBase
      * and extracting those that are of type Group.
      * @return the list of groups, sorted by name
      */
-    public static String printGroups( WikiContext context )
-    {
-        Principal[] roles = context.getWikiSession().getRoles();
-        List<String> tempRoles = new ArrayList<String>();
-        ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-        
-        for ( Principal role : roles )
-        {
-            if( role instanceof GroupPrincipal )
-            {
+    public static String printGroups( final WikiContext context ) {
+        final Principal[] roles = context.getWikiSession().getRoles();
+        final List< String > tempRoles = new ArrayList<>();
+        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
+
+        for( final Principal role : roles ) {
+            if( role instanceof GroupPrincipal ) {
                 tempRoles.add( role.getName() );
             }
         }
-        if ( tempRoles.size() == 0 )
-        {
-            return rb.getString("userprofile.nogroups");
+        if( tempRoles.size() == 0 ) {
+            return rb.getString( "userprofile.nogroups" );
         }
 
-        StringBuilder sb = new StringBuilder();
-        for ( int i = 0; i < tempRoles.size(); i++ )
-        {
-            String name = tempRoles.get( i );
+        final StringBuilder sb = new StringBuilder();
+        for( int i = 0; i < tempRoles.size(); i++ ) {
+            final String name = tempRoles.get( i );
 
             sb.append( name );
-            if ( i < ( tempRoles.size() - 1 ) )
-            {
-                sb.append(',');
-                sb.append(' ');
+            if( i < ( tempRoles.size() - 1 ) ) {
+                sb.append( ',' );
+                sb.append( ' ' );
             }
 
         }
@@ -257,37 +221,32 @@ public class UserProfileTag extends WikiTagBase
      * and extracting those that are of type Role.
      * @return the list of roles, sorted by name
      */
-    public static String printRoles( WikiContext context )
-    {
-        Principal[] roles = context.getWikiSession().getRoles();
-        List<String> tempRoles = new ArrayList<String>();
-        ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-        
-        for ( Principal role : roles )
-        {
-            if ( role instanceof Role )
-            {
+    public static String printRoles( final WikiContext context ) {
+        final Principal[] roles = context.getWikiSession().getRoles();
+        final List< String > tempRoles = new ArrayList<>();
+        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
+
+        for( final Principal role : roles ) {
+            if( role instanceof Role ) {
                 tempRoles.add( role.getName() );
             }
         }
-        if ( tempRoles.size() == 0 )
-        {
+        if( tempRoles.size() == 0 ) {
             return rb.getString( "userprofile.noroles" );
         }
 
-        StringBuilder sb = new StringBuilder();
-        for ( int i = 0; i < tempRoles.size(); i++ )
-        {
-            String name = tempRoles.get( i );
+        final StringBuilder sb = new StringBuilder();
+        for( int i = 0; i < tempRoles.size(); i++ ) {
+            final String name = tempRoles.get( i );
 
             sb.append( name );
-            if ( i < ( tempRoles.size() - 1 ) )
-            {
-                sb.append(',');
-                sb.append(' ');
+            if( i < ( tempRoles.size() - 1 ) ) {
+                sb.append( ',' );
+                sb.append( ' ' );
             }
 
         }
         return sb.toString();
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tags/VariableTag.java b/jspwiki-main/src/main/java/org/apache/wiki/tags/VariableTag.java
index 82328b0..45ccae6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tags/VariableTag.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tags/VariableTag.java
@@ -18,14 +18,14 @@
  */
 package org.apache.wiki.tags;
 
-import java.io.IOException;
-
-import javax.servlet.jsp.JspWriter;
-import javax.servlet.jsp.JspException;
-
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
 import org.apache.wiki.util.TextUtil;
+import org.apache.wiki.variables.VariableManager;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+import java.io.IOException;
 
 /**
  *  Returns the value of an Wiki variable.
@@ -43,16 +43,14 @@ import org.apache.wiki.util.TextUtil;
  *
  *  @since 2.0
  */
-public class VariableTag
-    extends WikiTagBase
-{
+public class VariableTag extends WikiTagBase {
+
     private static final long serialVersionUID = 0L;
 
     private String m_var      = null;
     private String m_default  = null;
 
-    public void initTag()
-    {
+    @Override public void initTag() {
         super.initTag();
         m_var = m_default = null;
     }
@@ -62,49 +60,40 @@ public class VariableTag
         return m_var;
     }
 
-    public void setVar( String arg )
+    public void setVar( final String arg )
     {
         m_var = arg;
     }
 
-    public void setDefault( String arg )
+    public void setDefault( final String arg )
     {
         m_default = arg;
     }
 
-    public final int doWikiStartTag()
-        throws JspException,
-               IOException
-    {
-        WikiEngine engine   = m_wikiContext.getEngine();
-        JspWriter out = pageContext.getOut();
+    @Override
+    public final int doWikiStartTag() throws JspException, IOException {
+        final Engine engine = m_wikiContext.getEngine();
+        final JspWriter out = pageContext.getOut();
         String msg = null;
         String value = null;
 
-        try
-        {
-            value = engine.getVariableManager().getValue( m_wikiContext,
-                                                          getVar() );
-        }
-        catch( NoSuchVariableException e )
-        {
-            msg = "No such variable: "+e.getMessage();
-        }
-        catch( IllegalArgumentException e )
-        {
-            msg = "Incorrect variable name: "+e.getMessage();
+        try {
+            value = engine.getManager( VariableManager.class ).getValue( m_wikiContext, getVar() );
+        } catch( final NoSuchVariableException e ) {
+            msg = "No such variable: " + e.getMessage();
+        } catch( final IllegalArgumentException e ) {
+            msg = "Incorrect variable name: " + e.getMessage();
         }
 
-        if( value == null )
-        {
+        if( value == null ) {
             value = m_default;
         }
 
-        if( value == null )
-        {
+        if( value == null ) {
             value = msg;
         }
         out.write( TextUtil.replaceEntities(value) );
         return SKIP_BODY;
     }
+
 }


[jspwiki] 26/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (3)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 25f87fd386a76ce06b022c0702c905800bb4821f
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:11:59 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (3)
---
 .../main/java/org/apache/wiki/rss/AtomFeed.java    | 11 ++---
 .../src/main/java/org/apache/wiki/rss/Feed.java    | 31 +++++++-------
 .../main/java/org/apache/wiki/rss/RSS10Feed.java   | 36 ++++++++--------
 .../main/java/org/apache/wiki/rss/RSS20Feed.java   | 48 +++++++++++-----------
 .../java/org/apache/wiki/rss/RSSGenerator.java     |  8 ++--
 5 files changed, 70 insertions(+), 64 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/AtomFeed.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/AtomFeed.java
index 4d38bc0..887accb 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/AtomFeed.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/AtomFeed.java
@@ -21,10 +21,11 @@ package org.apache.wiki.rss;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.wiki.Release;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.jdom2.Element;
 import org.jdom2.Namespace;
 import org.jdom2.output.Format;
@@ -76,7 +77,7 @@ public class AtomFeed extends Feed {
 
     private Collection<Element> getItems() {
         final ArrayList< Element > list = new ArrayList<>();
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         ServletContext servletContext = null;
         if( m_wikiContext.getHttpRequest() != null ) {
             servletContext = m_wikiContext.getHttpRequest().getSession().getServletContext();
@@ -97,9 +98,9 @@ public class AtomFeed extends Feed {
             entryEl.addContent( getElement( "content" ).setAttribute( "type", "html" ).setText( e.getContent() ) );
 
             //  Check for enclosures
-            if( engine.getAttachmentManager().hasAttachments( p ) && servletContext != null ) {
+            if( engine.getManager( AttachmentManager.class ).hasAttachments( p ) && servletContext != null ) {
                 try {
-                    final List< Attachment > c = engine.getAttachmentManager().listAttachments( p );
+                    final List< Attachment > c = engine.getManager( AttachmentManager.class ).listAttachments( p );
                     for( final Attachment att : c ) {
                         final Element attEl = getElement( "link" );
                         attEl.setAttribute( "rel", "enclosure" );
@@ -126,7 +127,7 @@ public class AtomFeed extends Feed {
     @Override
     public String getString() {
         final Element root = getElement("feed");
-        final WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
 
         Date lastModified = new Date(0L);
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/Feed.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/Feed.java
index 08bbcdf..92af083 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/Feed.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/Feed.java
@@ -20,8 +20,9 @@ package org.apache.wiki.rss;
 
 import org.apache.commons.text.StringEscapeUtils;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
+import org.apache.wiki.variables.VariableManager;
 
 import javax.servlet.ServletContext;
 import java.util.ArrayList;
@@ -31,7 +32,7 @@ import java.util.List;
  * Represents an abstract feed.
  */
 public abstract class Feed {
-    protected List<Entry> m_entries = new ArrayList<Entry>();
+    protected List<Entry> m_entries = new ArrayList<>();
 
     protected String m_feedURL;
     protected String m_channelTitle;
@@ -53,14 +54,14 @@ public abstract class Feed {
      * @param context the wiki context
      * @return the site name
      */
-    public static String getSiteName(WikiContext context) {
-        WikiEngine engine = context.getEngine();
+    public static String getSiteName( final WikiContext context ) {
+        final Engine engine = context.getEngine();
 
         String blogname = null;
 
         try {
-            blogname = engine.getVariableManager().getValue(context, VAR_BLOGNAME);
-        } catch (NoSuchVariableException e) {
+            blogname = engine.getManager( VariableManager.class ).getValue(context, VAR_BLOGNAME);
+        } catch( final NoSuchVariableException e ) {
         }
 
         if (blogname == null) {
@@ -75,7 +76,7 @@ public abstract class Feed {
      *
      * @param context The WikiContext.
      */
-    public Feed(WikiContext context) {
+    public Feed( final WikiContext context) {
         m_wikiContext = context;
     }
 
@@ -91,7 +92,7 @@ public abstract class Feed {
      *
      * @param mode As defined in RSSGenerator.
      */
-    public void setMode(String mode) {
+    public void setMode( final String mode) {
         m_mode = mode;
     }
 
@@ -100,7 +101,7 @@ public abstract class Feed {
      *
      * @param e The Entry to add.
      */
-    public void addEntry(Entry e) {
+    public void addEntry( final Entry e) {
         m_entries.add(e);
     }
 
@@ -121,7 +122,7 @@ public abstract class Feed {
     /**
      * @param description The m_channelDescription to set.
      */
-    public void setChannelDescription(String description) {
+    public void setChannelDescription( final String description) {
         m_channelDescription = description;
     }
 
@@ -135,7 +136,7 @@ public abstract class Feed {
     /**
      * @param language The m_channelLanguage to set.
      */
-    public void setChannelLanguage(String language) {
+    public void setChannelLanguage( final String language) {
         m_channelLanguage = language;
     }
 
@@ -149,7 +150,7 @@ public abstract class Feed {
     /**
      * @param title The m_channelTitle to set.
      */
-    public void setChannelTitle(String title) {
+    public void setChannelTitle( final String title) {
         m_channelTitle = title;
     }
 
@@ -163,7 +164,7 @@ public abstract class Feed {
     /**
      * @param feedurl The m_feedURL to set.
      */
-    public void setFeedURL(String feedurl) {
+    public void setFeedURL( final String feedurl) {
         m_feedURL = feedurl;
     }
 
@@ -174,7 +175,7 @@ public abstract class Feed {
      * @param name The filename
      * @return Something sane for a MIME type.
      */
-    protected String getMimeType(ServletContext c, String name) {
+    protected String getMimeType( final ServletContext c, final String name) {
         String type = c.getMimeType(name);
 
         if (type == null) {
@@ -190,7 +191,7 @@ public abstract class Feed {
      * @param s The String to format. Null is safe.
      * @return A formatted string.
      */
-    public static String format( String s ) {
+    public static String format( final String s ) {
         return StringEscapeUtils.escapeXml11( s );
     }
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS10Feed.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS10Feed.java
index 12f8625..57c8d07 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS10Feed.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS10Feed.java
@@ -19,8 +19,8 @@
 package org.apache.wiki.rss;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.util.XhtmlUtil;
 import org.jdom2.Element;
 import org.jdom2.Namespace;
@@ -46,16 +46,16 @@ public class RSS10Feed extends Feed {
      *
      * @param context The WikiContext.
      */
-    public RSS10Feed( WikiContext context ) {
+    public RSS10Feed( final WikiContext context ) {
         super( context );
     }
 
     private Element getRDFItems() {
-        Element items = new Element( "items", NS_XMNLS );
-        Element rdfseq = new Element( "Seq", NS_RDF );
+        final Element items = new Element( "items", NS_XMNLS );
+        final Element rdfseq = new Element( "Seq", NS_RDF );
 
-        for( Entry e : m_entries ) {
-            String url = e.getURL();
+        for( final Entry e : m_entries ) {
+            final String url = e.getURL();
             rdfseq.addContent( new Element( "li", NS_RDF ).setAttribute( "resource", url, NS_RDF ) );
         }
         items.addContent( rdfseq );
@@ -63,24 +63,24 @@ public class RSS10Feed extends Feed {
         return items;
     }
 
-    private void addItemList( Element root ) {
-        SimpleDateFormat iso8601fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-        WikiEngine engine = m_wikiContext.getEngine();
+    private void addItemList( final Element root ) {
+        final SimpleDateFormat iso8601fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        final Engine engine = m_wikiContext.getEngine();
 
-        for( Entry entry : m_entries ) {
-            String url = entry.getURL();
+        for( final Entry entry : m_entries ) {
+            final String url = entry.getURL();
 
-            Element item = new Element( "item", NS_XMNLS );
+            final Element item = new Element( "item", NS_XMNLS );
             item.setAttribute( "about", url, NS_RDF );
             item.addContent( new Element( "title", NS_XMNLS ).addContent( entry.getTitle() ) );
             item.addContent( new Element( "link", NS_XMNLS ).addContent( url ) );
 
-            Element content = new Element( "description", NS_XMNLS );
+            final Element content = new Element( "description", NS_XMNLS );
             // TODO: Add a size limiter here
             content.addContent( entry.getContent() );
             item.addContent( content );
 
-            WikiPage p = entry.getPage();
+            final WikiPage p = entry.getPage();
             if( p.getVersion() != -1 ) {
                 item.addContent( new Element( "version", NS_WIKI ).addContent( Integer.toString( p.getVersion() ) ) );
             }
@@ -92,7 +92,7 @@ public class RSS10Feed extends Feed {
 
             //
             //  Modification date.
-            Calendar cal = Calendar.getInstance();
+            final Calendar cal = Calendar.getInstance();
             cal.setTime(p.getLastModified());
             cal.add( Calendar.MILLISECOND,
                     - ( cal.get( Calendar.ZONE_OFFSET ) +
@@ -108,7 +108,7 @@ public class RSS10Feed extends Feed {
                 author = "unknown";
             }
 
-            Element contributor = new Element( "creator", NS_DC );
+            final Element contributor = new Element( "creator", NS_DC );
             item.addContent( contributor );
 
             /*
@@ -136,7 +136,7 @@ public class RSS10Feed extends Feed {
     }
 
     private Element getChannelElement() {
-        Element channel = new Element( "channel", NS_XMNLS );
+        final Element channel = new Element( "channel", NS_XMNLS );
         channel.setAttribute( "about", m_feedURL, NS_RDF )
                .addContent( new Element( "link", NS_XMNLS ).addContent( m_feedURL ) );
 
@@ -161,7 +161,7 @@ public class RSS10Feed extends Feed {
      */
     @Override
     public String getString() {
-        Element root = new Element( "RDF", NS_RDF );
+        final Element root = new Element( "RDF", NS_RDF );
         root.addContent( getChannelElement() );
         root.addNamespaceDeclaration( NS_XMNLS );
         root.addNamespaceDeclaration( NS_RDF );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS20Feed.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS20Feed.java
index d5026c2..a14b8d8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS20Feed.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSS20Feed.java
@@ -20,10 +20,12 @@ package org.apache.wiki.rss;
 
 import org.apache.wiki.Release;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
+import org.apache.wiki.variables.VariableManager;
 import org.jdom2.Element;
 import org.jdom2.output.Format;
 import org.jdom2.output.XMLOutputter;
@@ -50,30 +52,30 @@ public class RSS20Feed extends Feed
      *
      *  @param context The WikiContext.
      */
-    public RSS20Feed( WikiContext context )
+    public RSS20Feed( final WikiContext context )
     {
         super( context );
     }
 
     private List<Element> getItems()
     {
-        ArrayList<Element> list = new ArrayList<>();
-        SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
+        final ArrayList<Element> list = new ArrayList<>();
+        final SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
 
-        WikiEngine engine = m_wikiContext.getEngine();
+        final Engine engine = m_wikiContext.getEngine();
         ServletContext servletContext = null;
 
         if( m_wikiContext.getHttpRequest() != null )
             servletContext = m_wikiContext.getHttpRequest().getSession().getServletContext();
 
-        for( Iterator< Entry > i = m_entries.iterator(); i.hasNext(); )
+        for( final Iterator< Entry > i = m_entries.iterator(); i.hasNext(); )
         {
-            Entry e = i.next();
-            WikiPage p = e.getPage();
+            final Entry e = i.next();
+            final WikiPage p = e.getPage();
 
-            String url = e.getURL();
+            final String url = e.getURL();
 
-            Element item = new Element("item");
+            final Element item = new Element("item");
 
             item.addContent( new Element("link").setText(url) );
 
@@ -85,17 +87,17 @@ public class RSS20Feed extends Feed
             //  Attachments for enclosures
             //
 
-            if( engine.getAttachmentManager().hasAttachments(p) && servletContext != null )
+            if( engine.getManager( AttachmentManager.class ).hasAttachments(p) && servletContext != null )
             {
                 try
                 {
-                    List< Attachment > c = engine.getAttachmentManager().listAttachments(p);
+                    final List< Attachment > c = engine.getManager( AttachmentManager.class ).listAttachments(p);
 
-                    for( Iterator< Attachment > a = c.iterator(); a.hasNext(); )
+                    for( final Iterator< Attachment > a = c.iterator(); a.hasNext(); )
                     {
-                        Attachment att = a.next();
+                        final Attachment att = a.next();
 
-                        Element attEl = new Element("enclosure");
+                        final Element attEl = new Element("enclosure");
                         attEl.setAttribute( "url", engine.getURL( WikiContext.ATTACH, att.getName(), null ) );
                         attEl.setAttribute( "length", Long.toString(att.getSize()) );
                         attEl.setAttribute( "type", getMimeType( servletContext, att.getFileName() ) );
@@ -103,7 +105,7 @@ public class RSS20Feed extends Feed
                         item.addContent( attEl );
                     }
                 }
-                catch( ProviderException ex )
+                catch( final ProviderException ex )
                 {
                     // FIXME: log.info("Can't get attachment data",ex);
                 }
@@ -112,7 +114,7 @@ public class RSS20Feed extends Feed
             //
             //  Modification date.
             //
-            Calendar cal = Calendar.getInstance();
+            final Calendar cal = Calendar.getInstance();
             cal.setTime( p.getLastModified() );
             cal.add( Calendar.MILLISECOND,
                      - (cal.get( Calendar.ZONE_OFFSET ) +
@@ -132,11 +134,11 @@ public class RSS20Feed extends Feed
     @Override
     public String getString()
     {
-        WikiEngine engine = m_wikiContext.getEngine();
-        Element root = new Element("rss");
+        final Engine engine = m_wikiContext.getEngine();
+        final Element root = new Element("rss");
         root.setAttribute("version","2.0");
 
-        Element channel = new Element("channel");
+        final Element channel = new Element("channel");
         root.addContent( channel );
 
         //
@@ -152,10 +154,10 @@ public class RSS20Feed extends Feed
         channel.addContent( new Element("language").setText(getChannelLanguage()));
         channel.addContent( new Element("generator").setText("JSPWiki "+Release.VERSTR));
 
-        String mail = engine.getVariableManager().getVariable(m_wikiContext,RSSGenerator.PROP_RSS_AUTHOREMAIL);
+        String mail = engine.getManager( VariableManager.class ).getVariable(m_wikiContext,RSSGenerator.PROP_RSS_AUTHOREMAIL);
         if( mail != null )
         {
-            String editor = engine.getVariableManager().getVariable( m_wikiContext,RSSGenerator.PROP_RSS_AUTHOR );
+            final String editor = engine.getManager( VariableManager.class ).getVariable( m_wikiContext,RSSGenerator.PROP_RSS_AUTHOR );
 
             if( editor != null )
                 mail = mail + " ("+editor+")";
@@ -172,7 +174,7 @@ public class RSS20Feed extends Feed
         //
         //  aaand output
         //
-        XMLOutputter output = new XMLOutputter();
+        final XMLOutputter output = new XMLOutputter();
 
         output.setFormat( Format.getPrettyFormat() );
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSGenerator.java b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSGenerator.java
index d7df53c..cb48eb9 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSGenerator.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/rss/RSSGenerator.java
@@ -26,6 +26,8 @@ import org.apache.wiki.WikiProvider;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.diff.DifferenceManager;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.pages.PageTimeComparator;
 import org.apache.wiki.util.TextUtil;
 
@@ -180,7 +182,7 @@ public class RSSGenerator {
         final String author = getAuthor( page );
         final WikiContext ctx = new WikiContext( m_engine, page );
         if( page.getVersion() > 1 ) {
-            final String diff = m_engine.getDifferenceManager().getDiff( ctx,
+            final String diff = m_engine.getManager( DifferenceManager.class ).getDiff( ctx,
                                                                 page.getVersion() - 1, // FIXME: Will fail when non-contiguous versions
                                                                          page.getVersion() );
 
@@ -311,7 +313,7 @@ public class RSSGenerator {
         feed.setChannelLanguage( m_channelLanguage );
         feed.setChannelDescription( m_channelDescription );
 
-        final Set< WikiPage > changed = m_engine.getPageManager().getRecentChanges();
+        final Set< WikiPage > changed = m_engine.getManager( PageManager.class ).getRecentChanges();
 
         final WikiSession session = WikiSession.guestSession( m_engine );
         int items = 0;
@@ -449,7 +451,7 @@ public class RSSGenerator {
             e.setURL( url );
 
             //  Title
-            String pageText = m_engine.getPageManager().getPureText( page.getName(), WikiProvider.LATEST_VERSION );
+            String pageText = m_engine.getManager( PageManager.class ).getPureText( page.getName(), WikiProvider.LATEST_VERSION );
 
             String title = "";
             final int firstLine = pageText.indexOf('\n');


[jspwiki] 02/38: JSPWIKI-120: rename + extract interface from AttachmentManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 205b397c70d5e48ce5df1293622b6c7aee7436eb
Author: juanpablo <ju...@apache.org>
AuthorDate: Wed Feb 19 14:25:00 2020 +0100

    JSPWIKI-120: rename + extract interface from AttachmentManager
---
 .../apache/wiki/attachment/AttachmentManager.java  | 505 +++------------------
 .../wiki/attachment/DefaultAttachmentManager.java  | 350 ++++++++++++++
 2 files changed, 420 insertions(+), 435 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentManager.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentManager.java
index 7391967..07dd4a5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentManager.java
@@ -18,35 +18,21 @@
  */
 package org.apache.wiki.attachment;
 
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
-import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.exceptions.WikiException;
-import org.apache.wiki.pages.PageManager;
-import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.providers.WikiAttachmentProvider;
-import org.apache.wiki.util.ClassUtil;
-import org.apache.wiki.util.TextUtil;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
 import java.util.List;
-import java.util.Properties;
 
 
 /**
@@ -57,152 +43,35 @@ import java.util.Properties;
  *
  *  @since 1.9.28
  */
-public class AttachmentManager
-{
-    /**
-     *  The property name for defining the attachment provider class name.
-     */
-    public static final String  PROP_PROVIDER = "jspwiki.attachmentProvider";
-
-    /**
-     *  The maximum size of attachments that can be uploaded.
-     */
-    public static final String  PROP_MAXSIZE  = "jspwiki.attachment.maxsize";
+public interface AttachmentManager {
 
-    /**
-     *  A space-separated list of attachment types which can be uploaded
-     */
-    public static final String PROP_ALLOWEDEXTENSIONS    = "jspwiki.attachment.allowed";
+    /** The property name for defining the attachment provider class name. */
+    String PROP_PROVIDER = "jspwiki.attachmentProvider";
 
-    /**
-     *  A space-separated list of attachment types which cannot be uploaded
-     */
-    public static final String PROP_FORBIDDENEXTENSIONS = "jspwiki.attachment.forbidden";
+    /** The maximum size of attachments that can be uploaded. */
+    String PROP_MAXSIZE  = "jspwiki.attachment.maxsize";
 
-    /**
-     *  A space-separated list of attachment types which never will open in the browser.
-     */
-    public static final String PROP_FORCEDOWNLOAD = "jspwiki.attachment.forceDownload";
+    /** A space-separated list of attachment types which can be uploaded */
+    String PROP_ALLOWEDEXTENSIONS = "jspwiki.attachment.allowed";
 
-    /** List of attachment types which are forced to be downloaded */
-    private String[] m_forceDownloadPatterns;
+    /** A space-separated list of attachment types which cannot be uploaded */
+    String PROP_FORBIDDENEXTENSIONS = "jspwiki.attachment.forbidden";
 
-    static Logger log = Logger.getLogger( AttachmentManager.class );
-    private WikiAttachmentProvider m_provider;
-    private WikiEngine             m_engine;
-    private CacheManager m_cacheManager = CacheManager.getInstance();
+    /** A space-separated list of attachment types which never will open in the browser. */
+    String PROP_FORCEDOWNLOAD = "jspwiki.attachment.forceDownload";
 
-    private Cache m_dynamicAttachments;
     /** Name of the page cache. */
-    public static final String CACHE_NAME = "jspwiki.dynamicAttachmentCache";
+    String CACHE_NAME = "jspwiki.dynamicAttachmentCache";
 
     /** The capacity of the cache, if you want something else, tweak ehcache.xml. */
-    public static final int   DEFAULT_CACHECAPACITY   = 1000;
-
-    /**
-     *  Creates a new AttachmentManager.  Note that creation will never fail,
-     *  but it's quite likely that attachments do not function.
-     *  <p>
-     *  <b>DO NOT CREATE</b> an AttachmentManager on your own, unless you really
-     *  know what you're doing.  Just use WikiEngine.getAttachmentManager() if
-     *  you're making a module for JSPWiki.
-     *
-     *  @param engine The wikiengine that owns this attachment manager.
-     *  @param props  A list of properties from which the AttachmentManager will seek
-     *  its configuration.  Typically this is the "jspwiki.properties".
-     */
-
-    // FIXME: Perhaps this should fail somehow.
-    public AttachmentManager( WikiEngine engine, Properties props )
-    {
-        String classname;
-
-        m_engine = engine;
-
-
-        //
-        //  If user wants to use a cache, then we'll use the CachingProvider.
-        //
-        boolean useCache = "true".equals(props.getProperty( PageManager.PROP_USECACHE ));
-
-        if( useCache )
-        {
-            classname = "org.apache.wiki.providers.CachingAttachmentProvider";
-        }
-        else
-        {
-            classname = props.getProperty( PROP_PROVIDER );
-        }
-
-        //
-        //  If no class defined, then will just simply fail.
-        //
-        if( classname == null )
-        {
-            log.info( "No attachment provider defined - disabling attachment support." );
-            return;
-        }
-
-        //
-        //  Create and initialize the provider.
-        //
-        String cacheName = engine.getApplicationName() + "." + CACHE_NAME;
-        try {
-            if (m_cacheManager.cacheExists(cacheName)) {
-                m_dynamicAttachments = m_cacheManager.getCache(cacheName);
-            } else {
-                log.info("cache with name " + cacheName + " not found in ehcache.xml, creating it with defaults.");
-                m_dynamicAttachments = new Cache(cacheName, DEFAULT_CACHECAPACITY, false, false, 0, 0);
-                m_cacheManager.addCache(m_dynamicAttachments);
-            }
-
-            Class<?> providerclass = ClassUtil.findClass("org.apache.wiki.providers", classname);
-
-            m_provider = (WikiAttachmentProvider) providerclass.newInstance();
-
-            m_provider.initialize(m_engine, props);
-        } catch( ClassNotFoundException e )
-        {
-            log.error( "Attachment provider class not found",e);
-        }
-        catch( InstantiationException e )
-        {
-            log.error( "Attachment provider could not be created", e );
-        }
-        catch( IllegalAccessException e )
-        {
-            log.error( "You may not access the attachment provider class", e );
-        }
-        catch( NoRequiredPropertyException e )
-        {
-            log.error( "Attachment provider did not find a property that it needed: "+e.getMessage(), e );
-            m_provider = null; // No, it did not work.
-        }
-        catch( IOException e )
-        {
-            log.error( "Attachment provider reports IO error", e );
-            m_provider = null;
-        }
-
-        String forceDownload = TextUtil.getStringProperty( props, PROP_FORCEDOWNLOAD, null );
-
-        if( forceDownload != null && forceDownload.length() > 0 )
-            m_forceDownloadPatterns = forceDownload.toLowerCase().split("\\s");
-        else
-            m_forceDownloadPatterns = new String[0];
-
-
-    }
+    int DEFAULT_CACHECAPACITY = 1_000;
 
     /**
      *  Returns true, if attachments are enabled and running.
      *
      *  @return A boolean value indicating whether attachment functionality is enabled.
      */
-    public boolean attachmentsEnabled()
-    {
-        return m_provider != null;
-    }
+    boolean attachmentsEnabled();
 
     /**
      *  Gets info on a particular attachment, latest version.
@@ -211,9 +80,7 @@ public class AttachmentManager
      *  @return Attachment, or null, if no such attachment exists.
      *  @throws ProviderException If something goes wrong.
      */
-    public Attachment getAttachmentInfo( String name )
-        throws ProviderException
-    {
+    default Attachment getAttachmentInfo( final String name ) throws ProviderException {
         return getAttachmentInfo( name, WikiProvider.LATEST_VERSION );
     }
 
@@ -226,11 +93,8 @@ public class AttachmentManager
      *  @throws ProviderException If something goes wrong.
      */
 
-    public Attachment getAttachmentInfo( String name, int version )
-        throws ProviderException
-    {
-        if( name == null )
-        {
+    default Attachment getAttachmentInfo( final String name, final int version ) throws ProviderException {
+        if( name == null ) {
             return null;
         }
 
@@ -238,18 +102,14 @@ public class AttachmentManager
     }
 
     /**
-     *  Figures out the full attachment name from the context and
-     *  attachment name.
+     *  Figures out the full attachment name from the context and attachment name.
      *
      *  @param context The current WikiContext
      *  @param attachmentname The file name of the attachment.
      *  @return Attachment, or null, if no such attachment exists.
      *  @throws ProviderException If something goes wrong.
      */
-    public Attachment getAttachmentInfo( WikiContext context,
-                                         String attachmentname )
-        throws ProviderException
-    {
+    default Attachment getAttachmentInfo( final WikiContext context, final String attachmentname ) throws ProviderException {
         return getAttachmentInfo( context, attachmentname, WikiProvider.LATEST_VERSION );
     }
 
@@ -258,140 +118,42 @@ public class AttachmentManager
      *
      *  @param context The current WikiContext
      *  @param attachmentname The file name of the attachment.
-     *  @return Attachment, or null, if no such attachment exists.
+     *  @param version A particular version.
+     *  @return Attachment, or null, if no such attachment or version exists.
      *  @throws ProviderException If something goes wrong.
      */
-    public String getAttachmentInfoName( WikiContext context,
-                                         String attachmentname )
-    {
-        Attachment att = null;
-
-        try
-        {
-            att = getAttachmentInfo( context, attachmentname );
-        }
-        catch( ProviderException e )
-        {
-            log.warn("Finding attachments failed: ",e);
-            return null;
-        }
-
-        if( att != null )
-        {
-            return att.getName();
-        }
-        else if( attachmentname.indexOf('/') != -1 )
-        {
-            return attachmentname;
-        }
-
-        return null;
-    }
+    Attachment getAttachmentInfo( WikiContext context, String attachmentname, int version ) throws ProviderException;
 
     /**
-     *  Figures out the full attachment name from the context and
-     *  attachment name.
+     *  Figures out the full attachment name from the context and attachment name.
      *
      *  @param context The current WikiContext
      *  @param attachmentname The file name of the attachment.
-     *  @param version A particular version.
-     *  @return Attachment, or null, if no such attachment or version exists.
-     *  @throws ProviderException If something goes wrong.
+     *  @return Attachment, or null, if no such attachment exists.
      */
-
-    public Attachment getAttachmentInfo( final WikiContext context,
-                                         String attachmentname,
-                                         final int version ) throws ProviderException {
-        if( m_provider == null ) {
-            return null;
-        }
-
-        WikiPage currentPage = null;
-
-        if( context != null ) {
-            currentPage = context.getPage();
-        }
-
-        //
-        //  Figure out the parent page of this attachment.  If we can't find it, we'll assume this refers directly to the attachment.
-        //
-        final int cutpt = attachmentname.lastIndexOf('/');
-
-        if( cutpt != -1 ) {
-            String parentPage = attachmentname.substring(0,cutpt);
-            parentPage = MarkupParser.cleanLink( parentPage );
-            attachmentname = attachmentname.substring(cutpt+1);
-
-            // If we for some reason have an empty parent page name;
-            // this can't be an attachment
-            if(parentPage.length() == 0) return null;
-
-            currentPage = m_engine.getPageManager().getPage( parentPage );
-
-            //
-            // Go check for legacy name
-            //
-            // FIXME: This should be resolved using CommandResolver,
-            //        not this adhoc way.  This also assumes that the
-            //        legacy charset is a subset of the full allowed set.
-            if( currentPage == null ) {
-                currentPage = m_engine.getPageManager().getPage( MarkupParser.wikifyLink( parentPage ) );
-            }
-        }
-
-        //
-        //  If the page cannot be determined, we cannot possibly find the attachments.
-        //
-        if( currentPage == null || currentPage.getName().length() == 0 ) {
-            return null;
-        }
-
-        //
-        //  Finally, figure out whether this is a real attachment or a generated attachment.
-        //
-        Attachment att = getDynamicAttachment( currentPage.getName()+"/"+attachmentname );
-
-        if( att == null ) {
-            att = m_provider.getAttachmentInfo( currentPage, attachmentname, version );
-        }
-
-        return att;
-    }
+    String getAttachmentInfoName( WikiContext context, String attachmentname );
 
     /**
-     *  Returns the list of attachments associated with a given wiki page.
-     *  If there are no attachments, returns an empty Collection.
+     *  Returns the list of attachments associated with a given wiki page. If there are no attachments, returns an empty Collection.
      *
      *  @param wikipage The wiki page from which you are seeking attachments for.
      *  @return a valid collection of attachments.
      *  @throws ProviderException If there was something wrong in the backend.
      */
-    public List< Attachment > listAttachments( WikiPage wikipage ) throws ProviderException {
-        if( m_provider == null ) {
-            return new ArrayList<>();
-        }
-
-        List< Attachment >atts = new ArrayList<>( m_provider.listAttachments( wikipage ) );
-        Collections.< Attachment >sort( atts, Comparator.comparing( Attachment::getName, m_engine.getPageManager().getPageSorter() ) );
-
-        return atts;
-    }
+    List< Attachment > listAttachments( WikiPage wikipage ) throws ProviderException;
 
     /**
-     *  Returns true, if the page has any attachments at all.  This is
-     *  a convinience method.
-     *
+     *  Returns true, if the page has any attachments at all.  This is a convenience method.
      *
      *  @param wikipage The wiki page from which you are seeking attachments for.
      *  @return True, if the page has attachments, else false.
      */
-    public boolean hasAttachments( WikiPage wikipage )
-    {
-        try
-        {
+    default boolean hasAttachments( final WikiPage wikipage ) {
+        try {
             return listAttachments( wikipage ).size() > 0;
+        } catch( final Exception e ) {
+            Logger.getLogger( AttachmentManager.class ).info( e.getMessage(), e );
         }
-        catch( Exception e ) {}
 
         return false;
     }
@@ -403,103 +165,49 @@ public class AttachmentManager
      *  @return true, if the attachment should be downloaded when clicking the link
      *  @since 2.11.0 M4
     */
-    public boolean forceDownload( String name )
-    {
-        if( name == null || name.length() == 0 ) return false;
-
-        name = name.toLowerCase();
-
-        if( name.indexOf('.') == -1) return true;  //force download on attachments without extension or type indication
-
-        for( int i = 0; i < m_forceDownloadPatterns.length; i++ )
-        {
-            if( name.endsWith(m_forceDownloadPatterns[i]) && m_forceDownloadPatterns[i].length() > 0 )
-                return true;
-        }
-
-        return false;
-    }
+    boolean forceDownload( String name );
 
     /**
-     *  Finds a (real) attachment from the repository as a stream.
+     *  Finds a (real) attachment from the repository as an {@link InputStream}.
      *
      *  @param att Attachment
-     *  @return An InputStream to read from.  May return null, if
-     *          attachments are disabled.
+     *  @return An InputStream to read from. May return null, if attachments are disabled.
      *  @throws IOException If the stream cannot be opened
      *  @throws ProviderException If the backend fails due to some other reason.
      */
-    public InputStream getAttachmentStream( Attachment att )
-        throws IOException,
-               ProviderException
-    {
+    default InputStream getAttachmentStream( final Attachment att ) throws IOException, ProviderException {
         return getAttachmentStream( null, att );
     }
 
     /**
-     *  Returns an attachment stream using the particular WikiContext.  This method
-     *  should be used instead of getAttachmentStream(Attachment), since it also allows
-     *  the DynamicAttachments to function.
+     *  Returns an attachment stream using the particular WikiContext. This method should be used instead of
+     *  {@link #getAttachmentStream(Attachment)}, since it also allows the DynamicAttachments to function.
      *
      *  @param ctx The Wiki Context
      *  @param att The Attachment to find
-     *  @return An InputStream.  May return null, if attachments are disabled.  You must
-     *          take care of closing it.
+     *  @return An InputStream.  May return null, if attachments are disabled.  You must take care of closing it.
      *  @throws ProviderException If the backend fails due to some reason
      *  @throws IOException If the stream cannot be opened
      */
-    public InputStream getAttachmentStream( WikiContext ctx, Attachment att )
-        throws ProviderException, IOException
-    {
-        if( m_provider == null )
-        {
-            return null;
-        }
-
-        if( att instanceof DynamicAttachment )
-        {
-            return ((DynamicAttachment)att).getProvider().getAttachmentData( ctx, att );
-        }
-
-        return m_provider.getAttachmentData( att );
-    }
-
-
+    InputStream getAttachmentStream( WikiContext ctx, Attachment att ) throws ProviderException, IOException;
 
     /**
-     *  Stores a dynamic attachment.  Unlike storeAttachment(), this just stores
-     *  the attachment in the memory.
+     *  Stores a dynamic attachment.  Unlike storeAttachment(), this just stores the attachment in the memory.
      *
      *  @param ctx A WikiContext
      *  @param att An attachment to store
      */
-    public void storeDynamicAttachment( WikiContext ctx, DynamicAttachment att )
-    {
-        m_dynamicAttachments.put(new Element(att.getName(), att));
-    }
+    void storeDynamicAttachment( WikiContext ctx, DynamicAttachment att );
 
     /**
-     *  Finds a DynamicAttachment.  Normally, you should just use getAttachmentInfo(),
-     *  since that will find also DynamicAttachments.
+     *  Finds a DynamicAttachment.  Normally, you should just use {@link #getAttachmentInfo(String)} , since that will find also
+     *  {@link DynamicAttachment}s.
      *
      *  @param name The name of the attachment to look for
      *  @return An Attachment, or null.
      *  @see #getAttachmentInfo(String)
      */
-
-    public DynamicAttachment getDynamicAttachment(String name) {
-        Element element = m_dynamicAttachments.get(name);
-        if (element != null) {
-            return (DynamicAttachment) element.getObjectValue();
-        } else {
-            //
-            //  Remove from cache, it has expired.
-            //
-            m_dynamicAttachments.put(new Element(name, null));
-
-            return null;
-        }
-    }
+    DynamicAttachment getDynamicAttachment( String name );
 
     /**
      *  Stores an attachment that lives in the given file. If the attachment did not exist previously, this method will create it.
@@ -511,7 +219,7 @@ public class AttachmentManager
      *  @throws IOException If writing the attachment failed.
      *  @throws ProviderException If something else went wrong.
      */
-    public void storeAttachment( final Attachment att, final File source ) throws IOException, ProviderException {
+    default void storeAttachment( final Attachment att, final File source ) throws IOException, ProviderException {
         try( final FileInputStream in = new FileInputStream( source ) ) {
             storeAttachment( att, in );
         }
@@ -523,29 +231,10 @@ public class AttachmentManager
      *
      *  @param att Attachment to store this under.
      *  @param in  InputStream from which the attachment contents will be read.
-     *
      *  @throws IOException If writing the attachment failed.
      *  @throws ProviderException If something else went wrong.
      */
-    public void storeAttachment( final Attachment att, final InputStream in ) throws IOException, ProviderException {
-        if( m_provider == null ) {
-            return;
-        }
-
-        //  Checks if the actual, real page exists without any modifications
-        //  or aliases.  We cannot store an attachment to a non-existent page.
-        if( !m_engine.getPageManager().pageExists( att.getParentName() ) ) {
-            // the caller should catch the exception and use the exception text as an i18n key
-            throw new ProviderException( "attach.parent.not.exist" );
-        }
-
-        m_provider.putAttachmentData( att, in );
-        m_engine.getReferenceManager().updateReferences( att.getName(), new ArrayList<>() );
-
-        final WikiPage parent = new WikiPage( m_engine, att.getParentName() );
-        m_engine.getReferenceManager().updateReferences( parent );
-        m_engine.getSearchManager().reindexPage( att );
-    }
+    void storeAttachment( Attachment att, InputStream in ) throws IOException, ProviderException;
 
     /**
      *  Returns a list of versions of the attachment.
@@ -556,45 +245,22 @@ public class AttachmentManager
      *          disabled.
      *  @throws ProviderException If the provider fails for some reason.
      */
-    public List< Attachment > getVersionHistory( final String attachmentName ) throws ProviderException {
-        if( m_provider == null ) {
-            return null;
-        }
-
-        final Attachment att = getAttachmentInfo( null, attachmentName );
-
-        if( att != null ) {
-            return m_provider.getVersionHistory( att );
-        }
-
-        return null;
-    }
+    List< Attachment > getVersionHistory( String attachmentName ) throws ProviderException;
 
     /**
-     *  Returns a collection of Attachments, containing each and every attachment
-     *  that is in this Wiki.
+     *  Returns a collection of Attachments, containing each and every attachment that is in this Wiki.
      *
-     *  @return A collection of attachments.  If attachments are disabled, will
-     *          return an empty collection.
+     *  @return A collection of attachments.  If attachments are disabled, will return an empty collection.
      *  @throws ProviderException If something went wrong with the backend
      */
-    public Collection<Attachment> getAllAttachments() throws ProviderException {
-        if( attachmentsEnabled() ) {
-            return m_provider.listAllChanged( new Date(0L) );
-        }
-
-        return new ArrayList<>();
-    }
+    Collection< Attachment > getAllAttachments() throws ProviderException;
 
     /**
      *  Returns the current attachment provider.
      *
      *  @return The current provider.  May be null, if attachments are disabled.
      */
-    public WikiAttachmentProvider getCurrentProvider()
-    {
-        return m_provider;
-    }
+    WikiAttachmentProvider getCurrentProvider();
 
     /**
      *  Deletes the given attachment version.
@@ -602,82 +268,51 @@ public class AttachmentManager
      *  @param att The attachment to delete
      *  @throws ProviderException If something goes wrong with the backend.
      */
-    public void deleteVersion( Attachment att )
-        throws ProviderException
-    {
-        if( m_provider == null ) return;
-
-        m_provider.deleteVersion( att );
-    }
+    void deleteVersion( Attachment att ) throws ProviderException;
 
     /**
      *  Deletes all versions of the given attachment.
+     *
      *  @param att The Attachment to delete.
      *  @throws ProviderException if something goes wrong with the backend.
      */
-    // FIXME: Should also use events!
-    public void deleteAttachment( Attachment att )
-        throws ProviderException
-    {
-        if( m_provider == null ) return;
-
-        m_provider.deleteAttachment( att );
-
-        m_engine.getSearchManager().pageRemoved( att );
-
-        m_engine.getReferenceManager().clearPageEntries( att.getName() );
-
-    }
+    void deleteAttachment( Attachment att ) throws ProviderException;
 
     /**
-     *  Validates the filename and makes sure it is legal.  It trims and splits
-     *  and replaces bad characters.
+     *  Validates the filename and makes sure it is legal.  It trims and splits and replaces bad characters.
      *
-     *  @param filename
+     *  @param filename file name to validate.
      *  @return A validated name with annoying characters replaced.
      *  @throws WikiException If the filename is not legal (e.g. empty)
      */
-    static String validateFileName( String filename )
-        throws WikiException
-    {
-        if( filename == null || filename.trim().length() == 0 )
-        {
-            log.error("Empty file name given.");
+    static String validateFileName( String filename ) throws WikiException {
+        if( filename == null || filename.trim().length() == 0 ) {
+            Logger.getLogger( AttachmentManager.class ).error( "Empty file name given." );
 
             // the caller should catch the exception and use the exception text as an i18n key
             throw new WikiException(  "attach.empty.file" );
         }
 
-        //
         //  Some browser send the full path info with the filename, so we need
         //  to remove it here by simply splitting along slashes and then taking the path.
-        //
-
-        String[] splitpath = filename.split( "[/\\\\]" );
+        final String[] splitpath = filename.split( "[/\\\\]" );
         filename = splitpath[splitpath.length-1];
 
-        //
-        //  Should help with IE 5.22 on OSX
-        //
+        // Should help with IE 5.22 on OSX
         filename = filename.trim();
 
         // If file name ends with .jsp or .jspf, the user is being naughty!
-        if( filename.toLowerCase().endsWith( ".jsp" ) || filename.toLowerCase().endsWith(".jspf") )
-        {
-            log.info( "Attempt to upload a file with a .jsp/.jspf extension.  In certain cases this " +
-                      "can trigger unwanted security side effects, so we're preventing it." );
-            //
+        if( filename.toLowerCase().endsWith( ".jsp" ) || filename.toLowerCase().endsWith( ".jspf" ) ) {
+            Logger.getLogger( AttachmentManager.class )
+                  .info( "Attempt to upload a file with a .jsp/.jspf extension.  In certain cases this " +
+                         "can trigger unwanted security side effects, so we're preventing it." );
+
             // the caller should catch the exception and use the exception text as an i18n key
             throw new WikiException(  "attach.unwanted.file"  );
         }
 
-        //
-        //  Remove any characters that might be a problem. Most
-        //  importantly - characters that might stop processing
-        //  of the URL.
-        //
-        filename = StringUtils.replaceChars( filename, "#?\"'", "____" );
-
-        return filename;
+        //  Remove any characters that might be a problem. Most importantly - characters that might stop processing of the URL.
+        return StringUtils.replaceChars( filename, "#?\"'", "____" );
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
new file mode 100644
index 0000000..4ac6c5d
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
@@ -0,0 +1,350 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+package org.apache.wiki.attachment;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.providers.WikiAttachmentProvider;
+import org.apache.wiki.references.ReferenceManager;
+import org.apache.wiki.search.SearchManager;
+import org.apache.wiki.util.ClassUtil;
+import org.apache.wiki.util.TextUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+
+/**
+ *  Provides facilities for handling attachments.  All attachment handling goes through this class.
+ *  <p>
+ *  The AttachmentManager provides a facade towards the current WikiAttachmentProvider that is in use.
+ *  It is created by the WikiEngine as a singleton object, and can be requested through the WikiEngine.
+ *
+ *  @since 1.9.28
+ */
+public class DefaultAttachmentManager implements AttachmentManager {
+
+    /** List of attachment types which are forced to be downloaded */
+    private String[] m_forceDownloadPatterns;
+
+    private static final Logger log = Logger.getLogger( DefaultAttachmentManager.class );
+    private WikiAttachmentProvider m_provider;
+    private Engine m_engine;
+    private CacheManager m_cacheManager = CacheManager.getInstance();
+    private Cache m_dynamicAttachments;
+
+    /**
+     *  Creates a new AttachmentManager.  Note that creation will never fail, but it's quite likely that attachments do not function.
+     *  <p><b>DO NOT CREATE</b> an AttachmentManager on your own, unless you really know what you're doing. Just use
+     *  WikiEngine.getAttachmentManager() if you're making a module for JSPWiki.
+     *
+     *  @param engine The wikiengine that owns this attachment manager.
+     *  @param props A list of properties from which the AttachmentManager will seek its configuration. Typically this is the "jspwiki.properties".
+     */
+    // FIXME: Perhaps this should fail somehow.
+    public DefaultAttachmentManager( final Engine engine, final Properties props ) {
+        m_engine = engine;
+
+        //  If user wants to use a cache, then we'll use the CachingProvider.
+        final boolean useCache = "true".equals( props.getProperty( PageManager.PROP_USECACHE ) );
+
+        final String classname;
+        if( useCache ) {
+            classname = "org.apache.wiki.providers.CachingAttachmentProvider";
+        } else {
+            classname = props.getProperty( PROP_PROVIDER );
+        }
+
+        //  If no class defined, then will just simply fail.
+        if( classname == null ) {
+            log.info( "No attachment provider defined - disabling attachment support." );
+            return;
+        }
+
+        //  Create and initialize the provider.
+        final String cacheName = engine.getApplicationName() + "." + CACHE_NAME;
+        try {
+            if( m_cacheManager.cacheExists( cacheName ) ) {
+                m_dynamicAttachments = m_cacheManager.getCache( cacheName );
+            } else {
+                log.info( "cache with name " + cacheName + " not found in ehcache.xml, creating it with defaults." );
+                m_dynamicAttachments = new Cache( cacheName, DEFAULT_CACHECAPACITY, false, false, 0, 0 );
+                m_cacheManager.addCache( m_dynamicAttachments );
+            }
+
+            final Class< ? > providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname );
+
+            m_provider = ( WikiAttachmentProvider )providerclass.newInstance();
+            m_provider.initialize( m_engine.adapt( WikiEngine.class ), props );
+        } catch( final ClassNotFoundException e ) {
+            log.error( "Attachment provider class not found",e);
+        } catch( final InstantiationException e ) {
+            log.error( "Attachment provider could not be created", e );
+        } catch( final IllegalAccessException e ) {
+            log.error( "You may not access the attachment provider class", e );
+        } catch( final NoRequiredPropertyException e ) {
+            log.error( "Attachment provider did not find a property that it needed: " + e.getMessage(), e );
+            m_provider = null; // No, it did not work.
+        } catch( final IOException e ) {
+            log.error( "Attachment provider reports IO error", e );
+            m_provider = null;
+        }
+
+        final String forceDownload = TextUtil.getStringProperty( props, PROP_FORCEDOWNLOAD, null );
+        if( forceDownload != null && forceDownload.length() > 0 ) {
+            m_forceDownloadPatterns = forceDownload.toLowerCase().split( "\\s" );
+        } else {
+            m_forceDownloadPatterns = new String[ 0 ];
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean attachmentsEnabled() {
+        return m_provider != null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getAttachmentInfoName( final WikiContext context, final String attachmentname ) {
+        final Attachment att;
+        try {
+            att = getAttachmentInfo( context, attachmentname );
+        } catch( final ProviderException e ) {
+            log.warn( "Finding attachments failed: ", e );
+            return null;
+        }
+
+        if( att != null ) {
+            return att.getName();
+        } else if( attachmentname.indexOf( '/' ) != -1 ) {
+            return attachmentname;
+        }
+
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Attachment getAttachmentInfo( final WikiContext context, String attachmentname, final int version ) throws ProviderException {
+        if( m_provider == null ) {
+            return null;
+        }
+
+        WikiPage currentPage = null;
+
+        if( context != null ) {
+            currentPage = context.getPage();
+        }
+
+        //  Figure out the parent page of this attachment.  If we can't find it, we'll assume this refers directly to the attachment.
+        final int cutpt = attachmentname.lastIndexOf( '/' );
+        if( cutpt != -1 ) {
+            String parentPage = attachmentname.substring( 0, cutpt );
+            parentPage = MarkupParser.cleanLink( parentPage );
+            attachmentname = attachmentname.substring( cutpt + 1 );
+
+            // If we for some reason have an empty parent page name; this can't be an attachment
+            if( parentPage.length() == 0 ) {
+                return null;
+            }
+
+            currentPage = m_engine.getManager( PageManager.class ).getPage( parentPage );
+
+            // Go check for legacy name
+            // FIXME: This should be resolved using CommandResolver, not this adhoc way.  This also assumes that the
+            //        legacy charset is a subset of the full allowed set.
+            if( currentPage == null ) {
+                currentPage = m_engine.getManager( PageManager.class ).getPage( MarkupParser.wikifyLink( parentPage ) );
+            }
+        }
+
+        //  If the page cannot be determined, we cannot possibly find the attachments.
+        if( currentPage == null || currentPage.getName().length() == 0 ) {
+            return null;
+        }
+
+        //  Finally, figure out whether this is a real attachment or a generated attachment.
+        Attachment att = getDynamicAttachment( currentPage.getName() + "/" + attachmentname );
+        if( att == null ) {
+            att = m_provider.getAttachmentInfo( currentPage, attachmentname, version );
+        }
+
+        return att;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public List< Attachment > listAttachments( final WikiPage wikipage ) throws ProviderException {
+        if( m_provider == null ) {
+            return new ArrayList<>();
+        }
+
+        final List< Attachment > atts = new ArrayList<>( m_provider.listAttachments( wikipage ) );
+        atts.sort( Comparator.comparing( Attachment::getName, m_engine.getManager( PageManager.class ).getPageSorter() ) );
+
+        return atts;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean forceDownload( String name ) {
+        if( name == null || name.length() == 0 ) {
+            return false;
+        }
+
+        name = name.toLowerCase();
+        if( name.indexOf( '.' ) == -1 ) {
+            return true;  // force download on attachments without extension or type indication
+        }
+
+        for( final String forceDownloadPattern : m_forceDownloadPatterns ) {
+            if( name.endsWith( forceDownloadPattern ) && forceDownloadPattern.length() > 0 ) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public InputStream getAttachmentStream( final WikiContext ctx, final Attachment att ) throws ProviderException, IOException {
+        if( m_provider == null ) {
+            return null;
+        }
+
+        if( att instanceof DynamicAttachment ) {
+            return ( ( DynamicAttachment )att ).getProvider().getAttachmentData( ctx, att );
+        }
+
+        return m_provider.getAttachmentData( att );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void storeDynamicAttachment( final WikiContext ctx, final DynamicAttachment att ) {
+        m_dynamicAttachments.put( new Element( att.getName(), att ) );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public DynamicAttachment getDynamicAttachment( final String name ) {
+        final Element element = m_dynamicAttachments.get( name );
+        if( element != null ) {
+            return ( DynamicAttachment )element.getObjectValue();
+        } else {
+            // Remove from cache, it has expired.
+            m_dynamicAttachments.put( new Element( name, null ) );
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void storeAttachment( final Attachment att, final InputStream in ) throws IOException, ProviderException {
+        if( m_provider == null ) {
+            return;
+        }
+
+        // Checks if the actual, real page exists without any modifications or aliases. We cannot store an attachment to a non-existent page.
+        if( !m_engine.getManager( PageManager.class ).pageExists( att.getParentName() ) ) {
+            // the caller should catch the exception and use the exception text as an i18n key
+            throw new ProviderException( "attach.parent.not.exist" );
+        }
+
+        m_provider.putAttachmentData( att, in );
+        m_engine.getManager( ReferenceManager.class ).updateReferences( att.getName(), new ArrayList<>() );
+
+        final WikiPage parent = new WikiPage( m_engine, att.getParentName() );
+        m_engine.getManager( ReferenceManager.class ).updateReferences( parent );
+        m_engine.getManager( SearchManager.class ).reindexPage( att );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public List< Attachment > getVersionHistory( final String attachmentName ) throws ProviderException {
+        if( m_provider == null ) {
+            return null;
+        }
+
+        final Attachment att = getAttachmentInfo( null, attachmentName );
+        if( att != null ) {
+            return m_provider.getVersionHistory( att );
+        }
+
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Collection<Attachment> getAllAttachments() throws ProviderException {
+        if( attachmentsEnabled() ) {
+            return m_provider.listAllChanged( new Date( 0L ) );
+        }
+
+        return new ArrayList<>();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public WikiAttachmentProvider getCurrentProvider() {
+        return m_provider;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void deleteVersion( final Attachment att ) throws ProviderException {
+        if( m_provider == null ) {
+            return;
+        }
+
+        m_provider.deleteVersion( att );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    // FIXME: Should also use events!
+    public void deleteAttachment( final Attachment att ) throws ProviderException {
+        if( m_provider == null ) {
+            return;
+        }
+
+        m_provider.deleteAttachment( att );
+        m_engine.getManager( SearchManager.class ).pageRemoved( att );
+        m_engine.getManager( ReferenceManager.class ).clearPageEntries( att.getName() );
+    }
+
+}


[jspwiki] 05/38: JSPWIKI-120: rename + extract interface from AuthenticationManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 380de2a22cf5ef84d3f6efd218d51429b93726fe
Author: juanpablo <ju...@apache.org>
AuthorDate: Wed Feb 19 20:39:01 2020 +0100

    JSPWIKI-120: rename + extract interface from AuthenticationManager
---
 .../apache/wiki/auth/AuthenticationManager.java    | 679 +++------------------
 .../wiki/auth/DefaultAuthenticationManager.java    | 507 +++++++++++++++
 .../src/main/resources/ini/classmappings.xml       |   4 +-
 3 files changed, 600 insertions(+), 590 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
index b9eb341..197619a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
@@ -18,598 +18,182 @@
  */
 package org.apache.wiki.auth;
 
-import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
-import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.auth.authorize.Role;
-import org.apache.wiki.auth.authorize.WebAuthorizer;
-import org.apache.wiki.auth.authorize.WebContainerAuthorizer;
-import org.apache.wiki.auth.login.AnonymousLoginModule;
 import org.apache.wiki.auth.login.CookieAssertionLoginModule;
 import org.apache.wiki.auth.login.CookieAuthenticationLoginModule;
-import org.apache.wiki.auth.login.UserDatabaseLoginModule;
-import org.apache.wiki.auth.login.WebContainerCallbackHandler;
-import org.apache.wiki.auth.login.WebContainerLoginModule;
-import org.apache.wiki.auth.login.WikiCallbackHandler;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
-import org.apache.wiki.util.TextUtil;
-import org.apache.wiki.util.TimedCounterList;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.security.Principal;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Properties;
 import java.util.Set;
 
+
 /**
- * Manages authentication activities for a WikiEngine: user login, logout, and
- * credential refreshes. This class uses JAAS to determine how users log in.
+ * Manages authentication activities for a WikiEngine: user login, logout, and credential refreshes. This class uses JAAS to determine how
+ * users log in.
  * <p>
- * The login procedure is protected in addition by a mechanism which prevents
- * a hacker to try and force-guess passwords by slowing down attempts to log in
- * into the same account.  Every login attempt is recorded, and stored for a while
- * (currently ten minutes), and each login attempt during that time incurs a penalty
- * of 2^login attempts milliseconds - that is, 10 login attempts incur a login penalty of 1.024 seconds.
- * The delay is currently capped to 20 seconds.
+ * The login procedure is protected in addition by a mechanism which prevents a hacker to try and force-guess passwords by slowing down
+ * attempts to log in into the same account.  Every login attempt is recorded, and stored for a while (currently ten minutes), and each
+ * login attempt during that time incurs a penalty of 2^login attempts milliseconds - that is, 10 login attempts incur a login penalty
+ * of 1.024 seconds. The delay is currently capped to 20 seconds.
  * 
  * @since 2.3
  */
-public class AuthenticationManager {
-
-    /** How many milliseconds the logins are stored before they're cleaned away. */
-    private static final long LASTLOGINS_CLEANUP_TIME = 10*60*1000L; // Ten minutes
+public interface AuthenticationManager {
 
-    private static final long MAX_LOGIN_DELAY         = 20*1000L; // 20 seconds
-    
     /** The name of the built-in cookie assertion module */
-    public static final String                 COOKIE_MODULE       =  CookieAssertionLoginModule.class.getName();
+    String COOKIE_MODULE = CookieAssertionLoginModule.class.getName();
 
     /** The name of the built-in cookie authentication module */
-    public static final String                 COOKIE_AUTHENTICATION_MODULE =  CookieAuthenticationLoginModule.class.getName();
+    String COOKIE_AUTHENTICATION_MODULE = CookieAuthenticationLoginModule.class.getName();
 
     /** If this jspwiki.properties property is <code>true</code>, logs the IP address of the editor on saving. */
-    public static final String                 PROP_STOREIPADDRESS = "jspwiki.storeIPAddress";
+    String PROP_STOREIPADDRESS = "jspwiki.storeIPAddress";
     
     /** If this jspwiki.properties property is <code>true</code>, allow cookies to be used for authentication. */
-    public static final String                 PROP_ALLOW_COOKIE_AUTH = "jspwiki.cookieAuthentication";
+    String PROP_ALLOW_COOKIE_AUTH = "jspwiki.cookieAuthentication";
     
     /** Whether logins should be throttled to limit brute-forcing attempts. Defaults to true. */
-    public static final String                 PROP_LOGIN_THROTTLING = "jspwiki.login.throttling";
-
-    protected static final Logger              log                 = Logger.getLogger( AuthenticationManager.class );
+    String PROP_LOGIN_THROTTLING = "jspwiki.login.throttling";
 
     /** Prefix for LoginModule options key/value pairs. */
-    protected static final String                 PREFIX_LOGIN_MODULE_OPTIONS = "jspwiki.loginModule.options.";
+    String PREFIX_LOGIN_MODULE_OPTIONS = "jspwiki.loginModule.options.";
 
     /** If this jspwiki.properties property is <code>true</code>, allow cookies to be used to assert identities. */
-    protected static final String                 PROP_ALLOW_COOKIE_ASSERTIONS = "jspwiki.cookieAssertions";
-
-    /** The {@link javax.security.auth.spi.LoginModule} to use for custom authentication. */
-    protected static final String                 PROP_LOGIN_MODULE = "jspwiki.loginModule.class";
-    
-    /** Empty Map passed to JAAS {@link #doJAASLogin(Class, CallbackHandler, Map)} method. */
-    protected static final Map<String,String> EMPTY_MAP = Collections.unmodifiableMap( new HashMap<String,String>() );
-    
-    /** Class (of type LoginModule) to use for custom authentication. */
-    protected Class<? extends LoginModule> m_loginModuleClass = UserDatabaseLoginModule.class;
-    
-    /** Options passed to {@link javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, Map)}; 
-     * initialized by {@link #initialize(WikiEngine, Properties)}. */
-    protected Map<String,String> m_loginModuleOptions = new HashMap<String,String>();
-
-    /** The default {@link javax.security.auth.spi.LoginModule} class name to use for custom authentication. */
-    private static final String                 DEFAULT_LOGIN_MODULE = "org.apache.wiki.auth.login.UserDatabaseLoginModule";
-    
-    /** Empty principal set. */
-    private static final Set<Principal> NO_PRINCIPALS = new HashSet<>();
-
-    /** Static Boolean for lazily-initializing the "allows assertions" flag */
-    private boolean                     m_allowsCookieAssertions  = true;
-
-    private boolean                     m_throttleLogins = true;
-
-    /** Static Boolean for lazily-initializing the "allows cookie authentication" flag */
-    private boolean                     m_allowsCookieAuthentication = false;
-
-    private WikiEngine                         m_engine            = null;
-    
-    /** If true, logs the IP address of the editor */
-    private boolean                            m_storeIPAddress    = true;
-
-    /** Keeps a list of the usernames who have attempted a login recently. */
-    private TimedCounterList<String> m_lastLoginAttempts = new TimedCounterList<String>();
-    
-    /**
-     * Creates an AuthenticationManager instance for the given WikiEngine and
-     * the specified set of properties. All initialization for the modules is
-     * done here.
-     * @param engine the wiki engine
-     * @param props the properties used to initialize the wiki engine
-     * @throws WikiException if the AuthenticationManager cannot be initialized
-     */
-    @SuppressWarnings("unchecked")
-    public void initialize( WikiEngine engine, Properties props ) throws WikiException
-    {
-        m_engine = engine;
-        m_storeIPAddress = TextUtil.getBooleanProperty( props, PROP_STOREIPADDRESS, m_storeIPAddress );
-
-        // Should we allow cookies for assertions? (default: yes)
-        m_allowsCookieAssertions = TextUtil.getBooleanProperty( props,
-                                                              PROP_ALLOW_COOKIE_ASSERTIONS,
-                                                              true );
-        
-        // Should we allow cookies for authentication? (default: no)
-        m_allowsCookieAuthentication = TextUtil.getBooleanProperty( props,
-                                                                    PROP_ALLOW_COOKIE_AUTH,
-                                                                    false );
-        
-        // Should we throttle logins? (default: yes)
-        m_throttleLogins = TextUtil.getBooleanProperty( props,
-                                                        PROP_LOGIN_THROTTLING,
-                                                        true );
+    String PROP_ALLOW_COOKIE_ASSERTIONS = "jspwiki.cookieAssertions";
 
-        // Look up the LoginModule class
-        String loginModuleClassName = TextUtil.getStringProperty( props, PROP_LOGIN_MODULE, DEFAULT_LOGIN_MODULE );
-        try
-        {
-            m_loginModuleClass = (Class<? extends LoginModule>) Class.forName( loginModuleClassName );
-        }
-        catch (ClassNotFoundException e)
-        {
-            log.error( e.getMessage(), e );
-            throw new WikiException( "Could not instantiate LoginModule class.", e );
-        }
-        
-        // Initialize the LoginModule options
-        initLoginModuleOptions( props );
-    }
+    /** The {@link LoginModule} to use for custom authentication. */
+    String PROP_LOGIN_MODULE = "jspwiki.loginModule.class";
 
     /**
-     * Returns true if this WikiEngine uses container-managed authentication.
-     * This method is used primarily for cosmetic purposes in the JSP tier, and
-     * performs no meaningful security function per se. Delegates to
+     * Returns true if this WikiEngine uses container-managed authentication. This method is used primarily for cosmetic purposes in the
+     * JSP tier, and performs no meaningful security function per se. Delegates to
      * {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer#isContainerAuthorized()},
      * if used as the external authorizer; otherwise, returns <code>false</code>.
-     * @return <code>true</code> if the wiki's authentication is managed by
-     *         the container, <code>false</code> otherwise
+     *
+     * @return <code>true</code> if the wiki's authentication is managed by the container, <code>false</code> otherwise
      */
-    public boolean isContainerAuthenticated()
-    {
-        try
-        {
-            Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
-            if ( authorizer instanceof WebContainerAuthorizer )
-            {
-                 return ( ( WebContainerAuthorizer )authorizer ).isContainerAuthorized();
-            }
-        }
-        catch ( WikiException e )
-        {
-            // It's probably ok to fail silently...
-        }
-        return false;
-    }
+    boolean isContainerAuthenticated();
 
     /**
-     * <p>Logs in the user by attempting to populate a WikiSession Subject from
-     * a web servlet request by examining the request
-     *  for the presence of container credentials and user cookies. The processing
-     * logic is as follows:
+     * <p>Logs in the user by attempting to populate a WikiSession Subject from a web servlet request by examining the request
+     *  for the presence of container credentials and user cookies. The processing logic is as follows:
      * </p>
      * <ul>
-     * <li>If the WikiSession had previously been unauthenticated, check to see if
-     * user has subsequently authenticated. To be considered "authenticated,"
-     * the request must supply one of the following (in order of preference):
-     * the container <code>userPrincipal</code>, container <code>remoteUser</code>,
-     * or authentication cookie. If the user is authenticated, this method fires event
-     * {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_AUTHENTICATED}
-     * with two parameters: a Principal representing the login principal,
-     * and the current WikiSession. In addition, if the authorizer is of type
-     * WebContainerAuthorizer, this method iterates through the container roles returned by
-     * {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer#getRoles()},
-     * tests for membership in each one, and adds those that pass to the Subject's principal set.</li>
-     * <li>If, after checking for authentication, the WikiSession is still Anonymous,
-     * this method next checks to see if the user has "asserted" an identity
-     * by supplying an assertion cookie. If the user is found to be asserted,
-     * this method fires event {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_ASSERTED}
-     * with two parameters: <code>WikiPrincipal(<em>cookievalue</em>)</code>, and
-     * the current WikiSession.</li>
-     * <li>If, after checking for authenticated and asserted status, the  WikiSession is
-     * <em>still</em> anonymous, this method fires event
-     * {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_ANONYMOUS} with
-     * two parameters: <code>WikiPrincipal(<em>remoteAddress</em>)</code>,
+     * <li>If the WikiSession had previously been unauthenticated, check to see if user has subsequently authenticated. To be considered
+     * "authenticated," the request must supply one of the following (in order of preference): the container <code>userPrincipal</code>,
+     * container <code>remoteUser</code>, or authentication cookie. If the user is authenticated, this method fires event
+     * {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_AUTHENTICATED} with two parameters: a Principal representing the login principal,
+     * and the current WikiSession. In addition, if the authorizer is of type WebContainerAuthorizer, this method iterates through the
+     * container roles returned by {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer#getRoles()}, tests for membership in each
+     * one, and adds those that pass to the Subject's principal set.</li>
+     * <li>If, after checking for authentication, the WikiSession is still Anonymous, this method next checks to see if the user has
+     * "asserted" an identity by supplying an assertion cookie. If the user is found to be asserted, this method fires event
+     * {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_ASSERTED} with two parameters: <code>WikiPrincipal(<em>cookievalue</em>)</code>,
+     * and the current WikiSession.</li>
+     * <li>If, after checking for authenticated and asserted status, the  WikiSession is <em>still</em> anonymous, this method fires event
+     * {@link org.apache.wiki.event.WikiSecurityEvent#LOGIN_ANONYMOUS} with two parameters: <code>WikiPrincipal(<em>remoteAddress</em>)</code>,
      * and the current WikiSession </li>
      * </ul>
+     *
      * @param request servlet request for this user
      * @return always returns <code>true</code> (because anonymous login, at least, will always succeed)
      * @throws org.apache.wiki.auth.WikiSecurityException if the user cannot be logged in for any reason
      * @since 2.3
      */
-    public boolean login( HttpServletRequest request ) throws WikiSecurityException
-    {
-        HttpSession httpSession = request.getSession();
-        WikiSession session = SessionMonitor.getInstance(m_engine).find( httpSession );
-        AuthenticationManager authenticationMgr = m_engine.getAuthenticationManager();
-        AuthorizationManager authorizationMgr = m_engine.getAuthorizationManager();
-        CallbackHandler handler = null;
-        Map<String,String> options = EMPTY_MAP;
-
-        // If user not authenticated, check if container logged them in, or if
-        // there's an authentication cookie
-        if ( !session.isAuthenticated() )
-        {
-            // Create a callback handler
-            handler = new WebContainerCallbackHandler( m_engine, request );
-            
-            // Execute the container login module, then (if that fails) the cookie auth module
-            Set<Principal> principals = authenticationMgr.doJAASLogin( WebContainerLoginModule.class, handler, options );
-            if ( principals.size() == 0 && authenticationMgr.allowsCookieAuthentication() )
-            {
-                principals = authenticationMgr.doJAASLogin( CookieAuthenticationLoginModule.class, handler, options );
-            }
-            
-            // If the container logged the user in successfully, tell the WikiSession (and add all of the Principals)
-            if ( principals.size() > 0 )
-            {
-                fireEvent( WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
-                for ( Principal principal : principals )
-                {
-                    fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, principal, session );
-                }
-                
-                // Add all appropriate Authorizer roles
-                injectAuthorizerRoles( session, authorizationMgr.getAuthorizer(), request );
-            }
-        }
-
-        // If user still not authenticated, check if assertion cookie was supplied
-        if ( !session.isAuthenticated() && authenticationMgr.allowsCookieAssertions() )
-        {
-            // Execute the cookie assertion login module
-            Set<Principal> principals = authenticationMgr.doJAASLogin( CookieAssertionLoginModule.class, handler, options );
-            if ( principals.size() > 0 )
-            {
-                fireEvent( WikiSecurityEvent.LOGIN_ASSERTED, getLoginPrincipal( principals ), session);
-            }
-        }
-
-        // If user still anonymous, use the remote address
-        if (session.isAnonymous() )
-        {
-            Set<Principal> principals = authenticationMgr.doJAASLogin( AnonymousLoginModule.class, handler, options );
-            if ( principals.size() > 0 )
-            {
-                fireEvent( WikiSecurityEvent.LOGIN_ANONYMOUS, getLoginPrincipal( principals ), session );
-                return true;
-            }
-        }
-        
-        // If by some unusual turn of events the Anonymous login module doesn't work, login failed!
-        return false;
-    }
+    boolean login( HttpServletRequest request ) throws WikiSecurityException;
     
     /**
-     * Attempts to perform a WikiSession login for the given username/password
-     * combination using JSPWiki's custom authentication mode. In order to log in,
-     * the JAAS LoginModule supplied by the WikiEngine property {@link #PROP_LOGIN_MODULE}
-     * will be instantiated, and its
-     * {@link javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, Map)}
-     * method will be invoked. By default, the {@link org.apache.wiki.auth.login.UserDatabaseLoginModule}
-     * class will be used. When the LoginModule's <code>initialize</code> method is invoked,
-     * an options Map populated by properties keys prefixed by {@link #PREFIX_LOGIN_MODULE_OPTIONS}
-     * will be passed as a parameter.
+     * Attempts to perform a WikiSession login for the given username/password combination using JSPWiki's custom authentication mode. In
+     * order to log in, the JAAS LoginModule supplied by the WikiEngine property {@link #PROP_LOGIN_MODULE} will be instantiated, and its
+     * {@link javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, Map)} method will be invoked. By default,
+     * the {@link org.apache.wiki.auth.login.UserDatabaseLoginModule} class will be used. When the LoginModule's <code>initialize</code>
+     * method is invoked, an options Map populated by properties keys prefixed by {@link #PREFIX_LOGIN_MODULE_OPTIONS} will be passed as a
+     * parameter.
+     *
      * @param session the current wiki session; may not be <code>null</code>.
-     * @param request the user's HTTP request. This parameter may be <code>null</code>, but the configured
-     * LoginModule will not have access to the HTTP request in this case.
-     * @param username The user name. This is a login name, not a WikiName. In
-     *            most cases they are the same, but in some cases, they might
-     *            not be.
+     * @param request the user's HTTP request. This parameter may be <code>null</code>, but the configured LoginModule will not have access
+     *                to the HTTP request in this case.
+     * @param username The user name. This is a login name, not a WikiName. In most cases they are the same, but in some cases, they might not be.
      * @param password the password
      * @return true, if the username/password is valid
      * @throws org.apache.wiki.auth.WikiSecurityException if the Authorizer or UserManager cannot be obtained
      */
-    public boolean login( WikiSession session, HttpServletRequest request, String username, String password ) throws WikiSecurityException
-    {
-        if ( session == null )
-        {
-            log.error( "No wiki session provided, cannot log in." );
-            return false;
-        }
-
-        // Protect against brute-force password guessing if configured to do so
-        if ( m_throttleLogins )
-        {
-            delayLogin(username);
-        }
-        
-        CallbackHandler handler = new WikiCallbackHandler( m_engine, null, username, password );
-        
-        // Execute the user's specified login module
-        Set<Principal> principals = doJAASLogin( m_loginModuleClass, handler, m_loginModuleOptions );
-        if (principals.size() > 0)
-        {
-            fireEvent(WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
-            for ( Principal principal : principals )
-            {
-                fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, principal, session );
-            }
-            
-            // Add all appropriate Authorizer roles
-            injectAuthorizerRoles( session, m_engine.getAuthorizationManager().getAuthorizer(), null );
-            
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     *  This method builds a database of login names that are being attempted, and will try to
-     *  delay if there are too many requests coming in for the same username.
-     *  <p>
-     *  The current algorithm uses 2^loginattempts as the delay in milliseconds, i.e.
-     *  at 10 login attempts it'll add 1.024 seconds to the login.
-     *  
-     *  @param username The username that is being logged in
-     */
-    private void delayLogin( String username )
-    {
-        try
-        {
-            m_lastLoginAttempts.cleanup( LASTLOGINS_CLEANUP_TIME );
-            int count = m_lastLoginAttempts.count( username );
-            
-            long delay = Math.min( 1<<count, MAX_LOGIN_DELAY );
-            log.debug( "Sleeping for "+delay+" ms to allow login." );
-            Thread.sleep( delay );
-            
-            m_lastLoginAttempts.add( username );
-        }
-        catch( InterruptedException e )
-        {
-            // FALLTHROUGH is fine
-        }
-    }
+    boolean login( WikiSession session, HttpServletRequest request, String username, String password ) throws WikiSecurityException;
 
     /**
-     * Logs the user out by retrieving the WikiSession associated with the
-     * HttpServletRequest and unbinding all of the Subject's Principals,
-     * except for {@link Role#ALL}, {@link Role#ANONYMOUS}.
-     * is a cheap-and-cheerful way to do it without invoking JAAS LoginModules.
-     * The logout operation will also flush the JSESSIONID cookie from
-     * the user's browser session, if it was set.
+     * Logs the user out by retrieving the WikiSession associated with the HttpServletRequest and unbinding all of the Subject's Principals,
+     * except for {@link Role#ALL}, {@link Role#ANONYMOUS}. is a cheap-and-cheerful way to do it without invoking JAAS LoginModules.
+     * The logout operation will also flush the JSESSIONID cookie from the user's browser session, if it was set.
+     *
      * @param request the current HTTP request
      */
-    public void logout( HttpServletRequest request )
-    {
-        if( request == null )
-        {
-            log.error( "No HTTP reqest provided; cannot log out." );
-            return;
-        }
-
-        HttpSession session = request.getSession();
-        String sid = ( session == null ) ? "(null)" : session.getId();
-        if( log.isDebugEnabled() )
-        {
-            log.debug( "Invalidating WikiSession for session ID=" + sid );
-        }
-        // Retrieve the associated WikiSession and clear the Principal set
-        WikiSession wikiSession = WikiSession.getWikiSession( m_engine, request );
-        Principal originalPrincipal = wikiSession.getLoginPrincipal();
-        wikiSession.invalidate();
-
-        // Remove the wikiSession from the WikiSession cache
-        WikiSession.removeWikiSession( m_engine, request );
-
-        // We need to flush the HTTP session too
-        if ( session != null )
-        {
-            session.invalidate();
-        }
-
-        // Log the event
-        fireEvent( WikiSecurityEvent.LOGOUT, originalPrincipal, null );
-    }
+    void logout( HttpServletRequest request );
 
     /**
-     * Determines whether this WikiEngine allows users to assert identities using
-     * cookies instead of passwords. This is determined by inspecting
+     * Determines whether this WikiEngine allows users to assert identities using cookies instead of passwords. This is determined by inspecting
      * the WikiEngine property {@link #PROP_ALLOW_COOKIE_ASSERTIONS}.
+     *
      * @return <code>true</code> if cookies are allowed
      */
-    public boolean allowsCookieAssertions()
-    {
-        return m_allowsCookieAssertions;
-    }
+    boolean allowsCookieAssertions();
 
     /**
-     *  Determines whether this WikiEngine allows users to authenticate using
-     *  cookies instead of passwords. This is determined by inspecting
+     * Determines whether this WikiEngine allows users to authenticate using cookies instead of passwords. This is determined by inspecting
      * the WikiEngine property {@link #PROP_ALLOW_COOKIE_AUTH}.
+     *
      *  @return <code>true</code> if cookies are allowed for authentication
      *  @since 2.5.62
      */
-    public boolean allowsCookieAuthentication()
-    {
-        return m_allowsCookieAuthentication;
-    }
+    boolean allowsCookieAuthentication();
+
+    /**
+     * Instantiates and executes a single JAAS {@link LoginModule}, and returns a Set of Principals that results from a successful login.
+     * The LoginModule is instantiated, then its {@link LoginModule#initialize(Subject, CallbackHandler, Map, Map)} method is called. The
+     * parameters passed to <code>initialize</code> is a dummy Subject, an empty shared-state Map, and an options Map the caller supplies.
+     *
+     * @param clazz the LoginModule class to instantiate
+     * @param handler the callback handler to supply to the LoginModule
+     * @param options a Map of key/value strings for initializing the LoginModule
+     * @return the set of Principals returned by the JAAS method {@link Subject#getPrincipals()}
+     * @throws WikiSecurityException if the LoginModule could not be instantiated for any reason
+     */
+    Set< Principal > doJAASLogin( Class<? extends LoginModule> clazz, CallbackHandler handler, Map< String, String > options) throws WikiSecurityException;
     
     /**
      * Determines whether the supplied Principal is a "role principal".
+     *
      * @param principal the principal to test
-     * @return <code>true</code> if the Principal is of type
-     *         {@link GroupPrincipal} or
-     *         {@link org.apache.wiki.auth.authorize.Role},
-     *         <code>false</code> otherwise
+     * @return {@code true} if the Principal is of type {@link GroupPrincipal} or {@link Role}, {@code false} otherwise.
      */
-    public static boolean isRolePrincipal( final Principal principal ) {
+    static boolean isRolePrincipal( final Principal principal ) {
         return principal instanceof Role || principal instanceof GroupPrincipal;
     }
 
     /**
      * Determines whether the supplied Principal is a "user principal".
+     *
      * @param principal the principal to test
-     * @return <code>false</code> if the Principal is of type
-     *         {@link GroupPrincipal} or
-     *         {@link org.apache.wiki.auth.authorize.Role},
-     *         <code>true</code> otherwise
+     * @return {@code false} if the Principal is of type {@link GroupPrincipal} or {@link Role}, {@code true} otherwise.
      */
-    public static boolean isUserPrincipal( final Principal principal ) {
+    static boolean isUserPrincipal( final Principal principal ) {
         return !isRolePrincipal( principal );
     }
 
     /**
-     * Instantiates and executes a single JAAS
-     * {@link javax.security.auth.spi.LoginModule}, and returns a Set of
-     * Principals that results from a successful login. The LoginModule is instantiated,
-     * then its {@link javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, Map)}
-     * method is called. The parameters passed to <code>initialize</code> is a 
-     * dummy Subject, an empty shared-state Map, and an options Map the caller supplies.
-     * 
-     * @param clazz the LoginModule class to instantiate
-     * @param handler the callback handler to supply to the LoginModule
-     * @param options a Map of key/value strings for initializing the LoginModule
-     * @return the set of Principals returned by the JAAS method {@link Subject#getPrincipals()}
-     * @throws WikiSecurityException if the LoginModule could not be instantiated for any reason
-     */
-    protected Set<Principal> doJAASLogin(Class<? extends LoginModule> clazz, CallbackHandler handler, Map<String,String> options) throws WikiSecurityException
-    {
-        // Instantiate the login module
-        final LoginModule loginModule;
-        try {
-            loginModule = clazz.getDeclaredConstructor().newInstance();
-        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
-            throw new WikiSecurityException(e.getMessage(), e );
-        }
-
-        // Initialize the LoginModule
-        Subject subject = new Subject();
-        loginModule.initialize( subject, handler, EMPTY_MAP, options );
-
-        // Try to log in:
-        boolean loginSucceeded = false;
-        boolean commitSucceeded = false;
-        try
-        {
-            loginSucceeded = loginModule.login();
-            if (loginSucceeded)
-            {
-                commitSucceeded = loginModule.commit();
-            }
-        }
-        catch (LoginException e)
-        {
-            // Login or commit failed! No principal for you!
-        }
-
-        // If we successfully logged in & committed, return all the principals
-        if (loginSucceeded && commitSucceeded)
-        {
-            return subject.getPrincipals();
-        }
-        return NO_PRINCIPALS;
-    }
-
-    /**
-     * Looks up and obtains a configuration file inside the WEB-INF folder of a
-     * wiki webapp.
-     * @param engine the wiki engine
-     * @param name the file to obtain, <em>e.g.</em>, <code>jspwiki.policy</code>
-     * @return the URL to the file
-     */
-    protected static URL findConfigFile( WikiEngine engine, String name )
-    {
-        log.info( "looking for " + name + " inside WEB-INF " );
-        // Try creating an absolute path first
-        File defaultFile = null;
-        if( engine.getRootPath() != null )
-        {
-            defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + name );
-        }
-        if ( defaultFile != null && defaultFile.exists() )
-        {
-            try
-            {
-                return defaultFile.toURI().toURL();
-            }
-            catch ( MalformedURLException e)
-            {
-                // Shouldn't happen, but log it if it does
-                log.warn( "Malformed URL: " + e.getMessage() );
-            }
-
-        }
-
-        
-        // Ok, the absolute path didn't work; try other methods
-
-        URL path = null;
-        
-        if( engine.getServletContext() != null ) {
-            final File tmpFile;
-        	try {
-                tmpFile = File.createTempFile( "temp." + name, "" );
-            } catch( final IOException e ) {
-        	    log.error( "unable to create a temp file to load onto the policy", e );
-        	    return null;
-            }
-            tmpFile.deleteOnExit();
-            log.info( "looking for /" + name + " on classpath" );
-            //  create a tmp file of the policy loaded as an InputStream and return the URL to it
-            try( final InputStream is = AuthenticationManager.class.getResourceAsStream( "/" + name );
-                 final OutputStream os = new FileOutputStream( tmpFile )  ) {
-                if( is == null ) {
-                    throw new FileNotFoundException( name + " not found" );
-                }
-            	final URL url = engine.getServletContext().getResource( "/WEB-INF/" + name );
-            	if( url != null ) {
-            		return url;
-            	}
-            	
-                final byte[] buff = new byte[1024];
-                int bytes;
-                while( ( bytes = is.read( buff ) ) != -1 ) {
-                    os.write( buff, 0, bytes );
-                }
-
-                path = tmpFile.toURI().toURL();
-            } catch( final MalformedURLException e ) {
-                // This should never happen unless I screw up
-                log.fatal( "Your code is b0rked.  You are a bad person.", e );
-            } catch( final IOException e ) {
-               log.error( "failed to load security policy from file " + name + ",stacktrace follows", e );
-            }
-        }
-        return path;
-    }
-
-    /**
-     * Returns the first Principal in a set that isn't a {@link org.apache.wiki.auth.authorize.Role} or
-     * {@link org.apache.wiki.auth.GroupPrincipal}.
+     * Returns the first Principal in a set that isn't a {@link Role} or {@link GroupPrincipal}.
+     *
      * @param principals the principal set
      * @return the login principal
      */
-    protected Principal getLoginPrincipal( final Set< Principal > principals ) {
+    default Principal getLoginPrincipal( final Set< Principal > principals ) {
         for( final Principal principal : principals ) {
             if ( isUserPrincipal( principal ) ) {
                 return principal;
@@ -621,112 +205,31 @@ public class AuthenticationManager {
     // events processing .......................................................
 
     /**
-     * Registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( final WikiEventListener listener ) {
-        WikiEventManager.addWikiEventListener( this, listener );
-    }
+    void addWikiEventListener( WikiEventListener listener );
 
     /**
-     * Un-registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Un-registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
-        WikiEventManager.removeWikiEventListener( this, listener );
-    }
+    void removeWikiEventListener( final WikiEventListener listener );
 
     /**
-     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object
-     *  to all registered listeners.
+     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object to all registered listeners.
      *
      * @see org.apache.wiki.event.WikiSecurityEvent
      * @param type       the event type to be fired
      * @param principal  the subject of the event, which may be <code>null</code>
      * @param target     the changed Object, which may be <code>null</code>
      */
-    protected void fireEvent( final int type, final Principal principal, final Object target ) {
+    default void fireEvent( final int type, final Principal principal, final Object target ) {
         if ( WikiEventManager.isListening( this ) ) {
             WikiEventManager.fireEvent( this, new WikiSecurityEvent( this, type, principal, target ) );
         }
     }
-    
-    /**
-     * Initializes the options Map supplied to the configured LoginModule every time it is invoked.
-     * The properties and values extracted from
-     * <code>jspwiki.properties</code> are of the form
-     * <code>jspwiki.loginModule.options.<var>param</var> = <var>value</var>, where
-     * <var>param</var> is the key name, and <var>value</var> is the value.
-     * @param props the properties used to initialize JSPWiki
-     * @throws IllegalArgumentException if any of the keys are duplicated
-     */
-    private void initLoginModuleOptions(Properties props)
-    {
-        for ( Object key : props.keySet() )
-        {
-            String propName = key.toString();
-            if ( propName.startsWith( PREFIX_LOGIN_MODULE_OPTIONS ) )
-            {
-                // Extract the option name and value
-                String optionKey = propName.substring( PREFIX_LOGIN_MODULE_OPTIONS.length() ).trim();
-                if ( optionKey.length() > 0 )
-                {
-                    String optionValue = props.getProperty( propName );
-                    
-                    // Make sure the key is unique before stashing the key/value pair
-                    if ( m_loginModuleOptions.containsKey( optionKey ) )
-                    {
-                        throw new IllegalArgumentException( "JAAS LoginModule key " + propName + " cannot be specified twice!" );
-                    }
-                    m_loginModuleOptions.put( optionKey, optionValue );
-                }
-            }
-        }
-    }
-    
-    /**
-     * After successful login, this method is called to inject authorized role Principals into the WikiSession.
-     * To determine which roles should be injected, the configured Authorizer
-     * is queried for the roles it knows about by calling  {@link org.apache.wiki.auth.Authorizer#getRoles()}.
-     * Then, each role returned by the authorizer is tested by calling {@link org.apache.wiki.auth.Authorizer#isUserInRole(WikiSession, Principal)}.
-     * If this check fails, and the Authorizer is of type WebAuthorizer, the role is checked again by calling
-     * {@link org.apache.wiki.auth.authorize.WebAuthorizer#isUserInRole(javax.servlet.http.HttpServletRequest, Principal)}).
-     * Any roles that pass the test are injected into the Subject by firing appropriate authentication events.
-     * @param session the user's current WikiSession
-     * @param authorizer the WikiEngine's configured Authorizer
-     * @param request the user's HTTP session, which may be <code>null</code>
-     */
-    private void injectAuthorizerRoles( WikiSession session, Authorizer authorizer, HttpServletRequest request )
-    {
-        // Test each role the authorizer knows about
-        for ( Principal role : authorizer.getRoles() )
-        {
-            // Test the Authorizer
-            if ( authorizer.isUserInRole( session, role ) )
-            {
-                fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, role, session );
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug("Added authorizer role " + role.getName() + "." );
-                }
-            }
-            
-            // If web authorizer, test the request.isInRole() method also
-            else if ( request != null && authorizer instanceof WebAuthorizer )
-            {
-                WebAuthorizer wa = (WebAuthorizer)authorizer;
-                if ( wa.isUserInRole( request, role ) )
-                {
-                    fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, role, session );
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug("Added container role " + role.getName() + "." );
-                    }
-                }
-            }
-        }
-    }
 
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
new file mode 100644
index 0000000..547d28b
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
@@ -0,0 +1,507 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.    
+ */
+package org.apache.wiki.auth;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.authorize.WebAuthorizer;
+import org.apache.wiki.auth.authorize.WebContainerAuthorizer;
+import org.apache.wiki.auth.login.AnonymousLoginModule;
+import org.apache.wiki.auth.login.CookieAssertionLoginModule;
+import org.apache.wiki.auth.login.CookieAuthenticationLoginModule;
+import org.apache.wiki.auth.login.UserDatabaseLoginModule;
+import org.apache.wiki.auth.login.WebContainerCallbackHandler;
+import org.apache.wiki.auth.login.WebContainerLoginModule;
+import org.apache.wiki.auth.login.WikiCallbackHandler;
+import org.apache.wiki.event.WikiEventListener;
+import org.apache.wiki.event.WikiEventManager;
+import org.apache.wiki.event.WikiSecurityEvent;
+import org.apache.wiki.util.TextUtil;
+import org.apache.wiki.util.TimedCounterList;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+
+/**
+ * Default implementation for {@link AuthenticationManager}
+ *
+ * {@inheritDoc}
+ * 
+ * @since 2.3
+ */
+public class DefaultAuthenticationManager implements AuthenticationManager {
+
+    /** How many milliseconds the logins are stored before they're cleaned away. */
+    private static final long LASTLOGINS_CLEANUP_TIME = 10 * 60 * 1_000L; // Ten minutes
+
+    private static final long MAX_LOGIN_DELAY = 20 * 1_000L; // 20 seconds
+
+    private static final Logger log = Logger.getLogger( DefaultAuthenticationManager.class );
+
+    /** Empty Map passed to JAAS {@link #doJAASLogin(Class, CallbackHandler, Map)} method. */
+    protected static final Map< String, String > EMPTY_MAP = Collections.unmodifiableMap( new HashMap<>() );
+
+    /** Class (of type LoginModule) to use for custom authentication. */
+    protected Class< ? extends LoginModule > m_loginModuleClass = UserDatabaseLoginModule.class;
+
+    /** Options passed to {@link LoginModule#initialize(Subject, CallbackHandler, Map, Map)};
+     * initialized by {@link #initialize(Engine, Properties)}. */
+    protected Map< String, String > m_loginModuleOptions = new HashMap<>();
+
+    /** The default {@link LoginModule} class name to use for custom authentication. */
+    private static final String DEFAULT_LOGIN_MODULE = "org.apache.wiki.auth.login.UserDatabaseLoginModule";
+
+    /** Empty principal set. */
+    private static final Set<Principal> NO_PRINCIPALS = new HashSet<>();
+
+    /** Static Boolean for lazily-initializing the "allows assertions" flag */
+    private boolean m_allowsCookieAssertions = true;
+
+    private boolean m_throttleLogins = true;
+
+    /** Static Boolean for lazily-initializing the "allows cookie authentication" flag */
+    private boolean m_allowsCookieAuthentication = false;
+
+    private Engine m_engine = null;
+
+    /** If true, logs the IP address of the editor */
+    private boolean m_storeIPAddress = true;
+
+    /** Keeps a list of the usernames who have attempted a login recently. */
+    private TimedCounterList< String > m_lastLoginAttempts = new TimedCounterList<>();
+
+    /**
+     * Creates an AuthenticationManager instance for the given WikiEngine and
+     * the specified set of properties. All initialization for the modules is
+     * done here.
+     * @param engine the wiki engine
+     * @param props the properties used to initialize the wiki engine
+     * @throws WikiException if the AuthenticationManager cannot be initialized
+     */
+    @SuppressWarnings( "unchecked" )
+    public void initialize( final Engine engine, final Properties props ) throws WikiException {
+        m_engine = engine;
+        m_storeIPAddress = TextUtil.getBooleanProperty( props, PROP_STOREIPADDRESS, m_storeIPAddress );
+
+        // Should we allow cookies for assertions? (default: yes)
+        m_allowsCookieAssertions = TextUtil.getBooleanProperty( props, PROP_ALLOW_COOKIE_ASSERTIONS,true );
+
+        // Should we allow cookies for authentication? (default: no)
+        m_allowsCookieAuthentication = TextUtil.getBooleanProperty( props, PROP_ALLOW_COOKIE_AUTH, false );
+
+        // Should we throttle logins? (default: yes)
+        m_throttleLogins = TextUtil.getBooleanProperty( props, PROP_LOGIN_THROTTLING, true );
+
+        // Look up the LoginModule class
+        final String loginModuleClassName = TextUtil.getStringProperty( props, PROP_LOGIN_MODULE, DEFAULT_LOGIN_MODULE );
+        try {
+            m_loginModuleClass = ( Class< ? extends LoginModule > )Class.forName( loginModuleClassName );
+        } catch( final ClassNotFoundException e ) {
+            log.error( e.getMessage(), e );
+            throw new WikiException( "Could not instantiate LoginModule class.", e );
+        }
+
+        // Initialize the LoginModule options
+        initLoginModuleOptions( props );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isContainerAuthenticated() {
+        try {
+            final Authorizer authorizer = m_engine.getManager( AuthorizationManager.class ).getAuthorizer();
+            if ( authorizer instanceof WebContainerAuthorizer ) {
+                 return ( ( WebContainerAuthorizer )authorizer ).isContainerAuthorized();
+            }
+        } catch ( final WikiException e ) {
+            // It's probably ok to fail silently...
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean login( final HttpServletRequest request ) throws WikiSecurityException {
+        final HttpSession httpSession = request.getSession();
+        final WikiSession session = SessionMonitor.getInstance( m_engine.adapt( WikiEngine.class ) ).find( httpSession );
+        final AuthenticationManager authenticationMgr = m_engine.getManager( AuthenticationManager.class );
+        final AuthorizationManager authorizationMgr = m_engine.getManager( AuthorizationManager.class );
+        CallbackHandler handler = null;
+        final Map< String, String > options = EMPTY_MAP;
+
+        // If user not authenticated, check if container logged them in, or if there's an authentication cookie
+        if ( !session.isAuthenticated() ) {
+            // Create a callback handler
+            handler = new WebContainerCallbackHandler( m_engine.adapt( WikiEngine.class ), request );
+
+            // Execute the container login module, then (if that fails) the cookie auth module
+            Set< Principal > principals = authenticationMgr.doJAASLogin( WebContainerLoginModule.class, handler, options );
+            if ( principals.size() == 0 && authenticationMgr.allowsCookieAuthentication() ) {
+                principals = authenticationMgr.doJAASLogin( CookieAuthenticationLoginModule.class, handler, options );
+            }
+
+            // If the container logged the user in successfully, tell the WikiSession (and add all of the Principals)
+            if ( principals.size() > 0 ) {
+                fireEvent( WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
+                for( final Principal principal : principals ) {
+                    fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, principal, session );
+                }
+
+                // Add all appropriate Authorizer roles
+                injectAuthorizerRoles( session, authorizationMgr.getAuthorizer(), request );
+            }
+        }
+
+        // If user still not authenticated, check if assertion cookie was supplied
+        if ( !session.isAuthenticated() && authenticationMgr.allowsCookieAssertions() ) {
+            // Execute the cookie assertion login module
+            final Set< Principal > principals = authenticationMgr.doJAASLogin( CookieAssertionLoginModule.class, handler, options );
+            if ( principals.size() > 0 ) {
+                fireEvent( WikiSecurityEvent.LOGIN_ASSERTED, getLoginPrincipal( principals ), session);
+            }
+        }
+
+        // If user still anonymous, use the remote address
+        if( session.isAnonymous() ) {
+            final Set< Principal > principals = authenticationMgr.doJAASLogin( AnonymousLoginModule.class, handler, options );
+            if( principals.size() > 0 ) {
+                fireEvent( WikiSecurityEvent.LOGIN_ANONYMOUS, getLoginPrincipal( principals ), session );
+                return true;
+            }
+        }
+
+        // If by some unusual turn of events the Anonymous login module doesn't work, login failed!
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean login( final WikiSession session, final HttpServletRequest request, final String username, final String password ) throws WikiSecurityException {
+        if ( session == null ) {
+            log.error( "No wiki session provided, cannot log in." );
+            return false;
+        }
+
+        // Protect against brute-force password guessing if configured to do so
+        if ( m_throttleLogins ) {
+            delayLogin( username );
+        }
+
+        final CallbackHandler handler = new WikiCallbackHandler( m_engine.adapt( WikiEngine.class ), null, username, password );
+
+        // Execute the user's specified login module
+        final Set< Principal > principals = doJAASLogin( m_loginModuleClass, handler, m_loginModuleOptions );
+        if( principals.size() > 0 ) {
+            fireEvent(WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
+            for ( final Principal principal : principals ) {
+                fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, principal, session );
+            }
+
+            // Add all appropriate Authorizer roles
+            injectAuthorizerRoles( session, m_engine.getManager( AuthorizationManager.class ).getAuthorizer(), null );
+
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     *  This method builds a database of login names that are being attempted, and will try to delay if there are too many requests coming
+     *  in for the same username.
+     *  <p>
+     *  The current algorithm uses 2^loginattempts as the delay in milliseconds, i.e. at 10 login attempts it'll add 1.024 seconds to the login.
+     *
+     *  @param username The username that is being logged in
+     */
+    private void delayLogin( final String username ) {
+        try {
+            m_lastLoginAttempts.cleanup( LASTLOGINS_CLEANUP_TIME );
+            final int count = m_lastLoginAttempts.count( username );
+
+            final long delay = Math.min( 1 << count, MAX_LOGIN_DELAY );
+            log.debug( "Sleeping for " + delay + " ms to allow login." );
+            Thread.sleep( delay );
+
+            m_lastLoginAttempts.add( username );
+        } catch( final InterruptedException e ) {
+            // FALLTHROUGH is fine
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void logout( final HttpServletRequest request ) {
+        if( request == null ) {
+            log.error( "No HTTP reqest provided; cannot log out." );
+            return;
+        }
+
+        final HttpSession session = request.getSession();
+        final String sid = ( session == null ) ? "(null)" : session.getId();
+        if( log.isDebugEnabled() ) {
+            log.debug( "Invalidating WikiSession for session ID=" + sid );
+        }
+        // Retrieve the associated WikiSession and clear the Principal set
+        final WikiSession wikiSession = WikiSession.getWikiSession( m_engine.adapt( WikiEngine.class ), request );
+        final Principal originalPrincipal = wikiSession.getLoginPrincipal();
+        wikiSession.invalidate();
+
+        // Remove the wikiSession from the WikiSession cache
+        WikiSession.removeWikiSession( m_engine.adapt( WikiEngine.class ), request );
+
+        // We need to flush the HTTP session too
+        if ( session != null ) {
+            session.invalidate();
+        }
+
+        // Log the event
+        fireEvent( WikiSecurityEvent.LOGOUT, originalPrincipal, null );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean allowsCookieAssertions() {
+        return m_allowsCookieAssertions;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean allowsCookieAuthentication() {
+        return m_allowsCookieAuthentication;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set< Principal > doJAASLogin( final Class< ? extends LoginModule > clazz,
+                                         final CallbackHandler handler,
+                                         final Map< String, String > options ) throws WikiSecurityException {
+        // Instantiate the login module
+        final LoginModule loginModule;
+        try {
+            loginModule = clazz.getDeclaredConstructor().newInstance();
+        } catch( final InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e ) {
+            throw new WikiSecurityException( e.getMessage(), e );
+        }
+
+        // Initialize the LoginModule
+        final Subject subject = new Subject();
+        loginModule.initialize( subject, handler, EMPTY_MAP, options );
+
+        // Try to log in:
+        boolean loginSucceeded = false;
+        boolean commitSucceeded = false;
+        try {
+            loginSucceeded = loginModule.login();
+            if( loginSucceeded ) {
+                commitSucceeded = loginModule.commit();
+            }
+        } catch( final LoginException e ) {
+            // Login or commit failed! No principal for you!
+        }
+
+        // If we successfully logged in & committed, return all the principals
+        if( loginSucceeded && commitSucceeded ) {
+            return subject.getPrincipals();
+        }
+        return NO_PRINCIPALS;
+    }
+
+    /**
+     * Looks up and obtains a configuration file inside the WEB-INF folder of a wiki webapp.
+     *
+     * @param engine the wiki engine
+     * @param name the file to obtain, <em>e.g.</em>, <code>jspwiki.policy</code>
+     * @return the URL to the file
+     */
+    protected static URL findConfigFile( final Engine engine, final String name ) {
+        log.info( "looking for " + name + " inside WEB-INF " );
+        // Try creating an absolute path first
+        File defaultFile = null;
+        if( engine.getRootPath() != null ) {
+            defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + name );
+        }
+        if ( defaultFile != null && defaultFile.exists() ) {
+            try {
+                return defaultFile.toURI().toURL();
+            } catch ( final MalformedURLException e ) {
+                // Shouldn't happen, but log it if it does
+                log.warn( "Malformed URL: " + e.getMessage() );
+            }
+        }
+
+
+        // Ok, the absolute path didn't work; try other methods
+        URL path = null;
+
+        if( engine.getServletContext() != null ) {
+            final File tmpFile;
+        	try {
+                tmpFile = File.createTempFile( "temp." + name, "" );
+            } catch( final IOException e ) {
+        	    log.error( "unable to create a temp file to load onto the policy", e );
+        	    return null;
+            }
+            tmpFile.deleteOnExit();
+            log.info( "looking for /" + name + " on classpath" );
+            //  create a tmp file of the policy loaded as an InputStream and return the URL to it
+            try( final InputStream is = DefaultAuthenticationManager.class.getResourceAsStream( "/" + name );
+                 final OutputStream os = new FileOutputStream( tmpFile ) ) {
+                if( is == null ) {
+                    throw new FileNotFoundException( name + " not found" );
+                }
+            	final URL url = engine.getServletContext().getResource( "/WEB-INF/" + name );
+            	if( url != null ) {
+            		return url;
+            	}
+
+                final byte[] buff = new byte[1024];
+                int bytes;
+                while( ( bytes = is.read( buff ) ) != -1 ) {
+                    os.write( buff, 0, bytes );
+                }
+
+                path = tmpFile.toURI().toURL();
+            } catch( final MalformedURLException e ) {
+                // This should never happen unless I screw up
+                log.fatal( "Your code is b0rked.  You are a bad person.", e );
+            } catch( final IOException e ) {
+               log.error( "failed to load security policy from file " + name + ",stacktrace follows", e );
+            }
+        }
+        return path;
+    }
+
+    // events processing .......................................................
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.addWikiEventListener( this, listener );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.removeWikiEventListener( this, listener );
+    }
+
+    /**
+     * Initializes the options Map supplied to the configured LoginModule every time it is invoked. The properties and values extracted from
+     * <code>jspwiki.properties</code> are of the form <code>jspwiki.loginModule.options.<var>param</var> = <var>value</var>, where
+     * <var>param</var> is the key name, and <var>value</var> is the value.
+     *
+     * @param props the properties used to initialize JSPWiki
+     * @throws IllegalArgumentException if any of the keys are duplicated
+     */
+    private void initLoginModuleOptions( final Properties props ) {
+        for( final Object key : props.keySet() ) {
+            final String propName = key.toString();
+            if( propName.startsWith( PREFIX_LOGIN_MODULE_OPTIONS ) ) {
+                // Extract the option name and value
+                final String optionKey = propName.substring( PREFIX_LOGIN_MODULE_OPTIONS.length() ).trim();
+                if( optionKey.length() > 0 ) {
+                    final String optionValue = props.getProperty( propName );
+
+                    // Make sure the key is unique before stashing the key/value pair
+                    if ( m_loginModuleOptions.containsKey( optionKey ) ) {
+                        throw new IllegalArgumentException( "JAAS LoginModule key " + propName + " cannot be specified twice!" );
+                    }
+                    m_loginModuleOptions.put( optionKey, optionValue );
+                }
+            }
+        }
+    }
+
+    /**
+     * After successful login, this method is called to inject authorized role Principals into the WikiSession. To determine which roles
+     * should be injected, the configured Authorizer is queried for the roles it knows about by calling  {@link Authorizer#getRoles()}.
+     * Then, each role returned by the authorizer is tested by calling {@link Authorizer#isUserInRole(WikiSession, Principal)}. If this
+     * check fails, and the Authorizer is of type WebAuthorizer, the role is checked again by calling
+     * {@link WebAuthorizer#isUserInRole(HttpServletRequest, Principal)}). Any roles that pass the test are injected into the Subject by
+     * firing appropriate authentication events.
+     *
+     * @param session the user's current WikiSession
+     * @param authorizer the WikiEngine's configured Authorizer
+     * @param request the user's HTTP session, which may be <code>null</code>
+     */
+    private void injectAuthorizerRoles( final WikiSession session, final Authorizer authorizer, final HttpServletRequest request ) {
+        // Test each role the authorizer knows about
+        for( final Principal role : authorizer.getRoles() ) {
+            // Test the Authorizer
+            if( authorizer.isUserInRole( session, role ) ) {
+                fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, role, session );
+                if( log.isDebugEnabled() ) {
+                    log.debug( "Added authorizer role " + role.getName() + "." );
+                }
+            // If web authorizer, test the request.isInRole() method also
+            } else if ( request != null && authorizer instanceof WebAuthorizer ) {
+                final WebAuthorizer wa = ( WebAuthorizer )authorizer;
+                if ( wa.isUserInRole( request, role ) ) {
+                    fireEvent( WikiSecurityEvent.PRINCIPAL_ADD, role, session );
+                    if ( log.isDebugEnabled() ) {
+                        log.debug( "Added container role " + role.getName() + "." );
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index 160761c..ff4ad5a 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -65,11 +65,11 @@
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.attachment.AttachmentManager</requestedClass>
-    <mappedClass>org.apache.wiki.attachment.AttachmentManager</mappedClass>
+    <mappedClass>org.apache.wiki.attachment.DefaultAttachmentManager</mappedClass>
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.AuthenticationManager</requestedClass>
-    <mappedClass>org.apache.wiki.auth.AuthenticationManager</mappedClass>
+    <mappedClass>org.apache.wiki.auth.DefaultAuthenticationManager</mappedClass>
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.AuthorizationManager</requestedClass>


[jspwiki] 27/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (4)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit ab518d9ed666bdc6971280be4e5bef77c3561e45
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:12:23 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (4)
---
 .../src/main/webapp/templates/210/AttachmentTab.jsp  |  2 +-
 .../src/main/webapp/templates/210/CommentContent.jsp |  5 +++--
 .../src/main/webapp/templates/210/DiffTab.jsp        | 12 +++++++-----
 .../src/main/webapp/templates/210/EditContent.jsp    |  5 +++--
 .../src/main/webapp/templates/210/GroupTab.jsp       |  4 ++--
 .../src/main/webapp/templates/210/InfoContent.jsp    | 12 +++++++-----
 .../src/main/webapp/templates/210/LoginContent.jsp   |  2 +-
 .../src/main/webapp/templates/210/PageContent.jsp    |  4 ++--
 .../src/main/webapp/templates/210/PageTab.jsp        |  3 ++-
 .../src/main/webapp/templates/210/PreferencesTab.jsp |  2 +-
 .../src/main/webapp/templates/210/ProfileTab.jsp     |  2 +-
 .../src/main/webapp/templates/210/UploadTemplate.jsp |  5 +++--
 .../main/webapp/templates/210/editors/CKeditor.jsp   | 18 ++++++++++--------
 .../src/main/webapp/templates/210/editors/FCK.jsp    | 18 ++++++++++--------
 .../main/webapp/templates/210/editors/TinyMCE.jsp    | 20 +++++++++++---------
 .../src/main/webapp/templates/210/editors/plain.jsp  | 14 ++++++++------
 .../main/webapp/templates/210/editors/wysiwyg.jsp    | 14 ++++++++------
 17 files changed, 80 insertions(+), 62 deletions(-)

diff --git a/jspwiki-war/src/main/webapp/templates/210/AttachmentTab.jsp b/jspwiki-war/src/main/webapp/templates/210/AttachmentTab.jsp
index bc88026..aeb551c 100644
--- a/jspwiki-war/src/main/webapp/templates/210/AttachmentTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/AttachmentTab.jsp
@@ -29,7 +29,7 @@
 <%
   int MAXATTACHNAMELENGTH = 30;
   WikiContext c = WikiContext.findContext(pageContext);
-  String progressId = c.getEngine().getProgressManager().getNewProgressIdentifier();
+  String progressId = c.getEngine().getManager( ProgressManager.class ).getNewProgressIdentifier();
 %>
 
 <div id="addattachment">
diff --git a/jspwiki-war/src/main/webapp/templates/210/CommentContent.jsp b/jspwiki-war/src/main/webapp/templates/210/CommentContent.jsp
index 5ea2821..664e21a 100644
--- a/jspwiki-war/src/main/webapp/templates/210/CommentContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/CommentContent.jsp
@@ -18,14 +18,15 @@
 --%>
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
-<%@ page import="org.apache.wiki.*" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
+<%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.attachment.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  int attCount = c.getEngine().getAttachmentManager().listAttachments(c.getPage()).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments(c.getPage()).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";  
 %>
diff --git a/jspwiki-war/src/main/webapp/templates/210/DiffTab.jsp b/jspwiki-war/src/main/webapp/templates/210/DiffTab.jsp
index 35c0005..e533567 100644
--- a/jspwiki-war/src/main/webapp/templates/210/DiffTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/DiffTab.jsp
@@ -17,21 +17,23 @@
     under the License.
 --%>
 
-<%@ page import="org.apache.wiki.tags.InsertDiffTag" %>
-<%@ page import="org.apache.wiki.*" %>
 <%@ page import="java.util.*" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
+<%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+<%@ page import="org.apache.wiki.tags.InsertDiffTag" %>
+<%@ page import="org.apache.wiki.variables.VariableManager" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  List history = c.getEngine().getPageManager().getVersionHistory(c.getPage().getName());
+  List history = c.getEngine().getManager( PageManager.class ).getVersionHistory(c.getPage().getName());
   pageContext.setAttribute( "history", history );
-  pageContext.setAttribute( "diffprovider", c.getEngine().getVariableManager().getVariable(c,"jspwiki.diffProvider"));
+  pageContext.setAttribute( "diffprovider", c.getEngine().getManager( VariableManager.class ).getVariable(c,"jspwiki.diffProvider"));
  %>
 
 <wiki:PageExists>
diff --git a/jspwiki-war/src/main/webapp/templates/210/EditContent.jsp b/jspwiki-war/src/main/webapp/templates/210/EditContent.jsp
index b6b7649..f10741d 100644
--- a/jspwiki-war/src/main/webapp/templates/210/EditContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/EditContent.jsp
@@ -18,15 +18,16 @@
 --%>
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.attachment.AttachmentManager" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  int attCount = c.getEngine().getAttachmentManager().listAttachments(c.getPage()).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments(c.getPage()).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";
 %>
diff --git a/jspwiki-war/src/main/webapp/templates/210/GroupTab.jsp b/jspwiki-war/src/main/webapp/templates/210/GroupTab.jsp
index d6fc9a4..914cfbb 100644
--- a/jspwiki-war/src/main/webapp/templates/210/GroupTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/GroupTab.jsp
@@ -21,6 +21,7 @@
 <%@ page import="java.security.Principal" %>
 <%@ page import="java.text.MessageFormat" %>
 <%@ page import="java.util.*" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ page import="org.apache.wiki.WikiContext" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.PrincipalComparator" %>
@@ -29,7 +30,6 @@
 <%@ page import="org.apache.wiki.preferences.Preferences" %>
 <%@ page import="org.apache.log4j.*" %>
 <%@ page errorPage="/Error.jsp" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
@@ -166,7 +166,7 @@
     if ( roles[i] instanceof GroupPrincipal ) /* bugfix */
     {
       String name = roles[i].getName();
-      Group group = c.getEngine().getGroupManager().getGroup( name );
+      Group group = c.getEngine().getManager( GroupManager.class ).getGroup( name );
 
       %><%= printWikiGroupPutGroup( group, name, name.equals( groupname ), pageContext )  %><%
     }
diff --git a/jspwiki-war/src/main/webapp/templates/210/InfoContent.jsp b/jspwiki-war/src/main/webapp/templates/210/InfoContent.jsp
index 57baec4..c59d32b 100644
--- a/jspwiki-war/src/main/webapp/templates/210/InfoContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/InfoContent.jsp
@@ -18,15 +18,17 @@
 --%>
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
+<%@ page import="java.security.Permission" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ page import="org.apache.wiki.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.attachment.*" %>
 <%@ page import="org.apache.wiki.i18n.InternationalizationManager" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.preferences.Preferences" %>
+<%@ page import="org.apache.wiki.ui.progress.ProgressManager" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
-<%@ page import="java.security.Permission" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <fmt:setLocale value="${prefs.Language}" />
@@ -34,7 +36,7 @@
 <%
   WikiContext c = WikiContext.findContext(pageContext);
   WikiPage wikiPage = c.getPage();
-  int attCount = c.getEngine().getAttachmentManager().listAttachments( c.getPage() ).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments( c.getPage() ).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";
 
@@ -44,7 +46,7 @@
   String creationAuthor ="";
 
   //FIXME -- seems not to work correctly for attachments !!
-  WikiPage firstPage = c.getEngine().getPageManager().getPage( wikiPage.getName(), 1 );
+  WikiPage firstPage = c.getEngine().getManager( PageManager.class ).getPage( wikiPage.getName(), 1 );
   if( firstPage != null )
   {
     creationAuthor = firstPage.getAuthor();
@@ -265,7 +267,7 @@
 <wiki:PageType type="attachment">
 <%
   int MAXATTACHNAMELENGTH = 30;
-  String progressId = c.getEngine().getProgressManager().getNewProgressIdentifier();
+  String progressId = c.getEngine().getManager( ProgressManager.class ).getNewProgressIdentifier();
 %>
 
   <wiki:TabbedSection defaultTab="<%=tabParam%>">
diff --git a/jspwiki-war/src/main/webapp/templates/210/LoginContent.jsp b/jspwiki-war/src/main/webapp/templates/210/LoginContent.jsp
index b4266f0..542631e 100644
--- a/jspwiki-war/src/main/webapp/templates/210/LoginContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/LoginContent.jsp
@@ -30,7 +30,7 @@
 <%
     String postURL = "";
     WikiContext ctx = WikiContext.findContext( pageContext );
-    AuthenticationManager mgr = ctx.getEngine().getAuthenticationManager();
+    AuthenticationManager mgr = ctx.getEngine().getManager( AuthenticationManager.class );
 
     if( mgr.isContainerAuthenticated() )
     {
diff --git a/jspwiki-war/src/main/webapp/templates/210/PageContent.jsp b/jspwiki-war/src/main/webapp/templates/210/PageContent.jsp
index dfb4505..48ee36e 100644
--- a/jspwiki-war/src/main/webapp/templates/210/PageContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/PageContent.jsp
@@ -18,15 +18,15 @@
 --%>
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ page import="org.apache.wiki.*" %>
 <%@ page import="org.apache.wiki.attachment.*" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  int attCount = c.getEngine().getAttachmentManager().listAttachments(c.getPage()).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments( c.getPage() ).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";
 %>
diff --git a/jspwiki-war/src/main/webapp/templates/210/PageTab.jsp b/jspwiki-war/src/main/webapp/templates/210/PageTab.jsp
index 5b892a4..40393af 100644
--- a/jspwiki-war/src/main/webapp/templates/210/PageTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/PageTab.jsp
@@ -19,6 +19,7 @@
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ page import="javax.servlet.jsp.jstl.fmt.*" %><%--CHECK why is this needed --%>
@@ -52,7 +53,7 @@
           <%--<wiki:PageVersion/>--%>
           <select id="version" name="version" onchange="this.form.submit();" >
 <% 
-   int latestVersion = c.getEngine().getPageManager().getPage( pagename, WikiProvider.LATEST_VERSION ).getVersion();
+   int latestVersion = c.getEngine().getManager( PageManager.class ).getPage( pagename, WikiProvider.LATEST_VERSION ).getVersion();
    int thisVersion = p.getVersion();
 
    if( thisVersion == WikiProvider.LATEST_VERSION ) thisVersion = latestVersion; //should not happen
diff --git a/jspwiki-war/src/main/webapp/templates/210/PreferencesTab.jsp b/jspwiki-war/src/main/webapp/templates/210/PreferencesTab.jsp
index 36e6f54..7ba04fe 100644
--- a/jspwiki-war/src/main/webapp/templates/210/PreferencesTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/PreferencesTab.jsp
@@ -37,7 +37,7 @@
 <%
   //FIXME: this should better move to UserPreferences.jsp but that doesn't seem to work. Ugh ?
   WikiContext c = WikiContext.findContext( pageContext );
-  TemplateManager t = c.getEngine().getTemplateManager();
+  TemplateManager t = c.getEngine().getManager( TemplateManager.class );
   pageContext.setAttribute( "skins", t.listSkins(pageContext, c.getTemplate() ) );
   pageContext.setAttribute( "languages", t.listLanguages(pageContext) );
   pageContext.setAttribute( "timeformats", t.listTimeFormats(pageContext) );
diff --git a/jspwiki-war/src/main/webapp/templates/210/ProfileTab.jsp b/jspwiki-war/src/main/webapp/templates/210/ProfileTab.jsp
index 6c6378f..173dc2a 100644
--- a/jspwiki-war/src/main/webapp/templates/210/ProfileTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/ProfileTab.jsp
@@ -30,7 +30,7 @@
 <%
   /* dateformatting not yet supported by wiki:UserProfile tag - diy */
   WikiContext wikiContext = WikiContext.findContext(pageContext);
-  UserManager manager = wikiContext.getEngine().getUserManager();
+  UserManager manager = wikiContext.getEngine().getManager( UserManager.class );
   UserProfile profile = manager.getUserProfile( wikiContext.getWikiSession() );
 %>
 <form action="<wiki:CheckRequestContext 
diff --git a/jspwiki-war/src/main/webapp/templates/210/UploadTemplate.jsp b/jspwiki-war/src/main/webapp/templates/210/UploadTemplate.jsp
index 7df18fb..32265f2 100644
--- a/jspwiki-war/src/main/webapp/templates/210/UploadTemplate.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/UploadTemplate.jsp
@@ -18,14 +18,15 @@
 --%>
 
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.attachment.AttachmentManager" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  int attCount = c.getEngine().getAttachmentManager().listAttachments(c.getPage()).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments(c.getPage()).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";
 %>
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
index 08c287e..cf85ee8 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
@@ -21,11 +21,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.text.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -39,7 +41,7 @@
 --%>
 <%
     WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
 
     /* local download of CKeditor */
     TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
@@ -66,17 +68,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -87,7 +89,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -98,7 +100,7 @@
    try
    {
        //pageAsHtml = StringEscapeUtils.escapeEcmaScript( renderingManager.getHTML( context, usertext ) );
-       pageAsHtml = engine.getRenderingManager().getHTML( context, usertext );
+       pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
    }
        catch( Exception e )
    {
@@ -114,7 +116,7 @@
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
    /*not used
-   String templateDir = (String)copyOfWikiProperties.get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)copyOfWikiProperties.get( Engine.PROP_TEMPLATEDIR );
 
    String protocol = "http://";
    if( request.isSecure() )
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/FCK.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/FCK.jsp
index 4db5005..c6662b2 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/FCK.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/FCK.jsp
@@ -22,11 +22,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.text.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -38,7 +40,7 @@
     This provides the FCK editor for JSPWiki.
 --%>
 <%  WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
     context.setVariable( WikiContext.VAR_WYSIWYG_EDITOR_MODE, Boolean.TRUE );
     context.setVariable( VariableManager.VAR_RUNFILTERS,  "false" );
 
@@ -56,17 +58,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -77,12 +79,12 @@
 <%
     if( usertext == null )
     {
-        usertext = engine.getPageManager().getPureText( context.getPage() );
+        usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
     }%>
 </wiki:CheckRequestContext>
 <% if( usertext == null ) usertext = "";
 
-   String pageAsHtml = StringEscapeUtils.escapeEcmaScript( engine.getRenderingManager().getHTML( context, usertext ) );
+   String pageAsHtml = StringEscapeUtils.escapeEcmaScript( engine.getManager( RenderingManager.class ).getHTML( context, usertext ) );
 
    // Disable the WYSIWYG_EDITOR_MODE and reset the other properties immediately
    // after the XHTML for FCK has been rendered.
@@ -90,7 +92,7 @@
    context.setVariable( VariableManager.VAR_RUNFILTERS,  null );
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
-   String templateDir = (String)engine.getWikiProperties().get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)engine.getWikiProperties().get( Engine.PROP_TEMPLATEDIR );
 
    String protocol = "http://";
    if( request.isSecure() )
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
index 0372792..52047d2 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
@@ -21,11 +21,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.text.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -38,7 +40,7 @@
 --%>
 <%
     WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
 
     /* local download of TinyMCE */
     TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
@@ -65,17 +67,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -86,7 +88,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -95,8 +97,8 @@
 
    String pageAsHtml;
    try {
-       //pageAsHtml = StringEscapeUtils.escapeJavaScript( engine.getRenderingManager().getHTML( context, usertext ) );
-       pageAsHtml = engine.getRenderingManager().getHTML( context, usertext );
+       //pageAsHtml = StringEscapeUtils.escapeJavaScript( engine.getManager( RenderingManager.class ).getHTML( context, usertext ) );
+       pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
    } catch( Exception e ) {
        pageAsHtml = "Error in converting wiki-markup to well-formed HTML \n" + e.toString();
        //pageAsHtml = e.toString() + "\n" + usertext; //error
@@ -109,7 +111,7 @@
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
    /*not used
-   String templateDir = (String)engine.getWikiProperties().get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)engine.getWikiProperties().get( Engine.PROP_TEMPLATEDIR );
 
    String protocol = "http://";
    if( request.isSecure() )
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/plain.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/plain.jsp
index 7b8b7cb..e4743f7 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/plain.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/plain.jsp
@@ -20,10 +20,12 @@
 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
-<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.filters.SpamFilter" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
@@ -35,7 +37,7 @@
 --%>
 <%
    WikiContext context = WikiContext.findContext( pageContext );
-   WikiEngine engine = context.getEngine();
+   Engine engine = context.getEngine();
 
    TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
    		context.getURL( WikiContext.NONE, "scripts/jspwiki-edit.js" ) );
@@ -48,17 +50,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -69,7 +71,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/wysiwyg.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/wysiwyg.jsp
index 3eeba15..31991ce 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/wysiwyg.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/wysiwyg.jsp
@@ -20,10 +20,12 @@
 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
-<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.filters.SpamFilter" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
@@ -35,7 +37,7 @@
 --%>
 <%
    WikiContext context = WikiContext.findContext( pageContext );
-   WikiEngine engine = context.getEngine();
+   Engine engine = context.getEngine();
 
    TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
    		context.getURL( WikiContext.NONE, "scripts/jspwiki-edit.js" ) );
@@ -48,17 +50,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -69,7 +71,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>


[jspwiki] 11/38: add initialize( Engine, Properties ) to AuthenticationManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 05eec06caa81c3c9dbbae84c5976be16674bb753
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:51:46 2020 +0100

    add initialize( Engine, Properties ) to AuthenticationManager
---
 .../java/org/apache/wiki/auth/AuthenticationManager.java    | 13 +++++++++++++
 .../org/apache/wiki/auth/DefaultAuthenticationManager.java  |  9 ++-------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
index bd06cd6..b1a01a2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
@@ -19,6 +19,8 @@
 package org.apache.wiki.auth;
 
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.auth.authorize.Role;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
@@ -30,6 +32,7 @@ import javax.security.auth.spi.LoginModule;
 import javax.servlet.http.HttpServletRequest;
 import java.security.Principal;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 
@@ -65,6 +68,16 @@ public interface AuthenticationManager {
     String PROP_LOGIN_MODULE = "jspwiki.loginModule.class";
 
     /**
+     * Creates an AuthenticationManager instance for the given WikiEngine and
+     * the specified set of properties. All initialization for the modules is
+     * done here.
+     * @param engine the wiki engine
+     * @param props the properties used to initialize the wiki engine
+     * @throws WikiException if the AuthenticationManager cannot be initialized
+     */
+    void initialize( Engine engine, Properties props ) throws WikiException;
+
+    /**
      * Returns true if this WikiEngine uses container-managed authentication. This method is used primarily for cosmetic purposes in the
      * JSP tier, and performs no meaningful security function per se. Delegates to
      * {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer#isContainerAuthorized()},
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
index ee5e284..e4566b9 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
@@ -103,14 +103,9 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
     private TimedCounterList< String > m_lastLoginAttempts = new TimedCounterList<>();
 
     /**
-     * Creates an AuthenticationManager instance for the given WikiEngine and
-     * the specified set of properties. All initialization for the modules is
-     * done here.
-     * @param engine the wiki engine
-     * @param props the properties used to initialize the wiki engine
-     * @throws WikiException if the AuthenticationManager cannot be initialized
+     * {@inheritDoc}
      */
-    @SuppressWarnings( "unchecked" )
+    @Override
     public void initialize( final Engine engine, final Properties props ) throws WikiException {
         m_engine = engine;
         m_storeIPAddress = TextUtil.getBooleanProperty( props, PROP_STOREIPADDRESS, m_storeIPAddress );


[jspwiki] 13/38: class javadocs

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit ae43c07cd86475de3202ccd12b973dd8f2792b60
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:58:24 2020 +0100

    class javadocs
---
 jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java    | 11 ++++-------
 .../src/main/java/org/apache/wiki/api/core/Engine.java        | 10 ++++++++++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
index 1afc4b1..8b4aca4 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiEngine.java
@@ -80,17 +80,14 @@ import java.util.concurrent.ConcurrentHashMap;
 
 
 /**
- *  Provides Wiki services to the JSP page.
+ *  Main implementation for {@link Engine}.
  *
  *  <P>
- *  This is the main interface through which everything should go.
- *
- *  <P>
- *  Using this class:  Always get yourself an instance from JSP page by using the WikiEngine.getInstance() method.  Never create a new
- *  WikiEngine() from scratch, unless you're writing tests.
+ *  Using this class:  Always get yourself an instance from JSP page by using the {@code WikiEngine.getInstance(..)} method.  Never create
+ *  a new WikiEngine() from scratch, unless you're writing tests.
  *
  *  <p>
- *  There's basically only a single WikiEngine for each web application, and you should always get it using the WikiEngine.getInstance() method.
+ *  {@inheritDoc}
  */
 public class WikiEngine implements Engine {
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index bab095c..d51cb0d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -37,6 +37,16 @@ import java.util.Date;
 import java.util.Properties;
 
 
+/**
+ *  Provides Wiki services to the JSP page.
+ *
+ *  <P>
+ *  This is the main interface through which everything should go.
+ *
+ *  <p>
+ *  There's basically only a single Engine for each web application, and you should always get it using the {@code WikiEngine.getInstance(..)}
+ *  method.
+ */
 public interface Engine {
 
     /** The default inlining pattern.  Currently "*.png" */


[jspwiki] 04/38: apply format and fixes suggested by intellij

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit ae99ac7d3ed0aa4c1e2291c3697dd1a658c2f60b
Author: juanpablo <ju...@apache.org>
AuthorDate: Wed Feb 19 20:37:24 2020 +0100

    apply format and fixes suggested by intellij
---
 .../main/java/org/apache/wiki/util/ClassUtil.java  | 197 ++++++++-------------
 1 file changed, 77 insertions(+), 120 deletions(-)

diff --git a/jspwiki-util/src/main/java/org/apache/wiki/util/ClassUtil.java b/jspwiki-util/src/main/java/org/apache/wiki/util/ClassUtil.java
index 48cd1d6..bf51959 100644
--- a/jspwiki-util/src/main/java/org/apache/wiki/util/ClassUtil.java
+++ b/jspwiki-util/src/main/java/org/apache/wiki/util/ClassUtil.java
@@ -48,37 +48,32 @@ import java.util.jar.JarFile;
 public final class ClassUtil {
 
     private static final Logger log = Logger.getLogger(ClassUtil.class);
-    /**
-     *  The location of the classmappings.xml document. It will be searched for
-     *  in the classpath.  It's value is "{@value}".
-     */
+
+    /** The location of the classmappings.xml document. It will be searched for in the classpath.  It's value is "{@value}". */
     public  static final String MAPPINGS = "ini/classmappings.xml";
-    
-    private static Map<String, String> c_classMappings = new ConcurrentHashMap<>();
+
+    private static Map< String, String > c_classMappings = new ConcurrentHashMap<>();
 
     private static boolean classLoaderSetup = false;
     private static ClassLoader loader = null;
 
 
-    /**
+    /*
      *  Initialize the class mappings document.
      */
     static {
-        List< Element > nodes = XmlUtil.parse( MAPPINGS, "/classmappings/mapping" );
+        final List< Element > nodes = XmlUtil.parse( MAPPINGS, "/classmappings/mapping" );
 
         if( nodes.size() > 0 ) {
-            for( Iterator< Element > i = nodes.iterator(); i.hasNext(); ) {
-                Element f = i.next();
-            
-                String key = f.getChildText("requestedClass");
-                String className = f.getChildText("mappedClass");
-                
+            for( final Element f : nodes ) {
+                final String key = f.getChildText( "requestedClass" );
+                final String className = f.getChildText( "mappedClass" );
+
                 c_classMappings.put( key, className );
-                
-                log.debug("Mapped class '"+key+"' to class '"+className+"'");
+                log.debug( "Mapped class '" + key + "' to class '" + className + "'" );
             }
         } else {
-            log.info("Didn't find class mapping document in "+MAPPINGS);
+            log.info( "Didn't find class mapping document in " + MAPPINGS );
         }
     }
 
@@ -97,22 +92,20 @@ public final class ClassUtil {
      * @param packages A List of Strings, containing different package names.
      *  @param className The name of the class to find.
      * @return The class, if it was found.
-     *  @throws ClassNotFoundException if this particular class cannot be found
-     *          from the list.
+     *  @throws ClassNotFoundException if this particular class cannot be found from the list.
      */
-    public static Class<?> findClass( List< String > packages,  List< String > externaljars, String className ) throws ClassNotFoundException {
+    public static Class<?> findClass( final List< String > packages,  final List< String > externaljars, final String className ) throws ClassNotFoundException {
         if (!classLoaderSetup) {
             loader = setupClassLoader(externaljars);
         }
 
         try {
             return loader.loadClass( className );
-        } catch( ClassNotFoundException e ) {
-            for( Iterator< String > i = packages.iterator(); i.hasNext(); ) {
-                String packageName = i.next();
+        } catch( final ClassNotFoundException e ) {
+            for( final String packageName : packages ) {
                 try {
                     return loader.loadClass( packageName + "." + className );
-                } catch( ClassNotFoundException ex ) {
+                } catch( final ClassNotFoundException ex ) {
                     // This is okay, we go to the next package.
                 }
             }
@@ -128,23 +121,23 @@ public final class ClassUtil {
      * @param externaljars external jars to load into the classloader.
      * @return the classloader that can load classes from the configured external jars or, if not specified, the classloader that loaded this class.
      */
-    private static ClassLoader setupClassLoader(List<String> externaljars) {
+    private static ClassLoader setupClassLoader( final List< String > externaljars) {
         classLoaderSetup = true;
-        log.info("setting up classloaders for external (plugin) jars");
-        if (externaljars.size() == 0) {
-            log.info("no external jars configured, using standard classloading");
+        log.info( "setting up classloaders for external (plugin) jars" );
+        if( externaljars.size() == 0 ) {
+            log.info( "no external jars configured, using standard classloading" );
             return ClassUtil.class.getClassLoader();
         }
-        URL[] urls = new URL[externaljars.size()];
+        final URL[] urls = new URL[externaljars.size()];
         int i = 0;
-        for( String externaljar : externaljars ) {
+        for( final String externaljar : externaljars ) {
             try {
-                File jarFile = new File( externaljar );
-                URL ucl = jarFile.toURI().toURL();
-                urls[i++] = ucl;
-                log.info("added " + ucl + " to list of external jars");
-            } catch (MalformedURLException e) {
-                log.error("exception (" + e.getMessage() +") while setting up classloaders for external jar:" + externaljar + ", continuing without external jars.");
+                final File jarFile = new File( externaljar );
+                final URL ucl = jarFile.toURI().toURL();
+                urls[ i++ ] = ucl;
+                log.info( "added " + ucl + " to list of external jars" );
+            } catch( final MalformedURLException e ) {
+                log.error( "exception (" + e.getMessage() + ") while setting up classloaders for external jar:" + externaljar + ", continuing without external jars." );
             }
         }
         
@@ -159,20 +152,18 @@ public final class ClassUtil {
 
     /**
      *
-     *  It will first attempt to instantiate the class directly from the className,
-     *  and will then try to prefix it with the packageName.
+     *  It will first attempt to instantiate the class directly from the className, and will then try to prefix it with the packageName.
      *
      *  @param packageName A package name (such as "org.apache.wiki.plugins").
      *  @param className The class name to find.
      *  @return The class, if it was found.
      *  @throws ClassNotFoundException if this particular class cannot be found.
      */
-
-    public static Class<?> findClass(String packageName, String className) throws ClassNotFoundException {
+    public static Class< ? > findClass( final String packageName, final String className ) throws ClassNotFoundException {
         try {
-            return ClassUtil.class.getClassLoader().loadClass(className);
-        } catch (ClassNotFoundException e) {
-            return ClassUtil.class.getClassLoader().loadClass(packageName + "." + className);
+            return ClassUtil.class.getClassLoader().loadClass( className );
+        } catch( final ClassNotFoundException e ) {
+            return ClassUtil.class.getClassLoader().loadClass( packageName + "." + className );
         }
     }
     
@@ -182,38 +173,27 @@ public final class ClassUtil {
      * @param rootPackage the base package. Can be {code null}.
      * @return all files entries in classpath under the given package
      */
-    public static List< String > classpathEntriesUnder( final String rootPackage ) 
-    {
-        List< String > results = new ArrayList< >();
+    public static List< String > classpathEntriesUnder( final String rootPackage ) {
+        final List< String > results = new ArrayList<>();
         Enumeration< URL > en = null;
         if( StringUtils.isNotEmpty( rootPackage ) ) {
-            try
-            {
+            try {
                 en = ClassUtil.class.getClassLoader().getResources( rootPackage );
-            }
-            catch( IOException e )
-            {
+            } catch( final IOException e ) {
                 log.error( e.getMessage(), e );
             }
         }
         
-        while( en != null && en.hasMoreElements() )
-        {
-            URL url = en.nextElement();
-            try
-            {
-                if( "jar".equals( url.getProtocol() ) ) 
-                {
+        while( en != null && en.hasMoreElements() ) {
+            final URL url = en.nextElement();
+            try {
+                if( "jar".equals( url.getProtocol() ) ) {
                     jarEntriesUnder( results, ( JarURLConnection )url.openConnection(), rootPackage );
-                } 
-                else if( "file".equals( url.getProtocol() ) ) 
-                {
+                } else if( "file".equals( url.getProtocol() ) ) {
                     fileEntriesUnder( results, new File( url.getFile() ), rootPackage );
                 }
                 
-            }
-            catch (IOException ioe)
-            {
+            } catch( final IOException ioe ) {
                 log.error( ioe.getMessage(), ioe );
             }
         }
@@ -229,16 +209,14 @@ public final class ClassUtil {
      * @param file given {@link File} to search in.
      * @param rootPackage base package.
      */
-    static void fileEntriesUnder( List< String > results, File file, String rootPackage ) 
-    {
-        log.debug( "scanning [" + file.getName() +"]" );
+    static void fileEntriesUnder( final List< String > results, final File file, final String rootPackage ) {
+        log.debug( "scanning [" + file.getName() + "]" );
         if( file.isDirectory() ) {
-            Iterator< File > files = FileUtils.iterateFiles( file, null, true );
-            while( files.hasNext() ) 
-            {
-                File subfile = files.next();
+            final Iterator< File > files = FileUtils.iterateFiles( file, null, true );
+            while( files.hasNext() ) {
+                final File subfile = files.next();
                 // store an entry similar to the jarSearch(..) below ones
-                String entry = StringUtils.replace( subfile.getAbsolutePath(), file.getAbsolutePath() + File.separatorChar, StringUtils.EMPTY );
+                final String entry = StringUtils.replace( subfile.getAbsolutePath(), file.getAbsolutePath() + File.separatorChar, StringUtils.EMPTY );
                 results.add( rootPackage + "/" + entry );
             }
         } else {
@@ -253,17 +231,17 @@ public final class ClassUtil {
      * @param jurlcon given {@link JarURLConnection} to search in.
      * @param rootPackage base package.
      */
-    static void jarEntriesUnder( List< String > results, JarURLConnection jurlcon, String rootPackage ) {
-        try( JarFile jar = jurlcon.getJarFile() ) {
+    static void jarEntriesUnder( final List< String > results, final JarURLConnection jurlcon, final String rootPackage ) {
+        try( final JarFile jar = jurlcon.getJarFile() ) {
             log.debug( "scanning [" + jar.getName() +"]" );
-            Enumeration< JarEntry > entries = jar.entries();
+            final Enumeration< JarEntry > entries = jar.entries();
             while( entries.hasMoreElements() ) {
-                JarEntry entry = entries.nextElement();
+                final JarEntry entry = entries.nextElement();
                 if( entry.getName().startsWith( rootPackage ) && !entry.isDirectory() ) {
                     results.add( entry.getName() );
                 }
             }
-        } catch( IOException ioe ) {
+        } catch( final IOException ioe ) {
             log.error( ioe.getMessage(), ioe );
         }
     }
@@ -285,10 +263,8 @@ public final class ClassUtil {
      *  @since 2.5.40
      */
     @SuppressWarnings("unchecked")
-    public static < T > T getMappedObject( String requestedClass )
-        throws ReflectiveOperationException, IllegalArgumentException
-    {
-        Object[] initargs = {};
+    public static < T > T getMappedObject( final String requestedClass ) throws ReflectiveOperationException, IllegalArgumentException {
+        final Object[] initargs = {};
         return ( T )getMappedObject(requestedClass, initargs );
     }
 
@@ -313,60 +289,41 @@ public final class ClassUtil {
      *  @since 2.5.40
      */
     @SuppressWarnings( "unchecked" )
-    public static < T > T getMappedObject( String requestedClass, Object... initargs )
-        throws ReflectiveOperationException, IllegalArgumentException
-    {
-        Class<?> cl = getMappedClass( requestedClass );
-        Constructor<?>[] ctors = cl.getConstructors();
+    public static < T > T getMappedObject( final String requestedClass, final Object... initargs ) throws ReflectiveOperationException, IllegalArgumentException {
+        final Class< ? > cl = getMappedClass( requestedClass );
+        final Constructor< ? >[] ctors = cl.getConstructors();
         
-        //
-        //  Try to find the proper constructor by comparing the
-        //  initargs array classes and the constructor types.
-        //
-        for( int c = 0; c < ctors.length; c++ )
-        {
-            Class<?>[] params = ctors[c].getParameterTypes();
-            
-            if( params.length == initargs.length )
-            {
-                for( int arg = 0; arg < initargs.length; arg++ )
-                {
-                    if( params[arg].isAssignableFrom(initargs[arg].getClass()))
-                    {
-                        //
+        //  Try to find the proper constructor by comparing the initargs array classes and the constructor types.
+        for( final Constructor< ? > ctor : ctors ) {
+            final Class< ? >[] params = ctor.getParameterTypes();
+            if( params.length == initargs.length ) {
+                for( int arg = 0; arg < initargs.length; arg++ ) {
+                    if( params[ arg ].isAssignableFrom( initargs[ arg ].getClass() ) ) {
                         //  Ha, found it!  Instantiating and returning...
-                        //
-                        return ( T )ctors[c].newInstance(initargs);
+                        return ( T )ctor.newInstance( initargs );
                     }
                 }
             }
         }
         
-        //
         //  No arguments, so we can just call a default constructor and ignore the arguments.
-        //
         return ( T )cl.getDeclaredConstructor().newInstance();
     }
 
     /**
-     *  Finds a mapped class from the c_classMappings list.  If there is no
-     *  mappped class, will use the requestedClass.
+     *  Finds a mapped class from the c_classMappings list.  If there is no mappped class, will use the requestedClass.
      *  
-     *  @param requestedClass
+     *  @param requestedClass requested class.
      *  @return A Class object which you can then instantiate.
-     *  @throws ClassNotFoundException
+     *  @throws ClassNotFoundException if the class is not found.
      */
-    public static Class< ? > getMappedClass( String requestedClass ) throws ClassNotFoundException {
+    public static Class< ? > getMappedClass( final String requestedClass ) throws ClassNotFoundException {
         String mappedClass = c_classMappings.get( requestedClass );
-        
-        if( mappedClass == null )
-        {
+        if( mappedClass == null ) {
             mappedClass = requestedClass;
         }
         
-        Class< ? > cl = Class.forName(mappedClass);
-        
-        return cl;
+        return Class.forName( mappedClass );
     }
     
     /**
@@ -376,12 +333,12 @@ public final class ClassUtil {
      * @param parentClassName expected parent class.
      * @return {@code true} if {@code srcClassName} is a subclass of {@code parentClassname}, {@code false} otherwise.
      */
-    public static boolean assignable( String srcClassName, String parentClassName ) {
+    public static boolean assignable( final String srcClassName, final String parentClassName ) {
         try {
-            Class< ? > src = Class.forName( srcClassName );
-            Class< ? > parent = Class.forName( parentClassName );
+            final Class< ? > src = Class.forName( srcClassName );
+            final Class< ? > parent = Class.forName( parentClassName );
             return parent.isAssignableFrom( src );
-        } catch( Exception e ) {
+        } catch( final Exception e ) {
             log.error( e.getMessage(), e );
         }
         return false;


[jspwiki] 30/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (7)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 8d2e5ee0ac09c1a9d04f842ac4ada734acd754c6
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:15:34 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (7)
---
 .../apache/wiki/parser/JSPWikiMarkupParser.java    | 259 +++++++++++----------
 .../apache/wiki/parser/LinkParsingOperations.java  |   5 +-
 .../java/org/apache/wiki/parser/MarkupParser.java  |   4 +-
 .../java/org/apache/wiki/parser/PluginContent.java |  15 +-
 .../org/apache/wiki/parser/VariableContent.java    |   9 +-
 .../org/apache/wiki/preferences/Preferences.java   |  70 +++---
 .../wiki/references/DefaultReferenceManager.java   |  39 ++--
 .../wiki/render/DefaultRenderingManager.java       |   6 +-
 8 files changed, 205 insertions(+), 202 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
index 178e468..23eee96 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
@@ -34,12 +34,17 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.attachment.AttachmentManager;
+import org.apache.wiki.auth.AuthorizationManager;
+import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.WikiSecurityException;
 import org.apache.wiki.auth.acl.Acl;
+import org.apache.wiki.auth.acl.AclManager;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.util.TextUtil;
 import org.apache.wiki.util.XmlUtil;
+import org.apache.wiki.variables.VariableManager;
 import org.jdom2.Attribute;
 import org.jdom2.Content;
 import org.jdom2.Element;
@@ -165,7 +170,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  @param context The WikiContext which controls the parsing
      *  @param in Where the data is read from.
      */
-    public JSPWikiMarkupParser( WikiContext context, Reader in )
+    public JSPWikiMarkupParser( final WikiContext context, final Reader in )
     {
         super( context, in );
         initialize();
@@ -207,7 +212,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         m_allowHTML          = m_context.getBooleanWikiProperty( PROP_ALLOWHTML, m_allowHTML );
         m_useRelNofollow     = m_context.getBooleanWikiProperty( PROP_USERELNOFOLLOW, m_useRelNofollow );
 
-        if( m_engine.getUserManager().getUserDatabase() == null || m_engine.getAuthorizationManager() == null ) {
+        if( m_engine.getManager( UserManager.class ).getUserDatabase() == null || m_engine.getManager( AuthorizationManager.class ) == null ) {
             disableAccessRules();
         }
 
@@ -238,13 +243,13 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *
      * @param param A Heading object.
      */
-    protected void callHeadingListenerChain( Heading param )
+    protected void callHeadingListenerChain( final Heading param )
     {
-        List< HeadingListener > list = m_headingListenerChain;
+        final List< HeadingListener > list = m_headingListenerChain;
 
-        for( Iterator< HeadingListener > i = list.iterator(); i.hasNext(); )
+        for( final Iterator< HeadingListener > i = list.iterator(); i.hasNext(); )
         {
-            HeadingListener h = i.next();
+            final HeadingListener h = i.next();
 
             h.headingAdded( m_context, param );
         }
@@ -261,18 +266,18 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  @return An A element.
      *  @since 2.4.78
      */
-    protected Element createAnchor(int type, String link, String text, String section)
+    protected Element createAnchor( final int type, final String link, String text, String section)
     {
         text = escapeHTMLEntities( text );
         section = escapeHTMLEntities( section );
-        Element el = new Element("a");
+        final Element el = new Element("a");
         el.setAttribute("class",CLASS_TYPES[type]);
         el.setAttribute("href",link+section);
         el.addContent(text);
         return el;
     }
 
-    private Element makeLink( int type, String link, String text, String section, Iterator< Attribute > attributes )
+    private Element makeLink( int type, final String link, String text, String section, final Iterator< Attribute > attributes )
     {
         Element el = null;
 
@@ -289,7 +294,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         {
             type = EMPTY;
         }
-        ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
+        final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
 
         switch(type)
         {
@@ -344,7 +349,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 break;
 
             case IMAGEWIKILINK:
-                String pagelink = m_context.getURL(WikiContext.VIEW,text);
+                final String pagelink = m_context.getURL(WikiContext.VIEW,text);
                 el = new Element("img").setAttribute("class","inline");
                 el.setAttribute("src",link);
                 el.setAttribute("alt",text);
@@ -361,18 +366,18 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 break;
 
             case ATTACHMENT:
-                String attlink = m_context.getURL( WikiContext.ATTACH,
+                final String attlink = m_context.getURL( WikiContext.ATTACH,
                                                    link );
 
-                String infolink = m_context.getURL( WikiContext.INFO,
+                final String infolink = m_context.getURL( WikiContext.INFO,
                                                     link );
 
-                String imglink = m_context.getURL( WikiContext.NONE,
+                final String imglink = m_context.getURL( WikiContext.NONE,
                                                    "images/attachment_small.png" );
 
                 el = createAnchor( ATTACHMENT, attlink, text, "" );
 
-                if(  m_engine.getAttachmentManager().forceDownload( attlink ) )
+                if(  m_engine.getManager( AttachmentManager.class ).forceDownload( attlink ) )
                 {
                     el.setAttribute("download", "");
                 }
@@ -403,7 +408,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         {
             while( attributes.hasNext() )
             {
-                Attribute attr = attributes.next();
+                final Attribute attr = attributes.next();
                 if( attr != null )
                 {
                     el.setAttribute(attr);
@@ -428,7 +433,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         "hr", "noscript", "ol", "p", "pre", "table", "ul"
     };
 
-    private static boolean isBlockLevel( String name )
+    private static boolean isBlockLevel( final String name )
     {
         return Arrays.binarySearch( BLOCK_ELEMENTS, name ) >= 0;
     }
@@ -444,7 +449,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private String peekAheadLine()
         throws IOException
     {
-        String s = readUntilEOL().toString();
+        final String s = readUntilEOL().toString();
 
         if( s.length() > PUSHBACK_BUFFER_SIZE )
         {
@@ -457,7 +462,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
             {
                 pushBack( s );
             }
-            catch( IOException e )
+            catch( final IOException e )
             {
                 log.warn("Pushback failed: the line is probably too long.  Attempting to recover.");
             }
@@ -467,7 +472,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
     private int flushPlainText()
     {
-        int numChars = m_plainTextBuf.length();
+        final int numChars = m_plainTextBuf.length();
 
         if( numChars > 0 )
         {
@@ -503,15 +508,15 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
                     while( m_camelCaseMatcher.contains( buf, m_camelCasePattern ) )
                     {
-                        MatchResult result = m_camelCaseMatcher.getMatch();
+                        final MatchResult result = m_camelCaseMatcher.getMatch();
 
-                        String firstPart = buf.substring(0,result.beginOffset(0));
+                        final String firstPart = buf.substring(0,result.beginOffset(0));
                         String prefix = result.group(1);
 
                         if( prefix == null ) prefix = "";
 
-                        String camelCase = result.group(2);
-                        String protocol  = result.group(3);
+                        final String camelCase = result.group(2);
+                        final String protocol  = result.group(3);
                         String uri       = protocol+result.group(4);
                         buf              = buf.substring(result.endOffset(0));
 
@@ -547,7 +552,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                         //
                         if( protocol != null )
                         {
-                            char c = uri.charAt(uri.length()-1);
+                            final char c = uri.charAt(uri.length()-1);
                             if( c == '.' || c == ',' )
                             {
                                 uri = uri.substring(0,uri.length()-1);
@@ -578,7 +583,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                     m_currentElement.addContent( buf );
                 }
             }
-            catch( IllegalDataException e )
+            catch( final IllegalDataException e )
             {
                 //
                 // Sometimes it's possible that illegal XML chars is added to the data.
@@ -598,13 +603,13 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  @param buf
      *  @return An escaped string.
      */
-    private String escapeHTMLEntities(String buf)
+    private String escapeHTMLEntities( final String buf)
     {
-        StringBuilder tmpBuf = new StringBuilder( buf.length() + 20 );
+        final StringBuilder tmpBuf = new StringBuilder( buf.length() + 20 );
 
         for( int i = 0; i < buf.length(); i++ )
         {
-            char ch = buf.charAt(i);
+            final char ch = buf.charAt(i);
 
             if( ch == '<' )
             {
@@ -626,13 +631,13 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 //
 
                 boolean isEntity = false;
-                StringBuilder entityBuf = new StringBuilder();
+                final StringBuilder entityBuf = new StringBuilder();
 
                 if( i < buf.length() -1 )
                 {
                     for( int j = i; j < buf.length(); j++ )
                     {
-                        char ch2 = buf.charAt(j);
+                        final char ch2 = buf.charAt(j);
 
                         if( Character.isLetterOrDigit( ch2 ) || (ch2 == '#' && j == i+1) || ch2 == ';' || ch2 == '&' )
                         {
@@ -671,7 +676,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return tmpBuf.toString();
     }
 
-    private Element pushElement( Element e )
+    private Element pushElement( final Element e )
     {
         flushPlainText();
         m_currentElement.addContent( e );
@@ -680,7 +685,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return e;
     }
 
-    private Element addElement( Content e )
+    private Element addElement( final Content e )
     {
         if( e != null )
         {
@@ -705,9 +710,9 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  @param s
      *  @return The new current element, or null, if there was no such element in the entire stack.
      */
-    private Element popElement( String s )
+    private Element popElement( final String s )
     {
-        int flushedBytes = flushPlainText();
+        final int flushedBytes = flushPlainText();
 
         Element currEl = m_currentElement;
 
@@ -744,10 +749,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  ending characters, or stream end.  The ending character will be left
      *  in the stream.
      */
-    private String readUntil( String endChars )
+    private String readUntil( final String endChars )
         throws IOException
     {
-        StringBuilder sb = new StringBuilder( 80 );
+        final StringBuilder sb = new StringBuilder( 80 );
         int ch = nextToken();
 
         while( ch != -1 )
@@ -779,10 +784,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  Reads the stream while the characters that have been specified are
      *  in the stream, returning then the result as a String.
      */
-    private String readWhile( String endChars )
+    private String readWhile( final String endChars )
         throws IOException
     {
-        StringBuilder sb = new StringBuilder( 80 );
+        final StringBuilder sb = new StringBuilder( 80 );
         int ch = nextToken();
 
         while( ch != -1 )
@@ -897,9 +902,9 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *  a proper HTML link for it.  The local link mutator
      *  chain is also called.
      */
-    private Element makeCamelCaseLink( String wikiname )
+    private Element makeCamelCaseLink( final String wikiname )
     {
-        String matchedLink = m_linkParsingOperations.linkIfExists( wikiname );
+        final String matchedLink = m_linkParsingOperations.linkIfExists( wikiname );
 
         callMutatorChain( m_localLinkMutatorChain, wikiname );
 
@@ -955,7 +960,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      */
     private Element makeDirectURILink( String url )
     {
-        Element result;
+        final Element result;
         String last = null;
 
         if( url.endsWith(",") || url.endsWith(".") )
@@ -999,9 +1004,9 @@ public class JSPWikiMarkupParser extends MarkupParser {
      */
 
     // FIXME: isExternalLink() is called twice.
-    private Element handleImageLink( String reallink, String link, boolean hasLinkText )
+    private Element handleImageLink( final String reallink, final String link, final boolean hasLinkText )
     {
-        String possiblePage = MarkupParser.cleanLink( link );
+        final String possiblePage = MarkupParser.cleanLink( link );
 
         if( m_linkParsingOperations.isExternalLink( link ) && hasLinkText )
         {
@@ -1044,7 +1049,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         }
 
         try {
-            final Acl acl = m_engine.getAclManager().parseAcl( page, ruleLine );
+            final Acl acl = m_engine.getManager( AclManager.class ).parseAcl( page, ruleLine );
             page.setAcl( acl );
 
             if( log.isDebugEnabled() ) {
@@ -1080,7 +1085,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
             // log.debug("SET name='"+name+"', value='"+val+"'.");
 
             if( name.length() > 0 && val.length() > 0 ) {
-                val = m_engine.getVariableManager().expandVariables( m_context, val );
+                val = m_engine.getManager( VariableManager.class ).expandVariables( m_context, val );
                 m_context.getPage().setAttribute( name, val );
             }
         } catch( final Exception e ) {
@@ -1104,19 +1109,15 @@ public class JSPWikiMarkupParser extends MarkupParser {
     /**
      *  Gobbles up all hyperlinks that are encased in square brackets.
      */
-    private Element handleHyperlinks( String linktext, int pos )
-    {
-        ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
-
-        StringBuilder sb = new StringBuilder(linktext.length()+80);
+    private Element handleHyperlinks( String linktext, final int pos ) {
+        final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
+        final StringBuilder sb = new StringBuilder(linktext.length()+80);
 
-        if( m_linkParsingOperations.isAccessRule( linktext ) )
-        {
+        if( m_linkParsingOperations.isAccessRule( linktext ) ) {
             return handleAccessRule( linktext );
         }
 
-        if( m_linkParsingOperations.isMetadata( linktext ) )
-        {
+        if( m_linkParsingOperations.isMetadata( linktext ) ) {
             return handleMetadata( linktext );
         }
 
@@ -1124,7 +1125,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         {
             try
             {
-                PluginContent pluginContent = PluginContent.parsePluginLine( m_context, linktext, pos );
+                final PluginContent pluginContent = PluginContent.parsePluginLine( m_context, linktext, pos );
                 //
                 //  This might sometimes fail, especially if there is something which looks
                 //  like a plugin invocation but is really not.
@@ -1136,13 +1137,13 @@ public class JSPWikiMarkupParser extends MarkupParser {
                     pluginContent.executeParse( m_context );
                 }
             }
-            catch( PluginException e )
+            catch( final PluginException e )
             {
                 log.info( m_context.getRealPage().getWiki() + " : " + m_context.getRealPage().getName() + " - Failed to insert plugin: " + e.getMessage() );
                 //log.info( "Root cause:",e.getRootThrowable() );
                 if( !m_wysiwygEditorMode )
                 {
-                    ResourceBundle rbPlugin = Preferences.getBundle( m_context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+                    final ResourceBundle rbPlugin = Preferences.getBundle( m_context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
                     return addElement( makeError( MessageFormat.format( rbPlugin.getString( "plugin.error.insertionfailed" ),
                     		                                            m_context.getRealPage().getWiki(),
                     		                                            m_context.getRealPage().getName(),
@@ -1155,7 +1156,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
         try
         {
-            LinkParser.Link link = m_linkParser.parse(linktext);
+            final LinkParser.Link link = m_linkParser.parse(linktext);
             linktext       = link.getText();
             String linkref = link.getReference();
 
@@ -1168,7 +1169,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
             //
             if( m_linkParsingOperations.isVariableLink( linktext ) )
             {
-                Content el = new VariableContent(linktext);
+                final Content el = new VariableContent(linktext);
 
                 addElement( el );
             }
@@ -1201,8 +1202,8 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 //        is using, so you'll have to write the entire name as it appears
                 //        in the URL.  Bugger.
 
-                String extWiki  = link.getExternalWiki();
-                String wikiPage = link.getExternalWikiPage();
+                final String extWiki  = link.getExternalWiki();
+                final String wikiPage = link.getExternalWikiPage();
 
                 if( m_wysiwygEditorMode )
                 {
@@ -1233,7 +1234,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                     }
                     else
                     {
-                        Object[] args = { escapeHTMLEntities(extWiki) };
+                        final Object[] args = { escapeHTMLEntities(extWiki) };
 
                         addElement( makeError( MessageFormat.format( rb.getString( "markupparser.error.nointerwikiref" ), args ) ) );
                     }
@@ -1256,7 +1257,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 //
                 //  Internal wiki link, but is it an attachment link?
                 //
-                String attachment = m_engine.getAttachmentManager().getAttachmentInfoName( m_context, linkref );
+                String attachment = m_engine.getManager( AttachmentManager.class ).getAttachmentInfoName( m_context, linkref );
                 if( attachment != null )
                 {
                     callMutatorChain( m_attachmentLinkMutatorChain, attachment );
@@ -1275,14 +1276,14 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 {
                     // It's an internal Wiki link, but to a named section
 
-                    String namedSection = linkref.substring( hashMark+1 );
+                    final String namedSection = linkref.substring( hashMark+1 );
                     linkref = linkref.substring( 0, hashMark );
 
                     linkref = MarkupParser.cleanLink( linkref );
 
                     callMutatorChain( m_localLinkMutatorChain, linkref );
 
-                    String matchedLink = m_linkParsingOperations.linkIfExists( linkref );
+                    final String matchedLink = m_linkParsingOperations.linkIfExists( linkref );
                     if( matchedLink != null ) {
                         String sectref = "section-"+m_engine.encodeName(matchedLink+"-"+wikifyLink(namedSection));
                         sectref = sectref.replace('%', '_');
@@ -1298,7 +1299,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
                     callMutatorChain( m_localLinkMutatorChain, linkref );
 
-                    String matchedLink = m_linkParsingOperations.linkIfExists( linkref );
+                    final String matchedLink = m_linkParsingOperations.linkIfExists( linkref );
                     if( matchedLink != null ) {
                         makeLink( READ, matchedLink, linktext, null, link.getAttributes() );
                     } else {
@@ -1307,10 +1308,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 }
             }
         }
-        catch( ParseException e )
+        catch( final ParseException e )
         {
             log.info("Parser failure: ",e);
-            Object[] args = { e.getMessage() };
+            final Object[] args = { e.getMessage() };
             addElement( makeError( MessageFormat.format( rb.getString( "markupparser.error.parserfailure" ), args ) ) );
         }
 
@@ -1323,7 +1324,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *
      *  @since 2.1.77
      */
-    private void pushBack( String s )
+    private void pushBack( final String s )
         throws IOException
     {
         for( int i = s.length()-1; i >= 0; i-- )
@@ -1335,11 +1336,11 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleBackslash()
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
 
         if( ch == '\\' )
         {
-            int ch2 = nextToken();
+            final int ch2 = nextToken();
 
             if( ch2 == '\\' )
             {
@@ -1361,7 +1362,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleUnderscore()
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
         Element el = null;
 
         if( ch == '_' )
@@ -1391,7 +1392,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleApostrophe()
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
         Element el = null;
 
         if( ch == '\'' )
@@ -1414,14 +1415,14 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return el;
     }
 
-    private Element handleOpenbrace( boolean isBlock )
+    private Element handleOpenbrace( final boolean isBlock )
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
 
         if( ch == '{' )
         {
-            int ch2 = nextToken();
+            final int ch2 = nextToken();
 
             if( ch2 == '{' )
             {
@@ -1454,11 +1455,11 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleClosebrace()
         throws IOException
     {
-        int ch2 = nextToken();
+        final int ch2 = nextToken();
 
         if( ch2 == '}' )
         {
-            int ch3 = nextToken();
+            final int ch3 = nextToken();
 
             if( ch3 == '}' )
             {
@@ -1502,11 +1503,11 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
         if( ch == '-' )
         {
-            int ch2 = nextToken();
+            final int ch2 = nextToken();
 
             if( ch2 == '-' )
             {
-                int ch3 = nextToken();
+                final int ch3 = nextToken();
 
                 if( ch3 == '-' )
                 {
@@ -1539,31 +1540,31 @@ public class JSPWikiMarkupParser extends MarkupParser {
     {
         Element el = null;
 
-        int ch  = nextToken();
+        final int ch  = nextToken();
 
-        Heading hd = new Heading();
+        final Heading hd = new Heading();
 
         if( ch == '!' )
         {
-            int ch2 = nextToken();
+            final int ch2 = nextToken();
 
             if( ch2 == '!' )
             {
-                String title = peekAheadLine();
+                final String title = peekAheadLine();
 
                 el = makeHeading( Heading.HEADING_LARGE, title, hd);
             }
             else
             {
                 pushBack( ch2 );
-                String title = peekAheadLine();
+                final String title = peekAheadLine();
                 el = makeHeading( Heading.HEADING_MEDIUM, title, hd );
             }
         }
         else
         {
             pushBack( ch );
-            String title = peekAheadLine();
+            final String title = peekAheadLine();
             el = makeHeading( Heading.HEADING_SMALL, title, hd );
         }
 
@@ -1584,7 +1585,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         throws IOException
     {
         int ch;
-        StringBuilder buf = new StringBuilder( 256 );
+        final StringBuilder buf = new StringBuilder( 256 );
 
         while( true )
         {
@@ -1634,7 +1635,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         m_isbold   = false;
     }
 
-    private static String getListType( char c )
+    private static String getListType( final char c )
     {
         if( c == '*' )
         {
@@ -1660,7 +1661,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
          String strBullets = readWhile( "*#" );
          // String strBulletsRaw = strBullets;      // to know what was original before phpwiki style substitution
-         int numBullets = strBullets.length();
+         final int numBullets = strBullets.length();
 
          // override the beginning portion of bullet pattern to be like the previous
          // to simulate PHPWiki style lists
@@ -1733,7 +1734,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
              //  The pattern has changed, unwind and restart
              //
              int  numEqualBullets;
-             int  numCheckBullets;
+             final int  numCheckBullets;
 
              // find out how much is the same
              numEqualBullets = 0;
@@ -1817,8 +1818,8 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleOpenbracket()
         throws IOException
     {
-        StringBuilder sb = new StringBuilder(40);
-        int pos = getPosition();
+        final StringBuilder sb = new StringBuilder(40);
+        final int pos = getPosition();
         int ch = nextToken();
         boolean isPlugin = false;
 
@@ -1860,7 +1861,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
         while( ch != -1 )
         {
-            int ch2 = nextToken(); pushBack(ch2);
+            final int ch2 = nextToken(); pushBack(ch2);
 
             if( isPlugin )
             {
@@ -1911,10 +1912,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
     /**
      *  Reads the stream until the current brace is closed or stream end.
      */
-    private String readBraceContent( char opening, char closing )
+    private String readBraceContent( final char opening, final char closing )
         throws IOException
     {
-        StringBuilder sb = new StringBuilder(40);
+        final StringBuilder sb = new StringBuilder(40);
         int braceLevel = 1;
         int ch;
         while(( ch = nextToken() ) != -1 )
@@ -1947,7 +1948,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      * @return An Element containing the div or span, depending on the situation.
      * @throws IOException
      */
-    private Element handleDiv( boolean newLine )
+    private Element handleDiv( final boolean newLine )
         throws IOException
     {
         int ch = nextToken();
@@ -2010,7 +2011,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
                 try
                 {
-                    Boolean isSpan = m_styleStack.pop();
+                    final Boolean isSpan = m_styleStack.pop();
 
                     if( isSpan == null )
                     {
@@ -2025,7 +2026,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                         el = popElement( "div" );
                     }
                 }
-                catch( EmptyStackException e )
+                catch( final EmptyStackException e )
                 {
                     log.debug("Page '"+m_context.getName()+"' closes a %%-block that has not been opened.");
                     return m_currentElement;
@@ -2044,24 +2045,24 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 if( style != null && style.indexOf("javascript:") != -1 )
                 {
                     log.debug("Attempt to output javascript within CSS:"+style);
-                    ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
+                    final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
                     return addElement( makeError( rb.getString( "markupparser.error.javascriptattempt" ) ) );
                 }
             }
-            catch( NumberFormatException e )
+            catch( final NumberFormatException e )
             {
                 //
                 //  If there are unknown entities, we don't want the parser to stop.
                 //
-                ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
-                String msg = MessageFormat.format( rb.getString( "markupparser.error.parserfailure"), e.getMessage() );
+                final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
+                final String msg = MessageFormat.format( rb.getString( "markupparser.error.parserfailure"), e.getMessage() );
                 return addElement( makeError( msg ) );
             }
 
             //
             //  Decide if we should open a div or a span?
             //
-            String eol = peekAheadLine();
+            final String eol = peekAheadLine();
 
             if( eol.trim().length() > 0 )
             {
@@ -2090,10 +2091,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return el;
     }
 
-    private Element handleSlash( boolean newLine )
+    private Element handleSlash( final boolean newLine )
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
 
         pushBack(ch);
         if( ch == '%' && !m_styleStack.isEmpty() )
@@ -2104,7 +2105,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return null;
     }
 
-    private Element handleBar( boolean newLine )
+    private Element handleBar( final boolean newLine )
         throws IOException
     {
         Element el = null;
@@ -2130,7 +2131,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
             }
 
             m_rowNum++;
-            Element tr = ( m_rowNum % 2 != 0 )
+            final Element tr = ( m_rowNum % 2 != 0 )
                        ? new Element("tr").setAttribute("class", "odd")
                        : new Element("tr");
             el = pushElement( tr );
@@ -2140,7 +2141,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         //  Check out which table cell element to start;
         //  a header element (th) or a regular element (td).
         //
-        int ch = nextToken();
+        final int ch = nextToken();
 
         if( ch == '|' )
         {
@@ -2173,7 +2174,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
     private Element handleTilde()
         throws IOException
     {
-        int ch = nextToken();
+        final int ch = nextToken();
 
         if( ch == ' ' )
         {
@@ -2204,7 +2205,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
         return null;
     }
 
-    private void fillBuffer( Element startElement )
+    private void fillBuffer( final Element startElement )
         throws IOException
     {
         m_currentElement = startElement;
@@ -2215,7 +2216,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
         while(!quitReading)
         {
-            int ch = nextToken();
+            final int ch = nextToken();
 
             if( ch == -1 ) break;
 
@@ -2299,7 +2300,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
             {
                 skip = parseToken( ch );
             }
-            catch( IllegalDataException e )
+            catch( final IllegalDataException e )
             {
                 log.info("Page "+m_context.getPage().getName()+" contains data which cannot be added to DOM tree: "+e.getMessage());
 
@@ -2337,13 +2338,13 @@ public class JSPWikiMarkupParser extends MarkupParser {
         popElement("domroot");
     }
 
-    private String cleanupSuspectData( String s )
+    private String cleanupSuspectData( final String s )
     {
-        StringBuilder sb = new StringBuilder( s.length() );
+        final StringBuilder sb = new StringBuilder( s.length() );
 
         for( int i = 0; i < s.length(); i++ )
         {
-            char c = s.charAt(i);
+            final char c = s.charAt(i);
 
             if( Verifier.isXMLCharacter( c ) ) sb.append( c );
             else sb.append( "0x"+Integer.toString(c,16).toUpperCase() );
@@ -2375,7 +2376,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      * @return {@link #ELEMENT}, {@link #CHARACTER} or {@link #IGNORE}.
      * @throws IOException If parsing fails.
      */
-    protected int parseToken( int ch )
+    protected int parseToken( final int ch )
         throws IOException
     {
         Element el = null;
@@ -2415,7 +2416,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
                 //  Figure out which elements cannot be enclosed inside
                 //  a <p></p> pair according to XHTML rules.
                 //
-                String nextLine = peekAheadLine();
+                final String nextLine = peekAheadLine();
                 if( nextLine.length() == 0 ||
                     (nextLine.length() > 0 &&
                      !nextLine.startsWith("{{{") &&
@@ -2564,10 +2565,10 @@ public class JSPWikiMarkupParser extends MarkupParser {
     public WikiDocument parse()
         throws IOException
     {
-        WikiDocument d = new WikiDocument( m_context.getPage() );
+        final WikiDocument d = new WikiDocument( m_context.getPage() );
         d.setContext( m_context );
 
-        Element rootElement = new Element("domroot");
+        final Element rootElement = new Element("domroot");
 
         d.setRootElement( rootElement );
 
@@ -2583,25 +2584,25 @@ public class JSPWikiMarkupParser extends MarkupParser {
      *
      *  @param rootElement
      */
-    private void paragraphify(Element rootElement)
+    private void paragraphify( final Element rootElement)
     {
         //
         //  Add the paragraph tag to the first paragraph
         //
-        List< Content > kids = rootElement.getContent();
+        final List< Content > kids = rootElement.getContent();
 
         if( rootElement.getChild("p") != null )
         {
-            ArrayList<Content> ls = new ArrayList<>();
+            final ArrayList<Content> ls = new ArrayList<>();
             int idxOfFirstContent = 0;
             int count = 0;
 
-            for( Iterator< Content > i = kids.iterator(); i.hasNext(); count++ )
+            for( final Iterator< Content > i = kids.iterator(); i.hasNext(); count++ )
             {
-                Content c = i.next();
+                final Content c = i.next();
                 if( c instanceof Element )
                 {
-                    String name = ( ( Element )c ).getName();
+                    final String name = ( ( Element )c ).getName();
                     if( isBlockLevel( name ) ) break;
                 }
 
@@ -2618,11 +2619,11 @@ public class JSPWikiMarkupParser extends MarkupParser {
             //
             if( ls.size() > 0 )
             {
-                Element newel = new Element("p");
+                final Element newel = new Element("p");
 
-                for( Iterator< Content > i = ls.iterator(); i.hasNext(); )
+                for( final Iterator< Content > i = ls.iterator(); i.hasNext(); )
                 {
-                    Content c = i.next();
+                    final Content c = i.next();
 
                     c.detach();
                     newel.addContent(c);
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/LinkParsingOperations.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/LinkParsingOperations.java
index 58fd889..63cb21c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/LinkParsingOperations.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/LinkParsingOperations.java
@@ -23,6 +23,7 @@ import org.apache.oro.text.regex.Pattern;
 import org.apache.oro.text.regex.Perl5Matcher;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.render.RenderingManager;
 
 import java.util.Arrays;
 import java.util.Comparator;
@@ -152,9 +153,9 @@ public class LinkParsingOperations {
      *  determine whether it should be treated as an inline image or not.
      */
     public boolean isImageLink( String link ) {
-        if( wikiContext.getEngine().getRenderingManager().getParser( wikiContext, link ).isImageInlining() ) {
+        if( wikiContext.getEngine().getManager( RenderingManager.class ).getParser( wikiContext, link ).isImageInlining() ) {
             link = link.toLowerCase();
-            final List< Pattern > inlineImagePatterns = wikiContext.getEngine().getRenderingManager()
+            final List< Pattern > inlineImagePatterns = wikiContext.getEngine().getManager( RenderingManager.class )
             	                                                   .getParser( wikiContext, link ).getInlineImagePatterns();
 
             for( final Pattern p : inlineImagePatterns ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java
index 4acb8a7..aed6c63 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java
@@ -25,7 +25,7 @@ import org.apache.oro.text.regex.Pattern;
 import org.apache.oro.text.regex.PatternCompiler;
 import org.apache.wiki.StringTransmutator;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.util.TextUtil;
 import org.jdom2.Element;
 
@@ -50,7 +50,7 @@ public abstract class MarkupParser {
     protected PushbackReader m_in;
     private int m_pos = -1; // current position in reader stream
 
-    protected WikiEngine m_engine;
+    protected Engine m_engine;
     protected WikiContext m_context;
 
     /** Optionally stores internal wikilinks */
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
index a7f6f1c..506da58 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
@@ -24,13 +24,14 @@ import org.apache.oro.text.regex.PatternMatcher;
 import org.apache.oro.text.regex.Perl5Matcher;
 import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.engine.PluginManager;
 import org.apache.wiki.api.exceptions.PluginException;
-import org.apache.wiki.api.plugin.PluginElement;
 import org.apache.wiki.api.plugin.ParserStagePlugin;
+import org.apache.wiki.api.plugin.PluginElement;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.variables.VariableManager;
 import org.jdom2.Text;
 
 import java.io.IOException;
@@ -154,16 +155,16 @@ public class PluginContent extends Text implements PluginElement {
                     return BLANK;
                 }
 
-                final WikiEngine engine = context.getEngine();
+                final Engine engine = context.getEngine();
                 final Map< String, String > parsedParams = new HashMap<>();
 
                 //  Parse any variable instances from the string
                 for( final Map.Entry< String, String > e : m_params.entrySet() ) {
                     String val = e.getValue();
-                    val = engine.getVariableManager().expandVariables( context, val );
+                    val = engine.getManager( VariableManager.class).expandVariables( context, val );
                     parsedParams.put( e.getKey(), val );
                 }
-                final PluginManager pm = engine.getPluginManager();
+                final PluginManager pm = engine.getManager( PluginManager.class );
                 result = pm.execute( context, m_pluginName, parsedParams );
             }
         } catch( final Exception e ) {
@@ -185,7 +186,7 @@ public class PluginContent extends Text implements PluginElement {
     /**{@inheritDoc}*/
     @Override
     public void executeParse( final WikiContext context ) throws PluginException {
-        final PluginManager pm = context.getEngine().getPluginManager();
+        final PluginManager pm = context.getEngine().getManager( PluginManager.class );
         if( pm.pluginsEnabled() ) {
             final ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
             final Map< String, String > params = getParameters();
@@ -214,7 +215,7 @@ public class PluginContent extends Text implements PluginElement {
         final PatternMatcher matcher = new Perl5Matcher();
 
         try {
-            final PluginManager pm = context.getEngine().getPluginManager();
+            final PluginManager pm = context.getEngine().getManager( PluginManager.class );
             if( matcher.contains( commandline, pm.getPluginPattern() ) ) {
                 final MatchResult res = matcher.getMatch();
                 final String plugin = res.group( 2 );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/VariableContent.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/VariableContent.java
index 2d7ba47..6c9d397 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/VariableContent.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/VariableContent.java
@@ -21,6 +21,7 @@ package org.apache.wiki.parser;
 import org.apache.commons.text.StringEscapeUtils;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
+import org.apache.wiki.variables.VariableManager;
 import org.jdom2.Text;
 
 /**
@@ -52,7 +53,7 @@ public class VariableContent extends Text {
      *   
      *   @return The rendered value of the variable.
      */
-    public String getValue() {
+    @Override public String getValue() {
         String result;
         final WikiDocument root = (WikiDocument) getDocument();
 
@@ -71,7 +72,7 @@ public class VariableContent extends Text {
             result = "[" + m_varName + "]";
         } else {
             try {
-                result = context.getEngine().getVariableManager().parseAndGetValue( context, m_varName );
+                result = context.getEngine().getManager( VariableManager.class ).parseAndGetValue( context, m_varName );
             } catch( final NoSuchVariableException e ) {
                 result = MarkupParser.makeError( "No such variable: " + e.getMessage() ).getText(); 
             }
@@ -84,7 +85,7 @@ public class VariableContent extends Text {
      *  Returns exactly getValue().
      *  @return Whatever getValue() returns.
      */
-    public String getText() {
+    @Override public String getText() {
         return getValue();
     }
 
@@ -92,7 +93,7 @@ public class VariableContent extends Text {
      *  Returns a debug-suitable string.
      *  @return Debug string
      */
-    public String toString() {
+    @Override public String toString() {
         return "VariableElement[\"" + m_varName + "\"]";
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/preferences/Preferences.java b/jspwiki-main/src/main/java/org/apache/wiki/preferences/Preferences.java
index 2753b2e..7299981 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/preferences/Preferences.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/preferences/Preferences.java
@@ -73,7 +73,7 @@ public class Preferences
      *
      *  @param pageContext The JSP PageContext.
      */
-    public static void setupPreferences( PageContext pageContext )
+    public static void setupPreferences( final PageContext pageContext )
     {
         //HttpSession session = pageContext.getSession();
 
@@ -93,14 +93,13 @@ public class Preferences
     //        happened to first arrive to the site with.  This, unfortunately, means that
     //        even if the user changes e.g. language preferences (like in a web cafe),
     //        the old preferences still remain in a site cookie.
-    public static void reloadPreferences( PageContext pageContext )
+    public static void reloadPreferences( final PageContext pageContext )
     {
-        Preferences prefs = new Preferences();
-        Properties props = PropertyReader.loadWebAppProps( pageContext.getServletContext() );
-        WikiContext ctx = WikiContext.findContext( pageContext );
-        String dateFormat = ctx.getEngine().getInternationalizationManager().get( InternationalizationManager.CORE_BUNDLE,
-                                                                                  getLocale( ctx ),
-                                                                                  "common.datetimeformat" );
+        final Preferences prefs = new Preferences();
+        final Properties props = PropertyReader.loadWebAppProps( pageContext.getServletContext() );
+        final WikiContext ctx = WikiContext.findContext( pageContext );
+        final String dateFormat = ctx.getEngine().getManager( InternationalizationManager.class )
+                                           .get( InternationalizationManager.CORE_BUNDLE, getLocale( ctx ), "common.datetimeformat" );
 
         prefs.put("SkinName", TextUtil.getStringProperty( props, "jspwiki.defaultprefs.template.skinname", "PlainVanilla" ) );
         prefs.put("DateFormat", TextUtil.getStringProperty( props, "jspwiki.defaultprefs.template.dateformat", dateFormat ) );
@@ -137,18 +136,17 @@ public class Preferences
      *  @param prefs The default hashmap of preferences
      *
      */
-	private static void parseJSONPreferences( HttpServletRequest request, Preferences prefs ) {
-        String prefVal = TextUtil.urlDecodeUTF8( HttpUtil.retrieveCookieValue( request, "JSPWikiUserPrefs" ) );
+	private static void parseJSONPreferences( final HttpServletRequest request, final Preferences prefs ) {
+        final String prefVal = TextUtil.urlDecodeUTF8( HttpUtil.retrieveCookieValue( request, "JSPWikiUserPrefs" ) );
 
         if( prefVal != null ) {
             // Convert prefVal JSON to a generic hashmap
-            @SuppressWarnings("unchecked")
-            Map<String,String> map = new Gson().fromJson(prefVal, Map.class );
+            @SuppressWarnings("unchecked") final Map<String,String> map = new Gson().fromJson(prefVal, Map.class );
 
             for (String key : map.keySet()) {
                 key = TextUtil.replaceEntities( key );
                 // Sometimes this is not a String as it comes from the Cookie set by Javascript
-                Object value = map.get(key);
+                final Object value = map.get(key);
                 if (value != null) {
                     prefs.put( key, value.toString() );
                 }
@@ -164,11 +162,11 @@ public class Preferences
      *  @param name
      *  @return the preference value
      */
-    public static String getPreference( WikiContext wikiContext, String name ) {
-        HttpServletRequest request = wikiContext.getHttpRequest();
+    public static String getPreference( final WikiContext wikiContext, final String name ) {
+        final HttpServletRequest request = wikiContext.getHttpRequest();
         if ( request == null ) return null;
 
-        Preferences prefs = (Preferences)request.getSession().getAttribute( SESSIONPREFS );
+        final Preferences prefs = (Preferences)request.getSession().getAttribute( SESSIONPREFS );
 
         if( prefs != null ) {
             return prefs.get( name );
@@ -185,9 +183,9 @@ public class Preferences
      *  @param name
      *  @return the preference value
      */
-    public static String getPreference( PageContext pageContext, String name )
+    public static String getPreference( final PageContext pageContext, final String name )
     {
-        Preferences prefs = (Preferences)pageContext.getSession().getAttribute( SESSIONPREFS );
+        final Preferences prefs = (Preferences)pageContext.getSession().getAttribute( SESSIONPREFS );
 
         if( prefs != null )
             return prefs.get( name );
@@ -203,10 +201,10 @@ public class Preferences
      * @return a Locale object.
      * @since 2.8
      */
-    public static Locale getLocale( WikiContext context ) {
+    public static Locale getLocale( final WikiContext context ) {
         Locale loc = null;
 
-        String langSetting = getPreference( context, "Language" );
+        final String langSetting = getPreference( context, "Language" );
 
         // parse language and construct valid Locale object
         if( langSetting != null ) {
@@ -214,7 +212,7 @@ public class Preferences
             String country  = "";
             String variant  = "";
 
-            String[] res = StringUtils.split( langSetting, "-_" );
+            final String[] res = StringUtils.split( langSetting, "-_" );
 
             if( res.length > 2 ) variant = res[2];
             if( res.length > 1 ) country = res[1];
@@ -228,17 +226,17 @@ public class Preferences
 
         // see if default locale is set server side
         if( loc == null ) {
-            String locale = context.getEngine().getWikiProperties().getProperty( "jspwiki.preferences.default-locale" );
+            final String locale = context.getEngine().getWikiProperties().getProperty( "jspwiki.preferences.default-locale" );
             try {
                 loc = LocaleUtils.toLocale( locale );
-            } catch( IllegalArgumentException iae ) {
+            } catch( final IllegalArgumentException iae ) {
                 log.error( iae.getMessage() );
             }
         }
 
         // otherwise try to find out the browser's preferred language setting, or use the JVM's default
         if( loc == null ) {
-            HttpServletRequest request = context.getHttpRequest();
+            final HttpServletRequest request = context.getHttpRequest();
             loc = ( request != null ) ? request.getLocale() : Locale.getDefault();
         }
 
@@ -256,11 +254,11 @@ public class Preferences
      *  @return A localized string (or from the default language, if not found)
      *  @throws MissingResourceException If the bundle cannot be found
      */
-    public static ResourceBundle getBundle( WikiContext context, String bundle )
+    public static ResourceBundle getBundle( final WikiContext context, final String bundle )
         throws MissingResourceException
     {
-        Locale loc = getLocale( context );
-        InternationalizationManager i18n = context.getEngine().getInternationalizationManager();
+        final Locale loc = getLocale( context );
+        final InternationalizationManager i18n = context.getEngine().getManager( InternationalizationManager.class );
         return i18n.getBundle( bundle, loc );
     }
 
@@ -274,11 +272,11 @@ public class Preferences
      *  @return A SimpleTimeFormat object which you can use to render
      *  @since 2.8
      */
-    public static SimpleDateFormat getDateFormat( WikiContext context, TimeFormat tf )
+    public static SimpleDateFormat getDateFormat( final WikiContext context, final TimeFormat tf )
     {
-        InternationalizationManager imgr = context.getEngine().getInternationalizationManager();
-        Locale clientLocale = getLocale( context );
-        String prefTimeZone = getPreference( context, "TimeZone" );
+        final InternationalizationManager imgr = context.getEngine().getManager( InternationalizationManager.class );
+        final Locale clientLocale = getLocale( context );
+        final String prefTimeZone = getPreference( context, "TimeZone" );
         String prefDateFormat;
 
         log.debug("Checking for preferences...");
@@ -311,11 +309,11 @@ public class Preferences
 
         try
         {
-            SimpleDateFormat fmt = new SimpleDateFormat( prefDateFormat, clientLocale );
+            final SimpleDateFormat fmt = new SimpleDateFormat( prefDateFormat, clientLocale );
 
             if( prefTimeZone != null )
             {
-                TimeZone tz = TimeZone.getTimeZone( prefTimeZone );
+                final TimeZone tz = TimeZone.getTimeZone( prefTimeZone );
                 // TimeZone tz = TimeZone.getDefault();
                 // tz.setRawOffset(Integer.parseInt(prefTimeZone));
 
@@ -324,7 +322,7 @@ public class Preferences
 
             return fmt;
         }
-        catch( Exception e )
+        catch( final Exception e )
         {
             return null;
         }
@@ -340,9 +338,9 @@ public class Preferences
      *  @return A ready-rendered date.
      *  @since 2.8
      */
-    public static String renderDate( WikiContext context, Date date, TimeFormat tf )
+    public static String renderDate( final WikiContext context, final Date date, final TimeFormat tf )
     {
-        DateFormat df = getDateFormat( context, tf );
+        final DateFormat df = getDateFormat( context, tf );
 
         return df.format( date );
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java b/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java
index 5ebe5cc..e01de27 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/references/DefaultReferenceManager.java
@@ -32,6 +32,7 @@ import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiPageEvent;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 import org.apache.wiki.util.TextUtil;
 
@@ -163,7 +164,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *  Does a full reference update.  Does not sync; assumes that you do it afterwards.
      */
     private void updatePageReferences( final WikiPage page ) throws ProviderException {
-        final String content = m_engine.getPageManager().getPageText( page.getName(), WikiPageProvider.LATEST_VERSION );
+        final String content = m_engine.getManager( PageManager.class ).getPageText( page.getName(), WikiPageProvider.LATEST_VERSION );
         final Collection< String > links = scanWikiLinks( page, content );
         final TreeSet< String > res = new TreeSet<>( links );
         final List< Attachment > attachments = m_engine.getAttachmentManager().listAttachments( page );
@@ -181,7 +182,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *  @since 2.2
      *  @throws ProviderException If reading of pages fails.
      */
-    public void initialize( final Collection< WikiPage > pages ) throws ProviderException {
+    @Override public void initialize( final Collection< WikiPage > pages ) throws ProviderException {
         log.debug( "Initializing new ReferenceManager with " + pages.size() + " initial pages." );
         final StopWatch sw = new StopWatch();
         sw.start();
@@ -205,7 +206,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
             for( final WikiPage page : pages ) {
                 if( !( page instanceof Attachment ) ) {
                     // Refresh with the latest copy
-                    final WikiPage wp = m_engine.getPageManager().getPage( page.getName() );
+                    final WikiPage wp = m_engine.getManager( PageManager.class ).getPage( page.getName() );
 
                     if( wp.getLastModified() == null ) {
                         log.fatal( "Provider returns null lastModified.  Please submit a bug report." );
@@ -234,7 +235,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
         sw.stop();
         log.info( "Cross reference scan done in "+sw );
 
-        WikiEventManager.getInstance().addWikiEventListener( m_engine.getPageManager(), this );
+        WikiEventManager.getInstance().addWikiEventListener( m_engine.getManager( PageManager.class ), this );
     }
 
     /**
@@ -426,7 +427,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *  @param pagedata The page contents
      *  @return a Collection of Strings
      */
-    public Collection< String > scanWikiLinks( final WikiPage page, final String pagedata ) {
+    @Override public Collection< String > scanWikiLinks( final WikiPage page, final String pagedata ) {
         final LinkCollector localCollector = new LinkCollector();
         m_engine.getRenderingManager().textToHTML( new WikiContext( m_engine, page ),
                                                    pagedata,
@@ -448,7 +449,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *
      *  @param page Name of the page to remove from the maps.
      */
-    public synchronized void pageRemoved( final WikiPage page ) {
+    @Override public synchronized void pageRemoved( final WikiPage page ) {
         pageRemoved( page.getName() );
     }
 
@@ -467,7 +468,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
 
                 // We won't put it back again if it becomes empty and does not exist.  It will be added
                 // later on anyway, if it becomes referenced again.
-                if( !( refBy.isEmpty() && !m_engine.getPageManager().wikiPageExists( referredPageName ) ) ) {
+                if( !( refBy.isEmpty() && !m_engine.getManager( PageManager.class ).wikiPageExists( referredPageName ) ) ) {
                     m_referredBy.put( referredPageName, refBy );
                 }
             }
@@ -499,8 +500,8 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *
      *  @param page wiki page for which references should be updated
      */
-    public void updateReferences( final WikiPage page ) {
-        final String pageData = m_engine.getPageManager().getPureText( page.getName(), WikiProvider.LATEST_VERSION );
+    @Override public void updateReferences( final WikiPage page ) {
+        final String pageData = m_engine.getManager( PageManager.class ).getPureText( page.getName(), WikiProvider.LATEST_VERSION );
         updateReferences( page.getName(), scanWikiLinks( page, pageData ) );
     }
 
@@ -514,7 +515,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *  @param page Name of the page to update.
      *  @param references A Collection of Strings, each one pointing to a page this page references.
      */
-    public synchronized void updateReferences( final String page, final Collection< String > references ) {
+    @Override public synchronized void updateReferences( final String page, final Collection< String > references ) {
         internalUpdateReferences( page, references );
         serializeToDisk();
     }
@@ -603,7 +604,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
 
             // If the page is referred to by no one AND it doesn't even exist, we might just as well forget about this
             // entry. It will be added again elsewhere if new references appear.
-            if( ( oldRefBy == null || oldRefBy.isEmpty() ) && !m_engine.getPageManager().wikiPageExists( referredPage ) ) {
+            if( ( oldRefBy == null || oldRefBy.isEmpty() ) && !m_engine.getManager( PageManager.class ).wikiPageExists( referredPage ) ) {
                 m_referredBy.remove( referredPage );
             }
         }
@@ -673,7 +674,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *
      * @param pagename  Name of the page to clear references for.
      */
-    public synchronized void clearPageEntries( String pagename ) {
+    @Override public synchronized void clearPageEntries( String pagename ) {
         pagename = getFinalPageName( pagename );
 
         //  Remove this item from the referredBy list of any page which this item refers to.
@@ -696,7 +697,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *
      *  @return The Collection of Strings
      */
-    public synchronized Collection< String > findUnreferenced() {
+    @Override public synchronized Collection< String > findUnreferenced() {
         final ArrayList< String > unref = new ArrayList<>();
         for( final String key : m_referredBy.keySet() ) {
             final Set< ? > refs = getReferenceList( m_referredBy, key );
@@ -718,7 +719,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *
      * @return A Collection of Strings
      */
-    public synchronized Collection< String > findUncreated() {
+    @Override public synchronized Collection< String > findUncreated() {
         final TreeSet< String > uncreated = new TreeSet<>();
 
         // Go through m_refersTo values and check that m_refersTo has the corresponding keys.
@@ -727,7 +728,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
         for( final Collection<String> refs : allReferences ) {
             if( refs != null ) {
                 for( final String aReference : refs ) {
-                    if( !m_engine.getPageManager().wikiPageExists( aReference ) ) {
+                    if( !m_engine.getManager( PageManager.class ).wikiPageExists( aReference ) ) {
                         uncreated.add( aReference );
                     }
                 }
@@ -776,7 +777,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      * @param pagename The page to find referrers for.
      * @return A Set of Strings.  May return null, if the page does not exist, or if it has no references.
      */
-    public synchronized Set< String > findReferrers( final String pagename ) {
+    @Override public synchronized Set< String > findReferrers( final String pagename ) {
         final Set< String > refs = getReferenceList( m_referredBy, pagename );
         if( refs == null || refs.isEmpty() ) {
             return null;
@@ -798,7 +799,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *         not exist or has not been indexed yet.
      * @since 2.2.33
      */
-    public Set< String > findReferredBy( final String pageName ) {
+    @Override public Set< String > findReferredBy( final String pageName ) {
         return m_unmutableReferredBy.get( getFinalPageName(pageName) );
     }
 
@@ -816,7 +817,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *         does not exist or has not been indexed yet.
      * @since 2.2.33
      */
-    public Collection< String > findRefersTo( final String pageName ) {
+    @Override public Collection< String > findRefersTo( final String pageName ) {
         return m_unmutableRefersTo.get( getFinalPageName( pageName ) );
     }
 
@@ -859,7 +860,7 @@ public class DefaultReferenceManager extends BasicPageFilter implements Referenc
      *  @return A Set of all defined page names that ReferenceManager knows about.
      *  @since 2.3.24
      */
-    public Set< String > findCreated() {
+    @Override public Set< String > findCreated() {
         return new HashSet<>( m_refersTo.keySet() );
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/render/DefaultRenderingManager.java b/jspwiki-main/src/main/java/org/apache/wiki/render/DefaultRenderingManager.java
index c260455..bf7d9d3 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/render/DefaultRenderingManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/render/DefaultRenderingManager.java
@@ -272,7 +272,7 @@ public class DefaultRenderingManager implements RenderingManager {
      */
     @Override
     public String getHTML( final WikiContext context, final WikiPage page ) {
-        final String pagedata = m_engine.getPageManager().getPureText( page.getName(), page.getVersion() );
+        final String pagedata = m_engine.getManager( PageManager.class ).getPureText( page.getName(), page.getVersion() );
         return textToHTML( context, pagedata );
     }
 
@@ -284,8 +284,8 @@ public class DefaultRenderingManager implements RenderingManager {
      *  @param version Version number to fetch
      *  @return HTML-rendered page text.
      */
-    public String getHTML( final String pagename, final int version ) {
-        final WikiPage page = m_engine.getPageManager().getPage( pagename, version );
+    @Override public String getHTML( final String pagename, final int version ) {
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pagename, version );
         final WikiContext context = new WikiContext( m_engine, page );
         context.setRequestContext( WikiContext.NONE );
         return getHTML( context, page );


[jspwiki] 20/38: promote a couple of methods more from DefaultAuthorizationManager to AuthorizationManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit d03a5c770de98ae04ab2559ae941b013f2843c62
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 12:21:16 2020 +0100

    promote a couple of methods more from DefaultAuthorizationManager to AuthorizationManager
---
 .../org/apache/wiki/auth/AuthorizationManager.java | 46 +++++++++++++++++++
 .../wiki/auth/DefaultAuthorizationManager.java     | 51 ++++------------------
 2 files changed, 55 insertions(+), 42 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
index a0ab560..5c07767 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
@@ -29,6 +29,7 @@ import org.apache.wiki.event.WikiSecurityEvent;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.security.AccessController;
 import java.security.Permission;
 import java.security.Principal;
 import java.util.Properties;
@@ -145,6 +146,26 @@ public interface AuthorizationManager {
     Authorizer getAuthorizer() throws WikiSecurityException;
 
     /**
+     * <p>Determines if the Subject associated with a supplied WikiSession contains a desired user Principal or built-in Role principal,
+     * OR is a member a Group or external Role. The rules are as follows:</p>
+     * <ol>
+     * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to {@link #isUserInRole(WikiSession, Principal)} and
+     * return the result.</li>
+     * <li>Otherwise, we're looking for a user Principal, so iterate through the Principal set and see if any share the same name as the
+     * one we are looking for.</li>
+     * </ol>
+     * <p><em>Note: if the Principal parameter is a user principal, the session must be authenticated in order for the user to "possess it".
+     * Anonymous or asserted sessions will never posseess a named user principal.</em></p>
+     *
+     * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
+     * @param principal the Principal (role, group, or user principal) to look for, which must be non-null. If null, the result of this
+     *                  method always returns <code>false</code>
+     * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role, GroupPrincipal or desired
+     *         user Principal, <code>false</code> otherwise
+     */
+    boolean hasRoleOrPrincipal( WikiSession session, Principal principal );
+
+    /**
      * Checks whether the current user has access to the wiki context, by obtaining the required Permission ({@link WikiContext#requiredPermission()})
      * and delegating the access check to {@link #checkPermission(WikiSession, Permission)}. If the user is allowed, this method returns
      * <code>true</code>; <code>false</code> otherwise. If access is allowed, the wiki context will be added to the request as an attribute
@@ -187,6 +208,31 @@ public interface AuthorizationManager {
     void initialize( final Engine engine, final Properties properties ) throws WikiException;
 
     /**
+     * Checks to see if the local security policy allows a particular static Permission.
+     * Do not use this method for normal permission checks; use {@link #checkPermission(WikiSession, Permission)} instead.
+     *
+     * @param principals the Principals to check
+     * @param permission the Permission
+     * @return the result
+     */
+    boolean allowedByLocalPolicy( Principal[] principals, Permission permission );
+
+    /**
+     * Determines whether a Subject possesses a given "static" Permission as defined in the security policy file. This method uses standard
+     * Java 2 security calls to do its work. Note that the current access control context's <code>codeBase</code> is effectively <em>this
+     * class</em>, not that of the caller. Therefore, this method will work best when what matters in the policy is <em>who</em> makes the
+     * permission check, not what the caller's code source is. Internally, this method works by executing <code>Subject.doAsPrivileged</code>
+     * with a privileged action that simply calls {@link AccessController#checkPermission(Permission)}.
+     *
+     * @see AccessController#checkPermission(Permission) . A caught exception (or lack thereof) determines whether the
+     *       privilege is absent (or present).
+     * @param session the WikiSession whose permission status is being queried
+     * @param permission the Permission the Subject must possess
+     * @return <code>true</code> if the Subject possesses the permission, <code>false</code> otherwise
+     */
+    boolean checkStaticPermission( WikiSession session, Permission permission );
+
+    /**
      * <p>Given a supplied string representing a Principal's name from an Acl, this method resolves the correct type of Principal (role,
      * group, or user). This method is guaranteed to always return a Principal. The algorithm is straightforward:</p>
      * <ol>
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
index a388a08..b64834e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
@@ -170,25 +170,9 @@ public class DefaultAuthorizationManager implements AuthorizationManager {
         throw new WikiSecurityException( "Authorizer did not initialize properly. Check the logs." );
     }
 
-    /**
-     * <p>Determines if the Subject associated with a supplied WikiSession contains a desired user Principal or built-in Role principal,
-     * OR is a member a Group or external Role. The rules are as follows:</p>
-     * <ol>
-     * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to {@link #isUserInRole(WikiSession, Principal)} and
-     * return the result.</li>
-     * <li>Otherwise, we're looking for a user Principal, so iterate through the Principal set and see if any share the same name as the
-     * one we are looking for.</li>
-     * </ol>
-     * <p><em>Note: if the Principal parameter is a user principal, the session must be authenticated in order for the user to "possess it".
-     * Anonymous or asserted sessions will never posseess a named user principal.</em></p>
-     *
-     * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
-     * @param principal the Principal (role, group, or user principal) to look for, which must be non-null. If null, the result of this
-     *                  method always returns <code>false</code>
-     * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role, GroupPrincipal or desired
-     *         user Principal, <code>false</code> otherwise
-     */
-    protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal ) {
+    /** {@inheritDoc} */
+    @Override
+    public boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal ) {
         // If either parameter is null, always deny
         if( session == null || principal == null ) {
             return false;
@@ -308,15 +292,9 @@ public class DefaultAuthorizationManager implements AuthorizationManager {
         throw new NoRequiredPropertyException( "Unable to find a " + PROP_AUTHORIZER + " entry in the properties.", PROP_AUTHORIZER );
     }
 
-    /**
-     * Checks to see if the local security policy allows a particular static Permission.
-     * Do not use this method for normal permission checks; use {@link #checkPermission(WikiSession, Permission)} instead.
-     *
-     * @param principals the Principals to check
-     * @param permission the Permission
-     * @return the result
-     */
-    protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission ) {
+    /** {@inheritDoc} */
+    @Override
+    public boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission ) {
         for ( final Principal principal : principals ) {
             // Get ProtectionDomain for this Principal from cache, or create new one
             ProtectionDomain pd = m_cachedPds.get( principal );
@@ -335,20 +313,9 @@ public class DefaultAuthorizationManager implements AuthorizationManager {
         return false;
     }
 
-    /**
-     * Determines whether a Subject possesses a given "static" Permission as defined in the security policy file. This method uses standard
-     * Java 2 security calls to do its work. Note that the current access control context's <code>codeBase</code> is effectively <em>this
-     * class</em>, not that of the caller. Therefore, this method will work best when what matters in the policy is <em>who</em> makes the
-     * permission check, not what the caller's code source is. Internally, this method works by executing <code>Subject.doAsPrivileged</code>
-     * with a privileged action that simply calls {@link AccessController#checkPermission(Permission)}.
-     *
-     * @see AccessController#checkPermission(Permission) . A caught exception (or lack thereof) determines whether the
-     *       privilege is absent (or present).
-     * @param session the WikiSession whose permission status is being queried
-     * @param permission the Permission the Subject must possess
-     * @return <code>true</code> if the Subject possesses the permission, <code>false</code> otherwise
-     */
-    protected boolean checkStaticPermission( final WikiSession session, final Permission permission ) {
+    /** {@inheritDoc} */
+    @Override
+    public boolean checkStaticPermission( final WikiSession session, final Permission permission ) {
         return ( Boolean )WikiSession.doPrivileged( session, ( PrivilegedAction< Boolean > )() -> {
             try {
                 // Check the JVM-wide security policy first


[jspwiki] 06/38: add @SuppressWarnings annotation to E Engine#adapt( Class< E > )

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 3e3810d368f9a7835686c5bbbb906e713da164fe
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 14:29:39 2020 +0100

    add @SuppressWarnings annotation to E Engine#adapt( Class< E > )
---
 jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index cc45798..a336542 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -88,7 +88,8 @@ public interface Engine {
      * @param <E> type to adapt to.
      * @return engine instance adapted to the requested type. Might throw an unchecked exception if the instance cannot be adapted to requested type!
      */
-    default < E extends Engine > E adapt( Class< E > cls ) {
+    @SuppressWarnings( "unchecked" )
+    default < E extends Engine > E adapt( final Class< E > cls ) {
         return ( E )this;
     }
 


[jspwiki] 07/38: JSPWIKI-120: promote DefaultAuthenticationManager#findConfigFile( Engine, String ) to Engine#findConfigFile( String ) as default method

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 1cceed45ddea79676450dd7ee2e3d519eacd190b
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:18:33 2020 +0100

    JSPWIKI-120: promote DefaultAuthenticationManager#findConfigFile( Engine, String ) to Engine#findConfigFile( String ) as default method
---
 .../main/java/org/apache/wiki/api/core/Engine.java |  73 ++++++++
 .../apache/wiki/auth/AuthenticationManager.java    |  10 +-
 .../org/apache/wiki/auth/AuthorizationManager.java |  76 ++++----
 .../wiki/auth/DefaultAuthenticationManager.java    |  73 --------
 .../org/apache/wiki/auth/SecurityVerifier.java     | 196 ++++++++++-----------
 5 files changed, 203 insertions(+), 225 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index a336542..fdcb187 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -18,11 +18,21 @@
  */
 package org.apache.wiki.api.core;
 
+import org.apache.log4j.Logger;
 import org.apache.wiki.WatchDog;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.event.WikiEventListener;
 
 import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.Date;
@@ -192,6 +202,69 @@ public interface Engine {
     ServletContext getServletContext();
 
     /**
+     * Looks up and obtains a configuration file inside the WEB-INF folder of a wiki webapp.
+     *
+     * @param name the file to obtain, <em>e.g.</em>, <code>jspwiki.policy</code>
+     * @return the URL to the file
+     */
+    default URL findConfigFile( final String name ) {
+        Logger.getLogger( AuthenticationManager.class ).info( "looking for " + name + " inside WEB-INF " );
+        // Try creating an absolute path first
+        File defaultFile = null;
+        if( getRootPath() != null ) {
+            defaultFile = new File( getRootPath() + "/WEB-INF/" + name );
+        }
+        if ( defaultFile != null && defaultFile.exists() ) {
+            try {
+                return defaultFile.toURI().toURL();
+            } catch ( final MalformedURLException e ) {
+                // Shouldn't happen, but log it if it does
+                Logger.getLogger( Engine.class ).warn( "Malformed URL: " + e.getMessage() );
+            }
+        }
+
+        // Ok, the absolute path didn't work; try other methods
+        URL path = null;
+
+        if( getServletContext() != null ) {
+            final File tmpFile;
+            try {
+                tmpFile = File.createTempFile( "temp." + name, "" );
+            } catch( final IOException e ) {
+                Logger.getLogger( Engine.class ).error( "unable to create a temp file to load onto the policy", e );
+                return null;
+            }
+            tmpFile.deleteOnExit();
+            Logger.getLogger( Engine.class ).info( "looking for /" + name + " on classpath" );
+            //  create a tmp file of the policy loaded as an InputStream and return the URL to it
+            try( final InputStream is = AuthenticationManager.class.getResourceAsStream( "/" + name );
+                    final OutputStream os = new FileOutputStream( tmpFile ) ) {
+                if( is == null ) {
+                    throw new FileNotFoundException( name + " not found" );
+                }
+                final URL url = getServletContext().getResource( "/WEB-INF/" + name );
+                if( url != null ) {
+                    return url;
+                }
+
+                final byte[] buff = new byte[1024];
+                int bytes;
+                while( ( bytes = is.read( buff ) ) != -1 ) {
+                    os.write( buff, 0, bytes );
+                }
+
+                path = tmpFile.toURI().toURL();
+            } catch( final MalformedURLException e ) {
+                // This should never happen unless I screw up
+                Logger.getLogger( Engine.class ).fatal( "Your code is b0rked.  You are a bad person.", e );
+            } catch( final IOException e ) {
+                Logger.getLogger( Engine.class ).error( "failed to load security policy from file " + name + ",stacktrace follows", e );
+            }
+        }
+        return path;
+    }
+
+    /**
      *  Returns a collection of all supported InterWiki links.
      *
      *  @return A Collection of Strings.
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
index 197619a..bd06cd6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthenticationManager.java
@@ -20,8 +20,6 @@ package org.apache.wiki.auth;
 
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.auth.authorize.Role;
-import org.apache.wiki.auth.login.CookieAssertionLoginModule;
-import org.apache.wiki.auth.login.CookieAuthenticationLoginModule;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
@@ -48,12 +46,6 @@ import java.util.Set;
  */
 public interface AuthenticationManager {
 
-    /** The name of the built-in cookie assertion module */
-    String COOKIE_MODULE = CookieAssertionLoginModule.class.getName();
-
-    /** The name of the built-in cookie authentication module */
-    String COOKIE_AUTHENTICATION_MODULE = CookieAuthenticationLoginModule.class.getName();
-
     /** If this jspwiki.properties property is <code>true</code>, logs the IP address of the editor on saving. */
     String PROP_STOREIPADDRESS = "jspwiki.storeIPAddress";
     
@@ -165,7 +157,7 @@ public interface AuthenticationManager {
      * @return the set of Principals returned by the JAAS method {@link Subject#getPrincipals()}
      * @throws WikiSecurityException if the LoginModule could not be instantiated for any reason
      */
-    Set< Principal > doJAASLogin( Class<? extends LoginModule> clazz, CallbackHandler handler, Map< String, String > options) throws WikiSecurityException;
+    Set< Principal > doJAASLogin( Class< ? extends LoginModule > clazz, CallbackHandler handler, Map< String, String > options) throws WikiSecurityException;
     
     /**
      * Determines whether the supplied Principal is a "role principal".
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
index f7fb9c4..265cef2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
@@ -115,7 +115,7 @@ public class AuthorizationManager {
     private Authorizer                        m_authorizer      = null;
 
     /** Cache for storing ProtectionDomains used to evaluate the local policy. */
-    private Map<Principal, ProtectionDomain>                               m_cachedPds       = new WeakHashMap<Principal, ProtectionDomain>();
+    private Map<Principal, ProtectionDomain>                               m_cachedPds       = new WeakHashMap<>();
 
     private WikiEngine                        m_engine          = null;
 
@@ -171,7 +171,7 @@ public class AuthorizationManager {
      * @see #hasRoleOrPrincipal(WikiSession, Principal)
      * @return the result of the Permission check
      */
-    public boolean checkPermission( WikiSession session, Permission permission )
+    public boolean checkPermission( final WikiSession session, final Permission permission )
     {
         //
         //  A slight sanity check.
@@ -182,11 +182,11 @@ public class AuthorizationManager {
             return false;
         }
 
-        Principal user = session.getLoginPrincipal();
+        final Principal user = session.getLoginPrincipal();
 
         // Always allow the action if user has AllPermission
-        Permission allPermission = new AllPermission( m_engine.getApplicationName() );
-        boolean hasAllPermission = checkStaticPermission( session, allPermission );
+        final Permission allPermission = new AllPermission( m_engine.getApplicationName() );
+        final boolean hasAllPermission = checkStaticPermission( session, allPermission );
         if ( hasAllPermission )
         {
             fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
@@ -195,7 +195,7 @@ public class AuthorizationManager {
 
         // If the user doesn't have *at least* the permission
         // granted by policy, return false.
-        boolean hasPolicyPermission = checkStaticPermission( session, permission );
+        final boolean hasPolicyPermission = checkStaticPermission( session, permission );
         if ( !hasPolicyPermission )
         {
             fireEvent( WikiSecurityEvent.ACCESS_DENIED, user, permission );
@@ -212,9 +212,9 @@ public class AuthorizationManager {
         //
         // If the page or ACL is null, it's allowed.
         //
-        String pageName = ((PagePermission)permission).getPage();
-        WikiPage page = m_engine.getPageManager().getPage( pageName );
-        Acl acl = ( page == null) ? null : m_engine.getAclManager().getPermissions( page );
+        final String pageName = ((PagePermission)permission).getPage();
+        final WikiPage page = m_engine.getPageManager().getPage( pageName );
+        final Acl acl = ( page == null) ? null : m_engine.getAclManager().getPermissions( page );
         if ( page == null ||  acl == null || acl.isEmpty() )
         {
             fireEvent( WikiSecurityEvent.ACCESS_ALLOWED, user, permission );
@@ -226,7 +226,7 @@ public class AuthorizationManager {
         //  this permission. If the context's subject possesses
         //  any of these, the action is allowed.
 
-        Principal[] aclPrincipals = acl.findPrincipals( permission );
+        final Principal[] aclPrincipals = acl.findPrincipals( permission );
 
         log.debug( "Checking ACL entries..." );
         log.debug( "Acl for this page is: " + acl );
@@ -239,7 +239,7 @@ public class AuthorizationManager {
             // try to resolve it here & correct the Acl
             if ( aclPrincipal instanceof UnresolvedPrincipal )
             {
-                AclEntry aclEntry = acl.getEntry( aclPrincipal );
+                final AclEntry aclEntry = acl.getEntry( aclPrincipal );
                 aclPrincipal = resolvePrincipal( aclPrincipal.getName() );
                 if ( aclEntry != null && !( aclPrincipal instanceof UnresolvedPrincipal ) )
                 {
@@ -279,7 +279,7 @@ public class AuthorizationManager {
      * @return <code>true</code> if the Subject supplied with the WikiContext
      *         posesses the Role or GroupPrincipal, <code>false</code> otherwise
      */
-    public boolean isUserInRole( WikiSession session, Principal principal )
+    public boolean isUserInRole( final WikiSession session, final Principal principal )
     {
         if ( session == null || principal == null ||
              AuthenticationManager.isUserPrincipal( principal ) )
@@ -343,7 +343,7 @@ public class AuthorizationManager {
      *         posesses the Role, GroupPrincipal or desired
      *         user Principal, <code>false</code> otherwise
      */
-    protected boolean hasRoleOrPrincipal( WikiSession session, Principal principal )
+    protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal )
     {
         // If either parameter is null, always deny
         if( session == null || principal == null )
@@ -362,9 +362,9 @@ public class AuthorizationManager {
         // So just look for a name match.
         if( session.isAuthenticated() && AuthenticationManager.isUserPrincipal( principal ) )
         {
-            String principalName = principal.getName();
-            Principal[] userPrincipals = session.getPrincipals();
-            for( Principal userPrincipal : userPrincipals )
+            final String principalName = principal.getName();
+            final Principal[] userPrincipals = session.getPrincipals();
+            for( final Principal userPrincipal : userPrincipals )
             {
                 if( userPrincipal.getName().equals( principalName ) )
                 {
@@ -392,7 +392,7 @@ public class AuthorizationManager {
      * @return the result of the access check
      * @throws IOException In case something goes wrong
      */
-    public boolean hasAccess( WikiContext context, HttpServletResponse response ) throws IOException
+    public boolean hasAccess( final WikiContext context, final HttpServletResponse response ) throws IOException
     {
         return hasAccess( context, response, true );
     }
@@ -457,7 +457,7 @@ public class AuthorizationManager {
         // Initialize local security policy
         try {
             final String policyFileName = properties.getProperty( POLICY, DEFAULT_POLICY );
-            final URL policyURL = AuthenticationManager.findConfigFile( engine, policyFileName );
+            final URL policyURL = engine.findConfigFile( policyFileName );
 
             if (policyURL != null) {
                 final File policyFile = new File( policyURL.toURI().getPath() );
@@ -489,7 +489,7 @@ public class AuthorizationManager {
      * @return a Authorizer used to get page authorization information
      * @throws WikiException
      */
-    private Authorizer getAuthorizerImplementation( Properties props ) throws WikiException {
+    private Authorizer getAuthorizerImplementation( final Properties props ) throws WikiException {
         final String authClassName = props.getProperty( PROP_AUTHORIZER, DEFAULT_AUTHORIZER );
         return ( Authorizer )locateImplementation( authClassName );
     }
@@ -497,16 +497,16 @@ public class AuthorizationManager {
     private Object locateImplementation( final String clazz ) throws WikiException {
         if ( clazz != null ) {
             try {
-                Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
-                Object impl = authClass.newInstance();
+                final Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
+                final Object impl = authClass.newInstance();
                 return impl;
-            } catch( ClassNotFoundException e ) {
+            } catch( final ClassNotFoundException e ) {
                 log.fatal( "Authorizer " + clazz + " cannot be found", e );
                 throw new WikiException( "Authorizer " + clazz + " cannot be found", e );
-            } catch( InstantiationException e ) {
+            } catch( final InstantiationException e ) {
                 log.fatal( "Authorizer " + clazz + " cannot be created", e );
                 throw new WikiException( "Authorizer " + clazz + " cannot be created", e );
-            } catch( IllegalAccessException e ) {
+            } catch( final IllegalAccessException e ) {
                 log.fatal( "You are not allowed to access this authorizer class", e );
                 throw new WikiException( "You are not allowed to access this authorizer class", e );
             }
@@ -524,16 +524,16 @@ public class AuthorizationManager {
      * @param permission the Permission
      * @return the result
      */
-    protected boolean allowedByLocalPolicy( Principal[] principals, Permission permission )
+    protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission )
     {
-        for ( Principal principal : principals )
+        for ( final Principal principal : principals )
         {
             // Get ProtectionDomain for this Principal from cache, or create new one
             ProtectionDomain pd = m_cachedPds.get( principal );
             if ( pd == null )
             {
-                ClassLoader cl = this.getClass().getClassLoader();
-                CodeSource cs = new CodeSource( null, (Certificate[])null );
+                final ClassLoader cl = this.getClass().getClassLoader();
+                final CodeSource cs = new CodeSource( null, (Certificate[])null );
                 pd = new ProtectionDomain( cs, null, cl, new Principal[]{ principal } );
                 m_cachedPds.put( principal, pd );
             }
@@ -567,9 +567,9 @@ public class AuthorizationManager {
      */
     protected boolean checkStaticPermission( final WikiSession session, final Permission permission )
     {
-        Boolean allowed = (Boolean) WikiSession.doPrivileged( session, new PrivilegedAction<Boolean>()
+        final Boolean allowed = (Boolean) WikiSession.doPrivileged( session, new PrivilegedAction<Boolean>()
         {
-            public Boolean run()
+            @Override public Boolean run()
             {
                 try
                 {
@@ -577,7 +577,7 @@ public class AuthorizationManager {
                     AccessController.checkPermission( permission );
                     return Boolean.TRUE;
                 }
-                catch( AccessControlException e )
+                catch( final AccessControlException e )
                 {
                     // Global policy denied the permission
                 }
@@ -616,10 +616,10 @@ public class AuthorizationManager {
      * @param name the name of the Principal to resolve
      * @return the fully-resolved Principal
      */
-    public Principal resolvePrincipal( String name )
+    public Principal resolvePrincipal( final String name )
     {
         // Check built-in Roles first
-        Role role = new Role(name);
+        final Role role = new Role(name);
         if ( Role.isBuiltInRole( role ) )
         {
             return role;
@@ -642,7 +642,7 @@ public class AuthorizationManager {
         // Ok, no luck---this must be a user principal
         Principal[] principals = null;
         UserProfile profile = null;
-        UserDatabase db = m_engine.getUserManager().getUserDatabase();
+        final UserDatabase db = m_engine.getUserManager().getUserDatabase();
         try
         {
             profile = db.find( name );
@@ -656,7 +656,7 @@ public class AuthorizationManager {
                 }
             }
         }
-        catch( NoSuchPrincipalException e )
+        catch( final NoSuchPrincipalException e )
         {
             // We couldn't find the user...
         }
@@ -671,7 +671,7 @@ public class AuthorizationManager {
      * Registers a WikiEventListener with this instance.
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( WikiEventListener listener )
+    public synchronized void addWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.addWikiEventListener( this, listener );
     }
@@ -680,7 +680,7 @@ public class AuthorizationManager {
      * Un-registers a WikiEventListener with this instance.
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( WikiEventListener listener )
+    public synchronized void removeWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.removeWikiEventListener( this, listener );
     }
@@ -694,7 +694,7 @@ public class AuthorizationManager {
      * @param user        the user associated with the event
      * @param permission  the permission the subject must possess
      */
-    protected void fireEvent( int type, Principal user, Object permission )
+    protected void fireEvent( final int type, final Principal user, final Object permission )
     {
         if ( WikiEventManager.isListening(this) )
         {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
index 547d28b..ee5e284 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
@@ -44,15 +44,7 @@ import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.security.Principal;
 import java.util.Collections;
 import java.util.HashMap;
@@ -360,71 +352,6 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
         return NO_PRINCIPALS;
     }
 
-    /**
-     * Looks up and obtains a configuration file inside the WEB-INF folder of a wiki webapp.
-     *
-     * @param engine the wiki engine
-     * @param name the file to obtain, <em>e.g.</em>, <code>jspwiki.policy</code>
-     * @return the URL to the file
-     */
-    protected static URL findConfigFile( final Engine engine, final String name ) {
-        log.info( "looking for " + name + " inside WEB-INF " );
-        // Try creating an absolute path first
-        File defaultFile = null;
-        if( engine.getRootPath() != null ) {
-            defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + name );
-        }
-        if ( defaultFile != null && defaultFile.exists() ) {
-            try {
-                return defaultFile.toURI().toURL();
-            } catch ( final MalformedURLException e ) {
-                // Shouldn't happen, but log it if it does
-                log.warn( "Malformed URL: " + e.getMessage() );
-            }
-        }
-
-
-        // Ok, the absolute path didn't work; try other methods
-        URL path = null;
-
-        if( engine.getServletContext() != null ) {
-            final File tmpFile;
-        	try {
-                tmpFile = File.createTempFile( "temp." + name, "" );
-            } catch( final IOException e ) {
-        	    log.error( "unable to create a temp file to load onto the policy", e );
-        	    return null;
-            }
-            tmpFile.deleteOnExit();
-            log.info( "looking for /" + name + " on classpath" );
-            //  create a tmp file of the policy loaded as an InputStream and return the URL to it
-            try( final InputStream is = DefaultAuthenticationManager.class.getResourceAsStream( "/" + name );
-                 final OutputStream os = new FileOutputStream( tmpFile ) ) {
-                if( is == null ) {
-                    throw new FileNotFoundException( name + " not found" );
-                }
-            	final URL url = engine.getServletContext().getResource( "/WEB-INF/" + name );
-            	if( url != null ) {
-            		return url;
-            	}
-
-                final byte[] buff = new byte[1024];
-                int bytes;
-                while( ( bytes = is.read( buff ) ) != -1 ) {
-                    os.write( buff, 0, bytes );
-                }
-
-                path = tmpFile.toURI().toURL();
-            } catch( final MalformedURLException e ) {
-                // This should never happen unless I screw up
-                log.fatal( "Your code is b0rked.  You are a bad person.", e );
-            } catch( final IOException e ) {
-               log.error( "failed to load security policy from file " + name + ",stacktrace follows", e );
-            }
-        }
-        return path;
-    }
-
     // events processing .......................................................
 
     /**
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
index 748f5eb..6946732 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/SecurityVerifier.java
@@ -138,7 +138,7 @@ public final class SecurityVerifier {
      * @param engine the wiki engine
      * @param session the wiki session (typically, that of an administrator)
      */
-    public SecurityVerifier( WikiEngine engine, WikiSession session )
+    public SecurityVerifier( final WikiEngine engine, final WikiSession session )
     {
         super();
         m_engine = engine;
@@ -150,7 +150,7 @@ public final class SecurityVerifier {
         {
             verifyPolicyAndContainerRoles();
         }
-        catch ( WikiException e )
+        catch ( final WikiException e )
         {
             m_session.addMessage( ERROR_ROLES, e.getMessage() );
         }
@@ -179,21 +179,21 @@ public final class SecurityVerifier {
      */
     public String policyRoleTable()
     {
-        Principal[] roles = m_policyPrincipals;
-        String wiki = m_engine.getApplicationName();
+        final Principal[] roles = m_policyPrincipals;
+        final String wiki = m_engine.getApplicationName();
 
-        String[] pages = new String[]
+        final String[] pages = new String[]
         { "Main", "Index", "GroupTest", "GroupAdmin" };
-        String[] pageActions = new String[]
+        final String[] pageActions = new String[]
         { "view", "edit", "modify", "rename", "delete" };
 
-        String[] groups = new String[]
+        final String[] groups = new String[]
         { "Admin", "TestGroup", "Foo" };
-        String[] groupActions = new String[]
+        final String[] groupActions = new String[]
         { "view", "edit", null, null, "delete" };
 
         // Calculate column widths
-        String colWidth;
+        final String colWidth;
         if ( pageActions.length > 0 && roles.length > 0 )
         {
             colWidth =  (67f / ( pageActions.length * roles.length )) + "%";
@@ -203,7 +203,7 @@ public final class SecurityVerifier {
             colWidth = "67%";
         }
 
-        StringBuilder s = new StringBuilder();
+        final StringBuilder s = new StringBuilder();
 
         // Write the table header
         s.append( "<table class=\"wikitable\" border=\"1\">\n" );
@@ -223,24 +223,24 @@ public final class SecurityVerifier {
         s.append( "  <tr>\n" );
         for( int i = 0; i < roles.length; i++ )
         {
-            for( String pageAction : pageActions )
+            for( final String pageAction : pageActions )
             {
-                String action = pageAction.substring( 0, 1 );
+                final String action = pageAction.substring( 0, 1 );
                 s.append( "    <th title=\"" + pageAction + "\">" + action + "</th>\n" );
             }
         }
         s.append( "  </tr>\n" );
 
         // Write page permission tests first
-        for( String page : pages )
+        for( final String page : pages )
         {
             s.append( "  <tr>\n" );
             s.append( "    <td>PagePermission \"" + wiki + ":" + page + "\"</td>\n" );
-            for( Principal role : roles )
+            for( final Principal role : roles )
             {
-                for( String pageAction : pageActions )
+                for( final String pageAction : pageActions )
                 {
-                    Permission permission = PermissionFactory.getPagePermission( wiki + ":" + page, pageAction );
+                    final Permission permission = PermissionFactory.getPagePermission( wiki + ":" + page, pageAction );
                     s.append( printPermissionTest( permission, role, 1 ) );
                 }
             }
@@ -248,13 +248,13 @@ public final class SecurityVerifier {
         }
 
         // Now do the group tests
-        for( String group : groups )
+        for( final String group : groups )
         {
             s.append( "  <tr>\n" );
             s.append( "    <td>GroupPermission \"" + wiki + ":" + group + "\"</td>\n" );
-            for( Principal role : roles )
+            for( final Principal role : roles )
             {
-                for( String groupAction : groupActions )
+                for( final String groupAction : groupActions )
                 {
                     Permission permission = null;
                     if ( groupAction != null)
@@ -269,15 +269,15 @@ public final class SecurityVerifier {
 
 
         // Now check the wiki-wide permissions
-        String[] wikiPerms = new String[]
+        final String[] wikiPerms = new String[]
         { "createGroups", "createPages", "login", "editPreferences", "editProfile" };
-        for( String wikiPerm : wikiPerms )
+        for( final String wikiPerm : wikiPerms )
         {
             s.append( "  <tr>\n" );
             s.append( "    <td>WikiPermission \"" + wiki + "\",\"" + wikiPerm + "\"</td>\n" );
-            for( Principal role : roles )
+            for( final Principal role : roles )
             {
-                Permission permission = new WikiPermission( wiki, wikiPerm );
+                final Permission permission = new WikiPermission( wiki, wikiPerm );
                 s.append( printPermissionTest( permission, role, pageActions.length ) );
             }
             s.append( "  </tr>\n" );
@@ -286,9 +286,9 @@ public final class SecurityVerifier {
         // Lastly, check for AllPermission
         s.append( "  <tr>\n" );
         s.append( "    <td>AllPermission \"" + wiki + "\"</td>\n" );
-        for( Principal role : roles )
+        for( final Principal role : roles )
         {
-            Permission permission = new AllPermission( wiki );
+            final Permission permission = new AllPermission( wiki );
             s.append( printPermissionTest( permission, role, pageActions.length ) );
         }
         s.append( "  </tr>\n" );
@@ -304,9 +304,9 @@ public final class SecurityVerifier {
      * @param principal
      * @param cols
      */
-    private String printPermissionTest( Permission permission, Principal principal, int cols )
+    private String printPermissionTest( final Permission permission, final Principal principal, final int cols )
     {
-    	StringBuilder s = new StringBuilder();
+    	final StringBuilder s = new StringBuilder();
         if ( permission == null )
         {
             s.append( "    <td colspan=\"" + cols + "\" align=\"center\" title=\"N/A\">" );
@@ -314,7 +314,7 @@ public final class SecurityVerifier {
         }
         else
         {
-            boolean allowed = verifyStaticPermission( principal, permission );
+            final boolean allowed = verifyStaticPermission( principal, permission );
             s.append( "    <td colspan=\"" + cols + "\" align=\"center\" title=\"" );
             s.append( allowed ? "ALLOW: " : "DENY: " );
             s.append( permission.getClass().getName() );
@@ -350,8 +350,8 @@ public final class SecurityVerifier {
     public String containerRoleTable() throws WikiException
     {
 
-        AuthorizationManager authorizationManager = m_engine.getAuthorizationManager();
-        Authorizer authorizer = authorizationManager.getAuthorizer();
+        final AuthorizationManager authorizationManager = m_engine.getAuthorizationManager();
+        final Authorizer authorizer = authorizationManager.getAuthorizer();
 
         // If authorizer not WebContainerAuthorizer, print error message
         if ( !( authorizer instanceof WebContainerAuthorizer ) )
@@ -362,8 +362,8 @@ public final class SecurityVerifier {
         // Now, print a table with JSP pages listed on the left, and
         // an evaluation of each pages' constraints for each role
         // we discovered
-        StringBuilder s = new StringBuilder();
-        Principal[] roles = authorizer.getRoles();
+        final StringBuilder s = new StringBuilder();
+        final Principal[] roles = authorizer.getRoles();
         s.append( "<table class=\"wikitable\" border=\"1\">\n" );
         s.append( "<thead>\n" );
         s.append( "  <tr>\n" );
@@ -373,7 +373,7 @@ public final class SecurityVerifier {
         s.append( "  </tr>\n" );
         s.append( "  <tr>\n" );
         s.append( "    <th>Anonymous</th>\n" );
-        for( Principal role : roles )
+        for( final Principal role : roles )
         {
             s.append( "    <th>" + role.getName() + "</th>\n" );
         }
@@ -381,14 +381,14 @@ public final class SecurityVerifier {
         s.append( "</thead>\n" );
         s.append( "<tbody>\n" );
 
-        WebContainerAuthorizer wca = (WebContainerAuthorizer) authorizer;
+        final WebContainerAuthorizer wca = (WebContainerAuthorizer) authorizer;
         for( int i = 0; i < CONTAINER_ACTIONS.length; i++ )
         {
-            String action = CONTAINER_ACTIONS[i];
-            String jsp = CONTAINER_JSPS[i];
+            final String action = CONTAINER_ACTIONS[i];
+            final String jsp = CONTAINER_JSPS[i];
 
             // Print whether the page is constrained for each role
-            boolean allowsAnonymous = !wca.isConstrained( jsp, Role.ALL );
+            final boolean allowsAnonymous = !wca.isConstrained( jsp, Role.ALL );
             s.append( "  <tr>\n" );
             s.append( "    <td>" + action + "</td>\n" );
             s.append( "    <td>" + jsp + "</td>\n" );
@@ -399,9 +399,9 @@ public final class SecurityVerifier {
             s.append( "\"" );
             s.append( allowsAnonymous ? BG_GREEN + ">" : BG_RED + ">" );
             s.append( "&nbsp;</td>\n" );
-            for( Principal role : roles )
+            for( final Principal role : roles )
             {
-                boolean allowed = allowsAnonymous || wca.isConstrained( jsp, (Role)role );
+                final boolean allowed = allowsAnonymous || wca.isConstrained( jsp, (Role)role );
                 s.append( "    <td title=\"" );
                 s.append( allowed ? "ALLOW: " : "DENY: " );
                 s.append( jsp );
@@ -440,7 +440,7 @@ public final class SecurityVerifier {
      */
     public Principal[] webContainerRoles() throws WikiException
     {
-        Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
+        final Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
         if ( authorizer instanceof WebContainerAuthorizer )
         {
             return ( (WebContainerAuthorizer) authorizer ).getRoles();
@@ -455,15 +455,15 @@ public final class SecurityVerifier {
      */
     protected void verifyPolicyAndContainerRoles() throws WikiException
     {
-        Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
-        Principal[] containerRoles = authorizer.getRoles();
+        final Authorizer authorizer = m_engine.getAuthorizationManager().getAuthorizer();
+        final Principal[] containerRoles = authorizer.getRoles();
         boolean missing = false;
-        for( Principal principal : m_policyPrincipals )
+        for( final Principal principal : m_policyPrincipals )
         {
             if ( principal instanceof Role )
             {
-                Role role = (Role) principal;
-                boolean isContainerRole = ArrayUtils.contains( containerRoles, role );
+                final Role role = (Role) principal;
+                final boolean isContainerRole = ArrayUtils.contains( containerRoles, role );
                 if ( !Role.isBuiltInRole( role ) && !isContainerRole )
                 {
                     m_session.addMessage( ERROR_ROLES, "Role '" + role.getName() + "' is defined in security policy but not in web.xml." );
@@ -483,13 +483,13 @@ public final class SecurityVerifier {
      */
     protected void verifyGroupDatabase()
     {
-        GroupManager mgr = m_engine.getGroupManager();
+        final GroupManager mgr = m_engine.getGroupManager();
         GroupDatabase db = null;
         try
         {
             db = m_engine.getGroupManager().getGroupDatabase();
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_GROUPS, "Could not retrieve GroupManager: " + e.getMessage() );
         }
@@ -520,24 +520,24 @@ public final class SecurityVerifier {
         int oldGroupCount = 0;
         try
         {
-            Group[] groups = db.groups();
+            final Group[] groups = db.groups();
             oldGroupCount = groups.length;
             m_session.addMessage( INFO_GROUPS, "The group database contains " + oldGroupCount + " groups." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_GROUPS, "Could not obtain a list of current groups: " + e.getMessage() );
             return;
         }
 
         // Try adding a bogus group with random name
-        String name = "TestGroup" + System.currentTimeMillis();
+        final String name = "TestGroup" + System.currentTimeMillis();
         Group group = null;
         try
         {
             // Create dummy test group
             group = mgr.parseGroup( name, "", true );
-            Principal user = new WikiPrincipal( "TestUser" );
+            final Principal user = new WikiPrincipal( "TestUser" );
             group.add( user );
             db.save( group, new WikiPrincipal("SecurityVerifier") );
 
@@ -549,7 +549,7 @@ public final class SecurityVerifier {
             }
             m_session.addMessage( INFO_GROUPS, "The group database allows new groups to be created, as it should." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_GROUPS, "Could not add a group to the database: " + e.getMessage() );
             return;
@@ -566,7 +566,7 @@ public final class SecurityVerifier {
             }
             m_session.addMessage( INFO_GROUPS, "The group database allows groups to be deleted, as it should." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_GROUPS, "Could not delete a test group from the database: " + e.getMessage() );
             return;
@@ -584,7 +584,7 @@ public final class SecurityVerifier {
     protected void verifyJaas()
     {
         // Verify that the specified JAAS moduie corresponds to a class we can load successfully.
-        String jaasClass = m_engine.getWikiProperties().getProperty( AuthenticationManager.PROP_LOGIN_MODULE );
+        final String jaasClass = m_engine.getWikiProperties().getProperty( AuthenticationManager.PROP_LOGIN_MODULE );
         if ( jaasClass == null || jaasClass.length() == 0 )
         {
             m_session.addMessage( ERROR_JAAS, "The value of the '" + AuthenticationManager.PROP_LOGIN_MODULE +
@@ -601,7 +601,7 @@ public final class SecurityVerifier {
                                   "' specified the class '" + jaasClass + ".'" );
             c = Class.forName( jaasClass );
         }
-        catch( ClassNotFoundException e )
+        catch( final ClassNotFoundException e )
         {
             m_session.addMessage( ERROR_JAAS, "We could not find the the class '" + jaasClass + "' on the " +
             "classpath. This is fatal error." );
@@ -628,7 +628,7 @@ public final class SecurityVerifier {
      * @param property the system property to look up
      * @return the file object, or <code>null</code> if not found
      */
-    protected File getFileFromProperty( String property )
+    protected File getFileFromProperty( final String property )
     {
         String propertyValue = null;
         try
@@ -659,15 +659,15 @@ public final class SecurityVerifier {
                 {
                   propertyValue = "file:" + propertyValue;
                 }
-                URL url = new URL( propertyValue );
-                File file = new File( url.getPath() );
+                final URL url = new URL( propertyValue );
+                final File file = new File( url.getPath() );
                 if ( file.exists() )
                 {
                     m_session.addMessage( "Info." + property, "File '" + propertyValue + "' exists in the filesystem." );
                     return file;
                 }
             }
-            catch( MalformedURLException e )
+            catch( final MalformedURLException e )
             {
                 // Swallow exception because we can't find it anyway
             }
@@ -675,7 +675,7 @@ public final class SecurityVerifier {
                     + "' doesn't seem to exist. This might be a problem." );
             return null;
         }
-        catch( SecurityException e )
+        catch( final SecurityException e )
         {
             m_session.addMessage( "Error." + property, "We could not read system property '" + property
                     + "'. This is probably because you are running with a security manager." );
@@ -690,73 +690,59 @@ public final class SecurityVerifier {
      * represents a valid policy.
      */
     @SuppressWarnings("unchecked")
-    protected void verifyPolicy()
-    {
+    protected void verifyPolicy() {
         // Look up the policy file and set the status text.
-        URL policyURL = AuthenticationManager.findConfigFile( m_engine, AuthorizationManager.DEFAULT_POLICY );
+        final URL policyURL = m_engine.findConfigFile( AuthorizationManager.DEFAULT_POLICY );
         String path = policyURL.getPath();
-        if ( path.startsWith("file:") )
-        {
+        if ( path.startsWith("file:") ) {
             path = path.substring( 5 );
         }
-        File policyFile = new File( path );
+        final File policyFile = new File( path );
 
         // Next, verify the policy
-        try
-        {
+        try {
             // Get the file
-            PolicyReader policy = new PolicyReader( policyFile );
+            final PolicyReader policy = new PolicyReader( policyFile );
             m_session.addMessage( INFO_POLICY, "The security policy '" + policy.getFile() + "' exists." );
 
             // See if there is a keystore that's valid
-            KeyStore ks = policy.getKeyStore();
-            if ( ks == null )
-            {
+            final KeyStore ks = policy.getKeyStore();
+            if ( ks == null ) {
                 m_session.addMessage( WARNING_POLICY,
                     "Policy file does not have a keystore... at least not one that we can locate. If your policy file " +
                     "does not contain any 'signedBy' blocks, this is probably ok." );
-            }
-            else
-            {
+            } else {
                 m_session.addMessage( INFO_POLICY,
                     "The security policy specifies a keystore, and we were able to locate it in the filesystem." );
             }
 
             // Verify the file
             policy.read();
-            List<Exception> errors = policy.getMessages();
-            if ( errors.size() > 0 )
-            {
-                for( Exception e : errors )
-                {
+            final List<Exception> errors = policy.getMessages();
+            if ( errors.size() > 0 ) {
+                for( final Exception e : errors ) {
                     m_session.addMessage( ERROR_POLICY, e.getMessage() );
                 }
-            }
-            else
-            {
+            } else {
                 m_session.addMessage( INFO_POLICY, "The security policy looks fine." );
                 m_isSecurityPolicyConfigured = true;
             }
 
             // Stash the unique principals mentioned in the file,
             // plus our standard roles.
-            Set<Principal> principals = new LinkedHashSet<Principal>();
+            final Set<Principal> principals = new LinkedHashSet<>();
             principals.add( Role.ALL );
             principals.add( Role.ANONYMOUS );
             principals.add( Role.ASSERTED );
             principals.add( Role.AUTHENTICATED );
-            ProtectionDomain[] domains = policy.getProtectionDomains();
-            for ( ProtectionDomain domain : domains )
-            {
-                for( Principal principal : domain.getPrincipals() )
-                {
+            final ProtectionDomain[] domains = policy.getProtectionDomains();
+            for ( final ProtectionDomain domain : domains ) {
+                for( final Principal principal : domain.getPrincipals() ) {
                     principals.add( principal );
                 }
             }
             m_policyPrincipals = principals.toArray( new Principal[principals.size()] );
-        }
-        catch( IOException e )
-        {
+        } catch( final IOException e ) {
             m_session.addMessage( ERROR_POLICY, e.getMessage() );
         }
     }
@@ -769,21 +755,21 @@ public final class SecurityVerifier {
      * @return the result, based on consultation with the active Java security
      *         policy
      */
-    protected boolean verifyStaticPermission( Principal principal, final Permission permission )
+    protected boolean verifyStaticPermission( final Principal principal, final Permission permission )
     {
-        Subject subject = new Subject();
+        final Subject subject = new Subject();
         subject.getPrincipals().add( principal );
-        boolean allowedByGlobalPolicy = ((Boolean)
+        final boolean allowedByGlobalPolicy = ((Boolean)
             Subject.doAsPrivileged( subject, new PrivilegedAction<Object>()
             {
-                public Object run()
+                @Override public Object run()
                 {
                     try
                     {
                         AccessController.checkPermission( permission );
                         return Boolean.TRUE;
                     }
-                    catch ( AccessControlException e )
+                    catch ( final AccessControlException e )
                     {
                         return Boolean.FALSE;
                     }
@@ -796,7 +782,7 @@ public final class SecurityVerifier {
         }
 
         // Check local policy
-        Principal[] principals = new Principal[]{ principal };
+        final Principal[] principals = new Principal[]{ principal };
         return m_engine.getAuthorizationManager().allowedByLocalPolicy( principals, permission );
     }
 
@@ -806,7 +792,7 @@ public final class SecurityVerifier {
      */
     protected void verifyUserDatabase()
     {
-        UserDatabase db = m_engine.getUserManager().getUserDatabase();
+        final UserDatabase db = m_engine.getUserManager().getUserDatabase();
 
         // Check for obvious error conditions
         if ( db == null )
@@ -832,21 +818,21 @@ public final class SecurityVerifier {
         int oldUserCount = 0;
         try
         {
-            Principal[] users = db.getWikiNames();
+            final Principal[] users = db.getWikiNames();
             oldUserCount = users.length;
             m_session.addMessage( INFO_DB, "The user database contains " + oldUserCount + " users." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_DB, "Could not obtain a list of current users: " + e.getMessage() );
             return;
         }
 
         // Try adding a bogus user with random name
-        String loginName = "TestUser" + System.currentTimeMillis();
+        final String loginName = "TestUser" + System.currentTimeMillis();
         try
         {
-            UserProfile profile = db.newProfile();
+            final UserProfile profile = db.newProfile();
             profile.setEmail( "jspwiki.tests@mailinator.com" );
             profile.setLoginName( loginName );
             profile.setFullname( "FullName"+loginName );
@@ -861,7 +847,7 @@ public final class SecurityVerifier {
             }
             m_session.addMessage( INFO_DB, "The user database allows new users to be created, as it should." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_DB, "Could not add a test user to the database: " + e.getMessage() );
             return;
@@ -878,7 +864,7 @@ public final class SecurityVerifier {
             }
             m_session.addMessage( INFO_DB, "The user database allows users to be deleted, as it should." );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             m_session.addMessage( ERROR_DB, "Could not delete a test user to the database: " + e.getMessage() );
             return;


[jspwiki] 08/38: remove old references to AuthenticationManager on Engine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit f14bedcf1ec39b2804fc60eecc043dbfae6ec465
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 17:20:36 2020 +0100

    remove old references to AuthenticationManager on Engine
---
 jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
index fdcb187..f88eb88 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -21,7 +21,6 @@ package org.apache.wiki.api.core;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WatchDog;
 import org.apache.wiki.api.exceptions.ProviderException;
-import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.event.WikiEventListener;
 
 import javax.servlet.ServletContext;
@@ -208,7 +207,7 @@ public interface Engine {
      * @return the URL to the file
      */
     default URL findConfigFile( final String name ) {
-        Logger.getLogger( AuthenticationManager.class ).info( "looking for " + name + " inside WEB-INF " );
+        Logger.getLogger( Engine.class ).info( "looking for " + name + " inside WEB-INF " );
         // Try creating an absolute path first
         File defaultFile = null;
         if( getRootPath() != null ) {
@@ -237,7 +236,7 @@ public interface Engine {
             tmpFile.deleteOnExit();
             Logger.getLogger( Engine.class ).info( "looking for /" + name + " on classpath" );
             //  create a tmp file of the policy loaded as an InputStream and return the URL to it
-            try( final InputStream is = AuthenticationManager.class.getResourceAsStream( "/" + name );
+            try( final InputStream is = Engine.class.getResourceAsStream( "/" + name );
                     final OutputStream os = new FileOutputStream( tmpFile ) ) {
                 if( is == null ) {
                     throw new FileNotFoundException( name + " not found" );


[jspwiki] 16/38: use Engine instead of WikiEngine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 79af4e4d09fabb52ac7013427d02bcac47a0544d
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 20:19:23 2020 +0100

    use Engine instead of WikiEngine
---
 .../apache/wiki/workflow/DefaultWorkflowManager.java  | 19 ++++++++++---------
 .../org/apache/wiki/workflow/WorkflowManager.java     |  4 ++--
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java
index fac5361..0ace9d9 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java
@@ -18,9 +18,10 @@
  */
 package org.apache.wiki.workflow;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.acl.UnresolvedPrincipal;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WorkflowEvent;
@@ -44,10 +45,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
 public class DefaultWorkflowManager implements WorkflowManager {
 
     private final DecisionQueue m_queue = new DecisionQueue();
-    private final Set<Workflow> m_workflows;
-    private final Map<String, Principal> m_approvers;
-    private final List<Workflow> m_completed;
-    private WikiEngine m_engine = null;
+    private final Set< Workflow > m_workflows;
+    private final Map< String, Principal > m_approvers;
+    private final List< Workflow > m_completed;
+    private Engine m_engine = null;
 
     /**
      * Constructs a new WorkflowManager, with an empty workflow cache. New Workflows are automatically assigned unique identifiers,
@@ -93,7 +94,7 @@ public class DefaultWorkflowManager implements WorkflowManager {
      * {@inheritDoc}
      */
     @Override
-    public void initialize( final WikiEngine engine, final Properties props ) {
+    public void initialize( final Engine engine, final Properties props ) {
         m_engine = engine;
 
         // Identify the workflows requiring approvals
@@ -134,7 +135,7 @@ public class DefaultWorkflowManager implements WorkflowManager {
         // Try to resolve UnresolvedPrincipals
         if ( approver instanceof UnresolvedPrincipal ) {
             final String name = approver.getName();
-            approver = m_engine.getAuthorizationManager().resolvePrincipal( name );
+            approver = m_engine.getManager( AuthorizationManager.class ).resolvePrincipal( name );
 
             // If still unresolved, throw exception; otherwise, freshen our cache
             if ( approver instanceof UnresolvedPrincipal ) {
@@ -151,7 +152,7 @@ public class DefaultWorkflowManager implements WorkflowManager {
      *
      * @return the wiki engine
      */
-    protected WikiEngine getEngine() {
+    protected Engine getEngine() {
         if ( m_engine == null ) {
             throw new IllegalStateException( "WikiEngine cannot be null; please initialize WorkflowManager first." );
         }
@@ -163,7 +164,7 @@ public class DefaultWorkflowManager implements WorkflowManager {
      *
      * @return the decision queue
      */
-    public DecisionQueue getDecisionQueue()
+    @Override public DecisionQueue getDecisionQueue()
     {
         return m_queue;
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowManager.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowManager.java
index e82e02c..60858db 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowManager.java
@@ -18,8 +18,8 @@
  */
 package org.apache.wiki.workflow;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.event.WikiEventListener;
 
@@ -108,7 +108,7 @@ public interface WorkflowManager extends WikiEventListener {
      * @param engine the wiki engine to associate with this WorkflowManager
      * @param props the wiki engine's properties
      */
-    void initialize( WikiEngine engine, Properties props );
+    void initialize( Engine engine, Properties props );
 
     /**
      * Returns <code>true</code> if a workflow matching a particular key contains an approval step.


[jspwiki] 38/38: 2.11.0-M7-git-09

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit b03d0b5cceb56f2b7a47dc983a41581afcd1ff40
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:51:50 2020 +0100

    2.11.0-M7-git-09
---
 ChangeLog.md                                          | 19 ++++++++++++++++++-
 .../src/main/java/org/apache/wiki/Release.java        |  2 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/ChangeLog.md b/ChangeLog.md
index aecb3ad..3c4aca1 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -17,6 +17,23 @@ specific language governing permissions and limitations
 under the License.
 -->
 
+**2020-02-24  Juan Pablo Santos (juanpablo AT apache DOT org)**
+
+* _2.11.0-M7-git-09_
+
+* [JSPWIKI-120](https://issues.apache.org/jira/browse/JSPWIKI-120):
+    * Use `Engine` inside `WikiContext`, `WikiSession`, `WikiPage`, `Attachment` and `SessionMonitor`.
+        * e.g. `WikiContext#getEngine()` now returns an `Engine` instead of a `WikiEngine`. To retrieve a manager 
+        from it just use `Engine#getManager( DesiredManager.class )`. See implementations on `getXXXManager()`  
+        methods on `WikiEngine` for details. 
+    * `WikiProvider#initialize(..)` receives an `Engine` instead of a `WikiEngine`.
+    * `Engine` gains an `adapt( Class< E > cls )`, to facilitate downcasting to `Engine` implementation classes.
+    * Removed `Engine#getCurrentWatchDog()`, as it was a pass-through and introduced a package cycle; use instead 
+    `WatchDog#getCurrentWathDog( Engine )`. 
+    `o.a.wiki` and `o.a.w.event`. To obtain the `WikiEngine` reference from the event just use `getSrc()`
+    * Rename + extract interfaces from `AttachmentManager`, `AuthenticationManager`, `AuthorizationManager`, 
+    `GroupManager` and `UserManager`.
+
 **2020-02-20  Juan Pablo Santos (juanpablo AT apache DOT org)**
 
 * _2.11.0-M7-git-08_
@@ -648,7 +665,7 @@ and also scans `.md` and `.xml` files.
     * to compare WikiPages use `wikiPage.compareTo( anotherWikiPage );`
     * `sortPages` methods are also gone, as an alternative you can use something along these lines (see
     `AttachmentManager#listAttachments` for another example):
-    `Collections.< WikiPage >sort( pages, Comparator.comparing( WikiPage::getName, m_engine.getPageManager().getPageSorter() ) );`
+    `Collections.< WikiPage >sort( pages, Comparator.comparing( WikiPage::getName, m_engine.getManager( PageManager.class ).getPageSorter() ) );`
     * as a side effect of this change, `AbstractReferalPlugin#filter[AndSort]Collection` methods operate with
     `Collection< String >` instead of with plain `Collection` (except for `RecentChangesPlugin`, plugins
     inheriting this method were already doing it), custom plugins inheriting this method will have to use
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/Release.java b/jspwiki-main/src/main/java/org/apache/wiki/Release.java
index a06d3ab..05e2f55 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/Release.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/Release.java
@@ -69,7 +69,7 @@ public final class Release {
      *  <p>
      *  If the build identifier is empty, it is not added.
      */
-    public static final String     BUILD         = "git-08";
+    public static final String     BUILD         = "git-09";
 
     /**
      *  This is the generic version string you should use when printing out the version.  It is of


[jspwiki] 03/38: inherit javadoc

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 6039095f457ff666bc37170b1378be93f6c8f20a
Author: juanpablo <ju...@apache.org>
AuthorDate: Wed Feb 19 20:36:55 2020 +0100

    inherit javadoc
---
 .../java/org/apache/wiki/attachment/DefaultAttachmentManager.java  | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
index 4ac6c5d..688c3e0 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
@@ -47,10 +47,9 @@ import java.util.Properties;
 
 
 /**
- *  Provides facilities for handling attachments.  All attachment handling goes through this class.
- *  <p>
- *  The AttachmentManager provides a facade towards the current WikiAttachmentProvider that is in use.
- *  It is created by the WikiEngine as a singleton object, and can be requested through the WikiEngine.
+ *  Default implementation for {@link AttachmentManager}
+ *
+ * {@inheritDoc}
  *
  *  @since 1.9.28
  */


[jspwiki] 32/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (9)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit f44500b650582c9977b871472c15586dad8f5c72
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:16:57 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (9)
---
 .../org/apache/wiki/ui/DefaultCommandResolver.java |  5 +-
 .../src/main/java/org/apache/wiki/ui/Editor.java   |  2 +-
 .../java/org/apache/wiki/ui/admin/AdminBean.java   |  4 +-
 .../org/apache/wiki/ui/admin/SimpleAdminBean.java  | 22 +++---
 .../apache/wiki/ui/admin/WikiFormAdminBean.java    | 23 +++---
 .../org/apache/wiki/ui/admin/beans/CoreBean.java   | 17 ++---
 .../org/apache/wiki/ui/admin/beans/FilterBean.java | 24 +++----
 .../org/apache/wiki/ui/admin/beans/ModuleBean.java | 30 ++++----
 .../wiki/ui/admin/beans/PlainEditorAdminBean.java  | 57 +++++++--------
 .../org/apache/wiki/ui/admin/beans/PluginBean.java | 24 +++----
 .../wiki/ui/admin/beans/SearchManagerBean.java     | 81 ++++++++++------------
 .../org/apache/wiki/ui/admin/beans/UserBean.java   | 51 +++++++-------
 12 files changed, 161 insertions(+), 179 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultCommandResolver.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultCommandResolver.java
index 65348ed..ce25685 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultCommandResolver.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/DefaultCommandResolver.java
@@ -25,6 +25,7 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.auth.GroupPrincipal;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.util.TextUtil;
 
@@ -304,7 +305,7 @@ public final class DefaultCommandResolver implements CommandResolver {
             }
         }
 
-        WikiPage wikipage = m_engine.getPageManager().getPage( page, version );
+        WikiPage wikipage = m_engine.getManager( PageManager.class ).getPage( page, version );
         if ( wikipage == null ) {
             page = MarkupParser.cleanLink( page );
             wikipage = new WikiPage( m_engine, page );
@@ -324,7 +325,7 @@ public final class DefaultCommandResolver implements CommandResolver {
         if ( m_specialPages.containsKey( page ) ) {
             return true;
         }
-        return m_engine.getPageManager().pageExists( page );
+        return m_engine.getManager( PageManager.class ).pageExists( page );
     }
 
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/Editor.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/Editor.java
index 9c35e45..17df105 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/Editor.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/Editor.java
@@ -34,7 +34,7 @@ public class Editor {
     public Editor( final WikiContext wikiContext, final String editorName ) {
         m_wikiContext = wikiContext;
         m_editorName = editorName;
-        m_editorManager = wikiContext.getEngine().getEditorManager();
+        m_editorManager = wikiContext.getEngine().getManager( EditorManager.class );
     }
 
     public String getName() {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/AdminBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/AdminBean.java
index 92bb7f8..1805824 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/AdminBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/AdminBean.java
@@ -18,7 +18,7 @@
  */
 package org.apache.wiki.ui.admin;
 
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.ui.GenericHTTPHandler;
 
 
@@ -33,7 +33,7 @@ public interface AdminBean extends GenericHTTPHandler {
     int CORE    = 1;
     int EDITOR  = 2;
     
-    void initialize( WikiEngine engine );
+    void initialize( Engine engine );
     
     /**
      *  Return a human-readable title for this AdminBean.
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/SimpleAdminBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/SimpleAdminBean.java
index a5a9c34..b1e0ed5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/SimpleAdminBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/SimpleAdminBean.java
@@ -20,7 +20,7 @@ package org.apache.wiki.ui.admin;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.management.SimpleMBean;
 
 import javax.management.MBeanAttributeInfo;
@@ -41,7 +41,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
      *  Provides access to a WikiEngine instance to which this AdminBean
      *  belongs to.
      */
-    protected WikiEngine m_engine;
+    protected Engine m_engine;
     
     /**
      *  Constructor reserved for subclasses only.
@@ -56,7 +56,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
     /**
      *  Initialize the AdminBean by setting up a WikiEngine instance internally.
      */
-    public void initialize( WikiEngine engine )
+    @Override public void initialize( final Engine engine )
     {
         m_engine = engine;
     }
@@ -67,11 +67,11 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
      *  attribute is read-only, a readonly input widget is created.
      *  The value is determined by the toString() method of the attribute.
      */
-    public String doGet(WikiContext context)
+    @Override public String doGet( final WikiContext context)
     {
-        MBeanInfo info = getMBeanInfo();
-        MBeanAttributeInfo[] attributes = info.getAttributes();
-        StringBuilder sb = new StringBuilder();
+        final MBeanInfo info = getMBeanInfo();
+        final MBeanAttributeInfo[] attributes = info.getAttributes();
+        final StringBuilder sb = new StringBuilder();
         
         for( int i = 0; i < attributes.length; i++ )
         {
@@ -81,7 +81,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
             
             try
             {
-                Object value = getAttribute( attributes[i].getName() );
+                final Object value = getAttribute( attributes[i].getName() );
                 if( attributes[i].isWritable() )
                 {
                     sb.append( "<input type='text' name='question' size='30' value='"+value+"' />\n" );
@@ -91,7 +91,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
                     sb.append( "<input type='text' class='readonly' readonly='true' size='30' value='"+value+"' />\n" );
                 }
             }
-            catch( Exception e )
+            catch( final Exception e )
             {
                 sb.append("Exception: "+e.getMessage());
             }
@@ -106,7 +106,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
     /**
      *  Not implemented yet.
      */
-    public String doPost(WikiContext context)
+    @Override public String doPost( final WikiContext context)
     {
         // TODO Auto-generated method stub
         return null;
@@ -116,7 +116,7 @@ public abstract class SimpleAdminBean extends SimpleMBean implements AdminBean
      *  By default, this method returns the class name of the bean.  This is
      *  suitable, if you have a singleton bean.
      */
-    public String getId()
+    @Override public String getId()
     {
         return getClass().getName();
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/WikiFormAdminBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/WikiFormAdminBean.java
index dd11b18..3ca2668 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/WikiFormAdminBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/WikiFormAdminBean.java
@@ -18,16 +18,15 @@
  */
 package org.apache.wiki.ui.admin;
 
-import java.io.IOException;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.parser.WikiDocument;
 import org.apache.wiki.render.RenderingManager;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
 /**
  *  This class is still experimental.
  *
@@ -39,21 +38,21 @@ public abstract class WikiFormAdminBean
     
     public abstract void handleResponse( WikiContext context, Map< ?, ? > params );
 
-    public String doGet(WikiContext context)
+    @Override public String doGet( final WikiContext context)
     {
         String result = "";
         
-        String wikiMarkup = getForm(context);
+        final String wikiMarkup = getForm(context);
         
-        RenderingManager mgr = context.getEngine().getRenderingManager();
+        final RenderingManager mgr = context.getEngine().getManager( RenderingManager.class );
         
-        WikiDocument doc;
+        final WikiDocument doc;
         try
         {
             doc = mgr.getParser( context, wikiMarkup ).parse();
             result = mgr.getHTML(context, doc);
         }
-        catch (IOException e)
+        catch ( final IOException e)
         {
             // TODO Auto-generated catch block
             e.printStackTrace();
@@ -62,7 +61,7 @@ public abstract class WikiFormAdminBean
         return result;
     }
 
-    public String handlePost(WikiContext context, HttpServletRequest req, HttpServletResponse resp)
+    public String handlePost( final WikiContext context, final HttpServletRequest req, final HttpServletResponse resp)
     {
         return null;
         // FIXME: Not yet implemented
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/CoreBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/CoreBean.java
index 0a8e7d2..7d201df 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/CoreBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/CoreBean.java
@@ -19,7 +19,8 @@
 package org.apache.wiki.ui.admin.beans;
 
 import org.apache.wiki.Release;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.ui.admin.SimpleAdminBean;
 
 import javax.management.NotCompliantMBeanException;
@@ -33,7 +34,7 @@ public class CoreBean extends SimpleAdminBean {
     private static final String[] ATTRIBUTES = { "pages", "version" };
     private static final String[] METHODS = { };
 
-    public CoreBean( final WikiEngine engine ) throws NotCompliantMBeanException {
+    public CoreBean( final Engine engine ) throws NotCompliantMBeanException {
         m_engine = engine;
     }
 
@@ -43,7 +44,7 @@ public class CoreBean extends SimpleAdminBean {
      *  @return the page content
      */
     public int getPages() {
-        return m_engine.getPageManager().getTotalPageCount();
+        return m_engine.getManager( PageManager.class ).getTotalPageCount();
     }
 
     public String getPagesDescription()
@@ -61,27 +62,27 @@ public class CoreBean extends SimpleAdminBean {
         return "The JSPWiki engine version";
     }
 
-    public String getTitle()
+    @Override public String getTitle()
     {
         return "Core bean";
     }
 
-    public int getType()
+    @Override public int getType()
     {
         return CORE;
     }
 
-    public String getId()
+    @Override public String getId()
     {
         return "corebean";
     }
 
-    public String[] getAttributeNames()
+    @Override public String[] getAttributeNames()
     {
         return ATTRIBUTES;
     }
 
-    public String[] getMethodNames()
+    @Override public String[] getMethodNames()
     {
         return METHODS;
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/FilterBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/FilterBean.java
index 8d952bc..3b47696 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/FilterBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/FilterBean.java
@@ -18,34 +18,34 @@
 */
 package org.apache.wiki.ui.admin.beans;
 
-import java.util.Collection;
-
-import javax.management.NotCompliantMBeanException;
-
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.engine.FilterManager;
 import org.apache.wiki.modules.WikiModuleInfo;
 import org.apache.wiki.util.XHTML;
 import org.apache.wiki.util.XhtmlUtil;
 import org.jdom2.Element;
 
+import javax.management.NotCompliantMBeanException;
+import java.util.Collection;
+
 
 public class FilterBean extends ModuleBean {
 
-    public FilterBean( WikiEngine engine ) throws NotCompliantMBeanException {
+    public FilterBean( final Engine engine ) throws NotCompliantMBeanException {
         super( engine );
     }
 
     /**
      * {@inheritDoc}
      */
-    public String getTitle() {
+    @Override public String getTitle() {
         return "Filters";
     }
 
     /**
      * {@inheritDoc}
      */
-    public int getType() {
+    @Override public int getType() {
         return CORE;
     }
 
@@ -54,7 +54,7 @@ public class FilterBean extends ModuleBean {
      */
     @Override
     protected Collection< WikiModuleInfo > modules() {
-        return m_engine.getFilterManager().modules();
+        return m_engine.getManager( FilterManager.class ).modules();
     }
 
     /**
@@ -62,7 +62,7 @@ public class FilterBean extends ModuleBean {
      */
     @Override
     protected Element heading() {
-        Element trHead = XhtmlUtil.element( XHTML.tr );
+        final Element trHead = XhtmlUtil.element( XHTML.tr );
         trHead.addContent( XhtmlUtil.element( XHTML.th ).addContent( "Name" ) )
               .addContent( XhtmlUtil.element( XHTML.th ).addContent( "Author" ) )
               .addContent( XhtmlUtil.element( XHTML.th ).addContent( "Notes" ) );
@@ -73,8 +73,8 @@ public class FilterBean extends ModuleBean {
      * {@inheritDoc}
      */
     @Override
-    protected Element rowBody( WikiModuleInfo info ) {
-        Element tr = XhtmlUtil.element( XHTML.tr );
+    protected Element rowBody( final WikiModuleInfo info ) {
+        final Element tr = XhtmlUtil.element( XHTML.tr );
         tr.addContent( XhtmlUtil.element( XHTML.td ).addContent( info.getName() ) )
           .addContent( XhtmlUtil.element( XHTML.td ).addContent( info.getAuthor() ) )
           .addContent( XhtmlUtil.element( XHTML.td ).addContent( validModuleVersion( info ) ) );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/ModuleBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/ModuleBean.java
index f6340ad..aa84a5f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/ModuleBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/ModuleBean.java
@@ -21,7 +21,7 @@ package org.apache.wiki.ui.admin.beans;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.wiki.Release;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.modules.WikiModuleInfo;
 import org.apache.wiki.ui.admin.SimpleAdminBean;
 import org.apache.wiki.util.XHTML;
@@ -37,37 +37,37 @@ public abstract class ModuleBean extends SimpleAdminBean {
 
     private static final String VER_WARNING = "<span class='warning'>This module is not compatible with this version of JSPWiki.</span>";
 
-    public ModuleBean( WikiEngine engine ) throws NotCompliantMBeanException {
+    public ModuleBean( final Engine engine ) throws NotCompliantMBeanException {
         m_engine = engine;
     }
 
     /**
      * {@inheritDoc}
      */
-    public String[] getAttributeNames() {
+    @Override public String[] getAttributeNames() {
         return new String[0];
     }
 
     /**
      * {@inheritDoc}
      */
-    public String[] getMethodNames() {
+    @Override public String[] getMethodNames() {
         return new String[0];
     }
 
     /**
      * {@inheritDoc}
      */
-    public String doGet( WikiContext context ) {
-        Collection< WikiModuleInfo > filters = modules();
-        Element root = title();
-        Element tb = containerForModuleDetail( root );
+    @Override public String doGet( final WikiContext context ) {
+        final Collection< WikiModuleInfo > filters = modules();
+        final Element root = title();
+        final Element tb = containerForModuleDetail( root );
 
-        Element trHead = heading();
+        final Element trHead = heading();
         tb.addContent( trHead );
 
-        for( WikiModuleInfo info : filters ) {
-            Element tr = rowBody( info );
+        for( final WikiModuleInfo info : filters ) {
+            final Element tr = rowBody( info );
             tb.addContent( tr );
         }
 
@@ -75,13 +75,13 @@ public abstract class ModuleBean extends SimpleAdminBean {
     }
 
     protected Element title() {
-        Element root = XhtmlUtil.element( XHTML.div );
+        final Element root = XhtmlUtil.element( XHTML.div );
         root.addContent( XhtmlUtil.element( XHTML.h4 ).addContent( getTitle() ) );
         return root;
     }
 
-    protected Element containerForModuleDetail( Element root ) {
-        Element tb = XhtmlUtil.element( XHTML.table ).setAttribute( "border", "1" );
+    protected Element containerForModuleDetail( final Element root ) {
+        final Element tb = XhtmlUtil.element( XHTML.table ).setAttribute( "border", "1" );
         root.addContent( tb );
         return tb;
     }
@@ -108,7 +108,7 @@ public abstract class ModuleBean extends SimpleAdminBean {
      */
     protected abstract Element rowBody( WikiModuleInfo module );
 
-    protected String validModuleVersion( WikiModuleInfo info ) {
+    protected String validModuleVersion( final WikiModuleInfo info ) {
         return Release.isNewerOrEqual( info.getMinVersion() ) && Release.isOlderOrEqual( info.getMaxVersion() )
                ? StringUtils.EMPTY
                : VER_WARNING;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PlainEditorAdminBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PlainEditorAdminBean.java
index b2fc5ea..0ac1d9b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PlainEditorAdminBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PlainEditorAdminBean.java
@@ -18,44 +18,39 @@
  */
 package org.apache.wiki.ui.admin.beans;
 
-import javax.management.NotCompliantMBeanException;
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.ui.admin.AdminBean;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.management.SimpleMBean;
+import org.apache.wiki.ui.admin.AdminBean;
 import org.apache.wiki.util.TextUtil;
 
+import javax.management.NotCompliantMBeanException;
+import javax.servlet.http.HttpServletRequest;
+
 /**
  *  This class is still experimental.
  *  
  *
  */
-public class PlainEditorAdminBean
-    extends SimpleMBean
-    implements AdminBean
-{
-    private static final String TEMPLATE = 
-        "<div>"+
-        "<input type='checkbox' id='ajax' %checked/>Use AJAX?<br />"+
-        "<input type='submit' value='Submit'/>"+
-        "%messages"+
-        "</div>"
-        ;
+public class PlainEditorAdminBean extends SimpleMBean implements AdminBean {
+
+    private static final String TEMPLATE = "<div>"+
+                                           "<input type='checkbox' id='ajax' %checked/>Use AJAX?<br />" +
+                                           "<input type='submit' value='Submit'/>" +
+                                           "%messages" +
+                                           "</div>";
     
     private boolean m_checked;
     
     private static final String[] ATTRIBUTES = {"title","checked"};
     private static final String[] METHODS    = {};
     
-    public PlainEditorAdminBean() throws NotCompliantMBeanException
-    {
+    public PlainEditorAdminBean() throws NotCompliantMBeanException {
     }
     
-    public String doGet(WikiContext context)
+    @Override public String doGet( final WikiContext context)
     {
-        HttpServletRequest req = context.getHttpRequest();
+        final HttpServletRequest req = context.getHttpRequest();
         
         if( req != null && req.getMethod().equals("POST") && getTitle().equals( req.getParameter("form") ) )
         {
@@ -69,11 +64,11 @@ public class PlainEditorAdminBean
         return base;
     }
 
-    public String doPost( WikiContext context )
+    @Override public String doPost( final WikiContext context )
     {
-        HttpServletRequest req = context.getHttpRequest();
+        final HttpServletRequest req = context.getHttpRequest();
         
-        boolean checked = "checked".equals( req.getParameter( "id" ) );
+        final boolean checked = "checked".equals( req.getParameter( "id" ) );
         
         // Make changes
         
@@ -85,12 +80,12 @@ public class PlainEditorAdminBean
         return base;
     }
     
-    public String getTitle()
+    @Override public String getTitle()
     {
         return "Plain editor";
     }
 
-    public int getType()
+    @Override public int getType()
     {
         return EDITOR;
     }
@@ -100,7 +95,7 @@ public class PlainEditorAdminBean
         return true;
     }
 
-    public String getId()
+    @Override public String getId()
     {
         return "editor.plain";
     }
@@ -110,19 +105,17 @@ public class PlainEditorAdminBean
         return m_checked;
     }
     
-    public String[] getAttributeNames()
+    @Override public String[] getAttributeNames()
     {
         return ATTRIBUTES;
     }
 
-    public String[] getMethodNames()
+    @Override public String[] getMethodNames()
     {
         return METHODS;
     }
 
-    public void initialize(WikiEngine engine)
-    {
-        // TODO Auto-generated method stub
-        
+    @Override public void initialize( final Engine engine ) {
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PluginBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PluginBean.java
index 175fe9a..704567b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PluginBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/PluginBean.java
@@ -18,35 +18,35 @@
 */
 package org.apache.wiki.ui.admin.beans;
 
-import java.util.Collection;
-
-import javax.management.NotCompliantMBeanException;
-
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.engine.PluginManager;
 import org.apache.wiki.modules.WikiModuleInfo;
 import org.apache.wiki.plugin.DefaultPluginManager.WikiPluginInfo;
 import org.apache.wiki.util.XHTML;
 import org.apache.wiki.util.XhtmlUtil;
 import org.jdom2.Element;
 
+import javax.management.NotCompliantMBeanException;
+import java.util.Collection;
+
 
 public class PluginBean extends ModuleBean {
 
-    public PluginBean( WikiEngine engine ) throws NotCompliantMBeanException {
+    public PluginBean( final Engine engine ) throws NotCompliantMBeanException {
         super( engine );
     }
 
     /**
      * {@inheritDoc}
      */
-    public String getTitle() {
+    @Override public String getTitle() {
         return "Plugins";
     }
 
     /**
      * {@inheritDoc}
      */
-    public int getType() {
+    @Override public int getType() {
         return CORE;
     }
 
@@ -55,7 +55,7 @@ public class PluginBean extends ModuleBean {
      */
     @Override
     protected Collection< WikiModuleInfo > modules() {
-        return m_engine.getPluginManager().modules();
+        return m_engine.getManager( PluginManager.class ).modules();
     }
 
     /**
@@ -63,7 +63,7 @@ public class PluginBean extends ModuleBean {
      */
     @Override
     protected Element heading() {
-        Element trHead = XhtmlUtil.element( XHTML.tr );
+        final Element trHead = XhtmlUtil.element( XHTML.tr );
         trHead.addContent( XhtmlUtil.element( XHTML.th ).addContent( "Name" ) )
               .addContent( XhtmlUtil.element( XHTML.th ).addContent( "Alias" ) )
               .addContent( XhtmlUtil.element( XHTML.th ).addContent( "Author" ) )
@@ -75,8 +75,8 @@ public class PluginBean extends ModuleBean {
      * {@inheritDoc}
      */
     @Override
-    protected Element rowBody( WikiModuleInfo plugin ) {
-        Element tr = XhtmlUtil.element( XHTML.tr );
+    protected Element rowBody( final WikiModuleInfo plugin ) {
+        final Element tr = XhtmlUtil.element( XHTML.tr );
         tr.addContent( XhtmlUtil.element( XHTML.td ).addContent( plugin.getName() ) )
           .addContent( XhtmlUtil.element( XHTML.td ).addContent( ( ( WikiPluginInfo )plugin).getAlias() ) )
           .addContent( XhtmlUtil.element( XHTML.td ).addContent( plugin.getAuthor() ) )
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/SearchManagerBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/SearchManagerBean.java
index 99ad0f9..98b6988 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/SearchManagerBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/SearchManagerBean.java
@@ -18,17 +18,19 @@
  */
 package org.apache.wiki.ui.admin.beans;
 
-import java.util.Collection;
-
-import javax.management.NotCompliantMBeanException;
-
 import org.apache.wiki.WikiBackgroundThread;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.search.SearchManager;
 import org.apache.wiki.ui.admin.SimpleAdminBean;
 import org.apache.wiki.ui.progress.ProgressItem;
+import org.apache.wiki.ui.progress.ProgressManager;
+
+import javax.management.NotCompliantMBeanException;
+import java.util.Collection;
+
 
 /**
  *  The SearchManagerBean is a simple AdminBean interface
@@ -47,23 +49,23 @@ public class SearchManagerBean extends SimpleAdminBean
 
     private WikiBackgroundThread m_updater;
 
-    public SearchManagerBean(WikiEngine engine) throws NotCompliantMBeanException
+    public SearchManagerBean( final Engine engine) throws NotCompliantMBeanException
     {
         super();
         initialize(engine);
     }
 
-    public String[] getAttributeNames()
+    @Override public String[] getAttributeNames()
     {
         return new String[0];
     }
 
-    public String[] getMethodNames()
+    @Override public String[] getMethodNames()
     {
         return METHODS;
     }
 
-    public String getTitle()
+    @Override public String getTitle()
     {
         return "Search manager";
     }
@@ -74,44 +76,40 @@ public class SearchManagerBean extends SimpleAdminBean
      *  <p>
      *  This method prevents itself from being called twice.
      */
-    public synchronized void reload()
-    {
-        if( m_updater == null )
-        {
-            m_updater = new WikiBackgroundThread(m_engine, 0) {
+    public synchronized void reload() {
+        if( m_updater == null ) {
+            m_updater = new WikiBackgroundThread( m_engine, 0 ) {
+
                 int m_count;
                 int m_max;
 
-                public void startupTask() throws Exception
-                {
+                @Override public void startupTask() throws Exception {
                     super.startupTask();
 
-                    setName("Reindexer started");
+                    setName( "Reindexer started" );
                 }
 
-                public void backgroundTask() throws Exception
-                {
-                    Collection<WikiPage> allPages = m_engine.getPageManager().getAllPages();
+                @Override public void backgroundTask() throws Exception {
+                    final Collection< WikiPage > allPages = m_engine.getManager( PageManager.class ).getAllPages();
 
-                    SearchManager mgr = m_engine.getSearchManager();
+                    final SearchManager mgr = m_engine.getManager( SearchManager.class );
                     m_max = allPages.size();
 
-                    ProgressItem pi = new ProgressItem() {
-                        public int getProgress()
-                        {
+                    final ProgressItem pi = new ProgressItem() {
+
+                        @Override public int getProgress() {
                             return 100 * m_count / m_max;
                         }
                     };
 
-                    m_engine.getProgressManager().startProgress( pi, PROGRESS_ID );
+                    m_engine.getManager( ProgressManager.class ).startProgress( pi, PROGRESS_ID );
 
-                    for( WikiPage page : allPages )
-                    {
-                        mgr.reindexPage(page);
+                    for( final WikiPage page : allPages ) {
+                        mgr.reindexPage( page );
                         m_count++;
                     }
 
-                    m_engine.getProgressManager().stopProgress( PROGRESS_ID );
+                    m_engine.getManager( ProgressManager.class ).stopProgress( PROGRESS_ID );
                     shutdown();
                     m_updater = null;
                 }
@@ -122,38 +120,29 @@ public class SearchManagerBean extends SimpleAdminBean
         }
     }
 
-    public int getType()
+    @Override public int getType()
     {
         return CORE;
     }
 
-    public String doGet(WikiContext context)
-    {
-        if( m_updater != null )
-        {
-            return "Update already in progress ("+
-                   context.getEngine().getProgressManager().getProgress(PROGRESS_ID)+
-                   "%)";
+    @Override public String doGet( final WikiContext context ) {
+        if( m_updater != null ) {
+            return "Update already in progress ("+ context.getEngine().getManager( ProgressManager.class ).getProgress(PROGRESS_ID)+ "%)";
         }
 
         return "<input type='submit' id='searchmanagerbean-reload' name='searchmanagerbean-reload' value='Force index reload'/>"+
                "<div class='description'>Forces JSPWiki search engine to reindex all pages.  Use this if you think some pages are not being found even if they should.</div>";
     }
 
-    public String doPost(WikiContext context)
-    {
-        String val = context.getHttpParameter("searchmanagerbean-reload");
-
-        if( val != null )
-        {
+    @Override public String doPost( final WikiContext context ) {
+        final String val = context.getHttpParameter( "searchmanagerbean-reload" );
+        if( val != null ) {
             reload();
-
             context.getWikiSession().addMessage( "Started reload of all indexed pages..." );
-
             return "";
         }
 
-        return doGet(context);
+        return doGet( context );
     }
 
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/UserBean.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/UserBean.java
index 00074e8..2d662c5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/UserBean.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/admin/beans/UserBean.java
@@ -18,14 +18,9 @@
  */
 package org.apache.wiki.ui.admin.beans;
 
-import java.util.Date;
-
-import javax.management.NotCompliantMBeanException;
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.WikiSecurityException;
@@ -33,39 +28,43 @@ import org.apache.wiki.auth.user.UserProfile;
 import org.apache.wiki.ui.admin.AdminBean;
 import org.apache.wiki.ui.admin.SimpleAdminBean;
 
+import javax.management.NotCompliantMBeanException;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
 
 public class UserBean extends SimpleAdminBean
 {
-    public UserBean( WikiEngine engine ) throws NotCompliantMBeanException
+    public UserBean( final Engine engine ) throws NotCompliantMBeanException
     {
         super();
     }
 
-    public String[] getAttributeNames()
+    @Override public String[] getAttributeNames()
     {
         return new String[0];
     }
 
     // FIXME: We don't yet support MBean for this kind of stuff.
-    public String[] getMethodNames()
+    @Override public String[] getMethodNames()
     {
         return new String[0];
     }
 
 
 
-    public String doPost(WikiContext context)
+    @Override public String doPost( final WikiContext context)
     {
-        HttpServletRequest request = context.getHttpRequest();
-        WikiSession session = context.getWikiSession();
-        UserManager mgr = context.getEngine().getUserManager();
+        final HttpServletRequest request = context.getHttpRequest();
+        final WikiSession session = context.getWikiSession();
+        final UserManager mgr = context.getEngine().getManager( UserManager.class );
 
-        String loginid   = request.getParameter("loginid");
-        String loginname = request.getParameter("loginname");
-        String fullname  = request.getParameter("fullname");
-        String password  = request.getParameter("password");
-        String password2 = request.getParameter("password2");
-        String email     = request.getParameter("email");
+        final String loginid   = request.getParameter("loginid");
+        final String loginname = request.getParameter("loginname");
+        final String fullname  = request.getParameter("fullname");
+        final String password  = request.getParameter("password");
+        final String password2 = request.getParameter("password2");
+        final String email     = request.getParameter("email");
 
 
         if( request.getParameter("action").equalsIgnoreCase("remove") )
@@ -75,11 +74,11 @@ public class UserBean extends SimpleAdminBean
                 mgr.getUserDatabase().deleteByLoginName(loginid);
                 session.addMessage("User profile "+loginid+" ("+fullname+") has been deleted");
             }
-            catch (NoSuchPrincipalException e)
+            catch ( final NoSuchPrincipalException e)
             {
                 session.addMessage("User profile has already been removed");
             }
-            catch (WikiSecurityException e)
+            catch ( final WikiSecurityException e)
             {
                 session.addMessage("Security problem: "+e);
             }
@@ -93,7 +92,7 @@ public class UserBean extends SimpleAdminBean
             return "";
         }
 
-        UserProfile p;
+        final UserProfile p;
 
         if( loginid.equals("--New--") )
         {
@@ -108,7 +107,7 @@ public class UserBean extends SimpleAdminBean
             {
                 p = mgr.getUserDatabase().findByLoginName( loginid );
             }
-            catch (NoSuchPrincipalException e)
+            catch ( final NoSuchPrincipalException e)
             {
                 session.addMessage("I could not find user profile "+loginid);
                 return "";
@@ -124,7 +123,7 @@ public class UserBean extends SimpleAdminBean
         {
             mgr.getUserDatabase().save( p );
         }
-        catch( WikiSecurityException e )
+        catch( final WikiSecurityException e )
         {
             session.addMessage("Unable to save "+e.getMessage());
         }
@@ -134,12 +133,12 @@ public class UserBean extends SimpleAdminBean
         return "";
     }
 
-    public String getTitle()
+    @Override public String getTitle()
     {
         return "User administration";
     }
 
-    public int getType()
+    @Override public int getType()
     {
         return AdminBean.UNKNOWN;
     }


[jspwiki] 23/38: JSPWIKI-120: make callback handlers use Engine instead of WikiEngine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit db20d0e9baf513236e0832b9218c2f68b0b37c72
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 17:31:22 2020 +0100

    JSPWIKI-120: make callback handlers use Engine instead of WikiEngine
---
 .../wiki/attachment/DefaultAttachmentManager.java  |  3 +-
 .../wiki/auth/DefaultAuthenticationManager.java    | 11 ++-
 .../auth/login/WebContainerCallbackHandler.java    | 50 ++++++--------
 .../wiki/auth/login/WikiCallbackHandler.java       | 78 +++++++++-------------
 .../apache/wiki/auth/login/WikiEngineCallback.java | 25 ++++---
 5 files changed, 71 insertions(+), 96 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
index 688c3e0..4cf397c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
@@ -23,7 +23,6 @@ import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
@@ -106,7 +105,7 @@ public class DefaultAttachmentManager implements AttachmentManager {
             final Class< ? > providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname );
 
             m_provider = ( WikiAttachmentProvider )providerclass.newInstance();
-            m_provider.initialize( m_engine.adapt( WikiEngine.class ), props );
+            m_provider.initialize( m_engine, props );
         } catch( final ClassNotFoundException e ) {
             log.error( "Attachment provider class not found",e);
         } catch( final InstantiationException e ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
index e4566b9..ce76804 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthenticationManager.java
@@ -19,7 +19,6 @@
 package org.apache.wiki.auth;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
@@ -154,7 +153,7 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
     @Override
     public boolean login( final HttpServletRequest request ) throws WikiSecurityException {
         final HttpSession httpSession = request.getSession();
-        final WikiSession session = SessionMonitor.getInstance( m_engine.adapt( WikiEngine.class ) ).find( httpSession );
+        final WikiSession session = SessionMonitor.getInstance( m_engine ).find( httpSession );
         final AuthenticationManager authenticationMgr = m_engine.getManager( AuthenticationManager.class );
         final AuthorizationManager authorizationMgr = m_engine.getManager( AuthorizationManager.class );
         CallbackHandler handler = null;
@@ -163,7 +162,7 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
         // If user not authenticated, check if container logged them in, or if there's an authentication cookie
         if ( !session.isAuthenticated() ) {
             // Create a callback handler
-            handler = new WebContainerCallbackHandler( m_engine.adapt( WikiEngine.class ), request );
+            handler = new WebContainerCallbackHandler( m_engine, request );
 
             // Execute the container login module, then (if that fails) the cookie auth module
             Set< Principal > principals = authenticationMgr.doJAASLogin( WebContainerLoginModule.class, handler, options );
@@ -220,7 +219,7 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
             delayLogin( username );
         }
 
-        final CallbackHandler handler = new WikiCallbackHandler( m_engine.adapt( WikiEngine.class ), null, username, password );
+        final CallbackHandler handler = new WikiCallbackHandler( m_engine, null, username, password );
 
         // Execute the user's specified login module
         final Set< Principal > principals = doJAASLogin( m_loginModuleClass, handler, m_loginModuleOptions );
@@ -277,12 +276,12 @@ public class DefaultAuthenticationManager implements AuthenticationManager {
             log.debug( "Invalidating WikiSession for session ID=" + sid );
         }
         // Retrieve the associated WikiSession and clear the Principal set
-        final WikiSession wikiSession = WikiSession.getWikiSession( m_engine.adapt( WikiEngine.class ), request );
+        final WikiSession wikiSession = WikiSession.getWikiSession( m_engine, request );
         final Principal originalPrincipal = wikiSession.getLoginPrincipal();
         wikiSession.invalidate();
 
         // Remove the wikiSession from the WikiSession cache
-        WikiSession.removeWikiSession( m_engine.adapt( WikiEngine.class ), request );
+        WikiSession.removeWikiSession( m_engine, request );
 
         // We need to flush the HTTP session too
         if ( session != null ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WebContainerCallbackHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WebContainerCallbackHandler.java
index 23ed9ba..4836b58 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WebContainerCallbackHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WebContainerCallbackHandler.java
@@ -18,35 +18,34 @@
  */
 package org.apache.wiki.auth.login;
 
-import java.io.IOException;
+import org.apache.wiki.api.core.Engine;
 
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
 
-import org.apache.wiki.WikiEngine;
 
 /**
  * Handles logins made from within JSPWiki.
- * @see org.apache.wiki.WikiSession#getWikiSession(WikiEngine,HttpServletRequest)
+ *
+ * @see org.apache.wiki.WikiSession#getWikiSession(Engine,HttpServletRequest)
  * @since 2.3
  */
-public final class WebContainerCallbackHandler implements CallbackHandler
-{
-    private final HttpServletRequest m_request;
+public final class WebContainerCallbackHandler implements CallbackHandler {
 
-    private final WikiEngine         m_engine;
+    private final HttpServletRequest m_request;
+    private final Engine m_engine;
 
     /**
-     *  Create a new handler.
-     *  
-     *  @param engine The WikiEngine
-     *  @param request The request to look into
+     * Create a new handler.
+     *
+     * @param engine  The WikiEngine
+     * @param request The request to look into
      */
-    public WebContainerCallbackHandler( WikiEngine engine, HttpServletRequest request )
-    {
-        m_engine  = engine;
+    public WebContainerCallbackHandler( final Engine engine, final HttpServletRequest request ) {
+        m_engine = engine;
         m_request = request;
     }
 
@@ -55,21 +54,14 @@ public final class WebContainerCallbackHandler implements CallbackHandler
      * 
      * {@inheritDoc}
      */
-    public void handle( Callback[] callbacks ) throws IOException, UnsupportedCallbackException
-    {
-        for( int i = 0; i < callbacks.length; i++ )
-        {
-            Callback callback = callbacks[i];
-            if ( callback instanceof HttpRequestCallback )
-            {
-                ( (HttpRequestCallback) callback ).setRequest( m_request );
-            }
-            else if( callback instanceof WikiEngineCallback )
-            {
-                ( (WikiEngineCallback) callback ).setEngine( m_engine );
-            }
-            else
-            {
+    @Override
+    public void handle( final Callback[] callbacks ) throws IOException, UnsupportedCallbackException {
+        for( final Callback callback : callbacks ) {
+            if( callback instanceof HttpRequestCallback ) {
+                ( ( HttpRequestCallback )callback ).setRequest( m_request );
+            } else if( callback instanceof WikiEngineCallback ) {
+                ( ( WikiEngineCallback )callback ).setEngine( m_engine );
+            } else {
                 throw new UnsupportedCallbackException( callback );
             }
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiCallbackHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiCallbackHandler.java
index bcf469e..682ca99 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiCallbackHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiCallbackHandler.java
@@ -18,42 +18,42 @@
  */
 package org.apache.wiki.auth.login;
 
-import java.io.IOException;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.auth.UserManager;
 
-import javax.security.auth.callback.*;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
 
-import org.apache.wiki.WikiEngine;
 
 /**
- * Handles logins made from inside the wiki application, rather than via the web
- * container. This handler is instantiated in
+ * Handles logins made from inside the wiki application, rather than via the web container. This handler is instantiated in
  * {@link org.apache.wiki.auth.AuthenticationManager#login(org.apache.wiki.WikiSession,HttpServletRequest, String, String)}.
- * If container-managed authentication is used, the
- * {@link WebContainerCallbackHandler}is used instead. This callback handler is
+ * If container-managed authentication is used, the {@link WebContainerCallbackHandler}is used instead. This callback handler is
  * designed to be used with {@link UserDatabaseLoginModule}.
+ *
  * @since 2.3
  */
-public class WikiCallbackHandler implements CallbackHandler
-{
-    private final HttpServletRequest m_request;
+public class WikiCallbackHandler implements CallbackHandler {
 
-    private final WikiEngine m_engine;
-    
-    private final String       m_password;
-
-    private final String       m_username;
+    private final HttpServletRequest m_request;
+    private final Engine m_engine;
+    private final String m_password;
+    private final String m_username;
 
     /**
      *  Create a new callback handler.
+     *
      * @param engine the WikiEngine
-     * @param request the user's HTTP request. If passed as <code>null</code>,
-     *  later requests for {@link HttpRequestCallback} will return an UnsupportedCallbackException
+     * @param request the user's HTTP request. If passed as <code>null</code>, later requests for {@link HttpRequestCallback} will return an UnsupportedCallbackException
      * @param username the username
      * @param password the password
      */
-    public WikiCallbackHandler( WikiEngine engine, HttpServletRequest request, String username, String password )
-    {
+    public WikiCallbackHandler( final Engine engine, final HttpServletRequest request, final String username, final String password ) {
         m_request = request;
         m_engine = engine;
         m_username = username;
@@ -65,33 +65,19 @@ public class WikiCallbackHandler implements CallbackHandler
      * 
      * {@inheritDoc}
      */
-    public void handle( Callback[] callbacks ) throws IOException, UnsupportedCallbackException
-    {
-        for( int i = 0; i < callbacks.length; i++ )
-        {
-            Callback callback = callbacks[i];
-            if ( callback instanceof HttpRequestCallback )
-            {
-                ( (HttpRequestCallback) callback ).setRequest( m_request );
-            }
-            else if( callback instanceof WikiEngineCallback )
-            {
-                ( (WikiEngineCallback) callback ).setEngine( m_engine );
-            }
-            else if ( callback instanceof UserDatabaseCallback )
-            {
-                ( (UserDatabaseCallback) callback ).setUserDatabase( m_engine.getUserManager().getUserDatabase() );
-            }
-            else if ( callback instanceof NameCallback )
-            {
-                ( (NameCallback) callback ).setName( m_username );
-            }
-            else if ( callback instanceof PasswordCallback )
-            {
-                ( (PasswordCallback) callback ).setPassword( m_password.toCharArray() );
-            }
-            else
-            {
+    @Override public void handle( final Callback[] callbacks ) throws IOException, UnsupportedCallbackException {
+        for( final Callback callback : callbacks ) {
+            if( callback instanceof HttpRequestCallback ) {
+                ( ( HttpRequestCallback )callback ).setRequest( m_request );
+            } else if( callback instanceof WikiEngineCallback ) {
+                ( ( WikiEngineCallback )callback ).setEngine( m_engine );
+            } else if( callback instanceof UserDatabaseCallback ) {
+                ( ( UserDatabaseCallback )callback ).setUserDatabase( m_engine.getManager( UserManager.class ).getUserDatabase() );
+            } else if( callback instanceof NameCallback ) {
+                ( ( NameCallback )callback ).setName( m_username );
+            } else if( callback instanceof PasswordCallback ) {
+                ( ( PasswordCallback )callback ).setPassword( m_password.toCharArray() );
+            } else {
                 throw new UnsupportedCallbackException( callback );
             }
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiEngineCallback.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiEngineCallback.java
index 3fa57b4..e2e0ace 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiEngineCallback.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/WikiEngineCallback.java
@@ -18,38 +18,37 @@
  */
 package org.apache.wiki.auth.login;
 
+import org.apache.wiki.api.core.Engine;
+
 import javax.security.auth.callback.Callback;
 
-import org.apache.wiki.WikiEngine;
 
 /**
- * Callback for requesting and supplying the WikiEngine object required by a
- * LoginModule. This Callback is used by LoginModules needing access to the
- * external authorizer or group manager.
+ * Callback for requesting and supplying the WikiEngine object required by a LoginModule. This Callback is used by LoginModules needing
+ * access to the external authorizer or group manager.
  *
  * @since 2.5
  */
-public class WikiEngineCallback implements Callback
-{
+public class WikiEngineCallback implements Callback {
 
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
     /**
      * Sets the engine object. CallbackHandler objects call this method.
+     *
      * @param engine the engine
      */
-    public void setEngine( WikiEngine engine )
-    {
+    public void setEngine( final Engine engine ) {
         m_engine = engine;
     }
 
     /**
-     * Returns the engine. LoginModules call this method after a
-     * CallbackHandler sets the engine.
+     * Returns the engine. LoginModules call this method after a CallbackHandler sets the engine.
+     *
      * @return the engine
      */
-    public WikiEngine getEngine()
-    {
+    public Engine getEngine() {
         return m_engine;
     }
+
 }


[jspwiki] 34/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (11)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit de7c7705375ae346c61c4fa0e7c5c9c39e3225f1
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:18:13 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (11)
---
 .../main/java/org/apache/wiki/auth/Authorizer.java |  44 ++--
 .../apache/wiki/auth/acl/DefaultAclManager.java    |  14 +-
 .../login/CookieAuthenticationLoginModule.java     | 292 +++++++++------------
 .../wiki/variables/DefaultVariableManager.java     |  17 +-
 .../org/apache/wiki/xmlrpc/AbstractRPCHandler.java |  13 +-
 .../org/apache/wiki/xmlrpc/MetaWeblogHandler.java  |  37 +--
 .../java/org/apache/wiki/xmlrpc/RPCHandler.java    |  34 +--
 .../org/apache/wiki/xmlrpc/RPCHandlerUTF8.java     |  34 +--
 8 files changed, 219 insertions(+), 266 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
index 13f82c2..efdc60e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
@@ -26,41 +26,30 @@ import java.util.Properties;
 
 
 /**
- * Interface for service providers of authorization information. After a user
- * successfully logs in, the
- * {@link org.apache.wiki.auth.AuthenticationManager} consults the configured
- * Authorizer to determine which additional
- * {@link org.apache.wiki.auth.authorize.Role} principals should be added to
- * the user's WikiSession. To determine which roles should be injected, the
- * Authorizer is queried for the roles it knows about by calling
- * {@link org.apache.wiki.auth.Authorizer#getRoles()}. Then, each role
- * returned by the Authorizer is tested by calling
- * {@link org.apache.wiki.auth.Authorizer#isUserInRole(WikiSession, Principal)}.
- * If this check fails, and the Authorizer is of type WebAuthorizer,
- * AuthenticationManager checks the role again by calling
+ * Interface for service providers of authorization information. After a user successfully logs in, the
+ * {@link org.apache.wiki.auth.AuthenticationManager} consults the configured Authorizer to determine which additional
+ * {@link org.apache.wiki.auth.authorize.Role} principals should be added to the user's WikiSession. To determine which roles should be
+ * injected, the Authorizer is queried for the roles it knows about by calling {@link org.apache.wiki.auth.Authorizer#getRoles()}. Then,
+ * each role returned by the Authorizer is tested by calling {@link org.apache.wiki.auth.Authorizer#isUserInRole(WikiSession, Principal)}.
+ * If this check fails, and the Authorizer is of type WebAuthorizer, AuthenticationManager checks the role again by calling
  * {@link org.apache.wiki.auth.authorize.WebAuthorizer#isUserInRole(javax.servlet.http.HttpServletRequest, Principal)}).
- * Any roles that pass the test are injected into the Subject by firing
- * appropriate authentication events.
+ * Any roles that pass the test are injected into the Subject by firing appropriate authentication events.
  * 
  * @since 2.3
  */
 public interface Authorizer {
 
     /**
-     * Returns an array of role Principals this Authorizer knows about. This
-     * method will always return an array; an implementing class may choose to
-     * return an zero-length array if it has no ability to identify the roles
-     * under its control.
+     * Returns an array of role Principals this Authorizer knows about. This method will always return an array; an implementing class may
+     * choose to return an zero-length array if it has no ability to identify the roles under its control.
      * 
      * @return an array of Principals representing the roles
      */
     Principal[] getRoles();
 
     /**
-     * Looks up and returns a role Principal matching a given String. If a
-     * matching role cannot be found, this method returns <code>null</code>.
-     * Note that it may not always be feasible for an Authorizer implementation
-     * to return a role Principal.
+     * Looks up and returns a role Principal matching a given String. If a matching role cannot be found, this method returns
+     * <code>null</code>. Note that it may not always be feasible for an Authorizer implementation to return a role Principal.
      * 
      * @param role the name of the role to retrieve
      * @return the role Principal
@@ -77,16 +66,13 @@ public interface Authorizer {
     void initialize( Engine engine, Properties props ) throws WikiSecurityException;
 
     /**
-     * Determines whether the Subject associated with a WikiSession is in a
-     * particular role. This method takes two parameters: the WikiSession
-     * containing the subject and the desired role ( which may be a Role or a
-     * Group). If either parameter is <code>null</code>, this method must
-     * return <code>false</code>.
+     * Determines whether the Subject associated with a WikiSession is in a particular role. This method takes two parameters: the
+     * WikiSession containing the subject and the desired role ( which may be a Role or a Group). If either parameter is <code>null</code>,
+     * this method must return <code>false</code>.
      * 
      * @param session the current WikiSession
      * @param role the role to check
-     * @return <code>true</code> if the user is considered to be in the role,
-     *         <code>false</code> otherwise
+     * @return <code>true</code> if the user is considered to be in the role, <code>false</code> otherwise
      */
     boolean isUserInRole( WikiSession session, Principal role );
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java
index 7b0ca22..29b593f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java
@@ -80,7 +80,7 @@ public class DefaultAclManager implements AclManager {
      * @param props  the initialization properties
      * @see org.apache.wiki.auth.acl.AclManager#initialize(org.apache.wiki.WikiEngine, java.util.Properties)
      */
-    public void initialize( final WikiEngine engine, final Properties props ) {
+    @Override public void initialize( final WikiEngine engine, final Properties props ) {
         m_auth = engine.getAuthorizationManager();
         m_engine = engine;
     }
@@ -96,7 +96,7 @@ public class DefaultAclManager implements AclManager {
      * @throws WikiSecurityException if the ruleLine was faulty somehow.
      * @since 2.1.121
      */
-    public Acl parseAcl( final WikiPage page, final String ruleLine ) throws WikiSecurityException {
+    @Override public Acl parseAcl( final WikiPage page, final String ruleLine ) throws WikiSecurityException {
         Acl acl = page.getAcl();
         if (acl == null) {
             acl = new AclImpl();
@@ -150,7 +150,7 @@ public class DefaultAclManager implements AclManager {
      * @return the Acl representing permissions for the page
      * @since 2.2.121
      */
-    public Acl getPermissions( final WikiPage page ) {
+    @Override public Acl getPermissions( final WikiPage page ) {
         //  Does the page already have cached ACLs?
         Acl acl = page.getAcl();
         log.debug( "page=" + page.getName() + "\n" + acl );
@@ -158,7 +158,7 @@ public class DefaultAclManager implements AclManager {
         if( acl == null ) {
             //  If null, try the parent.
             if( page instanceof Attachment ) {
-                final WikiPage parent = m_engine.getPageManager().getPage( ( ( Attachment ) page ).getParentName() );
+                final WikiPage parent = m_engine.getManager( PageManager.class ).getPage( ( ( Attachment ) page ).getParentName() );
                 acl = getPermissions(parent);
             } else {
                 //  Or, try parsing the page
@@ -188,8 +188,8 @@ public class DefaultAclManager implements AclManager {
      * @throws WikiSecurityException of the Acl cannot be set
      * @since 2.5
      */
-    public void setPermissions( final WikiPage page, final Acl acl ) throws WikiSecurityException {
-        final PageManager pageManager = m_engine.getPageManager();
+    @Override public void setPermissions( final WikiPage page, final Acl acl ) throws WikiSecurityException {
+        final PageManager pageManager = m_engine.getManager( PageManager.class );
 
         // Forcibly expire any page locks
         final PageLock lock = pageManager.getCurrentLock( page );
@@ -198,7 +198,7 @@ public class DefaultAclManager implements AclManager {
         }
 
         // Remove all of the existing ACLs.
-        final String pageText = m_engine.getPageManager().getPureText( page );
+        final String pageText = m_engine.getManager( PageManager.class ).getPureText( page );
         final Matcher matcher = DefaultAclManager.ACL_PATTERN.matcher( pageText );
         final String cleansedText = matcher.replaceAll("" );
         final String newText = DefaultAclManager.printAcl( page.getAcl() ) + cleansedText;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/CookieAuthenticationLoginModule.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/CookieAuthenticationLoginModule.java
index f4615a0..c5facb7 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/login/CookieAuthenticationLoginModule.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/login/CookieAuthenticationLoginModule.java
@@ -20,6 +20,7 @@ package org.apache.wiki.auth.login;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.util.FileUtil;
 import org.apache.wiki.util.HttpUtil;
@@ -45,125 +46,109 @@ import java.io.Writer;
 import java.nio.charset.StandardCharsets;
 import java.util.UUID;
 
+
 /**
- *  Logs in an user based on a cookie stored in the user's computer.  The cookie
- *  information is stored in the <code>jspwiki.workDir</code>, under the directory
- *  {@value #COOKIE_DIR}.  For security purposes it is a very, very good idea
- *  to prevent access to this directory by everyone except the web server process;
- *  otherwise people having read access to this directory may be able to spoof
- *  other users.
- *  <p>
- *  The cookie directory is scrubbed of old entries at regular intervals.
- *  <p>
- *   This module must be used with a CallbackHandler (such as
- *   {@link WebContainerCallbackHandler}) that supports the following Callback
- *   types:
- *   </p>
- *   <ol>
- *   <li>{@link HttpRequestCallback}- supplies the cookie, which should contain
- *       an unique id for fetching the UID.</li>
- *   <li>{@link WikiEngineCallback} - allows access to the WikiEngine itself.
- *   </ol>
- *  <p>
- *  After authentication, a generic WikiPrincipal based on the username will be
- *  created and associated with the Subject.
- *  </p>
- *  @see javax.security.auth.spi.LoginModule#commit()
- *  @see CookieAssertionLoginModule
- *  @since  2.5.62
+ * Logs in an user based on a cookie stored in the user's computer.  The cookie
+ * information is stored in the <code>jspwiki.workDir</code>, under the directory
+ * {@value #COOKIE_DIR}.  For security purposes it is a very, very good idea
+ * to prevent access to this directory by everyone except the web server process;
+ * otherwise people having read access to this directory may be able to spoof
+ * other users.
+ * <p>
+ * The cookie directory is scrubbed of old entries at regular intervals.
+ * <p>
+ * This module must be used with a CallbackHandler (such as
+ * {@link WebContainerCallbackHandler}) that supports the following Callback
+ * types:
+ * </p>
+ *  <ol>
+ *  <li>{@link HttpRequestCallback}- supplies the cookie, which should contain
+ *      an unique id for fetching the UID.</li>
+ *  <li>{@link WikiEngineCallback} - allows access to the WikiEngine itself.
+ *  </ol>
+ * <p>
+ * After authentication, a generic WikiPrincipal based on the username will be
+ * created and associated with the Subject.
+ * </p>
+ * @see javax.security.auth.spi.LoginModule#commit()
+ * @see CookieAssertionLoginModule
+ * @since 2.5.62
  */
-public class CookieAuthenticationLoginModule extends AbstractLoginModule
-{
+public class CookieAuthenticationLoginModule extends AbstractLoginModule {
 
     private static final Logger log = Logger.getLogger( CookieAuthenticationLoginModule.class );
     private static final String LOGIN_COOKIE_NAME = "JSPWikiUID";
 
     /** The directory name under which the cookies are stored.  The value is {@value}. */
-    protected static final String COOKIE_DIR        = "logincookies";
+    protected static final String COOKIE_DIR = "logincookies";
 
     /**
-     *  User property for setting how long the cookie is stored on the user's computer.
-     *  The value is {@value}.  The default expiry time is 14 days.
+     * User property for setting how long the cookie is stored on the user's computer.
+     * The value is {@value}.  The default expiry time is 14 days.
      */
-    public static final  String PROP_LOGIN_EXPIRY_DAYS  = "jspwiki.cookieAuthentication.expiry";
+    public static final String PROP_LOGIN_EXPIRY_DAYS = "jspwiki.cookieAuthentication.expiry";
 
     /**
-     *  Built-in value for storing the cookie.
+     * Built-in value for storing the cookie.
      */
-    private static final int    DEFAULT_EXPIRY_DAYS = 14;
+    private static final int DEFAULT_EXPIRY_DAYS = 14;
 
-    private static       long   c_lastScrubTime   = 0L;
+    private static long c_lastScrubTime = 0L;
 
-    /** Describes how often we scrub the cookieDir directory.
+    /**
+     * Describes how often we scrub the cookieDir directory.
      */
-    private static final long   SCRUB_PERIOD      = 60*60*1000L; // In milliseconds
+    private static final long SCRUB_PERIOD = 60 * 60 * 1000L; // In milliseconds
 
     /**
      * @see javax.security.auth.spi.LoginModule#login()
-     *
      * {@inheritDoc}
      */
-    public boolean login() throws LoginException
-    {
+    @Override public boolean login() throws LoginException {
         // Otherwise, let's go and look for the cookie!
-        HttpRequestCallback hcb = new HttpRequestCallback();
-        WikiEngineCallback wcb  = new WikiEngineCallback();
+        final HttpRequestCallback hcb = new HttpRequestCallback();
+        final WikiEngineCallback wcb = new WikiEngineCallback();
 
-        Callback[] callbacks = new Callback[]
-        { hcb, wcb };
+        final Callback[] callbacks = new Callback[] { hcb, wcb };
 
-        try
-        {
+        try {
             m_handler.handle( callbacks );
 
-            HttpServletRequest request = hcb.getRequest();
-            String uid = getLoginCookie( request );
+            final HttpServletRequest request = hcb.getRequest();
+            final String uid = getLoginCookie( request );
 
-            if( uid != null )
-            {
-                WikiEngine engine = wcb.getEngine();
-                File cookieFile = getCookieFile(engine, uid);
+            if( uid != null ) {
+                final Engine engine = wcb.getEngine();
+                final File cookieFile = getCookieFile( engine, uid );
 
-                if( cookieFile != null && cookieFile.exists() && cookieFile.canRead() )
-                {
+                if( cookieFile != null && cookieFile.exists() && cookieFile.canRead() ) {
 
-                    try
-                    (
-                        Reader in = new BufferedReader( new InputStreamReader( new FileInputStream( cookieFile ), "UTF-8" ) );
-                    )
-                    {
-                        String username = FileUtil.readContents( in );
+                    try( final Reader in = new BufferedReader( new InputStreamReader( new FileInputStream( cookieFile ), "UTF-8" ) ) ) {
+                        final String username = FileUtil.readContents( in );
 
-                        if ( log.isDebugEnabled() )
-                        {
+                        if( log.isDebugEnabled() ) {
                             log.debug( "Logged in cookie authenticated name=" + username );
                         }
 
                         // If login succeeds, commit these principals/roles
-                        m_principals.add( new WikiPrincipal( username,  WikiPrincipal.LOGIN_NAME ) );
+                        m_principals.add( new WikiPrincipal( username, WikiPrincipal.LOGIN_NAME ) );
 
                         //
                         //  Tag the file so that we know that it has been accessed recently.
                         //
                         return cookieFile.setLastModified( System.currentTimeMillis() );
 
-                    }
-                    catch( IOException e )
-                    {
+                    } catch( final IOException e ) {
                         return false;
                     }
                 }
             }
-        }
-        catch( IOException e )
-        {
-            String message = "IO exception; disallowing login.";
+        } catch( final IOException e ) {
+            final String message = "IO exception; disallowing login.";
             log.error( message, e );
             throw new LoginException( message );
-        }
-        catch( UnsupportedCallbackException e )
-        {
-            String message = "Unable to handle callback; disallowing login.";
+        } catch( final UnsupportedCallbackException e ) {
+            final String message = "Unable to handle callback; disallowing login.";
             log.error( message, e );
             throw new LoginException( message );
         }
@@ -172,43 +157,36 @@ public class CookieAuthenticationLoginModule extends AbstractLoginModule
     }
 
     /**
-     *  Attempts to locate the cookie file.
-     *  @param engine WikiEngine
-     *  @param uid An unique ID fetched from the user cookie
-     *  @return A File handle, or null, if there was a problem.
+     * Attempts to locate the cookie file.
+     *
+     * @param engine WikiEngine
+     * @param uid    An unique ID fetched from the user cookie
+     * @return A File handle, or null, if there was a problem.
      */
-    private static File getCookieFile(WikiEngine engine, String uid)
-    {
-        File cookieDir = new File( engine.getWorkDir(), COOKIE_DIR );
+    private static File getCookieFile( final Engine engine, final String uid ) {
+        final File cookieDir = new File( engine.getWorkDir(), COOKIE_DIR );
 
-        if( !cookieDir.exists() )
-        {
+        if( !cookieDir.exists() ) {
             cookieDir.mkdirs();
         }
 
-        if( !cookieDir.canRead() )
-        {
-            log.error("Cannot read from cookie directory!"+cookieDir.getAbsolutePath());
+        if( !cookieDir.canRead() ) {
+            log.error( "Cannot read from cookie directory!" + cookieDir.getAbsolutePath() );
             return null;
         }
 
-        if( !cookieDir.canWrite() )
-        {
-            log.error("Cannot write to cookie directory!"+cookieDir.getAbsolutePath());
+        if( !cookieDir.canWrite() ) {
+            log.error( "Cannot write to cookie directory!" + cookieDir.getAbsolutePath() );
             return null;
         }
 
         //
         //  Scrub away old files
         //
-        long now = System.currentTimeMillis();
-
-        if( now > (c_lastScrubTime+SCRUB_PERIOD ) )
-        {
-            scrub( TextUtil.getIntegerProperty( engine.getWikiProperties(),
-                                                PROP_LOGIN_EXPIRY_DAYS,
-                                                DEFAULT_EXPIRY_DAYS ),
-                                                cookieDir );
+        final long now = System.currentTimeMillis();
+
+        if( now > ( c_lastScrubTime + SCRUB_PERIOD ) ) {
+            scrub( TextUtil.getIntegerProperty( engine.getWikiProperties(), PROP_LOGIN_EXPIRY_DAYS, DEFAULT_EXPIRY_DAYS ), cookieDir );
             c_lastScrubTime = now;
         }
 
@@ -219,23 +197,22 @@ public class CookieAuthenticationLoginModule extends AbstractLoginModule
     }
 
     /**
-     *  Extracts the login cookie UID from the servlet request.
+     * Extracts the login cookie UID from the servlet request.
      *
-     *  @param request The HttpServletRequest
-     *  @return The UID value from the cookie, or null, if no such cookie exists.
+     * @param request The HttpServletRequest
+     * @return The UID value from the cookie, or null, if no such cookie exists.
      */
-    private static String getLoginCookie(HttpServletRequest request)
-    {
+    private static String getLoginCookie( final HttpServletRequest request ) {
         return HttpUtil.retrieveCookieValue( request, LOGIN_COOKIE_NAME );
     }
 
     /**
-     *  Sets a login cookie based on properties set by the user.  This method also
-     *  creates the cookie uid-username mapping in the work directory.
+     * Sets a login cookie based on properties set by the user.  This method also
+     * creates the cookie uid-username mapping in the work directory.
      *
-     *  @param engine The WikiEngine
-     *  @param response The HttpServletResponse
-     *  @param username The username for whom to create the cookie.
+     * @param engine   The WikiEngine
+     * @param response The HttpServletResponse
+     * @param username The username for whom to create the cookie.
      */
     public static void setLoginCookie( final WikiEngine engine, final HttpServletResponse response, final String username ) {
         final UUID uid = UUID.randomUUID();
@@ -247,14 +224,11 @@ public class CookieAuthenticationLoginModule extends AbstractLoginModule
         final File cf = getCookieFile( engine, uid.toString() );
         if( cf != null ) {
             //  Write the cookie content to the cookie store file.
-            try(
-                final Writer out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(cf), StandardCharsets.UTF_8 ) )
-            )
-            {
-                FileUtil.copyContents( new StringReader(username), out );
+            try( final Writer out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( cf ), StandardCharsets.UTF_8 ) ) ) {
+                FileUtil.copyContents( new StringReader( username ), out );
 
                 if( log.isDebugEnabled() ) {
-                    log.debug( "Created login cookie for user "+username+" for "+days+" days" );
+                    log.debug( "Created login cookie for user " + username + " for " + days + " days" );
                 }
 
             } catch( final IOException ex ) {
@@ -264,86 +238,70 @@ public class CookieAuthenticationLoginModule extends AbstractLoginModule
     }
 
     /**
-     *  Clears away the login cookie, and removes the uid-username mapping file as well.
+     * Clears away the login cookie, and removes the uid-username mapping file as well.
      *
-     *  @param engine   WikiEngine
-     *  @param request  Servlet request
-     *  @param response Servlet response
+     * @param engine   WikiEngine
+     * @param request  Servlet request
+     * @param response Servlet response
      */
-    public static void clearLoginCookie( WikiEngine engine, HttpServletRequest request, HttpServletResponse response )
-    {
-        Cookie userId = getLoginCookie( "" );
+    public static void clearLoginCookie( final WikiEngine engine, final HttpServletRequest request, final HttpServletResponse response ) {
+        final Cookie userId = getLoginCookie( "" );
         userId.setMaxAge( 0 );
         response.addCookie( userId );
 
-        String uid = getLoginCookie( request );
+        final String uid = getLoginCookie( request );
 
-        if( uid != null )
-        {
-            File cf = getCookieFile( engine, uid );
+        if( uid != null ) {
+            final File cf = getCookieFile( engine, uid );
 
-            if( cf != null )
-            {
-                if( !cf.delete() )
-                {
-                    log.debug("Error deleting cookie login "+uid);
+            if( cf != null ) {
+                if( !cf.delete() ) {
+                    log.debug( "Error deleting cookie login " + uid );
                 }
             }
         }
     }
 
     /**
-     *  Helper function to get secure LOGIN cookie
+     * Helper function to get secure LOGIN cookie
      *
-     * @param:  value of the cookie
+     * @param: value of the cookie
      */
-    private static Cookie getLoginCookie( String value )
-    {
-        Cookie c = new Cookie( LOGIN_COOKIE_NAME, value );
-        c.setHttpOnly(true);  //no browser access
-        c.setSecure(true); //only access via encrypted https allowed
+    private static Cookie getLoginCookie( final String value ) {
+        final Cookie c = new Cookie( LOGIN_COOKIE_NAME, value );
+        c.setHttpOnly( true );  //no browser access
+        c.setSecure( true ); //only access via encrypted https allowed
         return c;
     }
 
-
     /**
-     *  Goes through the cookie directory and removes any obsolete files.
-     *  The scrubbing takes place one day after the cookie was supposed to expire.
-     *  However, if the user has logged in during the expiry period, the expiry is
-     *  reset, and the cookie file left here.
+     * Goes through the cookie directory and removes any obsolete files.
+     * The scrubbing takes place one day after the cookie was supposed to expire.
+     * However, if the user has logged in during the expiry period, the expiry is
+     * reset, and the cookie file left here.
      *
-     *  @param days
-     *  @param cookieDir
+     * @param days
+     * @param cookieDir
      */
-    private static synchronized void scrub( int days, File cookieDir )
-    {
-        log.debug("Scrubbing cookieDir...");
-
-        File[] files = cookieDir.listFiles();
-
-        long obsoleteDateLimit = System.currentTimeMillis() - ((long)days+1) * 24 * 60 * 60 * 1000L;
-
-        int  deleteCount = 0;
-
-        for( int i = 0; i < files.length; i++ )
-        {
-            File f = files[i];
-
-            long lastModified = f.lastModified();
-
-            if( lastModified < obsoleteDateLimit )
-            {
-                if( f.delete() )
-                {
+    private static synchronized void scrub( final int days, final File cookieDir ) {
+        log.debug( "Scrubbing cookieDir..." );
+        final File[] files = cookieDir.listFiles();
+        final long obsoleteDateLimit = System.currentTimeMillis() - ( ( long )days + 1 ) * 24 * 60 * 60 * 1000L;
+        int deleteCount = 0;
+
+        for( int i = 0; i < files.length; i++ ) {
+            final File f = files[ i ];
+            final long lastModified = f.lastModified();
+            if( lastModified < obsoleteDateLimit ) {
+                if( f.delete() ) {
                     deleteCount++;
-                }
-                else
-                {
-                    log.debug("Error deleting cookie login with index "+i);
+                } else {
+                    log.debug( "Error deleting cookie login with index " + i );
                 }
             }
         }
 
-        log.debug("Removed "+deleteCount+" obsolete cookie logins");
+        log.debug( "Removed " + deleteCount + " obsolete cookie logins" );
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/variables/DefaultVariableManager.java b/jspwiki-main/src/main/java/org/apache/wiki/variables/DefaultVariableManager.java
index c998d1d..7525759 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/variables/DefaultVariableManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/variables/DefaultVariableManager.java
@@ -25,10 +25,13 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.api.engine.FilterManager;
+import org.apache.wiki.api.engine.PluginManager;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
 import org.apache.wiki.api.filters.PageFilter;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.modules.InternalModule;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 
 import javax.servlet.http.HttpServletRequest;
@@ -298,24 +301,24 @@ public class DefaultVariableManager implements VariableManager {
         }
 
         public String getTotalpages() {
-            return Integer.toString( m_context.getEngine().getPageManager().getTotalPageCount() );
+            return Integer.toString( m_context.getEngine().getManager( PageManager.class ).getTotalPageCount() );
         }
 
         public String getPageprovider() {
-            return m_context.getEngine().getPageManager().getCurrentProvider();
+            return m_context.getEngine().getManager( PageManager.class ).getCurrentProvider();
         }
 
         public String getPageproviderdescription() {
-            return m_context.getEngine().getPageManager().getProviderDescription();
+            return m_context.getEngine().getManager( PageManager.class ).getProviderDescription();
         }
 
         public String getAttachmentprovider() {
-            final WikiProvider p = m_context.getEngine().getAttachmentManager().getCurrentProvider();
+            final WikiProvider p = m_context.getEngine().getManager( AttachmentManager.class ).getCurrentProvider();
             return (p != null) ? p.getClass().getName() : "-";
         }
 
         public String getAttachmentproviderdescription() {
-            final WikiProvider p = m_context.getEngine().getAttachmentManager().getCurrentProvider();
+            final WikiProvider p = m_context.getEngine().getManager( AttachmentManager.class ).getCurrentProvider();
             return (p != null) ? p.getProviderInfo() : "-";
         }
 
@@ -347,7 +350,7 @@ public class DefaultVariableManager implements VariableManager {
         }
 
         public String getPluginpath() {
-            final String s = m_context.getEngine().getPluginManager().getPluginSearchPath();
+            final String s = m_context.getEngine().getManager( PluginManager.class ).getPluginSearchPath();
 
             return ( s == null ) ? "-" : s;
         }
@@ -386,7 +389,7 @@ public class DefaultVariableManager implements VariableManager {
         }
 
         public String getPagefilters() {
-            final FilterManager fm = m_context.getEngine().getFilterManager();
+            final FilterManager fm = m_context.getEngine().getManager( FilterManager.class );
             final List< PageFilter > filters = fm.getFilterList();
             final StringBuilder sb = new StringBuilder();
             for( final PageFilter pf : filters ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/AbstractRPCHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/AbstractRPCHandler.java
index 3b1406b..bd7cbc1 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/AbstractRPCHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/AbstractRPCHandler.java
@@ -19,11 +19,12 @@
 package org.apache.wiki.xmlrpc;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.auth.permissions.WikiPermission;
+import org.apache.wiki.pages.PageManager;
 import org.apache.xmlrpc.AuthenticationFailed;
 
 import java.security.Permission;
@@ -54,13 +55,13 @@ public abstract class AbstractRPCHandler implements WikiRPCHandler {
     /** This is an inlined image. */
     public static final String LINK_INLINE   = "inline";
 
-    protected WikiEngine m_engine;
+    protected Engine m_engine;
     protected WikiContext m_context;
 
     /** This is the currently implemented JSPWiki XML-RPC code revision. */
     public static final int RPC_VERSION = 1;
 
-    public void initialize( final WikiContext context ) {
+    @Override public void initialize( final WikiContext context ) {
         m_context = context;
         m_engine  = context.getEngine();
     }
@@ -69,7 +70,7 @@ public abstract class AbstractRPCHandler implements WikiRPCHandler {
 
     public Vector getRecentChanges( final Date since ) {
         checkPermission( PagePermission.VIEW );
-        final Set< WikiPage > pages = m_engine.getPageManager().getRecentChanges();
+        final Set< WikiPage > pages = m_engine.getManager( PageManager.class ).getRecentChanges();
         final Vector< Hashtable< ?, ? > > result = new Vector<>();
 
         // Transform UTC into local time.
@@ -78,7 +79,7 @@ public abstract class AbstractRPCHandler implements WikiRPCHandler {
         cal.add( Calendar.MILLISECOND, cal.get( Calendar.ZONE_OFFSET ) +
                   (cal.getTimeZone().inDaylightTime( since ) ? cal.get( Calendar.DST_OFFSET ) : 0 ) );
 
-        for( WikiPage page : pages ) {
+        for( final WikiPage page : pages ) {
             if( page.getLastModified().after( cal.getTime() ) ) {
                 result.add( encodeWikiPage( page ) );
             }
@@ -94,7 +95,7 @@ public abstract class AbstractRPCHandler implements WikiRPCHandler {
      *  @param perm the Permission to check
      */
     protected void checkPermission( final Permission perm ) {
-        final AuthorizationManager mgr = m_engine.getAuthorizationManager();
+        final AuthorizationManager mgr = m_engine.getManager( AuthorizationManager.class );
 
         if( mgr.checkPermission( m_context.getWikiSession(), perm ) ) {
             return;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
index c40db82..6145a94 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
@@ -20,14 +20,15 @@ package org.apache.wiki.xmlrpc;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.WikiSecurityException;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.pages.PageTimeComparator;
 import org.apache.wiki.plugin.WeblogEntryPlugin;
 import org.apache.wiki.plugin.WeblogPlugin;
@@ -60,7 +61,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
     /**
      *  {@inheritDoc}
      */
-    public void initialize( final WikiContext context )
+    @Override public void initialize( final WikiContext context )
     {
         m_context = context;
     }
@@ -79,8 +80,8 @@ public class MetaWeblogHandler implements WikiRPCHandler {
                                    final String password,
                                    final String permission ) throws XmlRpcException {
         try {
-            final AuthenticationManager amm = m_context.getEngine().getAuthenticationManager();
-            final AuthorizationManager mgr = m_context.getEngine().getAuthorizationManager();
+            final AuthenticationManager amm = m_context.getEngine().getManager( AuthenticationManager.class );
+            final AuthorizationManager mgr = m_context.getEngine().getManager( AuthorizationManager.class );
 
             if( amm.login( m_context.getWikiSession(), m_context.getHttpRequest(), username, password ) ) {
                 if( !mgr.checkPermission( m_context.getWikiSession(), PermissionFactory.getPagePermission( page, permission ) ) ) {
@@ -104,7 +105,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
      *  @return An empty hashtable.
      */
     public Hashtable< Object, Object > getCategories( final String blogid, final String username, final String password )  throws XmlRpcException {
-        final WikiPage page = m_context.getEngine().getPageManager().getPage( blogid );
+        final WikiPage page = m_context.getEngine().getManager( PageManager.class ).getPage( blogid );
         checkPermissions( page, username, password, "view" );
         return new Hashtable<>();
     }
@@ -120,7 +121,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
      *  @return A metaWeblog entry struct.
      */
     private Hashtable< String,Object > makeEntry( final WikiPage page ) {
-        final WikiPage firstVersion = m_context.getEngine().getPageManager().getPage( page.getName(), 1 );
+        final WikiPage firstVersion = m_context.getEngine().getManager( PageManager.class ).getPage( page.getName(), 1 );
         final Hashtable< String, Object > ht = new Hashtable<>();
         ht.put( "dateCreated", firstVersion.getLastModified() );
         ht.put( "link", getURL(page.getName() ) );
@@ -128,7 +129,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
         ht.put( "postid", page.getName() );
         ht.put( "userid", page.getAuthor() );
 
-        final String pageText = m_context.getEngine().getPageManager().getText(page.getName());
+        final String pageText = m_context.getEngine().getManager( PageManager.class ).getText(page.getName());
         final int firstLine = pageText.indexOf('\n');
 
         String title = "";
@@ -165,7 +166,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
     public Hashtable getRecentPosts( final String blogid, final String username, final String password, final int numberOfPosts ) throws XmlRpcException {
         final Hashtable<String, Hashtable<String, Object>> result = new Hashtable<>();
         log.info( "metaWeblog.getRecentPosts() called");
-        final WikiPage page = m_context.getEngine().getPageManager().getPage( blogid );
+        final WikiPage page = m_context.getEngine().getManager( PageManager.class ).getPage( blogid );
         checkPermissions( page, username, password, "view" );
 
         final WeblogPlugin plugin = new WeblogPlugin();
@@ -198,8 +199,8 @@ public class MetaWeblogHandler implements WikiRPCHandler {
                            final Hashtable< String, Object > content,
                            final boolean publish ) throws XmlRpcException {
         log.info("metaWeblog.newPost() called");
-        final WikiEngine engine = m_context.getEngine();
-        final WikiPage page = engine.getPageManager().getPage( blogid );
+        final Engine engine = m_context.getEngine();
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( blogid );
         checkPermissions( page, username, password, "createPages" );
 
         try {
@@ -216,7 +217,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
 
             log.debug("Writing entry: "+text);
 
-            engine.getPageManager().saveText( context, text.toString() );
+            engine.getManager( PageManager.class ).saveText( context, text.toString() );
         } catch( final Exception e ) {
             log.error("Failed to create weblog entry",e);
             throw new XmlRpcException( 0, "Failed to create weblog entry: "+e.getMessage() );
@@ -241,18 +242,18 @@ public class MetaWeblogHandler implements WikiRPCHandler {
                                                        final String username,
                                                        final String password,
                                                        final Hashtable< String, Object > content ) throws XmlRpcException {
-        final WikiEngine engine = m_context.getEngine();
+        final Engine engine = m_context.getEngine();
         final String url;
 
         log.info( "metaWeblog.newMediaObject() called" );
 
-        final WikiPage page = engine.getPageManager().getPage( blogid );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( blogid );
         checkPermissions( page, username, password, "upload" );
 
         final String name = (String) content.get( "name" );
         final byte[] data = (byte[]) content.get( "bits" );
 
-        final AttachmentManager attmgr = engine.getAttachmentManager();
+        final AttachmentManager attmgr = engine.getManager( AttachmentManager.class );
 
         try {
             final Attachment att = new Attachment( engine, blogid, name );
@@ -280,11 +281,11 @@ public class MetaWeblogHandler implements WikiRPCHandler {
                       final String password,
                       final Hashtable< String,Object > content,
                       final boolean publish ) throws XmlRpcException {
-        final WikiEngine engine = m_context.getEngine();
+        final Engine engine = m_context.getEngine();
         log.info("metaWeblog.editPost("+postid+") called");
 
         // FIXME: Is postid correct?  Should we determine it from the page name?
-        final WikiPage page = engine.getPageManager().getPage( postid );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( postid );
         checkPermissions( page, username, password, "edit" );
 
         try {
@@ -300,7 +301,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
 
             log.debug("Updating entry: "+text);
 
-            engine.getPageManager().saveText( context, text.toString() );
+            engine.getManager( PageManager.class ).saveText( context, text.toString() );
         } catch( final Exception e ) {
             log.error("Failed to create weblog entry",e);
             throw new XmlRpcException( 0, "Failed to update weblog entry: "+e.getMessage() );
@@ -315,7 +316,7 @@ public class MetaWeblogHandler implements WikiRPCHandler {
      */
     Hashtable< String, Object > getPost( final String postid, final String username, final String password ) throws XmlRpcException {
         final String wikiname = "FIXME";
-        final WikiPage page = m_context.getEngine().getPageManager().getPage( wikiname );
+        final WikiPage page = m_context.getEngine().getManager( PageManager.class ).getPage( wikiname );
         checkPermissions( page, username, password, "view" );
         return makeEntry( page );
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandler.java
index e2a8f40..7bf5423 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandler.java
@@ -25,6 +25,8 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 import org.apache.xmlrpc.XmlRpcException;
 
@@ -77,7 +79,7 @@ public class RPCHandler extends AbstractRPCHandler {
 
     public Vector< String > getAllPages() {
         checkPermission( PagePermission.VIEW );
-        final Collection< WikiPage > pages = m_engine.getPageManager().getRecentChanges();
+        final Collection< WikiPage > pages = m_engine.getManager( PageManager.class ).getRecentChanges();
         final Vector< String > result = new Vector<>();
 
         for( final WikiPage p : pages ) {
@@ -128,7 +130,7 @@ public class RPCHandler extends AbstractRPCHandler {
     @Override
     public Vector< Hashtable< String, Object > > getRecentChanges( Date since ) {
         checkPermission( PagePermission.VIEW );
-        final Set< WikiPage > pages = m_engine.getPageManager().getRecentChanges();
+        final Set< WikiPage > pages = m_engine.getManager( PageManager.class ).getRecentChanges();
         final Vector< Hashtable< String, Object > > result = new Vector<>();
 
         final Calendar cal = Calendar.getInstance();
@@ -162,11 +164,11 @@ public class RPCHandler extends AbstractRPCHandler {
     private String parsePageCheckCondition( String pagename ) throws XmlRpcException {
         pagename = fromRPCString( pagename );
 
-        if( !m_engine.getPageManager().wikiPageExists(pagename) ) {
+        if( !m_engine.getManager( PageManager.class ).wikiPageExists(pagename) ) {
             throw new XmlRpcException( ERR_NOPAGE, "No such page '"+pagename+"' found, o master." );
         }
 
-        final WikiPage p = m_engine.getPageManager().getPage( pagename );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( pagename );
 
         checkPermission( PermissionFactory.getPagePermission( p, PagePermission.VIEW_ACTION ) );
 
@@ -175,50 +177,50 @@ public class RPCHandler extends AbstractRPCHandler {
 
     public Hashtable getPageInfo( String pagename ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
-        return encodeWikiPage( m_engine.getPageManager().getPage(pagename) );
+        return encodeWikiPage( m_engine.getManager( PageManager.class ).getPage(pagename) );
     }
 
-    public Hashtable getPageInfoVersion( String pagename, int version ) throws XmlRpcException {
+    public Hashtable getPageInfoVersion( String pagename, final int version ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        return encodeWikiPage( m_engine.getPageManager().getPage( pagename, version ) );
+        return encodeWikiPage( m_engine.getManager( PageManager.class ).getPage( pagename, version ) );
     }
 
     public byte[] getPage( final String pagename ) throws XmlRpcException {
-        final String text = m_engine.getPageManager().getPureText( parsePageCheckCondition( pagename ), -1 );
+        final String text = m_engine.getManager( PageManager.class ).getPureText( parsePageCheckCondition( pagename ), -1 );
         return toRPCBase64( text );
     }
 
     public byte[] getPageVersion( String pagename, final int version ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        return toRPCBase64( m_engine.getPageManager().getPureText( pagename, version ) );
+        return toRPCBase64( m_engine.getManager( PageManager.class ).getPureText( pagename, version ) );
     }
 
     public byte[] getPageHTML( String pagename ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        return toRPCBase64( m_engine.getRenderingManager().getHTML( pagename ) );
+        return toRPCBase64( m_engine.getManager( RenderingManager.class ).getHTML( pagename ) );
     }
 
-    public byte[] getPageHTMLVersion( String pagename, int version ) throws XmlRpcException {
+    public byte[] getPageHTMLVersion( String pagename, final int version ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        return toRPCBase64( m_engine.getRenderingManager().getHTML( pagename, version ) );
+        return toRPCBase64( m_engine.getManager( RenderingManager.class ).getHTML( pagename, version ) );
     }
 
     public Vector< Hashtable< String, String > > listLinks( String pagename ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        final WikiPage page = m_engine.getPageManager().getPage( pagename );
-        final String pagedata = m_engine.getPageManager().getPureText( page );
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pagename );
+        final String pagedata = m_engine.getManager( PageManager.class ).getPureText( page );
 
         final LinkCollector localCollector = new LinkCollector();
         final LinkCollector extCollector   = new LinkCollector();
         final LinkCollector attCollector   = new LinkCollector();
 
         final WikiContext context = new WikiContext( m_engine, page );
-        m_engine.getRenderingManager().textToHTML( context, pagedata, localCollector, extCollector, attCollector );
+        m_engine.getManager( RenderingManager.class ).textToHTML( context, pagedata, localCollector, extCollector, attCollector );
 
         final Vector< Hashtable< String, String > > result = new Vector<>();
 
@@ -240,7 +242,7 @@ public class RPCHandler extends AbstractRPCHandler {
             //  FIXME: The current link collector interface is not very good, since it causes this.
             //
 
-            if( m_engine.getPageManager().wikiPageExists( link ) ) {
+            if( m_engine.getManager( PageManager.class ).wikiPageExists( link ) ) {
                 ht.put( "href", context.getURL( WikiContext.VIEW, link ) );
             } else {
                 ht.put( "href", context.getURL( WikiContext.EDIT, link ) );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandlerUTF8.java b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandlerUTF8.java
index 40f143f..a184ec2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandlerUTF8.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCHandlerUTF8.java
@@ -24,6 +24,8 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.xmlrpc.XmlRpcException;
 
 import java.util.Calendar;
@@ -49,7 +51,7 @@ public class RPCHandlerUTF8 extends AbstractRPCHandler {
     public Vector< String > getAllPages() {
         checkPermission( PagePermission.VIEW );
 
-        final Set< WikiPage > pages = m_engine.getPageManager().getRecentChanges();
+        final Set< WikiPage > pages = m_engine.getManager( PageManager.class ).getRecentChanges();
         final Vector< String > result = new Vector<>();
 
         for( final WikiPage p : pages ) {
@@ -64,7 +66,7 @@ public class RPCHandlerUTF8 extends AbstractRPCHandler {
     /**
      *  Encodes a single wiki page info into a Hashtable.
      */
-    protected Hashtable<String, Object> encodeWikiPage( final WikiPage page ) {
+    @Override protected Hashtable<String, Object> encodeWikiPage( final WikiPage page ) {
         final Hashtable<String, Object> ht = new Hashtable<>();
         ht.put( "name", page.getName() );
 
@@ -90,10 +92,10 @@ public class RPCHandlerUTF8 extends AbstractRPCHandler {
         return ht;
     }
 
-    public Vector< Hashtable< String, Object > > getRecentChanges( Date since ) {
+    @Override public Vector< Hashtable< String, Object > > getRecentChanges( Date since ) {
         checkPermission( PagePermission.VIEW );
 
-        final Set< WikiPage > pages = m_engine.getPageManager().getRecentChanges();
+        final Set< WikiPage > pages = m_engine.getManager( PageManager.class ).getRecentChanges();
         final Vector< Hashtable< String, Object > > result = new Vector<>();
 
         final Calendar cal = Calendar.getInstance();
@@ -125,54 +127,54 @@ public class RPCHandlerUTF8 extends AbstractRPCHandler {
      *  @throws XmlRpcException, if there is something wrong with the page.
      */
     private String parsePageCheckCondition( final String pagename ) throws XmlRpcException {
-        if( !m_engine.getPageManager().wikiPageExists(pagename) ) {
+        if( !m_engine.getManager( PageManager.class ).wikiPageExists(pagename) ) {
             throw new XmlRpcException( ERR_NOPAGE, "No such page '"+pagename+"' found, o master." );
         }
 
-        final WikiPage p = m_engine.getPageManager().getPage( pagename );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( pagename );
 
         checkPermission( PermissionFactory.getPagePermission( p, PagePermission.VIEW_ACTION ) );
         return pagename;
     }
 
     public Hashtable<String, Object> getPageInfo( final String pagename ) throws XmlRpcException {
-        return encodeWikiPage( m_engine.getPageManager().getPage( parsePageCheckCondition( pagename ) ) );
+        return encodeWikiPage( m_engine.getManager( PageManager.class ).getPage( parsePageCheckCondition( pagename ) ) );
     }
 
     public Hashtable<String, Object> getPageInfoVersion( String pagename, final int version ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        return encodeWikiPage( m_engine.getPageManager().getPage( pagename, version ) );
+        return encodeWikiPage( m_engine.getManager( PageManager.class ).getPage( pagename, version ) );
     }
 
     public String getPage( final String pagename ) throws XmlRpcException {
-        return m_engine.getPageManager().getPureText( parsePageCheckCondition( pagename ), -1 );
+        return m_engine.getManager( PageManager.class ).getPureText( parsePageCheckCondition( pagename ), -1 );
     }
 
     public String getPageVersion( final String pagename, final int version ) throws XmlRpcException {
-        return m_engine.getPageManager().getPureText( parsePageCheckCondition( pagename ), version );
+        return m_engine.getManager( PageManager.class ).getPureText( parsePageCheckCondition( pagename ), version );
     }
 
     public String getPageHTML( final String pagename ) throws XmlRpcException  {
-        return m_engine.getRenderingManager().getHTML( parsePageCheckCondition( pagename ) );
+        return m_engine.getManager( RenderingManager.class ).getHTML( parsePageCheckCondition( pagename ) );
     }
 
     public String getPageHTMLVersion( final String pagename, final int version ) throws XmlRpcException {
-        return m_engine.getRenderingManager().getHTML( parsePageCheckCondition( pagename ), version );
+        return m_engine.getManager( RenderingManager.class ).getHTML( parsePageCheckCondition( pagename ), version );
     }
 
     public Vector< Hashtable< String, String > > listLinks( String pagename ) throws XmlRpcException {
         pagename = parsePageCheckCondition( pagename );
 
-        final WikiPage page = m_engine.getPageManager().getPage( pagename );
-        final String pagedata = m_engine.getPageManager().getPureText( page );
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pagename );
+        final String pagedata = m_engine.getManager( PageManager.class ).getPureText( page );
 
         final LinkCollector localCollector = new LinkCollector();
         final LinkCollector extCollector   = new LinkCollector();
         final LinkCollector attCollector   = new LinkCollector();
 
         final WikiContext context = new WikiContext( m_engine, page );
-        m_engine.getRenderingManager().textToHTML( context, pagedata, localCollector, extCollector, attCollector );
+        m_engine.getManager( RenderingManager.class ).textToHTML( context, pagedata, localCollector, extCollector, attCollector );
 
         final Vector< Hashtable< String, String > > result = new Vector<>();
 
@@ -186,7 +188,7 @@ public class RPCHandlerUTF8 extends AbstractRPCHandler {
             ht.put( "page", link );
             ht.put( "type", LINK_LOCAL );
 
-            if( m_engine.getPageManager().wikiPageExists( link ) ) {
+            if( m_engine.getManager( PageManager.class ).wikiPageExists( link ) ) {
                 ht.put( "href", context.getViewURL( link ) );
             } else {
                 ht.put( "href", context.getURL( WikiContext.EDIT, link ) );


[jspwiki] 29/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (6)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit e9f724fd26fcefeb1bc7222eb0c92b44ea22133e
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:14:29 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (6)
---
 .../apache/wiki/attachment/AttachmentServlet.java  |  60 +++---
 .../wiki/attachment/DefaultAttachmentManager.java  |   2 +-
 .../apache/wiki/content/DefaultPageRenamer.java    |  64 ++++---
 .../apache/wiki/diff/DefaultDifferenceManager.java |   9 +-
 .../apache/wiki/filters/PingWeblogsComFilter.java  |  11 +-
 .../java/org/apache/wiki/filters/SpamFilter.java   | 211 +++++++++++----------
 .../java/org/apache/wiki/forms/FormOutput.java     |  56 ++----
 .../org/apache/wiki/pages/DefaultPageManager.java  |  30 +--
 8 files changed, 219 insertions(+), 224 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentServlet.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentServlet.java
index 53c6b7f..9abea2d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentServlet.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentServlet.java
@@ -109,11 +109,11 @@ public class AttachmentServlet extends HttpServlet {
      *  Initializes the servlet from WikiEngine properties.
      *
      */
-    public void init( ServletConfig config ) throws ServletException {
-        String tmpDir;
+    @Override public void init( final ServletConfig config ) throws ServletException {
+        final String tmpDir;
 
         m_engine         = WikiEngine.getInstance( config );
-        Properties props = m_engine.getWikiProperties();
+        final Properties props = m_engine.getWikiProperties();
 
         tmpDir         = m_engine.getWorkDir()+File.separator+"attach-tmp";
 
@@ -121,7 +121,7 @@ public class AttachmentServlet extends HttpServlet {
                 AttachmentManager.PROP_MAXSIZE,
                 Integer.MAX_VALUE );
 
-        String allowed = TextUtil.getStringProperty( props,
+        final String allowed = TextUtil.getStringProperty( props,
                 AttachmentManager.PROP_ALLOWEDEXTENSIONS,
                 null );
 
@@ -130,7 +130,7 @@ public class AttachmentServlet extends HttpServlet {
         else
             m_allowedPatterns = new String[0];
 
-        String forbidden = TextUtil.getStringProperty( props,
+        final String forbidden = TextUtil.getStringProperty( props,
                 AttachmentManager.PROP_FORBIDDENEXTENSIONS,
                 null );
 
@@ -139,7 +139,7 @@ public class AttachmentServlet extends HttpServlet {
         else
             m_forbiddenPatterns = new String[0];
 
-        File f = new File( tmpDir );
+        final File f = new File( tmpDir );
         if( !f.exists() )
         {
             f.mkdirs();
@@ -181,7 +181,7 @@ public class AttachmentServlet extends HttpServlet {
      *  @param res The servlet response
      */
 
-    protected void doOptions( HttpServletRequest req, HttpServletResponse res )
+    @Override protected void doOptions( final HttpServletRequest req, final HttpServletResponse res )
     {
         res.setHeader( "Allow", "GET, PUT, POST, OPTIONS, PROPFIND, PROPPATCH, MOVE, COPY, DELETE");
         res.setStatus( HttpServletResponse.SC_OK );
@@ -193,9 +193,9 @@ public class AttachmentServlet extends HttpServlet {
      *
      */
     // FIXME: Messages would need to be localized somehow.
-    public void doGet( final HttpServletRequest  req, final HttpServletResponse res ) throws IOException {
+    @Override public void doGet( final HttpServletRequest  req, final HttpServletResponse res ) throws IOException {
         final WikiContext context = new WikiContext( m_engine, req, WikiContext.ATTACH );
-        final AttachmentManager mgr = m_engine.getAttachmentManager();
+        final AttachmentManager mgr = m_engine.getManager( AttachmentManager.class );
         final AuthorizationManager authmgr = m_engine.getAuthorizationManager();
 
         final String version = req.getParameter( HDR_VERSION );
@@ -339,14 +339,14 @@ public class AttachmentServlet extends HttpServlet {
      * @param fileName The name to check for.
      * @return A valid mime type, or application/binary, if not recognized
      */
-    private static String getMimeType(WikiContext ctx, String fileName )
+    private static String getMimeType( final WikiContext ctx, final String fileName )
     {
         String mimetype = null;
 
-        HttpServletRequest req = ctx.getHttpRequest();
+        final HttpServletRequest req = ctx.getHttpRequest();
         if( req != null )
         {
-            ServletContext s = req.getSession().getServletContext();
+            final ServletContext s = req.getSession().getServletContext();
 
             if( s != null )
             {
@@ -373,13 +373,13 @@ public class AttachmentServlet extends HttpServlet {
      * content of the file.
      *
      */
-    public void doPost( final HttpServletRequest req, final HttpServletResponse res ) throws IOException {
+    @Override public void doPost( final HttpServletRequest req, final HttpServletResponse res ) throws IOException {
         try {
             final String nextPage = upload( req );
             req.getSession().removeAttribute("msg");
             res.sendRedirect( nextPage );
         } catch( final RedirectException e ) {
-            WikiSession session = WikiSession.getWikiSession( m_engine, req );
+            final WikiSession session = WikiSession.getWikiSession( m_engine, req );
             session.addMessage( e.getMessage() );
 
             req.getSession().setAttribute("msg", e.getMessage());
@@ -391,7 +391,7 @@ public class AttachmentServlet extends HttpServlet {
      *  Validates the next page to be on the same server as this webapp.
      *  Fixes [JSPWIKI-46].
      */
-    private String validateNextPage( String nextPage, String errorPage )
+    private String validateNextPage( String nextPage, final String errorPage )
     {
         if( nextPage.indexOf("://") != -1 )
         {
@@ -444,12 +444,12 @@ public class AttachmentServlet extends HttpServlet {
                 upload.setFileSizeMax( m_maxSize );
             }
             upload.setProgressListener( pl );
-            List<FileItem> items = upload.parseRequest( req );
+            final List<FileItem> items = upload.parseRequest( req );
 
             String   wikipage   = null;
             String   changeNote = null;
             //FileItem actualFile = null;
-            List<FileItem> fileItems = new ArrayList<>();
+            final List<FileItem> fileItems = new ArrayList<>();
 
             for( final FileItem item : items ) {
                 if( item.isFormField() ) {
@@ -459,7 +459,7 @@ public class AttachmentServlet extends HttpServlet {
                         //
 
                         wikipage = item.getString("UTF-8");
-                        int x = wikipage.indexOf("/");
+                        final int x = wikipage.indexOf("/");
 
                         if( x != -1 ) wikipage = wikipage.substring(0,x);
                     } else if( item.getFieldName().equals("changenote") ) {
@@ -479,10 +479,10 @@ public class AttachmentServlet extends HttpServlet {
                 throw new RedirectException( "Broken file upload", errorPage );
 
             } else {
-                for( FileItem actualFile : fileItems ) {
-                    String filename = actualFile.getName();
-                    long   fileSize = actualFile.getSize();
-                    try( InputStream in  = actualFile.getInputStream() ) {
+                for( final FileItem actualFile : fileItems ) {
+                    final String filename = actualFile.getName();
+                    final long   fileSize = actualFile.getSize();
+                    try( final InputStream in  = actualFile.getInputStream() ) {
                         executeUpload( context, in, filename, nextPage, wikipage, changeNote, fileSize );
                     }
                 }
@@ -528,10 +528,10 @@ public class AttachmentServlet extends HttpServlet {
      * @throws IOException       If there is a problem in the upload.
      * @throws ProviderException If there is a problem in the backend.
      */
-    protected boolean executeUpload( WikiContext context, InputStream data,
-                                     String filename, String errorPage,
-                                     String parentPage, String changenote,
-                                     long contentLength )
+    protected boolean executeUpload( final WikiContext context, final InputStream data,
+                                     String filename, final String errorPage,
+                                     final String parentPage, final String changenote,
+                                     final long contentLength )
             throws RedirectException,
             IOException, ProviderException
     {
@@ -564,7 +564,7 @@ public class AttachmentServlet extends HttpServlet {
         }
 
         final Principal user    = context.getCurrentUser();
-        final AttachmentManager mgr = m_engine.getAttachmentManager();
+        final AttachmentManager mgr = m_engine.getManager( AttachmentManager.class );
 
         log.debug("file="+filename);
 
@@ -607,7 +607,7 @@ public class AttachmentServlet extends HttpServlet {
             }
 
             try {
-                m_engine.getAttachmentManager().storeAttachment( att, data );
+                m_engine.getManager( AttachmentManager.class ).storeAttachment( att, data );
             } catch( final ProviderException pe ) {
                 // this is a kludge, the exception that is caught here contains the i18n key
                 // here we have the context available, so we can internationalize it properly :
@@ -630,12 +630,12 @@ public class AttachmentServlet extends HttpServlet {
         public long m_currentBytes;
         public long m_totalBytes;
 
-        public void update( final long recvdBytes, final long totalBytes, final int item) {
+        @Override public void update( final long recvdBytes, final long totalBytes, final int item) {
             m_currentBytes = recvdBytes;
             m_totalBytes   = totalBytes;
         }
 
-        public int getProgress() {
+        @Override public int getProgress() {
             return ( int )( ( ( float )m_currentBytes / m_totalBytes ) * 100 + 0.5 );
         }
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
index 4cf397c..3070d2f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/DefaultAttachmentManager.java
@@ -66,7 +66,7 @@ public class DefaultAttachmentManager implements AttachmentManager {
     /**
      *  Creates a new AttachmentManager.  Note that creation will never fail, but it's quite likely that attachments do not function.
      *  <p><b>DO NOT CREATE</b> an AttachmentManager on your own, unless you really know what you're doing. Just use
-     *  WikiEngine.getAttachmentManager() if you're making a module for JSPWiki.
+     *  Wikiengine.getManager( AttachmentManager.class ) if you're making a module for JSPWiki.
      *
      *  @param engine The wikiengine that owns this attachment manager.
      *  @param props A list of properties from which the AttachmentManager will seek its configuration. Typically this is the "jspwiki.properties".
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/content/DefaultPageRenamer.java b/jspwiki-main/src/main/java/org/apache/wiki/content/DefaultPageRenamer.java
index e586d45..3df9abd 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/content/DefaultPageRenamer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/content/DefaultPageRenamer.java
@@ -21,15 +21,19 @@ package org.apache.wiki.content;
 import org.apache.log4j.Logger;
 import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiPageRenameEvent;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.JSPWikiMarkupParser;
 import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.references.ReferenceManager;
+import org.apache.wiki.search.SearchManager;
 import org.apache.wiki.util.TextUtil;
 
 import java.util.Collection;
@@ -62,7 +66,7 @@ public class DefaultPageRenamer implements PageRenamer {
      *  @return The final new name (in case it had to be modified)
      *  @throws WikiException If the page cannot be renamed.
      */
-    public String renamePage( final WikiContext context, final String renameFrom, final String renameTo, final boolean changeReferrers ) throws WikiException {
+    @Override public String renamePage( final WikiContext context, final String renameFrom, final String renameTo, final boolean changeReferrers ) throws WikiException {
         //  Sanity checks first
         if( renameFrom == null || renameFrom.length() == 0 ) {
             throw new WikiException( "From name may not be null or empty" );
@@ -78,12 +82,12 @@ public class DefaultPageRenamer implements PageRenamer {
         }
         
         //  Preconditions: "from" page must exist, and "to" page must not yet exist.
-        final WikiEngine engine = context.getEngine();
-        final WikiPage fromPage = engine.getPageManager().getPage( renameFrom );
+        final Engine engine = context.getEngine();
+        final WikiPage fromPage = engine.getManager( PageManager.class ).getPage( renameFrom );
         if( fromPage == null ) {
             throw new WikiException("No such page "+renameFrom);
         }
-        WikiPage toPage = engine.getPageManager().getPage( renameToClean );
+        WikiPage toPage = engine.getManager( PageManager.class ).getPage( renameToClean );
         if( toPage != null ) {
             throw new WikiException( "Page already exists " + renameToClean );
         }
@@ -92,29 +96,29 @@ public class DefaultPageRenamer implements PageRenamer {
 
         //  Do the actual rename by changing from the frompage to the topage, including all of the attachments
         //  Remove references to attachments under old name
-        final List< Attachment > attachmentsOldName = engine.getAttachmentManager().listAttachments( fromPage );
+        final List< Attachment > attachmentsOldName = engine.getManager( AttachmentManager.class ).listAttachments( fromPage );
         for( final Attachment att: attachmentsOldName ) {
-            final WikiPage fromAttPage = engine.getPageManager().getPage( att.getName() );
-            engine.getReferenceManager().pageRemoved( fromAttPage );
+            final WikiPage fromAttPage = engine.getManager( PageManager.class ).getPage( att.getName() );
+            engine.getManager( ReferenceManager.class ).pageRemoved( fromAttPage );
         }
 
-        engine.getPageManager().getProvider().movePage( renameFrom, renameToClean );
-        if( engine.getAttachmentManager().attachmentsEnabled() ) {
-            engine.getAttachmentManager().getCurrentProvider().moveAttachmentsForPage( renameFrom, renameToClean );
+        engine.getManager( PageManager.class ).getProvider().movePage( renameFrom, renameToClean );
+        if( engine.getManager( AttachmentManager.class ).attachmentsEnabled() ) {
+            engine.getManager( AttachmentManager.class ).getCurrentProvider().moveAttachmentsForPage( renameFrom, renameToClean );
         }
         
         //  Add a comment to the page notifying what changed.  This adds a new revision to the repo with no actual change.
-        toPage = engine.getPageManager().getPage( renameToClean );
+        toPage = engine.getManager( PageManager.class ).getPage( renameToClean );
         if( toPage == null ) {
             throw new InternalWikiException( "Rename seems to have failed for some strange reason - please check logs!" );
         }
         toPage.setAttribute( WikiPage.CHANGENOTE, fromPage.getName() + " ==> " + toPage.getName() );
         toPage.setAuthor( context.getCurrentUser().getName() );
-        engine.getPageManager().putPageText( toPage, engine.getPageManager().getPureText( toPage ) );
+        engine.getManager( PageManager.class ).putPageText( toPage, engine.getManager( PageManager.class ).getPureText( toPage ) );
 
         //  Update the references
-        engine.getReferenceManager().pageRemoved( fromPage );
-        engine.getReferenceManager().updateReferences( toPage );
+        engine.getManager( ReferenceManager.class ).pageRemoved( fromPage );
+        engine.getManager( ReferenceManager.class ).updateReferences( toPage );
 
         //  Update referrers
         if( changeReferrers ) {
@@ -122,14 +126,14 @@ public class DefaultPageRenamer implements PageRenamer {
         }
 
         //  re-index the page including its attachments
-        engine.getSearchManager().reindexPage( toPage );
+        engine.getManager( SearchManager.class ).reindexPage( toPage );
         
-        final Collection< Attachment > attachmentsNewName = engine.getAttachmentManager().listAttachments( toPage );
+        final Collection< Attachment > attachmentsNewName = engine.getManager( AttachmentManager.class ).listAttachments( toPage );
         for( final Attachment att:attachmentsNewName ) {
-            final WikiPage toAttPage = engine.getPageManager().getPage( att.getName() );
+            final WikiPage toAttPage = engine.getManager( PageManager.class ).getPage( att.getName() );
             // add reference to attachment under new page name
-            engine.getReferenceManager().updateReferences( toAttPage );
-            engine.getSearchManager().reindexPage( att );
+            engine.getManager( ReferenceManager.class ).updateReferences( toAttPage );
+            engine.getManager( SearchManager.class ).reindexPage( att );
         }
 
         firePageRenameEvent( renameFrom, renameToClean );
@@ -145,7 +149,7 @@ public class DefaultPageRenamer implements PageRenamer {
      * @param oldName the former page name
      * @param newName the new page name
      */
-    public void firePageRenameEvent( final String oldName, final String newName ) {
+    @Override public void firePageRenameEvent( final String oldName, final String newName ) {
         if( WikiEventManager.isListening(this) ) {
             WikiEventManager.fireEvent(this, new WikiPageRenameEvent(this, oldName, newName ) );
         }
@@ -164,16 +168,16 @@ public class DefaultPageRenamer implements PageRenamer {
             return;
         }
 
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
         for( String pageName : referrers ) {
             //  In case the page was just changed from under us, let's do this small kludge.
             if( pageName.equals( fromPage.getName() ) ) {
                 pageName = toPage.getName();
             }
             
-            final WikiPage p = engine.getPageManager().getPage( pageName );
+            final WikiPage p = engine.getManager( PageManager.class ).getPage( pageName );
 
-            final String sourceText = engine.getPageManager().getPureText( p );
+            final String sourceText = engine.getManager( PageManager.class ).getPureText( p );
             String newText = replaceReferrerString( context, sourceText, fromPage.getName(), toPage.getName() );
 
             m_camelCase = TextUtil.getBooleanProperty( engine.getWikiProperties(), JSPWikiMarkupParser.PROP_CAMELCASELINKS, m_camelCase );
@@ -186,8 +190,8 @@ public class DefaultPageRenamer implements PageRenamer {
                 p.setAuthor( context.getCurrentUser().getName() );
          
                 try {
-                    engine.getPageManager().putPageText( p, newText );
-                    engine.getReferenceManager().updateReferences( p );
+                    engine.getManager( PageManager.class ).putPageText( p, newText );
+                    engine.getManager( ReferenceManager.class ).updateReferences( p );
                 } catch( final ProviderException e ) {
                     //  We fail with an error, but we will try to continue to rename other referrers as well.
                     log.error("Unable to perform rename.",e);
@@ -196,17 +200,17 @@ public class DefaultPageRenamer implements PageRenamer {
         }
     }
 
-    private Set<String> getReferencesToChange( final WikiPage fromPage, final WikiEngine engine ) {
+    private Set<String> getReferencesToChange( final WikiPage fromPage, final Engine engine ) {
         final Set< String > referrers = new TreeSet<>();
-        final Collection< String > r = engine.getReferenceManager().findReferrers( fromPage.getName() );
+        final Collection< String > r = engine.getManager( ReferenceManager.class ).findReferrers( fromPage.getName() );
         if( r != null ) {
             referrers.addAll( r );
         }
         
         try {
-            final List< Attachment > attachments = engine.getAttachmentManager().listAttachments( fromPage );
+            final List< Attachment > attachments = engine.getManager( AttachmentManager.class ).listAttachments( fromPage );
             for( final Attachment att : attachments  ) {
-                final Collection< String > c = engine.getReferenceManager().findReferrers( att.getName() );
+                final Collection< String > c = engine.getManager( ReferenceManager.class ).findReferrers( att.getName() );
                 if( c != null ) {
                     referrers.addAll( c );
                 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/DefaultDifferenceManager.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/DefaultDifferenceManager.java
index 62229b9..859aed6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/DefaultDifferenceManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/DefaultDifferenceManager.java
@@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 import org.apache.wiki.util.ClassUtil;
 
@@ -85,7 +86,7 @@ public class DefaultDifferenceManager implements DifferenceManager {
      * @param secondWikiText the new text
      * @return XHTML, or empty string, if no difference detected.
      */
-    public String makeDiff( final WikiContext context, final String firstWikiText, final String secondWikiText ) {
+    @Override public String makeDiff( final WikiContext context, final String firstWikiText, final String secondWikiText ) {
         String diff;
         try {
             diff = m_provider.makeDiffHtml( context, firstWikiText, secondWikiText );
@@ -111,10 +112,10 @@ public class DefaultDifferenceManager implements DifferenceManager {
      *
      *  @return A HTML-ized difference between two pages.  If there is no difference, returns an empty string.
      */
-    public String getDiff( final WikiContext context, final int version1, final int version2 ) {
+    @Override public String getDiff( final WikiContext context, final int version1, final int version2 ) {
         final String page = context.getPage().getName();
-        String page1 = context.getEngine().getPageManager().getPureText( page, version1 );
-        final String page2 = context.getEngine().getPageManager().getPureText( page, version2 );
+        String page1 = context.getEngine().getManager( PageManager.class ).getPureText( page, version1 );
+        final String page2 = context.getEngine().getManager( PageManager.class ).getPureText( page, version2 );
 
         // Kludge to make diffs for new pages to work this way.
         if( version1 == WikiPageProvider.LATEST_VERSION ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/filters/PingWeblogsComFilter.java b/jspwiki-main/src/main/java/org/apache/wiki/filters/PingWeblogsComFilter.java
index f2a139a..6e1bfe6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/filters/PingWeblogsComFilter.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/filters/PingWeblogsComFilter.java
@@ -21,6 +21,7 @@ package org.apache.wiki.filters;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.filters.BasicPageFilter;
 import org.apache.xmlrpc.AsyncCallback;
 import org.apache.xmlrpc.XmlRpcClient;
@@ -52,16 +53,16 @@ public class PingWeblogsComFilter extends BasicPageFilter {
     /**
      *  {@inheritDoc}
      */
-    public void initialize( final WikiEngine engine, final Properties props ) {
+    @Override public void initialize( final WikiEngine engine, final Properties props ) {
         m_pingURL = props.getProperty( PROP_PINGURL, "http://rpc.weblogs.com/RPC2" );
     }
 
     /**
      *  {@inheritDoc}
      */
-    public void postSave( final WikiContext context, final String pagecontent ) {
+    @Override public void postSave( final WikiContext context, final String pagecontent ) {
         String blogName = context.getPage().getName();
-        final WikiEngine engine   = context.getEngine();
+        final Engine engine   = context.getEngine();
 
         final int blogentryTxt = blogName.indexOf("_blogentry_");
         if( blogentryTxt == -1 ) {
@@ -86,11 +87,11 @@ public class PingWeblogsComFilter extends BasicPageFilter {
 
             xmlrpc.executeAsync("weblogUpdates.ping", params, 
                                 new AsyncCallback() {
-                                    public void handleError( final Exception ex, final URL url, final String method ) {
+                                    @Override public void handleError( final Exception ex, final URL url, final String method ) {
                                         log.error( "Unable to execute weblogs.com ping to URL: " + url.toString(), ex );
                                     }
 
-                                    public void handleResult( final Object result, final URL url, final String method ) {
+                                    @Override public void handleResult( final Object result, final URL url, final String method ) {
                                         @SuppressWarnings("unchecked")
                                         final Hashtable< String, Object > res = (Hashtable < String, Object > ) result;
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/filters/SpamFilter.java b/jspwiki-main/src/main/java/org/apache/wiki/filters/SpamFilter.java
index c018bfc..0175d6c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/filters/SpamFilter.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/filters/SpamFilter.java
@@ -33,11 +33,14 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.exceptions.RedirectException;
 import org.apache.wiki.api.filters.BasicPageFilter;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.ui.EditorManager;
 import org.apache.wiki.util.FileUtil;
 import org.apache.wiki.util.HttpUtil;
@@ -194,11 +197,11 @@ public class SpamFilter extends BasicPageFilter {
     private static  Logger  log = Logger.getLogger( SpamFilter.class );
 
 
-    private Vector<Host>    m_temporaryBanList = new Vector<Host>();
+    private Vector<Host>    m_temporaryBanList = new Vector<>();
 
     private int             m_banTime = 60; // minutes
 
-    private Vector<Host>    m_lastModifications = new Vector<Host>();
+    private Vector<Host>    m_lastModifications = new Vector<>();
 
     /**
      *  How many times a single IP address can change a page per minute?
@@ -247,7 +250,7 @@ public class SpamFilter extends BasicPageFilter {
      *  {@inheritDoc}
      */
     @Override
-    public void initialize( WikiEngine engine, Properties properties ) {
+    public void initialize( final WikiEngine engine, final Properties properties ) {
         m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST, m_forbiddenWordsPage );
         m_forbiddenIPsPage = properties.getProperty( PROP_IPLIST, m_forbiddenIPsPage);
         m_pageNameMaxLength = properties.getProperty( PROP_MAX_PAGENAME_LENGTH, m_pageNameMaxLength);
@@ -272,7 +275,7 @@ public class SpamFilter extends BasicPageFilter {
 
         try {
             m_urlPattern = m_compiler.compile( URL_REGEXP );
-        } catch( MalformedPatternException e ) {
+        } catch( final MalformedPatternException e ) {
             log.fatal( "Internal error: Someone put in a faulty pattern.", e );
             throw new InternalWikiException( "Faulty pattern." , e);
         }
@@ -295,15 +298,15 @@ public class SpamFilter extends BasicPageFilter {
     private static final int ACCEPT = 1;
     private static final int NOTE   = 2;
 
-    private static String log( WikiContext ctx, int type, String source, String message ) {
+    private static String log( final WikiContext ctx, final int type, final String source, String message ) {
         message = TextUtil.replaceString( message, "\r\n", "\\r\\n" );
         message = TextUtil.replaceString( message, "\"", "\\\"" );
 
-        String uid = getUniqueID();
+        final String uid = getUniqueID();
 
-        String page   = ctx.getPage().getName();
+        final String page   = ctx.getPage().getName();
         String reason = "UNKNOWN";
-        String addr   = ctx.getHttpRequest() != null ? HttpUtil.getRemoteAddress( ctx.getHttpRequest() ) : "-";
+        final String addr   = ctx.getHttpRequest() != null ? HttpUtil.getRemoteAddress( ctx.getHttpRequest() ) : "-";
 
         switch( type ) {
             case REJECT:
@@ -324,10 +327,10 @@ public class SpamFilter extends BasicPageFilter {
     }
 
     /** {@inheritDoc} */
-    public String preSave( WikiContext context, String content ) throws RedirectException {
+    @Override public String preSave( final WikiContext context, final String content ) throws RedirectException {
         cleanBanList();
         refreshBlacklists( context );
-        Change change = getChange( context, content );
+        final Change change = getChange( context, content );
 
         if( !ignoreThisUser( context ) ) {
             checkBanList( context, change );
@@ -338,7 +341,7 @@ public class SpamFilter extends BasicPageFilter {
         }
 
         if( !m_stopAtFirstMatch ) {
-            Integer score = ( Integer )context.getVariable( ATTR_SPAMFILTER_SCORE );
+            final Integer score = ( Integer )context.getVariable( ATTR_SPAMFILTER_SCORE );
 
             if( score != null && score.intValue() >= m_scoreLimit ) {
                 throw new RedirectException( "Herb says you got too many points", getRedirectPage( context ) );
@@ -349,16 +352,16 @@ public class SpamFilter extends BasicPageFilter {
         return content;
     }
 
-    private void checkPageName(WikiContext context, String content, Change change) throws RedirectException {
-        WikiPage page = context.getPage();
-        String pageName = page.getName();
-        int maxlength = Integer.valueOf(m_pageNameMaxLength);
+    private void checkPageName( final WikiContext context, final String content, final Change change) throws RedirectException {
+        final WikiPage page = context.getPage();
+        final String pageName = page.getName();
+        final int maxlength = Integer.valueOf(m_pageNameMaxLength);
         if ( pageName.length() > maxlength) {
             //
             //  Spam filter has a match.
             //
 
-            String uid = log( context, REJECT, REASON_PAGENAME_TOO_LONG + "(" + m_pageNameMaxLength + ")" , pageName);
+            final String uid = log( context, REJECT, REASON_PAGENAME_TOO_LONG + "(" + m_pageNameMaxLength + ")" , pageName);
 
             log.info("SPAM:PageNameTooLong (" + uid + "). The length of the page name is too large (" + pageName.length() + " , limit is " + m_pageNameMaxLength + ")");
             checkStrategy( context, REASON_PAGENAME_TOO_LONG, "Herb says '" + pageName + "' is a bad pageName and I trust Herb! (Incident code " + uid + ")" );
@@ -366,7 +369,7 @@ public class SpamFilter extends BasicPageFilter {
         }
     }
 
-    private void checkStrategy( WikiContext context, String error, String message ) throws RedirectException {
+    private void checkStrategy( final WikiContext context, final String error, final String message ) throws RedirectException {
         if( m_stopAtFirstMatch ) {
             throw new RedirectException( message, getRedirectPage( context ) );
         }
@@ -389,18 +392,18 @@ public class SpamFilter extends BasicPageFilter {
      * @param list
      * @return A Collection of the Patterns that were found from the lists.
      */
-    private Collection< Pattern > parseWordList( WikiPage source, String list ) {
-        ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern >();
+    private Collection< Pattern > parseWordList( final WikiPage source, final String list ) {
+        final ArrayList< Pattern > compiledpatterns = new ArrayList<>();
 
         if( list != null ) {
-            StringTokenizer tok = new StringTokenizer( list, " \t\n" );
+            final StringTokenizer tok = new StringTokenizer( list, " \t\n" );
 
             while( tok.hasMoreTokens() ) {
-                String pattern = tok.nextToken();
+                final String pattern = tok.nextToken();
 
                 try {
                     compiledpatterns.add( m_compiler.compile( pattern ) );
-                } catch( MalformedPatternException e ) {
+                } catch( final MalformedPatternException e ) {
                     log.debug( "Malformed spam filter pattern " + pattern );
                     source.setAttribute("error", "Malformed spam filter pattern " + pattern);
                 }
@@ -416,12 +419,12 @@ public class SpamFilter extends BasicPageFilter {
      *  @param list
      *  @return The parsed blacklist patterns.
      */
-    private Collection< Pattern > parseBlacklist( String list ) {
-        ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern >();
+    private Collection< Pattern > parseBlacklist( final String list ) {
+        final ArrayList< Pattern > compiledpatterns = new ArrayList<>();
 
         if( list != null ) {
             try {
-                BufferedReader in = new BufferedReader( new StringReader(list) );
+                final BufferedReader in = new BufferedReader( new StringReader(list) );
                 String line;
                 while( (line = in.readLine() ) != null ) {
                     line = line.trim();
@@ -434,11 +437,11 @@ public class SpamFilter extends BasicPageFilter {
 
                     try {
                         compiledpatterns.add( m_compiler.compile( line ) );
-                    } catch( MalformedPatternException e ) {
+                    } catch( final MalformedPatternException e ) {
                         log.debug( "Malformed spam filter pattern " + line );
                     }
                 }
-            } catch( IOException e ) {
+            } catch( final IOException e ) {
                 log.info( "Could not read patterns; returning what I got" , e );
             }
         }
@@ -454,21 +457,21 @@ public class SpamFilter extends BasicPageFilter {
      *  @param content
      *  @throws RedirectException
      */
-    private synchronized void checkSinglePageChange( WikiContext context, String content, Change change ) 
+    private synchronized void checkSinglePageChange( final WikiContext context, final String content, final Change change )
     		throws RedirectException {
-        HttpServletRequest req = context.getHttpRequest();
+        final HttpServletRequest req = context.getHttpRequest();
 
         if( req != null ) {
-            String addr = HttpUtil.getRemoteAddress( req );
+            final String addr = HttpUtil.getRemoteAddress( req );
             int hostCounter = 0;
             int changeCounter = 0;
 
             log.debug( "Change is " + change.m_change );
 
-            long time = System.currentTimeMillis() - 60*1000L; // 1 minute
+            final long time = System.currentTimeMillis() - 60*1000L; // 1 minute
 
-            for( Iterator< Host > i = m_lastModifications.iterator(); i.hasNext(); ) {
-                Host host = i.next();
+            for( final Iterator< Host > i = m_lastModifications.iterator(); i.hasNext(); ) {
+                final Host host = i.next();
 
                 //
                 //  Check if this item is invalid
@@ -500,19 +503,19 @@ public class SpamFilter extends BasicPageFilter {
             //  Now, let's check against the limits.
             //
             if( hostCounter >= m_limitSinglePageChanges ) {
-                Host host = new Host( addr, null );
+                final Host host = new Host( addr, null );
                 m_temporaryBanList.add( host );
 
-                String uid = log( context, REJECT, REASON_TOO_MANY_MODIFICATIONS, change.m_change );
+                final String uid = log( context, REJECT, REASON_TOO_MANY_MODIFICATIONS, change.m_change );
                 log.info( "SPAM:TooManyModifications (" + uid + "). Added host " + addr + " to temporary ban list for doing too many modifications/minute" );
                 checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS, "Herb says you look like a spammer, and I trust Herb! (Incident code " + uid + ")" );
             }
 
             if( changeCounter >= m_limitSimilarChanges ) {
-                Host host = new Host( addr, null );
+                final Host host = new Host( addr, null );
                 m_temporaryBanList.add( host );
 
-                String uid = log( context, REJECT, REASON_SIMILAR_MODIFICATIONS, change.m_change );
+                final String uid = log( context, REJECT, REASON_SIMILAR_MODIFICATIONS, change.m_change );
                 log.info( "SPAM:SimilarModifications (" + uid + "). Added host " + addr + " to temporary ban list for doing too many similar modifications" );
                 checkStrategy( context, REASON_SIMILAR_MODIFICATIONS, "Herb says you look like a spammer, and I trust Herb! (Incident code "+uid+")");
             }
@@ -523,16 +526,16 @@ public class SpamFilter extends BasicPageFilter {
             String tstChange  = change.toString();
             int    urlCounter = 0;
             while( m_matcher.contains( tstChange,m_urlPattern ) ) {
-                MatchResult m = m_matcher.getMatch();
+                final MatchResult m = m_matcher.getMatch();
                 tstChange = tstChange.substring( m.endOffset(0) );
                 urlCounter++;
             }
 
             if( urlCounter > m_maxUrls ) {
-                Host host = new Host( addr, null );
+                final Host host = new Host( addr, null );
                 m_temporaryBanList.add( host );
 
-                String uid = log( context, REJECT, REASON_TOO_MANY_URLS, change.toString() );
+                final String uid = log( context, REJECT, REASON_TOO_MANY_URLS, change.toString() );
                 log.info( "SPAM:TooManyUrls (" + uid + "). Added host " + addr + " to temporary ban list for adding too many URLs" );
                 checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says you look like a spammer, and I trust Herb! (Incident code " + uid + ")" );
             }
@@ -565,7 +568,7 @@ public class SpamFilter extends BasicPageFilter {
      * @param change
      * @throws RedirectException
      */
-    private void checkAkismet( WikiContext context, Change change ) throws RedirectException {
+    private void checkAkismet( final WikiContext context, final Change change ) throws RedirectException {
         if( m_akismetAPIKey != null ) {
             if( m_akismet == null ) {
                 log.info( "Initializing Akismet spam protection." );
@@ -578,7 +581,7 @@ public class SpamFilter extends BasicPageFilter {
                 }
             }
 
-            HttpServletRequest req = context.getHttpRequest();
+            final HttpServletRequest req = context.getHttpRequest();
 
             //
             //  Akismet will mark all empty statements as spam, so we'll just
@@ -591,19 +594,19 @@ public class SpamFilter extends BasicPageFilter {
             if( req != null && m_akismet != null ) {
                 log.debug( "Calling Akismet to check for spam..." );
 
-                StopWatch sw = new StopWatch();
+                final StopWatch sw = new StopWatch();
                 sw.start();
 
-                String ipAddress     = HttpUtil.getRemoteAddress( req );
-                String userAgent     = req.getHeader( "User-Agent" );
-                String referrer      = req.getHeader( "Referer");
-                String permalink     = context.getViewURL( context.getPage().getName() );
-                String commentType   = context.getRequestContext().equals( WikiContext.COMMENT ) ? "comment" : "edit";
-                String commentAuthor = context.getCurrentUser().getName();
-                String commentAuthorEmail = null;
-                String commentAuthorURL   = null;
+                final String ipAddress     = HttpUtil.getRemoteAddress( req );
+                final String userAgent     = req.getHeader( "User-Agent" );
+                final String referrer      = req.getHeader( "Referer");
+                final String permalink     = context.getViewURL( context.getPage().getName() );
+                final String commentType   = context.getRequestContext().equals( WikiContext.COMMENT ) ? "comment" : "edit";
+                final String commentAuthor = context.getCurrentUser().getName();
+                final String commentAuthorEmail = null;
+                final String commentAuthorURL   = null;
 
-                boolean isSpam = m_akismet.commentCheck( ipAddress,
+                final boolean isSpam = m_akismet.commentCheck( ipAddress,
                                                          userAgent,
                                                          referrer,
                                                          permalink,
@@ -621,7 +624,7 @@ public class SpamFilter extends BasicPageFilter {
                     // Host host = new Host( ipAddress, null );
                     // m_temporaryBanList.add( host );
 
-                    String uid = log( context, REJECT, REASON_AKISMET, change.toString() );
+                    final String uid = log( context, REJECT, REASON_AKISMET, change.toString() );
                     log.info( "SPAM:Akismet (" + uid + "). Akismet thinks this change is spam; added host to temporary ban list." );
                     checkStrategy( context, REASON_AKISMET, "Akismet tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb! (Incident code " + uid + ")" );
                 }
@@ -645,13 +648,13 @@ public class SpamFilter extends BasicPageFilter {
      * @param change
      * @throws RedirectException
      */
-    private void checkBotTrap( WikiContext context, Change change ) throws RedirectException {
-        HttpServletRequest request = context.getHttpRequest();
+    private void checkBotTrap( final WikiContext context, final Change change ) throws RedirectException {
+        final HttpServletRequest request = context.getHttpRequest();
 
         if( request != null ) {
-            String unspam = request.getParameter( getBotFieldName() );
+            final String unspam = request.getParameter( getBotFieldName() );
             if( unspam != null && unspam.length() > 0 ) {
-                String uid = log( context, REJECT, REASON_BOT_TRAP, change.toString() );
+                final String uid = log( context, REJECT, REASON_BOT_TRAP, change.toString() );
 
                 log.info( "SPAM:BotTrap (" + uid + ").  Wildly behaving bot detected." );
                 checkStrategy( context, REASON_BOT_TRAP, "Spamming attempt detected. (Incident code " + uid + ")" );
@@ -659,14 +662,14 @@ public class SpamFilter extends BasicPageFilter {
         }
     }
 
-    private void checkUTF8( WikiContext context, Change change ) throws RedirectException {
-        HttpServletRequest request = context.getHttpRequest();
+    private void checkUTF8( final WikiContext context, final Change change ) throws RedirectException {
+        final HttpServletRequest request = context.getHttpRequest();
 
         if( request != null ) {
-            String utf8field = request.getParameter( "encodingcheck" );
+            final String utf8field = request.getParameter( "encodingcheck" );
 
             if( utf8field != null && !utf8field.equals( "\u3041" ) ) {
-                String uid = log( context, REJECT, REASON_UTF8_TRAP, change.toString() );
+                final String uid = log( context, REJECT, REASON_UTF8_TRAP, change.toString() );
 
                 log.info( "SPAM:UTF8Trap (" + uid + ").  Wildly posting dumb bot detected." );
                 checkStrategy( context, REASON_UTF8_TRAP, "Spamming attempt detected. (Incident code " + uid + ")" );
@@ -676,10 +679,10 @@ public class SpamFilter extends BasicPageFilter {
 
     /** Goes through the ban list and cleans away any host which has expired from it. */
     private synchronized void cleanBanList() {
-        long now = System.currentTimeMillis();
+        final long now = System.currentTimeMillis();
 
-        for( Iterator< Host > i = m_temporaryBanList.iterator(); i.hasNext(); ) {
-            Host host = i.next();
+        for( final Iterator< Host > i = m_temporaryBanList.iterator(); i.hasNext(); ) {
+            final Host host = i.next();
 
             if( host.getReleaseTime() < now ) {
                 log.debug( "Removed host " + host.getAddress() + " from temporary ban list (expired)" );
@@ -694,16 +697,16 @@ public class SpamFilter extends BasicPageFilter {
      *  @param context
      *  @throws RedirectException
      */
-    private void checkBanList( WikiContext context, Change change ) throws RedirectException {
-        HttpServletRequest req = context.getHttpRequest();
+    private void checkBanList( final WikiContext context, final Change change ) throws RedirectException {
+        final HttpServletRequest req = context.getHttpRequest();
 
         if( req != null ) {
-            String remote = HttpUtil.getRemoteAddress(req);
-            long now = System.currentTimeMillis();
+            final String remote = HttpUtil.getRemoteAddress(req);
+            final long now = System.currentTimeMillis();
 
-            for( Host host : m_temporaryBanList ) {
+            for( final Host host : m_temporaryBanList ) {
                 if( host.getAddress().equals( remote ) ) {
-                    long timeleft = ( host.getReleaseTime() - now ) / 1000L;
+                    final long timeleft = ( host.getReleaseTime() - now ) / 1000L;
 
                     log( context, REJECT, REASON_IP_BANNED_TEMPORARILY, change.m_change );
                     checkStrategy( context, REASON_IP_BANNED_TEMPORARILY,
@@ -726,21 +729,21 @@ public class SpamFilter extends BasicPageFilter {
             //
             //  Rebuild, if the spam words page, the attachment or the IP ban page has changed since.
             //
-            final WikiPage sourceSpam = context.getEngine().getPageManager().getPage( m_forbiddenWordsPage );
+            final WikiPage sourceSpam = context.getEngine().getManager( PageManager.class ).getPage( m_forbiddenWordsPage );
             if( sourceSpam != null ) {
                 if( m_spamPatterns == null || m_spamPatterns.isEmpty() || sourceSpam.getLastModified().after( m_lastRebuild ) ) {
                     rebuild = true;
                 }
             }
 
-            final Attachment att = context.getEngine().getAttachmentManager().getAttachmentInfo( context, m_blacklist );
+            final Attachment att = context.getEngine().getManager( AttachmentManager.class ).getAttachmentInfo( context, m_blacklist );
             if( att != null ) {
                 if( m_spamPatterns == null || m_spamPatterns.isEmpty() || att.getLastModified().after( m_lastRebuild ) ) {
                     rebuild = true;
                 }
             }
 
-            final WikiPage sourceIPs = context.getEngine().getPageManager().getPage( m_forbiddenIPsPage );
+            final WikiPage sourceIPs = context.getEngine().getManager( PageManager.class ).getPage( m_forbiddenIPsPage );
             if( sourceIPs != null ) {
                 if( m_IPPatterns == null || m_IPPatterns.isEmpty() || sourceIPs.getLastModified().after( m_lastRebuild ) ) {
                     rebuild = true;
@@ -761,7 +764,7 @@ public class SpamFilter extends BasicPageFilter {
                 log.info( "IP filter reloaded - recognizing " + m_IPPatterns.size() + " patterns from page " + m_forbiddenIPsPage );
 
                 if( att != null ) {
-                    final InputStream in = context.getEngine().getAttachmentManager().getAttachmentStream(att);
+                    final InputStream in = context.getEngine().getManager( AttachmentManager.class ).getAttachmentStream(att);
                     final StringWriter out = new StringWriter();
                     FileUtil.copyContents( new InputStreamReader( in, StandardCharsets.UTF_8 ), out );
                     final Collection< Pattern > blackList = parseBlacklist( out.toString() );
@@ -784,7 +787,7 @@ public class SpamFilter extends BasicPageFilter {
      *  @param change
      *  @throws RedirectException
      */
-    private void checkPatternList( WikiContext context, String content, Change change ) throws RedirectException {
+    private void checkPatternList( final WikiContext context, final String content, final Change change ) throws RedirectException {
         //
         //  If we have no spam patterns defined, or we're trying to save
         //  the page containing the patterns, just return.
@@ -798,14 +801,14 @@ public class SpamFilter extends BasicPageFilter {
             ch += HttpUtil.getRemoteAddress( context.getHttpRequest() );
         }
 
-        for( Pattern p : m_spamPatterns ) {
+        for( final Pattern p : m_spamPatterns ) {
             // log.debug("Attempting to match page contents with "+p.getPattern());
 
             if( m_matcher.contains( ch, p ) ) {
                 //
                 //  Spam filter has a match.
                 //
-                String uid = log( context, REJECT, REASON_REGEXP + "(" + p.getPattern() + ")", ch );
+                final String uid = log( context, REJECT, REASON_REGEXP + "(" + p.getPattern() + ")", ch );
 
                 log.info( "SPAM:Regexp (" + uid + "). Content matches the spam filter '" + p.getPattern() + "'" );
                 checkStrategy( context, REASON_REGEXP, "Herb says '" + p.getPattern() + "' is a bad spam word and I trust Herb! (Incident code " + uid + ")" );
@@ -820,7 +823,7 @@ public class SpamFilter extends BasicPageFilter {
      *  @param context
      *  @throws RedirectException
      */
-    private void checkIPList( WikiContext context ) throws RedirectException {
+    private void checkIPList( final WikiContext context ) throws RedirectException {
         //
         //  If we have no IP patterns defined, or we're trying to save
         //  the page containing the IP patterns, just return.
@@ -829,17 +832,17 @@ public class SpamFilter extends BasicPageFilter {
             return;
         }
 
-        String remoteIP = HttpUtil.getRemoteAddress( context.getHttpRequest() );
+        final String remoteIP = HttpUtil.getRemoteAddress( context.getHttpRequest() );
         log.info("Attempting to match remoteIP " + remoteIP + " against " + m_IPPatterns.size() + " patterns");
 
-        for( Pattern p : m_IPPatterns ) {
+        for( final Pattern p : m_IPPatterns ) {
              log.debug("Attempting to match remoteIP with " + p.getPattern());
 
             if( m_matcher.contains( remoteIP, p ) ) {
 
                 //  IP filter has a match.
                 //
-                String uid = log( context, REJECT, REASON_IP_BANNED_PERMANENTLY + "(" + p.getPattern() + ")", remoteIP );
+                final String uid = log( context, REJECT, REASON_IP_BANNED_PERMANENTLY + "(" + p.getPattern() + ")", remoteIP );
 
                 log.info( "SPAM:IPBanList (" + uid + "). remoteIP matches the IP filter '" + p.getPattern() + "'" );
                 checkStrategy( context, REASON_IP_BANNED_PERMANENTLY, "Herb says '" + p.getPattern() + "' is a banned IP and I trust Herb! (Incident code " + uid + ")" );
@@ -847,8 +850,8 @@ public class SpamFilter extends BasicPageFilter {
         }
     }
 
-    private void checkPatternList( WikiContext context, String content, String change ) throws RedirectException {
-        Change c = new Change();
+    private void checkPatternList( final WikiContext context, final String content, final String change ) throws RedirectException {
+        final Change c = new Change();
         c.m_change = change;
         checkPatternList( context, content, c );
     }
@@ -863,13 +866,13 @@ public class SpamFilter extends BasicPageFilter {
     private static Change getChange( final WikiContext context, final String newText ) {
         final WikiPage page = context.getPage();
         final StringBuffer change = new StringBuffer();
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
         // Get current page version
 
         final Change ch = new Change();
         
         try {
-            final String oldText = engine.getPageManager().getPureText( page.getName(), WikiProvider.LATEST_VERSION );
+            final String oldText = engine.getManager( PageManager.class ).getPureText( page.getName(), WikiProvider.LATEST_VERSION );
             final String[] first  = Diff.stringToArray( oldText );
             final String[] second = Diff.stringToArray( newText );
             final Revision rev = Diff.diff( first, second, new MyersDiff() );
@@ -924,7 +927,7 @@ public class SpamFilter extends BasicPageFilter {
      * @param context
      * @return True, if this users should be ignored.
      */
-    private boolean ignoreThisUser( WikiContext context ) {
+    private boolean ignoreThisUser( final WikiContext context ) {
         if( context.hasAdminPermissions() ) {
             return true;
         }
@@ -946,11 +949,11 @@ public class SpamFilter extends BasicPageFilter {
      *  @return A random string
      */
     private static String getUniqueID() {
-        StringBuilder sb = new StringBuilder();
-        Random rand = new Random();
+        final StringBuilder sb = new StringBuilder();
+        final Random rand = new Random();
 
         for( int i = 0; i < 6; i++ ) {
-            char x = ( char )( 'A' + rand.nextInt( 26 ) );
+            final char x = ( char )( 'A' + rand.nextInt( 26 ) );
             sb.append( x );
         }
 
@@ -963,7 +966,7 @@ public class SpamFilter extends BasicPageFilter {
      *  @param ctx WikiContext
      *  @return An URL to redirect to
      */
-    private String getRedirectPage( WikiContext ctx ) {
+    private String getRedirectPage( final WikiContext ctx ) {
         if( m_useCaptcha ) {
             return ctx.getURL( WikiContext.NONE, "Captcha.jsp", "page="+ctx.getEngine().encodeName( ctx.getPage().getName() ) );
         }
@@ -979,12 +982,12 @@ public class SpamFilter extends BasicPageFilter {
      *  @return False, if this userprofile is suspect and should not be allowed to be added.
      *  @since 2.6.1
      */
-    public boolean isValidUserProfile( WikiContext context, UserProfile profile ) {
+    public boolean isValidUserProfile( final WikiContext context, final UserProfile profile ) {
         try {
             checkPatternList( context, profile.getEmail(), profile.getEmail() );
             checkPatternList( context, profile.getFullname(), profile.getFullname() );
             checkPatternList( context, profile.getLoginName(), profile.getLoginName() );
-        } catch( RedirectException e ) {
+        } catch( final RedirectException e ) {
             log.info("Detected attempt to create a spammer user account (see above for rejection reason)");
             return false;
         }
@@ -1001,13 +1004,13 @@ public class SpamFilter extends BasicPageFilter {
      *  @since 2.6
      *  @return A hash value for this page and session
      */
-    public static final String getSpamHash( WikiPage page, HttpServletRequest request ) {
+    public static final String getSpamHash( final WikiPage page, final HttpServletRequest request ) {
         long lastModified = 0;
 
         if( page.getLastModified() != null ) {
             lastModified = page.getLastModified().getTime();
         }
-        long remote = HttpUtil.getRemoteAddress( request ).hashCode();
+        final long remote = HttpUtil.getRemoteAddress( request ).hashCode();
 
         return Long.toString( lastModified ^ remote );
     }
@@ -1020,7 +1023,7 @@ public class SpamFilter extends BasicPageFilter {
      *  @return The name to be used in the hash field
      *  @since  2.6
      */
-    public static final String getHashFieldName( HttpServletRequest request ) {
+    public static final String getHashFieldName( final HttpServletRequest request ) {
         String hash = null;
 
         if( request.getSession() != null ) {
@@ -1055,15 +1058,15 @@ public class SpamFilter extends BasicPageFilter {
      *  @throws IOException If redirection fails
      *  @since 2.6
      */
-    public static final boolean checkHash( WikiContext context, PageContext pageContext ) throws IOException {
-        String hashName = getHashFieldName( (HttpServletRequest)pageContext.getRequest() );
+    public static final boolean checkHash( final WikiContext context, final PageContext pageContext ) throws IOException {
+        final String hashName = getHashFieldName( (HttpServletRequest)pageContext.getRequest() );
 
         if( pageContext.getRequest().getParameter(hashName) == null ) {
             if( pageContext.getAttribute( hashName ) == null ) {
-                Change change = getChange( context, EditorManager.getEditedText( pageContext ) );
+                final Change change = getChange( context, EditorManager.getEditedText( pageContext ) );
                 log( context, REJECT, "MissingHash", change.m_change );
 
-                String redirect = context.getURL( WikiContext.VIEW,"SessionExpired" );
+                final String redirect = context.getURL( WikiContext.VIEW,"SessionExpired" );
                 ( ( HttpServletResponse )pageContext.getResponse() ).sendRedirect( redirect );
                 return false;
             }
@@ -1081,7 +1084,7 @@ public class SpamFilter extends BasicPageFilter {
      */
     public static final String insertInputFields( final PageContext pageContext ) {
         final WikiContext ctx = WikiContext.findContext( pageContext );
-        final WikiEngine engine = ctx.getEngine();
+        final Engine engine = ctx.getEngine();
         final StringBuilder sb = new StringBuilder();
         if( engine.getContentEncoding().equals( StandardCharsets.UTF_8 ) ) {
             sb.append( "<input name='encodingcheck' type='hidden' value='\u3041' />\n" );
@@ -1118,7 +1121,7 @@ public class SpamFilter extends BasicPageFilter {
             return m_change;
         }
 
-        public Host( String ipaddress, Change change ) {
+        public Host( final String ipaddress, final Change change ) {
             m_address = ipaddress;
             m_change  = change;
             m_releaseTime = System.currentTimeMillis() + m_banTime * 60 * 1000L;
@@ -1132,18 +1135,18 @@ public class SpamFilter extends BasicPageFilter {
         public int    m_adds;
         public int    m_removals;
         
-        public String toString() {
+        @Override public String toString() {
             return m_change;
         }
         
-        public boolean equals( Object o ) {
+        @Override public boolean equals( final Object o ) {
             if( o instanceof Change ) {
                 return m_change.equals( ( ( Change )o ).m_change );
             }
             return false;
         }
         
-        public int hashCode() {
+        @Override public int hashCode() {
             return m_change.hashCode() + 17;
         }
         
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/forms/FormOutput.java b/jspwiki-main/src/main/java/org/apache/wiki/forms/FormOutput.java
index 1789031..8c56300 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/forms/FormOutput.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/forms/FormOutput.java
@@ -55,53 +55,44 @@ public class FormOutput
      * @param params {@inheritDoc}
      * @return {@inheritDoc}
      */
-    public String execute( WikiContext ctx, Map< String, String > params )
-        throws PluginException
-    {
-        //
+    @Override public String execute( final WikiContext ctx, final Map< String, String > params ) throws PluginException {
         //  If there is no HTTP request, returns immediately.
-        //
-        if( ctx.getHttpRequest() == null )
-        {
+        if( ctx.getHttpRequest() == null ) {
             return "";
         }
-        ResourceBundle rb = Preferences.getBundle( ctx, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+        final ResourceBundle rb = Preferences.getBundle( ctx, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
         
         // If we are NOT here due to this form being submitted, we do nothing.
         // The submitted form MUST have parameter 'formname' equal to the name
         // parameter of this Form plugin.
 
-        String formName   = params.get( PARAM_FORM );
-        String submitForm = ctx.getHttpParameter( PARAM_FORMNAMEHIDDEN );
-        String populator  = params.get( PARAM_POPULATE );
+        final String formName   = params.get( PARAM_FORM );
+        final String submitForm = ctx.getHttpParameter( PARAM_FORMNAMEHIDDEN );
+        final String populator  = params.get( PARAM_POPULATE );
 
-        if( submitForm == null || formName == null || 
-            !formName.equals( submitForm ) )
-        {
+        if( formName == null || !formName.equals( submitForm ) ) {
             // No submitForm -> this was not a submission from the
             // generated form.  If populate is specified, we'll go
             // ahead and let the handler (populator) put stuff into
             // the context, otherwise we'll just hide.
-            if( populator == null || !PARAM_HANDLER.equals( populator ) )
+            if( !PARAM_HANDLER.equals( populator ) )
                 return "";
             // If population was allowed, we should first  
         }
 
-        String handler = params.get( PARAM_HANDLER );
-        if( handler == null || handler.length() == 0 )
-        {
+        final String handler = params.get( PARAM_HANDLER );
+        if( handler == null || handler.length() == 0 ) {
             // Need to print out an error here as this form is misconfigured
             return "<p class=\"error\">" + MessageFormat.format( rb.getString( "formoutput.missingargument" ), PARAM_HANDLER ) + "</p>";
         }
 
-        String sourcePage = ctx.getPage().getName();
-        String submitServlet = ctx.getURL( WikiContext.VIEW, sourcePage );
+        final String sourcePage = ctx.getPage().getName();
+        final String submitServlet = ctx.getURL( WikiContext.VIEW, sourcePage );
 
         // If there is previous FormInfo available - say, from a
         // FormSet plugin - use it.
         FormInfo info = getFormInfo( ctx );
-        if( info == null )
-        {
+        if( info == null ) {
             // Reconstruct the form info from post data
             info = new FormInfo();
             info.setName( formName );
@@ -110,31 +101,24 @@ public class FormOutput
         info.setHandler( handler );
         info.setAction( submitServlet );
 
-        // Sift out all extra parameters, leaving only those submitted
-        // in the HTML FORM.
-        Map< String, String > handlerParams = FormUtil.requestToMap( ctx.getHttpRequest(), 
-                                                                     HANDLERPARAM_PREFIX );
+        // Sift out all extra parameters, leaving only those submitted in the HTML FORM.
+        final Map< String, String > handlerParams = FormUtil.requestToMap( ctx.getHttpRequest(), HANDLERPARAM_PREFIX );
         // Previous submission info may be available from FormSet
         // plugin - add, don't replace.
         info.addSubmission( handlerParams );
 
         // Pass the _body parameter from FormOutput on to the handler
-        info.getSubmission().put( DefaultPluginManager.PARAM_BODY, 
-                                  params.get(DefaultPluginManager.PARAM_BODY)); 
+        info.getSubmission().put( DefaultPluginManager.PARAM_BODY, params.get(DefaultPluginManager.PARAM_BODY ) );
 
         String handlerOutput = null;
         String error = null;
-        try
-        {
-            // The plugin _can_ modify the parameters, so we make sure
-            // they stay with us.
-            PluginManager pm = ctx.getEngine().getPluginManager();
+        try {
+            // The plugin _can_ modify the parameters, so we make sure they stay with us.
+            final PluginManager pm = ctx.getEngine().getManager( PluginManager.class );
             handlerOutput = pm.execute( ctx, handler, info.getSubmission() );
             info.setResult( handlerOutput );
             info.setStatus( FormInfo.EXECUTED );
-        }
-        catch( PluginException pe )
-        {
+        } catch( final PluginException pe ) {
             error = "<p class=\"error\">" + pe.getMessage() + "</p>";
             info.setError( error );
             info.setStatus( FormInfo.ERROR );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/pages/DefaultPageManager.java b/jspwiki-main/src/main/java/org/apache/wiki/pages/DefaultPageManager.java
index 324d347..8dcaa8f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/pages/DefaultPageManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/pages/DefaultPageManager.java
@@ -35,6 +35,7 @@ import org.apache.wiki.auth.acl.Acl;
 import org.apache.wiki.auth.acl.AclEntry;
 import org.apache.wiki.auth.acl.AclEntryImpl;
 import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.diff.DifferenceManager;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiPageEvent;
@@ -43,6 +44,7 @@ import org.apache.wiki.modules.ModuleManager;
 import org.apache.wiki.modules.WikiModuleInfo;
 import org.apache.wiki.providers.RepositoryModifiedException;
 import org.apache.wiki.providers.WikiPageProvider;
+import org.apache.wiki.references.ReferenceManager;
 import org.apache.wiki.util.ClassUtil;
 import org.apache.wiki.util.TextUtil;
 import org.apache.wiki.workflow.Decision;
@@ -184,7 +186,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
             //  Empty the references and yay, it shall be recalculated
             final WikiPage p = m_provider.getPageInfo( pageName, version );
 
-            m_engine.getReferenceManager().updateReferences( p );
+            m_engine.getManager( ReferenceManager.class ).updateReferences( p );
             m_engine.getSearchManager().reindexPage( p );
             text = m_provider.getPageText( pageName, version );
         }
@@ -196,7 +198,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#getPureText(String, int)
      */
-    public String getPureText( final String page, final int version ) {
+    @Override public String getPureText( final String page, final int version ) {
         String result = null;
         try {
             result = getPageText( page, version );
@@ -214,12 +216,12 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#getText(String, int)
      */
-    public String getText( final String page, final int version ) {
+    @Override public String getText( final String page, final int version ) {
         final String result = getPureText( page, version );
         return TextUtil.replaceEntities( result );
     }
 
-    public void saveText( final WikiContext context, final String text ) throws WikiException {
+    @Override public void saveText( final WikiContext context, final String text ) throws WikiException {
         // Check if page data actually changed; bail if not
         final WikiPage page = context.getPage();
         final String oldText = getPureText( page );
@@ -243,7 +245,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
         final Principal submitter = context.getCurrentUser();
         final Step prepTask = m_engine.getTasksManager().buildPreSaveWikiPageTask( context, proposedText );
         final Step completionTask = m_engine.getTasksManager().buildSaveWikiPageTask();
-        final String diffText = m_engine.getDifferenceManager().makeDiff( context, oldText, proposedText );
+        final String diffText = m_engine.getManager( DifferenceManager.class ).makeDiff( context, oldText, proposedText );
         final boolean isAuthenticated = context.getWikiSession().isAuthenticated();
         final Fact[] facts = new Fact[ 5 ];
         facts[ 0 ] = new Fact( WorkflowManager.WF_WP_SAVE_FACT_PAGE_NAME, page.getName() );
@@ -363,7 +365,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#getPage(java.lang.String)
      */
-    public WikiPage getPage( final String pagereq ) {
+    @Override public WikiPage getPage( final String pagereq ) {
         return getPage( pagereq, WikiProvider.LATEST_VERSION );
     }
 
@@ -371,7 +373,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#getPage(java.lang.String, int)
      */
-    public WikiPage getPage( final String pagereq, final int version ) {
+    @Override public WikiPage getPage( final String pagereq, final int version ) {
         try {
             WikiPage p = getPageInfo( pagereq, version );
             if( p == null ) {
@@ -404,9 +406,9 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
             LOG.info("Repository has been modified externally while fetching info for " + pageName);
             page = m_provider.getPageInfo(pageName, version);
             if (page != null) {
-                m_engine.getReferenceManager().updateReferences(page);
+                m_engine.getManager( ReferenceManager.class ).updateReferences(page);
             } else {
-                m_engine.getReferenceManager().pageRemoved(new WikiPage(m_engine, pageName));
+                m_engine.getManager( ReferenceManager.class ).pageRemoved(new WikiPage(m_engine, pageName));
             }
         }
 
@@ -440,7 +442,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#getCurrentProvider()
      */
-    public String getCurrentProvider() {
+    @Override public String getCurrentProvider() {
         return getProvider().getClass().getName();
     }
 
@@ -519,7 +521,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#wikiPageExists(java.lang.String)
      */
-    public boolean wikiPageExists( final String page ) {
+    @Override public boolean wikiPageExists( final String page ) {
         if( m_engine.getCommandResolver().getSpecialPageReference( page ) != null ) {
             return true;
         }
@@ -542,7 +544,7 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#wikiPageExists(java.lang.String, int)
      */
-    public boolean wikiPageExists( final String page, final int version ) throws ProviderException {
+    @Override public boolean wikiPageExists( final String page, final int version ) throws ProviderException {
         if( m_engine.getCommandResolver().getSpecialPageReference( page ) != null ) {
             return true;
         }
@@ -583,13 +585,13 @@ public class DefaultPageManager extends ModuleManager implements PageManager {
      * {@inheritDoc}
      * @see org.apache.wiki.pages.PageManager#deletePage(java.lang.String)
      */
-    public void deletePage( final String pageName ) throws ProviderException {
+    @Override public void deletePage( final String pageName ) throws ProviderException {
         final WikiPage p = getPage( pageName );
         if( p != null ) {
             if( p instanceof Attachment ) {
                 m_engine.getAttachmentManager().deleteAttachment( ( Attachment )p );
             } else {
-                final Collection< String > refTo = m_engine.getReferenceManager().findRefersTo( pageName );
+                final Collection< String > refTo = m_engine.getManager( ReferenceManager.class ).findRefersTo( pageName );
                 // May return null, if the page does not exist or has not been indexed yet.
 
                 if( m_engine.getAttachmentManager().hasAttachments( p ) ) {


[jspwiki] 37/38: JSPWIKI-120: rename + extract interface from GroupManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 999c443643847effa3e840532aa93e0bc9bfefde
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:20:24 2020 +0100

    JSPWIKI-120: rename + extract interface from GroupManager
---
 .../wiki/auth/authorize/DefaultGroupManager.java   | 398 +++++++++++++
 .../apache/wiki/auth/authorize/GroupManager.java   | 659 +++------------------
 .../src/main/resources/ini/classmappings.xml       |   2 +-
 3 files changed, 485 insertions(+), 574 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/DefaultGroupManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/DefaultGroupManager.java
new file mode 100644
index 0000000..e24ba71
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/DefaultGroupManager.java
@@ -0,0 +1,398 @@
+/* 
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.  
+ */
+package org.apache.wiki.auth.authorize;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.AuthenticationManager;
+import org.apache.wiki.auth.Authorizer;
+import org.apache.wiki.auth.GroupPrincipal;
+import org.apache.wiki.auth.NoSuchPrincipalException;
+import org.apache.wiki.auth.UserManager;
+import org.apache.wiki.auth.WikiPrincipal;
+import org.apache.wiki.auth.WikiSecurityException;
+import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.event.WikiEvent;
+import org.apache.wiki.event.WikiEventListener;
+import org.apache.wiki.event.WikiEventManager;
+import org.apache.wiki.event.WikiSecurityEvent;
+import org.apache.wiki.ui.InputValidator;
+import org.apache.wiki.util.ClassUtil;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+
+/**
+ * <p>
+ * Facade class for storing, retrieving and managing wiki groups on behalf of AuthorizationManager, JSPs and other presentation-layer
+ * classes. GroupManager works in collaboration with a back-end {@link GroupDatabase}, which persists groups to permanent storage.
+ * </p>
+ * <p>
+ * <em>Note: prior to JSPWiki 2.4.19, GroupManager was an interface; it is now a concrete, final class. The aspects of GroupManager
+ * which previously extracted group information from storage (e.g., wiki pages) have been refactored into the GroupDatabase interface.</em>
+ * </p>
+ * @since 2.4.19
+ */
+public class DefaultGroupManager implements GroupManager, Authorizer, WikiEventListener {
+
+    private static final Logger log = Logger.getLogger( DefaultGroupManager.class );
+
+    protected Engine m_engine;
+
+    protected WikiEventListener m_groupListener;
+
+    private GroupDatabase m_groupDatabase    = null;
+
+    /** Map with GroupPrincipals as keys, and Groups as values */
+    private final Map< Principal, Group > m_groups = new HashMap<>();
+
+    /** {@inheritDoc} */
+    @Override
+    public Principal findRole( final String name ) {
+        try {
+            final Group group = getGroup( name );
+            return group.getPrincipal();
+        } catch( final NoSuchPrincipalException e ) {
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Group getGroup( final String name ) throws NoSuchPrincipalException {
+        final Group group = m_groups.get( new GroupPrincipal( name ) );
+        if( group != null ) {
+            return group;
+        }
+        throw new NoSuchPrincipalException( "Group " + name + " not found." );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public GroupDatabase getGroupDatabase() throws WikiSecurityException {
+        if( m_groupDatabase != null ) {
+            return m_groupDatabase;
+        }
+
+        String dbClassName = "<unknown>";
+        String dbInstantiationError = null;
+        Throwable cause = null;
+        try {
+            final Properties props = m_engine.getWikiProperties();
+            dbClassName = props.getProperty( PROP_GROUPDATABASE );
+            if( dbClassName == null ) {
+                dbClassName = XMLGroupDatabase.class.getName();
+            }
+            log.info( "Attempting to load group database class " + dbClassName );
+            final Class< ? > dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
+            m_groupDatabase = ( GroupDatabase )dbClass.newInstance();
+            m_groupDatabase.initialize( m_engine, m_engine.getWikiProperties() );
+            log.info( "Group database initialized." );
+        } catch( final ClassNotFoundException e ) {
+            log.error( "GroupDatabase class " + dbClassName + " cannot be found.", e );
+            dbInstantiationError = "Failed to locate GroupDatabase class " + dbClassName;
+            cause = e;
+        } catch( final InstantiationException e ) {
+            log.error( "GroupDatabase class " + dbClassName + " cannot be created.", e );
+            dbInstantiationError = "Failed to create GroupDatabase class " + dbClassName;
+            cause = e;
+        } catch( final IllegalAccessException e ) {
+            log.error( "You are not allowed to access group database class " + dbClassName + ".", e );
+            dbInstantiationError = "Access GroupDatabase class " + dbClassName + " denied";
+            cause = e;
+        } catch( final NoRequiredPropertyException e ) {
+            log.error( "Missing property: " + e.getMessage() + "." );
+            dbInstantiationError = "Missing property: " + e.getMessage();
+            cause = e;
+        }
+
+        if( dbInstantiationError != null ) {
+            throw new WikiSecurityException( dbInstantiationError + " Cause: " + cause.getMessage(), cause );
+        }
+
+        return m_groupDatabase;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Principal[] getRoles() {
+        return m_groups.keySet().toArray( new Principal[ m_groups.size() ] );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException {
+        m_engine = engine;
+
+        try {
+            m_groupDatabase = getGroupDatabase();
+        } catch( final WikiException e ) {
+            throw new WikiSecurityException( e.getMessage(), e );
+        }
+
+        // Load all groups from the database into the cache
+        final Group[] groups = m_groupDatabase.groups();
+        synchronized( m_groups ) {
+            for( final Group group : groups ) {
+                // Add new group to cache; fire GROUP_ADD event
+                m_groups.put( group.getPrincipal(), group );
+                fireEvent( WikiSecurityEvent.GROUP_ADD, group );
+            }
+        }
+
+        // Make the GroupManager listen for WikiEvents (WikiSecurityEvents for changed user profiles)
+        engine.getManager( UserManager.class ).addWikiEventListener( this );
+
+        // Success!
+        log.info( "Authorizer GroupManager initialized successfully; loaded " + groups.length + " group(s)." );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isUserInRole( final WikiSession session, final Principal role ) {
+        // Always return false if session/role is null, or if role isn't a GroupPrincipal
+        if ( session == null || !( role instanceof GroupPrincipal ) || !session.isAuthenticated() ) {
+            return false;
+        }
+
+        // Get the group we're examining
+        final Group group = m_groups.get( role );
+        if( group == null ) {
+            return false;
+        }
+
+        // Check each user principal to see if it belongs to the group
+        for( final Principal principal : session.getPrincipals() ) {
+            if( AuthenticationManager.isUserPrincipal( principal ) && group.isMember( principal ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Group parseGroup( String name, String memberLine, final boolean create ) throws WikiSecurityException {
+        // If null name parameter, it's because someone's creating a new group
+        if( name == null ) {
+            if( create ) {
+                name = "MyGroup";
+            } else {
+                throw new WikiSecurityException( "Group name cannot be blank." );
+            }
+        } else if( ArrayUtils.contains( Group.RESTRICTED_GROUPNAMES, name ) ) {
+            // Certain names are forbidden
+            throw new WikiSecurityException( "Illegal group name: " + name );
+        }
+        name = name.trim();
+
+        // Normalize the member line
+        if( InputValidator.isBlank( memberLine ) ) {
+            memberLine = "";
+        }
+        memberLine = memberLine.trim();
+
+        // Create or retrieve the group (may have been previously cached)
+        final Group group = new Group( name, m_engine.getApplicationName() );
+        try {
+            final Group existingGroup = getGroup( name );
+
+            // If existing, clone it
+            group.setCreator( existingGroup.getCreator() );
+            group.setCreated( existingGroup.getCreated() );
+            group.setModifier( existingGroup.getModifier() );
+            group.setLastModified( existingGroup.getLastModified() );
+            for( final Principal existingMember : existingGroup.members() ) {
+                group.add( existingMember );
+            }
+        } catch( final NoSuchPrincipalException e ) {
+            // It's a new group.... throw error if we don't create new ones
+            if( !create ) {
+                throw new NoSuchPrincipalException( "Group '" + name + "' does not exist." );
+            }
+        }
+
+        // If passed members not empty, overwrite
+        final String[] members = extractMembers( memberLine );
+        if( members.length > 0 ) {
+            group.clear();
+            for( final String member : members ) {
+                group.add( new WikiPrincipal( member ) );
+            }
+        }
+
+        return group;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void removeGroup( final String index ) throws WikiSecurityException {
+        if( index == null ) {
+            throw new IllegalArgumentException( "Group cannot be null." );
+        }
+
+        final Group group = m_groups.get( new GroupPrincipal( index ) );
+        if( group == null ) {
+            throw new NoSuchPrincipalException( "Group " + index + " not found" );
+        }
+
+        // Delete the group
+        // TODO: need rollback procedure
+        synchronized( m_groups ) {
+            m_groups.remove( group.getPrincipal() );
+        }
+        m_groupDatabase.delete( group );
+        fireEvent( WikiSecurityEvent.GROUP_REMOVE, group );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setGroup( final WikiSession session, final Group group ) throws WikiSecurityException {
+        // TODO: check for appropriate permissions
+
+        // If group already exists, delete it; fire GROUP_REMOVE event
+        final Group oldGroup = m_groups.get( group.getPrincipal() );
+        if( oldGroup != null ) {
+            fireEvent( WikiSecurityEvent.GROUP_REMOVE, oldGroup );
+            synchronized( m_groups ) {
+                m_groups.remove( oldGroup.getPrincipal() );
+            }
+        }
+
+        // Copy existing modifier info & timestamps
+        if( oldGroup != null ) {
+            group.setCreator( oldGroup.getCreator() );
+            group.setCreated( oldGroup.getCreated() );
+            group.setModifier( oldGroup.getModifier() );
+            group.setLastModified( oldGroup.getLastModified() );
+        }
+
+        // Add new group to cache; announce GROUP_ADD event
+        synchronized( m_groups ) {
+            m_groups.put( group.getPrincipal(), group );
+        }
+        fireEvent( WikiSecurityEvent.GROUP_ADD, group );
+
+        // Save the group to back-end database; if it fails, roll back to previous state. Note that the back-end
+        // MUST timestammp the create/modify fields in the Group.
+        try {
+            m_groupDatabase.save( group, session.getUserPrincipal() );
+        }
+
+        // We got an exception! Roll back...
+        catch( final WikiSecurityException e ) {
+            if( oldGroup != null ) {
+                // Restore previous version, re-throw...
+                fireEvent( WikiSecurityEvent.GROUP_REMOVE, group );
+                fireEvent( WikiSecurityEvent.GROUP_ADD, oldGroup );
+                synchronized( m_groups ) {
+                    m_groups.put( oldGroup.getPrincipal(), oldGroup );
+                }
+                throw new WikiSecurityException( e.getMessage() + " (rolled back to previous version).", e );
+            }
+            // Re-throw security exception
+            throw new WikiSecurityException( e.getMessage(), e );
+        }
+    }
+
+    /**
+     * Extracts carriage-return separated members into a Set of String objects.
+     *
+     * @param memberLine the list of members
+     * @return the list of members
+     */
+    protected String[] extractMembers( final String memberLine ) {
+        final Set< String > members = new HashSet<>();
+        if( memberLine != null ) {
+            final StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
+            while( tok.hasMoreTokens() ) {
+                final String uid = tok.nextToken().trim();
+                if( uid.length() > 0 ) {
+                    members.add( uid );
+                }
+            }
+        }
+        return members.toArray( new String[ members.size() ] );
+    }
+
+    // events processing .......................................................
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized void addWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.addWikiEventListener( this, listener );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
+        WikiEventManager.removeWikiEventListener( this, listener );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void actionPerformed( final WikiEvent event ) {
+        if( !( event instanceof WikiSecurityEvent ) ) {
+            return;
+        }
+
+        final WikiSecurityEvent se = ( WikiSecurityEvent )event;
+        if( se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED ) {
+            final WikiSession session = se.getSrc();
+            final UserProfile[] profiles = ( UserProfile[] )se.getTarget();
+            final Principal[] oldPrincipals = new Principal[] { new WikiPrincipal( profiles[ 0 ].getLoginName() ),
+                    new WikiPrincipal( profiles[ 0 ].getFullname() ), new WikiPrincipal( profiles[ 0 ].getWikiName() ) };
+            final Principal newPrincipal = new WikiPrincipal( profiles[ 1 ].getFullname() );
+
+            // Examine each group
+            int groupsChanged = 0;
+            try {
+                for( final Group group : m_groupDatabase.groups() ) {
+                    boolean groupChanged = false;
+                    for( final Principal oldPrincipal : oldPrincipals ) {
+                        if( group.isMember( oldPrincipal ) ) {
+                            group.remove( oldPrincipal );
+                            group.add( newPrincipal );
+                            groupChanged = true;
+                        }
+                    }
+                    if( groupChanged ) {
+                        setGroup( session, group );
+                        groupsChanged++;
+                    }
+                }
+            } catch( final WikiException e ) {
+                // Oooo! This is really bad...
+                log.error( "Could not change user name in Group lists because of GroupDatabase error:" + e.getMessage() );
+            }
+            log.info( "Profile name change for '" + newPrincipal.toString() + "' caused " + groupsChanged + " groups to change also." );
+        }
+    }
+
+}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
index 37e3c33..7c38ac5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
@@ -19,400 +19,103 @@
 package org.apache.wiki.auth.authorize;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiSession;
-import org.apache.wiki.api.core.Engine;
-import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
-import org.apache.wiki.api.exceptions.WikiException;
-import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.Authorizer;
-import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.NoSuchPrincipalException;
-import org.apache.wiki.auth.UserManager;
-import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.auth.WikiSecurityException;
-import org.apache.wiki.auth.user.UserProfile;
-import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
 import org.apache.wiki.ui.InputValidator;
-import org.apache.wiki.util.ClassUtil;
 
 import javax.servlet.http.HttpServletRequest;
 import java.security.Principal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
 
 
 /**
  * <p>
- * Facade class for storing, retrieving and managing wiki groups on behalf of
- * AuthorizationManager, JSPs and other presentation-layer classes. GroupManager
- * works in collaboration with a back-end {@link GroupDatabase}, which persists
- * groups to permanent storage.
+ * Facade class for storing, retrieving and managing wiki groups on behalf of AuthorizationManager, JSPs and other presentation-layer
+ * classes. GroupManager works in collaboration with a back-end {@link GroupDatabase}, which persists groups to permanent storage.
  * </p>
  * <p>
- * <em>Note: prior to JSPWiki 2.4.19, GroupManager was an interface; it
- * is now a concrete, final class. The aspects of GroupManager which previously
- * extracted group information from storage (e.g., wiki pages) have been
- * refactored into the GroupDatabase interface.</em>
+ * <em>Note: prior to JSPWiki 2.4.19, GroupManager was an interface; it is now a concrete, final class. The aspects of GroupManager
+ * which previously extracted group information from storage (e.g., wiki pages) have been refactored into the GroupDatabase interface.</em>
  * </p>
  * @since 2.4.19
  */
-public class GroupManager implements Authorizer, WikiEventListener {
+public interface GroupManager extends Authorizer, WikiEventListener {
 
     /** Key used for adding UI messages to a user's WikiSession. */
-    public static final String  MESSAGES_KEY = "group";
+    String MESSAGES_KEY = "group";
 
-    private static final String PROP_GROUPDATABASE = "jspwiki.groupdatabase";
-
-    private static final Logger log = Logger.getLogger( GroupManager.class );
-
-    protected Engine m_engine;
-
-    protected WikiEventListener m_groupListener;
-
-    private GroupDatabase       m_groupDatabase    = null;
-
-    /** Map with GroupPrincipals as keys, and Groups as values */
-    private final Map< Principal, Group > m_groups = new HashMap<>();
-
-    /**
-     * <p>
-     * Returns a GroupPrincipal matching a given name. If a group cannot be found, return <code>null</code>.
-     * </p>
-     * @param name Name of the group. This is case-sensitive.
-     * @return A DefaultGroup instance.
-     */
-    @Override public Principal findRole( final String name ) {
-        try {
-            final Group group = getGroup( name );
-            return group.getPrincipal();
-        } catch( final NoSuchPrincipalException e ) {
-            return null;
-        }
-    }
+    String PROP_GROUPDATABASE = "jspwiki.groupdatabase";
 
     /**
-     * Returns the Group matching a given name. If the group cannot be found,
-     * this method throws a <code>NoSuchPrincipalException</code>.
+     * Returns the Group matching a given name. If the group cannot be found, this method throws a <code>NoSuchPrincipalException</code>.
+     *
      * @param name the name of the group to find
      * @return the group
      * @throws NoSuchPrincipalException if the group cannot be found
      */
-    public Group getGroup( final String name ) throws NoSuchPrincipalException
-    {
-        final Group group = m_groups.get( new GroupPrincipal( name ) );
-        if ( group != null )
-        {
-            return group;
-        }
-        throw new NoSuchPrincipalException( "Group " + name + " not found." );
-    }
+    Group getGroup( final String name ) throws NoSuchPrincipalException;
 
     /**
-     * Returns the current external {@link GroupDatabase} in use. This method
-     * is guaranteed to return a properly-initialized GroupDatabase, unless
-     * it could not be initialized. In that case, this method throws
-     * a {@link org.apache.wiki.api.exceptions.WikiException}. The GroupDatabase
-     * is lazily initialized.
-     * @throws org.apache.wiki.auth.WikiSecurityException if the GroupDatabase could
-     * not be initialized
+     * Returns the current external {@link GroupDatabase} in use. This method is guaranteed to return a properly-initialized GroupDatabase,
+     * unless it could not be initialized. In that case, this method throws a {@link org.apache.wiki.api.exceptions.WikiException}. The
+     * GroupDatabase is lazily initialized.
+     *
+     * @throws org.apache.wiki.auth.WikiSecurityException if the GroupDatabase could not be initialized
      * @return the current GroupDatabase
      * @since 2.3
      */
-    public GroupDatabase getGroupDatabase() throws WikiSecurityException
-    {
-        if ( m_groupDatabase != null )
-        {
-            return m_groupDatabase;
-        }
-
-        String dbClassName = "<unknown>";
-        String dbInstantiationError = null;
-        Throwable cause = null;
-        try
-        {
-            final Properties props = m_engine.getWikiProperties();
-            dbClassName = props.getProperty( PROP_GROUPDATABASE );
-            if ( dbClassName == null )
-            {
-                dbClassName = XMLGroupDatabase.class.getName();
-            }
-            log.info( "Attempting to load group database class " + dbClassName );
-            final Class<?> dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
-            m_groupDatabase = (GroupDatabase) dbClass.newInstance();
-            m_groupDatabase.initialize( m_engine, m_engine.getWikiProperties() );
-            log.info( "Group database initialized." );
-        }
-        catch( final ClassNotFoundException e )
-        {
-            log.error( "GroupDatabase class " + dbClassName + " cannot be found.", e );
-            dbInstantiationError = "Failed to locate GroupDatabase class " + dbClassName;
-            cause = e;
-        }
-        catch( final InstantiationException e )
-        {
-            log.error( "GroupDatabase class " + dbClassName + " cannot be created.", e );
-            dbInstantiationError = "Failed to create GroupDatabase class " + dbClassName;
-            cause = e;
-        }
-        catch( final IllegalAccessException e )
-        {
-            log.error( "You are not allowed to access group database class " + dbClassName + ".", e );
-            dbInstantiationError = "Access GroupDatabase class " + dbClassName + " denied";
-            cause = e;
-        }
-        catch( final NoRequiredPropertyException e )
-        {
-            log.error( "Missing property: " + e.getMessage() + "." );
-            dbInstantiationError = "Missing property: " + e.getMessage();
-            cause = e;
-        }
-
-        if( dbInstantiationError != null )
-        {
-            throw new WikiSecurityException( dbInstantiationError + " Cause: " + (cause != null ? cause.getMessage() : ""), cause );
-        }
-
-        return m_groupDatabase;
-    }
-
-    /**
-     * Returns an array of GroupPrincipals this GroupManager knows about. This
-     * method will return an array of GroupPrincipal objects corresponding to
-     * the wiki groups managed by this class. This method actually returns a
-     * defensive copy of an internally stored hashmap.
-     * @return an array of Principals representing the roles
-     */
-    @Override public Principal[] getRoles()
-    {
-        return m_groups.keySet().toArray( new Principal[m_groups.size()] );
-    }
-
-    /**
-     * Initializes the group cache by initializing the group database and
-     * obtaining a list of all of the groups it stores.
-     * @param engine the wiki engine
-     * @param props the properties used to initialize the wiki engine
-     * @see GroupDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
-     * @see GroupDatabase#groups()
-     * @throws WikiSecurityException if GroupManager cannot be initialized
-     */
-    @Override public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException
-    {
-        m_engine = engine;
-
-        try
-        {
-            m_groupDatabase = getGroupDatabase();
-        }
-        catch ( final WikiException e )
-        {
-            throw new WikiSecurityException( e.getMessage(), e );
-        }
-
-        // Load all groups from the database into the cache
-        final Group[] groups = m_groupDatabase.groups();
-        synchronized( m_groups )
-        {
-            for( final Group group : groups )
-            {
-                // Add new group to cache; fire GROUP_ADD event
-                m_groups.put( group.getPrincipal(), group );
-                fireEvent( WikiSecurityEvent.GROUP_ADD, group );
-            }
-        }
-
-        // Make the GroupManager listen for WikiEvents (WikiSecurityEvents for changed user profiles)
-        engine.getManager( UserManager.class ).addWikiEventListener( this );
-
-        // Success!
-        log.info( "Authorizer GroupManager initialized successfully; loaded " + groups.length + " group(s)." );
-
-    }
+    GroupDatabase getGroupDatabase() throws WikiSecurityException;
 
     /**
      * <p>
-     * Determines whether the Subject associated with a WikiSession is in a
-     * particular role. This method takes two parameters: the WikiSession
-     * containing the subject and the desired role ( which may be a Role or a
-     * Group). If either parameter is <code>null</code>, or if the user is
-     * not authenticated, this method returns <code>false</code>.
-     * </p>
-     * <p>
-     * With respect to this implementation, the supplied Principal must be a
-     * GroupPrincipal. The Subject posesses the "role" if it the session is
-     * authenticated <em>and</em> a Subject's principal is a member of the
-     * corresponding Group. This method simply finds the Group in question, then
-     * delegates to {@link Group#isMember(Principal)} for each of the principals
-     * in the Subject's principal set.
+     * Extracts group name and members from passed parameters and populates an existing Group with them. The Group will either be a copy of
+     * an existing Group (if one can be found), or a new, unregistered Group (if not). Optionally, this method can throw a
+     * WikiSecurityException if the Group does not yet exist in the GroupManager cache.
      * </p>
-     * @param session the current WikiSession
-     * @param role the role to check
-     * @return <code>true</code> if the user is considered to be in the role,
-     *         <code>false</code> otherwise
-     */
-    @Override public boolean isUserInRole( final WikiSession session, final Principal role )
-    {
-        // Always return false if session/role is null, or if
-        // role isn't a GroupPrincipal
-        if ( session == null || role == null || !( role instanceof GroupPrincipal ) || !session.isAuthenticated() )
-        {
-            return false;
-        }
-
-        // Get the group we're examining
-        final Group group = m_groups.get( role );
-        if ( group == null )
-        {
-            return false;
-        }
-
-        // Check each user principal to see if it belongs to the group
-        for ( final Principal principal : session.getPrincipals() )
-        {
-            if ( AuthenticationManager.isUserPrincipal( principal ) && group.isMember( principal ) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * <p>
-     * Extracts group name and members from passed parameters and populates an
-     * existing Group with them. The Group will either be a copy of an existing
-     * Group (if one can be found), or a new, unregistered Group (if not).
-     * Optionally, this method can throw a WikiSecurityException if the Group
-     * does not yet exist in the GroupManager cache.
+     * The <code>group</code> parameter in the HTTP request contains the Group name to look up and populate. The <code>members</code>
+     * parameter contains the member list. If these differ from those in the existing group, the passed values override the old values.
      * </p>
      * <p>
-     * The <code>group</code> parameter in the HTTP request contains the Group
-     * name to look up and populate. The <code>members</code> parameter
-     * contains the member list. If these differ from those in the existing
-     * group, the passed values override the old values.
-     * </p>
-     * <p>
-     * This method does not commit the new Group to the GroupManager cache. To
-     * do that, use {@link #setGroup(WikiSession, Group)}.
+     * This method does not commit the new Group to the GroupManager cache. To do that, use {@link #setGroup(WikiSession, Group)}.
      * </p>
      * @param name the name of the group to construct
      * @param memberLine the line of text containing the group membership list
-     * @param create whether this method should create a new, empty Group if one
-     *            with the requested name is not found. If <code>false</code>,
-     *            groups that do not exist will cause a
-     *            <code>NoSuchPrincipalException</code> to be thrown
+     * @param create whether this method should create a new, empty Group if one with the requested name is not found. If <code>false</code>,
+     *            groups that do not exist will cause a <code>NoSuchPrincipalException</code> to be thrown
      * @return a new, populated group
      * @see org.apache.wiki.auth.authorize.Group#RESTRICTED_GROUPNAMES
-     * @throws WikiSecurityException if the group name isn't allowed, or if
-     * <code>create</code> is <code>false</code>
-     * and the Group named <code>name</code> does not exist
+     * @throws WikiSecurityException if the group name isn't allowed, or if <code>create</code> is <code>false</code>
+     *                               and the Group named <code>name</code> does not exist
      */
-    public Group parseGroup( String name, String memberLine, final boolean create ) throws WikiSecurityException
-    {
-        // If null name parameter, it's because someone's creating a new group
-        if ( name == null )
-        {
-            if ( create )
-            {
-                name = "MyGroup";
-            }
-            else
-            {
-                throw new WikiSecurityException( "Group name cannot be blank." );
-            }
-        }
-        else if ( ArrayUtils.contains( Group.RESTRICTED_GROUPNAMES, name ) )
-        {
-            // Certain names are forbidden
-            throw new WikiSecurityException( "Illegal group name: " + name );
-        }
-        name = name.trim();
-
-        // Normalize the member line
-        if ( InputValidator.isBlank( memberLine ) )
-        {
-            memberLine = "";
-        }
-        memberLine = memberLine.trim();
-
-        // Create or retrieve the group (may have been previously cached)
-        final Group group = new Group( name, m_engine.getApplicationName() );
-        try
-        {
-            final Group existingGroup = getGroup( name );
-
-            // If existing, clone it
-            group.setCreator( existingGroup.getCreator() );
-            group.setCreated( existingGroup.getCreated() );
-            group.setModifier( existingGroup.getModifier() );
-            group.setLastModified( existingGroup.getLastModified() );
-            for( final Principal existingMember : existingGroup.members() )
-            {
-                group.add( existingMember );
-            }
-        }
-        catch( final NoSuchPrincipalException e )
-        {
-            // It's a new group.... throw error if we don't create new ones
-            if ( !create )
-            {
-                throw new NoSuchPrincipalException( "Group '" + name + "' does not exist." );
-            }
-        }
-
-        // If passed members not empty, overwrite
-        final String[] members = extractMembers( memberLine );
-        if ( members.length > 0 )
-        {
-            group.clear();
-            for( final String member : members )
-            {
-                group.add( new WikiPrincipal( member ) );
-            }
-        }
-
-        return group;
-    }
+    Group parseGroup( String name, String memberLine, boolean create ) throws WikiSecurityException;
 
     /**
      * <p>
-     * Extracts group name and members from the HTTP request and populates an
-     * existing Group with them. The Group will either be a copy of an existing
-     * Group (if one can be found), or a new, unregistered Group (if not).
-     * Optionally, this method can throw a WikiSecurityException if the Group
-     * does not yet exist in the GroupManager cache.
+     * Extracts group name and members from the HTTP request and populates an existing Group with them. The Group will either be a copy of
+     * an existing Group (if one can be found), or a new, unregistered Group (if not). Optionally, this method can throw a
+     * WikiSecurityException if the Group does not yet exist in the GroupManager cache.
      * </p>
      * <p>
-     * The <code>group</code> parameter in the HTTP request contains the Group
-     * name to look up and populate. The <code>members</code> parameter
-     * contains the member list. If these differ from those in the existing
-     * group, the passed values override the old values.
+     * The <code>group</code> parameter in the HTTP request contains the Group name to look up and populate. The <code>members</code>
+     * parameter contains the member list. If these differ from those in the existing group, the passed values override the old values.
      * </p>
      * <p>
-     * This method does not commit the new Group to the GroupManager cache. To
-     * do that, use {@link #setGroup(WikiSession, Group)}.
+     * This method does not commit the new Group to the GroupManager cache. To do that, use {@link #setGroup(WikiSession, Group)}.
      * </p>
      * @param context the current wiki context
-     * @param create whether this method should create a new, empty Group if one
-     *            with the requested name is not found. If <code>false</code>,
-     *            groups that do not exist will cause a
-     *            <code>NoSuchPrincipalException</code> to be thrown
+     * @param create whether this method should create a new, empty Group if one with the requested name is not found. If <code>false</code>,
+     *            groups that do not exist will cause a <code>NoSuchPrincipalException</code> to be thrown
      * @return a new, populated group
-     * @throws WikiSecurityException if the group name isn't allowed, or if
-     * <code>create</code> is <code>false</code>
-     * and the Group does not exist
+     * @throws WikiSecurityException if the group name isn't allowed, or if <code>create</code> is <code>false</code>
+     *                               and the Group does not exist
      */
-    public Group parseGroup( final WikiContext context, final boolean create ) throws WikiSecurityException
-    {
+    default Group parseGroup( final WikiContext context, final boolean create ) throws WikiSecurityException {
         // Extract parameters
         final HttpServletRequest request = context.getHttpRequest();
         final String name = request.getParameter( "group" );
@@ -423,8 +126,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
         final Group group = parseGroup( name, memberLine, create );
 
         // If no members, add the current user by default
-        if ( group.members().length == 0 )
-        {
+        if( group.members().length == 0 ) {
             group.add( context.getWikiSession().getUserPrincipal() );
         }
 
@@ -432,310 +134,121 @@ public class GroupManager implements Authorizer, WikiEventListener {
     }
 
     /**
-     * Removes a named Group from the group database. If not found, throws a
-     * <code>NoSuchPrincipalException</code>. After removal, this method will
-     * commit the delete to the back-end group database. It will also fire a
-     * {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_REMOVE} event with
-     * the GroupManager instance as the source and the Group as target.
-     * If <code>index</code> is <code>null</code>, this method throws
-     * an {@link IllegalArgumentException}.
+     * Removes a named Group from the group database. If not found, throws a <code>NoSuchPrincipalException</code>. After removal, this
+     * method will commit the delete to the back-end group database. It will also fire a
+     * {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_REMOVE} event with the GroupManager instance as the source and the Group as target.
+     * If <code>index</code> is <code>null</code>, this method throws an {@link IllegalArgumentException}.
+     *
      * @param index the group to remove
-     * @throws WikiSecurityException if the Group cannot be removed by
-     * the back-end
+     * @throws WikiSecurityException if the Group cannot be removed by the back-end
      * @see org.apache.wiki.auth.authorize.GroupDatabase#delete(Group)
      */
-    public void removeGroup( final String index ) throws WikiSecurityException
-    {
-        if ( index == null )
-        {
-            throw new IllegalArgumentException( "Group cannot be null." );
-        }
-
-        final Group group = m_groups.get( new GroupPrincipal( index ) );
-        if ( group == null )
-        {
-            throw new NoSuchPrincipalException( "Group " + index + " not found" );
-        }
-
-        // Delete the group
-        // TODO: need rollback procedure
-        synchronized( m_groups )
-        {
-            m_groups.remove( group.getPrincipal() );
-        }
-        m_groupDatabase.delete( group );
-        fireEvent( WikiSecurityEvent.GROUP_REMOVE, group );
-    }
+    void removeGroup( final String index ) throws WikiSecurityException;
 
     /**
      * <p>
-     * Saves the {@link Group} created by a user in a wiki session. This method
-     * registers the Group with the GroupManager and saves it to the back-end
-     * database. If an existing Group with the same name already exists, the new
-     * group will overwrite it. After saving the Group, the group database
-     * changes are committed.
+     * Saves the {@link Group} created by a user in a wiki session. This method registers the Group with the GroupManager and saves it to
+     * the back-end database. If an existing Group with the same name already exists, the new group will overwrite it. After saving the
+     * Group, the group database changes are committed.
      * </p>
      * <p>
      * This method fires the following events:
      * </p>
      * <ul>
-     * <li><strong>When creating a new Group</strong>, this method fires a
-     * {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_ADD} with the
-     * GroupManager instance as its source and the new Group as the target.</li>
-     * <li><strong>When overwriting an existing Group</strong>, this method
-     * fires a new {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_REMOVE}
-     * with this GroupManager instance as the source, and the new Group as the
-     * target. It then fires a
-     * {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_ADD} event with the
-     * same source and target.</li>
+     * <li><strong>When creating a new Group</strong>, this method fires a {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_ADD} with
+     * the GroupManager instance as its source and the new Group as the target.</li>
+     * <li><strong>When overwriting an existing Group</strong>, this method fires a new
+     * {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_REMOVE} with this GroupManager instance as the source, and the new Group as the
+     * target. It then fires a {@link org.apache.wiki.event.WikiSecurityEvent#GROUP_ADD} event with the same source and target.</li>
      * </ul>
      * <p>
-     * In addition, if the save or commit actions fail, this method will attempt
-     * to restore the older version of the wiki group if it exists. This will
-     * result in a <code>GROUP_REMOVE</code> event (for the new version of the
-     * Group) followed by a <code>GROUP_ADD</code> event (to indicate
-     * restoration of the old version).
+     * In addition, if the save or commit actions fail, this method will attempt to restore the older version of the wiki group if it
+     * exists. This will result in a <code>GROUP_REMOVE</code> event (for the new version of the Group) followed by a <code>GROUP_ADD</code>
+     * event (to indicate restoration of the old version).
      * </p>
      * <p>
-     * This method will register the new Group with the GroupManager. For example,
-     * {@link org.apache.wiki.auth.AuthenticationManager} attaches each
-     * WikiSession as a GroupManager listener. Thus, the act of registering a
-     * Group with <code>setGroup</code> means that all WikiSessions will
-     * automatically receive group add/change/delete events immediately.
+     * This method will register the new Group with the GroupManager. For example, {@link org.apache.wiki.auth.AuthenticationManager}
+     * attaches each WikiSession as a GroupManager listener. Thus, the act of registering a Group with <code>setGroup</code> means that
+     * all WikiSessions will automatically receive group add/change/delete events immediately.
      * </p>
+     *
      * @param session the wiki session, which may not be <code>null</code>
      * @param group the Group, which may not be <code>null</code>
      * @throws WikiSecurityException if the Group cannot be saved by the back-end
      */
-    public void setGroup( final WikiSession session, final Group group ) throws WikiSecurityException
-    {
-        // TODO: check for appropriate permissions
-
-        // If group already exists, delete it; fire GROUP_REMOVE event
-        final Group oldGroup = m_groups.get( group.getPrincipal() );
-        if ( oldGroup != null )
-        {
-            fireEvent( WikiSecurityEvent.GROUP_REMOVE, oldGroup );
-            synchronized( m_groups )
-            {
-                m_groups.remove( oldGroup.getPrincipal() );
-            }
-        }
-
-        // Copy existing modifier info & timestamps
-        if ( oldGroup != null )
-        {
-            group.setCreator( oldGroup.getCreator() );
-            group.setCreated( oldGroup.getCreated() );
-            group.setModifier( oldGroup.getModifier() );
-            group.setLastModified( oldGroup.getLastModified() );
-        }
-
-        // Add new group to cache; announce GROUP_ADD event
-        synchronized( m_groups )
-        {
-            m_groups.put( group.getPrincipal(), group );
-        }
-        fireEvent( WikiSecurityEvent.GROUP_ADD, group );
-
-        // Save the group to back-end database; if it fails,
-        // roll back to previous state. Note that the back-end
-        // MUST timestammp the create/modify fields in the Group.
-        try
-        {
-            m_groupDatabase.save( group, session.getUserPrincipal() );
-        }
-
-        // We got an exception! Roll back...
-        catch( final WikiSecurityException e )
-        {
-            if ( oldGroup != null )
-            {
-                // Restore previous version, re-throw...
-                fireEvent( WikiSecurityEvent.GROUP_REMOVE, group );
-                fireEvent( WikiSecurityEvent.GROUP_ADD, oldGroup );
-                synchronized( m_groups )
-                {
-                    m_groups.put( oldGroup.getPrincipal(), oldGroup );
-                }
-                throw new WikiSecurityException( e.getMessage() + " (rolled back to previous version).", e );
-            }
-            // Re-throw security exception
-            throw new WikiSecurityException( e.getMessage(), e );
-        }
-    }
+    void setGroup( final WikiSession session, final Group group ) throws WikiSecurityException;
 
     /**
-     * Validates a Group, and appends any errors to the session errors list. Any
-     * validation errors are added to the wiki session's messages collection
-     * (see {@link WikiSession#getMessages()}.
+     * Validates a Group, and appends any errors to the session errors list. Any validation errors are added to the wiki session's messages
+     * collection (see {@link WikiSession#getMessages()}.
+     *
      * @param context the current wiki context
      * @param group the supplied Group
      */
-    public void validateGroup( final WikiContext context, final Group group )
-    {
+    default void validateGroup( final WikiContext context, final Group group ) {
         final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
 
         // Name cannot be null or one of the restricted names
-        try
-        {
+        try {
             checkGroupName( context, group.getName() );
-        }
-        catch( final WikiSecurityException e )
-        {
-
+        } catch( final WikiSecurityException e ) {
         }
 
         // Member names must be "safe" strings
         final Principal[] members = group.members();
-        for( int i = 0; i < members.length; i++ )
-        {
-            validator.validateNotNull( members[i].getName(), "Full name", InputValidator.ID );
+        for( final Principal member : members ) {
+            validator.validateNotNull( member.getName(), "Full name", InputValidator.ID );
         }
     }
 
-    /**
-     * Extracts carriage-return separated members into a Set of String objects.
-     * @param memberLine the list of members
-     * @return the list of members
-     */
-    protected String[] extractMembers( final String memberLine )
-    {
-        final Set<String> members = new HashSet<>();
-        if ( memberLine != null )
-        {
-            final StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
-            while( tok.hasMoreTokens() )
-            {
-                final String uid = tok.nextToken().trim();
-                if ( uid != null && uid.length() > 0 )
-                {
-                    members.add( uid );
-                }
-            }
-        }
-        return members.toArray( new String[members.size()] );
-    }
 
     /**
-     * Checks if a String is blank or a restricted Group name, and if it is,
-     * appends an error to the WikiSession's message list.
+     * Checks if a String is blank or a restricted Group name, and if it is, appends an error to the WikiSession's message list.
+     *
      * @param context the wiki context
      * @param name the Group name to test
-     * @throws WikiSecurityException if <code>session</code> is
-     * <code>null</code> or the Group name is illegal
+     * @throws WikiSecurityException if <code>session</code> is <code>null</code> or the Group name is illegal
      * @see Group#RESTRICTED_GROUPNAMES
      */
-    protected void checkGroupName( final WikiContext context, final String name ) throws WikiSecurityException
-    {
-        //TODO: groups cannot have the same name as a user
+    default void checkGroupName( final WikiContext context, final String name ) throws WikiSecurityException {
+        // TODO: groups cannot have the same name as a user
 
         // Name cannot be null
         final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
         validator.validateNotNull( name, "Group name" );
 
         // Name cannot be one of the restricted names either
-        if( ArrayUtils.contains( Group.RESTRICTED_GROUPNAMES, name ) )
-        {
+        if( ArrayUtils.contains( Group.RESTRICTED_GROUPNAMES, name ) ) {
             throw new WikiSecurityException( "The group name '" + name + "' is illegal. Choose another." );
         }
     }
 
-
     // events processing .......................................................
 
     /**
-     * Registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( final WikiEventListener listener )
-    {
-        WikiEventManager.addWikiEventListener( this, listener );
-    }
+    void addWikiEventListener( WikiEventListener listener );
 
     /**
-     * Un-registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Un-registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( final WikiEventListener listener )
-    {
-        WikiEventManager.removeWikiEventListener( this, listener );
-    }
+    void removeWikiEventListener( WikiEventListener listener );
 
     /**
-     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object
-     *  to all registered listeners.
+     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object to all registered listeners.
      *
      * @see org.apache.wiki.event.WikiSecurityEvent
      * @param type       the event type to be fired
      * @param target     the changed Object, which may be <code>null</code>
      */
-    protected void fireEvent( final int type, final Object target )
-    {
-        if ( WikiEventManager.isListening(this) )
-        {
-            WikiEventManager.fireEvent(this,new WikiSecurityEvent(this,type,target));
-        }
-    }
-
-    /**
-     * Listens for {@link org.apache.wiki.event.WikiSecurityEvent#PROFILE_NAME_CHANGED}
-     * events. If a user profile's name changes, each group is inspected. If an entry contains
-     * a name that has changed, it is replaced with the new one. No group events are emitted
-     * as a consequence of this method, because the group memberships are still the same; it is
-     * only the representations of the names within that are changing.
-     * @param event the incoming event
-     */
-    @Override public void actionPerformed( final WikiEvent event)
-    {
-        if (! ( event instanceof WikiSecurityEvent ) )
-        {
-            return;
-        }
-
-        final WikiSecurityEvent se = (WikiSecurityEvent)event;
-        if ( se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED )
-        {
-            final WikiSession session = se.getSrc();
-            final UserProfile[] profiles = (UserProfile[])se.getTarget();
-            final Principal[] oldPrincipals = new Principal[] {
-                new WikiPrincipal( profiles[0].getLoginName() ),
-                new WikiPrincipal( profiles[0].getFullname() ),
-                new WikiPrincipal( profiles[0].getWikiName() ) };
-            final Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() );
-
-            // Examine each group
-            int groupsChanged = 0;
-            try
-            {
-                for ( final Group group : m_groupDatabase.groups() )
-                {
-                    boolean groupChanged = false;
-                    for ( final Principal oldPrincipal : oldPrincipals )
-                    {
-                        if ( group.isMember( oldPrincipal ) )
-                        {
-                            group.remove( oldPrincipal );
-                            group.add( newPrincipal );
-                            groupChanged = true;
-                        }
-                    }
-                    if ( groupChanged )
-                    {
-                        setGroup( session, group );
-                        groupsChanged++;
-                    }
-                }
-            }
-            catch ( final WikiException e )
-            {
-                // Oooo! This is really bad...
-                log.error( "Could not change user name in Group lists because of GroupDatabase error:" + e.getMessage() );
-            }
-            log.info( "Profile name change for '" + newPrincipal.toString() +
-                      "' caused " + groupsChanged + " groups to change also." );
+    default void fireEvent( final int type, final Object target ) {
+        if( WikiEventManager.isListening( this ) ) {
+            WikiEventManager.fireEvent( this, new WikiSecurityEvent( this, type, target ) );
         }
     }
 
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index d572965..da8d88f 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -85,7 +85,7 @@
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.authorize.GroupManager</requestedClass>
-    <mappedClass>org.apache.wiki.auth.authorize.GroupManager</mappedClass>
+    <mappedClass>org.apache.wiki.auth.authorize.DefaultGroupManager</mappedClass>
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.content.PageRenamer</requestedClass>


[jspwiki] 21/38: JSPWIKI-120: use Engine instead of WikiEngine on Attachment, SessionMonitor, WikiContext and WikiSession

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit d3710e0da3f111f23f9f912e3b600f12fddc1db9
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 17:23:55 2020 +0100

    JSPWIKI-120: use Engine instead of WikiEngine on Attachment, SessionMonitor, WikiContext and WikiSession
---
 .../src/main/java/org/apache/wiki/WikiContext.java | 62 +++++++++---------
 .../src/main/java/org/apache/wiki/WikiSession.java | 31 ++++-----
 .../org/apache/wiki/attachment/Attachment.java     |  9 +--
 .../java/org/apache/wiki/auth/SessionMonitor.java  | 73 ++++++++++------------
 4 files changed, 85 insertions(+), 90 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java
index 65f1821..cd76c5a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java
@@ -19,11 +19,14 @@
 package org.apache.wiki;
 
 import org.apache.log4j.Logger;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.auth.permissions.AllPermission;
 import org.apache.wiki.auth.user.UserDatabase;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.ui.Command;
 import org.apache.wiki.ui.CommandResolver;
 import org.apache.wiki.ui.GroupCommand;
@@ -56,13 +59,12 @@ import java.util.PropertyPermission;
 public class WikiContext implements Cloneable, Command {
 
     private    Command m_command;
-
     private    WikiPage   m_page;
     private    WikiPage   m_realPage;
-    private    WikiEngine m_engine;
+    private    Engine     m_engine;
     private    String     m_template = "default";
 
-    private    HashMap<String,Object> m_variableMap = new HashMap<>();
+    private HashMap< String, Object > m_variableMap = new HashMap<>();
 
     /** Stores the HttpServletRequest.  May be null, if the request did not come from a servlet. */
     protected HttpServletRequest m_request;
@@ -167,30 +169,30 @@ public class WikiContext implements Cloneable, Command {
     private static final Permission DUMMY_PERMISSION = new PropertyPermission( "os.name", "read" );
 
     /**
-     *  Create a new WikiContext for the given WikiPage. Delegates to {@link #WikiContext(WikiEngine, HttpServletRequest, WikiPage)}.
+     *  Create a new WikiContext for the given WikiPage. Delegates to {@link #WikiContext(Engine, HttpServletRequest, WikiPage)}.
      *
-     *  @param engine The WikiEngine that is handling the request.
+     *  @param engine The Engine that is handling the request.
      *  @param page The WikiPage. If you want to create a WikiContext for an older version of a page, you must use this constructor.
      */
-    public WikiContext( final WikiEngine engine, final WikiPage page )
+    public WikiContext( final Engine engine, final WikiPage page )
     {
         this( engine, null, findCommand( engine, null, page ) );
     }
 
     /**
      * <p>
-     * Creates a new WikiContext for the given WikiEngine, Command and HttpServletRequest.
+     * Creates a new WikiContext for the given Engine, Command and HttpServletRequest.
      * </p>
      * <p>
      * This constructor will also look up the HttpSession associated with the request, and determine if a WikiSession object is present.
      * If not, a new one is created.
      * </p>
-     * @param engine The WikiEngine that is handling the request
+     * @param engine The Engine that is handling the request
      * @param request The HttpServletRequest that should be associated with this context. This parameter may be <code>null</code>.
      * @param command the command
      * @throws IllegalArgumentException if <code>engine</code> or <code>command</code> are <code>null</code>
      */
-    public WikiContext( final WikiEngine engine, final HttpServletRequest request, final Command command ) throws IllegalArgumentException {
+    public WikiContext( final Engine engine, final HttpServletRequest request, final Command command ) throws IllegalArgumentException {
         if ( engine == null || command == null ) {
             throw new IllegalArgumentException( "Parameter engine and command must not be null." );
         }
@@ -207,7 +209,7 @@ public class WikiContext implements Cloneable, Command {
 
         // If page not supplied, default to front page to avoid NPEs
         if( m_page == null ) {
-            m_page = m_engine.getPageManager().getPage( m_engine.getFrontPage() );
+            m_page = m_engine.getManager( PageManager.class ).getPage( m_engine.getFrontPage() );
 
             // Front page does not exist?
             if( m_page == null ) {
@@ -234,22 +236,22 @@ public class WikiContext implements Cloneable, Command {
     }
 
     /**
-     * Creates a new WikiContext for the given WikiEngine, WikiPage and HttpServletRequest. This method simply looks up the appropriate
-     * Command using {@link #findCommand(WikiEngine, HttpServletRequest, WikiPage)} and delegates to
-     * {@link #WikiContext(WikiEngine, HttpServletRequest, Command)}.
+     * Creates a new WikiContext for the given Engine, WikiPage and HttpServletRequest. This method simply looks up the appropriate
+     * Command using {@link #findCommand(Engine, HttpServletRequest, WikiPage)} and delegates to
+     * {@link #WikiContext(Engine, HttpServletRequest, Command)}.
      *
-     * @param engine The WikiEngine that is handling the request
+     * @param engine The Engine that is handling the request
      * @param request The HttpServletRequest that should be associated with this context. This parameter may be <code>null</code>.
      * @param page The WikiPage. If you want to create a WikiContext for an older version of a page, you must supply this parameter
      */
-    public WikiContext( final WikiEngine engine, final HttpServletRequest request, final WikiPage page ) {
+    public WikiContext( final Engine engine, final HttpServletRequest request, final WikiPage page ) {
         this( engine, request, findCommand( engine, request, page ) );
     }
 
     /**
      *  Creates a new WikiContext from a supplied HTTP request, using a default wiki context.
      *
-     *  @param engine The WikiEngine that is handling the request
+     *  @param engine The Engine that is handling the request
      *  @param request the HTTP request
      *  @param requestContext the default context to use
      *  @return a new WikiContext object.
@@ -258,10 +260,10 @@ public class WikiContext implements Cloneable, Command {
      *  @see org.apache.wiki.ui.Command
      *  @since 2.1.15.
      */
-    public WikiContext( final WikiEngine engine, final HttpServletRequest request, final String requestContext ) {
-        this( engine, request, engine.getCommandResolver().findCommand( request, requestContext ) );
+    public WikiContext( final Engine engine, final HttpServletRequest request, final String requestContext ) {
+        this( engine, request, engine.getManager( CommandResolver.class ).findCommand( request, requestContext ) );
         if( !engine.isConfigured() ) {
-            throw new InternalWikiException( "WikiEngine has not been properly started.  It is likely that the configuration is faulty.  Please check all logs for the possible reason." );
+            throw new InternalWikiException( "Engine has not been properly started.  It is likely that the configuration is faulty.  Please check all logs for the possible reason." );
         }
     }
 
@@ -333,7 +335,7 @@ public class WikiContext implements Cloneable, Command {
      */
     public String getRedirectURL() {
         final String pagename = m_page.getName();
-        String redirURL = m_engine.getCommandResolver().getSpecialPageReference( pagename );
+        String redirURL = m_engine.getManager( CommandResolver.class ).getSpecialPageReference( pagename );
         if( redirURL == null ) {
             final String alias = m_page.getAttribute( WikiPage.ALIAS );
             if( alias != null ) {
@@ -349,9 +351,9 @@ public class WikiContext implements Cloneable, Command {
     /**
      *  Returns the handling engine.
      *
-     *  @return The wikiengine owning this context.
+     *  @return The engine owning this context.
      */
-    public WikiEngine getEngine()
+    public Engine getEngine()
     {
         return m_engine;
     }
@@ -650,7 +652,7 @@ public class WikiContext implements Cloneable, Command {
 
     /**
      *  Returns the WikiSession associated with the context. This method is guaranteed to always return a valid WikiSession.
-     *  If this context was constructed without an associated HttpServletRequest, it will return {@link WikiSession#guestSession(WikiEngine)}.
+     *  If this context was constructed without an associated HttpServletRequest, it will return {@link WikiSession#guestSession(Engine)}.
      *
      *  @return The WikiSession associate with this context.
      */
@@ -687,7 +689,7 @@ public class WikiContext implements Cloneable, Command {
         if ( WikiCommand.INSTALL.equals( m_command ) ) {
             // See if admin users exists
             try {
-                final UserManager userMgr = m_engine.getUserManager();
+                final UserManager userMgr = m_engine.getManager( UserManager.class );
                 final UserDatabase userDb = userMgr.getUserDatabase();
                 userDb.findByLoginName( Installer.ADMIN_ID );
             } catch ( final NoSuchPrincipalException e ) {
@@ -728,7 +730,7 @@ public class WikiContext implements Cloneable, Command {
      *  @return true, if the user has all permissions.
      */
     public boolean hasAdminPermissions() {
-        return m_engine.getAuthorizationManager().checkPermission( getWikiSession(), new AllPermission( m_engine.getApplicationName() ) );
+        return m_engine.getManager( AuthorizationManager.class ).checkPermission( getWikiSession(), new AllPermission( m_engine.getApplicationName() ) );
     }
 
     /**
@@ -741,7 +743,7 @@ public class WikiContext implements Cloneable, Command {
         //  Figure out which template we should be using for this page.
         String template = null;
         if ( request != null ) {
-            String skin = request.getParameter( "skin" );
+            final String skin = request.getParameter( "skin" );
             if( skin != null )
             {
                 template = skin.replaceAll("\\p{Punct}", "");
@@ -753,7 +755,7 @@ public class WikiContext implements Cloneable, Command {
         if( template == null ) {
             final WikiPage page = getPage();
             if ( page != null ) {
-                template = page.getAttribute( WikiEngine.PROP_TEMPLATEDIR );
+                template = page.getAttribute( Engine.PROP_TEMPLATEDIR );
             }
 
         }
@@ -776,9 +778,9 @@ public class WikiContext implements Cloneable, Command {
      * @param page the wiki page
      * @return the correct command
      */
-    protected static Command findCommand( final WikiEngine engine, final HttpServletRequest request, final WikiPage page ) {
+    protected static Command findCommand( final Engine engine, final HttpServletRequest request, final WikiPage page ) {
         final String defaultContext = PageCommand.VIEW.getRequestContext();
-        Command command = engine.getCommandResolver().findCommand( request, defaultContext );
+        Command command = engine.getManager( CommandResolver.class ).findCommand( request, defaultContext );
         if ( command instanceof PageCommand && page != null ) {
             command = command.targetedCommand( page );
         }
@@ -796,7 +798,7 @@ public class WikiContext implements Cloneable, Command {
         if ( requestContext == null ) {
             m_command = PageCommand.NONE;
         } else {
-            final CommandResolver resolver = m_engine.getCommandResolver();
+            final CommandResolver resolver = m_engine.getManager( CommandResolver.class );
             m_command = resolver.findCommand( m_request, requestContext );
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiSession.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiSession.java
index 756260f..39ac604 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiSession.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiSession.java
@@ -20,6 +20,7 @@ package org.apache.wiki;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.auth.AuthenticationManager;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.NoSuchPrincipalException;
@@ -108,8 +109,8 @@ public final class WikiSession implements WikiEventListener {
 
     private final Map<String,Set<String>> m_messages  = new HashMap<>();
 
-    /** The WikiEngine that created this session. */
-    private WikiEngine          m_engine              = null;
+    /** The Engine that created this session. */
+    private Engine              m_engine              = null;
 
     private String              m_status              = ANONYMOUS;
 
@@ -362,7 +363,7 @@ public final class WikiSession implements WikiEventListener {
      * @param engine the wiki engine
      * @param request the users's HTTP request
      */
-    public static void removeWikiSession( final WikiEngine engine, final HttpServletRequest request ) {
+    public static void removeWikiSession( final Engine engine, final HttpServletRequest request ) {
         if ( engine == null || request == null ) {
             throw new IllegalArgumentException( "Request or engine cannot be null." );
         }
@@ -536,7 +537,7 @@ public final class WikiSession implements WikiEventListener {
         m_subject.getPrincipals().removeAll( m_subject.getPrincipals(GroupPrincipal.class) );
 
         // Get the GroupManager and test for each Group
-        final GroupManager manager = m_engine.getGroupManager();
+        final GroupManager manager = m_engine.getManager( GroupManager.class );
         for( final Principal group : manager.getRoles() ) {
             if ( manager.isUserInRole( this, group ) ) {
                 m_subject.getPrincipals().add( group );
@@ -559,7 +560,7 @@ public final class WikiSession implements WikiEventListener {
         }
 
         // Look up the user and go get the new Principals
-        final UserDatabase database = m_engine.getUserManager().getUserDatabase();
+        final UserDatabase database = m_engine.getManager( UserManager.class ).getUserDatabase();
         if( database == null ) {
             throw new IllegalStateException( "User database cannot be null." );
         }
@@ -603,7 +604,7 @@ public final class WikiSession implements WikiEventListener {
      * <p>Static factory method that returns the WikiSession object associated with the current HTTP request. This method looks up
      * the associated HttpSession in an internal WeakHashMap and attempts to retrieve the WikiSession. If not found, one is created.
      * This method is guaranteed to always return a WikiSession, although the authentication status is unpredictable until the user
-     * attempts to log in. If the servlet request parameter is <code>null</code>, a synthetic {@link #guestSession(WikiEngine)} is
+     * attempts to log in. If the servlet request parameter is <code>null</code>, a synthetic {@link #guestSession(Engine)} is
      * returned.</p>
      * <p>When a session is created, this method attaches a WikiEventListener to the GroupManager so that changes to groups are detected
      * automatically.</p>
@@ -612,7 +613,7 @@ public final class WikiSession implements WikiEventListener {
      * @param request the servlet request object
      * @return the existing (or newly created) wiki session
      */
-    public static WikiSession getWikiSession( final WikiEngine engine, final HttpServletRequest request ) {
+    public static WikiSession getWikiSession( final Engine engine, final HttpServletRequest request ) {
         if ( request == null ) {
             if ( log.isDebugEnabled() ) {
                 log.debug( "Looking up WikiSession for NULL HttpRequest: returning guestSession()" );
@@ -639,15 +640,15 @@ public final class WikiSession implements WikiEventListener {
      * @param engine the wiki engine
      * @return the guest wiki session
      */
-    public static WikiSession guestSession( final WikiEngine engine ) {
+    public static WikiSession guestSession( final Engine engine ) {
         final WikiSession session = new WikiSession();
         session.m_engine = engine;
         session.invalidate();
 
         // Add the session as listener for GroupManager, AuthManager, UserManager events
-        final GroupManager groupMgr = engine.getGroupManager();
-        final AuthenticationManager authMgr = engine.getAuthenticationManager();
-        final UserManager userMgr = engine.getUserManager();
+        final GroupManager groupMgr = engine.getManager( GroupManager.class );
+        final AuthenticationManager authMgr = engine.getManager( AuthenticationManager.class );
+        final UserManager userMgr = engine.getManager( UserManager.class );
         groupMgr.addWikiEventListener( session );
         authMgr.addWikiEventListener( session );
         userMgr.addWikiEventListener( session );
@@ -659,11 +660,11 @@ public final class WikiSession implements WikiEventListener {
      *  Returns a static guest session, which is available for this thread only.  This guest session is used internally whenever
      *  there is no HttpServletRequest involved, but the request is done e.g. when embedding JSPWiki code.
      *
-     *  @param engine WikiEngine for this session
+     *  @param engine Engine for this session
      *  @return A static WikiSession which is shared by all in this same Thread.
      */
     // FIXME: Should really use WeakReferences to clean away unused sessions.
-    private static WikiSession staticGuestSession( final WikiEngine engine ) {
+    private static WikiSession staticGuestSession( final Engine engine ) {
         WikiSession session = c_guestSession.get();
         if( session == null ) {
             session = guestSession( engine );
@@ -680,7 +681,7 @@ public final class WikiSession implements WikiEventListener {
      * @param engine the wiki session
      * @return the number of sessions
      */
-    public static int sessions( final WikiEngine engine ) {
+    public static int sessions( final Engine engine ) {
         final SessionMonitor monitor = SessionMonitor.getInstance( engine );
         return monitor.sessions();
     }
@@ -693,7 +694,7 @@ public final class WikiSession implements WikiEventListener {
      * @param engine the wiki engine
      * @return an array of Principal objects, sorted by name
      */
-    public static Principal[] userPrincipals( final WikiEngine engine ) {
+    public static Principal[] userPrincipals( final Engine engine ) {
         final SessionMonitor monitor = SessionMonitor.getInstance( engine );
         return monitor.userPrincipals();
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/attachment/Attachment.java b/jspwiki-main/src/main/java/org/apache/wiki/attachment/Attachment.java
index 6b608b0..fb59deb 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/attachment/Attachment.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/attachment/Attachment.java
@@ -18,8 +18,9 @@
  */
 package org.apache.wiki.attachment;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+
 
 /**
  *  Describes an attachment.  Attachments are actually derivatives of a WikiPage, since they do actually have a WikiName as well.
@@ -34,11 +35,11 @@ public class Attachment extends WikiPage {
      *  Creates a new attachment.  The final name of the attachment will be 
      *  a synthesis of the parent page name and the file name.
      *  
-     *  @param engine     The WikiEngine which is hosting this attachment.
+     *  @param engine     The Engine which is hosting this attachment.
      *  @param parentPage The page which will contain this attachment.
      *  @param fileName   The file name for the attachment.
      */
-    public Attachment( final WikiEngine engine, final String parentPage, final String fileName ) {
+    public Attachment( final Engine engine, final String parentPage, final String fileName ) {
         super( engine, parentPage + "/" + fileName );
 
         m_parentName = parentPage;
@@ -50,7 +51,7 @@ public class Attachment extends WikiPage {
      *  
      *  @return A debugging string
      */
-    public String toString() {
+    @Override public String toString() {
         return "Attachment [" + getName() + ";mod=" + getLastModified() + "]";
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/SessionMonitor.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/SessionMonitor.java
index c326a7b..4972c90 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/SessionMonitor.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/SessionMonitor.java
@@ -19,8 +19,8 @@
 package org.apache.wiki.auth;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
@@ -39,23 +39,21 @@ import java.util.concurrent.ConcurrentHashMap;
 
 /**
  *  <p>Manages WikiSession's for different WikiEngine's.</p>
- *  <p>The WikiSession's are stored both in the remote user
- *  HttpSession and in the SessionMonitor for the WikeEngine.
- *  This class must be configured as a session listener in the
- *  web.xml for the wiki web application.
+ *  <p>The WikiSession's are stored both in the remote user HttpSession and in the SessionMonitor for the WikeEngine.
+ *  This class must be configured as a session listener in the web.xml for the wiki web application.
  *  </p>
  */
 public class SessionMonitor implements HttpSessionListener {
 
-    private static Logger log = Logger.getLogger( SessionMonitor.class );
+    private static final Logger log = Logger.getLogger( SessionMonitor.class );
 
     /** Map with WikiEngines as keys, and SessionMonitors as values. */
-    private static ConcurrentHashMap<WikiEngine, SessionMonitor>          c_monitors   = new ConcurrentHashMap<>();
+    private static ConcurrentHashMap< Engine, SessionMonitor > c_monitors = new ConcurrentHashMap<>();
 
     /** Weak hashmap with HttpSessions as keys, and WikiSessions as values. */
-    private final Map<String, WikiSession>                 m_sessions   = new WeakHashMap<>();
+    private final Map< String, WikiSession > m_sessions = new WeakHashMap<>();
 
-    private       WikiEngine          m_engine;
+    private Engine m_engine;
 
     private final PrincipalComparator m_comparator = new PrincipalComparator();
 
@@ -65,8 +63,7 @@ public class SessionMonitor implements HttpSessionListener {
      * @param engine the wiki engine
      * @return the session monitor
      */
-    public static final SessionMonitor getInstance( WikiEngine engine )
-    {
+    public static final SessionMonitor getInstance( final Engine engine ) {
         if( engine == null )
         {
             throw new IllegalArgumentException( "Engine cannot be null." );
@@ -92,8 +89,7 @@ public class SessionMonitor implements HttpSessionListener {
     {
     }
 
-    private SessionMonitor( WikiEngine engine )
-    {
+    private SessionMonitor( final Engine engine ) {
         m_engine = engine;
     }
 
@@ -105,11 +101,10 @@ public class SessionMonitor implements HttpSessionListener {
      *  @param session the user's HTTP session
      *  @return the WikiSession, if found
      */
-    private WikiSession findSession( HttpSession session )
-    {
+    private WikiSession findSession( final HttpSession session ) {
         WikiSession wikiSession = null;
-        String sid = ( session == null ) ? "(null)" : session.getId();
-        WikiSession storedSession = m_sessions.get( sid );
+        final String sid = ( session == null ) ? "(null)" : session.getId();
+        final WikiSession storedSession = m_sessions.get( sid );
 
         // If the weak reference returns a wiki session, return it
         if( storedSession != null )
@@ -126,7 +121,7 @@ public class SessionMonitor implements HttpSessionListener {
     /**
      * <p>Looks up the wiki session associated with a user's Http session
      * and adds it to the session cache. This method will return the
-     * "guest session" as constructed by {@link WikiSession#guestSession(WikiEngine)}
+     * "guest session" as constructed by {@link org.apache.wiki.WikiSession#guestSession(Engine)}
      * if the HttpSession is not currently associated with a WikiSession.
      * This method is guaranteed to return a non-<code>null</code> WikiSession.</p>
      * <p>Internally, the session is stored in a HashMap; keys are
@@ -135,21 +130,17 @@ public class SessionMonitor implements HttpSessionListener {
      * @param session the HTTP session
      * @return the wiki session
      */
-    public final WikiSession find( HttpSession session )
-    {
+    public final WikiSession find( final HttpSession session ) {
         WikiSession wikiSession = findSession(session);
-        String sid = ( session == null ) ? "(null)" : session.getId();
+        final String sid = ( session == null ) ? "(null)" : session.getId();
 
         // Otherwise, create a new guest session and stash it.
-        if( wikiSession == null )
-        {
-            if( log.isDebugEnabled() )
-            {
+        if( wikiSession == null ) {
+            if( log.isDebugEnabled() ) {
                 log.debug( "Looking up WikiSession for session ID=" + sid + "... not found. Creating guestSession()" );
             }
             wikiSession = WikiSession.guestSession( m_engine );
-            synchronized( m_sessions )
-            {
+            synchronized( m_sessions ) {
                 m_sessions.put( sid, wikiSession );
             }
         }
@@ -162,7 +153,7 @@ public class SessionMonitor implements HttpSessionListener {
      * from the session cache.
      * @param session the user's HTTP session
      */
-    public final void remove( HttpSession session )
+    public final void remove( final HttpSession session )
     {
         if ( session == null )
         {
@@ -198,13 +189,13 @@ public class SessionMonitor implements HttpSessionListener {
      */
     public final Principal[] userPrincipals()
     {
-        Collection<Principal> principals = new ArrayList<>();
+        final Collection<Principal> principals = new ArrayList<>();
         synchronized ( m_sessions ) {
-            for (WikiSession session : m_sessions.values()) {
+            for ( final WikiSession session : m_sessions.values()) {
                 principals.add( session.getUserPrincipal() );
             }
         }
-        Principal[] p = principals.toArray( new Principal[principals.size()] );
+        final Principal[] p = principals.toArray( new Principal[principals.size()] );
         Arrays.sort( p, m_comparator );
         return p;
     }
@@ -214,7 +205,7 @@ public class SessionMonitor implements HttpSessionListener {
      * @param listener the event listener
      * @since 2.4.75
      */
-    public final synchronized void addWikiEventListener( WikiEventListener listener )
+    public final synchronized void addWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.addWikiEventListener( this, listener );
     }
@@ -224,7 +215,7 @@ public class SessionMonitor implements HttpSessionListener {
      * @param listener the event listener
      * @since 2.4.75
      */
-    public final synchronized void removeWikiEventListener( WikiEventListener listener )
+    public final synchronized void removeWikiEventListener( final WikiEventListener listener )
     {
         WikiEventManager.removeWikiEventListener( this, listener );
     }
@@ -236,7 +227,7 @@ public class SessionMonitor implements HttpSessionListener {
      * @param session the wiki session
      * @since 2.4.75
      */
-    protected final void fireEvent( int type, Principal principal, WikiSession session )
+    protected final void fireEvent( final int type, final Principal principal, final WikiSession session )
     {
         if( WikiEventManager.isListening(this) )
         {
@@ -250,9 +241,9 @@ public class SessionMonitor implements HttpSessionListener {
      * @param se the HTTP session event
      */
     @Override
-    public void sessionCreated( HttpSessionEvent se )
+    public void sessionCreated( final HttpSessionEvent se )
     {
-        HttpSession session = se.getSession();
+        final HttpSession session = se.getSession();
         log.debug( "Created session: " + session.getId() + "." );
     }
 
@@ -262,15 +253,15 @@ public class SessionMonitor implements HttpSessionListener {
      * @param se the HTTP session event
      */
     @Override
-    public void sessionDestroyed( HttpSessionEvent se )
+    public void sessionDestroyed( final HttpSessionEvent se )
     {
-        HttpSession session = se.getSession();
-        Iterator<SessionMonitor> it = c_monitors.values().iterator();
+        final HttpSession session = se.getSession();
+        final Iterator<SessionMonitor> it = c_monitors.values().iterator();
         while( it.hasNext() )
         {
-            SessionMonitor monitor = it.next();
+            final SessionMonitor monitor = it.next();
 
-            WikiSession storedSession = monitor.findSession(session);
+            final WikiSession storedSession = monitor.findSession(session);
 
             monitor.remove(session);
 


[jspwiki] 36/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (and 13)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 869dc56e04cd5c7945fc73d25f62a51b8d0bb48d
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:18:52 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (and 13)
---
 .../apache/wiki/search/tika/TikaSearchProviderTest.java   | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/jspwiki-tika-searchprovider/src/test/java/org/apache/wiki/search/tika/TikaSearchProviderTest.java b/jspwiki-tika-searchprovider/src/test/java/org/apache/wiki/search/tika/TikaSearchProviderTest.java
index cd0e6bf..95f93cb 100644
--- a/jspwiki-tika-searchprovider/src/test/java/org/apache/wiki/search/tika/TikaSearchProviderTest.java
+++ b/jspwiki-tika-searchprovider/src/test/java/org/apache/wiki/search/tika/TikaSearchProviderTest.java
@@ -19,6 +19,7 @@ package org.apache.wiki.search.tika;
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -47,20 +48,20 @@ public class TikaSearchProviderTest {
     @Test
     void testGetAttachmentContent() throws Exception {
         engine.saveText( "Test-tika", "blablablabla" );
-        byte[] filePdf = Files.readAllBytes( Paths.get( TikaSearchProviderTest.class.getClassLoader().getResource( "aaa-diagram.pdf" ).toURI() ) );
-        byte[] filePng = Files.readAllBytes( Paths.get( TikaSearchProviderTest.class.getClassLoader().getResource( "favicon.png" ).toURI() ) );
+        final byte[] filePdf = Files.readAllBytes( Paths.get( TikaSearchProviderTest.class.getClassLoader().getResource( "aaa-diagram.pdf" ).toURI() ) );
+        final byte[] filePng = Files.readAllBytes( Paths.get( TikaSearchProviderTest.class.getClassLoader().getResource( "favicon.png" ).toURI() ) );
         engine.addAttachment( "Test-tika", "aaa-diagram.pdf", filePdf );
         engine.addAttachment( "Test-tika", "favicon.png", filePng );
 
-        TikaSearchProvider tsp = ( TikaSearchProvider )engine.getSearchManager().getSearchEngine();
+        final TikaSearchProvider tsp = ( TikaSearchProvider )engine.getSearchManager().getSearchEngine();
 
-        Attachment attPdf = engine.getAttachmentManager().getAttachmentInfo( "Test-tika/aaa-diagram.pdf" );
-        String pdfIndexed = tsp.getAttachmentContent( attPdf );
+        final Attachment attPdf = engine.getManager( AttachmentManager.class ).getAttachmentInfo( "Test-tika/aaa-diagram.pdf" );
+        final String pdfIndexed = tsp.getAttachmentContent( attPdf );
         Assertions.assertTrue( pdfIndexed.contains( "aaa-diagram.pdf" ) );
         Assertions.assertTrue( pdfIndexed.contains( "WebContainerAuthorizer" ) );
 
-        Attachment attPng = engine.getAttachmentManager().getAttachmentInfo( "Test-tika/favicon.png" );
-        String pngIndexed = tsp.getAttachmentContent( attPng );
+        final Attachment attPng = engine.getManager( AttachmentManager.class ).getAttachmentInfo( "Test-tika/favicon.png" );
+        final String pngIndexed = tsp.getAttachmentContent( attPng );
         Assertions.assertTrue( pngIndexed.contains( "favicon.png" ) );
     }
 


[jspwiki] 35/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (12)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 6d6b17c82a16a60451b42493e60be121c0ceac2e
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:18:25 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (12)
---
 .../LocalLinkAttributeProviderState.java           |  8 ++---
 .../AccessRuleLinkNodePostProcessorState.java      |  6 ++--
 .../LocalLinkNodePostProcessorState.java           |  3 +-
 .../MetadataLinkNodePostProcessorState.java        |  3 +-
 .../VariableLinkNodePostProcessorState.java        |  3 +-
 .../wiki/parser/markdown/MarkdownParser.java       | 35 ++++++++++++----------
 .../apache/wiki/render/MarkdownRendererTest.java   |  5 ++--
 7 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
index ca53961..48c749c 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
@@ -19,14 +19,14 @@
 package org.apache.wiki.markdown.extensions.jspwikilinks.attributeprovider;
 
 import com.vladsch.flexmark.util.ast.Node;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.markdown.nodes.JSPWikiLink;
 import org.apache.wiki.parser.LinkParsingOperations;
 import org.apache.wiki.parser.MarkupParser;
 
-import com.vladsch.flexmark.util.html.Attributes;
-import com.vladsch.flexmark.util.sequence.CharSubSequence;
-
 
 /**
  * {@link NodeAttributeProviderState} which sets the attributes for local links.
@@ -51,7 +51,7 @@ public class LocalLinkAttributeProviderState implements NodeAttributeProviderSta
     @Override
     public void setAttributes( final Attributes attributes, final JSPWikiLink link ) {
         final int hashMark = link.getUrl().toString().indexOf( '#' );
-        final String attachment = wikiContext.getEngine().getAttachmentManager().getAttachmentInfoName( wikiContext, link.getWikiLink() );
+        final String attachment = wikiContext.getEngine().getManager( AttachmentManager.class ).getAttachmentInfoName( wikiContext, link.getWikiLink() );
         if( attachment != null ) {
             if( !linkOperations.isImageLink( link.getUrl().toString() ) ) {
                 attributes.replaceValue( "class", MarkupParser.CLASS_ATTACHMENT );
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
index 3d6c4cb..d977565 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
@@ -25,7 +25,9 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.auth.WikiSecurityException;
 import org.apache.wiki.auth.acl.Acl;
+import org.apache.wiki.auth.acl.AclManager;
 import org.apache.wiki.markdown.nodes.JSPWikiLink;
+import org.apache.wiki.render.RenderingManager;
 
 
 /**
@@ -51,7 +53,7 @@ public class AccessRuleLinkNodePostProcessorState implements NodePostProcessorSt
     @Override
     public void process( final NodeTracker state, final JSPWikiLink link ) {
         String ruleLine = NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
-        if( wikiContext.getEngine().getRenderingManager().getParser( wikiContext, link.getUrl().toString() ).isParseAccessRules() ) {
+        if( wikiContext.getEngine().getManager( RenderingManager.class ).getParser( wikiContext, link.getUrl().toString() ).isParseAccessRules() ) {
             final WikiPage page = wikiContext.getRealPage();
             if( ruleLine.startsWith( "{" ) ) {
                 ruleLine = ruleLine.substring( 1 );
@@ -62,7 +64,7 @@ public class AccessRuleLinkNodePostProcessorState implements NodePostProcessorSt
             LOG.debug( "page=" + page.getName() + ", ACL = " + ruleLine );
 
             try {
-                final Acl acl = wikiContext.getEngine().getAclManager().parseAcl( page, ruleLine );
+                final Acl acl = wikiContext.getEngine().getManager( AclManager.class ).parseAcl( page, ruleLine );
                 page.setAcl( acl );
                 link.unlink();
                 state.nodeRemoved( link );
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
index 1c6345a..0e1629a 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
@@ -23,6 +23,7 @@ import com.vladsch.flexmark.util.ast.Node;
 import com.vladsch.flexmark.util.ast.NodeTracker;
 import com.vladsch.flexmark.util.sequence.CharSubSequence;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.markdown.nodes.JSPWikiLink;
 import org.apache.wiki.parser.LinkParsingOperations;
 import org.apache.wiki.parser.MarkupParser;
@@ -49,7 +50,7 @@ public class LocalLinkNodePostProcessorState implements NodePostProcessorState<
     @Override
     public void process( final NodeTracker state, final JSPWikiLink link ) {
         final int hashMark = link.getUrl().toString().indexOf( '#' );
-        final String attachment = wikiContext.getEngine().getAttachmentManager().getAttachmentInfoName( wikiContext, link.getUrl().toString() );
+        final String attachment = wikiContext.getEngine().getManager( AttachmentManager.class ).getAttachmentInfoName( wikiContext, link.getUrl().toString() );
         if( attachment != null  ) {
             if( !linkOperations.isImageLink( link.getUrl().toString() ) ) {
                 final String attlink = wikiContext.getURL( WikiContext.ATTACH, link.getUrl().toString() );
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
index 47661b5..fadb459 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
@@ -25,6 +25,7 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.markdown.nodes.JSPWikiLink;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.variables.VariableManager;
 
 import java.text.MessageFormat;
 import java.util.ResourceBundle;
@@ -71,7 +72,7 @@ public class MetadataLinkNodePostProcessorState implements NodePostProcessorStat
             LOG.debug( "page=" + wikiContext.getRealPage().getName() + " SET name='" + name + "', value='" + val + "'" );
 
             if( name.length() > 0 && val.length() > 0 ) {
-                val = wikiContext.getEngine().getVariableManager().expandVariables( wikiContext, val );
+                val = wikiContext.getEngine().getManager( VariableManager.class ).expandVariables( wikiContext, val );
                 wikiContext.getPage().setAttribute( name, val );
                 link.unlink();
                 state.nodeRemoved( link );
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
index 6a72cf7..4c1ea59 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
@@ -26,6 +26,7 @@ import org.apache.commons.text.StringEscapeUtils;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
 import org.apache.wiki.markdown.nodes.JSPWikiLink;
+import org.apache.wiki.variables.VariableManager;
 
 
 /**
@@ -52,7 +53,7 @@ public class VariableLinkNodePostProcessorState implements NodePostProcessorStat
         final String variable = NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
         if( !m_wysiwygEditorMode ) {
             try {
-                final String parsedVariable = wikiContext.getEngine().getVariableManager().parseAndGetValue( wikiContext, variable );
+                final String parsedVariable = wikiContext.getEngine().getManager( VariableManager.class ).parseAndGetValue( wikiContext, variable );
                 final HtmlInline content = new HtmlInline( CharSubSequence.of( StringEscapeUtils.escapeXml11( parsedVariable ) ) );
                 NodePostProcessorStateCommonOperations.addContent( state, link, content );
             } catch( final NoSuchVariableException e ) {
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
index c98f4ef..d36647b 100755
--- a/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
@@ -21,6 +21,8 @@ package org.apache.wiki.parser.markdown;
 import com.vladsch.flexmark.parser.Parser;
 import com.vladsch.flexmark.util.ast.Node;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.auth.AuthorizationManager;
+import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.parser.WikiDocument;
 
@@ -33,26 +35,27 @@ import java.io.Reader;
  */
 public class MarkdownParser extends MarkupParser {
 
-	private final Parser parser;
+    private final Parser parser;
 
-	public MarkdownParser( final WikiContext context, final Reader in ) {
-		super( context, in );
-		if( context.getEngine().getUserManager().getUserDatabase() == null || context.getEngine().getAuthorizationManager() == null ) {
+    public MarkdownParser( final WikiContext context, final Reader in ) {
+        super( context, in );
+        if( context.getEngine().getManager( UserManager.class ).getUserDatabase() == null || 
+            context.getEngine().getManager( AuthorizationManager.class ) == null ) {
             disableAccessRules();
         }
-		parser = Parser.builder( MarkdownDocument.options( context ) ).build();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public WikiDocument parse() throws IOException {
-		final Node document = parser.parseReader( m_in );
-		final MarkdownDocument md = new MarkdownDocument( m_context.getPage(), document );
+        parser = Parser.builder( MarkdownDocument.options( context ) ).build();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WikiDocument parse() throws IOException {
+        final Node document = parser.parseReader( m_in );
+        final MarkdownDocument md = new MarkdownDocument( m_context.getPage(), document );
         md.setContext( m_context );
 
-		return md;
-	}
+        return md;
+    }
 
 }
diff --git a/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java b/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
index 19bbb2d..fbeb7b2 100755
--- a/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
+++ b/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
@@ -25,6 +25,7 @@ import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.markdown.MarkdownParser;
 import org.apache.wiki.render.markdown.MarkdownRenderer;
 import org.junit.jupiter.api.AfterEach;
@@ -105,14 +106,14 @@ public class MarkdownRendererTest {
         Assertions.assertEquals( "<p> This should be visible if the ACL allows you to see it</p>\n", translate( src ) );
         // in any case, we also check that the created wikipage has the ACL added
         Assertions.assertEquals( "  user = PerryMason: ((\"org.apache.wiki.auth.permissions.PagePermission\",\"JSPWiki:testpage\",\"view\"))\n",
-        		                 testEngine.getPageManager().getPage( PAGE_NAME ).getAcl().toString() );
+        		                 testEngine.getManager( PageManager.class ).getPage( PAGE_NAME ).getAcl().toString() );
     }
 
     @Test
     public void testMarkupExtensionMetadata() throws Exception {
         final String src = "[{SET Perry='Mason'}]() Some text after setting metadata";
         Assertions.assertEquals( "<p> Some text after setting metadata</p>\n", translate( src ) );
-        Assertions.assertEquals( "Mason", testEngine.getPageManager().getPage( PAGE_NAME ).getAttribute( "Perry" ) );
+        Assertions.assertEquals( "Mason", testEngine.getManager( PageManager.class ).getPage( PAGE_NAME ).getAttribute( "Perry" ) );
     }
 
     @Test


[jspwiki] 22/38: JSPWIKI-120: WikiProvider#initialize receives an Engine instead of a WikiEngine

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 43bf1824740ccc21c9abe807914b1e321216e975
Author: juanpablo <ju...@apache.org>
AuthorDate: Fri Feb 21 17:25:22 2020 +0100

    JSPWIKI-120: WikiProvider#initialize receives an Engine instead of a WikiEngine
---
 .../main/java/org/apache/wiki/WikiProvider.java    |  11 +-
 .../apache/wiki/diff/ContextualDiffProvider.java   |  19 +-
 .../java/org/apache/wiki/diff/DiffProvider.java    |   8 +-
 .../org/apache/wiki/diff/ExternalDiffProvider.java |  10 +-
 .../apache/wiki/diff/TraditionalDiffProvider.java  |  18 +-
 .../wiki/providers/AbstractFileProvider.java       | 412 ++++++++----------
 .../wiki/providers/BasicAttachmentProvider.java    | 469 ++++++++-------------
 .../wiki/providers/CachingAttachmentProvider.java  |  80 ++--
 .../org/apache/wiki/providers/CachingProvider.java | 135 +++---
 .../apache/wiki/providers/FileSystemProvider.java  | 179 +++-----
 .../wiki/providers/VersioningFileProvider.java     | 255 +++++------
 .../wiki/providers/WikiAttachmentProvider.java     | 107 ++---
 .../apache/wiki/providers/WikiPageProvider.java    |  61 +--
 .../apache/wiki/search/BasicSearchProvider.java    |  27 +-
 .../apache/wiki/search/LuceneSearchProvider.java   |  31 +-
 .../java/org/apache/wiki/search/SearchMatcher.java |  12 +-
 .../org/apache/wiki/providers/CounterProvider.java |  56 +--
 .../apache/wiki/providers/VerySimpleProvider.java  |  42 +-
 .../wiki/search/tika/TikaSearchProvider.java       |  17 +-
 19 files changed, 772 insertions(+), 1177 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/WikiProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/WikiProvider.java
index 8e13402..c401dae 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiProvider.java
@@ -18,6 +18,7 @@
  */
 package org.apache.wiki;
 
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 
 import java.io.IOException;
@@ -25,15 +26,13 @@ import java.util.Properties;
 
 
 /**
- *  A generic Wiki provider for all sorts of things that the Wiki can
- *  store.
+ *  A generic Wiki provider for all sorts of things that the Wiki can store.
  *
  *  @since 2.0
  */
 public interface WikiProvider {
-    /**
-     *  Passing this to any method should get the latest version
-     */
+
+    /** Passing this to any method should get the latest version */
     int LATEST_VERSION = -1;
 
     /**
@@ -44,7 +43,7 @@ public interface WikiProvider {
      *  @throws NoRequiredPropertyException If the provider needs a property which is not found in the property set
      *  @throws IOException If there is an IO problem
      */
-    void initialize( WikiEngine engine, Properties properties ) throws NoRequiredPropertyException, IOException;
+    void initialize( Engine engine, Properties properties ) throws NoRequiredPropertyException, IOException;
 
     /**
      *  Return a valid HTML string for information.  May be anything.
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/ContextualDiffProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/ContextualDiffProvider.java
index 27077c0..1fac181 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/ContextualDiffProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/ContextualDiffProvider.java
@@ -21,7 +21,7 @@ package org.apache.wiki.diff;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.util.TextUtil;
 import org.suigeneris.jrcs.diff.Diff;
@@ -101,18 +101,17 @@ public class ContextualDiffProvider implements DiffProvider {
      * 
      * {@inheritDoc}
      */
-    public String getProviderInfo()
+    @Override public String getProviderInfo()
     {
         return "ContextualDiffProvider";
     }
 
     /**
-     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.WikiEngine,
-     *      java.util.Properties)
+     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      *      
      * {@inheritDoc}
      */
-    public void initialize( final WikiEngine engine, final Properties properties) throws NoRequiredPropertyException, IOException {
+    @Override public void initialize( final Engine engine, final Properties properties) throws NoRequiredPropertyException, IOException {
         final String configuredLimit = properties.getProperty( PROP_UNCHANGED_CONTEXT_LIMIT, Integer.toString( LIMIT_MAX_VALUE ) );
         int limit = LIMIT_MAX_VALUE;
         try {
@@ -132,7 +131,7 @@ public class ContextualDiffProvider implements DiffProvider {
      * 
      * {@inheritDoc}
      */
-    public synchronized String makeDiffHtml( final WikiContext ctx, final String wikiOld, final String wikiNew ) {
+    @Override public synchronized String makeDiffHtml( final WikiContext ctx, final String wikiOld, final String wikiNew ) {
         //
         // Sequencing handles lineterminator to <br /> and every-other consequtive space to a &nbsp;
         //
@@ -274,11 +273,11 @@ public class ContextualDiffProvider implements DiffProvider {
             m_firstElem = orig.last() + 1;
         }
 
-        public void visit( final Revision rev ) {
+        @Override public void visit( final Revision rev ) {
             // GNDN (Goes nowhere, does nothing)
         }
 
-        public void visit( final AddDelta delta ) {
+        @Override public void visit( final AddDelta delta ) {
             updateState( delta );
 
             // We have run Deletes up to now. Flush them out.
@@ -298,7 +297,7 @@ public class ContextualDiffProvider implements DiffProvider {
             }
         }
 
-        public void visit( final ChangeDelta delta ) {
+        @Override public void visit( final ChangeDelta delta ) {
             updateState( delta );
 
             // We are in "neutral mode". A Change might be merged with an add or delete.
@@ -311,7 +310,7 @@ public class ContextualDiffProvider implements DiffProvider {
             addNew( delta.getRevised() );
         }
 
-        public void visit( final DeleteDelta delta ) {
+        @Override public void visit( final DeleteDelta delta ) {
             updateState( delta );
 
             // We have run Adds up to now. Flush them out.
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/DiffProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/DiffProvider.java
index 4a0aced..a6df9d0 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/DiffProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/DiffProvider.java
@@ -19,8 +19,8 @@
 package org.apache.wiki.diff;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 
 import java.io.IOException;
@@ -49,20 +49,20 @@ public interface DiffProvider extends WikiProvider {
         /**
          *  {@inheritDoc}
          */
-        public String makeDiffHtml( final WikiContext ctx, final String oldWikiText, final String newWikiText ) {
+        @Override public String makeDiffHtml( final WikiContext ctx, final String oldWikiText, final String newWikiText ) {
             return "You are using the NullDiffProvider, check your properties file.";
         }
 
         /**
          *  {@inheritDoc}
          */
-        public void initialize( final WikiEngine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
+        @Override public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         }
 
         /**
          *  {@inheritDoc}
          */
-        public String getProviderInfo()
+        @Override public String getProviderInfo()
         {
             return "NullDiffProvider";
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
index fdf7cee..8b8cdc3 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
@@ -21,7 +21,7 @@ package org.apache.wiki.diff;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.util.FileUtil;
 import org.apache.wiki.util.TextUtil;
@@ -75,16 +75,16 @@ public class ExternalDiffProvider implements DiffProvider {
      * @see org.apache.wiki.WikiProvider#getProviderInfo()
      * {@inheritDoc}
      */
-    public String getProviderInfo()
+    @Override public String getProviderInfo()
     {
         return "ExternalDiffProvider";
     }
 
     /**
      * {@inheritDoc}
-     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.WikiEngine, java.util.Properties)
+     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      */
-    public void initialize( final WikiEngine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
+    @Override public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         m_diffCommand = properties.getProperty( PROP_DIFFCOMMAND );
         if( m_diffCommand == null || m_diffCommand.trim().equals( "" ) ) {
             throw new NoRequiredPropertyException( "ExternalDiffProvider missing required property", PROP_DIFFCOMMAND );
@@ -98,7 +98,7 @@ public class ExternalDiffProvider implements DiffProvider {
      * Makes the diff by calling "diff" program.
      * {@inheritDoc}
      */
-    public String makeDiffHtml( final WikiContext ctx, final String p1, final String p2 ) {
+    @Override public String makeDiffHtml( final WikiContext ctx, final String p1, final String p2 ) {
         File f1 = null;
         File f2 = null;
         String diff = null;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/TraditionalDiffProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/TraditionalDiffProvider.java
index 6bd60bf..474bd4d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/TraditionalDiffProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/TraditionalDiffProvider.java
@@ -21,7 +21,7 @@ package org.apache.wiki.diff;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.preferences.Preferences;
@@ -66,16 +66,16 @@ public class TraditionalDiffProvider implements DiffProvider {
      * {@inheritDoc}
      * @see org.apache.wiki.WikiProvider#getProviderInfo()
      */
-    public String getProviderInfo()
+    @Override public String getProviderInfo()
     {
         return "TraditionalDiffProvider";
     }
 
     /**
      * {@inheritDoc}
-     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.WikiEngine, java.util.Properties)
+     * @see org.apache.wiki.WikiProvider#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      */
-    public void initialize( final WikiEngine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
+    @Override public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
     }
 
     /**
@@ -88,7 +88,7 @@ public class TraditionalDiffProvider implements DiffProvider {
      * 
      * @return Full HTML diff.
      */
-    public String makeDiffHtml( final WikiContext ctx, final String p1, final String p2 ) {
+    @Override public String makeDiffHtml( final WikiContext ctx, final String p1, final String p2 ) {
         final String diffResult;
 
         try {
@@ -129,24 +129,24 @@ public class TraditionalDiffProvider implements DiffProvider {
             m_rb = Preferences.getBundle( ctx, InternationalizationManager.CORE_BUNDLE );
         }
 
-        public void visit( final Revision rev ) {
+        @Override public void visit( final Revision rev ) {
             // GNDN (Goes nowhere, does nothing)
         }
 
-        public void visit( final AddDelta delta ) {
+        @Override public void visit( final AddDelta delta ) {
             final Chunk changed = delta.getRevised();
             print( changed, m_rb.getString( "diff.traditional.added" ) );
             changed.toString( m_result, CSS_DIFF_ADDED, CSS_DIFF_CLOSE );
         }
 
-        public void visit( final ChangeDelta delta ) {
+        @Override public void visit( final ChangeDelta delta ) {
             final Chunk changed = delta.getOriginal();
             print(changed, m_rb.getString( "diff.traditional.changed" ) );
             changed.toString( m_result, CSS_DIFF_REMOVED, CSS_DIFF_CLOSE );
             delta.getRevised().toString( m_result, CSS_DIFF_ADDED, CSS_DIFF_CLOSE );
         }
 
-        public void visit( final DeleteDelta delta ) {
+        @Override public void visit( final DeleteDelta delta ) {
             final Chunk changed = delta.getOriginal();
             print( changed, m_rb.getString( "diff.traditional.removed" ) );
             changed.toString( m_result, CSS_DIFF_REMOVED, CSS_DIFF_CLOSE );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/AbstractFileProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/AbstractFileProvider.java
index 980fade..4ab94fc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/AbstractFileProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/AbstractFileProvider.java
@@ -24,6 +24,7 @@ import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.search.QueryItem;
@@ -56,24 +57,20 @@ import java.util.TreeSet;
 /**
  *  Provides a simple directory based repository for Wiki pages.
  *  <P>
- *  All files have ".txt" appended to make life easier for those
- *  who insist on using Windows or other software which makes assumptions
+ *  All files have ".txt" appended to make life easier for those who insist on using Windows or other software which makes assumptions
  *  on the files contents based on its name.
  *  <p>
  *  This class functions as a superclass to all file based providers.
  *
  *  @since 2.1.21.
- *
  */
-public abstract class AbstractFileProvider
-    implements WikiPageProvider
-{
-    private static final Logger   log = Logger.getLogger(AbstractFileProvider.class);
-    private String m_pageDirectory = "/tmp/";
+public abstract class AbstractFileProvider implements WikiPageProvider {
 
+    private static final Logger log = Logger.getLogger(AbstractFileProvider.class);
+    private String m_pageDirectory = "/tmp/";
     protected String m_encoding;
 
-    protected WikiEngine m_engine;
+    protected Engine m_engine;
 
     public static final String PROP_CUSTOMPROP_MAXLIMIT = "custom.pageproperty.max.allowed";
     public static final String PROP_CUSTOMPROP_MAXKEYLENGTH = "custom.pageproperty.key.length";
@@ -87,14 +84,14 @@ public abstract class AbstractFileProvider
      * This parameter limits the number of custom page properties allowed on a page
      */
     public static int MAX_PROPLIMIT = DEFAULT_MAX_PROPLIMIT;
+
     /**
-     * This number limits the length of a custom page property key length
-     * The default value here designed with future JDBC providers in mind.
+     * This number limits the length of a custom page property key length. The default value here designed with future JDBC providers in mind.
      */
     public static int MAX_PROPKEYLENGTH = DEFAULT_MAX_PROPKEYLENGTH;
+
     /**
-     * This number limits the length of a custom page property value length
-     * The default value here designed with future JDBC providers in mind.
+     * This number limits the length of a custom page property value length. The default value here designed with future JDBC providers in mind.
      */
     public static int MAX_PROPVALUELENGTH = DEFAULT_MAX_PROPVALUELENGTH;
 
@@ -121,50 +118,37 @@ public abstract class AbstractFileProvider
      *  @throws IOException In case the specified page directory is a file, not a directory.
      */
     @Override
-    public void initialize( WikiEngine engine, Properties properties ) throws NoRequiredPropertyException, IOException, FileNotFoundException
-    {
-        log.debug("Initing FileSystemProvider");
-        m_pageDirectory = TextUtil.getCanonicalFilePathProperty(properties, PROP_PAGEDIR,
-                System.getProperty("user.home") + File.separator + "jspwiki-files");
-
-        File f = new File(m_pageDirectory);
-
-        if( !f.exists() )
-        {
-            if( !f.mkdirs() )
-            {
-                throw new IOException( "Failed to create page directory " + f.getAbsolutePath() + " , please check property "
-                                       + PROP_PAGEDIR );
+    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException, FileNotFoundException {
+        log.debug( "Initing FileSystemProvider" );
+        m_pageDirectory = TextUtil.getCanonicalFilePathProperty( properties, PROP_PAGEDIR,
+                                                          System.getProperty( "user.home" ) + File.separator + "jspwiki-files" );
+
+        final File f = new File( m_pageDirectory );
+
+        if( !f.exists() ) {
+            if( !f.mkdirs() ) {
+                throw new IOException(
+                        "Failed to create page directory " + f.getAbsolutePath() + " , please check property " + PROP_PAGEDIR );
             }
-        }
-        else
-        {
-            if( !f.isDirectory() )
-            {
+        } else {
+            if( !f.isDirectory() ) {
                 throw new IOException( "Page directory is not a directory: " + f.getAbsolutePath() );
             }
-            if( !f.canWrite() )
-            {
+            if( !f.canWrite() ) {
                 throw new IOException( "Page directory is not writable: " + f.getAbsolutePath() );
             }
         }
 
         m_engine = engine;
-
         m_encoding = properties.getProperty( WikiEngine.PROP_ENCODING, DEFAULT_ENCODING );
-
-        String os = System.getProperty( "os.name" ).toLowerCase();
-
-        if( os.startsWith("windows") || os.equals("nt") )
-        {
+        final String os = System.getProperty( "os.name" ).toLowerCase();
+        if( os.startsWith( "windows" ) || os.equals( "nt" ) ) {
             m_windowsHackNeeded = true;
         }
 
-    	if (properties != null) {
-            MAX_PROPLIMIT = TextUtil.getIntegerProperty(properties,PROP_CUSTOMPROP_MAXLIMIT,DEFAULT_MAX_PROPLIMIT);
-            MAX_PROPKEYLENGTH = TextUtil.getIntegerProperty(properties,PROP_CUSTOMPROP_MAXKEYLENGTH,DEFAULT_MAX_PROPKEYLENGTH);
-            MAX_PROPVALUELENGTH = TextUtil.getIntegerProperty(properties,PROP_CUSTOMPROP_MAXVALUELENGTH,DEFAULT_MAX_PROPVALUELENGTH);
-    	}
+        MAX_PROPLIMIT = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXLIMIT, DEFAULT_MAX_PROPLIMIT );
+        MAX_PROPKEYLENGTH = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXKEYLENGTH, DEFAULT_MAX_PROPKEYLENGTH );
+        MAX_PROPVALUELENGTH = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXVALUELENGTH, DEFAULT_MAX_PROPVALUELENGTH );
 
         log.info( "Wikipages are read from '" + m_pageDirectory + "'" );
     }
@@ -175,42 +159,31 @@ public abstract class AbstractFileProvider
         return m_pageDirectory;
     }
 
-    private static final String[] WINDOWS_DEVICE_NAMES =
-    {
+    private static final String[] WINDOWS_DEVICE_NAMES = {
         "con", "prn", "nul", "aux", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
         "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9"
     };
 
     /**
-     *  This makes sure that the queried page name
-     *  is still readable by the file system.  For example, all XML entities
+     *  This makes sure that the queried page name is still readable by the file system.  For example, all XML entities
      *  and slashes are encoded with the percent notation.
      *
      *  @param pagename The name to mangle
      *  @return The mangled name.
      */
-    protected String mangleName( String pagename )
-    {
+    protected String mangleName( String pagename ) {
         pagename = TextUtil.urlEncode( pagename, m_encoding );
-
         pagename = TextUtil.replaceString( pagename, "/", "%2F" );
 
-        //
-        //  Names which start with a dot must be escaped to prevent problems.
-        //  Since we use URL encoding, this is invisible in our unescaping.
-        //
-        if( pagename.startsWith( "." ) )
-        {
+        //  Names which start with a dot must be escaped to prevent problems. Since we use URL encoding, this is invisible in our unescaping.
+        if( pagename.startsWith( "." ) ) {
             pagename = "%2E" + pagename.substring( 1 );
         }
 
-        if( m_windowsHackNeeded )
-        {
-            String pn = pagename.toLowerCase();
-            for( int i = 0; i < WINDOWS_DEVICE_NAMES.length; i++ )
-            {
-                if( WINDOWS_DEVICE_NAMES[i].equals(pn) )
-                {
+        if( m_windowsHackNeeded ) {
+            final String pn = pagename.toLowerCase();
+            for( int i = 0; i < WINDOWS_DEVICE_NAMES.length; i++ ) {
+                if( WINDOWS_DEVICE_NAMES[i].equals(pn) ) {
                     pagename = "$$$" + pagename;
                 }
             }
@@ -225,12 +198,10 @@ public abstract class AbstractFileProvider
      *  @param filename The filename to unmangle
      *  @return The unmangled name.
      */
-    protected String unmangleName( String filename )
-    {
+    protected String unmangleName( String filename ) {
         // The exception should never happen.
-        if( m_windowsHackNeeded && filename.startsWith( "$$$") && filename.length() > 3 )
-        {
-            filename = filename.substring(3);
+        if( m_windowsHackNeeded && filename.startsWith( "$$$" ) && filename.length() > 3 ) {
+            filename = filename.substring( 3 );
         }
 
         return TextUtil.urlDecode( filename, m_encoding );
@@ -242,7 +213,7 @@ public abstract class AbstractFileProvider
      *  @param page The name of the page.
      *  @return A File to the page.  May be null.
      */
-    protected File findPage( String page )
+    protected File findPage( final String page )
     {
         return new File( m_pageDirectory, mangleName(page)+FILE_EXT );
     }
@@ -251,63 +222,47 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public boolean pageExists( String page )
-    {
-        File pagefile = findPage( page );
-
-        return pagefile.exists();
+    public boolean pageExists( final String page ) {
+        return findPage( page ).exists();
     }
 
     /**
      *  {@inheritDoc}
      */
     @Override
-    public boolean pageExists( String page, int version )
-    {
-        return pageExists (page);
+    public boolean pageExists( final String page, final int version ) {
+        return pageExists( page );
     }
 
     /**
-     *  This implementation just returns the current version, as filesystem
-     *  does not provide versioning information for now.
+     *  This implementation just returns the current version, as filesystem does not provide versioning information for now.
      *
-     *  @param page {@inheritDoc}
-     *  @param version {@inheritDoc}
-     *  @throws {@inheritDoc}
+     *  {@inheritDoc}
      */
     @Override
-    public String getPageText( String page, int version )
-        throws ProviderException
-    {
+    public String getPageText( final String page, final int version ) throws ProviderException {
         return getPageText( page );
     }
 
     /**
      *  Read the text directly from the correct file.
      */
-    private String getPageText( String page )
-    {
+    private String getPageText( final String page ) {
         String result  = null;
-
-        File pagedata = findPage( page );
-
+        final File pagedata = findPage( page );
         if( pagedata.exists() ) {
             if( pagedata.canRead() ) {
-                try( InputStream in = new FileInputStream( pagedata ) ) {
+                try( final InputStream in = new FileInputStream( pagedata ) ) {
                     result = FileUtil.readContents( in, m_encoding );
-                } catch( IOException e ) {
-                    log.error("Failed to read", e);
+                } catch( final IOException e ) {
+                    log.error( "Failed to read", e );
                 }
+            } else {
+                log.warn( "Failed to read page '" + page + "' from '" + pagedata.getAbsolutePath() + "', possibly a permissions problem" );
             }
-            else
-            {
-                log.warn("Failed to read page '"+page+"' from '"+pagedata.getAbsolutePath()+"', possibly a permissions problem");
-            }
-        }
-        else
-        {
+        } else {
             // This is okay.
-            log.info("New page '"+page+"'");
+            log.info( "New page '" + page + "'" );
         }
 
         return result;
@@ -317,12 +272,11 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public void putPageText( WikiPage page, String text ) throws ProviderException {
-        File file = findPage( page.getName() );
-
-        try( PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( file ), m_encoding ) ) ) {
+    public void putPageText( final WikiPage page, final String text ) throws ProviderException {
+        final File file = findPage( page.getName() );
+        try( final PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( file ), m_encoding ) ) ) {
             out.print( text );
-        } catch( IOException e ) {
+        } catch( final IOException e ) {
             log.error( "Saving failed", e );
         }
     }
@@ -331,35 +285,26 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public Collection< WikiPage > getAllPages()
-        throws ProviderException
-    {
+    public Collection< WikiPage > getAllPages()  throws ProviderException {
         log.debug("Getting all pages...");
+        final ArrayList< WikiPage > set = new ArrayList<>();
+        final File wikipagedir = new File( m_pageDirectory );
+        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
 
-        ArrayList<WikiPage> set = new ArrayList<>();
-
-        File wikipagedir = new File( m_pageDirectory );
-
-        File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
-
-        if( wikipages == null )
-        {
+        if( wikipages == null ) {
             log.error("Wikipages directory '" + m_pageDirectory + "' does not exist! Please check " + PROP_PAGEDIR + " in jspwiki.properties.");
-            throw new InternalWikiException("Page directory does not exist");
+            throw new InternalWikiException( "Page directory does not exist" );
         }
 
-        for( int i = 0; i < wikipages.length; i++ )
-        {
-            String wikiname = wikipages[i].getName();
-            int cutpoint = wikiname.lastIndexOf( FILE_EXT );
+        for( final File wikipage : wikipages ) {
+            final String wikiname = wikipage.getName();
+            final int cutpoint = wikiname.lastIndexOf( FILE_EXT );
 
-            WikiPage page = getPageInfo( unmangleName(wikiname.substring(0,cutpoint)),
-                                         WikiPageProvider.LATEST_VERSION );
-            if( page == null )
-            {
+            final WikiPage page = getPageInfo( unmangleName( wikiname.substring( 0, cutpoint ) ), WikiPageProvider.LATEST_VERSION );
+            if( page == null ) {
                 // This should not really happen.
                 // FIXME: Should we throw an exception here?
-                log.error("Page "+wikiname+" was found in directory listing, but could not be located individually.");
+                log.error( "Page " + wikiname + " was found in directory listing, but could not be located individually." );
                 continue;
             }
 
@@ -376,7 +321,7 @@ public abstract class AbstractFileProvider
      *  @return {@inheritDoc}
      */
     @Override
-    public Collection< WikiPage > getAllChangedSince( Date date )
+    public Collection< WikiPage > getAllChangedSince( final Date date )
     {
         return new ArrayList<>(); // FIXME
     }
@@ -385,49 +330,38 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public int getPageCount()
-    {
-        File wikipagedir = new File( m_pageDirectory );
-
-        File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
-
-        return wikipages.length;
+    public int getPageCount() {
+        final File wikipagedir = new File( m_pageDirectory );
+        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
+        return wikipages != null ? wikipages.length : 0;
     }
 
     /**
-     * Iterates through all WikiPages, matches them against the given query,
-     * and returns a Collection of SearchResult objects.
+     * Iterates through all WikiPages, matches them against the given query, and returns a Collection of SearchResult objects.
      *
-     * @param query {@inheritDoc}
-     * @return {@inheritDoc}
+     * {@inheritDoc}
      */
     @Override
-    public Collection< SearchResult > findPages( QueryItem[] query )
-    {
-        File wikipagedir = new File( m_pageDirectory );
-        TreeSet<SearchResult> res = new TreeSet<>( new SearchResultComparator() );
-        SearchMatcher matcher = new SearchMatcher( m_engine, query );
-
-        File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
-
-        for( int i = 0; i < wikipages.length; i++ )
-        {
-            // log.debug("Searching page "+wikipages[i].getPath() );
-
-            String filename = wikipages[i].getName();
-            int cutpoint    = filename.lastIndexOf( FILE_EXT );
-            String wikiname = filename.substring( 0, cutpoint );
-
-            wikiname = unmangleName( wikiname );
-
-            try( FileInputStream input = new FileInputStream( wikipages[i] ) ) {
-                String pagetext = FileUtil.readContents( input, m_encoding );
-                SearchResult comparison = matcher.matchPageContent( wikiname, pagetext );
-                if( comparison != null ) {
-                    res.add( comparison );
+    public Collection< SearchResult > findPages( final QueryItem[] query ) {
+        final File wikipagedir = new File( m_pageDirectory );
+        final TreeSet< SearchResult > res = new TreeSet<>( new SearchResultComparator() );
+        final SearchMatcher matcher = new SearchMatcher( m_engine, query );
+        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
+
+        if( wikipages != null ) {
+            for( final File wikipage : wikipages ) {
+                final String filename = wikipage.getName();
+                final int cutpoint = filename.lastIndexOf( FILE_EXT );
+                final String wikiname = unmangleName( filename.substring( 0, cutpoint ) );
+                try( final FileInputStream input = new FileInputStream( wikipage ) ) {
+                    final String pagetext = FileUtil.readContents( input, m_encoding );
+                    final SearchResult comparison = matcher.matchPageContent( wikiname, pagetext );
+                    if( comparison != null ) {
+                        res.add( comparison );
+                    }
+                } catch( final IOException e ) {
+                    log.error( "Failed to read " + filename, e );
                 }
-            } catch( IOException e ) {
-                log.error( "Failed to read " + filename, e );
             }
         }
 
@@ -438,22 +372,17 @@ public abstract class AbstractFileProvider
      *  Always returns the latest version, since FileSystemProvider
      *  does not support versioning.
      *
-     *  @param page {@inheritDoc}
-     *  @param version {@inheritDoc}
-     *  @return {@inheritDoc}
-     *  @throws {@inheritDoc}
+     *  {@inheritDoc}
      */
     @Override
-    public WikiPage getPageInfo( String page, int version ) throws ProviderException {
-        File file = findPage( page );
-
-        if( !file.exists() )
-        {
+    public WikiPage getPageInfo( final String page, final int version ) throws ProviderException {
+        final File file = findPage( page );
+        if( !file.exists() ) {
             return null;
         }
 
-        WikiPage p = new WikiPage( m_engine, page );
-        p.setLastModified( new Date(file.lastModified()) );
+        final WikiPage p = new WikiPage( m_engine, page );
+        p.setLastModified( new Date( file.lastModified() ) );
 
         return p;
     }
@@ -461,15 +390,11 @@ public abstract class AbstractFileProvider
     /**
      *  The FileSystemProvider provides only one version.
      *
-     *  @param page {@inheritDoc}
-     *  @throws {@inheritDoc}
-     *  @return {@inheritDoc}
+     *  {@inheritDoc}
      */
     @Override
-    public List<WikiPage> getVersionHistory( String page ) throws ProviderException
-    {
-        ArrayList<WikiPage> list = new ArrayList<>();
-
+    public List< WikiPage > getVersionHistory( final String page ) throws ProviderException {
+        final ArrayList< WikiPage > list = new ArrayList<>();
         list.add( getPageInfo( page, WikiPageProvider.LATEST_VERSION ) );
 
         return list;
@@ -488,13 +413,9 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public void deleteVersion( String pageName, int version )
-        throws ProviderException
-    {
-        if( version == WikiProvider.LATEST_VERSION )
-        {
-            File f = findPage( pageName );
-
+    public void deleteVersion( final String pageName, final int version ) throws ProviderException {
+        if( version == WikiProvider.LATEST_VERSION ) {
+            final File f = findPage( pageName );
             f.delete();
         }
     }
@@ -503,11 +424,8 @@ public abstract class AbstractFileProvider
      *  {@inheritDoc}
      */
     @Override
-    public void deletePage( String pageName )
-        throws ProviderException
-    {
-        File f = findPage( pageName );
-
+    public void deletePage( final String pageName ) throws ProviderException {
+        final File f = findPage( pageName );
         f.delete();
     }
 
@@ -516,13 +434,13 @@ public abstract class AbstractFileProvider
      *
      * @since 2.10.2
      */
-    protected void setCustomProperties(WikiPage page, Properties properties) {
-        Enumeration< ? > propertyNames = properties.propertyNames();
-    	while (propertyNames.hasMoreElements()) {
-    		String key = (String) propertyNames.nextElement();
-    		if (!key.equals(WikiPage.AUTHOR) && !key.equals(WikiPage.CHANGENOTE) && !key.equals(WikiPage.VIEWCOUNT)) {
-    			page.setAttribute(key, properties.get(key));
-    		}
+    protected void setCustomProperties( final WikiPage page, final Properties properties ) {
+        final Enumeration< ? > propertyNames = properties.propertyNames();
+    	while( propertyNames.hasMoreElements() ) {
+            final String key = ( String )propertyNames.nextElement();
+            if( !key.equals( WikiPage.AUTHOR ) && !key.equals( WikiPage.CHANGENOTE ) && !key.equals( WikiPage.VIEWCOUNT ) ) {
+                page.setAttribute( key, properties.get( key ) );
+            }
     	}
     }
 
@@ -532,10 +450,10 @@ public abstract class AbstractFileProvider
      *
      * @since 2.10.2
      */
-    protected void getCustomProperties(WikiPage page, Properties defaultProperties) throws IOException {
-        Properties customPageProperties = addCustomProperties(page,defaultProperties);
-    	validateCustomPageProperties(customPageProperties);
-    	defaultProperties.putAll(customPageProperties);
+    protected void getCustomProperties( final WikiPage page, final Properties defaultProperties ) throws IOException {
+        final Properties customPageProperties = addCustomProperties( page, defaultProperties );
+        validateCustomPageProperties( customPageProperties );
+        defaultProperties.putAll( customPageProperties );
     }
 
     /**
@@ -548,19 +466,19 @@ public abstract class AbstractFileProvider
      * @param props the default properties of this page
      * @return default implementation returns empty Properties.
      */
-    protected Properties addCustomProperties(WikiPage page, Properties props) {
-    	Properties customProperties = new Properties();
-    	if (page != null) {
-    		Map<String,Object> atts = page.getAttributes();
-    		for (String key : atts.keySet()) {
-    			Object value = atts.get(key);
-    			if (key.startsWith("@") && value != null) {
-    				customProperties.put(key,value.toString());
-    			}
-    		}
+    protected Properties addCustomProperties( final WikiPage page, final Properties props ) {
+        final Properties customProperties = new Properties();
+        if( page != null ) {
+            final Map< String, Object > atts = page.getAttributes();
+            for( final String key : atts.keySet() ) {
+                final Object value = atts.get( key );
+                if( key.startsWith( "@" ) && value != null ) {
+                    customProperties.put( key, value.toString() );
+                }
+            }
 
-    	}
-    	return customProperties;
+        }
+        return customProperties;
     }
 
     /**
@@ -570,34 +488,34 @@ public abstract class AbstractFileProvider
      * @since 2.10.2
      * @param customProperties the custom page properties being added
      */
-    protected void validateCustomPageProperties(Properties customProperties) throws IOException {
+    protected void validateCustomPageProperties( final Properties customProperties ) throws IOException {
     	// Default validation rules
-    	if (customProperties != null && !customProperties.isEmpty()) {
-    		if (customProperties.size()>MAX_PROPLIMIT) {
-    			throw new IOException("Too many custom properties. You are adding "+customProperties.size()+", but max limit is "+MAX_PROPLIMIT);
-    		}
-            Enumeration< ? > propertyNames = customProperties.propertyNames();
-        	while (propertyNames.hasMoreElements()) {
-        		String key = (String) propertyNames.nextElement();
-        		String value = (String)customProperties.get(key);
-    			if (key != null) {
-    				if (key.length()>MAX_PROPKEYLENGTH) {
-    					throw new IOException("Custom property key "+key+" is too long. Max allowed length is "+MAX_PROPKEYLENGTH);
-    				}
-    				if (!StringUtils.isAsciiPrintable(key)) {
-    					throw new IOException("Custom property key "+key+" is not simple ASCII!");
-    				}
-    			}
-    			if (value != null) {
-    				if (value.length()>MAX_PROPVALUELENGTH) {
-						throw new IOException("Custom property key "+key+" has value that is too long. Value="+value+". Max allowed length is "+MAX_PROPVALUELENGTH);
-					}
-    				if (!StringUtils.isAsciiPrintable(value)) {
-    					throw new IOException("Custom property key "+key+" has value that is not simple ASCII! Value="+value);
-    				}
-    			}
-        	}
-    	}
+        if( customProperties != null && !customProperties.isEmpty() ) {
+            if( customProperties.size() > MAX_PROPLIMIT ) {
+                throw new IOException( "Too many custom properties. You are adding " + customProperties.size() + ", but max limit is " + MAX_PROPLIMIT );
+            }
+            final Enumeration< ? > propertyNames = customProperties.propertyNames();
+            while( propertyNames.hasMoreElements() ) {
+                final String key = ( String )propertyNames.nextElement();
+                final String value = ( String )customProperties.get( key );
+                if( key != null ) {
+                    if( key.length() > MAX_PROPKEYLENGTH ) {
+                        throw new IOException( "Custom property key " + key + " is too long. Max allowed length is " + MAX_PROPKEYLENGTH );
+                    }
+                    if( !StringUtils.isAsciiPrintable( key ) ) {
+                        throw new IOException( "Custom property key " + key + " is not simple ASCII!" );
+                    }
+                }
+                if( value != null ) {
+                    if( value.length() > MAX_PROPVALUELENGTH ) {
+                        throw new IOException( "Custom property key " + key + " has value that is too long. Value=" + value + ". Max allowed length is " + MAX_PROPVALUELENGTH );
+                    }
+                    if( !StringUtils.isAsciiPrintable( value ) ) {
+                        throw new IOException( "Custom property key " + key + " has value that is not simple ASCII! Value=" + value );
+                    }
+                }
+            }
+        }
     }
 
     /**
@@ -609,7 +527,7 @@ public abstract class AbstractFileProvider
          *  {@inheritDoc}
          */
         @Override
-        public boolean accept( File dir, String name ) {
+        public boolean accept( final File dir, final String name ) {
             return name.endsWith( FILE_EXT );
         }
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/BasicAttachmentProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/BasicAttachmentProvider.java
index 5f6d67c..7d9e8f1 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/BasicAttachmentProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/BasicAttachmentProvider.java
@@ -19,9 +19,9 @@
 package org.apache.wiki.providers;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
@@ -40,9 +40,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 import java.util.regex.Matcher;
@@ -78,11 +76,10 @@ import java.util.regex.Pattern;
  *   <LI>1.author = author name for version 1 (etc)
  *  </UL>
  */
-public class BasicAttachmentProvider
-    implements WikiAttachmentProvider
-{
-    private WikiEngine         m_engine;
-    private String             m_storageDir;
+public class BasicAttachmentProvider implements WikiAttachmentProvider {
+
+    private Engine m_engine;
+    private String m_storageDir;
     
     /** The property name for where the attachments should be stored.  Value is <tt>{@value}</tt>. */
     public static final String PROP_STORAGEDIR = "jspwiki.basicAttachmentProvider.storageDir";
@@ -91,61 +88,54 @@ public class BasicAttachmentProvider
      * Disable client cache for files with patterns
      * since 2.5.96
      */
-    private Pattern            m_disableCache = null;
+    private Pattern m_disableCache = null;
     
     /** The property name for specifying which attachments are not cached.  Value is <tt>{@value}</tt>. */
     public static final String PROP_DISABLECACHE = "jspwiki.basicAttachmentProvider.disableCache";
 
     /** The name of the property file. */
-    public static final String PROPERTY_FILE   = "attachment.properties";
+    public static final String PROPERTY_FILE = "attachment.properties";
 
     /** The default extension for the page attachment directory name. */
-    public static final String DIR_EXTENSION   = "-att";
+    public static final String DIR_EXTENSION = "-att";
     
     /** The default extension for the attachment directory. */
     public static final String ATTDIR_EXTENSION = "-dir";
     
-    static final Logger log = Logger.getLogger( BasicAttachmentProvider.class );
+    private static final Logger log = Logger.getLogger( BasicAttachmentProvider.class );
 
     /**
      *  {@inheritDoc}
      */
     @Override
-    public void initialize( WikiEngine engine, Properties properties ) 
-        throws NoRequiredPropertyException,
-               IOException
-    {
+    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         m_engine = engine;
-        m_storageDir = TextUtil.getCanonicalFilePathProperty(properties, PROP_STORAGEDIR,
-                System.getProperty("user.home") + File.separator + "jspwiki-files");
+        m_storageDir = TextUtil.getCanonicalFilePathProperty( properties, PROP_STORAGEDIR,
+                                                       System.getProperty("user.home") + File.separator + "jspwiki-files");
 
-        String patternString = engine.getWikiProperties().getProperty( PROP_DISABLECACHE );
-        if ( patternString != null )
-        {
+        final String patternString = engine.getWikiProperties().getProperty( PROP_DISABLECACHE );
+        if ( patternString != null ) {
             m_disableCache = Pattern.compile(patternString);
         }
 
-        //
         //  Check if the directory exists - if it doesn't, create it.
-        //
-        File f = new File( m_storageDir );
-
-        if( !f.exists() )
-        {
+        final File f = new File( m_storageDir );
+        if( !f.exists() ) {
             f.mkdirs();
         }
 
-        //
         // Some sanity checks
-        //
-        if( !f.exists() ) 
-            throw new IOException("Could not find or create attachment storage directory '"+m_storageDir+"'");
+        if( !f.exists() ) {
+            throw new IOException( "Could not find or create attachment storage directory '" + m_storageDir + "'" );
+        }
 
-        if( !f.canWrite() ) 
-            throw new IOException("Cannot write to the attachment storage directory '"+m_storageDir+"'");
-        
-        if( !f.isDirectory() )
-            throw new IOException("Your attachment storage points to a file, not a directory: '"+m_storageDir+"'");
+        if( !f.canWrite() ) {
+            throw new IOException( "Cannot write to the attachment storage directory '" + m_storageDir + "'" );
+        }
+
+        if( !f.isDirectory() ) {
+            throw new IOException( "Your attachment storage points to a file, not a directory: '" + m_storageDir + "'" );
+        }
     }
 
     /**
@@ -153,29 +143,23 @@ public class BasicAttachmentProvider
      *
      *  @param wikipage Page to which this attachment is attached.
      */
-    private File findPageDir( String wikipage )
-        throws ProviderException
-    {
+    private File findPageDir( String wikipage ) throws ProviderException {
         wikipage = mangleName( wikipage );
 
-        File f = new File( m_storageDir, wikipage+DIR_EXTENSION );
+        final File f = new File( m_storageDir, wikipage + DIR_EXTENSION );
 
-        if( f.exists() && !f.isDirectory() )
-        {
-            throw new ProviderException("Storage dir '"+f.getAbsolutePath()+"' is not a directory!");
+        if( f.exists() && !f.isDirectory() ) {
+            throw new ProviderException( "Storage dir '" + f.getAbsolutePath() + "' is not a directory!" );
         }
 
         return f;
     }
 
-    private static String mangleName( String wikiname )
-    {
-        String res = TextUtil.urlEncodeUTF8( wikiname );
-
-        return res;
+    private static String mangleName( final String wikiname ) {
+        return TextUtil.urlEncodeUTF8( wikiname );
     }
 
-    private static String unmangleName( String filename )
+    private static String unmangleName( final String filename )
     {
         return TextUtil.urlDecodeUTF8( filename );
     }
@@ -183,33 +167,18 @@ public class BasicAttachmentProvider
     /**
      *  Finds the dir in which the attachment lives.
      */
-    private File findAttachmentDir( Attachment att )
-        throws ProviderException
-    {
-        File f = new File( findPageDir(att.getParentName()), 
-                           mangleName(att.getFileName()+ATTDIR_EXTENSION) );
-
-        //
-        //  Migration code for earlier versions of JSPWiki.
-        //  Originally, we used plain filename.  Then we realized we need
-        //  to urlencode it.  Then we realized that we have to use a
-        //  postfix to make sure illegal file names are never formed.
-        //
-        if( !f.exists() )
-        {
-            File oldf = new File( findPageDir( att.getParentName() ),
-                                  mangleName( att.getFileName() ) );
-            if( oldf.exists() )
-            {
+    private File findAttachmentDir( final Attachment att ) throws ProviderException {
+        File f = new File( findPageDir( att.getParentName() ), mangleName( att.getFileName() + ATTDIR_EXTENSION ) );
+
+        //  Migration code for earlier versions of JSPWiki. Originally, we used plain filename.  Then we realized we need
+        //  to urlencode it.  Then we realized that we have to use a postfix to make sure illegal file names are never formed.
+        if( !f.exists() ) {
+            File oldf = new File( findPageDir( att.getParentName() ), mangleName( att.getFileName() ) );
+            if( oldf.exists() ) {
                 f = oldf;
-            }
-            else
-            {
-                oldf = new File( findPageDir( att.getParentName() ),
-                                 att.getFileName() );
-
-                if( oldf.exists() )
-                {
+            } else {
+                oldf = new File( findPageDir( att.getParentName() ), att.getFileName() );
+                if( oldf.exists() ) {
                     f = oldf;
                 }
             }
@@ -225,39 +194,31 @@ public class BasicAttachmentProvider
      *  @return Latest version number in the repository, or 0, if
      *          there is no page in the repository.
      */
-    private int findLatestVersion( Attachment att )
-        throws ProviderException
-    {
-        // File pageDir = findPageDir( att.getName() );
-        File attDir  = findAttachmentDir( att );
+    private int findLatestVersion( final Attachment att ) throws ProviderException {
+        final File attDir  = findAttachmentDir( att );
 
         // log.debug("Finding pages in "+attDir.getAbsolutePath());
-        String[] pages = attDir.list( new AttachmentVersionFilter() );
+        final String[] pages = attDir.list( new AttachmentVersionFilter() );
 
-        if( pages == null )
-        {
+        if( pages == null ) {
             return 0; // No such thing found.
         }
 
         int version = 0;
-
-        for( int i = 0; i < pages.length; i++ )
-        {
+        for( int i = 0; i < pages.length; i++ ) {
             // log.debug("Checking: "+pages[i]);
-            int cutpoint = pages[i].indexOf( '.' );
-                String pageNum = ( cutpoint > 0 ) ? pages[i].substring( 0, cutpoint ) : pages[i] ;
+            final int cutpoint = pages[ i ].indexOf( '.' );
+            final String pageNum = ( cutpoint > 0 ) ? pages[ i ].substring( 0, cutpoint ) : pages[ i ];
 
-                try
-                {
-                    int res = Integer.parseInt( pageNum );
+            try {
+                final int res = Integer.parseInt( pageNum );
 
-                    if( res > version )
-                    {
-                        version = res;
-                    }
+                if( res > version ) {
+                    version = res;
                 }
-                catch( NumberFormatException e ) {} // It's okay to skip these.
-            }
+            } catch( final NumberFormatException e ) {
+            } // It's okay to skip these.
+        }
 
         return version;
     }
@@ -270,13 +231,11 @@ public class BasicAttachmentProvider
      *  @param filename The file name to check
      *  @return The extension.  If no extension is found, returns "bin".
      */
-    protected static String getFileExtension( String filename )
-    {
+    protected static String getFileExtension( final String filename ) {
         String fileExt = "bin";
 
-        int dot = filename.lastIndexOf('.');
-        if( dot >= 0 && dot < filename.length()-1 )
-        {
+        final int dot = filename.lastIndexOf('.');
+        if( dot >= 0 && dot < filename.length()-1 ) {
             fileExt = mangleName( filename.substring( dot+1 ) );
         }
 
@@ -290,7 +249,7 @@ public class BasicAttachmentProvider
     private void putPageProperties( final Attachment att, final Properties properties ) throws IOException, ProviderException {
         final File attDir = findAttachmentDir( att );
         final File propertyFile = new File( attDir, PROPERTY_FILE );
-        try( OutputStream out = new FileOutputStream( propertyFile ) ) {
+        try( final OutputStream out = new FileOutputStream( propertyFile ) ) {
             properties.store( out, " JSPWiki page properties for " + att.getName() + ". DO NOT MODIFY!" );
         }
     }
@@ -314,45 +273,36 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public void putAttachmentData( Attachment att, InputStream data ) throws ProviderException, IOException {
-        File attDir = findAttachmentDir( att );
+    public void putAttachmentData( final Attachment att, final InputStream data ) throws ProviderException, IOException {
+        final File attDir = findAttachmentDir( att );
 
-        if(!attDir.exists())
-        {
+        if( !attDir.exists() ) {
             attDir.mkdirs();
         }
+        final int latestVersion = findLatestVersion( att );
+        final int versionNumber = latestVersion + 1;
 
-        int latestVersion = findLatestVersion( att );
-
-        // System.out.println("Latest version is "+latestVersion);
-        int versionNumber = latestVersion+1;
-
-        File newfile = new File( attDir, versionNumber + "." + getFileExtension( att.getFileName() ) );
+        final File newfile = new File( attDir, versionNumber + "." + getFileExtension( att.getFileName() ) );
         try( final OutputStream out = new FileOutputStream( newfile ) ) {
-            log.info("Uploading attachment "+att.getFileName()+" to page "+att.getParentName());
-            log.info("Saving attachment contents to "+newfile.getAbsolutePath());
-
+            log.info( "Uploading attachment " + att.getFileName() + " to page " + att.getParentName() );
+            log.info( "Saving attachment contents to " + newfile.getAbsolutePath() );
             FileUtil.copyContents( data, out );
 
-            Properties props = getPageProperties( att );
+            final Properties props = getPageProperties( att );
 
             String author = att.getAuthor();
-
-            if( author == null )
-            {
+            if( author == null ) {
                 author = "unknown"; // FIXME: Should be localized, but cannot due to missing WikiContext
             }
+            props.setProperty( versionNumber + ".author", author );
 
-            props.setProperty( versionNumber+".author", author );
-            
-            String changeNote = att.getAttribute(WikiPage.CHANGENOTE);
-            if( changeNote != null )
-            {
-                props.setProperty( versionNumber+".changenote", changeNote );
+            final String changeNote = att.getAttribute( WikiPage.CHANGENOTE );
+            if( changeNote != null ) {
+                props.setProperty( versionNumber + ".changenote", changeNote );
             }
             
             putPageProperties( att, props );
-        } catch( IOException e ) {
+        } catch( final IOException e ) {
             log.error( "Could not save attachment data: ", e );
             throw (IOException) e.fillInStackTrace();
         }
@@ -366,31 +316,24 @@ public class BasicAttachmentProvider
         return "";
     }
 
-    private File findFile( File dir, Attachment att )
-        throws FileNotFoundException,
-               ProviderException
-    {
+    private File findFile( final File dir, final Attachment att ) throws FileNotFoundException, ProviderException {
         int version = att.getVersion();
-
-        if( version == WikiProvider.LATEST_VERSION )
-        {
+        if( version == WikiProvider.LATEST_VERSION ) {
             version = findLatestVersion( att );
         }
 
-        String ext = getFileExtension( att.getFileName() );
-        File f = new File( dir, version+"."+ext );
+        final String ext = getFileExtension( att.getFileName() );
+        File f = new File( dir, version + "." + ext );
 
-        if( !f.exists() )
-        {
-            if ("bin".equals(ext))
-            {
-                File fOld = new File( dir, version+"." );
-                if (fOld.exists())
+        if( !f.exists() ) {
+            if( "bin".equals( ext ) ) {
+                final File fOld = new File( dir, version + "." );
+                if( fOld.exists() ) {
                     f = fOld;
+                }
             }
-            if( !f.exists() )
-            {
-                throw new FileNotFoundException("No such file: "+f.getAbsolutePath()+" exists.");
+            if( !f.exists() ) {
+                throw new FileNotFoundException( "No such file: " + f.getAbsolutePath() + " exists." );
             }
         }
 
@@ -401,22 +344,14 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public InputStream getAttachmentData( Attachment att )
-        throws IOException,
-               ProviderException
-    {
-        File attDir = findAttachmentDir( att );
-
-        try
-        {
-            File f = findFile( attDir, att );
-
+    public InputStream getAttachmentData( final Attachment att ) throws IOException, ProviderException {
+        final File attDir = findAttachmentDir( att );
+        try {
+            final File f = findFile( attDir, att );
             return new FileInputStream( f );
-        }
-        catch( FileNotFoundException e )
-        {
-            log.error("File not found: "+e.getMessage());
-            throw new ProviderException("No such page was found.");
+        } catch( final FileNotFoundException e ) {
+            log.error( "File not found: " + e.getMessage() );
+            throw new ProviderException( "No such page was found." );
         }
     }
 
@@ -424,68 +359,36 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public List< Attachment > listAttachments( WikiPage page )
-        throws ProviderException
-    {
-        List<Attachment> result = new ArrayList<>();
-
-        File dir = findPageDir( page.getName() );
-
-        if( dir != null )
-        {
-            String[] attachments = dir.list();
-
-            if( attachments != null )
-            {
-                //
-                //  We now have a list of all potential attachments in 
-                //  the directory.
-                //
-                for( int i = 0; i < attachments.length; i++ )
-                {
-                    File f = new File( dir, attachments[i] );
-
-                    if( f.isDirectory() )
-                    {
+    public List< Attachment > listAttachments( final WikiPage page ) throws ProviderException {
+        final List< Attachment > result = new ArrayList<>();
+        final File dir = findPageDir( page.getName() );
+        if( dir != null ) {
+            final String[] attachments = dir.list();
+            if( attachments != null ) {
+                //  We now have a list of all potential attachments in the directory.
+                for( int i = 0; i < attachments.length; i++ ) {
+                    final File f = new File( dir, attachments[i] );
+                    if( f.isDirectory() ) {
                         String attachmentName = unmangleName( attachments[i] );
 
-                        //
-                        //  Is it a new-stylea attachment directory?  If yes,
-                        //  we'll just deduce the name.  If not, however,
-                        //  we'll check if there's a suitable property file
-                        //  in the directory.
-                        //
-                        if( attachmentName.endsWith( ATTDIR_EXTENSION ) )
-                        {
-                            attachmentName = attachmentName.substring( 0, attachmentName.length()-ATTDIR_EXTENSION.length() );
-                        }
-                        else
-                        {
-                            File propFile = new File( f, PROPERTY_FILE );
-
-                            if( !propFile.exists() )
-                            {
-                                //
-                                //  This is not obviously a JSPWiki attachment,
-                                //  so let's just skip it.
-                                //
+                        //  Is it a new-stylea attachment directory?  If yes, we'll just deduce the name.  If not, however,
+                        //  we'll check if there's a suitable property file in the directory.
+                        if( attachmentName.endsWith( ATTDIR_EXTENSION ) ) {
+                            attachmentName = attachmentName.substring( 0, attachmentName.length() - ATTDIR_EXTENSION.length() );
+                        } else {
+                            final File propFile = new File( f, PROPERTY_FILE );
+                            if( !propFile.exists() ) {
+                                //  This is not obviously a JSPWiki attachment, so let's just skip it.
                                 continue;
                             }
                         }
 
-                        Attachment att = getAttachmentInfo( page, attachmentName,
-                                                            WikiProvider.LATEST_VERSION );
-
-                        //
-                        //  Sanity check - shouldn't really be happening, unless
-                        //  you mess with the repository directly.
-                        //
-                        if( att == null )
-                        {
+                        final Attachment att = getAttachmentInfo( page, attachmentName, WikiProvider.LATEST_VERSION );
+                        //  Sanity check - shouldn't really be happening, unless you mess with the repository directly.
+                        if( att == null ) {
                             throw new ProviderException("Attachment disappeared while reading information:"+
                                                         " if you did not touch the repository, there is a serious bug somewhere. "+
-                                                        "Attachment = "+attachments[i]+
-                                                        ", decoded = "+attachmentName );
+                                                        "Attachment = " + attachments[ i ] + ", decoded = " + attachmentName );
                         }
 
                         result.add( att );
@@ -501,7 +404,7 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public Collection< Attachment > findAttachments( QueryItem[] query )
+    public Collection< Attachment > findAttachments( final QueryItem[] query )
     {
         return new ArrayList<>();
     }
@@ -511,39 +414,28 @@ public class BasicAttachmentProvider
      */
     // FIXME: Very unoptimized.
     @Override
-    public List<Attachment> listAllChanged( Date timestamp )
-        throws ProviderException
-    {
-        File attDir = new File( m_storageDir );
-
-        if( !attDir.exists() )
-        {
-            throw new ProviderException("Specified attachment directory "+m_storageDir+" does not exist!");
+    public List< Attachment > listAllChanged( final Date timestamp ) throws ProviderException {
+        final File attDir = new File( m_storageDir );
+        if( !attDir.exists() ) {
+            throw new ProviderException( "Specified attachment directory " + m_storageDir + " does not exist!" );
         }
 
-        ArrayList<Attachment> list = new ArrayList<>();
+        final ArrayList< Attachment > list = new ArrayList<>();
+        final String[] pagesWithAttachments = attDir.list( new AttachmentFilter() );
 
-        String[] pagesWithAttachments = attDir.list( new AttachmentFilter() );
+        for( int i = 0; i < pagesWithAttachments.length; i++ ) {
+            String pageId = unmangleName( pagesWithAttachments[ i ] );
+            pageId = pageId.substring( 0, pageId.length() - DIR_EXTENSION.length() );
 
-        for( int i = 0; i < pagesWithAttachments.length; i++ )
-        {
-            String pageId = unmangleName( pagesWithAttachments[i] );
-            pageId = pageId.substring( 0, pageId.length()-DIR_EXTENSION.length() );
-            
-            Collection<Attachment> c = listAttachments( new WikiPage( m_engine, pageId ) );
-
-            for( Iterator<Attachment> it = c.iterator(); it.hasNext(); )
-            {
-                Attachment att = it.next();
-
-                if( att.getLastModified().after( timestamp ) )
-                {
+            final Collection< Attachment > c = listAttachments( new WikiPage( m_engine, pageId ) );
+            for( final Attachment att : c ) {
+                if( att.getLastModified().after( timestamp ) ) {
                     list.add( att );
                 }
             }
         }
 
-        Collections.sort( list, new PageTimeComparator() );
+        list.sort( new PageTimeComparator() );
 
         return list;
     }
@@ -569,7 +461,7 @@ public class BasicAttachmentProvider
         
         // Should attachment be cachable by the client (browser)?
         if (m_disableCache != null) {
-            Matcher matcher = m_disableCache.matcher(name);
+            final Matcher matcher = m_disableCache.matcher(name);
             if (matcher.matches()) {
                 att.setCacheable(false);
             }
@@ -577,21 +469,21 @@ public class BasicAttachmentProvider
 
         // System.out.println("Fetching info on version "+version);
         try {
-            Properties props = getPageProperties(att);
+            final Properties props = getPageProperties(att);
             att.setAuthor( props.getProperty( version+".author" ) );
             final String changeNote = props.getProperty( version+".changenote" );
             if( changeNote != null ) {
                 att.setAttribute(WikiPage.CHANGENOTE, changeNote);
             }
-            
-            File f = findFile( dir, att );
+
+            final File f = findFile( dir, att );
 
             att.setSize( f.length() );
             att.setLastModified( new Date(f.lastModified()) );
-        } catch( FileNotFoundException e ) {
+        } catch( final FileNotFoundException e ) {
             log.error( "Can't get attachment properties for " + att, e );
             return null;
-        } catch( IOException e ) {
+        } catch( final IOException e ) {
             log.error("Can't read page properties", e );
             throw new ProviderException("Cannot read page properties: "+e.getMessage());
         }
@@ -604,28 +496,21 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public List<Attachment> getVersionHistory( Attachment att )
-    {
-        ArrayList<Attachment> list = new ArrayList<>();
+    public List< Attachment > getVersionHistory( final Attachment att ) {
+        final ArrayList< Attachment > list = new ArrayList<>();
 
-        try
-        {
-            int latest = findLatestVersion( att );
+        try {
+            final int latest = findLatestVersion( att );
 
-            for( int i = latest; i >= 1; i-- )
-            {
-                Attachment a = getAttachmentInfo( new WikiPage( m_engine, att.getParentName() ), 
-                                                  att.getFileName(), i );
+            for( int i = latest; i >= 1; i-- ) {
+                final Attachment a = getAttachmentInfo( new WikiPage( m_engine, att.getParentName() ), att.getFileName(), i );
 
-                if( a != null )
-                {
+                if( a != null ) {
                     list.add( a );
                 }
             }
-        }
-        catch( ProviderException e )
-        {
-            log.error("Getting version history failed for page: "+att,e);
+        } catch( final ProviderException e ) {
+            log.error( "Getting version history failed for page: " + att, e );
             // FIXME: SHould this fail?
         }
 
@@ -636,9 +521,7 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public void deleteVersion( Attachment att )
-        throws ProviderException
-    {
+    public void deleteVersion( final Attachment att ) throws ProviderException {
         // FIXME: Does nothing yet.
     }
 
@@ -646,32 +529,26 @@ public class BasicAttachmentProvider
      *  {@inheritDoc}
      */
     @Override
-    public void deleteAttachment( Attachment att )
-        throws ProviderException
-    {
-        File dir = findAttachmentDir( att );
-        String[] files = dir.list();
+    public void deleteAttachment( final Attachment att ) throws ProviderException {
+        final File dir = findAttachmentDir( att );
+        final String[] files = dir.list();
 
-        for( int i = 0; i < files.length; i++ )
-        {
-            File file = new File( dir.getAbsolutePath() + "/" + files[i] );
+        for( int i = 0; i < files.length; i++ ) {
+            final File file = new File( dir.getAbsolutePath() + "/" + files[ i ] );
             file.delete();
         }
         dir.delete();
     }
 
-
     /**
      *  Returns only those directories that contain attachments.
      */
-    public static class AttachmentFilter
-        implements FilenameFilter
-    {
+    public static class AttachmentFilter implements FilenameFilter {
         /**
          *  {@inheritDoc}
          */
         @Override
-        public boolean accept( File dir, String name )
+        public boolean accept( final File dir, final String name )
         {
             return name.endsWith( DIR_EXTENSION );
         }
@@ -680,14 +557,12 @@ public class BasicAttachmentProvider
     /**
      *  Accepts only files that are actual versions, no control files.
      */
-    public static class AttachmentVersionFilter
-        implements FilenameFilter
-    {
+    public static class AttachmentVersionFilter implements FilenameFilter {
         /**
          *  {@inheritDoc}
          */
         @Override
-        public boolean accept( File dir, String name )
+        public boolean accept( final File dir, final String name )
         {
             return !name.equals( PROPERTY_FILE );
         }
@@ -696,27 +571,21 @@ public class BasicAttachmentProvider
     /**
      *  {@inheritDoc}
      */
-
     @Override
-    public void moveAttachmentsForPage( String oldParent, String newParent )
-        throws ProviderException
-    {
-        File srcDir = findPageDir( oldParent );
-        File destDir = findPageDir( newParent );
-
-        log.debug("Trying to move all attachments from "+srcDir+" to "+destDir);
-
-        // If it exists, we're overwriting an old page (this has already been
-        // confirmed at a higher level), so delete any existing attachments.
-        if (destDir.exists())
-        {
-            log.error("Page rename failed because target dirctory "+destDir+" exists");
-        }
-        else
-        {
-            //destDir.getParentFile().mkdir();
-            srcDir.renameTo(destDir);
+    public void moveAttachmentsForPage( final String oldParent, final String newParent ) throws ProviderException {
+        final File srcDir = findPageDir( oldParent );
+        final File destDir = findPageDir( newParent );
+
+        log.debug( "Trying to move all attachments from " + srcDir + " to " + destDir );
+
+        // If it exists, we're overwriting an old page (this has already been confirmed at a higher level), so delete any existing attachments.
+        if( destDir.exists() ) {
+            log.error( "Page rename failed because target dirctory " + destDir + " exists" );
+        } else {
+            // destDir.getParentFile().mkdir();
+            srcDir.renameTo( destDir );
         }
     }
+
 }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java
index 930f8af..a7b6d3a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java
@@ -22,9 +22,9 @@ import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
@@ -54,9 +54,8 @@ import java.util.Properties;
  */
 
 //        EntryRefreshPolicy for that.
-public class CachingAttachmentProvider
-    implements WikiAttachmentProvider
-{
+public class CachingAttachmentProvider implements WikiAttachmentProvider {
+
     private static final Logger log = Logger.getLogger(CachingAttachmentProvider.class);
 
     private WikiAttachmentProvider m_provider;
@@ -97,10 +96,10 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public void initialize( WikiEngine engine, Properties properties ) throws NoRequiredPropertyException, IOException {
+    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         log.info("Initing CachingAttachmentProvider");
 
-        String attCollCacheName = engine.getApplicationName() + "." + ATTCOLLCACHE_NAME;
+        final String attCollCacheName = engine.getApplicationName() + "." + ATTCOLLCACHE_NAME;
         if (m_cacheManager.cacheExists(attCollCacheName)) {
             m_cache = m_cacheManager.getCache(attCollCacheName);
         } else {
@@ -111,7 +110,7 @@ public class CachingAttachmentProvider
         //
         // cache for the individual Attachment objects, attachment name is key, the Attachment object is the cached object
         //
-        String attCacheName = engine.getApplicationName() + "." + ATTCACHE_NAME;
+        final String attCacheName = engine.getApplicationName() + "." + ATTCACHE_NAME;
         if (m_cacheManager.cacheExists(attCacheName)) {
             m_attCache = m_cacheManager.getCache(attCacheName);
         } else {
@@ -130,24 +129,24 @@ public class CachingAttachmentProvider
 
         try
         {
-            Class<?> providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname);
+            final Class<?> providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname);
 
             m_provider = (WikiAttachmentProvider)providerclass.newInstance();
 
             log.debug("Initializing real provider class "+m_provider);
             m_provider.initialize( engine, properties );
         }
-        catch( ClassNotFoundException e )
+        catch( final ClassNotFoundException e )
         {
             log.error("Unable to locate provider class "+classname,e);
             throw new IllegalArgumentException("no provider class", e);
         }
-        catch( InstantiationException e )
+        catch( final InstantiationException e )
         {
             log.error("Unable to create provider class "+classname,e);
             throw new IllegalArgumentException("faulty provider class", e);
         }
-        catch( IllegalAccessException e )
+        catch( final IllegalAccessException e )
         {
             log.error("Illegal access to provider class "+classname,e);
             throw new IllegalArgumentException("illegal provider class", e);
@@ -159,7 +158,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public void putAttachmentData( Attachment att, InputStream data )
+    public void putAttachmentData( final Attachment att, final InputStream data )
         throws ProviderException, IOException {
         m_provider.putAttachmentData( att, data );
 
@@ -172,7 +171,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public InputStream getAttachmentData( Attachment att )
+    public InputStream getAttachmentData( final Attachment att )
         throws ProviderException, IOException {
         return m_provider.getAttachmentData( att );
     }
@@ -181,13 +180,12 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public List< Attachment > listAttachments(WikiPage page) throws ProviderException {
+    public List< Attachment > listAttachments( final WikiPage page) throws ProviderException {
         log.debug("Listing attachments for " + page);
-        Element element = m_cache.get(page.getName());
+        final Element element = m_cache.get(page.getName());
 
         if (element != null) {
-            @SuppressWarnings("unchecked") 
-            List< Attachment > c = ( List< Attachment > )element.getObjectValue();
+            @SuppressWarnings("unchecked") final List< Attachment > c = ( List< Attachment > )element.getObjectValue();
             log.debug("LIST from cache, " + page.getName() + ", size=" + c.size());
             return cloneCollection(c);
         }
@@ -197,9 +195,9 @@ public class CachingAttachmentProvider
         return refresh(page);
     }
 
-    private <T> List<T> cloneCollection( Collection<T> c )
+    private <T> List<T> cloneCollection( final Collection<T> c )
     {
-        ArrayList<T> list = new ArrayList<>();
+        final ArrayList<T> list = new ArrayList<>();
 
         list.addAll( c );
 
@@ -210,7 +208,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public Collection< Attachment > findAttachments( QueryItem[] query )
+    public Collection< Attachment > findAttachments( final QueryItem[] query )
     {
         return m_provider.findAttachments( query );
     }
@@ -219,7 +217,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public List<Attachment> listAllChanged(Date timestamp) throws ProviderException {
+    public List<Attachment> listAllChanged( final Date timestamp) throws ProviderException {
         List< Attachment > all = null;
         //
         // we do a one-time build up of the cache, after this the cache is updated for every attachment add/delete
@@ -229,19 +227,18 @@ public class CachingAttachmentProvider
             // Put all pages in the cache :
 
             synchronized (this) {
-                for (Iterator< Attachment > i = all.iterator(); i.hasNext(); ) {
-                    Attachment att = i.next();
+                for ( final Iterator< Attachment > i = all.iterator(); i.hasNext(); ) {
+                    final Attachment att = i.next();
                     m_attCache.put(new Element(att.getName(), att));
                 }
                 m_gotall = true;
             }
         } else {
-            @SuppressWarnings("unchecked")
-            List< String > keys = m_attCache.getKeysWithExpiryCheck();
+            @SuppressWarnings("unchecked") final List< String > keys = m_attCache.getKeysWithExpiryCheck();
             all = new ArrayList<>();
-            for (String key : keys) {
-                Element element = m_attCache.get(key);
-                Attachment cachedAttachment = ( Attachment )element.getObjectValue();
+            for ( final String key : keys) {
+                final Element element = m_attCache.get(key);
+                final Attachment cachedAttachment = ( Attachment )element.getObjectValue();
                 if (cachedAttachment != null) {
                     all.add(cachedAttachment);
                 }
@@ -257,8 +254,8 @@ public class CachingAttachmentProvider
      *
      *  @return null, if no such attachment was in this collection.
      */
-    private Attachment findAttachmentFromCollection( Collection< Attachment > c, String name ) {
-        for( Attachment att : new ArrayList< >( c ) ) {
+    private Attachment findAttachmentFromCollection( final Collection< Attachment > c, final String name ) {
+        for( final Attachment att : new ArrayList< >( c ) ) {
             if( name.equals( att.getFileName() ) ) {
                 return att;
             }
@@ -272,9 +269,9 @@ public class CachingAttachmentProvider
      *
      *  @return The newly fetched object from the provider.
      */
-    private List<Attachment> refresh( WikiPage page ) throws ProviderException
+    private List<Attachment> refresh( final WikiPage page ) throws ProviderException
     {
-        List<Attachment> c = m_provider.listAttachments( page );
+        final List<Attachment> c = m_provider.listAttachments( page );
         m_cache.put(new Element(page.getName(), c));
 
         return c;
@@ -285,7 +282,7 @@ public class CachingAttachmentProvider
      */
     @SuppressWarnings("unchecked")
     @Override
-    public Attachment getAttachmentInfo(WikiPage page, String name, int version) throws ProviderException {
+    public Attachment getAttachmentInfo( final WikiPage page, final String name, final int version) throws ProviderException {
         if (log.isDebugEnabled()) {
             log.debug("Getting attachments for " + page + ", name=" + name + ", version=" + version);
         }
@@ -299,7 +296,7 @@ public class CachingAttachmentProvider
         }
 
         Collection<Attachment> c = null;
-        Element element =   m_cache.get(page.getName());
+        final Element element =   m_cache.get(page.getName());
 
         if (element == null) {
             log.debug(page.getName() + " wasn't in the cache");
@@ -320,7 +317,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public List<Attachment> getVersionHistory( Attachment att )
+    public List<Attachment> getVersionHistory( final Attachment att )
     {
         return m_provider.getVersionHistory( att );
     }
@@ -329,7 +326,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public void deleteVersion( Attachment att ) throws ProviderException
+    public void deleteVersion( final Attachment att ) throws ProviderException
     {
         // This isn't strictly speaking correct, but it does not really matter
         m_cache.remove(att.getParentName());
@@ -340,7 +337,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public void deleteAttachment( Attachment att ) throws ProviderException
+    public void deleteAttachment( final Attachment att ) throws ProviderException
     {
         m_cache.remove(att.getParentName());
         m_attCache.remove(att.getName());
@@ -375,7 +372,7 @@ public class CachingAttachmentProvider
      * {@inheritDoc}
      */
     @Override
-    public void moveAttachmentsForPage( String oldParent, String newParent ) throws ProviderException
+    public void moveAttachmentsForPage( final String oldParent, final String newParent ) throws ProviderException
     {
         m_provider.moveAttachmentsForPage(oldParent, newParent);
         m_cache.remove(newParent);
@@ -385,11 +382,10 @@ public class CachingAttachmentProvider
         //  This is a kludge to make sure that the pages are removed
         //  from the other cache as well.
         //
-        String checkName = oldParent + "/";
+        final String checkName = oldParent + "/";
 
-        @SuppressWarnings("unchecked")
-        List< String > names = m_cache.getKeysWithExpiryCheck();
-        for( String name : names )
+        @SuppressWarnings("unchecked") final List< String > names = m_cache.getKeysWithExpiryCheck();
+        for( final String name : names )
         {
             if( name.startsWith( checkName ) )
             {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java
index 234d74b..d4088db 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java
@@ -23,8 +23,8 @@ import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.pages.PageManager;
@@ -72,7 +72,7 @@ public class CachingProvider implements WikiPageProvider {
 
     private WikiPageProvider m_provider;
     // FIXME: Find another way to the search engine to use instead of from WikiEngine?
-    private WikiEngine       m_engine;
+    private Engine m_engine;
 
     private Cache m_cache;
     /** Name of the regular page cache. */
@@ -106,7 +106,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void initialize( final WikiEngine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
+    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         log.debug("Initing CachingProvider");
 
         // engine is used for getting the search engine
@@ -121,7 +121,7 @@ public class CachingProvider implements WikiPageProvider {
             m_cacheManager.addCache(m_cache);
         }
 
-        String textCacheName = engine.getApplicationName() + "." + TEXTCACHE_NAME;
+        final String textCacheName = engine.getApplicationName() + "." + TEXTCACHE_NAME;
         if (m_cacheManager.cacheExists(textCacheName)) {
             m_textCache= m_cacheManager.getCache(textCacheName);
         } else {
@@ -130,7 +130,7 @@ public class CachingProvider implements WikiPageProvider {
             m_cacheManager.addCache(m_textCache);
         }
 
-        String historyCacheName = engine.getApplicationName() + "." + HISTORYCACHE_NAME;
+        final String historyCacheName = engine.getApplicationName() + "." + HISTORYCACHE_NAME;
         if (m_cacheManager.cacheExists(historyCacheName)) {
             m_historyCache= m_cacheManager.getCache(historyCacheName);
         } else {
@@ -152,40 +152,33 @@ public class CachingProvider implements WikiPageProvider {
             throw new NoRequiredPropertyException( e.getMessage(), PageManager.PROP_PAGEPROVIDER );
         }
 
-        try
-        {
-            Class< ? > providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname);
+        try {
+            final Class< ? > providerclass = ClassUtil.findClass( "org.apache.wiki.providers", classname );
 
-            m_provider = (WikiPageProvider)providerclass.newInstance();
+            m_provider = ( WikiPageProvider )providerclass.newInstance();
 
-            log.debug("Initializing real provider class "+m_provider);
+            log.debug( "Initializing real provider class " + m_provider );
             m_provider.initialize( engine, properties );
-        }
-        catch( ClassNotFoundException e )
-        {
-            log.error("Unable to locate provider class "+classname,e);
-            throw new IllegalArgumentException("no provider class", e);
-        }
-        catch( InstantiationException e )
-        {
-            log.error("Unable to create provider class "+classname,e);
-            throw new IllegalArgumentException("faulty provider class", e);
-        }
-        catch( IllegalAccessException e )
-        {
-            log.error("Illegal access to provider class "+classname,e);
-            throw new IllegalArgumentException("illegal provider class", e);
+        } catch( final ClassNotFoundException e ) {
+            log.error( "Unable to locate provider class " + classname, e );
+            throw new IllegalArgumentException( "no provider class", e );
+        } catch( final InstantiationException e ) {
+            log.error( "Unable to create provider class " + classname, e );
+            throw new IllegalArgumentException( "faulty provider class", e );
+        } catch( final IllegalAccessException e ) {
+            log.error( "Illegal access to provider class " + classname, e );
+            throw new IllegalArgumentException( "illegal provider class", e );
         }
     }
 
 
-    private WikiPage getPageInfoFromCache(String name) throws ProviderException {
+    private WikiPage getPageInfoFromCache( final String name) throws ProviderException {
         // Sanity check; seems to occur sometimes
         if (name == null) return null;
 
-        Element cacheElement = m_cache.get(name);
+        final Element cacheElement = m_cache.get(name);
         if (cacheElement == null) {
-            WikiPage refreshed = m_provider.getPageInfo(name, WikiPageProvider.LATEST_VERSION);
+            final WikiPage refreshed = m_provider.getPageInfo(name, WikiPageProvider.LATEST_VERSION);
             if (refreshed != null) {
                 m_cache.put(new Element(name, refreshed));
                 return refreshed;
@@ -202,7 +195,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public boolean pageExists( String pageName, int version )
+    public boolean pageExists( final String pageName, final int version )
     {
         if( pageName == null ) return false;
 
@@ -212,7 +205,7 @@ public class CachingProvider implements WikiPageProvider {
         {
             p = getPageInfoFromCache( pageName );
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             log.info("Provider failed while trying to check if page exists: "+pageName);
             return false;
@@ -220,7 +213,7 @@ public class CachingProvider implements WikiPageProvider {
 
         if( p != null )
         {
-            int latestVersion = p.getVersion();
+            final int latestVersion = p.getVersion();
 
             if( version == latestVersion || version == LATEST_VERSION )
             {
@@ -234,7 +227,7 @@ public class CachingProvider implements WikiPageProvider {
         {
             return getPageInfo( pageName, version ) != null;
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {}
 
         return false;
@@ -244,7 +237,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public boolean pageExists( String pageName )
+    public boolean pageExists( final String pageName )
     {
         if( pageName == null ) return false;
 
@@ -254,7 +247,7 @@ public class CachingProvider implements WikiPageProvider {
         {
             p = getPageInfoFromCache( pageName );
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             log.info("Provider failed while trying to check if page exists: "+pageName);
             return false;
@@ -295,7 +288,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public String getPageText( String pageName, int version )
+    public String getPageText( final String pageName, final int version )
         throws ProviderException
     {
         String result = null;
@@ -308,7 +301,7 @@ public class CachingProvider implements WikiPageProvider {
         }
         else
         {
-            WikiPage p = getPageInfoFromCache( pageName );
+            final WikiPage p = getPageInfoFromCache( pageName );
 
             //
             //  Or is this the latest version fetched by version number?
@@ -327,12 +320,12 @@ public class CachingProvider implements WikiPageProvider {
     }
 
 
-    private String getTextFromCache(String pageName) throws ProviderException {
+    private String getTextFromCache( final String pageName) throws ProviderException {
         String text = null;
 
         if (pageName == null) return null;
 
-        Element cacheElement = m_textCache.get(pageName);
+        final Element cacheElement = m_textCache.get(pageName);
 
         if (cacheElement != null) {
             m_cacheHits++;
@@ -352,7 +345,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void putPageText(WikiPage page, String text) throws ProviderException {
+    public void putPageText( final WikiPage page, final String text) throws ProviderException {
         synchronized (this) {
             m_provider.putPageText(page, text);
 
@@ -373,7 +366,7 @@ public class CachingProvider implements WikiPageProvider {
      */
     @Override
     public Collection< WikiPage > getAllPages() throws ProviderException {
-        Collection< WikiPage > all;
+        final Collection< WikiPage > all;
 
         if (m_gotall == false) {
             all = m_provider.getAllPages();
@@ -381,8 +374,8 @@ public class CachingProvider implements WikiPageProvider {
             // Make sure that all pages are in the cache.
 
             synchronized (this) {
-                for (Iterator< WikiPage > i = all.iterator(); i.hasNext(); ) {
-                    WikiPage p = i.next();
+                for ( final Iterator< WikiPage > i = all.iterator(); i.hasNext(); ) {
+                    final WikiPage p = i.next();
 
                     m_cache.put(new Element(p.getName(), p));
                 }
@@ -390,12 +383,11 @@ public class CachingProvider implements WikiPageProvider {
                 m_gotall = true;
             }
         } else {
-            @SuppressWarnings("unchecked")
-            List< String > keys = m_cache.getKeysWithExpiryCheck();
+            @SuppressWarnings("unchecked") final List< String > keys = m_cache.getKeysWithExpiryCheck();
             all = new TreeSet<>();
-            for (String key : keys) {
-                Element element = m_cache.get(key);
-                WikiPage cachedPage = ( WikiPage )element.getObjectValue();
+            for ( final String key : keys) {
+                final Element element = m_cache.get(key);
+                final WikiPage cachedPage = ( WikiPage )element.getObjectValue();
                 if (cachedPage != null) {
                     all.add(cachedPage);
                 }
@@ -416,7 +408,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public Collection< WikiPage > getAllChangedSince( Date date )
+    public Collection< WikiPage > getAllChangedSince( final Date date )
     {
         return m_provider.getAllChangedSince( date );
     }
@@ -435,7 +427,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public Collection< SearchResult > findPages( QueryItem[] query )
+    public Collection< SearchResult > findPages( final QueryItem[] query )
     {
         //
         //  If the provider is a fast searcher, then
@@ -451,24 +443,19 @@ public class CachingProvider implements WikiPageProvider {
     //         necessary variables.
     //
 
-    private void refreshMetadata( WikiPage page )
-    {
-        if( page != null && !page.hasMetadata() )
-        {
-            RenderingManager mgr = m_engine.getRenderingManager();
+    private void refreshMetadata( final WikiPage page ) {
+        if( page != null && !page.hasMetadata() ) {
+            final RenderingManager mgr = m_engine.getManager( RenderingManager.class );
 
-            try
-            {
-                String data = m_provider.getPageText(page.getName(), page.getVersion());
+            try {
+                final String data = m_provider.getPageText( page.getName(), page.getVersion() );
 
-                WikiContext ctx = new WikiContext( m_engine, page );
-                MarkupParser parser = mgr.getParser( ctx, data );
+                final WikiContext ctx = new WikiContext( m_engine, page );
+                final MarkupParser parser = mgr.getParser( ctx, data );
 
                 parser.parse();
-            }
-            catch( Exception ex )
-            {
-                log.debug("Failed to retrieve variables for wikipage "+page);
+            } catch( final Exception ex ) {
+                log.debug( "Failed to retrieve variables for wikipage " + page );
             }
         }
     }
@@ -477,18 +464,18 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public WikiPage getPageInfo( String pageName, int version ) throws ProviderException
+    public WikiPage getPageInfo( final String pageName, final int version ) throws ProviderException
     {
         WikiPage page = null;
-        WikiPage cached = getPageInfoFromCache( pageName );
+        final WikiPage cached = getPageInfoFromCache( pageName );
 
-        int latestcached = (cached != null) ? cached.getVersion() : Integer.MIN_VALUE;
+        final int latestcached = (cached != null) ? cached.getVersion() : Integer.MIN_VALUE;
 
         if( version == WikiPageProvider.LATEST_VERSION || version == latestcached )
         {
             if( cached == null )
             {
-                WikiPage data = m_provider.getPageInfo( pageName, version );
+                final WikiPage data = m_provider.getPageInfo( pageName, version );
 
                 if( data != null )
                 {
@@ -518,11 +505,11 @@ public class CachingProvider implements WikiPageProvider {
      */
     @SuppressWarnings("unchecked")
     @Override
-    public List< WikiPage > getVersionHistory(String pageName) throws ProviderException {
+    public List< WikiPage > getVersionHistory( final String pageName) throws ProviderException {
         List< WikiPage > history = null;
 
         if (pageName == null) return null;
-        Element element = m_historyCache.get(pageName);
+        final Element element = m_historyCache.get(pageName);
 
         if (element != null) {
             m_historyCacheHits++;
@@ -555,7 +542,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void deleteVersion( String pageName, int version )
+    public void deleteVersion( final String pageName, final int version )
         throws ProviderException
     {
         //
@@ -564,9 +551,9 @@ public class CachingProvider implements WikiPageProvider {
         //
         synchronized( this )
         {
-            WikiPage cached = getPageInfoFromCache( pageName );
+            final WikiPage cached = getPageInfoFromCache( pageName );
 
-            int latestcached = (cached != null) ? cached.getVersion() : Integer.MIN_VALUE;
+            final int latestcached = (cached != null) ? cached.getVersion() : Integer.MIN_VALUE;
 
             //
             //  If we have this version cached, remove from cache.
@@ -587,7 +574,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void deletePage( String pageName )
+    public void deletePage( final String pageName )
         throws ProviderException
     {
         //
@@ -606,7 +593,7 @@ public class CachingProvider implements WikiPageProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void movePage(String from, String to) throws ProviderException {
+    public void movePage( final String from, final String to) throws ProviderException {
         m_provider.movePage(from, to);
 
         synchronized (this) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/FileSystemProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/FileSystemProvider.java
index c8c7e3b..802beab 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/FileSystemProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/FileSystemProvider.java
@@ -38,28 +38,22 @@ import java.util.Properties;
  *  on the files contents based on its name.
  *
  */
-public class FileSystemProvider
-    extends AbstractFileProvider
-{
-    private static final Logger   log = Logger.getLogger(FileSystemProvider.class);
-    /**
-     *  All metadata is stored in a file with this extension.
-     */
+public class FileSystemProvider extends AbstractFileProvider {
+
+    private static final Logger log = Logger.getLogger( FileSystemProvider.class );
+
+    /** All metadata is stored in a file with this extension. */
     public static final String PROP_EXT = ".properties";
 
     /**
      *  {@inheritDoc}
      */
-    public void putPageText( WikiPage page, String text )        
-        throws ProviderException
-    {
-        try
-        {
+    @Override
+    public void putPageText( final WikiPage page, final String text ) throws ProviderException {
+        try {
             super.putPageText( page, text );
             putPageProperties( page );
-        }
-        catch( IOException e )
-        {
+        } catch( final IOException e ) {
             log.error( "Saving failed" );
         }
     }
@@ -67,112 +61,72 @@ public class FileSystemProvider
     /**
      *  Stores basic metadata to a file.
      */
-    private void putPageProperties( WikiPage page )        
-        throws IOException
-    {
-        Properties props = new Properties();        
-        OutputStream out = null;
-
-        try
-        {
-            String author = page.getAuthor();
-            String changenote = page.getAttribute( WikiPage.CHANGENOTE );
-            String viewcount = page.getAttribute( WikiPage.VIEWCOUNT );
-            
-            if( author != null )
-            {
-                props.setProperty( WikiPage.AUTHOR, author );
-            }
-            
-            if( changenote != null )
-            {
-                props.setProperty( WikiPage.CHANGENOTE, changenote );
-            }
+    private void putPageProperties( final WikiPage page ) throws IOException {
+        final Properties props = new Properties();
+        final String author = page.getAuthor();
+        final String changenote = page.getAttribute( WikiPage.CHANGENOTE );
+        final String viewcount = page.getAttribute( WikiPage.VIEWCOUNT );
+
+        if( author != null ) {
+            props.setProperty( WikiPage.AUTHOR, author );
+        }
 
-            if( viewcount != null )
-            {
-                props.setProperty( WikiPage.VIEWCOUNT, viewcount );
-            }
-            
-            // Get additional custom properties from page and add to props
-            getCustomProperties(page, props);
-            	
-            
-            File file = new File( getPageDirectory(), 
-                                  mangleName(page.getName())+PROP_EXT );
-     
-            out = new FileOutputStream( file );
+        if( changenote != null ) {
+            props.setProperty( WikiPage.CHANGENOTE, changenote );
+        }
 
-            props.store( out, "JSPWiki page properties for page "+page.getName() );
+        if( viewcount != null ) {
+            props.setProperty( WikiPage.VIEWCOUNT, viewcount );
         }
-        finally
-        {
-            if( out != null ) out.close();
+
+        // Get additional custom properties from page and add to props
+        getCustomProperties(page, props);
+
+        final File file = new File( getPageDirectory(), mangleName( page.getName() ) + PROP_EXT );
+        try( final OutputStream out = new FileOutputStream( file ) ) {
+            props.store( out, "JSPWiki page properties for page "+page.getName() );
         }
     }
     
     /**
      *  Gets basic metadata from file.
      */
-    private void getPageProperties( WikiPage page )
-        throws IOException
-    {
-        Properties  props = new Properties();
-        InputStream in    = null;
-
-        try
-        {
-            File file = new File( getPageDirectory(), 
-                                  mangleName(page.getName())+PROP_EXT );
-
-            if( file.exists() )
-            {
-                in = new FileInputStream( file );
-
-                props.load(in);
-
+    private void getPageProperties( final WikiPage page ) throws IOException {
+        final File file = new File( getPageDirectory(), mangleName( page.getName() ) + PROP_EXT );
+        if( file.exists() ) {
+            try( final InputStream in = new FileInputStream( file ) ) {
+                final Properties  props = new Properties();
+                props.load( in );
                 page.setAuthor( props.getProperty( WikiPage.AUTHOR ) );
-                
-                String changenote = props.getProperty( WikiPage.CHANGENOTE );
-                if( changenote != null )
-                {
+
+                final String changenote = props.getProperty( WikiPage.CHANGENOTE );
+                if( changenote != null ) {
                     page.setAttribute( WikiPage.CHANGENOTE, changenote );
                 }
-                
-                String viewcount = props.getProperty( WikiPage.VIEWCOUNT );
-                if( viewcount != null )
-                {
+
+                final String viewcount = props.getProperty( WikiPage.VIEWCOUNT );
+                if( viewcount != null ) {
                     page.setAttribute( WikiPage.VIEWCOUNT, viewcount );
                 }
-                
+
                 // Set the props values to the page attributes
-                setCustomProperties(page, props);
-            }            
-        }
-        finally
-        {
-            if( in != null ) in.close();
+                setCustomProperties( page, props );
+            }
         }
     }
 
     /**
      *  {@inheritDoc}
      */
-    public WikiPage getPageInfo( String page, int version )
-        throws ProviderException
-    {
-        WikiPage p = super.getPageInfo( page, version );
-
-        if( p != null )
-        {
-            try
-            {
+    @Override
+    public WikiPage getPageInfo( final String page, final int version ) throws ProviderException {
+        final WikiPage p = super.getPageInfo( page, version );
+        if( p != null ) {
+            try {
                 getPageProperties( p );
-            }
-            catch( IOException e )
-            {
-                log.error("Unable to read page properties", e );
-                throw new ProviderException("Unable to read page properties, check logs.");
+            } catch( final IOException e ) {
+                log.error( "Unable to read page properties", e );
+                throw new ProviderException( "Unable to read page properties, check logs." );
             }
         }
 
@@ -182,26 +136,23 @@ public class FileSystemProvider
     /**
      *  {@inheritDoc}
      */
-    public void deletePage(String pageName) throws ProviderException
-    {
-        super.deletePage(pageName);
-
-        File file = new File( getPageDirectory(), 
-                              mangleName(pageName)+PROP_EXT );
-        
-        if( file.exists() ) file.delete();
+    @Override
+    public void deletePage( final String pageName) throws ProviderException {
+        super.deletePage( pageName );
+        final File file = new File( getPageDirectory(), mangleName(pageName)+PROP_EXT );
+        if( file.exists() ) {
+            file.delete();
+        }
     }
 
     /**
      *  {@inheritDoc}
      */
-    public void movePage( String from,
-                          String to )
-        throws ProviderException
-    {
-        File fromPage = findPage( from );
-        File toPage = findPage( to );
-        
+    @Override
+    public void movePage( final String from, final String to ) throws ProviderException {
+        final File fromPage = findPage( from );
+        final File toPage = findPage( to );
         fromPage.renameTo( toPage );
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/VersioningFileProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/VersioningFileProvider.java
index 27dd7cb..5faea43 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/VersioningFileProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/VersioningFileProvider.java
@@ -20,9 +20,9 @@ package org.apache.wiki.providers;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.InternalWikiException;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.util.FileUtil;
@@ -38,7 +38,6 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 
@@ -84,56 +83,41 @@ public class VersioningFileProvider extends AbstractFileProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void initialize( WikiEngine engine, Properties properties )
-        throws NoRequiredPropertyException,
-               IOException
-    {
+    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
         super.initialize( engine, properties );
         // some additional sanity checks :
-        File oldpages = new File(getPageDirectory(), PAGEDIR);
-        if (!oldpages.exists())
-        {
-            if (!oldpages.mkdirs())
-            {
-                throw new IOException("Failed to create page version directory " + oldpages.getAbsolutePath());
+        final File oldpages = new File( getPageDirectory(), PAGEDIR );
+        if( !oldpages.exists() ) {
+            if( !oldpages.mkdirs() ) {
+                throw new IOException( "Failed to create page version directory " + oldpages.getAbsolutePath() );
             }
-        }
-        else
-        {
-            if (!oldpages.isDirectory())
-            {
-                throw new IOException("Page version directory is not a directory: " + oldpages.getAbsolutePath());
+        } else {
+            if( !oldpages.isDirectory() ) {
+                throw new IOException( "Page version directory is not a directory: " + oldpages.getAbsolutePath() );
             }
-            if (!oldpages.canWrite())
-            {
-                throw new IOException("Page version directory is not writable: " + oldpages.getAbsolutePath());
+            if( !oldpages.canWrite() ) {
+                throw new IOException( "Page version directory is not writable: " + oldpages.getAbsolutePath() );
             }
         }
-        log.info("Using directory " + oldpages.getAbsolutePath() + " for storing old versions of pages");
+        log.info( "Using directory " + oldpages.getAbsolutePath() + " for storing old versions of pages" );
     }
 
     /**
      *  Returns the directory where the old versions of the pages
      *  are being kept.
      */
-    private File findOldPageDir( String page )
-    {
-        if( page == null )
-        {
-            throw new InternalWikiException("Page may NOT be null in the provider!");
+    private File findOldPageDir( final String page ) {
+        if( page == null ) {
+            throw new InternalWikiException( "Page may NOT be null in the provider!" );
         }
-
-        File oldpages = new File( getPageDirectory(), PAGEDIR );
-
-        return new File( oldpages, mangleName(page) );
+        final File oldpages = new File( getPageDirectory(), PAGEDIR );
+        return new File( oldpages, mangleName( page ) );
     }
 
     /**
-     *  Goes through the repository and decides which version is
-     *  the newest one in that directory.
+     *  Goes through the repository and decides which version is the newest one in that directory.
      *
-     *  @return Latest version number in the repository, or -1, if
-     *          there is no page in the repository.
+     *  @return Latest version number in the repository, or -1, if there is no page in the repository.
      */
 
     // FIXME: This is relatively slow.
@@ -174,42 +158,32 @@ public class VersioningFileProvider extends AbstractFileProvider {
         return version;
     }
 */
-    private int findLatestVersion( String page )
-    {
+    private int findLatestVersion( final String page ) {
         int version = -1;
 
-        try
-        {
-            Properties props = getPageProperties( page );
-
-            for( Iterator<Object> i = props.keySet().iterator(); i.hasNext(); )
-            {
-                String key = (String)i.next();
+        try {
+            final Properties props = getPageProperties( page );
 
-                if( key.endsWith(".author") )
-                {
-                    int cutpoint = key.indexOf('.');
-                    if( cutpoint > 0 )
-                    {
-                        String pageNum = key.substring(0,cutpoint);
+            for( final Object o : props.keySet() ) {
+                final String key = ( String )o;
+                if( key.endsWith( ".author" ) ) {
+                    final int cutpoint = key.indexOf( '.' );
+                    if( cutpoint > 0 ) {
+                        final String pageNum = key.substring( 0, cutpoint );
 
-                        try
-                        {
-                            int res = Integer.parseInt( pageNum );
+                        try {
+                            final int res = Integer.parseInt( pageNum );
 
-                            if( res > version )
-                            {
+                            if( res > version ) {
                                 version = res;
                             }
-                        }
-                        catch( NumberFormatException e ) {} // It's okay to skip these.
+                        } catch( final NumberFormatException e ) {
+                        } // It's okay to skip these.
                     }
                 }
             }
-        }
-        catch( IOException e )
-        {
-            log.error("Unable to figure out latest version - dying...",e);
+        } catch( final IOException e ) {
+            log.error( "Unable to figure out latest version - dying...", e );
         }
 
         return version;
@@ -237,8 +211,8 @@ public class VersioningFileProvider extends AbstractFileProvider {
                 return cp.m_props;
             }
 
-            try( InputStream in = new BufferedInputStream(new FileInputStream( propertyFile ) ) ) {
-                Properties props = new Properties();
+            try( final InputStream in = new BufferedInputStream(new FileInputStream( propertyFile ) ) ) {
+                final Properties props = new Properties();
                 props.load( in );
                 cp = new CachedProperties( page, props, lastModified );
                 m_cachedProperties = cp; // Atomic
@@ -272,7 +246,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
      *
      *  @throws NoSuchVersionException if there is no such version.
      */
-    private int realVersion( String page, int requestedVersion ) throws NoSuchVersionException {
+    private int realVersion( final String page, final int requestedVersion ) throws NoSuchVersionException {
         //
         //  Quickly check for the most common case.
         //
@@ -281,7 +255,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
             return -1;
         }
 
-        int latest = findLatestVersion(page);
+        final int latest = findLatestVersion(page);
 
         if( requestedVersion == latest ||
             (requestedVersion == 1 && latest == -1 ) )
@@ -300,10 +274,10 @@ public class VersioningFileProvider extends AbstractFileProvider {
      *  {@inheritDoc}
      */
     @Override
-    public synchronized String getPageText( String page, int version )
+    public synchronized String getPageText( final String page, int version )
         throws ProviderException
     {
-        File dir = findOldPageDir( page );
+        final File dir = findOldPageDir( page );
 
         version = realVersion( page, version );
         if( version == -1 )
@@ -313,7 +287,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
             return super.getPageText( page, WikiPageProvider.LATEST_VERSION );
         }
 
-        File pageFile = new File( dir, ""+version+FILE_EXT );
+        final File pageFile = new File( dir, ""+version+FILE_EXT );
 
         if( !pageFile.exists() )
             throw new NoSuchVersionException("Version "+version+"does not exist.");
@@ -329,7 +303,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
             if( pagedata.canRead() ) {
                 try( final InputStream in = new FileInputStream( pagedata ) ) {
                     result = FileUtil.readContents( in, m_encoding );
-                } catch( IOException e ) {
+                } catch( final IOException e ) {
                     log.error("Failed to read", e);
                     throw new ProviderException("I/O error: "+e.getMessage());
                 }
@@ -388,8 +362,8 @@ public class VersioningFileProvider extends AbstractFileProvider {
 
             if( oldFile != null && oldFile.exists() ) {
                 final File pageFile = new File( pageDir, versionNumber + FILE_EXT );
-                try( InputStream in = new BufferedInputStream( new FileInputStream( oldFile ) );
-                     OutputStream out = new BufferedOutputStream( new FileOutputStream( pageFile ) ) ) {
+                try( final InputStream in = new BufferedInputStream( new FileInputStream( oldFile ) );
+                     final OutputStream out = new BufferedOutputStream( new FileOutputStream( pageFile ) ) ) {
                     FileUtil.copyContents( in, out );
 
                     //
@@ -413,18 +387,16 @@ public class VersioningFileProvider extends AbstractFileProvider {
             //  Finally, write page version data.
             //
             // FIXME: No rollback available.
-            Properties props = getPageProperties( page.getName() );
+            final Properties props = getPageProperties( page.getName() );
 
             String authorFirst = null;
             // if the following file exists, we are NOT migrating from FileSystemProvider
-            File pagePropFile = new File(getPageDirectory() + File.separator + PAGEDIR + File.separator + mangleName(page.getName()) + File.separator + "page" + FileSystemProvider.PROP_EXT);
+            final File pagePropFile = new File(getPageDirectory() + File.separator + PAGEDIR + File.separator + mangleName(page.getName()) + File.separator + "page" + FileSystemProvider.PROP_EXT);
             if( firstUpdate && ! pagePropFile.exists() ) {
-                // we might not yet have a versioned author because the
-                // old page was last maintained by FileSystemProvider
-                Properties props2 = getHeritagePageProperties( page.getName() );
+                // we might not yet have a versioned author because the old page was last maintained by FileSystemProvider
+                final Properties props2 = getHeritagePageProperties( page.getName() );
 
-                // remember the simulated original author (or something)
-                // in the new properties
+                // remember the simulated original author (or something) in the new properties
                 authorFirst = props2.getProperty( "1.author", "unknown" );
                 props.setProperty( "1.author", authorFirst );
             }
@@ -437,7 +409,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
             page.setAuthor(newAuthor);
             props.setProperty( versionNumber + ".author", newAuthor );
 
-            String changeNote = page.getAttribute(WikiPage.CHANGENOTE);
+            final String changeNote = page.getAttribute(WikiPage.CHANGENOTE);
             if( changeNote != null ) {
                 props.setProperty( versionNumber + ".changenote", changeNote );
             }
@@ -455,92 +427,74 @@ public class VersioningFileProvider extends AbstractFileProvider {
      *  {@inheritDoc}
      */
     @Override
-    public WikiPage getPageInfo( String page, int version )
-        throws ProviderException
-    {
-        int latest = findLatestVersion(page);
-        int realVersion;
+    public WikiPage getPageInfo( final String page, final int version ) throws ProviderException {
+        final int latest = findLatestVersion( page );
+        final int realVersion;
 
         WikiPage p = null;
 
-        if( version == WikiPageProvider.LATEST_VERSION ||
-            version == latest ||
-            (version == 1 && latest == -1) )
-        {
+        if( version == WikiPageProvider.LATEST_VERSION || version == latest || (version == 1 && latest == -1) ) {
             //
-            // Yes, we need to talk to the top level directory
-            // to get this version.
+            // Yes, we need to talk to the top level directory to get this version.
             //
-            // I am listening to Press Play On Tape's guitar version of
-            // the good old C64 "Wizardry" -tune at this moment.
+            // I am listening to Press Play On Tape's guitar version of the good old C64 "Wizardry" -tune at this moment.
             // Oh, the memories...
             //
             realVersion = (latest >= 0) ? latest : 1;
 
             p = super.getPageInfo( page, WikiPageProvider.LATEST_VERSION );
 
-            if( p != null )
-            {
+            if( p != null ) {
                 p.setVersion( realVersion );
             }
-        }
-        else
-        {
+        } else {
             //
             //  The file is not the most recent, so we'll need to
             //  find it from the deep trenches of the "OLD" directory
             //  structure.
             //
             realVersion = version;
-            File dir = findOldPageDir( page );
+            final File dir = findOldPageDir( page );
 
-            if( !dir.exists() || !dir.isDirectory() )
-            {
+            if( !dir.exists() || !dir.isDirectory() ) {
                 return null;
             }
 
-            File file = new File( dir, version+FILE_EXT );
+            final File file = new File( dir, version + FILE_EXT );
 
-            if( file.exists() )
-            {
+            if( file.exists() ) {
                 p = new WikiPage( m_engine, page );
 
-                p.setLastModified( new Date(file.lastModified()) );
+                p.setLastModified( new Date( file.lastModified() ) );
                 p.setVersion( version );
             }
         }
 
         //
-        //  Get author and other metadata information
-        //  (Modification date has already been set.)
+        //  Get author and other metadata information (Modification date has already been set.)
         //
-        if( p != null )
-        {
-            try
-            {
-                Properties props = getPageProperties( page );
-                String author = props.getProperty( realVersion+".author" );
-                if ( author == null )
-                {
+        if( p != null ) {
+            try {
+                final Properties props = getPageProperties( page );
+                String author = props.getProperty( realVersion + ".author" );
+                if( author == null ) {
                     // we might not have a versioned author because the
                     // old page was last maintained by FileSystemProvider
-                    Properties props2 = getHeritagePageProperties( page );
+                    final Properties props2 = getHeritagePageProperties( page );
                     author = props2.getProperty( WikiPage.AUTHOR );
                 }
-                if ( author != null )
-                {
+                if( author != null ) {
                     p.setAuthor( author );
                 }
 
-                String changenote = props.getProperty( realVersion+".changenote" );
-                if( changenote != null ) p.setAttribute( WikiPage.CHANGENOTE, changenote );
+                final String changenote = props.getProperty( realVersion + ".changenote" );
+                if( changenote != null )
+                    p.setAttribute( WikiPage.CHANGENOTE, changenote );
 
                 // Set the props values to the page attributes
-                setCustomProperties(p, props);
-            }
-            catch( IOException e )
-            {
-                log.error( "Cannot get author for page"+page+": ", e );
+                setCustomProperties( p, props );
+            } catch( final IOException e ) {
+                log.error( "Cannot get author for page" + page + ": ", e );
             }
         }
 
@@ -551,23 +505,17 @@ public class VersioningFileProvider extends AbstractFileProvider {
      *  {@inheritDoc}
      */
     @Override
-    public boolean pageExists( String pageName, int version )
-    {
+    public boolean pageExists( final String pageName, final int version ) {
         if (version == WikiPageProvider.LATEST_VERSION || version == findLatestVersion( pageName ) ) {
             return pageExists(pageName);
         }
 
-        File dir = findOldPageDir( pageName );
-
-        if( !dir.exists() || !dir.isDirectory() )
-        {
+        final File dir = findOldPageDir( pageName );
+        if( !dir.exists() || !dir.isDirectory() ) {
             return false;
         }
 
-        File file = new File( dir, version+FILE_EXT );
-
-        return file.exists();
-
+        return new File( dir, version + FILE_EXT ).exists();
     }
 
     /**
@@ -575,18 +523,16 @@ public class VersioningFileProvider extends AbstractFileProvider {
      */
      // FIXME: Does not get user information.
     @Override
-    public List< WikiPage > getVersionHistory( String page ) throws ProviderException {
-        ArrayList<WikiPage> list = new ArrayList<>();
-        int latest = findLatestVersion( page );
+    public List< WikiPage > getVersionHistory( final String page ) throws ProviderException {
+        final ArrayList< WikiPage > list = new ArrayList<>();
+        final int latest = findLatestVersion( page );
 
         // list.add( getPageInfo(page,WikiPageProvider.LATEST_VERSION) );
 
-        for( int i = latest; i > 0; i-- )
-        {
-            WikiPage info = getPageInfo( page, i );
+        for( int i = latest; i > 0; i-- ) {
+            final WikiPage info = getPageInfo( page, i );
 
-            if( info != null )
-            {
+            if( info != null ) {
                 list.add( info );
             }
         }
@@ -642,26 +588,19 @@ public class VersioningFileProvider extends AbstractFileProvider {
      */
     // FIXME: Should log errors.
     @Override
-    public void deletePage( String page )
-        throws ProviderException
-    {
+    public void deletePage( final String page ) throws ProviderException {
         super.deletePage( page );
+        final File dir = findOldPageDir( page );
+        if( dir.exists() && dir.isDirectory() ) {
+            final File[] files = dir.listFiles( new WikiFileFilter() );
 
-        File dir = findOldPageDir( page );
-
-        if( dir.exists() && dir.isDirectory() )
-        {
-            File[] files = dir.listFiles( new WikiFileFilter() );
-
-            for( int i = 0; i < files.length; i++ )
-            {
-                files[i].delete();
+            for( int i = 0; i < files.length; i++ ) {
+                files[ i ].delete();
             }
 
-            File propfile = new File( dir, PROPERTYFILE );
+            final File propfile = new File( dir, PROPERTYFILE );
 
-            if( propfile.exists() )
-            {
+            if( propfile.exists() ) {
                 propfile.delete();
             }
 
@@ -742,7 +681,7 @@ public class VersioningFileProvider extends AbstractFileProvider {
         final Collection< WikiPage > pages = super.getAllPages();
         final Collection< WikiPage > returnedPages = new ArrayList<>();
         for( final WikiPage page : pages ) {
-            WikiPage info = getPageInfo( page.getName(), WikiProvider.LATEST_VERSION );
+            final WikiPage info = getPageInfo( page.getName(), WikiProvider.LATEST_VERSION );
             returnedPages.add( info );
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiAttachmentProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiAttachmentProvider.java
index 2af6f9f..a02b00a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiAttachmentProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiAttachmentProvider.java
@@ -18,33 +18,28 @@
  */
 package org.apache.wiki.providers;
 
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.search.QueryItem;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
-import org.apache.wiki.WikiPage;
-import org.apache.wiki.WikiProvider;
-import org.apache.wiki.api.exceptions.ProviderException;
-import org.apache.wiki.attachment.Attachment;
-import org.apache.wiki.search.QueryItem;
 
 /**
- *  Defines an attachment provider - a class which is capable of saving
- *  binary data as attachments.
+ *  Defines an attachment provider - a class which is capable of saving binary data as attachments.
  *  <P>
- *  The difference between this class and WikiPageProvider is that there
- *  PageProviders handle Unicode text, whereas we handle binary data.
- *  While there are quite a lot of similarities in how we handle
- *  things, many providers can really use just one.  In addition,
- *  since binary files can be really large, we rely on
- *  Input/OutputStreams.
- *
+ *  The difference between this class and WikiPageProvider is that there PageProviders handle Unicode text, whereas we handle binary data.
+ *  While there are quite a lot of similarities in how we handle things, many providers can really use just one.  In addition,
+ *  since binary files can be really large, we rely on Input/OutputStreams.
  */
-public interface WikiAttachmentProvider
-    extends WikiProvider
-{
+public interface WikiAttachmentProvider extends WikiProvider {
+
     /**
      *  Put new attachment data.
      *  
@@ -53,23 +48,17 @@ public interface WikiAttachmentProvider
      *  @throws IOException If writing fails
      *  @throws ProviderException If there are other errors.
      */
-    void putAttachmentData( Attachment att, InputStream data )
-        throws ProviderException,
-               IOException;
+    void putAttachmentData( Attachment att, InputStream data ) throws ProviderException, IOException;
 
     /**
      *  Get attachment data.
      *  
      *  @param att The attachment
-     *  @return An InputStream which you contains the raw data of the object. It's your
-     *          responsibility to close it.
+     *  @return An InputStream which you contains the raw data of the object. It's your responsibility to close it.
      *  @throws ProviderException If the attachment cannot be found
      *  @throws IOException If the attachment cannot be opened
      */
-
-    InputStream getAttachmentData( Attachment att )
-        throws ProviderException,
-               IOException;
+    InputStream getAttachmentData( Attachment att ) throws ProviderException, IOException;
 
     /**
      *  Lists all attachments attached to a page.
@@ -78,25 +67,22 @@ public interface WikiAttachmentProvider
      *  @return A collection of Attachment objects.  May be empty, but never null.
      *  @throws ProviderException If something goes wrong when listing the attachments.
      */
-    List< Attachment > listAttachments( WikiPage page )
-        throws ProviderException;
+    List< Attachment > listAttachments( WikiPage page ) throws ProviderException;
 
     /**
      * Finds attachments based on the query.
+     *
      * @param query An array of QueryItem objects to search for
      * @return A Collection of Attachment objects.  May be empty, but never null.
      */
     Collection< Attachment > findAttachments( QueryItem[] query );
 
     /**
-     *  Lists changed attachments since given date.  Can also be used to fetch
-     *  a list of all pages.
+     *  Lists changed attachments since given date.  Can also be used to fetch a list of all pages.
      *  <P>
-     *  This is different from WikiPageProvider, where you basically get a list
-     *  of all pages, then sort them locally.  However, since some providers
-     *  can be more efficient in locating recently changed files (like any database) 
-     *  than our non-optimized Java
-     *  code, it makes more sense to fetch the whole list this way.
+     *  This is different from WikiPageProvider, where you basically get a list of all pages, then sort them locally.  However, since some
+     *  providers can be more efficient in locating recently changed files (like any database) than our non-optimized Java code, it makes
+     *  more sense to fetch the whole list this way.
      *  <P>
      *  To get all files, call this with Date(0L);
      *
@@ -104,8 +90,7 @@ public interface WikiAttachmentProvider
      *  @return A List of Attachment objects, in most-recently-changed first order.
      *  @throws ProviderException If something goes wrong.
      */
-    List<Attachment> listAllChanged( Date timestamp )
-        throws ProviderException;
+    List< Attachment > listAllChanged( Date timestamp ) throws ProviderException;
 
     /**
      *  Returns info about an attachment.
@@ -116,64 +101,46 @@ public interface WikiAttachmentProvider
      *  @return An attachment object
      *  @throws ProviderException If the attachment cannot be found or some other error occurs.
      */
-    Attachment getAttachmentInfo( WikiPage page, String name, int version )
-        throws ProviderException;
+    Attachment getAttachmentInfo( WikiPage page, String name, int version ) throws ProviderException;
 
     /**
-     *  Returns version history.  Each element should be
-     *  an Attachment.
+     *  Returns version history.  Each element should be an Attachment.
      *  
      *  @param att The attachment for which to find the version history for.
      *  @return A List of Attachment objects.
      */
-    List<Attachment> getVersionHistory( Attachment att );
+    List< Attachment > getVersionHistory( Attachment att );
 
     /**
-     *  Removes a specific version from the repository.  The implementations
-     *  should really do no more security checks, since that is the domain
-     *  of the AttachmentManager.  Just delete it as efficiently as you can.
+     *  Removes a specific version from the repository.  The implementations should really do no more security checks, since that is the
+     *  domain of the AttachmentManager.  Just delete it as efficiently as you can.
      *
      *  @since 2.0.19.
-     *
-     *  @param att Attachment to be removed.  The version field is checked, and thus
-     *             only that version is removed.
-     *
+     *  @param att Attachment to be removed.  The version field is checked, and thus only that version is removed.
      *  @throws ProviderException If the attachment cannot be removed for some reason.
      */
-
-    void deleteVersion( Attachment att )
-        throws ProviderException;
+    void deleteVersion( Attachment att ) throws ProviderException;
 
     /**
-     *  Removes an entire page from the repository.  The implementations
-     *  should really do no more security checks, since that is the domain
-     *  of the AttachmentManager.  Just delete it as efficiently as you can.  You should also
-     *  delete any auxiliary files and directories that belong to this attachment, 
-     *  IF they were created
-     *  by this provider.
+     *  Removes an entire page from the repository.  The implementations should really do no more security checks, since that is the domain
+     *  of the AttachmentManager.  Just delete it as efficiently as you can.  You should also delete any auxiliary files and directories
+     *  that belong to this attachment, IF they were created by this provider.
      *
      *  @since 2.0.17.
-     *
      *  @param att Attachment to delete.
-     *
      *  @throws ProviderException If the page could not be removed for some reason.
      */
-    void deleteAttachment( Attachment att )
-        throws ProviderException;
+    void deleteAttachment( Attachment att ) throws ProviderException;
    
     /**
-     * Move all the attachments for a given page so that they are attached to a
-     * new page.
+     * Move all the attachments for a given page so that they are attached to a new page.
      *
      * @param oldParent Name of the page we are to move the attachments from.
      * @param newParent Name of the page we are to move the attachments to.
-     *
-     * @throws ProviderException If the attachments could not be moved for some
-     *                           reason.
+     * @throws ProviderException If the attachments could not be moved for some reason.
      */
-    void moveAttachmentsForPage( String oldParent,
-                                        String newParent )
-        throws ProviderException;
+    void moveAttachmentsForPage( String oldParent, String newParent ) throws ProviderException;
+
 }
 
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiPageProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiPageProvider.java
index a0540fa..5fde3c9 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiPageProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/WikiPageProvider.java
@@ -18,36 +18,31 @@
  */
 package org.apache.wiki.providers;
 
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.search.QueryItem;
 import org.apache.wiki.search.SearchResult;
 
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
 
 /**
  *  Each Wiki page provider should implement this interface.
  *  <P>
- *  You can build whatever page providers based on this, just
- *  leave the unused methods do something useful.
+ *  You can build whatever page providers based on this, just leave the unused methods do something useful.
  *  <P>
- *  WikiPageProvider uses Strings and ints to refer to pages.  This may
- *  be a bit odd, since WikiAttachmentProviders all use Attachment
- *  instead of name/version.  We will perhaps modify these in the
- *  future.  In the mean time, name/version is quite sufficient.
+ *  WikiPageProvider uses Strings and ints to refer to pages.  This may be a bit odd, since WikiAttachmentProviders all use Attachment
+ *  instead of name/version.  We will perhaps modify these in the future.  In the mean time, name/version is quite sufficient.
  *  <P>
- *  FIXME: In reality we should have an AbstractWikiPageProvider,
- *  which would provide intelligent backups for subclasses.
+ *  FIXME: In reality we should have an AbstractWikiPageProvider, which would provide intelligent backups for subclasses.
  */
 public interface WikiPageProvider extends WikiProvider {
 
     /**
-     *  Attempts to save the page text for page "page".  Note that the
-     *  provider creates a new version regardless of what the version
+     *  Attempts to save the page text for page "page".  Note that the provider creates a new version regardless of what the version
      *  parameter of the WikiPage is.
      *  
      *  @param page The WikiPage to save
@@ -71,12 +66,10 @@ public interface WikiPageProvider extends WikiProvider {
      * @param version The version to check
      * @return True, if page exists; false otherwise.
      */
-
-    boolean pageExists(String page, int version);
+    boolean pageExists( String page, int version );
 
     /**
-     *  Finds pages based on the query.   Only applicable to providers
-     *  which implement the FastSearch interface.  Otherwise JSPWiki
+     *  Finds pages based on the query.   Only applicable to providers which implement the FastSearch interface.  Otherwise JSPWiki
      *  will use its internal cache.
      *  <p>
      *  This method should really be a part of the FastSearch IF.
@@ -97,8 +90,7 @@ public interface WikiPageProvider extends WikiProvider {
     WikiPage getPageInfo( String page, int version ) throws ProviderException;
 
     /**
-     *  Returns all pages.  Each element in the returned
-     *  Collection should be a WikiPage.
+     *  Returns all pages.  Each element in the returned Collection should be a WikiPage.
      *  
      *  @return A collection of WikiPages
      *  @throws ProviderException If something goes wrong.
@@ -124,8 +116,7 @@ public interface WikiPageProvider extends WikiProvider {
     int getPageCount() throws ProviderException;
 
     /**
-     *  Returns version history.  Each element should be
-     *  a WikiPage.
+     *  Returns version history.  Each element should be a WikiPage.
      *
      *  @param page The name of the page to get the history from.
      *  @return A collection of WikiPages.
@@ -138,43 +129,32 @@ public interface WikiPageProvider extends WikiProvider {
      *
      *  @param page Name of the page to fetch.
      *  @param version Version of the page to fetch.
-     *
      *  @return The content of the page, or null, if the page does not exist.
      *  @throws ProviderException If something goes wrong.
      */
     String getPageText( String page, int version ) throws ProviderException;
 
     /**
-     *  Removes a specific version from the repository.  The implementations
-     *  should really do no more security checks, since that is the domain
-     *  of the PageManager.  Just delete it as efficiently as you can.
+     *  Removes a specific version from the repository.  The implementations should really do no more security checks, since that is the
+     *  domain of the PageManager.  Just delete it as efficiently as you can.
      *
      *  @since 2.0.17.
-     *
      *  @param pageName Name of the page to be removed.
      *  @param version  Version of the page to be removed.  May be LATEST_VERSION.
-     *
      *  @throws ProviderException If the page cannot be removed for some reason.
      */
     void deleteVersion( String pageName, int version ) throws ProviderException;
 
     /**
-     *  Removes an entire page from the repository.  The implementations
-     *  should really do no more security checks, since that is the domain
-     *  of the PageManager.  Just delete it as efficiently as you can.  You should also
-     *  delete any auxiliary files that belong to this page, IF they were created
-     *  by this provider.
+     *  Removes an entire page from the repository.  The implementations should really do no more security checks, since that is the domain
+     *  of the PageManager.  Just delete it as efficiently as you can.  You should also delete any auxiliary files that belong to this page,
+     *  IF they were created by this provider.
      *
-     *  <P>The reason why this is named differently from
-     *  deleteVersion() (logically, this method should be an
-     *  overloaded version) is that I want to be absolutely sure I
-     *  don't accidentally use the wrong method.  With overloading
-     *  something like that happens sometimes...
+     *  <P>The reason why this is named differently from deleteVersion() (logically, this method should be an overloaded version) is that
+     *  I want to be absolutely sure I don't accidentally use the wrong method.  With overloading something like that happens sometimes...
      *
      *  @since 2.0.17.
-     *
      *  @param pageName Name of the page to be removed completely.
-     *
      *  @throws ProviderException If the page could not be removed for some reason.
      */
     void deletePage( String pageName ) throws ProviderException;
@@ -184,7 +164,6 @@ public interface WikiPageProvider extends WikiProvider {
      *
      * @param from  Name of the page to move.
      * @param to    New name of the page.
-     *
      * @throws ProviderException If the page could not be moved for some reason.
      */
     void movePage(String from, String to) throws ProviderException;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/BasicSearchProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/search/BasicSearchProvider.java
index 12e2887..981294f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/BasicSearchProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/BasicSearchProvider.java
@@ -20,13 +20,15 @@ package org.apache.wiki.search;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 
 import java.io.IOException;
@@ -45,25 +47,24 @@ import java.util.TreeSet;
 public class BasicSearchProvider implements SearchProvider {
 
     private static final Logger log = Logger.getLogger( BasicSearchProvider.class );
-
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
     /**
      *  {@inheritDoc}
      */
-    public void initialize( final WikiEngine engine, final Properties props ) throws NoRequiredPropertyException, IOException {
+    @Override public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, IOException {
         m_engine = engine;
     }
 
     /**
      *  {@inheritDoc}
      */
-    public void pageRemoved( final WikiPage page ) {}
+    @Override public void pageRemoved( final WikiPage page ) {}
 
     /**
      *  {@inheritDoc}
      */
-    public void reindexPage( final WikiPage page ) {}
+    @Override public void reindexPage( final WikiPage page ) {}
 
     /**
      *  Parses a query into something that we can use.
@@ -111,10 +112,10 @@ public class BasicSearchProvider implements SearchProvider {
     }
 
     private String attachmentNames( final WikiPage page ) {
-        if( m_engine.getAttachmentManager().hasAttachments( page ) ) {
+        if( m_engine.getManager( AttachmentManager.class ).hasAttachments( page ) ) {
             final List< Attachment > attachments;
             try {
-                attachments = m_engine.getAttachmentManager().listAttachments( page );
+                attachments = m_engine.getManager( AttachmentManager.class ).listAttachments( page );
             } catch( final ProviderException e ) {
                 log.error( "Unable to get attachments for page", e );
                 return "";
@@ -139,13 +140,13 @@ public class BasicSearchProvider implements SearchProvider {
         final SearchMatcher matcher = new SearchMatcher( m_engine, query );
         final Collection< WikiPage > allPages;
         try {
-            allPages = m_engine.getPageManager().getAllPages();
+            allPages = m_engine.getManager( PageManager.class ).getAllPages();
         } catch( final ProviderException pe ) {
             log.error( "Unable to retrieve page list", pe );
             return null;
         }
 
-        final AuthorizationManager mgr = m_engine.getAuthorizationManager();
+        final AuthorizationManager mgr = m_engine.getManager( AuthorizationManager.class );
 
         for( final WikiPage page : allPages ) {
             try {
@@ -154,7 +155,7 @@ public class BasicSearchProvider implements SearchProvider {
                     if( wikiContext == null || mgr.checkPermission( wikiContext.getWikiSession(), pp ) ) {
                         final String pageName = page.getName();
                         final String pageContent =
-                                m_engine.getPageManager().getPageText( pageName, WikiPageProvider.LATEST_VERSION ) + attachmentNames( page );
+                                m_engine.getManager( PageManager.class ).getPageText( pageName, WikiPageProvider.LATEST_VERSION ) + attachmentNames( page );
                         final SearchResult comparison = matcher.matchPageContent( pageName, pageContent );
                         if( comparison != null ) {
                             res.add( comparison );
@@ -174,14 +175,14 @@ public class BasicSearchProvider implements SearchProvider {
     /**
      *  {@inheritDoc}
      */
-    public Collection< SearchResult > findPages( final String query, final WikiContext wikiContext ) {
+    @Override public Collection< SearchResult > findPages( final String query, final WikiContext wikiContext ) {
         return findPages( parseQuery( query ), wikiContext );
     }
 
     /**
      *  {@inheritDoc}
      */
-    public String getProviderInfo() {
+    @Override public String getProviderInfo() {
         return "BasicSearchProvider";
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
index c6ab12a..30fbed8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/LuceneSearchProvider.java
@@ -50,15 +50,16 @@ import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.WatchDog;
 import org.apache.wiki.WikiBackgroundThread;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 import org.apache.wiki.util.ClassUtil;
 import org.apache.wiki.util.FileUtil;
@@ -90,7 +91,7 @@ public class LuceneSearchProvider implements SearchProvider {
 
     protected static final Logger log = Logger.getLogger(LuceneSearchProvider.class);
 
-    private WikiEngine m_engine;
+    private Engine m_engine;
     private Executor searchExecutor;
 
     // Lucene properties.
@@ -131,7 +132,7 @@ public class LuceneSearchProvider implements SearchProvider {
      *  {@inheritDoc}
      */
     @Override
-    public void initialize( final WikiEngine engine, final Properties props ) throws NoRequiredPropertyException, IOException  {
+    public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, IOException  {
         m_engine = engine;
         searchExecutor = Executors.newCachedThreadPool();
 
@@ -176,7 +177,7 @@ public class LuceneSearchProvider implements SearchProvider {
      *
      *  @return Current WikiEngine
      */
-    protected WikiEngine getEngine()
+    protected Engine getEngine()
     {
         return m_engine;
     }
@@ -204,17 +205,17 @@ public class LuceneSearchProvider implements SearchProvider {
 
                 final Directory luceneDir = new SimpleFSDirectory( dir.toPath() );
                 try( final IndexWriter writer = getIndexWriter( luceneDir ) ) {
-                    final Collection< WikiPage > allPages = m_engine.getPageManager().getAllPages();
+                    final Collection< WikiPage > allPages = m_engine.getManager( PageManager.class ).getAllPages();
                     for( final WikiPage page : allPages ) {
                         try {
-                            final String text = m_engine.getPageManager().getPageText( page.getName(), WikiProvider.LATEST_VERSION );
+                            final String text = m_engine.getManager( PageManager.class ).getPageText( page.getName(), WikiProvider.LATEST_VERSION );
                             luceneIndexPage( page, text, writer );
                         } catch( final IOException e ) {
                             log.warn( "Unable to index page " + page.getName() + ", continuing to next ", e );
                         }
                     }
 
-                    final Collection< Attachment > allAttachments = m_engine.getAttachmentManager().getAllAttachments();
+                    final Collection< Attachment > allAttachments = m_engine.getManager( AttachmentManager.class ).getAllAttachments();
                     for( final Attachment att : allAttachments ) {
                         try {
                             final String text = getAttachmentContent( att.getName(), WikiProvider.LATEST_VERSION );
@@ -252,7 +253,7 @@ public class LuceneSearchProvider implements SearchProvider {
      *  @return the content of the Attachment as a String.
      */
     protected String getAttachmentContent( final String attachmentName, final int version ) {
-        final AttachmentManager mgr = m_engine.getAttachmentManager();
+        final AttachmentManager mgr = m_engine.getManager( AttachmentManager.class );
         try {
             final Attachment att = mgr.getAttachmentInfo( attachmentName, version );
             //FIXME: Find out why sometimes att is null
@@ -272,7 +273,7 @@ public class LuceneSearchProvider implements SearchProvider {
      * This should be replaced /moved to Attachment search providers or some other 'pluggable' way to search attachments
      */
     protected String getAttachmentContent( final Attachment att ) {
-        final AttachmentManager mgr = m_engine.getAttachmentManager();
+        final AttachmentManager mgr = m_engine.getManager( AttachmentManager.class );
         //FIXME: Add attachment plugin structure
 
         final String filename = att.getFileName();
@@ -378,7 +379,7 @@ public class LuceneSearchProvider implements SearchProvider {
 
         // Now add the names of the attachments of this page
         try {
-            final List< Attachment > attachments = m_engine.getAttachmentManager().listAttachments( page );
+            final List< Attachment > attachments = m_engine.getManager( AttachmentManager.class ).listAttachments( page );
             String attachmentNames = "";
 
             for( final Attachment att : attachments ) {
@@ -434,9 +435,9 @@ public class LuceneSearchProvider implements SearchProvider {
 
             // TODO: Think if this was better done in the thread itself?
             if( page instanceof Attachment ) {
-                text = getAttachmentContent( (Attachment) page );
+                text = getAttachmentContent( ( Attachment )page );
             } else {
-                text = m_engine.getPageManager().getPureText( page );
+                text = m_engine.getManager( PageManager.class ).getPureText( page );
             }
 
             if( text != null ) {
@@ -490,14 +491,14 @@ public class LuceneSearchProvider implements SearchProvider {
             }
 
             final ScoreDoc[] hits = searcher.search(luceneQuery, MAX_SEARCH_HITS).scoreDocs;
-            final AuthorizationManager mgr = m_engine.getAuthorizationManager();
+            final AuthorizationManager mgr = m_engine.getManager( AuthorizationManager.class );
 
             list = new ArrayList<>(hits.length);
             for( final ScoreDoc hit : hits ) {
                 final int docID = hit.doc;
                 final Document doc = searcher.doc( docID );
                 final String pageName = doc.get( LUCENE_ID );
-                final WikiPage page = m_engine.getPageManager().getPage( pageName, WikiPageProvider.LATEST_VERSION );
+                final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pageName, WikiPageProvider.LATEST_VERSION );
 
                 if( page != null ) {
                     final PagePermission pp = new PagePermission( page, PagePermission.VIEW_ACTION );
@@ -555,7 +556,7 @@ public class LuceneSearchProvider implements SearchProvider {
 
         private WatchDog m_watchdog;
 
-        private LuceneUpdater( final WikiEngine engine, final LuceneSearchProvider provider, final int initialDelay, final int indexDelay ) {
+        private LuceneUpdater( final Engine engine, final LuceneSearchProvider provider, final int initialDelay, final int indexDelay ) {
             super( engine, indexDelay );
             m_provider = provider;
             m_initialDelay = initialDelay;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchMatcher.java b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchMatcher.java
index c741ac7..1c2a4a4 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/SearchMatcher.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/SearchMatcher.java
@@ -18,8 +18,8 @@
  */
 package org.apache.wiki.search;
 
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -36,7 +36,7 @@ import java.io.StringReader;
 public class SearchMatcher {
 	
     private QueryItem[] m_queries;
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
     /**
      *  Creates a new SearchMatcher.
@@ -44,7 +44,7 @@ public class SearchMatcher {
      *  @param engine The WikiEngine
      *  @param queries A list of queries
      */
-    public SearchMatcher( final WikiEngine engine, final QueryItem[] queries ) {
+    public SearchMatcher( final Engine engine, final QueryItem[] queries ) {
         m_engine = engine;
         m_queries = queries != null ? queries.clone() : null;
     }
@@ -134,7 +134,7 @@ public class SearchMatcher {
          *  Returns Wikipage for this result.
          *  @return WikiPage
          */
-        public WikiPage getPage() {
+        @Override public WikiPage getPage() {
             return m_page;
         }
 
@@ -143,7 +143,7 @@ public class SearchMatcher {
          *  
          *  @return Score from 0+
          */
-        public int getScore() {
+        @Override public int getScore() {
             return m_score;
         }
 
@@ -152,7 +152,7 @@ public class SearchMatcher {
          *  
          *  @return an empty array
          */
-        public String[] getContexts() {
+        @Override public String[] getContexts() {
             // Unimplemented
             return new String[0];
         }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/providers/CounterProvider.java b/jspwiki-main/src/test/java/org/apache/wiki/providers/CounterProvider.java
index 1003e56..4a29105 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/providers/CounterProvider.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/providers/CounterProvider.java
@@ -18,6 +18,12 @@
  */
 package org.apache.wiki.providers;
 
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.search.QueryItem;
+import org.apache.wiki.search.SearchResult;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -25,35 +31,24 @@ import java.util.List;
 import java.util.Properties;
 import java.util.Vector;
 
-import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiPage;
-import org.apache.wiki.api.exceptions.ProviderException;
-import org.apache.wiki.search.QueryItem;
-import org.apache.wiki.search.SearchResult;
-
 /**
  *  A provider who counts the hits to different parts.
  */
-public class CounterProvider
-    implements WikiPageProvider
-{
+public class CounterProvider implements WikiPageProvider {
+
     public int m_getPageCalls     = 0;
     public int m_pageExistsCalls  = 0;
     public int m_getPageTextCalls = 0;
     public int m_getAllPagesCalls = 0;
     public int m_initCalls        = 0;
 
-    static Logger log = Logger.getLogger( CounterProvider.class );
-
     WikiPage[]    m_pages         = new WikiPage[0];
     
     String m_defaultText = "[Foo], [Bar], [Blat], [Blah]";
 
 
     @Override
-    public void initialize( WikiEngine engine, Properties props )
-    {
+    public void initialize( final Engine engine, final Properties props ) {
         m_pages = new WikiPage[]
                   { new WikiPage(engine, "Foo"),
                     new WikiPage(engine, "Bar"),
@@ -77,13 +72,13 @@ public class CounterProvider
     }
 
     @Override
-    public void putPageText( WikiPage page, String text )
+    public void putPageText( final WikiPage page, final String text )
         throws ProviderException
     {
     }
 
     @Override
-    public boolean pageExists( String page )
+    public boolean pageExists( final String page )
     {
         m_pageExistsCalls++;
 
@@ -91,18 +86,18 @@ public class CounterProvider
     }
 
     @Override
-    public boolean pageExists( String page, int version )
+    public boolean pageExists( final String page, final int version )
     {
         return pageExists (page);
     }
 
     @Override
-    public Collection< SearchResult > findPages( QueryItem[] query )
+    public Collection< SearchResult > findPages( final QueryItem[] query )
     {
         return null;
     }
 
-    private WikiPage findPage( String page )
+    private WikiPage findPage( final String page )
     {
         for( int i = 0; i < m_pages.length; i++ )
         {
@@ -114,14 +109,11 @@ public class CounterProvider
     }
 
     @Override
-    public WikiPage getPageInfo( String page, int version )
+    public WikiPage getPageInfo( final String page, final int version )
     {            
         m_getPageCalls++;
 
-        //System.out.println("GETPAGEINFO="+page);
-        //TestEngine.trace();
-
-        WikiPage p = findPage(page);
+        final WikiPage p = findPage(page);
 
         return p;
     }
@@ -131,7 +123,7 @@ public class CounterProvider
     {
         m_getAllPagesCalls++;
 
-        List<WikiPage> l = new ArrayList<>();
+        final List<WikiPage> l = new ArrayList<>();
 
         for( int i = 0; i < m_pages.length; i++ )
         {
@@ -142,7 +134,7 @@ public class CounterProvider
     }
 
     @Override
-    public Collection< WikiPage > getAllChangedSince( Date date )
+    public Collection< WikiPage > getAllChangedSince( final Date date )
     {
         return new ArrayList<>();
     }
@@ -154,25 +146,25 @@ public class CounterProvider
     }
 
     @Override
-    public List< WikiPage > getVersionHistory( String page )
+    public List< WikiPage > getVersionHistory( final String page )
     {
         return new Vector<>();
     }
 
     @Override
-    public String getPageText( String page, int version )
+    public String getPageText( final String page, final int version )
     {
         m_getPageTextCalls++;
         return m_defaultText;
     }
 
     @Override
-    public void deleteVersion( String page, int version )
+    public void deleteVersion( final String page, final int version )
     {
     }
 
     @Override
-    public void deletePage( String page )
+    public void deletePage( final String page )
     {
     }
 
@@ -180,10 +172,8 @@ public class CounterProvider
      * @see org.apache.wiki.providers.WikiPageProvider#movePage(java.lang.String, java.lang.String)
      */
     @Override
-    public void movePage( String from, String to ) throws ProviderException
+    public void movePage( final String from, final String to ) throws ProviderException
     {
-        // TODO Auto-generated method stub
-        
     }
     
     
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/providers/VerySimpleProvider.java b/jspwiki-main/src/test/java/org/apache/wiki/providers/VerySimpleProvider.java
index a3067d0..f7fa810 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/providers/VerySimpleProvider.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/providers/VerySimpleProvider.java
@@ -18,6 +18,12 @@
  */
 package org.apache.wiki.providers;
 
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.search.QueryItem;
+import org.apache.wiki.search.SearchResult;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -25,12 +31,6 @@ import java.util.List;
 import java.util.Properties;
 import java.util.Vector;
 
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiPage;
-import org.apache.wiki.api.exceptions.ProviderException;
-import org.apache.wiki.search.QueryItem;
-import org.apache.wiki.search.SearchResult;
-
 /**
  *  This is a simple provider that is used by some of the tests.  It has some
  *  specific behaviours, like it always contains a single page.
@@ -53,10 +53,10 @@ public class VerySimpleProvider implements WikiPageProvider
      */
     public static final String AUTHOR   = "default-author";
     
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
     @Override
-    public void initialize( WikiEngine engine, Properties props )
+    public void initialize( final Engine engine, final Properties props )
     {
         m_engine = engine;
     }
@@ -68,7 +68,7 @@ public class VerySimpleProvider implements WikiPageProvider
     }
 
     @Override
-    public void putPageText( WikiPage page, String text )
+    public void putPageText( final WikiPage page, final String text )
         throws ProviderException
     {
     }
@@ -77,7 +77,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Always returns true.
      */
     @Override
-    public boolean pageExists( String page )
+    public boolean pageExists( final String page )
     {
         return true;
     }
@@ -86,7 +86,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Always returns true.
      */
     @Override
-    public boolean pageExists( String page, int version )
+    public boolean pageExists( final String page, final int version )
     {
         return true;
     }
@@ -95,7 +95,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Always returns null.
      */
     @Override
-    public Collection< SearchResult > findPages( QueryItem[] query )
+    public Collection< SearchResult > findPages( final QueryItem[] query )
     {
         return null;
     }
@@ -104,12 +104,12 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Returns always a valid WikiPage.
      */
     @Override
-    public WikiPage getPageInfo( String page, int version )
+    public WikiPage getPageInfo( final String page, final int version )
     {
         m_latestReq  = page;
         m_latestVers = version;
 
-        WikiPage p = new WikiPage( m_engine, page );
+        final WikiPage p = new WikiPage( m_engine, page );
         p.setVersion( 5 );
         p.setAuthor( AUTHOR );
         p.setLastModified( new Date(0L) );
@@ -122,7 +122,7 @@ public class VerySimpleProvider implements WikiPageProvider
     @Override
     public Collection< WikiPage > getAllPages()
     {
-        List< WikiPage > l = new ArrayList<>();
+        final List< WikiPage > l = new ArrayList<>();
         l.add( getPageInfo( PAGENAME, 5 ) );
         return l;
     }
@@ -131,7 +131,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Returns the same as getAllPages().
      */
     @Override
-    public Collection< WikiPage > getAllChangedSince( Date date )
+    public Collection< WikiPage > getAllChangedSince( final Date date )
     {
         return getAllPages();
     }
@@ -149,7 +149,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  Always returns an empty list.
      */
     @Override
-    public List< WikiPage > getVersionHistory( String page )
+    public List< WikiPage > getVersionHistory( final String page )
     {
         return new Vector<>();
     }
@@ -159,7 +159,7 @@ public class VerySimpleProvider implements WikiPageProvider
      *  then returns an empty string.
      */
     @Override
-    public String getPageText( String page, int version )
+    public String getPageText( final String page, final int version )
     {
         m_latestReq  = page;
         m_latestVers = version;
@@ -168,12 +168,12 @@ public class VerySimpleProvider implements WikiPageProvider
     }
 
     @Override
-    public void deleteVersion( String page, int version )
+    public void deleteVersion( final String page, final int version )
     {
     }
 
     @Override
-    public void deletePage( String page )
+    public void deletePage( final String page )
     {
     }
 
@@ -181,7 +181,7 @@ public class VerySimpleProvider implements WikiPageProvider
      * @see org.apache.wiki.providers.WikiPageProvider#movePage(java.lang.String, java.lang.String)
      */
     @Override
-    public void movePage( String from, String to ) throws ProviderException
+    public void movePage( final String from, final String to ) throws ProviderException
     {
         // TODO Auto-generated method stub
         
diff --git a/jspwiki-tika-searchprovider/src/main/java/org/apache/wiki/search/tika/TikaSearchProvider.java b/jspwiki-tika-searchprovider/src/main/java/org/apache/wiki/search/tika/TikaSearchProvider.java
index 2d9a95e..4f778d0 100644
--- a/jspwiki-tika-searchprovider/src/main/java/org/apache/wiki/search/tika/TikaSearchProvider.java
+++ b/jspwiki-tika-searchprovider/src/main/java/org/apache/wiki/search/tika/TikaSearchProvider.java
@@ -54,8 +54,8 @@ import java.util.Set;
 public class TikaSearchProvider extends LuceneSearchProvider {
 
     private static final Logger LOG = Logger.getLogger( TikaSearchProvider.class );
-    AutoDetectParser parser;
-    Set< String > textualMetadataFields;
+    final AutoDetectParser parser;
+    final Set< String > textualMetadataFields;
 
     public TikaSearchProvider() {
         parser = new AutoDetectParser();
@@ -91,8 +91,7 @@ public class TikaSearchProvider extends LuceneSearchProvider {
      */
     @Override
     protected String getAttachmentContent( final Attachment att ) {
-        // LOG.debug("indexing "+att.getFileName());
-        final AttachmentManager mgr = getEngine().getAttachmentManager();
+        final AttachmentManager mgr = getEngine().getManager( AttachmentManager.class );
         final StringBuilder out = new StringBuilder();
 
         try( final InputStream attStream = mgr.getAttachmentStream( att ) ) {
@@ -106,14 +105,14 @@ public class TikaSearchProvider extends LuceneSearchProvider {
             out.append( handler.toString() );
 
             final String[] names = metadata.names();
-            for( int j = 0; j < names.length; j++ ) {
-                if( textualMetadataFields.contains( names[ j ] ) ) {
-                    out.append( " " ).append( metadata.get( names[ j ] ) );
+            for( final String name : names ) {
+                if( textualMetadataFields.contains( name ) ) {
+                    out.append( " " ).append( metadata.get( name ) );
                 }
             }
-        } catch( TikaException | SAXException e ) {
+        } catch( final TikaException | SAXException e ) {
             LOG.error( "Attachment cannot be parsed", e );
-        } catch( ProviderException | IOException e ) {
+        } catch( final ProviderException | IOException e ) {
             LOG.error( "Attachment cannot be loaded", e );
         }
 


[jspwiki] 24/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (1)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit bbac3d4a375963a6184e1c40d17aa09ec3619bd7
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:11:02 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (1)
---
 .../apache/wiki/plugin/AbstractReferralPlugin.java |  91 +++++++--------
 .../org/apache/wiki/plugin/BugReportHandler.java   |  11 +-
 .../main/java/org/apache/wiki/plugin/Groups.java   |  12 +-
 .../main/java/org/apache/wiki/plugin/IfPlugin.java |  18 +--
 .../main/java/org/apache/wiki/plugin/Image.java    |  44 +++----
 .../java/org/apache/wiki/plugin/IndexPlugin.java   |  64 ++++++-----
 .../java/org/apache/wiki/plugin/InsertPage.java    |  46 ++++----
 .../org/apache/wiki/plugin/ListLocksPlugin.java    |  48 +++-----
 .../src/main/java/org/apache/wiki/plugin/Note.java |  25 ++--
 .../org/apache/wiki/plugin/PageViewPlugin.java     | 109 +++++++++---------
 .../apache/wiki/plugin/RecentChangesPlugin.java    |  14 ++-
 .../apache/wiki/plugin/ReferredPagesPlugin.java    |  15 +--
 .../apache/wiki/plugin/ReferringPagesPlugin.java   |  13 ++-
 .../wiki/plugin/ReferringUndefinedPagesPlugin.java |  24 ++--
 .../main/java/org/apache/wiki/plugin/Search.java   |  38 +++---
 .../org/apache/wiki/plugin/SessionsPlugin.java     |  34 +++---
 .../org/apache/wiki/plugin/TableOfContents.java    |  36 +++---
 .../apache/wiki/plugin/UndefinedPagesPlugin.java   |   4 +-
 .../org/apache/wiki/plugin/UnusedPagesPlugin.java  |  55 +++------
 .../apache/wiki/plugin/WeblogArchivePlugin.java    | 127 +++++++--------------
 .../org/apache/wiki/plugin/WeblogEntryPlugin.java  |  20 ++--
 .../java/org/apache/wiki/plugin/WeblogPlugin.java  |  36 +++---
 22 files changed, 408 insertions(+), 476 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/AbstractReferralPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/AbstractReferralPlugin.java
index 3260cb8..69d5ca3 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/AbstractReferralPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/AbstractReferralPlugin.java
@@ -28,10 +28,11 @@ import org.apache.oro.text.regex.PatternMatcher;
 import org.apache.oro.text.regex.Perl5Matcher;
 import org.apache.wiki.StringTransmutator;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.pages.PageSorter;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.parser.WikiDocument;
@@ -134,7 +135,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
     protected           Date m_dateLastModified = new Date(0);
     protected           SimpleDateFormat m_dateFormat;
 
-    protected           WikiEngine m_engine;
+    protected           Engine m_engine;
 
     /**
      * @param context the wiki context
@@ -142,7 +143,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      * @throws PluginException if any of the plugin parameters are malformed
      */
     // FIXME: The compiled pattern strings should really be cached somehow.
-    public void initialize( WikiContext context, Map<String, String> params )
+    public void initialize( final WikiContext context, final Map<String, String> params )
         throws PluginException
     {
         m_dateFormat = Preferences.getDateFormat( context, TimeFormat.DATETIME );
@@ -181,9 +182,9 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
         {
             try
             {
-                PatternCompiler pc = new GlobCompiler();
+                final PatternCompiler pc = new GlobCompiler();
 
-                String[] ptrns = StringUtils.split( s, "," );
+                final String[] ptrns = StringUtils.split( s, "," );
 
                 m_exclude = new Pattern[ptrns.length];
 
@@ -192,7 +193,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
                     m_exclude[i] = pc.compile( ptrns[i] );
                 }
             }
-            catch( MalformedPatternException e )
+            catch( final MalformedPatternException e )
             {
                 throw new PluginException("Exclude-parameter has a malformed pattern: "+e.getMessage());
             }
@@ -205,9 +206,9 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
         {
             try
             {
-                PatternCompiler pc = new GlobCompiler();
+                final PatternCompiler pc = new GlobCompiler();
 
-                String[] ptrns = StringUtils.split( s, "," );
+                final String[] ptrns = StringUtils.split( s, "," );
 
                 m_include = new Pattern[ptrns.length];
 
@@ -216,7 +217,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
                     m_include[i] = pc.compile( ptrns[i] );
                 }
             }
-            catch( MalformedPatternException e )
+            catch( final MalformedPatternException e )
             {
                 throw new PluginException("Include-parameter has a malformed pattern: "+e.getMessage());
             }
@@ -253,8 +254,8 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
         initSorter( context, params );
     }
 
-    protected List< WikiPage > filterWikiPageCollection( Collection< WikiPage > pages ) {
-        List< String > pageNames = filterCollection( pages.stream()
+    protected List< WikiPage > filterWikiPageCollection( final Collection< WikiPage > pages ) {
+        final List< String > pageNames = filterCollection( pages.stream()
                                                           .map( page -> page.getName() )
                                                           .collect( Collectors.toList() ) );
         return pages.stream()
@@ -268,15 +269,15 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      *  @param c The collection to filter.
      *  @return A filtered collection.
      */
-    protected List< String > filterCollection( Collection< String > c )
+    protected List< String > filterCollection( final Collection< String > c )
     {
-        ArrayList< String > result = new ArrayList<>();
+        final ArrayList< String > result = new ArrayList<>();
 
-        PatternMatcher pm = new Perl5Matcher();
+        final PatternMatcher pm = new Perl5Matcher();
 
-        for( Iterator< String > i = c.iterator(); i.hasNext(); )
+        for( final Iterator< String > i = c.iterator(); i.hasNext(); )
         {
-            String pageName = i.next();
+            final String pageName = i.next();
 
             //
             //  If include parameter exists, then by default we include only those
@@ -318,10 +319,10 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
                 WikiPage page = null;
                 if( m_lastModified )
                 {
-                    page = m_engine.getPageManager().getPage( pageName );
+                    page = m_engine.getManager( PageManager.class ).getPage( pageName );
                     if( page != null )
                     {
-                        Date lastModPage = page.getLastModified();
+                        final Date lastModPage = page.getLastModified();
                         if( log.isDebugEnabled() )
                         {
                             log.debug( "lastModified Date of page " + pageName + " : " + m_dateLastModified );
@@ -345,8 +346,8 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      *  @param c The collection to filter.
      *  @return A filtered and sorted collection.
      */
-    protected List< String > filterAndSortCollection( Collection< String > c ) {
-        List< String > result = filterCollection( c );
+    protected List< String > filterAndSortCollection( final Collection< String > c ) {
+        final List< String > result = filterCollection( c );
         result.sort( m_sorter );
         return result;
     }
@@ -359,14 +360,14 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      *  @param numItems How many items to show.
      *  @return The WikiText
      */
-    protected String wikitizeCollection( Collection< String > links, String separator, int numItems )
+    protected String wikitizeCollection( final Collection< String > links, final String separator, final int numItems )
     {
         if( links == null || links.isEmpty() )
             return "";
 
-        StringBuilder output = new StringBuilder();
+        final StringBuilder output = new StringBuilder();
 
-        Iterator< String > it = links.iterator();
+        final Iterator< String > it = links.iterator();
         int count = 0;
 
         //
@@ -374,7 +375,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
         //
         while( it.hasNext() && ( (count < numItems) || ( numItems == ALL_ITEMS ) ) )
         {
-            String value = it.next();
+            final String value = it.next();
 
             if( count > 0 )
             {
@@ -385,7 +386,7 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
             output.append( m_before );
 
             // Make a Wiki markup link. See TranslatorReader.
-            output.append( "[" + m_engine.getRenderingManager().beautifyTitle(value) + "|" + value + "]" );
+            output.append( "[" + m_engine.getManager( RenderingManager.class ).beautifyTitle(value) + "|" + value + "]" );
             count++;
         }
 
@@ -405,24 +406,24 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      *  @return HTML
      *  @since 1.6.4
      */
-    protected String makeHTML( WikiContext context, String wikitext )
+    protected String makeHTML( final WikiContext context, final String wikitext )
     {
         String result = "";
 
-        RenderingManager mgr = m_engine.getRenderingManager();
+        final RenderingManager mgr = m_engine.getManager( RenderingManager.class );
 
         try
         {
-            MarkupParser parser = mgr.getParser(context, wikitext);
+            final MarkupParser parser = mgr.getParser(context, wikitext);
 
             parser.addLinkTransmutator( new CutMutator(m_maxwidth) );
             parser.enableImageInlining( false );
 
-            WikiDocument doc = parser.parse();
+            final WikiDocument doc = parser.parse();
 
             result = mgr.getHTML( context, doc );
         }
-        catch( IOException e )
+        catch( final IOException e )
         {
             log.error("Failed to convert page data to HTML", e);
         }
@@ -434,19 +435,16 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
      *  A simple class that just cuts a String to a maximum
      *  length, adding three dots after the cutpoint.
      */
-    private static class CutMutator implements StringTransmutator
-    {
+    private static class CutMutator implements StringTransmutator {
+
         private int m_length;
 
-        public CutMutator( int length )
-        {
+        public CutMutator( final int length ) {
             m_length = length;
         }
 
-        public String mutate( WikiContext context, String text )
-        {
-            if( text.length() > m_length )
-            {
+        @Override public String mutate( final WikiContext context, final String text ) {
+            if( text.length() > m_length ) {
                 return text.substring( 0, m_length ) + "...";
             }
 
@@ -457,11 +455,11 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
     /**
      * Helper method to initialize the comparator for this page.
      */
-    private void initSorter( WikiContext context, Map< String, String > params ) {
-        String order = params.get( PARAM_SORTORDER );
+    private void initSorter( final WikiContext context, final Map< String, String > params ) {
+        final String order = params.get( PARAM_SORTORDER );
         if( order == null || order.length() == 0 ) {
             // Use the configured comparator
-            m_sorter = context.getEngine().getPageManager().getPageSorter();
+            m_sorter = context.getEngine().getManager( PageManager.class ).getPageSorter();
         } else if( order.equalsIgnoreCase( PARAM_SORTORDER_JAVA ) ) {
             // use Java "natural" ordering
             m_sorter = new PageSorter( JavaNaturalComparator.DEFAULT_JAVA_COMPARATOR );
@@ -472,16 +470,13 @@ public abstract class AbstractReferralPlugin implements WikiPlugin
             // use human ordering
             m_sorter = new PageSorter( HumanComparator.DEFAULT_HUMAN_COMPARATOR );
         } else {
-            try
-            {
-                Collator collator = new RuleBasedCollator( order );
+            try {
+                final Collator collator = new RuleBasedCollator( order );
                 collator.setStrength( Collator.PRIMARY );
                 m_sorter = new PageSorter( new CollatorComparator( collator ) );
-            }
-            catch( ParseException pe )
-            {
+            } catch( final ParseException pe ) {
                 log.info( "Failed to parse requested collator - using default ordering", pe );
-                m_sorter = context.getEngine().getPageManager().getPageSorter();
+                m_sorter = context.getEngine().getManager( PageManager.class ).getPageSorter();
             }
         }
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/BugReportHandler.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/BugReportHandler.java
index b725f7d..37eeda2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/BugReportHandler.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/BugReportHandler.java
@@ -20,12 +20,13 @@ package org.apache.wiki.plugin;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.RedirectException;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.preferences.Preferences;
 
@@ -72,7 +73,7 @@ public class BugReportHandler implements WikiPlugin {
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
         final String title = params.get( PARAM_TITLE );
         String description = params.get( PARAM_DESCRIPTION );
         String version = params.get( PARAM_VERSION );
@@ -141,7 +142,7 @@ public class BugReportHandler implements WikiPlugin {
             final WikiPage newPage = new WikiPage( context.getEngine(), pageName );
             final WikiContext newContext = (WikiContext)context.clone();
             newContext.setPage( newPage );
-            context.getEngine().getPageManager().saveText( newContext, str.toString() );
+            context.getEngine().getManager( PageManager.class ).saveText( newContext, str.toString() );
 
             final MessageFormat formatter = new MessageFormat("");
             formatter.applyPattern( rb.getString("bugreporthandler.new") );
@@ -163,11 +164,11 @@ public class BugReportHandler implements WikiPlugin {
      */
     private synchronized String findNextPage( final WikiContext context, final String title, final String baseName ) {
         final String basicPageName = ( ( baseName != null ) ? baseName : "Bug" ) + MarkupParser.cleanLink( title );
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
 
         String pageName = basicPageName;
         long   lastbug  = 2;
-        while( engine.getPageManager().wikiPageExists( pageName ) ) {
+        while( engine.getManager( PageManager.class ).wikiPageExists( pageName ) ) {
             pageName = basicPageName + lastbug++;
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Groups.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Groups.java
index 5a77dfc..6447a49 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Groups.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Groups.java
@@ -19,11 +19,12 @@
 package org.apache.wiki.plugin;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.auth.PrincipalComparator;
 import org.apache.wiki.auth.authorize.GroupManager;
+import org.apache.wiki.url.URLConstructor;
 
 import java.security.Principal;
 import java.util.Arrays;
@@ -46,10 +47,10 @@ public class Groups implements WikiPlugin {
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
         // Retrieve groups, and sort by name
-        final WikiEngine engine = context.getEngine();
-        final GroupManager groupMgr = engine.getGroupManager();
+        final Engine engine = context.getEngine();
+        final GroupManager groupMgr = engine.getManager( GroupManager.class );
         final Principal[] groups = groupMgr.getRoles();
         Arrays.sort( groups, COMPARATOR );
 
@@ -59,7 +60,7 @@ public class Groups implements WikiPlugin {
             final String name = groups[ i ].getName();
             
             // Make URL
-            final String url = engine.getURLConstructor().makeURL( WikiContext.VIEW_GROUP, name,  null );
+            final String url = engine.getManager( URLConstructor.class ).makeURL( WikiContext.VIEW_GROUP, name,  null );
             
             // Create hyperlink
             s.append( "<a href=\"" );
@@ -76,4 +77,5 @@ public class Groups implements WikiPlugin {
         }
         return s.toString();
     }
+
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java
index a6cb392..4461a77 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IfPlugin.java
@@ -30,8 +30,12 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.auth.AuthorizationManager;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.HttpUtil;
 import org.apache.wiki.util.TextUtil;
+import org.apache.wiki.variables.VariableManager;
 
 import java.security.Principal;
 import java.util.Map;
@@ -139,9 +143,9 @@ public class IfPlugin implements WikiPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
         return ifInclude( context,params )
-                ? context.getEngine().getRenderingManager().textToHTML( context, params.get( DefaultPluginManager.PARAM_BODY ) )
+                ? context.getEngine().getManager( RenderingManager.class ).textToHTML( context, params.get( DefaultPluginManager.PARAM_BODY ) )
                 : "" ;
     }
 
@@ -172,14 +176,14 @@ public class IfPlugin implements WikiPlugin
         include |= checkIP(context, ip);
 
         if( page != null ) {
-            final String content = context.getEngine().getPageManager().getPureText(page, WikiProvider.LATEST_VERSION).trim();
+            final String content = context.getEngine().getManager( PageManager.class ).getPureText(page, WikiProvider.LATEST_VERSION).trim();
             include |= checkContains(content,contains);
             include |= checkIs(content,is);
             include |= checkExists(context,page,exists);
         }
 
         if( var != null ) {
-            final String content = context.getEngine().getVariableManager().getVariable(context, var);
+            final String content = context.getEngine().getManager( VariableManager.class ).getVariable(context, var);
             include |= checkContains(content,contains);
             include |= checkIs(content,is);
             include |= checkVarExists(content,exists);
@@ -192,7 +196,7 @@ public class IfPlugin implements WikiPlugin
         if( exists == null ) {
             return false;
         }
-        return !context.getEngine().getPageManager().wikiPageExists( page ) ^ TextUtil.isPositive(exists);
+        return !context.getEngine().getManager( PageManager.class ).wikiPageExists( page ) ^ TextUtil.isPositive(exists);
     }
 
     private static boolean checkVarExists( final String varContent, final String exists ) {
@@ -219,9 +223,9 @@ public class IfPlugin implements WikiPlugin
                 invert = true;
             }
 
-            final Principal g = context.getEngine().getAuthorizationManager().resolvePrincipal( gname );
+            final Principal g = context.getEngine().getManager( AuthorizationManager.class ).resolvePrincipal( gname );
 
-            include |= context.getEngine().getAuthorizationManager().isUserInRole( context.getWikiSession(), g ) ^ invert;
+            include |= context.getEngine().getManager( AuthorizationManager.class ).isUserInRole( context.getWikiSession(), g ) ^ invert;
         }
         return include;
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Image.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Image.java
index 26142c9..16f7811 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Image.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Image.java
@@ -18,10 +18,8 @@
  */
 package org.apache.wiki.plugin;
 
-import java.util.Map;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.WikiPlugin;
@@ -29,6 +27,8 @@ import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.util.TextUtil;
 
+import java.util.Map;
+
 /**
  *  Provides an image plugin for better control than is possible with a simple image inclusion.
  *  <br> Most parameters are equivalents of the html image attributes.
@@ -87,7 +87,7 @@ public class Image
      *  This method is used to clean away things like quotation marks which
      *  a malicious user could use to stop processing and insert javascript.
      */
-    private static String getCleanParameter( Map<String, String> params, String paramId )
+    private static String getCleanParameter( final Map<String, String> params, final String paramId )
     {
         return TextUtil.replaceEntities( params.get( paramId ) );
     }
@@ -95,23 +95,23 @@ public class Image
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
+    @Override public String execute( final WikiContext context, final Map<String, String> params )
         throws PluginException
     {
-        WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
         String src     = getCleanParameter( params, PARAM_SRC );
-        String align   = getCleanParameter( params, PARAM_ALIGN );
-        String ht      = getCleanParameter( params, PARAM_HEIGHT );
-        String wt      = getCleanParameter( params, PARAM_WIDTH );
-        String alt     = getCleanParameter( params, PARAM_ALT );
-        String caption = getCleanParameter( params, PARAM_CAPTION );
-        String link    = getCleanParameter( params, PARAM_LINK );
+        final String align   = getCleanParameter( params, PARAM_ALIGN );
+        final String ht      = getCleanParameter( params, PARAM_HEIGHT );
+        final String wt      = getCleanParameter( params, PARAM_WIDTH );
+        final String alt     = getCleanParameter( params, PARAM_ALT );
+        final String caption = getCleanParameter( params, PARAM_CAPTION );
+        final String link    = getCleanParameter( params, PARAM_LINK );
         String target  = getCleanParameter( params, PARAM_TARGET );
-        String style   = getCleanParameter( params, PARAM_STYLE );
-        String cssclass= getCleanParameter( params, PARAM_CLASS );
+        final String style   = getCleanParameter( params, PARAM_STYLE );
+        final String cssclass= getCleanParameter( params, PARAM_CLASS );
         // String map     = getCleanParameter( params, PARAM_MAP );
-        String border  = getCleanParameter( params, PARAM_BORDER );
-        String title   = getCleanParameter( params, PARAM_TITLE );
+        final String border  = getCleanParameter( params, PARAM_BORDER );
+        final String title   = getCleanParameter( params, PARAM_TITLE );
 
         if( src == null )
         {
@@ -127,20 +127,20 @@ public class Image
 
         try
         {
-            AttachmentManager mgr = engine.getAttachmentManager();
-            Attachment        att = mgr.getAttachmentInfo( context, src );
+            final AttachmentManager mgr = engine.getManager( AttachmentManager.class );
+            final Attachment        att = mgr.getAttachmentInfo( context, src );
 
             if( att != null )
             {
                 src = context.getURL( WikiContext.ATTACH, att.getName() );
             }
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             throw new PluginException( "Attachment info failed: "+e.getMessage() );
         }
 
-        StringBuilder result = new StringBuilder();
+        final StringBuilder result = new StringBuilder();
 
         result.append( "<table border=\"0\" class=\"imageplugin\"" );
 
@@ -216,7 +216,7 @@ public class Image
         return result.toString();
     }
 
-    private boolean validTargetValue( String s )
+    private boolean validTargetValue( final String s )
     {
         if( s.equals("_blank")
                 || s.equals("_self")
@@ -227,7 +227,7 @@ public class Image
         }
         else if( s.length() > 0 ) // check [a-zA-z]
         {
-            char c = s.charAt(0);
+            final char c = s.charAt(0);
             return Character.isLowerCase(c) || Character.isUpperCase(c);
         }
         return false;
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IndexPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IndexPlugin.java
index 79c0431..3147d49 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/IndexPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/IndexPlugin.java
@@ -19,23 +19,25 @@
 
 package org.apache.wiki.plugin;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.references.ReferenceManager;
 import org.jdom2.Element;
 import org.jdom2.Namespace;
 import org.jdom2.output.Format;
 import org.jdom2.output.XMLOutputter;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
 /**
  *  A WikiPlugin that creates an index of pages according to a certain pattern.
  *  <br />
@@ -62,20 +64,20 @@ public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin
     /**
      * {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String,String> params ) throws PluginException
+    @Override public String execute( final WikiContext context, final Map<String,String> params ) throws PluginException
     {
-        String include = params.get(PARAM_INCLUDE);
-        String exclude = params.get(PARAM_EXCLUDE);
+        final String include = params.get(PARAM_INCLUDE);
+        final String exclude = params.get(PARAM_EXCLUDE);
         
-        Element masterDiv = getElement("div","index");     
-        Element indexDiv = getElement("div","header");
+        final Element masterDiv = getElement("div","index");
+        final Element indexDiv = getElement("div","header");
         masterDiv.addContent(indexDiv);
         try {
-            List<String> pages = listPages(context,include,exclude);
-            context.getEngine().getPageManager().getPageSorter().sort(pages);
+            final List<String> pages = listPages(context,include,exclude);
+            context.getEngine().getManager( PageManager.class ).getPageSorter().sort(pages);
             char initialChar = ' ';
             Element currentDiv = new Element("div",xmlns_XHTML);            
-            for ( String name : pages ) {
+            for ( final String name : pages ) {
                 if ( name.charAt(0) != initialChar ) {
                     if ( initialChar != ' ' ) {
                         indexDiv.addContent(" - ");
@@ -91,29 +93,29 @@ public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin
                 currentDiv.addContent(getLink(context.getURL(WikiContext.VIEW,name),name));
             }
             
-        } catch( ProviderException e ) {
+        } catch( final ProviderException e ) {
             log.warn("could not load page index",e);
             throw new PluginException( e.getMessage() );
         }
         // serialize to raw format string (no changes to whitespace)
-        XMLOutputter out = new XMLOutputter(Format.getRawFormat()); 
+        final XMLOutputter out = new XMLOutputter(Format.getRawFormat());
         return out.outputString(masterDiv);
     }
 
 
-    private Element getLink( String href, String content )
+    private Element getLink( final String href, final String content )
     {
-        Element a = new Element("a",xmlns_XHTML);
+        final Element a = new Element("a",xmlns_XHTML);
         a.setAttribute("href",href);
         a.addContent(content);
         return a;
     }
 
     
-    private Element makeHeader( String initialChar )
+    private Element makeHeader( final String initialChar )
     {
-        Element span = getElement("span","section");
-        Element a = new Element("a",xmlns_XHTML);
+        final Element span = getElement("span","section");
+        final Element a = new Element("a",xmlns_XHTML);
         a.setAttribute("id",initialChar);
         a.addContent(initialChar);
         span.addContent(a);
@@ -121,9 +123,9 @@ public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin
     }
 
     
-    private Element getElement( String gi, String classValue )
+    private Element getElement( final String gi, final String classValue )
     {
-        Element elt = new Element(gi,xmlns_XHTML);
+        final Element elt = new Element(gi,xmlns_XHTML);
         elt.setAttribute("class",classValue);
         return elt;
     }
@@ -138,13 +140,13 @@ public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin
      * @return A list containing page names which matched the filters.
      * @throws ProviderException
      */
-    private List<String> listPages( WikiContext context, String include, String exclude ) throws ProviderException {
-        Pattern includePtrn = include != null ? Pattern.compile( include ) : Pattern.compile(".*");
-        Pattern excludePtrn = exclude != null ? Pattern.compile( exclude ) : Pattern.compile("\\p{Cntrl}"); // there are no control characters in page names
-        List< String > result = new ArrayList<>();
-        Set< String > pages = context.getEngine().getReferenceManager().findCreated();
-        for ( Iterator<String> i = pages.iterator(); i.hasNext(); ) {
-            String pageName = i.next();
+    private List<String> listPages( final WikiContext context, final String include, final String exclude ) throws ProviderException {
+        final Pattern includePtrn = include != null ? Pattern.compile( include ) : Pattern.compile(".*");
+        final Pattern excludePtrn = exclude != null ? Pattern.compile( exclude ) : Pattern.compile("\\p{Cntrl}"); // there are no control characters in page names
+        final List< String > result = new ArrayList<>();
+        final Set< String > pages = context.getEngine().getManager( ReferenceManager.class ).findCreated();
+        for ( final Iterator<String> i = pages.iterator(); i.hasNext(); ) {
+            final String pageName = i.next();
             if ( excludePtrn.matcher( pageName ).matches() ) continue;
             if ( includePtrn.matcher( pageName ).matches() ) {
                 result.add( pageName );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/InsertPage.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/InsertPage.java
index d2b9449..e341041 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/InsertPage.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/InsertPage.java
@@ -19,14 +19,16 @@
 package org.apache.wiki.plugin;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.HttpUtil;
 import org.apache.wiki.util.TextUtil;
 
@@ -81,23 +83,21 @@ public class InsertPage
     /**
      *  {@inheritDoc}
      */
-    @SuppressWarnings("unchecked")
-    public String execute( WikiContext context, Map<String, String> params )
-        throws PluginException
-    {
-        WikiEngine engine = context.getEngine();
+    @Override @SuppressWarnings("unchecked")
+    public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
+        final Engine engine = context.getEngine();
 
-        StringBuilder res = new StringBuilder();
+        final StringBuilder res = new StringBuilder();
 
-        String clazz        = params.get( PARAM_CLASS );
-        String includedPage = params.get( PARAM_PAGENAME );
+        final String clazz        = params.get( PARAM_CLASS );
+        final String includedPage = params.get( PARAM_PAGENAME );
         String style        = params.get( PARAM_STYLE );
-        Boolean showOnce    = "once".equals( params.get( PARAM_SHOW ) );
-        String defaultstr   = params.get( PARAM_DEFAULT );
-        int    section      = TextUtil.parseIntParameter(params.get( PARAM_SECTION ), -1 );
+        final Boolean showOnce    = "once".equals( params.get( PARAM_SHOW ) );
+        final String defaultstr   = params.get( PARAM_DEFAULT );
+        final int    section      = TextUtil.parseIntParameter(params.get( PARAM_SECTION ), -1 );
         int    maxlen       = TextUtil.parseIntParameter(params.get( PARAM_MAXLENGTH ), -1 );
 
-        ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+        final ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
 
 
         if( style == null ) style = DEFAULT_STYLE;
@@ -106,13 +106,13 @@ public class InsertPage
 
         if( includedPage != null )
         {
-            WikiPage page;
+            final WikiPage page;
             try {
                 final String pageName = engine.getFinalPageName( includedPage );
                 if( pageName != null ) {
-                    page = engine.getPageManager().getPage( pageName );
+                    page = engine.getManager( PageManager.class ).getPage( pageName );
                 } else {
-                    page = engine.getPageManager().getPage( includedPage );
+                    page = engine.getManager( PageManager.class ).getPage( includedPage );
                 }
             } catch( final ProviderException e ) {
                 res.append( "<span class=\"error\">Page could not be found by the page provider.</span>" );
@@ -136,17 +136,15 @@ public class InsertPage
                 }
                 else
                 {
-                    previousIncludes = new ArrayList<String>();
+                    previousIncludes = new ArrayList<>();
                 }
 
                 //
                 // Check for permissions
                 //
-                AuthorizationManager mgr = engine.getAuthorizationManager();
+                final AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
 
-                if( !mgr.checkPermission( context.getWikiSession(),
-                                          PermissionFactory.getPagePermission( page, "view") ) )
-                {
+                if( !mgr.checkPermission( context.getWikiSession(), PermissionFactory.getPagePermission( page, "view") ) ) {
                     res.append("<span class=\"error\">You do not have permission to view this included page.</span>");
                     return res.toString();
                 }
@@ -180,10 +178,10 @@ public class InsertPage
                  *  its own page, because we need the links to be correct.
                  */
 
-                WikiContext includedContext = (WikiContext) context.clone();
+                final WikiContext includedContext = (WikiContext) context.clone();
                 includedContext.setPage( page );
 
-                String pageData = engine.getPageManager().getPureText( page );
+                String pageData = engine.getManager( PageManager.class ).getPureText( page );
                 String moreLink = "";
 
                 if( section != -1 ) {
@@ -206,7 +204,7 @@ public class InsertPage
                 if( showOnce ) res.append("\" data-once=\""+cookieName );
                 res.append("\" >");
 
-                res.append( engine.getRenderingManager().textToHTML( includedContext, pageData ) );
+                res.append( engine.getManager( RenderingManager.class ).textToHTML( includedContext, pageData ) );
                 res.append( moreLink );
 
                 res.append("</div>");
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ListLocksPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ListLocksPlugin.java
index 5e1dd2b..d88b00e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ListLocksPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ListLocksPlugin.java
@@ -18,11 +18,6 @@
  */
 package org.apache.wiki.plugin;
 
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
@@ -30,29 +25,27 @@ import org.apache.wiki.pages.PageLock;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+
 /**
- *  This is a plugin for the administrator: It allows him to see in a single
- *  glance who is editing what.
+ *  This is a plugin for the administrator: It allows him to see in a single glance who is editing what.
  *
  *  <p>Parameters : </p>
  *   NONE
  *  @since 2.0.22.
  */
-public class ListLocksPlugin
-    implements WikiPlugin
-{
+public class ListLocksPlugin implements WikiPlugin {
+
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
-        throws PluginException
-    {
-    	StringBuilder result = new StringBuilder();
-
-        PageManager mgr = context.getEngine().getPageManager();
-        List<PageLock> locks = mgr.getActiveLocks();
-        ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
-
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+    	final StringBuilder result = new StringBuilder();
+        final PageManager mgr = context.getEngine().getManager( PageManager.class );
+        final List< PageLock > locks = mgr.getActiveLocks();
+        final ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
         result.append("<table class=\"wikitable\">\n");
         result.append("<tr>\n");
         result.append( "<th>" + rb.getString( "plugin.listlocks.page" ) + "</th><th>" + rb.getString( "plugin.listlocks.locked.by" )
@@ -60,18 +53,11 @@ public class ListLocksPlugin
                        + rb.getString( "plugin.listlocks.expires" ) + "</th>\n" );
         result.append("</tr>");
 
-        if( locks.size() == 0 )
-        {
-            result.append( "<tr><td colspan=\"4\" class=\"odd\">" + rb.getString( "plugin.listlocks.no.locks.exist" )
-                           + "</td></tr>\n" );
-        }
-        else
-        {
+        if( locks.size() == 0 ) {
+            result.append( "<tr><td colspan=\"4\" class=\"odd\">" + rb.getString( "plugin.listlocks.no.locks.exist" ) + "</td></tr>\n" );
+        } else {
             int rowNum = 1;
-            for( Iterator<PageLock> i = locks.iterator(); i.hasNext(); )
-            {
-                PageLock lock = i.next();
-
+            for( final PageLock lock : locks ) {
                 result.append( rowNum % 2 != 0 ? "<tr class=\"odd\">" : "<tr>" );
                 result.append( "<td>" + lock.getPage() + "</td>" );
                 result.append( "<td>" + lock.getLocker() + "</td>" );
@@ -81,9 +67,7 @@ public class ListLocksPlugin
                 rowNum++;
             }
         }
-
         result.append("</table>");
-
         return result.toString();
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Note.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Note.java
index c3c02b3..4f9147d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Note.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Note.java
@@ -20,14 +20,15 @@
  */
 package org.apache.wiki.plugin;
 
-import java.util.Map;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.ui.TemplateManager;
 import org.apache.wiki.util.TextUtil;
 
+import java.util.Map;
+
 /**
  * Outputs an image with the supplied text as the <tt>title</tt> which is shown as a tooltip by
  * most browsers. This is intended for short one line comments.
@@ -60,33 +61,31 @@ public class Note implements WikiPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute(WikiContext context, Map<String, String> params) throws PluginException
+    @Override public String execute( final WikiContext context, final Map<String, String> params) throws PluginException
     {
-        String commandline = params.get(DefaultPluginManager.PARAM_CMDLINE);
+        final String commandline = params.get(DefaultPluginManager.PARAM_CMDLINE);
         if (commandline == null || commandline.length() == 0)
         {
             return "Unable to obtain plugin command line from parameter'" + DefaultPluginManager.PARAM_CMDLINE + "'"; // I18N
         }
 
-        String commentImage = imageUrl(context);
+        final String commentImage = imageUrl(context);
 
-        String commentText = clean(commandline);
+        final String commentText = clean(commandline);
 
         return "<img src='" + commentImage + "' alt=\"Comment: " + 
                commentText + "\" title=\"" + commentText + "\"/>";
     }
 
-    private String imageUrl( WikiContext ctx )
+    private String imageUrl( final WikiContext ctx )
     {
-        WikiEngine engine = ctx.getEngine();
+        final Engine engine = ctx.getEngine();
         String commentImage = engine.getWikiProperties().getProperty(PROP_NOTE_IMAGE,
                                                                      DEFAULT_NOTE_IMAGE);
 
         commentImage = "images/"+commentImage;
         
-        String resource = engine.getTemplateManager().findResource( ctx, 
-                                                                    engine.getTemplateDir(), 
-                                                                    commentImage );
+        String resource = engine.getManager( TemplateManager.class ).findResource( ctx, engine.getTemplateDir(), commentImage );
         
         // JSPWIKI-876 Fixed error with Note Plugin. Only one preceding "/" is needed.
         if (resource != null && resource.startsWith("/")) {
@@ -101,7 +100,7 @@ public class Note implements WikiPlugin
      * 
      * @param commandline
      */
-    private String clean(String commandline)
+    private String clean( final String commandline)
     {
         return TextUtil.replaceEntities( commandline );
     }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/PageViewPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/PageViewPlugin.java
index 1981a44..58777b4 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/PageViewPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/PageViewPlugin.java
@@ -31,6 +31,7 @@ import org.apache.wiki.WikiBackgroundThread;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.InitializablePlugin;
 import org.apache.wiki.api.plugin.WikiPlugin;
@@ -40,6 +41,7 @@ import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiPageEvent;
 import org.apache.wiki.event.WikiPageRenameEvent;
 import org.apache.wiki.references.ReferenceManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 
 import java.io.File;
@@ -132,7 +134,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
      * 
      * @param engine The wiki engine.
      */
-    public void initialize( WikiEngine engine )
+    @Override public void initialize( final WikiEngine engine )
     {
 
         log.info( "initializing PageViewPlugin" );
@@ -160,9 +162,9 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params ) throws PluginException
+    @Override public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException
     {
-        PageViewManager manager = c_singleton;
+        final PageViewManager manager = c_singleton;
         String result = STR_EMPTY;
 
         if( manager != null )
@@ -198,7 +200,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
 
         /** Comparator for descending sort on page count. */
         private final Comparator<Object> m_compareCountDescending = new Comparator<Object>() {
-            public int compare( Object o1, Object o2 )
+            @Override public int compare( final Object o1, final Object o2 )
             {
                 final int v1 = getCount( o1 );
                 final int v2 = getCount( o2 );
@@ -211,7 +213,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * 
          * @param engine The wiki engine.
          */
-        public synchronized void initialize( WikiEngine engine )
+        public synchronized void initialize( final WikiEngine engine )
         {
             log.info( "initializing PageView Manager" );
 
@@ -223,7 +225,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
             {
                 // Load the counters into a collection
                 m_storage = new Properties();
-                m_counters = new TreeMap<String, Counter>();
+                m_counters = new TreeMap<>();
 
                 loadCounters();
             }
@@ -271,7 +273,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * 
          * @param event The wiki event to inspect.
          */
-        public void actionPerformed( WikiEvent event )
+        @Override public void actionPerformed( final WikiEvent event )
         {
             if( event instanceof WikiEngineEvent )
             {
@@ -283,9 +285,9 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
             } 
             else if( (event instanceof WikiPageRenameEvent) && (event.getType() == WikiPageRenameEvent.PAGE_RENAMED) )
             {
-                String oldPageName = ((WikiPageRenameEvent) event).getOldPageName();
-                String newPageName = ((WikiPageRenameEvent) event).getNewPageName();
-                Counter oldCounter = m_counters.get(oldPageName);
+                final String oldPageName = ((WikiPageRenameEvent) event).getOldPageName();
+                final String newPageName = ((WikiPageRenameEvent) event).getNewPageName();
+                final Counter oldCounter = m_counters.get(oldPageName);
                 if ( oldCounter != null )
                 {
                     m_storage.remove(oldPageName);
@@ -297,7 +299,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
             }
             else if( (event instanceof WikiPageEvent) && (event.getType() == WikiPageEvent.PAGE_DELETED) )
             {
-                 String pageName = ((WikiPageEvent) event).getPageName();
+                 final String pageName = ((WikiPageEvent) event).getPageName();
                  m_storage.remove(pageName);
                  m_counters.remove(pageName);
             }
@@ -311,27 +313,26 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * @return String Wiki page snippet
          * @throws PluginException Malformed pattern parameter.
          */
-        public String execute( WikiContext context, Map<String, String> params ) throws PluginException
-        {
-            WikiEngine engine = context.getEngine();
-            WikiPage page = context.getPage();
+        public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
+            final Engine engine = context.getEngine();
+            final WikiPage page = context.getPage();
             String result = STR_EMPTY;
 
             if( page != null )
             {
                 // get parameters
-                String pagename = page.getName();
+                final String pagename = page.getName();
                 String count = params.get( PARAM_COUNT );
-                String show = params.get( PARAM_SHOW );
+                final String show = params.get( PARAM_SHOW );
                 int entries = TextUtil.parseIntParameter( params.get( PARAM_MAX_ENTRIES ), Integer.MAX_VALUE );
                 final int max = TextUtil.parseIntParameter( params.get( PARAM_MAX_COUNT ), Integer.MAX_VALUE );
                 final int min = TextUtil.parseIntParameter( params.get( PARAM_MIN_COUNT ), Integer.MIN_VALUE );
-                String sort = params.get( PARAM_SORT );
-                String body = params.get( DefaultPluginManager.PARAM_BODY );
-                Pattern[] exclude = compileGlobs( PARAM_EXCLUDE, params.get( PARAM_EXCLUDE ) );
-                Pattern[] include = compileGlobs( PARAM_INCLUDE, params.get( PARAM_INCLUDE ) );
-                Pattern[] refer = compileGlobs( PARAM_REFER, params.get( PARAM_REFER ) );
-                PatternMatcher matcher = (null != exclude || null != include || null != refer) ? new Perl5Matcher() : null;
+                final String sort = params.get( PARAM_SORT );
+                final String body = params.get( DefaultPluginManager.PARAM_BODY );
+                final Pattern[] exclude = compileGlobs( PARAM_EXCLUDE, params.get( PARAM_EXCLUDE ) );
+                final Pattern[] include = compileGlobs( PARAM_INCLUDE, params.get( PARAM_INCLUDE ) );
+                final Pattern[] refer = compileGlobs( PARAM_REFER, params.get( PARAM_REFER ) );
+                final PatternMatcher matcher = (null != exclude || null != include || null != refer) ? new Perl5Matcher() : null;
                 boolean increment = false;
 
                 // increment counter?
@@ -355,13 +356,13 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
 
                 if( refer != null )
                 {
-                    ReferenceManager refManager = engine.getReferenceManager();
+                    final ReferenceManager refManager = engine.getManager( ReferenceManager.class );
 
-                    Iterator< String > iter = refManager.findCreated().iterator();
+                    final Iterator< String > iter = refManager.findCreated().iterator();
 
                     while ( iter != null && iter.hasNext() )
                     {
-                        String name = iter.next();
+                        final String name = iter.next();
                         boolean use = false;
 
                         for( int n = 0; !use && n < refer.length; n++ )
@@ -371,13 +372,13 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
 
                         if( use )
                         {
-                            Collection< String > refs = engine.getReferenceManager().findReferrers( name );
+                            final Collection< String > refs = engine.getManager( ReferenceManager.class ).findReferrers( name );
 
                             if( refs != null && !refs.isEmpty() )
                             {
                                 if( referrers == null )
                                 {
-                                    referrers = new HashSet<String>();
+                                    referrers = new HashSet<>();
                                 }
                                 referrers.addAll( refs );
                             }
@@ -458,21 +459,21 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
 
                         if( sort != null && PARAM_COUNT.equals( sort ) )
                         {
-                            sorted = new TreeMap<String, Counter>( m_compareCountDescending );
+                            sorted = new TreeMap<>( m_compareCountDescending );
 
                             sorted.putAll( m_counters );
                         }
 
                         // build a messagebuffer with the list in wiki markup
-                        StringBuffer buf = new StringBuffer( header );
-                        MessageFormat fmt = new MessageFormat( line );
-                        Object[] args = new Object[] { pagename, STR_EMPTY, STR_EMPTY };
-                        Iterator< Entry< String, Counter > > iter = sorted.entrySet().iterator();
+                        final StringBuffer buf = new StringBuffer( header );
+                        final MessageFormat fmt = new MessageFormat( line );
+                        final Object[] args = new Object[] { pagename, STR_EMPTY, STR_EMPTY };
+                        final Iterator< Entry< String, Counter > > iter = sorted.entrySet().iterator();
 
                         while ( iter != null && 0 < entries && iter.hasNext() )
                         {
-                            Entry< String, Counter > entry = iter.next();
-                            String name = entry.getKey();
+                            final Entry< String, Counter > entry = iter.next();
+                            final String name = entry.getKey();
 
                             // check minimum/maximum count
                             final int value = entry.getValue().getValue();
@@ -506,7 +507,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
 
                             if( use )
                             {
-                                args[1] = engine.getRenderingManager().beautifyTitle( name );
+                                args[1] = engine.getManager( RenderingManager.class ).beautifyTitle( name );
                                 args[2] = entry.getValue();
 
                                 fmt.format( args, buf, null );
@@ -517,7 +518,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
                         buf.append( footer );
 
                         // let the engine render the list
-                        result = engine.getRenderingManager().textToHTML( context, buf.toString() );
+                        result = engine.getManager( RenderingManager.class ).textToHTML( context, buf.toString() );
                     }
                 }
             }
@@ -532,7 +533,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * @return Pattern[] The compiled patterns, or <code>null</code>.
          * @throws PluginException On malformed patterns.
          */
-        private Pattern[] compileGlobs( String name, String value ) throws PluginException
+        private Pattern[] compileGlobs( final String name, final String value ) throws PluginException
         {
             Pattern[] result = null;
 
@@ -540,9 +541,9 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
             {
                 try
                 {
-                    PatternCompiler pc = new GlobCompiler();
+                    final PatternCompiler pc = new GlobCompiler();
 
-                    String[] ptrns = StringUtils.split( value, STR_COMMA );
+                    final String[] ptrns = StringUtils.split( value, STR_COMMA );
 
                     result = new Pattern[ptrns.length];
 
@@ -551,7 +552,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
                         result[n] = pc.compile( ptrns[n] );
                     }
                 }
-                catch( MalformedPatternException e )
+                catch( final MalformedPatternException e )
                 {
                     throw new PluginException( "Parameter " + name + " has a malformed pattern: " + e.getMessage() );
                 }
@@ -567,7 +568,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * @param value String in which offset points.
          * @return int Adjusted offset into value.
          */
-        private int skipWhitespace( int offset, String value )
+        private int skipWhitespace( int offset, final String value )
         {
             while ( Character.isWhitespace( value.charAt( offset ) ) )
             {
@@ -582,7 +583,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * @return int The page count for the given key.
          * @param key the key for the Counter
          */
-        protected int getCount( Object key )
+        protected int getCount( final Object key )
         {
             return m_counters.get( key ).getValue();
         }
@@ -594,17 +595,17 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
             if( m_counters != null && m_storage != null ) {
                 log.info( "Loading counters." );
                 synchronized( this ) {
-                    try( InputStream fis = new FileInputStream( new File( m_workDir, COUNTER_PAGE ) ) ) {
+                    try( final InputStream fis = new FileInputStream( new File( m_workDir, COUNTER_PAGE ) ) ) {
                         m_storage.load( fis );
-                    } catch( IOException ioe ) {
+                    } catch( final IOException ioe ) {
                         log.error( "Can't load page counter store: " + ioe.getMessage() + " , will create a new one!" );
                     }
 
                     // Copy the collection into a sorted map
-                    Iterator< Entry< Object, Object > > iter = m_storage.entrySet().iterator();
+                    final Iterator< Entry< Object, Object > > iter = m_storage.entrySet().iterator();
 
                     while ( iter != null && iter.hasNext() ) {
-                        Entry< ?, ? > entry = iter.next();
+                        final Entry< ?, ? > entry = iter.next();
                         m_counters.put( (String) entry.getKey(), new Counter( (String) entry.getValue() ) );
                     }
                     
@@ -626,7 +627,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
                         fos.flush();
 
                         m_dirty = false;
-                    } catch( IOException ioe ) {
+                    } catch( final IOException ioe ) {
                         log.error( "Couldn't store counters values: " + ioe.getMessage() );
                     }
                 }
@@ -640,7 +641,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          *         background thread.
          * @param thrd
          */
-        private synchronized boolean isRunning( Thread thrd )
+        private synchronized boolean isRunning( final Thread thrd )
         {
             return m_initialized && thrd == m_pageCountSaveThread;
         }
@@ -669,7 +670,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * 
          * @param value Count value.
          */
-        public Counter( String value )
+        public Counter( final String value )
         {
             setValue( value );
         }
@@ -697,7 +698,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * 
          * @param value String representation of the count.
          */
-        public void setValue( String value )
+        public void setValue( final String value )
         {
             m_count = NumberUtils.toInt( value );
         }
@@ -705,7 +706,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
         /**
          * @return String String representation of the count.
          */
-        public String toString()
+        @Override public String toString()
         {
             return String.valueOf( m_count );
         }
@@ -727,7 +728,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
          * @param interval Delay in seconds between saves.
          * @param pageViewManager
          */
-        public CounterSaveThread( WikiEngine engine, int interval, PageViewManager pageViewManager )
+        public CounterSaveThread( final WikiEngine engine, final int interval, final PageViewManager pageViewManager )
         {
 
             super( engine, interval );
@@ -743,7 +744,7 @@ public class PageViewPlugin extends AbstractReferralPlugin implements WikiPlugin
         /**
          * Save the page counters to file.
          */
-        public void backgroundTask()
+        @Override public void backgroundTask()
         {
 
             if( m_manager.isRunning( this ) )
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/RecentChangesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/RecentChangesPlugin.java
index d68b0db..4351603 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/RecentChangesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/RecentChangesPlugin.java
@@ -21,14 +21,16 @@ package org.apache.wiki.plugin;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.preferences.Preferences.TimeFormat;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 import org.apache.wiki.util.XHTML;
 import org.apache.wiki.util.XhtmlUtil;
@@ -74,14 +76,14 @@ public class RecentChangesPlugin extends AbstractReferralPlugin implements WikiP
     /**
      * {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
         final int since = TextUtil.parseIntParameter( params.get( "since" ), DEFAULT_DAYS );
         String spacing  = "4";
         boolean showAuthor = true;
         boolean showChangenote = true;
         String tablewidth = "4";
         
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
 
         //
         //  Which format we want to see?
@@ -99,7 +101,7 @@ public class RecentChangesPlugin extends AbstractReferralPlugin implements WikiP
         log.debug("Calculating recent changes from "+sincedate.getTime());
 
         // FIXME: Should really have a since date on the getRecentChanges method.
-        Collection< WikiPage > changes = engine.getPageManager().getRecentChanges();
+        Collection< WikiPage > changes = engine.getManager( PageManager.class ).getRecentChanges();
         super.initialize( context, params );
         changes = filterWikiPageCollection( changes );
         
@@ -133,7 +135,7 @@ public class RecentChangesPlugin extends AbstractReferralPlugin implements WikiP
                 }
 
                 final String href = context.getURL( pageref instanceof Attachment ? WikiContext.ATTACH : WikiContext.VIEW, pageref.getName() );
-                Element link = XhtmlUtil.link( href, engine.getRenderingManager().beautifyTitle( pageref.getName() ) );
+                Element link = XhtmlUtil.link( href, engine.getManager( RenderingManager.class ).beautifyTitle( pageref.getName() ) );
                 final Element row = XhtmlUtil.element( XHTML.tr );
                 final Element col = XhtmlUtil.element( XHTML.td );
                 col.setAttribute( XHTML.ATTR_width, "30%" );
@@ -177,7 +179,7 @@ public class RecentChangesPlugin extends AbstractReferralPlugin implements WikiP
                     authorinfo.setAttribute( XHTML.ATTR_class, "author" );
 
                     if( author != null ) {
-                        if( engine.getPageManager().wikiPageExists( author ) ) {
+                        if( engine.getManager( PageManager.class ).wikiPageExists( author ) ) {
                             authorinfo.addContent( XhtmlUtil.link( context.getURL( WikiContext.VIEW, author ), author ) );
                         } else {
                             authorinfo.addContent( author );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferredPagesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferredPagesPlugin.java
index a284660..ab4b122 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferredPagesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferredPagesPlugin.java
@@ -26,10 +26,11 @@ import org.apache.oro.text.regex.PatternMatcher;
 import org.apache.oro.text.regex.Perl5Compiler;
 import org.apache.oro.text.regex.Perl5Matcher;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.references.ReferenceManager;
 import org.apache.wiki.util.TextUtil;
 
@@ -56,7 +57,7 @@ import java.util.Map;
 public class ReferredPagesPlugin implements WikiPlugin {
 
     private static final Logger log = Logger.getLogger( ReferredPagesPlugin.class );
-    private WikiEngine     m_engine;
+    private Engine         m_engine;
     private int            m_depth;
     private HashSet<String> m_exists  = new HashSet<>();
     private StringBuffer   m_result  = new StringBuffer(1024);
@@ -93,7 +94,7 @@ public class ReferredPagesPlugin implements WikiPlugin {
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
         m_engine = context.getEngine();
         final WikiPage page = context.getPage();
         if( page == null ) {
@@ -185,11 +186,11 @@ public class ReferredPagesPlugin implements WikiPlugin {
         if( pagename == null ) {
             return;
         }
-        if( !m_engine.getPageManager().wikiPageExists(pagename) ) {
+        if( !m_engine.getManager( PageManager.class ).wikiPageExists(pagename) ) {
             return;
         }
 
-        final ReferenceManager mgr = m_engine.getReferenceManager();
+        final ReferenceManager mgr = m_engine.getManager( ReferenceManager.class );
         final Collection< String > allPages = mgr.findRefersTo( pagename );
         handleLinks( context, allPages, ++depth, pagename );
     }
@@ -205,7 +206,7 @@ public class ReferredPagesPlugin implements WikiPlugin {
         if( links != null )
             allLinks.addAll( links );
 
-        if( m_formatSort ) context.getEngine().getPageManager().getPageSorter().sort( allLinks );
+        if( m_formatSort ) context.getEngine().getManager( PageManager.class ).getPageSorter().sort( allLinks );
 
         for( final String link : allLinks ) {
             if( localLinkSet.contains( link ) ) {
@@ -213,7 +214,7 @@ public class ReferredPagesPlugin implements WikiPlugin {
             }
             localLinkSet.add( link );
 
-            if( !m_engine.getPageManager().wikiPageExists( link ) ) {
+            if( !m_engine.getManager( PageManager.class ).wikiPageExists( link ) ) {
                 continue; // hide links to non existing pages
             }
             if(  m_matcher.matches( link , m_excludePattern ) ) {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringPagesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringPagesPlugin.java
index 51596ff..c889e92 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringPagesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringPagesPlugin.java
@@ -23,6 +23,7 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.references.ReferenceManager;
 import org.apache.wiki.util.TextUtil;
@@ -69,12 +70,12 @@ public class ReferringPagesPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
+    @Override public String execute( final WikiContext context, final Map<String, String> params )
         throws PluginException
     {
-        ReferenceManager refmgr = context.getEngine().getReferenceManager();
+        final ReferenceManager refmgr = context.getEngine().getManager( ReferenceManager.class );
         String pageName = params.get( PARAM_PAGE );
-        ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+        final ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
 
         StringBuilder result = new StringBuilder( 256 );
 
@@ -83,7 +84,7 @@ public class ReferringPagesPlugin
             pageName = context.getPage().getName();
         }
 
-        WikiPage page = context.getEngine().getPageManager().getPage( pageName );
+        final WikiPage page = context.getEngine().getManager( PageManager.class ).getPage( pageName );
 
         if( page != null )
         {
@@ -92,7 +93,7 @@ public class ReferringPagesPlugin
 
             super.initialize( context, params );
 
-            int items = TextUtil.parseIntParameter( params.get( PARAM_MAX ), ALL_ITEMS );
+            final int items = TextUtil.parseIntParameter( params.get( PARAM_MAX ), ALL_ITEMS );
 
             String extras = TextUtil.replaceEntities( params.get( PARAM_EXTRAS ) );
             if( extras == null )
@@ -113,7 +114,7 @@ public class ReferringPagesPlugin
 
                 if( items < links.size() && items > 0 )
                 {
-                    Object[] args = { "" + ( links.size() - items) };
+                    final Object[] args = { "" + ( links.size() - items) };
                     extras = MessageFormat.format(extras, args);
 
                     result.append( "<br />" );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringUndefinedPagesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringUndefinedPagesPlugin.java
index 93a7916..af03f85 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringUndefinedPagesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/ReferringUndefinedPagesPlugin.java
@@ -45,31 +45,31 @@ public class ReferringUndefinedPagesPlugin extends AbstractReferralPlugin {
     /** Parameter name for setting the text to show when the maximum items is overruled. Value is <tt>{@value}</tt>. */
     public static final String PARAM_EXTRAS = "extras";
 
-    public String execute(WikiContext context, Map<String, String> params) throws PluginException {
-        ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
+    @Override public String execute( final WikiContext context, final Map<String, String> params) throws PluginException {
+        final ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
 
-        ReferenceManager referenceManager = context.getEngine().getReferenceManager();
+        final ReferenceManager referenceManager = context.getEngine().getManager( ReferenceManager.class );
 
-        int items = TextUtil.parseIntParameter(params.get(PARAM_MAX), ALL_ITEMS);
+        final int items = TextUtil.parseIntParameter(params.get(PARAM_MAX), ALL_ITEMS);
         String extras = params.get(PARAM_EXTRAS);
         if (extras == null) {
             extras = rb.getString("referringundefinedpagesplugin.more");
         }
 
-        StringBuilder resultHTML = new StringBuilder();
+        final StringBuilder resultHTML = new StringBuilder();
 
-        Collection<String> uncreatedPages = referenceManager.findUncreated();
+        final Collection<String> uncreatedPages = referenceManager.findUncreated();
 
         super.initialize(context, params);
 
         Collection<String> result = null;
 
-        TreeMap< String, String > sortedMap = new TreeMap<>();
+        final TreeMap< String, String > sortedMap = new TreeMap<>();
         if (uncreatedPages != null) {
-            for (String uncreatedPageName : uncreatedPages) {
-                Collection<String> referrers = referenceManager.findReferrers(uncreatedPageName);
+            for ( final String uncreatedPageName : uncreatedPages) {
+                final Collection<String> referrers = referenceManager.findReferrers(uncreatedPageName);
                 if (referrers != null) {
-                    for (String referringPage : referrers) {
+                    for ( final String referringPage : referrers) {
                         sortedMap.put(referringPage, "");
                     }
                 }
@@ -79,13 +79,13 @@ public class ReferringUndefinedPagesPlugin extends AbstractReferralPlugin {
 
         result = super.filterAndSortCollection(result);
 
-        String wikitext = wikitizeCollection(result, m_separator, items);
+        final String wikitext = wikitizeCollection(result, m_separator, items);
 
         resultHTML.append(makeHTML(context, wikitext));
 
         // add the more.... text
         if (items < result.size() && items > 0) {
-            Object[] args = {"" + (result.size() - items)};
+            final Object[] args = {"" + (result.size() - items)};
             extras = MessageFormat.format(extras, args);
 
             resultHTML.append("<br/>" + extras + "<br/>");
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Search.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Search.java
index 571189d..0006a51 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/Search.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/Search.java
@@ -20,10 +20,12 @@ package org.apache.wiki.plugin;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.render.RenderingManager;
+import org.apache.wiki.search.SearchManager;
 import org.apache.wiki.search.SearchResult;
 import org.apache.wiki.util.XHTML;
 import org.apache.wiki.util.XhtmlUtil;
@@ -67,13 +69,13 @@ public class Search implements WikiPlugin {
      */
     @SuppressWarnings("unchecked")
     @Override
-    public String execute( WikiContext context, Map<String, String> params ) throws PluginException {
+    public String execute( final WikiContext context, final Map<String, String> params ) throws PluginException {
         int maxItems = Integer.MAX_VALUE;
         Collection<SearchResult> results = null;
 
-        String queryString = params.get( PARAM_QUERY );
+        final String queryString = params.get( PARAM_QUERY );
         String set         = params.get( PARAM_SET );
-        String max         = params.get( PARAM_MAX );
+        final String max         = params.get( PARAM_MAX );
 
         if ( set == null ) set = DEFAULT_SETNAME;
         if ( max != null ) maxItems = Integer.parseInt( max );
@@ -89,7 +91,7 @@ public class Search implements WikiPlugin {
                 results = doBasicQuery( context, queryString );
                 context.setVariable( set, results );
             }
-            catch( Exception e )
+            catch( final Exception e )
             {
                 return "<div class='error'>"+e.getMessage()+"</div>\n";
             }
@@ -105,21 +107,21 @@ public class Search implements WikiPlugin {
         return res;
     }
 
-    private Collection<SearchResult> doBasicQuery( WikiContext context, String query )
+    private Collection<SearchResult> doBasicQuery( final WikiContext context, final String query )
         throws ProviderException, IOException
     {
         log.debug("Searching for string "+query);
 
-        Collection<SearchResult> list = context.getEngine().getSearchManager().findPages( query, context );
+        final Collection<SearchResult> list = context.getEngine().getManager( SearchManager.class ).findPages( query, context );
 
         return list;
     }
 
-    private String renderResults( Collection<SearchResult> results, WikiContext context, int maxItems )
+    private String renderResults( final Collection<SearchResult> results, final WikiContext context, final int maxItems )
     {
-        WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
 
-        Element table = XhtmlUtil.element(XHTML.table);
+        final Element table = XhtmlUtil.element(XHTML.table);
         //table.setAttribute(XHTML.ATTR_border,"0");
         //table.setAttribute(XHTML.ATTR_cellpadding,"4");
         table.setAttribute(XHTML.ATTR_class,"wikitable search-result");
@@ -127,26 +129,26 @@ public class Search implements WikiPlugin {
         Element row = XhtmlUtil.element(XHTML.tr);
         table.addContent(row);
 
-        Element th1 = XhtmlUtil.element(XHTML.th,"Page");
+        final Element th1 = XhtmlUtil.element(XHTML.th,"Page");
         th1.setAttribute(XHTML.ATTR_width,"30%");
         th1.setAttribute(XHTML.ATTR_align,"left");
         row.addContent(th1);
 
-        Element th2 = XhtmlUtil.element(XHTML.th,"Score");
+        final Element th2 = XhtmlUtil.element(XHTML.th,"Score");
         th2.setAttribute(XHTML.ATTR_align,"left");
         row.addContent(th2);
 
         int idx = 0;
-        for ( Iterator<SearchResult> i = results.iterator(); i.hasNext() && idx++ <= maxItems; )
+        for ( final Iterator<SearchResult> i = results.iterator(); i.hasNext() && idx++ <= maxItems; )
         {
-            SearchResult sr = i.next();
+            final SearchResult sr = i.next();
             row = XhtmlUtil.element(XHTML.tr);
 
-            Element name = XhtmlUtil.element(XHTML.td);
+            final Element name = XhtmlUtil.element(XHTML.td);
             name.setAttribute(XHTML.ATTR_width,"30%");
 
             name.addContent( XhtmlUtil.link(context.getURL( WikiContext.VIEW, sr.getPage().getName()),
-                    engine.getRenderingManager().beautifyTitle(sr.getPage().getName())) );
+                    engine.getManager( RenderingManager.class ).beautifyTitle(sr.getPage().getName())) );
 
             row.addContent(name);
 
@@ -159,9 +161,9 @@ public class Search implements WikiPlugin {
         {
             row = XhtmlUtil.element(XHTML.tr);
 
-            Element td = XhtmlUtil.element(XHTML.td);
+            final Element td = XhtmlUtil.element(XHTML.td);
             td.setAttribute(XHTML.ATTR_colspan,"2");
-            Element b = XhtmlUtil.element(XHTML.b,"No results");
+            final Element b = XhtmlUtil.element(XHTML.b,"No results");
             td.addContent(b);
 
             row.addContent(td);
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/SessionsPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/SessionsPlugin.java
index 141a69e..aba5a0b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/SessionsPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/SessionsPlugin.java
@@ -18,18 +18,18 @@
  */
 package org.apache.wiki.plugin;
 
-import java.security.Principal;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.util.TextUtil;
 
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
 /**
  *  <p>Displays information about active wiki sessions. The parameter
  *  <code>property</code> specifies what information is displayed.
@@ -56,16 +56,16 @@ public class SessionsPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
+    @Override public String execute( final WikiContext context, final Map<String, String> params )
         throws PluginException
     {
-        WikiEngine engine = context.getEngine();
-        String prop = params.get( PARAM_PROP );
+        final Engine engine = context.getEngine();
+        final String prop = params.get( PARAM_PROP );
 
         if ( "users".equals( prop ) )
         {
-            Principal[] principals = WikiSession.userPrincipals( engine );
-            StringBuilder s = new StringBuilder();
+            final Principal[] principals = WikiSession.userPrincipals( engine );
+            final StringBuilder s = new StringBuilder();
             for ( int i = 0; i < principals.length; i++ )
             {
                 s.append(principals[i].getName() + ", ");
@@ -79,13 +79,13 @@ public class SessionsPlugin
         // number of sessions for each user)
         if ("distinctUsers".equals(prop))
         {
-            Principal[] principals = WikiSession.userPrincipals(engine);
+            final Principal[] principals = WikiSession.userPrincipals(engine);
             // we do not assume that the principals are sorted, so first count
             // them :
-            HashMap<String,Integer> distinctPrincipals = new HashMap<String,Integer>();
+            final HashMap<String,Integer> distinctPrincipals = new HashMap<>();
             for (int i = 0; i < principals.length; i++)
             {
-                String principalName = principals[i].getName();
+                final String principalName = principals[i].getName();
 
                 if (distinctPrincipals.containsKey(principalName))
                 {
@@ -102,11 +102,11 @@ public class SessionsPlugin
             }
             //
             //
-            StringBuilder s = new StringBuilder();
-            Iterator<Map.Entry<String, Integer>> entries = distinctPrincipals.entrySet().iterator();
+            final StringBuilder s = new StringBuilder();
+            final Iterator<Map.Entry<String, Integer>> entries = distinctPrincipals.entrySet().iterator();
             while (entries.hasNext())
             {
-                Map.Entry<String, Integer> entry = entries.next();
+                final Map.Entry<String, Integer> entry = entries.next();
                 s.append( entry.getKey() + "(" + entry.getValue().toString() + "), " );
             }
             // remove the last comma and blank :
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/TableOfContents.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/TableOfContents.java
index 79bc6c2..4b082d4 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/TableOfContents.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/TableOfContents.java
@@ -21,15 +21,17 @@ package org.apache.wiki.plugin;
 import org.apache.log4j.Logger;
 import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.engine.FilterManager;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.Heading;
 import org.apache.wiki.parser.HeadingListener;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 import org.apache.wiki.variables.VariableManager;
 
@@ -80,7 +82,7 @@ public class TableOfContents
     /**
      *  {@inheritDoc}
      */
-    public void headingAdded( WikiContext context, Heading hd )
+    @Override public void headingAdded( final WikiContext context, final Heading hd )
     {
         log.debug("HD: "+hd.m_level+", "+hd.m_titleText+", "+hd.m_titleAnchor);
 
@@ -118,10 +120,10 @@ public class TableOfContents
             m_level2Index = 0;
         }
 
-        String titleSection = hd.m_titleSection.replace( '%', '_' );
-        String pageName = context.getEngine().encodeName(context.getPage().getName()).replace( '%', '_' );
+        final String titleSection = hd.m_titleSection.replace( '%', '_' );
+        final String pageName = context.getEngine().encodeName(context.getPage().getName()).replace( '%', '_' );
 
-        String sectref = "#section-"+pageName+"-"+titleSection;
+        final String sectref = "#section-"+pageName+"-"+titleSection;
 
         m_buf.append( "<a class=\"wikipage\" href=\"" + sectref + "\">" );
         if (m_usingNumberedList)
@@ -149,12 +151,12 @@ public class TableOfContents
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
+    @Override public String execute( final WikiContext context, final Map<String, String> params )
         throws PluginException
     {
-        WikiEngine engine = context.getEngine();
-        WikiPage   page   = context.getPage();
-        ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+        final Engine engine = context.getEngine();
+        final WikiPage page = context.getPage();
+        final ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
 
         if( context.getVariable( VAR_ALREADY_PROCESSING ) != null )
         {
@@ -162,12 +164,12 @@ public class TableOfContents
             return "<a href=\"#section-TOC\" class=\"toc\">"+rb.getString("tableofcontents.title")+"</a>";
         }
 
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
 
         sb.append("<div class=\"toc\">\n");
         sb.append("<div class=\"collapsebox\">\n");
 
-        String title = params.get(PARAM_TITLE);
+        final String title = params.get(PARAM_TITLE);
         sb.append("<h4 id=\"section-TOC\">");
         if( title != null )
         {
@@ -183,7 +185,7 @@ public class TableOfContents
         m_usingNumberedList = false;
         if (params.containsKey(PARAM_NUMBERED))
         {
-            String numbered = params.get(PARAM_NUMBERED);
+            final String numbered = params.get(PARAM_NUMBERED);
             if (numbered.equalsIgnoreCase("true"))
             {
                 m_usingNumberedList = true;
@@ -198,7 +200,7 @@ public class TableOfContents
         if (m_usingNumberedList)
         {
             int start = 0;
-            String startStr = params.get(PARAM_START);
+            final String startStr = params.get(PARAM_START);
             if ((startStr != null) && (startStr.matches("^\\d+$")))
             {
                 start = Integer.parseInt(startStr);
@@ -216,12 +218,12 @@ public class TableOfContents
         }
 
         try {
-            String wikiText = engine.getPageManager().getPureText( page );
-            final boolean runFilters = "true".equals( engine.getVariableManager().getValue( context, VariableManager.VAR_RUNFILTERS, "true" ) );
+            String wikiText = engine.getManager( PageManager.class ).getPureText( page );
+            final boolean runFilters = "true".equals( engine.getManager( VariableManager.class ).getValue( context, VariableManager.VAR_RUNFILTERS, "true" ) );
 
             if( runFilters ) {
 				try {
-					final FilterManager fm = engine.getFilterManager();
+					final FilterManager fm = engine.getManager( FilterManager.class );
 					wikiText = fm.doPreTranslateFiltering(context, wikiText);
 
 				} catch( final Exception e ) {
@@ -232,7 +234,7 @@ public class TableOfContents
 
             context.setVariable( VAR_ALREADY_PROCESSING, "x" );
 
-            final MarkupParser parser = engine.getRenderingManager().getParser( context, wikiText );
+            final MarkupParser parser = engine.getManager( RenderingManager.class ).getParser( context, wikiText );
             parser.addHeadingListener( this );
             parser.parse();
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/UndefinedPagesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/UndefinedPagesPlugin.java
index d760a20..642f637 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/UndefinedPagesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/UndefinedPagesPlugin.java
@@ -40,8 +40,8 @@ public class UndefinedPagesPlugin extends AbstractReferralPlugin {
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
-        final ReferenceManager refmgr = context.getEngine().getReferenceManager();
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+        final ReferenceManager refmgr = context.getEngine().getManager( ReferenceManager.class );
         super.initialize( context, params );
 
         Collection< String > links = refmgr.findUncreated();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/UnusedPagesPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/UnusedPagesPlugin.java
index a979d8d..46e9332 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/UnusedPagesPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/UnusedPagesPlugin.java
@@ -24,7 +24,6 @@ import org.apache.wiki.references.ReferenceManager;
 import org.apache.wiki.util.TextUtil;
 
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.Map;
 
 /**
@@ -36,58 +35,36 @@ import java.util.Map;
  *  <li><b>separator</b> - how to separate generated links; default is a wikitext line break,  producing a vertical list</li>
  * <li><b> maxwidth</b> - maximum width, in chars, of generated links.</li>
  * </ul>
- *
  */
-public class UnusedPagesPlugin
-    extends AbstractReferralPlugin
-{
-    /**
-     *  If set to "true", attachments are excluded from display.  Value is {@value}.
-     */
+public class UnusedPagesPlugin extends AbstractReferralPlugin {
+
+    /** If set to "true", attachments are excluded from display.  Value is {@value}. */
     public static final String PARAM_EXCLUDEATTS = "excludeattachments";
 
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
-        throws PluginException
-    {
-        ReferenceManager refmgr = context.getEngine().getReferenceManager();
-        Collection<String> links = refmgr.findUnreferenced();
-        //
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+        final ReferenceManager refmgr = context.getEngine().getManager( ReferenceManager.class );
+        Collection< String > links = refmgr.findUnreferenced();
+
         // filter out attachments if "excludeattachments" was requested:
-        //
-        String prop = params.get( PARAM_EXCLUDEATTS );
-        if( TextUtil.isPositive(prop) )
-        {
-            //  remove links to attachments (recognizable by a slash in it)
-            Iterator< String > iterator = links.iterator();
-            while( iterator.hasNext() )
-            {
-                String link = iterator.next();
-                if (link.indexOf("/")!=-1)
-                {
-                    iterator.remove();
-                }
-            }
+        final String prop = params.get( PARAM_EXCLUDEATTS );
+        if( TextUtil.isPositive( prop ) ) {
+            // remove links to attachments (recognizable by a slash in it)
+            links.removeIf( link -> link.contains( "/" ) );
         }
 
         super.initialize( context, params );
-
         links = filterAndSortCollection( links );
 
-        String wikitext = null;
-
-        if (m_show.equals(PARAM_SHOW_VALUE_COUNT))
-        {
+        String wikitext;
+        if( m_show.equals( PARAM_SHOW_VALUE_COUNT ) ) {
             wikitext = "" + links.size();
-            if (m_lastModified && links.size()!=0)
-            {
-                wikitext = links.size() + " (" + m_dateFormat.format(m_dateLastModified) + ")";
+            if( m_lastModified && links.size() != 0 ) {
+                wikitext = links.size() + " (" + m_dateFormat.format( m_dateLastModified ) + ")";
             }
-        }
-        else
-        {
+        } else {
             wikitext = wikitizeCollection( links, m_separator, ALL_ITEMS );
         }
         return makeHTML( context, wikitext );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
index 1e3ae87..857bb9e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
@@ -18,26 +18,23 @@
  */
 package org.apache.wiki.plugin;
 
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.util.TextUtil;
+
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-import org.apache.log4j.Logger;
-import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiPage;
-import org.apache.wiki.api.exceptions.PluginException;
-import org.apache.wiki.api.exceptions.ProviderException;
-import org.apache.wiki.api.plugin.WikiPlugin;
-import org.apache.wiki.util.TextUtil;
-
 /**
  *  Creates a list of all weblog entries on a monthly basis.
  *
@@ -48,9 +45,7 @@ import org.apache.wiki.util.TextUtil;
  *
  *  @since 1.9.21
  */
-public class WeblogArchivePlugin implements WikiPlugin
-{
-    private static Logger     log = Logger.getLogger(WeblogArchivePlugin.class);
+public class WeblogArchivePlugin implements WikiPlugin {
 
     /** Parameter name for setting the page.  Value is <tt>{@value}</tt>. */
     public static final String PARAM_PAGE = "page";
@@ -60,14 +55,10 @@ public class WeblogArchivePlugin implements WikiPlugin
     /**
      *  {@inheritDoc}
      */
-    public String execute( WikiContext context, Map<String, String> params )
-        throws PluginException
-    {
-        WikiEngine engine = context.getEngine();
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+        final Engine engine = context.getEngine();
 
-        //
         //  Parameters
-        //
         String weblogName = params.get( PARAM_PAGE );
 
         if( weblogName == null ) weblogName = context.getPage().getName();
@@ -77,82 +68,48 @@ public class WeblogArchivePlugin implements WikiPlugin
                                                 context.getURL( WikiContext.VIEW, weblogName,
                                                                 "weblog.startDate='ddMMyy'&amp;weblog.days=%d")+"'");
 
-        StringBuilder sb = new StringBuilder();
-
+        final StringBuilder sb = new StringBuilder();
         sb.append( "<div class=\"weblogarchive\">\n" );
 
-
-        //
         //  Collect months that have blog entries
-        //
-
-        try
-        {
-            Collection< Calendar > months = collectMonths( engine, weblogName );
-            int year = 0;
-
-            //
-            //  Output proper HTML.
-            //
+        final Collection< Calendar > months = collectMonths( engine, weblogName );
+        int year = 0;
 
-            sb.append( "<ul>\n" );
+        //  Output proper HTML.
+        sb.append( "<ul>\n" );
 
-            if( months.size() > 0 )
-            {
-                year = (months.iterator().next()).get( Calendar.YEAR );
-
-                sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" );
-            }
-
-            for( Iterator< Calendar > i = months.iterator(); i.hasNext(); )
-            {
-                Calendar cal = i.next();
-
-                if( cal.get( Calendar.YEAR ) != year )
-                {
-                    year = cal.get( Calendar.YEAR );
-
-                    sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" );
-                }
-
-                sb.append( "  <li>" );
-
-                sb.append( getMonthLink( cal ) );
+        if( months.size() > 0 ) {
+            year = ( months.iterator().next() ).get( Calendar.YEAR );
+            sb.append( "<li class=\"archiveyear\">" + year + "</li>\n" );
+        }
 
-                sb.append( "</li>\n" );
+        for( final Calendar cal : months ) {
+            if( cal.get( Calendar.YEAR ) != year ) {
+                year = cal.get( Calendar.YEAR );
+                sb.append( "<li class=\"archiveyear\">" + year + "</li>\n" );
             }
-
-            sb.append( "</ul>\n" );
-        }
-        catch( ProviderException ex )
-        {
-            log.info( "Cannot get archive", ex );
-            sb.append("Cannot get archive: "+ex.getMessage());
+            sb.append( "  <li>" );
+            sb.append( getMonthLink( cal ) );
+            sb.append( "</li>\n" );
         }
 
+        sb.append( "</ul>\n" );
         sb.append( "</div>\n" );
-
         return sb.toString();
     }
 
-    private SortedSet< Calendar > collectMonths( WikiEngine engine, String page )
-        throws ProviderException
-    {
-        Comparator< Calendar > comp = new ArchiveComparator();
-        TreeSet<Calendar> res = new TreeSet<Calendar>( comp );
-
-        WeblogPlugin pl = new WeblogPlugin();
+    private SortedSet< Calendar > collectMonths( final Engine engine, final String page ) {
+        final Comparator< Calendar > comp = new ArchiveComparator();
+        final TreeSet<Calendar> res = new TreeSet<>( comp );
 
-        List< WikiPage > blogEntries = pl.findBlogEntries( engine, page, new Date(0L), new Date() );
+        final WeblogPlugin pl = new WeblogPlugin();
 
-        for( Iterator< WikiPage > i = blogEntries.iterator(); i.hasNext(); )
-        {
-            WikiPage p = i.next();
+        final List< WikiPage > blogEntries = pl.findBlogEntries( engine, page, new Date(0L), new Date() );
 
+        for( final WikiPage p : blogEntries ) {
             // FIXME: Not correct, should parse page creation time.
-
-            Date d = p.getLastModified();
-            Calendar cal = Calendar.getInstance();
+            final Date d = p.getLastModified();
+            final Calendar cal = Calendar.getInstance();
             cal.setTime( d );
             res.add( cal );
         }
@@ -160,10 +117,10 @@ public class WeblogArchivePlugin implements WikiPlugin
         return res;
     }
 
-    private String getMonthLink( Calendar day )
+    private String getMonthLink( final Calendar day )
     {
-        SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" );
-        String result;
+        final SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" );
+        final String result;
 
         if( m_monthUrlFormat == null )
         {
@@ -171,9 +128,9 @@ public class WeblogArchivePlugin implements WikiPlugin
         }
         else
         {
-            Calendar cal = (Calendar)day.clone();
-            int firstDay = cal.getActualMinimum( Calendar.DATE );
-            int lastDay  = cal.getActualMaximum( Calendar.DATE );
+            final Calendar cal = (Calendar)day.clone();
+            final int firstDay = cal.getActualMinimum( Calendar.DATE );
+            final int lastDay  = cal.getActualMaximum( Calendar.DATE );
 
             cal.set( Calendar.DATE, lastDay );
             String url = m_monthUrlFormat.format( cal.getTime() );
@@ -194,7 +151,7 @@ public class WeblogArchivePlugin implements WikiPlugin
      */
     private static class ArchiveComparator implements Comparator< Calendar > {
 
-        public int compare( Calendar a, Calendar b )
+        @Override public int compare( final Calendar a, final Calendar b )
         {
             if( a == null || b == null )
             {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogEntryPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogEntryPlugin.java
index 7e71e6e..706b53f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogEntryPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogEntryPlugin.java
@@ -20,12 +20,13 @@ package org.apache.wiki.plugin;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.WikiPlugin;
 import org.apache.wiki.pages.PageLock;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.util.TextUtil;
 
@@ -49,17 +50,19 @@ import java.util.ResourceBundle;
 public class WeblogEntryPlugin implements WikiPlugin {
 
     private static final Logger log = Logger.getLogger(WeblogEntryPlugin.class);
-    private static final int MAX_BLOG_ENTRIES = 10000; // Just a precaution.
+    private static final int MAX_BLOG_ENTRIES = 10_000; // Just a precaution.
 
     /**
      * Parameter name for setting the entrytext  Value is <tt>{@value}</tt>.
      */
     public static final String PARAM_ENTRYTEXT = "entrytext";
-    /**
+
+    /*
      * Optional parameter: page that actually contains the blog. This lets us provide a "new entry" link for a blog page
      * somewhere else than on the page itself.
      */
     // "page" for uniform naming with WeblogPlugin...
+    
     /**
      * Parameter name for setting the page Value is <tt>{@value}</tt>.
      */
@@ -73,7 +76,7 @@ public class WeblogEntryPlugin implements WikiPlugin {
      * @return A new name.
      * @throws ProviderException If something goes wrong.
      */
-    public String getNewEntryPage( final WikiEngine engine, final String blogName ) throws ProviderException {
+    public String getNewEntryPage( final Engine engine, final String blogName ) throws ProviderException {
         final SimpleDateFormat fmt = new SimpleDateFormat(WeblogPlugin.DEFAULT_DATEFORMAT);
         final String today = fmt.format(new Date());
         final int entryNum = findFreeEntry( engine, blogName, today );
@@ -84,9 +87,10 @@ public class WeblogEntryPlugin implements WikiPlugin {
     /**
      * {@inheritDoc}
      */
+    @Override
     public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
         final ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
 
         String weblogName = params.get(PARAM_BLOGNAME);
         if (weblogName == null) {
@@ -102,8 +106,8 @@ public class WeblogEntryPlugin implements WikiPlugin {
         return "<a href=\"" + url + "\">" + entryText + "</a>";
     }
 
-    private int findFreeEntry( final WikiEngine engine, final String baseName, final String date ) throws ProviderException {
-        final Collection< WikiPage > everyone = engine.getPageManager().getAllPages();
+    private int findFreeEntry( final Engine engine, final String baseName, final String date ) throws ProviderException {
+        final Collection< WikiPage > everyone = engine.getManager( PageManager.class ).getAllPages();
         final String startString = WeblogPlugin.makeEntryPage(baseName, date, "");
         int max = 0;
 
@@ -125,7 +129,7 @@ public class WeblogEntryPlugin implements WikiPlugin {
         int idx = max + 1;
         while( idx < MAX_BLOG_ENTRIES ) {
             final WikiPage page = new WikiPage( engine, WeblogPlugin.makeEntryPage( baseName, date, Integer.toString( idx ) ) );
-            final PageLock lock = engine.getPageManager().getCurrentLock(page);
+            final PageLock lock = engine.getManager( PageManager.class ).getCurrentLock(page);
             if (lock == null) {
                 break;
             }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
index 5247c4f..8c377de 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
@@ -20,9 +20,9 @@ package org.apache.wiki.plugin;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.PluginException;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.plugin.ParserStagePlugin;
@@ -33,6 +33,8 @@ import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
 import org.apache.wiki.preferences.Preferences.TimeFormat;
+import org.apache.wiki.references.ReferenceManager;
+import org.apache.wiki.render.RenderingManager;
 import org.apache.wiki.util.TextUtil;
 
 import java.text.DateFormat;
@@ -83,7 +85,7 @@ import java.util.regex.Pattern;
 
 public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
 
-    private static final Logger     log = Logger.getLogger(WeblogPlugin.class);
+    private static final Logger log = Logger.getLogger(WeblogPlugin.class);
     private static final Pattern HEADINGPATTERN;
 
     /** How many days are considered by default.  Default value is {@value} */
@@ -155,12 +157,12 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
     /**
      *  {@inheritDoc}
      */
-    public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
+    @Override public String execute( final WikiContext context, final Map< String, String > params ) throws PluginException {
         final Calendar   startTime;
         final Calendar   stopTime;
         int        numDays = DEFAULT_DAYS;
-        final WikiEngine engine = context.getEngine();
-        final AuthorizationManager mgr = engine.getAuthorizationManager();
+        final Engine engine = context.getEngine();
+        final AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
 
         //
         //  Parse parameters.
@@ -268,7 +270,7 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
      */
     private void addEntryHTML( final WikiContext context, final DateFormat entryFormat, final boolean hasComments,
                                final StringBuilder buffer, final WikiPage entry, final Map< String, String > params) {
-        final WikiEngine engine = context.getEngine();
+        final Engine engine = context.getEngine();
         final ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
 
         buffer.append("<div class=\"weblogentry\">\n");
@@ -288,7 +290,7 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
         final WikiContext entryCtx = (WikiContext) context.clone();
         entryCtx.setPage( entry );
 
-        String html = engine.getRenderingManager().getHTML( entryCtx, engine.getPageManager().getPage( entry.getName() ) );
+        String html = engine.getManager( RenderingManager.class ).getHTML( entryCtx, engine.getManager( PageManager.class ).getPage( entry.getName() ) );
 
         // Extract the first h1/h2/h3 as title, and replace with null
         buffer.append("<div class=\"weblogentrytitle\">\n");
@@ -342,8 +344,8 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
         String author = entry.getAuthor();
 
         if( author != null ) {
-            if( engine.getPageManager().wikiPageExists(author) ) {
-                author = "<a href=\""+entryCtx.getURL( WikiContext.VIEW, author )+"\">"+engine.getRenderingManager().beautifyTitle(author)+"</a>";
+            if( engine.getManager( PageManager.class ).wikiPageExists(author) ) {
+                author = "<a href=\""+entryCtx.getURL( WikiContext.VIEW, author )+"\">"+engine.getManager( RenderingManager.class ).beautifyTitle(author)+"</a>";
             }
         } else {
             author = "AnonymousCoward";
@@ -354,7 +356,7 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
         final String commentPageName = TextUtil.replaceString( entry.getName(), "blogentry", "comments" );
 
         if( hasComments ) {
-            int numComments = guessNumberOfComments( engine, commentPageName );
+            final int numComments = guessNumberOfComments( engine, commentPageName );
 
             //
             //  We add the number of comments to the URL so that the user's browsers would realize that the page has changed.
@@ -371,14 +373,12 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
 
         buffer.append("</div>\n");
 
-        //
         //  Done, close
-        //
         buffer.append("</div>\n");
     }
 
-    private int guessNumberOfComments( final WikiEngine engine, final String commentpage ) {
-        final String pagedata = engine.getPageManager().getPureText( commentpage, WikiProvider.LATEST_VERSION );
+    private int guessNumberOfComments( final Engine engine, final String commentpage ) {
+        final String pagedata = engine.getManager( PageManager.class ).getPureText( commentpage, WikiProvider.LATEST_VERSION );
         if( pagedata == null || pagedata.trim().length() == 0 ) {
             return 0;
         }
@@ -396,9 +396,9 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
      *  @param end   The end date which is the last to be considered
      *  @return a list of pages with their FIRST revisions.
      */
-    public List< WikiPage > findBlogEntries( final WikiEngine engine, String baseName, final Date start, final Date end ) {
-        final PageManager mgr = engine.getPageManager();
-        final Set< String > allPages = engine.getReferenceManager().findCreated();
+    public List< WikiPage > findBlogEntries( final Engine engine, String baseName, final Date start, final Date end ) {
+        final PageManager mgr = engine.getManager( PageManager.class );
+        final Set< String > allPages = engine.getManager( ReferenceManager.class ).findCreated();
         final ArrayList<WikiPage> result = new ArrayList<>();
 
         baseName = makeEntryPage( baseName );
@@ -442,7 +442,7 @@ public class WeblogPlugin implements WikiPlugin, ParserStagePlugin {
      *
      *  {@inheritDoc}
      */
-    public void executeParser( final PluginElement element, final WikiContext context, final Map< String, String > params ) {
+    @Override public void executeParser( final PluginElement element, final WikiContext context, final Map< String, String > params ) {
         context.getPage().setAttribute( ATTR_ISWEBLOG, "true" );
     }
 


[jspwiki] 33/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (10)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 2d9a75bf5cf499ff12e52a2ed4e8f381a6087cda
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:17:21 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (10)
---
 .../test/java/org/apache/wiki/WikiEngineTest.java  |  22 +-
 .../wiki/attachment/AttachmentManagerTest.java     |  80 +--
 .../apache/wiki/auth/AuthorizationManagerTest.java | 151 +++---
 .../java/org/apache/wiki/auth/UserManagerTest.java | 102 ++--
 .../wiki/auth/acl/DefaultAclManagerTest.java       |  16 +-
 .../org/apache/wiki/content/PageRenamerTest.java   | 110 +++--
 .../apache/wiki/pages/DefaultPageManagerTest.java  |  78 +--
 .../wiki/parser/JSPWikiMarkupParserTest.java       | 546 +++++++++++----------
 .../wiki/plugin/DefaultPluginManagerTest.java      |   5 +-
 .../java/org/apache/wiki/plugin/GroupsTest.java    |  11 +-
 .../java/org/apache/wiki/plugin/IfPluginTest.java  |  50 +-
 .../org/apache/wiki/plugin/InsertPageTest.java     |  31 +-
 .../org/apache/wiki/plugin/PageViewPluginTest.java |  77 +--
 .../apache/wiki/plugin/TableOfContentsTest.java    |  43 +-
 .../wiki/plugin/UndefinedPagesPluginTest.java      |   3 +-
 .../org/apache/wiki/plugin/WeblogPluginTest.java   |   3 +-
 .../apache/wiki/providers/CachingProviderTest.java |  27 +-
 .../wiki/providers/VersioningFileProviderTest.java | 184 +++----
 .../wiki/references/ReferenceManagerTest.java      |   4 +-
 .../apache/wiki/render/RenderingManagerTest.java   |  21 +-
 .../java/org/apache/wiki/rss/RSSGeneratorTest.java |  29 +-
 .../org/apache/wiki/search/SearchManagerTest.java  |   9 +-
 .../apache/wiki/stress/MassiveRepositoryTest.java  |  50 +-
 .../wiki/stress/StressTestVersioningProvider.java  |  27 +-
 .../org/apache/wiki/ui/CommandResolverTest.java    |   7 +-
 .../java/org/apache/wiki/ui/PageCommandTest.java   |   3 +-
 .../apache/wiki/workflow/ApprovalWorkflowTest.java |  85 ++--
 .../org/apache/wiki/xmlrpc/RPCHandlerTest.java     |  47 +-
 28 files changed, 927 insertions(+), 894 deletions(-)

diff --git a/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java b/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java
index 69d3f0e..7c78fed 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/WikiEngineTest.java
@@ -259,19 +259,19 @@ public class WikiEngineTest {
         engine.saveText( NAME1, "[{SET foo=bar}]" );
         engine.saveText( NAME1, "[{SET foo=notbar}]");
 
-        final WikiPage v1 = engine.getPageManager().getPage( NAME1, 1 );
-        final WikiPage v2 = engine.getPageManager().getPage( NAME1, 2 );
+        final WikiPage v1 = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
+        final WikiPage v2 = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
 
         Assertions.assertEquals( "bar", v1.getAttribute("foo"), "V1" );
         Assertions.assertEquals( "notbar", v2.getAttribute("foo"), "V2" );
 
-        engine.getPageManager().deletePage( NAME1 );
+        engine.getManager( PageManager.class ).deletePage( NAME1 );
     }
 
     @Test
     public void testSpacedNames1() throws Exception {
         m_engine.saveText("This is a test", "puppaa");
-        Assertions.assertEquals( "puppaa", m_engine.getPageManager().getText("This is a test").trim(), "normal" );
+        Assertions.assertEquals( "puppaa", m_engine.getManager( PageManager.class ).getText("This is a test").trim(), "normal" );
     }
 
     @Test
@@ -293,11 +293,11 @@ public class WikiEngineTest {
         Collection< String > pages = m_engine.getReferenceManager().findReferrers( "RenameBugTestPage" );
         Assertions.assertEquals( "OldNameTestPage", pages.iterator().next(), "has one" );
 
-        final WikiContext ctx = new WikiContext( m_engine, m_engine.getPageManager().getPage("OldNameTestPage") );
+        final WikiContext ctx = new WikiContext( m_engine, m_engine.getManager( PageManager.class ).getPage("OldNameTestPage") );
         m_engine.getPageRenamer().renamePage( ctx, "OldNameTestPage", "NewNameTestPage", true );
 
-        Assertions.assertFalse( m_engine.getPageManager().wikiPageExists( "OldNameTestPage"), "did not vanish" );
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( "NewNameTestPage"), "did not appear" );
+        Assertions.assertFalse( m_engine.getManager( PageManager.class ).wikiPageExists( "OldNameTestPage"), "did not vanish" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( "NewNameTestPage"), "did not appear" );
 
         pages = m_engine.getReferenceManager().findReferrers( "RenameBugTestPage" );
         Assertions.assertEquals( 1, pages.size(),  "wrong # of referrers" );
@@ -309,16 +309,16 @@ public class WikiEngineTest {
         final WikiPage p = new WikiPage( m_engine, NAME1 );
         final WikiContext context = new WikiContext(m_engine,p);
         context.getPage().setAttribute( WikiPage.CHANGENOTE, "Test change" );
-        m_engine.getPageManager().saveText( context, "test" );
+        m_engine.getManager( PageManager.class ).saveText( context, "test" );
 
         for( int i = 0; i < 5; i++ ) {
-            final WikiPage p2 = ( WikiPage )m_engine.getPageManager().getPage( NAME1 ).clone();
+            final WikiPage p2 = ( WikiPage )m_engine.getManager( PageManager.class ).getPage( NAME1 ).clone();
             p2.removeAttribute( WikiPage.CHANGENOTE );
             context.setPage( p2 );
-            m_engine.getPageManager().saveText( context, "test" + i );
+            m_engine.getManager( PageManager.class ).saveText( context, "test" + i );
         }
 
-        final WikiPage p3 = m_engine.getPageManager().getPage( NAME1, -1 );
+        final WikiPage p3 = m_engine.getManager( PageManager.class ).getPage( NAME1, -1 );
         Assertions.assertNull( p3.getAttribute( WikiPage.CHANGENOTE ) );
     }
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/attachment/AttachmentManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/attachment/AttachmentManagerTest.java
index a231cb9..ed7a400 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/attachment/AttachmentManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/attachment/AttachmentManagerTest.java
@@ -12,12 +12,14 @@
  * limitations under the License.
  */
 package org.apache.wiki.attachment;
+
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.util.FileUtil;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -86,24 +88,24 @@ public class AttachmentManagerTest {
     public void testSimpleStore()
         throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt" );
+        final Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt" );
 
         Assertions.assertNotNull( att2, "attachment disappeared" );
         Assertions.assertEquals( att.getName(), att2.getName(), "name" );
         Assertions.assertEquals( att.getAuthor(), att2.getAuthor(), "author" );
         Assertions.assertEquals( c_fileContents.length(), att2.getSize(), "size" );
 
-        InputStream in = m_manager.getAttachmentStream( att2 );
+        final InputStream in = m_manager.getAttachmentStream( att2 );
 
         Assertions.assertNotNull( in, "stream" );
 
-        StringWriter sout = new StringWriter();
+        final StringWriter sout = new StringWriter();
         FileUtil.copyContents( new InputStreamReader(in), sout );
 
         in.close();
@@ -116,13 +118,13 @@ public class AttachmentManagerTest {
     public void testSimpleStoreSpace()
         throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test file.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test file.txt" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine,
+        final Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine,
                                                                        new WikiPage(m_engine, NAME1)),
                                                        "test file.txt" );
 
@@ -131,11 +133,11 @@ public class AttachmentManagerTest {
         Assertions.assertEquals( att.getAuthor(), att2.getAuthor(), "author" );
         Assertions.assertEquals( c_fileContents.length(), att2.getSize(), "size" );
 
-        InputStream in = m_manager.getAttachmentStream( att2 );
+        final InputStream in = m_manager.getAttachmentStream( att2 );
 
         Assertions.assertNotNull( in, "stream" );
 
-        StringWriter sout = new StringWriter();
+        final StringWriter sout = new StringWriter();
         FileUtil.copyContents( new InputStreamReader(in), sout );
 
         in.close();
@@ -148,13 +150,13 @@ public class AttachmentManagerTest {
     public void testSimpleStoreByVersion()
         throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt", 1 );
+        final Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt", 1 );
 
         Assertions.assertNotNull( att2, "attachment disappeared" );
         Assertions.assertEquals( 1, att2.getVersion(), "version" );
@@ -162,11 +164,11 @@ public class AttachmentManagerTest {
         Assertions.assertEquals( att.getAuthor(), att2.getAuthor(), "author" );
         Assertions.assertEquals( c_fileContents.length(), att2.getSize(), "size" );
 
-        InputStream in = m_manager.getAttachmentStream( att2 );
+        final InputStream in = m_manager.getAttachmentStream( att2 );
 
         Assertions.assertNotNull( in, "stream" );
 
-        StringWriter sout = new StringWriter();
+        final StringWriter sout = new StringWriter();
         FileUtil.copyContents( new InputStreamReader(in), sout );
 
         in.close();
@@ -179,7 +181,7 @@ public class AttachmentManagerTest {
     public void testMultipleStore()
         throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
 
         att.setAuthor( "FirstPost" );
 
@@ -188,18 +190,18 @@ public class AttachmentManagerTest {
         att.setAuthor( "FooBar" );
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt" );
+        final Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt" );
 
         Assertions.assertNotNull( att2, "attachment disappeared" );
         Assertions.assertEquals( att.getName(), att2.getName(), "name" );
         Assertions.assertEquals( att.getAuthor(), att2.getAuthor(), "author" );
         Assertions.assertEquals( 2, att2.getVersion(), "version" );
 
-        InputStream in = m_manager.getAttachmentStream( att2 );
+        final InputStream in = m_manager.getAttachmentStream( att2 );
 
         Assertions.assertNotNull( in, "stream" );
 
-        StringWriter sout = new StringWriter();
+        final StringWriter sout = new StringWriter();
         FileUtil.copyContents( new InputStreamReader(in), sout );
 
         in.close();
@@ -212,7 +214,7 @@ public class AttachmentManagerTest {
         // Check that first author did not disappear
         //
 
-        Attachment att3 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt", 1 );
+        final Attachment att3 = m_manager.getAttachmentInfo( new WikiContext(m_engine, new WikiPage(m_engine, NAME1)), "test1.txt", 1 );
         Assertions.assertEquals( 1, att3.getVersion(), "version of v1" );
         Assertions.assertEquals( "FirstPost", att3.getAuthor(), "name of v1" );
     }
@@ -221,17 +223,17 @@ public class AttachmentManagerTest {
     public void testListAttachments()
         throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1.txt" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        List< Attachment > c = m_manager.listAttachments( new WikiPage(m_engine, NAME1) );
+        final List< Attachment > c = m_manager.listAttachments( new WikiPage(m_engine, NAME1) );
 
         Assertions.assertEquals( 1, c.size(), "Length" );
 
-        Attachment att2 = (Attachment) c.toArray()[0];
+        final Attachment att2 = (Attachment) c.toArray()[0];
 
         Assertions.assertEquals( att.getName(), att2.getName(), "name" );
         Assertions.assertEquals( att.getAuthor(), att2.getAuthor(), "author" );
@@ -240,13 +242,13 @@ public class AttachmentManagerTest {
     @Test
     public void testSimpleStoreWithoutExt() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine,
+        final Attachment att2 = m_manager.getAttachmentInfo( new WikiContext(m_engine,
                                                                        new WikiPage(m_engine, NAME1)),
                                                        "test1" );
 
@@ -256,11 +258,11 @@ public class AttachmentManagerTest {
         Assertions.assertEquals( c_fileContents.length(), att2.getSize(), "size" );
         Assertions.assertEquals( 1, att2.getVersion(), "version" );
 
-        InputStream in = m_manager.getAttachmentStream( att2 );
+        final InputStream in = m_manager.getAttachmentStream( att2 );
 
         Assertions.assertNotNull( in, "stream" );
 
-        StringWriter sout = new StringWriter();
+        final StringWriter sout = new StringWriter();
         FileUtil.copyContents( new InputStreamReader(in), sout );
 
         in.close();
@@ -273,61 +275,61 @@ public class AttachmentManagerTest {
     @Test
     public void testExists() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( NAME1+"/test1" ), "attachment disappeared" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( NAME1+"/test1" ), "attachment disappeared" );
     }
 
     @Test
     public void testExists2() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test1.bin" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test1.bin" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( att.getName() ), "attachment disappeared" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( att.getName() ), "attachment disappeared" );
     }
 
     @Test
     public void testExistsSpace() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test file.bin" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test file.bin" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( NAME1+"/test file.bin" ), "attachment disappeared" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( NAME1+"/test file.bin" ), "attachment disappeared" );
     }
 
     @Test
     public void testExistsUTF1() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAME1, "test\u00e4.bin" );
+        final Attachment att = new Attachment( m_engine, NAME1, "test\u00e4.bin" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( att.getName() ), "attachment disappeared" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( att.getName() ), "attachment disappeared" );
     }
 
     @Test
     public void testExistsUTF2() throws Exception
     {
-        Attachment att = new Attachment( m_engine, NAMEU, "test\u00e4.bin" );
+        final Attachment att = new Attachment( m_engine, NAMEU, "test\u00e4.bin" );
 
         att.setAuthor( "FirstPost" );
 
         m_manager.storeAttachment( att, makeAttachmentFile() );
 
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists( att.getName() ), "attachment disappeared" );
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists( att.getName() ), "attachment disappeared" );
     }
 
     @Test
@@ -337,20 +339,20 @@ public class AttachmentManagerTest {
         {
             m_engine.saveText( "TestPage", "xx" );
 
-            Attachment att = new Attachment( m_engine, "TestPages", "foo.bin" );
+            final Attachment att = new Attachment( m_engine, "TestPages", "foo.bin" );
 
             att.setAuthor("MonicaBellucci");
             m_manager.storeAttachment( att, makeAttachmentFile() );
 
             Assertions.fail("Attachment was stored even when the page does not exist");
         }
-        catch( ProviderException ex )
+        catch( final ProviderException ex )
         {
             // This is the intended exception
         }
         finally
         {
-            m_engine.getPageManager().deletePage("TestPage");
+            m_engine.getManager( PageManager.class ).deletePage("TestPage");
         }
     }
 
@@ -361,13 +363,13 @@ public class AttachmentManagerTest {
 
         Assertions.assertEquals( "test.jpg", AttachmentManager.validateFileName( "C:\\Windows\\test.jpg" ), "C:\\Windows\\test.jpg" );
 
-        WikiException thrown1 =
+        final WikiException thrown1 =
         Assertions.assertThrows( WikiException.class, () -> {
             AttachmentManager.validateFileName( "C:\\Windows\\test.jsp" );
         });
         Assertions.assertTrue(thrown1.getMessage().contains("attach.unwanted.file"), thrown1.getMessage());
 
-        WikiException thrown2 =
+        final WikiException thrown2 =
         Assertions.assertThrows( WikiException.class, () -> {
             AttachmentManager.validateFileName( "C:\\Windows\\test.jsp\\" );
         });
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthorizationManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthorizationManagerTest.java
index b199b14..096315c 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthorizationManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthorizationManagerTest.java
@@ -17,6 +17,7 @@
     under the License.
  */
 package org.apache.wiki.auth;
+
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiPage;
@@ -34,6 +35,7 @@ import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
 import org.apache.wiki.auth.permissions.WikiPermission;
 import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -60,11 +62,12 @@ public class AuthorizationManagerTest
     {
         private final String m_name;
 
-        public TestPrincipal( String name )
+        public TestPrincipal( final String name )
         {
             m_name = name;
         }
 
+        @Override
         public String getName()
         {
             return m_name;
@@ -74,7 +77,7 @@ public class AuthorizationManagerTest
     @BeforeEach
     public void setUp() throws Exception
     {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         // Make sure we are using the default security policy file jspwiki.policy
         props.put( AuthorizationManager.POLICY, AuthorizationManager.DEFAULT_POLICY );
@@ -97,8 +100,8 @@ public class AuthorizationManagerTest
     {
         // Save a page without an ACL
         m_engine.saveText( "TestDefaultPage", "Foo" );
-        Permission view = PermissionFactory.getPagePermission( "*:TestDefaultPage", "view" );
-        Permission edit = PermissionFactory.getPagePermission( "*:TestDefaultPage", "edit" );
+        final Permission view = PermissionFactory.getPagePermission( "*:TestDefaultPage", "view" );
+        final Permission edit = PermissionFactory.getPagePermission( "*:TestDefaultPage", "edit" );
         WikiSession session;
 
         // Alice is asserted
@@ -114,9 +117,9 @@ public class AuthorizationManagerTest
         // Delete the test page
         try
         {
-            m_engine.getPageManager().deletePage( "TestDefaultPage" );
+            m_engine.getManager( PageManager.class ).deletePage( "TestDefaultPage" );
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             Assertions.fail( e.getMessage() );
         }
@@ -173,19 +176,19 @@ public class AuthorizationManagerTest
     public void testAssertedSession() throws Exception
     {
         // Create Alice and her roles
-        Principal alice = new WikiPrincipal( Users.ALICE );
-        Role it = new Role( "IT" );
-        Role engineering = new Role( "Engineering" );
-        Role finance = new Role( "Finance" );
-        Principal admin = new GroupPrincipal( "Admin" );
-        WikiSession session = WikiSessionTest.assertedSession(
+        final Principal alice = new WikiPrincipal( Users.ALICE );
+        final Role it = new Role( "IT" );
+        final Role engineering = new Role( "Engineering" );
+        final Role finance = new Role( "Finance" );
+        final Principal admin = new GroupPrincipal( "Admin" );
+        final WikiSession session = WikiSessionTest.assertedSession(
                 m_engine,
                 Users.ALICE,
                 new Principal[] { it, engineering, admin } );
 
         // Create two groups: Alice should be part of group Bar, but not Foo
-        Group fooGroup = m_groupMgr.parseGroup( "Foo", "", true );
-        Group barGroup = m_groupMgr.parseGroup( "Bar", "", true );
+        final Group fooGroup = m_groupMgr.parseGroup( "Foo", "", true );
+        final Group barGroup = m_groupMgr.parseGroup( "Bar", "", true );
         barGroup.add( alice );
         m_groupMgr.setGroup( m_session, fooGroup );
         m_groupMgr.setGroup( m_session, barGroup );
@@ -221,19 +224,19 @@ public class AuthorizationManagerTest
     public void testAuthenticatedSession() throws Exception
     {
         // Create Alice and her roles
-        Principal alice = new WikiPrincipal( Users.ALICE );
-        Role it = new Role( "IT" );
-        Role engineering = new Role( "Engineering" );
-        Role finance = new Role( "Finance" );
-        Principal admin = new GroupPrincipal( "Admin" );
-        WikiSession session = WikiSessionTest.containerAuthenticatedSession(
+        final Principal alice = new WikiPrincipal( Users.ALICE );
+        final Role it = new Role( "IT" );
+        final Role engineering = new Role( "Engineering" );
+        final Role finance = new Role( "Finance" );
+        final Principal admin = new GroupPrincipal( "Admin" );
+        final WikiSession session = WikiSessionTest.containerAuthenticatedSession(
                 m_engine,
                 Users.ALICE,
                 new Principal[] { it, engineering, admin } );
 
         // Create two groups: Alice should be part of group Bar, but not Foo
-        Group fooGroup = m_groupMgr.parseGroup( "Foo", "", true );
-        Group barGroup = m_groupMgr.parseGroup( "Bar", "", true );
+        final Group fooGroup = m_groupMgr.parseGroup( "Foo", "", true );
+        final Group barGroup = m_groupMgr.parseGroup( "Bar", "", true );
         barGroup.add( alice );
         m_groupMgr.setGroup( m_session, fooGroup );
         m_groupMgr.setGroup( m_session, barGroup );
@@ -269,17 +272,17 @@ public class AuthorizationManagerTest
     public void testInheritedPermissions() throws Exception
     {
         // Create test page & attachment
-        String src = "[{ALLOW edit Alice}] ";
+        final String src = "[{ALLOW edit Alice}] ";
         m_engine.saveText( "Test", src );
 
-        File f = m_engine.makeAttachmentFile();
-        Attachment att = new Attachment( m_engine, "Test", "test1.txt" );
+        final File f = m_engine.makeAttachmentFile();
+        final Attachment att = new Attachment( m_engine, "Test", "test1.txt" );
         att.setAuthor( "FirstPost" );
         m_engine.getAttachmentManager().storeAttachment( att, f );
 
-        Attachment p = (Attachment) m_engine.getPageManager().getPage( "Test/test1.txt" );
-        Permission view = PermissionFactory.getPagePermission( p, "view" );
-        Permission edit = PermissionFactory.getPagePermission( p, "edit" );
+        final Attachment p = (Attachment) m_engine.getManager( PageManager.class ).getPage( "Test/test1.txt" );
+        final Permission view = PermissionFactory.getPagePermission( p, "view" );
+        final Permission edit = PermissionFactory.getPagePermission( p, "edit" );
 
         // Create authenticated session with user 'Alice', who can read & edit (in ACL)
         WikiSession session;
@@ -294,24 +297,24 @@ public class AuthorizationManagerTest
 
         // Delete test page & attachment
         m_engine.getAttachmentManager().deleteAttachment( att );
-        m_engine.getPageManager().deletePage( "Test" );
+        m_engine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     @Test
     public void testInheritedAclPermissions() throws Exception
     {
         // Create test page & attachment
-        String src = "[{ALLOW view Alice}] ";
+        final String src = "[{ALLOW view Alice}] ";
         m_engine.saveText( "Test", src );
 
-        File f = m_engine.makeAttachmentFile();
-        Attachment att = new Attachment( m_engine, "Test", "test1.txt" );
+        final File f = m_engine.makeAttachmentFile();
+        final Attachment att = new Attachment( m_engine, "Test", "test1.txt" );
         att.setAuthor( "FirstPost" );
         m_engine.getAttachmentManager().storeAttachment( att, f );
 
-        Attachment p = (Attachment) m_engine.getPageManager().getPage( "Test/test1.txt" );
-        Permission view = PermissionFactory.getPagePermission( p, "view" );
-        Permission edit = PermissionFactory.getPagePermission( p, "edit" );
+        final Attachment p = (Attachment) m_engine.getManager( PageManager.class ).getPage( "Test/test1.txt" );
+        final Permission view = PermissionFactory.getPagePermission( p, "view" );
+        final Permission edit = PermissionFactory.getPagePermission( p, "edit" );
 
         // Create session with user 'Alice', who can read (in ACL)
         WikiSession session;
@@ -326,25 +329,25 @@ public class AuthorizationManagerTest
 
         // Delete test page & attachment
         m_engine.getAttachmentManager().deleteAttachment( att );
-        m_engine.getPageManager().deletePage( "Test" );
+        m_engine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     @Test
     public void testHasRoleOrPrincipal() throws Exception
     {
         // Create new user Alice and 2 sample roles
-        Principal alice = new WikiPrincipal( Users.ALICE );
-        Role it = new Role( "IT" );
-        Role finance = new Role( "Finance" );
+        final Principal alice = new WikiPrincipal( Users.ALICE );
+        final Role it = new Role( "IT" );
+        final Role finance = new Role( "Finance" );
 
         // Create Group1 with Alice in it, Group2 without
         WikiSession session = WikiSessionTest.adminSession( m_engine );
-        Group g1 = m_groupMgr.parseGroup( "Group1", "Alice", true );
+        final Group g1 = m_groupMgr.parseGroup( "Group1", "Alice", true );
         m_groupMgr.setGroup( session, g1 );
-        Principal group1 = g1.getPrincipal();
-        Group g2 = m_groupMgr.parseGroup( "Group2", "Bob", true );
+        final Principal group1 = g1.getPrincipal();
+        final Group g2 = m_groupMgr.parseGroup( "Group2", "Bob", true );
         m_groupMgr.setGroup( session, g2 );
-        Principal group2 = g2.getPrincipal();
+        final Principal group2 = g2.getPrincipal();
 
         // Create anonymous session; not in ANY custom roles or groups
         session = WikiSessionTest.anonymousSession( m_engine );
@@ -390,18 +393,18 @@ public class AuthorizationManagerTest
     public void testIsUserInRole() throws Exception
     {
         // Create new user Alice and 2 sample roles
-        Principal alice = new WikiPrincipal( Users.ALICE );
-        Role it = new Role( "IT" );
-        Role finance = new Role( "Finance" );
+        final Principal alice = new WikiPrincipal( Users.ALICE );
+        final Role it = new Role( "IT" );
+        final Role finance = new Role( "Finance" );
 
         // Create Group1 with Alice in it, Group2 without
         WikiSession session = WikiSessionTest.adminSession( m_engine );
-        Group g1 = m_groupMgr.parseGroup( "Group1", "Alice", true );
+        final Group g1 = m_groupMgr.parseGroup( "Group1", "Alice", true );
         m_groupMgr.setGroup( session, g1 );
-        Principal group1 = g1.getPrincipal();
-        Group g2 = m_groupMgr.parseGroup( "Group2", "Bob", true );
+        final Principal group1 = g1.getPrincipal();
+        final Group g2 = m_groupMgr.parseGroup( "Group2", "Bob", true );
         m_groupMgr.setGroup( session, g2 );
-        Principal group2 = g2.getPrincipal();
+        final Principal group2 = g2.getPrincipal();
 
         // Create anonymous session; not in ANY custom roles or groups
         session = WikiSessionTest.anonymousSession( m_engine );
@@ -447,12 +450,12 @@ public class AuthorizationManagerTest
     public void testPrincipalAcl() throws Exception
     {
         // Create test page & attachment
-        String src = "[{ALLOW edit Alice}] ";
+        final String src = "[{ALLOW edit Alice}] ";
         m_engine.saveText( "Test", src );
 
-        WikiPage p = m_engine.getPageManager().getPage( "Test" );
-        Permission view = PermissionFactory.getPagePermission( p, "view" );
-        Permission edit = PermissionFactory.getPagePermission( p, "edit" );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( "Test" );
+        final Permission view = PermissionFactory.getPagePermission( p, "view" );
+        final Permission edit = PermissionFactory.getPagePermission( p, "edit" );
 
         // Create session with authenticated user 'Alice', who can read & edit (in ACL)
         WikiSession session;
@@ -468,9 +471,9 @@ public class AuthorizationManagerTest
         // Cleanup
         try
         {
-            m_engine.getPageManager().deletePage( "Test" );
+            m_engine.getManager( PageManager.class ).deletePage( "Test" );
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             Assertions.fail( "Could not delete page" );
         }
@@ -500,7 +503,7 @@ public class AuthorizationManagerTest
     @Test
     public void testResolveGroups() throws WikiException
     {
-        Group group1 = m_groupMgr.parseGroup( "SampleGroup", "", true );
+        final Group group1 = m_groupMgr.parseGroup( "SampleGroup", "", true );
         m_groupMgr.setGroup( m_session, group1 );
 
         Assertions.assertEquals( group1.getPrincipal(), m_auth.resolvePrincipal( "SampleGroup" ) );
@@ -509,10 +512,10 @@ public class AuthorizationManagerTest
         // We shouldn't be able to spoof a built-in role
         try
         {
-            Group group2 = m_groupMgr.parseGroup( "Authenticated", "", true );
+            final Group group2 = m_groupMgr.parseGroup( "Authenticated", "", true );
             Assertions.assertNotSame( group2.getPrincipal(), m_auth.resolvePrincipal( "Authenticated" ) );
         }
-        catch ( WikiSecurityException e )
+        catch ( final WikiSecurityException e )
         {
             Assertions.assertTrue ( true, "Authenticated not allowed as group name." );
         }
@@ -523,7 +526,7 @@ public class AuthorizationManagerTest
     public void testResolveUsers() throws WikiException
     {
         // We should be able to resolve a user by login, user, or wiki name
-        UserProfile profile = m_engine.getUserManager().getUserDatabase().newProfile();
+        final UserProfile profile = m_engine.getUserManager().getUserDatabase().newProfile();
         profile.setEmail( "authmanagertest@tester.net" );
         profile.setFullname( "AuthorizationManagerTest User" );
         profile.setLoginName( "authmanagertest" );
@@ -531,7 +534,7 @@ public class AuthorizationManagerTest
         {
             m_engine.getUserManager().getUserDatabase().save( profile );
         }
-        catch( WikiSecurityException e )
+        catch( final WikiSecurityException e )
         {
             Assertions.fail( "Failed save: " + e.getLocalizedMessage() );
         }
@@ -542,14 +545,14 @@ public class AuthorizationManagerTest
         {
             m_engine.getUserManager().getUserDatabase().deleteByLoginName( "authmanagertest" );
         }
-        catch( WikiSecurityException e )
+        catch( final WikiSecurityException e )
         {
             Assertions.fail( "Failed delete: " + e.getLocalizedMessage() );
         }
 
 
         // A wiki group should resolve to itself
-        Group group1 = m_groupMgr.parseGroup( "SampleGroup", "", true );
+        final Group group1 = m_groupMgr.parseGroup( "SampleGroup", "", true );
         m_groupMgr.setGroup( m_session, group1 );
         Assertions.assertEquals( group1.getPrincipal(), m_auth.resolvePrincipal( "SampleGroup" ) );
         m_groupMgr.removeGroup( "SampleGroup" );
@@ -561,7 +564,7 @@ public class AuthorizationManagerTest
         Assertions.assertNotSame( new WikiPrincipal( "Authenticated" ), m_auth.resolvePrincipal( "Authenticated" ) );
 
         // An unknown user should resolve to a generic UnresolvedPrincipal
-        Principal principal = new UnresolvedPrincipal( "Bart Simpson" );
+        final Principal principal = new UnresolvedPrincipal( "Bart Simpson" );
         Assertions.assertEquals( principal, m_auth.resolvePrincipal( "Bart Simpson" ) );
     }
 
@@ -569,12 +572,12 @@ public class AuthorizationManagerTest
     public void testRoleAcl() throws Exception
     {
         // Create test page & attachment
-        String src = "[{ALLOW edit Authenticated}] ";
+        final String src = "[{ALLOW edit Authenticated}] ";
         m_engine.saveText( "Test", src );
 
-        WikiPage p = m_engine.getPageManager().getPage( "Test" );
-        Permission view = PermissionFactory.getPagePermission( p, "view" );
-        Permission edit = PermissionFactory.getPagePermission( p, "edit" );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( "Test" );
+        final Permission view = PermissionFactory.getPagePermission( p, "view" );
+        final Permission edit = PermissionFactory.getPagePermission( p, "edit" );
 
         // Create session with authenticated user 'Alice', who can read & edit
         WikiSession session;
@@ -590,9 +593,9 @@ public class AuthorizationManagerTest
         // Cleanup
         try
         {
-            m_engine.getPageManager().deletePage( "Test" );
+            m_engine.getManager( PageManager.class ).deletePage( "Test" );
         }
-        catch( ProviderException e )
+        catch( final ProviderException e )
         {
             Assertions.fail( e.getMessage() );
         }
@@ -662,8 +665,8 @@ public class AuthorizationManagerTest
     {
         m_engine.saveText( "TestDefaultPage", "Foo [{ALLOW view FooBar}]" );
 
-        Principal admin = new GroupPrincipal( "Admin" );
-        WikiSession session = WikiSessionTest.containerAuthenticatedSession(
+        final Principal admin = new GroupPrincipal( "Admin" );
+        final WikiSession session = WikiSessionTest.containerAuthenticatedSession(
                 m_engine,
                 Users.ALICE,
                 new Principal[] { admin } );
@@ -677,7 +680,7 @@ public class AuthorizationManagerTest
     {
         m_engine.saveText( "TestDefaultPage", "Foo [{ALLOW view FooBar}]" );
 
-        WikiSession session = WikiSessionTest.adminSession(m_engine);
+        final WikiSession session = WikiSessionTest.adminSession(m_engine);
 
         Assertions.assertTrue( m_auth.checkPermission( session, new AllPermission( m_engine.getApplicationName() ) ), "Alice has AllPermission" );
         Assertions.assertTrue( m_auth.checkPermission( session, new PagePermission("TestDefaultPage","view") ),"Alice cannot read" );
@@ -686,7 +689,7 @@ public class AuthorizationManagerTest
     @Test
     public void testUserPolicy() throws Exception
     {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         // Make sure we are using the default security policy file jspwiki.policy
         props.put( AuthorizationManager.POLICY, "jspwiki-testUserPolicy.policy" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/UserManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/UserManagerTest.java
index 668d4f2..0cd9264 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/UserManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/UserManagerTest.java
@@ -61,7 +61,7 @@ public class UserManagerTest {
      */
     @BeforeEach
     public void setUp() throws Exception {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         // Make sure user profile save workflow is OFF
         props.remove( "jspwiki.approver" + WorkflowManager.WF_UP_CREATE_SAVE_APPROVER );
@@ -76,7 +76,7 @@ public class UserManagerTest {
 
     @AfterEach
     public void tearDown() throws Exception {
-        GroupManager groupManager = m_engine.getGroupManager();
+        final GroupManager groupManager = m_engine.getGroupManager();
         if( groupManager.findRole( m_groupName ) != null ) {
             groupManager.removeGroup( m_groupName );
         }
@@ -84,7 +84,7 @@ public class UserManagerTest {
 
     /** Call this setup program to use the save-profile workflow. */
     protected void setUpWithWorkflow() throws Exception {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         // Turn on user profile saves by the Admin group
         props.put( "jspwiki.approver." + WorkflowManager.WF_UP_CREATE_SAVE_APPROVER, "Admin" );
@@ -99,20 +99,20 @@ public class UserManagerTest {
     @Test
     public void testSetRenamedUserProfile() throws Exception {
         // First, count the number of users, groups, and pages
-        int oldUserCount = m_db.getWikiNames().length;
-        GroupManager groupManager = m_engine.getGroupManager();
-        PageManager pageManager = m_engine.getPageManager();
-        AuthorizationManager authManager = m_engine.getAuthorizationManager();
-        int oldGroupCount = groupManager.getRoles().length;
-        int oldPageCount = pageManager.getTotalPageCount();
+        final int oldUserCount = m_db.getWikiNames().length;
+        final GroupManager groupManager = m_engine.getGroupManager();
+        final PageManager pageManager = m_engine.getManager( PageManager.class );
+        final AuthorizationManager authManager = m_engine.getAuthorizationManager();
+        final int oldGroupCount = groupManager.getRoles().length;
+        final int oldPageCount = pageManager.getTotalPageCount();
 
         // Setup Step 1: create a new user with random name
-        WikiSession session = m_engine.guestSession();
-        long now = System.currentTimeMillis();
-        String oldLogin = "TestLogin" + now;
-        String oldName = "Test User " + now;
-        String newLogin = "RenamedLogin" + now;
-        String newName = "Renamed User " + now;
+        final WikiSession session = m_engine.guestSession();
+        final long now = System.currentTimeMillis();
+        final String oldLogin = "TestLogin" + now;
+        final String oldName = "Test User " + now;
+        final String newLogin = "RenamedLogin" + now;
+        final String newName = "Renamed User " + now;
         UserProfile profile = m_db.newProfile();
         profile.setEmail( "jspwiki.tests@mailinator.com" );
         profile.setLoginName( oldLogin );
@@ -144,14 +144,14 @@ public class UserManagerTest {
         m_engine.saveText( pageName, "Test text. [{ALLOW view " + oldName + ", " + oldLogin + ", Alice}] More text." );
 
         // 3a. Make sure the page got saved, and that ONLY our test user has permission to read it.
-        WikiPage p = m_engine.getPageManager().getPage( pageName );
+        WikiPage p = m_engine.getManager( PageManager.class ).getPage( pageName );
         Assertions.assertEquals( oldPageCount + 1, pageManager.getTotalPageCount() );
         Assertions.assertNotNull( p.getAcl().getEntry( new WikiPrincipal( oldLogin ) ) );
         Assertions.assertNotNull( p.getAcl().getEntry( new WikiPrincipal( oldName ) ) );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( newLogin ) ) );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( newName ) ) );
         Assertions.assertTrue( authManager.checkPermission( session, PermissionFactory.getPagePermission( p, "view" ) ), "Test User view page" );
-        WikiSession bobSession = WikiSessionTest.authenticatedSession( m_engine, Users.BOB, Users.BOB_PASS );
+        final WikiSession bobSession = WikiSessionTest.authenticatedSession( m_engine, Users.BOB, Users.BOB_PASS );
         Assertions.assertFalse( authManager.checkPermission( bobSession, PermissionFactory.getPagePermission( p, "view" ) ), "Bob !view page" );
 
         // Setup Step 4: change the user name in the profile and see what happens
@@ -179,7 +179,7 @@ public class UserManagerTest {
 
         // Test 3: our page should not contain the old wiki name OR login name
         // in the ACL any more (the full name is always used)
-        p = m_engine.getPageManager().getPage( pageName );
+        p = m_engine.getManager( PageManager.class ).getPage( pageName );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( oldLogin ) ) );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( oldName ) ) );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( newLogin ) ) );
@@ -190,11 +190,11 @@ public class UserManagerTest {
         // Test 4: our page text should have been re-written
         // (The new full name should be in the ACL, but the login name should have been removed)
         String expectedText = "[{ALLOW view Alice," + newName + "}]\nTest text.  More text.\r\n";
-        String actualText = m_engine.getPageManager().getText( pageName );
+        String actualText = m_engine.getManager( PageManager.class ).getText( pageName );
         Assertions.assertEquals( expectedText, actualText );
 
         // Remove our test page
-        m_engine.getPageManager().deletePage( pageName );
+        m_engine.getManager( PageManager.class ).deletePage( pageName );
 
         // Setup Step 6: re-create the group with our old test user names in it
         group = groupManager.parseGroup( m_groupName, "Alice \n Bob \n Charlie \n " + oldLogin + "\n" + oldName, true );
@@ -204,7 +204,7 @@ public class UserManagerTest {
         // The test user should still be able to see the page (because the login name matches...)
         pageName = "TestPage2" + now;
         m_engine.saveText( pageName, "More test text. [{ALLOW view " + oldName + ", " + oldLogin + ", Alice}] More text." );
-        p = m_engine.getPageManager().getPage( pageName );
+        p = m_engine.getManager( PageManager.class ).getPage( pageName );
         Assertions.assertEquals( oldPageCount + 1, pageManager.getTotalPageCount() );
         Assertions.assertNotNull( p.getAcl().getEntry( new WikiPrincipal( oldLogin ) ) );
         Assertions.assertNotNull( p.getAcl().getEntry( new WikiPrincipal( oldName ) ) );
@@ -238,7 +238,7 @@ public class UserManagerTest {
 
         // Test 7: our page should not contain the old wiki name OR login name
         // in the ACL any more (the full name is always used)
-        p = m_engine.getPageManager().getPage( pageName );
+        p = m_engine.getManager( PageManager.class ).getPage( pageName );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( oldLogin ) ) );
         Assertions.assertNotNull( p.getAcl().getEntry( new WikiPrincipal( oldName ) ) );
         Assertions.assertNull( p.getAcl().getEntry( new WikiPrincipal( newLogin ) ) );
@@ -249,7 +249,7 @@ public class UserManagerTest {
         // Test 8: our page text should have been re-written
         // (The new full name should be in the ACL, but the login name should have been removed)
         expectedText = "[{ALLOW view Alice," + oldName + "}]\nMore test text.  More text.\r\n";
-        actualText = m_engine.getPageManager().getText( pageName );
+        actualText = m_engine.getManager( PageManager.class ).getText( pageName );
         Assertions.assertEquals( expectedText, actualText );
 
         // CLEANUP: delete the profile; user and page; should be back to old counts
@@ -259,18 +259,18 @@ public class UserManagerTest {
         groupManager.removeGroup( group.getName() );
         Assertions.assertEquals( oldGroupCount, groupManager.getRoles().length );
 
-        m_engine.getPageManager().deletePage( pageName );
+        m_engine.getManager( PageManager.class ).deletePage( pageName );
         Assertions.assertEquals( oldPageCount, pageManager.getTotalPageCount() );
     }
 
     @Test
     public void testSetUserProfile() throws Exception {
         // First, count the number of users in the db now.
-        int oldUserCount = m_db.getWikiNames().length;
+        final int oldUserCount = m_db.getWikiNames().length;
 
         // Create a new user with random name
-        WikiSession session = m_engine.guestSession();
-        String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
+        final WikiSession session = m_engine.guestSession();
+        final String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
         UserProfile profile = m_db.newProfile();
         profile.setEmail( "jspwiki.tests@mailinator.com" );
         profile.setLoginName( loginName );
@@ -293,12 +293,12 @@ public class UserManagerTest {
         setUpWithWorkflow();
 
         // First, count the number of users in the db now.
-        int oldUserCount = m_db.getWikiNames().length;
+        final int oldUserCount = m_db.getWikiNames().length;
 
         // Create a new user with random name
-        WikiSession session = m_engine.guestSession();
-        String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
-        UserProfile profile = m_db.newProfile();
+        final WikiSession session = m_engine.guestSession();
+        final String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
+        final UserProfile profile = m_db.newProfile();
         profile.setEmail( "jspwiki.tests@mailinator.com" );
         profile.setLoginName( loginName );
         profile.setFullname( "FullName" + loginName );
@@ -308,20 +308,20 @@ public class UserManagerTest {
         try {
             m_mgr.setUserProfile( session, profile );
             Assertions.fail( "We should have caught a DecisionRequiredException caused by approval!" );
-        } catch( DecisionRequiredException e ) {
+        } catch( final DecisionRequiredException e ) {
         }
 
         // The user should NOT be saved yet
         Assertions.assertEquals( oldUserCount, m_db.getWikiNames().length );
 
         // Now, look in Admin's queue, and verify there's a pending Decision there
-        DecisionQueue dq = m_engine.getWorkflowManager().getDecisionQueue();
-        Collection< Decision > decisions = dq.getActorDecisions( m_engine.adminSession() );
+        final DecisionQueue dq = m_engine.getWorkflowManager().getDecisionQueue();
+        final Collection< Decision > decisions = dq.getActorDecisions( m_engine.adminSession() );
         Assertions.assertEquals( 1, decisions.size() );
 
         // Verify that the Decision has all the facts and attributes we need
-        Decision d = decisions.iterator().next();
-        List< Fact > facts = d.getFacts();
+        final Decision d = decisions.iterator().next();
+        final List< Fact > facts = d.getFacts();
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() ), facts.get( 0 ) );
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() ), facts.get( 1 ) );
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, session.getUserPrincipal().getName() ), facts.get( 2 ) );
@@ -344,12 +344,12 @@ public class UserManagerTest {
         setUpWithWorkflow();
 
         // First, count the number of users in the db now.
-        int oldUserCount = m_db.getWikiNames().length;
+        final int oldUserCount = m_db.getWikiNames().length;
 
         // Create a new user with random name
-        WikiSession session = m_engine.guestSession();
-        String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
-        UserProfile profile = m_db.newProfile();
+        final WikiSession session = m_engine.guestSession();
+        final String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
+        final UserProfile profile = m_db.newProfile();
         profile.setEmail( "jspwiki.tests@mailinator.com" );
         profile.setLoginName( loginName );
         profile.setFullname( "FullName" + loginName );
@@ -359,20 +359,20 @@ public class UserManagerTest {
         try {
             m_mgr.setUserProfile( session, profile );
             Assertions.fail( "We should have caught a DecisionRequiredException caused by approval!" );
-        } catch( DecisionRequiredException e ) {
+        } catch( final DecisionRequiredException e ) {
         }
 
         // The user should NOT be saved yet
         Assertions.assertEquals( oldUserCount, m_db.getWikiNames().length );
 
         // Now, look in Admin's queue, and verify there's a pending Decision there
-        DecisionQueue dq = m_engine.getWorkflowManager().getDecisionQueue();
-        Collection< Decision > decisions = dq.getActorDecisions( m_engine.adminSession() );
+        final DecisionQueue dq = m_engine.getWorkflowManager().getDecisionQueue();
+        final Collection< Decision > decisions = dq.getActorDecisions( m_engine.adminSession() );
         Assertions.assertEquals( 1, decisions.size() );
 
         // Verify that the Decision has all the facts and attributes we need
-        Decision d = decisions.iterator().next();
-        List< Fact > facts = d.getFacts();
+        final Decision d = decisions.iterator().next();
+        final List< Fact > facts = d.getFacts();
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() ), facts.get( 0 ) );
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() ), facts.get( 1 ) );
         Assertions.assertEquals( new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, session.getUserPrincipal().getName() ), facts.get( 2 ) );
@@ -389,12 +389,12 @@ public class UserManagerTest {
     @Test
     public void testSetCollidingUserProfile() throws Exception {
         // First, count the number of users in the db now.
-        int oldUserCount = m_db.getWikiNames().length;
+        final int oldUserCount = m_db.getWikiNames().length;
 
         // Create a new user with random name
-        WikiSession session = m_engine.guestSession();
-        String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
-        UserProfile profile = m_db.newProfile();
+        final WikiSession session = m_engine.guestSession();
+        final String loginName = "TestUser" + String.valueOf( System.currentTimeMillis() );
+        final UserProfile profile = m_db.newProfile();
         profile.setEmail( "jspwiki.tests@mailinator.com" );
         profile.setLoginName( loginName );
         profile.setFullname( "FullName" + loginName );
@@ -405,7 +405,7 @@ public class UserManagerTest {
         try {
             m_mgr.setUserProfile( session, profile );
             Assertions.fail( "UserManager allowed saving of user with login name 'janne', but it shouldn't have." );
-        } catch( DuplicateUserException e ) {
+        } catch( final DuplicateUserException e ) {
             // Good! That's what we expected; reset for next test
             profile.setLoginName( loginName );
         }
@@ -415,7 +415,7 @@ public class UserManagerTest {
         try {
             m_mgr.setUserProfile( session, profile );
             Assertions.fail( "UserManager allowed saving of user with login name 'janne', but it shouldn't have." );
-        } catch( DuplicateUserException e ) {
+        } catch( final DuplicateUserException e ) {
             // Good! That's what we expected
         }
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/acl/DefaultAclManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/acl/DefaultAclManagerTest.java
index c6a92e1..d287350 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/acl/DefaultAclManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/acl/DefaultAclManagerTest.java
@@ -17,12 +17,14 @@
     under the License.
  */
 package org.apache.wiki.auth.acl;
+
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.ProviderException;
 import org.apache.wiki.auth.WikiPrincipal;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -44,8 +46,8 @@ public class DefaultAclManagerTest
     @AfterEach
     public void tearDown() {
         try {
-            m_engine.getPageManager().deletePage( "TestDefaultPage" );
-            m_engine.getPageManager().deletePage( "TestAclPage" );
+            m_engine.getManager( PageManager.class ).deletePage( "TestDefaultPage" );
+            m_engine.getManager( PageManager.class ).deletePage( "TestAclPage" );
         } catch ( final ProviderException e ) {
         }
     }
@@ -53,12 +55,12 @@ public class DefaultAclManagerTest
     @Test
     public void testGetPermissions()
     {
-        WikiPage page = m_engine.getPageManager().getPage( "TestDefaultPage" );
+        WikiPage page = m_engine.getManager( PageManager.class ).getPage( "TestDefaultPage" );
         Acl acl = m_engine.getAclManager().getPermissions( page );
         Assertions.assertNotNull( page.getAcl() );
         Assertions.assertTrue(page.getAcl().isEmpty());
 
-        page = m_engine.getPageManager().getPage( "TestAclPage" );
+        page = m_engine.getManager( PageManager.class ).getPage( "TestAclPage" );
         acl = m_engine.getAclManager().getPermissions( page );
         Assertions.assertNotNull( page.getAcl() );
         Assertions.assertFalse(page.getAcl().isEmpty());
@@ -159,9 +161,9 @@ public class DefaultAclManagerTest
     public void testPrintAcl()
     {
         // Verify that the printed Acl for the test page is OK
-        WikiPage page = m_engine.getPageManager().getPage( "TestAclPage" );
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( "TestAclPage" );
         Acl acl = m_engine.getAclManager().getPermissions( page );
-        String aclString = DefaultAclManager.printAcl( acl );
+        final String aclString = DefaultAclManager.printAcl( acl );
         Assertions.assertEquals( "[{ALLOW edit Charlie,Herman}]\n", aclString );
 
         // Create an ACL from scratch
@@ -178,7 +180,7 @@ public class DefaultAclManagerTest
         acl.addEntry( entry );
 
         // Verify that the printed ACL is OK
-        String expectedValue = "[{ALLOW delete Devin}]\n[{ALLOW edit Charlie,Devin}]\n[{ALLOW view Charlie}]\n";
+        final String expectedValue = "[{ALLOW delete Devin}]\n[{ALLOW edit Charlie,Devin}]\n[{ALLOW view Charlie}]\n";
         Assertions.assertEquals( expectedValue, DefaultAclManager.printAcl( acl ) );
     }
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/content/PageRenamerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/content/PageRenamerTest.java
index fe57d7f..0eadaa0 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/content/PageRenamerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/content/PageRenamerTest.java
@@ -17,6 +17,7 @@
     under the License.
  */
 package org.apache.wiki.content;
+
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
@@ -25,6 +26,7 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -39,7 +41,7 @@ public class PageRenamerTest
 
     @BeforeEach
     public void setUp() throws Exception {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
         props.setProperty( WikiEngine.PROP_MATCHPLURALS, "true" );
         CacheManager.getInstance().removeAllCaches();
         TestEngine.emptyWorkDir();
@@ -71,23 +73,23 @@ public class PageRenamerTest
     @Test
     public void testSimpleRename() throws Exception {
         // Count the number of existing references
-        int refCount = m_engine.getReferenceManager().findCreated().size();
+        final int refCount = m_engine.getReferenceManager().findCreated().size();
 
         m_engine.saveText("TestPage", "the big lazy dog thing" );
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", false);
 
-        WikiPage newpage = m_engine.getPageManager().getPage("FooTest");
+        final WikiPage newpage = m_engine.getManager( PageManager.class ).getPage("FooTest");
 
         Assertions.assertNotNull( newpage, "no new page" );
-        Assertions.assertNull( m_engine.getPageManager().getPage("TestPage"), "old page not gone" );
+        Assertions.assertNull( m_engine.getManager( PageManager.class ).getPage("TestPage"), "old page not gone" );
 
         // Refmgr
-        Collection< String > refs = m_engine.getReferenceManager().findCreated();
+        final Collection< String > refs = m_engine.getReferenceManager().findCreated();
 
         Assertions.assertTrue( refs.contains("FooTest"), "FooTest does not exist" );
         Assertions.assertFalse( refs.contains("TestPage"), "TestPage exists" );
@@ -101,13 +103,13 @@ public class PageRenamerTest
         m_engine.saveText("TestPage", "foofoo" );
         m_engine.saveText("TestPage2", "[TestPage]");
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION);
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION);
 
         Assertions.assertEquals( "[FooTest]", data.trim(), "no rename" );
 
@@ -127,13 +129,13 @@ public class PageRenamerTest
         m_engine.saveText("TestPage", "foofoo" );
         m_engine.saveText("TestPage2", "TestPage");
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION);
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION);
 
         Assertions.assertEquals( "FooTest", data.trim(), "no rename" );
         Collection< String > refs = m_engine.getReferenceManager().findReferrers("TestPage");
@@ -152,13 +154,13 @@ public class PageRenamerTest
         m_engine.saveText("TestPage", "foofoo" );
         m_engine.saveText("TestPage2", "[TestPage#heading1]");
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION);
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION);
 
         Assertions.assertEquals( "[FooTest#heading1]", data.trim(), "no rename" );
         Collection< String > refs = m_engine.getReferenceManager().findReferrers("TestPage");
@@ -177,13 +179,13 @@ public class PageRenamerTest
         m_engine.saveText("TestPage", "foofoo" );
         m_engine.saveText("TestPage2", "[TestPage] [TestPage] [linktext|TestPage] TestPage [linktext|TestPage] [TestPage#Anchor] [TestPage] TestPage [TestPage]");
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION);
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION);
 
         Assertions.assertEquals( "[FooTest] [FooTest] [linktext|FooTest] FooTest [linktext|FooTest] [FooTest#Anchor] [FooTest] FooTest [FooTest]",
                                  data.trim(), 
@@ -205,13 +207,13 @@ public class PageRenamerTest
         m_engine.saveText("Test","foo");
         m_engine.saveText("TestPage2", "[Test] [Test#anchor] test Test [test] [link|test] [link|test]");
 
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "Test", "TestPage", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION );
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION );
 
         Assertions.assertEquals( "[TestPage] [TestPage#anchor] test Test [TestPage] [link|TestPage] [link|TestPage]", data.trim(), "wrong data" );
     }
@@ -225,13 +227,13 @@ public class PageRenamerTest
 
         m_engine.addAttachment("TestPage", "foo.txt", "testing".getBytes() );
         m_engine.addAttachment("TestPage", "bar.jpg", "pr0n".getBytes() );
-        WikiPage p = m_engine.getPageManager().getPage("TestPage");
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, "TestPage", "FooTest", true);
 
-        String data = m_engine.getPageManager().getPureText("TestPage2", WikiProvider.LATEST_VERSION);
+        final String data = m_engine.getManager( PageManager.class ).getPureText("TestPage2", WikiProvider.LATEST_VERSION);
 
         Assertions.assertEquals( "[FooTest/foo.txt] [linktext|FooTest/bar.jpg]", data.trim(), "no rename" );
 
@@ -263,11 +265,11 @@ public class PageRenamerTest
 
         rename( "TestPage", "FooTest" );
 
-        WikiPage p = m_engine.getPageManager().getPage( "FooTest" );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( "FooTest" );
 
         Assertions.assertNotNull( p, "no page" );
 
-        Assertions.assertEquals("[FooTest]", m_engine.getPageManager().getText("FooTest").trim() );
+        Assertions.assertEquals("[FooTest]", m_engine.getManager( PageManager.class ).getText("FooTest").trim() );
     }
 
     @Test
@@ -278,12 +280,12 @@ public class PageRenamerTest
 
         rename( "TestPage", "FooTest" );
 
-        WikiPage p = m_engine.getPageManager().getPage( "FooTest" );
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage( "FooTest" );
 
         Assertions.assertNotNull( p, "no page" );
 
         // Should be no change
-        Assertions.assertEquals("[TestPage|]", m_engine.getPageManager().getText("TestPage2").trim() );
+        Assertions.assertEquals("[TestPage|]", m_engine.getManager( PageManager.class ).getText("TestPage2").trim() );
     }
 
     @Test
@@ -292,21 +294,21 @@ public class PageRenamerTest
         m_engine.saveText( "TestPage", "hubbub");
         m_engine.saveText( "TestPage2", "[|TestPage]" );
 
-        WikiPage p;
+        final WikiPage p;
         rename( "TestPage", "FooTest" );
 
-        p = m_engine.getPageManager().getPage( "FooTest" );
+        p = m_engine.getManager( PageManager.class ).getPage( "FooTest" );
 
         Assertions.assertNotNull( p, "no page" );
 
-        Assertions.assertEquals("[|FooTest]", m_engine.getPageManager().getText("TestPage2").trim() );
+        Assertions.assertEquals("[|FooTest]", m_engine.getManager( PageManager.class ).getText("TestPage2").trim() );
     }
 
-    private void rename( String src, String dst ) throws WikiException
+    private void rename( final String src, final String dst ) throws WikiException
     {
-        WikiPage p = m_engine.getPageManager().getPage(src);
+        final WikiPage p = m_engine.getManager( PageManager.class ).getPage(src);
 
-        WikiContext context = new WikiContext(m_engine, p);
+        final WikiContext context = new WikiContext(m_engine, p);
 
         m_engine.getPageRenamer().renamePage(context, src, dst, true);
     }
@@ -314,11 +316,11 @@ public class PageRenamerTest
     @Test
     public void testBug25() throws Exception
     {
-        String src = "[Cdauth/attach.txt] [link|Cdauth/attach.txt] [cdauth|Cdauth/attach.txt]"+
+        final String src = "[Cdauth/attach.txt] [link|Cdauth/attach.txt] [cdauth|Cdauth/attach.txt]"+
                      "[CDauth/attach.txt] [link|CDauth/attach.txt] [cdauth|CDauth/attach.txt]"+
                      "[cdauth/attach.txt] [link|cdauth/attach.txt] [cdauth|cdauth/attach.txt]";
 
-        String dst = "[CdauthNew/attach.txt] [link|CdauthNew/attach.txt] [cdauth|CdauthNew/attach.txt]"+
+        final String dst = "[CdauthNew/attach.txt] [link|CdauthNew/attach.txt] [cdauth|CdauthNew/attach.txt]"+
                      "[CDauth/attach.txt] [link|CDauth/attach.txt] [cdauth|CDauth/attach.txt]"+
                      "[CdauthNew/attach.txt] [link|CdauthNew/attach.txt] [cdauth|CdauthNew/attach.txt]";
 
@@ -329,33 +331,33 @@ public class PageRenamerTest
 
         rename( "Cdauth", "CdauthNew" );
 
-        Assertions.assertEquals( dst, m_engine.getPageManager().getText("TestPage").trim() );
+        Assertions.assertEquals( dst, m_engine.getManager( PageManager.class ).getText("TestPage").trim() );
     }
 
     @Test
     public void testBug21() throws Exception
     {
-        String src = "[Link to TestPage2|TestPage2]";
+        final String src = "[Link to TestPage2|TestPage2]";
 
         m_engine.saveText( "TestPage", src );
         m_engine.saveText( "TestPage2", "foo" );
 
         rename ("TestPage2", "Test");
 
-        Assertions.assertEquals( "[Link to Test|Test]", m_engine.getPageManager().getText( "TestPage" ).trim() );
+        Assertions.assertEquals( "[Link to Test|Test]", m_engine.getManager( PageManager.class ).getText( "TestPage" ).trim() );
     }
 
     @Test
     public void testExtendedLinks() throws Exception
     {
-        String src = "[Link to TestPage2|TestPage2|target='_new']";
+        final String src = "[Link to TestPage2|TestPage2|target='_new']";
 
         m_engine.saveText( "TestPage", src );
         m_engine.saveText( "TestPage2", "foo" );
 
         rename ("TestPage2", "Test");
 
-        Assertions.assertEquals( "[Link to Test|Test|target='_new']", m_engine.getPageManager().getText( "TestPage" ).trim() );
+        Assertions.assertEquals( "[Link to Test|Test|target='_new']", m_engine.getManager( PageManager.class ).getText( "TestPage" ).trim() );
     }
 
     @Test
@@ -369,13 +371,13 @@ public class PageRenamerTest
             rename("TestPage123", "Main8887");
             rename("Main8887", "TestPage123");
         }
-        catch (NullPointerException npe)
+        catch ( final NullPointerException npe)
         {
             npe.printStackTrace();
             System.out.println("NPE: Bug 85 caught?");
             Assertions.fail( npe );
         }
-        catch( WikiException e )
+        catch( final WikiException e )
         {
             // Expected
         }
@@ -392,7 +394,7 @@ public class PageRenamerTest
             rename("TestPage1234", "Main8887");
             rename("Main8887", "TestPage1234");
         }
-        catch (NullPointerException npe)
+        catch ( final NullPointerException npe)
         {
             npe.printStackTrace();
             System.out.println("NPE: Bug 85 caught?");
@@ -411,13 +413,13 @@ public class PageRenamerTest
             rename("Main", "Main8887");
             rename("Main8887", "Main");
         }
-        catch (NullPointerException npe)
+        catch ( final NullPointerException npe)
         {
             npe.printStackTrace();
             System.out.println("NPE: Bug 85 caught?");
             Assertions.fail( npe );
         }
-        catch( WikiException e )
+        catch( final WikiException e )
         {
             // Expected
         }
@@ -434,7 +436,7 @@ public class PageRenamerTest
             rename("Main", "Main8887");
             rename("Main8887", "Main");
         }
-        catch (NullPointerException npe)
+        catch ( final NullPointerException npe)
         {
             npe.printStackTrace();
             System.out.println("NPE: Bug 85 caught?");
@@ -445,27 +447,27 @@ public class PageRenamerTest
     @Test
     public void testRenameOfEscapedLinks() throws Exception
     {
-        String src = "[[Link to TestPage2|TestPage2|target='_new']";
+        final String src = "[[Link to TestPage2|TestPage2|target='_new']";
 
         m_engine.saveText( "TestPage", src );
         m_engine.saveText( "TestPage2", "foo" );
 
         rename ("TestPage2", "Test");
 
-        Assertions.assertEquals( "[[Link to TestPage2|TestPage2|target='_new']", m_engine.getPageManager().getText( "TestPage" ).trim() );
+        Assertions.assertEquals( "[[Link to TestPage2|TestPage2|target='_new']", m_engine.getManager( PageManager.class ).getText( "TestPage" ).trim() );
     }
 
     @Test
     public void testRenameOfEscapedLinks2() throws Exception
     {
-        String src = "~[Link to TestPage2|TestPage2|target='_new']";
+        final String src = "~[Link to TestPage2|TestPage2|target='_new']";
 
         m_engine.saveText( "TestPage", src );
         m_engine.saveText( "TestPage2", "foo" );
 
         rename ("TestPage2", "Test");
 
-        Assertions.assertEquals( "~[Link to TestPage2|TestPage2|target='_new']", m_engine.getPageManager().getText( "TestPage" ).trim() );
+        Assertions.assertEquals( "~[Link to TestPage2|TestPage2|target='_new']", m_engine.getManager( PageManager.class ).getText( "TestPage" ).trim() );
     }
 
     /**
@@ -481,7 +483,7 @@ public class PageRenamerTest
 
         rename( "TestPageReferred", "TestPageReferredNew" );
 
-        String data = m_engine.getPageManager().getPureText( "TestPageReferring", WikiProvider.LATEST_VERSION );
+        final String data = m_engine.getManager( PageManager.class ).getPureText( "TestPageReferring", WikiProvider.LATEST_VERSION );
         Assertions.assertEquals( "[Test Page Referred|TestPageReferredNew]", data.trim(), "page not renamed" );
 
         Collection< String > refs = m_engine.getReferenceManager().findReferrers( "TestPageReferred" );
@@ -502,7 +504,7 @@ public class PageRenamerTest
 
         rename( "Link one", "Link uno" );
 
-        String data = m_engine.getPageManager().getPureText( "RenameTest", WikiProvider.LATEST_VERSION );
+        final String data = m_engine.getManager( PageManager.class ).getPureText( "RenameTest", WikiProvider.LATEST_VERSION );
         Assertions.assertEquals( "[link one|Link uno] [link two]", data.trim(), "page not renamed" );
 
         Collection< String > refs = m_engine.getReferenceManager().findReferrers( "Link one" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/pages/DefaultPageManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/pages/DefaultPageManagerTest.java
index 7966f79..6f39aa6 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/pages/DefaultPageManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/pages/DefaultPageManagerTest.java
@@ -62,7 +62,7 @@ public class DefaultPageManagerTest {
      */
     @Test
     public void testNonExistentPage() {
-        Assertions.assertFalse( engine.getPageManager().wikiPageExists( NAME1 ), "Page already exists" );
+        Assertions.assertFalse( engine.getManager( PageManager.class ).wikiPageExists( NAME1 ), "Page already exists" );
     }
 
     /**
@@ -71,7 +71,7 @@ public class DefaultPageManagerTest {
     @Test
     public void testNonExistentPage2() throws Exception {
         final WikiPage page = new WikiPage( engine, NAME1 );
-        Assertions.assertFalse( engine.getPageManager().wikiPageExists( page ), "Page already exists" );
+        Assertions.assertFalse( engine.getManager( PageManager.class ).wikiPageExists( page ), "Page already exists" );
     }
 
     @Test
@@ -97,8 +97,8 @@ public class DefaultPageManagerTest {
         final File saved = new File( files, NAME1+FileSystemProvider.FILE_EXT );
         Assertions.assertTrue( saved.exists(), "Didn't create it!" );
 
-        final WikiPage page = engine.getPageManager().getPage( NAME1, WikiProvider.LATEST_VERSION );
-        engine.getPageManager().deletePage( page.getName() );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, WikiProvider.LATEST_VERSION );
+        engine.getManager( PageManager.class ).deletePage( page.getName() );
         Assertions.assertFalse( saved.exists(), "Page has not been removed!" );
     }
 
@@ -118,9 +118,9 @@ public class DefaultPageManagerTest {
         Assertions.assertTrue( saved.exists(), "Didn't create it!" );
         Assertions.assertTrue( attfile.exists(), "Attachment dir does not exist" );
 
-        final WikiPage page = engine.getPageManager().getPage( NAME1, WikiProvider.LATEST_VERSION );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, WikiProvider.LATEST_VERSION );
 
-        engine.getPageManager().deletePage( page.getName() );
+        engine.getManager( PageManager.class ).deletePage( page.getName() );
 
         Assertions.assertFalse( saved.exists(), "Page has not been removed!" );
         Assertions.assertFalse( attfile.exists(), "Attachment has not been removed" );
@@ -142,14 +142,14 @@ public class DefaultPageManagerTest {
         Assertions.assertTrue( saved.exists(), "Didn't create it!" );
         Assertions.assertTrue( attfile.exists(), "Attachment dir does not exist" );
 
-        final WikiPage page = engine.getPageManager().getPage( NAME1, WikiProvider.LATEST_VERSION );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, WikiProvider.LATEST_VERSION );
         Assertions.assertNotNull( page, "page" );
 
         att = engine.getAttachmentManager().getAttachmentInfo(NAME1+"/TestAtt.txt");
-        engine.getPageManager().deletePage(att.getName());
-        engine.getPageManager().deletePage( NAME1 );
-        Assertions.assertNull( engine.getPageManager().getPage(NAME1), "Page not removed" );
-        Assertions.assertNull( engine.getPageManager().getPage(NAME1+"/TestAtt.txt"), "Att not removed" );
+        engine.getManager( PageManager.class ).deletePage(att.getName());
+        engine.getManager( PageManager.class ).deletePage( NAME1 );
+        Assertions.assertNull( engine.getManager( PageManager.class ).getPage(NAME1), "Page not removed" );
+        Assertions.assertNull( engine.getManager( PageManager.class ).getPage(NAME1+"/TestAtt.txt"), "Att not removed" );
 
         final Collection< String > refs = engine.getReferenceManager().findReferrers(NAME1);
         Assertions.assertNull( refs, "referrers" );
@@ -164,11 +164,11 @@ public class DefaultPageManagerTest {
         engine.saveText( NAME1, "Test2" );
         engine.saveText( NAME1, "Test3" );
 
-        final WikiPage page = engine.getPageManager().getPage( NAME1, 3 );
-        engine.getPageManager().deleteVersion( page );
-        Assertions.assertNull( engine.getPageManager().getPage( NAME1, 3 ), "got page" );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, 3 );
+        engine.getManager( PageManager.class ).deleteVersion( page );
+        Assertions.assertNull( engine.getManager( PageManager.class ).getPage( NAME1, 3 ), "got page" );
 
-        final String content = engine.getPageManager().getText( NAME1, WikiProvider.LATEST_VERSION );
+        final String content = engine.getManager( PageManager.class ).getText( NAME1, WikiProvider.LATEST_VERSION );
         Assertions.assertEquals( "Test2", content.trim(), "content" );
     }
 
@@ -181,13 +181,13 @@ public class DefaultPageManagerTest {
         engine.saveText( NAME1, "Test2" );
         engine.saveText( NAME1, "Test3" );
 
-        final WikiPage page = engine.getPageManager().getPage( NAME1, 1 );
-        engine.getPageManager().deleteVersion( page );
-        Assertions.assertNull( engine.getPageManager().getPage( NAME1, 1 ), "got page" );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
+        engine.getManager( PageManager.class ).deleteVersion( page );
+        Assertions.assertNull( engine.getManager( PageManager.class ).getPage( NAME1, 1 ), "got page" );
 
-        final String content = engine.getPageManager().getText( NAME1, WikiProvider.LATEST_VERSION );
+        final String content = engine.getManager( PageManager.class ).getText( NAME1, WikiProvider.LATEST_VERSION );
         Assertions.assertEquals( "Test3", content.trim(), "content" );
-        Assertions.assertEquals( "", engine.getPageManager().getText(NAME1, 1).trim(), "content1" );
+        Assertions.assertEquals( "", engine.getManager( PageManager.class ).getText(NAME1, 1).trim(), "content1" );
     }
 
     @Test
@@ -196,8 +196,8 @@ public class DefaultPageManagerTest {
         props.setProperty( "jspwiki.pageProvider", "org.apache.wiki.providers.VerySimpleProvider" );
         props.setProperty( "jspwiki.usePageCache", "false" );
         final WikiEngine engine = new TestEngine( props );
-        final WikiPage p = engine.getPageManager().getPage( "test", -1 );
-        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getPageManager().getProvider();
+        final WikiPage p = engine.getManager( PageManager.class ).getPage( "test", -1 );
+        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getManager( PageManager.class ).getProvider();
 
         Assertions.assertEquals( "test", vsp.m_latestReq, "wrong page" );
         Assertions.assertEquals( -1, vsp.m_latestVers, "wrong version" );
@@ -210,8 +210,8 @@ public class DefaultPageManagerTest {
         props.setProperty( "jspwiki.pageProvider", "org.apache.wiki.providers.VerySimpleProvider" );
         props.setProperty( "jspwiki.usePageCache", "false" );
         final WikiEngine engine = new TestEngine( props );
-        final String p = engine.getPageManager().getText( "test", -1 );
-        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getPageManager().getProvider();
+        final String p = engine.getManager( PageManager.class ).getText( "test", -1 );
+        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getManager( PageManager.class ).getProvider();
 
         Assertions.assertEquals( "test", vsp.m_latestReq, "wrong page" );
         Assertions.assertEquals( -1, vsp.m_latestVers, "wrong version" );
@@ -225,7 +225,7 @@ public class DefaultPageManagerTest {
         props.setProperty( "jspwiki.usePageCache", "false" );
         final WikiEngine engine = new TestEngine( props );
         final String p = engine.getRenderingManager().getHTML( "test", -1 );
-        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getPageManager().getProvider();
+        final VerySimpleProvider vsp = (VerySimpleProvider) engine.getManager( PageManager.class ).getProvider();
 
         Assertions.assertEquals( "test", vsp.m_latestReq, "wrong page" );
         Assertions.assertEquals( 5, vsp.m_latestVers, "wrong version" );
@@ -239,7 +239,7 @@ public class DefaultPageManagerTest {
         props.setProperty( "jspwiki.usePageCache", "true" );
         final WikiEngine engine = new TestEngine( props );
         final String p = engine.getRenderingManager().getHTML( VerySimpleProvider.PAGENAME, -1 );
-        final CachingProvider cp = (CachingProvider)engine.getPageManager().getProvider();
+        final CachingProvider cp = (CachingProvider)engine.getManager( PageManager.class ).getProvider();
         final VerySimpleProvider vsp = (VerySimpleProvider) cp.getRealProvider();
 
         Assertions.assertEquals( VerySimpleProvider.PAGENAME, vsp.m_latestReq, "wrong page" );
@@ -251,20 +251,20 @@ public class DefaultPageManagerTest {
     public void testCreatePage() throws Exception {
         final String text = "Foobar.\r\n";
         final String name = "mrmyxpltz";
-        Assertions.assertFalse( engine.getPageManager().wikiPageExists( name ), "page should not exist right now" );
+        Assertions.assertFalse( engine.getManager( PageManager.class ).wikiPageExists( name ), "page should not exist right now" );
 
         engine.saveText( name, text );
-        Assertions.assertTrue( engine.getPageManager().wikiPageExists( name ), "page does not exist" );
+        Assertions.assertTrue( engine.getManager( PageManager.class ).wikiPageExists( name ), "page does not exist" );
     }
 
     @Test
     public void testCreateEmptyPage() throws Exception {
         final String text = "";
         final String name = "mrmxyzptlk";
-        Assertions.assertFalse( engine.getPageManager().wikiPageExists( name ), "page should not exist right now" );
+        Assertions.assertFalse( engine.getManager( PageManager.class ).wikiPageExists( name ), "page should not exist right now" );
 
         engine.saveText( name, text );
-        Assertions.assertFalse( engine.getPageManager().wikiPageExists( name ), "page should not exist right now neither" );
+        Assertions.assertFalse( engine.getManager( PageManager.class ).wikiPageExists( name ), "page should not exist right now neither" );
     }
 
     @Test
@@ -273,8 +273,8 @@ public class DefaultPageManagerTest {
         final String name = NAME1;
         engine.saveText( name, text );
 
-        Assertions.assertTrue( engine.getPageManager().wikiPageExists( name ), "page does not exist" );
-        Assertions.assertEquals( text, engine.getPageManager().getText( name ), "wrong content" );
+        Assertions.assertTrue( engine.getManager( PageManager.class ).wikiPageExists( name ), "page does not exist" );
+        Assertions.assertEquals( text, engine.getManager( PageManager.class ).getText( name ), "wrong content" );
     }
 
     @Test
@@ -283,8 +283,8 @@ public class DefaultPageManagerTest {
         final String name = NAME1;
         engine.saveText( name, text );
 
-        Assertions.assertTrue( engine.getPageManager().wikiPageExists( name ), "page does not exist" );
-        Assertions.assertEquals( "Foobar. &amp;quot;\r\n", engine.getPageManager().getText( name ), "wrong content" );
+        Assertions.assertTrue( engine.getManager( PageManager.class ).wikiPageExists( name ), "page does not exist" );
+        Assertions.assertEquals( "Foobar. &amp;quot;\r\n", engine.getManager( PageManager.class ).getText( name ), "wrong content" );
     }
 
     /**
@@ -296,8 +296,8 @@ public class DefaultPageManagerTest {
         final String name = NAME1;
         engine.saveText( name, text );
 
-        Assertions.assertTrue( engine.getPageManager().wikiPageExists( name ), "page does not exist" );
-        Assertions.assertEquals( "Foobar. &quot;\r\n", engine.getPageManager().getText( name ), "wrong content" );
+        Assertions.assertTrue( engine.getManager( PageManager.class ).wikiPageExists( name ), "page does not exist" );
+        Assertions.assertEquals( "Foobar. &quot;\r\n", engine.getManager( PageManager.class ).getText( name ), "wrong content" );
     }
 
     @Test
@@ -306,12 +306,12 @@ public class DefaultPageManagerTest {
         final String name = NAME1;
         engine.saveText( name, text );
 
-        Assertions.assertTrue( engine.getPageManager().wikiPageExists( name ), "page does not exist" );
+        Assertions.assertTrue( engine.getManager( PageManager.class ).wikiPageExists( name ), "page does not exist" );
         // saveText uses normalizePostData to assure it conforms to certain rules
-        Assertions.assertEquals( TextUtil.normalizePostData( text ), engine.getPageManager().getText( name ), "wrong content" );
+        Assertions.assertEquals( TextUtil.normalizePostData( text ), engine.getManager( PageManager.class ).getText( name ), "wrong content" );
 
         engine.saveText( name, "" );
-        Assertions.assertEquals( TextUtil.normalizePostData( "" ), engine.getPageManager().getText( name ), "wrong content" );
+        Assertions.assertEquals( TextUtil.normalizePostData( "" ), engine.getManager( PageManager.class ).getText( name ), "wrong content" );
     }
 
 }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/parser/JSPWikiMarkupParserTest.java b/jspwiki-main/src/test/java/org/apache/wiki/parser/JSPWikiMarkupParserTest.java
index 36894d3..4becf60 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/parser/JSPWikiMarkupParserTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/parser/JSPWikiMarkupParserTest.java
@@ -27,6 +27,7 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.providers.BasicAttachmentProvider;
 import org.apache.wiki.render.XHTMLRenderer;
 import org.apache.wiki.stress.Benchmark;
@@ -49,7 +50,7 @@ import java.util.Vector;
 public class JSPWikiMarkupParserTest
 {
     Properties props = TestEngine.getTestProperties();
-    Vector<String>     created = new Vector<String>();
+    Vector<String>     created = new Vector<>();
 
     static final String PAGE_NAME = "testpage";
 
@@ -71,7 +72,7 @@ public class JSPWikiMarkupParserTest
         deleteCreatedPages();
     }
 
-    private void newPage( String name )
+    private void newPage( final String name )
         throws WikiException
     {
         testEngine.saveText( name, "<test>" );
@@ -81,9 +82,9 @@ public class JSPWikiMarkupParserTest
 
     private void deleteCreatedPages()
     {
-        for( Iterator< String > i = created.iterator(); i.hasNext(); )
+        for( final Iterator< String > i = created.iterator(); i.hasNext(); )
         {
-            String name = i.next();
+            final String name = i.next();
 
             testEngine.deleteTestPage(name);
             TestEngine.deleteAttachments(name);
@@ -92,7 +93,7 @@ public class JSPWikiMarkupParserTest
         created.clear();
     }
 
-    private String translate( String src )
+    private String translate( final String src )
     throws IOException,
             NoRequiredPropertyException,
             ServletException
@@ -100,7 +101,7 @@ public class JSPWikiMarkupParserTest
         return translate( new WikiPage(testEngine, PAGE_NAME), src );
     }
 
-    private String translate( WikiEngine e, String src )
+    private String translate( final WikiEngine e, final String src )
         throws IOException,
                NoRequiredPropertyException,
                ServletException
@@ -109,7 +110,7 @@ public class JSPWikiMarkupParserTest
     }
 
 
-    private String translate( WikiPage p, String src )
+    private String translate( final WikiPage p, final String src )
         throws IOException,
                NoRequiredPropertyException,
                ServletException
@@ -117,21 +118,21 @@ public class JSPWikiMarkupParserTest
         return translate( testEngine, p, src );
     }
 
-    private String translate( WikiEngine e, WikiPage p, String src )
+    private String translate( final WikiEngine e, final WikiPage p, final String src )
         throws IOException,
                NoRequiredPropertyException,
                ServletException
     {
-        WikiContext context = new WikiContext( e, testEngine.newHttpRequest(), p );
-        JSPWikiMarkupParser tr = new JSPWikiMarkupParser( context,
+        final WikiContext context = new WikiContext( e, testEngine.newHttpRequest(), p );
+        final JSPWikiMarkupParser tr = new JSPWikiMarkupParser( context,
                                                           new BufferedReader( new StringReader(src)) );
 
-        XHTMLRenderer conv = new XHTMLRenderer( context, tr.parse() );
+        final XHTMLRenderer conv = new XHTMLRenderer( context, tr.parse() );
 
         return conv.getString();
     }
 
-    private String translate_nofollow( String src )
+    private String translate_nofollow( final String src )
         throws IOException,
                NoRequiredPropertyException,
                ServletException,
@@ -140,14 +141,14 @@ public class JSPWikiMarkupParserTest
         props = TestEngine.getTestProperties();
 
         props.setProperty( "jspwiki.translatorReader.useRelNofollow", "true" );
-        TestEngine testEngine2 = new TestEngine( props );
+        final TestEngine testEngine2 = new TestEngine( props );
 
-        WikiContext context = new WikiContext( testEngine2,
+        final WikiContext context = new WikiContext( testEngine2,
                                                new WikiPage(testEngine2, PAGE_NAME) );
-        JSPWikiMarkupParser r = new JSPWikiMarkupParser( context,
+        final JSPWikiMarkupParser r = new JSPWikiMarkupParser( context,
                                                          new BufferedReader( new StringReader(src)) );
 
-        XHTMLRenderer conv = new XHTMLRenderer( context, r.parse() );
+        final XHTMLRenderer conv = new XHTMLRenderer( context, r.parse() );
 
         return conv.getString();
     }
@@ -158,7 +159,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("Hyperlink");
 
-        String src = "This should be a [hyperlink]";
+        final String src = "This should be a [hyperlink]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=Hyperlink\">hyperlink</a>",
                       translate(src) );
@@ -170,7 +171,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperlinkToo");
 
-        String src = "This should be a [hyperlink too]";
+        final String src = "This should be a [hyperlink too]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperlinkToo\">hyperlink too</a>",
                       translate(src) );
@@ -182,7 +183,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [HyperLink]";
+        final String src = "This should be a [HyperLink]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>",
                       translate(src) );
@@ -194,7 +195,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [here|HyperLink]";
+        final String src = "This should be a [here|HyperLink]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">here</a>",
                       translate(src) );
@@ -206,7 +207,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [here|HyperLink#heading]";
+        final String src = "This should be a [here|HyperLink#heading]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink#section-HyperLink-Heading\">here</a>",
                       translate(src) );
@@ -218,7 +219,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [HyperLink#heading]";
+        final String src = "This should be a [HyperLink#heading]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink#section-HyperLink-Heading\">HyperLink#heading</a>",
                       translate(src) );
@@ -230,7 +231,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "!Heading Too\r\nThis should be a [HyperLink#heading too]";
+        final String src = "!Heading Too\r\nThis should be a [HyperLink#heading too]";
 
         Assertions.assertEquals( "<h4 id=\"section-testpage-HeadingToo\">Heading Too<a class=\"hashlink\" href=\"#section-testpage-HeadingToo\">#</a></h4>\nThis should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink#section-HyperLink-HeadingToo\">HyperLink#heading too</a>",
                       translate(src) );
@@ -243,7 +244,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [HyperLink#headingwithnonASCIIZoltán]";
+        final String src = "This should be a [HyperLink#headingwithnonASCIIZoltán]";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink#section-HyperLink-HeadingwithnonASCIIZolt_E1n\">HyperLink#headingwithnonASCIIZoltán</a>",
                 translate(src) );
@@ -260,7 +261,7 @@ public class JSPWikiMarkupParserTest
         newPage("DiscussionAboutWiki");
         newPage("WikiMarkupDevelopment");
 
-        String src = "[DiscussionAboutWiki] [WikiMarkupDevelopment].";
+        final String src = "[DiscussionAboutWiki] [WikiMarkupDevelopment].";
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=DiscussionAboutWiki\">DiscussionAboutWiki</a> <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=WikiMarkupDevelopment\">WikiMarkupDevelopment</a>.",
                       translate(src) );
@@ -272,7 +273,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a HyperLink.";
+        final String src = "This should be a HyperLink.";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>.",
                       translate(src) );
@@ -282,7 +283,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCNonExistant()
     throws Exception
     {
-        String src = "This should be a HyperLink.";
+        final String src = "This should be a HyperLink.";
 
         Assertions.assertEquals( "This should be a <a class=\"createpage\" href=\"/test/Edit.jsp?page=HyperLink\" title=\"Create &quot;HyperLink&quot;\">HyperLink</a>.",
                       translate(src) );
@@ -299,7 +300,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should be a [  HyperLink  ].";
+        final String src = "This should be a [  HyperLink  ].";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">  HyperLink  </a>.",
                       translate(src) );
@@ -309,7 +310,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCC3()
     throws Exception
     {
-        String src = "This should be a nonHyperLink.";
+        final String src = "This should be a nonHyperLink.";
 
         Assertions.assertEquals( "This should be a nonHyperLink.",
                       translate(src) );
@@ -325,7 +326,7 @@ public class JSPWikiMarkupParserTest
         newPage("HyperLink");
         newPage("ThisToo");
 
-        String src = "This should be a HyperLink, and ThisToo.";
+        final String src = "This should be a HyperLink, and ThisToo.";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>, and <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ThisToo\">ThisToo</a>.",
                       translate(src) );
@@ -341,7 +342,7 @@ public class JSPWikiMarkupParserTest
         newPage("HyperLink");
         newPage("ThisToo");
 
-        String src = "This should be a [HyperLink], and ThisToo.";
+        final String src = "This should be a [HyperLink], and ThisToo.";
 
         Assertions.assertEquals( "This should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>, and <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ThisToo\">ThisToo</a>.",
                       translate(src) );
@@ -356,7 +357,7 @@ public class JSPWikiMarkupParserTest
         newPage("HyperLink");
         newPage("ThisToo");
 
-        String src = "] This ] should be a HyperLink], and ThisToo.";
+        final String src = "] This ] should be a HyperLink], and ThisToo.";
 
         Assertions.assertEquals( "] This ] should be a <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>], and <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ThisToo\">ThisToo</a>.",
                       translate(src) );
@@ -370,7 +371,7 @@ public class JSPWikiMarkupParserTest
         newPage("HyperLink");
         newPage("ThisToo");
 
-        String src = "HyperLink, and ThisToo";
+        final String src = "HyperLink, and ThisToo";
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>, and <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ThisToo\">ThisToo</a>",
                       translate(src) );
@@ -382,7 +383,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs()
     throws Exception
     {
-        String src = "http://www.foo.bar/ANewHope/";
+        final String src = "http://www.foo.bar/ANewHope/";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "<a class=\"external\" href=\"http://www.foo.bar/ANewHope/\">http://www.foo.bar/ANewHope/</a>",
@@ -395,7 +396,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs2()
     throws Exception
     {
-        String src = "mailto:foo@bar.com";
+        final String src = "mailto:foo@bar.com";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "<a class=\"external\" href=\"mailto:foo@bar.com\">mailto:foo@bar.com</a>",
@@ -408,7 +409,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs3()
     throws Exception
     {
-        String src = "This should be a link: http://www.foo.bar/ANewHope/.  Is it?";
+        final String src = "This should be a link: http://www.foo.bar/ANewHope/.  Is it?";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "This should be a link: <a class=\"external\" href=\"http://www.foo.bar/ANewHope/\">http://www.foo.bar/ANewHope/</a>.  Is it?",
@@ -421,7 +422,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs4()
     throws Exception
     {
-        String src = "This should be a link: (http://www.foo.bar/ANewHope/)  Is it?";
+        final String src = "This should be a link: (http://www.foo.bar/ANewHope/)  Is it?";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "This should be a link: (<a class=\"external\" href=\"http://www.foo.bar/ANewHope/\">http://www.foo.bar/ANewHope/</a>)  Is it?",
@@ -434,7 +435,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs5()
     throws Exception
     {
-        String src = "This should be a link: http://www.foo.bar/ANewHope/\nIs it?";
+        final String src = "This should be a link: http://www.foo.bar/ANewHope/\nIs it?";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "This should be a link: <a class=\"external\" href=\"http://www.foo.bar/ANewHope/\">http://www.foo.bar/ANewHope/</a>\nIs it?",
@@ -447,7 +448,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs6()
     throws Exception
     {
-        String src = "This should not be a link: http://''some.server''/wiki//test/Wiki.jsp\nIs it?";
+        final String src = "This should not be a link: http://''some.server''/wiki//test/Wiki.jsp\nIs it?";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "This should not be a link: http://<i>some.server</i>/wiki//test/Wiki.jsp\nIs it?",
@@ -459,7 +460,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs7()
     throws Exception
     {
-        String src = "http://www.foo.bar/ANewHope?q=foobar&gobble=bobble+gnoo";
+        final String src = "http://www.foo.bar/ANewHope?q=foobar&gobble=bobble+gnoo";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "<a class=\"external\" href=\"http://www.foo.bar/ANewHope?q=foobar&amp;gobble=bobble+gnoo\">http://www.foo.bar/ANewHope?q=foobar&amp;gobble=bobble+gnoo</a>",
@@ -470,7 +471,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs8()
     throws Exception
     {
-        String src = "http://www.foo.bar/~ANewHope/";
+        final String src = "http://www.foo.bar/~ANewHope/";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "<a class=\"external\" href=\"http://www.foo.bar/~ANewHope/\">http://www.foo.bar/~ANewHope/</a>",
@@ -481,7 +482,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCURLs9()
     throws Exception
     {
-        String src = "http://www.foo.bar/%7EANewHope/";
+        final String src = "http://www.foo.bar/%7EANewHope/";
 
         // System.out.println( "EX:"+translate(src) );
         Assertions.assertEquals( "<a class=\"external\" href=\"http://www.foo.bar/%7EANewHope/\">http://www.foo.bar/%7EANewHope/</a>",
@@ -492,7 +493,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCNegated()
     throws Exception
     {
-        String src = "This should not be a ~HyperLink.";
+        final String src = "This should not be a ~HyperLink.";
 
         Assertions.assertEquals( "This should not be a HyperLink.",
                       translate(src) );
@@ -502,7 +503,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCNegated2()
     throws Exception
     {
-        String src = "~HyperLinks should not be matched.";
+        final String src = "~HyperLinks should not be matched.";
 
         Assertions.assertEquals( "HyperLinks should not be matched.",
                       translate(src) );
@@ -512,7 +513,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCNegated3()
     throws Exception
     {
-        String src = "The page ~ASamplePage is not a hyperlink.";
+        final String src = "The page ~ASamplePage is not a hyperlink.";
 
         Assertions.assertEquals( "The page ASamplePage is not a hyperlink.",
                       translate(src) );
@@ -522,7 +523,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksCCNegated4()
     throws Exception
     {
-        String src = "The page \"~ASamplePage\" is not a hyperlink.";
+        final String src = "The page \"~ASamplePage\" is not a hyperlink.";
 
         Assertions.assertEquals( "The page &quot;ASamplePage&quot; is not a hyperlink.",
                       translate(src) );
@@ -534,7 +535,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "*HyperLink";
+        final String src = "*HyperLink";
 
         Assertions.assertEquals( "<ul><li><a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a></li></ul>",
                       translate(src) );
@@ -546,7 +547,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("BoldHyperLink");
 
-        String src = "__BoldHyperLink__";
+        final String src = "__BoldHyperLink__";
 
         Assertions.assertEquals( "<b><a class=\"wikipage\" href=\"/test/Wiki.jsp?page=BoldHyperLink\">BoldHyperLink</a></b>",
                       translate(src) );
@@ -558,7 +559,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "Let's see, if a bold __HyperLink__ is correct?";
+        final String src = "Let's see, if a bold __HyperLink__ is correct?";
 
         Assertions.assertEquals( "Let's see, if a bold <b><a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a></b> is correct?",
                       translate(src) );
@@ -570,7 +571,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("ItalicHyperLink");
 
-        String src = "''ItalicHyperLink''";
+        final String src = "''ItalicHyperLink''";
 
         Assertions.assertEquals( "<i><a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ItalicHyperLink\">ItalicHyperLink</a></i>",
                       translate(src) );
@@ -582,7 +583,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "Test. Punctuation. HyperLink.";
+        final String src = "Test. Punctuation. HyperLink.";
 
         Assertions.assertEquals( "Test. Punctuation. <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>.",
                       translate(src) );
@@ -595,7 +596,7 @@ public class JSPWikiMarkupParserTest
         newPage("HyperLink");
         newPage("ThisToo");
 
-        String src = "Punctuations: HyperLink,ThisToo.";
+        final String src = "Punctuations: HyperLink,ThisToo.";
 
         Assertions.assertEquals( "Punctuations: <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=HyperLink\">HyperLink</a>,<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=ThisToo\">ThisToo</a>.",
                       translate(src) );
@@ -607,7 +608,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("\u00c4itiSy\u00f6\u00d6ljy\u00e4");
 
-        String src = "Onko t\u00e4m\u00e4 hyperlinkki: \u00c4itiSy\u00f6\u00d6ljy\u00e4?";
+        final String src = "Onko t\u00e4m\u00e4 hyperlinkki: \u00c4itiSy\u00f6\u00d6ljy\u00e4?";
 
         Assertions.assertEquals( "Onko t\u00e4m\u00e4 hyperlinkki: <a class=\"wikipage\" href=\"/test/Wiki.jsp?page=%C4itiSy%F6%D6ljy%E4\">\u00c4itiSy\u00f6\u00d6ljy\u00e4</a>?",
                       translate(src) );
@@ -618,7 +619,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksExt()
     throws Exception
     {
-        String src = "This should be a [http://www.regex.fi/]";
+        final String src = "This should be a [http://www.regex.fi/]";
 
         Assertions.assertEquals( "This should be a <a class=\"external\" href=\"http://www.regex.fi/\">http://www.regex.fi/</a>",
                       translate(src) );
@@ -628,7 +629,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksExt2()
     throws Exception
     {
-        String src = "This should be a [link|http://www.regex.fi/]";
+        final String src = "This should be a [link|http://www.regex.fi/]";
 
         Assertions.assertEquals( "This should be a <a class=\"external\" href=\"http://www.regex.fi/\">link</a>",
                       translate(src) );
@@ -638,7 +639,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksExtNofollow()
     throws Exception
     {
-        String src = "This should be a [link|http://www.regex.fi/]";
+        final String src = "This should be a [link|http://www.regex.fi/]";
 
         Assertions.assertEquals( "This should be a <a class=\"external\" href=\"http://www.regex.fi/\" rel=\"nofollow\">link</a>",
                       translate_nofollow(src) );
@@ -652,7 +653,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksPluralMatch()
     throws Exception
     {
-        String src = "This should be a [HyperLinks]";
+        final String src = "This should be a [HyperLinks]";
 
         newPage("HyperLink");
 
@@ -664,7 +665,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksPluralMatch2()
     throws Exception
     {
-        String src = "This should be a [HyperLinks]";
+        final String src = "This should be a [HyperLinks]";
 
         Assertions.assertEquals( "This should be a <a class=\"createpage\" href=\"/test/Edit.jsp?page=HyperLinks\" title=\"Create &quot;HyperLinks&quot;\">HyperLinks</a>",
                       translate(src) );
@@ -674,7 +675,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksPluralMatch3()
     throws Exception
     {
-        String src = "This should be a [HyperLink]";
+        final String src = "This should be a [HyperLink]";
 
         newPage("HyperLinks");
 
@@ -686,7 +687,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksPluralMatch4()
     throws Exception
     {
-        String src = "This should be a [Hyper links]";
+        final String src = "This should be a [Hyper links]";
 
         newPage("HyperLink");
 
@@ -699,7 +700,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinkJS1()
     throws Exception
     {
-        String src = "This should be a [link|http://www.haxored.com/\" onMouseOver=\"alert('Hahhaa');\"]";
+        final String src = "This should be a [link|http://www.haxored.com/\" onMouseOver=\"alert('Hahhaa');\"]";
 
         Assertions.assertEquals( "This should be a <a class=\"external\" href=\"http://www.haxored.com/&quot; onMouseOver=&quot;alert('Hahhaa');&quot;\">link</a>",
                       translate(src) );
@@ -709,7 +710,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksInterWiki1()
     throws Exception
     {
-        String src = "This should be a [link|JSPWiki:HyperLink]";
+        final String src = "This should be a [link|JSPWiki:HyperLink]";
 
         Assertions.assertEquals( "This should be a <a class=\"interwiki\" href=\"http://jspwiki-wiki.apache.org/Wiki.jsp?page=HyperLink\">link</a>",
                       translate(src) );
@@ -719,7 +720,7 @@ public class JSPWikiMarkupParserTest
     public void testHyperlinksInterWiki2()
     throws Exception
     {
-        String src = "This should be a [JSPWiki:HyperLink]";
+        final String src = "This should be a [JSPWiki:HyperLink]";
 
         Assertions.assertEquals( "This should be a <a class=\"interwiki\" href=\"http://jspwiki-wiki.apache.org/Wiki.jsp?page=HyperLink\">JSPWiki:HyperLink</a>",
                       translate(src) );
@@ -731,11 +732,11 @@ public class JSPWikiMarkupParserTest
     {
         newPage("Test");
 
-        Attachment att = new Attachment( testEngine, "Test", "TestAtt.txt" );
+        final Attachment att = new Attachment( testEngine, "Test", "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
-        testEngine.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
+        testEngine.getManager( AttachmentManager.class ).storeAttachment( att, testEngine.makeAttachmentFile() );
 
-        String src = "This should be an [attachment link|Test/TestAtt.txt]";
+        final String src = "This should be an [attachment link|Test/TestAtt.txt]";
 
         Assertions.assertEquals( "This should be an <a class=\"attachment\" href=\"/test/attach/Test/TestAtt.txt\">attachment link</a>"+
                       "<a href=\"/test/PageInfo.jsp?page=Test/TestAtt.txt\" class=\"infolink\"><img src=\"/test/images/attachment_small.png\" border=\"0\" alt=\"(info)\" /></a>",
@@ -749,17 +750,17 @@ public class JSPWikiMarkupParserTest
         props.setProperty( "jspwiki.encoding", "ISO-8859-1" );
 
         //TODO
-        TestEngine testEngine2 = new TestEngine( props );
+        final TestEngine testEngine2 = new TestEngine( props );
 
         testEngine2.saveText( "Test", "foo ");
         created.addElement( "Test" );
 
-        Attachment att = new Attachment( testEngine2, "Test", "TestAtt.txt" );
+        final Attachment att = new Attachment( testEngine2, "Test", "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
 
         testEngine2.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
 
-        String src = "This should be an [attachment link|Test/TestAtt.txt]";
+        final String src = "This should be an [attachment link|Test/TestAtt.txt]";
 
         Assertions.assertEquals( "This should be an <a class=\"attachment\" href=\"/test/attach/Test/TestAtt.txt\">attachment link</a>"+
                       "<a href=\"/test/PageInfo.jsp?page=Test/TestAtt.txt\" class=\"infolink\"><img src=\"/test/images/attachment_small.png\" border=\"0\" alt=\"(info)\" /></a>",
@@ -773,17 +774,17 @@ public class JSPWikiMarkupParserTest
     public void testAttachmentLink3()
     throws Exception
     {
-        TestEngine testEngine2 = new TestEngine( props );
+        final TestEngine testEngine2 = new TestEngine( props );
 
         testEngine2.saveText( "TestPage", "foo ");
         created.addElement( "TestPage" );
 
-        Attachment att = new Attachment( testEngine2, "TestPage", "TestAtt.txt" );
+        final Attachment att = new Attachment( testEngine2, "TestPage", "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
 
         testEngine2.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
 
-        String src = "[Test page/TestAtt.txt]";
+        final String src = "[Test page/TestAtt.txt]";
 
         Assertions.assertEquals( "<a class=\"attachment\" href=\"/test/attach/TestPage/TestAtt.txt\">Test page/TestAtt.txt</a>"+
                       "<a href=\"/test/PageInfo.jsp?page=TestPage/TestAtt.txt\" class=\"infolink\"><img src=\"/test/images/attachment_small.png\" border=\"0\" alt=\"(info)\" /></a>",
@@ -794,17 +795,17 @@ public class JSPWikiMarkupParserTest
     public void testAttachmentLink4()
     throws Exception
     {
-        TestEngine testEngine2 = new TestEngine( props );
+        final TestEngine testEngine2 = new TestEngine( props );
 
         testEngine2.saveText( "TestPage", "foo ");
         created.addElement( "TestPage" );
 
-        Attachment att = new Attachment( testEngine2, "TestPage", "TestAtt.txt" );
+        final Attachment att = new Attachment( testEngine2, "TestPage", "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
 
         testEngine2.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
 
-        String src = "["+testEngine2.getRenderingManager().beautifyTitle("TestPage/TestAtt.txt")+"]";
+        final String src = "["+testEngine2.getRenderingManager().beautifyTitle("TestPage/TestAtt.txt")+"]";
 
         Assertions.assertEquals( "<a class=\"attachment\" href=\"/test/attach/TestPage/TestAtt.txt\">Test Page/TestAtt.txt</a>"+
                       "<a href=\"/test/PageInfo.jsp?page=TestPage/TestAtt.txt\" class=\"infolink\"><img src=\"/test/images/attachment_small.png\" border=\"0\" alt=\"(info)\" /></a>",
@@ -817,7 +818,7 @@ public class JSPWikiMarkupParserTest
     {
         newPage("HyperLink");
 
-        String src = "This should not be a [[HyperLink]";
+        final String src = "This should not be a [[HyperLink]";
 
         Assertions.assertEquals( "This should not be a [HyperLink]",
                       translate(src) );
@@ -827,7 +828,7 @@ public class JSPWikiMarkupParserTest
     public void testNoHyperlink2()
     throws Exception
     {
-        String src = "This should not be a [[[[HyperLink]";
+        final String src = "This should not be a [[[[HyperLink]";
 
         Assertions.assertEquals( "This should not be a [[[HyperLink]",
                       translate(src) );
@@ -837,7 +838,7 @@ public class JSPWikiMarkupParserTest
     public void testNoHyperlink3()
     throws Exception
     {
-        String src = "[[HyperLink], and this [[Neither].";
+        final String src = "[[HyperLink], and this [[Neither].";
 
         Assertions.assertEquals( "[HyperLink], and this [Neither].",
                       translate(src) );
@@ -847,7 +848,7 @@ public class JSPWikiMarkupParserTest
     public void testNoPlugin()
     throws Exception
     {
-        String src = "There is [[{NoPlugin}] here.";
+        final String src = "There is [[{NoPlugin}] here.";
 
         Assertions.assertEquals( "There is [{NoPlugin}] here.",
                       translate(src) );
@@ -857,7 +858,7 @@ public class JSPWikiMarkupParserTest
     public void testErroneousHyperlink()
     throws Exception
     {
-        String src = "What if this is the last char [";
+        final String src = "What if this is the last char [";
 
         Assertions.assertEquals( "What if this is the last char ",
                       translate(src) );
@@ -867,7 +868,7 @@ public class JSPWikiMarkupParserTest
     public void testErroneousHyperlink2()
     throws Exception
     {
-        String src = "What if this is the last char [[";
+        final String src = "What if this is the last char [[";
 
         Assertions.assertEquals( "What if this is the last char [",
                       translate(src) );
@@ -877,7 +878,7 @@ public class JSPWikiMarkupParserTest
     public void testExtraPagename1()
     throws Exception
     {
-        String src = "Link [test_page]";
+        final String src = "Link [test_page]";
 
         newPage("Test_page");
 
@@ -889,7 +890,7 @@ public class JSPWikiMarkupParserTest
     public void testExtraPagename2()
     throws Exception
     {
-        String src = "Link [test.page]";
+        final String src = "Link [test.page]";
 
         newPage("Test.page");
 
@@ -901,7 +902,7 @@ public class JSPWikiMarkupParserTest
     public void testExtraPagename3()
     throws Exception
     {
-        String src = "Link [.testpage_]";
+        final String src = "Link [.testpage_]";
 
         newPage(".testpage_");
 
@@ -913,7 +914,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImages()
     throws Exception
     {
-        String src = "Link [test|http://www.ecyrd.com/test.png]";
+        final String src = "Link [test|http://www.ecyrd.com/test.png]";
 
         Assertions.assertEquals("Link <img class=\"inline\" src=\"http://www.ecyrd.com/test.png\" alt=\"test\" />",
                      translate(src) );
@@ -923,7 +924,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImages2()
     throws Exception
     {
-        String src = "Link [test|http://www.ecyrd.com/test.ppm]";
+        final String src = "Link [test|http://www.ecyrd.com/test.ppm]";
 
         Assertions.assertEquals("Link <a class=\"external\" href=\"http://www.ecyrd.com/test.ppm\">test</a>",
                      translate(src) );
@@ -933,7 +934,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImages3()
     throws Exception
     {
-        String src = "Link [test|http://images.com/testi]";
+        final String src = "Link [test|http://images.com/testi]";
 
         Assertions.assertEquals("Link <img class=\"inline\" src=\"http://images.com/testi\" alt=\"test\" />",
                      translate(src) );
@@ -943,7 +944,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImages4()
     throws Exception
     {
-        String src = "Link [test|http://foobar.jpg]";
+        final String src = "Link [test|http://foobar.jpg]";
 
         Assertions.assertEquals("Link <img class=\"inline\" src=\"http://foobar.jpg\" alt=\"test\" />",
                      translate(src) );
@@ -954,7 +955,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImagesLink2()
     throws Exception
     {
-        String src = "Link [http://foobar.jpg]";
+        final String src = "Link [http://foobar.jpg]";
 
         Assertions.assertEquals("Link <img class=\"inline\" src=\"http://foobar.jpg\" alt=\"http://foobar.jpg\" />",
                      translate(src) );
@@ -964,7 +965,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImagesLink()
     throws Exception
     {
-        String src = "Link [http://link.to/|http://foobar.jpg]";
+        final String src = "Link [http://link.to/|http://foobar.jpg]";
 
         Assertions.assertEquals("Link <a class=\"external\" href=\"http://link.to/\"><img class=\"inline\" src=\"http://foobar.jpg\" alt=\"http://link.to/\" /></a>",
                      translate(src) );
@@ -974,7 +975,7 @@ public class JSPWikiMarkupParserTest
     public void testInlineImagesLink3()
     throws Exception
     {
-        String src = "Link [SandBox|http://foobar.jpg]";
+        final String src = "Link [SandBox|http://foobar.jpg]";
 
         newPage("SandBox");
 
@@ -986,7 +987,7 @@ public class JSPWikiMarkupParserTest
     public void testScandicPagename1()
     throws Exception
     {
-        String src = "Link [\u00C5\u00E4Test]";
+        final String src = "Link [\u00C5\u00E4Test]";
 
         newPage("\u00C5\u00E4Test"); // FIXME: Should be capital
 
@@ -998,7 +999,7 @@ public class JSPWikiMarkupParserTest
     public void testParagraph()
     throws Exception
     {
-        String src = "1\n\n2\n\n3";
+        final String src = "1\n\n2\n\n3";
 
         Assertions.assertEquals( "<p>1\n</p><p>2\n</p>\n<p>3</p>", translate(src) );
     }
@@ -1007,7 +1008,7 @@ public class JSPWikiMarkupParserTest
     public void testParagraph2()
     throws Exception
     {
-        String src = "[WikiEtiquette]\r\n\r\n[Search]";
+        final String src = "[WikiEtiquette]\r\n\r\n[Search]";
 
         newPage( "WikiEtiquette" );
 
@@ -1019,7 +1020,7 @@ public class JSPWikiMarkupParserTest
     public void testParagraph3()
     throws Exception
     {
-        String src = "\r\n\r\n!Testi\r\n\r\nFoo.";
+        final String src = "\r\n\r\n!Testi\r\n\r\nFoo.";
 
         Assertions.assertEquals( "<p />\n<h4 id=\"section-testpage-Testi\">Testi<a class=\"hashlink\" href=\"#section-testpage-Testi\">#</a></h4>\n<p>Foo.</p>",
                       translate(src) );
@@ -1029,7 +1030,7 @@ public class JSPWikiMarkupParserTest
     public void testParagraph4()
     throws Exception
     {
-        String src = "\r\n[Recent Changes]\\\\\r\n[WikiEtiquette]\r\n\r\n[Find pages|Search]\\\\\r\n[Unused pages|UnusedPages]";
+        final String src = "\r\n[Recent Changes]\\\\\r\n[WikiEtiquette]\r\n\r\n[Find pages|Search]\\\\\r\n[Unused pages|UnusedPages]";
 
         newPage("WikiEtiquette");
         newPage("RecentChanges");
@@ -1046,7 +1047,7 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testParagraph5() throws Exception
     {
-        String src = "__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
+        final String src = "__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
                      "In UNIX, the file(1) command can be used.";
 
         Assertions.assertEquals( "<p><b>File type sniffing</b> is a way of identifying the content type of a document.\n</p>"+
@@ -1057,7 +1058,7 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testParagraph6() throws Exception
     {
-        String src = "[{Counter}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
+        final String src = "[{Counter}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
                      "In UNIX, the file(1) command can be used.";
 
         Assertions.assertEquals( "<p>1\n</p><p><b>File type sniffing</b> is a way of identifying the content type of a document.\n</p>\n"+
@@ -1068,7 +1069,7 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testParagraph7() throws Exception
     {
-        String src = "[{$encoding}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
+        final String src = "[{$encoding}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
                      "In UNIX, the file(1) command can be used.";
 
         Assertions.assertEquals( "<p>ISO-8859-1\n</p><p><b>File type sniffing</b> is a way of identifying the content type of a document.\n</p>\n"+
@@ -1079,7 +1080,7 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testParagraph8() throws Exception
     {
-        String src = "[{SET foo=bar}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
+        final String src = "[{SET foo=bar}]\n\n__File type sniffing__ is a way of identifying the content type of a document.\n\n"+
                      "In UNIX, the file(1) command can be used.";
 
         Assertions.assertEquals( "<p><b>File type sniffing</b> is a way of identifying the content type of a document.\n</p>\n"+
@@ -1091,7 +1092,7 @@ public class JSPWikiMarkupParserTest
     public void testLinebreak()
     throws Exception
     {
-        String src = "1\\\\2";
+        final String src = "1\\\\2";
 
         Assertions.assertEquals( "1<br />2", translate(src) );
     }
@@ -1100,7 +1101,7 @@ public class JSPWikiMarkupParserTest
     public void testLinebreakEscape()
     throws Exception
     {
-        String src = "1~\\\\2";
+        final String src = "1~\\\\2";
 
         Assertions.assertEquals( "1\\\\2", translate(src) );
     }
@@ -1109,7 +1110,7 @@ public class JSPWikiMarkupParserTest
     public void testLinebreakClear()
     throws Exception
     {
-        String src = "1\\\\\\2";
+        final String src = "1\\\\\\2";
 
         Assertions.assertEquals( "1<br clear=\"all\" />2", translate(src) );
     }
@@ -1118,7 +1119,7 @@ public class JSPWikiMarkupParserTest
     public void testTT()
     throws Exception
     {
-        String src = "1{{2345}}6";
+        final String src = "1{{2345}}6";
 
         Assertions.assertEquals( "1<tt>2345</tt>6", translate(src) );
     }
@@ -1127,7 +1128,7 @@ public class JSPWikiMarkupParserTest
     public void testTTAcrossLines()
     throws Exception
     {
-        String src = "1{{\n2345\n}}6";
+        final String src = "1{{\n2345\n}}6";
 
         Assertions.assertEquals( "1<tt>\n2345\n</tt>6", translate(src) );
     }
@@ -1136,7 +1137,7 @@ public class JSPWikiMarkupParserTest
     public void testTTLinks()
     throws Exception
     {
-        String src = "1{{\n2345\n[a link]\n}}6";
+        final String src = "1{{\n2345\n[a link]\n}}6";
 
         newPage("ALink");
 
@@ -1147,7 +1148,7 @@ public class JSPWikiMarkupParserTest
     public void testPre()
     throws Exception
     {
-        String src = "1{{{2345}}}6";
+        final String src = "1{{{2345}}}6";
 
         Assertions.assertEquals( "1<span class=\"inline-code\">2345</span>6", translate(src) );
     }
@@ -1156,7 +1157,7 @@ public class JSPWikiMarkupParserTest
     public void testPre2()
     throws Exception
     {
-        String src = "1 {{{ {{{ 2345 }}} }}} 6";
+        final String src = "1 {{{ {{{ 2345 }}} }}} 6";
 
         Assertions.assertEquals( "1 <span class=\"inline-code\"> {{{ 2345 </span> }}} 6", translate(src) );
     }
@@ -1165,7 +1166,7 @@ public class JSPWikiMarkupParserTest
     public void testPre3()
     throws Exception
     {
-        String src = "foo\n\nbar{{{2345}}}6";
+        final String src = "foo\n\nbar{{{2345}}}6";
 
         Assertions.assertEquals( "<p>foo\n</p><p>bar<span class=\"inline-code\">2345</span>6</p>", translate(src) );
     }
@@ -1174,7 +1175,7 @@ public class JSPWikiMarkupParserTest
     public void testPreEscape()
     throws Exception
     {
-        String src = "1~{{{2345}}}6";
+        final String src = "1~{{{2345}}}6";
 
         Assertions.assertEquals( "1{{{2345}}}6", translate(src) );
     }
@@ -1183,7 +1184,7 @@ public class JSPWikiMarkupParserTest
     public void testPreEscape2()
     throws Exception
     {
-        String src = "1{{{{{{2345~}}}}}}6";
+        final String src = "1{{{{{{2345~}}}}}}6";
 
         Assertions.assertEquals( "1<span class=\"inline-code\">{{{2345}}}</span>6", translate(src) );
     }
@@ -1192,7 +1193,7 @@ public class JSPWikiMarkupParserTest
     public void testPreEscape3()
     throws Exception
     {
-        String src = "1 {{{ {{{ 2345 ~}}} }}} 6";
+        final String src = "1 {{{ {{{ 2345 ~}}} }}} 6";
 
         Assertions.assertEquals( "1 <span class=\"inline-code\"> {{{ 2345 }}} </span> 6", translate(src) );
     }
@@ -1201,7 +1202,7 @@ public class JSPWikiMarkupParserTest
     public void testPreEscape4()
     throws Exception
     {
-        String src = "1{{{ {{{2345~}} }}}6";
+        final String src = "1{{{ {{{2345~}} }}}6";
 
         Assertions.assertEquals( "1<span class=\"inline-code\"> {{{2345~}} </span>6", translate(src) );
     }
@@ -1210,7 +1211,7 @@ public class JSPWikiMarkupParserTest
     public void testPreEscape5()
     throws Exception
     {
-        String src = "1{{{ ~ }}}6";
+        final String src = "1{{{ ~ }}}6";
 
         Assertions.assertEquals( "1<span class=\"inline-code\"> ~ </span>6", translate(src) );
     }
@@ -1220,7 +1221,7 @@ public class JSPWikiMarkupParserTest
     public void testHTMLInPre()
     throws Exception
     {
-        String src = "1\n{{{ <b> }}}";
+        final String src = "1\n{{{ <b> }}}";
 
         Assertions.assertEquals( "1\n<pre> &lt;b&gt; </pre>", translate(src) );
     }
@@ -1229,7 +1230,7 @@ public class JSPWikiMarkupParserTest
     public void testCamelCaseInPre()
     throws Exception
     {
-        String src = "1\n{{{ CamelCase }}}";
+        final String src = "1\n{{{ CamelCase }}}";
 
         Assertions.assertEquals( "1\n<pre> CamelCase </pre>", translate(src) );
     }
@@ -1238,7 +1239,7 @@ public class JSPWikiMarkupParserTest
     public void testPreWithLines()
     throws Exception
     {
-        String src = "1\r\n{{{\r\nZippadii\r\n}}}";
+        final String src = "1\r\n{{{\r\nZippadii\r\n}}}";
 
         Assertions.assertEquals( "1\n<pre>\nZippadii\n</pre>", translate(src) );
     }
@@ -1247,7 +1248,7 @@ public class JSPWikiMarkupParserTest
     public void testList1()
     throws Exception
     {
-        String src = "A list:\n* One\n* Two\n* Three\n";
+        final String src = "A list:\n* One\n* Two\n* Three\n";
 
         Assertions.assertEquals( "A list:\n<ul><li>One\n</li><li>Two\n</li><li>Three\n</li></ul>",
                       translate(src) );
@@ -1265,7 +1266,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilineList1()
     throws Exception
     {
-        String src = "A list:\n* One\n continuing.\n* Two\n* Three\n";
+        final String src = "A list:\n* One\n continuing.\n* Two\n* Three\n";
 
         Assertions.assertEquals( "A list:\n<ul><li>One\n continuing.\n</li><li>Two\n</li><li>Three\n</li></ul>",
                       translate(src) );
@@ -1275,7 +1276,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilineList2()
     throws Exception
     {
-        String src = "A list:\n* One\n continuing.\n* Two\n* Three\nShould be normal.";
+        final String src = "A list:\n* One\n continuing.\n* Two\n* Three\nShould be normal.";
 
         Assertions.assertEquals( "A list:\n<ul><li>One\n continuing.\n</li><li>Two\n</li><li>Three\n</li></ul>Should be normal.",
                       translate(src) );
@@ -1285,7 +1286,7 @@ public class JSPWikiMarkupParserTest
     public void testHTML()
     throws Exception
     {
-        String src = "<b>Test</b>";
+        final String src = "<b>Test</b>";
 
         Assertions.assertEquals( "&lt;b&gt;Test&lt;/b&gt;", translate(src) );
     }
@@ -1294,7 +1295,7 @@ public class JSPWikiMarkupParserTest
     public void testHTML2()
     throws Exception
     {
-        String src = "<p>";
+        final String src = "<p>";
 
         Assertions.assertEquals( "&lt;p&gt;", translate(src) );
     }
@@ -1303,14 +1304,14 @@ public class JSPWikiMarkupParserTest
     public void testHTMLWhenAllowed()
     throws Exception
     {
-        String src = "<p>";
+        final String src = "<p>";
 
         props.setProperty( "jspwiki.translatorReader.allowHTML", "true" );
         testEngine = new TestEngine( props );
 
-        WikiPage page = new WikiPage(testEngine,PAGE_NAME);
+        final WikiPage page = new WikiPage(testEngine,PAGE_NAME);
 
-        String out = translate( testEngine, page, src );
+        final String out = translate( testEngine, page, src );
 
         Assertions.assertEquals( "<p>", out );
     }
@@ -1319,14 +1320,14 @@ public class JSPWikiMarkupParserTest
     public void testHTMLWhenAllowedPre()
     throws Exception
     {
-        String src = "{{{ <br /> }}}";
+        final String src = "{{{ <br /> }}}";
 
         props.setProperty( "jspwiki.translatorReader.allowHTML", "true" );
         testEngine = new TestEngine( props );
 
-        WikiPage page = new WikiPage(testEngine,PAGE_NAME);
+        final WikiPage page = new WikiPage(testEngine,PAGE_NAME);
 
-        String out = translate( testEngine, page, src );
+        final String out = translate( testEngine, page, src );
 
         Assertions.assertEquals( "<pre> &lt;br /&gt; </pre>", out );
     }
@@ -1347,7 +1348,7 @@ public class JSPWikiMarkupParserTest
     public void testHTMLEntities()
     throws Exception
     {
-        String src = "& &darr; foo&nbsp;bar &nbsp;&quot; &#2020;&";
+        final String src = "& &darr; foo&nbsp;bar &nbsp;&quot; &#2020;&";
 
         Assertions.assertEquals( "&amp; &darr; foo&nbsp;bar &nbsp;&quot; &#2020;&amp;", translate(src) );
     }
@@ -1356,7 +1357,7 @@ public class JSPWikiMarkupParserTest
     public void testItalicAcrossLinebreak()
     throws Exception
     {
-        String src="''This is a\ntest.''";
+        final String src="''This is a\ntest.''";
 
         Assertions.assertEquals( "<i>This is a\ntest.</i>", translate(src) );
     }
@@ -1365,7 +1366,7 @@ public class JSPWikiMarkupParserTest
     public void testBoldAcrossLinebreak()
     throws Exception
     {
-        String src="__This is a\ntest.__";
+        final String src="__This is a\ntest.__";
 
         Assertions.assertEquals( "<b>This is a\ntest.</b>", translate(src) );
     }
@@ -1374,7 +1375,7 @@ public class JSPWikiMarkupParserTest
     public void testBoldAcrossParagraph()
     throws Exception
     {
-        String src="__This is a\n\ntest.__";
+        final String src="__This is a\n\ntest.__";
 
         Assertions.assertEquals( "<p><b>This is a\n</b></p><p><b>test.</b></p>", translate(src) );
     }
@@ -1383,7 +1384,7 @@ public class JSPWikiMarkupParserTest
     public void testBoldItalic()
     throws Exception
     {
-        String src="__This ''is'' a test.__";
+        final String src="__This ''is'' a test.__";
 
         Assertions.assertEquals( "<b>This <i>is</i> a test.</b>", translate(src) );
     }
@@ -1392,7 +1393,7 @@ public class JSPWikiMarkupParserTest
     public void testFootnote1()
     throws Exception
     {
-        String src="Footnote[1]";
+        final String src="Footnote[1]";
 
         Assertions.assertEquals( "Footnote<a class=\"footnoteref\" href=\"#ref-testpage-1\">[1]</a>",
                       translate(src) );
@@ -1402,7 +1403,7 @@ public class JSPWikiMarkupParserTest
     public void testFootnote2()
     throws Exception
     {
-        String src="[#2356] Footnote.";
+        final String src="[#2356] Footnote.";
 
         Assertions.assertEquals( "<a class=\"footnote\" name=\"ref-testpage-2356\">[#2356]</a> Footnote.",
                       translate(src) );
@@ -1414,7 +1415,7 @@ public class JSPWikiMarkupParserTest
     public void testEmptySecondLevelList()
     throws Exception
     {
-        String src="A\n\n**\n\nB";
+        final String src="A\n\n**\n\nB";
 
         // System.out.println(translate(src));
         Assertions.assertEquals( "<p>A\n</p><ul><li><ul><li>\n</li></ul></li></ul><p>B</p>",
@@ -1425,7 +1426,7 @@ public class JSPWikiMarkupParserTest
     public void testEmptySecondLevelList2()
     throws Exception
     {
-        String src="A\n\n##\n\nB";
+        final String src="A\n\n##\n\nB";
 
         // System.out.println(translate(src));
         Assertions.assertEquals( "<p>A\n</p><ol><li><ol><li>\n</li></ol></li></ol><p>B</p>",
@@ -1461,7 +1462,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedList()
     throws Exception
     {
-        String src="*Item A\n##Numbered 1\n##Numbered 2\n*Item B\n";
+        final String src="*Item A\n##Numbered 1\n##Numbered 2\n*Item B\n";
 
         String result = translate(src);
 
@@ -1484,7 +1485,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedList2()
     throws Exception
     {
-        String src="#Item A\n**Numbered 1\n**Numbered 2\n#Item B\n";
+        final String src="#Item A\n**Numbered 1\n**Numbered 2\n#Item B\n";
 
         String result = translate(src);
 
@@ -1528,7 +1529,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedListOnSameLevel()
     throws Exception
     {
-        String src="* bullet A\n** bullet A_1\n*# number A_1\n* bullet B\n";
+        final String src="* bullet A\n** bullet A_1\n*# number A_1\n* bullet B\n";
 
         String result = translate(src);
 
@@ -1577,7 +1578,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedListOnSameLevel2()
     throws Exception
     {
-        String src="* bullet A\n** bullet A_1\n## number A_1\n* bullet B\n";
+        final String src="* bullet A\n** bullet A_1\n## number A_1\n* bullet B\n";
 
         String result = translate(src);
 
@@ -1625,7 +1626,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedListOnSameLevel3()
     throws Exception
     {
-        String src="* bullet 1\n## number 2\n** bullet 3\n## number 4\n* bullet 5\n";
+        final String src="* bullet 1\n## number 2\n** bullet 3\n## number 4\n* bullet 5\n";
 
         String result = translate(src);
 
@@ -1669,7 +1670,7 @@ public class JSPWikiMarkupParserTest
     public void testMixedListOnSameLevel4()
     throws Exception
     {
-        String src="# number 1\n** bullet 2\n## number 3\n** bullet 4\n# number 5\n";
+        final String src="# number 1\n** bullet 2\n## number 3\n** bullet 4\n# number 5\n";
 
         String result = translate(src);
 
@@ -1692,7 +1693,7 @@ public class JSPWikiMarkupParserTest
     public void testNestedList()
     throws Exception
     {
-        String src="*Item A\n**Numbered 1\n**Numbered 2\n*Item B\n";
+        final String src="*Item A\n**Numbered 1\n**Numbered 2\n*Item B\n";
 
         String result = translate(src);
 
@@ -1712,7 +1713,7 @@ public class JSPWikiMarkupParserTest
     public void testNestedList2()
     throws Exception
     {
-        String src="*Item A\n**Numbered 1\n**Numbered 2\n***Numbered3\n*Item B\n";
+        final String src="*Item A\n**Numbered 1\n**Numbered 2\n***Numbered3\n*Item B\n";
 
         String result = translate(src);
 
@@ -1735,7 +1736,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginInsert()
     throws Exception
     {
-        String src="[{INSERT org.apache.wiki.plugin.SamplePlugin WHERE text=test}]";
+        final String src="[{INSERT org.apache.wiki.plugin.SamplePlugin WHERE text=test}]";
 
         Assertions.assertEquals( "test", translate(src) );
     }
@@ -1744,7 +1745,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginHTMLInsert()
     throws Exception
     {
-        String src="[{INSERT org.apache.wiki.plugin.SamplePlugin WHERE text='<b>Foo</b>'}]";
+        final String src="[{INSERT org.apache.wiki.plugin.SamplePlugin WHERE text='<b>Foo</b>'}]";
 
         Assertions.assertEquals( "<b>Foo</b>", translate(src) );
     }
@@ -1753,7 +1754,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginNoInsert()
     throws Exception
     {
-        String src="[{SamplePlugin text=test}]";
+        final String src="[{SamplePlugin text=test}]";
 
         Assertions.assertEquals( "test", translate(src) );
     }
@@ -1762,7 +1763,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginInsertJS()
     throws Exception
     {
-        String src="Today: [{INSERT JavaScriptPlugin}] ''day''.";
+        final String src="Today: [{INSERT JavaScriptPlugin}] ''day''.";
 
         Assertions.assertEquals( "Today: <script language=\"JavaScript\"><!--\nfoo='';\n--></script>\n <i>day</i>.", translate(src) );
     }
@@ -1771,7 +1772,7 @@ public class JSPWikiMarkupParserTest
     public void testShortPluginInsert()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text=test}]";
+        final String src="[{INSERT SamplePlugin WHERE text=test}]";
 
         Assertions.assertEquals( "test", translate(src) );
     }
@@ -1783,7 +1784,7 @@ public class JSPWikiMarkupParserTest
     public void testShortPluginInsert2()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text=test}] [{INSERT SamplePlugin WHERE text=test2}]";
+        final String src="[{INSERT SamplePlugin WHERE text=test}] [{INSERT SamplePlugin WHERE text=test2}]";
 
         Assertions.assertEquals( "test test2", translate(src) );
     }
@@ -1792,7 +1793,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginQuotedArgs()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text='test me now'}]";
+        final String src="[{INSERT SamplePlugin WHERE text='test me now'}]";
 
         Assertions.assertEquals( "test me now", translate(src) );
     }
@@ -1801,7 +1802,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginDoublyQuotedArgs()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text='test \\'me too\\' now'}]";
+        final String src="[{INSERT SamplePlugin WHERE text='test \\'me too\\' now'}]";
 
         Assertions.assertEquals( "test 'me too' now", translate(src) );
     }
@@ -1810,7 +1811,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginQuotedArgs2()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text=foo}] [{INSERT SamplePlugin WHERE text='test \\'me too\\' now'}]";
+        final String src="[{INSERT SamplePlugin WHERE text=foo}] [{INSERT SamplePlugin WHERE text='test \\'me too\\' now'}]";
 
         Assertions.assertEquals( "foo test 'me too' now", translate(src) );
     }
@@ -1822,7 +1823,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginWikiText()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text=PageContent}]";
+        final String src="[{INSERT SamplePlugin WHERE text=PageContent}]";
 
         Assertions.assertEquals( "PageContent", translate(src) );
     }
@@ -1834,7 +1835,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginWikiText2()
     throws Exception
     {
-        String src="[{INSERT SamplePlugin WHERE text='----'}]";
+        final String src="[{INSERT SamplePlugin WHERE text='----'}]";
 
         Assertions.assertEquals( "----", translate(src) );
     }
@@ -1843,7 +1844,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilinePlugin1()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin WHERE\n text=PageContent}]";
+        final String src="Test [{INSERT SamplePlugin WHERE\n text=PageContent}]";
 
         Assertions.assertEquals( "Test PageContent", translate(src) );
     }
@@ -1852,7 +1853,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilinePluginBodyContent()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\ntext=PageContent\n\n123\n456\n}]";
+        final String src="Test [{INSERT SamplePlugin\ntext=PageContent\n\n123\n456\n}]";
 
         Assertions.assertEquals( "Test PageContent (123+456+)", translate(src) );
     }
@@ -1861,7 +1862,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilinePluginBodyContent2()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\ntext=PageContent\n\n\n123\n456\n}]";
+        final String src="Test [{INSERT SamplePlugin\ntext=PageContent\n\n\n123\n456\n}]";
 
         Assertions.assertEquals( "Test PageContent (+123+456+)", translate(src) );
     }
@@ -1870,7 +1871,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilinePluginBodyContent3()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\n123\n456\n}]";
+        final String src="Test [{INSERT SamplePlugin\n\n123\n456\n}]";
 
         Assertions.assertEquals( "Test  (123+456+)", translate(src) );
     }
@@ -1882,7 +1883,7 @@ public class JSPWikiMarkupParserTest
     public void testMultilinePluginBodyContent4()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin \n\n123\n456\n}]";
+        final String src="Test [{INSERT SamplePlugin \n\n123\n456\n}]";
 
         Assertions.assertEquals( "Test  (123+456+)", translate(src) );
     }
@@ -1894,7 +1895,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin text=']'}]";
+        final String src="Test [{INSERT SamplePlugin text=']'}]";
 
         Assertions.assertEquals( "Test ]", translate(src) );
     }
@@ -1903,7 +1904,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd2()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin text='a[]+b'}]";
+        final String src="Test [{INSERT SamplePlugin text='a[]+b'}]";
 
         Assertions.assertEquals( "Test a[]+b", translate(src) );
     }
@@ -1912,7 +1913,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd3()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\na[]+b\n}]";
+        final String src="Test [{INSERT SamplePlugin\n\na[]+b\n}]";
 
         Assertions.assertEquals( "Test  (a[]+b+)", translate(src) );
     }
@@ -1921,7 +1922,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd4()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin text='}'}]";
+        final String src="Test [{INSERT SamplePlugin text='}'}]";
 
         Assertions.assertEquals( "Test }", translate(src) );
     }
@@ -1930,7 +1931,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd5()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\na[]+b{}\nGlob.\n}]";
+        final String src="Test [{INSERT SamplePlugin\n\na[]+b{}\nGlob.\n}]";
 
         Assertions.assertEquals( "Test  (a[]+b{}+Glob.+)", translate(src) );
     }
@@ -1939,7 +1940,7 @@ public class JSPWikiMarkupParserTest
     public void testPluginEnd6()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\na[]+b{}\nGlob.\n}}]";
+        final String src="Test [{INSERT SamplePlugin\n\na[]+b{}\nGlob.\n}}]";
 
         Assertions.assertEquals( "Test  (a[]+b{}+Glob.+})", translate(src) );
     }
@@ -1948,7 +1949,7 @@ public class JSPWikiMarkupParserTest
     public void testNestedPlugin1()
         throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\n[{SamplePlugin}]\nGlob.\n}}]";
+        final String src="Test [{INSERT SamplePlugin\n\n[{SamplePlugin}]\nGlob.\n}}]";
 
         Assertions.assertEquals( "Test  ([{SamplePlugin}]+Glob.+})", translate(src) );
     }
@@ -1958,7 +1959,7 @@ public class JSPWikiMarkupParserTest
     public void testNestedPlugin2()
         throws Exception
     {
-        String src="[{SET foo='bar'}]Test [{INSERT SamplePlugin\n\n[{SamplePlugin text='[{$foo}]'}]\nGlob.\n}}]";
+        final String src="[{SET foo='bar'}]Test [{INSERT SamplePlugin\n\n[{SamplePlugin text='[{$foo}]'}]\nGlob.\n}}]";
 
         Assertions.assertEquals( "Test  ([{SamplePlugin text='[bar]'}]+Glob.+})", translate(src) );
     }
@@ -1970,14 +1971,14 @@ public class JSPWikiMarkupParserTest
     public void testPluginNoEnd()
     throws Exception
     {
-        String src="Test [{INSERT SamplePlugin\n\na+b{}\nGlob.\n}";
+        final String src="Test [{INSERT SamplePlugin\n\na+b{}\nGlob.\n}";
 
         Assertions.assertEquals( "Test {INSERT SamplePlugin\n\na+b{}\nGlob.\n}", translate(src) );
     }
 
     @Test
     public void testMissingPlugin() throws Exception {
-    	String src="Test [{SamplePlugino foo='bar'}]";
+    	final String src="Test [{SamplePlugino foo='bar'}]";
 
     	Assertions.assertEquals( "Test JSPWiki : testpage - Plugin insertion failed: Could not find plugin SamplePlugino" +
     			             "<span class=\"error\">JSPWiki : testpage - Plugin insertion failed: Could not find plugin SamplePlugino</span>",
@@ -1988,7 +1989,7 @@ public class JSPWikiMarkupParserTest
     public void testVariableInsert()
     throws Exception
     {
-        String src="[{$pagename}]";
+        final String src="[{$pagename}]";
 
         Assertions.assertEquals( PAGE_NAME+"", translate(src) );
     }
@@ -1997,7 +1998,7 @@ public class JSPWikiMarkupParserTest
     public void testTable1()
     throws Exception
     {
-        String src="|| heading || heading2 \n| Cell 1 | Cell 2 \n| Cell 3 | Cell 4\n\n";
+        final String src="|| heading || heading2 \n| Cell 1 | Cell 2 \n| Cell 3 | Cell 4\n\n";
 
         Assertions.assertEquals( "<table class=\"wikitable\" border=\"1\">"+
                       "<tr class=\"odd\"><th> heading </th><th> heading2 </th></tr>\n"+
@@ -2011,7 +2012,7 @@ public class JSPWikiMarkupParserTest
     public void testTable2()
     throws Exception
     {
-        String src="||heading||heading2\n|Cell 1| Cell 2\n| Cell 3 |Cell 4\n\n";
+        final String src="||heading||heading2\n|Cell 1| Cell 2\n| Cell 3 |Cell 4\n\n";
 
         Assertions.assertEquals( "<table class=\"wikitable\" border=\"1\">"+
                       "<tr class=\"odd\"><th>heading</th><th>heading2</th></tr>\n"+
@@ -2025,7 +2026,7 @@ public class JSPWikiMarkupParserTest
     public void testTable3()
     throws Exception
     {
-        String src="|Cell 1| Cell 2\n| Cell 3 |Cell 4\n\n";
+        final String src="|Cell 1| Cell 2\n| Cell 3 |Cell 4\n\n";
 
         Assertions.assertEquals( "<table class=\"wikitable\" border=\"1\">"+
                       "<tr class=\"odd\"><td>Cell 1</td><td> Cell 2</td></tr>\n"+
@@ -2038,7 +2039,7 @@ public class JSPWikiMarkupParserTest
     public void testTable4()
     throws Exception
     {
-        String src="|a\nbc";
+        final String src="|a\nbc";
 
         Assertions.assertEquals( "<table class=\"wikitable\" border=\"1\">"+
                       "<tr class=\"odd\"><td>a</td></tr>\n"+
@@ -2055,7 +2056,7 @@ public class JSPWikiMarkupParserTest
     public void testTable5()
     throws Exception
     {
-        String src="Testtable\n||header|cell\n\n|cell||header";
+        final String src="Testtable\n||header|cell\n\n|cell||header";
 
         Assertions.assertEquals( "<p>Testtable\n</p>"+
                       "<table class=\"wikitable\" border=\"1\">"+
@@ -2070,7 +2071,7 @@ public class JSPWikiMarkupParserTest
     public void testTableLink()
     throws Exception
     {
-        String src="|Cell 1| Cell 2\n|[Cell 3|ReallyALink]|Cell 4\n\n";
+        final String src="|Cell 1| Cell 2\n|[Cell 3|ReallyALink]|Cell 4\n\n";
 
         newPage("ReallyALink");
 
@@ -2085,7 +2086,7 @@ public class JSPWikiMarkupParserTest
     public void testTableLinkEscapedBar()
     throws Exception
     {
-        String src="|Cell 1| Cell~| 2\n|[Cell 3|ReallyALink]|Cell 4\n\n";
+        final String src="|Cell 1| Cell~| 2\n|[Cell 3|ReallyALink]|Cell 4\n\n";
 
         newPage("ReallyALink");
 
@@ -2100,7 +2101,7 @@ public class JSPWikiMarkupParserTest
     public void testDescription()
     throws Exception
     {
-        String src=";:Foo";
+        final String src=";:Foo";
 
         Assertions.assertEquals( "<dl><dt></dt><dd>Foo</dd></dl>",
                       translate(src) );
@@ -2110,7 +2111,7 @@ public class JSPWikiMarkupParserTest
     public void testDescription2()
     throws Exception
     {
-        String src=";Bar:Foo";
+        final String src=";Bar:Foo";
 
         Assertions.assertEquals( "<dl><dt>Bar</dt><dd>Foo</dd></dl>",
                       translate(src) );
@@ -2120,7 +2121,7 @@ public class JSPWikiMarkupParserTest
     public void testDescription3()
     throws Exception
     {
-        String src=";:";
+        final String src=";:";
 
         Assertions.assertEquals( "<dl><dt></dt><dd /></dl>",
                       translate(src) );
@@ -2130,7 +2131,7 @@ public class JSPWikiMarkupParserTest
     public void testDescription4()
     throws Exception
     {
-        String src=";Bar:Foo :-)";
+        final String src=";Bar:Foo :-)";
 
         Assertions.assertEquals( "<dl><dt>Bar</dt><dd>Foo :-)</dd></dl>",
                       translate(src) );
@@ -2140,7 +2141,7 @@ public class JSPWikiMarkupParserTest
     public void testDescription5()
     throws Exception
     {
-        String src=";Bar:Foo :-) ;-) :*]";
+        final String src=";Bar:Foo :-) ;-) :*]";
 
         Assertions.assertEquals( "<dl><dt>Bar</dt><dd>Foo :-) ;-) :*]</dd></dl>",
                       translate(src) );
@@ -2151,7 +2152,7 @@ public class JSPWikiMarkupParserTest
     public void testRuler()
     throws Exception
     {
-        String src="----";
+        final String src="----";
 
         Assertions.assertEquals( "<hr />",
                       translate(src) );
@@ -2161,7 +2162,7 @@ public class JSPWikiMarkupParserTest
     public void testRulerCombo()
     throws Exception
     {
-        String src="----Foo";
+        final String src="----Foo";
 
         Assertions.assertEquals( "<hr />Foo",
                       translate(src) );
@@ -2171,7 +2172,7 @@ public class JSPWikiMarkupParserTest
     public void testRulerCombo2()
     throws Exception
     {
-        String src="Bar----Foo";
+        final String src="Bar----Foo";
 
         Assertions.assertEquals( "Bar----Foo",
                       translate(src) );
@@ -2181,7 +2182,7 @@ public class JSPWikiMarkupParserTest
     public void testShortRuler1()
     throws Exception
     {
-        String src="-";
+        final String src="-";
 
         Assertions.assertEquals( "-",
                       translate(src) );
@@ -2191,7 +2192,7 @@ public class JSPWikiMarkupParserTest
     public void testShortRuler2()
     throws Exception
     {
-        String src="--";
+        final String src="--";
 
         Assertions.assertEquals( "--",
                       translate(src) );
@@ -2201,7 +2202,7 @@ public class JSPWikiMarkupParserTest
     public void testShortRuler3()
     throws Exception
     {
-        String src="---";
+        final String src="---";
 
         Assertions.assertEquals( "---",
                       translate(src) );
@@ -2211,7 +2212,7 @@ public class JSPWikiMarkupParserTest
     public void testLongRuler()
     throws Exception
     {
-        String src="------";
+        final String src="------";
 
         Assertions.assertEquals( "<hr />",
                       translate(src) );
@@ -2221,7 +2222,7 @@ public class JSPWikiMarkupParserTest
     public void testHeading1()
     throws Exception
     {
-        String src="!Hello\nThis is a test";
+        final String src="!Hello\nThis is a test";
 
         Assertions.assertEquals( "<h4 id=\"section-testpage-Hello\">Hello<a class=\"hashlink\" href=\"#section-testpage-Hello\">#</a></h4>\nThis is a test",
                       translate(src) );
@@ -2231,7 +2232,7 @@ public class JSPWikiMarkupParserTest
     public void testHeading2()
     throws Exception
     {
-        String src="!!Hello, testing 1, 2, 3";
+        final String src="!!Hello, testing 1, 2, 3";
 
         Assertions.assertEquals( "<h3 id=\"section-testpage-HelloTesting123\">Hello, testing 1, 2, 3<a class=\"hashlink\" href=\"#section-testpage-HelloTesting123\">#</a></h3>",
                       translate(src) );
@@ -2241,7 +2242,7 @@ public class JSPWikiMarkupParserTest
     public void testHeading3()
     throws Exception
     {
-        String src="!!!Hello there, how are you doing?";
+        final String src="!!!Hello there, how are you doing?";
 
         Assertions.assertEquals( "<h2 id=\"section-testpage-HelloThereHowAreYouDoing\">Hello there, how are you doing?<a class=\"hashlink\" href=\"#section-testpage-HelloThereHowAreYouDoing\">#</a></h2>",
                       translate(src) );
@@ -2251,7 +2252,7 @@ public class JSPWikiMarkupParserTest
     public void testHeadingHyperlinks()
     throws Exception
     {
-        String src="!!![Hello]";
+        final String src="!!![Hello]";
 
         Assertions.assertEquals( "<h2 id=\"section-testpage-Hello\"><a class=\"createpage\" href=\"/test/Edit.jsp?page=Hello\" title=\"Create &quot;Hello&quot;\">Hello</a><a class=\"hashlink\" href=\"#section-testpage-Hello\">#</a></h2>",
                       translate(src) );
@@ -2261,7 +2262,7 @@ public class JSPWikiMarkupParserTest
     public void testHeadingHyperlinks2()
     throws Exception
     {
-        String src="!!![Hello|http://www.google.com/]";
+        final String src="!!![Hello|http://www.google.com/]";
 
         Assertions.assertEquals( "<h2 id=\"section-testpage-Hello\"><a class=\"external\" href=\"http://www.google.com/\">Hello</a><a class=\"hashlink\" href=\"#section-testpage-Hello\">#</a></h2>",
                       translate(src) );
@@ -2271,7 +2272,7 @@ public class JSPWikiMarkupParserTest
     public void testHeadingHyperlinks3()
     throws Exception
     {
-        String src="![Hello|http://www.google.com/?p=a&c=d]";
+        final String src="![Hello|http://www.google.com/?p=a&c=d]";
 
         Assertions.assertEquals( "<h4 id=\"section-testpage-Hello\"><a class=\"external\" href=\"http://www.google.com/?p=a&amp;c=d\">Hello</a><a class=\"hashlink\" href=\"#section-testpage-Hello\">#</a></h4>",
                       translate(src) );
@@ -2284,7 +2285,7 @@ public class JSPWikiMarkupParserTest
     public void testBrokenPageText()
     throws Exception
     {
-        String translation = translate( brokenPageText );
+        final String translation = translate( brokenPageText );
 
         Assertions.assertNotNull( translation );
     }
@@ -2296,7 +2297,7 @@ public class JSPWikiMarkupParserTest
     public void testBrokenPageTextShort()
     throws Exception
     {
-        String src = "{{{\ncode.}}\n";
+        final String src = "{{{\ncode.}}\n";
 
         Assertions.assertEquals( "<pre>\ncode.}}\n</pre>", translate(src) );
     }
@@ -2308,7 +2309,7 @@ public class JSPWikiMarkupParserTest
     public void testBrokenPageTextShort2()
     throws Exception
     {
-        String src = "{{{\ncode.}\n";
+        final String src = "{{{\ncode.}\n";
 
         Assertions.assertEquals( "<pre>\ncode.}\n</pre>", translate(src) );
     }
@@ -2317,7 +2318,7 @@ public class JSPWikiMarkupParserTest
     public void testExtraExclamation()
         throws Exception
     {
-        String src = "Hello!";
+        final String src = "Hello!";
 
         Assertions.assertEquals( "Hello!", translate(src) );
     }
@@ -2439,11 +2440,11 @@ public class JSPWikiMarkupParserTest
     public void testSet1()
     throws Exception
     {
-        String src = "Foobar.[{SET name=foo}]";
+        final String src = "Foobar.[{SET name=foo}]";
 
-        WikiPage p = new WikiPage( testEngine, PAGE_NAME );
+        final WikiPage p = new WikiPage( testEngine, PAGE_NAME );
 
-        String res = translate( p, src );
+        final String res = translate( p, src );
 
         Assertions.assertEquals( "Foobar.", res, "Page text" );
 
@@ -2454,11 +2455,11 @@ public class JSPWikiMarkupParserTest
     public void testSet2()
     throws Exception
     {
-        String src = "Foobar.[{SET name = foo}]";
+        final String src = "Foobar.[{SET name = foo}]";
 
-        WikiPage p = new WikiPage( testEngine, PAGE_NAME );
+        final WikiPage p = new WikiPage( testEngine, PAGE_NAME );
 
-        String res = translate( p, src );
+        final String res = translate( p, src );
 
         Assertions.assertEquals( "Foobar.", res, "Page text" );
 
@@ -2469,11 +2470,11 @@ public class JSPWikiMarkupParserTest
     public void testSet3()
     throws Exception
     {
-        String src = "Foobar.[{SET name= Janne Jalkanen}]";
+        final String src = "Foobar.[{SET name= Janne Jalkanen}]";
 
-        WikiPage p = new WikiPage( testEngine, PAGE_NAME );
+        final WikiPage p = new WikiPage( testEngine, PAGE_NAME );
 
-        String res = translate( p, src );
+        final String res = translate( p, src );
 
         Assertions.assertEquals( "Foobar.", res, "Page text" );
 
@@ -2484,11 +2485,11 @@ public class JSPWikiMarkupParserTest
     public void testSet4()
     throws Exception
     {
-        String src = "Foobar.[{SET name='Janne Jalkanen'}][{SET too='{$name}'}]";
+        final String src = "Foobar.[{SET name='Janne Jalkanen'}][{SET too='{$name}'}]";
 
-        WikiPage p = new WikiPage( testEngine, PAGE_NAME );
+        final WikiPage p = new WikiPage( testEngine, PAGE_NAME );
 
-        String res = translate( p, src );
+        final String res = translate( p, src );
 
         Assertions.assertEquals( "Foobar.", res, "Page text" );
 
@@ -2500,11 +2501,11 @@ public class JSPWikiMarkupParserTest
     public void testSetHTML()
     throws Exception
     {
-        String src = "Foobar.[{SET name='<b>danger</b>'}] [{$name}]";
+        final String src = "Foobar.[{SET name='<b>danger</b>'}] [{$name}]";
 
-        WikiPage p = new WikiPage( testEngine, PAGE_NAME );
+        final WikiPage p = new WikiPage( testEngine, PAGE_NAME );
 
-        String res = translate( p, src );
+        final String res = translate( p, src );
 
         Assertions.assertEquals( "Foobar. &lt;b&gt;danger&lt;/b&gt;", res, "Page text");
 
@@ -2520,12 +2521,12 @@ public class JSPWikiMarkupParserTest
     public void testCollectingLinks()
     throws Exception
     {
-        LinkCollector coll = new LinkCollector();
-        String src = "[Test]";
-        WikiContext context = new WikiContext( testEngine,
+        final LinkCollector coll = new LinkCollector();
+        final String src = "[Test]";
+        final WikiContext context = new WikiContext( testEngine,
                                                new WikiPage(testEngine,PAGE_NAME) );
 
-        MarkupParser p = new JSPWikiMarkupParser( context,
+        final MarkupParser p = new JSPWikiMarkupParser( context,
                                                   new BufferedReader( new StringReader(src)) );
         p.addLocalLinkHook( coll );
         p.addExternalLinkHook( coll );
@@ -2533,7 +2534,7 @@ public class JSPWikiMarkupParserTest
 
         p.parse();
 
-        Collection< String > links = coll.getLinks();
+        final Collection< String > links = coll.getLinks();
 
         Assertions.assertEquals( 1, links.size(), "no links found" );
         Assertions.assertEquals( "Test", links.iterator().next(), "wrong link" );
@@ -2543,13 +2544,13 @@ public class JSPWikiMarkupParserTest
     public void testCollectingLinks2()
     throws Exception
     {
-        LinkCollector coll = new LinkCollector();
-        String src = "["+PAGE_NAME+"/Test.txt]";
+        final LinkCollector coll = new LinkCollector();
+        final String src = "["+PAGE_NAME+"/Test.txt]";
 
-        WikiContext context = new WikiContext( testEngine,
+        final WikiContext context = new WikiContext( testEngine,
                                                new WikiPage(testEngine,PAGE_NAME) );
 
-        MarkupParser p = new JSPWikiMarkupParser( context,
+        final MarkupParser p = new JSPWikiMarkupParser( context,
                                                   new BufferedReader( new StringReader(src)) );
         p.addLocalLinkHook( coll );
         p.addExternalLinkHook( coll );
@@ -2557,7 +2558,7 @@ public class JSPWikiMarkupParserTest
 
         p.parse();
 
-        Collection< String > links = coll.getLinks();
+        final Collection< String > links = coll.getLinks();
 
         Assertions.assertEquals( 1, links.size(), "no links found" );
         Assertions.assertEquals( PAGE_NAME+"/Test.txt", links.iterator().next(), "wrong link" );
@@ -2572,18 +2573,18 @@ public class JSPWikiMarkupParserTest
         try
         {
             testEngine.saveText( PAGE_NAME, "content" );
-            Attachment att = new Attachment( testEngine, PAGE_NAME, "TestAtt.txt" );
+            final Attachment att = new Attachment( testEngine, PAGE_NAME, "TestAtt.txt" );
             att.setAuthor( "FirstPost" );
-            testEngine.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
+            testEngine.getManager( AttachmentManager.class ).storeAttachment( att, testEngine.makeAttachmentFile() );
 
-            LinkCollector coll        = new LinkCollector();
-            LinkCollector coll_others = new LinkCollector();
+            final LinkCollector coll        = new LinkCollector();
+            final LinkCollector coll_others = new LinkCollector();
 
-            String src = "[TestAtt.txt]";
-            WikiContext context = new WikiContext( testEngine,
+            final String src = "[TestAtt.txt]";
+            final WikiContext context = new WikiContext( testEngine,
                                                    new WikiPage(testEngine,PAGE_NAME) );
 
-            MarkupParser p = new JSPWikiMarkupParser( context,
+            final MarkupParser p = new JSPWikiMarkupParser( context,
                                                       new BufferedReader( new StringReader(src)) );
             p.addLocalLinkHook( coll_others );
             p.addExternalLinkHook( coll_others );
@@ -2591,7 +2592,7 @@ public class JSPWikiMarkupParserTest
 
             p.parse();
 
-            Collection< String > links = coll.getLinks();
+            final Collection< String > links = coll.getLinks();
 
             Assertions.assertEquals( 1, links.size(), "no links found" );
             Assertions.assertEquals( PAGE_NAME+"/TestAtt.txt", links.iterator().next(), "wrong link" );
@@ -2600,11 +2601,12 @@ public class JSPWikiMarkupParserTest
         }
         finally
         {
-            String files = testEngine.getWikiProperties().getProperty( BasicAttachmentProvider.PROP_STORAGEDIR );
-            File storagedir = new File( files, PAGE_NAME+BasicAttachmentProvider.DIR_EXTENSION );
+            final String files = testEngine.getWikiProperties().getProperty( BasicAttachmentProvider.PROP_STORAGEDIR );
+            final File storagedir = new File( files, PAGE_NAME+BasicAttachmentProvider.DIR_EXTENSION );
 
-            if( storagedir.exists() && storagedir.isDirectory() )
+            if( storagedir.exists() && storagedir.isDirectory() ) {
                 TestEngine.deleteAll( storagedir );
+            }
         }
     }
 
@@ -2612,7 +2614,7 @@ public class JSPWikiMarkupParserTest
     public void testDivStyle1()
     throws Exception
     {
-        String src = "%%foo\ntest\n%%\n";
+        final String src = "%%foo\ntest\n%%\n";
 
         Assertions.assertEquals( "<div class=\"foo\">\ntest\n</div>\n", translate(src) );
     }
@@ -2621,7 +2623,7 @@ public class JSPWikiMarkupParserTest
     public void testDivStyle2()
     throws Exception
     {
-        String src = "%%foo.bar\ntest\n%%\n";
+        final String src = "%%foo.bar\ntest\n%%\n";
 
         Assertions.assertEquals( "<div class=\"foo bar\">\ntest\n</div>\n", translate(src) );
     }
@@ -2630,7 +2632,7 @@ public class JSPWikiMarkupParserTest
     public void testDivStyle3()
     throws Exception
     {
-        String src = "%%(foo:bar;)\ntest\n%%\n";
+        final String src = "%%(foo:bar;)\ntest\n%%\n";
 
         Assertions.assertEquals( "<div style=\"foo:bar;\">\ntest\n</div>\n", translate(src) );
     }
@@ -2639,7 +2641,7 @@ public class JSPWikiMarkupParserTest
     public void testDivStyle4()
     throws Exception
     {
-        String src = "%%zoo(foo:bar;)\ntest\n%%\n";
+        final String src = "%%zoo(foo:bar;)\ntest\n%%\n";
 
         Assertions.assertEquals( "<div style=\"foo:bar;\" class=\"zoo\">\ntest\n</div>\n", translate(src) );
     }
@@ -2648,7 +2650,7 @@ public class JSPWikiMarkupParserTest
     public void testDivStyle5()
     throws Exception
     {
-        String src = "%%zoo1.zoo2(foo:bar;)\ntest\n%%\n";
+        final String src = "%%zoo1.zoo2(foo:bar;)\ntest\n%%\n";
 
         Assertions.assertEquals( "<div style=\"foo:bar;\" class=\"zoo1 zoo2\">\ntest\n</div>\n", translate(src) );
     }
@@ -2657,7 +2659,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanStyle1()
     throws Exception
     {
-        String src = "%%foo test%%\n";
+        final String src = "%%foo test%%\n";
 
         Assertions.assertEquals( "<span class=\"foo\">test</span>\n", translate(src) );
     }
@@ -2666,7 +2668,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanStyle2()
     throws Exception
     {
-        String src = "%%(foo:bar;)test%%\n";
+        final String src = "%%(foo:bar;)test%%\n";
 
         Assertions.assertEquals( "<span style=\"foo:bar;\">test</span>\n", translate(src) );
     }
@@ -2675,7 +2677,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanStyle3()
     throws Exception
     {
-        String src = "Johan %%(foo:bar;)test%%\n";
+        final String src = "Johan %%(foo:bar;)test%%\n";
 
         Assertions.assertEquals( "Johan <span style=\"foo:bar;\">test</span>\n", translate(src) );
     }
@@ -2684,7 +2686,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanStyle4()
     throws Exception
     {
-        String src = "Johan %%(foo:bar;)test/%\n";
+        final String src = "Johan %%(foo:bar;)test/%\n";
 
         Assertions.assertEquals( "Johan <span style=\"foo:bar;\">test</span>\n", translate(src) );
     }
@@ -2693,7 +2695,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanEscape()
     throws Exception
     {
-        String src = "~%%foo test~%%\n";
+        final String src = "~%%foo test~%%\n";
 
         Assertions.assertEquals( "%%foo test%%\n", translate(src) );
     }
@@ -2702,7 +2704,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanNested()
     throws Exception
     {
-        String src = "Johan %%(color: rgb(1,2,3);)test%%\n";
+        final String src = "Johan %%(color: rgb(1,2,3);)test%%\n";
 
         Assertions.assertEquals( "Johan <span style=\"color: rgb(1,2,3);\">test</span>\n", translate(src) );
     }
@@ -2711,7 +2713,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanStyleTable()
     throws Exception
     {
-        String src = "|%%(foo:bar;)test%%|no test\n";
+        final String src = "|%%(foo:bar;)test%%|no test\n";
 
         Assertions.assertEquals( "<table class=\"wikitable\" border=\"1\"><tr class=\"odd\"><td><span style=\"foo:bar;\">test</span></td><td>no test</td></tr>\n</table>",
                       translate(src) );
@@ -2721,7 +2723,7 @@ public class JSPWikiMarkupParserTest
     public void testSpanJavascript()
     throws Exception
     {
-        String src = "%%(visibility: hidden; background-image:url(javascript:alert('X')))%%\nTEST";
+        final String src = "%%(visibility: hidden; background-image:url(javascript:alert('X')))%%\nTEST";
 
         Assertions.assertEquals( "<span class=\"error\">Attempt to output javascript!</span>\nTEST", translate(src) );
     }
@@ -2741,7 +2743,7 @@ public class JSPWikiMarkupParserTest
     public void testHTMLEntities1()
     throws Exception
     {
-        String src = "Janne&apos;s test";
+        final String src = "Janne&apos;s test";
 
         Assertions.assertEquals( "Janne&apos;s test", translate(src) );
     }
@@ -2750,7 +2752,7 @@ public class JSPWikiMarkupParserTest
     public void testHTMLEntities2()
     throws Exception
     {
-        String src = "&Auml;";
+        final String src = "&Auml;";
 
         Assertions.assertEquals( "&Auml;", translate(src) );
     }
@@ -2759,7 +2761,7 @@ public class JSPWikiMarkupParserTest
     public void testBlankEscape()
     throws Exception
     {
-        String src = "H2%%sub 2%%~ O";
+        final String src = "H2%%sub 2%%~ O";
 
         Assertions.assertEquals( "H2<span class=\"sub\">2</span>O", translate(src) );
     }
@@ -2769,7 +2771,7 @@ public class JSPWikiMarkupParserTest
     public void testEmptyBold()
     throws Exception
     {
-        String src = "____";
+        final String src = "____";
 
         Assertions.assertEquals( "<b></b>", translate(src) );
     }
@@ -2778,7 +2780,7 @@ public class JSPWikiMarkupParserTest
     public void testEmptyItalic()
     throws Exception
     {
-        String src = "''''";
+        final String src = "''''";
 
         Assertions.assertEquals( "<i></i>", translate(src) );
     }
@@ -2787,7 +2789,7 @@ public class JSPWikiMarkupParserTest
     public void testRenderingSpeed1()
        throws Exception
     {
-        Benchmark sw = new Benchmark();
+        final Benchmark sw = new Benchmark();
         sw.start();
 
         for( int i = 0; i < 100; i++ )
@@ -2803,7 +2805,7 @@ public class JSPWikiMarkupParserTest
     public void testPunctuatedWikiNames()
         throws Exception
     {
-        String src = "[-phobous]";
+        final String src = "[-phobous]";
 
         Assertions.assertEquals( "<a class=\"createpage\" href=\"/test/Edit.jsp?page=-phobous\" title=\"Create &quot;-phobous&quot;\">-phobous</a>", translate(src) );
     }
@@ -2812,7 +2814,7 @@ public class JSPWikiMarkupParserTest
     public void testPunctuatedWikiNames2()
         throws Exception
     {
-        String src = "[?phobous]";
+        final String src = "[?phobous]";
 
         Assertions.assertEquals( "<a class=\"createpage\" href=\"/test/Edit.jsp?page=Phobous\" title=\"Create &quot;Phobous&quot;\">?phobous</a>", translate(src) );
     }
@@ -2821,7 +2823,7 @@ public class JSPWikiMarkupParserTest
     public void testPunctuatedWikiNames3()
         throws Exception
     {
-        String src = "[Brightness (apical)]";
+        final String src = "[Brightness (apical)]";
 
         Assertions.assertEquals( "<a class=\"createpage\" href=\"/test/Edit.jsp?page=Brightness%20%28apical%29\" title=\"Create &quot;Brightness (apical)&quot;\">Brightness (apical)</a>", translate(src) );
     }
@@ -2830,9 +2832,9 @@ public class JSPWikiMarkupParserTest
     public void testDeadlySpammer()
         throws Exception
     {
-        String deadlySpammerText = "zzz <a href=\"http://ring1.gmum.net/frog-ringtone.html\">frogringtone</a> zzz http://ring1.gmum.net/frog-ringtone.html[URL=http://ring1.gmum.net/frog-ringtone.html]frog ringtone[/URL] frogringtone<br>";
+        final String deadlySpammerText = "zzz <a href=\"http://ring1.gmum.net/frog-ringtone.html\">frogringtone</a> zzz http://ring1.gmum.net/frog-ringtone.html[URL=http://ring1.gmum.net/frog-ringtone.html]frog ringtone[/URL] frogringtone<br>";
 
-        StringBuilder death = new StringBuilder( 20000 );
+        final StringBuilder death = new StringBuilder( 20000 );
 
         for( int i = 0; i < 1000; i++ )
         {
@@ -2843,7 +2845,7 @@ public class JSPWikiMarkupParserTest
 
         System.out.println("Trying to crash parser with a line which is "+death.length()+" chars in size");
         //  This should not Assertions.fail
-        String res = translate( death.toString() );
+        final String res = translate( death.toString() );
 
         Assertions.assertTrue( res.length() > 0 );
     }
@@ -2852,7 +2854,7 @@ public class JSPWikiMarkupParserTest
     public void testSpacesInLinks1() throws Exception
     {
         newPage("Foo bar");
-        String src = "[Foo bar]";
+        final String src = "[Foo bar]";
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=Foo%20bar\">Foo bar</a>", translate(src) );
     }
@@ -2862,7 +2864,7 @@ public class JSPWikiMarkupParserTest
     public void testSpacesInLinks2() throws Exception
     {
         newPage("Foo bar");
-        String src = "[Foo        bar]";
+        final String src = "[Foo        bar]";
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=Foo%20bar\">Foo        bar</a>", translate(src) );
     }
@@ -2870,9 +2872,9 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testIllegalXML() throws Exception
     {
-        String src = "Test \u001d foo";
+        final String src = "Test \u001d foo";
 
-        String dst = translate(src);
+        final String dst = translate(src);
 
         Assertions.assertTrue( dst.indexOf("JDOM") != -1, "No error" );
     }
@@ -2880,9 +2882,9 @@ public class JSPWikiMarkupParserTest
     @Test
     public void testXSS1() throws Exception
     {
-        String src = "[http://www.host.com/du=\"> <img src=\"foobar\" onerror=\"alert(document.cookie)\"/>]";
+        final String src = "[http://www.host.com/du=\"> <img src=\"foobar\" onerror=\"alert(document.cookie)\"/>]";
 
-        String dst = translate(src);
+        final String dst = translate(src);
 
         Assertions.assertEquals( "<a class=\"external\" href=\"http://www.host.com/du=&quot;&gt; &lt;img src=&quot;foobar&quot; onerror=&quot;alert(document.cookie)&quot;/&gt;\">http://www.host.com/du=&quot;&gt; &lt;img src=&quot;foobar&quot; onerror=&quot;alert(document.cookie)&quot;/&gt;</a>", dst );
     }
@@ -2891,9 +2893,9 @@ public class JSPWikiMarkupParserTest
     public void testAmpersand1() throws Exception
     {
         newPage( "Foo&Bar" );
-        String src = "[Foo&Bar]";
+        final String src = "[Foo&Bar]";
 
-        String dst = translate(src);
+        final String dst = translate(src);
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=Foo%26Bar\">Foo&amp;Bar</a>", dst );
     }
@@ -2902,9 +2904,9 @@ public class JSPWikiMarkupParserTest
     public void testAmpersand2() throws Exception
     {
         newPage( "Foo & Bar" );
-        String src = "[Foo & Bar]";
+        final String src = "[Foo & Bar]";
 
-        String dst = translate(src);
+        final String dst = translate(src);
 
         Assertions.assertEquals( "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page=Foo%20%26%20Bar\">Foo &amp; Bar</a>", dst );
     }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/DefaultPluginManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/DefaultPluginManagerTest.java
index 69cf0aa..2a7717e 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/DefaultPluginManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/DefaultPluginManagerTest.java
@@ -24,6 +24,7 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -46,7 +47,7 @@ public class DefaultPluginManagerTest {
 
     @AfterEach
     public void tearDown() throws ProviderException {
-        engine.getPageManager().deletePage("Testpage");
+        engine.getManager( PageManager.class ).deletePage("Testpage");
     }
 
     @Test
@@ -146,7 +147,7 @@ public class DefaultPluginManagerTest {
 
     @Test
     public void testParserPlugin() throws Exception {
-        engine.getPageManager().saveText(context, "[{SamplePlugin render=true}]");
+        engine.getManager( PageManager.class ).saveText(context, "[{SamplePlugin render=true}]");
         engine.getRenderingManager().getHTML( "Testpage" );
         Assertions.assertTrue( SamplePlugin.c_rendered );
     }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/GroupsTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/GroupsTest.java
index 6979a65..21619b2 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/GroupsTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/GroupsTest.java
@@ -20,27 +20,28 @@
 package org.apache.wiki.plugin;
 
 import org.apache.wiki.TestEngine;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 
 public class GroupsTest {
+
     TestEngine testEngine = TestEngine.build();
 
     @AfterEach
     public void tearDown() throws Exception {
-        testEngine.getPageManager().deletePage( "Test" );
+        testEngine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     @Test
-    public void testTag() throws Exception
-    {
-        String src="[{Groups}]";
+    public void testTag() throws Exception {
+        final String src="[{Groups}]";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getRenderingManager().getHTML( "Test" );
+        final String res = testEngine.getRenderingManager().getHTML( "Test" );
 
         Assertions.assertEquals( "<a href=\"/test/Group.jsp?group=Admin\">Admin</a>, "
                 + "<a href=\"/test/Group.jsp?group=Art\">Art</a>, "
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java
index 8879381..81b9240 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/IfPluginTest.java
@@ -17,6 +17,7 @@
     under the License.
  */
 package org.apache.wiki.plugin;
+
 import net.sourceforge.stripes.mock.MockHttpServletRequest;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
@@ -24,6 +25,7 @@ import org.apache.wiki.WikiPage;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.auth.Users;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.WikiPageProvider;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -35,7 +37,7 @@ public class IfPluginTest {
 
     @AfterEach
     public void tearDown() throws Exception {
-        testEngine.getPageManager().deletePage( "Test" );
+        testEngine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     /**
@@ -45,10 +47,10 @@ public class IfPluginTest {
      * @return {@link WikiContext} associated to given {@link WikiPage}.
      * @throws WikiException problems while logging in.
      */
-    WikiContext getJanneBasedWikiContextFor( WikiPage page ) throws WikiException
+    WikiContext getJanneBasedWikiContextFor( final WikiPage page ) throws WikiException
     {
-        MockHttpServletRequest request = testEngine.newHttpRequest();
-        WikiSession session =  WikiSession.getWikiSession( testEngine, request );
+        final MockHttpServletRequest request = testEngine.newHttpRequest();
+        final WikiSession session =  WikiSession.getWikiSession( testEngine, request );
         testEngine.getAuthenticationManager().login( session,
                                                      request,
                                                      Users.JANNE,
@@ -65,16 +67,16 @@ public class IfPluginTest {
     @Test
     public void testIfPluginUserAllowed() throws WikiException
     {
-        String src = "[{IfPlugin user='Janne Jalkanen'\n" +
+        final String src = "[{IfPlugin user='Janne Jalkanen'\n" +
         		     "\n" +
         		     "Content visible for Janne Jalkanen}]";
-        String expected = "<p>Content visible for Janne Jalkanen</p>\n";
+        final String expected = "<p>Content visible for Janne Jalkanen</p>\n";
 
         testEngine.saveText( "Test", src );
-        WikiPage page = testEngine.getPageManager().getPage( "Test", WikiPageProvider.LATEST_VERSION );
-        WikiContext context = getJanneBasedWikiContextFor( page );
+        final WikiPage page = testEngine.getManager( PageManager.class ).getPage( "Test", WikiPageProvider.LATEST_VERSION );
+        final WikiContext context = getJanneBasedWikiContextFor( page );
 
-        String res = testEngine.getRenderingManager().getHTML( context, page );
+        final String res = testEngine.getRenderingManager().getHTML( context, page );
         Assertions.assertEquals( expected, res );
     }
 
@@ -86,16 +88,16 @@ public class IfPluginTest {
     @Test
     public void testIfPluginUserNotAllowed() throws WikiException
     {
-        String src = "[{IfPlugin user='!Janne Jalkanen'\n" +
+        final String src = "[{IfPlugin user='!Janne Jalkanen'\n" +
                      "\n" +
                      "Content NOT visible for Janne Jalkanen}]";
-        String expected = "\n";
+        final String expected = "\n";
 
         testEngine.saveText( "Test", src );
-        WikiPage page = testEngine.getPageManager().getPage( "Test", WikiPageProvider.LATEST_VERSION );
-        WikiContext context = getJanneBasedWikiContextFor( page );
+        final WikiPage page = testEngine.getManager( PageManager.class ).getPage( "Test", WikiPageProvider.LATEST_VERSION );
+        final WikiContext context = getJanneBasedWikiContextFor( page );
 
-        String res = testEngine.getRenderingManager().getHTML( context, page );
+        final String res = testEngine.getRenderingManager().getHTML( context, page );
         Assertions.assertEquals( expected, res );
     }
 
@@ -106,16 +108,16 @@ public class IfPluginTest {
      */
     @Test
     public void testIfPluginIPAllowed() throws WikiException {
-        String src = "[{IfPlugin ip='127.0.0.1'\n" +
+        final String src = "[{IfPlugin ip='127.0.0.1'\n" +
                      "\n" +
                      "Content visible for 127.0.0.1}]";
-        String expected = "<p>Content visible for 127.0.0.1</p>\n";
+        final String expected = "<p>Content visible for 127.0.0.1</p>\n";
 
         testEngine.saveText( "Test", src );
-        WikiPage page = testEngine.getPageManager().getPage( "Test", WikiPageProvider.LATEST_VERSION );
-        WikiContext context = getJanneBasedWikiContextFor( page );
+        final WikiPage page = testEngine.getManager( PageManager.class ).getPage( "Test", WikiPageProvider.LATEST_VERSION );
+        final WikiContext context = getJanneBasedWikiContextFor( page );
 
-        String res = testEngine.getRenderingManager().getHTML( context, page );
+        final String res = testEngine.getRenderingManager().getHTML( context, page );
         Assertions.assertEquals( expected, res );
     }
 
@@ -126,16 +128,16 @@ public class IfPluginTest {
      */
     @Test
     public void testIfPluginIPNotAllowed() throws WikiException {
-        String src = "[{IfPlugin ip='!127.0.0.1'\n" +
+        final String src = "[{IfPlugin ip='!127.0.0.1'\n" +
                      "\n" +
                      "Content NOT visible for 127.0.0.1}]";
-        String expected = "\n";
+        final String expected = "\n";
 
         testEngine.saveText( "Test", src );
-        WikiPage page = testEngine.getPageManager().getPage( "Test", WikiPageProvider.LATEST_VERSION );
-        WikiContext context = getJanneBasedWikiContextFor( page );
+        final WikiPage page = testEngine.getManager( PageManager.class ).getPage( "Test", WikiPageProvider.LATEST_VERSION );
+        final WikiContext context = getJanneBasedWikiContextFor( page );
 
-        String res = testEngine.getRenderingManager().getHTML( context, page );
+        final String res = testEngine.getRenderingManager().getHTML( context, page );
         Assertions.assertEquals( expected, res );
     }
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/InsertPageTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/InsertPageTest.java
index 82cd0ce..85fb704 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/InsertPageTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/InsertPageTest.java
@@ -19,6 +19,7 @@
 package org.apache.wiki.plugin;
 
 import org.apache.wiki.TestEngine;
+import org.apache.wiki.render.RenderingManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -51,53 +52,53 @@ public class InsertPageTest
     @Test
     public void testRecursive() throws Exception
     {
-        String src = "[{InsertPage page='ThisPage'}] [{ALLOW view Anonymous}]";
+        final String src = "[{InsertPage page='ThisPage'}] [{ALLOW view Anonymous}]";
 
         testEngine.saveText("ThisPage",src);
 
         // Just check that it contains a proper error message; don't bother do HTML
         // checking.
-        String res = testEngine.getRenderingManager().getHTML("ThisPage");
+        final String res = testEngine.getManager( RenderingManager.class ).getHTML("ThisPage");
         Assertions.assertTrue( res.indexOf("Circular reference") != -1 );
     }
 
     @Test
     public void testRecursive2() throws Exception
     {
-        String src  = "[{InsertPage page='ThisPage2'}]";
-        String src2 = "[{InsertPage page='ThisPage'}]";
+        final String src  = "[{InsertPage page='ThisPage2'}]";
+        final String src2 = "[{InsertPage page='ThisPage'}]";
 
         testEngine.saveText("ThisPage",src);
         testEngine.saveText("ThisPage2",src2);
 
         // Just check that it contains a proper error message; don't bother do HTML
         // checking.
-        Assertions.assertTrue( testEngine.getRenderingManager().getHTML("ThisPage").indexOf("Circular reference") != -1 );
+        Assertions.assertTrue( testEngine.getManager( RenderingManager.class ).getHTML("ThisPage").indexOf("Circular reference") != -1 );
     }
 
     @Test
     public void testMultiInvocation() throws Exception {
-        String src  = "[{InsertPage page='ThisPage2'}] [{InsertPage page='ThisPage2'}]";
-        String src2 = "foo[{ALLOW view Anonymous}]";
+        final String src  = "[{InsertPage page='ThisPage2'}] [{InsertPage page='ThisPage2'}]";
+        final String src2 = "foo[{ALLOW view Anonymous}]";
 
         testEngine.saveText("ThisPage",src);
         testEngine.saveText("ThisPage2",src2);
 
-        Assertions.assertTrue( testEngine.getRenderingManager().getHTML("ThisPage").indexOf("Circular reference") == -1, "got circ ref" );
+        Assertions.assertTrue( testEngine.getManager( RenderingManager.class ).getHTML("ThisPage").indexOf("Circular reference") == -1, "got circ ref" );
         Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div> <div class=\"inserted-page \" >foo\n</div>\n",
-                                 testEngine.getRenderingManager().getHTML("ThisPage"), "found != 2" );
+                testEngine.getManager( RenderingManager.class ).getHTML("ThisPage"), "found != 2" );
     }
 
     @Test
     public void testUnderscore() throws Exception {
-        String src  = "[{InsertPage page='Test_Page'}]";
-        String src2 = "foo[{ALLOW view Anonymous}]";
+        final String src  = "[{InsertPage page='Test_Page'}]";
+        final String src2 = "foo[{ALLOW view Anonymous}]";
 
         testEngine.saveText("ThisPage",src);
         testEngine.saveText("Test_Page",src2);
 
-        Assertions.assertTrue( testEngine.getRenderingManager().getHTML("ThisPage").indexOf("Circular reference") == -1, "got circ ref" );
-        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getRenderingManager().getHTML("ThisPage"), "found != 1" );
+        Assertions.assertTrue( testEngine.getManager( RenderingManager.class ).getHTML("ThisPage").indexOf("Circular reference") == -1, "got circ ref" );
+        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getManager( RenderingManager.class ).getHTML("ThisPage"), "found != 1" );
     }
 
     /**
@@ -109,7 +110,7 @@ public class InsertPageTest
         testEngine.saveText( "ThisPage", "[{InsertPage page='Test Page'}]" );
         testEngine.saveText( "Test Page", "foo[{ALLOW view Anonymous}]" );
 
-        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getRenderingManager().getHTML( "ThisPage" ), "found != 1" );
+        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getManager( RenderingManager.class ).getHTML( "ThisPage" ), "found != 1" );
     }
 
     /**
@@ -121,7 +122,7 @@ public class InsertPageTest
         testEngine.saveText( "ThisPage", "[{InsertPage page='Test Page'}]" );
         testEngine.saveText( "TestPage", "foo[{ALLOW view Anonymous}]" );
 
-        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getRenderingManager().getHTML( "ThisPage" ), "found != 1" );
+        Assertions.assertEquals( "<div class=\"inserted-page \" >foo\n</div>\n", testEngine.getManager( RenderingManager.class ).getHTML( "ThisPage" ), "found != 1" );
     }
 
 }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/PageViewPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/PageViewPluginTest.java
index 2073349..638732d 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/PageViewPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/PageViewPluginTest.java
@@ -23,6 +23,7 @@ import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.engine.PluginManager;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -65,10 +66,10 @@ public class PageViewPluginTest
     @Test
     public void testShowCountsBasic() throws Exception
     {
-        WikiPage page1 = testEngine.getPageManager().getPage( "TestPage01" );
-        WikiContext context1 = new WikiContext( testEngine, page1 );
-        WikiPage page2 = testEngine.getPageManager().getPage( "TestPage02" );
-        WikiContext context2 = new WikiContext( testEngine, page2 );
+        final WikiPage page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
+        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final WikiPage page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
+        final WikiContext context2 = new WikiContext( testEngine, page2 );
 
         // generate counts:
         testEngine.getRenderingManager().getHTML( context1, page1 );
@@ -76,13 +77,13 @@ public class PageViewPluginTest
         testEngine.getRenderingManager().getHTML( context2, page2 );
 
         // mind the double \n in the following string:
-        String pageViewPageContent = "[{PageViewPlugin show='list''\n\n* {1} ({2} views)\n}]";
+        final String pageViewPageContent = "[{PageViewPlugin show='list''\n\n* {1} ({2} views)\n}]";
         testEngine.saveText( "PageViews", pageViewPageContent );
 
-        WikiPage pageviews = testEngine.getPageManager().getPage( "PageViews" );
-        WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final WikiPage pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
+        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
 
-        String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
+        final String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
 //        System.out.println( result );
 
         Assertions.assertTrue( result.contains( "Test Page 01 (2 views)" ) );
@@ -95,10 +96,10 @@ public class PageViewPluginTest
     {
         testEngine.saveText( "TestPageExcluded", "this is test page that should be excluded [{PageViewPlugin}]" );
 
-        WikiPage page1 = testEngine.getPageManager().getPage( "TestPage01" );
-        WikiContext context1 = new WikiContext( testEngine, page1 );
-        WikiPage page2 = testEngine.getPageManager().getPage( "TestPage02" );
-        WikiContext context2 = new WikiContext( testEngine, page2 );
+        final WikiPage page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
+        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final WikiPage page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
+        final WikiContext context2 = new WikiContext( testEngine, page2 );
 
         // generate counts:
         testEngine.getRenderingManager().getHTML( context1, page1 );
@@ -106,13 +107,13 @@ public class PageViewPluginTest
         testEngine.getRenderingManager().getHTML( context2, page2 );
 
         // mind the double \n in the following string:
-        String pageViewPageContent = "[{PageViewPlugin show='list' exclude='TestPageExcl*' '\n\n* {1} ({2} views)\n}]";
+        final String pageViewPageContent = "[{PageViewPlugin show='list' exclude='TestPageExcl*' '\n\n* {1} ({2} views)\n}]";
         testEngine.saveText( "PageViews", pageViewPageContent );
 
-        WikiPage pageviews = testEngine.getPageManager().getPage( "PageViews" );
-        WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final WikiPage pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
+        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
 
-        String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
+        final String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
 //        System.out.println( result );
 
         Assertions.assertTrue( result.contains( "Test Page 01" ) );
@@ -126,10 +127,10 @@ public class PageViewPluginTest
     @Test
     public void testShowCountsSorted() throws Exception
     {
-        WikiPage page1 = testEngine.getPageManager().getPage( "TestPage01" );
-        WikiContext context1 = new WikiContext( testEngine, page1 );
-        WikiPage page2 = testEngine.getPageManager().getPage( "TestPage02" );
-        WikiContext context2 = new WikiContext( testEngine, page2 );
+        final WikiPage page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
+        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final WikiPage page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
+        final WikiContext context2 = new WikiContext( testEngine, page2 );
 
         // generate counts:
         testEngine.getRenderingManager().getHTML( context1, page1 );
@@ -137,17 +138,17 @@ public class PageViewPluginTest
         testEngine.getRenderingManager().getHTML( context2, page2 );
 
         // mind the double \n in the following string:
-        String pageViewPageContent = "[{PageViewPlugin show='list' sort=count '\n\n* {1} ({2} views)\n}]";
+        final String pageViewPageContent = "[{PageViewPlugin show='list' sort=count '\n\n* {1} ({2} views)\n}]";
         testEngine.saveText( "PageViews", pageViewPageContent );
 
-        WikiPage pageviews = testEngine.getPageManager().getPage( "PageViews" );
-        WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final WikiPage pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
+        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
 
-        String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
+        final String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
 //        System.out.println( result );
 
-        int start1 = result.indexOf( "Test Page 01" );
-        int start2 = result.indexOf( "Test Page 02" );
+        final int start1 = result.indexOf( "Test Page 01" );
+        final int start2 = result.indexOf( "Test Page 02" );
 
         // page2 should be showed before page1
         Assertions.assertTrue( start2 < start1 );
@@ -160,14 +161,14 @@ public class PageViewPluginTest
         testEngine.saveText( "TestPage03", "this is test page 03 [{PageViewPlugin}]" );
         testEngine.saveText( "TestPage04", "this is test page 04 [{PageViewPlugin}]" );
 
-        WikiPage page1 = testEngine.getPageManager().getPage( "TestPage01" );
-        WikiContext context1 = new WikiContext( testEngine, page1 );
-        WikiPage page2 = testEngine.getPageManager().getPage( "TestPage02" );
-        WikiContext context2 = new WikiContext( testEngine, page2 );
-        WikiPage page3 = testEngine.getPageManager().getPage( "TestPage03" );
-        WikiContext context3 = new WikiContext( testEngine, page3 );
-        WikiPage page4 = testEngine.getPageManager().getPage( "TestPage04" );
-        WikiContext context4 = new WikiContext( testEngine, page4 );
+        final WikiPage page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
+        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final WikiPage page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
+        final WikiContext context2 = new WikiContext( testEngine, page2 );
+        final WikiPage page3 = testEngine.getManager( PageManager.class ).getPage( "TestPage03" );
+        final WikiContext context3 = new WikiContext( testEngine, page3 );
+        final WikiPage page4 = testEngine.getManager( PageManager.class ).getPage( "TestPage04" );
+        final WikiContext context4 = new WikiContext( testEngine, page4 );
 
         // generate counts:
         testEngine.getRenderingManager().getHTML( context1, page1 );
@@ -177,13 +178,13 @@ public class PageViewPluginTest
         testEngine.getRenderingManager().getHTML( context4, page4 );
 
         // mind the double \n in the following string:
-        String pageViewPageContent = "[{PageViewPlugin show='list' entries=3'\n\n* {1} ({2} views)\n}]";
+        final String pageViewPageContent = "[{PageViewPlugin show='list' entries=3'\n\n* {1} ({2} views)\n}]";
         testEngine.saveText( "PageViews", pageViewPageContent );
 
-        WikiPage pageviews = testEngine.getPageManager().getPage( "PageViews" );
-        WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final WikiPage pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
+        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
 
-        String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
+        final String result = testEngine.getRenderingManager().getHTML( contextPV, pageviews );
 //        System.out.println( result );
 
         Assertions.assertTrue( result.contains( "Test Page 03" ) );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/TableOfContentsTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/TableOfContentsTest.java
index 47a0784..b53c400 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/TableOfContentsTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/TableOfContentsTest.java
@@ -24,6 +24,7 @@ package org.apache.wiki.plugin;
 
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -38,18 +39,18 @@ public class TableOfContentsTest
 
     @AfterEach
     public void tearDown() throws Exception {
-        testEngine.getPageManager().deletePage( "Test" );
+        testEngine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     @Test
     public void testHeadingVariables()
         throws Exception
     {
-        String src="[{SET foo=bar}]\n\n[{TableOfContents}]\n\n!!!Heading [{$foo}]";
+        final String src="[{SET foo=bar}]\n\n[{TableOfContents}]\n\n!!!Heading [{$foo}]";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         // FIXME: The <p> should not be here.
         Assertions.assertEquals( "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
@@ -65,14 +66,14 @@ public class TableOfContentsTest
     public void testNumberedItems()
     throws Exception
     {
-        String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading";
+        final String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         // FIXME: The <p> should not be here.
-        String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
+        final String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
                 "<h4 id=\"section-TOC\">Table of Contents</h4>\n"+
                 "<ul>\n"+
                 "<li class=\"toclevel-1\"><a class=\"wikipage\" href=\"#section-Test-HeadingBar\">3 Heading bar</a></li>\n"+
@@ -90,14 +91,14 @@ public class TableOfContentsTest
     public void testNumberedItemsComplex()
     throws Exception
     {
-        String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading\n\n!Subsubheading2\n\n!!Subheading2\n\n!Subsubheading3\n\n!!!Heading\n\n!!Subheading3";
+        final String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading\n\n!Subsubheading2\n\n!!Subheading2\n\n!Subsubheading3\n\n!!!Heading\n\n!!Subheading3";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         // FIXME: The <p> should not be here.
-        String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
+        final String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
         "<h4 id=\"section-TOC\">Table of Contents</h4>\n"+
         "<ul>\n"+
         "<li class=\"toclevel-1\"><a class=\"wikipage\" href=\"#section-Test-HeadingBar\">3 Heading bar</a></li>\n"+
@@ -126,14 +127,14 @@ public class TableOfContentsTest
     public void testNumberedItemsComplex2()
     throws Exception
     {
-        String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!Subheading0\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading\n\n!Subsubheading2\n\n!!Subheading2\n\n!Subsubheading3\n\n!!!Heading\n\n!!Subheading3";
+        final String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3}]\n\n!!Subheading0\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading\n\n!Subsubheading2\n\n!!Subheading2\n\n!Subsubheading3\n\n!!!Heading\n\n!!Subheading3";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         // FIXME: The <p> should not be here.
-        String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
+        final String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
         "<h4 id=\"section-TOC\">Table of Contents</h4>\n"+
         "<ul>\n"+
         "<li class=\"toclevel-2\"><a class=\"wikipage\" href=\"#section-Test-Subheading0\">3.1 Subheading0</a></li>\n"+
@@ -164,14 +165,14 @@ public class TableOfContentsTest
     public void testNumberedItemsWithPrefix()
     throws Exception
     {
-        String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3,prefix=FooBar-}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading";
+        final String src="[{SET foo=bar}]\n\n[{INSERT TableOfContents WHERE numbered=true,start=3,prefix=FooBar-}]\n\n!!!Heading [{$foo}]\n\n!!Subheading\n\n!Subsubheading";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         // FIXME: The <p> should not be here.
-        String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
+        final String expecting = "<p><div class=\"toc\">\n<div class=\"collapsebox\">\n"+
         "<h4 id=\"section-TOC\">Table of Contents</h4>\n"+
         "<ul>\n"+
         "<li class=\"toclevel-1\"><a class=\"wikipage\" href=\"#section-Test-HeadingBar\">FooBar-3 Heading bar</a></li>\n"+
@@ -194,11 +195,11 @@ public class TableOfContentsTest
     public void testSelfReference()
         throws Exception
     {
-        String src = "!!![{TableOfContents}]";
+        final String src = "!!![{TableOfContents}]";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         Assertions.assertTrue( res.indexOf("Table of Contents") != -1 );
     }
@@ -207,11 +208,11 @@ public class TableOfContentsTest
     public void testHTML()
         throws Exception
     {
-        String src = "[{TableOfContents}]\n\n!<i>test</i>";
+        final String src = "[{TableOfContents}]\n\n!<i>test</i>";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         Assertions.assertTrue( res.indexOf("<i>") == -1, "<i>" ); // Check that there is no HTML left
         Assertions.assertTrue( res.indexOf("</i>") == -1, "</i>" ); // Check that there is no HTML left
@@ -220,11 +221,11 @@ public class TableOfContentsTest
     @Test
     public void testSimilarNames() throws WikiException
     {
-        String src = "[{TableOfContents}]\n\n!Test\n\n!Test\n\n";
+        final String src = "[{TableOfContents}]\n\n!Test\n\n!Test\n\n";
 
         testEngine.saveText( "Test", src );
 
-        String res = testEngine.getI18nHTML( "Test" );
+        final String res = testEngine.getI18nHTML( "Test" );
 
         Assertions.assertTrue( res.indexOf(  "id=\"section-Test-Test\"" ) != -1, "Final HTML 1" );
         Assertions.assertTrue( res.indexOf(  "id=\"section-Test-Test-2\"" ) != -1, "Final HTML 2" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/UndefinedPagesPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/UndefinedPagesPluginTest.java
index 58aab45..c63198a 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/UndefinedPagesPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/UndefinedPagesPluginTest.java
@@ -25,6 +25,7 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.engine.PluginManager;
 import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.render.RenderingManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -60,7 +61,7 @@ public class UndefinedPagesPluginTest {
     }
 
     private String wikitize( final String s ) {
-        return testEngine.getRenderingManager().textToHTML( context, s );
+        return testEngine.getManager( RenderingManager.class ).textToHTML( context, s );
     }
 
     /**
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/WeblogPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/WeblogPluginTest.java
index 3ae3b30..f568074 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/WeblogPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/WeblogPluginTest.java
@@ -2,6 +2,7 @@ package org.apache.wiki.plugin;
 
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -13,7 +14,7 @@ public class WeblogPluginTest {
 
     @AfterEach
     public void tearDown() throws Exception {
-        testEngine.getPageManager().deletePage( "Test" );
+        testEngine.getManager( PageManager.class ).deletePage( "Test" );
     }
 
     @Test
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/providers/CachingProviderTest.java b/jspwiki-main/src/test/java/org/apache/wiki/providers/CachingProviderTest.java
index 1d29bfa..c2543c4 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/providers/CachingProviderTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/providers/CachingProviderTest.java
@@ -22,6 +22,7 @@ package org.apache.wiki.providers;
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.util.FileUtil;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterEach;
@@ -52,22 +53,22 @@ public class CachingProviderTest
     public void testInitialization()
         throws Exception
     {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         props.setProperty( "jspwiki.usePageCache", "true" );
         props.setProperty( "jspwiki.pageProvider", "org.apache.wiki.providers.CounterProvider" );
         props.setProperty( "jspwiki.cachingProvider.capacity", "100" );
 
-        TestEngine engine = new TestEngine( props );
+        final TestEngine engine = new TestEngine( props );
 
-        CounterProvider p = (CounterProvider)((CachingProvider)engine.getPageManager().getProvider()).getRealProvider();
+        final CounterProvider p = (CounterProvider)((CachingProvider)engine.getManager( PageManager.class ).getProvider()).getRealProvider();
 
         Assertions.assertEquals( 1, p.m_initCalls, "init" );
         Assertions.assertEquals( 1, p.m_getAllPagesCalls, "getAllPages" );
         Assertions.assertEquals( 0, p.m_pageExistsCalls, "pageExists" );
         Assertions.assertEquals( 4, p.m_getPageTextCalls, "getPageText" );
 
-        engine.getPageManager().getPage( "Foo" );
+        engine.getManager( PageManager.class ).getPage( "Foo" );
 
         Assertions.assertEquals( 0, p.m_pageExistsCalls, "pageExists2" );
     }
@@ -76,26 +77,26 @@ public class CachingProviderTest
     public void testSneakyAdd()
         throws Exception
     {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         props.setProperty( "jspwiki.cachingProvider.cacheCheckInterval", "2" );
 
-        TestEngine engine = new TestEngine( props );
+        final TestEngine engine = new TestEngine( props );
 
-        String dir = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
+        final String dir = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
 
-        File f = new File( dir, "Testi.txt" );
-        String content = "[fuufaa]";
+        final File f = new File( dir, "Testi.txt" );
+        final String content = "[fuufaa]";
 
-        PrintWriter out = new PrintWriter( new FileWriter(f) );
+        final PrintWriter out = new PrintWriter( new FileWriter(f) );
         FileUtil.copyContents( new StringReader(content), out );
         out.close();
 
-        Awaitility.await( "testSneakyAdd" ).until( () -> engine.getPageManager().getPage( "Testi" ) != null );
-        WikiPage p = engine.getPageManager().getPage( "Testi" );
+        Awaitility.await( "testSneakyAdd" ).until( () -> engine.getManager( PageManager.class ).getPage( "Testi" ) != null );
+        final WikiPage p = engine.getManager( PageManager.class ).getPage( "Testi" );
         Assertions.assertNotNull( p, "page did not exist?" );
 
-        String text = engine.getPageManager().getText( "Testi");
+        final String text = engine.getManager( PageManager.class ).getText( "Testi");
         Assertions.assertEquals( "[fuufaa]", text, "text" );
 
         // TODO: ReferenceManager check as well
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/providers/VersioningFileProviderTest.java b/jspwiki-main/src/test/java/org/apache/wiki/providers/VersioningFileProviderTest.java
index 688ae5f..301a968 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/providers/VersioningFileProviderTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/providers/VersioningFileProviderTest.java
@@ -87,10 +87,10 @@ public class VersioningFileProviderTest
        // also create an associated properties file with some history
         injectFile(NAME1+FileSystemProvider.PROP_EXT, FAKE_HISTORY);
 
-        String res = engine.getPageManager().getText( NAME1 );
+        final String res = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( fakeWikiPage, res, "fetch latest should work" );
 
-        WikiPage page = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
         Assertions.assertEquals( 1, page.getVersion(), "original version expected" );
         Assertions.assertEquals( OLD_AUTHOR, page.getAuthor(), "original author" );
     }
@@ -108,13 +108,13 @@ public class VersioningFileProviderTest
         // initial FileSystemProvider wiki page must be faked.
         injectFile(NAME1+AbstractFileProvider.FILE_EXT, "foobar");
 
-        String res = engine.getPageManager().getText( NAME1 );
+        String res = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( "foobar", res, "fetch latest did not work" );
 
-        res = engine.getPageManager().getText( NAME1, 1 ); // Should be the first version.
+        res = engine.getManager( PageManager.class ).getText( NAME1, 1 ); // Should be the first version.
         Assertions.assertEquals( "foobar", res, "fetch by direct version did not work" );
 
-        WikiPage page = engine.getPageManager().getPage( NAME1 );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1 );
         Assertions.assertEquals( 1, page.getVersion(), "original version expected" );
         Assertions.assertNull( page.getAuthor(), "original author not expected" );
     }
@@ -136,13 +136,13 @@ public class VersioningFileProviderTest
        // now create the associated properties file with some history
         injectFile(NAME1+FileSystemProvider.PROP_EXT, FAKE_HISTORY);
 
-        String res = engine.getPageManager().getText( NAME1 );
+        String res = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( fakeWikiPage, res, "fetch latest did not work" );
 
-        res = engine.getPageManager().getText( NAME1, 1 ); // Should be the first version.
+        res = engine.getManager( PageManager.class ).getText( NAME1, 1 ); // Should be the first version.
         Assertions.assertEquals( fakeWikiPage, res, "fetch by direct version did not work" );
 
-        WikiPage page = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
         Assertions.assertEquals( 1, page.getVersion(), "original version expected" );
         Assertions.assertEquals( OLD_AUTHOR, page.getAuthor(), "original author" );
     }
@@ -166,7 +166,7 @@ public class VersioningFileProviderTest
        // also create an associated properties file with some history
         injectFile(NAME1+FileSystemProvider.PROP_EXT, FAKE_HISTORY);
 
-        String result1 = engine.getPageManager().getText( NAME1 );
+        final String result1 = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( fakeWikiPage, result1, "latest should be initial" );
 
         // now update the wiki page to create a new version
@@ -174,24 +174,24 @@ public class VersioningFileProviderTest
         engine.saveText( NAME1, text );
 
         // confirm the right number of versions have been recorded
-        List< WikiPage > versionHistory = engine.getPageManager().getVersionHistory(NAME1);
+        final List< WikiPage > versionHistory = engine.getManager( PageManager.class ).getVersionHistory(NAME1);
         Assertions.assertEquals( 2, versionHistory.size(), "number of versions" );
 
         // fetch the updated page
-        String result2 = engine.getPageManager().getText( NAME1 );
+        final String result2 = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( text, result2, "latest should be new version" );
-        String result3 = engine.getPageManager().getText( NAME1, 2 ); // Should be the 2nd version.
+        final String result3 = engine.getManager( PageManager.class ).getText( NAME1, 2 ); // Should be the 2nd version.
         Assertions.assertEquals( text, result3, "fetch new by version did not work" );
 
         // now confirm the original page has been archived
-        String result4 = engine.getPageManager().getText( NAME1, 1 );
+        final String result4 = engine.getManager( PageManager.class ).getText( NAME1, 1 );
         Assertions.assertEquals( fakeWikiPage, result4, "fetch original by version Assertions.failed" );
 
-        WikiPage pageNew = engine.getPageManager().getPage( NAME1, 2 );
+        final WikiPage pageNew = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
         Assertions.assertEquals( 2, pageNew.getVersion(), "new version" );
         Assertions.assertEquals( "Guest", pageNew.getAuthor(), "new author" );
 
-        WikiPage pageOld = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage pageOld = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
         Assertions.assertEquals( 1, pageOld.getVersion(), "old version" );
         Assertions.assertEquals( OLD_AUTHOR, pageOld.getAuthor(), "old author" );
     }
@@ -222,32 +222,32 @@ public class VersioningFileProviderTest
         engine.saveText( NAME1, text3 );
 
         // confirm the right number of versions have been recorded
-        Collection versionHistory = engine.getPageManager().getVersionHistory(NAME1);
+        final Collection versionHistory = engine.getManager( PageManager.class ).getVersionHistory(NAME1);
         Assertions.assertEquals( 3, versionHistory.size(), "number of versions" );
 
         // fetch the latest version of the page
-        String result = engine.getPageManager().getText( NAME1 );
+        final String result = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( text3, result, "latest should be newest version" );
-        String result2 = engine.getPageManager().getText( NAME1, 3 );
+        final String result2 = engine.getManager( PageManager.class ).getText( NAME1, 3 );
         Assertions.assertEquals( text3, result2, "fetch new by version did not work" );
 
         // confirm the original page was archived
-        String result3 = engine.getPageManager().getText( NAME1, 1 );
+        final String result3 = engine.getManager( PageManager.class ).getText( NAME1, 1 );
         Assertions.assertEquals( fakeWikiPage, result3, "fetch original by version Assertions.failed" );
 
         // confirm the first update was archived
-        String result4 = engine.getPageManager().getText( NAME1, 2 );
+        final String result4 = engine.getManager( PageManager.class ).getText( NAME1, 2 );
         Assertions.assertEquals( text2, result4, "fetch original by version Assertions.failed" );
 
-        WikiPage pageNew = engine.getPageManager().getPage( NAME1 );
+        final WikiPage pageNew = engine.getManager( PageManager.class ).getPage( NAME1 );
         Assertions.assertEquals( 3, pageNew.getVersion(), "newest version" );
         Assertions.assertEquals( pageNew.getAuthor(), "Guest", "newest author" );
 
-        WikiPage pageMiddle = engine.getPageManager().getPage( NAME1, 2 );
+        final WikiPage pageMiddle = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
         Assertions.assertEquals( 2, pageMiddle.getVersion(), "middle version" );
         Assertions.assertEquals( Users.JANNE, pageMiddle.getAuthor(), "middle author" );
 
-        WikiPage pageOld = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage pageOld = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
         Assertions.assertEquals( 1, pageOld.getVersion(), "old version" );
         Assertions.assertEquals( OLD_AUTHOR, pageOld.getAuthor(), "old author" );
     }
@@ -289,32 +289,32 @@ public class VersioningFileProviderTest
         engine.saveText( NAME1, text3 );
 
         // confirm the right number of versions have been recorded
-        Collection versionHistory = engine.getPageManager().getVersionHistory(NAME1);
+        final Collection versionHistory = engine.getManager( PageManager.class ).getVersionHistory(NAME1);
         Assertions.assertEquals( 3, versionHistory.size(), "number of versions" );
 
         // fetch the latest version of the page
-        String result = engine.getPageManager().getText( NAME1 );
+        final String result = engine.getManager( PageManager.class ).getText( NAME1 );
         Assertions.assertEquals( text3, result, "latest should be newest version" );
-        String result2 = engine.getPageManager().getText( NAME1, 3 );
+        final String result2 = engine.getManager( PageManager.class ).getText( NAME1, 3 );
         Assertions.assertEquals( text3, result2, "fetch new by version did not work" );
 
         // confirm the original page was archived
-        String result3 = engine.getPageManager().getText( NAME1, 1 );
+        final String result3 = engine.getManager( PageManager.class ).getText( NAME1, 1 );
         Assertions.assertEquals( fakeWikiPage, result3, "fetch original by version Assertions.failed" );
 
         // confirm the first update was archived
-        String result4 = engine.getPageManager().getText( NAME1, 2 );
+        final String result4 = engine.getManager( PageManager.class ).getText( NAME1, 2 );
         Assertions.assertEquals( text2, result4, "fetch original by version Assertions.failed" );
 
-        WikiPage pageNew = engine.getPageManager().getPage( NAME1 );
+        final WikiPage pageNew = engine.getManager( PageManager.class ).getPage( NAME1 );
         Assertions.assertEquals( 3, pageNew.getVersion(), "newest version" );
         Assertions.assertEquals( "Guest", pageNew.getAuthor(), "newest author" );
 
-        WikiPage pageMiddle = engine.getPageManager().getPage( NAME1, 2 );
+        final WikiPage pageMiddle = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
         Assertions.assertEquals( 2, pageMiddle.getVersion(), "middle version" );
         Assertions.assertEquals( Users.JANNE, pageMiddle.getAuthor(), "middle author" );
 
-        WikiPage pageOld = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage pageOld = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
         Assertions.assertEquals( 1, pageOld.getVersion(), "old version" );
         Assertions.assertEquals( OLD_AUTHOR, pageOld.getAuthor(), "old author" );
     }
@@ -324,8 +324,8 @@ public class VersioningFileProviderTest
         throws Exception
     {
         String text = "";
-        String name = NAME1;
-        int maxver = 100;           // Save 100 versions.
+        final String name = NAME1;
+        final int maxver = 100;           // Save 100 versions.
 
         for( int i = 0; i < maxver; i++ )
         {
@@ -333,23 +333,23 @@ public class VersioningFileProviderTest
             engine.saveText( name, text );
         }
 
-        WikiPage pageinfo = engine.getPageManager().getPage( NAME1 );
+        final WikiPage pageinfo = engine.getManager( PageManager.class ).getPage( NAME1 );
 
         Assertions.assertEquals( maxver, pageinfo.getVersion(), "wrong version" );
 
         // +2 comes from \r\n.
-        Assertions.assertEquals( maxver+2, engine.getPageManager().getText(NAME1).length(), "wrong text" );
+        Assertions.assertEquals( maxver+2, engine.getManager( PageManager.class ).getText(NAME1).length(), "wrong text" );
     }
 
     @Test
     public void testCheckin()
         throws Exception
     {
-        String text = "diddo\r\n";
+        final String text = "diddo\r\n";
 
         engine.saveText( NAME1, text );
 
-        String res = engine.getPageManager().getText(NAME1);
+        final String res = engine.getManager( PageManager.class ).getText(NAME1);
 
         Assertions.assertEquals( text, res );
     }
@@ -358,11 +358,11 @@ public class VersioningFileProviderTest
     public void testGetByVersion()
         throws Exception
     {
-        String text = "diddo\r\n";
+        final String text = "diddo\r\n";
 
         engine.saveText( NAME1, text );
 
-        WikiPage page = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage page = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
 
         Assertions.assertEquals( NAME1, page.getName(), "name" );
         Assertions.assertEquals( 1, page.getVersion(), "version" );
@@ -372,11 +372,11 @@ public class VersioningFileProviderTest
     public void testPageInfo()
         throws Exception
     {
-        String text = "diddo\r\n";
+        final String text = "diddo\r\n";
 
         engine.saveText( NAME1, text );
 
-        WikiPage res = engine.getPageManager().getPage(NAME1);
+        final WikiPage res = engine.getManager( PageManager.class ).getPage(NAME1);
 
         Assertions.assertEquals( 1, res.getVersion() );
     }
@@ -385,42 +385,42 @@ public class VersioningFileProviderTest
     public void testGetOldVersion()
         throws Exception
     {
-        String text = "diddo\r\n";
-        String text2 = "barbar\r\n";
-        String text3 = "Barney\r\n";
+        final String text = "diddo\r\n";
+        final String text2 = "barbar\r\n";
+        final String text3 = "Barney\r\n";
 
         engine.saveText( NAME1, text );
         engine.saveText( NAME1, text2 );
         engine.saveText( NAME1, text3 );
 
-        WikiPage res = engine.getPageManager().getPage(NAME1);
+        final WikiPage res = engine.getManager( PageManager.class ).getPage(NAME1);
 
         Assertions.assertEquals( 3, res.getVersion(), "wrong version" );
 
-        Assertions.assertEquals( text, engine.getPageManager().getText( NAME1, 1 ), "ver1" );
-        Assertions.assertEquals( text2, engine.getPageManager().getText( NAME1, 2 ), "ver2" );
-        Assertions.assertEquals( text3, engine.getPageManager().getText( NAME1, 3 ), "ver3" );
+        Assertions.assertEquals( text, engine.getManager( PageManager.class ).getText( NAME1, 1 ), "ver1" );
+        Assertions.assertEquals( text2, engine.getManager( PageManager.class ).getText( NAME1, 2 ), "ver2" );
+        Assertions.assertEquals( text3, engine.getManager( PageManager.class ).getText( NAME1, 3 ), "ver3" );
     }
 
     @Test
     public void testGetOldVersion2()
         throws Exception
     {
-        String text = "diddo\r\n";
-        String text2 = "barbar\r\n";
-        String text3 = "Barney\r\n";
+        final String text = "diddo\r\n";
+        final String text2 = "barbar\r\n";
+        final String text3 = "Barney\r\n";
 
         engine.saveText( NAME1, text );
         engine.saveText( NAME1, text2 );
         engine.saveText( NAME1, text3 );
 
-        WikiPage res = engine.getPageManager().getPage(NAME1);
+        final WikiPage res = engine.getManager( PageManager.class ).getPage(NAME1);
 
         Assertions.assertEquals( 3, res.getVersion(), "wrong version" );
 
-        Assertions.assertEquals( 1, engine.getPageManager().getPage( NAME1, 1 ).getVersion(), "ver1" );
-        Assertions.assertEquals( 2, engine.getPageManager().getPage( NAME1, 2 ).getVersion(), "ver2" );
-        Assertions.assertEquals( 3, engine.getPageManager().getPage( NAME1, 3 ).getVersion(), "ver3" );
+        Assertions.assertEquals( 1, engine.getManager( PageManager.class ).getPage( NAME1, 1 ).getVersion(), "ver1" );
+        Assertions.assertEquals( 2, engine.getManager( PageManager.class ).getPage( NAME1, 2 ).getVersion(), "ver2" );
+        Assertions.assertEquals( 3, engine.getManager( PageManager.class ).getPage( NAME1, 3 ).getVersion(), "ver3" );
 }
 
     /**
@@ -430,42 +430,42 @@ public class VersioningFileProviderTest
     public void testGetOldVersionUTF8()
         throws Exception
     {
-        String text = "\u00e5\u00e4\u00f6\r\n";
-        String text2 = "barbar\u00f6\u00f6\r\n";
-        String text3 = "Barney\u00e4\u00e4\r\n";
+        final String text = "\u00e5\u00e4\u00f6\r\n";
+        final String text2 = "barbar\u00f6\u00f6\r\n";
+        final String text3 = "Barney\u00e4\u00e4\r\n";
 
         engine.saveText( NAME1, text );
         engine.saveText( NAME1, text2 );
         engine.saveText( NAME1, text3 );
 
-        WikiPage res = engine.getPageManager().getPage(NAME1);
+        final WikiPage res = engine.getManager( PageManager.class ).getPage(NAME1);
 
         Assertions.assertEquals( 3, res.getVersion(), "wrong version" );
 
-        Assertions.assertEquals( text, engine.getPageManager().getText( NAME1, 1 ), "ver1" );
-        Assertions.assertEquals( text2, engine.getPageManager().getText( NAME1, 2 ), "ver2" );
-        Assertions.assertEquals( text3, engine.getPageManager().getText( NAME1, 3 ), "ver3" );
+        Assertions.assertEquals( text, engine.getManager( PageManager.class ).getText( NAME1, 1 ), "ver1" );
+        Assertions.assertEquals( text2, engine.getManager( PageManager.class ).getText( NAME1, 2 ), "ver2" );
+        Assertions.assertEquals( text3, engine.getManager( PageManager.class ).getText( NAME1, 3 ), "ver3" );
     }
 
     @Test
     public void testNonexistentPage()
     {
-        Assertions.assertNull( engine.getPageManager().getPage("fjewifjeiw") );
+        Assertions.assertNull( engine.getManager( PageManager.class ).getPage("fjewifjeiw") );
     }
 
     @Test
     public void testVersionHistory()
         throws Exception
     {
-        String text = "diddo\r\n";
-        String text2 = "barbar\r\n";
-        String text3 = "Barney\r\n";
+        final String text = "diddo\r\n";
+        final String text2 = "barbar\r\n";
+        final String text3 = "Barney\r\n";
 
         engine.saveText( NAME1, text );
         engine.saveText( NAME1, text2 );
         engine.saveText( NAME1, text3 );
 
-        Collection history = engine.getPageManager().getVersionHistory(NAME1);
+        final Collection history = engine.getManager( PageManager.class ).getVersionHistory(NAME1);
 
         Assertions.assertEquals( 3, history.size(), "size" );
     }
@@ -478,12 +478,12 @@ public class VersioningFileProviderTest
         engine.saveText( NAME1, "v2" );
         engine.saveText( NAME1, "v3" );
 
-        PageManager mgr = engine.getPageManager();
-        WikiPageProvider provider = mgr.getProvider();
+        final PageManager mgr = engine.getManager( PageManager.class );
+        final WikiPageProvider provider = mgr.getProvider();
 
         provider.deletePage( NAME1 );
 
-        File f = new File( files, NAME1+AbstractFileProvider.FILE_EXT );
+        final File f = new File( files, NAME1+AbstractFileProvider.FILE_EXT );
         Assertions.assertFalse( f.exists(), "file exists" );
     }
 
@@ -495,8 +495,8 @@ public class VersioningFileProviderTest
         engine.saveText( NAME1, "v2\r\n" );
         engine.saveText( NAME1, "v3\r\n" );
 
-        PageManager mgr = engine.getPageManager();
-        WikiPageProvider provider = mgr.getProvider();
+        final PageManager mgr = engine.getManager( PageManager.class );
+        final WikiPageProvider provider = mgr.getProvider();
 
         List l = provider.getVersionHistory( NAME1 );
         Assertions.assertEquals( 3, l.size(), "wrong # of versions" );
@@ -515,7 +515,7 @@ public class VersioningFileProviderTest
             provider.getPageText( NAME1, 2 );
             Assertions.fail( "v2" );
         }
-        catch( NoSuchVersionException e )
+        catch( final NoSuchVersionException e )
         {
             // This is expected
         }
@@ -526,13 +526,13 @@ public class VersioningFileProviderTest
     public void testChangeNote()
         throws Exception
     {
-        WikiPage p = new WikiPage( engine, NAME1 );
+        final WikiPage p = new WikiPage( engine, NAME1 );
         p.setAttribute(WikiPage.CHANGENOTE, "Test change" );
-        WikiContext context = new WikiContext(engine,p);
+        final WikiContext context = new WikiContext(engine,p);
 
-        engine.getPageManager().saveText( context, "test" );
+        engine.getManager( PageManager.class ).saveText( context, "test" );
 
-        WikiPage p2 = engine.getPageManager().getPage( NAME1 );
+        final WikiPage p2 = engine.getManager( PageManager.class ).getPage( NAME1 );
 
         Assertions.assertEquals( "Test change", p2.getAttribute(WikiPage.CHANGENOTE) );
     }
@@ -541,22 +541,22 @@ public class VersioningFileProviderTest
     public void testChangeNoteOldVersion()
         throws Exception
     {
-        WikiPage p = new WikiPage( engine, NAME1 );
+        final WikiPage p = new WikiPage( engine, NAME1 );
 
 
-        WikiContext context = new WikiContext(engine,p);
+        final WikiContext context = new WikiContext(engine,p);
 
         context.getPage().setAttribute(WikiPage.CHANGENOTE, "Test change" );
-        engine.getPageManager().saveText( context, "test" );
+        engine.getManager( PageManager.class ).saveText( context, "test" );
 
         context.getPage().setAttribute(WikiPage.CHANGENOTE, "Change 2" );
-        engine.getPageManager().saveText( context, "test2" );
+        engine.getManager( PageManager.class ).saveText( context, "test2" );
 
-        WikiPage p2 = engine.getPageManager().getPage( NAME1, 1 );
+        final WikiPage p2 = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
 
         Assertions.assertEquals( "Test change", p2.getAttribute(WikiPage.CHANGENOTE) );
 
-        WikiPage p3 = engine.getPageManager().getPage( NAME1, 2 );
+        final WikiPage p3 = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
 
         Assertions.assertEquals( "Change 2", p3.getAttribute(WikiPage.CHANGENOTE) );
     }
@@ -564,25 +564,25 @@ public class VersioningFileProviderTest
     @Test
     public void testChangeNoteOldVersion2() throws Exception
     {
-        WikiPage p = new WikiPage( engine, NAME1 );
+        final WikiPage p = new WikiPage( engine, NAME1 );
 
-        WikiContext context = new WikiContext(engine,p);
+        final WikiContext context = new WikiContext(engine,p);
 
         context.getPage().setAttribute( WikiPage.CHANGENOTE, "Test change" );
 
-        engine.getPageManager().saveText( context, "test" );
+        engine.getManager( PageManager.class ).saveText( context, "test" );
 
         for( int i = 0; i < 5; i++ )
         {
-            WikiPage p2 = (WikiPage)engine.getPageManager().getPage( NAME1 ).clone();
+            final WikiPage p2 = (WikiPage)engine.getManager( PageManager.class ).getPage( NAME1 ).clone();
             p2.removeAttribute(WikiPage.CHANGENOTE);
 
             context.setPage( p2 );
 
-            engine.getPageManager().saveText( context, "test"+i );
+            engine.getManager( PageManager.class ).saveText( context, "test"+i );
         }
 
-        WikiPage p3 = engine.getPageManager().getPage( NAME1, -1 );
+        final WikiPage p3 = engine.getManager( PageManager.class ).getPage( NAME1, -1 );
 
         Assertions.assertEquals( null, (String)p3.getAttribute(WikiPage.CHANGENOTE) );
     }
@@ -591,11 +591,11 @@ public class VersioningFileProviderTest
      * Creates a file of the given name in the wiki page directory,
      * containing the data provided.
      */
-    private void injectFile(String fileName, String fileContent)
+    private void injectFile( final String fileName, final String fileContent)
         throws IOException
     {
-        File ft = new File( files, fileName );
-        Writer out = new FileWriter( ft );
+        final File ft = new File( files, fileName );
+        final Writer out = new FileWriter( ft );
         FileUtil.copyContents( new StringReader(fileContent), out );
         out.close();
     }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java
index 76122de..e9ccc48 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/references/ReferenceManagerTest.java
@@ -12,11 +12,13 @@
  * limitations under the License.
  */
 package org.apache.wiki.references;
+
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.Util;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -82,7 +84,7 @@ public class ReferenceManagerTest  {
         Assertions.assertNotNull( c, "referrers expected" );
         Assertions.assertTrue( c.size() == 1 && c.contains("Foobar") );
 
-        engine.getPageManager().deletePage( "Foobar" );
+        engine.getManager( PageManager.class ).deletePage( "Foobar" );
         c = mgr.findReferrers("Foobar2");
         Assertions.assertNull( c );
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/render/RenderingManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/render/RenderingManagerTest.java
index 436427a..9a453b6 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/render/RenderingManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/render/RenderingManagerTest.java
@@ -23,6 +23,7 @@ import org.apache.commons.lang3.time.StopWatch;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.parser.WikiDocument;
 import org.junit.jupiter.api.AfterEach;
@@ -36,7 +37,7 @@ public class RenderingManagerTest {
 
     @AfterEach
     public void tearDown() throws Exception {
-        m_engine.getPageManager().deletePage( "TestPage" );
+        m_engine.getManager( PageManager.class ).deletePage( "TestPage" );
         CacheManager.getInstance().removeAllCaches();
     }
 
@@ -106,23 +107,23 @@ public class RenderingManagerTest {
     {
         m_engine.saveText( "TestPage", TEST_TEXT );
 
-        StopWatch sw = new StopWatch();
+        final StopWatch sw = new StopWatch();
 
         // System.out.println("DOM cache speed test:");
         sw.start();
 
         for( int i = 0; i < 300; i++ )
         {
-            WikiPage page = m_engine.getPageManager().getPage( "TestPage" );
-            String pagedata = m_engine.getPageManager().getPureText( page );
+            final WikiPage page = m_engine.getManager( PageManager.class ).getPage( "TestPage" );
+            final String pagedata = m_engine.getManager( PageManager.class ).getPureText( page );
 
-            WikiContext context = new WikiContext( m_engine, page );
+            final WikiContext context = new WikiContext( m_engine, page );
 
-            MarkupParser p = m_manager.getParser( context, pagedata );
+            final MarkupParser p = m_manager.getParser( context, pagedata );
 
-            WikiDocument d = p.parse();
+            final WikiDocument d = p.parse();
 
-            String html = m_manager.getHTML( context, d );
+            final String html = m_manager.getHTML( context, d );
             Assertions.assertNotNull( "noncached got null response",html);
         }
 
@@ -135,8 +136,8 @@ public class RenderingManagerTest {
         sw.start();
 
         for( int i = 0; i < 300; i++ ) {
-            final WikiPage page = m_engine.getPageManager().getPage( "TestPage" );
-            final String pagedata = m_engine.getPageManager().getPureText( page );
+            final WikiPage page = m_engine.getManager( PageManager.class ).getPage( "TestPage" );
+            final String pagedata = m_engine.getManager( PageManager.class ).getPureText( page );
             final WikiContext context = new WikiContext( m_engine, page );
             final String html = m_manager.getHTML( context, pagedata );
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/rss/RSSGeneratorTest.java b/jspwiki-main/src/test/java/org/apache/wiki/rss/RSSGeneratorTest.java
index ce8949d..ecef0e8 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/rss/RSSGeneratorTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/rss/RSSGeneratorTest.java
@@ -26,6 +26,7 @@ import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.plugin.WeblogEntryPlugin;
 import org.apache.wiki.plugin.WeblogPlugin;
 import org.apache.wiki.providers.FileSystemProvider;
@@ -65,7 +66,7 @@ public class RSSGeneratorTest {
     public void testBlogRSS()
         throws Exception
     {
-        WeblogEntryPlugin plugin = new WeblogEntryPlugin();
+        final WeblogEntryPlugin plugin = new WeblogEntryPlugin();
         m_testEngine.saveText( "TestBlog", "Foo1" );
 
         String newPage = plugin.getNewEntryPage( m_testEngine, "TestBlog" );
@@ -74,19 +75,19 @@ public class RSSGeneratorTest {
         newPage = plugin.getNewEntryPage( m_testEngine, "TestBlog" );
         m_testEngine.saveText( newPage, "!Title2\r\n__Bar__" );
 
-        RSSGenerator gen = m_testEngine.getRSSGenerator();
+        final RSSGenerator gen = m_testEngine.getRSSGenerator();
 
-        WikiContext context = new WikiContext( m_testEngine, m_testEngine.getPageManager().getPage("TestBlog") );
+        final WikiContext context = new WikiContext( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
 
-        WeblogPlugin blogplugin = new WeblogPlugin();
+        final WeblogPlugin blogplugin = new WeblogPlugin();
 
-        List< WikiPage > entries = blogplugin.findBlogEntries( m_testEngine,
+        final List< WikiPage > entries = blogplugin.findBlogEntries( m_testEngine,
                                                                "TestBlog",
                                                                new Date(0),
                                                                new Date(Long.MAX_VALUE) );
 
-        Feed feed = new RSS10Feed( context );
-        String blog = gen.generateBlogRSS( context, entries, feed );
+        final Feed feed = new RSS10Feed( context );
+        final String blog = gen.generateBlogRSS( context, entries, feed );
 
         Assertions.assertTrue( blog.indexOf("<description>Foo</description>") != -1, "has Foo" );
         Assertions.assertTrue( blog.indexOf("&lt;b&gt;Bar&lt;/b&gt;") != -1, "has proper Bar" );
@@ -96,7 +97,7 @@ public class RSSGeneratorTest {
     public void testBlogRSS2()
         throws Exception
     {
-        WeblogEntryPlugin plugin = new WeblogEntryPlugin();
+        final WeblogEntryPlugin plugin = new WeblogEntryPlugin();
         m_testEngine.saveText( "TestBlog", "Foo1" );
 
         String newPage = plugin.getNewEntryPage( m_testEngine, "TestBlog" );
@@ -105,19 +106,19 @@ public class RSSGeneratorTest {
         newPage = plugin.getNewEntryPage( m_testEngine, "TestBlog" );
         m_testEngine.saveText( newPage, "!Title2\r\n__Bar__" );
 
-        RSSGenerator gen = m_testEngine.getRSSGenerator();
+        final RSSGenerator gen = m_testEngine.getRSSGenerator();
 
-        WikiContext context = new WikiContext( m_testEngine, m_testEngine.getPageManager().getPage("TestBlog") );
+        final WikiContext context = new WikiContext( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
 
-        WeblogPlugin blogplugin = new WeblogPlugin();
+        final WeblogPlugin blogplugin = new WeblogPlugin();
 
-        List< WikiPage > entries = blogplugin.findBlogEntries( m_testEngine,
+        final List< WikiPage > entries = blogplugin.findBlogEntries( m_testEngine,
                                                                "TestBlog",
                                                                new Date(0),
                                                                new Date(Long.MAX_VALUE) );
 
-        Feed feed = new RSS20Feed( context );
-        String blog = gen.generateBlogRSS( context, entries, feed );
+        final Feed feed = new RSS20Feed( context );
+        final String blog = gen.generateBlogRSS( context, entries, feed );
 
         Assertions.assertTrue( blog.indexOf("<description>Foo &amp;quot;blah&amp;quot;.</description>") != -1, "has Foo" );
         Assertions.assertTrue( blog.indexOf("&lt;b&gt;Bar&lt;/b&gt;") != -1, "has proper Bar" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/search/SearchManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/search/SearchManagerTest.java
index cfed1dd..1f77ed2 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/search/SearchManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/search/SearchManagerTest.java
@@ -22,6 +22,7 @@ import net.sf.ehcache.CacheManager;
 import net.sourceforge.stripes.mock.MockHttpServletRequest;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.pages.PageManager;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -122,8 +123,8 @@ public class SearchManagerTest {
         final MockHttpServletRequest request = m_engine.newHttpRequest();
         request.getParameterMap().put( "page", new String[]{ "TestPage" } );
         final WikiContext ctx = new WikiContext( m_engine, request, WikiContext.EDIT );
-        m_engine.getPageManager().saveText( ctx, txt );
-        m_engine.getPageManager().saveText( ctx, "The Babylon Project was a dream given form. Its goal: to prevent another war by creating a place where humans and aliens could work out their differences peacefully." );
+        m_engine.getManager( PageManager.class ).saveText( ctx, txt );
+        m_engine.getManager( PageManager.class ).saveText( ctx, "The Babylon Project was a dream given form. Its goal: to prevent another war by creating a place where humans and aliens could work out their differences peacefully." );
 
         Collection< SearchResult > res = new ArrayList<>();
         Awaitility.await( "testSimpleSearch3" ).until( findsResultsFor( res, "Babylon" ) );
@@ -144,14 +145,14 @@ public class SearchManagerTest {
         final MockHttpServletRequest request = m_engine.newHttpRequest();
         request.getParameterMap().put( "page", new String[]{ "TestPage" } );
         final WikiContext ctx = new WikiContext( m_engine, request, WikiContext.EDIT );
-        m_engine.getPageManager().saveText( ctx, txt );
+        m_engine.getManager( PageManager.class ).saveText( ctx, txt );
 
         Collection< SearchResult > res = new ArrayList<>();
         Awaitility.await( "testSimpleSearch4" ).until( findsResultsFor( res, "mankind" ) );
 
         Assertions.assertEquals( 1, res.size(), "result not found" );
 
-        m_engine.getPageManager().saveText( ctx, "[{ALLOW view Authenticated}] It was the dawn of the third age of mankind... page is blocked" );
+        m_engine.getManager( PageManager.class ).saveText( ctx, "[{ALLOW view Authenticated}] It was the dawn of the third age of mankind... page is blocked" );
 
         res = m_mgr.findPages( "mankind" , ctx );
         Assertions.assertNotNull( res, "null result" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/stress/MassiveRepositoryTest.java b/jspwiki-main/src/test/java/org/apache/wiki/stress/MassiveRepositoryTest.java
index b6cbe09..e0d1db8 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/stress/MassiveRepositoryTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/stress/MassiveRepositoryTest.java
@@ -17,10 +17,12 @@
     under the License.  
  */
 package org.apache.wiki.stress;
+
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiProvider;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.FileSystemProvider;
 import org.apache.wiki.util.TextUtil;
 import org.junit.jupiter.api.AfterEach;
@@ -42,10 +44,10 @@ public class MassiveRepositoryTest {
     public void setUp() throws Exception {
 
 
-        String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
+        final String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
 
         // Remove file
-        File f = new File( files );
+        final File f = new File( files );
 
         TestEngine.deleteAll(f);
 
@@ -58,44 +60,44 @@ public class MassiveRepositoryTest {
     public void tearDown() throws Exception {
 
         
-        String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
+        final String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
 
         // Remove file
-        File f = new File( files );
+        final File f = new File( files );
 
         TestEngine.deleteAll(f);
     }
 
-    private String getName( int i ) {
-        String baseName = "Page";
+    private String getName( final int i ) {
+        final String baseName = "Page";
         return baseName + i;
     }
     
     @Test
     public void testMassiveRepositoryGettingAllPagesFromCache() throws Exception {
-        int    numPages = 900;
-        int    numRevisions = 900;
-        int    numRenders = 9000;
-        int    tickmarks  = 90;
+        final int    numPages = 900;
+        final int    numRevisions = 900;
+        final int    numRenders = 9000;
+        final int    tickmarks  = 90;
         
         stressTest( numPages, numRevisions, numRenders, tickmarks );
     }
     
     @Test
     public void testMassiveRepositoryBypassingCacheByHavingTooMuchPages() throws Exception {
-    	int    numPages = 1001;
-        int    numRevisions = 1001;
-        int    numRenders = 10001;
-        int    tickmarks  = 100;
+    	final int    numPages = 1001;
+        final int    numRevisions = 1001;
+        final int    numRenders = 10001;
+        final int    tickmarks  = 100;
         
         stressTest( numPages, numRevisions, numRenders, tickmarks );
     }
 
-	void stressTest( int numPages, int numRevisions, int numRenders, int tickmarks ) throws WikiException {
-		String baseText = "!This is a page %d\r\n\r\nX\r\n\r\nLinks to [%1], [%2], [%3], [%4], [%5], [%6], [%7], [%8], [%9], [%0]";
+	void stressTest( final int numPages, final int numRevisions, final int numRenders, final int tickmarks ) throws WikiException {
+		final String baseText = "!This is a page %d\r\n\r\nX\r\n\r\nLinks to [%1], [%2], [%3], [%4], [%5], [%6], [%7], [%8], [%9], [%0]";
         
-        Random random = new Random();
-        Benchmark sw = new Benchmark();
+        final Random random = new Random();
+        final Benchmark sw = new Benchmark();
         sw.start();
         
         System.out.println("Creating "+numPages+" pages");
@@ -107,7 +109,7 @@ public class MassiveRepositoryTest {
         
         for( int i = 0; i < numPages; i++ )
         {
-            String name = getName(i);
+            final String name = getName(i);
             String text = TextUtil.replaceString( baseText, "%d", name );
             
             for( int r = 0; r < 10; r++ )
@@ -132,9 +134,9 @@ public class MassiveRepositoryTest {
         
         for( int i = 0; i < numRevisions; i++ )
         {
-            String page = getName( random.nextInt( numPages ) );
+            final String page = getName( random.nextInt( numPages ) );
             
-            String content = engine.getPageManager().getPureText( page, WikiProvider.LATEST_VERSION );
+            String content = engine.getManager( PageManager.class ).getPureText( page, WikiProvider.LATEST_VERSION );
             
             content = TextUtil.replaceString( content, "X", "XX" );
             
@@ -145,7 +147,7 @@ public class MassiveRepositoryTest {
         
         System.out.println("\nTook "+sw.toString()+", which is "+sw.toString(numRevisions)+" adds/second");
         
-        Assertions.assertEquals( numPages, engine.getPageManager().getTotalPageCount(), "Right number of pages" );
+        Assertions.assertEquals( numPages, engine.getManager( PageManager.class ).getTotalPageCount(), "Right number of pages" );
         
         //
         //  Rendering random pages
@@ -159,9 +161,9 @@ public class MassiveRepositoryTest {
         
         for( int i = 0; i < numRenders; i++ )
         {
-            String page = getName( random.nextInt( numPages ) );
+            final String page = getName( random.nextInt( numPages ) );
             
-            String content = engine.getRenderingManager().getHTML( page, WikiProvider.LATEST_VERSION );
+            final String content = engine.getRenderingManager().getHTML( page, WikiProvider.LATEST_VERSION );
               
             Assertions.assertNotNull(content);
             
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/stress/StressTestVersioningProvider.java b/jspwiki-main/src/test/java/org/apache/wiki/stress/StressTestVersioningProvider.java
index 300fab6..4f31246 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/stress/StressTestVersioningProvider.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/stress/StressTestVersioningProvider.java
@@ -20,6 +20,7 @@ package org.apache.wiki.stress;
 
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.providers.FileSystemProvider;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -38,7 +39,7 @@ public class StressTestVersioningProvider {
     @AfterEach
     public void tearDown()
     {
-        String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
+        final String files = props.getProperty( FileSystemProvider.PROP_PAGEDIR );
 
         // Remove file
         File f = new File( files, NAME1+FileSystemProvider.FILE_EXT );
@@ -53,9 +54,9 @@ public class StressTestVersioningProvider {
         throws Exception
     {
         String text = "";
-        String name = NAME1;
-        int    maxver = 2000; // Save 2000 versions.
-        Benchmark mark = new Benchmark();
+        final String name = NAME1;
+        final int    maxver = 2000; // Save 2000 versions.
+        final Benchmark mark = new Benchmark();
 
         mark.start();
         for( int i = 0; i < maxver; i++ )
@@ -67,20 +68,20 @@ public class StressTestVersioningProvider {
         mark.stop();
 
         System.out.println("Benchmark: "+mark.toString(2000)+" pages/second");
-        WikiPage pageinfo = engine.getPageManager().getPage( NAME1 );
+        final WikiPage pageinfo = engine.getManager( PageManager.class ).getPage( NAME1 );
 
         Assertions.assertEquals( maxver, pageinfo.getVersion(), "wrong version" );
 
         // +2 comes from \r\n.
-        Assertions.assertEquals( maxver+2, engine.getPageManager().getText(NAME1).length(), "wrong text" );
+        Assertions.assertEquals( maxver+2, engine.getManager( PageManager.class ).getText(NAME1).length(), "wrong text" );
     }
 
-    private void runMassiveFileTest(int maxpages)
+    private void runMassiveFileTest( final int maxpages)
         throws Exception
     {
-        String text = "Testing, 1, 2, 3: ";
-        String name = NAME1;
-        Benchmark mark = new Benchmark();
+        final String text = "Testing, 1, 2, 3: ";
+        final String name = NAME1;
+        final Benchmark mark = new Benchmark();
 
         System.out.println("Building a massive repository of "+maxpages+" pages...");
 
@@ -97,7 +98,7 @@ public class StressTestVersioningProvider {
         mark.reset();
 
         mark.start();
-        Collection< WikiPage > pages = engine.getPageManager().getAllPages();
+        final Collection< WikiPage > pages = engine.getManager( PageManager.class ).getAllPages();
         mark.stop();
 
         System.out.println("Got a list of all pages in "+mark);
@@ -105,8 +106,8 @@ public class StressTestVersioningProvider {
         mark.reset();
         mark.start();
 
-        for( WikiPage page : pages ) {
-            String foo = engine.getPageManager().getPureText( page );
+        for( final WikiPage page : pages ) {
+            final String foo = engine.getManager( PageManager.class ).getPureText( page );
             Assertions.assertNotNull( foo );
         }
         mark.stop();
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/ui/CommandResolverTest.java b/jspwiki-main/src/test/java/org/apache/wiki/ui/CommandResolverTest.java
index 634bc7d..192aba2 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/ui/CommandResolverTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/ui/CommandResolverTest.java
@@ -28,6 +28,7 @@ import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.auth.GroupPrincipal;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -52,8 +53,8 @@ public class CommandResolverTest {
 
     @AfterEach
     public void tearDown() throws Exception {
-        m_engine.getPageManager().deletePage( "SinglePage" );
-        m_engine.getPageManager().deletePage( "PluralPage" );
+        m_engine.getManager( PageManager.class ).deletePage( "SinglePage" );
+        m_engine.getManager( PageManager.class ).deletePage( "PluralPage" );
     }
 
     @Test
@@ -124,7 +125,7 @@ public class CommandResolverTest {
 
     @Test
     public void testFindWikiActionWithParams() {
-        final WikiPage page = m_engine.getPageManager().getPage( "SinglePage" );
+        final WikiPage page = m_engine.getManager( PageManager.class ).getPage( "SinglePage" );
 
         // Passing an EDIT request with page param yields a wrapped action
         MockHttpServletRequest request = m_engine.newHttpRequest( "/Edit.jsp?page=SinglePage" );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/ui/PageCommandTest.java b/jspwiki-main/src/test/java/org/apache/wiki/ui/PageCommandTest.java
index 5e222d9..483713d 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/ui/PageCommandTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/ui/PageCommandTest.java
@@ -25,6 +25,7 @@ package org.apache.wiki.ui;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.auth.permissions.PermissionFactory;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -64,7 +65,7 @@ public class PageCommandTest {
     public void testTargetedCommand() throws Exception {
         final TestEngine testEngine = TestEngine.build();
         testEngine.saveText( "TestPage", "This is a test." );
-        final WikiPage testPage = testEngine.getPageManager().getPage( "TestPage" );
+        final WikiPage testPage = testEngine.getManager( PageManager.class ).getPage( "TestPage" );
 
         // Get view command
         Command a = PageCommand.VIEW;
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java b/jspwiki-main/src/test/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java
index a149a57..a55abea 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java
@@ -26,6 +26,7 @@ import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.api.filters.BasicPageFilter;
 import org.apache.wiki.auth.Users;
 import org.apache.wiki.auth.WikiPrincipal;
+import org.apache.wiki.pages.PageManager;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -45,7 +46,7 @@ public class ApprovalWorkflowTest {
     @BeforeEach
     public void setUp() throws Exception
     {
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
 
         // Explicitly turn on Admin approvals for page saves and our sample approval workflow
         props.put("jspwiki.approver.workflow.saveWikiPage", "Admin");
@@ -63,18 +64,18 @@ public class ApprovalWorkflowTest {
     public void testBuildApprovalWorkflow() throws WikiException
     {
 
-        Principal submitter = new WikiPrincipal( "Submitter" );
-        String workflowApproverKey = "workflow.approvalWorkflow";
-        Task prepTask = new TestPrepTask( "task.preSaveWikiPage" );
-        String decisionKey = "decision.saveWikiPage";
-        Fact[] facts = new Fact[3];
-        facts[0] = new Fact("fact1",new Integer(1));
+        final Principal submitter = new WikiPrincipal( "Submitter" );
+        final String workflowApproverKey = "workflow.approvalWorkflow";
+        final Task prepTask = new TestPrepTask( "task.preSaveWikiPage" );
+        final String decisionKey = "decision.saveWikiPage";
+        final Fact[] facts = new Fact[3];
+        facts[0] = new Fact("fact1",Integer.valueOf( 1 ) );
         facts[1] = new Fact("fact2","A factual String");
         facts[2] = new Fact("fact3",Outcome.DECISION_ACKNOWLEDGE);
-        Task completionTask = new TestPrepTask( "task.saveWikiPage" );
-        String rejectedMessageKey = "notification.saveWikiPage.reject";
+        final Task completionTask = new TestPrepTask( "task.saveWikiPage" );
+        final String rejectedMessageKey = "notification.saveWikiPage.reject";
 
-        Workflow w = m_builder.buildApprovalWorkflow(submitter, workflowApproverKey,
+        final Workflow w = m_builder.buildApprovalWorkflow(submitter, workflowApproverKey,
                                                    prepTask, decisionKey, facts,
                                                    completionTask, rejectedMessageKey);
         w.setWorkflowManager( m_engine.getWorkflowManager() );
@@ -96,7 +97,7 @@ public class ApprovalWorkflowTest {
         w.start();
 
         // Presave complete attribute should be set now, and current step should be Decision
-        Step decision = w.getCurrentStep();
+        final Step decision = w.getCurrentStep();
         Assertions.assertTrue( decision instanceof Decision );
         Assertions.assertEquals( 2, w.getHistory().size() );
         Assertions.assertEquals( prepTask, w.getHistory().get( 0 ) );
@@ -104,7 +105,7 @@ public class ApprovalWorkflowTest {
         Assertions.assertNotNull( w.getAttribute( "task.preSaveWikiPage") );
         Assertions.assertEquals( new WikiPrincipal( Users.JANNE ), decision.getActor() );
         Assertions.assertEquals( decisionKey, decision.getMessageKey() );
-        List< Fact > decisionFacts = ((Decision)decision).getFacts();
+        final List< Fact > decisionFacts = ((Decision)decision).getFacts();
         Assertions.assertEquals( 3, decisionFacts.size() );
         Assertions.assertEquals( facts[0], decisionFacts.get(0) );
         Assertions.assertEquals( facts[1], decisionFacts.get(1) );
@@ -120,7 +121,7 @@ public class ApprovalWorkflowTest {
         Assertions.assertEquals( completionTask, decision.getSuccessor( Outcome.DECISION_APPROVE ) );
 
         // The "deny" notification should use the right key
-        Step notification = decision.getSuccessor( Outcome.DECISION_DENY );
+        final Step notification = decision.getSuccessor( Outcome.DECISION_DENY );
         Assertions.assertNotNull( notification );
         Assertions.assertEquals( rejectedMessageKey, notification.getMessageKey() );
         Assertions.assertTrue( notification instanceof SimpleNotification );
@@ -138,18 +139,18 @@ public class ApprovalWorkflowTest {
     @Test
     public void testBuildApprovalWorkflowDeny() throws WikiException
     {
-        Principal submitter = new WikiPrincipal( "Submitter" );
-        String workflowApproverKey = "workflow.approvalWorkflow";
-        Task prepTask = new TestPrepTask( "task.preSaveWikiPage" );
-        String decisionKey = "decision.saveWikiPage";
-        Fact[] facts = new Fact[3];
+        final Principal submitter = new WikiPrincipal( "Submitter" );
+        final String workflowApproverKey = "workflow.approvalWorkflow";
+        final Task prepTask = new TestPrepTask( "task.preSaveWikiPage" );
+        final String decisionKey = "decision.saveWikiPage";
+        final Fact[] facts = new Fact[3];
         facts[0] = new Fact("fact1",new Integer(1));
         facts[1] = new Fact("fact2","A factual String");
         facts[2] = new Fact("fact3",Outcome.DECISION_ACKNOWLEDGE);
-        Task completionTask = new TestPrepTask( "task.saveWikiPage" );
-        String rejectedMessageKey = "notification.saveWikiPage.reject";
+        final Task completionTask = new TestPrepTask( "task.saveWikiPage" );
+        final String rejectedMessageKey = "notification.saveWikiPage.reject";
 
-        Workflow w = m_builder.buildApprovalWorkflow(submitter, workflowApproverKey,
+        final Workflow w = m_builder.buildApprovalWorkflow(submitter, workflowApproverKey,
                                                    prepTask, decisionKey, facts,
                                                    completionTask, rejectedMessageKey);
         w.setWorkflowManager( m_engine.getWorkflowManager() );
@@ -160,7 +161,7 @@ public class ApprovalWorkflowTest {
         // Now, deny the Decision and the submitter should see a notification
         Step step = w.getCurrentStep();
         Assertions.assertTrue( step instanceof Decision );
-        Decision decision = (Decision)step;
+        final Decision decision = (Decision)step;
         decision.decide( Outcome.DECISION_DENY );
         Assertions.assertFalse( w.isCompleted() );
 
@@ -168,7 +169,7 @@ public class ApprovalWorkflowTest {
         step = w.getCurrentStep();
         Assertions.assertTrue( step instanceof SimpleNotification );
         Assertions.assertEquals( rejectedMessageKey, step.getMessageKey() );
-        SimpleNotification notification = (SimpleNotification)step;
+        final SimpleNotification notification = (SimpleNotification)step;
         notification.acknowledge();
 
         // Workflow should be complete now
@@ -182,52 +183,52 @@ public class ApprovalWorkflowTest {
     public void testSaveWikiPageWithApproval() throws WikiException
     {
         // Create a sample test page and try to save it
-        String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
-        String text = "This is a test!";
+        final String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
+        final String text = "This is a test!";
         try
         {
             m_engine.saveTextAsJanne(pageName, text);
         }
-        catch ( DecisionRequiredException e )
+        catch ( final DecisionRequiredException e )
         {
             // Swallow exception, because it is expected...
         }
 
         // How do we know the workflow works? Well, first of all the page shouldn't exist yet...
-        Assertions.assertFalse( m_engine.getPageManager().wikiPageExists(pageName));
+        Assertions.assertFalse( m_engine.getManager( PageManager.class ).wikiPageExists(pageName));
 
         // Second, GroupPrincipal Admin should see a Decision in its queue
         Collection< Decision > decisions = m_dq.getActorDecisions( m_engine.adminSession() );
         Assertions.assertEquals(1, decisions.size());
 
         // Now, approve the decision and it should go away, and page should appear.
-        Decision decision = (Decision)decisions.iterator().next();
+        final Decision decision = (Decision)decisions.iterator().next();
         decision.decide(Outcome.DECISION_APPROVE);
-        Assertions.assertTrue( m_engine.getPageManager().wikiPageExists(pageName));
+        Assertions.assertTrue( m_engine.getManager( PageManager.class ).wikiPageExists(pageName));
         decisions = m_dq.getActorDecisions( m_engine.adminSession() );
         Assertions.assertEquals(0, decisions.size());
 
         // Delete the page we created
-        m_engine.getPageManager().deletePage( pageName );
+        m_engine.getManager( PageManager.class ).deletePage( pageName );
     }
 
     @Test
     public void testSaveWikiPageWithRejection() throws WikiException
     {
         // Create a sample test page and try to save it
-        String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
-        String text = "This is a test!";
+        final String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
+        final String text = "This is a test!";
         try
         {
             m_engine.saveTextAsJanne(pageName, text);
         }
-        catch ( DecisionRequiredException e )
+        catch ( final DecisionRequiredException e )
         {
             // Swallow exception, because it is expected...
         }
 
         // How do we know the workflow works? Well, first of all the page shouldn't exist yet...
-        Assertions.assertFalse( m_engine.getPageManager().wikiPageExists(pageName));
+        Assertions.assertFalse( m_engine.getManager( PageManager.class ).wikiPageExists(pageName));
 
         // ...and there should be a Decision in GroupPrincipal Admin's queue
         Collection< Decision > decisions = m_dq.getActorDecisions( m_engine.adminSession() );
@@ -236,7 +237,7 @@ public class ApprovalWorkflowTest {
         // Now, DENY the decision and the page should still not exist...
         Decision decision = (Decision)decisions.iterator().next();
         decision.decide(Outcome.DECISION_DENY);
-        Assertions.assertFalse( m_engine.getPageManager().wikiPageExists(pageName) );
+        Assertions.assertFalse( m_engine.getManager( PageManager.class ).wikiPageExists(pageName) );
 
         // ...but there should also be a notification decision in Janne's queue
         decisions = m_dq.getActorDecisions( m_engine.janneSession() );
@@ -254,17 +255,17 @@ public class ApprovalWorkflowTest {
     public void testSaveWikiPageWithException() throws WikiException
     {
         // Add a PageFilter that rejects all save attempts
-        FilterManager fm = m_engine.getFilterManager();
+        final FilterManager fm = m_engine.getFilterManager();
         fm.addPageFilter( new AbortFilter(), 0 );
 
         // Create a sample test page and try to save it
-        String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
-        String text = "This is a test!";
+        final String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
+        final String text = "This is a test!";
         try
         {
             m_engine.saveTextAsJanne(pageName, text);
         }
-        catch ( WikiException e )
+        catch ( final WikiException e )
         {
             Assertions.assertTrue( e instanceof FilterException );
             Assertions.assertEquals( "Page save aborted.", e.getMessage() );
@@ -281,12 +282,12 @@ public class ApprovalWorkflowTest {
     {
         private static final long serialVersionUID = 1L;
 
-        public TestPrepTask( String messageKey )
+        public TestPrepTask( final String messageKey )
         {
             super( messageKey );
         }
 
-        public Outcome execute() throws WikiException
+        @Override public Outcome execute() throws WikiException
         {
             getWorkflow().setAttribute( getMessageKey(), "Completed" );
             setOutcome( Outcome.STEP_COMPLETE );
@@ -300,7 +301,7 @@ public class ApprovalWorkflowTest {
      */
     public static class AbortFilter extends BasicPageFilter
     {
-        public String preSave(WikiContext wikiContext, String content) throws FilterException
+        @Override public String preSave( final WikiContext wikiContext, final String content) throws FilterException
         {
             throw new FilterException( "Page save aborted." );
         }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/xmlrpc/RPCHandlerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/xmlrpc/RPCHandlerTest.java
index 3ed8c2d..e8902d1 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/xmlrpc/RPCHandlerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/xmlrpc/RPCHandlerTest.java
@@ -24,6 +24,7 @@ import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
 import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.pages.PageManager;
 import org.apache.xmlrpc.XmlRpcException;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -52,7 +53,7 @@ public class RPCHandlerTest
         m_engine = new TestEngine( m_props );
 
         m_handler = new RPCHandler();
-        WikiContext ctx = new WikiContext( m_engine, new WikiPage(m_engine, "Dummy") );
+        final WikiContext ctx = new WikiContext( m_engine, new WikiPage(m_engine, "Dummy") );
         m_handler.initialize( ctx );
     }
 
@@ -72,7 +73,7 @@ public class RPCHandlerTest
             m_handler.getPage( "NoSuchPage" );
             Assertions.fail("No exception for missing page.");
         }
-        catch( XmlRpcException e )
+        catch( final XmlRpcException e )
         {
             Assertions.assertEquals( RPCHandler.ERR_NOPAGE, e.code, "Wrong error code." );
         }
@@ -83,12 +84,12 @@ public class RPCHandlerTest
         throws Exception
     {
         Date time = getCalendarTime( Calendar.getInstance().getTime() );
-        Vector previousChanges = m_handler.getRecentChanges( time );
+        final Vector previousChanges = m_handler.getRecentChanges( time );
 
         m_engine.saveText( NAME1, "Foo" );
-        WikiPage directInfo = m_engine.getPageManager().getPage( NAME1 );
+        final WikiPage directInfo = m_engine.getManager( PageManager.class ).getPage( NAME1 );
         time = getCalendarTime( directInfo.getLastModified() );
-        Vector recentChanges = m_handler.getRecentChanges( time );
+        final Vector recentChanges = m_handler.getRecentChanges( time );
 
         Assertions.assertEquals( 1, recentChanges.size() - previousChanges.size(), "wrong number of changes" );
     }
@@ -98,15 +99,15 @@ public class RPCHandlerTest
         throws Exception
     {
         Date time = getCalendarTime( Calendar.getInstance().getTime() );
-        Vector previousChanges = m_handler.getRecentChanges( time );
+        final Vector previousChanges = m_handler.getRecentChanges( time );
 
         m_engine.saveText( NAME1, "Foo" );
-        Attachment att = new Attachment( m_engine, NAME1, "TestAtt.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
         m_engine.getAttachmentManager().storeAttachment( att, m_engine.makeAttachmentFile() );
-        WikiPage directInfo = m_engine.getPageManager().getPage( NAME1 );
+        final WikiPage directInfo = m_engine.getManager( PageManager.class ).getPage( NAME1 );
         time = getCalendarTime( directInfo.getLastModified() );
-        Vector recentChanges = m_handler.getRecentChanges( time );
+        final Vector recentChanges = m_handler.getRecentChanges( time );
 
         Assertions.assertEquals( 1, recentChanges.size() - previousChanges.size(), "wrong number of changes" );
     }
@@ -116,14 +117,14 @@ public class RPCHandlerTest
         throws Exception
     {
         m_engine.saveText( NAME1, "Foobar.[{ALLOW view Anonymous}]" );
-        WikiPage directInfo = m_engine.getPageManager().getPage( NAME1 );
+        final WikiPage directInfo = m_engine.getManager( PageManager.class ).getPage( NAME1 );
 
-        Hashtable ht = m_handler.getPageInfo( NAME1 );
+        final Hashtable ht = m_handler.getPageInfo( NAME1 );
         Assertions.assertEquals( (String)ht.get( "name" ), NAME1, "name" );
 
-        Date d = (Date) ht.get( "lastModified" );
+        final Date d = (Date) ht.get( "lastModified" );
 
-        Calendar cal = Calendar.getInstance();
+        final Calendar cal = Calendar.getInstance();
         cal.setTime( d );
 
         // System.out.println("Real: "+directInfo.getLastModified() );
@@ -146,16 +147,16 @@ public class RPCHandlerTest
     public void testListLinks()
         throws Exception
     {
-        String text = "[Foobar]";
-        String pageName = NAME1;
+        final String text = "[Foobar]";
+        final String pageName = NAME1;
 
         m_engine.saveText( pageName, text );
 
-        Vector links = m_handler.listLinks( pageName );
+        final Vector links = m_handler.listLinks( pageName );
 
         Assertions.assertEquals( 1, links.size(), "link count" );
 
-        Hashtable linkinfo = (Hashtable) links.elementAt(0);
+        final Hashtable linkinfo = (Hashtable) links.elementAt(0);
 
         Assertions.assertEquals( "Foobar", linkinfo.get("page"), "name" );
         Assertions.assertEquals( "local",  linkinfo.get("type"), "type" );
@@ -167,18 +168,18 @@ public class RPCHandlerTest
     public void testListLinksWithAttachments()
         throws Exception
     {
-        String text = "[Foobar] [Test/TestAtt.txt]";
-        String pageName = NAME1;
+        final String text = "[Foobar] [Test/TestAtt.txt]";
+        final String pageName = NAME1;
 
         m_engine.saveText( pageName, text );
 
-        Attachment att = new Attachment( m_engine, NAME1, "TestAtt.txt" );
+        final Attachment att = new Attachment( m_engine, NAME1, "TestAtt.txt" );
         att.setAuthor( "FirstPost" );
         m_engine.getAttachmentManager().storeAttachment( att, m_engine.makeAttachmentFile() );
 
         // Test.
 
-        Vector links = m_handler.listLinks( pageName );
+        final Vector links = m_handler.listLinks( pageName );
 
         Assertions.assertEquals( 2, links.size(), "link count" );
 
@@ -195,9 +196,9 @@ public class RPCHandlerTest
         Assertions.assertEquals( "/test/attach/"+NAME1+"/TestAtt.txt", linkinfo.get("href"), "att href" );
     }
 
-    private Date getCalendarTime( Date modifiedDate )
+    private Date getCalendarTime( final Date modifiedDate )
     {
-        Calendar cal = Calendar.getInstance();
+        final Calendar cal = Calendar.getInstance();
         cal.setTime( modifiedDate );
         cal.add( Calendar.HOUR, -1 );
 


[jspwiki] 28/38: JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (5)

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 1433993221e37dc38d7846dfcb78671f524ea0bd
Author: juanpablo <ju...@apache.org>
AuthorDate: Mon Feb 24 17:12:32 2020 +0100

    JSPWIKI-120: propagate WikiContext#getEngine() now returns Engine instead of WikiEngine (5)
---
 .../main/webapp/templates/default/AttachmentTab.jsp  |  2 +-
 .../src/main/webapp/templates/default/DiffTab.jsp    | 12 +++++++-----
 .../src/main/webapp/templates/default/GroupTab.jsp   |  5 +++--
 .../main/webapp/templates/default/InfoContent.jsp    |  8 +++++---
 .../main/webapp/templates/default/LoginContent.jsp   |  9 +++------
 .../src/main/webapp/templates/default/Nav.jsp        | 11 ++++++-----
 .../src/main/webapp/templates/default/PageTab.jsp    |  6 +++---
 .../main/webapp/templates/default/PreferencesTab.jsp | 11 +++++------
 .../src/main/webapp/templates/default/ProfileTab.jsp |  2 +-
 .../webapp/templates/default/editors/CKeditor.jsp    | 20 +++++++++++---------
 .../webapp/templates/default/editors/TinyMCE.jsp     | 20 +++++++++++---------
 .../main/webapp/templates/default/editors/plain.jsp  | 16 +++++++++-------
 .../webapp/templates/default/editors/wysiwyg.jsp     | 20 +++++++++++---------
 13 files changed, 76 insertions(+), 66 deletions(-)

diff --git a/jspwiki-war/src/main/webapp/templates/default/AttachmentTab.jsp b/jspwiki-war/src/main/webapp/templates/default/AttachmentTab.jsp
index 634df52..84bd19f 100644
--- a/jspwiki-war/src/main/webapp/templates/default/AttachmentTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/AttachmentTab.jsp
@@ -32,7 +32,7 @@
   int MAXATTACHNAMELENGTH = 30;
   WikiContext c = WikiContext.findContext(pageContext);
 %>
-<c:set var="progressId" value="<%= c.getEngine().getProgressManager().getNewProgressIdentifier() %>" />
+<c:set var="progressId" value="<%= c.getEngine().getManager( ProgressManager.class ).getNewProgressIdentifier() %>" />
 <div class="page-content">
 <wiki:Permission permission="upload">
 
diff --git a/jspwiki-war/src/main/webapp/templates/default/DiffTab.jsp b/jspwiki-war/src/main/webapp/templates/default/DiffTab.jsp
index d88f3ef..46e3741 100644
--- a/jspwiki-war/src/main/webapp/templates/default/DiffTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/DiffTab.jsp
@@ -17,20 +17,22 @@
     under the License.
 --%>
 
-<%@ page import="org.apache.wiki.tags.InsertDiffTag" %>
-<%@ page import="org.apache.wiki.*" %>
 <%@ page import="java.util.*" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
+<%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+<%@ page import="org.apache.wiki.tags.InsertDiffTag" %>
+<%@ page import="org.apache.wiki.variables.VariableManager" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
 %>
-<c:set var="history" value="<%= c.getEngine().getPageManager().getVersionHistory(c.getPage().getName()) %>" />
-<c:set var="diffprovider" value='<%= c.getEngine().getVariableManager().getVariable(c,"jspwiki.diffProvider") %>' />
+<c:set var="history" value="<%= c.getEngine().getManager( PageManager.class ).getVersionHistory(c.getPage().getName()) %>" />
+<c:set var="diffprovider" value='<%= c.getEngine().getManager( VariableManager.class ).getVariable(c,"jspwiki.diffProvider") %>' />
 <wiki:PageExists>
 <form action="<wiki:Link jsp='Diff.jsp' format='url' />"
        class="diffbody form-inline"
diff --git a/jspwiki-war/src/main/webapp/templates/default/GroupTab.jsp b/jspwiki-war/src/main/webapp/templates/default/GroupTab.jsp
index 98bf0fb..a497f48 100644
--- a/jspwiki-war/src/main/webapp/templates/default/GroupTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/GroupTab.jsp
@@ -25,6 +25,7 @@
 <%@ page import="org.apache.wiki.auth.AuthorizationManager" %>
 <%@ page import="org.apache.wiki.auth.PrincipalComparator" %>
 <%@ page import="org.apache.wiki.auth.authorize.Group" %>
+<%@ page import="org.apache.wiki.auth.authorize.GroupManager" %>
 <%@ page import="org.apache.wiki.auth.permissions.GroupPermission" %>
 <%@ page import="org.apache.wiki.auth.authorize.GroupManager" %>
 <%@ page import="org.apache.wiki.preferences.Preferences" %>
@@ -43,8 +44,8 @@
   //String name = request.getParameter( "group" );
   //Group group = (Group)pageContext.getAttribute( "Group",PageContext.REQUEST_SCOPE );
 
-  AuthorizationManager authMgr = c.getEngine().getAuthorizationManager();
-  GroupManager groupMgr = c.getEngine().getGroupManager();
+  AuthorizationManager authMgr = c.getEngine().getManager( AuthorizationManager.class );
+  GroupManager groupMgr = c.getEngine().getManager( GroupManager.class );
 
   Principal[] groups = groupMgr.getRoles();
   Arrays.sort( groups, new PrincipalComparator() );
diff --git a/jspwiki-war/src/main/webapp/templates/default/InfoContent.jsp b/jspwiki-war/src/main/webapp/templates/default/InfoContent.jsp
index 3575a83..d9a5bef 100644
--- a/jspwiki-war/src/main/webapp/templates/default/InfoContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/InfoContent.jsp
@@ -22,7 +22,9 @@
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.attachment.*" %>
 <%@ page import="org.apache.wiki.i18n.InternationalizationManager" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.preferences.Preferences" %>
+<%@ page import="org.apache.wiki.ui.progress.ProgressManager" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="java.security.Permission" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
@@ -35,14 +37,14 @@
 <%
   WikiContext c = WikiContext.findContext(pageContext);
   WikiPage wikiPage = c.getPage();
-  int attCount = c.getEngine().getAttachmentManager().listAttachments( c.getPage() ).size();
+  int attCount = c.getEngine().getManager( AttachmentManager.class ).listAttachments( c.getPage() ).size();
   String attTitle = LocaleSupport.getLocalizedMessage(pageContext, "attach.tab");
   if( attCount != 0 ) attTitle += " (" + attCount + ")";
 
   String creationAuthor ="";
 
   //FIXME -- seems not to work correctly for attachments !!
-  WikiPage firstPage = c.getEngine().getPageManager().getPage( wikiPage.getName(), 1 );
+  WikiPage firstPage = c.getEngine().getManager( PageManager.class ).getPage( wikiPage.getName(), 1 );
   if( firstPage != null )
   {
     creationAuthor = firstPage.getAuthor();
@@ -249,7 +251,7 @@
 <%
   int MAXATTACHNAMELENGTH = 30;
 %>
-<c:set var="progressId" value="<%= c.getEngine().getProgressManager().getNewProgressIdentifier() %>" />
+<c:set var="progressId" value="<%= c.getEngine().getManager( ProgressManager.class ).getNewProgressIdentifier() %>" />
 <wiki:Permission permission="upload">
 
   <form action="<wiki:Link jsp='attach' format='url'><wiki:Param name='progressid' value='${progressId}'/></wiki:Link>"
diff --git a/jspwiki-war/src/main/webapp/templates/default/LoginContent.jsp b/jspwiki-war/src/main/webapp/templates/default/LoginContent.jsp
index 5c2f50e..f0d0db9 100644
--- a/jspwiki-war/src/main/webapp/templates/default/LoginContent.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/LoginContent.jsp
@@ -29,15 +29,12 @@
 <fmt:setBundle basename="templates.default"/>
 <%
     WikiContext ctx = WikiContext.findContext( pageContext );
-    AuthenticationManager mgr = ctx.getEngine().getAuthenticationManager();
+    AuthenticationManager mgr = ctx.getEngine().getManager( AuthenticationManager.class );
     String loginURL = "";
 
-    if( mgr.isContainerAuthenticated() )
-    {
+    if( mgr.isContainerAuthenticated() ) {
         loginURL = "j_security_check";
-    }
-    else
-    {
+    } else {
         String redir = (String)ctx.getVariable("redirect");
         if( redir == null ) redir = ctx.getEngine().getFrontPage();
         loginURL = ctx.getURL( WikiContext.LOGIN, redir );
diff --git a/jspwiki-war/src/main/webapp/templates/default/Nav.jsp b/jspwiki-war/src/main/webapp/templates/default/Nav.jsp
index a064b13..35e43b1 100644
--- a/jspwiki-war/src/main/webapp/templates/default/Nav.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/Nav.jsp
@@ -17,26 +17,27 @@
     under the License.
 --%>
 
-<%@ page import="org.apache.wiki.*" %>
 <%@ page import="java.util.StringTokenizer" %>
-
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
+<%@ page import="org.apache.wiki.*" %>
 <%@ page import="org.apache.wiki.attachment.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
 
-  String text = c.getEngine().getPageManager().getText( c.getPage() );
+  String text = c.getEngine().getManager( PageManager.class ).getText( c.getPage() );
   StringTokenizer tokens = new StringTokenizer( text );
   //avg reading speeds: https://iovs.arvojournals.org/article.aspx?articleid=2166061
 
 %>
-<c:set var="attachments" value="<%= c.getEngine().getAttachmentManager().listAttachments( c.getPage() ).size() %>" />
+<c:set var="attachments" value="<%= c.getEngine().getManager( AttachmentManager.class ).listAttachments( c.getPage() ).size() %>" />
 
 <c:set var="wordCount" value="<%= tokens.countTokens() %>" />
 <c:set var="readingTime" value="${wordCount / 228}" />
diff --git a/jspwiki-war/src/main/webapp/templates/default/PageTab.jsp b/jspwiki-war/src/main/webapp/templates/default/PageTab.jsp
index 1a17317..6917a73 100644
--- a/jspwiki-war/src/main/webapp/templates/default/PageTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/PageTab.jsp
@@ -18,6 +18,7 @@
 --%>
 
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
@@ -34,14 +35,13 @@
 </c:when>
 <c:otherwise>
 
-<%-- If the page is an older version, then offer a note and a possibility
-     to restore this version as the latest one. --%>
+<%-- If the page is an older version, then offer a note and a possibility to restore this version as the latest one. --%>
 <wiki:CheckVersion mode="notlatest">
   <%
     WikiContext c = WikiContext.findContext( pageContext );
   %>
   <c:set var="thisVersion" value="<%= c.getPage().getVersion() %>" />
-  <c:set var="latestVersion" value="<%= c.getEngine().getPageManager().getPage( c.getPage().getName(), WikiProvider.LATEST_VERSION ).getVersion() %>" />
+  <c:set var="latestVersion" value="<%= c.getEngine().getManager( PageManager.class ).getPage( c.getPage().getName(), WikiProvider.LATEST_VERSION ).getVersion() %>" />
 
   <form action="<wiki:Link format='url' jsp='Wiki.jsp'/>"
         method="get"  accept-charset='UTF-8'>
diff --git a/jspwiki-war/src/main/webapp/templates/default/PreferencesTab.jsp b/jspwiki-war/src/main/webapp/templates/default/PreferencesTab.jsp
index 0612f5b..5dd87b1 100644
--- a/jspwiki-war/src/main/webapp/templates/default/PreferencesTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/PreferencesTab.jsp
@@ -18,29 +18,28 @@
 --%>
 
 <%@ page errorPage="/Error.jsp" %>
-<%@ page import="java.util.*" %>
-<%@ page import="java.lang.*" %>
-<%@ page import="org.apache.wiki.*" %>
 <%@ page import="java.io.*" %>
+<%@ page import="java.util.*" %>
 <%@ page import="java.util.jar.*" %>
+<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
+<%@ page import="org.apache.wiki.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.preferences.*" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
-<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
 <fmt:setLocale value="${prefs.Language}" />
 <fmt:setBundle basename="templates.default"/>
 <%
   WikiContext c = WikiContext.findContext( pageContext );
-  TemplateManager t = c.getEngine().getTemplateManager();
+  TemplateManager t = c.getEngine().getManager( TemplateManager.class );
 %>
 <c:set var="skins"       value="<%= t.listSkins(pageContext, c.getTemplate() ) %>" />
 <c:set var="languages"   value="<%= t.listLanguages(pageContext) %>" />
 <c:set var="timezones"   value="<%= t.listTimeZones(pageContext) %>" />
 <c:set var="timeformats" value="<%= t.listTimeFormats(pageContext) %>" />
-<c:set var="editors"     value="<%= c.getEngine().getEditorManager().getEditorList() %>" />
+<c:set var="editors"     value="<%= c.getEngine().getManager( EditorManager.class ).getEditorList() %>" />
 <c:set var="redirect"><wiki:Variable var='redirect' default='<%=c.getEngine().getFrontPage() %>' /></c:set>
 
 <form action="<wiki:Link jsp='UserPreferences.jsp' format='url'><wiki:Param name='tab' value='prefs'/></wiki:Link>"
diff --git a/jspwiki-war/src/main/webapp/templates/default/ProfileTab.jsp b/jspwiki-war/src/main/webapp/templates/default/ProfileTab.jsp
index 927ed10..ff11b62 100644
--- a/jspwiki-war/src/main/webapp/templates/default/ProfileTab.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/ProfileTab.jsp
@@ -30,7 +30,7 @@
 <%
   /* dateformatting not yet supported by wiki:UserProfile tag - diy */
   WikiContext wikiContext = WikiContext.findContext(pageContext);
-  UserManager manager = wikiContext.getEngine().getUserManager();
+  UserManager manager = wikiContext.getEngine().getManager( UserManager.class );
   UserProfile profile = manager.getUserProfile( wikiContext.getWikiSession() );
 %>
 <form method="post" accept-charset="UTF-8"
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
index c292043..bc229c6 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
@@ -20,11 +20,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.lang3.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -39,7 +41,7 @@
 --%>
 <%
     WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
 
     /* local download of CKeditor */
     TemplateManager.addResourceRequest( context, TemplateManager.RESOURCE_SCRIPT,
@@ -67,17 +69,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -88,7 +90,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -98,7 +100,7 @@
     String pageAsHtml;
     try
     {
-        pageAsHtml = engine.getRenderingManager().getHTML( context, usertext );
+        pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
     }
         catch( Exception e )
     {
@@ -118,7 +120,7 @@
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
    /*FFS not used
-   String templateDir = (String)copyOfWikiProperties.get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)copyOfWikiProperties.get( Engine.PROP_TEMPLATEDIR );
 
    String protocol = "http://";
    if( request.isSecure() )
@@ -209,7 +211,7 @@
       </ul>
     </div>
 
-    <c:set var="editors" value="<%= engine.getEditorManager().getEditorList() %>" />
+    <c:set var="editors" value="<%= engine.getManager( EditorManager.class ).getEditorList() %>" />
     <c:if test='${fn:length(editors)>1}'>
    <div class="btn-group config">
       <%-- note: 'dropdown-toggle' is only here to style the last button properly! --%>
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
index 106f3d9..515fba0 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
@@ -21,11 +21,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.lang3.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -45,7 +47,7 @@
 --%>
 <%
     WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
 
     context.setVariable( WikiContext.VAR_WYSIWYG_EDITOR_MODE, Boolean.TRUE );
     context.setVariable( VariableManager.VAR_RUNFILTERS,  "false" );
@@ -65,17 +67,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -86,7 +88,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -96,7 +98,7 @@
     String pageAsHtml;
     try
     {
-        pageAsHtml = engine.getRenderingManager().getHTML( context, usertext );
+        pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
 
     }
         catch( Exception e )
@@ -119,7 +121,7 @@
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
    /*FSS not used
-   String templateDir = (String)engine.getWikiProperties().get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)engine.getWikiProperties().get( Engine.PROP_TEMPLATEDIR );
    String protocol = "http://";
    if( request.isSecure() )
    {
@@ -209,7 +211,7 @@
       </ul>
     </div>
 
-    <c:set var="editors" value="<%= engine.getEditorManager().getEditorList() %>" />
+    <c:set var="editors" value="<%= engine.getManager( EditorManager.class ).getEditorList() %>" />
     <c:if test='${fn:length(editors)>1}'>
    <div class="btn-group config">
       <%-- note: 'dropdown-toggle' is only here to style the last button properly! --%>
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/plain.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/plain.jsp
index d91cedb..88d54fb 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/plain.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/plain.jsp
@@ -19,10 +19,12 @@
 
 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
-<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.filters.SpamFilter" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
+<%@ page import="org.apache.wiki.tags.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ taglib uri="http://jspwiki.apache.org/tags" prefix="wiki" %>
@@ -36,7 +38,7 @@
 --%>
 <%
    WikiContext context = WikiContext.findContext( pageContext );
-   WikiEngine engine = context.getEngine();
+   Engine engine = context.getEngine();
 
    String usertext = EditorManager.getEditedText( pageContext );
 %>
@@ -48,17 +50,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -69,7 +71,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -226,7 +228,7 @@
       </ul>
     </div>
 
-    <c:set var="editors" value="<%= context.getEngine().getEditorManager().getEditorList() %>" />
+    <c:set var="editors" value="<%= context.getEngine().getManager( EditorManager.class ).getEditorList() %>" />
     <c:if test='${fn:length(editors) > 1}'>
     <div class="btn-group config">
       <%-- note: 'dropdown-toggle' is only here to style the last button properly! --%>
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
index 2849bf3..2a556ce 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
@@ -21,11 +21,13 @@
 <%@ page import="java.util.Properties"%>
 <%@ page import="org.apache.commons.lang3.*" %>
 <%@ page import="org.apache.wiki.*" %>
+<%@ page import="org.apache.wiki.api.core.*" %>
 <%@ page import="org.apache.wiki.auth.*" %>
 <%@ page import="org.apache.wiki.auth.permissions.*" %>
 <%@ page import="org.apache.wiki.filters.*" %>
-<%@ page import="org.apache.wiki.render.*" %>
+<%@ page import="org.apache.wiki.pages.PageManager" %>
 <%@ page import="org.apache.wiki.parser.JSPWikiMarkupParser" %>
+<%@ page import="org.apache.wiki.render.*" %>
 <%@ page import="org.apache.wiki.ui.*" %>
 <%@ page import="org.apache.wiki.util.TextUtil" %>
 <%@ page import="org.apache.wiki.variables.VariableManager" %>
@@ -41,7 +43,7 @@
 --%>
 <%
     WikiContext context = WikiContext.findContext( pageContext );
-    WikiEngine engine = context.getEngine();
+    Engine engine = context.getEngine();
 
     context.setVariable( WikiContext.VAR_WYSIWYG_EDITOR_MODE, Boolean.TRUE );
     context.setVariable( VariableManager.VAR_RUNFILTERS,  "false" );
@@ -59,17 +61,17 @@
   String clone = request.getParameter( "clone" );
   if( clone != null )
   {
-    WikiPage p = engine.getPageManager().getPage( clone );
+    WikiPage p = engine.getManager( PageManager.class ).getPage( clone );
     if( p != null )
     {
-        AuthorizationManager mgr = engine.getAuthorizationManager();
+        AuthorizationManager mgr = engine.getManager( AuthorizationManager.class );
         PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
 
         try
         {
           if( mgr.checkPermission( context.getWikiSession(), pp ) )
           {
-            usertext = engine.getPageManager().getPureText( p );
+            usertext = engine.getManager( PageManager.class ).getPureText( p );
           }
         }
         catch( Exception e ) {  /*log.error( "Accessing clone page "+clone, e );*/ }
@@ -80,7 +82,7 @@
 <%
   if( usertext == null )
   {
-    usertext = engine.getPageManager().getPureText( context.getPage() );
+    usertext = engine.getManager( PageManager.class ).getPureText( context.getPage() );
   }
 %>
 </wiki:CheckRequestContext>
@@ -90,7 +92,7 @@
     String pageAsHtml;
     try
     {
-        pageAsHtml = engine.getRenderingManager().getHTML( context, usertext );
+        pageAsHtml = engine.getManager( RenderingManager.class ).getHTML( context, usertext );
     }
         catch( Exception e )
     {
@@ -110,7 +112,7 @@
    wikiPage.setAttribute( JSPWikiMarkupParser.PROP_CAMELCASELINKS, originalCCLOption );
 
    /*not used
-   String templateDir = (String)engine.getWikiProperties().get( WikiEngine.PROP_TEMPLATEDIR );
+   String templateDir = (String)engine.getWikiProperties().get( Engine.PROP_TEMPLATEDIR );
    String protocol = "http://";
    if( request.isSecure() )
    {
@@ -202,7 +204,7 @@
       </ul>
     </div>
 
-    <c:set var="editors" value="<%= engine.getEditorManager().getEditorList() %>" />
+    <c:set var="editors" value="<%= engine.getManager( EditorManager.class ).getEditorList() %>" />
     <c:if test='${fn:length(editors)>1}'>
    <div class="btn-group config">
       <%-- note: 'dropdown-toggle' is only here to style the last button properly! --%>


[jspwiki] 15/38: JSPWIKI-120: rename + extract interface from UserManager

Posted by ju...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 11a0ada483246feb26f70a563c5a53aa29e0218e
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 20:16:19 2020 +0100

    JSPWIKI-120: rename + extract interface from UserManager
---
 .../{UserManager.java => DefaultUserManager.java}  | 383 +++--------
 .../java/org/apache/wiki/auth/UserManager.java     | 712 ++-------------------
 .../wiki/auth/user/AbstractUserDatabase.java       | 169 ++---
 .../apache/wiki/auth/user/JDBCUserDatabase.java    | 143 ++---
 .../org/apache/wiki/auth/user/UserDatabase.java    | 172 ++---
 .../org/apache/wiki/auth/user/XMLUserDatabase.java | 287 ++++-----
 .../org/apache/wiki/tasks/DefaultTasksManager.java |  10 +-
 .../java/org/apache/wiki/tasks/TasksManager.java   |   4 +-
 .../wiki/tasks/auth/SaveUserProfileTask.java       |  18 +-
 .../org/apache/wiki/workflow/WorkflowBuilder.java  |  89 +--
 .../src/main/resources/ini/classmappings.xml       |   2 +-
 11 files changed, 546 insertions(+), 1443 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
similarity index 59%
copy from jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
copy to jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
index 5d51ec4..c2b13af 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
@@ -21,11 +21,11 @@ package org.apache.wiki.auth;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
 import org.apache.wiki.ajax.AjaxUtil;
 import org.apache.wiki.ajax.WikiAjaxDispatcherServlet;
 import org.apache.wiki.ajax.WikiAjaxServlet;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.engine.FilterManager;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.exceptions.WikiException;
@@ -41,7 +41,9 @@ import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
 import org.apache.wiki.filters.SpamFilter;
 import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.tasks.TasksManager;
 import org.apache.wiki.ui.InputValidator;
 import org.apache.wiki.util.ClassUtil;
 import org.apache.wiki.util.TextUtil;
@@ -69,10 +71,11 @@ import java.util.WeakHashMap;
 
 
 /**
- * Provides a facade for obtaining user information.
+ * Default implementation for {@link UserManager}.
+ *
  * @since 2.3
  */
-public class UserManager {
+public class DefaultUserManager implements UserManager {
 
     private static final String USERDATABASE_PACKAGE = "org.apache.wiki.auth.user";
     private static final String SESSION_MESSAGES = "profile";
@@ -82,47 +85,31 @@ public class UserManager {
     private static final String PARAM_LOGINNAME = "loginname";
     private static final String UNKNOWN_CLASS = "<unknown>";
 
-    private WikiEngine m_engine;
+    private Engine m_engine;
 
-    private static final Logger log = Logger.getLogger(UserManager.class);
-
-    /** Message key for the "save profile" message. */
-    private static final String PROP_DATABASE               = "jspwiki.userdatabase";
-
-    public static final String JSON_USERS = "users";
-
-    // private static final String  PROP_ACLMANAGER     = "jspwiki.aclManager";
+    private static final Logger log = Logger.getLogger( DefaultUserManager.class);
 
     /** Associates wiki sessions with profiles */
-    private final Map<WikiSession,UserProfile> m_profiles = new WeakHashMap<>();
+    private final Map< WikiSession, UserProfile > m_profiles = new WeakHashMap<>();
 
     /** The user database loads, manages and persists user identities */
-    private UserDatabase     m_database;
+    private UserDatabase m_database;
 
-    /**
-     * Initializes the engine for its nefarious purposes.
-     * @param engine the current wiki engine
-     * @param props the wiki engine initialization properties
-     */
-    public void initialize( final WikiEngine engine, final Properties props ) {
+    /** {@inheritDoc} */
+    @Override
+    public void initialize( final Engine engine, final Properties props ) {
         m_engine = engine;
 
         // Attach the PageManager as a listener
         // TODO: it would be better if we did this in PageManager directly
-        addWikiEventListener( engine.getPageManager() );
+        addWikiEventListener( engine.getManager( PageManager.class ) );
 
         //TODO: Replace with custom annotations. See JSPWIKI-566
         WikiAjaxDispatcherServlet.registerServlet( JSON_USERS, new JSONUserModule(this), new AllPermission(null));
     }
 
-    /**
-     * Returns the UserDatabase employed by this WikiEngine. The UserDatabase is lazily initialized by this method, if it does
-     * not exist yet. If the initialization fails, this method will use the inner class DummyUserDatabase as a default (which
-     * is enough to get JSPWiki running).
-     *
-     * @return the dummy user database
-     * @since 2.3
-     */
+    /** {@inheritDoc} */
+    @Override
     public UserDatabase getUserDatabase() {
         if( m_database != null ) {
             return m_database;
@@ -158,29 +145,8 @@ public class UserManager {
         return m_database;
     }
 
-    /**
-     * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile}for the
-     * user in a wiki session. If the user is authenticated, the UserProfile
-     * returned will be the one stored in the user database; if one does not
-     * exist, a new one will be initialized and returned. If the user is
-     * anonymous or asserted, the UserProfile will <i>always</i> be newly
-     * initialized to prevent spoofing of identities. If a UserProfile needs to
-     * be initialized, its
-     * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will
-     * return <code>true</code>, and its login name will will be set
-     * automatically if the user is authenticated. Note that this method does
-     * not modify the retrieved (or newly created) profile otherwise; other
-     * fields in the user profile may be <code>null</code>.</p>
-     * <p>If a new UserProfile was created, but its
-     * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
-     * <code>false</code>, this method throws an {@link IllegalStateException}.
-     * This is meant as a quality check for UserDatabase providers;
-     * it should only be thrown if the implementation is faulty.</p>
-     * @param session the wiki session, which may not be <code>null</code>
-     * @return the user's profile, which will be newly initialized if the user
-     * is anonymous or asserted, or if the user cannot be found in the user
-     * database
-     */
+    /** {@inheritDoc} */
+    @Override
     public UserProfile getUserProfile( final WikiSession session ) {
         // Look up cached user profile
         UserProfile profile = m_profiles.get( session );
@@ -211,48 +177,12 @@ public class UserManager {
         return profile;
     }
 
-    /**
-     * <p>
-     * Saves the {@link org.apache.wiki.auth.user.UserProfile}for the user in
-     * a wiki session. This method verifies that a user profile to be saved
-     * doesn't collide with existing profiles; that is, the login name
-     * or full name is already used by another profile. If the profile
-     * collides, a <code>DuplicateUserException</code> is thrown. After saving
-     * the profile, the user database changes are committed, and the user's
-     * credential set is refreshed; if custom authentication is used, this means
-     * the user will be automatically be logged in.
-     * </p>
-     * <p>
-     * When the user's profile is saved successfully, this method fires a
-     * {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession as the
-     * source and the UserProfile as target. For existing profiles, if the
-     * user's full name changes, this method also fires a "name changed"
-     * event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the
-     * WikiSession as the source and an array containing the old and new
-     * UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows
-     * the GroupManager and PageManager can change group memberships and
-     * ACLs if needed.
-     * </p>
-     * <p>
-     * Note that WikiSessions normally attach event listeners to the
-     * UserManager, so changes to the profile will automatically cause the
-     * correct Principals to be reloaded into the current WikiSession's Subject.
-     * </p>
-     * @param session the wiki session, which may not be <code>null</code>
-     * @param profile the user profile, which may not be <code>null</code>
-     * @throws DuplicateUserException if the proposed profile's login name or full name collides with another
-     * @throws WikiException if the save fails for some reason. If the current user does not have
-     * permission to save the profile, this will be a {@link org.apache.wiki.auth.WikiSecurityException};
-     * if if the user profile must be approved before it can be saved, it will be a
-     * {@link org.apache.wiki.workflow.DecisionRequiredException}. All other WikiException
-     * indicate a condition that is not normal is probably due to mis-configuration
-     */
-    public void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException
-    {
+    /** {@inheritDoc} */
+    @Override
+    public void setUserProfile( final WikiSession session, final UserProfile profile ) throws DuplicateUserException, WikiException {
         // Verify user is allowed to save profile!
         final Permission p = new WikiPermission( m_engine.getApplicationName(), WikiPermission.EDIT_PROFILE_ACTION );
-        if ( !m_engine.getAuthorizationManager().checkPermission( session, p ) )
-        {
+        if ( !m_engine.getManager( AuthorizationManager.class ).checkPermission( session, p ) ) {
             throw new WikiSecurityException( "You are not allowed to save wiki profiles." );
         }
 
@@ -265,139 +195,97 @@ public class UserManager {
                                     !( oldProfile.getFullname().equals( profile.getFullname() ) &&
                                     oldProfile.getLoginName().equals( profile.getLoginName() ) );
         UserProfile otherProfile;
-        try
-        {
+        try {
             otherProfile = getUserDatabase().findByLoginName( profile.getLoginName() );
-            if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
-            {
+            if( otherProfile != null && !otherProfile.equals( oldProfile ) ) {
                 throw new DuplicateUserException( "security.error.login.taken", profile.getLoginName() );
             }
+        } catch( final NoSuchPrincipalException e ) {
         }
-        catch( final NoSuchPrincipalException e )
-        {
-        }
-        try
-        {
+        try {
             otherProfile = getUserDatabase().findByFullName( profile.getFullname() );
-            if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
-            {
+            if( otherProfile != null && !otherProfile.equals( oldProfile ) ) {
                 throw new DuplicateUserException( "security.error.fullname.taken", profile.getFullname() );
             }
-        }
-        catch( final NoSuchPrincipalException e )
-        {
+        } catch( final NoSuchPrincipalException e ) {
         }
 
         // For new accounts, create approval workflow for user profile save.
-        if ( newProfile && oldProfile != null && oldProfile.isNew() )
-        {
-            startUserProfileCreationWorkflow(session, profile);
+        if( newProfile && oldProfile != null && oldProfile.isNew() ) {
+            startUserProfileCreationWorkflow( session, profile );
 
             // If the profile doesn't need approval, then just log the user in
 
-            try
-            {
-                final AuthenticationManager mgr = m_engine.getAuthenticationManager();
-                if ( newProfile && !mgr.isContainerAuthenticated() )
-                {
+            try {
+                final AuthenticationManager mgr = m_engine.getManager( AuthenticationManager.class );
+                if( !mgr.isContainerAuthenticated() ) {
                     mgr.login( session, null, profile.getLoginName(), profile.getPassword() );
                 }
-            }
-            catch ( final WikiException e )
-            {
+            } catch( final WikiException e ) {
                 throw new WikiSecurityException( e.getMessage(), e );
             }
 
             // Alert all listeners that the profile changed...
             // ...this will cause credentials to be reloaded in the wiki session
             fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
-        }
-
-        // For existing accounts, just save the profile
-        else
-        {
+        } else { // For existing accounts, just save the profile
             // If login name changed, rename it first
-            if ( nameChanged && oldProfile != null && !oldProfile.getLoginName().equals( profile.getLoginName() ) )
-            {
+            if( nameChanged && !oldProfile.getLoginName().equals( profile.getLoginName() ) ) {
                 getUserDatabase().rename( oldProfile.getLoginName(), profile.getLoginName() );
             }
 
             // Now, save the profile (userdatabase will take care of timestamps for us)
             getUserDatabase().save( profile );
 
-            if ( nameChanged )
-            {
+            if( nameChanged ) {
                 // Fire an event if the login name or full name changed
                 final UserProfile[] profiles = new UserProfile[] { oldProfile, profile };
                 fireEvent( WikiSecurityEvent.PROFILE_NAME_CHANGED, session, profiles );
-            }
-            else
-            {
+            } else {
                 // Fire an event that says we have new a new profile (new principals)
                 fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
             }
         }
     }
 
+    /** {@inheritDoc} */
+    @Override
     public void startUserProfileCreationWorkflow( final WikiSession session, final UserProfile profile ) throws WikiException {
         final WorkflowBuilder builder = WorkflowBuilder.getBuilder( m_engine );
         final Principal submitter = session.getUserPrincipal();
-        final Step completionTask = m_engine.getTasksManager().buildSaveUserProfileTask( m_engine, session.getLocale() );
+        final Step completionTask = m_engine.getManager( TasksManager.class ).buildSaveUserProfileTask( m_engine, session.getLocale() );
 
         // Add user profile attribute as Facts for the approver (if required)
         final boolean hasEmail = profile.getEmail() != null;
-        final Fact[] facts = new Fact[ hasEmail ? 4 : 3];
-        facts[0] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
-        facts[1] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
-        facts[2] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
-        if ( hasEmail )
-        {
-            facts[3] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
-        }
-        final Workflow workflow = builder.buildApprovalWorkflow( submitter, 
-                                                                 WorkflowManager.WF_UP_CREATE_SAVE_APPROVER, 
-                                                                 null, 
-                                                                 WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY, 
-                                                                 facts, 
-                                                                 completionTask, 
+        final Fact[] facts = new Fact[ hasEmail ? 4 : 3 ];
+        facts[ 0 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
+        facts[ 1 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
+        facts[ 2 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
+        if ( hasEmail ) {
+            facts[ 3 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
+        }
+        final Workflow workflow = builder.buildApprovalWorkflow( submitter,
+                                                                 WorkflowManager.WF_UP_CREATE_SAVE_APPROVER,
+                                                                 null,
+                                                                 WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY,
+                                                                 facts,
+                                                                 completionTask,
                                                                  null );
 
         workflow.setAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE, profile );
-        m_engine.getWorkflowManager().start(workflow);
+        m_engine.getManager( WorkflowManager.class ).start( workflow );
 
         final boolean approvalRequired = workflow.getCurrentStep() instanceof Decision;
 
         // If the profile requires approval, redirect user to message page
-        if ( approvalRequired )
-        {
+        if ( approvalRequired ) {
             throw new DecisionRequiredException( "This profile must be approved before it becomes active" );
         }
     }
 
-    /**
-     * <p> Extracts user profile parameters from the HTTP request and populates
-     * a UserProfile with them. The UserProfile will either be a copy of the
-     * user's existing profile (if one can be found), or a new profile (if not).
-     * The rules for populating the profile as as follows: </p> <ul> <li>If the
-     * <code>email</code> or <code>password</code> parameter values differ
-     * from those in the existing profile, the passed parameters override the
-     * old values.</li> <li>For new profiles, the user-supplied
-     * <code>fullname</code> parameter is always
-     * used; for existing profiles the existing value is used, and whatever
-     * value the user supplied is discarded. The wiki name is automatically
-     * computed by taking the full name and extracting all whitespace.</li>
-     * <li>In all cases, the
-     * created/last modified timestamps of the user's existing or new profile
-     * always override whatever values the user supplied.</li> <li>If
-     * container authentication is used, the login name property of the profile
-     * is set to the name of
-     * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise,
-     * the value of the <code>loginname</code> parameter is used.</li> </ul>
-     * @param context the current wiki context
-     * @return a new, populated user profile
-     */
-    public UserProfile parseProfile( WikiContext context )
-    {
+    /** {@inheritDoc} */
+    @Override
+    public UserProfile parseProfile( final WikiContext context ) {
         // Retrieve the user's profile (may have been previously cached)
         final UserProfile profile = getUserProfile( context.getWikiSession() );
         final HttpServletRequest request = context.getHttpRequest();
@@ -414,9 +302,7 @@ public class UserManager {
 
         // A special case if we have container authentication
         // If authenticated, login name is always taken from container
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated() &&
-                context.getWikiSession().isAuthenticated() )
-        {
+        if ( m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated() && context.getWikiSession().isAuthenticated() ) {
             loginName = context.getWikiSession().getLoginPrincipal().getName();
         }
 
@@ -428,36 +314,20 @@ public class UserManager {
         return profile;
     }
 
-    /**
-     * Validates a user profile, and appends any errors to the session errors
-     * list. If the profile is new, the password will be checked to make sure it
-     * isn't null. Otherwise, the password is checked for length and that it
-     * matches the value of the 'password2' HTTP parameter. Note that we have a
-     * special case when container-managed authentication is used and the user
-     * is not authenticated; this will always cause validation to fail. Any
-     * validation errors are added to the wiki session's messages collection
-     * (see {@link WikiSession#getMessages()}.
-     * @param context the current wiki context
-     * @param profile the supplied UserProfile
-     */
-    public void validateProfile( WikiContext context, UserProfile profile )
-    {
+    /** {@inheritDoc} */
+    @Override
+    public void validateProfile( final WikiContext context, final UserProfile profile ) {
         final boolean isNew = profile.isNew();
         final WikiSession session = context.getWikiSession();
         final InputValidator validator = new InputValidator( SESSION_MESSAGES, context );
         final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
 
-        //
         //  Query the SpamFilter first
-        //
-        final FilterManager fm = m_engine.getFilterManager();
-        final List<PageFilter> ls = fm.getFilterList();
-        for( final PageFilter pf : ls )
-        {
-            if( pf instanceof SpamFilter )
-            {
-                if( ((SpamFilter)pf).isValidUserProfile( context, profile ) == false )
-                {
+        final FilterManager fm = m_engine.getManager( FilterManager.class );
+        final List< PageFilter > ls = fm.getFilterList();
+        for( final PageFilter pf : ls ) {
+            if( pf instanceof SpamFilter ) {
+                if( !( ( SpamFilter )pf ).isValidUserProfile( context, profile ) ) {
                     session.addMessage( SESSION_MESSAGES, "Invalid userprofile" );
                     return;
                 }
@@ -466,9 +336,8 @@ public class UserManager {
         }
 
         // If container-managed auth and user not logged in, throw an error
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated()
-             && !context.getWikiSession().isAuthenticated() )
-        {
+        if ( m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated()
+             && !context.getWikiSession().isAuthenticated() ) {
             session.addMessage( SESSION_MESSAGES, rb.getString("security.error.createprofilebeforelogin") );
         }
 
@@ -477,23 +346,17 @@ public class UserManager {
         validator.validate( profile.getEmail(), rb.getString("security.user.email"), InputValidator.EMAIL );
 
         // If new profile, passwords must match and can't be null
-        if ( !m_engine.getAuthenticationManager().isContainerAuthenticated() )
-        {
+        if( !m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated() ) {
             final String password = profile.getPassword();
-            if ( password == null )
-            {
-                if ( isNew )
-                {
-                    session.addMessage( SESSION_MESSAGES, rb.getString("security.error.blankpassword") );
+            if( password == null ) {
+                if( isNew ) {
+                    session.addMessage( SESSION_MESSAGES, rb.getString( "security.error.blankpassword" ) );
                 }
-            }
-            else
-            {
+            } else {
                 final HttpServletRequest request = context.getHttpRequest();
                 final String password2 = ( request == null ) ? null : request.getParameter( "password2" );
-                if ( !password.equals( password2 ) )
-                {
-                    session.addMessage( SESSION_MESSAGES, rb.getString("security.error.passwordnomatch") );
+                if( !password.equals( password2 ) ) {
+                    session.addMessage( SESSION_MESSAGES, rb.getString( "security.error.passwordnomatch" ) );
                 }
             }
         }
@@ -504,56 +367,38 @@ public class UserManager {
         final String email = profile.getEmail();
 
         // It's illegal to use as a full name someone else's login name
-        try
-        {
+        try {
             otherProfile = getUserDatabase().find( fullName );
-            if ( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) )
-            {
+            if( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) ) {
                 final Object[] args = { fullName };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalfullname"), args ) );
+                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.illegalfullname" ), args ) );
             }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
+        } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
 
         // It's illegal to use as a login name someone else's full name
-        try
-        {
+        try {
             otherProfile = getUserDatabase().find( loginName );
-            if ( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) )
-            {
+            if( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) ) {
                 final Object[] args = { loginName };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalloginname"), args ) );
+                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.illegalloginname" ), args ) );
             }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
+        } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
 
         // It's illegal to use multiple accounts with the same email
-        try
-        {
+        try {
             otherProfile = getUserDatabase().findByEmail( email );
-            if ( otherProfile != null
-                && !profile.getUid().equals(otherProfile.getUid()) // Issue JSPWIKI-1042
-                && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ).equals( StringUtils.lowerCase(otherProfile.getEmail() ) ) )
-            {
+            if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042
+                    && !profile.equals( otherProfile ) && StringUtils.lowerCase( email )
+                    .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) {
                 final Object[] args = { email };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.email.taken"), args ) );
+                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) );
             }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
+        } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
     }
 
-    /**
-     *  A helper method for returning all of the known WikiNames in this system.
-     *
-     *  @return An Array of Principals
-     *  @throws WikiSecurityException If for reason the names cannot be fetched
-     */
-    public Principal[] listWikiNames()
-        throws WikiSecurityException
-    {
+    /** {@inheritDoc} */
+    @Override
+    public Principal[] listWikiNames() throws WikiSecurityException {
         return getUserDatabase().getWikiNames();
     }
 
@@ -568,7 +413,7 @@ public class UserManager {
          * @param loginName the login name to delete
          */
         @Override
-        public void deleteByLoginName( String loginName ) {
+        public void deleteByLoginName( final String loginName ) {
             // No operation
         }
 
@@ -642,7 +487,7 @@ public class UserManager {
          * @param props the properties used to initialize the wiki engine
          */
         @Override
-        public void initialize(final WikiEngine engine, final Properties props) {
+        public void initialize( final Engine engine, final Properties props ) {
         }
 
         /**
@@ -673,8 +518,7 @@ public class UserManager {
      * This is a convenience method.
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( WikiEventListener listener )
-    {
+    @Override public synchronized void addWikiEventListener( final WikiEventListener listener ) {
         WikiEventManager.addWikiEventListener( this, listener );
     }
 
@@ -683,29 +527,11 @@ public class UserManager {
      * This is a convenience method.
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( WikiEventListener listener )
-    {
+    @Override public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
         WikiEventManager.removeWikiEventListener( this, listener );
     }
 
     /**
-     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object
-     *  to all registered listeners.
-     *
-     * @see org.apache.wiki.event.WikiSecurityEvent
-     * @param type       the event type to be fired
-     * @param session    the wiki session supporting the event
-     * @param profile    the user profile (or array of user profiles), which may be <code>null</code>
-     */
-    protected void fireEvent( int type, WikiSession session, Object profile )
-    {
-        if ( WikiEventManager.isListening(this) )
-        {
-            WikiEventManager.fireEvent(this,new WikiSecurityEvent(session,type,profile));
-        }
-    }
-
-    /**
      *  Implements the JSON API for usermanager.
      *  <p>
      *  Even though this gets serialized whenever container shuts down/restarts, this gets reinstalled to the session when JSPWiki starts.
@@ -713,13 +539,13 @@ public class UserManager {
      */
     public static final class JSONUserModule implements WikiAjaxServlet {
 
-		private volatile UserManager m_manager;
+		private volatile DefaultUserManager m_manager;
 
         /**
          *  Create a new JSONUserModule.
          *  @param mgr Manager
          */
-        public JSONUserModule( UserManager mgr )
+        public JSONUserModule( final DefaultUserManager mgr )
         {
             m_manager = mgr;
         }
@@ -730,7 +556,7 @@ public class UserManager {
         }
 
         @Override
-        public void service(HttpServletRequest req, HttpServletResponse resp, String actionName, List<String> params) throws ServletException, IOException {
+        public void service( final HttpServletRequest req, final HttpServletResponse resp, final String actionName, final List<String> params) throws ServletException, IOException {
         	try {
             	if( params.size() < 1 ) {
             		return;
@@ -753,13 +579,12 @@ public class UserManager {
          *  @return A UserProfile object
          *  @throws NoSuchPrincipalException If such a name does not exist.
          */
-        public UserProfile getUserInfo( String uid ) throws NoSuchPrincipalException {
+        public UserProfile getUserInfo( final String uid ) throws NoSuchPrincipalException {
             if( m_manager != null ) {
-                final UserProfile prof = m_manager.getUserDatabase().find( uid );
-                return prof;
+                return m_manager.getUserDatabase().find( uid );
             }
 
-            throw new IllegalStateException("The manager is offline.");
+            throw new IllegalStateException( "The manager is offline." );
         }
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
index 5d51ec4..c59130b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
@@ -18,102 +18,40 @@
  */
 package org.apache.wiki.auth;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiSession;
-import org.apache.wiki.ajax.AjaxUtil;
-import org.apache.wiki.ajax.WikiAjaxDispatcherServlet;
-import org.apache.wiki.ajax.WikiAjaxServlet;
-import org.apache.wiki.api.engine.FilterManager;
-import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
-import org.apache.wiki.api.filters.PageFilter;
-import org.apache.wiki.auth.permissions.AllPermission;
-import org.apache.wiki.auth.permissions.WikiPermission;
-import org.apache.wiki.auth.user.AbstractUserDatabase;
 import org.apache.wiki.auth.user.DuplicateUserException;
 import org.apache.wiki.auth.user.UserDatabase;
 import org.apache.wiki.auth.user.UserProfile;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiSecurityEvent;
-import org.apache.wiki.filters.SpamFilter;
-import org.apache.wiki.i18n.InternationalizationManager;
-import org.apache.wiki.preferences.Preferences;
-import org.apache.wiki.ui.InputValidator;
-import org.apache.wiki.util.ClassUtil;
-import org.apache.wiki.util.TextUtil;
-import org.apache.wiki.workflow.Decision;
-import org.apache.wiki.workflow.DecisionRequiredException;
-import org.apache.wiki.workflow.Fact;
-import org.apache.wiki.workflow.Step;
-import org.apache.wiki.workflow.Workflow;
-import org.apache.wiki.workflow.WorkflowBuilder;
-import org.apache.wiki.workflow.WorkflowManager;
 
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.security.Permission;
 import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.WeakHashMap;
 
 
 /**
  * Provides a facade for obtaining user information.
+ *
  * @since 2.3
  */
-public class UserManager {
-
-    private static final String USERDATABASE_PACKAGE = "org.apache.wiki.auth.user";
-    private static final String SESSION_MESSAGES = "profile";
-    private static final String PARAM_EMAIL = "email";
-    private static final String PARAM_FULLNAME = "fullname";
-    private static final String PARAM_PASSWORD = "password";
-    private static final String PARAM_LOGINNAME = "loginname";
-    private static final String UNKNOWN_CLASS = "<unknown>";
-
-    private WikiEngine m_engine;
-
-    private static final Logger log = Logger.getLogger(UserManager.class);
+public interface UserManager {
 
     /** Message key for the "save profile" message. */
-    private static final String PROP_DATABASE               = "jspwiki.userdatabase";
-
-    public static final String JSON_USERS = "users";
+    String PROP_DATABASE = "jspwiki.userdatabase";
 
-    // private static final String  PROP_ACLMANAGER     = "jspwiki.aclManager";
-
-    /** Associates wiki sessions with profiles */
-    private final Map<WikiSession,UserProfile> m_profiles = new WeakHashMap<>();
-
-    /** The user database loads, manages and persists user identities */
-    private UserDatabase     m_database;
+    String JSON_USERS = "users";
 
     /**
      * Initializes the engine for its nefarious purposes.
+     *
      * @param engine the current wiki engine
      * @param props the wiki engine initialization properties
      */
-    public void initialize( final WikiEngine engine, final Properties props ) {
-        m_engine = engine;
-
-        // Attach the PageManager as a listener
-        // TODO: it would be better if we did this in PageManager directly
-        addWikiEventListener( engine.getPageManager() );
-
-        //TODO: Replace with custom annotations. See JSPWIKI-566
-        WikiAjaxDispatcherServlet.registerServlet( JSON_USERS, new JSONUserModule(this), new AllPermission(null));
-    }
+    void initialize( final Engine engine, final Properties props );
 
     /**
      * Returns the UserDatabase employed by this WikiEngine. The UserDatabase is lazily initialized by this method, if it does
@@ -123,121 +61,44 @@ public class UserManager {
      * @return the dummy user database
      * @since 2.3
      */
-    public UserDatabase getUserDatabase() {
-        if( m_database != null ) {
-            return m_database;
-        }
-
-        String dbClassName = UNKNOWN_CLASS;
-
-        try {
-            dbClassName = TextUtil.getRequiredProperty( m_engine.getWikiProperties(), PROP_DATABASE );
-
-            log.info( "Attempting to load user database class " + dbClassName );
-            final Class<?> dbClass = ClassUtil.findClass( USERDATABASE_PACKAGE, dbClassName );
-            m_database = (UserDatabase) dbClass.newInstance();
-            m_database.initialize( m_engine, m_engine.getWikiProperties() );
-            log.info("UserDatabase initialized.");
-        } catch( final NoSuchElementException | NoRequiredPropertyException e ) {
-            log.error( "You have not set the '"+PROP_DATABASE+"'. You need to do this if you want to enable user management by JSPWiki.", e );
-        } catch( final ClassNotFoundException e ) {
-            log.error( "UserDatabase class " + dbClassName + " cannot be found", e );
-        } catch( final InstantiationException e ) {
-            log.error( "UserDatabase class " + dbClassName + " cannot be created", e );
-        } catch( final IllegalAccessException e ) {
-            log.error( "You are not allowed to access this user database class", e );
-        } catch( final WikiSecurityException e ) {
-            log.error( "Exception initializing user database: " + e.getMessage(), e );
-        } finally {
-            if( m_database == null ) {
-                log.info("I could not create a database object you specified (or didn't specify), so I am falling back to a default.");
-                m_database = new DummyUserDatabase();
-            }
-        }
-
-        return m_database;
-    }
+    UserDatabase getUserDatabase();
 
     /**
-     * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile}for the
-     * user in a wiki session. If the user is authenticated, the UserProfile
-     * returned will be the one stored in the user database; if one does not
-     * exist, a new one will be initialized and returned. If the user is
-     * anonymous or asserted, the UserProfile will <i>always</i> be newly
-     * initialized to prevent spoofing of identities. If a UserProfile needs to
-     * be initialized, its
-     * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will
-     * return <code>true</code>, and its login name will will be set
-     * automatically if the user is authenticated. Note that this method does
-     * not modify the retrieved (or newly created) profile otherwise; other
-     * fields in the user profile may be <code>null</code>.</p>
-     * <p>If a new UserProfile was created, but its
-     * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
-     * <code>false</code>, this method throws an {@link IllegalStateException}.
-     * This is meant as a quality check for UserDatabase providers;
+     * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile} for the user in a wiki session. If the user is authenticated, the
+     * UserProfile returned will be the one stored in the user database; if one does not exist, a new one will be initialized and returned.
+     * If the user is anonymous or asserted, the UserProfile will <i>always</i> be newly initialized to prevent spoofing of identities.
+     * If a UserProfile needs to be initialized, its {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will return
+     * <code>true</code>, and its login name will will be set automatically if the user is authenticated. Note that this method does
+     * not modify the retrieved (or newly created) profile otherwise; other fields in the user profile may be <code>null</code>.</p>
+     * <p>If a new UserProfile was created, but its {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
+     * <code>false</code>, this method throws an {@link IllegalStateException}. This is meant as a quality check for UserDatabase providers;
      * it should only be thrown if the implementation is faulty.</p>
+     *
      * @param session the wiki session, which may not be <code>null</code>
-     * @return the user's profile, which will be newly initialized if the user
-     * is anonymous or asserted, or if the user cannot be found in the user
-     * database
+     * @return the user's profile, which will be newly initialized if the user is anonymous or asserted, or if the user cannot be found in
+     *         the user database
      */
-    public UserProfile getUserProfile( final WikiSession session ) {
-        // Look up cached user profile
-        UserProfile profile = m_profiles.get( session );
-        boolean newProfile = profile == null;
-        Principal user = null;
-
-        // If user is authenticated, figure out if this is an existing profile
-        if ( session.isAuthenticated() ) {
-            user = session.getUserPrincipal();
-            try {
-                profile = getUserDatabase().find( user.getName() );
-                newProfile = false;
-            } catch( final NoSuchPrincipalException e ) { }
-        }
-
-        if ( newProfile ) {
-            profile = getUserDatabase().newProfile();
-            if ( user != null ) {
-                profile.setLoginName( user.getName() );
-            }
-            if ( !profile.isNew() ) {
-                throw new IllegalStateException( "New profile should be marked 'new'. Check your UserProfile implementation." );
-            }
-        }
-
-        // Stash the profile for next time
-        m_profiles.put( session, profile );
-        return profile;
-    }
+    UserProfile getUserProfile( WikiSession session );
 
     /**
      * <p>
-     * Saves the {@link org.apache.wiki.auth.user.UserProfile}for the user in
-     * a wiki session. This method verifies that a user profile to be saved
-     * doesn't collide with existing profiles; that is, the login name
-     * or full name is already used by another profile. If the profile
-     * collides, a <code>DuplicateUserException</code> is thrown. After saving
-     * the profile, the user database changes are committed, and the user's
-     * credential set is refreshed; if custom authentication is used, this means
-     * the user will be automatically be logged in.
+     * Saves the {@link org.apache.wiki.auth.user.UserProfile} for the user in a wiki session. This method verifies that a user profile to
+     * be saved doesn't collide with existing profiles; that is, the login name or full name is already used by another profile. If the
+     * profile collides, a <code>DuplicateUserException</code> is thrown. After saving the profile, the user database changes are committed,
+     * and the user's credential set is refreshed; if custom authentication is used, this means the user will be automatically be logged in.
      * </p>
      * <p>
-     * When the user's profile is saved successfully, this method fires a
-     * {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession as the
-     * source and the UserProfile as target. For existing profiles, if the
-     * user's full name changes, this method also fires a "name changed"
-     * event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the
-     * WikiSession as the source and an array containing the old and new
-     * UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows
-     * the GroupManager and PageManager can change group memberships and
-     * ACLs if needed.
+     * When the user's profile is saved successfully, this method fires a {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession
+     * as the source and the UserProfile as target. For existing profiles, if the user's full name changes, this method also fires a
+     * "name changed" event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the WikiSession as the source and an array containing
+     * the old and new UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows the GroupManager and PageManager can change
+     * group memberships and ACLs if needed.
      * </p>
      * <p>
-     * Note that WikiSessions normally attach event listeners to the
-     * UserManager, so changes to the profile will automatically cause the
+     * Note that WikiSessions normally attach event listeners to the UserManager, so changes to the profile will automatically cause the
      * correct Principals to be reloaded into the current WikiSession's Subject.
      * </p>
+     *
      * @param session the wiki session, which may not be <code>null</code>
      * @param profile the user profile, which may not be <code>null</code>
      * @throws DuplicateUserException if the proposed profile's login name or full name collides with another
@@ -247,303 +108,42 @@ public class UserManager {
      * {@link org.apache.wiki.workflow.DecisionRequiredException}. All other WikiException
      * indicate a condition that is not normal is probably due to mis-configuration
      */
-    public void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException
-    {
-        // Verify user is allowed to save profile!
-        final Permission p = new WikiPermission( m_engine.getApplicationName(), WikiPermission.EDIT_PROFILE_ACTION );
-        if ( !m_engine.getAuthorizationManager().checkPermission( session, p ) )
-        {
-            throw new WikiSecurityException( "You are not allowed to save wiki profiles." );
-        }
+    void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException;
 
-        // Check if profile is new, and see if container allows creation
-        final boolean newProfile = profile.isNew();
-
-        // Check if another user profile already has the fullname or loginname
-        final UserProfile oldProfile = getUserProfile( session );
-        final boolean nameChanged = ( oldProfile != null && oldProfile.getFullname() != null ) &&
-                                    !( oldProfile.getFullname().equals( profile.getFullname() ) &&
-                                    oldProfile.getLoginName().equals( profile.getLoginName() ) );
-        UserProfile otherProfile;
-        try
-        {
-            otherProfile = getUserDatabase().findByLoginName( profile.getLoginName() );
-            if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
-            {
-                throw new DuplicateUserException( "security.error.login.taken", profile.getLoginName() );
-            }
-        }
-        catch( final NoSuchPrincipalException e )
-        {
-        }
-        try
-        {
-            otherProfile = getUserDatabase().findByFullName( profile.getFullname() );
-            if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
-            {
-                throw new DuplicateUserException( "security.error.fullname.taken", profile.getFullname() );
-            }
-        }
-        catch( final NoSuchPrincipalException e )
-        {
-        }
-
-        // For new accounts, create approval workflow for user profile save.
-        if ( newProfile && oldProfile != null && oldProfile.isNew() )
-        {
-            startUserProfileCreationWorkflow(session, profile);
-
-            // If the profile doesn't need approval, then just log the user in
-
-            try
-            {
-                final AuthenticationManager mgr = m_engine.getAuthenticationManager();
-                if ( newProfile && !mgr.isContainerAuthenticated() )
-                {
-                    mgr.login( session, null, profile.getLoginName(), profile.getPassword() );
-                }
-            }
-            catch ( final WikiException e )
-            {
-                throw new WikiSecurityException( e.getMessage(), e );
-            }
-
-            // Alert all listeners that the profile changed...
-            // ...this will cause credentials to be reloaded in the wiki session
-            fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
-        }
-
-        // For existing accounts, just save the profile
-        else
-        {
-            // If login name changed, rename it first
-            if ( nameChanged && oldProfile != null && !oldProfile.getLoginName().equals( profile.getLoginName() ) )
-            {
-                getUserDatabase().rename( oldProfile.getLoginName(), profile.getLoginName() );
-            }
-
-            // Now, save the profile (userdatabase will take care of timestamps for us)
-            getUserDatabase().save( profile );
-
-            if ( nameChanged )
-            {
-                // Fire an event if the login name or full name changed
-                final UserProfile[] profiles = new UserProfile[] { oldProfile, profile };
-                fireEvent( WikiSecurityEvent.PROFILE_NAME_CHANGED, session, profiles );
-            }
-            else
-            {
-                // Fire an event that says we have new a new profile (new principals)
-                fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
-            }
-        }
-    }
-
-    public void startUserProfileCreationWorkflow( final WikiSession session, final UserProfile profile ) throws WikiException {
-        final WorkflowBuilder builder = WorkflowBuilder.getBuilder( m_engine );
-        final Principal submitter = session.getUserPrincipal();
-        final Step completionTask = m_engine.getTasksManager().buildSaveUserProfileTask( m_engine, session.getLocale() );
-
-        // Add user profile attribute as Facts for the approver (if required)
-        final boolean hasEmail = profile.getEmail() != null;
-        final Fact[] facts = new Fact[ hasEmail ? 4 : 3];
-        facts[0] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
-        facts[1] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
-        facts[2] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
-        if ( hasEmail )
-        {
-            facts[3] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
-        }
-        final Workflow workflow = builder.buildApprovalWorkflow( submitter, 
-                                                                 WorkflowManager.WF_UP_CREATE_SAVE_APPROVER, 
-                                                                 null, 
-                                                                 WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY, 
-                                                                 facts, 
-                                                                 completionTask, 
-                                                                 null );
-
-        workflow.setAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE, profile );
-        m_engine.getWorkflowManager().start(workflow);
-
-        final boolean approvalRequired = workflow.getCurrentStep() instanceof Decision;
-
-        // If the profile requires approval, redirect user to message page
-        if ( approvalRequired )
-        {
-            throw new DecisionRequiredException( "This profile must be approved before it becomes active" );
-        }
-    }
+    void startUserProfileCreationWorkflow( WikiSession session, UserProfile profile ) throws WikiException;
 
     /**
-     * <p> Extracts user profile parameters from the HTTP request and populates
-     * a UserProfile with them. The UserProfile will either be a copy of the
-     * user's existing profile (if one can be found), or a new profile (if not).
-     * The rules for populating the profile as as follows: </p> <ul> <li>If the
-     * <code>email</code> or <code>password</code> parameter values differ
-     * from those in the existing profile, the passed parameters override the
-     * old values.</li> <li>For new profiles, the user-supplied
-     * <code>fullname</code> parameter is always
-     * used; for existing profiles the existing value is used, and whatever
-     * value the user supplied is discarded. The wiki name is automatically
-     * computed by taking the full name and extracting all whitespace.</li>
-     * <li>In all cases, the
-     * created/last modified timestamps of the user's existing or new profile
-     * always override whatever values the user supplied.</li> <li>If
-     * container authentication is used, the login name property of the profile
-     * is set to the name of
-     * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise,
-     * the value of the <code>loginname</code> parameter is used.</li> </ul>
+     * <p> Extracts user profile parameters from the HTTP request and populates a UserProfile with them. The UserProfile will either be a
+     * copy of the user's existing profile (if one can be found), or a new profile (if not). The rules for populating the profile as as
+     * follows: </p>
+     * <ul>
+     * <li>If the <code>email</code> or <code>password</code> parameter values differ from those in the existing profile, the passed
+     * parameters override the old values.</li>
+     * <li>For new profiles, the user-supplied <code>fullname</code> parameter is always used; for existing profiles the existing value is
+     * used, and whatever value the user supplied is discarded. The wiki name is automatically computed by taking the full name and
+     * extracting all whitespace.</li>
+     * <li>In all cases, the created/last modified timestamps of the user's existing or new profile always override whatever values the user
+     * supplied.</li>
+     * <li>If container authentication is used, the login name property of the profile is set to the name of
+     * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise, the value of the <code>loginname</code> parameter is used.</li>
+     * </ul>
+     *
      * @param context the current wiki context
      * @return a new, populated user profile
      */
-    public UserProfile parseProfile( WikiContext context )
-    {
-        // Retrieve the user's profile (may have been previously cached)
-        final UserProfile profile = getUserProfile( context.getWikiSession() );
-        final HttpServletRequest request = context.getHttpRequest();
-
-        // Extract values from request stream (cleanse whitespace as needed)
-        String loginName = request.getParameter( PARAM_LOGINNAME );
-        String password = request.getParameter( PARAM_PASSWORD );
-        String fullname = request.getParameter( PARAM_FULLNAME );
-        String email = request.getParameter( PARAM_EMAIL );
-        loginName = InputValidator.isBlank( loginName ) ? null : loginName;
-        password = InputValidator.isBlank( password ) ? null : password;
-        fullname = InputValidator.isBlank( fullname ) ? null : fullname;
-        email = InputValidator.isBlank( email ) ? null : email;
-
-        // A special case if we have container authentication
-        // If authenticated, login name is always taken from container
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated() &&
-                context.getWikiSession().isAuthenticated() )
-        {
-            loginName = context.getWikiSession().getLoginPrincipal().getName();
-        }
-
-        // Set the profile fields!
-        profile.setLoginName( loginName );
-        profile.setEmail( email );
-        profile.setFullname( fullname );
-        profile.setPassword( password );
-        return profile;
-    }
+    UserProfile parseProfile( WikiContext context );
 
     /**
-     * Validates a user profile, and appends any errors to the session errors
-     * list. If the profile is new, the password will be checked to make sure it
-     * isn't null. Otherwise, the password is checked for length and that it
-     * matches the value of the 'password2' HTTP parameter. Note that we have a
-     * special case when container-managed authentication is used and the user
-     * is not authenticated; this will always cause validation to fail. Any
-     * validation errors are added to the wiki session's messages collection
+     * Validates a user profile, and appends any errors to the session errors list. If the profile is new, the password will be checked to
+     * make sure it isn't null. Otherwise, the password is checked for length and that it matches the value of the 'password2' HTTP
+     * parameter. Note that we have a special case when container-managed authentication is used and the user is not authenticated;
+     * this will always cause validation to fail. Any validation errors are added to the wiki session's messages collection
      * (see {@link WikiSession#getMessages()}.
+     *
      * @param context the current wiki context
      * @param profile the supplied UserProfile
      */
-    public void validateProfile( WikiContext context, UserProfile profile )
-    {
-        final boolean isNew = profile.isNew();
-        final WikiSession session = context.getWikiSession();
-        final InputValidator validator = new InputValidator( SESSION_MESSAGES, context );
-        final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-
-        //
-        //  Query the SpamFilter first
-        //
-        final FilterManager fm = m_engine.getFilterManager();
-        final List<PageFilter> ls = fm.getFilterList();
-        for( final PageFilter pf : ls )
-        {
-            if( pf instanceof SpamFilter )
-            {
-                if( ((SpamFilter)pf).isValidUserProfile( context, profile ) == false )
-                {
-                    session.addMessage( SESSION_MESSAGES, "Invalid userprofile" );
-                    return;
-                }
-                break;
-            }
-        }
-
-        // If container-managed auth and user not logged in, throw an error
-        if ( m_engine.getAuthenticationManager().isContainerAuthenticated()
-             && !context.getWikiSession().isAuthenticated() )
-        {
-            session.addMessage( SESSION_MESSAGES, rb.getString("security.error.createprofilebeforelogin") );
-        }
-
-        validator.validateNotNull( profile.getLoginName(), rb.getString("security.user.loginname") );
-        validator.validateNotNull( profile.getFullname(), rb.getString("security.user.fullname") );
-        validator.validate( profile.getEmail(), rb.getString("security.user.email"), InputValidator.EMAIL );
-
-        // If new profile, passwords must match and can't be null
-        if ( !m_engine.getAuthenticationManager().isContainerAuthenticated() )
-        {
-            final String password = profile.getPassword();
-            if ( password == null )
-            {
-                if ( isNew )
-                {
-                    session.addMessage( SESSION_MESSAGES, rb.getString("security.error.blankpassword") );
-                }
-            }
-            else
-            {
-                final HttpServletRequest request = context.getHttpRequest();
-                final String password2 = ( request == null ) ? null : request.getParameter( "password2" );
-                if ( !password.equals( password2 ) )
-                {
-                    session.addMessage( SESSION_MESSAGES, rb.getString("security.error.passwordnomatch") );
-                }
-            }
-        }
-
-        UserProfile otherProfile;
-        final String fullName = profile.getFullname();
-        final String loginName = profile.getLoginName();
-        final String email = profile.getEmail();
-
-        // It's illegal to use as a full name someone else's login name
-        try
-        {
-            otherProfile = getUserDatabase().find( fullName );
-            if ( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) )
-            {
-                final Object[] args = { fullName };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalfullname"), args ) );
-            }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
-
-        // It's illegal to use as a login name someone else's full name
-        try
-        {
-            otherProfile = getUserDatabase().find( loginName );
-            if ( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) )
-            {
-                final Object[] args = { loginName };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalloginname"), args ) );
-            }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
-
-        // It's illegal to use multiple accounts with the same email
-        try
-        {
-            otherProfile = getUserDatabase().findByEmail( email );
-            if ( otherProfile != null
-                && !profile.getUid().equals(otherProfile.getUid()) // Issue JSPWIKI-1042
-                && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ).equals( StringUtils.lowerCase(otherProfile.getEmail() ) ) )
-            {
-                final Object[] args = { email };
-                session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.email.taken"), args ) );
-            }
-        }
-        catch ( final NoSuchPrincipalException e)
-        { /* It's clean */ }
-    }
+    void validateProfile( WikiContext context, UserProfile profile );
 
     /**
      *  A helper method for returning all of the known WikiNames in this system.
@@ -551,215 +151,35 @@ public class UserManager {
      *  @return An Array of Principals
      *  @throws WikiSecurityException If for reason the names cannot be fetched
      */
-    public Principal[] listWikiNames()
-        throws WikiSecurityException
-    {
-        return getUserDatabase().getWikiNames();
-    }
-
-    /**
-     * This is a database that gets used if nothing else is available. It does nothing of note - it just mostly throws
-     * NoSuchPrincipalExceptions if someone tries to log in.
-     */
-    public static class DummyUserDatabase extends AbstractUserDatabase {
-
-        /**
-         * No-op.
-         * @param loginName the login name to delete
-         */
-        @Override
-        public void deleteByLoginName( String loginName ) {
-            // No operation
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByEmail(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByFullName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByLoginName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param uid the unique identifier to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param index the name to search for
-         * @return the user profile
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public UserProfile findByWikiName(final String index) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op.
-         * @return a zero-length array
-         */
-        @Override
-        public Principal[] getWikiNames() {
-            return new Principal[0];
-        }
-
-        /**
-         * No-op.
-         *
-         * @param engine the wiki engine
-         * @param props the properties used to initialize the wiki engine
-         */
-        @Override
-        public void initialize(final WikiEngine engine, final Properties props) {
-        }
-
-        /**
-         * No-op; always throws <code>NoSuchPrincipalException</code>.
-         * @param loginName the login name
-         * @param newName the proposed new login name
-         * @throws NoSuchPrincipalException always...
-         */
-        @Override
-        public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException {
-            throw new NoSuchPrincipalException("No user profiles available");
-        }
-
-        /**
-         * No-op.
-         * @param profile the user profile
-         */
-        @Override
-        public void save( final UserProfile profile ) {
-        }
-
-    }
+    Principal[] listWikiNames() throws WikiSecurityException;
 
     // events processing .......................................................
 
     /**
-     * Registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void addWikiEventListener( WikiEventListener listener )
-    {
-        WikiEventManager.addWikiEventListener( this, listener );
-    }
+    void addWikiEventListener( WikiEventListener listener );
 
     /**
-     * Un-registers a WikiEventListener with this instance.
-     * This is a convenience method.
+     * Un-registers a WikiEventListener with this instance. This is a convenience method.
+     *
      * @param listener the event listener
      */
-    public synchronized void removeWikiEventListener( WikiEventListener listener )
-    {
-        WikiEventManager.removeWikiEventListener( this, listener );
-    }
+    void removeWikiEventListener( WikiEventListener listener );
 
     /**
-     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object
-     *  to all registered listeners.
+     *  Fires a WikiSecurityEvent of the provided type, Principal and target Object to all registered listeners.
      *
      * @see org.apache.wiki.event.WikiSecurityEvent
      * @param type       the event type to be fired
      * @param session    the wiki session supporting the event
      * @param profile    the user profile (or array of user profiles), which may be <code>null</code>
      */
-    protected void fireEvent( int type, WikiSession session, Object profile )
-    {
-        if ( WikiEventManager.isListening(this) )
-        {
-            WikiEventManager.fireEvent(this,new WikiSecurityEvent(session,type,profile));
-        }
-    }
-
-    /**
-     *  Implements the JSON API for usermanager.
-     *  <p>
-     *  Even though this gets serialized whenever container shuts down/restarts, this gets reinstalled to the session when JSPWiki starts.
-     *  This means that it's not actually necessary to save anything.
-     */
-    public static final class JSONUserModule implements WikiAjaxServlet {
-
-		private volatile UserManager m_manager;
-
-        /**
-         *  Create a new JSONUserModule.
-         *  @param mgr Manager
-         */
-        public JSONUserModule( UserManager mgr )
-        {
-            m_manager = mgr;
-        }
-
-        @Override
-        public String getServletMapping() {
-        	return JSON_USERS;
-        }
-
-        @Override
-        public void service(HttpServletRequest req, HttpServletResponse resp, String actionName, List<String> params) throws ServletException, IOException {
-        	try {
-            	if( params.size() < 1 ) {
-            		return;
-            	}
-        		final String uid = params.get(0);
-	        	log.debug("uid="+uid);
-	        	if (StringUtils.isNotBlank(uid)) {
-		            final UserProfile prof = getUserInfo(uid);
-		            resp.getWriter().write(AjaxUtil.toJson(prof));
-	        	}
-        	} catch (final NoSuchPrincipalException e) {
-        		throw new ServletException(e);
-        	}
-        }
-
-        /**
-         *  Directly returns the UserProfile object attached to an uid.
-         *
-         *  @param uid The user id (e.g. WikiName)
-         *  @return A UserProfile object
-         *  @throws NoSuchPrincipalException If such a name does not exist.
-         */
-        public UserProfile getUserInfo( String uid ) throws NoSuchPrincipalException {
-            if( m_manager != null ) {
-                final UserProfile prof = m_manager.getUserDatabase().find( uid );
-                return prof;
-            }
-
-            throw new IllegalStateException("The manager is offline.");
+    default void fireEvent( final int type, final WikiSession session, final Object profile ) {
+        if( WikiEventManager.isListening( this ) ) {
+            WikiEventManager.fireEvent( this, new WikiSecurityEvent( session, type, profile ) );
         }
     }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
index df51c10..78b030d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
@@ -20,7 +20,7 @@ package org.apache.wiki.auth.user;
 
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiPrincipal;
@@ -37,12 +37,11 @@ import java.util.Properties;
 import java.util.UUID;
 
 /**
- * Abstract UserDatabase class that provides convenience methods for finding
- * profiles, building Principal collections and hashing passwords.
+ * Abstract UserDatabase class that provides convenience methods for finding profiles, building Principal collections and hashing passwords.
+ *
  * @since 2.3
  */
-public abstract class AbstractUserDatabase implements UserDatabase
-{
+public abstract class AbstractUserDatabase implements UserDatabase {
 
     protected static final Logger log = Logger.getLogger( AbstractUserDatabase.class );
     protected static final String SHA_PREFIX = "{SHA}";
@@ -57,46 +56,33 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * @param index the login name, full name, or wiki name
      * @see org.apache.wiki.auth.user.UserDatabase#find(java.lang.String)
      */
-    public UserProfile find( String index ) throws NoSuchPrincipalException
-    {
+    @Override public UserProfile find( final String index ) throws NoSuchPrincipalException {
         UserProfile profile = null;
 
         // Try finding by full name
-        try
-        {
+        try {
             profile = findByFullName( index );
+        } catch( final NoSuchPrincipalException e ) {
         }
-        catch ( NoSuchPrincipalException e )
-        {
-        }
-        if ( profile != null )
-        {
+        if( profile != null ) {
             return profile;
         }
 
         // Try finding by wiki name
-        try
-        {
+        try {
             profile = findByWikiName( index );
+        } catch( final NoSuchPrincipalException e ) {
         }
-        catch ( NoSuchPrincipalException e )
-        {
-        }
-        if ( profile != null )
-        {
+        if( profile != null ) {
             return profile;
         }
 
         // Try finding by login name
-        try
-        {
+        try {
             profile = findByLoginName( index );
+        } catch( final NoSuchPrincipalException e ) {
         }
-        catch ( NoSuchPrincipalException e )
-        {
-        }
-        if ( profile != null )
-        {
+        if( profile != null ) {
             return profile;
         }
 
@@ -107,25 +93,25 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * {@inheritDoc}
      * @see org.apache.wiki.auth.user.UserDatabase#findByEmail(java.lang.String)
      */
-    public abstract UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
+    @Override public abstract UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
 
     /**
      * {@inheritDoc}
      * @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
      */
-    public abstract UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
+    @Override public abstract UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
 
     /**
      * {@inheritDoc}
      * @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
      */
-    public abstract UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
+    @Override public abstract UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
 
     /**
      * {@inheritDoc}
      * @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(java.lang.String)
      */
-    public abstract UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
+    @Override public abstract UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
 
     /**
      * <p>Looks up the Principals representing a user from the user database. These
@@ -142,38 +128,31 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * @see org.apache.wiki.auth.user.UserDatabase#getPrincipals(java.lang.String)
      * @throws NoSuchPrincipalException {@inheritDoc}
      */
-    public Principal[] getPrincipals( String identifier ) throws NoSuchPrincipalException
+    @Override public Principal[] getPrincipals( final String identifier ) throws NoSuchPrincipalException
     {
-        try
-        {
-            UserProfile profile = findByLoginName( identifier );
-            ArrayList<Principal> principals = new ArrayList<Principal>();
-            if ( profile.getLoginName() != null && profile.getLoginName().length() > 0 )
-            {
+        try {
+            final UserProfile profile = findByLoginName( identifier );
+            final ArrayList< Principal > principals = new ArrayList<>();
+            if( profile.getLoginName() != null && profile.getLoginName().length() > 0 ) {
                 principals.add( new WikiPrincipal( profile.getLoginName(), WikiPrincipal.LOGIN_NAME ) );
             }
-            if ( profile.getFullname() != null && profile.getFullname().length() > 0 )
-            {
+            if( profile.getFullname() != null && profile.getFullname().length() > 0 ) {
                 principals.add( new WikiPrincipal( profile.getFullname(), WikiPrincipal.FULL_NAME ) );
             }
-            if ( profile.getWikiName() != null && profile.getWikiName().length() > 0 )
-            {
+            if( profile.getWikiName() != null && profile.getWikiName().length() > 0 ) {
                 principals.add( new WikiPrincipal( profile.getWikiName(), WikiPrincipal.WIKI_NAME ) );
             }
-            return principals.toArray( new Principal[principals.size()] );
-        }
-        catch( NoSuchPrincipalException e )
-        {
+            return principals.toArray( new Principal[ principals.size() ] );
+        } catch( final NoSuchPrincipalException e ) {
             throw e;
         }
     }
 
     /**
      * {@inheritDoc}
-     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine, java.util.Properties)
+     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      */
-    public abstract void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException,
-            WikiSecurityException;
+    @Override public abstract void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
 
     /**
      * Factory method that instantiates a new DefaultUserProfile with a new, distinct
@@ -181,7 +160,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * 
      * @return A new, empty profile.
      */
-    public UserProfile newProfile()
+    @Override public UserProfile newProfile()
     {
         return DefaultUserProfile.newProfile( this );
     }
@@ -190,66 +169,51 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * {@inheritDoc}
      * @see org.apache.wiki.auth.user.UserDatabase#save(org.apache.wiki.auth.user.UserProfile)
      */
-    public abstract void save( UserProfile profile ) throws WikiSecurityException;
+    @Override public abstract void save( UserProfile profile ) throws WikiSecurityException;
 
     /**
-     * Validates the password for a given user. If the user does not exist in
-     * the user database, this method always returns <code>false</code>. If
-     * the user exists, the supplied password is compared to the stored
-     * password. Note that if the stored password's value starts with
-     * <code>{SHA}</code>, the supplied password is hashed prior to the
-     * comparison.
+     * Validates the password for a given user. If the user does not exist in the user database, this method always returns
+     * <code>false</code>. If the user exists, the supplied password is compared to the stored password. Note that if the stored password's
+     * value starts with <code>{SHA}</code>, the supplied password is hashed prior to the comparison.
+     *
      * @param loginName the user's login name
      * @param password the user's password (obtained from user input, e.g., a web form)
-     * @return <code>true</code> if the supplied user password matches the
-     * stored password
-     * @see org.apache.wiki.auth.user.UserDatabase#validatePassword(java.lang.String,
-     *      java.lang.String)
+     * @return <code>true</code> if the supplied user password matches the stored password
+     * @see org.apache.wiki.auth.user.UserDatabase#validatePassword(java.lang.String, java.lang.String)
      */
-    public boolean validatePassword( String loginName, String password )
-    {
-        String hashedPassword;
-        try
-        {
-            UserProfile profile = findByLoginName( loginName );
+    @Override public boolean validatePassword( final String loginName, final String password ) {
+        final String hashedPassword;
+        try {
+            final UserProfile profile = findByLoginName( loginName );
             String storedPassword = profile.getPassword();
-            
+
             // Is the password stored as a salted hash (the new 2.8 format?)
-            boolean newPasswordFormat = storedPassword.startsWith( SSHA_PREFIX );
-            
+            final boolean newPasswordFormat = storedPassword.startsWith( SSHA_PREFIX );
+
             // If new format, verify the hash
-            if ( newPasswordFormat )
-            {
+            if( newPasswordFormat ) {
                 hashedPassword = getHash( password );
                 return CryptoUtil.verifySaltedPassword( password.getBytes( StandardCharsets.UTF_8 ), storedPassword );
             }
 
             // If old format, verify using the old SHA verification algorithm
-            if ( storedPassword.startsWith( SHA_PREFIX ) )
-            {
+            if( storedPassword.startsWith( SHA_PREFIX ) ) {
                 storedPassword = storedPassword.substring( SHA_PREFIX.length() );
             }
             hashedPassword = getOldHash( password );
-            boolean verified = hashedPassword.equals( storedPassword ); 
-            
+            final boolean verified = hashedPassword.equals( storedPassword );
+
             // If in the old format and password verified, upgrade the hash to SSHA
-            if ( verified )
-            {
+            if( verified ) {
                 profile.setPassword( password );
                 save( profile );
             }
-            
+
             return verified;
-        }
-        catch( NoSuchPrincipalException e )
-        {
-        }
-        catch( NoSuchAlgorithmException e )
-        {
+        } catch( final NoSuchPrincipalException e ) {
+        } catch( final NoSuchAlgorithmException e ) {
             log.error( "Unsupported algorithm: " + e.getMessage() );
-        }
-        catch( WikiSecurityException e )
-        {
+        } catch( final WikiSecurityException e ) {
             log.error( "Could not upgrade SHA password to SSHA because profile could not be saved. Reason: " + e.getMessage(), e );
         }
         return false;
@@ -261,21 +225,17 @@ public abstract class AbstractUserDatabase implements UserDatabase
      * @param db The database for which the UID should be generated.
      * @return A random, unique UID.
      */
-    protected static String generateUid( UserDatabase db ) {
+    protected static String generateUid( final UserDatabase db ) {
         // Keep generating UUIDs until we find one that doesn't collide
-        String uid = null;
+        String uid;
         boolean collision;
         
-        do 
-        {
+        do {
             uid = UUID.randomUUID().toString();
             collision = true;
-            try
-            {
+            try {
                 db.findByUid( uid );
-            }
-            catch ( NoSuchPrincipalException e )
-            {
+            } catch ( final NoSuchPrincipalException e ) {
                 collision = false;
             }
         } 
@@ -284,9 +244,9 @@ public abstract class AbstractUserDatabase implements UserDatabase
     }
     
     /**
-     * Private method that calculates the salted SHA-1 hash of a given
-     * <code>String</code>. Note that as of JSPWiki 2.8, this method calculates
-     * a <em>salted</em> hash rather than a plain hash.
+     * Private method that calculates the salted SHA-1 hash of a given <code>String</code>. Note that as of JSPWiki 2.8, this method
+     * calculates a <em>salted</em> hash rather than a plain hash.
+     *
      * @param text the text to hash
      * @return the result hash
      */
@@ -300,8 +260,8 @@ public abstract class AbstractUserDatabase implements UserDatabase
     }
 
     /**
-     * Private method that calculates the SHA-1 hash of a given
-     * <code>String</code>
+     * Private method that calculates the SHA-1 hash of a given <code>String</code>
+     *
      * @param text the text to hash
      * @return the result hash
      * @deprecated this method is retained for backwards compatibility purposes; use {@link #getHash(String)} instead
@@ -310,7 +270,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
         try {
             final MessageDigest md = MessageDigest.getInstance( "SHA" );
             md.update( text.getBytes( StandardCharsets.UTF_8 ) );
-            byte[] digestedBytes = md.digest();
+            final byte[] digestedBytes = md.digest();
             return ByteUtils.bytes2hex( digestedBytes );
         } catch( final NoSuchAlgorithmException e ) {
             log.error( "Error creating SHA password hash:" + e.getMessage() );
@@ -320,6 +280,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
 
     /**
      * Parses a long integer from a supplied string, or returns 0 if not parsable.
+     *
      * @param value the string to parse
      * @return the value parsed
      */
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
index 53da585..93ca181 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
@@ -19,7 +19,7 @@
 package org.apache.wiki.auth.user;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiPrincipal;
@@ -181,13 +181,7 @@ import java.util.Set;
  * </p>
  * <p>
  * JDBCUserDatabase commits changes as transactions if the back-end database
- * supports them. If the database supports transactions, user profile changes
- * are saved to permanent storage only when the {@link #commit()} method is
- * called. If the database does <em>not</em> support transactions, then
- * changes are made immediately (during the {@link #save(UserProfile)} method),
- * and the {@linkplain #commit()} method no-ops. Thus, callers should always
- * call the {@linkplain #commit()} method after saving a profile to guarantee
- * that changes are applied.
+ * supports them. Changes are made immediately (during the {@link #save(UserProfile)} method).
  * </p>
  * 
  * @since 2.3
@@ -316,13 +310,13 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @param loginName the login name of the user profile that shall be deleted
      */
     @Override
-    public void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException {
+    public void deleteByLoginName( final String loginName ) throws NoSuchPrincipalException, WikiSecurityException {
         // Get the existing user; if not found, throws NoSuchPrincipalException
         findByLoginName( loginName );
 
-        try( Connection conn = m_ds.getConnection() ; 
-             PreparedStatement ps1 = conn.prepareStatement( m_deleteUserByLoginName ); 
-             PreparedStatement ps2 = conn.prepareStatement( m_deleteRoleByLoginName ) )
+        try( final Connection conn = m_ds.getConnection() ;
+             final PreparedStatement ps1 = conn.prepareStatement( m_deleteUserByLoginName );
+             final PreparedStatement ps2 = conn.prepareStatement( m_deleteRoleByLoginName ) )
         {
             // Open the database connection
             if( m_supportsCommits ) {
@@ -341,7 +335,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
             if( m_supportsCommits ) {
                 conn.commit();
             }
-        } catch( SQLException e ) {
+        } catch( final SQLException e ) {
             throw new WikiSecurityException( e.getMessage(), e );
         }
     }
@@ -350,7 +344,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#findByEmail(java.lang.String)
      */
     @Override
-    public UserProfile findByEmail( String index ) throws NoSuchPrincipalException {
+    public UserProfile findByEmail( final String index ) throws NoSuchPrincipalException {
         return findByPreparedStatement( m_findByEmail, index );
     }
 
@@ -358,7 +352,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
      */
     @Override
-    public UserProfile findByFullName( String index ) throws NoSuchPrincipalException {
+    public UserProfile findByFullName( final String index ) throws NoSuchPrincipalException {
         return findByPreparedStatement( m_findByFullName, index );
     }
 
@@ -366,7 +360,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
      */
     @Override
-    public UserProfile findByLoginName( String index ) throws NoSuchPrincipalException {
+    public UserProfile findByLoginName( final String index ) throws NoSuchPrincipalException {
         return findByPreparedStatement( m_findByLoginName, index );
     }
 
@@ -374,7 +368,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(String)
      */
     @Override
-    public UserProfile findByUid( String uid ) throws NoSuchPrincipalException {
+    public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
         return findByPreparedStatement( m_findByUid, uid );
     }
 
@@ -382,7 +376,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(String)
      */
     @Override
-    public UserProfile findByWikiName( String index ) throws NoSuchPrincipalException {
+    public UserProfile findByWikiName( final String index ) throws NoSuchPrincipalException {
         return findByPreparedStatement( m_findByWikiName, index );
     }
 
@@ -395,21 +389,21 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      */
     @Override
     public Principal[] getWikiNames() throws WikiSecurityException {
-        Set<Principal> principals = new HashSet<>();
-        try( Connection conn = m_ds.getConnection();
-             PreparedStatement ps = conn.prepareStatement( m_findAll );
-             ResultSet rs = ps.executeQuery() )
+        final Set<Principal> principals = new HashSet<>();
+        try( final Connection conn = m_ds.getConnection();
+             final PreparedStatement ps = conn.prepareStatement( m_findAll );
+             final ResultSet rs = ps.executeQuery() )
         {
             while ( rs.next() ) {
-                String wikiName = rs.getString( m_wikiName );
+                final String wikiName = rs.getString( m_wikiName );
                 if( wikiName == null ) {
                     log.warn( "Detected null wiki name in XMLUserDataBase. Check your user database." );
                 } else {
-                    Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
+                    final Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
                     principals.add( principal );
                 }
             }
-        } catch( SQLException e ) {
+        } catch( final SQLException e ) {
             throw new WikiSecurityException( e.getMessage(), e );
         }
 
@@ -417,19 +411,18 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
     }
 
     /**
-     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine,
-     *      java.util.Properties)
+     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      */
     @Override
-    public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException {
-        String jndiName = props.getProperty( PROP_DB_DATASOURCE, DEFAULT_DB_JNDI_NAME );
+    public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException {
+        final String jndiName = props.getProperty( PROP_DB_DATASOURCE, DEFAULT_DB_JNDI_NAME );
         try {
-            Context initCtx = new InitialContext();
-            Context ctx = (Context) initCtx.lookup( "java:comp/env" );
+            final Context initCtx = new InitialContext();
+            final Context ctx = (Context) initCtx.lookup( "java:comp/env" );
             m_ds = (DataSource) ctx.lookup( jndiName );
 
             // Prepare the SQL selectors
-            String userTable = props.getProperty( PROP_DB_TABLE, DEFAULT_DB_TABLE );
+            final String userTable = props.getProperty( PROP_DB_TABLE, DEFAULT_DB_TABLE );
             m_email = props.getProperty( PROP_DB_EMAIL, DEFAULT_DB_EMAIL );
             m_fullName = props.getProperty( PROP_DB_FULL_NAME, DEFAULT_DB_FULL_NAME );
             m_lockExpiry = props.getProperty( PROP_DB_LOCK_EXPIRY, DEFAULT_DB_LOCK_EXPIRY );
@@ -475,8 +468,8 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                               + "WHERE " + m_loginName + "=?";
 
             // Prepare the role insert SQL
-            String roleTable = props.getProperty( PROP_DB_ROLE_TABLE, DEFAULT_DB_ROLE_TABLE );
-            String role = props.getProperty( PROP_DB_ROLE, DEFAULT_DB_ROLE );
+            final String roleTable = props.getProperty( PROP_DB_ROLE_TABLE, DEFAULT_DB_ROLE_TABLE );
+            final String role = props.getProperty( PROP_DB_ROLE, DEFAULT_DB_ROLE );
             m_insertRole = "INSERT INTO " + roleTable + " (" + m_loginName + "," + role + ") VALUES (?,?)";
             m_findRoles = "SELECT * FROM " + roleTable + " WHERE " + m_loginName + "=?";
 
@@ -490,28 +483,28 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
             m_renameProfile = "UPDATE " + userTable + " SET " + m_loginName + "=?," + m_modified + "=? WHERE " + m_loginName
                               + "=?";
             m_renameRoles = "UPDATE " + roleTable + " SET " + m_loginName + "=? WHERE " + m_loginName + "=?";
-        } catch( NamingException e ) {
+        } catch( final NamingException e ) {
             log.error( "JDBCUserDatabase initialization error: " + e.getMessage() );
             throw new NoRequiredPropertyException( PROP_DB_DATASOURCE, "JDBCUserDatabase initialization error: " + e.getMessage() );
         }
 
         // Test connection by doing a quickie select
-        try( Connection conn = m_ds.getConnection(); PreparedStatement ps = conn.prepareStatement( m_findAll ) ) {
-        } catch( SQLException e ) {
+        try( final Connection conn = m_ds.getConnection(); final PreparedStatement ps = conn.prepareStatement( m_findAll ) ) {
+        } catch( final SQLException e ) {
             log.error( "DB connectivity error: " + e.getMessage() );
             throw new WikiSecurityException("DB connectivity error: " + e.getMessage(), e );
         }
         log.info( "JDBCUserDatabase initialized from JNDI DataSource: " + jndiName );
 
         // Determine if the datasource supports commits
-        try( Connection conn = m_ds.getConnection() ) {
-            DatabaseMetaData dmd = conn.getMetaData();
+        try( final Connection conn = m_ds.getConnection() ) {
+            final DatabaseMetaData dmd = conn.getMetaData();
             if( dmd.supportsTransactions() ) {
                 m_supportsCommits = true;
                 conn.setAutoCommit( false );
                 log.info( "JDBCUserDatabase supports transactions. Good; we will use them." );
             }
-        } catch( SQLException e ) {
+        } catch( final SQLException e ) {
             log.warn( "JDBCUserDatabase warning: user database doesn't seem to support transactions. Reason: " + e.getMessage() );
         }
     }
@@ -520,30 +513,30 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#rename(String, String)
      */
     @Override
-    public void rename( String loginName, String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException {
+    public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException {
         // Get the existing user; if not found, throws NoSuchPrincipalException
-        UserProfile profile = findByLoginName( loginName );
+        final UserProfile profile = findByLoginName( loginName );
 
         // Get user with the proposed name; if found, it's a collision
         try {
-            UserProfile otherProfile = findByLoginName( newName );
+            final UserProfile otherProfile = findByLoginName( newName );
             if( otherProfile != null ) {
                 throw new DuplicateUserException( "security.error.cannot.rename", newName );
             }
-        } catch( NoSuchPrincipalException e ) {
+        } catch( final NoSuchPrincipalException e ) {
             // Good! That means it's safe to save using the new name
         }
 
-        try( Connection conn = m_ds.getConnection(); 
-             PreparedStatement ps1 = conn.prepareStatement( m_renameProfile );
-             PreparedStatement ps2 = conn.prepareStatement( m_renameRoles ) )
+        try( final Connection conn = m_ds.getConnection();
+             final PreparedStatement ps1 = conn.prepareStatement( m_renameProfile );
+             final PreparedStatement ps2 = conn.prepareStatement( m_renameRoles ) )
         {
             if( m_supportsCommits ) {
                 conn.setAutoCommit( false );
             }
 
-            Timestamp ts = new Timestamp( System.currentTimeMillis() );
-            Date modDate = new Date( ts.getTime() );
+            final Timestamp ts = new Timestamp( System.currentTimeMillis() );
+            final Date modDate = new Date( ts.getTime() );
 
             // Change the login ID for the user record
             ps1.setString( 1, newName );
@@ -564,7 +557,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
             if( m_supportsCommits ) {
                 conn.commit();
             }
-        } catch( SQLException e ) {
+        } catch( final SQLException e ) {
             throw new WikiSecurityException( e.getMessage(), e );
         }
     }
@@ -573,23 +566,23 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @see org.apache.wiki.auth.user.UserDatabase#save(org.apache.wiki.auth.user.UserProfile)
      */
     @Override
-    public void save( UserProfile profile ) throws WikiSecurityException {
-        String initialRole = "Authenticated";
+    public void save( final UserProfile profile ) throws WikiSecurityException {
+        final String initialRole = "Authenticated";
 
         // Figure out which prepared statement to use & execute it
-        String loginName = profile.getLoginName();
+        final String loginName = profile.getLoginName();
         UserProfile existingProfile = null;
 
         try {
             existingProfile = findByLoginName( loginName );
-        } catch( NoSuchPrincipalException e ) {
+        } catch( final NoSuchPrincipalException e ) {
             // Existing profile will be null
         }
 
         // Get a clean password from the passed profile.
         // Blank password is the same as null, which means we re-use the existing one.
         String password = profile.getPassword();
-        String existingPassword = (existingProfile == null) ? null : existingProfile.getPassword();
+        final String existingPassword = (existingProfile == null) ? null : existingProfile.getPassword();
         if( NOTHING.equals( password ) ) {
             password = null;
         }
@@ -602,19 +595,19 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
             password = getHash( password );
         }
 
-        try( Connection conn = m_ds.getConnection();
-             PreparedStatement ps1 = conn.prepareStatement( m_insertProfile );
-             PreparedStatement ps2 = conn.prepareStatement( m_findRoles );
-             PreparedStatement ps3 = conn.prepareStatement( m_insertRole );
-             PreparedStatement ps4 = conn.prepareStatement( m_updateProfile ) )
+        try( final Connection conn = m_ds.getConnection();
+             final PreparedStatement ps1 = conn.prepareStatement( m_insertProfile );
+             final PreparedStatement ps2 = conn.prepareStatement( m_findRoles );
+             final PreparedStatement ps3 = conn.prepareStatement( m_insertRole );
+             final PreparedStatement ps4 = conn.prepareStatement( m_updateProfile ) )
         {
             if( m_supportsCommits ) {
                 conn.setAutoCommit( false );
             }
 
-            Timestamp ts = new Timestamp( System.currentTimeMillis() );
-            Date modDate = new Date( ts.getTime() );
-            java.sql.Date lockExpiry = profile.getLockExpiry() == null ? null : new java.sql.Date( profile.getLockExpiry().getTime() );
+            final Timestamp ts = new Timestamp( System.currentTimeMillis() );
+            final Date modDate = new Date( ts.getTime() );
+            final java.sql.Date lockExpiry = profile.getLockExpiry() == null ? null : new java.sql.Date( profile.getLockExpiry().getTime() );
             if( existingProfile == null )
             {
                 // User is new: insert new user record
@@ -627,7 +620,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                 ps1.setString( 7, profile.getLoginName() );
                 try {
                     ps1.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
-                } catch ( IOException e ) {
+                } catch ( final IOException e ) {
                     throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
                 }
                 ps1.setTimestamp( 9, ts );
@@ -636,7 +629,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                 // Insert new role record
                 ps2.setString( 1, profile.getLoginName() );
                 int roles = 0;
-                try ( ResultSet rs = ps2.executeQuery() ) {
+                try ( final ResultSet rs = ps2.executeQuery() ) {
                     while ( rs.next() ) {
                         roles++;
                     }
@@ -663,7 +656,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                 {
                     ps4.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
                 }
-                catch ( IOException e )
+                catch ( final IOException e )
                 {
                     throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
                 }
@@ -679,7 +672,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                 conn.commit();
             }
         }
-        catch( SQLException e )
+        catch( final SQLException e )
         {
             throw new WikiSecurityException( e.getMessage(), e );
         }
@@ -694,12 +687,12 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
      * @return the resolved UserProfile
      * @throws SQLException
      */
-    private UserProfile findByPreparedStatement( String sql, Object index ) throws NoSuchPrincipalException
+    private UserProfile findByPreparedStatement( final String sql, final Object index ) throws NoSuchPrincipalException
     {
         UserProfile profile = null;
         boolean found = false;
         boolean unique = true;
-        try( Connection conn = m_ds.getConnection(); PreparedStatement ps = conn.prepareStatement( sql ) ) {
+        try( final Connection conn = m_ds.getConnection(); final PreparedStatement ps = conn.prepareStatement( sql ) ) {
             if( m_supportsCommits ) {
                 conn.setAutoCommit( false );
             }
@@ -714,7 +707,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
             }
             
             // Go and get the record!
-            try ( ResultSet rs = ps.executeQuery() ) {
+            try ( final ResultSet rs = ps.executeQuery() ) {
                 while ( rs.next() ) {
                     if( profile != null ) {
                         unique = false;
@@ -731,25 +724,25 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
                     profile.setEmail( rs.getString( m_email ) );
                     profile.setFullname( rs.getString( m_fullName ) );
                     profile.setLastModified( rs.getTimestamp( m_modified ) );
-                    Date lockExpiry = rs.getDate( m_lockExpiry );
+                    final Date lockExpiry = rs.getDate( m_lockExpiry );
                     profile.setLockExpiry( rs.wasNull() ? null : lockExpiry );
                     profile.setLoginName( rs.getString( m_loginName ) );
                     profile.setPassword( rs.getString( m_password ) );
                     
                     // Fetch the user attributes
-                    String rawAttributes = rs.getString( m_attributes );
+                    final String rawAttributes = rs.getString( m_attributes );
                     if ( rawAttributes != null ) {
                         try {
-                            Map<String,? extends Serializable> attributes = Serializer.deserializeFromBase64( rawAttributes );
+                            final Map<String,? extends Serializable> attributes = Serializer.deserializeFromBase64( rawAttributes );
                             profile.getAttributes().putAll( attributes );
-                        } catch ( IOException e ) {
+                        } catch ( final IOException e ) {
                             log.error( "Could not parse user profile attributes!", e );
                         }
                     }
                     found = true;
                 }
             }
-        } catch( SQLException e ) {
+        } catch( final SQLException e ) {
             throw new NoSuchPrincipalException( e.getMessage() );
         }
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
index 1312ecc..c8928cc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
@@ -18,103 +18,89 @@
  */
 package org.apache.wiki.auth.user;
 
-import java.security.Principal;
-import java.util.Properties;
-
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiSecurityException;
 
+import java.security.Principal;
+import java.util.Properties;
+
 /**
  * Defines an interface for loading, persisting and storing users.
+ *
  * @since 2.3
  */
-public interface UserDatabase
-{
+public interface UserDatabase {
 
     /**
-     * Looks up and deletes the first {@link UserProfile} in the user database
-     * that matches a profile having a given login name. If the user database
-     * does not contain a user with a matching attribute, throws a
-     * {@link NoSuchPrincipalException}. This method is intended to be atomic;
-     * results cannot be partially committed. If the commit fails, it should
-     * roll back its state appropriately. Implementing classes that persist
-     * to the file system may wish to make this method <code>synchronized</code>.
+     * Looks up and deletes the first {@link UserProfile} in the user database that matches a profile having a given login name. If the
+     * user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}. This method is intended
+     * to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state appropriately. Implementing
+     * classes that persist to the file system may wish to make this method <code>synchronized</code>.
+     *
      * @param loginName the login name of the user profile that shall be deleted
      */
     void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException;
 
     /**
      * <p>
-     * Looks up the Principals representing a user from the user database. These
-     * are defined as a set of Principals manufactured from the login name, full
-     * name, and wiki name. The order of the Principals returned is not
-     * significant. If the user database does not contain a user with the
-     * supplied identifier, throws a {@link NoSuchPrincipalException}.
+     * Looks up the Principals representing a user from the user database. These are defined as a set of Principals manufactured from the
+     * login name, full name, and wiki name. The order of the Principals returned is not significant. If the user database does not contain
+     * a user with the supplied identifier, throws a {@link NoSuchPrincipalException}.
      * </p>
      * <p>
-     * Note that if an implememtation wishes to mark one of the returned
-     * Principals as representing the user's common name, it should instantiate
-     * this Principal using
-     * {@link org.apache.wiki.auth.WikiPrincipal#WikiPrincipal(String, String)}
-     * with the <code>type</code> parameter set to
-     * {@link org.apache.wiki.auth.WikiPrincipal#WIKI_NAME}. The method
-     * {@link org.apache.wiki.WikiSession#getUserPrincipal()} will return this
-     * principal as the "primary" principal. Note that this method can also be
-     * used to mark a WikiPrincipal as a login name or a wiki name.
+     * Note that if an implememtation wishes to mark one of the returned Principals as representing the user's common name, it should
+     * instantiate this Principal using {@link org.apache.wiki.auth.WikiPrincipal#WikiPrincipal(String, String)} with the <code>type</code>
+     * parameter set to {@link org.apache.wiki.auth.WikiPrincipal#WIKI_NAME}. The method
+     * {@link org.apache.wiki.WikiSession#getUserPrincipal()} will return this principal as the "primary" principal. Note that this method
+     * can also be used to mark a WikiPrincipal as a login name or a wiki name.
      * </p>
-     * @param identifier the name of the user to retrieve; this corresponds to
-     *            value returned by the user profile's
-     *            {@link UserProfile#getLoginName()} method.
+     *
+     * @param identifier the name of the user to retrieve; this corresponds to value returned by the user profile's {@link UserProfile#getLoginName()} method.
      * @return the array of Principals representing the user's identities
      */
     Principal[] getPrincipals( String identifier ) throws NoSuchPrincipalException;
 
     /**
-     * Returns all WikiNames that are stored in the UserDatabase
-     * as an array of Principal objects. If the database does not
-     * contain any profiles, this method will return a zero-length
-     * array.
+     * Returns all WikiNames that are stored in the UserDatabase as an array of Principal objects. If the database does not
+     * contain any profiles, this method will return a zero-length array.
+     *
      * @return the WikiNames
      */
     Principal[] getWikiNames() throws WikiSecurityException;
 
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that whose login name, full name, or wiki name matches the supplied
-     * string. This method provides a "forgiving" search algorithm for resolving
-     * Principal names when the exact profile attribute that supplied the name
-     * is unknown.
+     * Looks up and returns the first {@link UserProfile} in the user database that whose login name, full name, or wiki name matches the
+     * supplied string. This method provides a "forgiving" search algorithm for resolving Principal names when the exact profile attribute
+     * that supplied the name is unknown.
+     *
      * @param index the login name, full name, or wiki name
      */
     UserProfile find( String index ) throws NoSuchPrincipalException;
 
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that matches a profile having a given e-mail address. If the user
-     * database does not contain a user with a matching attribute, throws a
-     * {@link NoSuchPrincipalException}.
+     * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given e-mail address. If
+     * the user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+     *
      * @param index the e-mail address of the desired user profile
      * @return the user profile
      */
     UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
 
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that matches a profile having a given login name. If the user database
-     * does not contain a user with a matching attribute, throws a
-     * {@link NoSuchPrincipalException}.
+     * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given login name. If the
+     * user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+     *
      * @param index the login name of the desired user profile
      * @return the user profile
      */
     UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
 
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that matches a profile having a given unique ID (uid). If the user database
-     * does not contain a user with a unique ID, it throws a
-     * {@link NoSuchPrincipalException}.
+     * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given unique ID (uid). If
+     * the user database does not contain a user with a unique ID, it throws a {@link NoSuchPrincipalException}.
+     *
      * @param uid the unique identifier of the desired user profile
      * @return the user profile
      * @since 2.8
@@ -122,95 +108,75 @@ public interface UserDatabase
     UserProfile findByUid( String uid ) throws NoSuchPrincipalException;
     
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that matches a profile having a given wiki name. If the user database
-     * does not contain a user with a matching attribute, throws a
-     * {@link NoSuchPrincipalException}.
+     * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given wiki name. If the user
+     * database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+     *
      * @param index the wiki name of the desired user profile
      * @return the user profile
      */
     UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
 
     /**
-     * Looks up and returns the first {@link UserProfile} in the user database
-     * that matches a profile having a given full name. If the user database
-     * does not contain a user with a matching attribute, throws a
-     * {@link NoSuchPrincipalException}.
+     * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given full name. If the user
+     * database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+     *
      * @param index the fill name of the desired user profile
      * @return the user profile
      */
     UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
 
-    /**
-     * Initializes the user database based on values from a Properties object.
-     */
-    void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
+    /** Initializes the user database based on values from a Properties object. */
+    void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
 
     /**
-     * Factory method that instantiates a new user profile.
-     * The {@link UserProfile#isNew()} method of profiles created using
+     * Factory method that instantiates a new user profile. The {@link UserProfile#isNew()} method of profiles created using
      * this method should return <code>true</code>.
      */
     UserProfile newProfile();
 
     /**
-     * <p>Renames a {@link UserProfile} in the user database by changing
-     * the profile's login name. Because the login name is the profile's unique
-     * identifier, implementations should verify that the identifier is
-     * "safe" to change before actually changing it. Specifically: the profile
-     * with the supplied login name must already exist, and the proposed new
-     * name must not be in use by another profile.</p>
-     * <p>This method is intended to be atomic; results cannot be partially committed.
-     * If the commit fails, it should roll back its state appropriately.
-     * Implementing classes that persist to the file system may wish to make
-     * this method <code>synchronized</code>.</p>
+     * <p>Renames a {@link UserProfile} in the user database by changing the profile's login name. Because the login name is the profile's
+     * unique identifier, implementations should verify that the identifier is "safe" to change before actually changing it. Specifically:
+     * the profile with the supplied login name must already exist, and the proposed new name must not be in use by another profile.</p>
+     * <p>This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state
+     * appropriately. Implementing classes that persist to the file system may wish to make this method <code>synchronized</code>.</p>
+     *
      * @param loginName the existing login name for the profile
      * @param newName the proposed new login name
-     * @throws NoSuchPrincipalException if the user profile identified by
-     * <code>loginName</code> does not exist
-     * @throws DuplicateUserException if another user profile with the
-     * proposed new login name already exists
-     * @throws WikiSecurityException if the profile cannot be renamed for
-     * any reason, such as an I/O error, database connection failure
+     * @throws NoSuchPrincipalException if the user profile identified by <code>loginName</code> does not exist
+     * @throws DuplicateUserException if another user profile with the proposed new login name already exists
+     * @throws WikiSecurityException if the profile cannot be renamed for any reason, such as an I/O error, database connection failure
      * or lack of support for renames.
      */
     void rename( String loginName, String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException;
 
     /**
      * <p>
-     * Saves a {@link UserProfile}to the user database, overwriting the
-     * existing profile if it exists. The user name under which the profile
-     * should be saved is returned by the supplied profile's
-     * {@link UserProfile#getLoginName()} method.
+     * Saves a {@link UserProfile}to the user database, overwriting the existing profile if it exists. The user name under which the profile
+     * should be saved is returned by the supplied profile's {@link UserProfile#getLoginName()} method.
      * </p>
      * <p>
-     * The database implementation is responsible for detecting potential
-     * duplicate user profiles; specifically, the login name, wiki name, and
-     * full name must be unique. The implementation is not required to check for
-     * validity of passwords or e-mail addresses. Special case: if the profile
-     * already exists and the password is null, it should retain its previous
-     * value, rather than being set to null.
+     * The database implementation is responsible for detecting potential duplicate user profiles; specifically, the login name, wiki name,
+     * and full name must be unique. The implementation is not required to check for validity of passwords or e-mail addresses. Special
+     * case: if the profile already exists and the password is null, it should retain its previous value, rather than being set to null.
      * </p>
-     * <p>Implementations are <em>required</em> to time-stamp the creation
-     * or modification fields of the UserProfile./p>
-     * <p>This method is intended to be atomic; results cannot be partially committed.
-     * If the commit fails, it should roll back its state appropriately.
-     * Implementing classes that persist to the file system may wish to make
-     * this method <code>synchronized</code>.</p>
+     * <p>Implementations are <em>required</em> to time-stamp the creation or modification fields of the UserProfile./p>
+     * <p>This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state
+     * appropriately. Implementing classes that persist to the file system may wish to make this method <code>synchronized</code>.</p>
+     *
      * @param profile the user profile to save
      * @throws WikiSecurityException if the profile cannot be saved
      */
     void save( UserProfile profile ) throws WikiSecurityException;
 
     /**
-     * Determines whether a supplied user password is valid, given a login name
-     * and password. It is up to the implementing class to determine how the
-     * comparison should be made. For example, the password might be hashed
-     * before comparing it to the value persisted in the back-end data store.
+     * Determines whether a supplied user password is valid, given a login name and password. It is up to the implementing class to
+     * determine how the comparison should be made. For example, the password might be hashed before comparing it to the value persisted
+     * in the back-end data store.
+     *
      * @param loginName the login name
      * @param password the password
-     * @return <code>true</code> if the password is valid, <code>false</code>
-     *         otherwise
+     * @return <code>true</code> if the password is valid, <code>false</code> otherwise
      */
     boolean validatePassword( String loginName, String password );
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
index 466587c..3357407 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
@@ -19,7 +19,7 @@
 package org.apache.wiki.auth.user;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.auth.NoSuchPrincipalException;
 import org.apache.wiki.auth.WikiPrincipal;
@@ -115,17 +115,17 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * {@link NoSuchPrincipalException}.
      * @param loginName the login name of the user profile that shall be deleted
      */
-    public synchronized void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException
+    @Override public synchronized void deleteByLoginName( final String loginName ) throws NoSuchPrincipalException, WikiSecurityException
     {
         if ( c_dom == null )
         {
             throw new WikiSecurityException( "FATAL: database does not exist" );
         }
 
-        NodeList users = c_dom.getDocumentElement().getElementsByTagName( USER_TAG );
+        final NodeList users = c_dom.getDocumentElement().getElementsByTagName( USER_TAG );
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element user = (Element) users.item( i );
+            final Element user = (Element) users.item( i );
             if ( user.getAttribute( LOGIN_NAME ).equals( loginName ) )
             {
                 c_dom.getDocumentElement().removeChild(user);
@@ -147,9 +147,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @return the user profile
      * @see org.apache.wiki.auth.user.UserDatabase#findByEmail(String)
      */
-    public UserProfile findByEmail( String index ) throws NoSuchPrincipalException
+    @Override public UserProfile findByEmail( final String index ) throws NoSuchPrincipalException
     {
-        UserProfile profile = findByAttribute( EMAIL, index );
+        final UserProfile profile = findByAttribute( EMAIL, index );
         if ( profile != null )
         {
             return profile;
@@ -166,9 +166,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @return the user profile
      * @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
      */
-    public UserProfile findByFullName( String index ) throws NoSuchPrincipalException
+    @Override public UserProfile findByFullName( final String index ) throws NoSuchPrincipalException
     {
-        UserProfile profile = findByAttribute( FULL_NAME, index );
+        final UserProfile profile = findByAttribute( FULL_NAME, index );
         if ( profile != null )
         {
             return profile;
@@ -185,9 +185,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @return the user profile
      * @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
      */
-    public UserProfile findByLoginName( String index ) throws NoSuchPrincipalException
+    @Override public UserProfile findByLoginName( final String index ) throws NoSuchPrincipalException
     {
-        UserProfile profile = findByAttribute( LOGIN_NAME, index );
+        final UserProfile profile = findByAttribute( LOGIN_NAME, index );
         if ( profile != null )
         {
             return profile;
@@ -198,9 +198,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
     /**
      * {@inheritDoc}
      */
-    public UserProfile findByUid( String uid ) throws NoSuchPrincipalException
+    @Override public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException
     {
-        UserProfile profile = findByAttribute( UID, uid );
+        final UserProfile profile = findByAttribute( UID, uid );
         if ( profile != null )
         {
             return profile;
@@ -217,9 +217,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @return the user profile
      * @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(java.lang.String)
      */
-    public UserProfile findByWikiName( String index ) throws NoSuchPrincipalException
+    @Override public UserProfile findByWikiName( final String index ) throws NoSuchPrincipalException
     {
-        UserProfile profile = findByAttribute( WIKI_NAME, index );
+        final UserProfile profile = findByAttribute( WIKI_NAME, index );
         if ( profile != null )
         {
             return profile;
@@ -235,25 +235,25 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @return the WikiNames
      * @throws WikiSecurityException In case things fail.
      */
-    public Principal[] getWikiNames() throws WikiSecurityException
+    @Override public Principal[] getWikiNames() throws WikiSecurityException
     {
         if ( c_dom == null )
         {
             throw new IllegalStateException( "FATAL: database does not exist" );
         }
-        SortedSet<Principal> principals = new TreeSet<Principal>();
-        NodeList users = c_dom.getElementsByTagName( USER_TAG );
+        final SortedSet<Principal> principals = new TreeSet<>();
+        final NodeList users = c_dom.getElementsByTagName( USER_TAG );
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element user = (Element) users.item( i );
-            String wikiName = user.getAttribute( WIKI_NAME );
+            final Element user = (Element) users.item( i );
+            final String wikiName = user.getAttribute( WIKI_NAME );
             if ( wikiName == null )
             {
                 log.warn( "Detected null wiki name in XMLUserDataBase. Check your user database." );
             }
             else
             {
-                Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
+                final Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
                 principals.add( principal );
             }
         }
@@ -264,115 +264,83 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * Initializes the user database based on values from a Properties object.
      * The properties object must contain a file path to the XML database file
      * whose key is {@link #PROP_USERDATABASE}.
-     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine,
-     *      java.util.Properties)
+     * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
      * @throws NoRequiredPropertyException if the user database cannot be located, parsed, or opened
      */
-    public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException
-    {
-        File defaultFile = null;
-        if( engine.getRootPath() == null )
-        {
-            log.warn( "Cannot identify JSPWiki root path"  );
+    @Override public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException {
+        final File defaultFile;
+        if( engine.getRootPath() == null ) {
+            log.warn( "Cannot identify JSPWiki root path" );
             defaultFile = new File( "WEB-INF/" + DEFAULT_USERDATABASE ).getAbsoluteFile();
-        }
-        else
-        {
+        } else {
             defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + DEFAULT_USERDATABASE );
         }
 
         // Get database file location
-        String file = TextUtil.getStringProperty(props, PROP_USERDATABASE, defaultFile.getAbsolutePath());
-        if( file == null )
-        {
-            log.warn( "XML user database property " + PROP_USERDATABASE + " not found; trying " + defaultFile  );
+        final String file = TextUtil.getStringProperty( props, PROP_USERDATABASE, defaultFile.getAbsolutePath() );
+        if( file == null ) {
+            log.warn( "XML user database property " + PROP_USERDATABASE + " not found; trying " + defaultFile );
             c_file = defaultFile;
-        }
-        else
-        {
+        } else {
             c_file = new File( file );
         }
 
-        log.info("XML user database at "+c_file.getAbsolutePath());
+        log.info( "XML user database at " + c_file.getAbsolutePath() );
 
         buildDOM();
         sanitizeDOM();
     }
 
-    private void buildDOM()
-    {
+    private void buildDOM() {
         // Read DOM
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         factory.setValidating( false );
         factory.setExpandEntityReferences( false );
         factory.setIgnoringComments( true );
         factory.setNamespaceAware( false );
-        try
-        {
+        try {
             c_dom = factory.newDocumentBuilder().parse( c_file );
             log.debug( "Database successfully initialized" );
             c_lastModified = c_file.lastModified();
-            c_lastCheck    = System.currentTimeMillis();
-        }
-        catch( ParserConfigurationException e )
-        {
+            c_lastCheck = System.currentTimeMillis();
+        } catch( final ParserConfigurationException e ) {
             log.error( "Configuration error: " + e.getMessage() );
-        }
-        catch( SAXException e )
-        {
+        } catch( final SAXException e ) {
             log.error( "SAX error: " + e.getMessage() );
-        }
-        catch( FileNotFoundException e )
-        {
-            log.info("User database not found; creating from scratch...");
-        }
-        catch( IOException e )
-        {
+        } catch( final FileNotFoundException e ) {
+            log.info( "User database not found; creating from scratch..." );
+        } catch( final IOException e ) {
             log.error( "IO error: " + e.getMessage() );
         }
-        if ( c_dom == null )
-        {
-            try
-            {
-                //
+        if( c_dom == null ) {
+            try {
                 //  Create the DOM from scratch
-                //
                 c_dom = factory.newDocumentBuilder().newDocument();
-                c_dom.appendChild( c_dom.createElement( "users") );
-            }
-            catch( ParserConfigurationException e )
-            {
+                c_dom.appendChild( c_dom.createElement( "users" ) );
+            } catch( final ParserConfigurationException e ) {
                 log.fatal( "Could not create in-memory DOM" );
             }
         }
     }
 
-    private void saveDOM() throws WikiSecurityException
-    {
-        if ( c_dom == null )
-        {
+    private void saveDOM() throws WikiSecurityException {
+        if( c_dom == null ) {
             log.fatal( "User database doesn't exist in memory." );
         }
 
-        File newFile = new File( c_file.getAbsolutePath() + ".new" );
-        try
-        (
-            BufferedWriter io = new BufferedWriter( new OutputStreamWriter (
-                    new FileOutputStream( newFile ), "UTF-8" ) );
-        )
-        {
+        final File newFile = new File( c_file.getAbsolutePath() + ".new" );
+        try( final BufferedWriter io = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( newFile ), "UTF-8" ) ) ) {
 
             // Write the file header and document root
-            io.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-            io.write("<users>\n");
+            io.write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
+            io.write( "<users>\n" );
 
             // Write each profile as a <user> node
-            Element root = c_dom.getDocumentElement();
-            NodeList nodes = root.getElementsByTagName( USER_TAG );
-            for( int i = 0; i < nodes.getLength(); i++ )
-            {
-                Element user = (Element)nodes.item( i );
-                io.write( "    <" + USER_TAG + " ");
+            final Element root = c_dom.getDocumentElement();
+            final NodeList nodes = root.getElementsByTagName( USER_TAG );
+            for( int i = 0; i < nodes.getLength(); i++ ) {
+                final Element user = ( Element )nodes.item( i );
+                io.write( "    <" + USER_TAG + " " );
                 io.write( UID );
                 io.write( "=\"" + user.getAttribute( UID ) + "\" " );
                 io.write( LOGIN_NAME );
@@ -392,43 +360,34 @@ public class XMLUserDatabase extends AbstractUserDatabase {
                 io.write( LOCK_EXPIRY );
                 io.write( "=\"" + user.getAttribute( LOCK_EXPIRY ) + "\" " );
                 io.write( ">" );
-                NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
-                for ( int j = 0; j < attributes.getLength(); j++ )
-                {
-                    Element attribute = (Element)attributes.item( j );
-                    String value = extractText( attribute );
+                final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+                for( int j = 0; j < attributes.getLength(); j++ ) {
+                    final Element attribute = ( Element )attributes.item( j );
+                    final String value = extractText( attribute );
                     io.write( "\n        <" + ATTRIBUTES_TAG + ">" );
                     io.write( value );
                     io.write( "</" + ATTRIBUTES_TAG + ">" );
                 }
-                io.write("\n    </" +USER_TAG + ">\n");
+                io.write( "\n    </" + USER_TAG + ">\n" );
             }
-            io.write("</users>");
-            io.close();
-        }
-        catch ( IOException e )
-        {
+            io.write( "</users>" );
+        } catch( final IOException e ) {
             throw new WikiSecurityException( e.getLocalizedMessage(), e );
         }
 
         // Copy new file over old version
-        File backup = new File( c_file.getAbsolutePath() + ".old" );
-        if ( backup.exists() )
-        {
-            if ( !backup.delete() )
-            {
+        final File backup = new File( c_file.getAbsolutePath() + ".old" );
+        if( backup.exists() ) {
+            if( !backup.delete() ) {
                 log.error( "Could not delete old user database backup: " + backup );
             }
         }
-        if ( !c_file.renameTo( backup ) )
-        {
+        if( !c_file.renameTo( backup ) ) {
             log.error( "Could not create user database backup: " + backup );
         }
-        if ( !newFile.renameTo( c_file ) )
-        {
+        if( !newFile.renameTo( c_file ) ) {
             log.error( "Could not save database: " + backup + " restoring backup." );
-            if ( !backup.renameTo( c_file ) )
-            {
+            if( !backup.renameTo( c_file ) ) {
                 log.error( "Restore failed. Check the file permissions." );
             }
             log.error( "Could not save database: " + c_file + ". Check the file permissions" );
@@ -438,16 +397,12 @@ public class XMLUserDatabase extends AbstractUserDatabase {
     private long c_lastCheck    = 0;
     private long c_lastModified = 0;
 
-    private void checkForRefresh()
-    {
-        long time = System.currentTimeMillis();
+    private void checkForRefresh() {
+        final long time = System.currentTimeMillis();
+        if( time - c_lastCheck > 60 * 1000L ) {
+            final long lastModified = c_file.lastModified();
 
-        if( time - c_lastCheck > 60*1000L )
-        {
-            long lastModified = c_file.lastModified();
-
-            if( lastModified > c_lastModified )
-            {
+            if( lastModified > c_lastModified ) {
                 buildDOM();
             }
         }
@@ -456,7 +411,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
     /**
      * @see org.apache.wiki.auth.user.UserDatabase#rename(String, String)
      */
-    public synchronized void rename(String loginName, String newName) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException
+    @Override public synchronized void rename( final String loginName, final String newName) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException
     {
         if ( c_dom == null )
         {
@@ -466,31 +421,31 @@ public class XMLUserDatabase extends AbstractUserDatabase {
         checkForRefresh();
 
         // Get the existing user; if not found, throws NoSuchPrincipalException
-        UserProfile profile = findByLoginName( loginName );
+        final UserProfile profile = findByLoginName( loginName );
 
         // Get user with the proposed name; if found, it's a collision
         try
         {
-            UserProfile otherProfile = findByLoginName( newName );
+            final UserProfile otherProfile = findByLoginName( newName );
             if ( otherProfile != null )
             {
                 throw new DuplicateUserException( "security.error.cannot.rename", newName );
             }
         }
-        catch ( NoSuchPrincipalException e )
+        catch ( final NoSuchPrincipalException e )
         {
             // Good! That means it's safe to save using the new name
         }
 
         // Find the user with the old login id attribute, and change it
-        NodeList users = c_dom.getElementsByTagName( USER_TAG );
+        final NodeList users = c_dom.getElementsByTagName( USER_TAG );
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element user = (Element) users.item( i );
+            final Element user = (Element) users.item( i );
             if ( user.getAttribute( LOGIN_NAME ).equals( loginName ) )
             {
-            	DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
-                Date modDate = new Date( System.currentTimeMillis() );
+            	final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+                final Date modDate = new Date( System.currentTimeMillis() );
                 setAttribute( user, LOGIN_NAME, newName );
                 setAttribute( user, LAST_MODIFIED, c_format.format( modDate ) );
                 profile.setLoginName( newName );
@@ -511,7 +466,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @param profile the user profile to save
      * @throws WikiSecurityException if the profile cannot be saved
      */
-    public synchronized void save( UserProfile profile ) throws WikiSecurityException
+    @Override public synchronized void save( final UserProfile profile ) throws WikiSecurityException
     {
         if ( c_dom == null )
         {
@@ -521,13 +476,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
 
         checkForRefresh();
 
-        DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
-        String index = profile.getLoginName();
-        NodeList users = c_dom.getElementsByTagName( USER_TAG );
+        final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+        final String index = profile.getLoginName();
+        final NodeList users = c_dom.getElementsByTagName( USER_TAG );
         Element user = null;
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element currentUser = (Element) users.item( i );
+            final Element currentUser = (Element) users.item( i );
             if ( currentUser.getAttribute( LOGIN_NAME ).equals( index ) )
             {
                 user = currentUser;
@@ -537,7 +492,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
 
         boolean isNew = false;
 
-        Date modDate = new Date( System.currentTimeMillis() );
+        final Date modDate = new Date( System.currentTimeMillis() );
         if( user == null )
         {
             // Create new user node
@@ -551,7 +506,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
         else
         {
             // To update existing user node, delete old attributes first...
-            NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+            final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
             for ( int i = 0; i < attributes.getLength(); i++ )
             {
                 user.removeChild( attributes.item( i ) );
@@ -564,14 +519,14 @@ public class XMLUserDatabase extends AbstractUserDatabase {
         setAttribute( user, FULL_NAME, profile.getFullname() );
         setAttribute( user, WIKI_NAME, profile.getWikiName() );
         setAttribute( user, EMAIL, profile.getEmail() );
-        Date lockExpiry = profile.getLockExpiry();
+        final Date lockExpiry = profile.getLockExpiry();
         setAttribute( user, LOCK_EXPIRY, lockExpiry == null ? "" : c_format.format( lockExpiry ) );
 
         // Hash and save the new password if it's different from old one
-        String newPassword = profile.getPassword();
+        final String newPassword = profile.getPassword();
         if ( newPassword != null && !newPassword.equals( "" ) )
         {
-            String oldPassword = user.getAttribute( PASSWORD );
+            final String oldPassword = user.getAttribute( PASSWORD );
             if ( !oldPassword.equals( newPassword ) )
             {
                 setAttribute( user, PASSWORD, getHash( newPassword ) );
@@ -583,13 +538,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
         {
             try
             {
-                String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() );
-                Element attributes = c_dom.createElement( ATTRIBUTES_TAG );
+                final String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() );
+                final Element attributes = c_dom.createElement( ATTRIBUTES_TAG );
                 user.appendChild( attributes );
-                Text value = c_dom.createTextNode( encodedAttributes );
+                final Text value = c_dom.createTextNode( encodedAttributes );
                 attributes.appendChild( value );
             }
-            catch ( IOException e )
+            catch ( final IOException e )
             {
                 throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
             }
@@ -614,7 +569,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @param index
      * @return the profile, or <code>null</code> if not found
      */
-    private UserProfile findByAttribute( String matchAttribute, String index )
+    private UserProfile findByAttribute( final String matchAttribute, String index )
     {
         if ( c_dom == null )
         {
@@ -623,7 +578,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
 
         checkForRefresh();
 
-        NodeList users = c_dom.getElementsByTagName( USER_TAG );
+        final NodeList users = c_dom.getElementsByTagName( USER_TAG );
 
         if( users == null ) return null;
 
@@ -636,7 +591,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
 
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element user = (Element) users.item( i );
+            final Element user = (Element) users.item( i );
             String userAttribute = user.getAttribute( matchAttribute );
             if (!caseSensitiveCompare)
             {
@@ -645,7 +600,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
             }
             if ( userAttribute.equals( index ) )
             {
-                UserProfile profile = newProfile();
+                final UserProfile profile = newProfile();
 
                 // Parse basic attributes
                 profile.setUid( user.getAttribute( UID ) );
@@ -659,13 +614,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
                 profile.setEmail( user.getAttribute( EMAIL ) );
 
                 // Get created/modified timestamps
-                String created = user.getAttribute( CREATED );
-                String modified = user.getAttribute( LAST_MODIFIED );
+                final String created = user.getAttribute( CREATED );
+                final String modified = user.getAttribute( LAST_MODIFIED );
                 profile.setCreated( parseDate( profile, created ) );
                 profile.setLastModified( parseDate( profile, modified ) );
 
                 // Is the profile locked?
-                String lockExpiry = user.getAttribute( LOCK_EXPIRY );
+                final String lockExpiry = user.getAttribute( LOCK_EXPIRY );
                 if ( lockExpiry == null || lockExpiry.length() == 0 )
                 {
                     profile.setLockExpiry( null );
@@ -676,17 +631,17 @@ public class XMLUserDatabase extends AbstractUserDatabase {
                 }
 
                 // Extract all of the user's attributes (should only be one attributes tag, but you never know!)
-                NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+                final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
                 for ( int j = 0; j < attributes.getLength(); j++ )
                 {
-                    Element attribute = (Element)attributes.item( j );
-                    String serializedMap = extractText( attribute );
+                    final Element attribute = (Element)attributes.item( j );
+                    final String serializedMap = extractText( attribute );
                     try
                     {
-                        Map<String,? extends Serializable> map = Serializer.deserializeFromBase64( serializedMap );
+                        final Map<String,? extends Serializable> map = Serializer.deserializeFromBase64( serializedMap );
                         profile.getAttributes().putAll( map );
                     }
-                    catch ( IOException e )
+                    catch ( final IOException e )
                     {
                         log.error( "Could not parse user profile attributes!", e );
                     }
@@ -703,15 +658,15 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @param element the base element
      * @return the text nodes that are immediate children of the base element, concatenated together
      */
-    private String extractText( Element element )
+    private String extractText( final Element element )
     {
         String text = "";
         if ( element.getChildNodes().getLength() > 0 )
         {
-            NodeList children = element.getChildNodes();
+            final NodeList children = element.getChildNodes();
             for ( int k = 0; k < children.getLength(); k++ )
             {
-                Node child = children.item( k );
+                final Node child = children.item( k );
                 if ( child.getNodeType() == Node.TEXT_NODE )
                 {
                     text = text + ((Text)child).getData();
@@ -729,20 +684,20 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      *  @param date
      *  @return A parsed date, or null, if both parse attempts fail.
      */
-    private Date parseDate( UserProfile profile, String date )
+    private Date parseDate( final UserProfile profile, final String date )
     {
         try
         {
-        	DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+        	final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
             return c_format.parse( date );
         }
-        catch( ParseException e )
+        catch( final ParseException e )
         {
             try
             {
                 return DateFormat.getDateTimeInstance().parse( date );
             }
-            catch ( ParseException e2)
+            catch ( final ParseException e2)
             {
                 log.warn("Could not parse 'created' or 'lastModified' "
                     + "attribute for "
@@ -764,10 +719,10 @@ public class XMLUserDatabase extends AbstractUserDatabase {
             throw new IllegalStateException( "FATAL: database does not exist" );
         }
 
-        NodeList users = c_dom.getElementsByTagName( USER_TAG );
+        final NodeList users = c_dom.getElementsByTagName( USER_TAG );
         for( int i = 0; i < users.getLength(); i++ )
         {
-            Element user = (Element) users.item( i );
+            final Element user = (Element) users.item( i );
 
             // Sanitize UID (and generate a new one if one does not exist)
             String uid = user.getAttribute( UID ).trim();
@@ -778,10 +733,10 @@ public class XMLUserDatabase extends AbstractUserDatabase {
             }
 
             // Sanitize dates
-            String loginName = user.getAttribute( LOGIN_NAME );
+            final String loginName = user.getAttribute( LOGIN_NAME );
             String created = user.getAttribute( CREATED );
             String modified = user.getAttribute( LAST_MODIFIED );
-            DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+            final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
             try
             {
                 created = c_format.format( c_format.parse( created ) );
@@ -789,7 +744,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
                 user.setAttribute( CREATED,  created );
                 user.setAttribute( LAST_MODIFIED,  modified );
             }
-            catch( ParseException e )
+            catch( final ParseException e )
             {
                 try
                 {
@@ -798,7 +753,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
                     user.setAttribute( CREATED,  created );
                     user.setAttribute( LAST_MODIFIED,  modified );
                 }
-                catch ( ParseException e2 )
+                catch ( final ParseException e2 )
                 {
                     log.warn( "Could not parse 'created' or 'lastModified' attribute for profile '" + loginName + "'."
                             + " It may have been tampered with." );
@@ -813,7 +768,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
      * @param attribute the name of the attribute to set
      * @param value the desired attribute value
      */
-    private void setAttribute( Element element, String attribute, String value ) {
+    private void setAttribute( final Element element, final String attribute, final String value ) {
         if( value != null ) {
             element.setAttribute( attribute, value );
         }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
index a0f2557..0ee74e5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
@@ -18,15 +18,15 @@
  */
 package org.apache.wiki.tasks;
 
-import java.util.Locale;
-
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.tasks.auth.SaveUserProfileTask;
 import org.apache.wiki.tasks.pages.PreSaveWikiPageTask;
 import org.apache.wiki.tasks.pages.SaveWikiPageTask;
 import org.apache.wiki.workflow.Step;
 
+import java.util.Locale;
+
 
 /**
  * Default implementation for {@link TasksManager}.
@@ -37,7 +37,7 @@ public class DefaultTasksManager implements TasksManager {
      * {@inheritDoc}
      */
     @Override
-    public Step buildPreSaveWikiPageTask( WikiContext context, String proposedText ) {
+    public Step buildPreSaveWikiPageTask( final WikiContext context, final String proposedText ) {
         return new PreSaveWikiPageTask( context, proposedText );
     }
     
@@ -53,7 +53,7 @@ public class DefaultTasksManager implements TasksManager {
      * {@inheritDoc}
      */
     @Override
-    public Step buildSaveUserProfileTask( WikiEngine engine, Locale loc ) {
+    public Step buildSaveUserProfileTask( final Engine engine, final Locale loc ) {
         return new SaveUserProfileTask( engine, loc );
     }
     
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
index f2a7b61..c78774c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
@@ -19,7 +19,7 @@
 package org.apache.wiki.tasks;
 
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.workflow.Step;
 
 import java.security.Principal;
@@ -64,6 +64,6 @@ public interface TasksManager {
      * @param loc text proposed to be saved on the wiki page.
      * @return a save user profile task.
      */
-    Step buildSaveUserProfileTask( WikiEngine engine, Locale loc );
+    Step buildSaveUserProfileTask( Engine engine, Locale loc );
     
 }
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
index 3ec7cb3..22f0f20 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
@@ -2,8 +2,9 @@ package org.apache.wiki.tasks.auth;
 
 import org.apache.log4j.Logger;
 import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.UserManager;
 import org.apache.wiki.auth.user.UserProfile;
 import org.apache.wiki.i18n.InternationalizationManager;
 import org.apache.wiki.tasks.TasksManager;
@@ -24,14 +25,15 @@ public class SaveUserProfileTask extends Task {
 
     private static final long serialVersionUID = 6994297086560480285L;
     private static final Logger LOG = Logger.getLogger( SaveUserProfileTask.class );
-    private final WikiEngine m_engine;
+    private final Engine m_engine;
     private final Locale m_loc;
 
     /**
      * Constructs a new Task for saving a user profile.
+     *
      * @param engine the wiki engine
      */
-    public SaveUserProfileTask( final WikiEngine engine, final Locale loc ) {
+    public SaveUserProfileTask( final Engine engine, final Locale loc ) {
         super( TasksManager.USER_PROFILE_SAVE_TASK_MESSAGE_KEY );
         m_engine = engine;
         m_loc = loc;
@@ -39,8 +41,8 @@ public class SaveUserProfileTask extends Task {
 
     /**
      * Saves the user profile to the user database.
-     * @return {@link org.apache.wiki.workflow.Outcome#STEP_COMPLETE} if the
-     * task completed successfully
+     *
+     * @return {@link org.apache.wiki.workflow.Outcome#STEP_COMPLETE} if the task completed successfully
      * @throws WikiException if the save did not complete for some reason
      */
     @Override
@@ -49,12 +51,12 @@ public class SaveUserProfileTask extends Task {
         final UserProfile profile = ( UserProfile )getWorkflow().getAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE );
 
         // Save the profile (userdatabase will take care of timestamps for us)
-        m_engine.getUserManager().getUserDatabase().save( profile );
+        m_engine.getManager( UserManager.class ).getUserDatabase().save( profile );
 
         // Send e-mail if user supplied an e-mail address
-        if ( profile.getEmail() != null ) {
+        if ( profile != null && profile.getEmail() != null ) {
             try {
-                final InternationalizationManager i18n = m_engine.getInternationalizationManager();
+                final InternationalizationManager i18n = m_engine.getManager( InternationalizationManager.class );
                 final String app = m_engine.getApplicationName();
                 final String to = profile.getEmail();
                 final String subject = i18n.get( InternationalizationManager.DEF_TEMPLATE, m_loc,
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
index 4aa3de8..c18b8b8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
@@ -18,26 +18,26 @@
  */
 package org.apache.wiki.workflow;
 
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.WikiException;
+
 import java.security.Principal;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.api.exceptions.WikiException;
-
 /**
  * Factory class that creates common Workflow instances such as a standard approval workflow.
  */
-public final class WorkflowBuilder
-{
-    private static final Map<WikiEngine, WorkflowBuilder> BUILDERS = new ConcurrentHashMap<>();
-    private final WikiEngine m_engine;
+public final class WorkflowBuilder {
+
+    private static final Map< Engine, WorkflowBuilder > BUILDERS = new ConcurrentHashMap<>();
+    private final Engine m_engine;
 
     /**
      * Private constructor that creates a new WorkflowBuilder for the supplied WikiEngine.
      * @param engine the wiki engine
      */
-    private WorkflowBuilder( WikiEngine engine )
+    private WorkflowBuilder( final Engine engine )
     {
         m_engine = engine;
     }
@@ -48,11 +48,9 @@ public final class WorkflowBuilder
      * @param engine the wiki engine
      * @return the workflow builder
      */
-    public static WorkflowBuilder getBuilder( WikiEngine engine )
-    {
+    public static WorkflowBuilder getBuilder( final Engine engine ) {
         WorkflowBuilder builder = BUILDERS.get( engine );
-        if ( builder == null )
-        {
+        if ( builder == null ) {
             builder = new WorkflowBuilder( engine );
             BUILDERS.put( engine, builder );
         }
@@ -102,46 +100,40 @@ public final class WorkflowBuilder
      * @return the created workflow
      * @throws WikiException if the name of the approving user, Role or Group cannot be determined
      */
-    public Workflow buildApprovalWorkflow( Principal submitter,
-                                           String workflowApproverKey,
-                                           Step prepTask,
-                                           String decisionKey,
-                                           Fact[] facts,
-                                           Step completionTask,
-                                           String rejectedMessageKey ) throws WikiException
-    {
-        WorkflowManager mgr = m_engine.getWorkflowManager();
-        Workflow workflow = new Workflow( workflowApproverKey, submitter );
+    public Workflow buildApprovalWorkflow( final Principal submitter,
+                                           final String workflowApproverKey,
+                                           final Step prepTask,
+                                           final String decisionKey,
+                                           final Fact[] facts,
+                                           final Step completionTask,
+                                           final String rejectedMessageKey ) throws WikiException {
+        final WorkflowManager mgr = m_engine.getManager( WorkflowManager.class );
+        final Workflow workflow = new Workflow( workflowApproverKey, submitter );
 
         // Is a Decision required to run the approve task?
-        boolean decisionRequired = mgr.requiresApproval( workflowApproverKey );
+        final boolean decisionRequired = mgr.requiresApproval( workflowApproverKey );
 
         // If Decision required, create a simple approval workflow
-        if ( decisionRequired )
-        {
+        if ( decisionRequired ) {
             // Look up the name of the approver (user or group) listed in jspwiki.properties;
             // approvals go to the approver's decision cue
-            Principal approverPrincipal = mgr.getApprover( workflowApproverKey );
-            Decision decision = new SimpleDecision( workflow, decisionKey, approverPrincipal );
+            final Principal approverPrincipal = mgr.getApprover( workflowApproverKey );
+            final Decision decision = new SimpleDecision( workflow, decisionKey, approverPrincipal );
 
             // Add facts to the Decision, if any were supplied
-            if ( facts != null )
-            {
-                for ( Fact fact: facts )
-                {
+            if( facts != null ) {
+                for( final Fact fact : facts ) {
                     decision.addFact( fact );
                 }
                 // Add the first one as a message key
-                if ( facts.length > 0 )
-                {
-                    workflow.addMessageArgument( facts[0].getValue() );
+                if( facts.length > 0 ) {
+                    workflow.addMessageArgument( facts[ 0 ].getValue() );
                 }
             }
 
             // If rejected, sent a notification
-            if ( rejectedMessageKey != null )
-            {
-                SimpleNotification rejectNotification = new SimpleNotification( workflow, rejectedMessageKey, submitter );
+            if ( rejectedMessageKey != null ) {
+                final SimpleNotification rejectNotification = new SimpleNotification( workflow, rejectedMessageKey, submitter );
                 decision.addSuccessor( Outcome.DECISION_DENY, rejectNotification );
             }
 
@@ -149,35 +141,24 @@ public final class WorkflowBuilder
             decision.addSuccessor( Outcome.DECISION_APPROVE, completionTask );
 
             // Set the first step
-            if ( prepTask == null )
-            {
+            if( prepTask == null ) {
                 workflow.setFirstStep( decision );
-            }
-            else
-            {
+            } else {
                 workflow.setFirstStep( prepTask );
                 prepTask.addSuccessor( Outcome.STEP_COMPLETE, decision );
             }
-        }
-
-        // If Decision not required, just run the prep + approved tasks in succession
-        else
-        {
+        } else { // If Decision not required, just run the prep + approved tasks in succession
             // Set the first step
-            if ( prepTask == null )
-            {
+            if ( prepTask == null ) {
                 workflow.setFirstStep( completionTask );
-            }
-            else
-            {
+            } else {
                 workflow.setFirstStep( prepTask );
                 prepTask.addSuccessor( Outcome.STEP_COMPLETE, completionTask );
             }
         }
 
         // Make sure our tasks have this workflow as the parent, then return
-        if ( prepTask != null )
-        {
+        if( prepTask != null ) {
             prepTask.setWorkflow( workflow );
         }
         completionTask.setWorkflow( workflow );
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index b419955..d572965 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -77,7 +77,7 @@
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.UserManager</requestedClass>
-    <mappedClass>org.apache.wiki.auth.UserManager</mappedClass>
+    <mappedClass>org.apache.wiki.auth.DefaultUserManager</mappedClass>
   </mapping>
   <mapping>
     <requestedClass>org.apache.wiki.auth.acl.AclManager</requestedClass>