DefaultExecutionContextManager implements ExecutionContextManager { @Override public ExecutionContext clone(ExecutionContext context) throws ExecutionContextException { ExecutionContext clonedContext = new ExecutionContext(); try { this.execution.pushContext(clonedContext); } catch (RuntimeException e) { throw new ExecutionContextException("Failed to push cloned execution context.", e); } try { runInitializers(clonedContext); } finally { this.execution.popContext(); } return clonedContext; }  @Override ExecutionContext clone(ExecutionContext context); @Override void initialize(ExecutionContext context); @Override void pushContext(ExecutionContext context, boolean inherit); @Override void popContext();  }
@Test void cloneExecutionContext() throws Exception { ExecutionContext context = new ExecutionContext(); this.execution.setContext(context); Map<Object, Object> xwikicontext = new HashMap<>(); context.newProperty("property1").initial(xwikicontext).inherited().declare(); context.newProperty("property2").initial(xwikicontext).inherited().makeFinal().cloneValue().declare(); ExecutionContext clonedContext = contextManager.clone(context); assertSame(context, execution.getContext()); assertEquals("value", ((List<String>) clonedContext.getProperty("key")).get(0)); assertNotSame(context.getProperty("key"), clonedContext.getProperty("key")); assertSame(xwikicontext, clonedContext.getProperty("property1")); assertNotSame(xwikicontext, clonedContext.getProperty("property2")); }