diff --git a/README b/README
index 36915d9..e0146be 100644
--- a/README
+++ b/README
@@ -1,167 +1,13 @@
-== Firebot ==
+IRC Bot Framework
+=================
-FireBot is a winner!
+I recommend you check example.py and modify it to your needs.
-Firebot is an IRC bot combining the functionality of a Linkbot, an
-Infobot, and a Clickolinko, which is this cool thing Emad El-Haraty and
-I came up with to make short URLs out of stuff posted into the channel,
-for people with text browsers that wrap URLs.
+The irc framework encapsulates all messages with a sender and forum.
+For messages to a channel, the forum is the channel, and the sender is
+the nickname who sent it.
+For private messages, the forum and sender are both the nickname who sent
+it.
-Note that, in addition to interacting with FireBot within a channel, you
-can also communicate directly with FireBot via `/msg` commands. Just in
-case you need a little one-on-one action and don't want spew your
-playtime around some channel with other folks watching. That can be *so*
-distracting. Some commands still require you to preface them with
-FireBot's name. Example:
-
- /msg firebot firebot: literal ...
-
-
-Downloading
------------
-
-You can download a [tarball snapshot of the latest release](http://woozle.org/neale/g.cgi/net/firebot/snapshot/firebot-master.zip), or use git:
-
- git clone http://woozle.org/neale/g.cgi/net/firebot
-
-
-LinkBot Features
-----------------
-
-Firebot can link channels across networks. It is present in all
-channels and the same functions can be accessed on either side.
-Everything said on one channel is relayed to the others.
-
-It is possible to link multiple channels on multiple servers, including
-multiple channels on a single server.
-
-
-
-ClickLinko (UrlBot)
--------------------
-
-Whenever FireBot sees a URL in the channel, he makes a note of it and
-creates a shorter URL out of it.
-
-
-
-InfoBot
--------
-
-As an InfoBot, FireBot listens in the channel for anything of the form
-"x is y", and then stores that little tidbit. Later, when someone asks
-a question about x ("what is x?", "who is x?", "wtf is x?"), FireBot
-answers with the factoid he gathered.
-
-
-- firebot, _x_
-- look up a factoid for _x_
-
-- firebot, _x_ is _y_
-- store _y_ as a factiod about _x_
-
-- firebot, _x_ is also _y_
-- store _y_ as another factoid about _x_
-
-- firebot, append _x_ <= _y_
-- store _y_ as another factoid about _x_. You'd use this for things where _x_ has the word "is" in it, or other things that you can't store with the preceding commands.
-
-- no, firebot, _x_ is _y_
-- store _y_ as the only factoid about _x_, even if _x_ already has factoids
-
-- firebot, literal _x_
-- display all factoids about _x_
-
-- firebot, lock _x_
-- do not learn any more factoids about _x_
-
-- firebot, unlock _x_
-- resume learning factoids about _x_
-
-- firebot, forget _x_
-- forget all factoids about _x_
-
-- firebot, forget _x_ from _y_
-- forget a single entry (x) that is listed in _y_; _x_ can be a single word, it does not need to be the whole entry
-
-- firebot, shut up
-
- make the bot only respond to factoids when addressed specifically
-
-- firebot, be chatty
-
- make the bot respond to factoids even when not addressed
-
-
-
-In addition, the following tricks can be used within factiods:
-
-* Any factoid beginning with `\\` (a backslash) is displayed directly.
- That is, instead of saying " x is y", FireBot just says
- " y".
-* Any factoid beginning with :
(a colon) is
- displayed an action. That is, instead of saying " x is y",
- FireBot says "* firebot y"
-* You may put `%(sender)s` in the factoid to print the name of the
- person who asked about the factoid (when sent to a user in a private
- message, it's the recipient of the message)
-
-
-
-Utilities
----------
-
-
-
-- firebot, later tell _whom_ _what_
-- The next time _whom_ says something in the channel, deliver the message _what_ publically.
-
-- firebot, in _time_ say _what_
-- after _time_ (eg. "15 seconds", "2 hours", "5 days"), announce _what_ in the channel
-
-- seen _whom_
-- Report the last thing said in the channel by _whom_, and how long ago it was said.
-
-- dict _word_
-- look _word_ up in the dictionary
-
-- quote _symbol_
-- get a stock quote for _symbol_
-
-- pollen _zip_
-- report pollen forecast for US zip code _zip_
-
-- cdecl explain _jibberish_
-- explain the C declaration _jibberish_ (eg. "cdecl explain struct bar *(*foo)[](int)")
-
-- cdecl declare _english_
-- give the C declaration for _english_ (eg. "cdecl declare foo as pointer to array of function (int) returning pointer to struct bar")
-
-- how many _x_ in _y_ _z_
-- determine the number of _x_ items that are contained in _y_ amount of _z_ items (eg. how many miles in 1 light year)
-
-- how much is _amt_ _source_ in _dest_
-- do a currency conversion from _source_ to _dest_. Both must be three-letter currency codes. (eg. "how much is 100 USD in EUR")
-
-- calc _expr_
-- calculate _expr_ (eg. "calc 2 * 5")
-
-
-
-
-Toys
-----
-
-
-
-- 8ball, _question_
-- consult the magic 8-ball regarding _question_
-
-- _nickname_++
-- add a whuffie point for _nickname_
-
-- _nickname_--
-- remove a whuffie point for _nickname_
-
-- whuffie for _nickname_
-- check the whuffie for _nickname_
-
-
+The idea here is that you can write a bot that responds to the forum,
+and it will go to the right place.
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..36915d9
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,167 @@
+== Firebot ==
+
+FireBot is a winner!
+
+Firebot is an IRC bot combining the functionality of a Linkbot, an
+Infobot, and a Clickolinko, which is this cool thing Emad El-Haraty and
+I came up with to make short URLs out of stuff posted into the channel,
+for people with text browsers that wrap URLs.
+
+Note that, in addition to interacting with FireBot within a channel, you
+can also communicate directly with FireBot via `/msg` commands. Just in
+case you need a little one-on-one action and don't want spew your
+playtime around some channel with other folks watching. That can be *so*
+distracting. Some commands still require you to preface them with
+FireBot's name. Example:
+
+ /msg firebot firebot: literal ...
+
+
+Downloading
+-----------
+
+You can download a [tarball snapshot of the latest release](http://woozle.org/neale/g.cgi/net/firebot/snapshot/firebot-master.zip), or use git:
+
+ git clone http://woozle.org/neale/g.cgi/net/firebot
+
+
+LinkBot Features
+----------------
+
+Firebot can link channels across networks. It is present in all
+channels and the same functions can be accessed on either side.
+Everything said on one channel is relayed to the others.
+
+It is possible to link multiple channels on multiple servers, including
+multiple channels on a single server.
+
+
+
+ClickLinko (UrlBot)
+-------------------
+
+Whenever FireBot sees a URL in the channel, he makes a note of it and
+creates a shorter URL out of it.
+
+
+
+InfoBot
+-------
+
+As an InfoBot, FireBot listens in the channel for anything of the form
+"x is y", and then stores that little tidbit. Later, when someone asks
+a question about x ("what is x?", "who is x?", "wtf is x?"), FireBot
+answers with the factoid he gathered.
+
+
+- firebot, _x_
+- look up a factoid for _x_
+
+- firebot, _x_ is _y_
+- store _y_ as a factiod about _x_
+
+- firebot, _x_ is also _y_
+- store _y_ as another factoid about _x_
+
+- firebot, append _x_ <= _y_
+- store _y_ as another factoid about _x_. You'd use this for things where _x_ has the word "is" in it, or other things that you can't store with the preceding commands.
+
+- no, firebot, _x_ is _y_
+- store _y_ as the only factoid about _x_, even if _x_ already has factoids
+
+- firebot, literal _x_
+- display all factoids about _x_
+
+- firebot, lock _x_
+- do not learn any more factoids about _x_
+
+- firebot, unlock _x_
+- resume learning factoids about _x_
+
+- firebot, forget _x_
+- forget all factoids about _x_
+
+- firebot, forget _x_ from _y_
+- forget a single entry (x) that is listed in _y_; _x_ can be a single word, it does not need to be the whole entry
+
+- firebot, shut up
+
- make the bot only respond to factoids when addressed specifically
+
+- firebot, be chatty
+
- make the bot respond to factoids even when not addressed
+
+
+
+In addition, the following tricks can be used within factiods:
+
+* Any factoid beginning with `\\` (a backslash) is displayed directly.
+ That is, instead of saying " x is y", FireBot just says
+ " y".
+* Any factoid beginning with :
(a colon) is
+ displayed an action. That is, instead of saying " x is y",
+ FireBot says "* firebot y"
+* You may put `%(sender)s` in the factoid to print the name of the
+ person who asked about the factoid (when sent to a user in a private
+ message, it's the recipient of the message)
+
+
+
+Utilities
+---------
+
+
+
+- firebot, later tell _whom_ _what_
+- The next time _whom_ says something in the channel, deliver the message _what_ publically.
+
+- firebot, in _time_ say _what_
+- after _time_ (eg. "15 seconds", "2 hours", "5 days"), announce _what_ in the channel
+
+- seen _whom_
+- Report the last thing said in the channel by _whom_, and how long ago it was said.
+
+- dict _word_
+- look _word_ up in the dictionary
+
+- quote _symbol_
+- get a stock quote for _symbol_
+
+- pollen _zip_
+- report pollen forecast for US zip code _zip_
+
+- cdecl explain _jibberish_
+- explain the C declaration _jibberish_ (eg. "cdecl explain struct bar *(*foo)[](int)")
+
+- cdecl declare _english_
+- give the C declaration for _english_ (eg. "cdecl declare foo as pointer to array of function (int) returning pointer to struct bar")
+
+- how many _x_ in _y_ _z_
+- determine the number of _x_ items that are contained in _y_ amount of _z_ items (eg. how many miles in 1 light year)
+
+- how much is _amt_ _source_ in _dest_
+- do a currency conversion from _source_ to _dest_. Both must be three-letter currency codes. (eg. "how much is 100 USD in EUR")
+
+- calc _expr_
+- calculate _expr_ (eg. "calc 2 * 5")
+
+
+
+
+Toys
+----
+
+
+
+- 8ball, _question_
+- consult the magic 8-ball regarding _question_
+
+- _nickname_++
+- add a whuffie point for _nickname_
+
+- _nickname_--
+- remove a whuffie point for _nickname_
+
+- whuffie for _nickname_
+- check the whuffie for _nickname_
+
+
diff --git a/acrobot.py b/contrib/acrobot.py
similarity index 100%
rename from acrobot.py
rename to contrib/acrobot.py
diff --git a/addfacts.py b/contrib/addfacts.py
similarity index 100%
rename from addfacts.py
rename to contrib/addfacts.py
diff --git a/arsenic.py b/contrib/arsenic.py
similarity index 100%
rename from arsenic.py
rename to contrib/arsenic.py
diff --git a/async_proc.py b/contrib/async_proc.py
similarity index 100%
rename from async_proc.py
rename to contrib/async_proc.py
diff --git a/bindingsbot.py b/contrib/bindingsbot.py
similarity index 100%
rename from bindingsbot.py
rename to contrib/bindingsbot.py
diff --git a/convert.py b/contrib/convert.py
similarity index 100%
rename from convert.py
rename to contrib/convert.py
diff --git a/daemon.py b/contrib/daemon.py
similarity index 100%
rename from daemon.py
rename to contrib/daemon.py
diff --git a/dbdump.py b/contrib/dbdump.py
similarity index 100%
rename from dbdump.py
rename to contrib/dbdump.py
diff --git a/dorkbot.py b/contrib/dorkbot.py
similarity index 100%
rename from dorkbot.py
rename to contrib/dorkbot.py
diff --git a/filedbm.py b/contrib/filedbm.py
similarity index 100%
rename from filedbm.py
rename to contrib/filedbm.py
diff --git a/finger.py b/contrib/finger.py
similarity index 100%
rename from finger.py
rename to contrib/finger.py
diff --git a/firebot.py b/contrib/firebot.py
similarity index 100%
rename from firebot.py
rename to contrib/firebot.py
diff --git a/gallium.py b/contrib/gallium.py
similarity index 100%
rename from gallium.py
rename to contrib/gallium.py
diff --git a/health.sh b/contrib/health.sh
similarity index 100%
rename from health.sh
rename to contrib/health.sh
diff --git a/infobot.py b/contrib/infobot.py
similarity index 100%
rename from infobot.py
rename to contrib/infobot.py
diff --git a/linkbot.py b/contrib/linkbot.py
similarity index 100%
rename from linkbot.py
rename to contrib/linkbot.py
diff --git a/opbot.py b/contrib/opbot.py
similarity index 100%
rename from opbot.py
rename to contrib/opbot.py
diff --git a/procbot.py b/contrib/procbot.py
similarity index 100%
rename from procbot.py
rename to contrib/procbot.py
diff --git a/seedyb.py b/contrib/seedyb.py
similarity index 100%
rename from seedyb.py
rename to contrib/seedyb.py
diff --git a/shorturl.py b/contrib/shorturl.py
similarity index 100%
rename from shorturl.py
rename to contrib/shorturl.py
diff --git a/testbot.py b/contrib/testbot.py
similarity index 100%
rename from testbot.py
rename to contrib/testbot.py
diff --git a/webretriever.py b/contrib/webretriever.py
similarity index 100%
rename from webretriever.py
rename to contrib/webretriever.py
diff --git a/example.py b/example.py
new file mode 100755
index 0000000..b68713f
--- /dev/null
+++ b/example.py
@@ -0,0 +1,19 @@
+#! /usr/bin/env python
+
+import irc
+
+SERVER = ('irc.synirc.net', 6667)
+NAMES = ['idiot15']
+INFO = "Example bot"
+CHANNELS = ["#idiotbot"]
+
+class IdiotBot(irc.Bot):
+ debug = True
+
+ # Every time anybody says anything, respond like an idiot.
+ def cmd_privmsg(self, sender, forum, addl):
+ forum.msg("I am an idiot!")
+
+l2 = IdiotBot(SERVER, NAMES, INFO, CHANNELS)
+
+irc.run_forever()