diff --git a/.gitignore b/.gitignore
index 103edc6..c885d84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,7 +73,6 @@
 /docs/libvirt-lxc-*.xml
 /docs/libvirt-qemu-*.xml
 /docs/libvirt-refs.xml
-/docs/todo.html.in
 /examples/object-events/event-test
 /examples/dominfo/info1
 /examples/domsuspend/suspend
diff --git a/TODO b/TODO
index 6843a17..c837ce8 100644
--- a/TODO
+++ b/TODO
@@ -1,22 +1,12 @@
          libvirt TODO list
          =================
 
-The TODO list changes frequently, so is maintained online
-in the libvirt bugzilla
+Libvirt does not maintain an authoritative TODO list. However you
+can find a list of open feature requests at:
 
-  http://bugzilla.redhat.com/
+  http://wiki.libvirt.org/page/Todo
 
-Search against
+A list of introductory tasks for new contributors is
+maintained at:
 
-    Product: Virtualization Tools
-  Component: libvirt
-    Subject: RFE
-
-Or browse dependent bugs under
-
-  https://bugzilla.redhat.com/show_bug.cgi?id=libvirtTodo
-
-Summarized reports automatically generated from bugzilla
-and provided online at
-
-  http://libvirt.org/todo.html
+  http://wiki.libvirt.org/page/BiteSizedTasks
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 282d101..b5379bf 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -95,14 +95,12 @@ internals_html_in = \
   $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
 internals_html = $(internals_html_in:%.html.in=%.html)
 
-# todo.html is special - it is shipped in the tarball, but we
-# have a dedicated 'todo' target to rebuild it from a proper
-# config file, all other users are able to build it locally.
+# hvsupport.html.in is special, it's automatically generated so we
+# list it here explicitly.
 # For all other files, since we ship pre-built html in the
 # tarball, we must also ship the sources, even when those
 # sources are themselves generated.
 dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
-  todo.html.in \
   hvsupport.html.in
 dot_html = $(dot_html_in:%.html.in=%.html)
 
