Index: aim.c
===================================================================
--- aim.c	(revision 0ff8fb572754799e77ac2cf2d386b7699f995257)
+++ aim.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -411,5 +411,5 @@
 
   /*aim_bos_setprofile(sess, fr->conn, profile, awaymsg, AIM_CAPS_BUDDYICON | AIM_CAPS_CHAT | AIM_CAPS_GETFILE | AIM_CAPS_SENDFILE | AIM_CAPS_IMIMAGE | AIM_CAPS_GAMES | AIM_CAPS_SAVESTOCKS | AIM_CAPS_SENDBUDDYLIST | AIM_CAPS_ICQ | AIM_CAPS_ICQUNKNOWN | AIM_CAPS_ICQRTF | AIM_CAPS_ICQSERVERRELAY | AIM_CAPS_TRILLIANCRYPT); */
-  aim_bos_setprofile(sess, fr->conn, profile, awaymsg, AIM_CAPS_SENDBUDDYLIST | AIM_CAPS_CHAT );
+  aim_bos_setprofile(sess, fr->conn, profile, "", AIM_CAPS_SENDBUDDYLIST | AIM_CAPS_CHAT );
   aim_bos_reqbuddyrights(sess, fr->conn);
 
@@ -951,5 +951,6 @@
   } else if (strstr(tmpstr, "haveicon") && priv->buddyicon) {
     struct aim_sendimext_args args;
-    static const char iconmsg[] = {"I have an icon"};
+    /* static const char iconmsg[] = {"I have an icon"}; */
+    static const char iconmsg[] = {""};
     
     args.destsn = userinfo->sn;
@@ -961,5 +962,5 @@
     args.iconsum = priv->buddyiconsum;
     
-    aim_send_im_ext(sess, &args);
+    /* aim_send_im_ext(sess, &args); */
     
   } else if (strstr(tmpstr, "sendbin")) {
@@ -1170,4 +1171,5 @@
   int clienttype = AIM_CLIENTTYPE_UNKNOWN;
   owl_message *m;
+  char *stripmsg;
   char realmsg[8192+1] = {""};
   clienttype = aim_fingerprintclient(args->features, args->featureslen);
@@ -1244,8 +1246,9 @@
 
   /* create a message, and put it on the message queue */
+  stripmsg=owl_text_htmlstrip(realmsg);
   m=owl_malloc(sizeof(owl_message));
-  owl_message_create_aim(m, userinfo->sn, owl_global_get_aim_screenname(&g), realmsg);
-  owl_message_set_direction_in(m);
+  owl_message_create_incoming_aim(m, userinfo->sn, owl_global_get_aim_screenname(&g), stripmsg);
   owl_global_messagequeue_addmsg(&g, m);
+  owl_free(stripmsg);
   
   /* printf("icbm: message: %s\n", realmsg); */
Index: commands.c
===================================================================
--- commands.c	(revision 31e48a31baadb6973aeafc691fec373040f39690)
+++ commands.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -1567,5 +1567,5 @@
     return NULL;
   }
-  filtname = owl_function_fastclassinstfilt(argv[1], NULL);
+  filtname = owl_function_classinstfilt(argv[1], NULL);
   owl_function_change_view(filtname);
   owl_free(filtname);
@@ -1579,5 +1579,5 @@
     return NULL;
   }
-  filtname = owl_function_fastuserfilt(argv[1]);
+  filtname=owl_function_zuserfilt(argv[1]);
   owl_function_change_view(filtname);
   owl_free(filtname);
