public function JoinUsers(&$Data, $Columns, $Options = array()) {
      // Grab all of the user fields that need to be joined.
      $UserIDs = array();
      foreach ($Data as $Row) {
         foreach ($Columns as $ColumnName) {
            $ID = GetValue($ColumnName, $Row);
            if (is_numeric($ID))
               $UserIDs[$ID] = 1;
         }
      }
      
      // Get the users.
      $Users = $this->GetIDs(array_keys($UserIDs));
      
      // Get column name prefix (ex: 'Insert' from 'InsertUserID')
      $Prefixes = array();
      foreach ($Columns as $ColumnName) {
         $Prefixes[] = StringEndsWith($ColumnName, 'UserID', TRUE, TRUE);
      }
      
      // Join the user data using prefixes (ex: 'Name' for 'InsertUserID' becomes 'InsertName')
      $Join = GetValue('Join', $Options, array('Name', 'Email', 'Photo'));
      $UserPhotoDefaultUrl = function_exists('UserPhotoDefaultUrl');
      
      foreach ($Data as &$Row) {
         foreach ($Prefixes as $Px) {
            $ID = GetValue($Px.'UserID', $Row);
            if (is_numeric($ID)) {
               $User = GetValue($ID, $Users, FALSE);
               foreach ($Join as $Column) {
                  $Value = $User[$Column];
                  if ($Column == 'Photo') {
                     if (!$Value) {
                        if ($UserPhotoDefaultUrl)
                           $Value = UserPhotoDefaultUrl($User);
                     } elseif (!IsUrl($Value)) {
                        $Value = Gdn_Upload::Url(ChangeBasename($Value, 'n%s'));
                     }
                  }
                  SetValue($Px.$Column, $Row, $Value);
               }
            } else {
               foreach ($Join as $Column) {
                  SetValue($Px.$Column, $Row, NULL);
               }
            }
            
            
         }
      }
   }