CREATE OR REPLACE PROCEDURE dbms_feature_priv_capture
     ( feature_boolean  OUT NUMBER,
       aux_count        OUT NUMBER,
       feature_info     OUT CLOB)
AS
  cursor priv_capture is select id#, type,
                         CASE type 
                           WHEN 1 THEN 'DATABASE'
                           WHEN 2 THEN 'ROLE'
                           WHEN 3 THEN 'CONTEXT'
                           WHEN 4 THEN 'ROLE_AND_CONTEXT'
                         END l_type
                         from sys.priv_capture$ where id# >= 5000;
  l_capture   priv_capture%ROWTYPE;
  feature_usage varchar2(1000) := NULL;
  l_prefix      varchar2(100) := NULL;
  l_count       number := 0;
begin
  -- initialize output parameters
  aux_count := 0;
  feature_boolean := 0;
  feature_info := NULL;
  
  -- total number of captures
  select count(*) into l_count from sys.priv_capture$ where id# >= 5000;

  if (l_count > 0) then
    -- feature is used if a capture is created
    feature_boolean := 1;
    aux_count := l_count;

    l_prefix := 'Number of privilege captures=' || to_char(l_count) 
                || Chr(13) || Chr(10) || '(';
   
    -- Information for each capture
    for l_capture in priv_capture loop
        
        feature_usage := feature_usage || 'Type=' || l_capture.l_type;

        select count(*) into l_count from sys.capture_run_log$ 
        where capture = l_capture.id#;

        feature_usage := feature_usage || ' Number of Runs=' || 
                         to_char(l_count) || Chr(13) || Chr(10);
    end loop;
    feature_info := to_clob(l_prefix || feature_usage || ')');

  end if; 
end dbms_feature_priv_capture;
/
show errors;

/*******************************************************************
 * DBMS_FEATURE_TSDP
 *  The procedure to detect usage for TSDP
 *******************************************************************/

create or replace procedure DBMS_FEATURE_TSDP
    (feature_boolean  OUT  NUMBER,
     aux_count        OUT  NUMBER,
     feature_info     OUT  CLOB)
AS
    feature_usage         varchar2(1000);
    num_sensitive_cols    number;
    num_policies          number;
    num_columns_protected number;
    num_sensitive_types   number;

begin
    -- initialize
    feature_boolean := 0;
    aux_count := 0;
    num_sensitive_cols := 0;
    num_policies := 0;
    num_columns_protected := 0;
    num_sensitive_types := 0;

    -- check if sensitive columns have been identified.
    execute immediate 'select count(*) from DBA_SENSITIVE_DATA'
        into num_sensitive_cols;

    -- check if Sensitive Column Types have been created.
    execute immediate 'select count(*) from DBA_SENSITIVE_COLUMN_TYPES'
            into num_sensitive_types;

    -- check if TSDP policies have been created.
    execute immediate 'select count(*) from DBA_TSDP_POLICY_FEATURE'
            into num_policies;

    -- check for protected sensitive columns.
    execute immediate 'select count(*) from DBA_TSDP_POLICY_PROTECTION'
            into num_columns_protected;

    -- Feature_usage information will contain:
    -- number of Sensitive Column Types created,
    -- number of TSDP policies created, and 
    -- number of Sensitive Columns protected using TSDP. 
    -- Note: Number of Sensitive Columns identified is not shown here
    --       as it is a sensitive metric.
    feature_usage :=
                'Number of Sensitive Column Types created: ' ||
                 to_char(num_sensitive_types) ||
        ', ' || 'Number of TSDP policies created: ' ||
                 to_char(num_policies) ||
        ', ' || 'Number of Sensitive Columns protected using TSDP: ' ||
                 to_char(num_columns_protected)
        ;

    -- In order to conclude that TSDP is in use, we check if
    --   atleast one Sensitive Column Type is created,
    --   OR if atleast one column identified as sensitive,
    --   OR atleast two TSDP policies exist. (Note that
    --      REDACT_AUDIT policy is created by default,
    --      and this policy cannot be dropped).
    if ((num_sensitive_cols > 0) or (num_sensitive_types > 0)
        or (num_policies > 1))
     then
       feature_boolean := 1;
       feature_info := to_clob(feature_usage);

    else
       feature_info := to_clob('Transparent Sensitive Data Protection ' ||
                               'feature not used');

    end if;

end;
/

/***************************************************************
 * DBMS_FEATURE_SEG_MAIN_ONL_COMP
 *   Segment Maintenance Online Compress
 *   This procedure tracks the segments compressed as a result 
 *   of an online partition maintenance operation like MOVE.
 ***************************************************************/
CREATE OR REPLACE PROCEDURE DBMS_FEATURE_SEG_MAIN_ONL_COMP
  (isAnyFragCompressed OUT  NUMBER,
   numFragsCompressed  OUT  NUMBER,
   fragObjNumList      OUT  CLOB)
AS
  partnFragsCompressed     NUMBER;
  subpartnFragsCompressed  NUMBER;
  fragObjNumListStr        VARCHAR2(1000);

  -- select from tabpart$
  cursor tp_cursor is      select tp.obj# from sys.tabpart$ tp
                           where bitand(tp.flags, 33554432) = 33554432;
  
  -- select from tabsubpart$
  cursor tsp_cursor is     select tsp.obj# from sys.tabsubpart$ tsp 
                           where bitand(tsp.flags, 33554432) = 33554432;
BEGIN
  -- initialize
  isAnyFragCompressed := 0;
  numFragsCompressed  := 0;
  fragObjNumListStr   := NULL;

  -- count partitions compressed through an online PMOP
  select count(*) into partnFragsCompressed
  from sys.tabpart$ where bitand(flags, 33554432) = 33554432;

  -- count subpartitions compressed through an online PMOP
  select count(*) into subpartnFragsCompressed 
  from sys.tabsubpart$ where bitand(flags, 33554432) = 33554432;

  -- loop through tabpart$
  if (partnFragsCompressed > 0) then
    isAnyFragCompressed := 1;
    fragObjNumListStr   := fragObjNumListStr || 'Partition Obj# list: ';
    for ri in tp_cursor 
    loop
      fragObjNumListStr := fragObjNumListStr || ri.obj# || ':';
    end loop;
    fragObjNumListStr := fragObjNumListStr || chr(10);
  end if;
  
  -- loop through subpart$
  if (subpartnFragsCompressed > 0) then
    isAnyFragCompressed := 1;
    fragObjNumListStr   := fragObjNumListStr || 'Subpartition Obj# list: ';
    for ri in tsp_cursor 
    loop
      fragObjNumListStr := fragObjNumListStr || ri.obj# || ':';
    end loop;
  end if;

  -- populate the variables to be returned
  if (partnFragsCompressed + subpartnFragsCompressed > 0) then
    isAnyFragCompressed := 1;
    numFragsCompressed  := partnFragsCompressed + subpartnFragsCompressed;
    fragObjNumList      := to_clob(fragObjNumListStr);
  end if;

END DBMS_FEATURE_SEG_MAIN_ONL_COMP;
/

show errors;


/******************************************************************************
 * DBMS_FEATURE_EMX
 *  The procedure to detect usage for EM Express
 *****************************************************************************/

CREATE OR REPLACE PROCEDURE dbms_feature_emx
     ( feature_boolean  OUT NUMBER,
       aux_count        OUT NUMBER,
       feature_info     OUT CLOB)
AS
  -- total em express usage count since last feature usage collection
  l_count_total_delta number := 0;

  -- total em express usage count since the first time it's used
  l_count_total number := 0;

  -- feature_info clob
  l_detailed_usage_clob CLOB := NULL;

  -- feature_info xml
  l_detailed_usage_xml xmltype := NULL;

  -- new xml to add to feature_info xml for one report
  l_report_usage_xml xmltype   := NULL;

  -- xpath key to find out if report already has entry in feature_info xml
  l_report_usage_key varchar2(32767);

  -- report name
  l_report_name varchar2(32767) := NULL;

  -- statistics of existing entry in feature_info xml for report
  l_old_report_count         number;
  l_old_report_avg_time      number;
  l_old_report_avg_cputime   number;

  -- new statistics to put into feature_info xml for report
  l_new_report_count         number:= NULL;
  l_new_report_total_time    number:= NULL;
  l_new_report_avg_time      number:= NULL;
  l_new_report_total_cputime number:= NULL;
  l_new_report_avg_cputime   number:= NULL;

  -- last db feature usage sample collection time
  l_last_collection_time date;

  -- Query to select the delta since last feature usage collection
  -- from internal fixed table X$KEXSVFU.
  -- Note if count for the report is 0, but last request timestamp is greater
  -- than or equal to the latest sample date of db feature usage framework,
  -- then this report must have been used at least once, therefore decoding
  -- count from 0 to 1.
  -- If in CDB, returned result is for this container only
  cursor emx_fu_cursor(p_last_collection_time date) is      
    select report, 
           sum(total_count) as total_count, 
           sum(total_elapsed_time) as total_elapsed_time, 
           sum(total_cpu_time) as total_cpu_time 
      from table(gv$(cursor(
             select report_kexsvfu       as report, 
                    decode(count_kexsvfu, 0, 1, count_kexsvfu) as total_count, 
                    elapsed_time_kexsvfu as total_elapsed_time,
                    cpu_time_kexsvfu     as total_cpu_time
               from X$KEXSVFU
              where last_req_time_kexsvfu >= p_last_collection_time
                and con_id = sys_context('userenv', 'con_id'))))
    group by report;

begin

  -- initialize output parameters
  feature_boolean := 0;
  aux_count := 0;
  feature_info := NULL;

  -- get total em express usage count from aux_count column and
  -- detailed em express usage info from feature_info column before 
  -- last usage collection
  begin
    select nvl(aux_count, 0), feature_info
      into l_count_total, l_detailed_usage_clob
      from dba_feature_usage_statistics
     where name = 'EM Express';
  exception
    when NO_DATA_FOUND then
      l_count_total := 0;
      l_detailed_usage_clob := NULL;
  end;

  -- if no feature_info xml exists, construct a brand new one
  if (l_detailed_usage_clob is NULL) then
    l_detailed_usage_xml := 
      xmltype('<emx_usage time_unit="us"></emx_usage>');
  -- otherwise update the existing one
  else
    l_detailed_usage_xml := xmltype(l_detailed_usage_clob);
  end if;

  -- get last db feature usage collection time
  select nvl(max(last_sample_date), sysdate-7)
    into l_last_collection_time
    from dba_feature_usage_statistics;

  -- get report usage info since last feature usage collection
  for rc in emx_fu_cursor(l_last_collection_time)
  loop
    l_report_name              := rc.report;
    l_new_report_count         := rc.total_count;
    l_new_report_total_time    := rc.total_elapsed_time;
    l_new_report_total_cputime := rc.total_cpu_time;

    -- update total count for all EM Express reports since last usage
    -- collection, this will indicate if EM Express has been used since last
    -- collection, and be added to aux_count column
    l_count_total_delta := l_count_total_delta + l_new_report_count;

    --
    -- update the feature_info detail xml
    --

    -- build the xpath key to find out if the report already exists
    -- in the xml. The key looks like: 
    --   '//report_usage[@report="<report_id>"]'
    l_report_usage_key := '//report_usage[' ||
                          '@report="' || l_report_name || '"' ||
                          ']';

    -- find out if an xml element for this report already exists in the xml
    if (l_detailed_usage_xml.existsNode(l_report_usage_key) > 0) then

      -- get the old count for this report 
      -- if any of the attributes is not found for this report, 
      -- reset it to 0
      select NVL(EXTRACTVALUE(l_detailed_usage_xml, 
                              l_report_usage_key || '//@count'), 0),
             NVL(EXTRACTVALUE(l_detailed_usage_xml, 
                              l_report_usage_key || '//@avg_elapsed_time'), 0),
             NVL(EXTRACTVALUE(l_detailed_usage_xml, 
                              l_report_usage_key || '//@avg_cpu_time'), 0)
        into l_old_report_count, 
             l_old_report_avg_time,
             l_old_report_avg_cputime
        from dual;

      -- update the statistics, increment count and total time with stats 
      -- since the last usage collection
      l_new_report_count 
        := l_old_report_count + l_new_report_count; 

      -- recalculate average time
      l_new_report_avg_time 
        := round((l_old_report_avg_time * l_old_report_count 
                  + l_new_report_total_time) / l_new_report_count, 1);

      l_new_report_avg_cputime 
        := round((l_old_report_avg_cputime * l_old_report_count
                 + l_new_report_total_cputime) / l_new_report_count, 1);

      -- update the xml using the new stats
      select updateXML(l_detailed_usage_xml, 
                       l_report_usage_key || '//@count', 
                       l_new_report_count,
                       l_report_usage_key || '//@avg_elapsed_time', 
                       l_new_report_avg_time,
                       l_report_usage_key || '//@avg_cpu_time',
                       l_new_report_avg_cputime)
        into l_detailed_usage_xml
        from dual;

    -- if no xml element is found for this report, construct a new one
    else
      -- calculate average time
      l_new_report_avg_time    
        := round(l_new_report_total_time / l_new_report_count, 1);
      l_new_report_avg_cputime 
        := round(l_new_report_total_cputime / l_new_report_count, 1);

      -- construct new xml element for this report usage
      select xmlelement("report_usage", 
                        xmlattributes(
                          l_report_name              as "report",
                          l_new_report_count         as "count",
                          l_new_report_avg_time      as "avg_elapsed_time",
                          l_new_report_avg_cputime   as "avg_cpu_time"))
        into l_report_usage_xml
        from dual;

      -- append this report usage to the main emx feature usage xml
      l_detailed_usage_xml := 
        l_detailed_usage_xml.appendChildxml('/*', l_report_usage_xml);

    end if;

  end loop;

  -- update feature_boolean to indicate if em express has been used or not
  -- by setting it to the total count since last usage collection
  feature_boolean := l_count_total_delta;

  -- update total count in aux_count column
  aux_count := l_count_total + l_count_total_delta;

  -- update feature_info for the new collection
  feature_info := l_detailed_usage_xml.getClobVal();

end dbms_feature_emx;
/
show errors;

/****************************************************************
 * DBMS_FEATURE_IMA
 * The procedure to detect In-Memory Aggregation usage
 ****************************************************************/
create or replace procedure DBMS_FEATURE_IMA(
    feature_boolean OUT NUMBER,
    aux_count       OUT NUMBER,
    feature_info    OUT CLOB)
AS
    feature_usage               varchar2(1000);
    num_kv                      number;
    avg_num_dim                 number;
    max_num_dim                 number;
    num_fact                    number;

