Merge "Include action in permission error messages"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 18 Aug 2014 14:02:56 +0000 (14:02 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 18 Aug 2014 14:02:56 +0000 (14:02 +0000)
1  2 
includes/Title.php
languages/i18n/qqq.json
tests/phpunit/includes/TitlePermissionTest.php

diff --combined includes/Title.php
@@@ -74,9 -74,6 +74,9 @@@ class Title 
        /** @var string Interwiki prefix */
        public $mInterwiki = '';
  
 +      /** @var bool Was this Title created from a string with a local interwiki prefix? */
 +      private $mLocalInterwiki = false;
 +
        /** @var string Title fragment (i.e. the bit after the #) */
        public $mFragment = '';
  
@@@ -98,7 -95,7 +98,7 @@@
        /** @var array Array of groups allowed to edit this article */
        public $mRestrictions = array();
  
 -      /** @var bool  */
 +      /** @var bool */
        protected $mOldRestrictions = false;
  
        /** @var bool Cascade restrictions on this page to included templates and images? */
        /** @var bool The (string) language code of the page's language and content code. */
        private $mPageLanguage = false;
  
 +      /** @var string The page language code from the database */
 +      private $mDbPageLanguage = null;
 +
        /** @var TitleValue A corresponding TitleValue object */
        private $mTitleValue = null;
        // @}
                        } else {
                                $this->mContentModel = false; # initialized lazily in getContentModel()
                        }
 +                      if ( isset( $row->page_lang ) ) {
 +                              $this->mDbPageLanguage = (string)$row->page_lang;
 +                      }
                } else { // page not found
                        $this->mArticleID = 0;
                        $this->mLength = 0;
         * Note that this doesn't pick up many things that could be wrong with titles, but that
         * replacing this regex with something valid will make many titles valid.
         *
 -       * @todo: move this into MediaWikiTitleCodec
 +       * @todo move this into MediaWikiTitleCodec
         *
         * @return string Regex string
         */
                return $this->mInterwiki;
        }
  
 +      /**
 +       * Was this a local interwiki link?
 +       *
 +       * @return bool
 +       */
 +      public function wasLocalInterwiki() {
 +              return $this->mLocalInterwiki;
 +      }
 +
        /**
         * Determine whether the object refers to a page within
         * this project and is transcludable.
        /**
         * Get a TitleValue object representing this Title.
         *
 -       * @note: Not all valid Titles have a corresponding valid TitleValue
 +       * @note Not all valid Titles have a corresponding valid TitleValue
         * (e.g. TitleValues cannot represent page-local links that have a
         * fragment but no title text).
         *
                }
  
                try {
 -                      $formatter = $this->getTitleFormatter();
 +                      $formatter = self::getTitleFormatter();
                        return $formatter->getNamespaceName( $this->mNamespace, $this->mDbkeyform );
 -              } catch ( InvalidArgumentException $ex )  {
 +              } catch ( InvalidArgumentException $ex ) {
                        wfDebug( __METHOD__ . ': ' . $ex->getMessage() . "\n" );
                        return false;
                }
        /**
         * Returns true if the title is inside one of the specified namespaces.
         *
 -       * @param ...$namespaces The namespaces to check for
 +       * @param int $namespaces,... The namespaces to check for
         * @return bool
         * @since 1.19
         */
         *
         * @param string $name The text
         * @return string The prefixed text
 -       * @private
         */
        private function prefix( $name ) {
                $p = '';
                return Title::makeTitleSafe( $this->getNamespace(), $this->getText() . '/' . $text );
        }
  
 -      /**
 -       * Get the HTML-escaped displayable text form.
 -       * Used for the title field in <a> tags.
 -       *
 -       * @return string The text, including any prefixes
 -       * @deprecated since 1.19
 -       */
 -      public function getEscapedText() {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              return htmlspecialchars( $this->getPrefixedText() );
 -      }
 -
        /**
         * Get a URL-encoded form of the subpage text
         *
         * $wgServer is prepended to make an absolute URL.
         *
         * @see self::getFullURL to always get an absolute URL.
 +       * @see self::getLinkURL to always get a URL that's the simplest URL that will be
 +       *  valid to link, locally, to the current Title.
         * @see self::newFromText to produce a Title object.
         *
 -       * @param string|array $query an optional query string,
 +       * @param string|array $query An optional query string,
         *   not used for interwiki links. Can be specified as an associative array as well,
         *   e.g., array( 'action' => 'edit' ) (keys and values will be URL-escaped).
         *   Some query patterns will trigger various shorturl path replacements.
                return $ret;
        }
  
 -      /**
 -       * Get an HTML-escaped version of the URL form, suitable for
 -       * using in a link, without a server name or fragment
 -       *
 -       * @see self::getLocalURL for the arguments.
 -       * @param string $query
 -       * @param bool|string $query2
 -       * @return string The URL
 -       * @deprecated since 1.19
 -       */
 -      public function escapeLocalURL( $query = '', $query2 = false ) {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              return htmlspecialchars( $this->getLocalURL( $query, $query2 ) );
 -      }
 -
 -      /**
 -       * Get an HTML-escaped version of the URL form, suitable for
 -       * using in a link, including the server name and fragment
 -       *
 -       * @see self::getLocalURL for the arguments.
 -       * @return string The URL
 -       * @deprecated since 1.19
 -       */
 -      public function escapeFullURL( $query = '', $query2 = false ) {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              return htmlspecialchars( $this->getFullURL( $query, $query2 ) );
 -      }
 -
        /**
         * Get the URL form for an internal link.
         * - Used in various Squid-related code, in case we have a different
                return $url;
        }
  
 -      /**
 -       * HTML-escaped version of getCanonicalURL()
 -       *
 -       * @see self::getLocalURL for the arguments.
 -       * @since 1.18
 -       * @return string
 -       * @deprecated since 1.19
 -       */
 -      public function escapeCanonicalURL( $query = '', $query2 = false ) {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              return htmlspecialchars( $this->getCanonicalURL( $query, $query2 ) );
 -      }
 -
        /**
         * Get the edit URL for this Title
         *
                return $this->mWatched;
        }
  
 -      /**
 -       * Can $wgUser read this page?
 -       *
 -       * @deprecated since 1.19; use userCan(), quickUserCan() or getUserPermissionsErrors() instead
 -       * @return bool
 -       */
 -      public function userCanRead() {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              return $this->userCan( 'read' );
 -      }
 -
        /**
         * Can $user perform $action on this page?
         * This skips potentially expensive cascading permission checks
         *
         * @todo FIXME: This *does not* check throttles (User::pingLimiter()).
         *
 -       * @param string $action action that permission needs to be checked for
 +       * @param string $action Action that permission needs to be checked for
         * @param User $user User to check
         * @param bool $doExpensiveQueries Set this to false to avoid doing unnecessary
         *   queries by skipping checks for cascading protections and user blocks.
 -       * @param array $ignoreErrors of Strings Set this to a list of message keys
 +       * @param array $ignoreErrors Array of Strings Set this to a list of message keys
         *   whose corresponding errors may be ignored.
         * @return array Array of arguments to wfMessage to explain permissions problems.
         */
        /**
         * Permissions checks that fail most often, and which are easiest to test.
         *
 -       * @param string $action the action to check
 +       * @param string $action The action to check
         * @param User $user User to check
         * @param array $errors List of current errors
         * @param bool $doExpensiveQueries Whether or not to perform expensive queries
                        $ns = $this->mNamespace == NS_MAIN ?
                                wfMessage( 'nstab-main' )->text() : $this->getNsText();
                        $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
-                               array( 'protectedinterface' ) : array( 'namespaceprotected', $ns );
+                               array( 'protectedinterface', $action ) : array( 'namespaceprotected', $ns, $action );
                }
  
                return $errors;
                if ( $action != 'patrol' && !$user->isAllowed( 'editusercssjs' ) ) {
                        if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $this->mTextform ) ) {
                                if ( $this->isCssSubpage() && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) {
-                                       $errors[] = array( 'mycustomcssprotected' );
+                                       $errors[] = array( 'mycustomcssprotected', $action );
                                } elseif ( $this->isJsSubpage() && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) ) {
-                                       $errors[] = array( 'mycustomjsprotected' );
+                                       $errors[] = array( 'mycustomjsprotected', $action );
                                }
                        } else {
                                if ( $this->isCssSubpage() && !$user->isAllowed( 'editusercss' ) ) {
-                                       $errors[] = array( 'customcssprotected' );
+                                       $errors[] = array( 'customcssprotected', $action );
                                } elseif ( $this->isJsSubpage() && !$user->isAllowed( 'edituserjs' ) ) {
-                                       $errors[] = array( 'customjsprotected' );
+                                       $errors[] = array( 'customjsprotected', $action );
                                }
                        }
                }
                                continue;
                        }
                        if ( !$user->isAllowed( $right ) ) {
-                               $errors[] = array( 'protectedpagetext', $right );
+                               $errors[] = array( 'protectedpagetext', $right, $action );
                        } elseif ( $this->mCascadeRestriction && !$user->isAllowed( 'protect' ) ) {
-                               $errors[] = array( 'protectedpagetext', 'protect' );
+                               $errors[] = array( 'protectedpagetext', 'protect', $action );
                        }
                }
  
                                                foreach ( $cascadingSources as $page ) {
                                                        $pages .= '* [[:' . $page->getPrefixedText() . "]]\n";
                                                }
-                                               $errors[] = array( 'cascadeprotected', count( $cascadingSources ), $pages );
+                                               $errors[] = array( 'cascadeprotected', count( $cascadingSources ), $pages, $action );
                                        }
                                }
                        }
                                $errors[] = array( 'immobile-target-page' );
                        }
                } elseif ( $action == 'delete' ) {
 +                      if ( count( $this->getUserPermissionsErrorsInternal( 'edit',
 +                              $user, $doExpensiveQueries, true ) )
 +                      ) {
 +                              // If they can't edit, they shouldn't delete.
 +                              $errors[] = array( 'delete-cantedit' );
 +                      }
                        if ( $doExpensiveQueries && $wgDeleteRevisionsLimit
                                && !$this->userCan( 'bigdelete', $user ) && $this->isBigDeletion()
                        ) {
                                'checkPermissionHooks',
                                'checkReadPermissions',
                        );
+               # Don't call checkSpecialsAndNSPermissions or checkCSSandJSPermissions
+               # here as it will lead to duplicate error messages. This is okay to do
+               # since anywhere that checks for create will also check for edit, and
+               # those checks are called for edit.
+               } elseif ( $action == 'create' ) {
+                       $checks = array(
+                               'checkQuickPermissions',
+                               'checkPermissionHooks',
+                               'checkPageRestrictions',
+                               'checkCascadingSourcesRestrictions',
+                               'checkActionPermissions',
+                               'checkUserBlock'
+                       );
                } else {
                        $checks = array(
                                'checkQuickPermissions',
                        return false;
                }
  
 -              if ( !isset( $this->mTitleProtection ) ) {
 +              if ( $this->mTitleProtection === null ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $res = $dbr->select(
                                'protected_titles',
                return $this->mTitleProtection;
        }
  
 -      /**
 -       * Update the title protection status
 -       *
 -       * @deprecated since 1.19; use WikiPage::doUpdateRestrictions() instead.
 -       * @param string $create_perm Permission required for creation
 -       * @param string $reason Reason for protection
 -       * @param string $expiry Expiry timestamp
 -       * @return bool
 -       */
 -      public function updateTitleProtection( $create_perm, $reason, $expiry ) {
 -              wfDeprecated( __METHOD__, '1.19' );
 -
 -              global $wgUser;
 -
 -              $limit = array( 'create' => $create_perm );
 -              $expiry = array( 'create' => $expiry );
 -
 -              $page = WikiPage::factory( $this );
 -              $cascade = false;
 -              $status = $page->doUpdateRestrictions( $limit, $expiry, $cascade, $reason, $wgUser );
 -
 -              return $status->isOK();
 -      }
 -
        /**
         * Remove any title protection due to page existing
         */
        /**
         * Does the title correspond to a protected article?
         *
 -       * @param string $action the action the page is protected from,
 +       * @param string $action The action the page is protected from,
         * by default checks all actions.
         * @return bool
         */
         * @since 1.23
         */
        public function areCascadeProtectionSourcesLoaded( $getPages = true ) {
 -              return $getPages ? isset( $this->mCascadeSources ) : isset( $this->mHasCascadingRestrictions );
 +              return $getPages ? $this->mCascadeSources !== null : $this->mHasCascadingRestrictions !== null;
        }
  
        /**
                global $wgContLang;
                $pagerestrictions = array();
  
 -              if ( isset( $this->mCascadeSources ) && $getPages ) {
 +              if ( $this->mCascadeSources !== null && $getPages ) {
                        return array( $this->mCascadeSources, $this->mCascadingRestrictions );
 -              } elseif ( isset( $this->mHasCascadingRestrictions ) && !$getPages ) {
 +              } elseif ( $this->mHasCascadingRestrictions !== null && !$getPages ) {
                        return array( $this->mHasCascadingRestrictions, $pagerestrictions );
                }
  
  
                $method = __METHOD__;
                $dbw = wfGetDB( DB_MASTER );
 -              $dbw->onTransactionIdle( function() use ( $dbw, $method ) {
 +              $dbw->onTransactionIdle( function () use ( $dbw, $method ) {
                        $dbw->delete(
                                'page_restrictions',
                                array( 'pr_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ),
                # alone to cache the result.  There's no point in having it hanging
                # around uninitialized in every Title object; therefore we only add it
                # if needed and don't declare it statically.
 -              if ( !isset( $this->mHasSubpages ) ) {
 +              if ( $this->mHasSubpages === null ) {
                        $this->mHasSubpages = false;
                        $subpages = $this->getSubpages( 1 );
                        if ( $subpages instanceof TitleArray ) {
                $this->mContentModel = false;
                $this->mEstimateRevisions = null;
                $this->mPageLanguage = false;
 +              $this->mDbPageLanguage = null;
        }
  
        /**
                        // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share
                        //        the parsing code with Title, while avoiding massive refactoring.
                        // @todo: get rid of secureAndSplit, refactor parsing code.
 -                      $parser = $this->getTitleParser();
 +                      $parser = self::getTitleParser();
                        $parts = $parser->splitTitleString( $dbkey, $this->getDefaultNamespace() );
                } catch ( MalformedTitleException $ex ) {
                        return false;
                # Fill fields
                $this->setFragment( '#' . $parts['fragment'] );
                $this->mInterwiki = $parts['interwiki'];
 +              $this->mLocalInterwiki = $parts['local_interwiki'];
                $this->mNamespace = $parts['namespace'];
                $this->mUserCaseDBKey = $parts['user_case_dbkey'];
  
                        $log->addRelations( 'pr_id', $logRelationsValues, $logId );
                }
  
 +              // Update *_from_namespace fields as needed
 +              if ( $this->getNamespace() != $nt->getNamespace() ) {
 +                      $dbw->update( 'pagelinks',
 +                              array( 'pl_from_namespace' => $nt->getNamespace() ),
 +                              array( 'pl_from' => $pageid ),
 +                              __METHOD__
 +                      );
 +                      $dbw->update( 'templatelinks',
 +                              array( 'tl_from_namespace' => $nt->getNamespace() ),
 +                              array( 'tl_from' => $pageid ),
 +                              __METHOD__
 +                      );
 +                      $dbw->update( 'imagelinks',
 +                              array( 'il_from_namespace' => $nt->getNamespace() ),
 +                              array( 'il_from' => $pageid ),
 +                              __METHOD__
 +                      );
 +              }
 +
                # Update watchlists
 -              $oldnamespace = MWNamespace::getSubject( $this->getNamespace() );
 -              $newnamespace = MWNamespace::getSubject( $nt->getNamespace() );
                $oldtitle = $this->getDBkey();
                $newtitle = $nt->getDBkey();
 -
 -              if ( $oldnamespace != $newnamespace || $oldtitle != $newtitle ) {
 +              $oldsnamespace = MWNamespace::getSubject( $this->getNamespace() );
 +              $newsnamespace = MWNamespace::getSubject( $nt->getNamespace() );
 +              if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
                        WatchedItem::duplicateEntries( $this, $nt );
                }
  
                $method = __METHOD__;
                $dbw = wfGetDB( DB_MASTER );
                $conds = $this->pageCond();
 -              $dbw->onTransactionIdle( function() use ( $dbw, $conds, $method ) {
 +              $dbw->onTransactionIdle( function () use ( $dbw, $conds, $method ) {
                        $dbw->update(
                                'page',
                                array( 'page_touched' => $dbw->timestamp() ),
         * @return string Last-touched timestamp
         */
        public function getTouched( $db = null ) {
 -              $db = isset( $db ) ? $db : wfGetDB( DB_SLAVE );
 +              if ( $db === null ) {
 +                      $db = wfGetDB( DB_SLAVE );
 +              }
                $touched = $db->selectField( 'page', 'page_touched', $this->pageCond(), __METHOD__ );
                return $touched;
        }
                        return $wgLang;
                }
  
 +              // Checking if DB language is set
 +              if ( $this->mDbPageLanguage ) {
 +                      wfProfileOut( __METHOD__ );
 +                      return wfGetLangObj( $this->mDbPageLanguage );
 +              }
 +
                if ( !$this->mPageLanguage || $this->mPageLanguage[1] !== $wgLanguageCode ) {
                        // Note that this may depend on user settings, so the cache should
                        // be only per-request.
                } else {
                        $langObj = wfGetLangObj( $this->mPageLanguage[0] );
                }
 +
                wfProfileOut( __METHOD__ );
                return $langObj;
        }
