docs: protected AttributeInfo getAttributeInfo(String attr, boolean useOuterJoins, UserAlias aUserAlias, Map pathClasses)
  	{
  		AttributeInfo result = new AttributeInfo();
  		TableAlias tableAlias;
  		SqlHelper.PathInfo pathInfo = SqlHelper.splitPath(attr);
  		String colName = pathInfo.column;
  		int sp;
  
  		// BRJ:
  		// check if we refer to an attribute in the parent query
  		// this prefix is temporary !
  		if (colName.startsWith(Criteria.PARENT_QUERY_PREFIX) && m_parentStatement != null)
  		{
  			String[] fieldNameRef = {colName.substring(Criteria.PARENT_QUERY_PREFIX.length())};
  			return m_parentStatement.getAttributeInfo(fieldNameRef[0], useOuterJoins, aUserAlias, pathClasses);
  		}
  
  		sp = colName.lastIndexOf(".");
  		if (sp == -1)
  		{
  			tableAlias = getRoot();
  		}
  		else
  		{
  			String pathName = colName.substring(0, sp);
  			String[] fieldNameRef = {colName.substring(sp + 1)};
  
  			tableAlias = getTableAlias(pathName, useOuterJoins, aUserAlias, fieldNameRef, pathClasses);
  			/**
  			 * if we have not found an alias by the pathName or
  			 * aliasName (if given), try again because pathName
  			 * may be an aliasname. it can be only and only if it is not
  			 * a path, which means there may be no path separators (,)
  			 * in the pathName.
  			 */
  			if ((tableAlias == null) && (colName.lastIndexOf(".") == -1))
  			{
  				/**
  				 * pathName might be an alias, so check this first
  				 */
  				tableAlias = getTableAlias(pathName, useOuterJoins, new UserAlias(pathName, pathName, pathName), null, pathClasses);
  			}
  
  			if (tableAlias != null)
  			{
  				// correct column name to match the alias
  				// productGroup.groupName -> groupName
  				pathInfo.column = fieldNameRef[0];
  			}
  		}
  
  		result.tableAlias = tableAlias;
  		result.pathInfo = pathInfo;
  		return result;
  	}