Modularization, I
authorMyhailo Danylenko <isbear@ukrpost.net>
Fri, 27 Mar 2009 12:06:19 +0200
changeset 66 542f61e113cb
parent 65 f1be8dbb209c
child 67 d33ca5572e91
Modularization, I * activity * attention * avatar * disco * evil * geoloc * ibb * iq * mood * oob * ping * pubsub * tune * mpd * pep
TODO
examples/activity.lua
examples/attention.lua
examples/avatar.lua
examples/disco.lua
examples/evil.lua
examples/geoloc.lua
examples/ibb.lua
examples/iq.lua
examples/iq_register.lua
examples/mc_activity.lua
examples/mc_attention.lua
examples/mc_avatar.lua
examples/mc_disco.lua
examples/mc_evil.lua
examples/mc_geoloc.lua
examples/mc_ibb.lua
examples/mc_mood.lua
examples/mc_oob.lua
examples/mc_ping.lua
examples/mc_pubsub.lua
examples/mc_tune.lua
examples/mcabberrc.lua
examples/mood.lua
examples/mpd.lua
examples/oob.lua
examples/pep.lua
examples/ping.lua
examples/pubsub.lua
examples/remote.lua
examples/tune.lua
examples/vcard.lua
examples/x_data.lua
examples/xep0004.lua
examples/xep0030.lua
examples/xep0047.lua
examples/xep0060.lua
examples/xep0066.lua
examples/xep0077.lua
examples/xep0146.lua
examples/xep0163.lua
--- a/TODO	Fri Mar 27 09:48:17 2009 +0200
+++ b/TODO	Fri Mar 27 12:06:19 2009 +0200
@@ -22,4 +22,5 @@
 publish library handlers?
 fix add_feature to 1) not add existing items 2) not add default items
 check all that callbacks for empty 'to' fields in print_info
+reply routine?
 
--- a/examples/activity.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/activity.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,14 +3,13 @@
 
 -- library
 
-require 'lm'
-require 'pep'
+local pep    = require 'pep'
 
 -- public
 
-activity = { }
+local F = { }
 
-function activity.publish ( conn, success, fail, general, specific, message )
+function F.publish ( conn, success, fail, general, specific, message )
 	local item = { xmlns = 'http://jabber.org/protocol/activity' }
 	if general then
 		item[general] = { }
@@ -24,56 +23,6 @@
 	pep.publish ( conn, 'http://jabber.org/protocol/activity', { activity = item }, success, fail )
 end
 
--- mcabber
-
-pep.handlers['http://jabber.org/protocol/activity'] =
-	function ( from, node, data )
-		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
-			return true
-		end
-		local item = data:children ()
-		local activity, desc
-		while item do
-			if item:name () == 'text' then
-				desc = item:value ()
-			else
-				activity = item:name ()
-				local subitem = item:children ()
-				if subitem then
-					-- here we can check for non-standard subactivity elements,
-					-- add subactivity child elements handling
-					activity = ("%s: %s"):format ( activity, subitem:name () )
-				end
-			end
-			item = item:next ()
-		end
-		if activity then
-			main.print_info ( from, ("Now %s %s"):format ( activity, desc or '' ) )
-		else
-			main.print_info ( from, "Buddy hides his activity" )
-		end
-		return true
-	end
-
-main.command ( 'activity',
-	function ( args )
-		local a, text = args[1], args[2]
-		local act, subact = a:match ( "(.-)%-(.+)" )
-		if not act then
-			act = a
-		end
-		activity.publish ( lm.connection.bless ( main.connection () ),
-			function ()
-				print ( 'Activity published' )
-			end,
-			function ( mesg )
-				print ( 'Error publishing activity: ' .. mesg )
-			end, act, subact, text )
-	end, true )
-
-commands_help['activity'] = "[activity[-specific_activity] [text]]\n\nPublishes your activity.\nNote, that for now it does not checks for activity validity, so, see xep0108 for valid activity values."
-
-main.add_feature ( 'http://jabber.org/protocol/activity+notify' )
-main.add_feature ( 'http://jabber.org/protocol/activity' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/attention.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/attention.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,17 +3,19 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 
--- public
+--
 
-attention = {
+local O = {
 	handler =
 		function ( mesg )
 		end,
 }
 
-function attention.send ( conn, to, message )
+local F = { }
+
+function F.send ( conn, to, message )
 	local body = nil
 	if message then
 		body = { message }
@@ -25,65 +27,22 @@
 		} )
 end
 
--- private
-
-local attention_incoming_message_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local a = mess:child ( 'attention' )
-		if a and a:attribute ( 'xmlns' ) == 'urn:xmpp:attention:0' then
-			local body = mess:child ( 'body' )
-			if body then
-				body = body:value ()
-			end
-			attention.handler ( body )
-		end
-		return false
-	end )
+function F.handler ( handler )
+	O.handler = handler
+end
 
--- mcabber
-
-attention.handler =
-	function ( mesg )
-		local times = 0
-		main.timer ( 1,
-			function ()
-				if times < 6 then
-					main.beep ()
-					times = times + 1
-					return true
-				end
-				return false
-			end )
+function F.message_handler ( conn, mess )
+	local a = mess:child ( 'attention' )
+	if a and a:attribute ( 'xmlns' ) == 'urn:xmpp:attention:0' then
+		local body = mess:child ( 'body' )
+		if body then
+			body = body:value ()
+		end
+		O.handler ( body )
 	end
-
-main.command ( 'attention',
-	function ( args )
-		local who
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
-		end
-		attention.send ( lm.connection.bless ( main.connection () ), who, args[1] )
-	end, true, 'jid' )
-
-commands_help['attention'] = "[-t to] [message]\n\nTries to get buddy's attention."
+	return false
+end
 
