class JcrResultSetMetaData implements ResultSetMetaData {

    @Override
    public int isNullable( int column ) throws SQLException {
        if (nullable == null) {
            int length = getColumnCount();
            nullable = new int[length];
            for (int i = 0; i != length; ++i) {
                nullable[i] = -1;
            }
        } else {
            int result = nullable[column - 1];
            if (result != -1) {
                // Already found this value, so return it ...
                return result;
            }
        }
        // Find the node type for the column (given that the column name is the property name and
        // the table name is the node type), and determine if the property definition is multi-valued or not mandatory.
        String nodeTypeName = getTableName(column);
        if (nodeTypeName.length() == 0) {
            // There is no table for the column, so therefore we don't know the node type ...
            return ResultSetMetaData.columnNullableUnknown;
        }
        String propertyName = getColumnName(column);
        boolean singleProp = false;
        boolean singleResidual = false;
        boolean multiResidual = false;
        NodeType type = connection.nodeType(nodeTypeName);
        for (PropertyDefinition defn : type.getPropertyDefinitions()) {
            if (defn.getName().equals(propertyName)) {
                if (defn.isMultiple() || defn.isMandatory()) {
                    // We know this IS nullable
                    return ResultSetMetaData.columnNullable;
                }
                // Otherwise this is a single-valued property that is mandatory,
                // but we can't return columnNotNullable because we may not have found the multi-valued property ...
                singleProp = true;
            } else if (defn.getName().equals("*")) { // Residual
                if (defn.isMultiple() || defn.isMandatory()) multiResidual = true;
                else singleResidual = true;
            }
        }
        int result = ResultSetMetaData.columnNullableUnknown;
        if (multiResidual) result = ResultSetMetaData.columnNullable;
        else if (singleProp || singleResidual) result = ResultSetMetaData.columnNoNulls;
        nullable[column - 1] = result;
        return result;
    }

    protected  JcrResultSetMetaData( JcrConnection connection,
                                    QueryResult results );

}