JSPWIKI-303: added ContextSPI

also, SPIs are initialized to their default values; that way there's no need to invoke init() on unit tests
last, propagate changes
diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextDSL.java b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextDSL.java
new file mode 100644
index 0000000..04ac3bf
--- /dev/null
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextDSL.java
@@ -0,0 +1,64 @@
+package org.apache.wiki.api.spi;
+
+import org.apache.wiki.api.core.Command;
+import org.apache.wiki.api.core.Context;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.core.Page;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+public class ContextDSL {
+
+    private final ContextSPI contextSPI;
+
+    ContextDSL( final ContextSPI contextSPI ) {
+        this.contextSPI = contextSPI;
+    }
+
+    /**
+     *  Create a new Context for the given Page.
+     *
+     *  @param engine The Engine that is handling the request.
+     *  @param page The Page. If you want to create a Context for an older version of a page, you must use this method.
+     */
+    public Context create( final Engine engine, final Page page ) {
+        return contextSPI.create( engine, page );
+    }
+
+    /**
+     * <p>Creates a new Context 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 Session object is present.
+     * If not, a new one is created.</p>
+     *
+     * @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
+     */
+    public Context create( final Engine engine, final HttpServletRequest request, final Command command ) {
+        return contextSPI.create( engine, request, command );
+    }
+
+    /**
+     * Creates a new Context for the given Engine, Page and HttpServletRequest.
+     *
+     * @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 Context create( final Engine engine, final HttpServletRequest request, final Page page ) {
+        return contextSPI.create( engine, request, page );
+    }
+
+    /**
+     *  Creates a new Context from a supplied HTTP request, using a default wiki context.
+     *
+     *  @param engine The Engine that is handling the request
+     *  @param request the HTTP request
+     *  @param requestContext the default context to use
+     */
+    public Context create( final Engine engine, final HttpServletRequest request, final String requestContext ) {
+        return contextSPI.create( engine, request, requestContext );
+    }
+
+}
diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextSPI.java b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextSPI.java
new file mode 100644
index 0000000..b9916a7
--- /dev/null
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/ContextSPI.java
@@ -0,0 +1,71 @@
+/*
+    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.api.spi;
+
+import org.apache.wiki.api.core.Command;
+import org.apache.wiki.api.core.Context;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.core.Page;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * SPI used to locate and provide {@link Context} instances.
+ */
+public interface ContextSPI {
+
+    /**
+     *  Create a new Context for the given Page.
+     *
+     *  @param engine The Engine that is handling the request.
+     *  @param page The Page. If you want to create a Context for an older version of a page, you must use this method.
+     */
+    Context create( Engine engine, Page page );
+
+    /**
+     * <p>Creates a new Context 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 Session object is present.
+     * If not, a new one is created.</p>
+     * 
+     * @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
+     */
+    Context create( Engine engine, HttpServletRequest request, Command command );
+
+    /**
+     * Creates a new Context for the given Engine, Page and HttpServletRequest.
+     *
+     * @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
+     */
+    Context create( Engine engine, HttpServletRequest request, Page page );
+
+    /**
+     *  Creates a new Context from a supplied HTTP request, using a default wiki context.
+     *
+     *  @param engine The Engine that is handling the request
+     *  @param request the HTTP request
+     *  @param requestContext the default context to use
+     */
+    Context create( Engine engine, HttpServletRequest request, String requestContext );
+
+}
diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/spi/Wiki.java b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/Wiki.java
index 7d22fd2..e31732c 100644
--- a/jspwiki-api/src/main/java/org/apache/wiki/api/spi/Wiki.java
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/spi/Wiki.java
@@ -29,16 +29,26 @@
 
 public class Wiki {
 
+    private static final String PROP_PROVIDER_IMPL_CONTEXT = "jspwiki.provider.impl.context";
     private static final String PROP_PROVIDER_IMPL_ENGINE = "jspwiki.provider.impl.engine";
+    private static final String DEFAULT_PROVIDER_IMPL_CONTEXT = "org.apache.wiki.spi.ContextSPIDefaultImpl";
     private static final String DEFAULT_PROVIDER_IMPL_ENGINE = "org.apache.wiki.spi.EngineSPIDefaultImpl";
 
-    private static EngineSPI engineSPI;
+    // default values
+    private static Properties properties = PropertyReader.getDefaultProperties();
+    private static ContextSPI contextSPI = getSPI( ContextSPI.class, properties, PROP_PROVIDER_IMPL_CONTEXT, DEFAULT_PROVIDER_IMPL_CONTEXT );
+    private static EngineSPI engineSPI = getSPI( EngineSPI.class, properties, PROP_PROVIDER_IMPL_ENGINE, DEFAULT_PROVIDER_IMPL_ENGINE );
 
     static void init( final ServletContext context ) {
-        final Properties properties = PropertyReader.loadWebAppProps( context );
+        properties = PropertyReader.loadWebAppProps( context );
+        contextSPI = getSPI( ContextSPI.class, properties, PROP_PROVIDER_IMPL_CONTEXT, DEFAULT_PROVIDER_IMPL_CONTEXT );
         engineSPI = getSPI( EngineSPI.class, properties, PROP_PROVIDER_IMPL_ENGINE, DEFAULT_PROVIDER_IMPL_ENGINE );
     }
 
+    public static ContextDSL context() {
+        return new ContextDSL( contextSPI );
+    }
+
     public static EngineDSL engine() {
         return new EngineDSL( engineSPI );
     }
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 a075874..13550ae 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/WikiContext.java
@@ -244,8 +244,6 @@
      *  @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.
-     *
      *  @see org.apache.wiki.ui.CommandResolver
      *  @see org.apache.wiki.api.core.Command
      *  @since 2.1.15.
@@ -648,8 +646,8 @@
             copy.m_variableMap = (HashMap<String,Object>)m_variableMap.clone();
             copy.m_request     = m_request;
             copy.m_session     = m_session;
-            copy.m_page        = (WikiPage)m_page.clone();
-            copy.m_realPage    = (WikiPage)m_realPage.clone();
+            copy.m_page        = m_page.clone();
+            copy.m_realPage    = m_realPage.clone();
             return copy;
         }
         catch( final CloneNotSupportedException e ){} // Never happens