-local attention_handler_registered = false
-
-hooks_d['hook-post-connect'].attention =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( attention_incoming_message_handler, 'message', 'normal' )
-		attention_handler_registered = true
-		hooks_d['hook-post-connect'].attention = nil
-		hooks_d['hook-quit'].attention =
-			function ( args )
-				if attention_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( attention_incoming_message_handler, 'message' )
-				end
-			end
-	end
-
-main.add_feature ( 'urn:xmpp:attention:0' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/avatar.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/avatar.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,22 +3,22 @@
 
 -- library
 
-require 'lm'
-require 'sha1'
-require 'base64'
-require 'pubsub'
-require 'pep'
+local sha1   = require 'sha1'
+local base64 = require 'base64'
+local lm     = require 'lm'
+local pep    = require 'pep'
+local pubsub = require 'pubsub'
 
--- public
+--
 
-avatar = { }
+local F = { }
 
 -- TODO 'temporary disabling'
 --          however I cannot see a method to enable it back without republishing avatar :(
 --          this requires client to know, what is published on the server now
 --          maybe we can do that by requesting item without payload from server
 
-function avatar.publish ( conn, data, success, fail, height, width )
+function F.publish ( conn, data, success, fail, height, width )
 	local id = sha1.digest ( data )
 	pep.publish ( conn, 'urn:xmpp:avatar:data',
 		{ id = id,
@@ -34,14 +34,14 @@
 		end, fail )
 end
 
-function avatar.publish_url ( conn, url, iid, size, id, mtype, success, fail, height, width )
+function F.publish_url ( conn, url, iid, size, id, mtype, success, fail, height, width )
 	pep.publish ( conn, 'urn:xmpp:avatar:metadata',
 		{ id = iid,
 			info = { bytes = size, id = id, type = mtype, url = url, height = height, width = width },
 		}, success, fail )
 end
 
-function avatar.get ( conn, from, id, success, fail )
+function F.get ( conn, from, id, success, fail )
 	pubsub.retrieve ( conn, from, 'urn:xmpp:avatar:data',
 		function ( from, node, item )
 			local data = item:child ( 'data' )
@@ -53,74 +53,6 @@
 		end, fail, nil, { id } )
 end
 
--- mcabber
-
-pep.handlers['urn:xmpp:avatar:metadata'] =
-	function ( from, node, data )
-		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
-			return true
-		end
-		local item = data:children ()
-		while item do
-			main.print_info ( from, ('Avatar: %s [%s] %s bytes, %sx%s %s'):format (
-					item:attribute ( 'id' ),
-					item:attribute ( 'type' ),
-					item:attribute ( 'bytes' ),
-					item:attribute ( 'width' ) or '?',
-					item:attribute ( 'height' ) or '?',
-					item:attribute ( 'url' ) or '' ) )
-			item = item:next ()
-		end
-	end
-
-main.command ( 'avatar',
-	function ( args )
-		local action = args[1]
-		if action == 'get' then
-			local who
-			if args.t then
-				who = args.t
-			else
-				who = main.current_buddy ()
-			end
-			avatar.get ( lm.connection.bless ( main.connection () ), who, args[2],
-				function ( data )
-					local h = io.open ( args[3], 'w' )
-					if h then
-						h:write ( data )
-						h:close ()
-						main.print_info ( who, 'Avatar saved to ' .. args[3] )
-					else
-						print ( 'Cannot open file for writing ' .. args[3] )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Error obtaining avatar: ' .. mesg )
-				end )
-		else
-			local file = action
-			if action == 'set' then
-				file = args[2]
-			end
-			local h = io.open ( file )
-			if h then
-				data = h:read ( '*a' )
-				h:close ()
-				avatar.publish ( lm.connection.bless ( main.connection () ), data,
-					function ()
-						print ( 'Avatar published' )
-					end,
-					function ( mesg )
-						print ( 'Avatar publishing error: ' .. mesg )
-					end )
-			else
-				print ( 'Cannot open file ' .. file )
-			end
-		end
-	end, true, 'file' )
-
-commands_help['avatar'] = '[-t jid] get id filename | [set] filename\n\nGet action tries to get from server avatar with specified id and save it to \'filename\'.\nSet action publishes avatar to server. File must be a PNG image.'
-
-main.add_feature ( 'urn:xmpp:avatar:metadata+notify' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/disco.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/disco.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -1,22 +1,23 @@
 
 -- SERVICE DISCOVERY (XEP-0030)
 
+-- TODO add handler (unused by mcabber)
+
 -- library
 
-require 'lm'
 local iq = require 'iq'
 
--- public
+--
 
-disco = { }
+local F = { }
 
-function disco.items ( conn, to, success, fail, node )
+function F.items ( conn, to, success, fail, node )
 	iq.send ( conn, to, 'get',
 		{
 			query = { xmlns = 'http://jabber.org/protocol/disco#items', node = node }
 		},
 		function ( mess )
-			local item  = mess:child( 'query' ):children ()
+			local item  = mess:child( 'query' ):child ()
 			local items = { }
 			while item do
 				if item:name () == 'item' then
@@ -29,7 +30,7 @@
 		fail )
 end
 
-function disco.info ( conn, to, success, fail )
+function F.info ( conn, to, success, fail )
 	iq.send ( conn, to, 'get',
 		{
 			query = { xmlns='http://jabber.org/protocol/disco#info' }
@@ -37,7 +38,7 @@
 		function ( mess )
 			local identities = { }
 			local features   = { }
-			local item       = mess:child( 'query' ):children ()
+			local item       = mess:child( 'query' ):child ()
 			while item do
 				local name  = item:name ()
 				if name == 'identity' then
@@ -52,63 +53,6 @@
 		fail )
 end
 
--- mcabber
-
-main.command ( 'disco',
-	function ( args )
-		local who
-		local conn = lm.connection.bless ( main.connection () )
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
-		end
-		if args[1] == 'items' then
-			local node = args[2]
-			disco.items ( conn, who,
-				function ( items )
-					local text = ''
-					for index, item in ipairs ( items ) do
-						text = text .. ("\n    [%s (%s)] %s"):format ( item.jid or '', item.node or '', item.name or '' )
-					end
-					if text ~= '' then
-						main.print_info ( who, ("Items service discovery result for %s (%s):%s"):format ( who, node or '', text ) )
-					else
-						main.print_info ( who, ("No items in discovery result for %s (%s)"):format ( who, node or '' ) )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, ("Items service discovery for %s (%s) failed: %s"):format ( who, node or '', mesg ) )
-				end, node )
-		else
-			disco.info ( conn, who,
-				function ( identities, features )
-					main.print_info ( who, ("Service info discovery result for %s:"):format ( who ) )
-					local text = ''
-					for index, identity in ipairs ( identities ) do
-						text = text .. ("\n    [%s (%s)] %s"):format ( identity.category or '', identity.type or '', identity.name or '' )
-					end
-					if text ~= '' then
-						main.print_info ( who, "  Identities:" .. text )
-					else
-						main.print_info ( who, "  No identities" )
-					end
-					text = ''
-					for index, feature in ipairs ( features ) do
-						text = text .. ("\n    [%s]"):format ( feature or '' )
-					end
-					if text ~= '' then
-						main.print_info ( who, "  Features:" .. text )
-					else
-						main.print_info ( who, "  No features" )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, ("Info service discovery for %s failed: %s"):format ( who, mesg ) )
-				end )
-		end
-	end, true, 'jid' )
-
-commands_help['disco'] = "[-t target_jid] [info | items] [node]\n\nService discovery request.\nInfo is sent if omitted."
+return F
 
 -- vim: se ts=4: --
--- a/examples/evil.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/evil.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -1,31 +1,34 @@
 
 -- MALICIOUS STANZAS (XEP-0076)
 
--- FIXME for now we only can send evil messages
---       also we cannot detect stream-level evil :(
-
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 
 -- public
 
-evil = {
+local O = {
 	handler =
 		function ( mess )
 			return false
 		end,
 }
 
-function evil.message ( conn, to, mtype, message )
+local F = { }
+
+function F.handler ( handler )
+	O.handler = handler
+end
+
+function F.message ( conn, to, mtype, message )
 	conn:send ( lm.message.create { mtype = 'message-' .. mtype, to = to,
 			body = { message },
 			evil = { xmlns = 'http://jabber.org/protocol/evil' },
 		} )
 end
 
-function evil.presence ( conn, to, status, message )
+function F.presence ( conn, to, status, message )
 	local mtype = 'presence-available'
 	if status == 'unavailable' then
 		mtype = 'presence-unavailable'
@@ -38,120 +41,18 @@
 		} )
 end
 
--- private
-
-local evil_incoming_stanza_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local e = mess:child ( 'evil' )
-		if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/evil' then
-			return evil.handler ( mess )
-		end
-	end )
-
--- mcabber
-
-evil.handler =
-	function ( mess )
-		local evillevel = tonumber(main.option ( 'lua_evil_sensibility' ))
-		local mtype, smtype = mess:type ()
-		if evillevel > 1 then
-			main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. '.' .. smtype .. ' detected!' )
-		elseif evillevel > 0 then
-			print ( 'Tainted by evil stanza of type ' .. mtype .. '.' .. smtype .. ' from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
-		end
-		return main.yesno ( main.option ( 'lua_filter_evil' ) )
-	end
-
-local stat2xmpp = {
-	free     = 'chat',
-	online   = '',
-	away     = 'away',
-	dnd      = 'dnd',
-	notavail = 'xa',
-	offline  = 'unavailable',
-}
+function F.iq ( conn, to, action, contents, success, fail )
+	contents.evil = { xmlns = 'http://jabber.org/protocol/evil' }
+	iq.send ( conn, to, action, contents, success, fail )
+end
 
--- TODO improve interface, check if we sending right thing for offline
-main.command ( 'evil',
-	function ( args )
-		local conn = lm.connection.bless ( main.connection () )
-		if args[1] == 'status' then
-			local text = ''
-			for i, mesg in ipairs ( args ) do
-				if i > 2 then
-					text = text .. ' ' .. mesg
-				end
-			end
-			local st = stat2xmpp[args[2]]
-			if not st then
-				st = ''
-			end
-			evil.presence ( conn, args.t, st, text:sub ( 2 ) )
-		else
-			local text = ''
-			if args[1] == 'message' then
-				for i, mesg in ipairs ( args ) do
-					if i > 1 then
-						text = text .. ' ' .. mesg
-					end
-				end
-			else
-				for i, mesg in ipairs ( args ) do
-					text = text .. ' ' .. mesg
-				end
-			end
-			local mtype = 'chat'
-			if args.k then
-				mtype = args.k
-			end
-			local who
-			if args.t then
-				who = args.t
-			else
-				who = main.current_buddy ()
-			end
-			evil.message ( conn, who, mtype, text:sub ( 2 ) )
-		end
-	end, true )
+function F.stanza_handler ( conn, mess )
+	local e = mess:child ( 'evil' )
+	if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/evil' then
+		return O.handler ( mess )
+	end
+end
 
-commands_help['evil'] = "[-t jid] [status stat [message] | [-k message_type] [message] message]\n\nSends evil message or presence.\nmessage_type may be chat, normal, headline.\nNote, that for now it will not change mcabber's status."
-
-local evil_handler_registered = false
-
-hooks_d['hook-post-connect'].evil =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'iq',       'first' )
-		lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'message',  'first' )
-		lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'presence', 'first' )
-		evil_handler_registered = true
-		hooks_d['hook-post-connect'].evil = nil
-		hooks_d['hook-quit'].evil =
-			function ( args )
-				if evil_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'iq'       )
-					lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'message'  )
-					lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'presence' )
-				end
-			end
-	end
-
-local char2xmpp = {
-	f = 'chat',
-	o = '',
-	a = 'away',
-	d = 'dnd',
-	n = 'xa',
-	_ = 'unavailable',
-}
-
--- hack, but working ;)
-hooks_d['hook-my-status-change'].evil =
-	function ( args )
-		if main.yesno ( main.option ( 'lua_evil_mode' ) ) then
-			evil.presence ( lm.connection.bless ( main.connection () ), nil, char2xmpp[args.new_status], args.message )
-		end
-	end
-
-main.add_feature ( 'http://jabber.org/protocol/evil' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/geoloc.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/geoloc.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,14 +3,13 @@
 
 -- library
 
-require 'lm'
-require 'pep'
+local pep = require 'pep'
 
 -- public
 
-geoloc = { }
+local F = { }
 
-function geoloc.publish ( conn, success, fail, data )
+function F.publish ( conn, success, fail, data )
 	local sdata = { xmlns = 'http://jabber.org/protocol/geoloc' }
 	if data then
 		for key, value in pairs ( data ) do
@@ -20,42 +19,6 @@
 	pep.publish ( conn, 'http://jabber.org/protocol/geoloc', { geoloc = sdata }, success, fail )
 end
 
--- mcabber
-
-pep.handlers['http://jabber.org/protocol/geoloc'] =
-	function ( from, node, data )
-		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
-			return true
-		end
-		local item = data:children ()
-		local text = ''
-		while item do
-			text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
-			item = item:next ()
-		end
-		if text ~= '' then
-			text = 'Now at:' .. text
-		else
-			text = 'Now in unknown location'
-		end
-		main.print_info ( from, text )
-		return true
-	end
-
-main.command ( 'location',
-	function ( args )
-		geoloc.publish ( lm.connection.bless ( main.connection () ),
-			function ()
-				print ( 'Geolocation published' )
-			end,
-			function ( mesg )
-				print ( 'Error geolocation publishing: ' .. mesg )
-			end, args )
-	end, true )
-
-commands_help['location'] = "[-key value [-key value ...]]\n\nPublishes your current geolocation.\nValid keys are accuracy, alt, area, bearing, building, country, datum, description, error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp and uri, according to xep0080."
-
-main.add_feature ( 'http://jabber.org/protocol/geoloc+notify' )
-main.add_feature ( 'http://jabber.org/protocol/geoloc' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/ibb.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/ibb.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -6,10 +6,14 @@
 --        as if we received and accepted incoming request.
 --      message stanzas
 
-require 'lm' -- FIXME
+-- library
+
+local lm     = require 'lm'
 local iq     = require 'iq'
 local base64 = require 'base64'
 
+--
+
 local F = { }
 local M = { }
 M.__index = M
@@ -84,7 +88,7 @@
 		return false
 	end
 
-	local child = mess:children ()
+	local child = mess:child ()
 	if not child or child:attribute ( 'xmlns' ) ~= 'http://jabber.org/protocol/ibb' then
 		return false
 	end
--- a/examples/iq.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/iq.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,9 +3,9 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 
--- public
+--
 
 local F = { }
 
@@ -18,7 +18,7 @@
 			if smtype == 'result' then
 				success ( mess )
 			elseif smtype == 'error' then
-				fail ( mess:child( 'error' ):children():name (), mess ) -- FIXME
+				fail ( mess:child( 'error' ):child():name (), mess ) -- FIXME
 			else
 				fail ( mess:xml (), mess )
 				return false
--- a/examples/iq_register.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/iq_register.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,8 +3,9 @@
 
 -- library
 
-require 'lm'
-local iq = require 'iq'
+local lm     = require 'lm'
+local iq     = require 'iq'
+--local x_data =
 require 'x_data'
 
 -- public
@@ -36,7 +37,7 @@
 		return form
 	end
 
-	local field = query:children ()
+	local field = query:child ()
 	while field do
 		local name  = field:name ()
 		if name ~= 'instructions' and name ~= 'registered' then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_activity.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,56 @@
+
+local lm       = require 'lm'
+local activity = require 'activity'
+local pubsub   = require 'pubsub'
+
+pubsub.handler ( 'http://jabber.org/protocol/activity',
+	function ( from, node, data )
+		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
+			return true
+		end
+		local item = data:child ()
+		local activity, desc
+		while item do
+			if item:name () == 'text' then
+				desc = item:value ()
+			else
+				activity = item:name ()
+				local subitem = item:child ()
+				if subitem then
+					-- here we can check for non-standard subactivity elements,
+					-- add subactivity child elements handling
+					activity = ("%s: %s"):format ( activity, subitem:name () )
+				end
+			end
+			item = item:next ()
+		end
+		if activity then
+			main.print_info ( from, ("Now %s %s"):format ( activity, desc or '' ) )
+		else
+			main.print_info ( from, "Buddy hides his activity" )
+		end
+		return true
+	end )
+
+main.command ( 'activity',
+	function ( args )
+		local a, text = args[1], args[2]
+		local act, subact = a:match ( "(.-)%-(.+)" )
+		if not act then
+			act = a
+		end
+		activity.publish ( lm.connection.bless ( main.connection () ),
+			function ()
+				print ( 'Activity published' )
+			end,
+			function ( mesg )
+				print ( 'Error publishing activity: ' .. mesg )
+			end, act, subact, text )
+	end, true )
+
+commands_help['activity'] = "[activity[-specific_activity] [text]]\n\nPublishes your activity.\nNote, that for now it does not checks for activity validity, so, see xep0108 for valid activity values."
+
+main.add_feature ( 'http://jabber.org/protocol/activity+notify' )
+main.add_feature ( 'http://jabber.org/protocol/activity' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_attention.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,50 @@
+
+local lm        = require 'lm'
+local attention = require 'attention'
+
+attention.handler (
+	function ( mesg )
+		local times = 0
+		main.timer ( 1,
+			function ()
+				if times < 6 then
+					main.beep ()
+					times = times + 1
+					return true
+				end
+				return false
+			end )
+	end )
+
+main.command ( 'attention',
+	function ( args )
+		local who
+		if args.t then
+			who = args.t
+		else
+			who = main.full_jid ()
+		end
+		attention.send ( lm.connection.bless ( main.connection () ), who, args[1] )
+	end, true, 'jid' )
+
+commands_help['attention'] = "[-t to] [message]\n\nTries to get buddy's attention."
+
+local attention_handler = lm.message_handler.new ( attention.message_handler )
+local attention_handler_registered = false
+
+hooks_d['hook-post-connect'].attention =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( attention_handler, 'message', 'normal' )
+		attention_handler_registered = true
+		hooks_d['hook-post-connect'].attention = nil
+		hooks_d['hook-quit'].attention =
+			function ( args )
+				if attention_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( attention_handler, 'message' )
+				end
+			end
+	end
+
+main.add_feature ( 'urn:xmpp:attention:0' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_avatar.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,74 @@
+
+local lm     = require 'lm'
+local pubsub = require 'pubsub'
+local avatar = require 'avatar'
+
+pubsub.handler ( 'urn:xmpp:avatar:metadata',
+	function ( from, node, data, id )
+		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
+			return true
+		end
+		local item = data:child ()
+		while item do
+			main.print_info ( from, ('Avatar: %s [%s] %s bytes, %sx%s %s'):format (
+					item:attribute ( 'id' ),
+					item:attribute ( 'type' ),
+					item:attribute ( 'bytes' ),
+					item:attribute ( 'width' ) or '?',
+					item:attribute ( 'height' ) or '?',
+					item:attribute ( 'url' ) or '' ) )
+			item = item:next ()
+		end
+	end )
+
+main.command ( 'avatar',
+	function ( args )
+		local action = args[1]
+		if action == 'get' then
+			local who
+			if args.t then
+				who = args.t
+			else
+				who = main.current_buddy ()
+			end
+			avatar.get ( lm.connection.bless ( main.connection () ), who, args[2],
+				function ( data )
+					local h = io.open ( args[3], 'w' )
+					if h then
+						h:write ( data )
+						h:close ()
+						main.print_info ( who, 'Avatar saved to ' .. args[3] )
+					else
+						print ( 'Cannot open file for writing ' .. args[3] )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Error obtaining avatar: ' .. mesg )
+				end )
+		else
+			local file = action
+			if action == 'set' then
+				file = args[2]
+			end
+			local h = io.open ( file )
+			if h then
+				data = h:read ( '*a' )
+				h:close ()
+				avatar.publish ( lm.connection.bless ( main.connection () ), data,
+					function ()
+						print ( 'Avatar published' )
+					end,
+					function ( mesg )
+						print ( 'Avatar publishing error: ' .. mesg )
+					end )
+			else
+				print ( 'Cannot open file ' .. file )
+			end
+		end
+	end, true, 'file' )
+
+commands_help['avatar'] = '[-t jid] get id filename | [set] filename\n\nGet action tries to get from server avatar with specified id and save it to \'filename\'.\nSet action publishes avatar to server. File must be a PNG image.'
+
+main.add_feature ( 'urn:xmpp:avatar:metadata+notify' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_disco.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,62 @@
+
+local lm    = require 'lm'
+local disco = require 'disco'
+
+main.command ( 'disco',
+	function ( args )
+		local who
+		local conn = lm.connection.bless ( main.connection () )
+		if args.t then
+			who = args.t
+		else
+			who = main.full_jid ()
+		end
+		if args[1] == 'items' then
+			local node = args[2]
+			disco.items ( conn, who,
+				function ( items )
+					local text = ''
+					for index, item in ipairs ( items ) do
+						text = text .. ("\n    [%s (%s)] %s"):format ( item.jid or '', item.node or '', item.name or '' )
+					end
+					if text ~= '' then
+						main.print_info ( who, ("Items service discovery result for %s (%s):%s"):format ( who, node or '', text ) )
+					else
+						main.print_info ( who, ("No items in discovery result for %s (%s)"):format ( who, node or '' ) )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, ("Items service discovery for %s (%s) failed: %s"):format ( who, node or '', mesg ) )
+				end, node )
+		else
+			disco.info ( conn, who,
+				function ( identities, features )
+					main.print_info ( who, ("Service info discovery result for %s:"):format ( who ) )
+					local text = ''
+					for index, identity in ipairs ( identities ) do
+						text = text .. ("\n    [%s (%s)] %s"):format ( identity.category or '', identity.type or '', identity.name or '' )
+					end
+					if text ~= '' then
+						main.print_info ( who, "  Identities:" .. text )
+					else
+						main.print_info ( who, "  No identities" )
+					end
+					text = ''
+					for index, feature in ipairs ( features ) do
+						text = text .. ("\n    [%s]"):format ( feature or '' )
+					end
+					if text ~= '' then
+						main.print_info ( who, "  Features:" .. text )
+					else
+						main.print_info ( who, "  No features" )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, ("Info service discovery for %s failed: %s"):format ( who, mesg ) )
+				end )
+		end
+	end, true, 'jid' )
+
+commands_help['disco'] = "[-t target_jid] [info | items] [node]\n\nService discovery request.\nInfo is sent if omitted."
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_evil.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,110 @@
+
+local lm   = require 'lm'
+local evil = require 'evil'
+
+evil.handler (
+	function ( mess )
+		local evillevel = tonumber(main.option ( 'lua_evil_sensibility' ))
+		local mtype, smtype = mess:type ()
+		if evillevel > 1 then
+			main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. '.' .. smtype .. ' detected!' )
+		elseif evillevel > 0 then
+			print ( 'Tainted by evil stanza of type ' .. mtype .. '.' .. smtype .. ' from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
+		end
+		return main.yesno ( main.option ( 'lua_filter_evil' ) )
+	end )
+
+local stat2xmpp = {
+	free     = 'chat',
+	online   = '',
+	away     = 'away',
+	dnd      = 'dnd',
+	notavail = 'xa',
+	offline  = 'unavailable',
+}
+
+-- TODO improve interface, check if we sending right thing for offline
+main.command ( 'evil',
+	function ( args )
+		local conn = lm.connection.bless ( main.connection () )
+		if args[1] == 'status' then
+			local text = ''
+			for i, mesg in ipairs ( args ) do
+				if i > 2 then
+					text = text .. ' ' .. mesg
+				end
+			end
+			local st = stat2xmpp[args[2]]
+			if not st then
+				st = ''
+			end
+			evil.presence ( conn, args.t, st, text:sub ( 2 ) )
+		else
+			local text = ''
+			if args[1] == 'message' then
+				for i, mesg in ipairs ( args ) do
+					if i > 1 then
+						text = text .. ' ' .. mesg
+					end
+				end
+			else
+				for i, mesg in ipairs ( args ) do
+					text = text .. ' ' .. mesg
+				end
+			end
+			local mtype = 'chat'
+			if args.k then
+				mtype = args.k
+			end
+			local who
+			if args.t then
+				who = args.t
+			else
+				who = main.current_buddy ()
+			end
+			evil.message ( conn, who, mtype, text:sub ( 2 ) )
+		end
+	end, true )
+
+commands_help['evil'] = "[-t jid] [status stat [message] | [-k message_type] [message] message]\n\nSends evil message or presence.\nmessage_type may be chat, normal, headline.\nNote, that for now it will not change mcabber's status."
+
+local evil_handler = lm.message_handler.new ( evil.stanza_handler )
+local evil_handler_registered = false
+
+hooks_d['hook-post-connect'].evil =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'iq',       'first' )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'message',  'first' )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'presence', 'first' )
+		evil_handler_registered = true
+		hooks_d['hook-post-connect'].evil = nil
+		hooks_d['hook-quit'].evil =
+			function ( args )
+				if evil_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'iq'       )
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'message'  )
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'presence' )
+				end
+			end
+	end
+
+local char2xmpp = {
+	f = 'chat',
+	o = '',
+	a = 'away',
+	d = 'dnd',
+	n = 'xa',
+	_ = 'unavailable',
+}
+
+-- hack, but working ;)
+hooks_d['hook-my-status-change'].evil =
+	function ( args )
+		if main.yesno ( main.option ( 'lua_evil_mode' ) ) then
+			evil.presence ( lm.connection.bless ( main.connection () ), nil, char2xmpp[args.new_status], args.message )
+		end
+	end
+
+main.add_feature ( 'http://jabber.org/protocol/evil' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_geoloc.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,42 @@
+
+local lm     = require 'lm'
+local geoloc = require 'geoloc'
+local pubsub = require 'pubsub'
+
+pubsub.handler ( 'http://jabber.org/protocol/geoloc',
+	function ( from, node, data )
+		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
+			return true
+		end
+		local item = data:child ()
+		local text = ''
+		while item do
+			text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
+			item = item:next ()
+		end
+		if text ~= '' then
+			text = 'Now at:' .. text
+		else
+			text = 'Now in unknown location'
+		end
+		main.print_info ( from, text )
+		return true
+	end )
+
+main.command ( 'location',
+	function ( args )
+		geoloc.publish ( lm.connection.bless ( main.connection () ),
+			function ()
+				print ( 'Geolocation published' )
+			end,
+			function ( mesg )
+				print ( 'Error geolocation publishing: ' .. mesg )
+			end, args )
+	end, true )
+
+commands_help['location'] = "[-key value [-key value ...]]\n\nPublishes your current geolocation.\nValid keys are accuracy, alt, area, bearing, building, country, datum, description, error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp and uri, according to xep0080."
+
+main.add_feature ( 'http://jabber.org/protocol/geoloc+notify' )
+main.add_feature ( 'http://jabber.org/protocol/geoloc' )
+
+-- vim: se ts=4: --
--- a/examples/mc_ibb.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/mc_ibb.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -1,5 +1,5 @@
 
-require 'lm'
+local lm  = require 'lm'
 local ibb = require 'ibb'
 
 local mc_incoming_files = { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_mood.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,45 @@
+
+local lm     = require 'lm'
+local mood   = require 'mood'
+local pubsub = require 'pubsub'
+
+pubsub.handler ( 'http://jabber.org/protocol/mood',
+	function ( from, node, data )
+		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
+			return true
+		end
+		local item = data:child ()
+		local mood, desc
+		while item do
+			if item:name () == 'text' then
+				desc = item:value ()
+			else
+				mood = item:name ()
+				-- here we can add child elements handling (by namespace)
+			end
+			item = item:next ()
+		end
+		if mood then
+			main.print_info ( from, ("Buddy's mood now %s %s"):format ( mood, desc or '' ) )
+		else
+			main.print_info ( from, "Buddy hides his mood" )
+		end
+	end )
+
+main.command ( 'mood',
+	function ( args )
+		mood.publish ( lm.connection.bless ( main.connection () ),
+			function ()
+				print ( 'Mood published' )
+			end,
+			function ( mesg )
+				print ( 'Error publishing mood: ' .. mesg )
+			end, args[1], args[2] )
+	end, true )
+
+commands_help['mood'] = "[mood [message]]\n\nPublishes your mood.\nNote, that for now it does not checks for mood validity, so, see xep0107 for valid moods."
+
+main.add_feature ( 'http://jabber.org/protocol/mood+notify' )
+main.add_feature ( 'http://jabber.org/protocol/mood' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_oob.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,59 @@
+
+local lm  = require 'lm'
+local oob = require 'oob'
+
+oob.handler (
+	function ( from, url, desc, success, fail )
+		if desc then
+			main.print_info ( from, 'Buddy wants you to download link: ' .. url .. ' (' .. desc .. ')' )
+		else
+			main.print_info ( from, 'Buddy wants you to download link: ' .. url )
+		end
+		success ()
+	end )
+
+main.command ( 'oob',
+	function ( args )
+		local who
+		if args.t then
+			who = args.t
+		else
+			who = main.full_jid ()
+		end
+		-- here we can run something external to put file on server and obtain link to it
+		oob.send ( lm.connection.bless ( main.connection () ), who, args[1],
+			function ()
+				main.print_info ( who, 'OOB link accepted' )
+			end,
+			function ( mesg )
+				main.print_info ( who, 'OOB link refused: ' .. mesg )
+			end, args[2] )
+	end, true )
+
+local oob_iq_handler = lm.message_handler.new ( oob.iq_handler )
+local oob_message_handler = lm.message_handler.new ( oob.message_handler )
+local oob_handler_registered = false
+
+hooks_d['hook-post-connect'].oob =
+	function ( args )
+		local conn = lm.connection.bless ( main.connection () )
+		conn:handler ( oob_iq_handler, 'iq', 'normal' )
+		conn:handler ( oob_message_handler, 'message', 'normal' )
+		conn:handler ( oob_message_handler, 'presence', 'normal' )
+		oob_handler_registered = true
+		hooks_d['hook-post-connect'].oob = nil
+		hooks_d['hook-quit'].oob =
+			function ( args )
+				if oob_handler_registered then
+					local conn = lm.connection.bless ( main.connection () )
+					conn:handler ( oob_iq_handler, 'iq' )
+					conn:handler ( oob_message_handler, 'message' )
+					conn:handler ( oob_message_handler, 'presence' )
+				end
+			end
+	end
+
+main.add_feature ( 'jabber:iq:oob' )
+main.add_feature ( 'jabber:x:oob' )
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_ping.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,43 @@
+
+local lm   = require 'lm'
+local ping = require 'ping'
+
+main.command ( 'ping',
+	function ( args )
+		local who
+		if args[1] then
+			who = args[1]
+		else
+			who = main.full_jid ()
+		end
+		local time = os.time ()
+		ping.send ( lm.connection.bless ( main.connection () ), who,
+			function ()
+				main.print_info ( who, ('Pong: %d seconds'):format ( os.time () - time ) )
+			end,
+			function ( mesg )
+				main.print_info ( who, 'Ping failed: ' .. mesg )
+			end )
+	end, true, 'jid' )
+
+--[[
+local ping_handler = lm.message_handler.new ( ping.iq_handler )
+local ping_handler_registered = false
+
+hooks_d['hook-post-connect'].ping =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( ping_handler, 'iq', 'normal' )
+		ping_handler_registered = true
+		hooks_d['hook-post-connect'].ping = nil
+		hooks_d['hook-quit'].ping =
+			function ( args )
+				if ping_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( ping_handler, 'iq' )
+				end
+			end
+	end
+
+main.add_feature ( 'urn:xmpp:ping' )
+--]]
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_pubsub.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,167 @@
+
+local lm     = require 'lm'
+local pubsub = require 'pubsub'
+
+main.command ( 'node',
+	function ( args )
+		local who, action, node = args.t, args[1], args[2]
+		local conn = lm.connection.bless ( main.connection () )
+		if not who then
+			who = main.current_buddy ()
+		end
+		if action == 'subscribe' then
+			pubsub.subscribe ( conn, who, node,
+				function ( id )
+					if id then
+						main.print_info ( who, 'Subscription succeeds with id ' .. id )
+					else
+						main.print_info ( who, 'Subscription successful' )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Subscription unsuccessful: ' .. mesg )
+				end )
+		elseif action == 'unsubscribe' then
+			pubsub.unsubscribe ( conn, who, node,
+				function ()
+					main.print_info ( who, 'Unubscription successful' )
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Unsubscription unsuccessful: ' .. mesg )
+				end )
+		elseif action == 'retrieve' or action == 'items' or action == 'get' then
+			pubsub.retrieve ( conn, who, node,
+				function ( from, node, item )
+					main.print_info ( who, 'Item from ' .. from .. ', node ' .. node .. ':\n' .. item:xml () ) 
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Retrieval failed: ' .. mesg )
+				end, args.m )
+		elseif action == 'create' or action == 'new' then
+			pubsub.create_node ( conn, who, node,
+				function ( node )
+					if node then
+						main.print_info ( who, 'Node ' .. node .. ' successfully created' )
+					else
+						main.print_info ( who, 'Node successfully created' )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Creation failed: ' .. mesg )
+				end )
+		elseif action == 'delete' or action == 'del' then
+			pubsub.delete_node ( conn, who, node,
+				function ()
+					main.print_info ( who, 'Node deleted' )
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Node deletion failed: ' .. mesg )
+				end )
+		elseif action == 'purge' or action == 'del_items' then
+			pubsub.purge_node ( conn, who, node,
+				function ()
+					main.print_info ( who, 'Node purged' )
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Node purge failed: ' .. mesg )
+				end )
+		elseif action:sub ( 1, 4 ) == 'conf' then
+			pubsub.configure_node ( conn, who, node,
+				function ( form, submit, reject )
+					local id = #forms + 1
+					forms[id] = {
+						form = form,
+						submit =
+							function ( form )
+								submit ( form,
+									function ()
+										main.print_info ( who, 'Node configuration completed' )
+									end,
+									function ( mesg )
+										main.print_info ( who, 'Node configuration failed: ' .. mesg )
+									end )
+							end,
+						reject =
+							function ( form )
+								reject ( form,
+									function ()
+										main.print_info ( who, 'Node configuration cancelled' )
+									end,
+									function ( mesg )
+										main.print_info ( who, 'Node configuration cancellation failed: ' .. mesg )
+									end )
+							end,
+					}
+					print ( 'You have new form ' .. id )
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Node configuration failed: ' .. mesg )
+				end )
+		elseif action == 'subscriptions' or action == 'subscribers' then
+			pubsub.list_subscriptions ( conn, who, node,
+				function ( s )
+					local text = ''
+					for i, v in ipairs ( s ) do
+						local subid = v.subid
+						if subid then
+							subid = '(id ' .. subid .. ')'
+						else
+							subid = ''
+						end
+						text = text .. ('\n- [%s] %s %s'):format ( v.subscription, v.jid, subid )
+					end
+					if text ~= '' then
+						main.print_info ( who, 'Node subscriptions:' .. text )
+					else
+						main.print_info ( who, 'No subscriptions' )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Node subscriptions retrieval failed: ' .. mesg )
+				end )
+		elseif action == 'subscription' or action == 'modify' then -- XXX
+			pubsub.modify_subscription ( conn, args.t or main.current_buddy (), node, args[3], args[4],
+				function ()
+					main.print_info ( who, 'Subscription modified' )
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Subsrciption modification failed: ' .. mesg )
+				end, args[5] )
+		else
+			print ( 'Error: unknown action' )
+		end
+	end, true )
+
+-- FIXME
+commands_help['node']           = "[-t jid] [-m max_items] action [node_name]\n\nAction can be subscribe, unsubscribe, retrieve (items, get), create (new), delete (del), purge (del_items), configure (conf*), subscriptions (subscribers), subscription (modify?)"
+--[[
+commands_help['subscribe']      = "[-t jid] node_name\n\nSends pubsub subscription request to specified node of jid or current buddy."
+commands_help['unsubscribe']    = "[-t jid] node_name\n\nSends pubsub unsubscription request to specified node of jid or current buddy."
+commands_help['retrieve']       = "[-t jid] [-m max_items] node_name\n\nSends pubsub items retrieval request to specified node of jid or current buddy.\nNote, that we cannot know, how to deal with these itemss, so, raw xml will be printed as a result."
+commands_help['create_node']    = "[-t jid] [node_name]\n\nSends pubsub node creation request to specified node of jid or current buddy. If node name is not specified, server can generate unique id for it, if supported."
+commands_help['configure_node'] = "[-t jid] node_name\n\nSends pubsub node configuration request to specified node of jid or current buddy."
+commands_help['delete_node']    = "[-t jid] node_name\n\nSends pubsub node deletion request to specified node of jid or current buddy."
+commands_help['purge_node']     = "[-t jid] node_name\n\nSends pubsub node items purging request to specified node of jid or current buddy."
+commands_help['subscriptions']  = "[-t jid] node_name\n\nSends pubsub subscription list request to specified node of jid or current buddy."
+commands_help['subscription']   = "[-t jid] node_name subscriber_jid state [subscription_id]\n\nSends pubsub subscription modification request to change subscription state of 'subscriber_jid' to 'state'. Optional id is used when multiple subscriptions for one jid are available."
+--]]
+
+local pubsub_handler = lm.message_handler.new ( pubsub.message_handler )
+
+local pubsub_handler_registered = false
+
+hooks_d['hook-post-connect'].pubsub =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( pubsub_handler, 'message', 'normal' )
+		pubsub_handler_registered = true
+		hooks_d['hook-post-connect'].pubsub = nil
+		hooks_d['hook-quit'].pubsub =
+			function ( args )
+				if pubsub_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( pubsub_handler, 'message' )
+					pubsub_handler_registered = false
+				end
+			end
+	end
+
+-- vim: se ts=4: --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_tune.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -0,0 +1,147 @@
+
+local mpd    = require 'mpd'
+local lm     = require 'lm'
+local pubsub = require 'pubsub'
+
+local tune_enabled = false
+local mpd_pub_song = { }
+
+pubsub.handler ( 'http://jabber.org/protocol/tune',
+	function ( from, node, data )
+		local self = false
+		if from == lm.connection.bless ( main.connection () ):jid():gsub ( '/.*', '' ) then -- o_O
+			self         = true
+			mpd_pub_song = { }
+		end
+		local item = data:child ()
+		local text = ''
+		while item do
+			local name  = item:name ()
+			local value = item:value ()
+			if self then
+				mpd_pub_song[name] = value or ''
+			end
+			text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
+			item = item:next ()
+		end
+		if main.yesno ( main.option ( 'lua_pep_notification' ) ) then
+			if text ~= '' then
+				text = 'Now listening to:' .. text
+			else
+				text = 'Now not listening to anything'
+			end
+		end
+		main.print_info ( from, text )
+		return true
+	end )
+
+local function mpd_getstatus ()
+	local status = mpd.call_command { 'status' }
+	if not tune_enabled or ( status.state ~= 'play' and status.state ~= 'pause' ) then
+		for k, v in pairs ( mpd_pub_song ) do -- if there is anything published, publish nothing
+			return { }
+		end
+		return nil
+	end
+	
+	local song      = mpd.call_command { 'currentsong' }
+	local dir, file = song.file:match ( '(.+)/(.-)' )
+	-- populate according to currentsong fields: artist - artist, length - time, source - album, title - title, track - id, rating - ?, uri - ?
+	local ret = {
+		artist = song.artist or 'Unknown',
+		length = song.time,
+		source = song.album  or dir,
+		title  = song.title  or file,
+		track  = song.id,
+	}
+
+	if not song.time or song.time == '0' then -- XXX
+		ret.length = nil
+	end
+
+	local modified = false
+	for k, v in pairs ( ret ) do
+		if mpd_pub_song[k] ~= v then
+			modified = true
+			break
+		end
+	end
+	if not modified then
+		for k, v in pairs ( mpd_pub_song ) do
+			if ret[k] ~= v then
+				modified = true
+				break
+			end
+		end
+	end
+
+	if modified then
+		return ret
+	else
+		return nil
+	end
+end
+
+local function mpd_callback ()
+	local sdata = mpd_getstatus ()
+	if sdata then
+		pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/tune',
+			function ()
+			end,
+			function ( mesg )
+				print ( 'Error publishing tune: ' .. mesg )
+			end, sdata )
+	end
+	if tune_enabled then
+		return true
+	else
+		return false
+	end
+end
+
+-- do not call it too fast, or you end up with many daemons at once
+local function enable_tune ( yn )
+	if yn == nil then
+		yn = true
+	end
+	if yn then
+		if not tune_enabled then
+			main.timer ( 15, mpd_callback )
+			tune_enabled = true
+			-- update status
+		end
+	else
+		if tune_enabled then
+			tune_enabled = false
+			-- update status
+		end
+	end
+end
+
+main.command ( 'tune',
+	function ( args )
+		local enable = main.yesno ( args )
+		if enable == nil then
+			if tune_enabled then
+				print ( "Tune notifications enabled" )
+			else
+				print ( "Tune notifications disabled" )
+			end
+		else
+			enable_tune ( enable )
+		end
+	end, false, 'yesno' )
+
+commands_help['tune'] = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables publishing of notifications about playing music in your player (currently only mpd is supported)."
+
+hooks_d['hook-post-connect'].tune =
+	function ( args )
+		if tune_enabled then
+			mpd_callback ()
+		end
+	end
+
+main.add_feature ( 'http://jabber.org/protocol/tune+notify' )
+main.add_feature ( 'http://jabber.org/protocol/tune' )
+
+-- vim: se ts=4: --
--- a/examples/mcabberrc.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/mcabberrc.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -261,7 +261,7 @@
 
 -- SERVICE DISCOVERY (XEP-0030)
 
-require 'disco'
+require 'mc_disco'
 
 -- IN-BAND BYTESTREAMS (XEP-0047)
 
@@ -273,15 +273,15 @@
 
 -- PUBLISH-SUBSRIBE (XEP-0060)
 
-require 'pubsub'
+require 'mc_pubsub'
 
 -- OUT OF BAND DATA (XEP-0066)
 
-require 'oob'
+require 'mc_oob'
 
 -- MALICIOUS STANZAS (XEP-0076)
 
-require 'evil'
+require 'mc_evil'
 
 -- IN-BAND REGISTRATION (XEP-0077)
 
@@ -289,23 +289,23 @@
 
 -- USER LOCATION (XEP-0080)
 
-require 'geoloc'
+require 'mc_geoloc'
 
 -- USER AVATAR (XEP-0084)
 
-require 'avatar'
+require 'mc_avatar'
 
 -- USER MOOD (XEP-0107)
 
-require 'mood'
+require 'mc_mood'
 
 -- USER ACTIVITY (XEP-0108)
 
-require 'activity'
+require 'mc_activity'
 
 -- USER TUNE (XEP-0118)
 
-require 'tune'
+require 'mc_tune'
 
 -- REMOTE CONTROLLING CLIENTS (XEP-0146)
 
@@ -313,14 +313,12 @@
 
 -- PERSONAL EVENTING PROTOCOL (XEP-0163)
 
-require 'pep'
-
 -- XMPP PING (XEP-0199)
 
-require 'ping'
+require 'mc_ping'
 
 -- ATTENTION (XEP-0224)
 
-require 'attention'
+require 'mc_attention'
 
 -- The End -- vim: se ts=4: --
--- a/examples/mood.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/mood.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,14 +3,13 @@
 
 -- library
 
-require 'lm'
-require 'pep'
+local pep = require 'pep'
+
+--
 
--- public
+local F = { }
 
-mood = { }
-
-function mood.publish ( conn, success, fail, mood, message )
+function F.publish ( conn, success, fail, mood, message )
 	local item = { xmlns = 'http://jabber.org/protocol/mood' }
 	if mood then
 		item[mood] = { }
@@ -21,45 +20,6 @@
 	pep.publish ( conn, 'http://jabber.org/protocol/mood', { mood = item }, success, fail )
 end
 
--- mcabber
-
-pep.handlers['http://jabber.org/protocol/mood'] =
-	function ( from, node, data )
-		if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then
-			return true
-		end
-		local item = data:children ()
-		local mood, desc
-		while item do
-			if item:name () == 'text' then
-				desc = item:value ()
-			else
-				mood = item:name ()
-				-- here we can add child elements handling (by namespace)
-			end
-			item = item:next ()
-		end
-		if mood then
-			main.print_info ( from, ("Buddy's mood now %s %s"):format ( mood, desc or '' ) )
-		else
-			main.print_info ( from, "Buddy hides his mood" )
-		end
-	end
-
-main.command ( 'mood',
-	function ( args )
-		mood.publish ( lm.connection.bless ( main.connection () ),
-			function ()
-				print ( 'Mood published' )
-			end,
-			function ( mesg )
-				print ( 'Error publishing mood: ' .. mesg )
-			end, args[1], args[2] )
-	end, true )
-
-commands_help['mood'] = "[mood [message]]\n\nPublishes your mood.\nNote, that for now it does not checks for mood validity, so, see xep0107 for valid moods."
-
-main.add_feature ( 'http://jabber.org/protocol/mood+notify' )
-main.add_feature ( 'http://jabber.org/protocol/mood' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/mpd.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/mpd.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -5,23 +5,23 @@
 
 -- library
 
-require 'socket'
+local socket = require 'socket'
 
--- public
+--
 
-local settings = {
+local O = {
 	hostname     = "localhost",
 	password     = nil,
 	port         = 6600,
 }
 
-mpd = { }
+local F = { }
 
 -- separator allows split output into records, that are started by any of present in separator keys
 -- returns table of field (lowercase) - value records
 -- command status is returned in STATUS field
 -- on unexpected errors returns just false, dropping any available data
-function mpd.receive_message ( tcp, separator )
+function F.receive_message ( tcp, separator )
 	local ret  = {}
 	local line = tcp:receive ( '*l' )
 	while line and not ( line:match ( '^OK' ) or line:match ( '^ACK' ) ) do
@@ -54,12 +54,12 @@
 -- on one command returns just results of that command, on multi - array of results
 -- on errors returns nil
 -- noret can terminate socket too early, thus, do not use it with lists of commands
-function mpd.call_command ( opts )
+function F.call_command ( opts )
 	local tcp = socket.tcp ()
 	if not tcp then
 		print ( 'mpd: cannot get master tcp object' )
 		return nil
-	elseif not tcp:connect ( settings.hostname, settings.port ) then
+	elseif not tcp:connect ( O.hostname, O.port ) then
 		tcp:close ()
 		print ( 'mpd: cannot connect to server' )
 		return nil
@@ -67,7 +67,7 @@
 
 	local ret = {}
 	if not opts.noret then
-		ret = mpd.receive_message ( tcp )
+		ret = F.receive_message ( tcp )
 		if not ret then
 			tcp:close ()
 			print ( 'mpd: error getting greeting from server' )
@@ -84,7 +84,7 @@
 			return nil
 		end
 		if not opts.noret then
-			ret[num] = mpd.receive_message ( tcp, opts.list )
+			ret[num] = F.receive_message ( tcp, opts.list )
 			if not ret[num] then
 				print ( 'mpd: error getting result' )
 			end
@@ -102,4 +102,12 @@
 	end
 end
 
+function F.server ( host, port, password )
+	O.hostname = host
+	O.port     = port
+	O.password = password
+end
+
+return F
+
 -- vim: se ts=4: --
--- a/examples/oob.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/oob.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,19 +3,21 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 
--- public
+--
 
-oob = {
+local O = {
 	handler =
 		function ( from, url, desc, success, fail )
 			fail ()
 		end,
 }
 
-function oob.send ( conn, to, url, success, fail, desc )
+local F = { }
+
+function F.send ( conn, to, url, success, fail, desc )
 	if desc then
 		desc = { desc }
 	end
@@ -28,109 +30,58 @@
 		}, success, fail )
 end
 
--- private
+function F.handler ( handler )
+	O.handler = handler
+end
 
-local oob_incoming_iq_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local mtype, smtype = mess:type ()
-		if smtype == 'set' then
-			local query = mess:child ( 'query' )
-			if query and query:attribute ( 'xmlns' ) == 'jabber:iq:oob' then
-				local from = mess:attribute ( 'from' )
-				local url  = query:child( 'url' ):value ()
-				local desc = query:child( 'desc' )
-				if desc then
-					desc = desc:value ()
-				end
-				oob.handler ( from, url, desc,
-					function ()
-						conn:send ( lm.message.create { mtype = 'iq-result', to = from, id = mess:attribute ( 'id' ) } )
-					end,
-					function () -- XXX distinguish download error and reject
-						conn:send (
-							lm.message.create { mype = 'iq-error', to = from, id = mess:attribute ( 'id' ),
-								-- XXX must we include query here?
-								error = { code = '406', type = 'modify',
-									['not-acceptable'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-								},
-							} )
-					end )
-				return true
-			end
-		end
-		return false
-	end )
-local oob_incoming_message_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local x = mess:child ( 'x' )
-		if x and x:attribute ( 'xmlns' ) == 'jabber:x:oob' then
+function F.iq_handler ( conn, mess )
+	local mtype, smtype = mess:type ()
+	if smtype == 'set' then
+		local query = mess:child ( 'query' )
+		if query and query:attribute ( 'xmlns' ) == 'jabber:iq:oob' then
 			local from = mess:attribute ( 'from' )
-			local url  = x:child( 'url' ):value ()
-			local desc = x:child( 'desc' )
+			local url  = query:child( 'url' ):value ()
+			local desc = query:child( 'desc' )
 			if desc then
 				desc = desc:value ()
 			end
-			oob.handler ( from, url, desc,
+			O.handler ( from, url, desc,
 				function ()
+					conn:send ( lm.message.create { mtype = 'iq-result', to = from, id = mess:attribute ( 'id' ) } )
 				end,
-				function ()
+				function () -- XXX distinguish download error and reject
+					conn:send (
+						lm.message.create { mype = 'iq-error', to = from, id = mess:attribute ( 'id' ),
+							-- XXX must we include query here?
+							error = { code = '406', type = 'modify',
+								['not-acceptable'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+							},
+						} )
 				end )
-		end
-		return false
-	end )
-
--- mcabber
-
-oob.handler =
-	function ( from, url, desc, success, fail )
-		if desc then
-			main.print_info ( from, 'Buddy wants you to download link: ' .. url .. ' (' .. desc .. ')' )
-		else
-			main.print_info ( from, 'Buddy wants you to download link: ' .. url )
-		end
-		success ()
-	end
-
-main.command ( 'oob',
-	function ( args )
-		local who
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
+			return true
 		end
-		-- here we can run something external to put file on server and obtain link to it
-		oob.send ( lm.connection.bless ( main.connection () ), who, args[1],
-			function ()
-				main.print_info ( who, 'OOB link accepted' )
-			end,
-			function ( mesg )
-				main.print_info ( who, 'OOB link refused: ' .. mesg )
-			end, args[2] )
-	end, true )
-
-local oob_handler_registered = false
+	end
+	return false
+end
 
-hooks_d['hook-post-connect'].oob =
-	function ( args )
-		local conn = lm.connection.bless ( main.connection () )
-		conn:handler ( oob_incoming_iq_handler, 'iq', 'normal' )
-		conn:handler ( oob_incoming_message_handler, 'message', 'normal' )
-		conn:handler ( oob_incoming_message_handler, 'presence', 'normal' )
-		oob_handler_registered = true
-		hooks_d['hook-post-connect'].oob = nil
-		hooks_d['hook-quit'].oob =
-			function ( args )
-				if oob_handler_registered then
-					local conn = lm.connection.bless ( main.connection () )
-					conn:handler ( oob_incoming_iq_handler, 'iq' )
-					conn:handler ( oob_incoming_message_handler, 'message' )
-					conn:handler ( oob_incoming_message_handler, 'presence' )
-				end
-			end
+function F.message_handler ( conn, mess )
+	local x = mess:child ( 'x' )
+	if x and x:attribute ( 'xmlns' ) == 'jabber:x:oob' then
+		local from = mess:attribute ( 'from' )
+		local url  = x:child( 'url' ):value ()
+		local desc = x:child( 'desc' )
+		if desc then
+			desc = desc:value ()
+		end
+		O.handler ( from, url, desc,
+			function ()
+			end,
+			function ()
+			end )
 	end
+	return false
+end
 
-main.add_feature ( 'jabber:iq:oob' )
-main.add_feature ( 'jabber:x:oob' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/pep.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/pep.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,16 +3,14 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 
--- public
+--
 
-pep = {
-	handlers = {},
-}
+local F = { }
 
-function pep.publish ( conn, node, item, success, fail )
+function F.publish ( conn, node, item, success, fail )
 --	local bjid = conn:jid():gsub ( '/.*', '' )
 --	item.id = 'current'
 	iq.send ( conn, nil, 'set',
@@ -36,56 +34,6 @@
 		}, success, fail )
 end
 
--- private
-
--- XXX in fact, it is not a pep handler, it is pubsub handler.
---     should it go there?
-local pep_incoming_message_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local e = mess:child ( 'event' )
-		if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/pubsub#event' then
-			local is = e:child ( 'items' )
-			if is then
-				local from = mess:attribute ( 'from' )
-				local node = is:attribute ( 'node' )
-				local item = is:child ( 'item' )
-				if item then
-					local handled = true -- XXX should we do this? well, if it becomes general pubsub handler - then no.
-					local n       = item:children ()
-					while n do
-						local xmlns = n:attribute ( 'xmlns' )
-						if pep.handlers[xmlns] then
-							if not pep.handlers[xmlns] ( from, node, n ) then
-								handled = false
-							end
-						else
-							handled = false
-						end
-						n = n:next ()
-					end
-					return handled
-				end
-			end
-		end
-		return false
-	end )
-
--- mcabber
-
-local pep_handler_registered = false
-
-hooks_d['hook-post-connect'].pep =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message', 'normal' )
-		pep_handler_registered = true
-		hooks_d['hook-post-connect'].pep = nil
-		hooks_d['hook-quit'].pep =
-			function ( args )
-				if pep_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message' )
-					pep_handler_registered = false
-				end
-			end
-	end
+return F
 
 -- vim: se ts=4: --
--- a/examples/ping.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/ping.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,72 +3,32 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 
--- public
+--
 
-ping = { }
+local F = { }
 
-function ping.send ( conn, to, success, fail )
+function F.send ( conn, to, success, fail )
 	iq.send ( conn, to, 'get',
 		{
 			ping = { xmlns = 'urn:xmpp:ping' },
 		}, success, fail )
 end
 
--- private
-
-local ping_incoming_iq_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local mtype, smtype = mess:type ()
-		if smtype == 'get' then
-			local p = mess:child ( 'ping' )
-			if p and p:attribute ( 'xmlns' ) == 'urn:xmpp:ping' then
-				conn:send ( lm.message.create { mtype = 'iq-result', to = mess:attribute ( 'from' ), id = mess:attribute ( 'id' ) } )
-				return true
-			end
-		end
-		return false
-	end )
-
--- mcabber
-
-main.command ( 'ping',
-	function ( args )
-		local who
-		if args[1] then
-			who = args[1]
-		else
-			who = main.full_jid ()
+function F.iq_handler ( conn, mess )
+	local mtype, smtype = mess:type ()
+	if smtype == 'get' then
+		local p = mess:child ( 'ping' )
+		if p and p:attribute ( 'xmlns' ) == 'urn:xmpp:ping' then
+			conn:send ( lm.message.create { mtype = 'iq-result', to = mess:attribute ( 'from' ), id = mess:attribute ( 'id' ) } )
+			return true
 		end
-		local time = os.time ()
-		ping.send ( lm.connection.bless ( main.connection () ), who,
-			function ()
-				main.print_info ( who, ('Pong: %d seconds'):format ( os.time () - time ) )
-			end,
-			function ( mesg )
-				main.print_info ( who, 'Ping failed: ' .. mesg )
-			end )
-	end, true, 'jid' )
-
---[[
-local ping_handler_registered = false
+	end
+	return false
+end
 
-hooks_d['hook-post-connect'].ping =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( ping_incoming_iq_handler, 'iq', 'normal' )
-		ping_handler_registered = true
-		hooks_d['hook-post-connect'].ping = nil
-		hooks_d['hook-quit'].ping =
-			function ( args )
-				if ping_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( ping_incoming_iq_handler, 'iq' )
-				end
-			end
-	end
-
-main.add_feature ( 'urn:xmpp:ping' )
---]]
+return F
 
 -- vim: se ts=4: --
--- a/examples/pubsub.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/pubsub.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,17 +3,51 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 require 'x_data'
 
--- public
+--
+
+local O = {
+	handlers = { },
+}
+
+local F = { }
+
+function F.handler ( xmlns, handler )
+	O.handlers[xmlns] = handler
+end
 
-pubsub = { }
+function F.message_handler ( conn, mess )
+	local e = mess:child ( 'event' )
+	if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/pubsub#event' then
+		local is = e:child ( 'items' )
+		if is then
+			local from = mess:attribute ( 'from' )
+			local node = is:attribute ( 'node' )
+			local item = is:child ()
+			while item do
+				local id = item:attribute ( 'id' )
+				local n  = item:child ()
+				while n do
+					local xmlns = n:attribute ( 'xmlns' )
+					if O.handlers[xmlns] then
+						O.handlers[xmlns] ( from, node, n, id )
+					end
+					n = n:next ()
+				end
+				item = item:next ()
+			end
+			return true
+		end
+	end
+	return false
+end
 
 -- SUBSCRIBER USE CASES
 
-function pubsub.subscribe ( conn, to, node, success, fail )
+function F.subscribe ( conn, to, node, success, fail )
 	local jid = conn:jid():gsub ( '/.*', '' )
 	iq.send ( conn, to, 'set',
 		{
@@ -32,7 +66,7 @@
 		fail )
 end
 
-function pubsub.unsubscribe ( conn, to, node, success, fail )
+function F.unsubscribe ( conn, to, node, success, fail )
 	local jid = conn:jid():gsub ( '/.*', '' )
 	iq.send ( conn, to, 'set',
 		{
@@ -45,7 +79,7 @@
 -- I found no servers with subscription options support thus it is not implemented.
 
 -- untested :(
-function pubsub.retrieve ( conn, to, node, success, fail, max, ids )
+function F.retrieve ( conn, to, node, success, fail, max, ids )
 	local items = { node = node, max_items = max }
 	if ids then
 		items.item = { }
@@ -64,7 +98,7 @@
 			if items then
 				local from = mess:attribute ( 'from' )
 				local node = items:attribute ( 'node' )
-				local item = items:children ()
+				local item = items:child ()
 				while item do
 					success ( from, node, item ) -- XXX use registered xmlns handlers for that?
 					item = item:next ()
@@ -78,7 +112,7 @@
 -- OWNER USE CASES
 
 -- node may be nil
-function pubsub.create_node ( conn, to, node, success, fail )
+function F.create_node ( conn, to, node, success, fail )
 	iq.send ( conn, to, 'set',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
@@ -99,7 +133,7 @@
 		end, fail )
 end
 
-function pubsub.delete_node ( conn, to, node, success, fail )
+function F.delete_node ( conn, to, node, success, fail )
 	iq.send ( conn, to, 'set',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
@@ -108,7 +142,7 @@
 		}, success, fail )
 end
 
-function pubsub.purge_node ( conn, to, node, success, fail )
+function F.purge_node ( conn, to, node, success, fail )
 	iq.send ( conn, to, 'set',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
@@ -117,7 +151,7 @@
 		}, success, fail )
 end
 
-function pubsub.configure_node ( conn, to, node, success, fail )
+function F.configure_node ( conn, to, node, success, fail )
 	iq.send ( conn, to, 'get',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
@@ -153,7 +187,7 @@
 		end, fail )
 end
 
-function pubsub.list_subscriptions ( conn, to, node, success, fail )
+function F.list_subscriptions ( conn, to, node, success, fail )
 	iq.send ( conn, to, 'get',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
@@ -163,7 +197,7 @@
 		function ( mess )
 			local s = mess:path ( 'pubsub', 'subscriptions' )
 			if s then
-				local sub = s:children ()
+				local sub = s:child ()
 				local ret = { }
 				while sub do
 					table.insert ( ret, { jid = sub:attribute ( 'jid' ), subscription = sub:attribute ( 'subscription' ), subid = sub:attribute ( 'subid' ) } )
@@ -176,7 +210,7 @@
 		end, fail )
 end
 
-function pubsub.modify_subscription ( conn, to, node, jid, state, success, fail, id )
+function F.modify_subscription ( conn, to, node, jid, state, success, fail, id )
 	iq.send ( conn, to, 'set',
 		{
 			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
@@ -187,150 +221,6 @@
 		}, success, fail )
 end
 
--- mcabber
-
-main.command ( 'node',
-	function ( args )
-		local who, action, node = args.t, args[1], args[2]
-		local conn = lm.connection.bless ( main.connection () )
-		if not who then
-			who = main.current_buddy ()
-		end
-		if action == 'subscribe' then
-			pubsub.subscribe ( conn, who, node,
-				function ( id )
-					if id then
-						main.print_info ( who, 'Subscription succeeds with id ' .. id )
-					else
-						main.print_info ( who, 'Subscription successful' )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Subscription unsuccessful: ' .. mesg )
-				end )
-		elseif action == 'unsubscribe' then
-			pubsub.unsubscribe ( conn, who, node,
-				function ()
-					main.print_info ( who, 'Unubscription successful' )
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Unsubscription unsuccessful: ' .. mesg )
-				end )
-		elseif action == 'retrieve' or action == 'items' or action == 'get' then
-			pubsub.retrieve ( conn, who, node,
-				function ( from, node, item )
-					main.print_info ( who, 'Item from ' .. from .. ', node ' .. node .. ':\n' .. item:xml () ) 
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Retrieval failed: ' .. mesg )
-				end, args.m )
-		elseif action == 'create' or action == 'new' then
-			pubsub.create_node ( conn, who, node,
-				function ( node )
-					if node then
-						main.print_info ( who, 'Node ' .. node .. ' successfully created' )
-					else
-						main.print_info ( who, 'Node successfully created' )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Creation failed: ' .. mesg )
-				end )
-		elseif action == 'delete' or action == 'del' then
-			pubsub.delete_node ( conn, who, node,
-				function ()
-					main.print_info ( who, 'Node deleted' )
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Node deletion failed: ' .. mesg )
-				end )
-		elseif action == 'purge' or action == 'del_items' then
-			pubsub.purge_node ( conn, who, node,
-				function ()
-					main.print_info ( who, 'Node purged' )
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Node purge failed: ' .. mesg )
-				end )
-		elseif action:sub ( 1, 4 ) == 'conf' then
-			pubsub.configure_node ( conn, who, node,
-				function ( form, submit, reject )
-					local id = #forms + 1
-					forms[id] = {
-						form = form,
-						submit =
-							function ( form )
-								submit ( form,
-									function ()
-										main.print_info ( who, 'Node configuration completed' )
-									end,
-									function ( mesg )
-										main.print_info ( who, 'Node configuration failed: ' .. mesg )
-									end )
-							end,
-						reject =
-							function ( form )
-								reject ( form,
-									function ()
-										main.print_info ( who, 'Node configuration cancelled' )
-									end,
-									function ( mesg )
-										main.print_info ( who, 'Node configuration cancellation failed: ' .. mesg )
-									end )
-							end,
-					}
-					print ( 'You have new form ' .. id )
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Node configuration failed: ' .. mesg )
-				end )
-		elseif action == 'subscriptions' or action == 'subscribers' then
-			pubsub.list_subscriptions ( conn, who, node,
-				function ( s )
-					local text = ''
-					for i, v in ipairs ( s ) do
-						local subid = v.subid
-						if subid then
-							subid = '(id ' .. subid .. ')'
-						else
-							subid = ''
-						end
-						text = text .. ('\n- [%s] %s %s'):format ( v.subscription, v.jid, subid )
-					end
-					if text ~= '' then
-						main.print_info ( who, 'Node subscriptions:' .. text )
-					else
-						main.print_info ( who, 'No subscriptions' )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Node subscriptions retrieval failed: ' .. mesg )
-				end )
-		elseif action == 'subscription' or action == 'modify' then -- XXX
-			pubsub.modify_subscription ( conn, args.t or main.current_buddy (), node, args[3], args[4],
-				function ()
-					main.print_info ( who, 'Subscription modified' )
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Subsrciption modification failed: ' .. mesg )
-				end, args[5] )
-		else
-			print ( 'Error: unknown action' )
-		end
-	end, true )
-
--- FIXME
-commands_help['node']           = "[-t jid] [-m max_items] action [node_name]\n\nAction can be subscribe, unsubscribe, retrieve (items, get), create (new), delete (del), purge (del_items), configure (conf*), subscriptions (subscribers), subscription (modify?)"
---[[
-commands_help['subscribe']      = "[-t jid] node_name\n\nSends pubsub subscription request to specified node of jid or current buddy."
-commands_help['unsubscribe']    = "[-t jid] node_name\n\nSends pubsub unsubscription request to specified node of jid or current buddy."
-commands_help['retrieve']       = "[-t jid] [-m max_items] node_name\n\nSends pubsub items retrieval request to specified node of jid or current buddy.\nNote, that we cannot know, how to deal with these itemss, so, raw xml will be printed as a result."
-commands_help['create_node']    = "[-t jid] [node_name]\n\nSends pubsub node creation request to specified node of jid or current buddy. If node name is not specified, server can generate unique id for it, if supported."
-commands_help['configure_node'] = "[-t jid] node_name\n\nSends pubsub node configuration request to specified node of jid or current buddy."
-commands_help['delete_node']    = "[-t jid] node_name\n\nSends pubsub node deletion request to specified node of jid or current buddy."
-commands_help['purge_node']     = "[-t jid] node_name\n\nSends pubsub node items purging request to specified node of jid or current buddy."
-commands_help['subscriptions']  = "[-t jid] node_name\n\nSends pubsub subscription list request to specified node of jid or current buddy."
-commands_help['subscription']   = "[-t jid] node_name subscriber_jid state [subscription_id]\n\nSends pubsub subscription modification request to change subscription state of 'subscriber_jid' to 'state'. Optional id is used when multiple subscriptions for one jid are available."
---]]
+return F
 
 -- vim: se ts=4: --
--- a/examples/remote.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/remote.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,10 +3,10 @@
 
 -- library
 
-require 'lm'
-local iq = require 'iq'
+local lm    = require 'lm'
+local iq    = require 'iq'
 require 'x_data'
-require 'disco'
+local disco = require 'disco'
 
 -- public
 
--- a/examples/tune.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/tune.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,15 +3,13 @@
 
 -- library
 
-require 'lm'
-require 'pep'
-require 'mpd'
+local pep = require 'pep'
+
+--
 
--- public
+local F = { }
 
-tune = { }
-
-function tune.publish ( conn, node, success, fail, data )
+function F.publish ( conn, node, success, fail, data )
 	local item = { xmlns = 'http://jabber.org/protocol/tune' }
 	if data then
 		for key, value in pairs ( data ) do
@@ -21,147 +19,6 @@
 	pep.publish ( conn, 'http://jabber.org/protocol/tune', { tune = item }, success, fail )
 end
 
--- mcabber
-
-local tune_enabled = false
-local mpd_pub_song = { }
-
-pep.handlers['http://jabber.org/protocol/tune'] =
-	function ( from, node, data )
-		local self = false
-		if from == lm.connection.bless ( main.connection () ):jid():gsub ( '/.*', '' ) then -- o_O
-			self         = true
-			mpd_pub_song = { }
-		end
-		local item = data:children ()
-		local text = ''
-		while item do
-			local name  = item:name ()
-			local value = item:value ()
-			if self then
-				mpd_pub_song[name] = value or ''
-			end
-			text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
-			item = item:next ()
-		end
-		if main.yesno ( main.option ( 'lua_pep_notification' ) ) then
-			if text ~= '' then
-				text = 'Now listening to:' .. text
-			else
-				text = 'Now not listening to anything'
-			end
-		end
-		main.print_info ( from, text )
-		return true
-	end
-
-local function mpd_getstatus ()
-	local status = mpd.call_command { 'status' }
-	if not tune_enabled or ( status.state ~= 'play' and status.state ~= 'pause' ) then
-		for k, v in pairs ( mpd_pub_song ) do -- if there is anything published, publish nothing
-			return { }
-		end
-		return nil
-	end
-	
-	local song      = mpd.call_command { 'currentsong' }
-	local dir, file = song.file:match ( '(.+)/(.-)' )
-	-- populate according to currentsong fields: artist - artist, length - time, source - album, title - title, track - id, rating - ?, uri - ?
-	local ret = {
-		artist = song.artist or 'Unknown',
-		length = song.time,
-		source = song.album  or dir,
-		title  = song.title  or file,
-		track  = song.id,
-	}
-
-	if not song.time or song.time == '0' then -- XXX
-		ret.length = nil
-	end
-
-	local modified = false
-	for k, v in pairs ( ret ) do
-		if mpd_pub_song[k] ~= v then
-			modified = true
-			break
-		end
-	end
-	if not modified then
-		for k, v in pairs ( mpd_pub_song ) do
-			if ret[k] ~= v then
-				modified = true
-				break
-			end
-		end
-	end
-
-	if modified then
-		return ret
-	else
-		return nil
-	end
-end
-
-local function mpd_callback ()
-	local sdata = mpd_getstatus ()
-	if sdata then
-		pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/tune',
-			function ()
-			end,
-			function ( mesg )
-				print ( 'Error publishing tune: ' .. mesg )
-			end, sdata )
-	end
-	if tune_enabled then
-		return true
-	else
-		return false
-	end
-end
-
--- do not call it too fast, or you end up with many daemons at once
-local function enable_tune ( yn )
-	if yn == nil then
-		yn = true
-	end
-	if yn then
-		if not tune_enabled then
-			main.timer ( 15, mpd_callback )
-			tune_enabled = true
-			-- update status
-		end
-	else
-		if tune_enabled then
-			tune_enabled = false
-			-- update status
-		end
-	end
-end
-
-main.command ( 'tune',
-	function ( args )
-		local enable = main.yesno ( args )
-		if enable == nil then
-			if tune_enabled then
-				print ( "Tune notifications enabled" )
-			else
-				print ( "Tune notifications disabled" )
-			end
-		else
-			enable_tune ( enable )
-		end
-	end, false, 'yesno' )
-
-commands_help['tune'] = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables publishing of notifications about playing music in your player (currently only mpd is supported)."
-
-hooks_d['hook-post-connect'].tune =
-	function ( args )
-		if tune_enabled then
-			mpd_callback ()
-		end
-	end
-
-main.add_feature ( 'http://jabber.org/protocol/tune+notify' )
-main.add_feature ( 'http://jabber.org/protocol/tune' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/vcard.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/vcard.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,7 +3,7 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 local iq = require 'iq'
 require 'x_data'
 
--- a/examples/x_data.lua	Fri Mar 27 09:48:17 2009 +0200
+++ b/examples/x_data.lua	Fri Mar 27 12:06:19 2009 +0200
@@ -3,7 +3,7 @@
 
 -- library
 
-require 'lm'
+local lm = require 'lm'
 
 -- public
 
@@ -47,7 +47,7 @@
 		f.instructions = instructions:value ()
 	end
 
-	local field = x:children ()
+	local field = x:child ()
 	while field do
 		if field:name () == 'field' then
 			local ftype = field:attribute ( 'type' ) or 'text-single'
@@ -69,7 +69,7 @@
 				local values  = { }
 				local options = { }
 
-				local item = field:children ()
+				local item = field:child ()
 				while item do
 					local name = item:name ()
 					if name == 'value' then
--- a/examples/xep0004.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-
-forms = { }
-form_cid = main.add_category { 'del', 'send' }
-
-function insert_form ( form )
-	table.insert ( forms, form )
-	main.add_completion ( form_cid, tostring(#forms) )
-	return #forms
-end
-
--- expects lm node   x = { xmlns = 'jabber:x:data', type = 'form', ... }
--- returns form index in forms table, you can do whatever you want to upper level table, except exp and val fields.
-function parse_form ( node )
-	local form = { title = 'unknown', exp = '', val = { } }
-	if node:child ( 'title' ) then
-		form.title = node:child( 'title' ):value ()
-	end
-	if node:child ( 'instructions' ) then
-		form.exp = form.exp .. 'Instructions: ' .. node:child( 'instructions' ):value () .. '\n'
-	end
-	form.exp = form.exp .. 'Fields:\n'
-	local field = node:children ()
-	while field do
-		if field:name () == 'field' then
-			local field_type  = field:attribute ( 'type' ) or 'text-single'
-			local field_var   = field:attribute ( 'var' ) or ''
-			form.exp = form.exp .. ' - ' .. field_var .. '\n   Type: ' .. field_type .. '\n'
-			if field:attribute ( 'label' ) then
-				form.exp = form.exp .. '   Label: ' .. ( field:attribute ( 'label' ) or '' ) .. '\n'
-			end
-			if field:child ( 'desc' ) then
-				form.exp = form.exp .. '   Description: ' .. field:child( 'desc' ):value () .. '\n'
-			end
-			if field:child ( 'required' ) then
-				form.exp = form.exp .. '   Required: yes\n'
-			end
-
-			local field_value
-			if field_type == 'jid-multi' or field_type == 'list-multi' or field_type == 'text-multi' then
-				field_value = { }
-				local value = field:children ()
-				form.exp = form.exp .. '   Default values:\n'
-				while value do
-					if value:name () == 'value' then
-						table.insert ( field_value, { value:value () } )
-						form.exp = form.exp .. '    - ' .. value:value () .. '\n'
-					end
-					value = value:next ()
-				end
-			else
-				if field:child ( 'value' ) then
-					field_value = field:child( 'value' ):value ()
-					form.exp = form.exp .. '   Default value: ' .. (field_value or '') .. '\n'
-				end
-			end
-
-			if field_type == 'list-single' or field_type == 'list-multi' then
-				form.exp = form.exp .. '   List options:\n'
-				local option = field:children ()
-				while option do
-					if option:name () == 'option' then
-						form.exp = form.exp .. '    - ' .. ( option:child( 'value' ):value () or '' ) .. ': ' .. ( option:attribute ( 'label' ) or '' ) .. '\n'
-					end
-					option = option:next ()
-				end
-			end
-
-			if field_type == 'boolean' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '0' } } )
-			elseif field_type == 'fixed' then
-			elseif field_type == 'hidden' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
-			elseif field_type == 'list-single' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
-			elseif field_type == 'list-multi' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = field_value or { } } )
-			elseif field_type == 'jid-multi' or field_type == 'text-multi' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = field_value or { } } )
-			elseif field_type == 'jid-single' or field_type == 'text-single' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
-			elseif field_type == 'text-private' then
-				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
-			end
-		end
-		field = field:next ()
-	end
-	return insert_form ( form )
-end
-
-function form_set ( id, name, value )
-	if forms[id] then
-		for index, field in ipairs ( forms[id].val ) do
-			if field.var == name then
-				if value == nil then
-					field.value = { }
-				else
-					if field.type == 'jid-multi' or field.type == 'list-multi' or field.type == 'text-multi' then
-						table.insert ( field.value, { value } )
-					else
-						field.value = { value }
-					end
-				end
-			end
-		end
-	end
-end
-
-main.command ( 'form',
-	function ( args )
-		local action = args[1]
-		local id = tonumber (args[1])
-		if forms[id] then
-			local field = args[2]
-			if field then
-				local value = args[3]
-				if value == 'clear' then
-					value = nil
-				elseif value == 'set' then
-					value = args[4]
-				end
-				form_set ( id, field, value )
-			else
-				print ( 'Form: ' .. ( forms[id].title or '' ) .. '\n' .. forms[id].exp )
-				local text = 'Fields:'
-				for index, field in ipairs ( forms[id].val ) do -- this should not be here, but setting up callback just for this...
-					if field.type == 'jid-multi' or field.type == 'list-multi' or field.type == 'text-multi' then
-						text = text .. '\n - ' .. field.var .. ' [' .. field.type .. ']:'
-						for vin, value in ipairs ( field.value ) do
-							text = text .. '\n    * ' .. value[1]
-						end
-					else
-						text = text .. '\n - ' .. field.var .. ' [' .. field.type .. ']: ' .. field.value[1]
-					end
-				end
-				print ( text )
-			end
-		elseif action == 'del' then
-			forms[tonumber(args[2])] = nil
-			main.del_completion ( form_cid, tostring(args[2]) )
-		elseif action == 'send' then
-			local form = forms[tonumber(args[2])]
-			if form then
-				form.send ( form )
-			end
-		else
-			local text = ''
-			for id, form in pairs ( forms ) do
-				text = text .. '\n - ' .. id .. ' ' .. form.title .. ' [' .. ( form.status or 'unknown' ) .. ']'
-			end
-			if text ~= '' then
-				print ( 'Forms list:' .. text )
-			else
-				print ( 'No forms' )
-			end
-		end
-	end, true, form_cid )
-
-commands_help['form'] = "[del form_id | send form_id | form_id [field_name {clear | [set] value}]\n\nWith bare form id prints info on that form.\nWith field name sets or clears field value. Set subcommand is optional, just to allow values, starting with 'clear'.\nWithout arguments prints form list."
-
--- vim: se ts=4: --
--- a/examples/xep0030.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-
-function disco_items ( connection, callback, what, node )
-	local request =
-		lm.message.create { to = what, mtype = 'iq-get',
-			query = { xmlns = 'http://jabber.org/protocol/disco#items' }
-		}
-	if node then
-		request:child( 'query' ):attribute ( 'node', node )
-	end
-	return connection:send ( request,
-		function ( conn, message )
-			if message:child ( 'error' ) then
-				callback ( message:child( 'error' ):children():name () )
-			else
-				local item = message:child( 'query' ):children ()
-				local items = { }
-				while item do
-					if item:name () == 'item' then
-						table.insert ( items, { jid = item:attribute ( 'jid' ), node = item:attribute ( 'node' ), name = item:attribute ( 'name' ) } )
-					end
-					item = item:next ()
-				end
-				callback ( items )
-			end
-			return true
-		end )
-end
-
-function disco_info ( connection, callback, what )
-	return connection:send (
-		lm.message.create { to = what, mtype = 'iq-get',
-			query = { xmlns='http://jabber.org/protocol/disco#info' }
-		},
-		function ( conn, message )
-			local items_supported = false
-			if message:child ( 'error' ) then
-				callback ( message:child( 'error' ):children():name () )
-			else
-				local item = message:child( 'query' ):children ()
-				local identities = { }
-				local features   = { }
-				while item do
-					if item:name () == 'identity' then
-						table.insert ( identities, { category = item:attribute ( 'category' ), type = item:attribute ( 'type' ), name = item:attribute ( 'name' ) } )
-					elseif item:name () == 'feature' then
-						table.insert ( features, item:attribute ( 'var' ) )
-					end
-					item = item:next ()
-				end
-				callback ( identities, features )
-			end
-			return true
-		end )
-end
-
-main.command ( 'disco',
-	function ( args )
-		local who
-		local conn = lm.connection.bless ( main.connection () )
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
-		end
-		if args[1] == 'items' then
-			local node = args[2]
-			disco_items ( conn,
-				function ( items )
-					if type ( items ) == 'string' then
-						main.print_info ( who, ("Items service discovery for %s (%s) failed: %s"):format ( who, node or '', items ) )
-					else
-						local text = ''
-						for index, item in ipairs ( items ) do
-							text = text .. ("\n    [%s (%s)] %s"):format ( item.jid or '', item.node or '', item.name or '' )
-						end
-						if text ~= '' then
-							main.print_info ( who, ("Items service discovery result for %s (%s):%s"):format ( who, node or '', text ) )
-						else
-							main.print_info ( who, ("No items in discovery result for %s (%s)"):format ( who, node or '' ) )
-						end
-					end
-				end, who, node )
-		else
-			disco_info ( conn,
-				function ( identities, features )
-					if type ( identities ) == 'string' then
-						main.print_info ( who, ("Info service discovery for %s failed: %s"):format ( who, identities ) )
-					else
-						main.print_info ( who, ("Service info discovery result for %s:"):format ( who ) )
-						local text = ''
-						for index, identity in ipairs ( identities ) do
-							text = text .. ("\n    [%s (%s)] %s"):format ( identity.category or '', identity.type or '', identity.name or '' )
-						end
-						if text ~= '' then
-							main.print_info ( who, "  Identities:" .. text )
-						else
-							main.print_info ( who, "  No identities" )
-						end
-						text = ''
-						for index, feature in ipairs ( features ) do
-							text = text .. ("\n    [%s]"):format ( feature or '' )
-						end
-						if text ~= '' then
-							main.print_info ( who, "  Features:" .. text )
-						else
-							main.print_info ( who, "  No features" )
-						end
-					end
-				end, who )
-		end
-	end, true, 'jid' )
-
-commands_help['disco'] = "[-t target_jid] [info | items] [node]\n\nService discovery request.\nInfo is sent if omitted."
-
--- vim: se ts=4: --
--- a/examples/xep0047.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-
-receiving_files = {}
-ibb_block_size  = 4096
-local ibb_sid = 0
-
-ibb_incoming_iq_handler = lm.message_handler.new ( 
-	function ( conn, mess )
-		local id   = mess:attribute ( 'id' )
-		local from = mess:attribute ( 'from' )
-
-		local open = mess:child ( 'open' )
-		if open and open:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = open:attribute ( 'sid' )
-			if not receiving_files[sid] then
-				local buffer = ''
-				receiving_files[sid] = { from = from, status = 'pending' }
-				receiving_files[sid].accept =
-					function ( name )
-						main.print_info ( from, string.format ( "Receiving stream from %s, id %s", from, sid ) )
-						conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-						receiving_files[sid].name = name
-						receiving_files[sid].status = 'accepted'
-					end
-				receiving_files[sid].reject =
-					function ()
-						conn:send (
-							lm.message.create { to = from, mtype = 'iq-error', id = id,
-								error = { code = '405', type = 'cancel',
-									['not-allowed'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
-								}
-							} )
-						receiving_files[sid].status = 'rejected'
-					end
-				print ( 'You have a new bytestream to receive. To save it use /ibb accept ' .. sid .. ' filename' )
-			else
-				conn:send (
-					lm.message.create { to = from, mtype = 'iq-error', id = id,
-						error = { code = '409', type = 'cancel',
-							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
-						}
-					} )
-			end
-			return true
-		end
-
-		local qdata = mess:child ( 'data' )
-		if qdata and qdata:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = qdata:attribute ( 'sid' )
-			local seq  = qdata:attribute ( 'seq' )
-			if receiving_files[sid] and from == receiving_files[sid].from and not receiving_files[sid][tonumber(seq)+1] then
-				local data = qdata:value ()
-				main.print_info ( from, string.format ( " - stream part %s, id %s, %d bytes", seq, sid, data:len() ) )
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				receiving_files[sid][tonumber(seq)+1] = data
-			else
-				receiving_files[sid] = nil -- invalidate session
-				conn:send (
-					lm.message.create { to = from, mtype = 'iq-error', id = id,
-						error = { code = '409', type = 'cancel',
-							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
-						}
-					} )
-			end
-			return true
-		end
-
-		local close = mess:child ( 'close' )
-		if close and close:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = close:attribute ( 'sid' )
-			if receiving_files[sid] and from == receiving_files[sid].from then
-				main.print_info ( from, "Done with stream id " .. sid )
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				local decoder = io.popen ( string.format ( "base64 -d -i >%q", receiving_files[sid].name ), "w" )
-				if not decoder then
-					main.print_info ( from, "Error opening decoder" )
-				else
-					for i, v in ipairs ( receiving_files[sid] ) do
-						decoder:write ( v )
-					end
-					decoder:close ()
-				end
-			else
-				receiving_files[sid] = nil -- invalidate session
-				conn:send (
-					lm.message.create { to = from, mtype = 'iq-error', id = id,
-						error = { code = '409', type = 'cancel',
-							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
-						}
-					} )
-			end
-			return true
-		end
-
-		return false
-	end )
-
-function ibb_send_file ( conn, to, name, id )
-	if not to then
-		to = main.full_jid ()
-	elseif not to:match ( "/" ) then
-		to = main.full_jid ( to )
-	end
-	local sid = id
-	if not sid then -- XXX: move out of here?
-		ibb_sid = ibb_sid + 1
-		sid = 'ibb_' .. ibb_sid
-	end
-	conn:send (
-		lm.message.create { to = to, mtype = 'iq-set',
-			open = { sid = sid, ['block-size'] = ibb_block_size, xmlns = 'http://jabber.org/protocol/ibb' }
-		},
-		function ( conn, message )
-			if message:child ( 'error' ) then
-				main.print_info ( to, "Stream request refused: " .. message:child( 'error' ):children():name () )
-			else
-				main.print_info ( to, "Stream accepted, starting sequence" )
-				local buffer = ''
-				main.bgread ( string.format ( 'base64 -w 0 %q', name ), -- FIXME: stream reader function? XXX: then we need in-place base64 encoder.
-					function ( data )
-						if data then
-							buffer = buffer .. data
-							return true
-						else
-							local seq = 0
-							local msgbuf = buffer:sub ( 1, ibb_block_size )
-							buffer = buffer:sub ( ibb_block_size + 1 )
-							local function handler ( conn, mess )
-								local mtype, smtype = mess:type ()
-								if smtype == 'error' then
-									main.print_info ( to, "Stream error, transfer ceased at seq = " .. seq .. ": " .. message:child( 'error' ):children():name () )
-								elseif smtype == 'result' then
-									main.print_info ( to, " - acquired seq = " .. seq )
-									seq = seq + 1
-									if buffer:len () == 0 then
-										conn:send (
-											lm.message.create { to = to, mtype = 'iq-set',
-												close = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb' }
-											},
-											function ( conn, mess )
-												local mtype, smtype = mess:type ()
-												if smtype == 'error' then
-													main.print_info ( to, "Error at closing stream: " .. mess:child( 'error' ):children():name () )
-												elseif smtype == 'result' then
-													main.print_info ( to, "File successfully transferred" )
-												else
-													print ( 'Weird response for close of ibb stream: ' .. mess:xml () )
-													return false
-												end
-												return true
-											end )
-									else
-										local msgbuf = buffer:sub ( 1, ibb_block_size )
-										buffer = buffer:sub ( ibb_block_size )
-										conn:send (
-											lm.message.create { to = to, mtype = 'iq-set',
-												data = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb', seq = seq,
-													msgbuf
-												}
-											},
-											handler )
-									end
-								else
-									print ( 'Weird response for ibb block: ' .. mess:xml () )
-									return false
-								end
-								return true
-							end
-							conn:send (
-								lm.message.create { to = to, mtype = 'iq-set',
-									data = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb', seq = seq,
-										msgbuf
-									}
-								},
-								handler )
-							return false
-						end
-					end )
-			end
-			return true
-		end )
-end
-
-main.command ( 'ibb',
-	function ( args )
-		local action = args[1]
-		if action == 'send' then
-			local who
-			if args.t then
-				who = args.t
-			else
-				who = main.full_jid ()
-			end
-			ibb_send_file ( lm.connection.bless ( main.connection () ), who, args[2] )
-		elseif action == 'accept' then
-			local id = args[2]
-			if receiving_files[id] then
-				receiving_files[id].accept ( args[3] )
-			end
-		elseif action == 'reject' then
-			local id = args[2]
-			if receiving_files[id] then
-				receiving_files[id].reject ()
-			end
-		elseif action == 'del' then
-			local id = args[2]
-			receiving_files[id] = nil
-		else
-			local text = ''
-			for sid, data in pairs ( receiving_files ) do
-				text = text .. '\n' ..  sid .. ': ' .. ( data.name or '(not set)' ) .. ' [' .. data.status .. ']'
-			end
-			if text ~= '' then
-				print ( 'List of incoming streams:' .. text )
-			else
-				print ( 'No streams' )
-			end
-		end
-	end, true, { "send", "accept", "reject", "del" } )
-
-commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid filename | del sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."
-
-hooks_d['hook-post-connect'].xep0047 =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
-		ibb_handler_registered = true
-		hooks_d['hook-post-connect'].xep0047 = nil
-		hooks_d['hook-quit'].xep0047 =
-			function ( args )
-				if ibb_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
-				end
-			end
-	end
-
-main.add_feature ( 'http://jabber.org/protocol/ibb' )
-
--- vim: se ts=4: --
--- a/examples/xep0060.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-
--- SUBSCRIBER USE CASES
-
-function pubsub_subscribe ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	local jid = conn:jid():gsub ( '/.*', '' )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to, -- from = conn:jid (),
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
-				subscribe = { node = node, jid = jid },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				local s = mess:path ( 'pubsub', 'subscription' )
-				local info
-				if s then
-					local id = s:attribute ( 'subid' )
-					if not id then
-						id = 'unspecified'
-					end
-					info = ('%s is now %s to node %s (id %s)'):format ( s:attribute ( 'jid' ), s:attribute ( 'subscription' ), s:attribute ( 'node' ), id )
-				else
-					info = 'Subscription successful, but server supplied no info about it...'
-				end
-				main.print_info ( to, info )
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for subscription request: ' .. mess:xml () ) -- FIXME
-				-- XXX: handle configuration forms?
-				return true
-			else
-				print ( 'Weird response for subscription request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_unsubscribe ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	local jid = conn:jid():gsub ( '/.*', '' )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
-				unsubscribe = { node = node, jid = jid },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				main.print_info ( to, 'Unsubscription successful' )
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for unsubscription request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for unsubscription request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
--- I found no servers with subscription options support thus it is not implemented.
-
--- untested :(
-function pubsub_retrieve ( to, node, handler, max, ids )
-	local items = { node = node, max_items = max }
-	if ids then
-		items.item = { }
-		for k, id in pairs ( ids ) do
-			table.insert ( items.item, { id = id } )
-		end
-	end
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
-				items = items,
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				local items = mess:path ( 'pubsub', 'items' )
-				if items then
-					local item = items:children ()
-					while item do
-						-- we cannot know, what item contains
-						handler ( item )
-						item = item:next ()
-					end
-				end
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for items retrieval request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for items retrieval request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
--- OWNER USE CASES
-
--- node may be nil
-function pubsub_create_node ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
-				create = { node = node },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				if node then
-					main.print_info ( to, 'Node ' .. node .. ' successfully created' )
-				else
-					local create = mess:path ( 'pubsub', 'create' )
-					if create then
-						local nid = create:attribute ( 'node' )
-						main.print_info ( to, 'Node created, id ' .. (nid or 'unspecified') )
-					else
-						main.print_info ( to, 'Node created, but no id provieded' )
-					end
-				end
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node creation request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node creation request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_delete_node ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-				delete = { node = node },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				main.print_info ( to, 'Node ' .. node .. ' successfully deleted' )
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node deletion request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node deletion request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_purge_node ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-				purge = { node = node },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				main.print_info ( to, 'Node ' .. node .. ' items successfully purged' )
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node items purging request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node items purging request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_configure_node ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-get', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-				configure = { node = node },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				local x = mess:path ( 'pubsub', 'configure', 'x' )
-				if x then
-					local fid = parse_form ( x )
-					forms[fid].send =
-						function ( form )
-							conn:send (
-								lm.message.create { mtype = 'iq-set', to = to,
-									pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-										configure = { node = node,
-											x = { xmlns = 'jabber:x:data', type = 'submit',
-												field = form.val,
-											},
-										},
-									},
-								},
-								function ( conn, mess )
-									local mt, st = mess:type ()
-									if st == 'result' then
-										main.print_info ( to, 'Now you can run /form del ' .. fid .. ' to delete form from list' )
-										form.status = 'acquired'
-									elseif st == 'error' then
-										main.print_info ( to, 'Got non-successful response to form:\n' .. mess:xml () )
-										form.status = 'rejected'
-									else
-										print ( 'Weird response to submitted form:\n' .. mess:xml () )
-										form.status = 'unknown'
-										return false
-									end
-									return true
-								end )
-							form.status = 'sent'
-						end
-					forms[fid].status = 'filling'
-					main.print_info ( to, 'You have new form. To fill it, use /form ' .. fid .. ' fieldname value' )
-				else
-					main.print_info ( to, 'Weird, no error and no node configuration form: ' .. mess:xml () )
-				end
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node configuration request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node configuration request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_list_subscriptions ( to, node )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-get', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-				subscriptions = { node = node },
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				local s = mess:path ( 'pubsub', 'subscriptions' )
-				if s then
-					local sub = s:children ()
-					main.print_info ( to, "List of subscriptions for node " .. node )
-					while sub do
-						local subid = sub:attribute ( 'subid' ) or 'unspecified'
-						main.print_info ( to, ("%s is %s (id %s)"):format ( sub:attribute ( 'jid' ), sub:attribute ( 'subscription' ), subid ) )
-						sub = sub:next ()
-					end
-				else
-					main.print_info ( to, 'Weird response to node subscription list request: ' .. mess:xml () )
-				end
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node subscription list request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node subscription list request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
-function pubsub_modify_subscription ( to, node, who, state, id )
-	local conn = lm.connection.bless ( main.connection () )
-	conn:send (
-		lm.message.create { mtype = 'iq-get', to = to,
-			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
-				subscriptions = { node = node,
-					subscription = { jid = who, subscription = state, id = id },
-				},
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				main.print_info ( to, ('Subscription of %s to %s is successfully set to %s (id %s)'):format ( who, node, state, id or 'unspecified' ) )
-				return true
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Error response for node subscription list request: ' .. mess:xml () ) -- FIXME
-				return true
-			else
-				print ( 'Weird response for node subscription list request: ' .. mess:xml () )
-				return false
-			end
-		end )
-end
-
--- INTERFACE
-
-main.command ( 'node',
-	function ( args )
-		local who, action, node = args.t, args[1], args[2]
-		if not who then
-			who = main.current_buddy ()
-		end
-		if action == 'subscribe' then
-			pubsub_subscribe ( who, node )
-		elseif action == 'unsubscribe' then
-			pubsub_unsubscribe ( who, node )
-		elseif action == 'retrieve' or action == 'items' or action == 'get' then
-			pubsub_retrieve ( who, node,
-				function ( item )
-					main.print_to ( who, item:xml () ) 
-				end, args.m )
-		elseif action == 'create' or action == 'new' then
-			pubsub_create_node ( who, node )
-		elseif action == 'delete' or action == 'del' then
-			pubsub_delete_node ( who, node )
-		elseif action == 'purge' or action == 'del_items' then
-			pubsub_purge_node ( who, node )
-		elseif action:sub ( 1, 4 ) == 'conf' then
-			pubsub_configure_node ( who, node )
-		elseif action == 'subscriptions' or action == 'subscribers' then
-			pubsub_list_subscriptions ( who, node )
-		elseif action == 'subscription' or action == 'modify' then -- XXX
-			pubsub_modify_subscription ( args.t or main.current_buddy (), node, args[3], args[4], args[5] )
-		else
-			print ( 'Error: unknown action' )
-		end
-	end, true )
-
--- FIXME
-commands_help['node']           = "[-t jid] [-m max_items] action [node_name]\n\nAction can be subscribe, unsubscribe, retrieve (items, get), create (new), delete (del), purge (del_items), configure (conf*), subscriptions (subscribers), subscription (modify?)"
---[[
-commands_help['subscribe']      = "[-t jid] node_name\n\nSends pubsub subscription request to specified node of jid or current buddy."
-commands_help['unsubscribe']    = "[-t jid] node_name\n\nSends pubsub unsubscription request to specified node of jid or current buddy."
-commands_help['retrieve']       = "[-t jid] [-m max_items] node_name\n\nSends pubsub items retrieval request to specified node of jid or current buddy.\nNote, that we cannot know, how to deal with these itemss, so, raw xml will be printed as a result."
-commands_help['create_node']    = "[-t jid] [node_name]\n\nSends pubsub node creation request to specified node of jid or current buddy. If node name is not specified, server can generate unique id for it, if supported."
-commands_help['configure_node'] = "[-t jid] node_name\n\nSends pubsub node configuration request to specified node of jid or current buddy."
-commands_help['delete_node']    = "[-t jid] node_name\n\nSends pubsub node deletion request to specified node of jid or current buddy."
-commands_help['purge_node']     = "[-t jid] node_name\n\nSends pubsub node items purging request to specified node of jid or current buddy."
-commands_help['subscriptions']  = "[-t jid] node_name\n\nSends pubsub subscription list request to specified node of jid or current buddy."
-commands_help['subscription']   = "[-t jid] node_name subscriber_jid state [subscription_id]\n\nSends pubsub subscription modification request to change subscription state of 'subscriber_jid' to 'state'. Optional id is used when multiple subscriptions for one jid are available."
---]]
-
--- vim: se ts=4: --
--- a/examples/xep0066.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-
--- OUT OF BAND DATA
-
--- we can do more - use external command to put file on server,
--- read it's output for link, and then send that link.
--- that will be much more convenient.
-function oob_send_link ( conn, to, url, desc )
-	if desc then
-		desc = { desc }
-	end
-	conn:send (
-		lm.message.create { mtype = 'iq-set', to = to,
-			query = { xmlns = 'jabber:iq:oob',
-				url = { url },
-				desc = desc,
-			},
-		},
-		function ( conn, mess )
-			local mtype, smtype = mess:type ()
-			if smtype == 'result' then
-				main.print_info ( to, 'Url is successfully downloaded' )
-			elseif smtype == 'error' then
-				main.print_info ( to, 'Url is not accepted: ' .. mess:child( 'error' ):children():name () )
-			else
-				print ( 'Weird response to oob url: ' .. mess:xml () )
-				return false
-			end
-			return true
-		end )
-end
-
-oob_incoming_iq_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local mtype, smtype = mess:type ()
-		if smtype == 'set' then
-			local query = mess:child ( 'query' )
-			if query and query:attribute ( 'xmlns' ) == 'jabber:iq:oob' then
-				local url  = query:child( 'url' ):value ()
-				local desc = query:child( 'desc' )
-				if desc then
-					desc = ('(%s)'):format ( desc:value () )
-				else
-					desc = ''
-				end
-				main.print_info ( mess:attribute ( 'from' ), ('Buddy wants you to download url: %s %s'):format ( url, desc ) )
-
-				-- FIXME: in fact, we need to register file and after downloading (or rejecting) should send a notification to sender,
-				-- but first we need to develop common file infrastructure (as with forms, though even that still needs redesign)
-				-- however, to be nice (in hope, that others also would be nice to us :), we'll send reply right now.
-				-- this saves memory and resources for pending handlers on the other side.
-				conn:send ( lm.message.create { mtype = 'iq-result', to = mess:attribute ( 'from' ), id = mess:attribute ( 'id' ) } )
-
-				return true
-			end
-		end
-		return false
-	end )
-oob_incoming_message_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local x = mess:child ( 'x' )
-		if x and x:attribute ( 'xmlns' ) == 'jabber:x:oob' then
-			local url = x:child( 'url' ):value ()
-			local desc = x:child( 'desc' )
-			if desc then
-				desc = ('(%s)'):format ( desc:value () )
-			else
-				desc = ''
-			end
-			main.print_info ( mess:attribute ( 'from' ), ('Attached url: %s %s'):format ( url, desc ) )
-		end
-		return false
-	end )
-
-main.command ( 'oob',
-	function ( args )
-		local who
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
-		end
-		oob_send_link ( lm.connection.bless ( main.connection () ), who, args[1], args[2] )
-	end, true )
-
-oob_handler_registered = false
-
-hooks_d['hook-post-connect'].xep0066 =
-	function ( args )
-		local conn = lm.connection.bless ( main.connection () )
-		conn:handler ( oob_incoming_iq_handler, 'iq', 'normal' )
-		conn:handler ( oob_incoming_message_handler, 'message', 'normal' )
-		conn:handler ( oob_incoming_message_handler, 'presence', 'normal' )
-		oob_handler_registered = true
-		hooks_d['hook-post-connect'].xep0066 = nil
-		hooks_d['hook-quit'].xep0066 =
-			function ( args )
-				if oob_handler_registered then
-					local conn = lm.connection.bless ( main.connection () )
-					conn:handler ( oob_incoming_iq_handler, 'iq' )
-					conn:handler ( oob_incoming_message_handler, 'message' )
-					conn:handler ( oob_incoming_message_handler, 'presence' )
-				end
-			end
-	end
-
-main.add_feature ( 'jabber:iq:oob' )
-main.add_feature ( 'jabber:x:oob' )
-
--- vim: se ts=4: --
--- a/examples/xep0077.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-
-function parse_iq_register ( node )
-	local form = { title = 'jabber:iq:register', exp = '', val = { } }
-	if node:child ( 'instructions' ) then
-		form.exp = form.exp .. 'Instructions: ' .. node:child( 'instructions' ):value () .. '\n'
-	end
-	if node:child ( 'registered' ) then
-		form.exp = form.exp .. 'Registered: yes\n'
-	end
-	form.exp = form.exp .. 'Fields:\n'
-	local field = node:children ()
-	while field do
-		local name = field:name ()
-		if name ~= 'instructions' and name ~= 'registered' then
-			form.exp = form.exp .. ' - ' .. name .. '\n'
-			if field:value () and field:value () ~= '' then
-				form.exp = form.exp .. '   Default value: ' .. field:value () .. '\n'
-			end
-			table.insert ( form.val, { type = 'text-single', var = name, value = { field:value () or '' } } )
-		end
-		field = field:next ()
-	end
-	return insert_form ( form )
-end
-
-function format_iq_register ( fields )
-	local result = { xmlns = 'jabber:iq:register' }
-	for index, field in ipairs ( fields ) do
-		result[field.var] = field.value
-	end
-	return result
-end
-
-function register_to ( who )
-	lm.connection.bless( main.connection () ):send (
-		lm.message.create { mtype = 'iq-get', to = who,
-			query = { xmlns = 'jabber:iq:register' }
-		},
-		function ( conn, mess )
-			local node = mess:child ( 'query' )
-			if node and node:attribute ( 'xmlns' ) == 'jabber:iq:register' then
-				main.print_info ( who, 'D: Got:\n' .. mess:xml () )
-				local x = node:child ( 'x' )
-				local id
-				local finalizer =
-					function ( conn, mess )
-						local mt, st = mess:type ()
-						if st == 'result' then
-							main.print_info ( who, 'Now you can run /form del ' .. id .. ' to delete form from list' )
-							forms[id].status = 'acquired'
-						elseif st == 'error' then
-							main.print_info ( who, 'Got non-successful response to form:\n' .. mess:xml () )
-							forms[id].status = 'rejected'
-						else
-							print ( 'Weird response to submitted form:\n' .. mess:xml () )
-							forms[id].status = 'unknown'
-							return false
-						end
-						return true
-					end
-				if x and x:attribute ( 'xmlns' ) == 'jabber:x:data' then
-					id = parse_form ( x )
-					-- local sid = mess:child( 'command' ):attribute ( 'sessionid' )
-					forms[id].send =
-						function ( form )
-							conn:send (
-								lm.message.create { mtype = 'iq-set', to = who,
-									query = { xmlns = 'jabber:iq:register',
-										x = { xmlns = 'jabber:x:data', type = 'submit',
-											field = form.val,
-										},
-									},
-								}, finalizer )
-							form.status = 'sent'
-						end
-					forms[id].status = 'filling'
-					main.print_info ( who, 'You have new form. To fill it, use /form ' .. id .. ' fieldname value' )
-				else
-					id = parse_iq_register ( mess:child ( 'query' ) )
-					forms[id].send =
-						function ( form )
-							conn:send (
-								lm.message.create { mtype = 'iq-set', to = who,
-									query = format_iq_register ( form.val ),
-								}, finalizer )
-							form.status = 'sent'
-						end
-					forms[id].status = 'filling'
-					main.print_info ( who, 'You have new form. To fill it, use /form ' .. id .. ' fieldname value' )
-				end
-			else
-				main.print_info ( who, 'Error response:\n' .. mess:xml () )
-			end
-			return true
-		end )
-end
-
-function unregister_from ( who )
-	lm.connection.bless( main.connection () ):send (
-		lm.message.create { mtype = 'iq-set', to = who,
-			query = { xmlns = 'jabber:iq:register',
-				remove = { },
-			},
-		},
-		function ( conn, mess )
-			local mt, st = mess:type ()
-			if st == 'result' then
-				main.print_info ( who, 'Registration cancelled' )
-			elseif st == 'error' then
-				if mess:child ( 'error' ) then
-					main.print_info ( who, 'Error response: ' .. mess:child( 'error' ):children():name () )
-				else
-					local query = mess:child ( 'query' )
-					if query and query:child ( 'x' ) then
-						local id = parse_form ( query:child ( 'x' ) )
-						forms[id].send =
-							function ( form )
-								conn:send (
-									lm.message.create { mtype = 'iq-set', to = who,
-										query = { xmlns = 'jabber:iq:register',
-											x = { xmlns = 'jabber:x:data', type = 'submit',
-												field = form.val,
-											},
-										},
-									},
-									function ( conn, mess )
-										local mt, st = mess:type ()
-										if st == 'result' then
-											main.print_info ( who, 'Now you can run /form del ' .. id .. ' to delete form from list' )
-											forms[id].status = 'acquired'
-										elseif st == 'error' then
-											main.print_info ( who, 'Got non-successful response to form:\n' .. mess:xml () )
-											forms[id].status = 'rejected'
-										else
-											print ( 'Weird response to submitted form:\n' .. mess:xml () )
-											forms[id].status = 'unknown'
-											return false
-										end
-										return true
-									end )
-								form.status = 'sent'
-							end
-						forms[id].status = 'filling'
-						main.print_info ( who, 'You have new form. To fill it, use /form ' .. id .. ' fieldname value' )
-					else
-						main.print_info ( who, 'Got non-successful response to form:\n' .. mess:xml () )
-					end
-				end
-			else
-				main.print_info ( who, 'Got non-successful response to form:\n' .. mess:xml () )
-			end
-			return true
-		end )
-end
-
-main.command ( 'register',
-	function ( args )
-		local who
-		if args and args ~= '' then
-			who = args
-		else
-			who = main.full_jid ()
-		end
-		register_to ( who )
-	end, false, 'jid' )
-
-main.command ( 'cancel',
-	function ( args )
-		local who
-		if args and args ~= '' then
-			who = args
-		else
-			who = main.full_jid ()
-		end
-		unregister_from ( who )
-	end, false, 'jid' )
-
-commands_help['register'] = "[jid]\n\nSends registration request to jid (or current buddy). You, probably, then will need to fill and send some form."
-commands_help['cancel'] = "[jid]\n\nSends registration cancellation request to jid (or current buddy). May require a form filling."
-
--- vim: se ts=4: --
--- a/examples/xep0146.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-
-function remote_command ( who, command )
-	lm.connection.bless( main.connection () ):send (
-		lm.message.create { mtype = 'iq-set', to = who,
-			command = { xmlns = 'http://jabber.org/protocol/commands', action = 'execute', node = command }
-		},
-		function ( conn, mess )
-			if mess:child ( 'command' ) and mess:child( 'command' ):child ( 'x' ) then
-				local id = parse_form ( mess:child( 'command' ):child ( 'x' ) )
-				local sid = mess:child( 'command' ):attribute ( 'sessionid' )
-				forms[id].send =
-					function ( form )
-						conn:send (
-							lm.message.create { mtype = 'iq-set', to = who,
-								command = { xmlns = 'http://jabber.org/protocol/commands', node = command, sessionid = sid,
-									x = { xmlns = 'jabber:x:data', type = 'form',
-										field = form.val,
-									},
-								},
-							},
-							function ( conn, mess )
-								if mess:child ( 'command' ) and mess:child( 'command' ):attribute ( 'status' ) == 'completed' then
-									main.print_info ( who, 'Now you can run /form del ' .. id .. ' to delete form from list' )
-									forms.status = 'acquired'
-								else
-									main.print_info ( who, 'Got non-successful response to form:\n' .. mess:xml () )
-									forms.status = 'rejected'
-								end
-								return true
-							end )
-						form.status = 'sent'
-					end
-				forms[id].status = 'filling'
-				main.print_info ( who, 'You have new form. To fill it, use /form ' .. id .. ' fieldname value' )
-			else
-				main.print_info ( who, 'Got response to command request:\n' .. mess:xml () )
-			end
-			return true
-		end )
-end
-
-main.command ( 'remote',
-	function ( args )
-		local who
-		if args.t then
-			who = args.t
-		else
-			who = main.full_jid ()
-		end
-		local action = args[1]
-		if not action then
-			disco_items ( lm.connection.bless ( main.connection () ),
-				function ( items )
-					if type ( items ) == 'string' then
-						main.print_info ( who, string.format ( "Service items discovery for %s (http://jabber.org/protocol/commands) failed: %s", who, items ) )
-					else
-						local text = ''
-						for index, item in ipairs ( items ) do
-							text = text .. '\n - ' .. item.node
-						end
-						if text ~= '' then
-							main.print_info ( who, 'Available commands:' .. text )
-						else
-							main.print_info ( who, 'No commands available.' )
-						end
-					end
-				end, who, 'http://jabber.org/protocol/commands' )
-		elseif action then
-			remote_command ( who, action )
-		end
-	end, true, 'jid' )
-
-commands_help['remote'] = "[-t target_jid] [remote_command]\n\nPrints list of available remote command or requests execution of specified command."
-
--- vim: se ts=4: --
--- a/examples/xep0163.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-
-dopath 'mpd'
-
-tune_enabled = false
-
-mpd_pub_song = { }
-
-function mpd_getstatus ()
-	local status   = mpd.call_command { 'status' }
-	if not tune_enabled or ( status.state ~= 'play' and status.state ~= 'pause' ) then
-		if mpd_pub_song.artist or mpd_pub_song.length or mpd_pub_song.source or mpd_pub_song.title or mpd_pub_song.track then
-			mpd_pub_song.artist = nil
-			mpd_pub_song.length = nil
-			mpd_pub_song.source = nil
-			mpd_pub_song.title  = nil
-			mpd_pub_song.track  = nil
-			return mpd_pub_song
-		else
-			return nil
-		end
-	end
-	
-	local modified  = false
-	local song      = mpd.call_command { 'currentsong' }
-	local dir, file = song.file:match ( '(.+)/(.-)' )
-	-- populate according to currentsong fields: artist - artist, length - time, source - album, title - title, track - id, rating - ?, uri - ?
-	local artist, length, source, title, track = song.artist, song.time, song.album, song.title, song.id
-
-	if not artist or artist == '' then
-		artist = 'Unknown'
-	end
-	if not mpd_pub_song.artist or artist ~= mpd_pub_song.artist[1] then
-		mpd_pub_song.artist = { artist }
-		modified = true
-	end
-
-	if length and length ~= 0 then
-		if not mpd_pub_song.length or length ~= mpd_pub_song.length[1] then
-			mpd_pub_song.length = { length }
-			modified = true
-		end
-	elseif mpd_pub_song.length then -- no length
-		mpd_pub_song.length = nil
-		modified = true
-	end
-
-	if not source or source == '' then
-		source = dir
-	end
-	if not mpd_pub_song.source or source ~= mpd_pub_song.source[1] then
-		mpd_pub_song.source = { source }
-		modified = true
-	end
-
-	if not title or title == '' then
-		title = file
-	end
-	if not mpd_pub_song.title or title ~= mpd_pub_song.title[1] then
-		mpd_pub_song.title = { title }
-		modified = true
-	end
-
-	if not mpd_pub_song.track or track ~= mpd_pub_song.track[1] then
-		mpd_pub_song.track = { track }
-		modified = true
-	end
-
-	if modified then
-		return mpd_pub_song
-	else
-		return nil
-	end
-end
-
-function pep_publish ( conn, callback, node, data )
-	if not callback then
-		callback =
-			function ( mesg )
-				if mesg then
-					print ( mesg ) -- FIXME
-				end
-			end
-	end
-	data.xmlns = 'http://jabber.org/protocol/' .. node -- this may modify original data? imo it does not matter.
-	if conn:status () == 'authenticated' then
---		local bjid = conn:jid():gsub ( '/.*', '' )
-		conn:send (
-			lm.message.create { mtype = 'iq-set', -- from = conn:jid (), to = bjid,
-				pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
-					publish = { node = 'http://jabber.org/protocol/' .. node,
-						item = { -- id = "current",
-							[node] = data,
-						},
-					},
-				},
---[[
-				configure = {
-					x = {
-						field = {{ type = "hidden", var = 'FORM_TYPE',
-							value = { 'http://jabber.org/protocol/pubsub#node_config' },
-						},{ var = "pubsub#access_model",
-							value = { 'presence' },
-						}},
-					},
-				},
---]]
-			},
-			function ( conn, mess )
-				local mtype, smtype = mess:type ()
-				if smtype == 'result' then
-					callback ()
-					return true
-				elseif smtype == 'error' then
-					callback ( message:child( 'error' ):children():name () )
-					return true
-				else
-					callback ( 'Weird ansver to publishing request: ' .. mess:xml () )
-					return false
-				end
-			end )
-	end
-end
-
-pep_incoming_message_handler = lm.message_handler.new (
-	function ( conn, mess )
-		local e = mess:child ( 'event' )
-		if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/pubsub#event' then
-			local enable = main.yesno ( main.option ( 'lua_pep_notification' ) )
-			if enable == false then
-				return true
-			end
-			local is = e:child ( 'items' )
-			if is then
-				local from = mess:attribute ( 'from' )
-				local node = is:attribute ( 'node' )
-				if node == 'http://jabber.org/protocol/tune' then
-					local tune = is:path ( 'item', 'tune' )
-					if tune then
-						local item = tune:children ()
-						local text = ''
-						while item do
-							text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
-							item = item:next ()
-						end
-						if text ~= '' then
-							text = 'Now listening to:' .. text
-						else
-							text = 'Now not listening to anything'
-						end
-						main.print_info ( from, text )
-						return true
-					else
-						main.print_info ( from, 'Strange: no tune item in pep notification' )
-					end
-				elseif node == 'http://jabber.org/protocol/mood' then
-					local mood = is:path ( 'item', 'mood' )
-					if mood then
-						local item = mood:children ()
-						local mood, desc
-						while item do
-							if item:name () == 'text' then
-								desc = item:value ()
-							else
-								mood = item:name ()
-								-- here we can add child elements handling (by namespace)
-							end
-							item = item:next ()
-						end
-						if mood then
-							main.print_info ( from, ("Buddy's mood now %s %s"):format ( mood, desc or '' ) )
-						else
-							main.print_info ( from, "Buddy hides his mood" )
-						end
-						return true
-					else
-						main.print_info ( from, 'Strange: no mood item in pep notification' )
-					end
-				elseif node == 'http://jabber.org/protocol/activity' then
-					local activity = is:path ( 'item', 'activity' )
-					if activity then
-						local item = activity:children ()
-						local activity, desc
-						while item do
-							if item:name () == 'text' then
-								desc = item:value ()
-							else
-								activity = item:name ()
-								local subitem = item:children ()
-								if subitem then
-									-- here we can check for non-standard subactivity elements,
-									-- add subactivity child elements handling
-									activity = ("%s: %s"):format ( activity, subitem:name () )
-								end
-							end
-							item = item:next ()
-						end
-						if activity then
-							main.print_info ( from, ("Now %s %s"):format ( activity, desc or '' ) )
-						else
-							main.print_info ( from, "Buddy hides his activity" )
-						end
-						return true
-					else
-						main.print_info ( from, 'Strange: no activity item in pep notification' )
-					end
-				elseif node == 'http://jabber.org/protocol/geoloc' then
-					local loc = is:path ( 'item', 'geoloc' )
-					if loc then
-						local item = loc:children ()
-						local text = ''
-						while item do
-							text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
-							item = item:next ()
-						end
-						if text ~= '' then
-							text = 'Now at:' .. text
-						else
-							text = 'Now in unknown location'
-						end
-						main.print_info ( from, text )
-						return true
-					else
-						main.print_info ( from, 'Strange: no geoloc item in pep notification' )
-					end
-				else
-					main.print_info ( from, 'Unknown node in pep notification: ' .. is:xml () )
-				end
-			end
-		end
-		return false
-	end )
-
-
-function mpd_callback ()
-	local sdata = mpd_getstatus ()
-	if sdata then
-		pep_publish ( lm.connection.bless ( main.connection () ), nil, 'tune', sdata )
-	end
-	if tune_enabled then
-		return true
-	else
-		return false
-	end
-end
-
--- do not call it too fast, or you end up with many daemons at once
-function enable_tune ( yn )
-	if yn == nil then
-		yn = true
-	end
-	if yn then
-		if not tune_enabled then
-			main.timer ( 15, mpd_callback )
-			tune_enabled = true
-			-- update status
-		end
-	else
-		if tune_enabled then
-			tune_enabled = false
-			-- update status
-		end
-	end
-end
-
-main.command ( 'tune',
-	function ( args )
-		local enable = main.yesno ( args )
-		if enable == nil then
-			if tune_enabled then
-				print ( "Tune notifications enabled" )
-			else
-				print ( "Tune notifications disabled" )
-			end
-		else
-			enable_tune ( enable )
-		end
-	end, false, 'yesno' )
-main.command ( 'mood',
-	function ( args )
-		local data = { }
-		local mood, text = args[1], args[2]
-		if text then
-			data.text  = { text }
-		end
-		if mood then
-			data[mood] = { }
-		end
-		pep_publish ( lm.connection.bless ( main.connection () ), nil, 'mood', data )
-	end, true )
-main.command ( 'activity',
-	function ( args )
-		local data = { }
-		local activity, text = args[1], args[2]
-		if text then
-			data.text = { text }
-		end
-		local act, subact = activity:match ( "(.-)%-(.+)" )
-		if not act then
-			act = activity
-		end
-		if act ~= '' then
-			data[act] = { }
-			if subact then
-				data[act][subact] = { }
-			end
-		end
-		pep_publish ( lm.connection.bless ( main.connection () ), nil, 'activity', data )
-	end, true )
-main.command ( 'location',
-	function ( args )
-		local data = { }
-		for key, val in pairs ( args ) do
-			data[key] = { val }
-		end
-		pep_publish ( lm.connection.bless ( main.connection () ), nil, 'geoloc', data )
-	end, true )
-
-commands_help['tune']     = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables publishing of notifications about playing music in your player (currently only mpd is supported)."
-commands_help['mood']     = "[mood [message]]\n\nPublishes your mood.\nNote, that for now it does not checks for mood validity, so, see xep0107 for valid moods."
-commands_help['activity'] = "[activity[-specific_activity] [text]]\n\nPublishes your activity.\nNote, that for now it does not checks for activity validity, so, see xep0108 for valid activity values."
-commands_help['location'] = "[-key value [-key value ...]]\n\nPublishes your current geolocation.\nValid keys are accuracy, alt, area, bearing, building, country, datum, description, error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp and uri, according to xep0080."
-
-pep_handler_registered = false
-
-hooks_d['hook-post-connect'].xep0163 =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message', 'normal' )
-		pep_handler_registered = true
-		if tune_enabled then
-			mpd_callback ()
-		end
-		-- XXX: may it confuse pairs()?
-		hooks_d['hook-post-connect'].xep0163 =
-			function ( args )
-				if tune_enabled then
-					mpd_callback ()
-				end
-			end
-		hooks_d['hook-quit'].xep0163 =
-			function ( args )
-				if mpd_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message' )
-					pep_handler_registered = false
-				end
-			end
-	end
-
--- XXX: this really should be initialized after connection establishment?
--- but as this thing is implemented by now, it will be cached by server,
--- and, thus, we will be unable to get notifications.
-main.add_feature ( 'http://jabber.org/protocol/tune+notify' )
-main.add_feature ( 'http://jabber.org/protocol/tune' )
-main.add_feature ( 'http://jabber.org/protocol/mood+notify' )
-main.add_feature ( 'http://jabber.org/protocol/mood' )
-main.add_feature ( 'http://jabber.org/protocol/activity+notify' )
-main.add_feature ( 'http://jabber.org/protocol/activity' )
-main.add_feature ( 'http://jabber.org/protocol/geoloc+notify' )
-main.add_feature ( 'http://jabber.org/protocol/geoloc' )
-
--- vim: se ts=4: --