BEGIN
    feature_boolean             := 0;
    aux_count                   := 0;

    -- find the total number of recent key vectors 
    execute immediate 'select count(*) from gv$key_vector 
                       where state = ''FINISHED'''
      into num_kv;

    -- average number of recent key vectors per query, overall maximum and
    -- total number of unique fact tables referenced (does not include 
    -- complex facts)
    execute immediate 'select round(avg(key_vector_count),2),
                              max(key_vector_count),
                              count(distinct fact_name)
                       from (select fact_name, count(*) key_vector_count
                             from gv$key_vector
                             where state = ''FINISHED''
                             group by sql_id, sql_exec_id, fact_name)'
      into avg_num_dim, max_num_dim, num_fact;

    --Summary
    feature_usage :=
        ' In-Memory Aggregation Feature Usage: ' ||
                'Total Number of Key Vectors: ' ||
                  to_char(num_kv) ||
         ', ' || 'Maximum Number of Key Vectors for a Query: ' ||
                  to_char(max_num_dim) ||
        ', ' || 'Average Number of Key Vectors per Query: ' ||
                  to_char(avg_num_dim) ||
        ', ' || 'Total Number of Unique Fact Tables: ' ||
                  to_char(num_fact);

     if (num_kv > 0) then
      feature_boolean := 1;
      feature_info := to_clob(feature_usage);
    else
      feature_boolean := 0;
      feature_info := to_clob('In-Memory Aggregation Not Detected');
    end if;
END DBMS_FEATURE_IMA;
/
show errors;

/****************************************************************
 * DBMS_FEATURE_IMFS
 * The procedure to detect In-Memory FastStart usage
 ****************************************************************/
create or replace procedure DBMS_FEATURE_IMFS (
    feature_boolean OUT NUMBER,
    aux_count       OUT NUMBER,
    feature_info    OUT CLOB)
as
  val       varchar2(4096);     -- FS status
  tbs       varchar2(4096);     -- FS tablespace name
  spspace   number;             -- space used by savepoints
  spcnttot  number;             -- total number of savepoints processed by FS
BEGIN
  select value into val from SYSDBIMFS_METADATA$ where key='STATUS';
  if( val = 'ENABLE' ) then
    feature_boolean := 1;
    
    -- Get FS assigned tbs
    select name into tbs
    from 
      v$tablespace vtbs, 
      (select to_number(value) as tsn from SYSDBIMFS_METADATA$ where key='TSN') t2
    where t2.tsn = vtbs.ts#;

    -- Get the number of CU persisted in FS.
    select count(*) into aux_count from SYS.SYSDBIMFS$;

    -- Get FS savepoint space usage.  Table is not created until feature is enabled
    -- so we need to do exec immediate.
    execute immediate 'select sum(dbms_lob.getlength(data)) from SYSDBIMFSDATA$' 
      into spspace;

    -- Get total number of CU cached in FS
    select max(cuid) into spcnttot from sys.sysdbimfs$;

    feature_info := to_clob('In-Memory FastStart enabled on ' || tbs || 
                            ': Current Number of Savepoints in FastStart Area: ' || aux_count ||
                            ', Current Space Usage: ' || spspace ||
                            ', Total Number of Savepoints in FastStart Area: ' || spcnttot);
  else
    feature_boolean := 0;
    aux_count := 0;
    feature_info := to_clob('In-Memory FastStart Not Used');
  end if;
END DBMS_FEATURE_IMFS;
/
show errors;

/****************************************************************
 * DBMS_HWM_SHARDS
 * Procedure to get current number of deployed shards in catalog
 ****************************************************************/
create or replace procedure DBMS_HWM_SHARDS
  (current_value OUT NUMBER) 
AS
    loc_count  number;
    loc_shtype number;
    loc_repl   number;
BEGIN
    current_value := 0;

    execute immediate 'SELECT COUNT(*) 
                       FROM GSMADMIN_INTERNAL.CLOUD'
      into loc_count;

    -- if not a catalog or not initialized, then no shards yet
    IF loc_count = 0 THEN
      RETURN;
    END IF;

    execute immediate 'SELECT SHARDING_TYPE, REPLICATION_TYPE 
                       FROM GSMADMIN_INTERNAL.CLOUD'
      into loc_shtype, loc_repl;

    -- if not a sharded catalog, then no shards possible
    IF loc_shtype = 0 THEN
      RETURN;
    END IF;

    IF loc_repl = 0 THEN
      -- DataGuard
      execute immediate 'SELECT COUNT(*) 
                         FROM GSMADMIN_INTERNAL.DATABASE
                         WHERE DPL_STATUS = 4'
        into current_value;
    ELSE
      -- GoldenGate
      execute immediate 'SELECT COUNT(*) 
                         FROM GSMADMIN_INTERNAL.DATABASE
                         WHERE DPL_STATUS = 5'
        into current_value;
    END IF;
 
END DBMS_HWM_SHARDS;
/
show errors;

/*************************************************************************
 * DBMS_HWM_PRIM_SHARDS
 * Procedure to get current number of deployed primary shards in catalog
 *************************************************************************/
create or replace procedure DBMS_HWM_PRIM_SHARDS
  (current_value OUT NUMBER) 
AS
    loc_count  number;
    loc_shtype number;
    loc_repl   number;
BEGIN
    current_value := 0;

    execute immediate 'SELECT COUNT(*) 
                       FROM GSMADMIN_INTERNAL.CLOUD'
      into loc_count;

    -- if not a catalog or not initialized, then no shards yet
    IF loc_count = 0 THEN
      RETURN;
    END IF;

    execute immediate 'SELECT SHARDING_TYPE, REPLICATION_TYPE 
                       FROM GSMADMIN_INTERNAL.CLOUD'
      into loc_shtype, loc_repl;

    -- if not a sharded catalog, then no shards possible
    IF loc_shtype = 0 THEN
      RETURN;
    END IF;

    IF loc_repl = 0 THEN
      -- DataGuard, 0= primary
      execute immediate 'SELECT COUNT(*) 
                         FROM GSMADMIN_INTERNAL.DATABASE
                         WHERE DPL_STATUS = 4 AND DEPLOY_AS = 0'
        into current_value;
    ELSE
      -- GoldenGate
      execute immediate 'SELECT COUNT(*) 
                         FROM GSMADMIN_INTERNAL.DATABASE
                         WHERE DPL_STATUS = 5'
        into current_value;
    END IF;
 
END DBMS_HWM_PRIM_SHARDS;
/
show errors;

/*************************************************
 * Database Features Usage Tracking Registration 
 *************************************************/

create or replace procedure DBMS_FEATURE_REGISTER_ALLFEAT
as
  /* string to get the last sample date */
  DBFUS_LAST_SAMPLE_DATE_STR CONSTANT VARCHAR2(100) :=
            ' (select nvl(max(last_sample_date), sysdate-7) ' || 
                'from wri$_dbu_usage_sample) ';

begin

  /********************** 
   * Advanced Replication
   **********************/

  declare 
    DBFUS_ADV_REPLICATION_STR CONSTANT VARCHAR2(1000) := 
        'select count(*), NULL, NULL from dba_repcat';

  begin
    dbms_feature_usage.register_db_feature
     ('Advanced Replication',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_ADV_REPLICATION_STR,
      'Advanced Replication has been enabled.');
  end;

  /********************** 
   * Advanced Security Option Encryption/Checksumming
   **********************/

  declare
    DBFUS_ASO_STR CONSTANT VARCHAR2(1000) := 
     'select count (*), NULL, NULL from v$session_connect_info where ' ||
        'network_service_banner like ''%AES256 encryption%'' or ' ||
        'network_service_banner like ''%AES192 encryption%'' or ' ||
        'network_service_banner like ''%AES128 encryption%'' or ' ||
        'network_service_banner like ''%RC4_256 encryption%'' or ' ||
        'network_service_banner like ''%RC4_128 encryption%'' or ' ||
        'network_service_banner like ''%3DES168 encryption%'' or ' ||
        'network_service_banner like ''%3DES112 encryption%'' or ' ||
        'network_service_banner like ''%RC4_56 encryption%'' or ' ||
        'network_service_banner like ''%RC4_40 encryption%'' or ' ||
        'network_service_banner like ''%DES encryption%'' or ' ||
        'network_service_banner like ''%DES40 encryption%'' or ' ||
        'network_service_banner like ''%SHA1 crypto-checksumming%'' or ' ||
        'network_service_banner like ''%MD5 crypto-checksumming%''';
  begin
    dbms_feature_usage.register_db_feature
     ('ASO native encryption and checksumming',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_ASO_STR,
      'ASO network native encryption and checksumming is being used.');
  end;

  /********************** 
   * Advanced Network Compression 
   **********************/
  declare
   DBFUS_NETWORK_COMPRESSION_STR CONSTANT VARCHAR2(1000) :=
    'select count (*), 0, null' ||
      ' from  v$session_connect_info' ||
      ' where network_service_banner like ''%Compression%''';
  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Advanced Network Compression Service',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL, 
      DBFUS_NETWORK_COMPRESSION_STR,
      'Oracle Advanced Network Compression Service Used');
  end;

  /********************** 
   * Thin Provisioning
   **********************/

  declare
    DBFUS_THP_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_THP';

  begin
    dbms_feature_usage.register_db_feature
     ('Thin Provisioning',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_THP_PROC,
      'Thin Provisioning in use');
  end;

  /********************** 
   * Flex ASM
   **********************/
  declare
    DBFUS_FLX_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_FLEX_ASM';

  begin
    dbms_feature_usage.register_db_feature
     ('Flex ASM',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_FLX_PROC,
      'Flex ASM in use');
  end;

  /************************** 
   * ASM Filter Driver (AFD)
   **************************/
  declare
    DBFUS_AFD_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_AFD';

  begin
    dbms_feature_usage.register_db_feature
     ('ASM Filter Driver',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_AFD_PROC,
      'ASM Filter Driver in use');
  end;

  /************************** 
   * Automatic Storage Management Cluster File System (ACFS)
   **************************/
  declare
    DBFUS_ACFS_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_ACFS';

  begin
    dbms_feature_usage.register_db_feature
     ('ACFS',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ACFS_PROC,
      'ACFS in use');
  end;

  /************************** 
   * Automatic Storage Management Cluster File System (ACFS) SNAPSHOT
   **************************/
  declare
    DBFUS_ACFS_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_ACFS_SNAPSHOT';

  begin
    dbms_feature_usage.register_db_feature
     ('ACFS Snapshot',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ACFS_PROC,
      'ACFS Snapshot in use');
  end;

  /************************** 
   * Automatic Storage Management Cluster File System (ACFS)
   * Encryption
   **************************/
  declare
    DBFUS_ACFS_ENCR_PROC CONSTANT VARCHAR2(1000) :=
      'DBMS_FEATURE_ACFS_ENCR';

  begin
    dbms_feature_usage.register_db_feature
     ('ACFS Encryption',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ACFS_ENCR_PROC,
      'ACFS encryption in use');
  end;

  /********************** 
   * Traditional Audit
   **********************/
  declare 
    DBFUS_AUDIT_PROC CONSTANT VARCHAR2(1000) := 
      'dbms_feature_audit_options';

  begin
    dbms_feature_usage.register_db_feature
     ('Traditional Audit',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_AUDIT_PROC,
      'Traditional Audit in use.');
  end;

  /**************************
   * Fine Grained Audit (FGA)
   **************************/
  declare 
    DBFUS_FGA_PROC CONSTANT VARCHAR2(1000) := 
      'dbms_feature_fga_audit';

  begin
    dbms_feature_usage.register_db_feature
     ('Fine Grained Audit',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_FGA_PROC,
      'Fine Grained Audit in use.');
  end;

  /**********************
   * Unified Audit 
   **********************/
  declare 
    DBFUS_UNIFIED_PROC CONSTANT VARCHAR2(1000) := 
      'dbms_feature_unified_audit';

  begin
    dbms_feature_usage.register_db_feature
     ('Unified Audit',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_UNIFIED_PROC,
      'Unified Audit in use.');
  end;

  /**********************************************
   * Auto-Maintenance Tasks
   *********************************************/

  declare 
    DBFUS_KET_OPT_STATS_STR CONSTANT VARCHAR(1000) :=
     'select nvl(ats, 0) * nvl(cls, 0) enabled, ' ||
      'NVL((select SUM(jobs_created) ' ||
             'from dba_autotask_client_history ' ||
            'where client_name = ''auto optimizer stats collection'' ' ||
              'and window_start_time >  ' ||
                  '(SYSDATE - INTERVAL ''168'' HOUR) ), 0) jobs, NULL ' ||
     'from (select DECODE(MAX(autotask_status),''ENABLED'',1,0) ats, ' ||
            'DECODE(MAX(OPTIMIZER_STATS),''ENABLED'',1,0) cls ' ||
            'from dba_autotask_window_clients)';

    DBFUS_KET_SEG_STATS_STR CONSTANT VARCHAR(1000) :=
     'select nvl(ats, 0) * nvl(cls, 0) enabled, ' ||
      'NVL((select SUM(jobs_created) ' ||
             'from dba_autotask_client_history ' ||
            'where client_name = ''auto space advisor'' ' ||
              'and window_start_time >  ' ||
                  '(SYSDATE - INTERVAL ''168'' HOUR) ), 0) jobs, NULL ' ||
     'from (select DECODE(MAX(autotask_status),''ENABLED'',1,0) ats, ' ||
            'DECODE(MAX(SEGMENT_ADVISOR),''ENABLED'',1,0) cls ' ||
            'from dba_autotask_window_clients)';

    DBFUS_KET_SQL_STATS_STR CONSTANT VARCHAR(1000) :=
     'select nvl(ats, 0) * nvl(cls, 0) enabled, ' ||
      'NVL((select SUM(jobs_created) ' ||
             'from dba_autotask_client_history ' ||
            'where client_name = ''sql tuning advisor'' ' ||
              'and window_start_time >  ' ||
                  '(SYSDATE - INTERVAL ''168'' HOUR) ), 0) jobs, NULL ' ||
     'from (select DECODE(MAX(autotask_status),''ENABLED'',1,0) ats, ' ||
            'DECODE(MAX(SQL_TUNE_ADVISOR),''ENABLED'',1,0) cls ' ||
            'from dba_autotask_window_clients)';


  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Maintenance - Optimizer Statistics Gathering',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_KET_OPT_STATS_STR,
      'Automatic initiation of Optimizer Statistics Collection');

    dbms_feature_usage.register_db_feature
     ('Automatic Maintenance - Space Advisor',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_KET_SEG_STATS_STR,
      'Automatic initiation of Space Advisor');

    dbms_feature_usage.register_db_feature
     ('Automatic Maintenance - SQL Tuning Advisor',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_KET_SQL_STATS_STR,
      'Automatic initiation of SQL Tuning Advisor');
  end;

  /**********************************************
   * Automatic Segment Space Management (system)
   **********************************************/

  declare 
    DBFUS_BITMAP_SEGMENT_SYS_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_AUTO_SSM';

  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Segment Space Management (system)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_BITMAP_SEGMENT_SYS_PROC,
      'Extents of locally managed tablespaces are managed ' ||
      'automatically by Oracle.');
  end;

  /********************************************
   * Automatic Segment Space Management (user)
   ********************************************/

  declare 
    DBFUS_BITMAP_SEGMENT_USER_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from dba_tablespaces where ' ||
        'segment_space_management = ''AUTO'' and ' ||
        'tablespace_name not in ' ||
          '(''SYSTEM'', ''SYSAUX'', ''TEMP'', ''USERS'', ''EXAMPLE'', ''SYSEXT'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Segment Space Management (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BITMAP_SEGMENT_USER_STR,
      'Extents of locally managed user tablespaces are managed ' ||
      'automatically by Oracle.');
  end;

  /*********************************
   * Automatic SQL Execution Memory
   *********************************/

  declare 
    DBFUS_AUTO_PGA_STR CONSTANT VARCHAR2(1000) := 
      'select decode(pga + wap, 2, 1, 0), pga_aux + wap_aux, NULL from ' ||
        '(select count(*) pga, 0 pga_aux from v$system_parameter ' ||
          'where name = ''pga_aggregate_target'' and value != ''0''), ' ||
        '(select count(*) wap, 0 wap_aux from v$system_parameter ' ||
          'where name = ''workarea_size_policy'' and upper(value) = ''AUTO'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Automatic SQL Execution Memory',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_AUTO_PGA_STR,
      'Sizing of work areas for all dedicated sessions (PGA) is automatic.');
  end;

  /******************************** 
   * Automatic Storage Management
   ******************************/

  declare 
    DBFUS_ASM_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_ASM';
 
  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Storage Management',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ASM_PROC,
      'Automatic Storage Management has been enabled');
  end;

  /***************************
   * Automatic Undo Management
   ***************************/

  declare 
    DBFUS_AUM_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_AUM';

  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Undo Management',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_AUM_PROC,
      'Oracle automatically manages undo data using an UNDO tablespace.');
  end;

  /**************************************
   * Automatic Workload Repository (AWR)
   **************************************/
  begin
    dbms_feature_usage.register_db_feature
       ('Automatic Workload Repository'
       ,dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED
       ,NULL
       ,dbms_feature_usage.DBU_DETECT_BY_PROCEDURE
       ,'DBMS_FEATURE_AWR'
       ,'A manual Automatic Workload Repository (AWR) snapshot was taken ' ||
        'in the last sample period.');
  end;


  /***************
   * AWR Baseline
   ***************/

  declare 
    DBFUS_AWR_BASELINE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), count(*), NULL from dba_hist_baseline ' ||
        'where baseline_name != ''SYSTEM_MOVING_WINDOW''';

  begin
    dbms_feature_usage.register_db_feature
     ('AWR Baseline',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_AWR_BASELINE_STR,
      'At least one AWR Baseline has been created by the user');
  end;

  /************************
   * AWR Baseline Template
   ************************/

  declare 
    DBFUS_AWR_BL_TEMPLATE_STR VARCHAR2(1000) := 
      'select count(*), count(*), NULL ' ||
        'from dba_hist_baseline_template';

  begin
    dbms_feature_usage.register_db_feature
     ('AWR Baseline Template',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_AWR_BL_TEMPLATE_STR,
      'At least one AWR Baseline Template has been created by the user');
  end;

  /***************
   * AWR Reports
   ***************/

  declare 
    DBFUS_AWR_REPORT_STR CONSTANT VARCHAR2(1000) := 
    q'[with last_period as
       (select * from wrm$_wr_usage
         where upper(feature_type) like 'REPORT'
           and usage_time >= ]' ||
    DBFUS_LAST_SAMPLE_DATE_STR ||
    q'[) 
       select decode (count(*), 0, 0, 1),
              count(*),
              feature_list
         from last_period,
        (select substr(sys_connect_by_path(feature_count, ','),2) feature_list
           from 
             (select feature_count,
                     count(*) over () cnt, 
                     row_number () over (order by 1) seq 
                from 
                  (select feature_name || ':' || count(*) feature_count
                     from last_period
                 group by feature_name)
             ) 
        where seq=cnt
        start with seq=1 
   connect by prior seq+1=seq)
     group by feature_list]';

  begin
    dbms_feature_usage.register_db_feature
     ('AWR Report',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_AWR_REPORT_STR,
      'At least one Workload Repository Report has been created by the user');
  end;

  /**************************
   * Backup Encryption
   **************************/

  /* This query returns 1 if there are any encrypted backup pieces,
   * whose status is 'available'.
   * Controlfile autobackups are ignored, because we don't want to 
   * consider RMAN in use if they just turned on the controlfile autobackup
   * feature. */

  begin
    dbms_feature_usage.register_db_feature
     ('Backup Encryption',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_BACKUP_ENCRYPTION',
      'Encrypted backups are being used.');
  end;

  /********************************
   * Baseline Adaptive Thresholds
   ********************************/

  declare
    DBFUS_BASELINE_ADAPTIVE_STR CONSTANT VARCHAR2(1000) :=
      'select decode(nvl(sum(moving)+sum(static),0), 0, 0, 1) '||
            ',nvl(sum(moving)+sum(static),0) '||
            ',''Adaptive: ''||nvl(sum(moving),0)||''; Static:''||nvl(sum(static),0) '||
        'from (select decode(AB.baseline_id, 0, 0, 1) static '||
                    ',decode(AB.baseline_id, 0, 1, 0) moving '||
                'from dbsnmp.bsln_threshold_params TP '||
                    ',dbsnmp.bsln_baselines B '||
                    ',dba_hist_baseline AB '||
                    ',v$database D '||
                    ',v$instance I '||
               'where AB.dbid = D.dbid '||
                 'and B.dbid = AB.dbid '||
                 'and B.baseline_id = AB.baseline_id '||
                 'and B.instance_name = I.instance_name '||
                 'and TP.bsln_guid = B.bsln_guid '||
                 'and in_effect = ''Y'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Baseline Adaptive Thresholds',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BASELINE_ADAPTIVE_STR,
      'Adaptive Thresholds have been configured.');
  end;

  /********************************
   * Baseline Static Computations
   ********************************/

  declare
    DBFUS_BASELINE_COMPUTES_STR CONSTANT VARCHAR2(1000) :=
      'select decode(count(*), 0, 0, 1), count(*), NULL '||
        'from dba_hist_baseline_metadata AB '||
            ',dbsnmp.bsln_baselines B '||
            ',v$database D '||
            ',v$instance I '||
       'where AB.dbid = D.dbid '||
         'and AB.baseline_type <> ''MOVING_WINDOW'' '||
         'and B.dbid = AB.dbid '||
         'and B.baseline_id = AB.baseline_id '||
         'and B.instance_name = I.instance_name '||
         'and B.last_compute_date IS NOT NULL';
  begin
    dbms_feature_usage.register_db_feature
     ('Baseline Static Computations',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BASELINE_COMPUTES_STR,
      'Static baseline statistics have been computed.');
  end;

  /************************ 
   * Block Change Tracking
   ************************/

  declare 
    DBFUS_BLOCK_CHANGE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL ' ||
        'from v$block_change_tracking where status = ''ENABLED''';

  begin
    dbms_feature_usage.register_db_feature
     ('Change-Aware Incremental Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BLOCK_CHANGE_STR,
      'Track blocks that have changed in the database.');
  end;

  /********************** 
   * Client Identifier
   **********************/

  declare 
    DBFUS_CLIENT_IDN_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$session ' ||
      'where client_identifier is not null';

  begin
    dbms_feature_usage.register_db_feature
     ('Client Identifier',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CLIENT_IDN_STR,
      'Application User Proxy Authentication: Client Identifier is ' ||
      'used at this specific time.');
  end;


  /**********************************
   * Clusterwide Global Transactions
   **********************************/

  declare 
    DBFUS_CLUSTER_GTX_STR CONSTANT VARCHAR2(1000) :=
      'select value, NULL, NULL from v$sysstat ' ||
        'where name = ''Clusterwide global transactions''';
  
  begin
    dbms_feature_usage.register_db_feature
     ('Clusterwide Global Transactions',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CLUSTER_GTX_STR,
      'Clusterwide Global Transactions is being used.');
  end;

  /**********************************
   * Crossedition Triggers
   **********************************/

  declare 
    DBFUS_XEDTRG_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), count(1), NULL from trigger$ t ' ||
        'where bitand(t.property, 8192) = 8192';
  
  begin
    dbms_feature_usage.register_db_feature
     ('Crossedition Triggers',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_XEDTRG_STR,
      'Crossedition triggers is being used.');
  end;

  /****************************** 
   * CSSCAN - character set scan
   *******************************/

  declare 
    DBFUS_CSSCAN_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), null, null  from ' ||
      'csmig.csm$parameters c ' ||
      'where c.name=''TIME_START'' and ' ||
      'to_date(c.value, ''YYYY-MM-DD HH24:MI:SS'') ' ||
      '>= ' || DBFUS_LAST_SAMPLE_DATE_STR;

  begin
    dbms_feature_usage.register_db_feature
     ('CSSCAN',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'CSMIG.csm$parameters',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CSSCAN_STR,
      'Oracle Database has been scanned at least once for character set:' ||
      'CSSCAN has been run at least once.');
  end;
  
 
  /****************************** 
   * Character semantics turned on
   *******************************/

  declare 
    DBFUS_CHAR_SEMANTICS_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), null, null  from ' ||
      'sys.v$nls_parameters where ' ||
      'parameter=''NLS_LENGTH_SEMANTICS'' and upper(value)=''CHAR'' ';

  begin
    dbms_feature_usage.register_db_feature
     ('Character Semantics',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CHAR_SEMANTICS_STR,
      'Character length semantics is used in Oracle Database');
  end;
  
  /**************************** 
   * Character Set of Database
   ****************************/

  declare 
    DBFUS_CHAR_SET_STR CONSTANT VARCHAR2(1000) := 
      'select 1, null, value  from ' ||
      'sys.v$nls_parameters where ' ||
      'parameter=''NLS_CHARACTERSET'' ';

  begin
    dbms_feature_usage.register_db_feature
     ('Character Set',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CHAR_SET_STR,
      'Character set is used in Oracle Database');
  end;
  

  /********************** 
   * Data Guard
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Data Guard',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_DATA_GUARD',
      'Data Guard, a set of services, is being used to create, ' ||
      'maintain, manage, and monitor one or more standby databases.');
  end;

  /********************** 
   * Data Mining
   **********************/

 declare
    DBFUS_ODM_PROC VARCHAR2(100) := 'DBMS_FEATURE_DATABASE_ODM';
  begin
    dbms_feature_usage.register_db_feature
     ('Data Mining',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ODM_PROC,
      'There exist Oracle Data Mining models in the database.');
  end;


  /********************** 
   * Dynamic SGA
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Dynamic SGA',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_DYN_SGA',
      'The Oracle SGA has been dynamically resized through an ' ||
      'ALTER SYSTEM SET statement.');
  end;

  /*************************************************
   * DMU - Database Migration Assistant for Unicode
   *************************************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Database Migration Assistant for Unicode',
      dbms_feature_usage.DBU_INST_OBJECT,
      'SYS.PROPS$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_DMU',
      'Database Migration Assistant for Unicode has been used.');
  end;

  /******************************
   * Editions
   *******************************/

  declare
    DBFUS_EDITION_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), count(1), null from sys.edition$ e, sys.obj$ o ' ||
      'where e.obj# = o.obj# and o.name != ''ORA$BASE''';

  begin
    dbms_feature_usage.register_db_feature
     ('Editions',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_EDITION_STR,
      'Editions is being used.');
  end;

  /******************************
   * Editioning Views
   *******************************/

  declare
    DBFUS_EDITION_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), count(1), null from sys.view$ v ' ||
      'where bitand(v.property, 32) = 32';

  begin
    dbms_feature_usage.register_db_feature
     ('Editioning Views',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_EDITION_STR,
      'Editioning views is being used.');
  end;

  /******************************
   * EM - Cloud Control tracking
   *******************************/

  declare
    DBFUS_EM_GC_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), null, null from ' ||
      'dbsnmp.mgmt_db_feature_log a ' ||
      'where a.source=''GC'' and ' ||
      'CAST(a.last_update_date AS DATE) ' ||
      '>= ' || DBFUS_LAST_SAMPLE_DATE_STR;
  begin
    dbms_feature_usage.register_db_feature
     ('EM Cloud Control',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_EM_GC_STR,
      'EM Cloud Control Database Home Page has been visited at least once.');
  end;

  /******************************
   * EM Performance Page  tracking
   *******************************/

  declare
    DBFUS_EM_DIAG_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), null, null from ' ||
      'dbsnmp.mgmt_db_feature_log a ' ||
      'where a.source=''Diagnostic'' and ' ||
      'CAST(a.last_update_date AS DATE) ' ||
      '>= ' || DBFUS_LAST_SAMPLE_DATE_STR;
  begin
    dbms_feature_usage.register_db_feature
     ('EM Performance Page',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_EM_DIAG_STR,
      'EM Performance Page has been visited at least once.');
  end;

  /******************************
   * EM - SQL Monitoring and Tuning pages tracking
   *******************************/

  declare
    DBFUS_EM_TUNING_STR CONSTANT VARCHAR2(1000) :=
      'select count(1), null, null from ' ||
      'dbsnmp.mgmt_db_feature_log a ' ||
      'where a.source=''Tuning'' and ' ||
      'CAST(a.last_update_date AS DATE) ' ||
      '>= ' || DBFUS_LAST_SAMPLE_DATE_STR;
  begin
    dbms_feature_usage.register_db_feature
     ('SQL Monitoring and Tuning pages',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_EM_TUNING_STR,
      'EM SQL Monitoring and Tuning pages has been visited at least once.');
  end;

  /********************** 
   * File Mapping
   **********************/

  declare 
    DBFUS_FILE_MAPPING_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter where ' ||
        'name = ''file_mapping'' and upper(value) = ''TRUE'' and ' ||
        'exists (select 1 from v$map_file)';

  begin
    dbms_feature_usage.register_db_feature
     ('File Mapping',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_FILE_MAPPING_STR,
      'File Mapping, the mechanism that shows a complete mapping ' ||
      'of a file to logical volumes and physical devices, is ' ||
      'being used.');
  end;


  /***************************
   * Flashback Database
   ***************************/

  declare 
    DBFUS_FB_DB_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$database where ' ||
        'flashback_on = ''YES''';

  begin
    dbms_feature_usage.register_db_feature
     ('Flashback Database',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_FB_DB_STR,
      'Flashback Database, a rewind button for the database, is enabled');
  end;


  /***************************
   * Flashback Data Archive
   ***************************/

  declare 
    DBFUS_FDA_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from DBA_FLASHBACK_ARCHIVE_TABLES';

  begin
    dbms_feature_usage.register_db_feature
     ('Flashback Data Archive',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_FDA_STR,
      'Flashback Data Archive, a historical repository of changes to data ' ||
      'contained in a table, is used ');
  end;


  /******************************
   * Internode Parallel Execution
   ******************************/

  declare 
    DBFUS_INODE_PRL_EXEC_STR CONSTANT VARCHAR2(1000) := 
      'select sum(value), NULL, NULL from gv$pq_sysstat ' ||
        'where statistic like ''%Initiated (IPQ)%''';
      

  begin
    dbms_feature_usage.register_db_feature
     ('Internode Parallel Execution',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_INODE_PRL_EXEC_STR,
      'Internode Parallel Execution is being used.');
  end;

  /********************** 
   * Label Security
   **********************/

  declare 
    DBFUS_LABEL_SECURITY_PROC CONSTANT VARCHAR2(1000) :=
      'dbms_feature_label_security';
  begin
    dbms_feature_usage.register_db_feature
     ('Label Security',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_LABEL_SECURITY_PROC,
      'Oracle Label Security is being used');
  end;

  /********************** 
   * Oracle Database Vault
   **********************/
  declare
     DBFUS_DATABASE_VAULT_PROC CONSTANT VARCHAR2(1000) :=
       'DBMS_FEATURE_DATABASE_VAULT';
  begin
     dbms_feature_usage.register_db_feature
     ('Oracle Database Vault',
      dbms_feature_usage.DBU_INST_OBJECT,
      'dvsys.realm$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DATABASE_VAULT_PROC,
      'Oracle Database Vault is being used');
  end;

  /***************************************
   * Deferred Segment Creation
   ***************************************/

  declare 
    DBFUS_DEFERRED_SEG_CRT_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_DEFERRED_SEG_CRT';
  begin
    dbms_feature_usage.register_db_feature
     ('Deferred Segment Creation',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DEFERRED_SEG_CRT_PROC,
      'Deferred Segment Creation is being used');
  end;

  /***************************************
   * Locally Managed Tablespaces (system)
   ***************************************/

  declare 
    DBFUS_LOCALLY_MANAGED_SYS_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_LMT';

  begin
    dbms_feature_usage.register_db_feature
     ('Locally Managed Tablespaces (system)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_LOCALLY_MANAGED_SYS_PROC,
      'There exists tablespaces that are locally managed in ' ||
      'the database.');
  end;

  /*************************************
   * Locally Managed Tablespaces (user)
   *************************************/

  declare 
    DBFUS_LOCALLY_MANAGED_USER_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from dba_tablespaces where ' ||
        'extent_management = ''LOCAL'' and ' ||
        'tablespace_name not in ' ||
          '(''SYSTEM'', ''SYSAUX'', ''TEMP'', ''USERS'', ''EXAMPLE'',''SYSEXT'',''UD1'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Locally Managed Tablespaces (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_LOCALLY_MANAGED_USER_STR,
      'There exists user tablespaces that are locally managed in ' ||
      'the database.');
  end;

  /******************************
   * Messaging Gateway
   ******************************/

  declare
    DBFUS_MSG_GATEWAY_STR CONSTANT VARCHAR2(1000) :=
      'select count(*), NULL, NULL from dba_registry ' ||
        'where comp_id = ''MGW'' and status != ''REMOVED'' and ' ||
        'exists (select 1 from mgw$_links)';

  begin
    dbms_feature_usage.register_db_feature
     ('Messaging Gateway',
      dbms_feature_usage.DBU_INST_OBJECT,
      'SYS.MGW$_GATEWAY',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_MSG_GATEWAY_STR,
      'Messaging Gateway, that enables communication between non-Oracle ' ||
      'messaging systems and Advanced Queuing (AQ), link configured.');
  end;

  /********************** 
   * VLM
   **********************/

  declare 
    DBFUS_VLM_ADV_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter where ' ||
        'name like ''use_indirect_data_buffers'' and upper(value) != ''FALSE''';
  begin
    dbms_feature_usage.register_db_feature
     ('Very Large Memory',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_VLM_ADV_STR,
      'Very Large Memory is enabled.');
  end;


  /********************** 
   * Automatic Memory Tuning
   **********************/
  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Memory Tuning',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_AUTO_MEM',
      'Automatic Memory Tuning is enabled.');
  end;

  /********************** 
   * Automatic SGA Tuning
   **********************/
  begin
    dbms_feature_usage.register_db_feature
     ('Automatic SGA Tuning',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_AUTO_SGA',
      'Automatic SGA Tuning is enabled.');
  end;


  /********************** 
   * ENCRYPTED Tablespace
   **********************/
  declare 
    DBFUS_ENT_ADV_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$encrypted_tablespaces'; 
  begin
    dbms_feature_usage.register_db_feature
     ('Encrypted Tablespaces',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_ENT_ADV_STR,
      'Encrypted Tablespaces is enabled.');
  end;

  
  /********************** 
   * MTTR Advisor
   **********************/

  declare 
    DBFUS_MTTR_ADV_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$statistics_level where ' ||
        'statistics_name = ''MTTR Advice'' and ' ||
        'system_status = ''ENABLED'' and ' ||
        'exists (select 1 from v$instance_recovery ' ||
                  'where target_mttr != 0) and ' ||
        'exists (select 1 from v$mttr_target_advice ' ||
                  'where advice_status = ''ON'')';

  begin
    dbms_feature_usage.register_db_feature
     ('MTTR Advisor',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_MTTR_ADV_STR,
      'Mean Time to Recover Advisor is enabled.');
  end;

  /*********************** 
   * Multiple Block Sizes
   ***********************/

  declare 
    DBFUS_MULT_BLOCK_SIZE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter where ' ||
        'name like ''db_%_cache_size'' and value != ''0''';

  begin
    dbms_feature_usage.register_db_feature
     ('Multiple Block Sizes',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_MULT_BLOCK_SIZE_STR,
      'Multiple Block Sizes are being used with this database.');
  end;

  /***************************** 
   * OLAP - Analytic Workspaces
   *****************************/

  declare 
    DBFUS_OLAP_AW_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), count(*), NULL from dba_aws where AW_NUMBER >= 1000' ||
        'and owner not in (''DM'',''OLAPTRAIN'',''GLOBAL'',''HR'',''OE'','||
        '''PM'',''SH'',''IX'',''BI'',''SCOTT'')';

  begin
    dbms_feature_usage.register_db_feature
     ('OLAP - Analytic Workspaces',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_OLAP_AW_STR,
      'OLAP - the analytic workspaces stored in the database.');
  end;

  /***************************** 
   * OLAP - Cubes
   *****************************/

  declare 
    DBFUS_OLAP_CUBE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), count(*), NULL from DBA_OLAP2_CUBES ' ||
        'where invalid != ''Y'' and OWNER = ''SYS'' ' ||
        'and CUBE_NAME = ''STKPRICE_TBL''';

  begin
    dbms_feature_usage.register_db_feature
     ('OLAP - Cubes',
      dbms_feature_usage.DBU_INST_OBJECT,
      'PUBLIC.DBA_OLAP2_CUBES',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_OLAP_CUBE_STR,
      'OLAP - number of cubes in the OLAP catalog that are fully ' ||
      'mapped and accessible by the OLAP API.');
  end;

  /*********************** 
   * Oracle Managed Files 
   ***********************/

  declare 
    DBFUS_OMF_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from dba_data_files where ' ||
        'upper(file_name) like ''%O1_MF%''';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Managed Files',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_OMF_STR,
      'Database files are being managed by Oracle.');
  end;

  /***********************
   * Oracle Secure Backup
   ***********************/

  /* This query returns the number of backup pieces created with 
   * Oracle Secure Backup whose status is 'available'. */

  declare
    DBFUS_OSB_STR CONSTANT VARCHAR2(1000) :=
      'select count(*), NULL, NULL from x$kccbp where ' ||
      'bitand(bpext, 256) = 256 and '                   ||
      'bitand(bpflg,1+4096+8192) = 0';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Secure Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_OSB_STR,
      'Oracle Secure Backup is used for backups to tertiary storage.');
  end;

  /*******************************
   * Parallel SQL DDL Execution
   *******************************/

  declare 
    DBFUS_PSQL_DDL_STR CONSTANT VARCHAR2(1000) := 
      'select value, NULL, NULL from v$pq_sysstat ' ||
        'where rtrim(statistic,'' '') = ''DDL Initiated''';

  begin
    dbms_feature_usage.register_db_feature
     ('Parallel SQL DDL Execution',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_PSQL_DDL_STR,
      'Parallel SQL DDL Execution is being used.');
  end;

  /*******************************
   * Parallel SQL DML Execution
   *******************************/

  declare 
    DBFUS_PSQL_DML_STR CONSTANT VARCHAR2(1000) := 
      'select value, NULL, NULL from v$pq_sysstat ' ||
        'where rtrim(statistic,'' '') = ''DML Initiated''';

  begin
    dbms_feature_usage.register_db_feature
     ('Parallel SQL DML Execution',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_PSQL_DML_STR,
      'Parallel SQL DML Execution is being used.');
  end;

  /****************************
   * Oracle Multitenant
   ****************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Multitenant',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_PDB_NUM',
      'Oracle Multitenant is being used.');
  end;

  /****************************
   * Oracle Pluggable Database
   ****************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Pluggable Databases',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_NULL,
      'DBMS_PDB_NUM',
      'Oracle Pluggable Databases is being used.');
  end;

  /*******************************
   * Parallel SQL Query Execution
   *******************************/

  declare 
    DBFUS_PSQL_QUERY_STR CONSTANT VARCHAR2(1000) := 
      'select value, NULL, NULL from v$pq_sysstat ' ||
        'where rtrim(statistic,'' '') = ''Queries Initiated''';

  begin
    dbms_feature_usage.register_db_feature
     ('Parallel SQL Query Execution',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_PSQL_QUERY_STR,
      'Parallel SQL Query Execution is being used.');
  end;

  /************************
   * Partitioning (system)
   ************************/

  declare 
    DBFUS_PARTN_SYS_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_PARTITION_SYSTEM';

  begin
    dbms_feature_usage.register_db_feature
     ('Partitioning (system)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_PARTN_SYS_PROC,
      'Oracle Partitioning option is being used - there is at ' ||
      'least one partitioned object created.');
  end;

  /**********************
   * Partitioning (user)
   **********************/

  declare 
    DBFUS_PARTN_USER_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_PARTITION_USER';

  begin
    dbms_feature_usage.register_db_feature
     ('Partitioning (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_PARTN_USER_PROC,
      'Oracle Partitioning option is being used - there is at ' ||
      'least one user partitioned object created.');
  end;

  /**********************
   * Zone Maps
   **********************/

  declare 
    DBFUS_ZMAP_USER_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_ZMAP';
  begin
    dbms_feature_usage.register_db_feature
      ('Zone maps',       
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       DBFUS_ZMAP_USER_PROC,
       'Zone maps');
  end;


  /****************************
   * Oracle Text
   ****************************/
  
  declare
    DBFUS_TEXT_PROC CONSTANT VARCHAR2(1000) := 'ctxsys.drifeat.dr$feature_track';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Text',
      dbms_feature_usage.DBU_INST_OBJECT,
      'ctxsys.drifeat',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_TEXT_PROC,
      'Oracle Text is being used - there is at least one oracle '|| 
      'text index');
  end;

  /****************************
   * PL/SQL Native Compilation
   ****************************/

  declare 
    DBFUS_PLSQL_NATIVE_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_PLSQL_NATIVE';

  begin
    dbms_feature_usage.register_db_feature
     ('PL/SQL Native Compilation',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_PLSQL_NATIVE_PROC,
      'PL/SQL Native Compilation is being used - there is at least one ' ||
      'natively compiled PL/SQL library unit in the database.');
  end;

  /********************************
   * Quality of Service Management
   ********************************/

  declare 
    DBFUS_QOSM_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_QOSM';
 
  begin
    dbms_feature_usage.register_db_feature
     ('Quality of Service Management',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_QOSM_PROC,
      'Quality of Service Management has been used.');
  end;

  /********************************
   * RAC One Node
   ********************************/

  declare
    DBFUS_ROND_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_ROND';

  begin
    dbms_feature_usage.register_db_feature
     ('Real Application Cluster One Node',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ROND_PROC,
      'Real Application Cluster One Node is being used.');
  end;

  /****************************
   * Real Application Clusters 
   ****************************/

  declare 
    DBFUS_RAC_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_RAC';

  begin
    dbms_feature_usage.register_db_feature
     ('Real Application Clusters (RAC)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_RAC_PROC,
      'Real Application Clusters (RAC) is configured.');
  end;

  /********************** 
   * Recovery Area
   **********************/

  declare 
    DBFUS_RECOVERY_AREA_STR CONSTANT VARCHAR2(1000) := 
      'select p, s, NULL from ' ||
        '(select count(*) p from v$parameter ' ||
         'where name = ''db_recovery_file_dest'' and value is not null), ' ||
        '(select to_number(value) s from v$parameter ' ||
         'where name = ''db_recovery_file_dest_size'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Recovery Area',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_RECOVERY_AREA_STR,
      'The recovery area is configured.');
  end;

  /**************************
   * Recovery Manager (RMAN)
   **************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Recovery Manager (RMAN)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_BACKUP',
      'Recovery Manager (RMAN) is being used to backup the database.');
  end;

  /********************** 
   * RMAN - Disk Backup
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('RMAN - Disk Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_DISK_BACKUP',
      'Recovery Manager (RMAN) is being used to backup the database to disk.');
  end;

  /********************** 
   * RMAN - Tape Backup
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('RMAN - Tape Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_TAPE_BACKUP',
      'Recovery Manager (RMAN) is being used to backup the database to tape.');
  end;

  /**********************************
   * RMAN - ZLIB compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup ZLIB Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_ZLIB',
      'ZLIB compressed backups are being used.');
  end;

  /**********************************
   * RMAN - BZIP2 compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup BZIP2 Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_BZIP2',
      'BZIP2 compressed backups are being used.');
  end;

  /**********************************
   * RMAN - BASIC compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup BASIC Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_BASIC',
      'BASIC compressed backups are being used.');
  end;

  /**********************************
   * RMAN - LOW compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup LOW Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_LOW',
      'LOW compressed backups are being used.');
  end;

  /**********************************
   * RMAN - MEDIUM compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup MEDIUM Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_MEDIUM',
      'MEDIUM compressed backups are being used.');
  end;

  /**********************************
   * RMAN - HIGH compressed backups
   **********************************/
  begin
    
    dbms_feature_usage.register_db_feature
     ('Backup HIGH Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RMAN_HIGH',
      'HIGH compressed backups are being used.');
  end;

  /****************************
  * Long-term archival backups
  *****************************/

  declare
  DBFUS_KEEP_BACKUP_STR CONSTANT VARCHAR2(1000) :=
    'select count(*), NULL, decode(min(keep_options), ''BACKUP_LOGS'',
    ''Consistent backups archived'') from v$backup_set where keep = ''YES'''; 

  begin
    dbms_feature_usage.register_db_feature
     ('Long-term Archival Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_KEEP_BACKUP_STR,
      'Long-term archival backups are being used.');
  end;

  /****************************
  * Multi section backups
  *****************************/

  declare
  DBFUS_MULTI_SECTION_BACKUP_STR CONSTANT VARCHAR2(1000) :=
    'select count(*), NULL, NULL ' ||
    'from v$backup_set where multi_section = ''YES'''; 

  begin
    dbms_feature_usage.register_db_feature
     ('Multi Section Backup',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_MULTI_SECTION_BACKUP_STR,
      'Multi section backups are being used.');
  end;    

  /*********************** 
   * Block Media Recovery
   ***********************/

  declare
    DBFUS_BLOCK_MEDIA_RCV_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''BLOCK MEDIA RECOVERY%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Block Media Recovery',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BLOCK_MEDIA_RCV_STR,
      'Block Media Recovery is being used to repair the database.');
  end;


  /*********************** 
   * Restore Point
   ***********************/

  declare
    DBFUS_RESTORE_POINT_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$restore_point)';
  begin
    dbms_feature_usage.register_db_feature
     ('Restore Point',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_RESTORE_POINT_STR,
      'Restore Points are being used as targets for Flashback');
  end;

  /*********************** 
   * Logfile Multiplexing
   ***********************/

  declare
    DBFUS_LOGFILE_MULTIPLEX_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from ' ||
        '  (select count(*) a from v$logfile group by group#)' ||
        '  where a>1)';
  begin
    dbms_feature_usage.register_db_feature
     ('Logfile Multiplexing',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_LOGFILE_MULTIPLEX_STR,
      'Multiple members are used in a single log file group');
  end;


  /*********************** 
   * Bigfile Tablespace
   ***********************/

  declare
    DBFUS_BIGFILE_TBS_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$tablespace' ||
        '  where bigfile = ''YES'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Bigfile Tablespace',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BIGFILE_TBS_STR,
      'Bigfile tablespace is being used');
  end;


  /************************** 
   * Transportable Tablespace
   **************************/

  declare
    DBFUS_TRANSPORTABLE_TBS_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$datafile' ||
        '  where plugged_in = 1)';
  begin
    dbms_feature_usage.register_db_feature
     ('Transportable Tablespace',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_TRANSPORTABLE_TBS_STR,
      'Transportable tablespace is being used');
  end;


  /*********************** 
   * Read Only Tablespace
   ***********************/
  
  declare
    DBFUS_READONLY_TBS_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$datafile' ||
        '  where enabled = ''READ ONLY'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Read Only Tablespace',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_READONLY_TBS_STR,
      'Read only tablespace is being used');
  end;

  /************************* 
   * Read Only Open Delayed
   *************************/
  
  declare
    DBFUS_READOPEN_DELAY_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$parameter' ||
        '  where name = ''read_only_open_delayed'' and value = ''TRUE'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Deferred Open Read Only',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_READOPEN_DELAY_STR,
      'Deferred open read only feature is enabled');
  end;


  /********************** 
   * Active Data Guard
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Active Data Guard - Real-Time Query on Physical Standby',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_ACTIVE_DATA_GUARD',
      'Active Data Guard, a set of services, is being used to enhance ' ||
      'Data Guard');
  end;


  /********************** 
   * Online Move Datafile
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Online Move Datafile',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_MOVE_DATAFILE',
      'Online Move Datafile is being used to move datafiles');
  end;


  /********************* 
   * Backup Rollforward
   *********************/

  declare
    DBFUS_BACKUP_ROLLFORWARD_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''BACKUP COPYROLLFORWARD%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Backup Rollforward',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BACKUP_ROLLFORWARD_STR,
      'Backup Rollforward strategy is being used to backup the database.');
  end;

  /************************ 
   * Data Recovery Advisor
   ************************/

  declare
    DBFUS_DATA_RCV_ADVISOR_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$ir_repair' ||
        '  where rownum = 1)';
  begin
    dbms_feature_usage.register_db_feature
     ('Data Recovery Advisor',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DATA_RCV_ADVISOR_STR,
      'Data Recovery Advisor (DRA) is being used to repair the database.');
  end;

  /***********************
   * Backup and Restore of plugged database
   ***********************/

  declare
    DBFUS_BR_PLUGGED_DB_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''%PLUGGABLE DATABASE%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Backup and Restore of plugged database',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_BR_PLUGGED_DB_STR,
      'Backup and Restore of plugged database by RMAN is used.');
  end;

  /********************* 
   * Recover Table, additional space after TABLE is intentional.
   *********************/

  declare
    DBFUS_RECOVER_TABLE_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''RECOVER TABLE %'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Recover Table',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_RECOVER_TABLE_STR,
      'Recover Table is used to recover a table in the database.');
  end;

  /********************* 
   * Recover Until Snapshot
   *********************/

  declare
    DBFUS_RECOVER_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''RECOVER UNTIL SNAPSHOT%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Recover Until Snapshot',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_RECOVER_STR,
      'Recover until snapshot is used to recover the database.');
  end;

  /********************* 
   * TRANSPORT TABLESPACE command
   *********************/

  declare
    DBFUS_TRANSPORT_TBS_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''TRANSPORT TABLESPACE%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('TRANSPORT TABLESPACE command',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_TRANSPORT_TBS_STR,
      'RMAN''s TRANSPORT TABLESPACE command used by the database.');
  end;

  /********************* 
   * CONVERT command
   *********************/

  declare
    DBFUS_CONVERT_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''CONVERT%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('CONVERT command',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CONVERT_STR,
      'RMAN''s CONVERT command used by the database.');
  end;

  /********************* 
   * Cross Platform Backup and Restore
   *********************/

  declare
    DBFUS_CROSS_PLATFORM_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation in '||
        '     (''RECOVER FROM PLATFORM'', ''BACKUP FOR TRANSPORT'', '||
        '      ''BACKUP FROM PLATFORM'', ''RESTORE FROM PLATFORM''))';
  begin
    dbms_feature_usage.register_db_feature
     ('Cross-Platform Backups',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CROSS_PLATFORM_STR,
      'Cross-Platform Backup and Restore used by the database.');
  end;

  /********************* 
   * Duplicate from Active Database using BackupSet
   *********************/

  declare
    DBFUS_DUPDB_USINGBCK_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''DUPLICATE DB FROM ACTIVE USING B%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('Duplicate Db from Active Db using BackupSet',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DUPDB_USINGBCK_STR,
      'Duplicate from Active Database using BackupSet is used.');
  end;

  /********************** 
   * Resource Manager
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Resource Manager',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_RESOURCE_MANAGER',
      'Oracle Database Resource Manager is being used to manage ' ||
      'database resources.');
  end;

  /********************** 
   * Instance Caging
   **********************/

  declare
    DBFUS_DATA_INSTANCE_CAGING_STR CONSTANT VARCHAR2(2000) :=
      'select count(*), NULL, NULL from v$rsrc_plan_history top where ' ||
      'instance_caging = ''ON'' and ' ||
      '(name != ''ORA$INTERNAL_CDB_PLAN'' and ' ||
      ' name != ''INTERNAL_PLAN'' and name is not null and ' ||
      ' (name != ''DEFAULT_MAINTENANCE_PLAN'' or ' ||
      '   (window_name is null or ' ||
      '    (window_name != ''MONDAY_WINDOW'' and ' ||
      '     window_name != ''TUESDAY_WINDOW'' and ' ||
      '     window_name != ''WEDNESDAY_WINDOW'' and ' ||
      '     window_name != ''THURSDAY_WINDOW'' and ' ||
      '     window_name != ''FRIDAY_WINDOW'' and ' ||
      '     window_name != ''SATURDAY_WINDOW'' and ' ||
      '     window_name != ''SUNDAY_WINDOW''))) and ' ||
      ' (name != ''DEFAULT_CDB_PLAN'' or ' ||
      '   (select count(*) from v$rsrc_plan_history pdb ' ||
      '      where pdb.con_id > 1 and pdb.name is not null) = 0 or ' ||
      '   (select count(*) from v$rsrc_plan_history pdb ' ||
      '      where pdb.con_id > 1 and ' ||
      '            pdb.name is not null and ' ||
      '            pdb.name != ''INTERNAL_PLAN'' and ' ||
      '            (pdb.name != ''DEFAULT_MAINTENANCE_PLAN'' or ' ||
      '              (pdb.window_name is null or ' ||
      '               (pdb.window_name != ''MONDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''TUESDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''WEDNESDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''THURSDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''FRIDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''SATURDAY_WINDOW'' and ' ||
      '                pdb.window_name != ''SUNDAY_WINDOW'')))) > 0))';
  begin
    dbms_feature_usage.register_db_feature
     ('Instance Caging',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DATA_INSTANCE_CAGING_STR,
      'Instance Caging is being used to limit the CPU usage by the ' ||
      'database instance.');
  end;

  /********************** 
   * dNFS
   **********************/

  declare
    DBFUS_DATA_DNFS_STR CONSTANT VARCHAR2(1000) :=
      'select count(*), NULL, NULL from v$dnfs_servers';
  begin
    dbms_feature_usage.register_db_feature
     ('Direct NFS',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DATA_DNFS_STR,
      'Direct NFS is being used to connect to an NFS server');
  end;

  /********************** 
   * PDB I/O rate limits
   **********************/

  declare
    DBFUS_DATA_PDB_IORL_STR CONSTANT VARCHAR2(1000) :=
      'select count(*), NULL, NULL from pdb_spfile$ ' ||
      'where name = ''max_iops'' or name = ''max_mbps''';
  begin
    dbms_feature_usage.register_db_feature
     ('PDB I/O Rate Limits',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DATA_PDB_IORL_STR,
      'PDB I/O Rate Limits are being used to limit the I/O usage by ' ||
      'Pluggable databases.');
  end;

  /*********************** 
   * Server Flash Cache
   ***********************/

  declare 
    DBFUS_SRV_FLASH_CACHE_SIZE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter where ' ||
        'name like ''%flash_cache_size'' and value != ''0''';

  begin
    dbms_feature_usage.register_db_feature
     ('Server Flash Cache',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SRV_FLASH_CACHE_SIZE_STR,
      'Server Flash Cache is being used with this database.');
  end;

  /************************ 
   * Server Parameter File
   ************************/

  declare 
    DBFUS_SPFILE_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter where ' ||
        'name = ''spfile'' and value is not null';

  begin
    dbms_feature_usage.register_db_feature
     ('Server Parameter File',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SPFILE_STR,
      'The server parameter file (SPFILE) was used to startup the database.');
  end;

  /********************** 
   * Shared Server
   **********************/

  declare 
    DBFUS_MTS_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from v$system_parameter ' ||
        'where name = ''shared_servers'' and value != ''0'' and ' ||
        'exists (select 1 from v$shared_server where requests > 0)';

  begin
    dbms_feature_usage.register_db_feature
     ('Shared Server',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_MTS_STR,
      'The database is configured as Shared Server, where one server ' ||
      'process can service multiple client programs.');
  end;

  /********************************************** 
   * Database Resident Connection Pooling  (DRCP)
   **********************************************/

  declare 
    DBFUS_DRCP_STR CONSTANT VARCHAR2(1000) := 
      'select count(maxsize), nvl(sum(maxsize),0), NULL from dba_cpool_info '||
      'where status=''ACTIVE''';

  begin
    dbms_feature_usage.register_db_feature
     ('Database Resident Connection Pooling (DRCP)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_DRCP_STR,
      'Active Database Resident Connection Pool has been detected');
  end;

  /********************** 
   * Spatial 
     If Spatial is installed then the second query returns 1;
     else it returns 0. So use that to multiply the metadata count
     to get only the Spatial install usage and not the Locator install 
     usage. 
   **********************/

  declare 
    DBFUS_SPATIAL_STR CONSTANT VARCHAR2(1000) := 
     'select atc*ix, atc*ix, NULL from ' ||
       '(select count(*) atc ' ||
         'from mdsys.sdo_feature_usage '||
         'where used = ''Y'' and ' ||
         'feature_name in (''3D_FUNCTIONS'', ''AGGREGATES'', ''CSW'', ' ||
         ' ''GEOCODER'', ''GEORASTER'', ''LRS'', ''NDM'', ''OPEN_LS'', ' ||
         ' ''POINTCLOUD'', ''RELATE'', ''ROUTER'', ''SAM'', ''TIN'', ' ||
         ' ''TOPOLOGY'', ''UNION_INTERSECTION'', ''WFS'')), ' ||
       '(select count(*) ix ' ||
          'from dba_registry where comp_id = ''SDO'' and status != ''REMOVED'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Spatial',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'MDSYS.all_sdo_index_metadata',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SPATIAL_STR,
      'There is at least one usage of the Oracle Spatial feature usage table.');
  end;

  /**********************
   * Locator
     If Locator is installed then the second query returns 1;
     else it returns 0. So use that to multiply the metadata count
     to get only the Locator install usage and not the Spatial install
     usage.
   **********************/

  declare
    DBFUS_LOCATOR_STR CONSTANT VARCHAR2(1000) :=
     'select atc*six, atc*six, NULL from ' ||
       '(select count(*) atc ' ||
         'from mdsys.sdo_feature_usage '||
         'where used = ''Y'' and ' ||
         'feature_name not in (''3D_FUNCTIONS'', ''AGGREGATES'', ''CSW'', ' ||
         ' ''GEOCODER'', ''GEORASTER'', ''LRS'', ''NDM'', ''OPEN_LS'', ' ||
         ' ''POINTCLOUD'', ''RELATE'', ''ROUTER'', ''SAM'', ''TIN'', ' ||
         ' ''TOPOLOGY'', ''UNION_INTERSECTION'', ''WFS'')), ' ||
     ' ( select decode(sx-ix, -1, 0, 0, 0, 1) six from ( ' ||
     ' select count(*) sx from  dba_registry where comp_id = ''ORDIM''), '||
     ' ( select count(*) ix from dba_registry where comp_id = ''SDO'' and status != ''REMOVED'')) ';

  begin
    dbms_feature_usage.register_db_feature
     ('Locator',
      dbms_feature_usage.DBU_INST_OBJECT,
      'MDSYS.sdo_geom_metadata_table',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_LOCATOR_STR,
      'There is at least one usage of the Oracle Locator feature usage table.');
  end;


  /***********************************************************************
   * All advisors using the advisor framework. This includes all advisors 
   * listed in DBA_ADVISOR_DEFINITIONS and DBA_ADVISOR_USAGE views.
   ************************************************************************/
  /* FIXME: Mike would like to use a pl/sql procedure instead of a query */ 
  declare 
      dbu_detect_sql VARCHAR2(32767); 
  begin 
      FOR adv_rec IN (SELECT advisor_name, advisor_id 
                      FROM dba_advisor_definitions
                      WHERE bitand(property, 64) != 64
                      ORDER BY advisor_id)  
      LOOP
        -- build the query that will be executed to track an advisor usage

        -- clob column FEATURE_INFO will contain XML for advisor framework-
        -- level info, with advisor extra info sitting beneath the framework
        -- tag
        IF (adv_rec.advisor_name = 'ADDM') THEN 
          dbu_detect_sql := ', xmltype(prvt_hdm.db_feature_clob) ';
        ELSE
          dbu_detect_sql := '';
        END IF;

        dbu_detect_sql := 
          ' xmlelement("advisor_usage", 
              xmlelement("reports", 
                xmlelement("first_report_time", 
                            to_char(first_report_time, 
                                    ''dd-mon-yyyy hh24:mi:ss'')), 
                xmlelement("last_report_time", 
                           to_char(last_report_time, 
                                   ''dd-mon-yyyy hh24:mi:ss'')),
                xmlelement("num_db_reports", num_db_reports)) 
                ' || dbu_detect_sql || ').getClobVal(2,2) ';

        -- used:       1 if advisor executed since last sample
        -- sofar_exec: total # of executions since db create
        -- dbf_clob:   reporting, plus advisor-specific stuff
        dbu_detect_sql := 
          'SELECT used, sofar_exec, dbf_clob FROM 
             (SELECT num_execs sofar_exec, ' || dbu_detect_sql || ' dbf_clob
              FROM   dba_advisor_usage u 
              WHERE  u.advisor_name = ''' || adv_rec.advisor_name || '''), ' ||
            '(SELECT count(*) used
              FROM   dba_advisor_usage u
              WHERE u.advisor_name = ''' || adv_rec.advisor_name || ''' AND 
                    (u.num_execs > 0 or u.num_db_reports > 0) and 
                     greatest(nvl(u.last_exec_time, sysdate - 1000), 
                              nvl(u.last_report_time, sysdate - 1000)) >= 
                                       ' || DBFUS_LAST_SAMPLE_DATE_STR || ')';

        -- register the current advisor
        dbms_feature_usage.register_db_feature
          (adv_rec.advisor_name,
           dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
           NULL,
           dbms_feature_usage.DBU_DETECT_BY_SQL,
           dbu_detect_sql,
           adv_rec.advisor_name || ' has been used.');
      END LOOP;
  end;

  /******************************
   * Real-Time SQL Monitoring
   ******************************/
  declare 
      dbu_detect_sql VARCHAR2(32767); 
  begin 
      -- used:       1 if db report for monitoring details requested since
      --             last sample (list report is not tracked)
      -- sofar_exec: total # of db reports requested since db creation
      -- dbf_clob:   extra XML info
      dbu_detect_sql := 
        'SELECT used, sofar_exec, dbf_clob
         FROM   (SELECT count(*) used
                 FROM   dba_sql_monitor_usage
                 WHERE  num_db_reports > 0 AND
                        last_db_report_time >= ' || DBFUS_LAST_SAMPLE_DATE_STR
                || '), 
                (SELECT num_db_reports sofar_exec, 
                        xmlelement("sqlmon_usage", 
                         xmlelement("num_em_reports", num_em_reports),
                         xmlelement("first_db_report_time", 
                           to_char(first_db_report_time, 
                                   ''dd-mon-yyyy hh24:mi:ss'')),
                         xmlelement("last_db_report_time", 
                           to_char(last_db_report_time, 
                                   ''dd-mon-yyyy hh24:mi:ss'')),
                         xmlelement("first_em_report_time", 
                           to_char(first_em_report_time, 
                                   ''dd-mon-yyyy hh24:mi:ss'')),
                         xmlelement("last_em_report_time", 
                           to_char(last_em_report_time, 
                                   ''dd-mon-yyyy hh24:mi:ss''))
                        ).getClobVal(2,2) dbf_clob
                FROM dba_sql_monitor_usage)'; 

      -- register the feature
      dbms_feature_usage.register_db_feature
        ('Real-Time SQL Monitoring',
         dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
         NULL,
         dbms_feature_usage.DBU_DETECT_BY_SQL,
         dbu_detect_sql,
         'Real-Time SQL Monitoring Usage.');
  end;
  

  /******************************
   * SQL Tuning Set
   ******************************/
  declare 
    -- A 'user' SQL Tuning Set is one not owned by SYS, and a 'system' SQL
    -- Tuning Set is one that is owned by SYS.  This will cover the $$ STSes
    -- that Access Advisor creates, and users do not use EM as SYS, so it should
    -- be good enough for now.
    DBFUS_USER_SQL_TUNING_SET_STR CONSTANT VARCHAR2(1000) := 
      'select numss, numref, NULL from ' ||
        '(select count(*) numss ' ||
        ' from wri$_sqlset_definitions ' ||
        ' where owner <> ''SYS''), ' ||
        '(select count(*) numref ' ||
        ' from wri$_sqlset_references r, wri$_sqlset_definitions d ' ||
        ' where d.id = r.sqlset_id and d.owner <> ''SYS'')';

    DBFUS_SYS_SQL_TUNING_SET_STR CONSTANT VARCHAR2(1000) := 
      'select numss, numref, NULL from ' ||
        '(select count(*) numss ' ||
        ' from wri$_sqlset_definitions ' ||
        ' where owner = ''SYS''), ' ||
        '(select count(*) numref ' ||
        ' from wri$_sqlset_references r, wri$_sqlset_definitions d ' ||
        ' where d.id = r.sqlset_id and d.owner = ''SYS'')';
  begin
    dbms_feature_usage.register_db_feature
     ('SQL Tuning Set (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_USER_SQL_TUNING_SET_STR,
      'A SQL Tuning Set has been created in the database in a user schema.');


    dbms_feature_usage.register_db_feature
     ('SQL Tuning Set (system)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SYS_SQL_TUNING_SET_STR,
      'A SQL Tuning Set has been created in the database in the SYS schema.');
  end;

  /******************************
   * Automatic SQL Tuning Advisor
   ******************************/
  declare
    DBFUS_AUTOSTA_PROC VARCHAR2(100) := 'DBMS_FEATURE_AUTOSTA';
  begin
    dbms_feature_usage.register_db_feature
     ('Automatic SQL Tuning Advisor',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_AUTOSTA_PROC,
      'Automatic SQL Tuning Advisor has been used.');
  end;

  /******************************
   * SQL Profiles 
   ******************************/
  /* FIXME: Mike would like to use a pl/sql procedure instead of a query */ 
  declare 
    DBFUS_SQLPROFILE_STR CONSTANT VARCHAR2(32767) := 
      q'#SELECT used,
                prof_count, 
                profs || ', ' || manual || ', ' || auto || ', ' || 
                enabl || ', ' || cat as details
         FROM (SELECT sum(decode(status, 'ENABLED', 1, 0)) used,
                      sum(1) prof_count,
                     'Total so far: ' || sum(1) profs, 
                     'Enabled: ' || sum(decode(status, 'ENABLED', 1, 0)) enabl,
                     'Manual: ' || sum(decode(type, 'MANUAL', 1, 0)) manual,
                     'Auto: ' || sum(decode(type, 'AUTO', 1, 0)) auto,
                     'Category count: ' || count(unique category) cat
               FROM dba_sql_profiles)#';
  begin
    dbms_feature_usage.register_db_feature
     ('SQL Profile',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SQLPROFILE_STR,
      'SQL profiles have been used.');
  end;

  /************************************************
   * Database Replay: Workload Capture and Replay *
   ************************************************/
  declare
    prev_sample_count     NUMBER;
    prev_sample_date      NUMBER;

    DBFUS_WCR_CAPTURE_PROC VARCHAR2(1000) := 'DBMS_FEATURE_WCR_CAPTURE';
    DBFUS_WCR_REPLAY_PROC  VARCHAR2(1000) := 'DBMS_FEATURE_WCR_REPLAY';
  begin
    dbms_feature_usage.register_db_feature
     ('Database Replay: Workload Capture',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_WCR_CAPTURE_PROC,
      'Database Replay: Workload was ever captured.');

    dbms_feature_usage.register_db_feature
     ('Database Replay: Workload Replay',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_WCR_REPLAY_PROC,
      'Database Replay: Workload was ever replayed.');
  end;

  /********************** 
   * Streams (system)
   **********************/

  declare 
    DBFUS_STREAMS_SYS_PROC CONSTANT VARCHAR2(1000) := 
       'dbms_feature_streams';

  begin
    dbms_feature_usage.register_db_feature
     ('Streams (system)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_STREAMS_SYS_PROC,
      'Oracle Streams processes have been configured');
  end;

  /********************** 
   * Streams (user)
   **********************/

  declare 
    DBFUS_STREAMS_USER_STR CONSTANT VARCHAR2(1000) := 
    -- for AQ, there are default queues in the sys, system, ix, 
    -- wmsys, sysman, and gsmdamin_internal
    -- schemas which we do not want to count towards Streams user feature usage
    -- for Streams messaging these consumers are in db by default
     'select decode(strmsg + aq, 0, 0, 1), 0, NULL from ' ||
     '(select decode(count(*), 0, 0, 1) strmsg ' ||
     '  from dba_streams_message_consumers ' ||
     '  where streams_name != ''SCHEDULER_COORDINATOR'' and ' ||
     '  streams_name != ''SCHEDULER_PICKUP''),' ||  
     '(select decode (count(*), 0, 0, 1) aq ' ||
     '  from system.aq$_queue_tables where schema not in ' ||
     '  (''SYS'', ''SYSTEM'', ''IX'', ''WMSYS'', ''SYSMAN'', ' ||
     '''GSMADMIN_INTERNAL''))';

  begin
    dbms_feature_usage.register_db_feature
     ('Streams (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_STREAMS_USER_STR,
      'Users have configured Oracle Streams AQ');
  end;

  /********************** 
   * XStream In
   **********************/

  declare 
    DBFUS_XSTREAM_IN_PROC CONSTANT VARCHAR2(1000) := 
       'dbms_feature_xstream_in';

  begin
    dbms_feature_usage.register_db_feature
     ('XStream In',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_XSTREAM_IN_PROC,
      'Oracle XStream Inbound servers have been configured');
  end;

  /**********************
   * XStream Out
   **********************/

  declare
    DBFUS_XSTREAM_OUT_PROC CONSTANT VARCHAR2(1000) :=
       'dbms_feature_xstream_out';

  begin
    dbms_feature_usage.register_db_feature
     ('XStream Out',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_XSTREAM_OUT_PROC,
      'Oracle XStream Outbound servers have been configured');
  end;

  /**********************
   * XStream Streams
   **********************/

  declare
    DBFUS_XSTREAM_STREAMS_PROC CONSTANT VARCHAR2(1000) :=
       'dbms_feature_xstream_streams';

  begin
    dbms_feature_usage.register_db_feature
     ('XStream Streams',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_XSTREAM_STREAMS_PROC,
      'Oracle Streams with XStream functionality has been configured');
  end;

  /**********************
   * GoldenGate
   **********************/

  declare
    DBFUS_GOLDENGATE_PROC CONSTANT VARCHAR2(1000) :=
    'dbms_feature_goldengate';

  begin
    dbms_feature_usage.register_db_feature
     ('GoldenGate',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_GOLDENGATE_PROC,
      'Oracle GoldenGate Capabilities are in use.');
  end;

  /********************** 
   * Transparent Gateway
   **********************/

  declare 
    DBFUS_GATEWAYS_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from hs_fds_class_date ' || 
        'where fds_class_name != ''BITE''';

  begin
    dbms_feature_usage.register_db_feature
     ('Transparent Gateway',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_GATEWAYS_STR,
      'Heterogeneous Connectivity, access to a non-Oracle system, has ' ||
      'been configured.');
  end;

  /***************************
   * Virtual Private Database
   ***************************/

  declare 
    DBFUS_VPD_STR CONSTANT VARCHAR2(1000) := 
      'select count(*), NULL, NULL from DBA_POLICIES where OBJECT_OWNER ' || 
      'NOT IN (''SYSMAN'',''MDSYS'',''SYSMAN_MDS'',''XDB'',''CTXSYS'',' ||
      '''OE'',''LBACSYS'', ''GSMADMIN_INTERNAL'', ''SYSTEM'')';

  begin
    dbms_feature_usage.register_db_feature
     ('Virtual Private Database (VPD)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_VPD_STR,
      'Virtual Private Database (VPD) policies are being used.');
  end;

  /********************** 
   * Workspace Manager
   **********************/

  declare 
    DBFUS_OWM_STR CONSTANT VARCHAR2(1000) := 
     'select count(*), count(*), NULL ' ||
     'from wmsys.wm$versioned_tables';

  begin
    dbms_feature_usage.register_db_feature
     ('Workspace Manager',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'WMSYS.wm$versioned_tables',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_OWM_STR,
      'There is at least one version enabled table.');
  end;

  /**************************
   * XDB
   **************************/
   
  begin
    dbms_feature_usage.register_db_feature
     ('XDB',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'XDB.Resource_View',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_XDB',
      'XDB feature is being used.');
  end;

  /*****************************
   * JSON
   *****************************/

  begin
    dbms_feature_usage.register_db_feature
     ('JSON',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_JSON',
      'JSON feature is being used.');
  end;

  /*****************************
   * Application Express (APEX)
   *****************************/
  begin
    dbms_feature_usage.register_db_feature
    ( 'Application Express',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_APEX',
      'Application Express feature is being used.');
  end;

  /***************************
   * LOB 
   ***************************/

  declare
    DBMS_FEATURE_LOB CONSTANT VARCHAR2(1000) :=
      'select count(*), NULL, NULL from sys.lob$ l, sys.obj$ o, sys.user$ u ' ||
       'where l.obj# = o.obj# ' ||
         'and o.owner# = u.user# ' ||
         'and u.name not in (select schema_name from v$sysaux_occupants) ' ||
         'and u.name not in (''OUTLN'', ''OE'', ''IX'', ''PM'', ''SH'', 
                             ''OJVMSYS'', ''DVSYS'', ''GSMADMIN_INTERNAL'', 
                             ''SYSMAN_MDS'', ''SYSMAN_OPSS'', 
                             ''SYSMAN_BIPLATFORM'') ' ||
         'and u.name not like ''APEX_% '' ' ||
         'and u.name not like ''FLOWS_%'''; 

  begin
    dbms_feature_usage.register_db_feature
     ('LOB',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBMS_FEATURE_LOB,
      'Persistent LOBs are being used.');
  end;

  /***************************
   * OBJECT 
   ***************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Object',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_OBJECT',
      'Object feature is being used.');
  end;

  /***************************
   * EXTENSIBILITY 
   ***************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Extensibility',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_EXTENSIBILITY',
      'Extensibility feature is being used.');
  end;

  /******************************
   * SQL Plan Management
   ******************************/

  declare 
    DBFUS_SQL_PLAN_MANAGEMENT_STR CONSTANT VARCHAR2(4000) := 
      q'#SELECT nvl(total_count, 0) total_count,
                nvl(enabled_count, 0) enabled_count, 
                decode(total_count, null, null,
                                    0, null,
                                    (manual_load || ', ' ||
                                     auto_capture || ', ' ||
                                     manual_sqltune || ', ' || 
                                     auto_sqltune || ', ' ||
                                     stored_outline || ', ' ||
                                     evolve_adaptive || ', ' ||
                                     manual_load_sts || ', ' ||
                                     manual_load_awr || ', ' ||
                                     manual_load_cc || ', ' ||
                                     evolve_load_sts || ', ' ||
                                     evolve_load_awr || ', ' ||
                                     evolve_load_cc || ', ' ||
                                     accepted_count || ', ' ||
                                     fixed_count || ', ' ||
                                     reproduced_count)) as details
         FROM (SELECT
                 sum(1) total_count,
                 sum(decode(enabled, 'YES', 1, 0)) enabled_count,
                 'Manual-load: ' ||
                   sum(decode(origin, 'MANUAL-LOAD', 1, 0)) manual_load,
                 'Auto-capture: ' ||
                   sum(decode(origin, 'AUTO-CAPTURE', 1, 0)) auto_capture,
                 'Manual-sqltune: ' ||
                   sum(decode(origin, 'MANUAL-SQLTUNE', 1, 0)) manual_sqltune,
                 'Auto-sqltune: ' ||
                   sum(decode(origin, 'AUTO-SQLTUNE', 1, 0)) auto_sqltune,
                 'Stored-outline: ' ||
                   sum(decode(origin, 'STORED-OUTLINE', 1, 0)) stored_outline,
                 'Evolve-create-from-adaptive: ' ||
                   sum(decode(origin, 'EVOLVE-CREATE-FROM-ADAPTIVE', 1, 0)) 
                     evolve_adaptive,
                 'Manual-load-from-sts: ' ||
                   sum(decode(origin, 'MANUAL-LOAD-FROM-STS', 1, 0))
                     manual_load_sts,
                 'Manual-load-from-awr: ' ||
                   sum(decode(origin, 'MANUAL-LOAD-FROM-AWR', 1, 0))
                     manual_load_awr,
                 'Manual-load-from-cursor-cache: ' ||
                   sum(decode(origin, 'MANUAL-LOAD-FROM-CURSOR-CACHE', 1, 0))
                     manual_load_cc,
                 'Evolve-load-from-sts: ' ||
                   sum(decode(origin, 'EVOLVE-LOAD-FROM-STS', 1, 0))
                     evolve_load_sts,
                 'Evolve-load-from-awr: ' ||
                   sum(decode(origin, 'EVOLVE-LOAD-FROM-AWR', 1, 0))
                     evolve_load_awr,
                 'Evolve-load-from-cursor-cache: ' ||
                   sum(decode(origin, 'EVOLVE-LOAD-FROM-CURSOR-CACHE', 1, 0))
                     evolve_load_cc,
                 'Accepted: ' ||
                   sum(decode(accepted, 'YES', 1, 0)) accepted_count,
                 'Fixed: ' ||
                   sum(decode(fixed, 'YES', 1, 0)) fixed_count,
                 'Reproduced: ' ||
                   sum(decode(reproduced, 'YES', 1, 0)) reproduced_count
               FROM dba_sql_plan_baselines)#';
  begin
    dbms_feature_usage.register_db_feature
     ('SQL Plan Management',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SQL_PLAN_MANAGEMENT_STR,
      'SQL Plan Management has been used.');
  end;

  /******************************
   * DBMS_FEATURE_ADAPTIVE_PLANS
   ******************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Adaptive Plans',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_ADAPTIVE_PLANS',
      'Adaptive Plans have been used');
  end;

  /**********************************
   * DBMS_FEATURE_AUTO_REOPT
   **********************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Automatic Reoptimization',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_AUTO_REOPT',
      'Automatic Reoptimization have been used');
  end;

  begin
    dbms_feature_usage.register_db_feature
     ('SQL Plan Directive',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_SPD',
      'Sql plan directive has been used');
  end;

  /******************************
   * DBMS_FEATURE_STATS_CONCURRENT
   ******************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Concurrent Statistics Gathering',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_CONCURRENT_STATS',
      'Concurrent Statistics Gathering has been used');
  end;

  /******************************
   * DBMS_FEATURE_STATS_INCREMENTAL
   ******************************/
  begin
    dbms_feature_usage.register_db_feature
     ('DBMS_STATS Incremental Maintenance',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_STATS_INCREMENTAL',
      'DBMS_STATS Incremental Maintenance has been used.');
  end;


  /***************************
   * RULES MANAGER and EXPRESSION FILTER
   ***************************/
  begin
    dbms_feature_usage.register_db_feature
        ('Rules Manager',
          dbms_feature_usage.DBU_INST_OBJECT, 
          'EXFSYS.exf$attrset',
          dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
          'DBMS_FEATURE_RULESMANAGER',
           'Rules Manager and Expression Filter');
  end;

  /***************************************************************
   *  DATABASE UTILITY: ORACLE DATAPUMP EXPORT
   ***************************************************************/
  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility Datapump (Export)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities1',
       'Oracle Utility Datapump (Export) has been used.');
  end;

  /***************************************************************
   *  DATABASE UTILITY: ORACLE DATAPUMP IMPORT
   ***************************************************************/
  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility Datapump (Import)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities2',
       'Oracle Utility Datapump (Import) has been used.');
  end;

  /***************************************************************
   *  DATABASE UTILITY: SQL*LOADER (DIRECT PATH LOAD)
   ***************************************************************/
  declare
   DBFUS_UTL_SQLLOADER_STR CONSTANT VARCHAR2(1000) :=
       'select usecnt, NULL, NULL from sys.ku_utluse                      ' ||
       ' where utlname = ''Oracle Utility SQL Loader (Direct Path Load)'' ' ||
       ' and   (last_used >=                                              ' ||
       '       (SELECT nvl(max(last_sample_date), sysdate-7)              ' ||
       '          FROM dba_feature_usage_statistics))';

  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility SQL Loader (Direct Path Load)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_SQL,
       DBFUS_UTL_SQLLOADER_STR,
       'Oracle Utility SQL Loader (Direct Path Load) has been used.');
  end;

  /***************************************************************
   *  DATABASE UTILITY: METADATA API
   ***************************************************************/
  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility Metadata API',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities3',
       'Oracle Utility (Metadata API) has been used.');
  end;

  /***************************************************************
   *  DATABASE UTILITY: EXTERNAL TABLE
   ***************************************************************/

  /* As of 12.2 we treat each invocation of external tables according
   * to which access driver is used.  Deprecate this registration of
   * 'Oracle Utility External Table' by setting DBU_DETECT_NULL.
   */
  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility External Table',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_NULL,
       'dbms_feature_utilities4',
       'Oracle Utility External Table has been used.');
  end;

  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility External Table (ORACLE_DATAPUMP)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities4',
       'Oracle Utility External Table (ORACLE_DATAPUMP) has been used.');
  end;

  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility External Table (ORACLE_LOADER)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities5',
       'Oracle Utility External Table (ORACLE_LOADER) has been used.');
  end;

  declare
  begin
   dbms_feature_usage.register_db_feature
      ('Oracle Utility External Table (ORACLE_BIGSQL)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'dbms_feature_utilities6',
       'Oracle Utility External Table (ORACLE_BIGSQL) has been used.');
  end;
  
  /***************************************************************
   *  RESULT CACHE
   ***************************************************************/
  declare
   DBFUS_RESULT_CACHE_STR CONSTANT VARCHAR2(1000) :=
       'select (select value from v$result_cache_statistics ' ||
       '        where name = ''Block Count Current''), '      ||
       '       (select value from v$result_cache_statistics ' ||
       '        where name = ''Find Count''), null '          ||
       'from dual';

  begin
   dbms_feature_usage.register_db_feature
      ('Result Cache', 
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_SQL,
       DBFUS_RESULT_CACHE_STR,
       'The Result Cache feature has been used.');
  end;

  /************************************** 
   * TDE - Transparent Data Encryption
   **************************************/

  declare 
    DBFUS_TDE_STR CONSTANT VARCHAR2(1000) :=
      'SELECT (T1.A + T2.B) IsFeatureUsed, ' ||
             '(T1.A + T2.B) AUX_COUNT, ' ||
             '''Encryption TABLESPACE Count = '' || T1.A || '','||
               'Encryption COLUMN Count = '' || T2.B REMARK ' ||
      'FROM   (SELECT count(*) A FROM DBA_TABLESPACES WHERE ' ||
                    ' UPPER(ENCRYPTED) = ''YES'') T1, ' ||
             '(SELECT count(*) B FROM DBA_ENCRYPTED_COLUMNS) T2 ' ;
  begin
    dbms_feature_usage.register_db_feature
     ('Transparent Data Encryption',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_TDE_STR,
      'Transparent Database Encryption is being used. There is' || 
      ' atleast one column or tablespace that is encrypted.');
  end;

  /******************* 
   * Data Redaction
   *******************/
  
  /* Bug# 13888340: Data redaction feature usage tracking
   * Related test files are tmfudru.tsc and tmfudr.tsc.
   */
  begin
    dbms_feature_usage.register_db_feature
     ('Data Redaction',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_DATA_REDACTION',
      'Data redaction is being used. There is' || 
      ' at least one policy that is defined.');
  end;

  /********************** 
   * Oracle Multimedia
   **********************/

  declare 
    DBFUS_MULTIMEDIA_STR CONSTANT VARCHAR2(1000) := 
      'ordsys.CARTRIDGE.dbms_feature_multimedia';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Multimedia',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'ORDSYS.ORDIMERRORCODES',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_MULTIMEDIA_STR,
      'Oracle Multimedia has been used');
  end;

  /*****************************************************************
   * Oracle Multimedia DICOM: medical imaging 
   * DICOM stands for Digital Imaging and COmmunications in Medicine
   *****************************************************************/

  declare 
    DBFUS_DICOM_STR CONSTANT VARCHAR2(1000) := 
      'ordsys.CARTRIDGE.dbms_feature_dicom';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Multimedia DICOM',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'ORDSYS.ORDDICOM',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DICOM_STR,
      'Oracle Multimedia DICOM (Digital Imaging and COmmunications in Medicine) has been used');
  end;

  /****************************
   * Materialized Views (User)
   ****************************/

  declare
    DBFUS_USER_MVS CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_USER_MVS';

  begin
    dbms_feature_usage.register_db_feature
     ('Materialized Views (User)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_USER_MVS,
      'User Materialized Views exist in the database');
  end;

  /***************************
   * Change Data Capture (CDC) 
   ***************************/
  begin
    dbms_feature_usage.register_db_feature
        ('Change Data Capture',
          dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
          NULL,
          dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
          'DBMS_FEATURE_CDC',
           'Change Data Capture exit in the database');
  end;

  /********************************
   * Services
   *********************************/
  declare
    DBFUS_SERVICES_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_SERVICES';
  begin
    dbms_feature_usage.register_db_feature
     ('Services',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_SERVICES_PROC,
      'Oracle Services.');
  end;

  /***********************
   * Semantics/RDF/OWL
   ***********************/

   declare
     DBFUS_SEMANTICS_RDF_STR CONSTANT VARCHAR2(1000) := 
        'select cnt, cnt, null from ' ||
        ' (select count(*) cnt from mdsys.rdf_model$)';

   begin
     dbms_feature_usage.register_db_feature
       ('Semantics/RDF', 
         dbms_feature_usage.DBU_INST_OBJECT, 
         'MDSYS.RDF_Models',
         dbms_feature_usage.DBU_DETECT_BY_SQL,
         DBFUS_SEMANTICS_RDF_STR,
         'A semantic network has been created indicating usage of the ' ||
         'Oracle Semantics Feature.');
    end;
    
  /***********************
   * SecureFiles (user)
   ***********************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFiles (user)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SECUREFILES_USR',
       'SecureFiles is being used');
  end;

  /***********************
   * SecureFiles (system)
   ***********************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFiles (system)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SECUREFILES_SYS',
       'SecureFiles is being used by system users');
  end;

  /*********************************
   * SecureFile Encryption (user)
   *********************************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFile Encryption (user)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SFENCRYPT_USR',
       'SecureFile Encryption is being used');
  end;

  /*********************************
   * SecureFile Encryption (system)
   *********************************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFile Encryption (system)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SFENCRYPT_SYS',
       'SecureFile Encryption is being used by system users');
  end;

  /*********************************
   * SecureFile Compression (user)
   *********************************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFile Compression (user)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SFCOMPRESS_USR',
       'SecureFile Compression is being used');
  end;

  /*********************************
   * SecureFile Compression (system)
   *********************************/

  begin
   dbms_feature_usage.register_db_feature
      ('SecureFile Compression (system)',
        dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
        NULL,
        dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_SFCOMPRESS_SYS',
       'SecureFile Compression is being used by system users');
  end;

  /*********************************
   * SecureFile Deduplication (user)
   *********************************/

  begin
    dbms_feature_usage.register_db_feature
     ('SecureFile Deduplication (user)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_SFDEDUP_USR',
      'SecureFile Deduplication is being used');
  end;

  /*********************************
   * SecureFile Deduplication (system)
   *********************************/

  begin
    dbms_feature_usage.register_db_feature
     ('SecureFile Deduplication (system)',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_SFDEDUP_SYS',
      'SecureFile Deduplication is being used by system users');
  end;

  /******************************
   * Segment Advisor
   ******************************/

  declare 
    DBFUS_SEGADV_USER_PROC CONSTANT VARCHAR2(100) := 'DBMS_FEATURE_SEGADV_USER';
  begin
    dbms_feature_usage.register_db_feature
     ('Segment Advisor (user)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED, 
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_SEGADV_USER_PROC,
      'Segment Advisor has been used. There is at least one user task executed.');
  end;


  /***************************
   * In-Memory Expressions
   ***************************/

  begin
   dbms_feature_usage.register_db_feature
      ('In-Memory Expressions',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_IM_EXPRESSIONS',
       'In-Memory Expressions or In-Memory Virtual Columns are being used');
  end;

  /***************************
   * In-Memory Join Groups
   ***************************/

  begin
   dbms_feature_usage.register_db_feature
      ('In-Memory Join Groups',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_IM_JOINGROUPS',
       'In-Memory Join Groups are being used');
  end;
  
  /***************************
   * In-Memory ADO Policies
   ***************************/

  begin
   dbms_feature_usage.register_db_feature
      ('In-Memory ADO Policies',
       dbms_feature_usage.DBU_INST_OBJECT,
       'SYS.ILM$',
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_IM_ADO',
       'In-Memory ADO Policies are being used');
  end;
  
  /***********************
   * Compression
   ***********************/

  begin
   dbms_feature_usage.register_db_feature
      ('HeapCompression',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_ADV_TABCMP',
       'Heap Compression is being used');
  end;

 /******************************
   * Advanced Index Compression
   *****************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Advanced Index Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_ADV_IDXCMP',
      'Advanced Index Compression is used');
  end;

/******************************
   * Index Organized Tables
   *****************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Index Organized Tables',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_IOT',
      'Index Organized Tables are being used');
  end;

/******************************
   * In-Memory Column Store
   *****************************/
  begin
    dbms_feature_usage.register_db_feature
     ('In-Memory Column Store',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_IMC',
      'In-Memory Column Store is being used');
  end;

/***************************************
   * In-Memory Distribute For Service (User Defined)
   *************************************/
  begin
    dbms_feature_usage.register_db_feature
     ('In-Memory Distribute For Service (User Defined)',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_IM_FORSERVICE',
      'In-Memory Distribute For Service (User Defined) is being used');
  end;


 /******************************
   * Hybrid Columnar Compression
   *****************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Hybrid Columnar Compression',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_HCC',
      'Hybrid Columnar Compression is used');
  end;

 /***************************************************
   * Hybrid Columnar Compression Conventional Load
   ****************************************************/
  begin
    dbms_feature_usage.register_db_feature
    ('Hybrid Columnar Compression Conventional Load',
     dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
     NULL,
     dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
     'DBMS_FEATURE_HCCCONV',
     'Hybrid Columnar Compression with Conventional Load is used');
  end;

 /************************************************
   * Hybrid Columnar Compression Row Level Locking
   **********************************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Hybrid Columnar Compression Row Level Locking',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_HCCRLL',
      'Hybrid Columnar Compression Row Level Locking is used');
  end;

  /*****************************************
    * Information Lifecycle Management (ILM)
    ****************************************/

  begin
    dbms_feature_usage.register_db_feature
      ('Information Lifecycle Management',
       dbms_feature_usage.DBU_INST_OBJECT,
       'SYS.ilm$',
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_ILM',
       'Information Lifecycle Management is used');
  end;

  /*****************************************
    * Heat Map
    ****************************************/

  begin
    dbms_feature_usage.register_db_feature
      ('Heat Map',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_HEATMAP',
       'Heat Map is used');
  end;


  /******************************
    * ZFS Storage
    ******************************/
  begin
    dbms_feature_usage.register_db_feature
      ('ZFS Storage',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_ZFS_STORAGE',
       'Tablespaces stored on Oracles Sun ZFS Storage');
  end;

  /******************************
    * Pillar Storage
    ******************************/
  begin
    dbms_feature_usage.register_db_feature
      ('Pillar Storage',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_PILLAR_STORAGE',
       'Tablespaces stored on Oracles Pillar Axiom Storage');
  end;

  /******************************
    * ZFS Storage + EHCC
    *****************************/
  begin
    dbms_feature_usage.register_db_feature
      ('Sun ZFS with EHCC',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_ZFS_EHCC',
       'EHCC used on tablespaces stored on Oracles Sun ZFS Storage');
  end;

  /******************************
    * Pillar Storage + EHCC
    *****************************/
  begin
    dbms_feature_usage.register_db_feature
      ('Pillar Storage with EHCC',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_PILLAR_EHCC',
       'EHCC used on tablespaces stored on Oracles Pillar Axiom Storage');
  end;

  /******************************
    * Cloud + EHCC
    *****************************/
  begin
    dbms_feature_usage.register_db_feature
      ('Cloud DB with EHCC',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_CLOUD_EHCC',
       'EHCC used for Cloud Database');
  end;

  /******************************
   * Segment Shrink
   ******************************/

  declare 
    DBFUS_SEG_SHRINK_STR CONSTANT VARCHAR2(1000) :=
      'select  count(*), 0, null ' ||
        'from  sys.seg$ s ' ||
        'where s.scanhint != 0 and ' ||
              'bitand(s.spare1, 65793) = 257 and ' ||
              's.type# in (5, 6,8) ';
  begin
    dbms_feature_usage.register_db_feature
     ('Segment Shrink',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SEG_SHRINK_STR,
      'Segment Shrink has been used.');
  end;

  /***************************
   * Job Scheduler 
   ***************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Job Scheduler',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_JOB_SCHEDULER',
      'Job Scheduler feature is being used.');
  end;

  /***************************
   * Orcle Gateways
   ***************************/

  begin
    dbms_feature_usage.register_db_feature
     ('Gateways',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_GATEWAYS',
      'Gateways feature is being used.');
  end;

  /*******************************
   * Java Virtual Machine (user)
   *******************************/

  declare 
    DBFUS_OJVM_STR CONSTANT VARCHAR2(1000) := 
      'sys.dbms_java.dbms_feature_ojvm';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Java Virtual Machine (user)',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'SYS.JAVA$POLICY$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_OJVM_STR,
      'OJVM has been used by at least one non-system user');
  end;

  /*********************************
   * Java Virtual Machine (system)
   *********************************/

  declare 
    DBFUS_OJVM_SYS_STR CONSTANT VARCHAR2(1000) := 
      'sys.dbms_java.dbms_feature_system_ojvm';

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle Java Virtual Machine (system)',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'SYS.JAVA$POLICY$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_OJVM_SYS_STR,
      'OJVM default system users');
  end;
  
  /**********************
   * In-Database Hadoop
   **********************/

  begin
    dbms_feature_usage.register_db_feature
     ('Oracle In-Database Hadoop',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'SYS.JAVA$POLICY$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_IDH',
      'In-Database Hadoop for running MapReduce in java');
  end;


  /************************
   * DBFS Content
   ************************/

  declare 
    DBFUS_DBFS_CONTENT_PROC CONSTANT VARCHAR2(1000) := 
      'sys.dbms_feature_dbfs_content';

  begin
    dbms_feature_usage.register_db_feature
     ('DBFS Content',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DBFS_CONTENT_PROC,
      'Oracle Database FileSystem Content feature is being used');
  end;

  /************************
   * DBFS SecureFile Store
   ************************/ 

  declare 
    DBFUS_DBFS_SFS_PROC CONSTANT VARCHAR2(1000) := 
      'sys.dbms_feature_dbfs_sfs';

  begin
    dbms_feature_usage.register_db_feature
     ('DBFS SFS',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DBFS_SFS_PROC,
      'Oracle Database FileSystem SecureFile Store feature is being used');
  end;

  /**************************
   * DBFS Hierarchical Store
   **************************/ 

  declare 
    DBFUS_DBFS_HS_PROC CONSTANT VARCHAR2(1000) := 
      'sys.dbms_feature_dbfs_hs';

  begin
    dbms_feature_usage.register_db_feature
     ('DBFS HS',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_DBFS_HS_PROC,
      'Oracle Database FileSystem Hierarchical Store feature is being used');
  end;

  /******************************
   * EXADATA
   ******************************/

  declare 
    DBFUS_EXADATA_PROC CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_EXADATA';

  begin
    dbms_feature_usage.register_db_feature
     ('Exadata',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_EXADATA_PROC,
      'Exadata is being used');
  end;

  /**************************
   * GSM CATALOG
   *************************/
   
   declare
     DBFUS_GSMCAT_STR CONSTANT VARCHAR2(1000) :=
        'select count(*), 0, NULL from gsmadmin_internal.cloud';

   begin
    dbms_feature_usage.register_db_feature
     ('GDS Catalog',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_GSMCAT_STR,
      'Database is a GDS catalog database.');
   end;
   
  /**************************
   * GSM GLOBAL SERVICES
   *************************/
   
   declare
     DBFUS_GSMGLOB_STR CONSTANT VARCHAR2(1000) :=
        'select count(*), 0, NULL from dba_services ' ||
        'where global_service = ''YES''';

   begin
    dbms_feature_usage.register_db_feature
     ('Global Data Services',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_GSMGLOB_STR,
      'Database contains global services.');
   end;

  /**************************
   * SYSTEM SHARDING CATALOG
   *************************/
  
  declare
    DBFUS_SYSSHDCAT_STR CONSTANT VARCHAR2(1000) :=
       'select count(*), 0, NULL from gsmadmin_internal.cloud gc, v$parameter vp ' ||
       'WHERE gc.sharding_type in (1,2,3) and vp.name = ''_gws_deployed'' and vp.value = 2'; 
  begin
    dbms_feature_usage.register_db_feature 
     ('Sharding Catalog',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_SYSSHDCAT_STR,
      'Database is a Sharding Catalog.');
  end;


  /**************************
   * SHARD DATABASE
   *************************/
  
  declare
    DBFUS_SHARD_STR CONSTANT VARCHAR2(1000) := 'DBMS_FEATURE_SHARD';
  begin
   dbms_feature_usage.register_db_feature 
    ('Shard Database',
     dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
     NULL,
     dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
     DBFUS_SHARD_STR,
     'Database is a Shard.');
  end;

  /*************************************
   * Real Application Security
   *************************************/
  
  declare
    DBFUS_RAS_STR CONSTANT VARCHAR2(1000) := 'SYS.DBMS_FEATURE_RAS';
    
  begin
    dbms_feature_usage.register_db_feature
     ('Real Application Security',
      dbms_feature_usage.DBU_INST_OBJECT,
      'SYS.XS$OBJ',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_RAS_STR,
      'Oracle Real Application Security is being used');
  end;

  /**********************
   * Privilege Capture  *
   **********************/

  declare
    DBFUS_PRIV_CAPTURE_PROC CONSTANT VARCHAR2(1000) := 
      'SYS.DBMS_FEATURE_PRIV_CAPTURE';

  begin
    dbms_feature_usage.register_db_feature
     ('Privilege Capture',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_PRIV_CAPTURE_PROC,
      'Privilege Capture is being used');
  end;

 /****************************
   * Online Redefintion
   ****************************/

  declare
    DBFUS_ONLINE_REDEF CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_ONLINE_REDEF';

  begin
    dbms_feature_usage.register_db_feature
     ('Online Redefinition',
       dbms_feature_usage.DBU_INST_OBJECT,
      'SYS.REDEF$',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBFUS_ONLINE_REDEF,
      'Online Redefinition is being used');
  end;

  /***************************************************************
   *  In-Memory Aggregation
   ***************************************************************/

  begin
   dbms_feature_usage.register_db_feature
      ('In-Memory Aggregation',
       dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
       NULL,
       dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
       'DBMS_FEATURE_IMA',
       'In-Memory Aggregation is being used.');
  end;


  /******************************
   * In-Memory FastStart
   *****************************/
  begin
    dbms_feature_usage.register_db_feature
     ('In-Memory FastStart',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_IMFS',
      'In-Memory FastStart is being used');
  end;


  /*********************************************
   * TEST features to test the infrastructure 
   *********************************************/

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_1',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 1, 0, NULL from dual',
      'Test sql 1');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_2',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 0, 10, to_clob(''hi, mike'') from dual',
      'Test sql 2');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_3',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 13, NULL, to_clob(''hello, mike'') from dual',
      'Test sql 3');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_4',
      dbms_feature_usage.DBU_INST_OBJECT + 
      dbms_feature_usage.DBU_INST_TEST,
      'sys.tab$',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 11, 11, to_clob(''test sql 4 check tab$'') from dual',
      'Test sql 4');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_5',
      dbms_feature_usage.DBU_INST_OBJECT + 
      dbms_feature_usage.DBU_INST_TEST,
      'sys.foo',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 2, 0, to_clob(''check foo'') from dual',
      'Test sql 5');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_6',
      dbms_feature_usage.DBU_INST_OBJECT + 
      dbms_feature_usage.DBU_INST_TEST,
      'sys.tab$',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select 0, 0, to_clob(''should not see'') from dual',
      'Test sql 6');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_7',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_NULL,
      'junk',
      'Test sql 7');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_8',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select junk from foo',
      'Test sql 8 - Test error case');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_9',
      dbms_feature_usage.DBU_INST_OBJECT + 
      dbms_feature_usage.DBU_INST_TEST,
      'test.test',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select junk from foo',
      'Test sql 9 - Test error case for install');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_SQL_10',
      dbms_feature_usage.DBU_INST_OBJECT + 
      dbms_feature_usage.DBU_INST_TEST,
      'sys.dbu_test_table',
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      'select count(*), count(*), max(letter) from dbu_test_table',
      'Test sql 10 - Test infrastructure');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_PROC_1',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_TEST_PROC_1',
      'Test feature 1');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_PROC_2',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_TEST_PROC_2',
      'Test feature 2');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_PROC_3',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'Junk Procedure',
      'Test feature 3 - Bad procedure name');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_PROC_4',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_TEST_PROC_4',
      'Test feature 4');

  dbms_feature_usage.register_db_feature
     ('_DBFUS_TEST_PROC_5',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED + 
      dbms_feature_usage.DBU_INST_TEST,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_TEST_PROC_5',
      'Test feature 5');

  /*********************************************
   * Transparent Sensitive Data Protection (TSDP) 
   ********************************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Transparent Sensitive Data Protection',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_TSDP',
      'Transparent Sensitive Data Protection (TSDP)');
  end;

  /*********************************************
   * Segment Maintenance Online Compress 
   ********************************************/
  begin
    dbms_feature_usage.register_db_feature
     ('Segment Maintenance Online Compress',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_SEG_MAIN_ONL_COMP',
      'Segment Maintenance Online Compress');
  end;

  /**************************
   * EM Express
   **************************/
  begin
    dbms_feature_usage.register_db_feature
     ('EM Express',
      dbms_feature_usage.DBU_INST_OBJECT, 
      'sys.wri$_emx_files',
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      'DBMS_FEATURE_EMX',
      'EM Database Express has been used');
  end;

  /*********************************************
   * BA Owner 
   ********************************************/
  declare
    DBMS_FEATURE_BA_OWNER_STR CONSTANT VARCHAR2(1000) := 
       'DBMS_FEATURE_BA_OWNER';
  begin
    dbms_feature_usage.register_db_feature
     ('BA Owner',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_PROCEDURE,
      DBMS_FEATURE_BA_OWNER_STR,
      'BA OWNER');
   end;

  /****************************** 
   * INSTANT RESTORE command
   *********************************/
  declare
    DBFUS_INSTANT_RES_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from v$rman_status' ||
        '  where operation like ''RESTORE INSTANT%'')';
  begin
    dbms_feature_usage.register_db_feature
     ('INSTANT RESTORE command',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_INSTANT_RES_STR,
      'RMAN''s INSTANT RESTORE command used by the database.');
  end;

  /****************************** 
   * Container Usage
   *********************************/
  declare
    DBFUS_CONTAINER_STR CONSTANT VARCHAR2(1000) :=
      'select p, NULL, NULL from ' ||
        '(select count(*) p from sys.amgrp$)'; 
  begin
    dbms_feature_usage.register_db_feature
     ('Container Usage',
      dbms_feature_usage.DBU_INST_ALWAYS_INSTALLED,
      NULL,
      dbms_feature_usage.DBU_DETECT_BY_SQL,
      DBFUS_CONTAINER_STR,
      'CONTAINER FILES used by backup appliance.');
  end;

