Index: perl/modules/jabber.pl
===================================================================
--- perl/modules/jabber.pl	(revision 1d8503b4e014e17c4b3af4c4f5bfa545459f473f)
+++ perl/modules/jabber.pl	(revision 455f1ab158975acb92743114af8ef277ad73c0a7)
@@ -183,8 +183,9 @@
 }
 
-sub getConnectionFromJidStr {
-    my $self = shift;
-    my $jidStr = shift;
-    return $self->{$jidStr}->{Client};
+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};
 }
 
@@ -199,8 +200,9 @@
 }
 
-sub getRosterFromJidStr {
-    my $self = shift;
-    my $jidStr = shift;
-    return $self->{$jidStr}->{Roster};
+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};
 }
 ################################################################################
@@ -246,5 +248,5 @@
 
     foreach my $jid ( $conn->getJids() ) {
-        my $client = $conn->getConnectionFromJidStr($jid);
+        my $client = $conn->getConnectionFromJID($jid);
 
         unless($client) {
@@ -304,8 +306,8 @@
 sub getSingleBuddyList {
     my $jid = shift;
-    $jid = resolveJID($jid);
+    $jid = resolveConnectedJID($jid);
     return "" unless $jid;
     my $blist = "";
-    my $roster = $conn->getRosterFromJidStr($jid);
+    my $roster = $conn->getRosterFromJID($jid);
     if ($roster) {
         $blist .= "\n" . boldify("Jabber Roster for $jid\n");
@@ -354,5 +356,5 @@
         {
             summary => "Send a Jabber Message",
-            usage   => "jwrite JID [-g] [-t thread] [-s subject]"
+            usage   => "jwrite JID [-t thread] [-s subject]"
         }
     );
@@ -480,5 +482,5 @@
                 BarnOwl::error( "Error in connect: " . join( " ", @result ) );
             } else {
-                $conn->getRosterFromJidStr($jidStr)->fetch();
+                $conn->getRosterFromJID($jidStr)->fetch();
                 $client->PresenceSend( priority => 1 );
                 queue_admin_msg("Connected to jabber as $jidStr");
@@ -524,5 +526,5 @@
             else                    #One account.
             {
-                my $jid = resolveJID( $_[1] );
+                my $jid = resolveConnectedJID( $_[1] );
                 do_logout($jid) if ( $jid ne '' );
             }
@@ -555,4 +557,5 @@
     my $jwrite_thread  = "";
     my $jwrite_subject = "";
+    my $to;
     my $jwrite_type    = "chat";
 
@@ -566,5 +569,4 @@
         'account=s' => \$jwrite_from,
         'id=s'     =>  \$jwrite_sid,
-        'groupchat' => \$gc
     );
     $jwrite_type = 'groupchat' if $gc;
@@ -572,25 +574,17 @@
     if ( scalar @ARGV != 1 ) {
         BarnOwl::error(
-            "Usage: jwrite JID [-g] [-t thread] [-s 'subject'] [-a account]");
+            "Usage: jwrite JID [-t thread] [-s 'subject'] [-a account]");
         return;
     }
     else {
-        $jwrite_to = shift @ARGV;
-    }
-
-    if ( !$jwrite_from ) {
-        if ( $conn->connected() == 1 ) {
-            $jwrite_from = ( $conn->getJids() )[0];
-        }
-        else {
-            BarnOwl::error("Please specify an account with -a JID");
-            return;
-        }
-    }
-    else {
-        $jwrite_from = resolveJID($jwrite_from);
-        return unless $jwrite_from;
-    }
-
+        $to = shift @ARGV;
+    }
+
+    ($jwrite_from, $jwrite_to, $jwrite_type) = guess_jwrite($jwrite_from, $to);
+
+    unless($jwrite_from && $jwrite_to) {
+        die("Unable to resolve JID $to");
+    }
+    
     $vars{jwrite} = {
         to      => $jwrite_to,
@@ -605,5 +599,8 @@
 "Type your message below.  End with a dot on a line by itself.  ^C will quit."
     );
-    BarnOwl::start_edit_win( join( ' ', @args ), \&process_owl_jwrite );
+    my $cmd = "jwrite $jwrite_to -a $jwrite_from";
+    $cmd .= " -t $jwrite_thread" if $jwrite_thread;
+    $cmd .= " -t $jwrite_subject" if $jwrite_subject;
+    BarnOwl::start_edit_win( $cmd, \&process_owl_jwrite );
 }
 