@@ -159,7 +157,7 @@ EXTRA_DIST=					\
   $(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
   $(internals_html_in) $(internals_html) \
   sitemap.html.in aclperms.htmlinc \
-  todo.pl hvsupport.pl todo.cfg-example \
+  hvsupport.pl \
   $(schema_DATA)
 
 acl_generated = aclperms.htmlinc
@@ -186,24 +184,6 @@ admin_api: $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
 web: $(dot_html) $(internals_html) html/index.html devhelp/index.html \
   $(dot_php)
 
-todo.html.in: todo.pl
-	if [ -f  todo.cfg ]; then \
-		echo "Generating $@"; \
-		$(PERL) $< > $@ \
-		|| { rm $@ && exit 1; }; \
-	else \
-		echo "Stubbing $@"; \
-		printf "%s\n" \
-		  "<html xmlns=\"http://www.w3.org/1999/xhtml\">" \
-		  "<body>" \
-		  "<h1>Todo list unavailable: no config file</h1>" \
-		  "</body></html>" > $@ ; \
-	fi
-
-todo:
-	rm -f todo.html.in
-	$(MAKE) todo.html
-
 hvsupport.html: $(srcdir)/hvsupport.html.in
 
 $(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
@@ -213,8 +193,6 @@ $(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
 	$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(top_srcdir)/src > $@ \
 		|| { rm $@ && exit 1; }
 
-.PHONY: todo
-
 %.png: %.fig
 	convert -rotate 90 $< $@
 
@@ -336,8 +314,7 @@ clean-local:
 	rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
 
 maintainer-clean-local: clean-local
-	rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml \
-		todo.html.in
+	rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
 	rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
 	rm -rf $(srcdir)/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-refs.xml
 	rm -rf $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index d5cf723..3ea34b1 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -445,7 +445,7 @@
             <span>Security bug reporting and resolution process</span>
           </li>
           <li>
-            <a href="todo.html">Todo list</a>
+            <a href="http://wiki.libvirt.org/page/Todo">Todo list</a>
             <span>Main feature request list</span>
           </li>
           <li>
diff --git a/docs/todo.cfg-example b/docs/todo.cfg-example
deleted file mode 100644
index a99c61a..0000000
--- a/docs/todo.cfg-example
+++ /dev/null
@@ -1,26 +0,0 @@
-bugzilla = {
-	 #username = ...some email addr...
-	 #password = ...some bz password...
-	 server = https://bugzilla.redhat.com
-}
-query = {
-      product = Virtualization Tools
-      alias = libvirtTodo
-}
-
-output = {
-       title = Todo list
-       blurb = <<EOF
-This is a summary of all the ideas submitted for future todo items in
-libvirt. Listing an idea here does not imply that it is committed to
-for inclusion in libvirt, just that someone thought it might be a
-useful feature. Discussion for final approval of features always takes
-place on the <a href="contact.html">development mailing list</a>.
-If you intend to work on one of the items here, it is recommended to
-add a comment to the corresponding bugzilla ticket to this effect.
-This will reduce the risk of duplicated effort between developers.
-It is also strongly recommended to mail the development mailing list
-with proposals for new APIs &amp; XML before fully implementing them, to
-allow for early design review.
-EOF
-}
diff --git a/docs/todo.pl b/docs/todo.pl
deleted file mode 100755
index 36698e8..0000000
--- a/docs/todo.pl
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use BZ::Client;
-use BZ::Client::Bug;
-
-use Config::Record;
-
-my $cfg = Config::Record->new(file => "todo.cfg");
-my $server = $cfg->get("bugzilla/server", "https://bugzilla.redhat.com");
-my $username = $cfg->get("bugzilla/username");
-my $password = $cfg->get("bugzilla/password");
-
-my $product = $cfg->get("query/product", "Virtualization Tools");
-my $todoalias = $cfg->get("query/todoalias", "libvirtTodo");
-
-my $title = $cfg->get("output/title", undef);
-my $blurb = $cfg->get("output/blurb", undef);
-
-$SIG{__DIE__} = sub {
-    my $err = shift;
-    if (UNIVERSAL::isa($err, "BZ::Client::Exception")) {
-        die "Unable to access bugzilla: " . $err->message;
-    }
-    die $err;
-};
-
-my $client = BZ::Client->new(url => $server,
-                             user => $username,
-                             password => $password);
-
-my $todo = BZ::Client::Bug->search($client, {'product' => $product,
-                                             'alias' => $todoalias});
-
-die "Cannot find bug alias 'libvirtTodo'" unless $#{$todo} > -1;
-my $todoid = $todo->[0]->{'bug_id'};
-my $todosummary = $todo->[0]->{'short_desc'};
-$todosummary =~ s/^\s*RFE\s*:\s*//;
-$todosummary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
-$todosummary =~ s/^\s*Tracker\s*:\s*//;
-
-my $trackers = BZ::Client::Bug->search($client, {'product' => $product,
-                                                 'blocked' => $todoid });
-
-my @trackers;
-
-foreach my $tracker (@{$trackers}) {
-    next if $tracker->{'bug_status'} eq "CLOSED";
-
-    my $summary = $tracker->{'short_desc'};
-    $summary =~ s/^\s*RFE\s*:\s*//;
-    $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
-    $summary =~ s/^\s*Tracker\s*:\s*//;
-
-    push @trackers, {
-        id => $tracker->{'bug_id'},
-        summary => $summary,
-        features => [],
-    };
-}
-
-foreach my $tracker (@trackers) {
-    my $features = BZ::Client::Bug->search($client, {'product' => $product,
-                                                     'blocked' => $tracker->{id}});
-
-    foreach my $feature (@{$features}) {
-        next if $feature->{'bug_status'} eq "CLOSED";
-
-        my $summary = $feature->{'short_desc'};
-        $summary =~ s/^\s*RFE\s*:\s*//;
-        $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
-
-        push @{$tracker->{features}}, {
-            id => $feature->{'bug_id'},
-            summary => $summary,
-        };
-    }
-}
-
-sub escape {
-    my $txt = shift;
-    $txt =~ s/&/&amp;/g;
-    $txt =~ s/</&lt;/g;
-    $txt =~ s/>/&gt;/g;
-    return $txt;
-};
-
-print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
-print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
-print "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";
-print "  <body>\n";
-if (defined $title) {
-    print "    <h1>", &escape($title), "</h1>\n";
-} else {
-    print "    <h1>", &escape($todosummary), "</h1>\n";
-}
-if (defined $blurb) {
-    print "    <p>\n";
-    print $blurb;
-    print "    </p>\n";
-}
-foreach my $tracker (sort { $a->{summary} cmp $b->{summary} } @trackers) {
-    next unless $#{$tracker->{features}} >= 0;
-
-    my $summary = &escape($tracker->{summary});
-    my $id = $tracker->{id};
-    print "    <h2><a href=\"$server/$id\">$summary</a></h2>\n";
-    print "    <ul>\n";
-    foreach my $feature (sort { $a->{summary} cmp $b->{summary} } @{$tracker->{features}}) {
-        $summary = &escape($feature->{summary});
-        $summary =~ s,^([^:]+):,<strong>$1</strong>,;
-
-        $id = $feature->{id};
-        print "      <li>$summary (<strong>rhbz <a href=\"$server/$id\">$id</a></strong>)</li>\n";
-    }
-    print "    </ul>\n";
-}
-
-print "    <p>\n";
-print "    This page is automatically generated from <a href=\"$server/$todoid\">", &escape($todosummary), "</a>\n";
-print "    </p>\n";
-print "  </body>\n";
-print "</html>\n";
