<html>
<head>
<style><!--
  body {background-color:#ffffff;}
  .file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
  .pathname {font-family:monospace; float:right;}
  .fileheader {margin-bottom:.5em;}
  .diff {margin:0;}
  .tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
  .tasklist ul {margin-top:0;margin-bottom:0;}
  tr.alt {background-color:#eeeeee}
  #added {background-color:#ddffdd;}
  #addedchars {background-color:#99ff99;font-weight:bolder;}
  tr.alt #added {background-color:#ccf7cc;}
  #removed {background-color:#ffdddd;}
  #removedchars {background-color:#ff9999;font-weight:bolder;}
  tr.alt #removed {background-color:#f7cccc;}
  #info {color:#888888;}
  #context {background-color:#eeeeee;}
  td {padding-left:.3em;padding-right:.3em;}
  tr.head {border-bottom-width:1px;border-bottom-style:solid;}
  tr.head td {padding:0;padding-top:.2em;}
  .task {background-color:#ffff00;}
  .comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
  .error {color:red;}
  hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="4">Commit in <b><tt>trunk/as2api</tt></b><span id="info"> on MAIN</span></td></tr>
<tr><td><tt><a href="#file1"><span id="removed">html_diff_output.rb</span></a></tt></td><td></td><td align="right" id="removed">-282</td><td nowrap="nowrap">242 removed</td></tr>
<tr class="alt"><td><tt><a href="#file2"><span id="removed">html_output.rb</span></a></tt></td><td></td><td align="right" id="removed">-2010</td><td nowrap="nowrap">242 removed</td></tr>
<tr><td><tt>output/html/<a href="#file3"><span id="added">core_pages.rb</span></a></tt></td><td align="right" id="added">+813</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file4"><span id="added">default_css.rb</span></a></tt></td><td align="right" id="added">+149</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file5"><span id="added">default_frameset.rb</span></a></tt></td><td align="right" id="added">+170</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file6"><span id="added">diff.rb</span></a></tt></td><td align="right" id="added">+281</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file7"><span id="added">driver.rb</span></a></tt></td><td align="right" id="added">+115</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file8"><span id="added">html_framework.rb</span></a></tt></td><td align="right" id="added">+436</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file9"><span id="added">index.rb</span></a></tt></td><td align="right" id="added">+143</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file10"><span id="added">sources.rb</span></a></tt></td><td align="right" id="added">+194</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr><td><tt>output/<a href="#file11"><span id="added">utils.rb</span></a></tt></td><td align="right" id="added">+30</td><td></td><td nowrap="nowrap" align="right">added 243</td></tr>
<tr class="alt"><td><tt>ui/<a href="#file12">cli.rb</a></tt></td><td align="right" id="added">+2</td><td align="right" id="removed">-2</td><td nowrap="nowrap" align="center">242 -&gt; 243</td></tr>
<tr><td></td><td align="right" id="added">+2333</td><td align="right" id="removed">-2294</td><td></td></tr>
</table>
<small id="info">9 added + 2 removed + 1 modified, total 12 files</small><br />
<div class="tasklist"><ul>
<li><a href="#task1">TODO: need to resolve interface name, make links</a></li>
<li><a href="#task2">TODO: assumes that params named in docs match formal arguments</a></li>
<li><a href="#task3">TODO: ASCII art is an accessability problem.  Replace with images that</a></li>
<li><a href="#task4">TODO: package description</a></li>
<li><a href="#task5">TODO</a></li>
<li><a href="#task6">TODO</a></li>
<li><a href="#task7">TODO</a></li>
<li><a href="#task8">FIXME: push this code down into XHTMLWriter, and have it switch the</a></li>
<li><a href="#task9">TODO: include packages</a></li>
</ul></div>
<pre class="comment">
html_output.rb got tall enough to require refactoring into smaller pieces.
Moved html_diff_output.rb while I was at it.
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname" id="removed">trunk/as2api</span><br />
<div class="fileheader" id="removed"><big><b>html_diff_output.rb</b></big> <small id="info">removed after 242</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/html_diff_output.rb        2005-09-06 20:50:08 UTC (rev 242)
+++ trunk/as2api/html_diff_output.rb        2005-09-06 21:07:00 UTC (rev 243)
@@ -1,282 +0,0 @@
</small></pre><pre class="diff" id="removed">-
-require 'html_output'
-
-class BasicDiffPage &lt; BasicPage
-
-  def summary_table(rows, caption)
-    summary_table_tr(rows, caption) do |row|
-      html_td do
-        yield row
-      end
-    end
-  end
-
-  def summary_table_tr(rows, caption)
-    unless rows.nil? || rows.empty?
-      html_table("class"=&gt;"summary_list", "summary"=&gt;"") do
-        html_caption(caption)
-        rows.each do |row|
-          html_tr do
-            yield row
-          end
-        end
-      end
-    end
-  end
-
-end
-
-class DiffOverviewPage &lt; BasicDiffPage
-  def initialize(conf, api_changes)
-    super(conf, "change-summary", "changes")
-    @title = "API Change Overview"
-    @api_changes = api_changes
-  end
-
-  def generate_body_content
-    html_h1("API Change Overview")
-
-    unless @api_changes
-      html_p("No changes")
-      return
-    end
-
-    summary_table(@api_changes.added_packages, "Added Packages") do |as_package|
-      name = package_display_name_for(as_package)
-      href = File.join("..", package_link_for(as_package, "package-summary.html"))
-      html_a(name, {"href"=&gt;href})
-    end
-
-    summary_table(@api_changes.modified_packages, "Modified Packages") do |as_package|
-      name = package_display_name_for(as_package)
-      href = package_link_for(as_package, "change-summary.html")
-      html_a(name, {"href", href})
-    end
-
-    summary_table(@api_changes.removed_packages, "Removed Packages") do |as_package|
-      name = package_display_name_for(as_package)
-      pcdata(name)
-    end
-  end
-
-  def navigation
-    html_ul("class"=&gt;"main_nav") do
-      # TODO
-    end
-  end
-end
-
-
-class PackageDiffIndexPage &lt; BasicDiffPage
-  def initialize(conf, package_changes)
-    dir = File.join("changes", package_dir_for(package_changes))
-    super(conf, "change-summary", dir)
-    @title = "Package #{package_display_name_for(package_changes)} API Change Overview"
-    @package_changes = package_changes
-  end
-
-  def generate_body_content
-    html_h1(@title)
-
-    summary_table(@package_changes.added_types, "Added Types") do |as_type|
-      name = as_type.unqualified_name
-      pcdata(name)
-    end
-
-    summary_table(@package_changes.modified_types, "Modified Types") do |as_type|
-      name = as_type.new_type.unqualified_name
-      href = "#{name}.html"
-      html_a(name, {"href", href})
-    end
-
-    summary_table(@package_changes.removed_types, "Removed Types") do |as_type|
-      name = as_type.unqualified_name
-      pcdata(name)
-    end
-  end
-
-  def navigation
-    html_ul("class"=&gt;"main_nav") do
-      # TODO
-    end
-  end
-end
-
-
-class TypeDiffPage &lt; BasicDiffPage
-  def initialize(conf, type_changes)
-    dir = File.join("changes", type_changes.new_type.package_name.gsub(/\./, "/"))
-    super(conf, type_changes.new_type.unqualified_name, dir)
-    @title = "#{type_changes.new_type.unqualified_name} API Change Overview"
-    @type_changes = type_changes
-  end
-
-  def generate_body_content
-    html_h1(@title)
-
-    summary_table(@type_changes.added_fields, "Added Fields") do |as_field|
-      pcdata(as_field.name)
-    end
-
-    summary_table_tr(@type_changes.modified_fields, "Modified Fields") do |field_changes|
-      html_td do
-        pcdata(field_changes.name)
-      end
-      html_td do
-        generate_visibility_change(field_changes)
-        generate_static_change(field_changes)
-        generate_type_change("Field", field_changes)
-        generate_readwrite_change(field_changes)
-      end
-    end
-
-    summary_table(@type_changes.removed_fields, "Removed Fields") do |as_field|
-      pcdata(as_field.name)
-    end
-
-    summary_table(@type_changes.added_methods, "Added Methods") do |as_method|
-      pcdata(as_method.name)
-    end
-
-    summary_table_tr(@type_changes.modified_methods, "Modified Methods") do |method_changes|
-      html_td do
-        pcdata(method_changes.name)
-      end
-      html_td do
-        generate_visibility_change(method_changes)
-        generate_static_change(method_changes)
-        generate_type_change("Return", method_changes)
-        generate_args_change(method_changes)
-      end
-    end
-
-    summary_table(@type_changes.removed_methods, "Removed Methods") do |as_method|
-      pcdata(as_method.name)
-    end
-  end
-
-  def generate_visibility_change(field_changes)
-    if field_changes.visibility_change
-      pcdata("Visibility changed from ")
-      html_code(field_changes.visibility_change.old_vis)
-      pcdata(" to ")
-      html_code(field_changes.visibility_change.new_vis)
-      pcdata(". ")
-    end
-  end
-
-  def generate_static_change(field_changes)
-    if field_changes.static_change
-      if field_changes.static_change.new_flag
-        pcdata("Is now ")
-      else
-        pcdata("Is no longer ")
-      end
-      html_code("static")
-      pcdata(". ")
-    end
-  end
-
-  def generate_type_name(name)
-      if name
-        html_code(name)
-      else
-        pcdata("unspecified")
-      end
-  end
-
-  def generate_type_change(kind, field_changes)
-    if field_changes.type_change
-      pcdata(kind)
-      pcdata(" type changed from ")
-      generate_type_name(field_changes.type_change.old_type_name)
-      pcdata(" to ")
-      generate_type_name(field_changes.type_change.new_type_name)
-      pcdata(". ")
-    end
-  end
-
-  def generate_readwrite_change(field_changes)
-    change = field_changes.readwrite_change
-    if change
-      if change.old_read != change.new_read
-        if change.new_read
-          pcdata("Is now readable")
-        else
-          pcdata("Is no longer readable")
-        end
-      end
-      if change.old_write != change.new_write
-        if change.new_write
-          pcdata("Is now writeable")
-        else
-          pcdata("Is no longer writeable")
-        end
-      end
-    end
-  end
-
-  def generate_args_change(method_changes)
-    changes = method_changes.args_change
-    if changes
-      pcdata("Argument list changed from ")
-      list_args(changes.old_args)
-      pcdata(" to ")
-      list_args(changes.new_args)
-      pcdata(".")
-    end
-  end
-
-  def list_args(args)
-    html_code do
-      pcdata("(")
-      first = true
-      args.each do |arg|
-        if first
-          first = false
-        else
-          pcdata(", ")
-        end
-        pcdata(arg.name)
-        if arg.arg_type
-          pcdata(":")
-          pcdata(arg.arg_type.name)
-        end
-      end
-      pcdata(")")
-    end
-  end
-
-  def navigation
-    html_ul("class"=&gt;"main_nav") do
-      # TODO
-    end
-  end
-end
-
-
-def make_diff_pages(conf, api_changes)
-  list = []
-
-  list &lt;&lt; DiffOverviewPage.new(conf, api_changes)
-
-  if api_changes
-    api_changes.modified_packages.each do |package_changes|
-      list &lt;&lt; PackageDiffIndexPage.new(conf, package_changes)
-
-      package_changes.modified_types.each do |type_changes|
-        list &lt;&lt; TypeDiffPage.new(conf, type_changes)
-      end
-    end
-  end
-
-  list
-end
-
-def generate_diffs(conf, api_changes)
-  list = make_diff_pages(conf, api_changes)
-  create_all_pages(conf, list)
-end
-
-
-# vim:softtabstop=2:shiftwidth=2
</pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname" id="removed">trunk/as2api</span><br />
<div class="fileheader" id="removed"><big><b>html_output.rb</b></big> <small id="info">removed after 242</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/html_output.rb        2005-09-06 20:50:08 UTC (rev 242)
+++ trunk/as2api/html_output.rb        2005-09-06 21:07:00 UTC (rev 243)
@@ -1,2010 +0,0 @@
</small></pre><pre class="diff" id="removed">-
-require 'xmlwriter'
-require 'xhtmlwriter'
-require 'doc_comment'
-require 'rexml/document'
-require 'set'
-
-def stylesheet(output_dir)
-  name = "style.css"
-
-  # avoid overwriting a (possibly modified) existing stylesheet
-  return if FileTest.exist?(File.join(output_dir, name))
-
-  write_file(output_dir, name) do |out|
-    out.print &lt;&lt;-HERE
-h1, h2, h3, h4, caption {
-        font-family: sans-serif;
-}
-
-h2 {
-        background-color: #ccccff;
-        padding-left: .2em;
-        padding-right: .2em;
-        -moz-border-radius: .2em;
-}
-
-h4 {
-        margin: 0;
-}
-
-.extra_info {
-        padding-left: 2em;
-        margin: 0;
-}
-
-.method_details, .field_details {
-        padding-bottom: .5em;
-}
-
-.method_info, .field_info {
-        padding-left: 3em;
-}
-
-p.inherited_docs {
-        margin-bottom: 0;
-        font-weight: bolder;
-        -moz-opacity: 0.5;
-        font-size: smaller;
-}
-p.inherited_docs+p {
-        margin-top: 0;
-}
-
-.alt_row {
-        background-color: #eeeeee;
-}
-
-body {
-        /* make some space for the navigation */
-        padding-top: 2em;
-}
-.main_nav {
-        background-color: #EEEEFF;
-        position: fixed;
-        top: 0;
-        left: 0;
-        display: block;
-        width: 100%;
-        margin: 0;
-        padding: .5em;
-        border-top: .5em solid white;
-}
-.main_nav li {
-        font-family: sans-serif;
-        font-weight: bolder;
-        display: inline;
-}
-.main_nav li * {
-        padding: 4px;
-}
-.nav_current {
-        background-color: #00008B;
-        color: #FFFFFF;
-}
-
-table.summary_list {
-        border-collapse: collapse;
-        width: 100%;
-        margin-bottom: 1em;
-}
-table.summary_list td, table.summary_list caption {
-        border: 2px solid grey;
-        padding: .2em;
-}
-table.summary_list caption {
-        background-color: #CCCCFF;
-        border-bottom: 0;
-        font-size: larger;
-        font-weight: bolder;
-}
-ul.navigation_list {
-        padding-left: 0;
-}
-ul.navigation_list li {
-        margin: 0 0 .4em 0;
-        list-style: none;
-}
-
-table.exceptions td, table.arguments td {
-        vertical-align: text-top;
-        padding: 0 1em .5em 0;
-}
-
-/*
-.unresolved_type_name {
-        background-color: red;
-        color: white;
-}
-*/
-
-.interface_name {
-        font-style: italic;
-}
-
-.footer {
-        text-align: center;
-        font-size: smaller;
-}
-/*
-.read_write_only {
-}
-*/
-.diagram {
-        text-align: center;
-}
-
-
-/* Source highlighting rules */
-
-.lineno {
-  color: gray;
-  background-color:lightgray;
-  border-right: 1px solid gray;
-  margin-right: .5em;
-}
-.comment { color: green; }
-.comment.doc { color: 4466ff; }
-.str_const, .num_const { color: blue; }
-.key { font-weight: bolder; color: purple; }
-    HERE
-  end
-end
-
-
-def ensure_dir(path)
-  path_components = path.split(File::SEPARATOR)
-  base_path = nil
-  if path_components.first == ""
-    path_components.shift
-    base_path = "/"
-  end
-  path_components.each do |part|
-    if base_path.nil?
-      base_path = part
-    else
-      base_path = File.join(base_path, part)
-    end
-    unless FileTest.exist?(base_path)
-      Dir.mkdir(base_path)
-    end
-  end
-end
-
-def write_file(path, name)
-  ensure_dir(path)
-  name = File.join(path, name)
-  File.open(name, "w") do |io|
-    yield io
-  end
-end
-
-def create_page(output_dir, page)
-  dir = File.join(output_dir, page.path_name)
-  write_file(dir, "#{page.base_name}.html") do |io|
-    page.generate(XMLWriter.new(io))
-  end
-end
-
-def document_member?(member)
-  !member.access.private?
-end
-
-
-PROJECT_PAGE = "http://www.badgers-in-foil.co.uk/projects/as2api/"
-
-
-NavLink = Struct.new("NavLink", :href, :content, :title, :is_current)
-
-# superclass for a kind of object able to build a navigation link for
-# BasicPage instances.
-class NavLinkBuilder
-  def initialize(conf, content)
-    @conf, @content = conf, content
-  end
-
-  def build_for_page(page)
-    NavLink.new(href_on(page), @content, title_on(page), is_current?(page))
-  end
-end
-
-class OverviewNavLinkBuilder &lt; NavLinkBuilder
-  def href_on(page); page.base_path("overview-summary.html"); end
-
-  def is_current?(page); page.is_a?(OverviewPage); end
-
-  def title_on(page)
-    if @conf.title
-      "Overview of #{@conf.title}"
-    else
-      "Overview of API"
-    end
-  end
-end
-
-class PackageNavLinkBuilder &lt; NavLinkBuilder
-  def href_on(page)
-    if page.aspackage
-      "package-summary.html"
-    else
-      nil
-    end
-  end
-
-  def is_current?(page); page.is_a?(PackageIndexPage); end
-
-  def title_on(page)
-    if page.aspackage
-      "Overview of package #{package_display_name_for(page.aspackage)}"
-    else
-      nil
-    end
-  end
-end
-
-class TypeNavLinkBuilder &lt; NavLinkBuilder
-  def href_on(page)
-    if page.astype
-      page.astype.unqualified_name+".html"
-    else
-      nil
-    end
-  end
-
-  def is_current?(page); page.is_a?(TypePage); end
-
-  def title_on(page)
-    if page.astype
-      "Detail of #{page.astype.qualified_name} API"
-    else
-      nil
-    end
-  end
-end
-
-class SourceNavLinkBuilder &lt; NavLinkBuilder
-  def href_on(page)
-    if page.astype
-      page.astype.unqualified_name+".as.html"
-    else
-      nil
-    end
-  end
-
-  def is_current?(page); page.is_a?(SourcePage); end
-
-  def title_on(page)
-    if page.astype
-      "Source code of #{page.astype.qualified_name}"
-    else
-      nil
-    end
-  end
-end
-
-class IndexNavLinkBuilder &lt; NavLinkBuilder
-  def href_on(page); page.base_path("index-files/index.html"); end
-
-  def is_current?(page) page.is_a?(IndexPage); end
-
-  def title_on(page); "Alpabetical index of types and members"; end
-end
-
-
-class Page
-  include XHTMLWriter
-
-  def initialize(base_name, path_name=nil)
-    @path_name = path_name
-    @base_name = base_name
-    @encoding = nil
-    @doctype_id = :strict
-    @title = nil
-    @title_extra = nil
-    @io = nil  # to be set during the lifetime of generate() call
-  end
-
-  attr_accessor :path_name, :base_name, :encoding, :doctype_id, :title_extra
-
-  attr_writer :title
-
-  def title
-    if @title_extra
-      if @title
-        "#{@title} - #{@title_extra}"
-      else
-        @title_extra
-      end
-    else
-      @title
-    end
-  end
-
-  def generate(xml_writer)
-    @io = xml_writer
-    if encoding.nil?
-      pi("xml version=\"1.0\"")
-    else
-      pi("xml version=\"1.0\" encoding=\"#{encoding}\"")
-    end
-    case doctype_id
-    # FIXME: push this code down into XHTMLWriter, and have it switch the
-    # allowed elements depending on the value passed at construction
-    when :strict
-      doctype("html", "PUBLIC",
-              "-//W3C//DTD XHTML 1.0 Strict//EN",
-              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")
-    when :transitional
-      doctype("html", "PUBLIC",
-              "-//W3C//DTD XHTML 1.0 Transitionalt//EN",
-              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")
-    when :frameset
-      doctype("html", "PUBLIC",
-              "-//W3C//DTD XHTML 1.0 Frameset//EN",
-              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd")
-    else
-      raise "unhandled doctype #{doctype_id.inspect}"
-    end
-    html_html do
-      generate_head
-      generate_content
-    end
-  end
-
-  def generate_head
-    html_head do
-      html_title(title) unless title.nil?
-      generate_links
-      html_meta("name"=&gt;"generator", "content"=&gt;PROJECT_PAGE)
-      unless encoding.nil?
-        html_meta("http-equiv"=&gt;"Content-Type",
-                  "content"=&gt;"text/html; charset=#{encoding}")
-      end
-      extra_metadata.each do |key, val|
-        html_meta("name"=&gt;key, "content"=&gt;val)
-      end
-    end
-  end
-
-  def extra_metadata
-    {}
-  end
-
-  def generate_links
-    html_link("rel"=&gt;"stylesheet",
-             "type"=&gt;"text/css",
-             "href"=&gt;base_path("style.css"))
-    link_top do |title, href|
-      html_link("rel"=&gt;"top", "title"=&gt;title, "href"=&gt;href)
-    end
-    link_up do |title, href|
-      html_link("rel"=&gt;"up", "title"=&gt;title, "href"=&gt;href)
-    end
-    link_prev do |title, href|
-      html_link("rel"=&gt;"prev", "title"=&gt;title, "href"=&gt;href)
-    end
-    link_next do |title, href|
-      html_link("rel"=&gt;"next", "title"=&gt;title, "href"=&gt;href)
-    end
-  end
-
-  def link_top; end
-  def link_up; end
-  def link_prev; end
-  def link_next; end
-
-  def link_for_type(type)
-    base_path(type.qualified_name.gsub(/\./, "/")+".html")
-  end
-
-  def link_type(type, qualified=false, attrs={})
-    desc = type_description_for(type)
-    attrs["title"] = desc unless desc.nil?
-    if type.instance_of?(ASInterface)
-      attrs["class"] = "interface_name"
-    elsif type.instance_of?(ASClass)
-      attrs["class"] = "class_name"
-    elsif type == AS_VOID
-      attrs["class"] = "void_name"
-    end
-    if qualified
-      content = type.qualified_name
-    else
-      content = type.unqualified_name
-    end
-    if type.document?
-      attrs["href"] = link_for_type(type)
-      html_a(content, attrs)
-    else
-      html_span(content, attrs)
-    end
-  end
-
-  def link_type_proxy(type_proxy, qualified=false)
-    if type_proxy.resolved?
-      link_type(type_proxy.resolved_type, qualified)
-    else
-      html_span(type_proxy.local_name, {"class"=&gt;"unresolved_type_name"})
-    end
-  end
-
-  def signature_for_method(method)
-    sig = ""
-    if method.access.is_static
-      sig &lt;&lt; "static "
-    end
-    unless method.access.visibility.nil?
-      sig &lt;&lt; "#{method.access.visibility.body} "
-    end
-    sig &lt;&lt; "function "
-    sig &lt;&lt; method.name
-    sig &lt;&lt; "("
-    method.arguments.each_with_index do |arg, index|
-      sig &lt;&lt; ", " if index &gt; 0
-      sig &lt;&lt; arg.name
-      if arg.arg_type
-        sig &lt;&lt; ":"
-        sig &lt;&lt; arg.arg_type.name
-      end
-    end
-    sig &lt;&lt; ")"
-    if method.return_type
-      sig &lt;&lt; ":"
-      sig &lt;&lt; method.return_type.name
-    end
-    sig
-  end
-
-  def link_for_method(method)
-    if @type == method.containing_type
-      "#method_#{method.name}"
-    else
-      "#{link_for_type(method.containing_type)}#method_#{method.name}"
-    end
-  end
-
-  def link_method(method)
-    sig = signature_for_method(method)
-    if method.containing_type.document?
-      html_a("href"=&gt;link_for_method(method), "title"=&gt;sig) do
-        pcdata(method.name)
-        pcdata("()")
-      end
-    else
-      html_span("title"=&gt;sig) do
-        pcdata(method.name)
-        pcdata("()")
-      end
-    end
-  end
-
-  def signature_for_field(field)
-    sig = ""
-    if field.access.is_static
-      sig &lt;&lt; "static "
-    end
-    unless field.access.visibility.nil?
-      sig &lt;&lt; "#{field.access.visibility.body} "
-    end
-    sig &lt;&lt; field.name
-    if field.field_type
-      sig &lt;&lt; ":"
-      sig &lt;&lt; field.field_type.name
-    end
-    sig
-  end
-
-  def link_for_field(field)
-    if @type == field.containing_type
-      "##{field.name}"
-    else
-      "#{link_for_type(field.containing_type)}##{field.name}"
-    end
-  end
-
-  def link_field(field)
-    sig = signature_for_field(field)
-    if field.containing_type.document?
-      html_a("href"=&gt;link_for_field(field), "title"=&gt;sig) do
-        pcdata(field.name)
-      end
-    else
-      html_span("title"=&gt;sig) do
-        pcdata(field.name)
-      end
-    end
-  end
-
-  def base_path(file)
-    return file if @path_name.nil?
-    ((".."+File::SEPARATOR) * @path_name.split(File::SEPARATOR).length) + file
-  end
-end
-
-class BasicPage &lt; Page
-  def initialize(conf, base_name, path_name=nil)
-    super(base_name, path_name)
-    @conf = conf
-    @type = nil
-    @package = nil
-    @navigation = nil
-  end
-
-  attr_accessor :navigation
-
-  def astype; @type; end
-
-  def aspackage; @package; end
-
-  def generate_content
-    html_body do
-      generate_body_content
-      generate_navigation
-      generate_footer
-    end
-  end
-
-  def generate_footer
-    html_div("class"=&gt;"footer") do
-      html_a("as2api", {"href"=&gt;PROJECT_PAGE, "title"=&gt;"ActionScript 2 API Documentation Generator"})
-    end
-  end
-
-  def output_doccomment_blocktag(block)
-    block.each_inline do |inline|
-      output_doccomment_inlinetag(inline)
-    end
-  end
-
-  def output_doccomment_inlinetag(inline)
-    if inline.is_a?(String)
-      passthrough(inline)  # allow HTML through unabused (though I wish it were
-                           # easy to require it be valid XHTML)
-    elsif inline.is_a?(LinkTag)
-      if inline.target &amp;&amp; inline.member
-        if inline.target.resolved?
-          href = link_for_type(inline.target.resolved_type)
-          if inline.member =~ /\(/
-            target = "##{$`}"
-          else
-            target = "##{inline.member}"
-          end
-          href &lt;&lt; target
-          html_a("href"=&gt;href) do
-            pcdata("#{inline.target.name}.#{inline.member}")
-          end
-        else
-          pcdata("#{inline.target.name}##{inline.member}")
-        end
-      elsif inline.target
-        link_type_proxy(inline.target)
-      else
-        if inline.member =~ /\(/
-          target = "##{$`}"
-        else
-          target = "##{inline.member}"
-        end
-        html_a("href"=&gt;target) do
-          pcdata(inline.member)
-        end
-      end
-    elsif inline.is_a?(CodeTag)
-      input = StringIO.new(inline.text)
-      input.lineno = inline.lineno
-      highlight = CodeHighlighter.new
-      highlight.number_lines = false
-      if inline.text =~ /[\n\r]/
-        html_pre do
-          highlight.highlight(input, self)
-        end
-      else
-        html_code do
-          highlight.highlight(input, self)
-        end
-      end
-    else
-      html_em(inline.inspect)
-    end
-  end
-
-  def output_doccomment_initial_sentence(block)
-    block.each_inline do |inline|
-      if inline.is_a?(String)
-        if inline =~ /(?:[\.:]\s+[A-Z])|(?:[\.:]\s+\Z)|(?:&lt;\/?[Pp]\b)/
-          output_doccomment_inlinetag($`)
-          return
-        else
-          output_doccomment_inlinetag(inline)
-        end
-      else
-        output_doccomment_inlinetag(inline)
-      end
-    end
-  end
-
-  def generate_navigation
-    html_ul("class"=&gt;"main_nav") do
-      @navigation.each do |nav|
-        link = nav.build_for_page(self)
-        html_li do
-          if link.is_current
-            html_span(link.content, {"class"=&gt;"nav_current"})
-          else
-            if link.href
-              attrs = {"href"=&gt;link.href}
-              attrs["title"] = link.title if link.title
-              html_a(link.content, attrs)
-            else
-              if link.title
-                html_span(link.content, {"title"=&gt;link.title})
-              else
-                html_span(link.content)
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-end
-
-class TypePage &lt; BasicPage
-
-  def initialize(conf, type)
-    dir = type.package_name.gsub(/\./, "/")
-    super(conf, type.unqualified_name, dir)
-    @type = type
-    @package = type.package
-    if @type.source_utf8
-      @encoding = "utf-8"
-    end
-    @title = type.qualified_name
-    @prev_type = nil
-    @next_type = nil
-  end
-
-  attr_accessor :prev_type, :next_type
-
-  def generate_body_content
-      html_h1(type_description_for(@type))
-
-      type_hierachy(@type)
-
-      if @type.implements_interfaces?
-        html_div("class"=&gt;"interfaces") do
-          html_h2("Implemented Interfaces")
-          @type.each_interface do |interface|
-            # TODO: need to resolve interface name, make links
-            html_code do
-              link_type_proxy(interface)
-            end
-            pcdata(" ")
-          end
-        end
-      end
-      html_div("class"=&gt;"type_description") do
-        if @type.comment
-          comment_data = @type.comment
-
-          html_h2("Description")
-          html_p do
-            output_doccomment_blocktag(comment_data[0])
-          end
-          if comment_data.has_seealso?
-            html_h4("See Also")
-            html_ul("class"=&gt;"extra_info") do
-              comment_data.each_seealso do |see_comment|
-                html_li do
-                  output_doccomment_blocktag(see_comment)
-                end
-              end
-            end
-          end
-        end
-      end
-      
-      field_index_list(@type) if has_or_inherits_documentable_fields?(@type)
-      method_index_list(@type) if has_or_inherits_documentable_methods?(@type)
-      constructor_detail(@type) if @type.constructor? &amp;&amp; document_member?(@type.constructor)
-      field_detail_list(@type) if has_documentable_fields?(@type)
-      method_detail_list(@type) if has_documentable_methods?(@type)
-  end
-
-  def has_or_inherits_documentable_fields?(astype)
-    return true if has_documentable_fields?(astype)
-    astype.each_ancestor do |ancestor|
-      return true if has_documentable_fields?(ancestor)
-    end
-
-    false
-  end
-
-  def has_or_inherits_documentable_methods?(astype)
-    return true if has_documentable_methods?(astype)
-    astype.each_ancestor do |ancestor|
-      return true if has_documentable_methods?(ancestor)
-    end
-
-    false
-  end
-
-  def link_top
-    yield "Overview", base_path("overview-summary.html")
-  end
-
-  def link_up
-    yield package_description_for(@type.package), "package-summary.html"
-  end
-
-  def link_prev
-    if @prev_type
-      kind = @prev_type.is_a?(ASInterface) ? "Interface" : "Class"
-      yield "#{kind} #{@prev_type.qualified_name}", link_for_type(@prev_type)
-    end
-  end
-
-  def link_next
-    if @next_type
-      kind = @next_type.is_a?(ASInterface) ? "Interface" : "Class"
-      yield "#{kind} #{@next_type.qualified_name}", link_for_type(@next_type)
-    end
-  end
-
-  def field_index_list(type)
-    html_div("class"=&gt;"field_index") do
-      html_h2("Field Index")
-      list_fields(type)
-      if type.has_ancestor?
-        type.each_ancestor do |type|
-          if has_documentable_fields?(type)
-            html_h4 do
-              pcdata("Inherited from ")
-              link_type(type)
-            end
-            html_p("class"=&gt;"extra_info") do
-              list_fields(type, link_for_type(type))
-            end
-          end
-        end
-      end
-    end
-  end
-
-  def has_documentable_fields?(astype)
-    return false if astype.is_a?(ASInterface)
-    astype.each_field do |asfield|
-      return true if document_member?(asfield)
-    end
-
-    false
-  end
-
-  def list_fields(type, href_prefix="")
-    fields = type.fields.sort
-    index = 0
-    fields.each do |field|
-      next unless document_member?(field)
-      pcdata(", ") if index &gt; 0
-      link_field(field)
-      index += 1
-    end
-  end
-
-  def method_index_list(type)
-    html_div("class"=&gt;"method_index") do
-      html_h2("Method Index")
-      if type.constructor? &amp;&amp; document_member?(type.constructor)
-        html_p do
-          html_code do
-            pcdata("new ")
-            link_method(type.constructor)
-          end
-        end
-      end
-      known_method_names = []
-      list_methods(type, known_method_names)
-      if type.has_ancestor?
-        type.each_ancestor do |type|
-          if has_documentable_methods?(type, known_method_names)
-            html_h4 do
-              pcdata("Inherited from ")
-              link_type(type)
-            end
-            html_p("class"=&gt;"extra_info") do
-              list_methods(type, known_method_names, link_for_type(type))
-            end
-          end
-        end
-      end
-    end
-  end
-
-  def has_documentable_methods?(astype, ignore_method_names=[])
-    astype.methods.each do |asmethod|
-      return true if document_member?(asmethod) &amp;&amp; !ignore_method_names.include?(asmethod.name)
-    end
-
-    false
-  end
-
-  def list_methods(type, known_method_names, href_prefix="")
-    methods = type.methods.select do |method|
-      !known_method_names.include?(method.name) &amp;&amp; document_member?(method)
-    end
-    methods.sort!
-    methods.each_with_index do |method, index|
-      known_method_names &lt;&lt; method.name
-      pcdata(", ") if index &gt; 0
-      link_method(method)
-    end
-  end
-
-  def constructor_detail(type)
-    html_div("class"=&gt;"constructor_detail_list") do
-      html_h2("Constructor Detail")
-      document_method(type.constructor)
-    end
-  end
-
-  def field_detail_list(type)
-    html_div("class"=&gt;"field_detail_list") do
-      html_h2("Field Detail")
-      type.each_field do |field|
-        document_field(field) if document_member?(field)
-      end
-    end
-  end
-
-  def document_field(field)
-    html_a("", "name"=&gt;"#{field.name}")
-    html_h3(field.name)
-    html_div("class"=&gt;"field_details") do
-      field_synopsis(field)
-      if field.comment
-        html_div("class"=&gt;"field_info") do
-          comment_data = field.comment
-          output_doccomment_blocktag(comment_data[0])
-          if comment_data.has_field_additional_info?
-            if comment_data.has_seealso?
-              document_seealso(comment_data)
-            end
-          end
-        end
-      end
-    end
-  end
-
-  def method_detail_list(type)
-    html_div("class"=&gt;"method_detail_list") do
-      html_h2("Method Detail")
-      count = 0
-      type.each_method do |method|
-        next unless document_member?(method)
-        document_method(method, count%2==0)
-        count += 1
-      end
-    end
-  end
-
-  def document_method(method, alt_row=false)
-    css_class = "method_details"
-    css_class &lt;&lt; " alt_row" if alt_row
-    html_div("class"=&gt;css_class) do
-      html_a("", "name"=&gt;"#{method.name}")
-      html_h3(method.name)
-      method_synopsis(method)
-      html_div("class"=&gt;"method_info") do
-        if method.comment
-          comment_data = method.comment
-          html_p do
-            output_doccomment_blocktag(comment_data[0])
-          end
-          if method_additional_info?(method, comment_data)
-            # TODO: assumes that params named in docs match formal arguments
-            #       should really filter out those that don't match before this
-            #       test
-            if comment_data.has_params?
-              document_parameters(method.arguments, comment_data)
-            end
-            if comment_data.has_return?
-              document_return(comment_data)
-            end
-            if comment_data.has_exceptions?
-              document_exceptions(comment_data)
-            end
-            method_info_from_supertype(method)
-            if comment_data.has_seealso?
-              document_seealso(comment_data)
-            end
-          end
-        else
-          documented_method = method.inherited_comment
-          unless documented_method.nil?
-            comment_data = documented_method.comment
-            html_p("class"=&gt;"inherited_docs") do
-              pcdata("Description copied from ")
-              link_type(documented_method.containing_type)
-            end
-            html_p do
-              output_doccomment_blocktag(comment_data[0])
-            end
-          end
-          method_info_from_supertype(method)
-        end
-      end
-    end
-  end
-
-  def method_info_from_supertype(method)
-    if method.containing_type.is_a?(ASClass)
-      spec_method = method.specified_by
-      unless spec_method.nil?
-        document_specified_by(spec_method)
-      end
-    end
-    overridden_method = method.overrides
-    unless overridden_method.nil?
-      document_overridden(overridden_method)
-    end
-  end
-
-  def type_hierachy(type)
-    # TODO: ASCII art is an accessability problem.  Replace with images that
-    #       have alt-text, or use CSS to generate content, e.g.
-    #          &lt;span class="inherit_relation" title="inherited by"&gt;&lt;/span&gt;
-    html_pre("class"=&gt;"type_hierachy") do
-      count = 0
-      unless type.extends.nil?
-        count = type_hierachy_recursive(type.extends)
-      end
-      if count &gt; 0
-        pcdata("   " * count)
-        pcdata("+--")
-      end
-      html_strong(type.qualified_name)
-    end
-  end
-
-  def type_hierachy_recursive(type_proxy)
-    count = 0
-    if type_proxy.resolved?
-      type = type_proxy.resolved_type
-      unless type.extends.nil?
-        count = type_hierachy_recursive(type.extends)
-      end
-    else
-      pcdata("????\n")
-      count = 1
-    end
-    if count &gt; 0
-      pcdata("   " * count)
-      pcdata("+--")
-    end
-    link_type_proxy(type_proxy, true)
-    pcdata("\n")
-    return count + 1
-  end
-
-  def document_parameters(arguments, comment_data)
-    html_h4("Parameters")
-    html_table("class"=&gt;"arguments extra_info", "summary"=&gt;"") do
-      arguments.each do |arg|
-        desc = comment_data.find_param(arg.name)
-        if desc
-          html_tr do
-            html_td do
-              html_code(arg.name)
-            end
</pre></pre>
<strong class="error">[truncated at 1000 lines; 1013 more skipped]</strong>
</div>
<hr /><a name="file3" /><div class="file">
<span class="pathname" id="added">trunk/as2api/output/html</span><br />
<div class="fileheader" id="added"><big><b>core_pages.rb</b></big> <small id="info">added at 243</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/output/html/core_pages.rb        2005-09-06 20:50:08 UTC (rev 242)
+++ trunk/as2api/output/html/core_pages.rb        2005-09-06 21:07:00 UTC (rev 243)
@@ -0,0 +1,813 @@
</small></pre><pre class="diff" id="added">+
+require 'output/html/html_framework'
+require 'output/utils'
+require 'rexml/document'
+
+class OverviewNavLinkBuilder &lt; NavLinkBuilder
+  def href_on(page); page.base_path("overview-summary.html"); end
+
+  def is_current?(page); page.is_a?(OverviewPage); end
+
+  def title_on(page)
+    if @conf.title
+      "Overview of #{@conf.title}"
+    else
+      "Overview of API"
+    end
+  end
+end
+
+class PackageNavLinkBuilder &lt; NavLinkBuilder
+  def href_on(page)
+    if page.aspackage
+      "package-summary.html"
+    else
+      nil
+    end
+  end
+
+  def is_current?(page); page.is_a?(PackageIndexPage); end
+
+  def title_on(page)
+    if page.aspackage
+      "Overview of package #{page.package_display_name_for(page.aspackage)}"
+    else
+      nil
+    end
+  end
+end
+
+
+class TypeNavLinkBuilder &lt; NavLinkBuilder
+  def href_on(page)
+    if page.astype
+      page.astype.unqualified_name+".html"
+    else
+      nil
+    end
+  end
+
+  def is_current?(page); page.is_a?(TypePage); end
+
+  def title_on(page)
+    if page.astype
+      "Detail of #{page.astype.qualified_name} API"
+    else
+      nil
+    end
+  end
+end
+
+
+class TypePage &lt; BasicPage
+
+  def initialize(conf, type)
+    dir = type.package_name.gsub(/\./, "/")
+    super(conf, type.unqualified_name, dir)
+    @type = type
+    @package = type.package
+    if @type.source_utf8
+      @encoding = "utf-8"
+    end
+    @title = type.qualified_name
+    @prev_type = nil
+    @next_type = nil
+  end
+
+  attr_accessor :prev_type, :next_type
+
+  def generate_body_content
+      html_h1(type_description_for(@type))
+
+      type_hierachy(@type)
+
+      if @type.implements_interfaces?
+        html_div("class"=&gt;"interfaces") do
+          html_h2("Implemented Interfaces")
+          @type.each_interface do |interface|
<a name="task1" />+            # <span class="task">TODO</span>: need to resolve interface name, make links
+            html_code do
+              link_type_proxy(interface)
+            end
+            pcdata(" ")
+          end
+        end
+      end
+      html_div("class"=&gt;"type_description") do
+        if @type.comment
+          comment_data = @type.comment
+
+          html_h2("Description")
+          html_p do
+            output_doccomment_blocktag(comment_data[0])
+          end
+          if comment_data.has_seealso?
+            html_h4("See Also")
+            html_ul("class"=&gt;"extra_info") do
+              comment_data.each_seealso do |see_comment|
+                html_li do
+                  output_doccomment_blocktag(see_comment)
+                end
+              end
+            end
+          end
+        end
+      end
+      
+      field_index_list(@type) if has_or_inherits_documentable_fields?(@type)
+      method_index_list(@type) if has_or_inherits_documentable_methods?(@type)
+      constructor_detail(@type) if @type.constructor? &amp;&amp; document_member?(@type.constructor)
+      field_detail_list(@type) if has_documentable_fields?(@type)
+      method_detail_list(@type) if has_documentable_methods?(@type)
+  end
+
+  def has_or_inherits_documentable_fields?(astype)
+    return true if has_documentable_fields?(astype)
+    astype.each_ancestor do |ancestor|
+      return true if has_documentable_fields?(ancestor)
+    end
+
+    false
+  end
+
+  def has_or_inherits_documentable_methods?(astype)
+    return true if has_documentable_methods?(astype)
+    astype.each_ancestor do |ancestor|
+      return true if has_documentable_methods?(ancestor)
+    end
+
+    false
+  end
+
+  def link_top
+    yield "Overview", base_path("overview-summary.html")
+  end
+
+  def link_up
+    yield package_description_for(@type.package), "package-summary.html"
+  end
+
+  def link_prev
+    if @prev_type
+      kind = @prev_type.is_a?(ASInterface) ? "Interface" : "Class"
+      yield "#{kind} #{@prev_type.qualified_name}", link_for_type(@prev_type)
+    end
+  end
+
+  def link_next
+    if @next_type
+      kind = @next_type.is_a?(ASInterface) ? "Interface" : "Class"
+      yield "#{kind} #{@next_type.qualified_name}", link_for_type(@next_type)
+    end
+  end
+
+  def field_index_list(type)
+    html_div("class"=&gt;"field_index") do
+      html_h2("Field Index")
+      list_fields(type)
+      if type.has_ancestor?
+        type.each_ancestor do |type|
+          if has_documentable_fields?(type)
+            html_h4 do
+              pcdata("Inherited from ")
+              link_type(type)
+            end
+            html_p("class"=&gt;"extra_info") do
+              list_fields(type, link_for_type(type))
+            end
+          end
+        end
+      end
+    end
+  end
+
+  def has_documentable_fields?(astype)
+    return false if astype.is_a?(ASInterface)
+    astype.each_field do |asfield|
+      return true if document_member?(asfield)
+    end
+
+    false
+  end
+
+  def list_fields(type, href_prefix="")
+    fields = type.fields.sort
+    index = 0
+    fields.each do |field|
+      next unless document_member?(field)
+      pcdata(", ") if index &gt; 0
+      link_field(field)
+      index += 1
+    end
+  end
+
+  def method_index_list(type)
+    html_div("class"=&gt;"method_index") do
+      html_h2("Method Index")
+      if type.constructor? &amp;&amp; document_member?(type.constructor)
+        html_p do
+          html_code do
+            pcdata("new ")
+            link_method(type.constructor)
+          end
+        end
+      end
+      known_method_names = []
+      list_methods(type, known_method_names)
+      if type.has_ancestor?
+        type.each_ancestor do |type|
+          if has_documentable_methods?(type, known_method_names)
+            html_h4 do
+              pcdata("Inherited from ")
+              link_type(type)
+            end
+            html_p("class"=&gt;"extra_info") do
+              list_methods(type, known_method_names, link_for_type(type))
+            end
+          end
+        end
+      end
+    end
+  end
+
+  def has_documentable_methods?(astype, ignore_method_names=[])
+    astype.methods.each do |asmethod|
+      return true if document_member?(asmethod) &amp;&amp; !ignore_method_names.include?(asmethod.name)
+    end
+
+    false
+  end
+
+  def list_methods(type, known_method_names, href_prefix="")
+    methods = type.methods.select do |method|
+      !known_method_names.include?(method.name) &amp;&amp; document_member?(method)
+    end
+    methods.sort!
+    methods.each_with_index do |method, index|
+      known_method_names &lt;&lt; method.name
+      pcdata(", ") if index &gt; 0
+      link_method(method)
+    end
+  end
+
+  def constructor_detail(type)
+    html_div("class"=&gt;"constructor_detail_list") do
+      html_h2("Constructor Detail")
+      document_method(type.constructor)
+    end
+  end
+
+  def field_detail_list(type)
+    html_div("class"=&gt;"field_detail_list") do
+      html_h2("Field Detail")
+      type.each_field do |field|
+        document_field(field) if document_member?(field)
+      end
+    end
+  end
+
+  def document_field(field)
+    html_a("", "name"=&gt;"#{field.name}")
+    html_h3(field.name)
+    html_div("class"=&gt;"field_details") do
+      field_synopsis(field)
+      if field.comment
+        html_div("class"=&gt;"field_info") do
+          comment_data = field.comment
+          output_doccomment_blocktag(comment_data[0])
+          if comment_data.has_field_additional_info?
+            if comment_data.has_seealso?
+              document_seealso(comment_data)
+            end
+          end
+        end
+      end
+    end
+  end
+
+  def method_detail_list(type)
+    html_div("class"=&gt;"method_detail_list") do
+      html_h2("Method Detail")
+      count = 0
+      type.each_method do |method|
+        next unless document_member?(method)
+        document_method(method, count%2==0)
+        count += 1
+      end
+    end
+  end
+
+  def document_method(method, alt_row=false)
+    css_class = "method_details"
+    css_class &lt;&lt; " alt_row" if alt_row
+    html_div("class"=&gt;css_class) do
+      html_a("", "name"=&gt;"#{method.name}")
+      html_h3(method.name)
+      method_synopsis(method)
+      html_div("class"=&gt;"method_info") do
+        if method.comment
+          comment_data = method.comment
+          html_p do
+            output_doccomment_blocktag(comment_data[0])
+          end
+          if method_additional_info?(method, comment_data)
<a name="task2" />+            # <span class="task">TODO</span>: assumes that params named in docs match formal arguments
+            #       should really filter out those that don't match before this
+            #       test
+            if comment_data.has_params?
+              document_parameters(method.arguments, comment_data)
+            end
+            if comment_data.has_return?
+              document_return(comment_data)
+            end
+            if comment_data.has_exceptions?
+              document_exceptions(comment_data)
+            end
+            method_info_from_supertype(method)
+            if comment_data.has_seealso?
+              document_seealso(comment_data)
+            end
+          end
+        else
+          documented_method = method.inherited_comment
+          unless documented_method.nil?
+            comment_data = documented_method.comment
+            html_p("class"=&gt;"inherited_docs") do
+              pcdata("Description copied from ")
+              link_type(documented_method.containing_type)
+            end
+            html_p do
+              output_doccomment_blocktag(comment_data[0])
+            end
+          end
+          method_info_from_supertype(method)
+        end
+      end
+    end
+  end
+
+  def method_info_from_supertype(method)
+    if method.containing_type.is_a?(ASClass)
+      spec_method = method.specified_by
+      unless spec_method.nil?
+        document_specified_by(spec_method)
+      end
+    end
+    overridden_method = method.overrides
+    unless overridden_method.nil?
+      document_overridden(overridden_method)
+    end
+  end
+
+  def type_hierachy(type)
<a name="task3" />+    # <span class="task">TODO</span>: ASCII art is an accessability problem.  Replace with images that
+    #       have alt-text, or use CSS to generate content, e.g.
+    #          &lt;span class="inherit_relation" title="inherited by"&gt;&lt;/span&gt;
+    html_pre("class"=&gt;"type_hierachy") do
+      count = 0
+      unless type.extends.nil?
+        count = type_hierachy_recursive(type.extends)
+      end
+      if count &gt; 0
+        pcdata("   " * count)
+        pcdata("+--")
+      end
+      html_strong(type.qualified_name)
+    end
+  end
+
+  def type_hierachy_recursive(type_proxy)
+    count = 0
+    if type_proxy.resolved?
+      type = type_proxy.resolved_type
+      unless type.extends.nil?
+        count = type_hierachy_recursive(type.extends)
+      end
+    else
+      pcdata("????\n")
+      count = 1
+    end
+    if count &gt; 0
+      pcdata("   " * count)
+      pcdata("+--")
+    end
+    link_type_proxy(type_proxy, true)
+    pcdata("\n")
+    return count + 1
+  end
+
+  def document_parameters(arguments, comment_data)
+    html_h4("Parameters")
+    html_table("class"=&gt;"arguments extra_info", "summary"=&gt;"") do
+      arguments.each do |arg|
+        desc = comment_data.find_param(arg.name)
+        if desc
+          html_tr do
+            html_td do
+              html_code(arg.name)
+            end
+            html_td do
+              output_doccomment_blocktag(desc)
+            end
+          end
+        end
+      end
+      # arg with magic name '..' or '...'?
+      vararg = comment_data.find_param(/\.{2,3}/)
+      if vararg
+        html_tr do
+          html_td do
+            html_code("...", {"title", "Variable length argument list"})
+          end
+          html_td do
+            output_doccomment_blocktag(vararg)
+          end
+        end
+      end
+    end
+  end
+
+  def document_return(comment_data)
+    html_h4("Return")
+    return_comment = comment_data.find_return
+    html_p("class"=&gt;"extra_info") do
+      output_doccomment_blocktag(return_comment)
+    end
+  end
+
+  def document_exceptions(comment_data)
+    html_h4("Throws")
+    html_table("class"=&gt;"exceptions extra_info", "summary"=&gt;"") do
+      comment_data.each_exception do |exception_comment|
+        html_tr do
+          html_td do
+            link_type_proxy(exception_comment.exception_type)
+          end
+          html_td do
+            output_doccomment_blocktag(exception_comment)
+          end
+        end
+      end
+    end
+  end
+
+  def document_seealso(comment_data)
+    html_h4("See Also")
+    html_ul("class"=&gt;"extra_info") do
+      comment_data.each_seealso do |see_comment|
+        html_li do
+          output_doccomment_blocktag(see_comment)
+        end
+      end
+    end
+  end
+
+  def document_specified_by(method)
+    html_h4("Specified By")
+    html_p("class"=&gt;"extra_info") do
+      link_method(method)
+      pcdata(" in ")
+      link_type(method.containing_type, true)
+    end
+  end
+
+  def document_overridden(method)
+    html_h4("Overrides")
+    html_p("class"=&gt;"extra_info") do
+      link_method(method)
+      pcdata(" in ")
+      link_type(method.containing_type, true)
+    end
+  end
+
+  def method_additional_info?(method, comment_data)
+    if method.containing_type.is_a?(ASClass)
+      spec_method = method.specified_by
+    else
+      spec_method = nil
+    end
+    return comment_data.has_method_additional_info? || !spec_method.nil?
+  end
+
+  def method_synopsis(method)
+    html_code("class"=&gt;"method_synopsis") do
+      if method.access.is_static
+        pcdata("static ")
+      end
+      unless method.access.visibility.nil?
+        pcdata("#{method.access.visibility.body} ")
+      end
+      pcdata("function ")
+      html_strong("class"=&gt;"method_name") do
+        pcdata(method.name)
+      end
+      pcdata("(")
+      method.arguments.each_with_index do |arg, index|
+        pcdata(", ") if index &gt; 0
+        pcdata(arg.name)
+        if arg.arg_type
+          pcdata(":")
+          link_type_proxy(arg.arg_type)
+        end
+      end
+      pcdata(")")
+      if method.return_type
+        pcdata(":")
+        link_type_proxy(method.return_type)
+      end
+    end
+  end
+
+  def field_synopsis(field)
+    html_code("class"=&gt;"field_synopsis") do
+      if field.instance_of?(ASImplicitField)
+        implicit_field_synopsis(field)
+      else
+        explicit_field_synopsis(field)
+      end
+    end
+  end
+
+  def explicit_field_synopsis(field)
+    if field.access.is_static
+      pcdata("static ")
+    end
+    unless field.access.visibility.nil?
+      pcdata("#{field.access.visibility.body} ")
+    end
+    html_strong("class"=&gt;"field_name") do
+      pcdata(field.name)
+    end
+    if field.field_type
+      pcdata(":")
+      link_type_proxy(field.field_type)
+    end
+  end
+
+  def implicit_field_synopsis(field)
+    if field.access.is_static
+      pcdata("static ")
+    end
+    unless field.access.visibility.nil?
+      pcdata("#{field.access.visibility.body} ")
+    end
+    html_strong("class"=&gt;"field_name") do
+      pcdata(field.name)
+    end
+    field_type = field.field_type
+    unless field_type.nil?
+      pcdata(":")
+      link_type_proxy(field_type)
+    end
+    unless field.readwrite?
+      pcdata(" ")
+      html_em("class"=&gt;"read_write_only") do
+        if field.read?
+          pcdata("[Read Only]")
+        else
+          pcdata("[Write Only]")
+        end
+      end
+    end
+  end
+
+end
+
+
+class PackageIndexPage &lt; BasicPage
+
+  def initialize(conf, package)
+    dir = package_dir_for(package)
+    super(conf, "package-summary", dir)
+    @package = package
+    @title = "#{package_description_for(@package)} API Documentation"
+    @prev_package = nil
+    @next_package = nil
+  end
+
+  attr_accessor :prev_package, :next_package
+
+  def generate_body_content
+      html_h1(package_description_for(@package))
+      interfaces = @package.interfaces
+      unless interfaces.empty?
+        interfaces.sort!
+        html_table("class"=&gt;"summary_list", "summary"=&gt;"") do
+          html_caption("Interface Summary")
+          interfaces.each do |type|
+            html_tr do
+        
+              html_td do
+                html_a(type.unqualified_name, {"href"=&gt;type.unqualified_name+".html"})
+              end
+              html_td do
+                if type.comment
+                  output_doccomment_initial_sentence(type.comment[0])
+                end
+              end
+            end
+          end
+        end
+      end
+      classes = @package.classes
+      unless classes.empty?
+        classes.sort!
+        html_table("class"=&gt;"summary_list", "summary"=&gt;"") do
+          html_caption("Class Summary")
+          classes.each do |type|
+            html_tr do
+        
+              html_td do
+                html_a(type.unqualified_name, {"href"=&gt;type.unqualified_name+".html"})
+              end
+              html_td do
+                if type.comment
+                  output_doccomment_initial_sentence(type.comment[0])
+                end
+              end
+            end
+          end
+        end
+      end
+
+    if @conf.draw_diagrams
+      draw_package_diagrams
+      class_diagram
+      interface_diagram
+    end
+  end
+
+  def link_top
+    yield "Overview", base_path("overview-summary.html")
+  end
+  def link_prev
+    if @prev_package
+      yield package_description_for(@prev_package), base_path(package_link_for(@prev_package, "package-summary.html"))
+    end
+  end
+  def link_next
+    if @next_package
+      yield package_description_for(@next_package), base_path(package_link_for(@next_package, "package-summary.html"))
+    end
+  end
+
+  def class_diagram
+    dir = File.join(@conf.output_dir, path_name)
+    if FileTest.exists?(File.join(dir, "package-classes.png"))
+      html_h1("Class Inheritance Diagram")
+      html_div("class"=&gt;"diagram") do
+        if FileTest.exists?(File.join(dir, "package-classes.cmapx"))
+          map = true
+          File.open(File.join(dir, &