diff --combined languages/i18n/qqq.json
        "tog-watchdefault": "[[Special:Preferences]], tab 'Watchlist'. Offers user to add edited pages to watchlist. {{Gender}}",
        "tog-watchmoves": "[[Special:Preferences]], tab 'Watchlist'. Offers user to add moved pages to watchlist. {{Gender}}",
        "tog-watchdeletion": "[[Special:Preferences]], tab 'Watchlist'. Offers user to add deleted pages to watchlist. {{Gender}}",
 +      "tog-watchrollback": "[[Special:Preferences]], tab 'Watchlist'. Offers user to add pages where the user has rollbacked an edit to watchlist. {{Gender}}\n\nSee also {{msg-mw|tog-watchdefault}}, {{msg-mw|tog-watchcreations}}.",
        "tog-minordefault": "[[Special:Preferences]], tab 'Edit'. Offers user to mark all edits minor by default.  {{Gender}}",
        "tog-previewontop": "Toggle option used in [[Special:Preferences]]. {{Gender}}",
        "tog-previewonfirst": "Toggle option used in [[Special:Preferences]]. {{Gender}}",
        "faqpage": "{{doc-important|Do not translate <code>Project:</code> part.}}\n\"FAQ\" is short for \"frequently asked questions\".\n\nThis page is only linked in CologneBlue (an old skin), not in Monobook or Vector.",
        "sitetitle": "{{Ignore}}",
        "sitesubtitle": "{{Ignore}}",
 -      "vector-action-addsection": "Used in the Vector skin. See for example {{canonicalurl:Talk:Main_Page|useskin=vector}}",
 -      "vector-action-delete": "Used in the Vector skin, as the name of a tab at the top of the page. See for example {{canonicalurl:Main_Page|useskin=vector}}\n\n{{Identical|Delete}}",
 -      "vector-action-move": "Used in the Vector skin, on the tabs at the top of the page. See for example {{canonicalurl:Talk:Main_Page|useskin=vector}}\n\n{{Identical|Move}}",
 -      "vector-action-protect": "Tab at top of page, in vector skin\n\n{{Identical|Protect}}",
 -      "vector-action-undelete": "Tab at top of page, in vector skin.\n{{Identical|Undelete}}",
 -      "vector-action-unprotect": "Tab at top of page, in vector skin.\n{{Identical|Change protection}}",
 -      "vector-view-create": "Tab label in the Vector skin. See for example {{canonicalurl:Foo|useskin=vector}}\n{{Identical|Create}}",
 -      "vector-view-edit": "Tab label in the Vector skin. See for example {{canonicalurl:Main_Page|useskin=vector}}\n{{Identical|Edit}}",
 -      "vector-view-history": "Tab label in the Vector skin. See for example {{canonicalurl:Main_Page|useskin=vector}}\n{{Identical|View history}}",
 -      "vector-view-view": "Tab label in the Vector skin (verb). See for example {{canonicalurl:Main_Page|useskin=vector}}.\n{{Identical|Read}}",
 -      "vector-view-viewsource": "Tab label in the Vector skin.\n{{Identical|View source}}",
        "actions": "{{Identical|Action}}",
 -      "vector-more-actions": "Label in the Vector skin's menu for the less-important or rarer actions which are not shown as tabs (like moving the page, or for sysops deleting or protecting the page), as well as (for users with a narrow viewing window in their browser) the less-important tab actions which the user's browser is unable to fit in. {{Identical|More}}",
        "namespaces": "{{Identical|Namespace}}",
        "variants": "Used by the Vector skin.",
        "navigation-heading": "Heading shown above the navigation menu (sidebar) for screen-readers (or in non-standard skins).",
        "talkpagelinktext": "Used as name of links going to talk page in some places, like in [[Special:RecentChanges]], [[Special:Allmessages]], [[Special:Logs]], and [[Special:Watchlist/edit]].\n\n{{Identical|Talk}}",
        "specialpage": "{{Identical|Special page}}",
        "personaltools": "Heading for a group of links to your user page, talk page, preferences, watchlist, and contributions. This heading is visible in the sidebar in some skins. For an example, see [{{canonicalurl:Main_Page|useskin=simple}} Main Page using simple skin].",
 -      "postcomment": "Used as link text.\n\nThe link points to the talk page and has the parameters \"action=edit&section=new\".",
        "addsection": "{{notranslate}}\nText of the new section tab (the one next to the \"edit\" tab on non-Vector skins).\n\nSee also:\n* {{msg-mw|Addsection}}\n* {{msg-mw|Accesskey-ca-addsection}}\n* {{msg-mw|Tooltip-ca-addsection}}",
        "articlepage": "'Content page' is used for NS_MAIN and any other non-standard namespaces. Only used in the Cologne Blue skin in the bottomLinks part.\n\n{{Identical|Content page}}",
        "talk": "Used as display name for the tab to all {{msg-mw|Talk}} pages. These pages accompany all content pages and can be used for discussing the content page. Example: [[Talk:Example]].\n\nSee also:\n* {{msg-mw|Talk}}\n* {{msg-mw|Accesskey-ca-talk}}\n* {{msg-mw|Tooltip-ca-talk}}\n{{Identical|Discussion}}",
        "hidetoc": "This is the link used to hide the table of contents\n\n{{Identical|Hide}}",
        "collapsible-collapse": "{{Doc-actionlink}}\nThis is the link used to collapse a collapsible element. (used as plaintext. No wikitext or html is parsed.)\n\nSee also:\n* {{msg-mw|Collapsible-expand}}\n{{Identical|Collapse}}",
        "collapsible-expand": "{{Doc-actionlink}}\nThis is the link used to expand a collapsible element (used as plaintext. No wikitext or html is parsed.)\n\nSee also:\n* {{msg-mw|Collapsible-collapse}}\n\nSee the following example:\n{{Identical|Expand}}",
 +      "confirmable-confirm": "Question asking the user to confirm a potentially uncancellable action.\n\"Yes\" and \"No\" buttons are displayed beside it.\n\nSee also:\n* {{msg-mw|confirmable-yes}}\n* {{msg-mw|confirmable-no}}",
 +      "confirmable-yes": "{{Doc-actionlink}}\nText of a button that will confirm triggering of a potentially uncancellable action.\n\nSee also:\n* {{msg-mw|confirmable-confirm}}\n* {{msg-mw|confirmable-no}}\n{{Identical|Yes}}",
 +      "confirmable-no": "{{Doc-actionlink}}\nText of a button that will cancel triggering of a potentially uncancellable action.\n\nSee also:\n* {{msg-mw|confirmable-confirm}}\n* {{msg-mw|confirmable-yes}}\n{{Identical|No}}",
        "thisisdeleted": "Message shown on a deleted page when the user has the undelete right. Parameters:\n* $1 - a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text\nSee also:\n* {{msg-mw|viewdeleted}}",
        "viewdeleted": "Message shown on a deleted page when the user does not have the undelete right (but has the deletedhistory right).\n\nParameters:\n* $1 - a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text\nSee also:\n* {{msg-mw|thisisdeleted}}",
        "restorelink": "This text is always displayed in conjunction with the {{msg-mw|thisisdeleted}} message (View or restore $1?). The user will see\nView or restore <nowiki>{{PLURAL:$1|one deleted edit|$1 deleted edits}}</nowiki>?    i.e ''View or restore one deleted edit?''     or\n''View or restore n deleted edits?''",
        "anonnotice": "{{notranslate}}",
        "newsectionheaderdefaultlevel": "{{notranslate}}\nParameters:\n* $1 - section name",
        "red-link-title": "Title for red hyperlinks. Indicates, that the page is empty, not written yet.\n\nParameters:\n* $1 - page title",
 -      "sort-descending": "JavaScript message. Used by sortable table script.",
 -      "sort-ascending": "JavaScript message. Used by sortable table script.",
 +      "sort-descending": "JavaScript message. Used by sortable table script.\n\nSee also:\n* {{msg-mw|Sort-ascending}}",
 +      "sort-ascending": "JavaScript message. Used by sortable table script.\n\nSee also:\n* {{msg-mw|Sort-descending}}\n{{Identical|Sort ascending}}",
        "nstab-main": "The name for the tab of the main namespace. Example: [[Example]]\n\nSee also:\n* {{msg-mw|Nstab-main}}\n* {{msg-mw|Accesskey-ca-nstab-main}}\n* {{msg-mw|Tooltip-ca-nstab-main}}\n{{Identical|Page}}",
        "nstab-user": "The name for the tab of the user namespace. Example: [[User:Example]]. It is possible to use <nowiki>{{GENDER:{{ROOTPAGENAME}}|male form|female form}}</nowiki> if needed.\n\nSee also:\n* {{msg-mw|Nstab-user}}\n* {{msg-mw|Accesskey-ca-nstab-user}}\n* {{msg-mw|Tooltip-ca-nstab-user}}\n{{Identical|User page}}",
        "nstab-media": "The name for the tab of the media namespace. Example: [[Media:Example]]\n\nSee also:\n* {{msg-mw|Nstab-media}}\n* {{msg-mw|Accesskey-ca-nstab-media}}\n* {{msg-mw|Tooltip-ca-nstab-media}}",
        "viewsource-title": "Page title shown when trying to edit a protected page. Parameters:\n* $1 - the name of the page",
        "actionthrottled": "This is the title of an error page. Read it in combination with {{msg-mw|actionthrottledtext}}.",
        "actionthrottledtext": "Used as error message. Read it in combination with {{msg-mw|actionthrottled}}.",
