dev sync.

tong [10-01-15 19:16]
dev sync.
Filename
Makefile
hxmpp.exclude
hxmpp.source
hxmpp.stable
jabber/BOSHConnection.hx
jabber/Lib.hx
jabber/MUCUtil.hx
jabber/PubSub.hx
jabber/SocketConnection.hx
jabber/Stream.hx
jabber/XMPPDebug.hx
jabber/client/Authentication.hx
jabber/client/NonSASLAuth.hx
jabber/client/NonSASLAuthentication.hx
jabber/client/Roster.hx
jabber/client/SASLAuth.hx
jabber/client/SASLAuthentication.hx
jabber/client/Stream.hx
jabber/component/Stream.hx
jabber/file/FileTransfer.hx
jabber/file/io/ByteStreamInput.hx
jabber/file/io/ByteStreamOutput.hx
jabber/stream/Connection.hx
out/hxmpp-debug.swc
out/hxmpp.swc
samples/client/ClientDemo.hx
samples/client/build.hxml
samples/client/test.html
util/neko.h
xmpp/Auth.hx
xmpp/BOB.hx
xmpp/Caps.hx
xmpp/ChatStateExtension.hx
xmpp/Compression.hx
xmpp/HXR.hx
xmpp/MUC.hx
xmpp/NS.hx
xmpp/Namespace.hx
xmpp/PlainPacket.hx
xmpp/PubSub.hx
xmpp/XHTML.hx
xmpp/disco/Info.hx
xmpp/disco/Items.hx
xmpp/file/ByteStream.hx
xmpp/file/IB.hx
xmpp/filter/PacketAllFilter.hx
xmpp/filter/PacketFieldFilter.hx
xmpp/filter/PacketFromFilter.hx
xmpp/filter/PacketIDFilter.hx
xmpp/filter/PacketToFilter.hx
xmpp/filter/PacketTypeFilter.hx
xmpp/pep/UserActivity.hx
xmpp/pep/UserLocation.hx
xmpp/pep/UserMood.hx
xmpp/pep/UserTune.hx
xmpp/pubsub/NodeType.hx
diff --git a/Makefile b/Makefile
index cdd8322..0941385 100644
--- a/Makefile
+++ b/Makefile
@@ -1,54 +1,41 @@

 SYSTEM = Linux

+include hxmpp.source
 include hxmpp.stable

-STABLE_BASE = jabber.ServiceDiscovery
-STABEL_CLIENT_BASE = jabber.client.Stream jabber.client.Roster jabber.client.NonSASLAuthentication jabber.client.SASLAuthentication jabber.client.VCard net.sasl.PlainMechanism
-STABEL_CLIENT_JS = $(STABEL_BASE) $(STABEL_CLIENT_BASE) jabber.BOSHConnection
-
-
 NDLL = ndll/$(SYSTEM)/hxmpp.ndll
 NDLL_OBJECTS = util/sha1.o #util/base64.o
+LIB_JS = out/hxmpp.js
+LIB_SWC = out/hxmpp.swc
+FLAGS = -cp lib/ -exclude hxmpp.exclude

-all : $(NDLL) lib
+all : $(NDLL) \
+	  $(LIB_JS) \
+	  $(LIB_SWC)

-$(NDLL) : $(NDLL_OBJECTS)
+$(NDLL) : $(NDLL_OBJECTS)
 	$(CC) -shared -O3 -I/usr/lib/neko/include $(NDLL_OBJECTS) -o $@

-libjs :
-	haxe -js out/hxmpp.js -cp lib/ --no-traces -exclude hxmpp.exclude $(STABEL_CLIENT_JS)
-	#haxe -js tmp -cp lib/ --no-traces -exclude hxmpp.exclude $(STABEL_CLIENT_JS)
-	#-java -jar ~/bin/closure.jar -js=tmp --js_output_file=out/hxmpp.js
-	#rm tmp
-	haxe -js out/hxmpp-debug.js -cp lib/ -exclude hxmpp.exclude \
-		-D JABBER_DEBUG \
-		-D XMPP_DEBUG \
-		-D JABBER_CONSOLE \
-		-debug \
-		$(STABEL_CLIENT_JS)
-
-libswc :
-	haxe -swf9 out/hxmpp.swc -cp lib/ --no-traces -exclude hxmpp.exclude $(STABLE_CLIENT)
-	haxe -swf9 out/hxmpp-debug.swc -cp lib/ -D JABBER_DEBUG -D JABBER_CONSOLE -D XMPP_DEBUG jabber.client.Stream
-
-#libas3 :
-	#haxe -as3 out/as3
-
-lib : libjs libswc
-
-tools :
+$(LIB_JS) : $(HXMPP_SRC)
+	haxe -js out/hxmpp.js $(FLAGS) $(STABLE_CLIENT_JS) --no-traces
+	haxe -js out/hxmpp-debug.js $(FLAGS) $(STABLE_CLIENT_JS) \
+		-D JABBER_DEBUG -D XMPP_DEBUG -D JABBER_CONSOLE \
+		-debug
+
+$(LIB_SWC) : $(HXMPP_SRC)
+	haxe -swf9 out/hxmpp.swc $(FLAGS) $(STABLE_CLIENT) --no-traces
+	haxe -swf9 out/hxmpp-debug.swc $(FLAGS) $(STABLE_CLIENT) \
+		-D JABBER_DEBUG -D JABBER_CONSOLE -D XMPP_DEBUG \
+		-debug
+
+utilities :
 	haxe utilities.hxml

 doc :
-	haxe doc.hxml
+	#haxe doc.hxml

 clean :
 	rm util/*.o

 .PHONY: all doc clean lib
-
-##find jabber/ xmpp/ -name "*.hx" | sed -e 's/\//./g' -e 's/\.hx//' > temp;
-##paste -s -d' ' temp > Makefile.inc
-##sed -i  '1i CLASSES=' Makefile.inc
-
\ No newline at end of file
diff --git a/hxmpp.exclude b/hxmpp.exclude
index 5d09be7..877d719 100644
--- a/hxmpp.exclude
+++ b/hxmpp.exclude
@@ -1 +1,3 @@
 xmpp.ErrorCondition
+xmpp.jingle.RTMP
+xmpp.Namespace
diff --git a/hxmpp.source b/hxmpp.source
new file mode 100644
index 0000000..548cd60
--- /dev/null
+++ b/hxmpp.source
@@ -0,0 +1,21 @@
+
+HXMPP_SRC = jabber/*.hx \
+jabber/client/*.hx \
+jabber/component/*.hx \
+jabber/file/*.hx jabber/file/io/*.hx \
+jabber/jingle/*.hx jabber/jingle/transport/*.hx \
+jabber/remoting/*.hx \
+jabber/stream/*.hx \
+xmpp/*.hx \
+xmpp/dataform/*.hx \
+xmpp/disco/*.hx \
+xmpp/file/*.hx \
+xmpp/filter/*.hx \
+xmpp/jingle/*.hx \
+xmpp/muc/*.hx \
+xmpp/pep/*.hx \
+xmpp/privacylist/*.hx \
+xmpp/pubsub/*.hx \
+xmpp/roster/*.hx \
+xmpp/disco/*.hx \
+xmpp/vcard/*.hx \
diff --git a/hxmpp.stable b/hxmpp.stable
new file mode 100644
index 0000000..1a9676c
--- /dev/null
+++ b/hxmpp.stable
@@ -0,0 +1,56 @@
+
+STABLE_XMPP = xmpp.Bind \
+xmpp.ChatState \
+xmpp.ChatStateExtension \
+xmpp.Compression \
+xmpp.DataForm \
+xmpp.DateTime \
+xmpp.Delayed \
+xmpp.Error \
+xmpp.ErrorCondition \
+xmpp.IQ \
+xmpp.MUC \
+xmpp.PlainPacket \
+xmpp.Presence \
+xmpp.PrivacyLists \
+xmpp.SASL \
+xmpp.XHTML \
+xmpp.dataform.Field xmpp.dataform.FieldOption xmpp.dataform.FieldType xmpp.dataform.Item xmpp.dataform.Reported \
+xmpp.disco.Identity xmpp.disco.Info xmpp.disco.Item xmpp.disco.Items
+
+STABLE = jabber.JID \
+jabber.JIDUtil \
+jabber.LastActivity \
+jabber.LastActivityListener \
+jabber.MessageListener \
+jabber.Ping \
+jabber.Pong \
+jabber.PresenceListener \
+jabber.ServiceDiscovery \
+#jabber.SocketConnection \
+jabber.SoftwareVersion \
+jabber.XMPPDebug \
+jabber.XMPPError \
+
+STABLE_CLIENT = jabber.client.Stream \
+jabber.client.Account \
+jabber.client.Authentication \
+jabber.client.MUChat \
+jabber.client.NonSASLAuthentication \
+jabber.client.Roster \
+jabber.client.SASLAuthentication \
+jabber.client.VCard \
+jabber.Chat \
+jabber.ChatStateNotification \
+net.sasl.Handshake \
+net.sasl.AnonymousMechanism \
+net.sasl.PlainMechanism
+
+STABLE_CLIENT_JS = $(STABLE) $(STABLE_CLIENT) \
+jabber.BOSHConnection
+
+UNSTABLE = jabber.EntityCapabilities \
+jabber.PersonalEvent \
+jabber.PersonalEventListener \
+jabber.PubSub \
+
diff --git a/jabber/BOSHConnection.hx b/jabber/BOSHConnection.hx
index c6a007a..93bcb82 100644
--- a/jabber/BOSHConnection.hx
+++ b/jabber/BOSHConnection.hx
@@ -30,6 +30,7 @@ import flash.events.SecurityErrorEvent;

 	// timeout timer (?), added but needed?

+	// neko/cpp/php
 	// polling
 	/// multiple streams over one connection
 	// secure!
@@ -337,7 +338,6 @@ class BOSHConnection extends jabber.stream.Connection {
 			t = x.get( "inactivity" );
 			if( t != null ) inactivity = Std.parseInt( t );
 		//	#if XMPP_DEBUG
-		//	trace("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
 		//	XMPPDebug.inc( t );
 		//	#end
 			__onConnect();
diff --git a/jabber/Lib.hx b/jabber/Lib.hx
index 71dcc1d..44aa070 100644
--- a/jabber/Lib.hx
+++ b/jabber/Lib.hx
@@ -29,7 +29,7 @@ class Lib {

 	#if JABBER_SOCKETBRIDGE

-	public static var defaultSocketBridgeID = "f9bridge";
+	public static var defaultSocketBridgeID = "socketbridge";

 	static function initSocketBridge( ?id : String ) {
 		if( id == null ) id = defaultSocketBridgeID;
diff --git a/jabber/MUCUtil.hx b/jabber/MUCUtil.hx
index fc2fea1..e7ecce8 100644
--- a/jabber/MUCUtil.hx
+++ b/jabber/MUCUtil.hx
@@ -37,7 +37,7 @@ class MUCUtil {
 	/**
 		Returns Bool if the given string is a full valid muchat address (including occupant name).
 	*/
