function($mid, $p, $partno)
  {
    // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
    global $htmlmsg, $htmlmsg_noimg, $plainmsg, $charset, $attachments;
    // DECODE DATA
    $data = ($partno) ? imap_fetchbody($this->stream, $mid, $partno) : // multipart
    imap_body($this->stream, $mid); // simple
    // Any part may be encoded, even plain text messages, so check everything.
    if ($p->encoding == 4) {
      $data = quoted_printable_decode($data);
    } elseif ($p->encoding == 3) {
      $data = base64_decode($data);
    }
    // PARAMETERS
    // get all parameters, like charset, Filenames of attachments, etc.
    $params = array();
    if ($p->parameters) {
      foreach ($p->parameters as $x) {
        $params[strtolower($x->attribute)] = $x->value;
      }
    }
    if ($p->dparameters) {
      foreach ($p->dparameters as $x) {
        $params[strtolower($x->attribute)] = $x->value;
      }
    }
    // ATTACHMENT
    // Any part with a filename is an attachment,
    // so an attached text file (type 0) is not mistaken as the message.
    if ($params['filename'] || $params['name']) {
      // filename may be given as 'Filename' or 'Name' or both
      $filename = ($params['filename']) ? $params['filename'] : $params['name'];
      // filename may be encoded, so see imap_mime_header_decode()
      array_push($attachments, $filename);
      file_put_contents($bbng_data_path . 'users/' . $_SESSION['bbn_user']['id'] . '/tmp_mail/' . $filename, $data);
      // this is a problem if two files have same name
    }
    // TEXT
    if ($p->type == 0 && $data) {
      // Messages may be split in different parts because of inline attachments,
      // so append parts together with blank row.
      $charset = $params['charset']; // assume all parts are same charset
      if (strtolower($p->subtype) == 'plain') {
        if (stripos($charset, 'ISO') !== false) {
          /*
          include_once $bbng_app_path . 'classes/convert.php';
          $utfConverter = new utf8($charset);
          if ($utfConverter->loadCharset($charset)) {
            $plainmsg .= $utfConverter->strToUtf8(trim($data)) .PHP_EOL;
          }
          else {
            $plainmsg .= trim($data) .PHP_EOL;
          }
          */
          $plainmsg .= trim(utf8_encode($data)) .PHP_EOL;
        }
        else {
          $plainmsg .= trim($data) .PHP_EOL;
        }
      }
      else {
        if (stripos($charset, 'ISO') !== false) {
          /*
          include_once $bbng_app_path . 'classes/convert.php';
          if ($utfConverter = new utf8($charset)) {
            $htmlmsg .= $utfConverter->strToUtf8(trim($data)) . '
';
          }
          else {
            $htmlmsg .= trim($data) . '
';
          }
          */
          $htmlmsg .= trim(utf8_encode($data)) . '
';
        }
        else {
          $htmlmsg .= trim($data) . '
';
        }
        if (!empty($htmlmsg)) {
          $body_pattern = "/]*)>(.*)<\/body>/smi";
          preg_match($body_pattern, $htmlmsg, $body);
          if (!empty($body[2])) {
            $htmlmsg = $body[2];
          }
          $img_pattern   = "/![]() ]+)>/smi";
          $htmlmsg_noimg = preg_replace($img_pattern, '', $htmlmsg);
        }
      }
    }
    // EMBEDDED MESSAGE
    // Many bounce notifications embed the original message as type 2,
    // but AOL uses type 1 (multipart), which is not handled here.
    // There are no PHP functions to parse embedded messages,
    // so this just appends the raw source to the main message.
    elseif ($p->type == 2 && $data && strtolower($p->subtype) == 'plain') {
      if (stripos($charset, 'ISO') !== false) {
        /*
        include_once $bbng_app_path . 'classes/convert.php';
        $utfConverter = new utf8($charset);
        if ($utfConverter->loadCharset($charset)) {
          $plainmsg .= $utfConverter->strToUtf8(trim($data)) . "
";
        } else {
          $plainmsg .= trim($data) . "
";
        }
        */
        $plainmsg .= trim(utf8_encode($data)) .PHP_EOL;
      }
      else {
        $plainmsg .= trim($data) .PHP_EOL;
      }
    }
    // SUBPART RECURSION
    if ($p->parts) {
      foreach ($p->parts as $partno0 => $p2) {
        $this->getpart($mid, $p2, $partno . '.' . ($partno0 + 1)); // 1.2, 1.2.1, etc.
      }
    }
  }
]+)>/smi";
          $htmlmsg_noimg = preg_replace($img_pattern, '', $htmlmsg);
        }
      }
    }
    // EMBEDDED MESSAGE
    // Many bounce notifications embed the original message as type 2,
    // but AOL uses type 1 (multipart), which is not handled here.
    // There are no PHP functions to parse embedded messages,
    // so this just appends the raw source to the main message.
    elseif ($p->type == 2 && $data && strtolower($p->subtype) == 'plain') {
      if (stripos($charset, 'ISO') !== false) {
        /*
        include_once $bbng_app_path . 'classes/convert.php';
        $utfConverter = new utf8($charset);
        if ($utfConverter->loadCharset($charset)) {
          $plainmsg .= $utfConverter->strToUtf8(trim($data)) . "
";
        } else {
          $plainmsg .= trim($data) . "
";
        }
        */
        $plainmsg .= trim(utf8_encode($data)) .PHP_EOL;
      }
      else {
        $plainmsg .= trim($data) .PHP_EOL;
      }
    }
    // SUBPART RECURSION
    if ($p->parts) {
      foreach ($p->parts as $partno0 => $p2) {
        $this->getpart($mid, $p2, $partno . '.' . ($partno0 + 1)); // 1.2, 1.2.1, etc.
      }
    }
  }