-       "protectedpagetext": "This message is displayed when trying to edit a page you can't edit because it has been protected.\n\nThe title for this message is {{msg-mw|Protectedpage}}.\n\nParameters:\n* $1 - (Unused) the raw name of the right which is needed to edit the page",
+       "protectedpagetext": "This message is displayed when trying to edit a page you can't edit because it has been protected.\n\nThe title for this message is {{msg-mw|Protectedpage}}.\n\nParameters:\n* $1 - (Unused) the raw name of the right which is needed to edit the page\n* $2 - (Unused) the action the user attempted to perform",
        "viewsourcetext": "The text shown when displaying the source of a page that the user has no permission to edit",
        "viewyourtext": "Same as {{msg-mw|viewsourcetext}} but when showing the text submitted by the user, this happens e.g. when the user was blocked while he is editing the page",
-       "protectedinterface": "Message shown if a user without the \"editinterface\" right tries to edit a page in the MediaWiki namespace.\n\nSee also {{msg-mw|editinginterface}}.",
+       "protectedinterface": "Message shown if a user without the \"editinterface\" right tries to edit a page in the MediaWiki namespace.\n\nSee also {{msg-mw|editinginterface}}. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "editinginterface": "A message shown when editing pages in the namespace MediaWiki:.\n\nSee also {{msg-mw|protectedinterface}}.",
-       "cascadeprotected": "Parameters:\n* $1 - number of cascade-protected pages, used for PLURAL\n* $2 - list of cascade-protected pages",
-       "namespaceprotected": "Parameters:\n* $1 - namespace name",
-       "customcssprotected": "Used as error message.",
-       "customjsprotected": "Used as error message.",
-       "mycustomcssprotected": "Used as error message.",
-       "mycustomjsprotected": "Used as error message.",
+       "cascadeprotected": "Parameters:\n* $1 - number of cascade-protected pages, used for PLURAL\n* $2 - list of cascade-protected pages\n* $3 - (Unused) the action the user attempted to perform",
+       "namespaceprotected": "Parameters:\n* $1 - namespace name\n* $2 - (Unused) the action the user attempted to perform",
+       "customcssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "customjsprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "mycustomcssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "mycustomjsprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "myprivateinfoprotected": "Used as error message.",
        "mypreferencesprotected": "Used as error message.",
        "ns-specialprotected": "Error message displayed when trying to edit a page in the Special namespace",
        "yourpasswordagain": "Since 1.22 no longer used in core, but may be used by some extensions. DEPRECATED",
        "createacct-yourpasswordagain": "In create account form, label for field to re-enter password\n\nSee example: [{{canonicalurl:Special:UserLogin|type=signup}} Special:UserLogin?type=signup]\n{{Identical|Confirm password}}",
        "createacct-yourpasswordagain-ph": "Placeholder text in create account form for re-enter password field.\n\nSee example: [{{canonicalurl:Special:UserLogin|type=signup}} Special:UserLogin?type=signup]",
 -      "remembermypassword": "Used as checkbox label in [[Special:UserLogin]]. Parameters:\n* $1 - number of days\n{{Identical|Remember my login on this computer}}",
 +      "remembermypassword": "Used as checkbox label on [[Special:ChangePassword]]. Parameters:\n* $1 - number of days\n{{Identical|Remember my login on this computer}}",
        "userlogin-remembermypassword": "The text for a check box in [[Special:UserLogin]].",
        "userlogin-signwithsecure": "Text of link to HTTPS login form.\n\nSee example: [[Special:UserLogin]]",
        "yourdomainname": "Used as label for listbox.",
        "externaldberror": "This message is thrown when a valid attempt to change the wiki password for a user fails because of a database error or an error from an external system.",
        "login": "{{Doc-special|UserLogin|unlisted=1}}\n{{Identical|Log in}}",
        "nav-login-createaccount": "Shown to anonymous users in the upper right corner of the page. When you can't create an account, the message {{msg-mw|login}} is shown.\n{{Identical|Log in / create account}}",
 -      "loginprompt": "A small notice in the log in form.",
 +      "loginprompt": "{{ignored}}",
        "userlogin": "Since 1.22 no longer used in core, but may still be used by extensions. DEPRECATED\n\n{{Identical|Log in / create account}}",
        "userloginnocreate": "Since 1.22 no longer used in core, but may still be used by some extensions. A variant of {{msg-mw|Userlogin}} when the user is not allowed to create a new account. DEPRECATED\n\n{{Identical|Log in}}",
        "logout": "Used as link text in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}\n{{Identical|Log out}}",
        "passwordreset-disabled": "Used as error message in changing password.",
        "passwordreset-emaildisabled": "Used as error message in changing password when site's email feature is disabled.",
        "passwordreset-username": "{{Identical|Username}}",
 -      "passwordreset-domain": "A domain like used in Domain Name System (DNS) or more specifically like a domain component in the Lightweight Directory Access Protocol (LDAP)",
 +      "passwordreset-domain": "A domain like used in Domain Name System (DNS) or more specifically like a domain component in the Lightweight Directory Access Protocol (LDAP).\n{{Identical|Domain}}",
        "passwordreset-capture": "Label for checkbox asking the user whether they want to see the contents of the password reset email (only shown if they have the <code>passwordreset</code> permission).",
        "passwordreset-capture-help": "Longer explanatory message for the capture checkbox label.",
        "passwordreset-email": "{{Identical|E-mail address}}",
        "preview": "The title of the Preview page shown after clicking the \"Show preview\" button in the edit page. Since this is a heading, it should probably be translated as a noun and not as a verb.\n\n{{Identical|Preview}}",
        "showpreview": "The text of the button to preview the page you are editing. See also {{msg-mw|showdiff}} and {{msg-mw|savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}\n{{Identical|Show preview}}",
        "showdiff": "Button below the edit page. See also {{msg-mw|Showpreview}} and {{msg-mw|Savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}\n{{Identical|Show change}}",
 +      "blankarticle": "Notice displayed once after the user tries to save an empty page.",
        "anoneditwarning": "Shown when editing a page anonymously.\nSee also:\n* {{msg-mw|Sf autoedit anoneditwarning}}\n* {{msg-mw|Wikibase-anonymouseditwarning-property}}\n* {{msg-mw|Wikibase-anonymouseditwarning-item}}\n* {{msg-mw|Anonpreviewwarning}}",
        "anonpreviewwarning": "See also:\n* {{msg-mw|Anoneditwarning}}",
        "missingsummary": "The text \"edit summary\" is in {{msg-mw|Summary}}.\n\nSee also:\n* {{msg-mw|Missingcommentheader}}\n* {{msg-mw|Savearticle}}",
        "rev-deleted-user": "See also:\n* {{msg-mw|Rev-deleted-event}}",
        "rev-deleted-event": "See also:\n* {{msg-mw|Rev-deleted-user}}",
        "rev-deleted-user-contribs": "Part of revision deletion.",
 -      "rev-deleted-text-permission": "{{Related|Rev-deleted-text}}",
 +      "rev-deleted-text-permission": "This message appears in case a user lacking permission tries to view a past deleted revision of a page, although later revisions of the page still exist.\n{{Related|Rev-deleted-text}}",
 +      "rev-suppressed-text-permission": "This message appears in case a user lacking permission tries to view a past suppressed revision of a page, although later revisions of the page still exist.\n{{Related|Rev-deleted-text}}",
        "rev-deleted-text-unhide": "Parameters:\n* $1 - a HTML link to the revision\n{{Related|Rev-deleted-text}}",
        "rev-suppressed-text-unhide": "Parameters:\n* $1 - a HTML link to the revision\n{{Related|Rev-deleted-text}}",
 -      "rev-deleted-text-view": "This is an error message which appears if a user tries to view a past revision of a page, where the revision has been hidden from view, although later revisions of the page still exist.",
 -      "rev-suppressed-text-view": "{{Related|Rev-deleted-text}}",
 +      "rev-deleted-text-view": "This message appears in case a user tries to view a past deleted revision of a page, although later revisions of the page still exist.\n{{Related|Rev-deleted-text}}",
 +      "rev-suppressed-text-view": "This message appears in case a user tries to view a past suppressed revision of a page, although later revisions of the page still exist.\n{{Related|Rev-deleted-text}}",
        "rev-deleted-no-diff": "See also:\n* {{msg-mw|Rev-suppressed-no-diff}}",
        "rev-suppressed-no-diff": "See also:\n* {{msg-mw|Rev-deleted-no-diff}}",
        "rev-deleted-unhide-diff": "Parameters:\n* $1 - a HTML link to the diff\n{{Related|Rev-deleted-diff}}",
        "mergehistory-empty": "Used in [[Special:MergeHistory]].",
        "mergehistory-success": "Used in [[Special:MergeHistory]].\n* $1 - target page title\n* $2 - destination page title\n* $3 - number of revisions which succeeded to merge",
        "mergehistory-fail": "Used as error message in [[Special:MergeHistory]].",
 +      "mergehistory-fail-toobig": "Used as error message in [[Special:MergeHistory]].\n* $1 - maximum allowed number of revisions that can be moved",
        "mergehistory-no-source": "Used as error message in [[Special:MergeHistory]].\n* $1 - source page title\nSee also:\n* {{msg-mw|mergehistory-invalid-source}}\n* {{msg-mw|mergehistory-invalid-destination}}\n* {{msg-mw|mergehistory-no-destination}}\n* {{msg-mw|mergehistory-same-destination}}",
        "mergehistory-no-destination": "Used as error message in [[Special:MergeHistory]].\n* $1 - destination page title\nSee also:\n* {{msg-mw|mergehistory-invalid-source}}\n* {{msg-mw|mergehistory-no-source}}\n* {{msg-mw|mergehistory-invalid-destination}}\n* {{msg-mw|mergehistory-same-destination}}",
        "mergehistory-invalid-source": "Used as error message in [[Special:MergeHistory]].\n\nSee also:\n* {{msg-mw|mergehistory-no-source}}\n* {{msg-mw|mergehistory-invalid-destination}}\n* {{msg-mw|mergehistory-no-destination}}\n* {{msg-mw|mergehistory-same-destination}}",
        "search-summary": "{{doc-specialpagesummary|search}}",
        "searchresults": "This is the title of the page that contains the results of a search.\n\n{{Identical|Search results}}",
        "searchresults-title": "Appears as page title in the html header of the search result special page.\n\nParameters:\n* $1 - the search term",
 -      "toomanymatches": "Used as section header in [[Special:Search]], when there are too many hits.",
        "titlematches": "Used as section header in [[Special:Search]].\n\nThis message is followed by search results.",
        "textmatches": "When displaying search results",
        "notextmatches": "Error message when there are no results",
        "searchprofile-advanced-tooltip": "Used as tooltip for the option {{msg-mw|Searchprofile-advanced}} in [[Special:Search]].\n\nSee also:\n* {{msg-mw|Searchprofile-advanced|message}}\n* {{msg-mw|Searchprofile-advanced-tooltip|tooltip}}",
        "search-result-size": "Shown per line of a [[Special:Search|search result]]\n* $1 - the size of the page in bytes, but no need to add \"byte\" or similar as the unit is added by special function\n* $2 - the sum of all words in this page",
        "search-result-category-size": "Parameters:\n* $1 - number of members in this category. $1 is equal to $2+$3.\n* $2 - number of subcategories\n* $3 - number of files",
 -      "search-result-score": "Shown per line of a [[Special:Search|search result]]. Parameters:\n* $1 - the relevance of this result in percent\n{{Identical|Relevance: $1%}}",
        "search-redirect": "\"Redirect\" is a noun here, not a verb.\n\nParameters:\n* $1 - a link to the redirect to the page (so, $1 is the page that the search result is redirected '''from''')",
        "search-section": "This text will be shown on the search result listing after the page title of a result if the search algorithm thinks that section is more relevant than the rest of the page. $1 is a section title.\n{{Identical|Section}}",
        "search-file-match": "This text will be shown on the search result listing after the page title of a result if the search engine got search results from the contents of files, rather than the pages.",
        "searchall": "{{Identical|All}}",
        "showingresults": "This message is used on some special pages such as [[Special:WantedCategories]]. Parameters:\n* $1 - the total number of results in the batch shown\n* $2 - the number of the first item listed\nSee also:\n* {{msg-mw|Showingresultsnum}}",
        "showingresultsinrange": "Used in pagination of [[Special:MostLinkedCategories]]. Parameters:\n* $1 - the total number of results in the batch shown\n* $2 - the number of the first item listed\n* $3 - the number of last item in the batch shown\n\nSee also {{msg-mw|Showingresults}}",
 -      "showingresultsnum": "Parameters:\n* $1 - (Unused) the total number of results in the batch shown\n* $2 - the first number in the batch of results\n* $3 - the number of results on the page\nSee also:\n* {{msg-mw|Showingresults}}",
        "showingresultsheader": "Used in search results of [[Special:Search]]. Parameters:\n* $1 - minimum offset\n* $2 - maximum offset\n* $3 - total number of results\n* $4 - the search term\n* $5 - number of results",
        "search-nonefound": "Message shown when a search returned no results (when using the default MediaWiki search engine).",
        "powersearch-legend": "Advanced search\n\n{{Identical|Advanced search}}",
        "preferences-summary": "{{doc-specialpagesummary|preferences}}",
        "mypreferences": "Action link label that leads to [[Special:Preferences]]; appears in the top menu (e.g. \"Username Talk Preferences Watchlist Contributions Log out\").\n\nSee also:\n* {{msg-mw|Mypreferences}}\n* {{msg-mw|Accesskey-pt-preferences}}\n* {{msg-mw|Tooltip-pt-preferences}}\n{{Identical|Preferences}}",
        "prefs-edits": "In user preferences.",
 -      "prefsnologintext2": "Parameters:\n* $1 - a link to [[Special:UserLogin]] with {{msg-mw|loginreqlink}} as link description",
 +      "prefsnologintext2": "Showed on Special:Userlogin when user tries to access their preferences before logging in",
        "prefs-skin": "Used in user preferences.\n{{Identical|Skin}}",
        "skin-preview": "{{doc-actionlink}}\nThe link beside each skin name in [[Special:Preferences|your user preferences]], tab \"skin\".\n{{Identical|Preview}}",
        "datedefault": "Used as checkbox label in [[Special:Preferences#mw-prefsection-datetime|user preferences]], {{msg-mw|prefs-datetime}} tab.\n\nThis message indicates {{msg-mw|prefs-dateformat}} is default (= not specified).",
        "prefs-labs": "Header of a subsection at [[Special:Preferences]], tab ''{{int:prefs-editing}}'', listing features that are experimental",
 -      "prefs-user-pages": "Header of a subsection at [[Special:Preferences]], tab ''{{int:prefs-misc}}'', listing features that are related to user pages",
 +      "prefs-user-pages": "Header of a subsection at [[Special:Preferences]], tab ''{{int:prefs-misc}}'', listing features that are related to user pages\n{{Identical|User page}}",
        "prefs-personal": "Title of a tab in [[Special:Preferences]].\n{{Identical|User profile}}",
        "prefs-rc": "Used in user preferences.\n\n{{Identical|Recent changes}}",
        "prefs-watchlist": "Used in user preferences.\n{{Identical|Watchlist}}",
        "group-suppress-member": "{{doc-group|suppress|member}}\nThis is a member of the optional (disabled by default) user group, meant for the [[mw:RevisionDelete|RevisionDelete]] feature, to change the visibility of revisions through [[Special:RevisionDelete]].\n\n{{Identical|Oversight}}",
        "grouppage-user": "{{doc-group|user|page}}",
        "grouppage-autoconfirmed": "{{doc-group|autoconfirmed|page}}",
 -      "grouppage-bot": "{{doc-group|bot|page}}",
 +      "grouppage-bot": "{{doc-group|bot|page}}\n{{Identical|Bot}}",
        "grouppage-sysop": "{{doc-group|sysop|page}}",
        "grouppage-bureaucrat": "{{doc-group|bureaucrat|page}}",
        "grouppage-suppress": "{{doc-group|suppress|page}}\n{{Identical|Oversight}}",
        "right-deletedtext": "{{doc-right|deletedtext}}",
        "right-browsearchive": "{{doc-right|browsearchive}}",
        "right-undelete": "{{doc-right|undelete}}",
 -      "right-suppressrevision": "{{doc-right|suppressrevision}}\nThis user right is part of the [[mw:RevisionDelete|RevisionDelete]] feature.\nIt can be given to the group {{msg-mw|group-suppress}}, although that group is disabled by default.\n\nSee also:\n* {{msg-mw|right-suppressionlog}}\n* {{msg-mw|right-hideuser}}\n* {{msg-mw|right-deletelogentry}}\n* {{msg-mw|right-deleterevision}}",
 +      "right-suppressrevision": "{{doc-right|suppressrevision}}\nThis user right is part of the [[mw:RevisionDelete|RevisionDelete]] feature.\nIt can be given to the group {{msg-mw|group-suppress}}, although that group is disabled by default.\n\nSee also:\n* {{msg-mw|right-suppressionlog}}\n* {{msg-mw|right-viewsuppressed}}\n* {{msg-mw|right-hideuser}}\n* {{msg-mw|right-deletelogentry}}\n* {{msg-mw|right-deleterevision}}",
 +      "right-viewsuppressed": "{{doc-right|viewsuppressed}}\nThis user right is part of the [[mw:RevisionDelete|RevisionDelete]] feature.\nIt can be given to any group for observation of suppression activities.\n\nSee also:\n* {{msg-mw|right-suppressrevision}}",
        "right-suppressionlog": "{{doc-right|suppressionlog}}\nThis user right is part of the [[mw:RevisionDelete|RevisionDelete]] feature.\nIt can be given to the group {{msg-mw|group-suppress}}, although that group is disabled by default.\n\nSee also\n* {{msg-mw|right-suppressrevision}}\n* {{msg-mw|right-hideuser}}\n* {{msg-mw|right-deletelogentry}}\n* {{msg-mw|right-deleterevision}}",
        "right-block": "{{doc-right|block}}",
        "right-blockemail": "{{doc-right|blockemail}}",
        "recentchanges-label-unpatrolled": "Tooltip for {{msg-mw|unpatrolledletter}}",
        "recentchanges-label-plusminus": "Legend item for plus/minus.\n\nPreceded by legend example {{msg-mw|Recentchanges-legend-plusminus}}.",
        "recentchanges-legend-heading": "Used as a heading for legend box on [[Special:RecentChanges]] and [[Special:Watchlist]].\n{{Identical|Legend}}",
 -      "recentchanges-legend-newpage": "Used as legend in [[Special:RecentChanges]]. Preceded by {{msg-mw|Recentchanges-label-newpage}}.",
 +      "recentchanges-legend-newpage": "{{doc-important|Do not translate <code>Special:NewPages</code>.}}\nUsed as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-newpage}}.",
 +      "recentchanges-legend-minor": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-minor}}.",
 +      "recentchanges-legend-bot": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-bot}}.",
 +      "recentchanges-legend-unpatrolled": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-unpatrolled}}.",
        "recentchanges-legend-plusminus": "{{optional}}\nA plus/minus sign with a number for the legend.",
 -      "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}} (split into date and time).\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - a date and time\n* $3 - (Optional) a date\n* $4 - (Optional) a time",
 +      "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}}.\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - (Optional) a date and time\n* $3 - a date\n* $4 - a time\n* $5 - Number of changes are displayed, for use with PLURAL",
        "rclistfrom": "Used on [[Special:RecentChanges]]. Parameters:\n* $1 - (Currently not use) date and time. The date and the time adds to the rclistfrom description.\n* $2 - time. The time adds to the rclistfrom link description (with split of date and time).\n* $3 - date. The date adds to the rclistfrom link description (with split of date and time).\n\nThe corresponding message is {{msg-mw|Rcnotefrom}}.",
        "rcshowhideminor": "Option text in [[Special:RecentChanges]]. Parameters:\n* $1 - the \"show/hide\" command, with the text taken from either {{msg-mw|rcshowhideminor-show}} or {{msg-mw|rcshowhideminor-hide}}\n{{Identical|Minor edit}}",
        "rcshowhideminor-show": "{{doc-actionlink}}\nOption text in [[Special:RecentChanges]] in conjunction with {{msg-mw|rcshowhideminor}}.\n\nSee also:\n* {{msg-mw|rcshowhideminor-hide}}\n{{Identical|Show}}",
        "uploadwarning": "Used as section header in [[Special:Upload]].",
        "uploadwarning-text": "Used in [[Special:Upload]].",
        "savefile": "When uploading a file",
 -      "uploadedimage": "This is the text of an entry in the [[Special:Log|upload log]] (and Recent Changes), after hour (and date, only in the Upload log) and user name. $1 is the name of the file uploaded.",
 -      "overwroteimage": "This is the text of an entry in the [[Special:Log|upload log]] (and Recent Changes), after hour (and date, only in the Upload log) and user name. $1 is the name of the file uploaded.",
 +      "uploadedimage": "{{ignored}}This is ''logentry'' message only used on IRC. $1 is the name of the file uploaded.",
 +      "overwroteimage": "{{ignored}}This is ''logentry'' message only used on IRC. $1 is the name of the file uploaded.",
        "uploaddisabled": "Title of the [[Special:Upload]] page when upload is disabled.\n\nSee also:\n* {{msg-mw|Copyuploaddisabled}}",
        "copyuploaddisabled": "See also:\n* {{msg-mw|Uploaddisabled}}",
        "uploaddisabledtext": "Parameters:\n* $1 - (Optional) the name of the target file. See r22243 and [[bugzilla:8818|bug 8818]].",
        "license-header": "Used as section header in [[Special:Upload]].\n\nSee also:\n* {{msg-mw|Filedesc}}\n* {{msg-mw|Filestatus}}\n* {{msg-mw|Filesource}}\n{{Identical|Licensing}}",
        "nolicense": "{{Identical|None selected}}",
        "licenses": "{{notranslate}}",
 +      "licenses-edit": "Label text for a link on Special:Upload to edit MediaWiki:Licenses",
        "license-nopreview": "Error message when a certain license does not exist",
        "upload_source_url": "Used in [[Special:Upload]].\n\nSee also:\n* {{msg-mw|Sourcefilename|label}}\n* {{msg-mw|Sourceurl|label}}\n* {{msg-mw|Upload source file}}\n* {{msg-mw|Upload-maxfilesize}}",
        "upload_source_file": "Used in [[Special:Upload]].\n\nSee also:\n* {{msg-mw|Sourcefilename|label}}\n* {{msg-mw|Sourceurl|label}}\n* {{msg-mw|Upload source url}}\n* {{msg-mw|Upload-maxfilesize}}",
 +      "listfiles-delete": "Text of the delete links next to the entries on [[Special:ListFiles]], surrounded by parentheses.\n{{Identical|Delete}}",
        "listfiles-summary": "This message is displayed at the top of [[Special:ImageList]] to explain how to use that special page.",
        "listfiles_search_for": "Input label for the form displayed on [[Special:ListFiles]].",
        "imgfile": "{{Identical|File}}",
        "nrevisions": "Used as link text in [[Special:FewestRevisions]].\n\nThe link points to the page history (action=history).\n\nParameters:\n* $1 - number of revisions",
        "nviews": "This message is used on [[Special:PopularPages]] to say how many times each page has been viewed.\n\nPreceded by the page title, like: Page title ($1 views)\n\nParameters:\n* $1 - the number of views",
        "nimagelinks": "Used on [[Special:MostLinkedFiles]] to indicate how often a specific file is used.\n\nParameters:\n* $1 - number of pages\nSee also:\n* {{msg-mw|Ntransclusions}}",
 -      "ntransclusions": "Used on [[Special:MostLinkedTemplates]] to indicate how often a template is in use.\n\nParameters:\n* $1 - number of pages\nSee also:\n* {{msg-mw|Nimagelinks}}",
 +      "ntransclusions": "Used on [[Special:MostTranscludedPages]] to indicate how often a template is in use.\n\nParameters:\n* $1 - number of pages\nSee also:\n* {{msg-mw|Nimagelinks}}",
        "specialpage-empty": "Used on a special page when there is no data. For example on [[Special:Unusedimages]] when all images are used.",
        "lonelypages": "{{doc-special|LonelyPages}}",
        "lonelypages-summary": "{{doc-specialpagesummary|lonelypages}}",
        "popularpages-summary": "{{doc-specialpagesummary|popularpages}}",
        "wantedcategories": "{{doc-special|WantedCategories}}",
        "wantedcategories-summary": "{{doc-specialpagesummary|wantedcategories}}",
 -      "wantedpages": "{{doc-special|WantedPages}}",
 +      "wantedpages": "{{doc-special|WantedPages}}\n{{Identical|Wanted page}}",
        "wantedpages-summary": "{{doc-specialpagesummary|wantedpages}}",
        "wantedpages-badtitle": "Error message shown when [[Special:WantedPages]] is listing a page with a title that shouldn't exist.\n\nParameters:\n* $1 - a page title",
        "wantedfiles": "{{doc-special|WantedFiles}}",
        "wantedfiles-summary": "{{doc-specialpagesummary|wantedfiles}}",
 -      "wantedfiletext-cat": "Message displayed at top of [[special:WantedFiles]]. $1 contains the name of the tracking category for broken files (Including Category prefix). {{msg-mw|wantedfiletext-nocat}} is used if the tracking category is disabled.",
 -      "wantedfiletext-nocat": "Message displayed at top of [[special:WantedFiles]] when broken file tracking category is disabled. See {{msg-mw|wantedfiletext-cat}}.",
 +      "wantedfiletext-cat": "Message displayed at top of [[special:WantedFiles]] when false positives from foreign file repositories (like commons) are likely. $1 contains the name of the tracking category for broken files (Including Category prefix). {{msg-mw|wantedfiletext-nocat}} is used if the tracking category is disabled.\n\nSee also: {{msg-mw|wantedfiletext-cat-noforeign}}, {{msg-mw|wantedfiletext-nocat}}",
 +      "wantedfiletext-cat-noforeign": "Message displayed at top of [[Special:WantedFiles]] when the wiki has no foreign repositories. See also {{msg-mw|wantedfilestext-cat}}. $1 contains the name of the tracking category for broken files (Including Category prefix). {{msg-mw|wantedfiletext-nocat}} is used if the tracking category is disabled.",
 +      "wantedfiletext-nocat": "Message displayed at top of [[special:WantedFiles]] when broken file tracking category is disabled and false positives from foreign file repositories (like commons) are likely. See {{msg-mw|wantedfiletext-cat}}.",
 +      "wantedfiletext-nocat-noforeign": "Message displayed at top of [[special:WantedFiles]] when broken file tracking category is disabled and their are no foreign file repositories enabled on the wiki. See {{msg-mw|wantedfiletext-cat}}, {{msg-mw|wantedfiletext-nocat}}.",
        "wantedtemplates": "{{doc-special|WantedTemplates}}",
        "wantedtemplates-summary": "{{doc-specialpagesummary|wantedtemplates}}",
        "mostlinked": "{{doc-special|MostLinked}}",
        "mostlinked-summary": "{{doc-specialpagesummary|mostlinked}}",
        "mostlinkedcategories": "{{doc-special|MostLinkedCategories}}",
        "mostlinkedcategories-summary": "{{doc-specialpagesummary|mostlinkedcategories}}",
 -      "mostlinkedtemplates": "{{doc-special|MostLinkedTemplates}}",
 +      "mostlinkedtemplates": "{{doc-special|MostTranscludedPages}}",
        "mostlinkedtemplates-summary": "{{doc-specialpagesummary|mostlinkedtemplates}}",
        "mostcategories": "{{doc-special|MostCategories}}",
        "mostcategories-summary": "{{doc-specialpagesummary|mostcategories}}",
        "categoriespagetext": "{{doc-important|Do not translate or change links.}}\nText displayed in [[Special:Categories]].\n\nIn order to translate \"Unused categories\" and \"wanted categories\" see {{msg-mw|Unusedcategories}} and {{msg-mw|Wantedcategories}}.\n\nParameters:\n* $1 - number of categories",
        "categoriesfrom": "Used as label for the input box in [[Special:Categories]].\n\nThis message follows the fieldset label {{msg-mw|categories}}, and is followed by the input box.",
        "special-categories-sort-count": "Commented out at this time.\n\nThis message is used on [[Special:Categories]] to sort the list by the number of members in the categories.\n\nSee also:\n* {{msg-mw|Special-categories-sort-abc}}",
 -      "special-categories-sort-abc": "Commented out at this time.\n\nThis message is used on [[Special:Categories]] to sort the list by the category name.\n\nSee also:\n* {{msg-mw|Special-categories-sort-count}}",
 +      "special-categories-sort-abc": "Commented out at this time.\n\nThis message is used on [[Special:Categories]] to sort the list by the category name.\n\nSee also:\n* {{msg-mw|Special-categories-sort-count}}\n{{Identical|Sort alphabetically}}",
        "deletedcontributions": "The message is shown as a link on [[Special:SpecialPages]] to [[Special:DeletedContributions]].\n\n{{Identical|Deleted user contributions}}",
        "deletedcontributions-summary": "{{doc-specialpagesummary|deletedcontributions}}",
        "deletedcontributions-title": "Title of [[Special:DeletedContributions]] (extension), a special page with a list of edits to pages which were deleted. Only viewable by sysops.\n\n{{Identical|Deleted user contributions}}",
        "mywatchlist": "Link at the upper right corner of the screen.\n\nSee also:\n* {{msg-mw|Mywatchlist}}\n* {{msg-mw|Accesskey-pt-watchlist}}\n* {{msg-mw|Tooltip-pt-watchlist}}\n{{Identical|Watchlist}}",
        "watchlistfor2": "Subtitle on [[Special:Watchlist]].\nParameters:\n* $1 - Username of current user\n* $2 - Tool links (View relevant changes | View and edit watchlist | Edit raw watchlist)\n{{Identical|For $1}}",
        "nowatchlist": "Displayed when there is no pages in the watchlist.",
 -      "watchlistanontext": "Parameters:\n* $1 - a link to [[Special:UserLogin]] with {{msg-mw|loginreqlink}} as link description",
 +      "watchlistanontext": "Shown on Special:Userlogin when user tries to access their watchlist before logging in",
        "watchnologin": "Used as error page title.\n\nThe error message for this title is:\n* {{msg-mw|Watchnologintext}}\n{{Identical|Not logged in}}",
        "addwatch": "Link to a dialog box, displayed at the end of the list of categories at the foot of each page.\n\nSee also:\n* {{msg-mw|Removewatch}}",
        "addedwatchtext": "Explanation shown when clicking on the {{msg-mw|Watch}} tab. Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Addedwatch}}",
        "watchlist-details": "Message on [[Special:Watchlist]]. Parameters:\n* $1 - number of pages in your watchlist\nThis is paired with the message {{msg-mw|Nowatchlist}} which appears instead of Watchlist-details when $1 is 0.\nSee also:\n* {{msg-mw|Watchlist-options|fieldset}}\n* {{msg-mw|Wlheader-enotif|watchlist header}}\n* {{msg-mw|enotif reset|Submit button text}}\n* {{msg-mw|Watchlistcontains}}",
        "wlheader-enotif": "Message at the top of [[Special:Watchlist]], after {{msg-mw|watchlist-details}}. Has to be a full sentence.\n\nSee also:\n* {{msg-mw|Watchlist-options|fieldset}}\n* {{msg-mw|enotif reset|Submit button text}}",
        "wlheader-showupdated": "Message at the top of [[Special:Watchlist]], after {{msg-mw|watchlist-details}}. Has to be a full sentence.",
 -      "wlnote2": "Used on [[Special:Watchlist]] when a maximum number of hours or days is specified.\n\nParameters:\n* $1 - the number of hours for which the changes are shown\n* $2 - a date alone\n* $3 - a time alone\nSee also:\n* {{msg-mw|Wlnote}}",
 +      "wlnote": "Used on [[Special:Watchlist]] when a maximum number of hours or days is specified.\n\nParameters:\n* $1 - the number of changes shown\n* $2 - the number of hours for which the changes are shown\n* $3 - a date alone\n* $4 - a time alone",
        "wlshowlast": "Appears on [[Special:Watchlist]]. Parameters:\n* $1 - a choice of different numbers of hours (\"1 | 2 | 6 | 12\")\n* $2 - a choice of different numbers of days (\"1 | 3 | 7\")\n* $3 - {{msg-mw|watchlistall2}}\nClicking on your choice changes the list of changes you see (without changing the default in my preferences).",
        "watchlist-options": "Legend of the fieldset of [[Special:Watchlist]]\n\nSee also:\n* {{msg-mw|Watchlist-details|watchlist header}}\n* {{msg-mw|Wlheader-enotif|watchlist header}}\n* {{msg-mw|enotif reset|Submit button text}}",
        "watching": "Text displayed when clicked on the watch tab: {{msg-mw|Watch}}. It means the wiki is adding that page to your watchlist.",
        "excontent": "Automated deletion reason when deleting a page for admins. Parameters:\n* $1 - content before deletion",
        "excontentauthor": "Automated deletion reason when deleting a page for admins providing that the page has one author only.\n\nParameters:\n* $1 - content before deletion\n* $2 - username",
        "exbeforeblank": "Automated deletion reason when deleting a page for admins providing that the page was blanked before deletion.\n\nParameters:\n* $1 - content before blanking",
 -      "delete-confirm": "Used as page title. Parameters:\n* $1 - the page title",
 +      "delete-confirm": "Used as page title. Parameters:\n* $1 - the page title\n{{Identical|Delete}}",
        "delete-legend": "{{Identical|Delete}}",
        "historywarning": "Warning when about to delete a page that has history.\n\nFollowed by a link which points to the history page.\n\nParameters:\n* $1 - the <b>approximate</b> number of revisions that the page has, the message should not claim to give an exact count",
        "confirmdeletetext": "Introduction shown when deleting a page.\n\nRefers to {{msg-mw|Policy-url}}.",
        "delete-edit-reasonlist": "Shown beneath the page deletion form on the right side. It is a link to {{msg-mw|Deletereason-dropdown|notext=1}}.\n\nSee also:\n* {{msg-mw|Ipb-edit-dropdown}}\n* {{msg-mw|Protect-edit-reasonlist}}.\n{{Identical|Edit delete reasons}}",
        "delete-toobig": "Parameters:\n* $1 - the upper limit of number of revisions\nSee also:\n* {{msg-mw|Delete-warning-toobig}}",
        "delete-warning-toobig": "Parameters:\n* $1 - the upper limit of number of revisions\nSee also:\n* {{msg-mw|Delete-toobig}}",
 +      "delete-cantedit": "Used as error message when deleting the page.",
        "deleting-backlinks-warning": "A warning shown when a page that is being deleted has at least one link to it or is transcluded in at least one page.",
        "rollback": "{{Identical|Rollback}}",
        "rollback_short": "{{Identical|Rollback}}",
        "protect-summary-cascade": "Used in edit summary when cascade protecting a page. Appears in protection log. See [[Special:Log]] and [[m:Special:Log]].\n\nAlso used in [[Special:ProtectedPages]] when a page is cascade protected. See example: [[m:Special:ProtectedPages]].<br />\nSee also:\n*{{msg-mw|Restriction-level-sysop}}\n*{{msg-mw|Restriction-level-autoconfirmed}}",
        "protect-expiring": "Used as expiry text in page history, and in [[Special:Protectedtitles]], [[Special:Protectedpages]], and extension FlaggedRevs.\n* $1 - a date and time\n* $2 - a date (optional)\n* $3 - a time (optional)\nIf the expiry is indefinite, {{msg-mw|protect-expiry-indefinite}} is used.\n{{Identical|Expires $1 (UTC)}}",
        "protect-expiring-local": "Parameter:\n* $1 - a timestamp like \"22:51, 23 July 2011 (UTC)\" depending on the wiki content language.\n{{Identical|Expire}}",
 -      "protect-expiry-indefinite": "Used as expiry text in page history, and in [[Special:Protectedtitles]], [[Special:Protectedpages]], and extension FlaggedRevs.\n\nIf the expiry is definite, {{msg-mw|protect-expiring}} is used.",
 +      "protect-expiry-indefinite": "Used as expiry text in page history, and in [[Special:Protectedtitles]], [[Special:Protectedpages]], and extension FlaggedRevs.\n\nIf the expiry is definite, {{msg-mw|protect-expiring}} is used.\n{{Identical|Indefinite}}",
        "protect-cascade": "See [[meta:Protect]] for more information.",
        "protect-cantedit": "Used as error message when changing the protection levels of the page.",
        "protect-othertime": "Used on the page protection form as label for the following input field (text)\n{{Identical|Other time}}",
        "block": "{{doc-special|Block}}\n{{Identical|Block user}}",
        "unblock": "{{doc-special|Unblock}}",
        "unblock-summary": "{{doc-specialpagesummary|unblock}}",
 -      "blockip": "Used as the text of a link in the sidebar toolbox. Clicking this link takes you to [[Special:Block]], with a relevant username or IP address (e.g. \"Username\" on [[User talk:Username]], [[Special:Contributions/Username]], etc.) already filled in.\n\n{{Identical|Block user}}",
 +      "blockip": "Used as the text of a link in the sidebar toolbox. Clicking this link takes you to [[Special:Block]], with a relevant username or IP address (e.g. \"Username\" on [[User talk:Username]], [[Special:Contributions/Username]], etc.) already filled in.\n\nParameters:\n* $1 - username, for GENDER support\n{{Identical|Block user}}",
        "blockip-legend": "Legend/Header for the fieldset around the input form of [[Special:Block]].\n\n{{Identical|Block user}}",
        "blockiptext": "Used in the {{msg-mw|Blockip}} form in [[Special:Block]].\n\nRefers to {{msg-mw|Policy-url}}.\n\nThis message may follow the message {{msg-mw|Ipb-otherblocks-header}} and other block messages.\n\nSee also:\n* {{msg-mw|Unblockiptext}}",
        "ipaddressorusername": "{{Identical|IP address or username}}",
        "importlogpage": "{{doc-logpage}}",
        "importlogpagetext": "This text appears at the top of the [{{canonicalurl:Special:Log|type=import}} import log] special page.",
        "import-logentry-upload": "This is the text of an entry in the Import log (and Recent Changes), after hour (and date, only in the Import log) and sysop name:\n* $1 is the name of the imported file",
 -      "import-logentry-upload-detail": "Used as success message. Parameters:\n* $1 - number of succeeded revisions\nSee also:\n* {{msg-mw|Import-logentry-interwiki-detail}}",
 +      "import-logentry-upload-detail": "Used as success message and log entry. Parameters:\n* $1 - number of succeeded revisions\nSee also:\n* {{msg-mw|Import-logentry-interwiki-detail}}",
        "import-logentry-interwiki": "Used as action listed in the log. Parameters:\n* $1 - page title",
 -      "import-logentry-interwiki-detail": "Used as success message. Parameters:\n* $1 - number of succeeded revisions\n* $2 - interwiki name\nSee also:\n* {{msg-mw|Import-logentry-upload-detail}}",
 +      "import-logentry-interwiki-detail": "Used as success message and log entry. Parameters:\n* $1 - number of succeeded revisions\n* $2 - interwiki name\nSee also:\n* {{msg-mw|Import-logentry-upload-detail}}",
        "javascripttest": "Title of the special page [[Special:JavaScriptTest]].\n\nSee also:\n* {{msg-mw|Javascripttest|title}}\n* {{msg-mw|Javascripttest-pagetext-noframework|summary}}\n* {{msg-mw|Javascripttest-pagetext-unknownframework|error message}}",
        "javascripttest-backlink": "{{optional}}\nUsed as subtitle in [[Special:JavaScriptTest]]. Parameters:\n* $1 - page title",
        "javascripttest-title": "Title of the special page when running a test suite. Parameters:\n* $1 is the name of the framework, for example QUnit.",
        "tooltip-summary": "Used as tooltip for Summary input box in Editor page.\n\nSee also:\n* {{msg-mw|Summary}}\n* {{msg-mw|Accesskey-summary}}\n* {{msg-mw|Tooltip-summary}}",
        "interlanguage-link-title": "{{Optional}}\nFormat of a sidebar interwiki link tooltip. Parameters:\n* $1 - page name in the target wiki\n* $2 - target wiki language autonym",
        "interlanguage-link-title-langonly": "{{ignored}}Interlanguage link title. Parameters: $1 replaced with a language name.",
 +      "interlanguage-link-title-nonlang": "{{Optional}}\nFormat of a tooltip for a sidebar interwiki link that points to a specific project. Parameters:\n* $1 - page name in the target wiki\n* $2 - name of the target wiki (probably not a language name)",
 +      "interlanguage-link-title-nonlangonly": "{{ignored}}Interlanguage link title. Parameters: $1 replaced with name of the target wiki (probably not a language name).",
        "common.css": "{{optional}}\nCSS applied to all users.",
 -      "monobook.css": "{{optional}}\nCSS applied to users using Monobook skin.",
 -      "vector.css": "{{optional}}",
        "print.css": "{{optional}}",
        "noscript.css": "{{optional}}",
        "group-autoconfirmed.css": "{{doc-group|autoconfirmed|css}}",
        "group-sysop.css": "{{doc-group|sysop|css}}",
        "group-bureaucrat.css": "{{doc-group|bureaucrat|css}}",
        "common.js": "{{optional}}\nJS for all users.",
 -      "monobook.js": "{{optional}}\nJS for users using Monobook skin.",
 -      "vector.js": "{{optional}}",
        "group-autoconfirmed.js": "{{doc-group|autoconfirmed|js}}",
        "group-user.js": "{{doc-group|user|js}}",
        "group-bot.js": "{{doc-group|bot|js}}",
        "pageinfo-category-pages": "See also:\n* {{msg-mw|Pageinfo-category-subcats}}\n* {{msg-mw|Pageinfo-category-files}}",
        "pageinfo-category-subcats": "See also:\n* {{msg-mw|Pageinfo-category-pages}}\n* {{msg-mw|Pageinfo-category-files}}",
        "pageinfo-category-files": "See also:\n* {{msg-mw|Pageinfo-category-pages}}\n* {{msg-mw|Pageinfo-category-subcats}}",
 -      "skinname-monobook": "{{optional}}",
 -      "skinname-vector": "{{optional}}",
        "markaspatrolleddiff": "{{doc-actionlink}}\nSee also:\n* {{msg-mw|Markaspatrolledtext}}\n{{Identical|Mark as patrolled}}",
        "markaspatrolledlink": "{{notranslate}}\nParameters:\n* $1 - link which has text {{msg-mw|Markaspatrolledtext}}",
        "markaspatrolledtext": "{{doc-actionlink}}\nSee also:\n* {{msg-mw|Markaspatrolleddiff}}",
        "days-abbrev": "{{optional}}\nAbbreviation for \"days\". $1 is the number of days.\n\nSee also {{msg-mw|days}}",
        "seconds": "Full word for \"seconds\". $1 is the number of seconds.\n\nSee also {{msg-mw|seconds-abbrev}}, {{msg-mw|seconds-ago}}.\n{{Identical|Second}}",
        "minutes": "Full word for \"minutes\". $1 is the number of minutes.\n\nSee also {{msg-mw|minutes-abbrev}}, {{msg-mw|minutes-ago}}.\n\n{{Identical|Minute}}",
 -      "hours": "Full word for \"hours\". $1 is the number of hours.\n\nSee also {{msg-mw|hours-abbrev}}, {{msg-mw|hours-ago}}.",
 +      "hours": "Full word for \"hours\". $1 is the number of hours.\n\nSee also {{msg-mw|hours-abbrev}}, {{msg-mw|hours-ago}}.\n{{Identical|Hour}}",
        "days": "Full word for \"days\". $1 is the number of days.\n\nSee also {{msg-mw|Days-abbrev}}\n\n{{Identical|Day}}",
 -      "weeks": "Full word for \"weeks\". Parameters:\n* $1 is the number of weeks",
 -      "months": "Full word for \"months\". $1 is the number of months.",
 -      "years": "Full word for \"years\".\n\nParameters:\n* $1 - the number of years",
 +      "weeks": "Full word for \"weeks\". Parameters:\n* $1 is the number of weeks\n{{Identical|Week}}",
 +      "months": "Full word for \"months\".\n* $1 - the number of months.\n{{Identical|Month}}",
 +      "years": "Full word for \"years\".\n\nParameters:\n* $1 - the number of years\n{{Identical|Year}}",
        "ago": "Phrase for indicating how long ago something happened. Parameters:\n* $1 - some kind of timestamp\n{{Identical|Ago}}",
 -      "just-now": "Phrase for indicating something happened just now.",
 +      "just-now": "Phrase for indicating something happened just now.\n{{Identical|Just now}}",
        "hours-ago": "Phrase for indicating that something occurred a certain number of hours ago.\n\nParameters:\n* $1 - number of hours",
        "minutes-ago": "Phrase for indicating that something occurred a certain number of minutes ago.\n\nParameters:\n* $1 - number of minutes",
        "seconds-ago": "Phrase for indicating that something occurred a certain number of seconds ago.\n\nParameters:\n* $1 - number of seconds",
        "exif-meteringmode-2": "{{Related|Exif-meteringmode}}",
        "exif-meteringmode-3": "{{Related|Exif-meteringmode}}",
        "exif-meteringmode-4": "{{Related|Exif-meteringmode}}",
 -      "exif-meteringmode-5": "{{Related|Exif-meteringmode}}",
 +      "exif-meteringmode-5": "{{Related|Exif-meteringmode}}\n{{Identical|Pattern}}",
        "exif-meteringmode-6": "{{Related|Exif-meteringmode}}",
        "exif-meteringmode-255": "{{Identical|Other}}",
        "exif-lightsource-0": "{{Identical|Unknown}}\n{{Related|Exif-lightsource}}",
        "autosumm-replace": "The auto summary when a user removes a lot of characters in the page.\n\nParameters:\n* $1 - truncated text",
        "autoredircomment": "The auto summary when making a redirect. Parameters:\n* $1 - the page where it redirects to\n* $2 - (Optional) the first X number of characters of the redirect ($2 is usually only used when end users customize the message)",
        "autosumm-new": "The auto summary when creating a new page. $1 are the first X number of characters of the new page.",
 +      "autosumm-newblank": "The automatic edit summary when creating a blank page. This is not the same as blanking a page.",
        "autoblock_whitelist": "{{notranslate}}",
        "size-bytes": "{{optional}}\nSize (of a page, typically) in bytes.",
        "size-kilobytes": "{{optional}}\nSize (of a page, typically) in kibibytes (1 kibibyte = 1024 bytes).",
        "timezone-utc": "{{optional}}",
        "unknown_extension_tag": "This is an error shown when you use an unknown extension tag name.\n\nThis feature allows tags like <code><nowiki><pre></nowiki></code> to be called with a parser like <code><nowiki>{{#tag:pre}}</nowiki></code>.\n\nParameters:\n* $1 - the unknown extension tag name",
        "duplicate-defaultsort": "See definition of [[w:Sorting|sort key]] on Wikipedia. Parameters:\n* $1 - old default sort key\n* $2 - new default sort key",
 +      "duplicate-displaytitle": "Warning shown when a page has its display title set multiple times. Parameters:\n* $1 - old display title\n* $2 - new display title",
        "version": "{{doc-special|Version}}\n{{Identical|Version}}",
        "version-summary": "{{doc-specialpagesummary|version}}",
        "version-extensions": "Header on [[Special:Version]].",
 +      "version-skins": "Header on [[Special:Version]].\n\nSee also:\n* {{msg-mw|Version-software}}\n* {{msg-mw|Version-extensions}}",
        "version-specialpages": "Part of [[Special:Version]].\n{{Identical|Special page}}",
        "version-parserhooks": "This message is a heading at [[Special:Version]] for extensions that modifies the parser of wikitext.",
        "version-variables": "{{Identical|Variable}}",
        "version-antispam": "Part of [[Special:Version]].\nThis message is followed by the list of SPAM prevention extensions.",
 -      "version-skins": "{{Identical|Skin}}",
        "version-api": "{{optional}}",
        "version-other": "{{Identical|Other}}",
        "version-mediahandlers": "Used in [[Special:Version]]. It is the title of a section for media handler extensions (e.g. [[mw:Extension:OggHandler]]).\nThere are no such extensions here, so look at [[wikipedia:Special:Version]] for an example.",
        "version-hook-name": "Shown in [[Special:Version]].\n\nFor meaning of hook see [[mw:Special:MyLanguage/Manual:Hooks|mw:Manual:Hooks]] and [[w:Hooking]].",
        "version-hook-subscribedby": "Shown in [[Special:Version]]",
        "version-version": "{{Optional}}\nUsed in [[Special:Version]]. Preceded by the MediaWiki extension name.\n\nParameters:\n* $1 - version number of the extension",
 +      "version-no-ext-name": "Used in [[Special:Version]], in the rows of the main table when a name for an extension is not provided.",
        "version-svn-revision": "{{Identical|Revision}}{{optional}}\nUsed in [[Special:Version]], preceeding the Subversion revision numbers of the extensions loaded inside brackets, like this: \"({{int:version-revision}} r012345\"). Parameters:\n* $1 - (Unused) directory revision number or empty string\n* $2 - checkout revision number",
        "version-license": "Used specifically for the MediaWiki software.\n\nUsed as heading in [[Special:Version]].",
        "version-ext-license": "Used in [[Special:Version]].\n\nUsed as label for the link pointing to the extension's license page. e.g. [[Special:Version/License/Maps]]\n{{Identical|License}}",
        "version-ext-colheader-name": "Column header for the name of an extension.\n{{Identical|Extension}}",
 +      "version-skin-colheader-name": "Column header for the name of a skin.\n{{Identical|Skin}}",
        "version-ext-colheader-version": "Column header for describing an extensions version.\n{{Identical|Version}}",
        "version-ext-colheader-license": "Column header for describing an extensions license.\n{{Identical|License}}",
        "version-ext-colheader-description": "Column header for the description of an extension.\n{{Identical|Description}}",
        "logentry-rights-rights": "* $1 - username\n* $2 - (see below)\n* $3 - username\n* $4 - list of user groups or {{msg-mw|Rightsnone}}\n* $5 - list of user groups or {{msg-mw|Rightsnone}}\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-rights-rights-legacy": "* $1 - username\n* $2 - (see below)\n* $3 - username\n----\n{{Logentry|[[Special:Log/rights]]}}",
        "logentry-rights-autopromote": "* $1 - username\n* $2 - (see below)\n* $3 - (see below)\n* $4 - comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $5 - comma separated list of new user groups\n----\n{{Logentry|[[Special:Log/rights]]}}",
 +      "logentry-upload-upload": "{{Logentry|[[Special:Log/upload]]}}",
 +      "logentry-upload-overwrite": "{{Logentry|[[Special:Log/upload]]}}",
 +      "logentry-upload-revert": "{{Logentry|[[Special:Log/upload]]}}",
        "rightsnone": "Default rights for registered users.\n\n{{Identical|None}}",
        "revdelete-logentry": "{{RevisionDelete}}\nThis is the message for the log entry in [[Special:Log/delete]] when changing visibility restrictions for page revisions.\n\nFollowed by the message {{msg-mw|revdelete-log-message}} in brackets.\n\nPreceded by the name of the user doing this task.\n\nParameters:\n* $1 - the page name\nSee also:\n* {{msg-mw|Logdelete-logentry}}",
        "logdelete-logentry": "{{RevisionDelete}}\nThis is the message for the log entry in [[Special:Log/delete]] when changing visibility restrictions for log events.\n\nFollowed by the message {{msg-mw|logdelete-log-message}} in brackets.\n\nPreceded by the name of the user who did this task.\n\nParameters:\n* $1 - the log name in brackets\nSee also:\n* {{msg-mw|Revdelete-logentry}}",
        "expand_templates_remove_nowiki": "Option on [[Special:Expandtemplates]]\n\nHere's what the tick box does:\n\nFor:\n<pre>\n&lt;nowiki>test&lt;/nowiki>\n</pre>\n\nNot ticked:\n<pre>\n&lt;nowiki>test&lt;/nowiki>\n</pre>\n\nTicked:\n<pre>\ntest\n</pre>",
        "expand_templates_generate_xml": "Used as checkbox label.",
        "expand_templates_generate_rawhtml": "Used as checkbox label.",
 -      "expand_templates_preview": "{{Identical|Preview}}"
 +      "expand_templates_preview": "{{Identical|Preview}}",
 +      "pagelanguage": "Title for page Special:PageLanguage",
 +      "pagelang-name": "Input label for page name on Special:PageLanguage\n{{Identical|Page}}",
 +      "pagelang-language": "Language selector label for Special:PageLanguage\n{{Identical|Language}}",
 +      "pagelang-use-default": "Radio label for selector on Special:PageLanguage for default language",
 +      "pagelang-select-lang": "Radio label for selector on Special:PageLanguage for language selection\n{{Identical|Select language}}",
 +      "right-pagelang": "{{Doc-right|pagelang}}\nRight to change page language on Special:PageLanguage",
 +      "action-pagelang": "{{Doc-action|pagelang}}",
 +      "log-name-pagelang": "Display entry for log name for changes in page language in Special:Log.",
 +      "log-description-pagelang": "Display description for log name for changes in page language in Special:Log.",
 +      "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n* $4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or \"[def]\" (hard-coded)",
 +      "default-skin-not-found": "Message shown when the default skin for this MediaWiki installation can not be found.\n\nParameters:\n* $1: skin identifier for the default skin\n* $2: list of installed skins, composed using {{msg-mw|default-skin-not-found-row-enabled}} and {{msg-mw|default-skin-not-found-row-disabled}}\n* $3: code snippet to use to enable installed skins",
 +      "default-skin-not-found-no-skins": "Message shown when the default skin for this MediaWiki installation can not be found and the installation has no skins at all.\n\nParameters:\n* $1: name of the default skin",
 +      "default-skin-not-found-row-enabled": "One row of the list of installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for an enabled skin.\n\nParameters:\n* $1: skin identifier\n* $2: human-readable skin name",
 +      "default-skin-not-found-row-disabled": "One row of the list of installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for a disabled skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin name"
  }
