public  static  void registerVTI
        (
         Method         method,
         String[]       columnNames,
         String[]       columnTypes,
         boolean        readsSqlData
         )
        throws Exception
    {
        String              methodName = method.getName();
        String              sqlName = doubleQuote( methodName );
        Class               methodClass = method.getDeclaringClass();
        Class[]             parameterTypes = method.getParameterTypes();
        int                 parameterCount = parameterTypes.length;
        int                 columnCount = columnNames.length;
        StringBuilder       buffer = new StringBuilder();

        buffer.append( "create function " );
        buffer.append( sqlName );
        buffer.append( "\n( " );
        for ( int i = 0; i < parameterCount; i++ )
        {
            if ( i > 0 ) { buffer.append( ", " ); }
            
            String      parameterType = mapType( parameterTypes[ i ] );

            buffer.append( "arg" ); buffer.append( i );
            buffer.append( " " ); buffer.append( parameterType );
        }
        buffer.append( " )\n" );

        buffer.append( "returns table\n" );
        buffer.append( "( " );
        for ( int i = 0; i < columnCount; i++ )
        {
            if ( i > 0 ) { buffer.append( ", " ); }

            buffer.append( "\"" + columnNames[ i ] + "\"" );
            buffer.append( " " ); buffer.append( columnTypes[ i ] );
        }
        buffer.append( " )\n" );
        
        buffer.append( "language java\n" );
        buffer.append( "parameter style DERBY_JDBC_RESULT_SET\n" );
        if ( readsSqlData ) { buffer.append( "reads sql data\n" ); }
        else { buffer.append( "no sql\n" ); }
        
        buffer.append( "external name " );
        buffer.append( "'" );
        buffer.append( methodClass.getName() ); buffer.append( "." ); buffer.append( methodName );
        buffer.append( "'\n" );
        
        executeDDL( buffer.toString() );
    }