int32 MSNConnection::Receiver(void *con) {
	LOG(kProtocolName, liLow, "C[r] %lX: Receiver init", con);

	MSNConnection *connection = reinterpret_cast<MSNConnection *>(con);

	const uint32 kSleep = 2000000;
	BMessenger **kMsgr = &connection->fSockMsgr;
	int32 socket = 0;
	
	if ( !(*kMsgr)->IsValid() ) {
		LOG(kProtocolName, liLow, "C[r] %lX: Messenger wasn't valid!", connection);
		return B_ERROR;
	}
	
	BMessage reply;
	socket = connection->fSock;
		
	struct fd_set read;
	struct fd_set error;
	int16 bytes = 0;
	int32 processed = 0;
	char buffer[1024];
	BString commandBuff = "";
	int32 kNewLineLen = strlen("\r\n");
	
	LOG(kProtocolName, liLow, "C[r] %lX: Starting receiver loop", connection);
	
	while ((*kMsgr)->IsValid() == true) {
		FD_ZERO(&read);
		FD_ZERO(&error);
		
		FD_SET(socket, &read);
		FD_SET(socket, &error);

		memset(buffer, 0, sizeof(buffer));

		if (select(socket + 1, &read, NULL, &error, NULL) > 0) {

			if (FD_ISSET(socket, &error)) {
				LOG(kProtocolName, liLow, "C[r] %lX: Got socket error", connection);
				snooze(kSleep);
				continue;
			};
			
			if (FD_ISSET(socket, &read)) {
				bytes = recv(socket, buffer, sizeof(buffer), 0);
				if (bytes > 0) {
					commandBuff.Append(buffer, bytes);
					processed += bytes;
				} else {
					if ((*kMsgr)->IsValid() == false) return B_OK;
					
					LOG(kProtocolName, liLow, "C[r] %lX: Socket got less than 0 (or 0)",
						connection);
					perror("SOCKET ERROR");
					
					BMessage msg(msnmsgCloseConnection);
					msg.AddPointer("connection", con);
					
					connection->fManMsgr.SendMessage(&msg);
					connection->fState = otOffline;
					
					return B_ERROR;
				};					
			};
		};
		
		int32 commandLen = commandBuff.FindFirst("\r\n");
		
		while (commandLen > 0) {
			BString command = "";
			int32 totalLen = commandBuff.Length();
			commandBuff.MoveInto(command, 0, commandLen + kNewLineLen);

			processed = totalLen - (commandLen + kNewLineLen);

			Command *comm = new Command("");
			comm->MakeObject(command.String());
			int32 payloadLen = 0;

			if (comm->ExpectsPayload(&payloadLen) == true) {
				LOG(kProtocolName, liDebug, "C[r] %lX: Payload of %i, have %i bytes",
					connection, payloadLen, processed);		
				
				while (processed < payloadLen) {
					FD_ZERO(&read);
					FD_ZERO(&error);
					
					FD_SET(socket, &read);
					FD_SET(socket, &error);
			
					memset(buffer, 0, sizeof(buffer));
			
					if (select(socket + 1, &read, NULL, &error, NULL) > 0) {				
						if (FD_ISSET(socket, &error)) {
							LOG(kProtocolName, liLow, "C[r] %lX: Got socket error", 
								connection);
							snooze(kSleep);
							continue;
						};
						
						if (FD_ISSET(socket, &read)) {
							bytes = recv(socket, buffer, min_c(payloadLen - processed, (int32)sizeof(buffer)), 0);
							if (bytes > 0) {
								commandBuff.Append(buffer, bytes);
								processed += bytes;
							} else {
								if ( (*kMsgr)->IsValid() == false) return B_OK;
		
								LOG(kProtocolName, liLow, "--C[r] %lX: Socket got less than 0 (or 0: %i)",
									connection, bytes);
								perror("SOCKET ERROR");
		
								BMessage msg(msnmsgCloseConnection);
								msg.AddPointer("connection", con);
				
								connection->fManMsgr.SendMessage(&msg);
								connection->fState = otOffline;
								
								return B_ERROR;
							};					
						};
					};
					
				};
				
//				add payload to message?
				comm->AddPayload( commandBuff.String(), payloadLen, false );
				commandBuff.Remove( 0, payloadLen );
				
				processed = commandBuff.Length();
			};
			
			BMessage dataReady(msnmsgDataReady);
			dataReady.AddPointer("command", comm);
			
			(*kMsgr)->SendMessage(&dataReady);
			
// 			this line needed to process several commands at once if they're in the
//			buffer
			commandLen = commandBuff.FindFirst("\r\n");
		};
	};
	
	return B_OK;
};