So tonight, I've started to refactor POE::Component::Jabber to make use of updated tools, including ones that I have written. That list includes everything from MooseX::Declare to POEx::Role::TCPClient. The following is a brain storming session.
The first step to is break the machine out of its mold, so to speak. Initially when I embarked on the 3.0 design, I recognized that there is nothing but an artificial limit imposed on multiple connections. Really, there should be no reason not to enable multiple connections. By using a level of indirection via POE::Component::PubSub, I could have delivered all of the pertinent state and connection information along with the received packet. But the changes introduced into 3.0 seemed a little overwhelming. I didn't want to fundamentally alter the behavior of one connection manager per connection. Now I want to change that. Having developed POEx::Role::TCPClient for the possibility of multiple outbound connections with no arbitrary limits, I solved the multiple connection problem. And in fact, consuming that role wipes out large swaths of wheel reinvention code.
And I think I could take that a step further and even allow a different connection type on each connection. Right now this is handled per instance of the connection manager with arguments passed to the constructor. The connection type determines which "dialect helper" gets instantiated and how the session is constructed. Currently, dialect helpers are a poorman's POE "role" in the sense that I hacked together an API for crudely introspecting which events the helper exposed. Then I used that method when creating the main PCJ session. The right way to do that is to instead is to have a /real/ Moose::Role represent the given functionality and consume it as needed.
Even then, that isn't enough. The dialect specific portions are only relevant during the connection negotiation phase. Once the connection is negotiated, those bits are never used again. And that leads me to think that perhaps I need to abstract that away and use a separate class for making connections. Then at the top level, PCJ merely delegates between a couple of different objects, mainly the connection maker, the pubsub component, and a controlling session for it all, but provides a uniform API for communicating over XMPP.
So we will see. I am going to work on it and see where it takes me.