First pass at basic functionality. Needs some serious tests.