-	public static inline  function isValidFull( t : String ) : Bool {
+	public static inline function isValidFull( t : String ) : Bool {
 		return EREG_FULL.match( t );
 	}

diff --git a/jabber/PubSub.hx b/jabber/PubSub.hx
index efd753f..68869a2 100644
--- a/jabber/PubSub.hx
+++ b/jabber/PubSub.hx
@@ -18,8 +18,7 @@
 package jabber;

 /**
-	PubSub client implementation.<br/>
-	<a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060: Publish-Subscribe</a>
+	PubSub client implementation. <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060: Publish-Subscribe</a>
 */
 class PubSub {

@@ -162,9 +161,9 @@ class PubSub {
 		} );
 	}

+	//TODO why subid required?
 	/**
 		Load all items from the given node.
-		TODO why subid required?
 	*/
 	public function loadItems( node : String, ?subid : String, ?maxItems : Int, ?ids : Array<String> ) {
 		var iq = new xmpp.IQ( null, null, service );
@@ -181,9 +180,9 @@ class PubSub {
 		} );
 	}

+	//TODO ?? retractItems( node : String, ids : Array<String> )
 	/**
 		Publisher deletes an item once it has been published to a node that supports persistent items.
-		//TODO ?? retractItems( node : String, ids : Array<String> )
 	*/
 	public function retract( retract : xmpp.pubsub.Retract ) {
 		var iq = new xmpp.IQ( xmpp.IQType.set, null, service );
diff --git a/jabber/SocketConnection.hx b/jabber/SocketConnection.hx
index a0dbf48..f08297d 100644
--- a/jabber/SocketConnection.hx
+++ b/jabber/SocketConnection.hx
@@ -68,8 +68,7 @@ class SocketConnection extends jabber.stream.Connection {
 						 ?secure : Bool = false ,
 						 ?timeout : Int = 10,
 						 ?maxBufSize : Int = 131072 ) {
-		if( port == null )
-			port = 5222;
+		if( port == null ) port = 5222;
 		super( host );
 		this.port = port;
 		#if (flash10||neko||php||cpp)
@@ -128,18 +127,18 @@ class SocketConnection extends jabber.stream.Connection {
 		connected = true;
 		__onConnect();
 		#else
-		#if flash10
-		socket.timeout = timeout*1000;
-		#end
+		#if flash10 socket.timeout = timeout*1000; #end
 		socket.connect( host, port );
 		#end
 	}

 	public override function disconnect() {
 		if( !connected ) return;
-		#if (neko||php||cpp) reading = false; #end
-		connected = #if (neko||php||cpp) reading = #end false;
-		socket.close();
+		#if (neko||php||cpp)
+		reading = false;
+		#end
+		connected = false;
+		try socket.close() catch( e : Dynamic ) {};
 	}

 	public override function read( ?yes : Bool = true ) : Bool {
@@ -170,7 +169,7 @@ class SocketConnection extends jabber.stream.Connection {
 	public override function write( t : String ) : Bool {
 		if( !connected || t == null || t.length == 0 )
 			return false;
-		#if flash9
+		#if flash
 		socket.writeUTFBytes( t );
 		socket.flush();
 		#elseif (neko||php||cpp)
diff --git a/jabber/Stream.hx b/jabber/Stream.hx
index 6a9134d..76afccf 100644
--- a/jabber/Stream.hx
+++ b/jabber/Stream.hx
@@ -29,7 +29,6 @@ import util.Base64;
 private typedef TDataFilter = {
 	function filterData( t : haxe.io.Bytes ) : haxe.io.Bytes;
 }
-
 private typedef TDataInterceptor = {
 	function interceptData( t : haxe.io.Bytes ) : haxe.io.Bytes;
 }
@@ -65,7 +64,6 @@ class Stream {
 	//public static function onXMPP( s : Stream, p : xmpp.Packet, out : Bool ) : Void;
 	public static function onXMPP(default,null) : EventDispatcher<XMPPTransfer>;
 	public static function debugXMPP( t : String ) {
-
 	}
 	#end
 	*/
@@ -77,16 +75,16 @@ class Stream {

 	public var status : StreamStatus;
 	public var cnx(default,setConnection) : Connection;
-	public var id(default,null) : String;
-	public var lang(default,null) : String;
 	public var jidstr(getJIDStr,null) : String;
-	public var server(default,null) : Server;
 	public var features(default,null) : StreamFeatures;
+	public var server(default,null) : Server;
+	public var id(default,null) : String;
+	public var lang(default,null) : String;
 	public var version : Bool; //Indicates if the version number of the XMPP stream ("1.0") should get added to the stream opening XML element.
 	//public var dataFilters : List<TDataFilter>;
 	//public var dataInterceptors : List<TDataInterceptor>;
 	/** Indicates if this streams connection is a http connection */
-	public var http(default,null) : Bool;
+	public var http(default,null) : Bool; //TODO move to: jabber.stream.Connection

 	var collectors : List<PacketCollector>; // public var packetCollectors : Array<TPacketCollector>;
 	var interceptors : List<TPacketInterceptor>; // public var packetInterceptors : Array<TPacketCollector>;
@@ -108,8 +106,10 @@ class Stream {
 		//dataInterceptors = new List();
 		if( cnx != null )
 			setConnection( cnx );
+
+		 // TODO HACK
 		#if (flash&&JABBER_CONSOLE)
-		XMPPDebug.stream = this; // TODO HACK
+		XMPPDebug.stream = this;
 		#end
 	}

@@ -189,14 +189,14 @@ class Stream {
 	public function sendData( t : String ) : String {
 		if( !cnx.connected )
 			return null;
+		//TODO
 		//for( i in dataInterceptors )
 			//t = i.interceptData( t );
 		if( !cnx.write( t ) )
 			return null;
 		numPacketsSent++;
 		#if XMPP_DEBUG
-		XMPPDebug.out( t );
-		//XMPPDebug.outPacket( t );
+		XMPPDebug.out( t );//XMPPDebug.outPacket( t );
 		#end
 		return t;
 	}
@@ -215,14 +215,6 @@ class Stream {
 	*/

 	/**
-		Runs the XMPP packet interceptor on the given packet.
-	*/
-	public function interceptPacket( p : xmpp.Packet ) : xmpp.Packet {
-		for( i in interceptors ) i.interceptPacket( p );
-		return p;
-	}
-
-	/**
 		Send an IQ packet and forward the collected response to the given handler function.
 	*/
 	public function sendIQ( iq : xmpp.IQ, ?handler : xmpp.IQ->Void,
@@ -261,6 +253,22 @@ class Stream {

 	}

+	/*
+	public function sendCollect<T>( p : T, handler : T->Void ) : {
+		if( p.id == null ) p.id = nextID();
+		collect( [cast new PacketIDFilter( p.id )], handler, false );
+		sendPacket( p );
+	}
+	*/
+
+	/**
+		Runs the XMPP packet interceptor on the given packet.
+	*/
+	public function interceptPacket( p : xmpp.Packet ) : xmpp.Packet {
+		for( i in interceptors ) i.interceptPacket( p );
+		return p;
+	}
+
 	/**
 		Creates, adds and returns a packet collector.
 	*/
@@ -312,10 +320,8 @@ class Stream {
 		if( status == StreamStatus.closed )
 			return -1;
 		//TODO .. data filters
-		//
 		var t : String = buf.readString( bufpos, buflen );
-		//TODO
-		/*
+		/*//TODO
 		if( xmpp.Stream.REGEXP_CLOSE.match( t ) ) {
 			close( true );
 			return -1;
@@ -326,58 +332,23 @@ class Stream {
 			close( true );
 			return -1;
 		} else if( StringTools.startsWith( t, '</stream:error' ) ) {
-			//close( true );
-			//TODO
-			return -1;
-		}
-		//TODO
-		/*
-		if( xmpp.Stream.REGEXP_ERROR.match( t ) ) {
-		//if( ~/stream:error/.match( t ) ) {
-			var err : xmpp.StreamError = null;
-			try {
-				err = xmpp.StreamError.parse( Xml.parse( t ) );
-			} catch( e : Dynamic ) {
-				onClose( "Invalid XMPP stream "+e );
-				close( true );
-				return -1;
-			}
-			onClose( err );
 			close( true );
 			return -1;
 		}
-		*/
 		switch( status ) {
 		case closed :
-			return -1;//buflen; //hm?
+			return -1;//buflen?
 		case pending :
 			return processStreamInit( XmlUtil.removeXmlHeader( t ), buflen );
 		case open :
-
-			// HACK flash/js Xml bug !
-			#if (flash||js)
-			if(  t.charAt( 0 ) != "<" || t.charAt( t.length-1 ) != ">" ) {
-				return 0;
-			}
-			/*
-			if( !StringTools.startsWith(t,"<") || !StringTools.endsWith(t, ">") ) {
-				if( !REG_HACK.match( t ) ) {
-					#if JABBER_DEBUG
-					trace( "Invalid XML " );
-					#end
-					return 0;
-				}
-			}
-			*/
-			#end
 			// filter data here ?
 			var x : Xml = null;
 			try {
 				x = Xml.parse( t );
 			} catch( e : Dynamic ) {
-				//#if JABBER_DEBUG
-				//trace("WAIT FOR MORE "+t,"warn" );
-				//#end
+				#if JABBER_DEBUG
+				trace( "Packet incomplete, wating for more data ..", "info" );
+				#end
 				return 0; // wait for more data
 			}
 			handleXml( x );
@@ -386,19 +357,19 @@ class Stream {
 		return 0;
 	}

-	//HACK
-	#if (flash||js)
-	//static inline var REG_HACK = ~/(.+)(\/[a-zA-Z-]*)>$/;
-	#end
-	//HACK
-
 	/**
 		Inject incoming XML data to handle.<br/>
-		Returns array of handled packets.
+		Returns array of handled XMPP packets.
 	*/
 	public function handleXml( x : Xml ) : Array<xmpp.Packet> {
 		var ps = new Array<xmpp.Packet>();
 		for( e in x.elements() ) {
+			//TODO
+			/*
+			var p = xmpp.Packet.parse( e );
+			if( p != null && handlePacket( p ) )
+				ps.push( p );
+			*/
 			var p = xmpp.Packet.parse( e );
 			handlePacket( p );
 			ps.push( p );
@@ -416,27 +387,28 @@ class Stream {
 		#end
 		var collected = false;
 		for( c in collectors ) {
-			//if( c == null ) {
-				//collectors.remove( c );
-			//}
+			/*
+			if( c.handlers.length == 0 ) {
+				collectors.remove( c );
+				continue;
+			}
+			*/
 			if( c.accept( p ) ) {
 				collected = true;
-				//if( c.deliver == null )
-				//	collectors.remove( c );
-				//if( !c.deliver( p ) ) {
-				//}
 				c.deliver( p );
-				if( !c.permanent )
+				if( !c.permanent ) {
 					collectors.remove( c );
-				if( c.block )
+				}
+				if( c.block ) {
 					break;
+				}
 			}
 		}
 		if( !collected ) {
 			#if JABBER_DEBUG
 			trace( "incoming '"+Type.enumConstructor( p._type )+"' packet not handled ( "+p.from+" -> "+p.to+" )", "warn" );
 			#end
-			if( p._type == xmpp.PacketType.iq ) { // send a 'feature not implemented' response
+			if( p._type == xmpp.PacketType.iq ) { // send 'feature not implemented' response
 				var q : xmpp.IQ = cast p;
 				if( q.type != xmpp.IQType.error ) {
 					var r = new xmpp.IQ( xmpp.IQType.error, p.id, p.from, p.to );
@@ -457,11 +429,7 @@ class Stream {
 	*/

 	function processStreamInit( t : String, buflen : Int ) : Int {
-		#if JABBER_DEBUG
 		return throw "Abstract method";
-		#else
-		return -1;
-		#end
 	}

 	function closeHandler() {
diff --git a/jabber/XMPPDebug.hx b/jabber/XMPPDebug.hx
index eedcef9..456ee6b 100644
--- a/jabber/XMPPDebug.hx
+++ b/jabber/XMPPDebug.hx
@@ -58,9 +58,9 @@ class XMPPDebug {
 			return;
 		}
 		ExternalInterface.addCallback( "sendData", function(t:String){
-			if( stream != null )
-				return stream.sendData( t );
-			return null;
+			if( stream == null )
+				return null;
+			return stream.sendData( t );
 		} );
 		#end
 		#elseif js
@@ -73,6 +73,21 @@ class XMPPDebug {
 	}
 	#end

+	/*
+	public static function outPacket( p : xmpp.Packet ) {
+		var v = haxe.Serializer.run( p );
+		try {
+			#if flash
+			ExternalInterface.call( 'hxmpp.Console.printPacket("'+v+'",'+out+')' );
+			#elseif js
+			untyped hxmpp.Console.printPacket( v, out );
+			#end
+		} catch( e : Dynamic ) {
+			trace( "HXMPP.console debugging error: "+e, "warn" );
+		}
+	}
+	*/
+
 	public static function inc( t : String ) {
 		#if JABBER_CONSOLE
 		printToXMPPConsole( t, false );
@@ -89,7 +104,7 @@ class XMPPDebug {

 	#if JABBER_CONSOLE
 	static function printToXMPPConsole( t : String, out : Bool ) {
-	var v = haxe.Serializer.run( t );
+		var v = haxe.Serializer.run( t );
 		try {
 			#if flash
 			ExternalInterface.call( 'hxmpp.Console.print("'+v+'",'+out+')' );
@@ -149,8 +164,7 @@ class XMPPDebug {
 			untyped console[level]( dir+t );
 			#end
 		} else {
-			//TODO
-			haxe.Log.trace( t, { className : "", methodName : "", fileName : dir, lineNumber : 0, customParams : [] } );
+			//haxe.Log.trace( t, { className : "", methodName : "", fileName : dir, lineNumber : 0, customParams : [] } );
 		}
 	}

diff --git a/jabber/client/Authentication.hx b/jabber/client/Authentication.hx
index d3cd850..6635c2d 100644
--- a/jabber/client/Authentication.hx
+++ b/jabber/client/Authentication.hx
@@ -18,7 +18,7 @@
 package jabber.client;

 /**
-	Abstract client account authentication.
+	Abstract client authentication.
 */
 class Authentication {

@@ -33,7 +33,11 @@ class Authentication {
 	}

 	public function authenticate( password : String, ?resource : String ) : Bool {
+		#if JABBER_DEBUG
 		return throw "Abstract error";
+		#else
+		return false;
+		#end
 	}

 }
diff --git a/jabber/client/NonSASLAuth.hx b/jabber/client/NonSASLAuth.hx
new file mode 100644
index 0000000..0acb6b8
--- /dev/null
+++ b/jabber/client/NonSASLAuth.hx
@@ -0,0 +1,81 @@
+/*
+ *	This file is part of HXMPP.
+ *	Copyright (c)2009 http://www.disktree.net
+ *
+ *	HXMPP is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HXMPP is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *	See the GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
+*/
+package jabber.client;
+
+/**
+	<a href="http://xmpp.org/extensions/xep-0078.html">XEP-0078: Multi-User Chat</a><br>
+*/
+class NonSASLAuth extends Authentication {
+
+	public var active(default,null) : Bool;
+	public var usePlainText(default,null) : Bool;
+	public var username(default,null) : String;
+	public var password(default,null) : String;
+
+	public function new( stream : Stream,
+						 /*?onSuccess : Void->Void, ?onFail : jabber.XMPPError->Void,*/
+					 	 ?usePlainText : Bool = false ) {
+		#if JABBER_DEBUG
+		if( stream.http )
+			throw "NonSASL authentication is not supported on HTTP/BOSH connections";
+		#end
+		super( stream );
+		this.usePlainText = usePlainText;
+		username = stream.jid.node;
+		active = false;
+	}
+
+	public override function authenticate( password : String, ?resource : String ) {
+		if( active )
+			throw "Authentication in progress";
+		this.password = password;
+		if( resource != null ) {
+			this.resource = resource;
+			stream.jid.resource = resource; // update stream jid resource
+		}
+		active = true;
+		var iq = new xmpp.IQ();
+		iq.x = new xmpp.Auth( username );
+		stream.sendIQ( iq, handleResponse );
+		return true;
+	}
+
+
+	function handleResponse( iq : xmpp.IQ ) {
+		switch( iq.type ) {
+		case result :
+			var hasDigest = ( !usePlainText && iq.x.toXml().elementsNamed( "digest" ).next() != null );
+			var r = new xmpp.IQ( xmpp.IQType.set );
+			r.x = if( hasDigest ) new xmpp.Auth( username, null, crypt.SHA1.encode( stream.id+password ), resource );
+			else new xmpp.Auth( username, password, null, resource );
+			stream.sendIQ( r, handleResult );
+		case error : onFail( new jabber.XMPPError( this, iq ) );
+		default : //#
+		}
+	}
+
+	function handleResult( iq : xmpp.IQ ) {
+		active = false;
+		switch( iq.type ) {
+		case result : onSuccess();
+		case error : onFail( new jabber.XMPPError( this, iq ) );
+		default : //#
+		}
+	}
+
+}
diff --git a/jabber/client/NonSASLAuthentication.hx b/jabber/client/NonSASLAuthentication.hx
deleted file mode 100644
index 4a689e9..0000000
--- a/jabber/client/NonSASLAuthentication.hx
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *	This file is part of HXMPP.
- *	Copyright (c)2009 http://www.disktree.net
- *
- *	HXMPP is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  HXMPP is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *	See the GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
-*/
-package jabber.client;
-
-/**
-	<a href="http://xmpp.org/extensions/xep-0078.html">XEP-0078: Multi-User Chat</a><br>
-*/
-class NonSASLAuthentication extends Authentication {
-
-	public var active(default,null) : Bool;
-	public var usePlainText(default,null) : Bool;
-	public var username(default,null) : String;
-	public var password(default,null) : String;
-
-	public function new( stream : Stream,
-						 /*?onSuccess : Void->Void, ?onFail : jabber.XMPPError->Void,*/
-					 	 ?usePlainText : Bool = false ) {
-		#if JABBER_DEBUG
-		if( stream.http )
-			throw "NonSASL authentication is not supported on HTTP/BOSH connections";
-		#end
-		super( stream );
-		this.usePlainText = usePlainText;
-		username = stream.jid.node;
-		active = false;
-	}
-
-	public override function authenticate( password : String, ?resource : String ) {
-		if( active )
-			throw "Authentication in progress";
-		this.password = password;
-		if( resource != null ) {
-			this.resource = resource;
-			stream.jid.resource = resource; // update stream jid resource
-		}
-		active = true;
-		var iq = new xmpp.IQ();
-		iq.x = new xmpp.Auth( username );
-		stream.sendIQ( iq, handleResponse );
-		return true;
-	}
-
-
-	function handleResponse( iq : xmpp.IQ ) {
-		switch( iq.type ) {
-		case result :
-			var hasDigest = ( !usePlainText && iq.x.toXml().elementsNamed( "digest" ).next() != null );
-			var r = new xmpp.IQ( xmpp.IQType.set );
-			trace(stream.id+" /// "+password);
-			r.x = if( hasDigest ) new xmpp.Auth( username, null, crypt.SHA1.encode( stream.id+password ), resource );
-			else new xmpp.Auth( username, password, null, resource );
-			stream.sendIQ( r, handleResult );
-		case error : onFail( new jabber.XMPPError( this, iq ) );
-		default : //#
-		}
-	}
-
-	function handleResult( iq : xmpp.IQ ) {
-		active = false;
-		switch( iq.type ) {
-		case result : onSuccess();
-		case error : onFail( new jabber.XMPPError( this, iq ) );
-		default : //#
-		}
-	}
-
-}
diff --git a/jabber/client/Roster.hx b/jabber/client/Roster.hx
index 9cb49eb..ec18349 100644
--- a/jabber/client/Roster.hx
+++ b/jabber/client/Roster.hx
@@ -24,8 +24,6 @@ import xmpp.roster.Item;
 import xmpp.roster.AskType;
 import xmpp.roster.Subscription;

-/**
-*/
 enum RosterSubscriptionMode {
 	/** Accept all subscription and unsubscription requests. */
 	acceptAll( subscribe : Bool );
diff --git a/jabber/client/SASLAuth.hx b/jabber/client/SASLAuth.hx
new file mode 100644
index 0000000..e2e5c14
--- /dev/null
+++ b/jabber/client/SASLAuth.hx
@@ -0,0 +1,195 @@
+/*
+ *	This file is part of HXMPP.
+ *	Copyright (c)2009 http://www.disktree.net
+ *
+ *	HXMPP is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HXMPP is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *	See the GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
+*/
+package jabber.client;
+
+import jabber.stream.PacketCollector;
+import xmpp.IQ;
+import xmpp.IQType;
+import xmpp.filter.PacketNameFilter;
+import xmpp.filter.FilterGroup;
+
+// try another mechanism on fail (?)
+
+/**
+	Responsible for authenticating a client account using SASL,
+	binding the resource to the connection and establishing a session with the server.<br/>
+	<a href="http://xmpp.org/rfcs/rfc3920.html#sasl">RFC3920-SASL</a><br/>
+	<a href="http://xmpp.org/rfcs/rfc3920.html#bind">RFC3920-BIND</a><br/>
+*/
+class SASLAuth extends Authentication {
+
+	public dynamic function onNegotiated() : Void;
+
+	/** Used SASL method */
+	public var handshake(default,null) : net.sasl.Handshake;
+	/** Available mechanisms ids (server) */
+	public var mechanisms(default,null) : Array<String>;
+	//public var negotiated(default,null) : Bool;
+
+	var onStreamOpenHandler : Void->Void;
+	var c_challenge : PacketCollector;
+	var c_fail : PacketCollector;
+	var c_success : PacketCollector;
+
+	public function new( stream : Stream, mechanisms : Iterable<net.sasl.Mechanism> ) {
+		var x = stream.server.features.get( "mechanisms" );
+		if( x == null )
+			throw "Server does't support SASL";
+		if( mechanisms == null || Lambda.count( mechanisms ) == 0 )
+			throw "No SASL mechanisms given";
+		super( stream );
+		this.mechanisms = xmpp.SASL.parseMechanisms( x );
+		handshake = new net.sasl.Handshake();
+		for( m in mechanisms )
+			handshake.mechanisms.push( m );
+	}
+
+	/**
+		Inits SASL authentication.
+		Returns false if no compatible SASL mechanism was found.
+	*/
+	public override function authenticate( password : String, ?resource : String ) : Bool {
+		this.resource = resource;
+		// update stream jid resource
+		if( stream.jid != null && resource != null )
+			stream.jid.resource = resource;
+		// locate mechanism to use.
+		if( handshake.mechanism == null ) {
+			for( amechs in mechanisms ) {
+				for( m in handshake.mechanisms ) {
+					if( m.id != amechs )
+						continue;
+					handshake.mechanism = m;
+					break;
+				}
+				if( handshake.mechanism != null )
+					break;
+			}
+		}
+		if( handshake.mechanism == null ) {
+			#if JABBER_DEBUG
+			trace( "No matching SASL mechanism found.", "warn" );
+			#end
+			return false;
+		}
+		// collect failures
+		var f = new FilterGroup();
+		f.add( new PacketNameFilter( ~/failure/ ) ); //?
+		f.add( new PacketNameFilter( ~/not-authorized/ ) );
+		f.add( new PacketNameFilter( ~/aborted/ ) );
+		f.add( new PacketNameFilter( ~/incorrect-encoding/ ) );
+		f.add( new PacketNameFilter( ~/invalid-authzid/ ) );
+		f.add( new PacketNameFilter( ~/invalid-mechanism/ ) );
+		f.add( new PacketNameFilter( ~/mechanism-too-weak/ ) );
+		f.add( new PacketNameFilter( ~/temporary-auth-failure/ ) );
+		c_fail = new PacketCollector( [cast f], handleSASLFailed );
+		stream.addCollector( c_fail );
+		// collect success response
+		c_success = new PacketCollector( [cast new PacketNameFilter( ~/success/ )], handleSASLSuccess );
+		stream.addCollector( c_success );
+		// collect challenge response
+		c_challenge = new PacketCollector( [cast new PacketNameFilter( ~/challenge/ )], handleSASLChallenge, true );
+		stream.addCollector( c_challenge );
+		// init auth
+		var t = handshake.mechanism.createAuthenticationText( stream.jid.node, stream.jid.domain, password );
+		if( t != null ) t = util.Base64.encode( t );
+		return stream.sendData( xmpp.SASL.createAuthXml( handshake.mechanism.id, t ).toString() ) != null;
+	}
+
+	function handleSASLFailed( p : xmpp.Packet ) {
+		removeSASLCollectors();
+		onFail();
+	}
+
+	function handleSASLChallenge( p : xmpp.Packet ) {
+		// create/send challenge response
+		var c = p.toXml().firstChild().nodeValue;
+		var r = util.Base64.encode( handshake.getChallengeResponse( c ) );
+		stream.sendData( xmpp.SASL.createResponseXml( r ).toString() );
+	}
+
+	function handleSASLSuccess( p : xmpp.Packet ) {
+		removeSASLCollectors(); // remove the challenge collector
+		onStreamOpenHandler = stream.onOpen; // relay the stream open event
+		stream.onOpen = handleStreamOpen;
+		onNegotiated();
+		//stream.version = false;
+		stream.open(); // re-open XMPP stream
+		//return p.toString().length;
+	}
+
+	function handleStreamOpen() {
+		stream.onOpen = onStreamOpenHandler;
+		//onStreamOpenHandler = null;
+		if( stream.server.features.exists( "bind" ) ) { // bind the resource
+			var iq = new IQ( IQType.set );
+			iq.x = new xmpp.Bind( ( handshake.mechanism.id == "ANONYMOUS" ) ? null : resource );
+			stream.sendIQ( iq, handleBind );
+		} else {
+			onSuccess(); // TODO ?
+		}
+	}
+
+	function handleBind( iq : IQ ) {
+		switch( iq.type ) {
+		case IQType.result :
+			/*
+			// TODO required ?
+			var b = xmpp.Bind.parse( iq.x.toXml() );
+			if( jabber.util.JIDUtil.parseResource( b.jid ) != resource ) {
+				throw "Unexpected resource bound ?";
+			}
+			*/
+			//onBind();
+			var b = xmpp.Bind.parse( iq.x.toXml() );
+			var jid = new jabber.JID( b.jid );
+			stream.jid.node = jid.node;
+			stream.jid.resource = jid.resource;
+			if( stream.server.features.exists( "session" ) ) {
+				// init session
+				var iq = new IQ( IQType.set );
+				iq.x = new xmpp.PlainPacket( Xml.parse( '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' ).firstElement() );
+				stream.sendIQ( iq, handleSession );
+			} else
+				onSuccess(); //?
+		case IQType.error :
+			onFail( new jabber.XMPPError( this, iq ) );
+		}
+	}
+
+	function handleSession( iq : IQ ) {
+		switch( iq.type ) {
+		case result :
+			////onSession();
+			onSuccess();
+		case error :
+			onFail( new jabber.XMPPError( this, iq ) );
+		default : //#
+		}
+	}
+
+	function removeSASLCollectors() {
+		stream.removeCollector( c_challenge );
+		c_challenge = null;
+		stream.removeCollector( c_fail );
+		c_fail = null;
+		stream.removeCollector( c_success );
+		c_success = null;
+	}
+
+}
diff --git a/jabber/client/SASLAuthentication.hx b/jabber/client/SASLAuthentication.hx
deleted file mode 100644
index d5696a7..0000000
--- a/jabber/client/SASLAuthentication.hx
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *	This file is part of HXMPP.
- *	Copyright (c)2009 http://www.disktree.net
- *
- *	HXMPP is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  HXMPP is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *	See the GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
-*/
-package jabber.client;
-
-import jabber.stream.PacketCollector;
-import xmpp.IQ;
-import xmpp.IQType;
-import xmpp.filter.PacketNameFilter;
-import xmpp.filter.FilterGroup;
-
-// try another mechanism on fail (?)
-
-/**
-	Responsible for authenticating a client account using SASL,
-	binding the resource to the connection and establishing a session with the server.<br/>
-	<a href="http://xmpp.org/rfcs/rfc3920.html#sasl">RFC3920-SASL</a><br/>
-	<a href="http://xmpp.org/rfcs/rfc3920.html#bind">RFC3920-BIND</a><br/>
-*/
-class SASLAuthentication extends Authentication {
-
-	public dynamic function onNegotiated() : Void;
-
-	/** Used SASL method */
-	public var handshake(default,null) : net.sasl.Handshake;
-	/** Available mechanisms ids (server) */
-	public var mechanisms(default,null) : Array<String>;
-	//public var negotiated(default,null) : Bool;
-
-	var onStreamOpenHandler : Void->Void;
-	var c_challenge : PacketCollector;
-	var c_fail : PacketCollector;
-	var c_success : PacketCollector;
-
-	public function new( stream : Stream, mechanisms : Iterable<net.sasl.Mechanism> ) {
-		var x = stream.server.features.get( "mechanisms" );
-		if( x == null )
-			throw "Server does't support SASL";
-		if( mechanisms == null || Lambda.count( mechanisms ) == 0 )
-			throw "No SASL mechanisms given";
-		super( stream );
-		this.mechanisms = xmpp.SASL.parseMechanisms( x );
-		handshake = new net.sasl.Handshake();
-		for( m in mechanisms )
-			handshake.mechanisms.push( m );
-	}
-
-	/**
-		Inits SASL authentication.
-		Returns false if no compatible SASL mechanism was found.
-	*/
-	public override function authenticate( password : String, ?resource : String ) : Bool {
-		this.resource = resource;
-		// update stream jid resource
-		if( stream.jid != null && resource != null )
-			stream.jid.resource = resource;
-		// locate mechanism to use.
-		if( handshake.mechanism == null ) {
-			for( amechs in mechanisms ) {
-				for( m in handshake.mechanisms ) {
-					if( m.id != amechs )
-						continue;
-					handshake.mechanism = m;
-					break;
-				}
-				if( handshake.mechanism != null )
-					break;
-			}
-		}
-		if( handshake.mechanism == null ) {
-			#if JABBER_DEBUG
-			trace( "No matching SASL mechanism found.", "warn" );
-			#end
-			return false;
-		}
-		// collect failures
-		var f = new FilterGroup();
-		f.add( new PacketNameFilter( ~/failure/ ) ); //?
-		f.add( new PacketNameFilter( ~/not-authorized/ ) );
-		f.add( new PacketNameFilter( ~/aborted/ ) );
-		f.add( new PacketNameFilter( ~/incorrect-encoding/ ) );
-		f.add( new PacketNameFilter( ~/invalid-authzid/ ) );
-		f.add( new PacketNameFilter( ~/invalid-mechanism/ ) );
-		f.add( new PacketNameFilter( ~/mechanism-too-weak/ ) );
-		f.add( new PacketNameFilter( ~/temporary-auth-failure/ ) );
-		c_fail = new PacketCollector( [cast f], handleSASLFailed );
-		stream.addCollector( c_fail );
-		// collect success response
-		c_success = new PacketCollector( [cast new PacketNameFilter( ~/success/ )], handleSASLSuccess );
-		stream.addCollector( c_success );
-		// collect challenge response
-		c_challenge = new PacketCollector( [cast new PacketNameFilter( ~/challenge/ )], handleSASLChallenge, true );
-		stream.addCollector( c_challenge );
-		// init auth
-		var t = handshake.mechanism.createAuthenticationText( stream.jid.node, stream.jid.domain, password );
-		if( t != null ) t = util.Base64.encode( t );
-		return stream.sendData( xmpp.SASL.createAuthXml( handshake.mechanism.id, t ).toString() ) != null;
-	}
-
-	function handleSASLFailed( p : xmpp.Packet ) {
-		removeSASLCollectors();
-		onFail();
-	}
-
-	function handleSASLChallenge( p : xmpp.Packet ) {
-		// create/send challenge response
-		var c = p.toXml().firstChild().nodeValue;
-		var r = util.Base64.encode( handshake.getChallengeResponse( c ) );
-		stream.sendData( xmpp.SASL.createResponseXml( r ).toString() );
-	}
-
-	function handleSASLSuccess( p : xmpp.Packet ) {
-		removeSASLCollectors(); // remove the challenge collector
-		onStreamOpenHandler = stream.onOpen; // relay the stream open event
-		stream.onOpen = handleStreamOpen;
-		onNegotiated();
-		//stream.version = false;
-		stream.open(); // re-open XMPP stream
-		//return p.toString().length;
-	}
-
-	function handleStreamOpen() {
-		stream.onOpen = onStreamOpenHandler;
-		//onStreamOpenHandler = null;
-		if( stream.server.features.exists( "bind" ) ) { // bind the resource
-			var iq = new IQ( IQType.set );
-			iq.x = new xmpp.Bind( ( handshake.mechanism.id == "ANONYMOUS" ) ? null : resource );
-			stream.sendIQ( iq, handleBind );
-		} else {
-			onSuccess(); // TODO ?
-		}
-	}
-
-	function handleBind( iq : IQ ) {
-		switch( iq.type ) {
-		case IQType.result :
-			/*
-			// TODO required ?
-			var b = xmpp.Bind.parse( iq.x.toXml() );
-			if( jabber.util.JIDUtil.parseResource( b.jid ) != resource ) {
-				throw "Unexpected resource bound ?";
-			}
-			*/
-			//onBind();
-			var b = xmpp.Bind.parse( iq.x.toXml() );
-			var jid = new jabber.JID( b.jid );
-			stream.jid.node = jid.node;
-			stream.jid.resource = jid.resource;
-			if( stream.server.features.exists( "session" ) ) {
-				// init session
-				var iq = new IQ( IQType.set );
-				iq.x = new xmpp.PlainPacket( Xml.parse( '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' ) );
-				stream.sendIQ( iq, handleSession );
-			} else
-				onSuccess(); //?
-		case IQType.error :
-			onFail( new jabber.XMPPError( this, iq ) );
-		}
-	}
-
-	function handleSession( iq : IQ ) {
-		switch( iq.type ) {
-		case result :
-			////onSession();
-			onSuccess();
-		case error :
-			onFail( new jabber.XMPPError( this, iq ) );
-		default : //#
-		}
-	}
-
-	function removeSASLCollectors() {
-		stream.removeCollector( c_challenge );
-		c_challenge = null;
-		stream.removeCollector( c_fail );
-		c_fail = null;
-		stream.removeCollector( c_success );
-		c_success = null;
-	}
-
-}
diff --git a/jabber/client/Stream.hx b/jabber/client/Stream.hx
index 16b0eca..43946a7 100644
--- a/jabber/client/Stream.hx
+++ b/jabber/client/Stream.hx
@@ -31,7 +31,6 @@ class Stream extends jabber.Stream {
 	public static var defaultPort = PORT_STANDARD;

 	public var jid(default,setJID) : JID;
-	// public var tls(default,null) : Bool;

 	public function new( ?jid : JID, ?cnx : Connection, ?version : Bool = true ) {
 		if( jid == null )
@@ -39,7 +38,6 @@ class Stream extends jabber.Stream {
 		super( cnx );
 		this.jid = jid;
 		this.version = version;
-		//this.tls = tls;
 	}

 	override function getJIDStr() : String {
@@ -54,12 +52,11 @@ class Stream extends jabber.Stream {

 	override function processStreamInit( t : String, buflen : Int ) : Int {
 		if( http ) {
-			var sx = Xml.parse( t ).firstElement();
-			var sf = sx.firstElement();
 			#if XMPP_DEBUG
-			//jabber.XMPPDebug.inc( sf.toString() );
 			jabber.XMPPDebug.inc( t );
 			#end
+			var x = Xml.parse( t ).firstElement();
+			var sf = x.firstElement();
 			parseStreamFeatures( sf );
 			status = StreamStatus.open;
 			onOpen();
@@ -70,7 +67,7 @@ class Stream extends jabber.Stream {
 				return 0;
 			}
 			if( id == null ) { // parse open stream
-				var s = t.substr( 0, sei ) + " />";
+				var s = t.substr( 0, sei )+" />";
 				#if XMPP_DEBUG
 				jabber.XMPPDebug.inc( s );
 				#end
@@ -83,6 +80,7 @@ class Stream extends jabber.Stream {
 				}
 			}
 			if( id == null ) {
+				//TODO throw error
 				#if JABBER_DEBUG
 				trace( "Invalid XMPP stream, missing ID" );
 				#end
@@ -96,13 +94,13 @@ class Stream extends jabber.Stream {
 			}
 		}
 		var sfi = t.indexOf( "<stream:features>" );
-		var sf = t.substr( t.indexOf( "<stream:features>" ) );
+		var sf = t.substr( sfi );
 		if( sfi != -1 ) {
 			try {
-				var sfx = Xml.parse( sf ).firstElement();
-				parseStreamFeatures( sfx );
+				var x = Xml.parse( sf ).firstElement();
+				parseStreamFeatures( x );
 				#if XMPP_DEBUG
-				jabber.XMPPDebug.inc( sfx.toString() );
+				jabber.XMPPDebug.inc( x.toString() );
 				#end
 				status = StreamStatus.open;
 				onOpen();
@@ -133,8 +131,9 @@ class Stream extends jabber.Stream {
 	}
 	*/

-	function parseStreamFeatures( x : Xml ) {
+	inline function parseStreamFeatures( x : Xml ) {
 		for( e in x.elements() )
 			server.features.set( e.nodeName, e );
 	}
+
 }
diff --git a/jabber/component/Stream.hx b/jabber/component/Stream.hx
index 7467f7a..7e16b00 100644
--- a/jabber/component/Stream.hx
+++ b/jabber/component/Stream.hx
@@ -86,13 +86,34 @@ class Stream extends jabber.Stream {
 		cnx.read( true );
 	}

+	//TODO!!!!!!!!!
 	override function processStreamInit( t : String, len : Int ) {
-		//TODO
 		var i = t.indexOf( ">" );
 		if( i == -1 )
 			return 0;
+		/*
+		try {
+			var x = Xml.parse( t ).firstChild();
+			for( e in x.elements() ) {
+				trace(e.nodeName);
+				if( e.nodeName == "stream:error" ) {
+					trace(e.firstChild().nodeName);
+					onClose( e.firstChild().nodeName );
+					return -1;
+				}
+			}
+		} catch( e : Dynamic ) {
+			trace("ERRORERRORERRORERROR "+e);
+		}
+		trace(t);
+		*/
+		//TODO
 		id = Xml.parse( t+"</stream:stream>" ).firstChild().get( "id" );
+		//..
 		status = jabber.StreamStatus.open;
+		#if XMPP_DEBUG
+		jabber.XMPPDebug.inc( t );
+		#end
 		onOpen();
 		collectors.add( new  jabber.stream.PacketCollector( [ cast new xmpp.filter.PacketNameFilter( ~/handshake/ ) ], readyHandler, false ) );
 		sendData( util.XmlUtil.createElement( "handshake", Xml.createPCData( crypt.SHA1.encode( id+secret ) ).toString() ).toString() );
diff --git a/jabber/file/FileTransfer.hx b/jabber/file/FileTransfer.hx
index d9bfc1e..1d298bf 100644
--- a/jabber/file/FileTransfer.hx
+++ b/jabber/file/FileTransfer.hx
@@ -23,9 +23,9 @@ package jabber.file;
 class FileTransfer {

 	//public dynamic function onReject( t : Transfer ) : Void;
-	public dynamic function onInit( t : FileTransfer ) : Void;
-	public dynamic function onComplete( t : FileTransfer ) : Void;
-	public dynamic function onFail( t : FileTransfer, e : jabber.XMPPError  ) : Void;
+	public dynamic function onInit( ft : FileTransfer ) : Void;
+	public dynamic function onComplete( ft : FileTransfer ) : Void;
+	public dynamic function onFail( ft : FileTransfer, e : jabber.XMPPError  ) : Void;

 	public var stream(default,null) : jabber.Stream;
 	/** The namespace of the transfer method used */
@@ -46,7 +46,9 @@ class FileTransfer {
 	}

 	public function init( input : haxe.io.Input ) {
+		#if JABBER_DEBUG
 		throw "Abstract method";
+		#end
 	}

 }
diff --git a/jabber/file/io/ByteStreamInput.hx b/jabber/file/io/ByteStreamInput.hx
index 741214c..51c01bd 100644
--- a/jabber/file/io/ByteStreamInput.hx
+++ b/jabber/file/io/ByteStreamInput.hx
@@ -52,9 +52,8 @@ typedef Buffer = {
 /**
 	flash9,neko,cpp,php.
 	Socket bytestream input.
-	!Attention: PHP does not support threads, means, transfer blocks until ended!
+	!Attention: PHP does not support threads, which means the transfer will block until finished.
 */
-//TODO SockInput
 //TODO SOCKSInput
 class ByteStreamInput {

diff --git a/jabber/file/io/ByteStreamOutput.hx b/jabber/file/io/ByteStreamOutput.hx
index f1d304b..5744d5c 100644
--- a/jabber/file/io/ByteStreamOutput.hx
+++ b/jabber/file/io/ByteStreamOutput.hx
@@ -33,8 +33,8 @@ enum SOCKS5State {
 }


+	//TODO SOCKS5 server
 /**
-	TODO SOCKS5 server

 	neko,cpp.
 */
diff --git a/jabber/stream/Connection.hx b/jabber/stream/Connection.hx
index 694e2b0..7c096cc 100644
--- a/jabber/stream/Connection.hx
+++ b/jabber/stream/Connection.hx
@@ -33,7 +33,7 @@ class Connection {
 	public var __onData : haxe.io.Bytes->Int->Int->Int;

 	/** Callback connection level errors */
-	public var __onError : String->Void;
+	public var __onError : String->Void; //TODO remove, use: __onDisconnect(?e)

 	/** Server IP/hostname */
 	public var host(default,null) : String;
@@ -60,28 +60,35 @@ class Connection {
 		Try to connect the stream data connection.
 	*/
 	public function connect() {
+		#if JABBER_DEBUG
 		throw "Abstract method";
+		#end
 	}

 	/**
 		Disconnects stream connection.
 	*/
 	public function disconnect() { //: Bool
+		#if JABBER_DEBUG
 		throw "Abstract method";
+		#end
 	}

 	/**
 		Starts/Stops reading data input.
 	*/
 	public function read( ?yes : Bool = true ) : Bool {
-		return throw "Abstract method";
+		return false;
 	}

 	/**
 		Send string.
 	*/
 	public function write( t : String ) : Bool {
+		#if JABBER_DEBUG
 		return throw "Abstract method";
+		#end
+		return false;
 	}

 	//TODO
diff --git a/out/hxmpp-debug.swc b/out/hxmpp-debug.swc
deleted file mode 100644
index fa3e5a9..0000000
Binary files a/out/hxmpp-debug.swc and /dev/null differ
diff --git a/out/hxmpp.swc b/out/hxmpp.swc
deleted file mode 100644
index a51ce47..0000000
Binary files a/out/hxmpp.swc and /dev/null differ
diff --git a/samples/client/ClientDemo.hx b/samples/client/ClientDemo.hx
index d0e9c1a..6521180 100644
--- a/samples/client/ClientDemo.hx
+++ b/samples/client/ClientDemo.hx
@@ -1,7 +1,7 @@

 import jabber.SocketConnection;
 import jabber.ServiceDiscovery;
-import jabber.client.NonSASLAuthentication;
+import jabber.client.NonSASLAuth;
 import jabber.client.Stream;
 import jabber.client.Roster;
 import jabber.client.VCard;
@@ -46,7 +46,7 @@ class ClientDemo {
 			*/
 			var mechanisms = new Array<net.sasl.Mechanism>();
 			mechanisms.push( new net.sasl.PlainMechanism() );
-			var auth = new jabber.client.SASLAuthentication( stream, mechanisms );
+			var auth = new jabber.client.SASLAuth( stream, mechanisms );
 			auth.onSuccess = handleLogin;
 			auth.onFail = function(?e) {
 				trace( "Authentication failed", "warn" );
diff --git a/samples/client/build.hxml b/samples/client/build.hxml
index baac607..e28a8a2 100644
--- a/samples/client/build.hxml
+++ b/samples/client/build.hxml
@@ -36,15 +36,15 @@
 -D JABBER_DEBUG
 -debug

-#--next
-#-cp ../../
-#-cp ../../lib
-#-cpp client
-#-main ClientDemo
-#-D XMPP_DEBUG
-#-D JABBER_DEBUG
-#-D HXCPP_MULTI_THREADED
+--next
+-cp ../../
+-cp ../../lib
+-cpp client
+-main ClientDemo
+-D XMPP_DEBUG
+-D JABBER_DEBUG
+-D HXCPP_MULTI_THREADED
 #-debug

 ### MXMLC-SWC
--cmd mxmlc ClientDemo.as -default-size 800 600 -include-libraries ../../out//hxmpp.swc -output clientAS3.swf
+#-cmd mxmlc ClientDemo.as -default-size 800 600 -include-libraries ../../out//hxmpp.swc -output clientAS3.swf
diff --git a/samples/client/test.html b/samples/client/test.html
new file mode 100644
index 0000000..9247a13
--- /dev/null
+++ b/samples/client/test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="author" content="disktree.net" />
+<title>HXMPP</title>
+<script type="text/javascript" src="../swfobject.js"/></script>
+<style type="text/css">
+html { height:100%; }
+body { height:100%; }
+</style>
+</head>
+<body>
+<div>HXMPP flash usage</div>
+<div id="swf">NO FLASHPLAYER DETECTED</div>
+<script type="text/javascript">
+swfobject.embedSWF("client.swf","swf","100%","100%","9.0.0");
+</script>
+</body>
+</html>
diff --git a/util/neko.h b/util/neko.h
new file mode 100644
index 0000000..aa265bf
--- /dev/null
+++ b/util/neko.h
@@ -0,0 +1,431 @@
+/* ************************************************************************ */
+/*																			*/
+/*  Neko Virtual Machine													*/
+/*  Copyright (c)2005 Motion-Twin											*/
+/*																			*/
+/* This library is free software; you can redistribute it and/or			*/
+/* modify it under the terms of the GNU Lesser General Public				*/
+/* License as published by the Free Software Foundation; either				*/
+/* version 2.1 of the License, or (at your option) any later version.		*/
+/*																			*/
+/* This library is distributed in the hope that it will be useful,			*/
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of			*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU		*/
+/* Lesser General Public License or the LICENSE file for more details.		*/
+/*																			*/
+/* ************************************************************************ */
+#ifndef _NEKO_H
+#define _NEKO_H
+
+// OS FLAGS
+#if defined(_WIN32)
+#	define NEKO_WINDOWS
+#endif
+
+#if defined(__APPLE__) || defined(__MACH__) || defined(macintosh)
+#	define NEKO_MAC
+#endif
+
+#if defined(linux) || defined(__linux__)
+#	define NEKO_LINUX
+#endif
+
+#if defined(__FreeBSD_kernel__)
+#	define NEKO_GNUKBSD
+#endif
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#	define NEKO_BSD
+#endif
+
+// COMPILER/PROCESSOR FLAGS
+#if defined(__GNUC__)
+#	define NEKO_GCC
+#endif
+
+#if defined(_MSC_VER)
+#	define NEKO_VCC
+#endif
+
+#if defined(__MINGW32__)
+#	define NEKO_MINGW
+#endif
+
+#if defined(__i386__) || defined(_WIN32)
+#	define NEKO_X86
+#endif
+
+#if defined(__ppc__)
+#	define NEKO_PPC
+#endif
+
+#if defined(_64BITS)
+#	define NEKO_64BITS
+#endif
+
+#if defined(NEKO_LINUX) || defined(NEKO_MAC) || defined(NEKO_BSD) || defined(NEKO_GNUKBSD)
+#	define NEKO_POSIX
+#endif
+
+#if defined(NEKO_GCC)
+#	define NEKO_THREADED
+#	define NEKO_DIRECT_THREADED
+#endif
+
+#ifndef NEKO_NO_THREADS
+#	define NEKO_THREADS
+#endif
+
+#include <stddef.h>
+#ifndef NEKO_VCC
+#	include <stdint.h>
+#endif
+
+#define NEKO_VERSION	181
+
+typedef intptr_t int_val;
+
+typedef enum {
+	VAL_INT			= 0xFF,
+	VAL_NULL		= 0,
+	VAL_FLOAT		= 1,
+	VAL_BOOL		= 2,
+	VAL_STRING		= 3,
+	VAL_OBJECT		= 4,
+	VAL_ARRAY		= 5,
+	VAL_FUNCTION	= 6,
+	VAL_ABSTRACT	= 7,
+	VAL_PRIMITIVE	= 6 | 8,
+	VAL_JITFUN		= 6 | 16,
+	VAL_32_BITS		= 0xFFFFFFFF
+} val_type;
+
+struct _value {
+	val_type t;
+};
+
+struct _buffer;
+typedef int field;
+typedef struct { int __zero; } *vkind;
+typedef struct _value *value;
+
+typedef struct {
+	field id;
+	value v;
+} objcell;
+
+typedef struct _objtable
+{
+	int count;
+	objcell *cells;
+} objtable;
+
+typedef struct _buffer *buffer;
+typedef double tfloat;
+
+typedef void (*finalizer)(value v);
+
+#pragma pack(4)
+typedef struct {
+	val_type t;
+	tfloat f;
+} vfloat;
+#pragma pack()
+
+typedef struct _vobject {
+	val_type t;
+	objtable table;
+	struct _vobject *proto;
+} vobject;
+
+typedef struct {
+	val_type t;
+	int nargs;
+	void *addr;
+	value env;
+	void *module;
+} vfunction;
+
+typedef struct {
+	val_type t;
+	char c;
+} vstring;
+
+typedef struct {
+	val_type t;
+	value ptr;
+} varray;
+
+typedef struct {
+	val_type t;
+	vkind kind;
+	void *data;
+} vabstract;
+
+typedef struct hcell {
+	int hkey;
+	value key;
+	value val;
+	struct hcell *next;
+} hcell;
+
+typedef struct {
+	hcell **cells;
+	int ncells;
+	int nitems;
+} vhash;
+
+struct _mt_local;
+struct _mt_lock;
+typedef struct _mt_local mt_local;
+typedef struct _mt_lock mt_lock;
+
+#define val_tag(v)			(*(val_type*)(v))
+#define val_is_null(v)		((v) == val_null)
+#define val_is_int(v)		((((int)(int_val)(v)) & 1) != 0)
+#define val_is_bool(v)		((v) == val_true || (v) == val_false)
+#define val_is_number(v)	(val_is_int(v) || val_tag(v) == VAL_FLOAT)
+#define val_is_float(v)		(!val_is_int(v) && val_tag(v) == VAL_FLOAT)
+#define val_is_string(v)	(!val_is_int(v) && (val_tag(v)&7) == VAL_STRING)
+#define val_is_function(v)	(!val_is_int(v) && (val_tag(v)&7) == VAL_FUNCTION)
+#define val_is_object(v)	(!val_is_int(v) && val_tag(v) == VAL_OBJECT)
+#define val_is_array(v)		(!val_is_int(v) && (val_tag(v)&7) == VAL_ARRAY)
+#define val_is_abstract(v)  (!val_is_int(v) && val_tag(v) == VAL_ABSTRACT)
+#define val_is_kind(v,t)	(val_is_abstract(v) && val_kind(v) == (t))
+#define val_check_kind(v,t)	if( !val_is_kind(v,t) ) neko_error();
+#define val_check_function(f,n) if( !val_is_function(f) || (val_fun_nargs(f) != (n) && val_fun_nargs(f) != VAR_ARGS) ) neko_error();
+#define val_check(v,t)		if( !val_is_##t(v) ) neko_error();
+#define val_data(v)			((vabstract*)(v))->data
+#define val_kind(v)			((vabstract*)(v))->kind
+
+#define val_type(v)			(val_is_int(v) ? VAL_INT : (val_tag(v)&7))
+#define val_int(v)			(((int)(int_val)(v)) >> 1)
+#define val_float(v)		(CONV_FLOAT ((vfloat*)(v))->f)
+#define val_bool(v)			((v) == val_true)
+#define val_number(v)		(val_is_int(v)?val_int(v):val_float(v))
+#define val_hdata(v)		((vhash*)val_data(v))
+#define val_string(v)		(&((vstring*)(v))->c)
+#define val_strlen(v)		(val_tag(v) >> 3)
+#define val_set_length(v,l) val_tag(v) = (val_tag(v)&7) | ((l) << 3)
+#define val_set_size		val_set_length
+
+#define val_array_size(v)	(val_tag(v) >> 3)
+#define val_array_ptr(v)	(&((varray*)(v))->ptr)
+#define val_fun_nargs(v)	((vfunction*)(v))->nargs
+#define alloc_int(v)		((value)(int_val)((((int)(v)) << 1) | 1))
+#define alloc_bool(b)		((b)?val_true:val_false)
+
+#define max_array_size		((1 << 29) - 1)
+#define max_string_size		((1 << 29) - 1)
+#define invalid_comparison	0xFE
+
+#undef EXTERN
+#undef EXPORT
+#undef IMPORT
+#if defined(NEKO_VCC) || defined(NEKO_MINGW)
+#	define INLINE __inline
+#	define EXPORT __declspec( dllexport )
+#	define IMPORT __declspec( dllimport )
+#else
+#	define INLINE inline
+#	define EXPORT
+#	define IMPORT
+#endif
+
+#if defined(NEKO_SOURCES) || defined(NEKO_STANDALONE)
+#	define EXTERN EXPORT
+#else
+#	define EXTERN IMPORT
+#endif
+
+#define VEXTERN extern EXTERN
+
+#ifdef __cplusplus
+#	define C_FUNCTION_BEGIN extern "C" {
+#	define C_FUNCTION_END	};
+#else
+#	define C_FUNCTION_BEGIN
+#	define C_FUNCTION_END
+#	ifndef true
+#		define true 1
+#		define false 0
+		typedef int bool;
+#	endif
+#endif
+
+#define alloc_int32(i) alloc_abstract(k_int32, (value)(int_val)(i))
+// the two upper bits must be either 00 or 11
+#define need_32_bits(i) ( ((((unsigned int)i) >> 30) + 1) & 2 )
+#define alloc_best_int(i) (need_32_bits(i) ? alloc_int32(i) : alloc_int(i))
+#define val_int32(v) (val_is_int(v)?val_int(v):(int)(int_val)val_data(v))
+#define val_is_int32(v) (val_is_int(v) || val_is_kind(v,k_int32))
+
+#define neko_error()		return NULL
+#define failure(msg)		_neko_failure(alloc_string(msg),__FILE__,__LINE__)
+#define bfailure(buf)		_neko_failure(buffer_to_string(b),__FILE__,__LINE__)
+
+#ifndef CONV_FLOAT
+#	define CONV_FLOAT
+#endif
+
+#ifdef NEKO_POSIX
+#	include <errno.h>
+#	define POSIX_LABEL(name)	name:
+#	define HANDLE_EINTR(label)	if( errno == EINTR ) goto label
+#	define HANDLE_FINTR(f,label) if( ferror(f) && errno == EINTR ) goto label
+#else
+#	define POSIX_LABEL(name)
+#	define HANDLE_EINTR(label)
+#	define HANDLE_FINTR(f,label)
+#endif
+
+#define VAR_ARGS (-1)
+#define DEFINE_PRIM_MULT(func) C_FUNCTION_BEGIN EXPORT void *func##__MULT() { return (void*)(&func); } C_FUNCTION_END
+#define DEFINE_PRIM(func,nargs) C_FUNCTION_BEGIN EXPORT void *func##__##nargs() { return (void*)(&func); } C_FUNCTION_END
+#define DEFINE_KIND(name) int_val __kind_##name = 0; vkind name = (vkind)&__kind_##name;
+
+#ifdef NEKO_STANDALONE
+#	define DEFINE_ENTRY_POINT(name)
+#else
+#	define DEFINE_ENTRY_POINT(name) C_FUNCTION_BEGIN void name(); EXPORT void *__neko_entry_point() { return &name; } C_FUNCTION_END
+#endif
+
+#ifdef HEADER_IMPORTS
+#	define H_EXTERN IMPORT
+#else
+#	define H_EXTERN EXPORT
+#endif
+
+#define DECLARE_PRIM(func,nargs) C_FUNCTION_BEGIN H_EXTERN void *func##__##nargs(); C_FUNCTION_END
+#define DECLARE_KIND(name) C_FUNCTION_BEGIN H_EXTERN extern vkind name; C_FUNCTION_END
+
+#define alloc_float			neko_alloc_float
+#define alloc_string		neko_alloc_string
+#define alloc_empty_string	neko_alloc_empty_string
+#define copy_string			neko_copy_string
+#define val_this			neko_val_this
+#define val_id				neko_val_id
+#define val_field			neko_val_field
+#define alloc_object		neko_alloc_object
+#define alloc_field			neko_alloc_field
+#define alloc_array			neko_alloc_array
+#define val_call0			neko_val_call0
+#define val_call1			neko_val_call1
+#define val_call2			neko_val_call2
+#define val_call3			neko_val_call3
+#define val_callN			neko_val_callN
+#define val_ocall0			neko_val_ocall0
+#define val_ocall1			neko_val_ocall1
+#define val_ocall2			neko_val_ocall2
+#define val_ocallN			neko_val_ocallN
+#define val_callEx			neko_val_callEx
+#define	alloc_root			neko_alloc_root
+#define free_root			neko_free_root
+#define alloc				neko_alloc
+#define alloc_private		neko_alloc_private
+#define alloc_abstract		neko_alloc_abstract
+#define alloc_function		neko_alloc_function
+#define alloc_buffer		neko_alloc_buffer
+#define buffer_append		neko_buffer_append
+#define buffer_append_sub	neko_buffer_append_sub
+#define buffer_append_char	neko_buffer_append_char
+#define buffer_to_string	neko_buffer_to_string
+#define val_buffer			neko_val_buffer
+#define val_compare			neko_val_compare
+#define val_print			neko_val_print
+#define val_gc				neko_val_gc
+#define val_throw			neko_val_throw
+#define val_rethrow			neko_val_rethrow
+#define val_iter_fields		neko_val_iter_fields
+#define val_field_name		neko_val_field_name
+#define val_hash			neko_val_hash
+#define k_int32				neko_k_int32
+#define k_hash				neko_k_hash
+#define kind_share			neko_kind_share
+
+#define alloc_local			neko_alloc_local
+#define local_get			neko_local_get
+#define local_set			neko_local_set
+#define free_local			neko_free_local
+#define alloc_lock			neko_alloc_lock
+#define lock_acquire		neko_lock_acquire
+#define lock_try			neko_lock_try
+#define lock_release		neko_lock_release
+#define free_lock			neko_free_lock
+
+C_FUNCTION_BEGIN
+
+	VEXTERN vkind k_int32;
+	VEXTERN vkind k_hash;
+
+	VEXTERN value val_null;
+	VEXTERN value val_true;
+	VEXTERN value val_false;
+
+	EXTERN value alloc_float( tfloat t );
+
+	EXTERN value alloc_string( const char *str );
+	EXTERN value alloc_empty_string( unsigned int size );
+	EXTERN value copy_string( const char *str, int_val size );
+
+	EXTERN value val_this();
+	EXTERN field val_id( const char *str );
+	EXTERN value val_field( value o, field f );
+	EXTERN value alloc_object( value o );
+	EXTERN void alloc_field( value obj, field f, value v );
+	EXTERN void val_iter_fields( value obj, void f( value v, field f, void * ), void *p );
+	EXTERN value val_field_name( field f );
+
+	EXTERN value alloc_array( unsigned int n );
+	EXTERN value alloc_abstract( vkind k, void *data );
+
+	EXTERN value val_call0( value f );
+	EXTERN value val_call1( value f, value arg );
+	EXTERN value val_call2( value f, value arg1, value arg2 );
+	EXTERN value val_call3( value f, value arg1, value arg2, value arg3 );
+	EXTERN value val_callN( value f, value *args, int nargs );
+	EXTERN value val_ocall0( value o, field f );
+	EXTERN value val_ocall1( value o, field f, value arg );
+	EXTERN value val_ocall2( value o, field f, value arg1, value arg2 );
+	EXTERN value val_ocallN( value o, field f, value *args, int nargs );
+	EXTERN value val_callEx( value vthis, value f, value *args, int nargs, value *exc );
+
+	EXTERN value *alloc_root( unsigned int nvals );
+	EXTERN void free_root( value *r );
+	EXTERN char *alloc( unsigned int nbytes );
+	EXTERN char *alloc_private( unsigned int nbytes );
+	EXTERN value alloc_function( void *c_prim, unsigned int nargs, const char *name );
+
+	EXTERN buffer alloc_buffer( const char *init );
+	EXTERN void buffer_append( buffer b, const char *s );
+	EXTERN void buffer_append_sub( buffer b, const char *s, int_val len );
+	EXTERN void buffer_append_char( buffer b, char c );
+	EXTERN value buffer_to_string( buffer b );
+	EXTERN void val_buffer( buffer b, value v );
+
+	EXTERN int val_compare( value a, value b );
+	EXTERN void val_print( value s );
+	EXTERN void val_gc( value v, finalizer f );
+	EXTERN void val_throw( value v );
+	EXTERN void val_rethrow( value v );
+	EXTERN int val_hash( value v );
+
+	EXTERN void kind_share( vkind *k, const char *name );
+	EXTERN void _neko_failure( value msg, const char *file, int line );
+
+	// MULTITHREADING API
+	EXTERN mt_local *alloc_local();
+	EXTERN void *local_get( mt_local *l );
+	EXTERN void local_set( mt_local *l, void *v );
+	EXTERN void free_local( mt_local *l );
+
+	EXTERN mt_lock *alloc_lock();
+	EXTERN void lock_acquire( mt_lock *l );
+	EXTERN int lock_try( mt_lock *l );
+	EXTERN void lock_release( mt_lock *l );
+	EXTERN void free_lock( mt_lock *l );
+
+C_FUNCTION_END
+
+#endif
+/* ************************************************************************ */
diff --git a/xmpp/Auth.hx b/xmpp/Auth.hx
index 21c438b..43f01b8 100644
--- a/xmpp/Auth.hx
+++ b/xmpp/Auth.hx
@@ -24,7 +24,7 @@ import util.XmlUtil;
 */
 class Auth {

-	public static inline var XMLNS = "jabber:iq:auth";
+	public static var XMLNS = "jabber:iq:auth";

 	public var username : String;
 	public var password : String;
diff --git a/xmpp/BOB.hx b/xmpp/BOB.hx
index 932d4f8..2fbdbba 100644
--- a/xmpp/BOB.hx
+++ b/xmpp/BOB.hx
@@ -59,9 +59,9 @@ class BOB {

 	/**
 		Parses cids ('algo+hash@bob.xmpp.org') from the given string.
-		//TODO return : Array<{algo:String,hash:String}>
 	*/
 	public static function parseCID( t : String ) : {algo:String,hash:String} {
+		//TODO return : Array<{algo:String,hash:String}>
 		var algo : String = null;
 		var hash : String = null;
 		~/cid:(.*?)\+(.*?)@bob.xmpp.org/.customReplace( t, function(r) {
diff --git a/xmpp/Caps.hx b/xmpp/Caps.hx
index 4d276c2..39d07de 100644
--- a/xmpp/Caps.hx
+++ b/xmpp/Caps.hx
@@ -22,7 +22,7 @@ package xmpp;
 */
 class Caps {

-	public static inline var XMLNS = xmpp.NS.PROTOCOL+"/caps";
+	public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/caps";

 	/**
 		The hashing algorithm used to generate the verification string, fe: sha-1.
diff --git a/xmpp/ChatStateExtension.hx b/xmpp/ChatStateExtension.hx
index df8755d..0a7259a 100644
--- a/xmpp/ChatStateExtension.hx
+++ b/xmpp/ChatStateExtension.hx
@@ -22,7 +22,7 @@ package xmpp;
 */
 class ChatStateExtension {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/chatstates";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/chatstates";

 	/**
 		Adds (or changes if already has) the chat state property of the givent message packet.
diff --git a/xmpp/Compression.hx b/xmpp/Compression.hx
index 0297eaf..f56c41d 100644
--- a/xmpp/Compression.hx
+++ b/xmpp/Compression.hx
@@ -22,7 +22,7 @@ package xmpp;
 */
 class Compression {

-	public static var XMLNS = xmpp.NS.PROTOCOL+'/compress';
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+'/compress';

 	/**
 	*/
diff --git a/xmpp/HXR.hx b/xmpp/HXR.hx
index d416a2f..df7244b 100644
--- a/xmpp/HXR.hx
+++ b/xmpp/HXR.hx
@@ -1,3 +1,20 @@
+/*
+ *	This file is part of HXMPP.
+ *	Copyright (c)2009 http://www.disktree.net
+ *
+ *	HXMPP is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HXMPP is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *	See the GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
+*/
 package xmpp;

 /**
@@ -5,9 +22,7 @@ package xmpp;
 */
 class HXR {

-	public static inline var XMLNS = "http://haxe.org/hxr";
-	//public static inline var XMLNS_CALL = XMLNS+"/call";
-	//public static inline var XMLNS_RESPONSE = XMLNS+"/response";
+	public static var XMLNS = "http://haxe.org/hxr";

 	public static inline function create( ?data : String ) : Xml {
 		var x = xmpp.IQ.createQueryXml( XMLNS );
diff --git a/xmpp/MUC.hx b/xmpp/MUC.hx
index 1439d3f..f9c0e05 100644
--- a/xmpp/MUC.hx
+++ b/xmpp/MUC.hx
@@ -18,7 +18,5 @@
 package xmpp;

 class MUC {
-
-	public static var XMLNS = xmpp.NS.PROTOCOL+'/muc';
-
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+'/muc';
 }
diff --git a/xmpp/NS.hx b/xmpp/NS.hx
deleted file mode 100644
index e0a9fb5..0000000
--- a/xmpp/NS.hx
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- *	This file is part of HXMPP.
- *	Copyright (c)2009 http://www.disktree.net
- *
- *	HXMPP is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  HXMPP is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *	See the GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
-*/
-package xmpp;
-
-class NS {
-	public static inline var PROTOCOL = "http://jabber.org/protocol";
-}
diff --git a/xmpp/Namespace.hx b/xmpp/Namespace.hx
new file mode 100644
index 0000000..e2acac4
--- /dev/null
+++ b/xmpp/Namespace.hx
@@ -0,0 +1,24 @@
+/*
+ *	This file is part of HXMPP.
+ *	Copyright (c)2009 http://www.disktree.net
+ *
+ *	HXMPP is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HXMPP is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *	See the GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
+*/
+package xmpp;
+
+// haxe -exclude this class
+
+class Namespace {
+	public static inline var PROTOCOL = "http://jabber.org/protocol";
+}
diff --git a/xmpp/PlainPacket.hx b/xmpp/PlainPacket.hx
index b918690..00b30be 100644
--- a/xmpp/PlainPacket.hx
+++ b/xmpp/PlainPacket.hx
@@ -21,19 +21,19 @@ package xmpp;
 	Plain/Custom XMPP packet.
 */
 class PlainPacket extends Packet {
-
+
 	/**
 		Plain XML content of the packet.
 	*/
 	public var src : Xml;

-	public function new( x : Xml ) {
+	public function new( src : Xml ) {
 		super();
 		this._type = xmpp.PacketType.custom;
-		this.src = x;
+		this.src = src;
 	}

-	override public function toXml(): Xml {
+	public override function toXml(): Xml {
 		return src;
 	}

diff --git a/xmpp/PubSub.hx b/xmpp/PubSub.hx
index 30e7f51..d535a0f 100644
--- a/xmpp/PubSub.hx
+++ b/xmpp/PubSub.hx
@@ -19,7 +19,7 @@ package xmpp;

 class PubSub {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/pubsub";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/pubsub";

 	public var subscribe : { node : String, jid : String };
 	public var options : xmpp.pubsub.Options;
diff --git a/xmpp/XHTML.hx b/xmpp/XHTML.hx
index 7cb7aaa..2df5c3e 100644
--- a/xmpp/XHTML.hx
+++ b/xmpp/XHTML.hx
@@ -22,7 +22,7 @@ package xmpp;
 */
 class XHTML {

-	public static inline var XMLNS = xmpp.NS.PROTOCOL+"/xhtml-im";
+	public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/xhtml-im";
 	static inline var W3NS = "http://www.w3.org/1999/xhtml";

 	public var body : String;
@@ -78,4 +78,11 @@ class XHTML {
 		m.properties.push( new XHTML( body ).toXml() );
 		return m;
 	}
+
+	/*
+	public static inline function create( body : String ) :  {
+		return new XHTML( body ).toXml();
+	}
+	*/
+
 }
diff --git a/xmpp/disco/Info.hx b/xmpp/disco/Info.hx
index 82f951b..616297f 100644
--- a/xmpp/disco/Info.hx
+++ b/xmpp/disco/Info.hx
@@ -22,7 +22,7 @@ package xmpp.disco;
 */
 class Info {

-	public static inline var XMLNS = xmpp.NS.PROTOCOL+'/disco#info';
+	public static inline var XMLNS = xmpp.Namespace.PROTOCOL+'/disco#info';

 	public var identities : Array<Identity>;
 	public var features : Array<String>;
diff --git a/xmpp/disco/Items.hx b/xmpp/disco/Items.hx
index 45f6b59..772ae51 100644
--- a/xmpp/disco/Items.hx
+++ b/xmpp/disco/Items.hx
@@ -19,7 +19,7 @@ package xmpp.disco;

 class Items extends List<xmpp.disco.Item> {

-	public static var XMLNS = xmpp.NS.PROTOCOL+'/disco#items';
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+'/disco#items';

 	public var node : String;

diff --git a/xmpp/file/ByteStream.hx b/xmpp/file/ByteStream.hx
index cdca01d..4d0e2e0 100644
--- a/xmpp/file/ByteStream.hx
+++ b/xmpp/file/ByteStream.hx
@@ -19,7 +19,7 @@ package xmpp.file;

 class ByteStream {

-	public static inline var XMLNS = xmpp.NS.PROTOCOL+"/bytestreams";
+	public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/bytestreams";

 	public var sid : String;
 	public var mode : String; //ByteStreamMode;
diff --git a/xmpp/file/IB.hx b/xmpp/file/IB.hx
index fd27ab5..2416e5a 100644
--- a/xmpp/file/IB.hx
+++ b/xmpp/file/IB.hx
@@ -19,7 +19,7 @@ package xmpp.file;

 class IB {

-	public static inline var XMLNS = xmpp.NS.PROTOCOL+"/ibb";
+	public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/ibb";

 	public var type : IBType;
 	public var sid : String;
diff --git a/xmpp/filter/PacketAllFilter.hx b/xmpp/filter/PacketAllFilter.hx
index 3363bf7..2c3c6ad 100644
--- a/xmpp/filter/PacketAllFilter.hx
+++ b/xmpp/filter/PacketAllFilter.hx
@@ -28,7 +28,7 @@ class PacketAllFilter {
 		this.yes = yes;
 	}

-	public function accept( p : xmpp.Packet ) : Bool {
+	public inline function accept( p : xmpp.Packet ) : Bool {
 		return yes;
 	}

diff --git a/xmpp/filter/PacketFieldFilter.hx b/xmpp/filter/PacketFieldFilter.hx
index dc3c7a7..7a6ac75 100644
--- a/xmpp/filter/PacketFieldFilter.hx
+++ b/xmpp/filter/PacketFieldFilter.hx
@@ -18,11 +18,13 @@
 package xmpp.filter;

 /**
+	Filters XMPP packets where a packet object field matches a given value.
 */
 class PacketFieldFilter {

 	public var name : String;
 	public var value : String;
+//	public var attributes : Array<String>;

 	public function new( name : String, ?value : String ) {
 		this.name = name;
@@ -31,8 +33,11 @@ class PacketFieldFilter {

 	public function accept( p : xmpp.Packet ) : Bool {
 		if( !Reflect.hasField( p, name ) ) return false;
+		/*
 		if( value == null ) return true;
 		return Reflect.field( p, name ) == value;
+		*/
+		return ( value == null ) ? true : ( Reflect.field( p, name ) == value );
 	}

 }
diff --git a/xmpp/filter/PacketFromFilter.hx b/xmpp/filter/PacketFromFilter.hx
index 446140c..210530c 100644
--- a/xmpp/filter/PacketFromFilter.hx
+++ b/xmpp/filter/PacketFromFilter.hx
@@ -17,6 +17,8 @@
 */
 package xmpp.filter;

+//(TODO )extends packetField filter
+
 /**
 	Filters XMPP packets with matching 'from' attribute.
 */
@@ -28,7 +30,7 @@ class PacketFromFilter {
 		this.jid = jid;
 	}

-	public function accept( p : xmpp.Packet ) : Bool {
+	public inline function accept( p : xmpp.Packet ) : Bool {
 		return p.from == jid;
 	}

diff --git a/xmpp/filter/PacketIDFilter.hx b/xmpp/filter/PacketIDFilter.hx
index 2548206..ec5c6a6 100644
--- a/xmpp/filter/PacketIDFilter.hx
+++ b/xmpp/filter/PacketIDFilter.hx
@@ -28,7 +28,7 @@ class PacketIDFilter {
 		this.id = id;
 	}

-	public function accept( p : xmpp.Packet ) : Bool {
+	public inline function accept( p : xmpp.Packet ) : Bool {
 		return p.id == id;
 	}

diff --git a/xmpp/filter/PacketToFilter.hx b/xmpp/filter/PacketToFilter.hx
index 15e57ed..7f89409 100644
--- a/xmpp/filter/PacketToFilter.hx
+++ b/xmpp/filter/PacketToFilter.hx
@@ -28,7 +28,7 @@ class PacketToFilter {
 		this.jid = jid;
 	}

-	public function accept( p : xmpp.Packet ) : Bool {
+	public inline function accept( p : xmpp.Packet ) : Bool {
 		return p.to == jid;
 	}

diff --git a/xmpp/filter/PacketTypeFilter.hx b/xmpp/filter/PacketTypeFilter.hx
index 6991b11..2e5c19e 100644
--- a/xmpp/filter/PacketTypeFilter.hx
+++ b/xmpp/filter/PacketTypeFilter.hx
@@ -17,7 +17,6 @@
 */
 package xmpp.filter;

-
 /**
 	Filters packets with matching xmpp.PacketType.
 */
@@ -29,7 +28,7 @@ class PacketTypeFilter {
 		this.type = type;
 	}

-	public function accept( p : xmpp.Packet ) : Bool {
+	public inline function accept( p : xmpp.Packet ) : Bool {
 		return p._type == type;
 	}

diff --git a/xmpp/pep/UserActivity.hx b/xmpp/pep/UserActivity.hx
index a12ea23..896b553 100644
--- a/xmpp/pep/UserActivity.hx
+++ b/xmpp/pep/UserActivity.hx
@@ -23,7 +23,7 @@ package xmpp.pep;
 */
 class UserActivity extends Event {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/activity";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/activity";

 	public var activity : Activity;
 	public var text : String;
diff --git a/xmpp/pep/UserLocation.hx b/xmpp/pep/UserLocation.hx
index 61bd21d..0512e81 100644
--- a/xmpp/pep/UserLocation.hx
+++ b/xmpp/pep/UserLocation.hx
@@ -23,7 +23,7 @@ package xmpp.pep;
 */
 class UserLocation extends Event {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/geoloc";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/geoloc";

 	/** Horizontal GPS error in meters; this element obsoletes the <error/> element */
 	public var accuracy : Int;
diff --git a/xmpp/pep/UserMood.hx b/xmpp/pep/UserMood.hx
index 7aa2cbe..d999d37 100644
--- a/xmpp/pep/UserMood.hx
+++ b/xmpp/pep/UserMood.hx
@@ -23,7 +23,7 @@ package xmpp.pep;
 */
 class UserMood extends Event {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/mood";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/mood";

 	public var type : Mood;
 	public var text : String;
diff --git a/xmpp/pep/UserTune.hx b/xmpp/pep/UserTune.hx
index bd5a5b9..47b507d 100644
--- a/xmpp/pep/UserTune.hx
+++ b/xmpp/pep/UserTune.hx
@@ -23,7 +23,7 @@ package xmpp.pep;
 */
 class UserTune extends Event {

-	public static var XMLNS = xmpp.NS.PROTOCOL+"/tune";
+	public static var XMLNS = xmpp.Namespace.PROTOCOL+"/tune";

 	/** The artist or performer of the song or piece */
 	public var artist : String;
diff --git a/xmpp/pubsub/NodeType.hx b/xmpp/pubsub/NodeType.hx
new file mode 100644
index 0000000..52cc76f
--- /dev/null
+++ b/xmpp/pubsub/NodeType.hx
@@ -0,0 +1,23 @@
+/*
+ *	This file is part of HXMPP.
+ *	Copyright (c)2009 http://www.disktree.net
+ *
+ *	HXMPP is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  HXMPP is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *	See the GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with HXMPP. If not, see <http://www.gnu.org/licenses/>.
+*/
+package xmpp.pubsub;
+
+enum NodeType {
+	leaf;
+	collection;
+}
ViewGit