/**
  * Tag output function must be called by caller
  * Parser cache control deferred to caller
  * @param \FlaggedRevision|\stable $srev stable version
  * @param string $tag review box/bar info
  * @param string $prot protection notice
  * @return ParserOutput
  */
 protected function showStableVersion(FlaggedRevision $srev, &$tag, $prot)
 {
     $reqUser = $this->getUser();
     $this->load();
     $flags = $srev->getTags();
     $time = $this->getLanguage()->date($srev->getTimestamp(), true);
     # Set display revision ID
     $this->out->setRevisionId($srev->getRevId());
     # Get quality level
     $quality = FlaggedRevs::isQuality($flags);
     $synced = $this->article->stableVersionIsSynced();
     # Construct some tagging
     if (!$this->out->isPrintable() && !($this->article->lowProfileUI() && $synced)) {
         $revsSince = $this->article->getPendingRevCount();
         // Simple icon-based UI
         if ($this->useSimpleUI()) {
             $icon = '';
             # For protection based configs, show lock only if it's not redundant.
             if ($this->showRatingIcon()) {
                 $icon = FlaggedRevsXML::stableStatusIcon($quality);
             }
             if (!$reqUser->getId()) {
                 $msgHTML = '';
                 // Anons just see simple icons
             } else {
                 $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic';
                 # Uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
                 $msg = $synced ? "{$msg}-same" : $msg;
                 $msgHTML = $this->msg($msg, $srev->getRevId())->numParams($revsSince)->parse();
             }
             $msgHTML = $prot . $icon . $msgHTML;
             $tag = FlaggedRevsXML::prettyRatingBox($srev, $msgHTML, $revsSince, 'stable', $synced);
             // Standard UI
         } else {
             $icon = FlaggedRevsXML::stableStatusIcon($quality);
             $msg = $quality ? 'revreview-quality' : 'revreview-basic';
             if ($synced) {
                 # uses messages 'revreview-quality-same', 'revreview-basic-same'
                 $msg .= '-same';
             } elseif ($revsSince == 0) {
                 # uses messages 'revreview-quality-i', 'revreview-basic-i'
                 $msg .= '-i';
             }
             $tag = $prot . $icon;
             $tag .= $this->msg($msg, $srev->getRevId(), $time)->numParams($revsSince)->parse();
             if (!empty($flags)) {
                 $tag .= FlaggedRevsXML::ratingToggle();
                 $tag .= "<div id='mw-fr-revisiondetails'>" . FlaggedRevsXML::addTagRatings($flags) . '</div>';
             }
         }
     }
     # Get parsed stable version and output HTML
     $pOpts = $this->article->makeParserOptions($reqUser);
     if (!$this->article->getTitle()->quickUserCan('edit', $reqUser)) {
         $pOpts->setEditSection(false);
     }
     $parserCache = FRParserCacheStable::singleton();
     $parserOut = $parserCache->get($this->article, $pOpts);
     # Do not use the parser cache if it lacks mImageTimeKeys and there is a
     # chance that a review form will be added to this page (which requires the versions).
     $canReview = $this->article->getTitle()->userCan('review');
     if ($parserOut && (!$canReview || FlaggedRevs::parserOutputIsVersioned($parserOut))) {
         # Cache hit. Note that redirects are not cached.
         $this->out->addParserOutput($parserOut);
     } else {
         # Get the new stable parser output...
         if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT && $synced) {
             # We can try the current version cache, since they are the same revision
             $parserOut = ParserCache::singleton()->get($this->article, $pOpts);
         } else {
             $parserOut = false;
         }
         if (!$parserOut) {
             $parserOut = FlaggedRevs::parseStableRevision($srev, $pOpts);
         }
         if (!$parserOut) {
             // serious error
             $this->out->addWikiMsg('missing-article', $this->article->getTitle()->getPrefixedText(), $this->msg('missingarticle-rev', $srev->getRevId())->text());
             return null;
         }
         # Update the stable version cache
         $parserCache->save($parserOut, $this->article, $pOpts);
         # Add the stable output to the page view
         $this->out->addParserOutput($parserOut);
         # Update the stable version dependancies
         FlaggedRevs::updateStableOnlyDeps($this->article, $parserOut);
     }
     # Update page sync status for tracking purposes.
     # NOTE: avoids master hits and doesn't have to be perfect for what it does
     if ($this->article->syncedInTracking() != $synced) {
         if (wfGetLB()->safeGetLag(wfGetDB(DB_SLAVE)) <= 5) {
             // avoid write-delay cycles
             $this->article->updateSyncStatus($synced);
         }
     }
     return $parserOut;
 }