Index: filter.c
===================================================================
--- filter.c	(revision d09e5a1609d038695dbc6bc34a8177935a9bf7ea)
+++ filter.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -150,13 +150,5 @@
       match=owl_message_get_realm(m);
     } else if (!strcasecmp(field, "type")) {
-      if (owl_message_is_type_zephyr(m)) {
-	match="zephyr";
-      } else if (owl_message_is_type_aim(m)) {
-	match="aim";
-      } else if (owl_message_is_type_admin(m)) {
-	match="admin";
-      } else {
-	match="";
-      }
+      match=owl_message_type_to_string(m);
     } else if (!strcasecmp(field, "direction")) {
       if (owl_message_is_direction_out(m)) {
Index: functions.c
===================================================================
--- functions.c	(revision df0d93ab052f98d5b33d143b414f633faff6626c)
+++ functions.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -134,6 +134,5 @@
   /* create the message */
   m=owl_malloc(sizeof(owl_message));
-  owl_message_create_aim(m, owl_global_get_aim_screenname(&g), to, body);
-  owl_message_set_direction_out(m);
+  owl_message_create_outgoing_aim(m, owl_global_get_aim_screenname(&g), to, body);
 
   /* add it to the global list and current view */
@@ -2116,9 +2115,10 @@
 }
 
-char *owl_function_fastclassinstfilt(char *class, char *instance) 
-{
-  /* creates a filter for a class, instance if one doesn't exist.
-   * If instance is null then apply for all messgaes in the class.
-   * returns the name of the filter, which the caller must free.*/
+/* Create a filter for a class, instance if one doesn't exist.  If
+ * instance is NULL then catch all messgaes in the class.  Returns the
+ * name of the filter, which the caller must free.
+ */
+char *owl_function_classinstfilt(char *class, char *instance) 
+{
   owl_list *fl;
   owl_filter *f;
@@ -2173,5 +2173,12 @@
 }
 
-char *owl_function_fastuserfilt(char *user)
+/* Create a filter for personal zephyrs to or from the specified
+ * zephyr user.  Includes login/logout notifications for the user.
+ * The name of the filter will be 'user-<user>'.  If a filter already
+ * exists with this name, no new filter will be created.  This allows
+ * the configuration to override this function.  Returns the name of
+ * the filter, which the caller must free.
+ */
+char *owl_function_zuserfilt(char *user)
 {
   owl_filter *f;
@@ -2188,5 +2195,5 @@
   /* if it already exists then go with it.  This lets users override */
   if (owl_global_get_filter(&g, filtname)) {
-    return(filtname);
+    return(owl_strdup(filtname));
   }
 
@@ -2212,5 +2219,44 @@
 }
 
-char *owl_function_fasttypefilt(char *type)
+/* Create a filter for AIM IM messages to or from the specified
+ * screenname.  The name of the filter will be 'aimuser-<user>'.  If a
+ * filter already exists with this name, no new filter will be
+ * created.  This allows the configuration to override this function.
+ * Returns the name of the filter, which the caller must free.
+ */
+char *owl_function_aimuserfilt(char *user)
+{
+  owl_filter *f;
+  char *argbuff, *filtname;
+
+  /* name for the filter */
+  filtname=owl_malloc(strlen(user)+40);
+  sprintf(filtname, "aimuser-%s", user);
+
+  /* if it already exists then go with it.  This lets users override */
+  if (owl_global_get_filter(&g, filtname)) {
+    return(owl_strdup(filtname));
+  }
+
+  /* create the new-internal filter */
+  f=owl_malloc(sizeof(owl_filter));
+
+  argbuff=owl_malloc(1000);
+  sprintf(argbuff,
+	  "( type ^aim$ and ( ( sender ^%s$ and recipient ^%s$ ) or ( sender ^%s$ and recipient ^%s$ ) ) )",
+	  user, owl_global_get_aim_screenname(&g), owl_global_get_aim_screenname(&g), user);
+
+  owl_filter_init_fromstring(f, filtname, argbuff);
+
+  /* add it to the global list */
+  owl_global_add_filter(&g, f);
+
+  /* free stuff */
+  owl_free(argbuff);
+
+  return(filtname);
+}
+
+char *owl_function_typefilt(char *type)
 {
   owl_filter *f;
@@ -2263,17 +2309,20 @@
 }
 
+/* Create a filter based on the current message.  Returns the name of
+ * a filter or null.  The caller must free this name.
+ *
+ * if the curmsg is a personal zephyr return a filter name
+ *    to the zephyr converstaion with that user.
+ * If the curmsg is a zephyr class message, instance foo, recip *,
+ *    return a filter name to the class, inst.
+ * If the curmsg is a zephyr class message and type==0 then 
+ *    return a filter name for just the class.
+ * If the curmsg is a zephyr class message and type==1 then 
+ *    return a filter name for the class and instance.
+ * If the curmsg is a personal AIM message returna  filter
+ *    name to the AIM conversation with that user 
+ */
 char *owl_function_smartfilter(int type)
 {
-  /* Returns the name of a filter, or null.  The caller 
-   * must free this name.  */
-  /* if the curmsg is a personal message return a filter name
-   *    to the converstaion with that user.
-   * If the curmsg is a class message, instance foo, recip *
-   *    message, return a filter name to the class, inst.
-   * If the curmsg is a class message and type==0 then 
-   *    return a filter name for just the class.
-   * If the curmsg is a class message and type==1 then 
-   *    return a filter name for the class and instance.
-   */
   owl_view *v;
   owl_message *m;
@@ -2290,5 +2339,15 @@
   /* very simple handling of admin messages for now */
   if (owl_message_is_type_admin(m)) {
-    return(owl_function_fasttypefilt("admin"));
+    return(owl_function_typefilt("admin"));
+  }
+
+  /* aim messages */
+  if (owl_message_is_type_aim(m)) {
+    if (owl_message_is_direction_in(m)) {
+      filtname=owl_function_aimuserfilt(owl_message_get_sender(m));
+    } else if (owl_message_is_direction_out(m)) {
+      filtname=owl_function_aimuserfilt(owl_message_get_recipient(m));
+    }
+    return(filtname);
   }
 
@@ -2301,5 +2360,5 @@
 	zperson=short_zuser(owl_message_get_recipient(m));
       }
-      filtname=owl_function_fastuserfilt(zperson);
+      filtname=owl_function_zuserfilt(zperson);
       owl_free(zperson);
       return(filtname);
@@ -2309,7 +2368,6 @@
 
   /* narrow class MESSAGE, instance foo, recip * messages to class, inst */
-  if (!strcasecmp(owl_message_get_class(m), "message") &&
-      !owl_message_is_personal(m)) {
-    filtname=owl_function_fastclassinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
+  if (!strcasecmp(owl_message_get_class(m), "message") && !owl_message_is_personal(m)) {
+    filtname=owl_function_classinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
     return(filtname);
   }
@@ -2317,7 +2375,7 @@
   /* otherwise narrow to the class */
   if (type==0) {
-    filtname=owl_function_fastclassinstfilt(owl_message_get_class(m), NULL);
+    filtname=owl_function_classinstfilt(owl_message_get_class(m), NULL);
   } else if (type==1) {
-    filtname=owl_function_fastclassinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
+    filtname=owl_function_classinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
   }
   return(filtname);
Index: message.c
===================================================================
--- message.c	(revision df0d93ab052f98d5b33d143b414f633faff6626c)
+++ message.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -529,5 +529,5 @@
 }
 
-void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text)
+void owl_message_create_incoming_aim(owl_message *m, char *sender, char *recipient, char *text)
 {
   char *indent;
@@ -538,4 +538,31 @@
   owl_message_set_recipient(m, recipient);
   owl_message_set_type_aim(m);
+  owl_message_set_direction_in(m);
+
+  indent=owl_malloc(strlen(text)+owl_text_num_lines(text)*OWL_MSGTAB+10);
+  owl_text_indent(indent, text, OWL_MSGTAB);
+  owl_fmtext_init_null(&(m->fmtext));
+  owl_fmtext_append_bold(&(m->fmtext), OWL_TABSTR);
+  owl_fmtext_append_bold(&(m->fmtext), "AIM from ");
+  owl_fmtext_append_bold(&(m->fmtext), sender);
+  owl_fmtext_append_bold(&(m->fmtext), "\n");
+  owl_fmtext_append_bold(&(m->fmtext), indent);
+  if (text[strlen(text)-1]!='\n') {
+    owl_fmtext_append_bold(&(m->fmtext), "\n");
+  }
+  
+  owl_free(indent);
+}
+
+void owl_message_create_outgoing_aim(owl_message *m, char *sender, char *recipient, char *text)
+{
+  char *indent;
+
+  owl_message_init(m);
+  owl_message_set_body(m, text);
+  owl_message_set_sender(m, sender);
+  owl_message_set_recipient(m, recipient);
+  owl_message_set_type_aim(m);
+  owl_message_set_direction_out(m);
 
   indent=owl_malloc(strlen(text)+owl_text_num_lines(text)*OWL_MSGTAB+10);
@@ -543,7 +570,5 @@
   owl_fmtext_init_null(&(m->fmtext));
   owl_fmtext_append_normal(&(m->fmtext), OWL_TABSTR);
-  owl_fmtext_append_normal(&(m->fmtext), "AIM: ");
-  owl_fmtext_append_normal(&(m->fmtext), sender);
-  owl_fmtext_append_normal(&(m->fmtext), " -> ");
+  owl_fmtext_append_normal(&(m->fmtext), "AIM sent to ");
   owl_fmtext_append_normal(&(m->fmtext), recipient);
   owl_fmtext_append_normal(&(m->fmtext), "\n");
@@ -889,5 +914,5 @@
     owl_fmtext_append_ztext(&(m->fmtext), indent);
 
-    /* make personal messages bold for smaat users */
+    /* make private messages bold for smaat users */
     if (owl_global_is_userclue(&g, OWL_USERCLUE_CLASSES)) {
       if (owl_message_is_personal(m)) {
Index: owl.c
===================================================================
--- owl.c	(revision 31e48a31baadb6973aeafc691fec373040f39690)
+++ owl.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -138,6 +138,12 @@
 
   /* setup the default filters */
-  f=malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "personal", "class ^message$ and instance ^personal$ and ( recipient ^%me%$ or sender ^%me%$ )");
+
+  /* the personal filter will need to change again when AIM chat's are
+   *  included.  Also, there should be an %aimme% */
+  f=malloc(sizeof(owl_filter));
+  owl_filter_init_fromstring(f, "personal", "( type ^zephyr$ "
+			     "and class ^message$ and instance ^personal$ "
+			     "and ( recipient ^%me%$ or sender ^%me%$ ) ) "
+			     "or ( type ^aim$ )");
   owl_list_append_element(owl_global_get_filterlist(&g), f);
 
@@ -330,5 +336,7 @@
 
       /* ring the bell if it's a personal */
-      if (owl_global_is_personalbell(&g) && owl_message_is_personal(m)) {
+      if (owl_global_is_personalbell(&g) &&
+	  (owl_message_is_personal(m) ||
+	  (owl_message_is_type_aim(m) && owl_message_is_to_me(m)))) {
 	owl_function_beep();
       }
Index: owl_prototypes.h
===================================================================
--- owl_prototypes.h	(revision df0d93ab052f98d5b33d143b414f633faff6626c)
+++ owl_prototypes.h	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -356,7 +356,8 @@
 extern void owl_function_show_filter(char *name);
 extern void owl_function_show_zpunts();
-extern char *owl_function_fastclassinstfilt(char *class, char *instance);
-extern char *owl_function_fastuserfilt(char *user);
-extern char *owl_function_fasttypefilt(char *type);
+extern char *owl_function_classinstfilt(char *class, char *instance);
+extern char *owl_function_zuserfilt(char *user);
+extern char *owl_function_aimuserfilt(char *user);
+extern char *owl_function_typefilt(char *type);
 extern void owl_function_delete_curview_msgs(int flag);
 extern char *owl_function_smartfilter(int type);
@@ -610,5 +611,6 @@
 extern int owl_message_search(owl_message *m, char *string);
 extern void owl_message_create(owl_message *m, char *header, char *text);
-extern void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text);
+extern void owl_message_create_incoming_aim(owl_message *m, char *sender, char *recipient, char *text);
+extern void owl_message_create_outgoing_aim(owl_message *m, char *sender, char *recipient, char *text);
 extern void owl_message_create_admin(owl_message *m, char *header, char *text);
 extern void owl_message_create_from_znotice(owl_message *m, ZNotice_t *n);
@@ -690,4 +692,5 @@
 extern void owl_text_indent(char *out, char *in, int n);
 extern int owl_text_num_lines(char *in);
+extern char *owl_text_htmlstrip(char *in);
 
 /* -------------------------------- util.c -------------------------------- */
Index: text.c
===================================================================
--- text.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ text.c	(revision 3abf28bfbedff7d4c809523f93b98d6fd70d120e)
@@ -127,2 +127,55 @@
 }
 
+
+/* caller must free the return */
+char *owl_text_htmlstrip(char *in) {
+  char *ptr1, *end, *ptr2, *ptr3, *out;
+
+  out=owl_malloc(strlen(in)+30);
+  strcpy(out, "");
+
+  ptr1=in;
+  end=in+strlen(in);
+  
+  while(ptr1<end) {
+    /* look for an open bracket */
+    ptr2=strchr(ptr1, '<');
+
+    /* if not, copy in from here to end and exit */
+    if (ptr2==NULL) {
+      strcat(out, ptr1);
+      return(out);
+    }
+
+    /* otherwise copy in everything before the open bracket */
+    if (ptr2>ptr1) {
+      strncat(out, ptr1, ptr2-ptr1);
+    }
+
+    /* find the close bracket */
+    ptr3=strchr(ptr2, '>');
+    
+    /* if there is no close, copy as you are and exit */
+    if (!ptr3) {
+      strcat(out, ptr2);
+    }
+
+    /* look for things we know */
+    if (!strncasecmp(ptr2, "<BODY ", 6) ||
+	!strncasecmp(ptr2, "<FONT ", 6) ||
+	!strncasecmp(ptr2, "<HTML", 5) ||
+	!strncasecmp(ptr2, "</FONT", 6) ||
+	!strncasecmp(ptr2, "</HTML", 6) ||
+	!strncasecmp(ptr2, "</BODY", 6)) {
+
+      /* advance to beyond the angle brakcet and go again */
+      ptr1=ptr3+1;
+      continue;
+    }
+
+    /* if it wasn't something we know, copy to the > and  go again */
+    strncat(out, ptr2, ptr3-ptr2);
+    ptr1=ptr3+1;
+  }
+  return(out);
+}