@@ -646,5 +643,5 @@
         $jid ||= defaultJID();
         if ($jid) {
-            $jid = resolveJID($jid);
+            $jid = resolveConnectedJID($jid);
             return unless $jid;
         }
@@ -665,5 +662,5 @@
       or die("Usage: jmuc join MUC [-p password] [-a account]");
 
-    $conn->getConnectionFromJidStr($jid)->MUCJoin(Jid      => $muc,
+    $conn->getConnectionFromJID($jid)->MUCJoin(Jid      => $muc,
                                                   Password => $password,
                                                   History  => {
@@ -679,5 +676,5 @@
     die("Usage: jmuc part MUC [-a account]") unless $muc;
 
-    $conn->getConnectionFromJidStr($jid)->MUCLeave(JID => $muc);
+    $conn->getConnectionFromJID($jid)->MUCLeave(JID => $muc);
     queue_admin_msg("$jid has left $muc.");
 }
@@ -697,5 +694,5 @@
     $x->AddInvite();
     $x->GetInvite()->SetTo($invite_jid);
-    $conn->getConnectionFromJidStr($jid)->Send($message);
+    $conn->getConnectionFromJID($jid)->Send($message);
     queue_admin_msg("$jid has invited $invite_jid to $muc.");
 }
@@ -712,5 +709,5 @@
     $x->SetType('submit');
 
-    $conn->getConnectionFromJidStr($jid)->Send($iq);
+    $conn->getConnectionFromJID($jid)->Send($iq);
     queue_admin_msg("Accepted default instant configuration for $muc");
 }
@@ -722,5 +719,5 @@
     die("Usage: jmuc presence MUC") unless $muc;
 
-    my $m = $conn->getConnectionFromJidStr($jid)->FindMUC(jid => $muc);
+    my $m = $conn->getConnectionFromJID($jid)->FindMUC(jid => $muc);
     die("No such muc: $muc") unless $m;
 
@@ -772,5 +769,5 @@
         $jid ||= defaultJID();
         if ($jid) {
-            $jid = resolveJID($jid);
+            $jid = resolveConnectedJID($jid);
             return unless $jid;
         }
@@ -789,5 +786,5 @@
     my $baseJid = baseJID($jid);
 
-    my $roster = $conn->getRosterFromJidStr($jid);
+    my $roster = $conn->getRosterFromJID($jid);
 
     # Adding lots of users with the same name is a bad idea.
@@ -801,5 +798,5 @@
 
         $p->SetTo($to);
-        $conn->getConnectionFromJidStr($jid)->Send($p);
+        $conn->getConnectionFromJID($jid)->Send($p);
         queue_admin_msg("You ($baseJid) have requested a subscription to ($to)'s presence.");
     }
@@ -817,5 +814,5 @@
     foreach my $to (@ARGV) {
         $p->SetTo($to);
-        $conn->getConnectionFromJidStr($jid)->Send($p);
+        $conn->getConnectionFromJID($jid)->Send($p);
         queue_admin_msg("You ($baseJid) have unsubscribed from ($to)'s presence.");
     }
@@ -829,5 +826,5 @@
     my $baseJid = baseJID($jid);
 
-    my $roster = $conn->getRosterFromJidStr($jid);
+    my $roster = $conn->getRosterFromJID($jid);
 
     # Adding lots of users with the same name is a bad idea.
@@ -859,5 +856,5 @@
         $item->put_attrib(jid => $to);
         $item->put_attrib(name => $name) if $name;
-        $conn->getConnectionFromJidStr($jid)->Send($iq);
+        $conn->getConnectionFromJID($jid)->Send($iq);
         my $msg = "$baseJid: "
           . ($name ? "$name ($to)" : "($to)")
@@ -883,5 +880,5 @@
     foreach my $to (@ARGV) {
         $item->put_attrib(jid => $to);
-        $conn->getConnectionFromJidStr($jid)->Send($iq);
+        $conn->getConnectionFromJID($jid)->Send($iq);
         queue_admin_msg("You ($baseJid) have removed ($to) from your roster.");
     }
