diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css
index abe2829c1eacbb7e06454311c51046987eef5109..4b880e8c3ceaf57e5adb2575e835a0a2a9ff2872 100644
--- a/assets/default/css/theme.css
+++ b/assets/default/css/theme.css
@@ -1067,6 +1067,10 @@ table.custom-data .headline {
 img.avatar {
     border-radius: inherit;
 }
+.avatar > img.avatar {
+    width: 100%;
+    height: 100%;
+}
 .thread-entry .header {
     padding: 8px 0.9em;
     border: 1px solid #ccc;
diff --git a/avatar.php b/avatar.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0dced7de27d45d72642320a112d52c2de2f3ada
--- /dev/null
+++ b/avatar.php
@@ -0,0 +1,36 @@
+<?php
+/*********************************************************************
+    file.php
+
+    File download facilitator for clients
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2014 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+require('client.inc.php');
+
+if (!isset($_GET['uid']) || !isset($_GET['mode']))
+    Http::response(400, '`uid` and `mode` parameters are required');
+
+require_once INCLUDE_DIR . 'class.avatar.php';
+
+try {
+    $ra = new RandomAvatar($_GET['mode']);
+    $avatar = $ra->makeAvatar($_GET['uid']);
+
+    Http::response(200, false, 'image/png', false);
+    Http::cacheable($_GET['uid'], false, 86400);
+    imagepng($avatar, null, 1);
+    imagedestroy($avatar);
+    exit;
+}
+catch (InvalidArgumentException $ex) {
+    Http::response(422, 'No such avatar image set');
+}
diff --git a/include/class.avatar.php b/include/class.avatar.php
index 7adefad798c989e40d268eebf376cf1b18b55e5c..d46a066e224f1b99b3cf353007fd8c82dd5cd897 100644
--- a/include/class.avatar.php
+++ b/include/class.avatar.php
@@ -23,12 +23,25 @@ abstract class Avatar {
     }
 
     abstract function getUrl($size);
-    abstract function __toString();
+
+    function getImageTag($size=null) {
+        return '<img class="avatar" alt="'.__('Avatar').'" src="'.$this->getUrl($size).'" />';
+    }
+
+    function __toString() {
+        return $this->getImageTag();
+    }
 }
 
 abstract class AvatarSource {
     static $id;
     static $name;
+    var $mode;
+
+    function __construct($mode=null) {
+        if (isset($mode))
+            $this->mode = $mode;
+    }
 
     function getName() {
         return __(static::$name);
@@ -124,12 +137,80 @@ extends Avatar {
         $url .= "?s=$size&d={$this->d}";
         return $url;
     }
+}
 
-    function getImageTag($size=null) {
-        return '<img class="avatar" alt="'.__('Avatar').'" src="'.$this->getUrl($size).'" />';
+class LocalAvatarSource
+extends AvatarSource {
+    static $id = 'local';
+    static $name = /* @trans */ 'Built-In';
+    var $mode = 'ateam';
+
+    static function getModes() {
+        return array(
+            'ateam' => __("Oscar's A-Team"),
+        );
     }
 
-    function __toString() {
-        return $this->getImageTag();
+    function getAvatar($user) {
+        return new LocalAvatar($user, $this->mode);
+    }
+}
+AvatarSource::register('LocalAvatarSource');
+
+class LocalAvatar
+extends Avatar {
+    var $mode;
+
+    function __construct($user, $mode) {
+        parent::__construct($user);
+        $this->mode = $mode;
+    }
+
+    function getUrl($size) {
+        if (false && ($file = $this->user->getAvatarFile()))
+            return $file->getDownloadUrl();
+
+        // Generate a random string of 0-6 chars for the avatar signature
+        $uid = md5(strtolower($this->user->getEmail()));
+        return 'avatar.php?'.Http::build_query(array('uid'=>$uid,
+            'mode' => $this->mode));
+    }
+
+    static function serveRandomAvatar($uid, $mode) {
+    }
+}
+
+class RandomAvatar {
+    var $mode;
+
+    static $sprites = array(
+        'ateam' => array(
+            'file' => 'images/avatar-sprite-ateam.png',
+            'grid' => 96,
+        ),
+    );
+
+    function __construct($mode) {
+        $this->mode = $mode;
+    }
+
+    function makeAvatar($uid) {
+        $sprite = self::$sprites[$this->mode];
+        $source =  imagecreatefrompng(ROOT_DIR . $sprite['file']);
+        $grid = $sprite['grid'];
+        $avatar = imagecreatetruecolor($grid, $grid);
+        $width = imagesx($source) / $grid;
+        $height = imagesy($source) / $grid;
+
+        // Start with a white matte
+        $white = imagecolorallocate($avatar, 255, 255, 255);
+        imagefill($avatar, 0, 0, $white);
+
+        for ($i=0, $k=$height-1; $i<$k; $i++) {
+            $idx = hexdec($uid[$i]) % $width;
+            imagecopy($avatar, $source, 0, 0, $idx*$grid, $i*$grid, $grid, $grid);
+        }
+
+        return $avatar;
     }
 }
diff --git a/include/class.http.php b/include/class.http.php
index 5e14ee932bb2acbd013b348083a4176a13fc42cb..2fd09a8d70f7aa37041bd8b57597216024cc5cc7 100644
--- a/include/class.http.php
+++ b/include/class.http.php
@@ -37,10 +37,15 @@ class Http {
         header('HTTP/1.1 '.Http::header_code_verbose($code));
 		header('Status: '.Http::header_code_verbose($code)."\r\n");
 		header("Connection: Close\r\n");
-		header("Content-Type: $contentType; charset=$charset\r\n");
-        header('Content-Length: '.strlen($content)."\r\n\r\n");
-       	print $content;
-        exit;
+        $ct = "Content-Type: $contentType";
+        if ($charset)
+            $ct .= "; charset=$charset";
+        header($ct);
+        if ($content) {
+            header('Content-Length: '.strlen($content)."\r\n\r\n");
+            print $content;
+            exit;
+        }
     }
 
     function redirect($url,$delay=0,$msg='') {