@@@ -41,9 -41,6 +41,9 @@@ class TitlePermissionTest extends Media
                                NS_MEDIAWIKI => 'editinterface',
                        ),
                ) );
 +              // Without this testUserBlock will use a non-English context on non-English MediaWiki
 +              // installations (because of how Title::checkUserBlock is implemented) and fail.
 +              RequestContext::resetMain();
  
                $this->userName = 'Useruser';
                $this->altUserName = 'Altuseruser';
  
                $this->setTitle( NS_USER );
                $this->setUserPerm( '' );
-               $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ),
+               $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( array( 'protectedinterface' ) ),
+               $this->assertEquals( array( array( 'protectedinterface', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( array( 'protectedinterface' ) ),
+               $this->assertEquals( array( array( 'protectedinterface', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  
                $wgNamespaceProtection = null;
  
                $this->setTitle( NS_USER, $this->userName . '/test.js' );
                $this->runCSSandJSPermissions(
-                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'mycustomjsprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) )
                );
  
                $this->setTitle( NS_USER, $this->userName . '/test.css' );
                $this->runCSSandJSPermissions(
-                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) )
+                       array( array( 'badaccess-group0' ), array( 'mycustomcssprotected', 'bogus' ) )
                );
  
                $this->setTitle( NS_USER, $this->altUserName . '/test.js' );
                $this->runCSSandJSPermissions(
-                       array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customjsprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customjsprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customjsprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customjsprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) )
                );
  
                $this->setTitle( NS_USER, $this->altUserName . '/test.css' );
                $this->runCSSandJSPermissions(
-                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected', 'bogus' ) ),
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected', 'bogus' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) )
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected', 'bogus' ) )
                );
  
                $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
                        "bogus" => array( 'bogus', "sysop", "protect", "" ) );
  
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'bogus' ),
+                               array( 'protectedpagetext', 'editprotected', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus',
                                $this->user ) );