end;
/
show errors; 

Rem ************************************
Rem     High Water Mark Registration
Rem ************************************

create or replace procedure DBMS_FEATURE_REGISTER_ALLHWM
as
begin

  /**************************
   * User Tables
   **************************/

  declare 
    HWM_USER_TABLES_STR CONSTANT VARCHAR2(1000) := 
     'select count(*) from sys.tab$ t, sys.obj$ o ' ||
       'where t.obj# = o.obj# ' ||
         'and bitand(t.property, 1) = 0 ' ||
         'and bitand(o.flags, 128) = 0 ' ||
         'and o.owner# not in (select u.user# from user$ u ' ||
                                'where u.name in (''SYS'', ''SYSTEM''))';

  begin
    dbms_feature_usage.register_high_water_mark
     ('USER_TABLES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_USER_TABLES_STR,
      'Number of User Tables');
  end;

  /**************************
   * Segment Size 
   **************************/

  declare 
    HWM_SEG_SIZE_STR CONSTANT VARCHAR2(1000) := 
      'select max(bytes) from dba_segments';

  begin
    dbms_feature_usage.register_high_water_mark
     ('SEGMENT_SIZE',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_SEG_SIZE_STR,
      'Size of Largest Segment (Bytes)');
  end;

  /**************************
   * Partition Tables
   **************************/

  declare 
    HWM_PART_TABLES_STR CONSTANT VARCHAR2(1000) := 
     'select nvl(max(p.partcnt), 0) from sys.partobj$ p, sys.obj$ o ' ||
       'where p.obj# = o.obj# ' ||
         'and o.type# = 2 ' ||
         'and o.owner# not in (select u.user# from user$ u ' ||
                               'where u.name in (''SYS'', ''SYSTEM'', ''SH''))';

  begin
    dbms_feature_usage.register_high_water_mark
     ('PART_TABLES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_PART_TABLES_STR,
      'Maximum Number of Partitions belonging to an User Table');
  end;

  /**************************
   * Partition Indexes
   **************************/

  declare 
    HWM_PART_INDEXES_STR CONSTANT VARCHAR2(1000) := 
     'select nvl(max(p.partcnt), 0) from sys.partobj$ p, sys.obj$ o ' ||
       'where p.obj# = o.obj# ' ||
         'and o.type# = 1 ' ||
         'and o.owner# not in (select u.user# from user$ u ' ||
                               'where u.name in (''SYS'', ''SYSTEM'', ''SH''))';

  begin
    dbms_feature_usage.register_high_water_mark
     ('PART_INDEXES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_PART_INDEXES_STR,
      'Maximum Number of Partitions belonging to an User Index');
  end;

  /**************************
   * User Indexes
   **************************/

  declare 
    HWM_USER_INDEX_STR CONSTANT VARCHAR2(1000) := 
     'select count(*) from sys.ind$ i, sys.obj$ o ' ||
       'where i.obj# = o.obj# ' ||
         'and bitand(i.flags, 4096) = 0 ' ||
         'and o.owner# not in (select u.user# from user$ u ' ||
                                'where u.name in (''SYS'', ''SYSTEM''))';

  begin
    dbms_feature_usage.register_high_water_mark
     ('USER_INDEXES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_USER_INDEX_STR,
      'Number of User Indexes');
  end;

  /**************************
   * Sessions
   **************************/

  declare 
    HWM_SESSIONS_STR CONSTANT VARCHAR2(1000) := 
      'select sessions_highwater from V$LICENSE';

  begin
    dbms_feature_usage.register_high_water_mark
     ('SESSIONS',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_SESSIONS_STR,
      'Maximum Number of Concurrent Sessions seen in the database');
  end;

  /**************************
   * DB Size
   **************************/

  declare 
    HWM_DB_SIZE_STR CONSTANT VARCHAR2(1000) := 
      'select sum(bytes) from dba_data_files';

  begin
    dbms_feature_usage.register_high_water_mark
     ('DB_SIZE',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_DB_SIZE_STR,
      'Maximum Size of the Database (Bytes)');
  end;

  /**************************
   * Datafiles
   **************************/

  declare 
    HWM_DATAFILES_STR CONSTANT VARCHAR2(1000) := 
      'select count(*) from dba_data_files';

  begin
    dbms_feature_usage.register_high_water_mark
     ('DATAFILES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_DATAFILES_STR,
      'Maximum Number of Datafiles');
  end;

  /**************************
   * Tablespaces
   **************************/

  declare 
    HWM_TABLESPACES_STR CONSTANT VARCHAR2(1000) := 
     'select count(*) from sys.ts$ ts ' ||
       'where ts.online$ != 3 ' ||
         'and bitand(ts.flags, 2048) != 2048';

  begin
    dbms_feature_usage.register_high_water_mark
     ('TABLESPACES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_TABLESPACES_STR,
      'Maximum Number of Tablespaces');
  end;

  /**************************
   * CPU count
   **************************/

  declare 
    HWM_CPU_COUNT_STR CONSTANT VARCHAR2(1000) := 
      'select sum(cpu_count_highwater) from gv$license';

  begin
    dbms_feature_usage.register_high_water_mark
     ('CPU_COUNT',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_CPU_COUNT_STR,
      'Maximum Number of CPUs');
  end;

  /**************************
   * Query Length
   **************************/

  declare 
    HWM_QUERY_LENGTH_STR CONSTANT VARCHAR2(1000) := 
      'select max(maxquerylen) from v$undostat';

  begin
    dbms_feature_usage.register_high_water_mark
     ('QUERY_LENGTH',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_QUERY_LENGTH_STR,
      'Maximum Query Length');
  end;

  /****************************** 
   * National Character Set Usage
   *******************************/

  declare 
    HWM_NCHAR_COLUMNS_STR CONSTANT VARCHAR2(1000) := 
      'select count(*) from col$ c, obj$ o ' ||
      ' where c.charsetform = 2 and c.obj# = o.obj# ' ||
      ' and o.owner# not in ' || 
      ' (select distinct u.user_id from all_users u, ' ||
      ' sys.ku_noexp_view k where (k.OBJ_TYPE=''USER'' and ' ||
      ' k.name=u.username) or (u.username=''SYSTEM'')) ' ;

  begin
    dbms_feature_usage.register_high_water_mark
     ('SQL_NCHAR_COLUMNS',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_NCHAR_COLUMNS_STR,
      'Maximum Number of SQL NCHAR Columns');
  end;
  
  /********************************
   * Instances
   *********************************/
  declare
    HWM_INSTANCES_STR CONSTANT VARCHAR2(1000) := 
      'SELECT count(*) FROM gv$instance';
  begin
    dbms_feature_usage.register_high_water_mark
     ('INSTANCES',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_INSTANCES_STR,
      'Oracle Database instances');
  end;

  /****************************
   * Materialized Views (User)
   ****************************/

  declare
    HWM_USER_MV_STR CONSTANT VARCHAR2(1000) :=
     'select count(*) from dba_mviews ' ||
       'where owner not in (''SYS'',''SYSTEM'', ''SH'')';

  begin
    dbms_feature_usage.register_high_water_mark
     ('USER_MV',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_USER_MV_STR,
      'Maximum Number of Materialized Views (User)');
  end;


  /*******************
   * Active Sessions
   *******************/

  declare
    HWM_ACTIVE_SESSIONS_STR CONSTANT VARCHAR2(1000) :=
     'select max(value) from v$sysmetric_history ' ||
       'where metric_name = ''Average Active Sessions''';

  begin
    dbms_feature_usage.register_high_water_mark
     ('ACTIVE_SESSIONS',
      dbms_feature_usage.DBU_HWM_BY_SQL,
      HWM_ACTIVE_SESSIONS_STR,
      'Maximum Number of Active Sessions seen in the system');
  end;

  /*******************
   * DBMS_SCHEDULER   HWM is number of jobs per day
   *******************/

   declare 
     HWM_DBMS_SCHEDULER_STR CONSTANT VARCHAR2(1000) := 
       'select '||
         'round(max(runs*((max_id-min_id)/2 + 1)/tot),0) '||
       'from '||
         '( select '||
             'trunc(log_date) day, '||
             'max(log_id) max_id, '||
             'min(log_id) min_id, '||
             'count(log_id) tot, '||
             'count(case when operation = ''RUN'' then 1 end) runs '||
           'from '||
             'scheduler$_event_log '||
           'where '||
             'log_date > systimestamp - interval ''8'' day '||
           'group by trunc(log_date) '||
          ')' ;
   begin
     dbms_feature_usage.register_high_water_mark
      ('HWM_DBMS_SCHEDULER',
       dbms_feature_usage.DBU_HWM_BY_SQL,
       HWM_DBMS_SCHEDULER_STR,
       'Number of job runs per day');
   end;

  /*******************
   * Exadata
   *******************/

   declare 
     HWM_EXADATA_STR CONSTANT VARCHAR2(1000) := 
        'select replace(substr(statistics_value, 23), ''</nphysicaldisks_stats>'') from gv$cell_state where statistics_type = ''NPHYSDISKS''';
   begin
     dbms_feature_usage.register_high_water_mark
      ('EXADATA_DISKS',
       dbms_feature_usage.DBU_HWM_BY_SQL,
       HWM_EXADATA_STR,
       'Number of physical disks');
   end;
   
  /************************
   * GSM Global services
   ***********************/
   
   declare 
     HWM_GSM_STR CONSTANT VARCHAR2(1000) := 
        'select count(*) from dba_services ' ||
        'where global_service = ''YES''';
   begin
     dbms_feature_usage.register_high_water_mark
      ('GLOBAL SERVICES',
       dbms_feature_usage.DBU_HWM_BY_SQL,
       HWM_GSM_STR,
       'Number of global services');
   end;

  /************
   * Shards 
   ***********/

   declare
     DBMS_HWM_SHARDS_STR CONSTANT VARCHAR2(1000) := 
       'DBMS_HWM_SHARDS';
   begin
     dbms_feature_usage.register_high_water_mark
      ('SHARDS',
       dbms_feature_usage.DBU_HWM_BY_PROCEDURE,
       DBMS_HWM_SHARDS_STR,
       'Number of deployed shards in catalog');
   end;

  /*******************
   * Primary Shards 
   ******************/

   declare
     DBMS_HWM_PRIM_SHARDS_STR CONSTANT VARCHAR2(1000) := 
       'DBMS_HWM_PRIM_SHARDS';
   begin
     dbms_feature_usage.register_high_water_mark
      ('PRIMARY SHARDS',
       dbms_feature_usage.DBU_HWM_BY_PROCEDURE,
       DBMS_HWM_PRIM_SHARDS_STR,
       'Number of deployed primary shards in catalog');
   end;

  /************************
   * Flex ASM
   ***********************/

   declare
     HWM_FLX_STR CONSTANT VARCHAR2(1000) :=
        'select sys_context(''SYS_CLUSTER_PROPERTIES'',''FLEXASM_STATE_HW'') '||
        'from dual';
   begin
     dbms_feature_usage.register_high_water_mark
      ('Flex ASM',
       dbms_feature_usage.DBU_HWM_BY_SQL,
       HWM_FLX_STR,
       'Number of completed and successful failovers');
   end;

  /**************************
   * Test HWM
   **************************/

  declare 
    HWM_TEST_PROC CONSTANT VARCHAR2(1000) := 
      'DBMS_FEATURE_TEST_PROC_3';

  begin
    dbms_feature_usage.register_high_water_mark
     ('_HWM_TEST_1',
      dbms_feature_usage.DBU_HWM_BY_PROCEDURE +
      dbms_feature_usage.DBU_HWM_TEST,
      HWM_TEST_PROC,
      'Test HWM 1');
  end;

  dbms_feature_usage.register_high_water_mark
     ('_HWM_TEST_2',
      dbms_feature_usage.DBU_HWM_NULL +
      dbms_feature_usage.DBU_HWM_TEST,
      'Junk',
      'Test HWM 2');
  
  dbms_feature_usage.register_high_water_mark
     ('_HWM_TEST_3',
      dbms_feature_usage.DBU_HWM_BY_SQL +
      dbms_feature_usage.DBU_HWM_TEST,
      'select 10 from dual',
      'Test HWM 3');

  dbms_feature_usage.register_high_water_mark  
     ('_HWM_TEST_4',
      dbms_feature_usage.DBU_HWM_BY_SQL +
      dbms_feature_usage.DBU_HWM_TEST,
      'select 1240 from foo',
      'Test HWM 4 - Error case');

end;
/
show errors; 

@?/rdbms/admin/sqlsessend.sql
