@Test
  public void testRequestScope() {
    // Create global scope
    int nPrev = AbstractScopeSPI.getBegin();
    int nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.onGlobalBegin("global");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // Create request scope
    nPrev = AbstractScopeSPI.getBegin();
    nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.onRequestBegin("appid", "scopeid", "sessionid");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // End request scope
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.onRequestEnd();
    assertEquals(nPrev + 1, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getEnd());

    // End global scope
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.onGlobalEnd();
    assertEquals(nPrev + 1, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getEnd());
  }
  @Test
  public void testSessionScopes() {
    // Create global scope
    int nPrev = AbstractScopeSPI.getBegin();
    int nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.onGlobalBegin("global");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // Create request scope
    nPrev = AbstractScopeSPI.getBegin();
    nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.onRequestBegin("appid", "scopeid", "sessionid");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // Create application scope
    nPrev = AbstractScopeSPI.getBegin();
    nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.getApplicationScope();
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // Create second application scope
    nPrev = AbstractScopeSPI.getBegin();
    nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.getApplicationScope("any other blabla");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // Begin session scope
    nPrev = AbstractScopeSPI.getBegin();
    nPrevT = AbstractThrowingScopeSPI.getBegin();
    final ISessionScope aSessionScope = ScopeManager.getSessionScope();
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // End request scope
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.onRequestEnd();
    assertEquals(nPrev + 1, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getEnd());

    // End session scope
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.destroySessionScope(aSessionScope);
    assertEquals(nPrev + 1, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getEnd());

    // End global scope and application scopes
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.onGlobalEnd();
    assertEquals(nPrev + 3, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 3, AbstractThrowingScopeSPI.getEnd());
  }
  @Test
  public void testGlobalScope() {
    // Create global scope only
    int nPrev = AbstractScopeSPI.getBegin();
    int nPrevT = AbstractThrowingScopeSPI.getBegin();
    ScopeManager.onGlobalBegin("global");
    assertEquals(nPrev + 1, AbstractScopeSPI.getBegin());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getBegin());

    // End global scope
    nPrev = AbstractScopeSPI.getEnd();
    nPrevT = AbstractThrowingScopeSPI.getEnd();
    ScopeManager.onGlobalEnd();
    assertEquals(nPrev + 1, AbstractScopeSPI.getEnd());
    assertEquals(nPrevT + 1, AbstractThrowingScopeSPI.getEnd());
  }
  @Nonnull
  public static RequestScopeInitializer create(
      @Nonnull @Nonempty final String sApplicationID,
      @Nonnull final HttpServletRequest aHttpRequest,
      @Nonnull final HttpServletResponse aHttpResponse) {
    ValueEnforcer.notEmpty(sApplicationID, "ApplicationID");

    // Check if a request scope is already present
    final IRequestWebScope aExistingRequestScope = WebScopeManager.getRequestScopeOrNull();
    if (aExistingRequestScope != null) {
      // A scope is already present - e.g. from a scope aware filter

      // Check if scope is in destruction or destroyed!
      if (aExistingRequestScope.isValid()) {
        // Check the application IDs
        final String sExistingApplicationID =
            ScopeManager.getRequestApplicationID(aExistingRequestScope);
        if (!sApplicationID.equals(sExistingApplicationID)) {
          // Application ID mismatch!
          s_aLogger.warn(
              "The existing request scope has the application ID '"
                  + sExistingApplicationID
                  + "' but now the application ID '"
                  + sApplicationID
                  + "' should be used. The old application ID '"
                  + sExistingApplicationID
                  + "' is continued to be used!!!");
        }
        return new RequestScopeInitializer(aExistingRequestScope, false);
      }

      // Wow...
      s_aLogger.error(
          "The existing request scope is no longer valid - creating a new one: "
              + aExistingRequestScope.toString());
    }

    // No valid scope present
    // -> create a new scope
    final IRequestWebScope aRequestScope =
        WebScopeManager.onRequestBegin(sApplicationID, aHttpRequest, aHttpResponse);
    return new RequestScopeInitializer(aRequestScope, true);
  }
 /**
  * @param bCreateIfNotExisting <code>true</code> to create a new scope, if none is present yet,
  *     <code>false</code> to return <code>null</code> if either no global scope or no application
  *     scope is present.
  * @return The scope to be used for this type of singleton.
  */
 @Nullable
 private static IApplicationScope _getStaticScope(final boolean bCreateIfNotExisting) {
   return ScopeManager.getApplicationScope(bCreateIfNotExisting);
 }