-               $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+               $this->assertEquals( array( array( 'protectedpagetext', 'bogus', 'edit' ),
+                               array( 'protectedpagetext', 'editprotected', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ) ),
                        $this->title->getUserPermissionsErrors( 'edit',
                                $this->user ) );
                $this->setUserPerm( "" );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'bogus' ),
+                               array( 'protectedpagetext', 'editprotected', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus',
                                $this->user ) );
                $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'edit' ),
+                               array( 'protectedpagetext', 'editprotected', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ) ),
                        $this->title->getUserPermissionsErrors( 'edit',
                                $this->user ) );
                $this->setUserPerm( array( "edit", "editprotected" ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus',
                                $this->user ) );
                $this->assertEquals( array(
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ) ),
                        $this->title->getUserPermissionsErrors( 'edit',
                                $this->user ) );
  
                $this->assertEquals( false,
                        $this->title->quickUserCan( 'edit', $this->user ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'bogus' ),
+                               array( 'protectedpagetext', 'editprotected', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus',
                                $this->user ) );
-               $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'editprotected' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+               $this->assertEquals( array( array( 'protectedpagetext', 'bogus', 'edit' ),
+                               array( 'protectedpagetext', 'editprotected', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ) ),
                        $this->title->getUserPermissionsErrors( 'edit',
                                $this->user ) );
  
                $this->assertEquals( false,
                        $this->title->quickUserCan( 'edit', $this->user ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                               array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'protect' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+                               array( 'protectedpagetext', 'bogus', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ),
+                               array( 'protectedpagetext', 'protect', 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus',
                                $this->user ) );
-               $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                               array( 'protectedpagetext', 'protect' ),
-                               array( 'protectedpagetext', 'protect' ) ),
+               $this->assertEquals( array( array( 'protectedpagetext', 'bogus', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ),
+                               array( 'protectedpagetext', 'protect', 'edit' ) ),
                        $this->title->getUserPermissionsErrors( 'edit',
                                $this->user ) );
        }
  
                $this->assertEquals( false,
                        $this->title->userCan( 'bogus', $this->user ) );
-               $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ),
-                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ),
-                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ),
+               $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ),
+                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ),
+                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ) ),
                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  
                $this->assertEquals( true,