@@ -899,5 +896,5 @@
     foreach my $to (@ARGV) {
         $p->SetTo($to);
-        $conn->getConnectionFromJidStr($jid)->Send($p);
+        $conn->getConnectionFromJID($jid)->Send($p);
         queue_admin_msg("($to) has been subscribed to your ($baseJid) presence.");
     }
@@ -915,5 +912,5 @@
     foreach my $to (@ARGV) {
         $p->SetTo($to);
-        $conn->getConnectionFromJidStr($jid)->Send($p);
+        $conn->getConnectionFromJID($jid)->Send($p);
         queue_admin_msg("($to) has been unsubscribed from your ($baseJid) presence.");
     }
@@ -947,5 +944,5 @@
     }
     else {
-        $conn->getConnectionFromJidStr($vars{jwrite}{from})->Send($j);
+        $conn->getConnectionFromJID($vars{jwrite}{from})->Send($j);
     }
 
@@ -1083,5 +1080,5 @@
             $to eq $cJid->GetJID('full')) {
 	    my $reply = $p->Reply(type=>"unsubscribed");
-	    $conn->getConnectionFromJidStr($jid)->Send($reply);
+	    $conn->getConnectionFromJID($jid)->Send($reply);
 	    return;
 	}
@@ -1157,5 +1154,5 @@
         my $nick = $props{nick} = $from->GetResource();
         my $room = $props{room} = $from->GetJID('base');
-        $props{replycmd} = "jwrite -g $room";
+        $props{replycmd} = "jwrite $room";
         $props{replycmd} .=
           " -a " . ( ( $dir eq 'out' ) ? $props{from} : $props{to} );
@@ -1243,5 +1240,5 @@
 }
 
-sub resolveJID {
+sub resolveConnectedJID {
     my $givenJidStr = shift;
     my $givenJid    = new Net::XMPP::JID;
@@ -1252,5 +1249,5 @@
         # Specified account exists
         return $givenJidStr if ($conn->jidExists($givenJidStr) );
-        BarnOwl::error("Invalid account: $givenJidStr");
+        die("Invalid account: $givenJidStr");
     }
 
@@ -1274,10 +1271,10 @@
         # Need further disambiguation.
         if ($ambiguous) {
-            queue_admin_msg($errStr);
+            die($errStr);
         }
 
         # Not one of ours.
         elsif ( $matchingJid eq "" ) {
-            BarnOwl::error("Invalid account: $givenJidStr");
+            die("Invalid account: $givenJidStr");
         }
 
@@ -1288,4 +1285,59 @@
     }
     return "";
+}
+
+sub resolveDestJID {
+    my ($to, $from) = @_;
+    my $jid = Net::Jabber::JID->new($to);
+    if($jid->GetResource()) {
+        return $jid->GetJID('full');
+    }
+
+    my $roster = $conn->getRosterFromJID($from);
+    my @jids = $roster->jids('all');
+    for my $j (@jids) {
+        if($roster->query($j, 'name') eq $to) {
+            return $j->GetJID('full');
+        }
+    }
+
+    return undef;
+}
+
+sub resolveType {
+    my $to = shift;
+    my $from = shift;
+    my @mucs = $conn->getConnectionFromJID($from)->MUCs;
+    if(grep {$_->BaseJID eq $to } @mucs) {
+        return 'groupchat';
+    } else {
+        return 'chat';
+    }
+}
+
+sub guess_jwrite {
+    # Heuristically guess what jids a jwrite was meant to be going to/from
+    my ($from, $to) = (@_);
+    my ($from_jid, $to_jid);
+    if($from) {
+        $from_jid = resolveConnectedJID($from);
+        die("Unable to resolve account $from") unless $from_jid;
+        $to_jid = resolveDestJID($to, $from_jid);
+    } elsif($to =~ /@/) {
+        $to_jid = $to;
+        $from_jid = defaultJID();
+        die("You must specify a JID with -a") unless $from_jid;
+    } else {
+        for my $f ($conn->getJids) {
+            $to_jid = resolveDestJID($to, $f);
+            if(defined($to_jid)) {
+                $from_jid = $f;
+            }
+        }
+        die("Unable to resolve JID $to") unless $to_jid;
+    }
+
+    my $type = resolveType($to_jid, $from_jid);
+    return ($from_jid, $to_jid, $type);
 }
 