@@ -676,7 +674,7 @@
      * @since 2.4
      * @param pageContext the JSP page context
      * @return Current WikiContext, or null, of no context exists.
-     * @deprecated use {@Context#findContext( PageContext )} instead.
+     * @deprecated use {@link Context#findContext( PageContext )} instead.
      * @see Context#findContext( PageContext )
      */
     @Deprecated
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ajax/WikiAjaxDispatcherServlet.java b/jspwiki-main/src/main/java/org/apache/wiki/ajax/WikiAjaxDispatcherServlet.java
index e1bce1a..78793cb 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ajax/WikiAjaxDispatcherServlet.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ajax/WikiAjaxDispatcherServlet.java
@@ -161,7 +161,7 @@
      * @return true if permission is valid
      */
     private boolean validatePermission( final HttpServletRequest req, final AjaxServletContainer container ) {
-        final Engine e = Wiki.engine( req.getSession().getServletContext(), null );
+        final Engine e = Wiki.engine().find( req.getSession().getServletContext(), null );
         boolean valid = false;
         if( container != null ) {
             valid = e.getManager( AuthorizationManager.class ).checkPermission( WikiSession.getWikiSession( e, req ), container.permission );
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 3ecda49..e17d807 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
@@ -19,7 +19,6 @@
 package org.apache.wiki.auth.acl;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.core.Acl;
 import org.apache.wiki.api.core.AclEntry;
 import org.apache.wiki.api.core.Attachment;
@@ -27,6 +26,7 @@
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.auth.AuthorizationManager;
 import org.apache.wiki.auth.WikiSecurityException;
 import org.apache.wiki.auth.permissions.PagePermission;
@@ -143,7 +143,7 @@
                 acl = getPermissions(parent);
             } else {
                 //  Or, try parsing the page
-                final WikiContext ctx = new WikiContext( m_engine, page );
+                final Context ctx = Wiki.context().create( m_engine, page );
                 ctx.setVariable( Context.VAR_EXECUTE_PLUGINS, Boolean.FALSE );
                 m_engine.getManager( RenderingManager.class ).getHTML(ctx, page);
 
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 47f253d..fb33eaa 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
@@ -22,7 +22,7 @@
 import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
@@ -30,6 +30,7 @@
 import org.apache.wiki.api.providers.PageProvider;
 import org.apache.wiki.api.search.QueryItem;
 import org.apache.wiki.api.search.SearchResult;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.parser.MarkupParser;
 import org.apache.wiki.render.RenderingManager;
@@ -391,7 +392,7 @@
             final RenderingManager mgr = m_engine.getManager( RenderingManager.class );
             try {
                 final String data = m_provider.getPageText( page.getName(), page.getVersion() );
-                final WikiContext ctx = new WikiContext( m_engine, page );
+                final Context ctx = Wiki.context().create( m_engine, page );
                 final MarkupParser parser = mgr.getParser( ctx, data );
 
                 parser.parse();
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 14ed653..5db59b1 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
@@ -22,7 +22,6 @@
 import org.apache.log4j.Logger;
 import org.apache.wiki.InternalWikiException;
 import org.apache.wiki.LinkCollector;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.core.Attachment;
 import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
@@ -31,6 +30,7 @@
 import org.apache.wiki.api.filters.BasePageFilter;
 import org.apache.wiki.api.providers.PageProvider;
 import org.apache.wiki.api.providers.WikiProvider;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventManager;
@@ -434,7 +434,7 @@
     @Override
     public Collection< String > scanWikiLinks( final Page page, final String pagedata ) {
         final LinkCollector localCollector = new LinkCollector();
-        m_engine.getManager( RenderingManager.class ).textToHTML( new WikiContext( m_engine, page ),
+        m_engine.getManager( RenderingManager.class ).textToHTML( Wiki.context().create( m_engine, page ),
                                                                   pagedata,
                                                                   localCollector,
                                                                   null,
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 392ca51..faa031b 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
@@ -19,8 +19,8 @@
 package org.apache.wiki.rpc.atom;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.ProviderException;
@@ -69,7 +69,7 @@
      */
     @Override
     public void init( final ServletConfig config ) throws ServletException {
-        m_engine = Wiki.engine( config );
+        m_engine = Wiki.engine().find( config );
     }
 
     /**
@@ -126,7 +126,7 @@
             final Page entryPage = new WikiPage( m_engine, pageName );
             entryPage.setAuthor( username );
 
-            final WikiContext context = new WikiContext( m_engine, request, entryPage );
+            final Context context = Wiki.context().create( m_engine, request, entryPage );
             final StringBuilder text = new StringBuilder();
             text.append( "!" )
                 .append( title.getBody() )
@@ -223,7 +223,7 @@
             }
 
             final String encodedName = TextUtil.urlEncodeUTF8( p.getName() );
-            final WikiContext context = new WikiContext( m_engine, p );
+            final Context context = Wiki.context().create( m_engine, p );
             final String title = TextUtil.replaceEntities( org.apache.wiki.rss.Feed.getSiteName( context ) );
             final Link postlink = createLink( "service.post", m_engine.getBaseURL() + "atom/" + encodedName, title );
             final Link editlink = createLink( "service.edit", m_engine.getBaseURL() + "atom/" + encodedName, title );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java b/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java
index 824c20a..a4a6b9f 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/search/DefaultSearchManager.java
@@ -25,12 +25,14 @@
 import org.apache.wiki.ajax.AjaxUtil;
 import org.apache.wiki.ajax.WikiAjaxDispatcherServlet;
 import org.apache.wiki.ajax.WikiAjaxServlet;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.FilterException;
 import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
 import org.apache.wiki.api.filters.BasePageFilter;
 import org.apache.wiki.api.search.SearchResult;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.event.WikiEvent;
 import org.apache.wiki.event.WikiEventManager;
 import org.apache.wiki.event.WikiPageEvent;
@@ -122,7 +124,7 @@
                     result = AjaxUtil.toJson( callResults );
                 } else if( actionName.equals( AJAX_ACTION_PAGES ) ) {
                     log.debug("Calling findPages() START");
-                    final WikiContext wikiContext = new WikiContext( m_engine, req, WikiContext.VIEW );
+                    final Context wikiContext = Wiki.context().create( m_engine, req, WikiContext.VIEW );
                     final List< Map< String, Object > > callResults = findPages( itemId, maxResults, wikiContext );
                     log.debug( "Calling findPages() DONE. " + callResults.size() );
                     result = AjaxUtil.toJson( callResults );
@@ -182,7 +184,7 @@
          *  @param maxLength How many hits to return
          *  @return the pages found
          */
-        public List< Map< String, Object > > findPages( final String searchString, final int maxLength, final WikiContext wikiContext ) {
+        public List< Map< String, Object > > findPages( final String searchString, final int maxLength, final Context wikiContext ) {
             final StopWatch sw = new StopWatch();
             sw.start();
 
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/spi/ContextSPIDefaultImpl.java b/jspwiki-main/src/main/java/org/apache/wiki/spi/ContextSPIDefaultImpl.java
new file mode 100644
index 0000000..fd05b93
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/spi/ContextSPIDefaultImpl.java
@@ -0,0 +1,70 @@
+/*
+    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.spi;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.core.Command;
+import org.apache.wiki.api.core.Context;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.ContextSPI;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * Default implementation for {@link ContextSPI}
+ *
+ * @see ContextSPI
+ */
+public class ContextSPIDefaultImpl implements ContextSPI {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Context create( final Engine engine, final Page page ) {
+        return new WikiContext( engine, page );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Context create( final Engine engine, final HttpServletRequest request, final Command command ) {
+        return new WikiContext( engine, request, command );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Context create( final Engine engine, final HttpServletRequest request, final Page page ) {
+        return new WikiContext( engine, request, page );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Context create( final Engine engine, final HttpServletRequest request, final String requestContext ) {
+        return new WikiContext( engine, request, requestContext );
+    }
+
+}
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 1a6ad51..f7b1b4e 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
@@ -19,11 +19,11 @@
 package org.apache.wiki.tags;
 
 import org.apache.log4j.Logger;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.core.Command;
 import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.search.SearchResult;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.ui.PageCommand;
 
 import javax.servlet.http.HttpServletRequest;
@@ -101,7 +101,7 @@
             final Engine engine = m_wikiContext.getEngine();
             final HttpServletRequest request = m_wikiContext.getHttpRequest();
             final Command command = PageCommand.VIEW.targetedCommand( r.getPage() );
-            final Context context = new WikiContext( engine, request, command );
+            final Context context = Wiki.context().create( engine, request, command );
 
             // Stash it in the page context
             pageContext.setAttribute( Context.ATTR_CONTEXT, context, PageContext.REQUEST_SCOPE );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiServletFilter.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiServletFilter.java
index 284ee33..6ef788b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiServletFilter.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/WikiServletFilter.java
@@ -78,7 +78,7 @@
             context.log( "== JSPWIKI WARNING ==  : This container is running with a security manager. JSPWiki does not yet really support that right now. See issue JSPWIKI-129 for details and information on how to proceed." );
         }
 
-        m_engine = Wiki.engine( context, null );
+        m_engine = Wiki.engine().find( context, null );
     }
 
     /**
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 b9cd7a2..ac4cde9 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
@@ -24,6 +24,7 @@
 import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Engine;
 import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.auth.AuthenticationManager;
@@ -209,10 +210,10 @@
         try {
             final WeblogEntryPlugin plugin = new WeblogEntryPlugin();
             final String pageName = plugin.getNewEntryPage( engine, blogid );
-            final WikiPage entryPage = new WikiPage( engine, pageName );
+            final Page entryPage = new WikiPage( engine, pageName );
             entryPage.setAuthor( username );
 
-            final WikiContext context = new WikiContext( engine, entryPage );
+            final Context context = Wiki.context().create( engine, entryPage );
             final StringBuilder text = new StringBuilder();
             text.append( "!" ).append( content.get( "title" ) );
             text.append( "\n\n" );
@@ -295,7 +296,7 @@
             final Page entryPage = page.clone();
             entryPage.setAuthor( username );
 
-            final WikiContext context = new WikiContext( engine, entryPage );
+            final Context context = Wiki.context().create( engine, entryPage );
 
             final StringBuilder text = new StringBuilder();
             text.append( "!" ).append( content.get( "title" ) );
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 9808333..31b59d5 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
@@ -21,7 +21,9 @@
 import org.apache.wiki.LinkCollector;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.core.Attachment;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.auth.permissions.PagePermission;
 import org.apache.wiki.auth.permissions.PermissionFactory;
 import org.apache.wiki.pages.PageManager;
@@ -175,7 +177,7 @@
         final LinkCollector extCollector   = new LinkCollector();
         final LinkCollector attCollector   = new LinkCollector();
 
-        final WikiContext context = new WikiContext( m_engine, page );
+        final Context context = Wiki.context().create( m_engine, page );
         m_engine.getManager( RenderingManager.class ).textToHTML( context, pagedata, localCollector, extCollector, attCollector );
 
         final Vector< Hashtable< String, String > > result = new Vector<>();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCServlet.java b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCServlet.java
index 99e7982..ac9bbf7 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCServlet.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/xmlrpc/RPCServlet.java
@@ -79,7 +79,7 @@
      */
     @Override
     public void init( final ServletConfig config ) throws ServletException {
-        m_engine = Wiki.engine( config );
+        m_engine = Wiki.engine().find( config );
 
         String handlerName = config.getInitParameter( "handler" );
         String prefix      = config.getInitParameter( "prefix" );
@@ -110,7 +110,7 @@
         log.debug("Received POST to RPCServlet");
 
         try {
-            final WikiContext ctx = new WikiContext( m_engine, request, WikiContext.NONE );
+            final Context ctx = Wiki.context().create( m_engine, request, WikiContext.NONE );
             final XmlRpcContext xmlrpcContext = new WikiXmlRpcContext( m_xmlrpcServer.getHandlerMapping(), ctx );
             final byte[] result = m_xmlrpcServer.execute( request.getInputStream(), xmlrpcContext );
 
diff --git a/jspwiki-main/src/main/resources/META-INF/services/org.apache.wiki.api.spi.ContextSPI b/jspwiki-main/src/main/resources/META-INF/services/org.apache.wiki.api.spi.ContextSPI
new file mode 100644
index 0000000..a0b1218
--- /dev/null
+++ b/jspwiki-main/src/main/resources/META-INF/services/org.apache.wiki.api.spi.ContextSPI
@@ -0,0 +1 @@
+org.apache.wiki.spi.ContextSPIDefaultImpl
\ No newline at end of file
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 b748798..84a009a 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
@@ -20,12 +20,13 @@
 
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.api.core.Attachment;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.api.providers.WikiProvider;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.references.ReferenceManager;
@@ -81,7 +82,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", false);
 
@@ -107,7 +108,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", true);
 
@@ -133,7 +134,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", true);
 
@@ -158,7 +159,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", true);
 
@@ -183,7 +184,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", true);
 
@@ -211,7 +212,7 @@
 
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "Test", "TestPage", true);
 
@@ -231,7 +232,7 @@
         m_engine.addAttachment("TestPage", "bar.jpg", "pr0n".getBytes() );
         final Page p = m_engine.getManager( PageManager.class ).getPage("TestPage");
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, "TestPage", "FooTest", true);
 
@@ -310,7 +311,7 @@
     {
         final Page p = m_engine.getManager( PageManager.class ).getPage(src);
 
-        final WikiContext context = new WikiContext(m_engine, p);
+        final Context context = Wiki.context().create(m_engine, p);
 
         m_engine.getManager( PageRenamer.class ).renamePage(context, src, dst, true);
     }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/diff/ContextualDiffProviderTest.java b/jspwiki-main/src/test/java/org/apache/wiki/diff/ContextualDiffProviderTest.java
index d2432bb..3f24843 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/diff/ContextualDiffProviderTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/diff/ContextualDiffProviderTest.java
@@ -20,9 +20,10 @@
 
 import org.apache.log4j.PropertyConfigurator;
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.api.spi.Wiki;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -38,7 +39,7 @@
      * <p>
      * Get it?
      */
-    private void specializedNotation(ContextualDiffProvider diff)
+    private void specializedNotation( final ContextualDiffProvider diff)
     {
         diff.CHANGE_END_HTML = "|";
         diff.CHANGE_START_HTML = "|";
@@ -190,24 +191,24 @@
     }
      */
 
-    private void diffTest(String contextLimit, String oldText, String newText, String expectedDiff)
+    private void diffTest( final String contextLimit, final String oldText, final String newText, final String expectedDiff)
         throws IOException, WikiException
     {
-        ContextualDiffProvider diff = new ContextualDiffProvider();
+        final ContextualDiffProvider diff = new ContextualDiffProvider();
 
         specializedNotation(diff);
 
-        Properties props = TestEngine.getTestProperties();
+        final Properties props = TestEngine.getTestProperties();
         if (null != contextLimit)
             props.put(ContextualDiffProvider.PROP_UNCHANGED_CONTEXT_LIMIT, contextLimit);
 
         diff.initialize(null, props);
 
         PropertyConfigurator.configure(props);
-        TestEngine engine = new TestEngine(props);
+        final TestEngine engine = new TestEngine(props);
 
-        WikiContext ctx = new WikiContext( engine, new WikiPage(engine,"Dummy") );
-        String actualDiff = diff.makeDiffHtml( ctx, oldText, newText);
+        final Context ctx = Wiki.context().create( engine, new WikiPage(engine,"Dummy") );
+        final String actualDiff = diff.makeDiffHtml( ctx, oldText, newText);
 
         Assertions.assertEquals(expectedDiff, actualDiff);
     }
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 4ca9548..f015842 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
@@ -21,7 +21,9 @@
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.render.RenderingManager;
 import org.junit.jupiter.api.AfterEach;
@@ -67,9 +69,9 @@
     public void testShowCountsBasic() throws Exception
     {
         final Page page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
-        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final Context context1 = Wiki.context().create( testEngine, page1 );
         final Page page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
-        final WikiContext context2 = new WikiContext( testEngine, page2 );
+        final Context context2 = Wiki.context().create( testEngine, page2 );
 
         // generate counts:
         testEngine.getManager( RenderingManager.class ).getHTML( context1, page1 );
@@ -81,7 +83,7 @@
         testEngine.saveText( "PageViews", pageViewPageContent );
 
         final Page pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
-        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final Context contextPV = Wiki.context().create( testEngine, pageviews );
 
         final String result = testEngine.getManager( RenderingManager.class ).getHTML( contextPV, pageviews );
 //        System.out.println( result );
@@ -97,9 +99,9 @@
         testEngine.saveText( "TestPageExcluded", "this is test page that should be excluded [{PageViewPlugin}]" );
 
         final Page page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
-        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final Context context1 = Wiki.context().create( testEngine, page1 );
         final Page page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
-        final WikiContext context2 = new WikiContext( testEngine, page2 );
+        final Context context2 = Wiki.context().create( testEngine, page2 );
 
         // generate counts:
         testEngine.getManager( RenderingManager.class ).getHTML( context1, page1 );
@@ -111,7 +113,7 @@
         testEngine.saveText( "PageViews", pageViewPageContent );
 
         final Page pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
-        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final Context contextPV = Wiki.context().create( testEngine, pageviews );
 
         final String result = testEngine.getManager( RenderingManager.class ).getHTML( contextPV, pageviews );
 //        System.out.println( result );
@@ -128,9 +130,9 @@
     public void testShowCountsSorted() throws Exception
     {
         final Page page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
-        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final Context context1 = Wiki.context().create( testEngine, page1 );
         final Page page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
-        final WikiContext context2 = new WikiContext( testEngine, page2 );
+        final Context context2 = Wiki.context().create( testEngine, page2 );
 
         // generate counts:
         testEngine.getManager( RenderingManager.class ).getHTML( context1, page1 );
@@ -142,7 +144,7 @@
         testEngine.saveText( "PageViews", pageViewPageContent );
 
         final Page pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
-        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final Context contextPV = Wiki.context().create( testEngine, pageviews );
 
         final String result = testEngine.getManager( RenderingManager.class ).getHTML( contextPV, pageviews );
 //        System.out.println( result );
@@ -162,13 +164,13 @@
         testEngine.saveText( "TestPage04", "this is test page 04 [{PageViewPlugin}]" );
 
         final Page page1 = testEngine.getManager( PageManager.class ).getPage( "TestPage01" );
-        final WikiContext context1 = new WikiContext( testEngine, page1 );
+        final Context context1 = Wiki.context().create( testEngine, page1 );
         final Page page2 = testEngine.getManager( PageManager.class ).getPage( "TestPage02" );
-        final WikiContext context2 = new WikiContext( testEngine, page2 );
+        final Context context2 = Wiki.context().create( testEngine, page2 );
         final Page page3 = testEngine.getManager( PageManager.class ).getPage( "TestPage03" );
-        final WikiContext context3 = new WikiContext( testEngine, page3 );
+        final Context context3 = Wiki.context().create( testEngine, page3 );
         final Page page4 = testEngine.getManager( PageManager.class ).getPage( "TestPage04" );
-        final WikiContext context4 = new WikiContext( testEngine, page4 );
+        final Context context4 = Wiki.context().create( testEngine, page4 );
 
         // generate counts:
         testEngine.getManager( RenderingManager.class ).getHTML( context1, page1 );
@@ -182,7 +184,7 @@
         testEngine.saveText( "PageViews", pageViewPageContent );
 
         final Page pageviews = testEngine.getManager( PageManager.class ).getPage( "PageViews" );
-        final WikiContext contextPV = new WikiContext( testEngine, pageviews );
+        final Context contextPV = Wiki.context().create( testEngine, pageviews );
 
         final String result = testEngine.getManager( RenderingManager.class ).getHTML( contextPV, pageviews );
 //        System.out.println( result );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/RecentChangesPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/RecentChangesPluginTest.java
index 3a4c3ad..43455b8 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/RecentChangesPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/RecentChangesPluginTest.java
@@ -21,8 +21,9 @@
 
 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.core.Context;
+import org.apache.wiki.api.spi.Wiki;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -35,7 +36,7 @@
     TestEngine testEngine = TestEngine.build( props );
     PluginManager manager = new DefaultPluginManager(testEngine, props);
 
-    WikiContext context;
+    Context context;
 
     @BeforeEach
     public void setUp() throws Exception {
@@ -63,7 +64,7 @@
      */
     @Test
     public void testSimple() throws Exception {
-        context = new WikiContext(testEngine, new WikiPage(testEngine, "TestPage01"));
+        context = Wiki.context().create(testEngine, new WikiPage(testEngine, "TestPage01"));
 
         final String res = manager.execute(context, "{INSERT org.apache.wiki.plugin.RecentChangesPlugin}");
 
@@ -82,7 +83,7 @@
      */
     @Test
     public void testParmInClude() throws Exception {
-        context = new WikiContext(testEngine, new WikiPage(testEngine, "TestPage02"));
+        context = Wiki.context().create(testEngine, new WikiPage(testEngine, "TestPage02"));
 
         final String res = manager.execute( context, "{INSERT org.apache.wiki.plugin.RecentChangesPlugin include='TestPage02*'}" );
 
@@ -99,7 +100,7 @@
      */
     @Test
     public void testParmExClude() throws Exception {
-        context = new WikiContext(testEngine, new WikiPage(testEngine, "TestPage03"));
+        context = Wiki.context().create(testEngine, new WikiPage(testEngine, "TestPage03"));
 
         final String res = manager.execute( context,
                                       "{INSERT org.apache.wiki.plugin.RecentChangesPlugin exclude='TestPage03*'}" );
@@ -117,7 +118,7 @@
      */
     @Test
     public void testNoRecentChanges() throws Exception {
-        context = new WikiContext(testEngine, new WikiPage(testEngine, "TestPage04"));
+        context = Wiki.context().create(testEngine, new WikiPage(testEngine, "TestPage04"));
 
         final String res = manager.execute( context, "{INSERT org.apache.wiki.plugin.RecentChangesPlugin since='-1'}" );
 
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringPagesPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringPagesPluginTest.java
index cdf40fe..34aa905 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringPagesPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringPagesPluginTest.java
@@ -22,7 +22,9 @@
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.api.spi.Wiki;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -76,30 +78,23 @@
         return mkFullLink( page, page );
     }
 
-    private String mkFullLink( final String page, final String link )
-    {
+    private String mkFullLink( final String page, final String link ) {
         return "<a class=\"wikipage\" href=\"/test/Wiki.jsp?page="+link+"\">"+page+"</a>";
     }
 
     @Test
-    public void testSingleReferral()
-        throws Exception
-    {
-        final WikiContext context2 = new WikiContext( engine, new WikiPage(engine, "Foobar") );
+    public void testSingleReferral() throws Exception {
+        final Context context2 = Wiki.context().create( engine, new WikiPage(engine, "Foobar") );
 
-        final String res = manager.execute( context2,
-                                      "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE max=5}");
+        final String res = manager.execute( context2, "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE max=5}");
 
         Assertions.assertEquals( mkLink( "TestPage" )+"<br />",
                       res );
     }
 
     @Test
-    public void testMaxReferences()
-        throws Exception
-    {
-        final String res = manager.execute( context,
-                                      "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE max=5}");
+    public void testMaxReferences() throws Exception {
+        final String res = manager.execute( context, "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE max=5}");
 
         int count = 0;
         int index = -1;
@@ -125,31 +120,22 @@
     }
 
     @Test
-    public void testReferenceWidth()
-        throws Exception
-    {
-        final WikiContext context2 = new WikiContext( engine, new WikiPage(engine, "Foobar") );
-
-        final String res = manager.execute( context2,
-                                      "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE maxwidth=5}");
-
-        Assertions.assertEquals( mkFullLink( "TestP...", "TestPage" )+"<br />",
-                      res );
+    public void testReferenceWidth() throws Exception {
+        final Context context2 = Wiki.context().create( engine, new WikiPage(engine, "Foobar") );
+        final String res = manager.execute( context2, "{INSERT org.apache.wiki.plugin.ReferringPagesPlugin WHERE maxwidth=5}");
+        Assertions.assertEquals( mkFullLink( "TestP...", "TestPage" )+"<br />", res );
     }
 
     @Test
-    public void testInclude()
-        throws Exception
-    {
-        final String res = manager.execute( context,
-                                      "{ReferringPagesPlugin include='*7'}" );
+    public void testInclude() throws Exception {
+        final String res = manager.execute( context, "{ReferringPagesPlugin include='*7'}" );
 
-        Assertions.assertTrue( res.indexOf("Foobar7") != -1, "7" );
-        Assertions.assertTrue( res.indexOf("Foobar6") == -1, "6" );
-        Assertions.assertTrue( res.indexOf("Foobar5") == -1, "5" );
-        Assertions.assertTrue( res.indexOf("Foobar4") == -1, "4" );
-        Assertions.assertTrue( res.indexOf("Foobar3") == -1, "3" );
-        Assertions.assertTrue( res.indexOf("Foobar2") == -1, "2" );
+        Assertions.assertTrue( res.contains( "Foobar7" ), "7" );
+        Assertions.assertEquals( res.indexOf( "Foobar6" ), -1, "6" );
+        Assertions.assertEquals( res.indexOf( "Foobar5" ), -1, "5" );
+        Assertions.assertEquals( res.indexOf( "Foobar4" ), -1, "4" );
+        Assertions.assertEquals( res.indexOf( "Foobar3" ), -1, "3" );
+        Assertions.assertEquals( res.indexOf( "Foobar2" ), -1, "2" );
     }
 
     @Test
@@ -164,10 +150,8 @@
     public void testExclude2()
         throws Exception
     {
-        final String res = manager.execute( context,
-                                      "{ReferringPagesPlugin exclude='*7'}");
-
-        Assertions.assertTrue( res.indexOf("Foobar7") == -1 );
+        final String res = manager.execute( context, "{ReferringPagesPlugin exclude='*7'}");
+        Assertions.assertEquals( res.indexOf( "Foobar7" ), -1 );
     }
 
     @Test
@@ -177,12 +161,12 @@
         final String res = manager.execute( context,
                                       "{ReferringPagesPlugin exclude='*7,*5,*4'}");
 
-        Assertions.assertTrue( res.indexOf("Foobar7") == -1, "7" );
-        Assertions.assertTrue( res.indexOf("Foobar6") != -1, "6" );
-        Assertions.assertTrue( res.indexOf("Foobar5") == -1, "5" );
-        Assertions.assertTrue( res.indexOf("Foobar4") == -1, "4" );
-        Assertions.assertTrue( res.indexOf("Foobar3") != -1, "3" );
-        Assertions.assertTrue( res.indexOf("Foobar2") != -1, "2" );
+        Assertions.assertEquals( res.indexOf( "Foobar7" ), -1, "7" );
+        Assertions.assertTrue( res.contains( "Foobar6" ), "6" );
+        Assertions.assertEquals( res.indexOf( "Foobar5" ), -1, "5" );
+        Assertions.assertFalse( res.contains( "Foobar4" ), "4" );
+        Assertions.assertTrue( res.contains( "Foobar3" ), "3" );
+        Assertions.assertTrue( res.contains( "Foobar2" ), "2" );
     }
 
     @Test
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringUndefinedPagesPluginTest.java b/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringUndefinedPagesPluginTest.java
index b217e57..988c80f 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringUndefinedPagesPluginTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/plugin/ReferringUndefinedPagesPluginTest.java
@@ -16,13 +16,13 @@
 specific language governing permissions and limitations
 under the License.
  */
-
 package org.apache.wiki.plugin;
 
 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.core.Context;
+import org.apache.wiki.api.spi.Wiki;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -30,12 +30,14 @@
 
 import java.util.Properties;
 
+
 public class ReferringUndefinedPagesPluginTest {
+
     Properties props = TestEngine.getTestProperties();
 
 	TestEngine testEngine;
 
-	WikiContext context;
+	Context context;
 
 	PluginManager manager;
 
@@ -48,8 +50,9 @@
         testEngine.saveText("TestPage02", "Some Text for testing 02 which refers [NonExistingPageB] ");
 		testEngine.saveText("TestPage03", "Some Text for testing 03 which refers [NonExistingPageC] ");
 
-        context = new WikiContext( testEngine, testEngine.newHttpRequest(), new WikiPage(testEngine,"TestPage") );
-        manager = new DefaultPluginManager( testEngine, props );	}
+        context = Wiki.context().create( testEngine, testEngine.newHttpRequest(), new WikiPage(testEngine,"TestPage") );
+        manager = new DefaultPluginManager( testEngine, props );
+    }
 
     @AfterEach
     public void tearDown() {
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 1b0c938..dac7843 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
@@ -21,9 +21,10 @@
 
 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.core.Context;
 import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.render.RenderingManager;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -37,7 +38,7 @@
 
     Properties props = TestEngine.getTestProperties();
     TestEngine testEngine;
-    WikiContext context;
+    Context context;
     PluginManager manager;
 
     @BeforeEach
@@ -48,7 +49,7 @@
         testEngine.saveText( "TestPage", "Reference to [Foobar]." );
         testEngine.saveText( "Foobar", "Reference to [Foobar 2], [Foobars]" );
 
-        context = new WikiContext( testEngine, new WikiPage(testEngine, "TestPage") );
+        context = Wiki.context().create( testEngine, new WikiPage(testEngine, "TestPage") );
         manager = new DefaultPluginManager( testEngine, props );
     }
 
@@ -70,7 +71,7 @@
      */
     @Test
     public void testSimpleUndefined() throws Exception {
-        final WikiContext context2 = new WikiContext( testEngine, new WikiPage( testEngine, "Foobar" ) );
+        final Context context2 = Wiki.context().create( testEngine, new WikiPage( testEngine, "Foobar" ) );
         final String res = manager.execute( context2,"{INSERT org.apache.wiki.plugin.UndefinedPagesPlugin" );
         final String exp = "[Foobar 2]\\\\";
 
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 44eb925..ca4d632 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
@@ -21,10 +21,11 @@
 
 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.core.Context;
 import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.providers.PageProvider;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.auth.Users;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.util.FileUtil;
@@ -529,55 +530,55 @@
         throws Exception
     {
         final WikiPage p = new WikiPage( engine, NAME1 );
-        p.setAttribute(WikiPage.CHANGENOTE, "Test change" );
-        final WikiContext context = new WikiContext(engine,p);
+        p.setAttribute(Page.CHANGENOTE, "Test change" );
+        final Context context = Wiki.context().create(engine,p);
 
         engine.getManager( PageManager.class ).saveText( context, "test" );
 
         final Page p2 = engine.getManager( PageManager.class ).getPage( NAME1 );
 
-        Assertions.assertEquals( "Test change", p2.getAttribute(WikiPage.CHANGENOTE) );
+        Assertions.assertEquals( "Test change", p2.getAttribute(Page.CHANGENOTE) );
     }
 
     @Test
     public void testChangeNoteOldVersion()
         throws Exception
     {
-        final WikiPage p = new WikiPage( engine, NAME1 );
+        final Page p = new WikiPage( engine, NAME1 );
 
 
-        final WikiContext context = new WikiContext(engine,p);
+        final Context context = Wiki.context().create(engine,p);
 
-        context.getPage().setAttribute(WikiPage.CHANGENOTE, "Test change" );
+        context.getPage().setAttribute(Page.CHANGENOTE, "Test change" );
         engine.getManager( PageManager.class ).saveText( context, "test" );
 
-        context.getPage().setAttribute(WikiPage.CHANGENOTE, "Change 2" );
+        context.getPage().setAttribute(Page.CHANGENOTE, "Change 2" );
         engine.getManager( PageManager.class ).saveText( context, "test2" );
 
         final Page p2 = engine.getManager( PageManager.class ).getPage( NAME1, 1 );
 
-        Assertions.assertEquals( "Test change", p2.getAttribute(WikiPage.CHANGENOTE) );
+        Assertions.assertEquals( "Test change", p2.getAttribute(Page.CHANGENOTE) );
 
         final Page p3 = engine.getManager( PageManager.class ).getPage( NAME1, 2 );
 
-        Assertions.assertEquals( "Change 2", p3.getAttribute(WikiPage.CHANGENOTE) );
+        Assertions.assertEquals( "Change 2", p3.getAttribute(Page.CHANGENOTE) );
     }
 
     @Test
     public void testChangeNoteOldVersion2() throws Exception
     {
-        final WikiPage p = new WikiPage( engine, NAME1 );
+        final Page p = new WikiPage( engine, NAME1 );
 
-        final WikiContext context = new WikiContext(engine,p);
+        final Context context = Wiki.context().create(engine,p);
 
-        context.getPage().setAttribute( WikiPage.CHANGENOTE, "Test change" );
+        context.getPage().setAttribute( Page.CHANGENOTE, "Test change" );
 
         engine.getManager( PageManager.class ).saveText( context, "test" );
 
         for( int i = 0; i < 5; i++ )
         {
-            final WikiPage p2 = (WikiPage)engine.getManager( PageManager.class ).getPage( NAME1 ).clone();
-            p2.removeAttribute(WikiPage.CHANGENOTE);
+            final Page p2 = engine.getManager( PageManager.class ).getPage( NAME1 ).clone();
+            p2.removeAttribute(Page.CHANGENOTE);
 
             context.setPage( p2 );
 
@@ -586,7 +587,7 @@
 
         final Page p3 = engine.getManager( PageManager.class ).getPage( NAME1, -1 );
 
-        Assertions.assertEquals( null, (String)p3.getAttribute(WikiPage.CHANGENOTE) );
+        Assertions.assertNull( p3.getAttribute( Page.CHANGENOTE ) );
     }
 
     /*
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java b/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
index 5dd12c5..47ef3e0 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
@@ -19,8 +19,10 @@
 package org.apache.wiki.render;
 
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
+import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.parser.JSPWikiMarkupParser;
 import org.apache.wiki.parser.WikiDocument;
 import org.junit.jupiter.api.AfterEach;
@@ -48,8 +50,8 @@
     }
 
     private String render( final String s ) throws IOException {
-        final WikiPage dummyPage = new WikiPage(testEngine,"TestPage");
-        final WikiContext ctx = new WikiContext(testEngine,dummyPage);
+        final Page dummyPage = new WikiPage(testEngine,"TestPage");
+        final Context ctx = Wiki.context().create(testEngine,dummyPage);
 
         final StringReader in = new StringReader(s);
 
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 763ba95..b5945c6 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
@@ -24,8 +24,9 @@
 
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.core.Page;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.pages.PageManager;
 import org.apache.wiki.plugin.WeblogEntryPlugin;
 import org.apache.wiki.plugin.WeblogPlugin;
@@ -77,7 +78,7 @@
 
         final RSSGenerator gen = m_testEngine.getManager( RSSGenerator.class );
 
-        final WikiContext context = new WikiContext( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
+        final Context context = Wiki.context().create( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
 
         final WeblogPlugin blogplugin = new WeblogPlugin();
 
@@ -108,7 +109,7 @@
 
         final RSSGenerator gen = m_testEngine.getManager( RSSGenerator.class );
 
-        final WikiContext context = new WikiContext( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
+        final Context context = Wiki.context().create( m_testEngine, m_testEngine.getManager( PageManager.class ).getPage("TestBlog") );
 
         final WeblogPlugin blogplugin = new WeblogPlugin();
 
@@ -120,8 +121,8 @@
         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" );
+        Assertions.assertTrue( blog.contains( "<description>Foo &amp;quot;blah&amp;quot;.</description>" ), "has Foo" );
+        Assertions.assertTrue( blog.contains( "&lt;b&gt;Bar&lt;/b&gt;" ), "has proper Bar" );
     }
 
 }
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/variables/DefaultVariableManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/variables/DefaultVariableManagerTest.java
index 63a4826..ad79d3c 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/variables/DefaultVariableManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/variables/DefaultVariableManagerTest.java
@@ -20,9 +20,10 @@
 package org.apache.wiki.variables;
 
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
 import org.apache.wiki.api.exceptions.NoSuchVariableException;
+import org.apache.wiki.api.spi.Wiki;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -31,7 +32,7 @@
 public class DefaultVariableManagerTest {
 
     static VariableManager m_variableManager;
-    static WikiContext m_context;
+    static Context m_context;
 
     static final String PAGE_NAME = "TestPage";
 
@@ -39,7 +40,7 @@
     public static void setUp() {
         final TestEngine testEngine = TestEngine.build();
         m_variableManager = new DefaultVariableManager( TestEngine.getTestProperties() );
-        m_context = new WikiContext( testEngine, new WikiPage( testEngine, PAGE_NAME ) );
+        m_context = Wiki.context().create( testEngine, new WikiPage( testEngine, PAGE_NAME ) );
     }
 
     @Test
diff --git a/jspwiki-markdown/src/test/java/org/apache/wiki/render/markdown/MarkdownRendererTest.java b/jspwiki-markdown/src/test/java/org/apache/wiki/render/markdown/MarkdownRendererTest.java
index f400a82..81c3c7e 100644
--- a/jspwiki-markdown/src/test/java/org/apache/wiki/render/markdown/MarkdownRendererTest.java
+++ b/jspwiki-markdown/src/test/java/org/apache/wiki/render/markdown/MarkdownRendererTest.java
@@ -20,10 +20,12 @@
 
 import net.sf.ehcache.CacheManager;
 import org.apache.wiki.TestEngine;
-import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
 import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.core.Context;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.core.Page;
 import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.api.spi.Wiki;
 import org.apache.wiki.attachment.Attachment;
 import org.apache.wiki.attachment.AttachmentManager;
 import org.apache.wiki.pages.PageManager;
@@ -106,7 +108,7 @@
         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",
-                                 ( ( WikiPage )testEngine.getManager( PageManager.class ).getPage( PAGE_NAME ) ).getAcl().toString() );
+                                 ( testEngine.getManager( PageManager.class ).getPage( PAGE_NAME ) ).getAcl().toString() );
     }
 
     @Test
@@ -293,16 +295,16 @@
         return translate( new WikiPage( testEngine, PAGE_NAME ), src );
     }
 
-    String translate( final WikiEngine e, final String src ) throws Exception {
+    String translate( final Engine e, final String src ) throws Exception {
         return translate( e, new WikiPage( testEngine, PAGE_NAME ), src );
     }
 
-    String translate( final WikiPage p, final String src ) throws Exception {
+    String translate( final Page p, final String src ) throws Exception {
         return translate( testEngine, p, src );
     }
 
-    String translate( final WikiEngine e, final WikiPage p, final String src ) throws Exception {
-        final WikiContext context = new WikiContext( e, testEngine.newHttpRequest(), p );
+    String translate( final Engine e, final Page p, final String src ) throws Exception {
+        final Context context = Wiki.context().create( e, testEngine.newHttpRequest(), p );
         final MarkdownParser tr = new MarkdownParser( context, new BufferedReader( new StringReader( src ) ) );
         final MarkdownRenderer conv = new MarkdownRenderer( context, tr.parse() );
         newPage( p.getName(), src );