public void switchUser(String pUsername) 
  throws SQLException {
    
    pUsername = pUsername.toUpperCase();
    
    //Validate not attempting to CONNECT as the main user
    if(mPromoteUserName.equals(pUsername)){
      throw new ExFatalError("Illegal attempt to CONNECT as promotion control user " + pUsername + "; use DISCONNECT instead");
    }
    
    //If we're already connected as the requested user, short-circuit out
    if(mProxyUserName.equals(pUsername) || (SYSDBA_USER.equals(pUsername) && mIsSysDBAConnectionActive)){
      Logger.logDebug("Connect as " + pUsername + " requested but already connected as that user");
      return;
    }
    
    //Validate that there is no active transaction before attempting to CONNECT
    if(isTransactionActive()){
      safelyRollback();
      throw new ExFatalError("Attempted to switch user from " + currentUserName() + " to " + pUsername + " but a transaction is still active");
    }
    
    //Disconnect from the current proxy user first
    if(mIsProxyConnectionActive || mIsSysDBAConnectionActive){
      disconnectProxyUser();
    }
    
    if(SYSDBA_USER.equals(pUsername)){
      //Switch the connection to be SYSDBA
      //Create a connection just in time if necessary
      if(mSysDBAPromoteConnection == null){
        mSysDBAPromoteConnection = createOracleConnection(mJDBCConnectString, mPromoteUserName, mPromoteUserPassword, true);
      }
      mIsSysDBAConnectionActive = true;
    }
    else {
      //Switch to a proxy connection
      
      //Allow the target user to connect through the promotion user
      grantProxyConnectToUser(pUsername);
      
      //Switch the session
      Properties lProps = new Properties();
      lProps.put(OracleConnection.PROXY_USER_NAME, pUsername);
      mPromoteConnection.openProxySession(OracleConnection.PROXYTYPE_USER_NAME, lProps);
      
      mProxyUserName = pUsername;
      mIsProxyConnectionActive = true;
    }    
    
  }