We are still in development, so I don't have access to more recent Oracle versions.  But what is happening here is that explain plan is not including access paths from sub-queries in a select list.
I have some very complex sub-queries that seem to be generating sub-optimal plans, but I can't tell what's happening.
Simple example:
SQL*Plus: Release 9.2.0.1.0 - Production on Thu May 5 13:55:08 2005
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
test@TEST> create table test as select * from all_objects;
Table created.
test@TEST> exec dbms_stats.gather_table_stats( user, 'TEST');
PL/SQL procedure successfully completed.
test@TEST> select count(*) from test;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=83 Card=1)
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF 'TEST' (Cost=83 Card=29025)
test@TEST> select (select count(*) from test) from dual;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=4072)
   1    0   TABLE ACCESS (FULL) OF 'DUAL' (Cost=11 Card=4072)
tkprof:
select count(*) 
from
 test
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.31       9.45        812        816          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.31       9.45        812        816          0           1
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 46
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  SORT AGGREGATE
  29025   TABLE ACCESS FULL TEST
select (select count(*) 
from
 test) from dual
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.00       0.00          0          0          0           0
Execute      2      0.01       0.01          0          0          0           0
Fetch        4      0.35       9.41       1624       1638          0           2
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        8      0.36       9.42       1624       1638          0           2
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 46  
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  TABLE ACCESS FULL DUAL 
 
 
I have 9203 as my "oldest" 9ir2 database -- in 9203 the plan is:
select (select count(*)
from
 test) from dual                                                                                                                             
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.06       0.05          0        406          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.06       0.06          0        407          0           1 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 145  (OPS$TKYTE) 
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  SORT AGGREGATE (cr=403 r=0 w=0 time=59500 us)
  29239   TABLE ACCESS FULL OBJ#(33017) (cr=403 r=0 w=0 time=39853 us)
      1  TABLE ACCESS FULL OBJ#(222) (cr=3 r=0 w=0 time=127 us)
Now, that aside, you should be able to rip out the scalar subquery and replace any "push in" correlation variables with bind variables.
Eg:
if you have:
select deptno, (select count(*) from emp where emp.deptno = dept.deptno) cnt
  from dept;
you should be able to run:
select count(*) from emp where emp.deptno = :x
and supply a value or two from the original query to see what you see.
Also, if you didn't know about scalar subquery caching, you could find it appears "magic".  consider:
ops$tkyte@ORA9IR2> create or replace function f( p_str1 in varchar2, p_str2 in varchar2 ) return varchar2
  2  as
  3  begin
  4          dbms_application_info.set_client_info( userenv('client_info')+1 );
  5          return p_str1 || '.' || p_str2;
  6  end;
  7  / 
Function created.
function counts how many times it was called... ops$tkyte@ORA9IR2> drop table t; 
Table dropped. 
ops$tkyte@ORA9IR2> create table t as select * from all_objects; 
Table created. 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0); 
PL/SQL procedure successfully completed. 
ops$tkyte@ORA9IR2> set autotrace traceonly
ops$tkyte@ORA9IR2> select (select f(owner,object_type) from dual) from t; 
27952 rows selected.  
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'DUAL'
   2    0   TABLE ACCESS (FULL) OF 'T'    
Statistics
----------------------------------------------------------
         23  recursive calls
          0  db block gets
       3108  consistent gets
        383  physical reads
          0  redo size
     402996  bytes sent via SQL*Net to client
      20992  bytes received via SQL*Net from client
       1865  SQL*Net roundtrips to/from client
          5  sorts (memory)
          0  sorts (disk)
      27952  rows processed 
ops$tkyte@ORA9IR2> set autotrace off
ops$tkyte@ORA9IR2> select userenv('client_info') from dual; 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
292
scalar subquery was invoked 292 times -- NOT once per row, but 292 times... However: ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0); 
PL/SQL procedure successfully completed. 
ops$tkyte@ORA9IR2> set autotrace traceonly
ops$tkyte@ORA9IR2> select (select f(owner,object_type) from dual)
  2    from (select * from t order by owner, object_type); 
27952 rows selected.  
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'DUAL'
   2    0   VIEW
   3    2     SORT (ORDER BY)
   4    3       TABLE ACCESS (FULL) OF 'T'    
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        798  consistent gets
          0  physical reads
          0  redo size
     367620  bytes sent via SQL*Net to client
      20992  bytes received via SQL*Net from client
       1865  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      27952  rows processed 
ops$tkyte@ORA9IR2> set autotrace off
ops$tkyte@ORA9IR2> select userenv('client_info') from dual; 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
137
ops$tkyte@ORA9IR2> select count(distinct owner||'.'||object_type) from t; 
COUNT(DISTINCTOWNER||'.'||OBJECT_TYPE)
--------------------------------------
                                   137
by presorting the data and then invoking the scalar subquery, we can reduce the number of scalar subquery calls to the number of distinct inputsops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0); 
PL/SQL procedure successfully completed. 
ops$tkyte@ORA9IR2> set autotrace traceonly
ops$tkyte@ORA9IR2> select (select f(owner,object_type) from dual)
  2    from (select * from t order by dbms_random.random);                                                                                                                             
27952 rows selected.                                                                                                                                                                                                                                                          
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'DUAL'
   2    0   VIEW
   3    2     SORT (ORDER BY)
   4    3       TABLE ACCESS (FULL) OF 'T'                                                                                                                                                                                                                                                            
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1731  consistent gets
          0  physical reads
          0  redo size
     645656  bytes sent via SQL*Net to client
      20992  bytes received via SQL*Net from client
       1865  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      27952  rows processed 
ops$tkyte@ORA9IR2> set autotrace off
ops$tkyte@ORA9IR2> select userenv('client_info') from dual;                                                                                                                             
USERENV('CLIENT_INFO')
----------------------------------------------------------------
448 
ops$tkyte@ORA9IR2> edit test 
And that last bit shows why it would appear "magic" -- it depends on the order of the data processed by the query.There is a hash table where they cache the results (see </code>  
http://tinyurl.com/7ztl5  <code>) and if you avoid collisions (by sorting) you get the best "cache hit" but -- you pay the sort price.