code: String join(Dialect d, boolean isTopLevel, DialectSqlItem function, DialectSqlItem[] items) {//NOSONAR
  		int pos = 0;
  		for (DialectSqlItem item : items) {
  			if (item.subItems != null) {
  				String value;
  				if (pos > 0 && items[pos - 1] != null && items[pos - 1].type == 'F')
  					// join as parameters
  					value = join(d, false, items[pos - 1], item.subItems);
  				else
  					value = join(d, false, null, item.subItems); // join as
  																	// string
  				item.type = 'S';
  				item.value = value;
  				item.subItems = null;
  			}
  			pos++;
  		} // now there is no subItems
  
  		if (function != null) {
  			List<String> l = new ArrayList<String>();
  			for (DialectSqlItem item : items) {
  				if (item.type != '0')
  					l.add((String) item.value);
  			}
  			return renderFunction(d, function, l.toArray(new String[l.size()]));
  		}
  
  		StringBuilder sb = new StringBuilder();
  		if (!isTopLevel)
  			sb.append("(");
  		for (DialectSqlItem item : items)
  			if (item.type != '0') {
  				sb.append(item.value);
  			}
  		if (!isTopLevel)
  			sb.append(")");
  		return sb.toString();
  	}
docs: Join items list into one String, if function is null, join as String,
  otherwise treat as function parameters