Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision 2cedb7a8d0c3cef0ef838d33f20af91a503f34dc)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision 2cedb7a8d0c3cef0ef838d33f20af91a503f34dc)
@@ -0,0 +1,112 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+BarnOwl::Module::Jabber::Connection
+
+=head1 DESCRIPTION
+
+A subclass of L<Net::Jabber::Client> used in the BarnOwl jabber module
+
+=cut
+
+package BarnOwl::Module::Jabber::Connection;
+
+use base qw(Net::Jabber::Client);
+
+use Net::Jabber;
+
+sub new {
+    my $class = shift;
+
+    my %args = ();
+    if(BarnOwl::getvar('debug') eq 'on') {
+        $args{debuglevel} = 1;
+        $args{debugfile} = 'jabber.log';
+    }
+    my $self = $class->SUPER::new(%args);
+    $self->{_BARNOWL_MUCS} = [];
+    return $self;
+}
+
+=head2 MUCJoin
+
+Extends MUCJoin to keep track of the MUCs we're joined to as
+Net::Jabber::MUC objects. Takes the same arguments as
+L<Net::Jabber::MUC/new> and L<Net::Jabber::MUC/Connect>
+
+=cut
+
+sub MUCJoin {
+    my $self = shift;
+    my $muc = Net::Jabber::MUC->new(connection => $self, @_);
+    $muc->Join(@_);
+    push @{$self->MUCs}, $muc;
+}
+
+=head2 MUCLeave ARGS
+
+Leave a MUC. The MUC is specified in the same form as L</FindMUC>
+
+=cut
+
+sub MUCLeave {
+    my $self = shift;
+    my $muc = $self->FindMUC(@_);
+    return unless $muc;
+
+    $muc->Leave();
+    $self->{_BARNOWL_MUCS} = [grep {$_->BaseJID ne $muc->BaseJID} $self->MUCs];
+}
+
+=head2 FindMUC ARGS
+
+Return the Net::Jabber::MUC object representing a specific MUC we're
+joined to, undef if it doesn't exists. ARGS can be either JID => $JID,
+or Room => $room, Server => $server.
+
+=cut
+
+sub FindMUC {
+    my $self = shift;
+
+    my %args;
+    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
+
+    my $jid;
+    if($args{jid}) {
+        $jid = $args{jid};
+    } elsif($args{room} && $args{server}) {
+        $jid = Net::Jabber::JID->new(userid => $args{room},
+                                     server => $args{server});
+    }
+    $jid = $jid->GetJID('base') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
+
+    foreach my $muc ($self->MUCs) {
+        return $muc if $muc->BaseJID eq $jid;
+    }
+    return undef;
+}
+
+=head2 MUCs
+
+Returns a list (or arrayref in scalar context) of Net::Jabber::MUC
+objects we believe ourself to be connected to.
+
+=cut
+
+sub MUCs {
+    my $self = shift;
+    my $mucs = $self->{_BARNOWL_MUCS};
+    return wantarray ? @$mucs : $mucs;
+}
+
+
+=head1 SEE ALSO
+
+L<Net::Jabber::Client>, L<BarnOwl::Module::Jabber>
+
+=cut
+
+1;
Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm	(revision 2cedb7a8d0c3cef0ef838d33f20af91a503f34dc)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm	(revision 2cedb7a8d0c3cef0ef838d33f20af91a503f34dc)
@@ -0,0 +1,105 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+BarnOwl::Module::Jabber::ConnectionManager
+
+=head1 DESCRIPTION
+
+A class to keep track of all the active connection in the barnowl
+jabber module
+
+=cut
+
+package BarnOwl::Module::Jabber::ConnectionManager;
+
+sub new {
+    my $class = shift;
+    return bless { }, $class;
+}
+
+sub addConnection {
+    my $self = shift;
+    my $jidStr = shift;
+
+    my $client = BarnOwl::Module::Jabber::Connection->new;
+
+    $self->{$jidStr}->{Client} = $client;
+    $self->{$jidStr}->{Roster} = $client->Roster();
+    $self->{$jidStr}->{Status} = "available";
+    return $client;
+}
+
+sub removeConnection {
+    my $self = shift;
+    my $jidStr = shift;
+    return 0 unless exists $self->{$jidStr};
+
+    $self->{$jidStr}->{Client}->Disconnect()
+      if $self->{$jidStr}->{Client};
+    delete $self->{$jidStr};
+
+    return 1;
+}
+
+sub connected {
+    my $self = shift;
+    return scalar keys %{ $self };
+}
+
+sub getJIDs {
+    my $self = shift;
+    return keys %{ $self };
+}
+
+sub jidExists {
+    my $self = shift;
+    my $jidStr = shift;
+    return exists $self->{$jidStr};
+}
+
+sub sidExists {
+    my $self = shift;
+    my $sid = shift || "";
+    foreach my $c ( values %{ $self } ) {
+        return 1 if ($c->{Client}->{SESSION}->{id} eq $sid);
+    }
+    return 0;
+}
+
+sub getConnectionFromSid {
+    my $self = shift;
+    my $sid = shift;
+    foreach my $c (values %{ $self }) {
+        return $c->{Client} if $c->{Client}->{SESSION}->{id} eq $sid;
+    }
+    return undef;
+}
+
+sub getConnectionFromJID {
+    my $self = shift;
+    my $jid = shift;
+    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
+    return $self->{$jid}->{Client} if exists $self->{$jid};
+}
+
+sub getRosterFromSid {
+    my $self = shift;
+    my $sid = shift;
+    foreach my $c (values %{ $self }) {
+        return $c->{Roster}
+          if $c->{Client}->{SESSION}->{id} eq $sid;
+    }
+    return undef;
+}
+
+sub getRosterFromJID {
+    my $self = shift;
+    my $jid = shift;
+    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
+    return $self->{$jid}->{Roster} if exists $self->{$jid};
+}
+
+
+1;
