docs: public DatasourceConnection getDatasourceConnection(Config config, DataSource datasource, String user, String pass) throws PageException {
  	config = ThreadLocalPageContext.getConfig(config);
  
  	if (StringUtil.isEmpty(user)) {
  	    user = datasource.getUsername();
  	    pass = datasource.getPassword();
  	}
  	if (pass == null) pass = "";
  
  	// get stack
  	DCStack stack = getDCStack(datasource, user, pass);
  	int max = datasource.getConnectionLimit();
  
  	// get an existing connection
  	DatasourceConnection rtn;
  	boolean wait = false;
  	outer: while (true) {
  	    rtn = null;
  
  	    // wait until it is again my turn
  	    if (wait) {
  		SystemUtil.wait(waiter, WAIT);
  		wait = false;
  	    }
  
  	    synchronized (stack) {
  		// do we have already to many open connections?
  		if (max != -1) {
  		    RefInteger _counter = stack.getCounter();// _getCounter(stack,datasource,user,pass);
  		    if (max <= _counter.toInt()) {// go back ant wait
  			wait = true;
  			continue outer;
  		    }
  		}
  
  		// get an existing connection
  		while (!stack.isEmpty()) {
  		    DatasourceConnection dc = (DatasourceConnection) stack.get();
  		    if (dc != null) {
  			rtn = dc;
  			break;
  		    }
  		}
  
  		_inc(stack, datasource, user, pass); // if new or fine we
  						     // increase in any case
  		// create a new instance
  		if (rtn == null) {
  		    try {
  			rtn = loadDatasourceConnection(config, datasource, user, pass);
  		    }
  		    catch (PageException pe) {
  			_dec(stack, datasource, user, pass);
  			throw pe;
  		    }
  		    if (rtn instanceof DatasourceConnectionImpl) ((DatasourceConnectionImpl) rtn).using();
  		    return rtn;
  		}
  	    }
  
  	    // we get us a fine connection (we do validation outside the
  	    // synchronized to safe shared time)
  	    if (isValid(rtn, Boolean.TRUE)) {
  		if (rtn instanceof DatasourceConnectionImpl) ((DatasourceConnectionImpl) rtn).using();
  		return rtn;
  	    }
  
  	    // we have an invalid connection (above check failed), so we have to
  	    // start over
  	    synchronized (stack) {
  		_dec(stack, datasource, user, pass); // we already did increment
  						     // in case we are fine
  		SystemUtil.notify(waiter);
  	    }
  	    IOUtil.closeEL(rtn.getConnection());
  	    rtn = null;
  	}
      }