jenkins-bot has submitted this change and it was merged.

Change subject: New Wikidata Build - 2015-12-17T10:00:01+0000
......................................................................


New Wikidata Build - 2015-12-17T10:00:01+0000

Change-Id: I7805e9326b6fa40887c5502d7f476614f7574106
---
M composer.lock
M extensions/Wikibase/client/includes/WikibaseClient.php
M extensions/Wikibase/lib/WikibaseLib.datatypes.php
M extensions/Wikibase/lib/config/WikibaseLib.default.php
M extensions/Wikibase/lib/i18n/de.json
M extensions/Wikibase/lib/i18n/en.json
M extensions/Wikibase/lib/i18n/mk.json
M extensions/Wikibase/lib/i18n/qqq.json
M extensions/Wikibase/lib/includes/formatters/DispatchingSnakFormatter.php
M extensions/Wikibase/lib/includes/formatters/PropertyValueSnakFormatter.php
A extensions/Wikibase/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
D extensions/Wikibase/lib/includes/store/PropertyDataTypeMatcher.php
M 
extensions/Wikibase/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
M 
extensions/Wikibase/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
A 
extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
D extensions/Wikibase/lib/tests/phpunit/store/PropertyDataTypeMatcherTest.php
M extensions/Wikibase/phpcs.xml
M extensions/Wikibase/purtle/tests/phpunit/RdfWriterFactoryTest.php
M extensions/Wikibase/repo/WikibaseRepo.datatypes.php
M extensions/Wikibase/repo/i18n/de.json
M extensions/Wikibase/repo/i18n/en.json
M extensions/Wikibase/repo/i18n/fr.json
M extensions/Wikibase/repo/i18n/he.json
M extensions/Wikibase/repo/i18n/qqq.json
M extensions/Wikibase/repo/i18n/zh-hans.json
M extensions/Wikibase/repo/includes/Diff/DiffOpValueFormatter.php
M 
extensions/Wikibase/repo/includes/ParserOutput/EntityParserOutputGeneratorFactory.php
M extensions/Wikibase/repo/includes/ParserOutput/ExternalLinksDataUpdater.php
M extensions/Wikibase/repo/includes/ParserOutput/GeoDataDataUpdater.php
M extensions/Wikibase/repo/includes/ParserOutput/ImageLinksDataUpdater.php
M extensions/Wikibase/repo/includes/Parsers/TimeParserFactory.php
M extensions/Wikibase/repo/includes/Parsers/YearTimeParser.php
M extensions/Wikibase/repo/includes/WikibaseRepo.php
M extensions/Wikibase/repo/includes/specials/SpecialListDatatypes.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/EntityParserOutputGeneratorTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ExternalLinksDataUpdaterTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/GeoDataDataUpdaterTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ImageLinksDataUpdaterTest.php
M extensions/Wikibase/repo/tests/phpunit/includes/Parsers/YearTimeParserTest.php
M vendor/composer/autoload_classmap.php
M vendor/composer/installed.json
41 files changed, 580 insertions(+), 227 deletions(-)

Approvals:
  Aude: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/composer.lock b/composer.lock
index a74e5c2..21e0250 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1448,12 +1448,12 @@
             "source": {
                 "type": "git",
                 "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-                "reference": "ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e"
+                "reference": "b0012d18588ddefc754696aeb09b5f880f2f1dd5"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e";,
-                "reference": "ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e",
+                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b0012d18588ddefc754696aeb09b5f880f2f1dd5";,
+                "reference": "b0012d18588ddefc754696aeb09b5f880f2f1dd5",
                 "shasum": ""
             },
             "require": {
@@ -1524,7 +1524,7 @@
                 "wikibaserepo",
                 "wikidata"
             ],
-            "time": "2015-12-16 08:26:55"
+            "time": "2015-12-16 21:37:31"
         },
         {
             "name": "wikibase/wikimedia-badges",
diff --git a/extensions/Wikibase/client/includes/WikibaseClient.php 
b/extensions/Wikibase/client/includes/WikibaseClient.php
index b92ca27..12f5f9c 100644
--- a/extensions/Wikibase/client/includes/WikibaseClient.php
+++ b/extensions/Wikibase/client/includes/WikibaseClient.php
@@ -60,6 +60,7 @@
 use Wikibase\Lib\PropertyInfoDataTypeLookup;
 use Wikibase\Lib\Store\EntityContentDataCodec;
 use Wikibase\Lib\MediaWikiContentLanguages;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
 use Wikibase\Lib\WikibaseValueFormatterBuilders;
 use Wikibase\Lib\Interactors\TermIndexSearchInteractor;
 use Wikibase\NamespaceChecker;
@@ -213,6 +214,48 @@
        }
 
        /**
+        * Returns the default WikibaseSnakFormatterBuilders instance.
+        * @warning This is for use with bootstrap code in 
WikibaseClient.datatypes.php only!
+        * Program logic should use WikibaseClient::getSnakFormatterFactory() 
instead!
+        *
+        * @since 0.5
+        *
+        * @param string $reset Flag: Pass "reset" to reset the default instance
+        *
+        * @return WikibaseSnakFormatterBuilders
+        */
+       public static function getDefaultSnakFormatterBuilders( $reset = 
'noreset' ) {
+               static $builders;
+
+               if ( $builders === null || $reset === 'reset' ) {
+                       $builders = 
self::getDefaultInstance()->newWikibaseSnakFormatterBuilders(
+                               self::getDefaultFormatterBuilders()
+                       );
+               }
+
+               return $builders;
+       }
+
+       /**
+        * Returns a low level factory object for creating formatters for well 
known data types.
+        *
+        * @warning This is for use with getDefaultFormatterBuilders() during 
bootstrap only!
+        * Program logic should use WikibaseClient::getSnakFormatterFactory() 
instead!
+        *
+        * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+        *
+        * @return WikibaseSnakFormatterBuilders
+        */
+       private function newWikibaseSnakFormatterBuilders( 
WikibaseValueFormatterBuilders $valueFormatterBuilders ) {
+               return new WikibaseSnakFormatterBuilders(
+                       $valueFormatterBuilders,
+                       $this->getStore()->getPropertyInfoStore(),
+                       $this->getPropertyDataTypeLookup(),
+                       $this->getDataTypeFactory()
+               );
+       }
+
+       /**
         * @param SettingsArray $settings
         * @param Language $contentLanguage
         * @param DataTypeDefinitions $dataTypeDefinitions
diff --git a/extensions/Wikibase/lib/WikibaseLib.datatypes.php 
b/extensions/Wikibase/lib/WikibaseLib.datatypes.php
index 642bee0..b879d8b 100644
--- a/extensions/Wikibase/lib/WikibaseLib.datatypes.php
+++ b/extensions/Wikibase/lib/WikibaseLib.datatypes.php
@@ -22,6 +22,7 @@
        'PT:string'            => array( 'value-type' => 'string' ),
        'PT:time'              => array( 'value-type' => 'time' ),
        'PT:url'               => array( 'value-type' => 'string' ),
+       'PT:external-id'       => array( 'value-type' => 'string' ),
        'PT:wikibase-item'     => array( 'value-type' => 'wikibase-entityid' ),
        'PT:wikibase-property' => array( 'value-type' => 'wikibase-entityid' ),
 );
diff --git a/extensions/Wikibase/lib/config/WikibaseLib.default.php 
b/extensions/Wikibase/lib/config/WikibaseLib.default.php
index 1e2ce32..de19c74 100644
--- a/extensions/Wikibase/lib/config/WikibaseLib.default.php
+++ b/extensions/Wikibase/lib/config/WikibaseLib.default.php
@@ -68,6 +68,7 @@
                'string',
                'time',
                'url',
+               'external-id',
                'wikibase-item',
                'wikibase-property',
        ),
diff --git a/extensions/Wikibase/lib/i18n/de.json 
b/extensions/Wikibase/lib/i18n/de.json
index afe41db..16857c1 100644
--- a/extensions/Wikibase/lib/i18n/de.json
+++ b/extensions/Wikibase/lib/i18n/de.json
@@ -79,6 +79,7 @@
        "datatypes-type-wikibase-item": "Datenobjekt",
        "datatypes-type-wikibase-property": "Eigenschaft",
        "datatypes-type-commonsMedia": "Mediendatei auf Commons",
+       "datatypes-type-external-id": "Externer Identifikator",
        "version-wikibase": "Wikibase-Erweiterungen",
        "wikibase-time-precision-Gannum": "$1 Milliarden Jahre n. Chr.",
        "wikibase-time-precision-Mannum": "$1 Millionen Jahre n. Chr.",
diff --git a/extensions/Wikibase/lib/i18n/en.json 
b/extensions/Wikibase/lib/i18n/en.json
index f869813..1eeff22 100644
--- a/extensions/Wikibase/lib/i18n/en.json
+++ b/extensions/Wikibase/lib/i18n/en.json
@@ -71,6 +71,7 @@
        "datatypes-type-wikibase-item": "Item",
        "datatypes-type-wikibase-property": "Property",
        "datatypes-type-commonsMedia": "Commons media file",
+       "datatypes-type-external-id": "External identifier",
        "version-wikibase": "Wikibase",
        "wikibase-time-precision-Gannum": "$1 billion years CE",
        "wikibase-time-precision-Mannum": "$1 million years CE",
diff --git a/extensions/Wikibase/lib/i18n/mk.json 
b/extensions/Wikibase/lib/i18n/mk.json
index f0be769..3580e78 100644
--- a/extensions/Wikibase/lib/i18n/mk.json
+++ b/extensions/Wikibase/lib/i18n/mk.json
@@ -71,6 +71,7 @@
        "datatypes-type-wikibase-item": "Предмет",
        "datatypes-type-wikibase-property": "Својство",
        "datatypes-type-commonsMedia": "Податотека од Ризницата",
+       "datatypes-type-external-id": "Надворешна назнака",
        "version-wikibase": "Викибаза",
        "wikibase-time-precision-Gannum": "$1 {{PLURAL:$1|милијарда|милијадри}} 
години н.е.",
        "wikibase-time-precision-Mannum": "$1 {{PLURAL:$1|милион|милиони}} 
години н.е.",
diff --git a/extensions/Wikibase/lib/i18n/qqq.json 
b/extensions/Wikibase/lib/i18n/qqq.json
index b4112ac..6a01306 100644
--- a/extensions/Wikibase/lib/i18n/qqq.json
+++ b/extensions/Wikibase/lib/i18n/qqq.json
@@ -81,6 +81,7 @@
        "datatypes-type-wikibase-item": "The name of a data type for items in 
Wikibase.\n{{Identical|Item}}",
        "datatypes-type-wikibase-property": "The name of a data type for 
properties in Wikibase.\n{{Identical|Property}}",
        "datatypes-type-commonsMedia": "The name of a data type for media files 
on Wikimedia Commons (proper name, capitalised in English; first letter 
capitalised anyway in this message and 
relatives).\n\n{{related|Datatypes-type}}",
+       "datatypes-type-external-id": "The name of a data type for external 
identifiers in Wikibase.",
        "version-wikibase": "Name of the Wikibase extension collection, used on 
[[Special:Version]]",
        "wikibase-time-precision-Gannum": "Used to present a point in time with 
the precession of 1 billion of years. $1 is the point in time in billion years, 
rounded to billion years.\n{{Related|Wikibase-time-precision}}",
        "wikibase-time-precision-Mannum": "Used to present a point in time with 
the precession of 1 million of years. $1 is the point in time in million years, 
rounded to million years.\n{{Related|Wikibase-time-precision}}",
diff --git 
a/extensions/Wikibase/lib/includes/formatters/DispatchingSnakFormatter.php 
b/extensions/Wikibase/lib/includes/formatters/DispatchingSnakFormatter.php
index 081b1a1..fd7467f 100644
--- a/extensions/Wikibase/lib/includes/formatters/DispatchingSnakFormatter.php
+++ b/extensions/Wikibase/lib/includes/formatters/DispatchingSnakFormatter.php
@@ -39,8 +39,11 @@
        private $formattersBySnakType;
 
        /**
-        * @param string $format The output format generated by this formatter. 
All formatters
-        *  provided to the constructor must produce the same output format.
+        * @param string $format The output format generated by this formatter. 
All SnakFormatters
+        *  provided via $formattersBySnakType and $formattersByDataType must 
be safe for this
+        *  output format. This is checked by comparing the $format with what 
each SnakFormatter
+        *  returns from getFormat(). MIME parameters are ignored for this 
check, so FORMAT_HTML
+        *  is considered compatible with FORMAT_HTML_DIFF, etc.
         * @param PropertyDataTypeLookup $dataTypeLookup
         * @param SnakFormatter[] $formattersBySnakType An associative array 
mapping snak types
         *  to SnakFormatter objects. If no formatter is defined for the a 
given snak type,
@@ -49,7 +52,9 @@
         *  to SnakFormatter objects. If no formatter is defined for the a 
given data type,
         *  the "*" key in this array is checked for a default formatter.
         *
-        * @throws InvalidArgumentException
+        * @throws InvalidArgumentException If any of the given formatters is 
incompatible
+        *         with $format. Formats are assumed to be represented by MIME 
types,
+        *         MIME parameters are ignored.
         */
        public function __construct(
                $format,
@@ -78,7 +83,10 @@
                                throw new InvalidArgumentException( 'formatter 
array must contain instances of SnakFormatter.' );
                        }
 
-                       if ( $formatter->getFormat() !== $format ) {
+                       // Ignore MIME parameters when checking output format. 
We only care that the base format
+                       // is the same, so we can assume that all formatters 
apply the correct escaping and are
+                       // safe to use.
+                       if ( $this->getBaseFormat( $formatter->getFormat() ) 
!== $this->getBaseFormat( $format ) ) {
                                throw new InvalidArgumentException( 'The 
formatter supplied for ' . $type
                                        . ' produces ' . 
$formatter->getFormat() . ', but we expect ' . $format . '.' );
                        }
@@ -86,6 +94,15 @@
        }
 
        /**
+        * @param string $format MIME type
+        *
+        * @return string MIME type with parameters stripped.
+        */
+       private function getBaseFormat( $format ) {
+               return preg_replace( '/ *;.*$/', '', $format );
+       }
+
+       /**
         * @param Snak $snak
         *
         * @throws PropertyDataTypeLookupException
diff --git 
a/extensions/Wikibase/lib/includes/formatters/PropertyValueSnakFormatter.php 
b/extensions/Wikibase/lib/includes/formatters/PropertyValueSnakFormatter.php
index d3e5a66..a00d008 100644
--- a/extensions/Wikibase/lib/includes/formatters/PropertyValueSnakFormatter.php
+++ b/extensions/Wikibase/lib/includes/formatters/PropertyValueSnakFormatter.php
@@ -10,6 +10,7 @@
 use ValueFormatters\Exceptions\MismatchingDataValueTypeException;
 use ValueFormatters\FormatterOptions;
 use ValueFormatters\FormattingException;
+use ValueFormatters\ValueFormatter;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
@@ -35,7 +36,7 @@
        private $options;
 
        /**
-        * @var TypedValueFormatter
+        * @var ValueFormatter
         */
        private $valueFormatter;
 
@@ -53,7 +54,7 @@
         * @param string $format The name of this formatter's output format.
         *        Use the FORMAT_XXX constants defined in SnakFormatter.
         * @param FormatterOptions|null $options
-        * @param TypedValueFormatter $valueFormatter
+        * @param ValueFormatter $valueFormatter
         * @param PropertyDataTypeLookup $typeLookup
         * @param DataTypeFactory $dataTypeFactory
         *
@@ -62,7 +63,7 @@
        public function __construct(
                $format,
                FormatterOptions $options = null,
-               TypedValueFormatter $valueFormatter,
+               ValueFormatter $valueFormatter,
                PropertyDataTypeLookup $typeLookup,
                DataTypeFactory $dataTypeFactory
        ) {
@@ -171,7 +172,11 @@
         */
        private function formatValue( DataValue $value, $dataTypeId = null ) {
                if ( !$this->isUnDeserializableValue( $value ) ) {
-                       $text = $this->valueFormatter->formatValue( $value, 
$dataTypeId );
+                       if ( $this->valueFormatter instanceof 
TypedValueFormatter ) {
+                               $text = $this->valueFormatter->formatValue( 
$value, $dataTypeId );
+                       } else {
+                               $text = $this->valueFormatter->format( $value );
+                       }
                } else {
                        $text = '';
                }
diff --git 
a/extensions/Wikibase/lib/includes/formatters/WikibaseSnakFormatterBuilders.php 
b/extensions/Wikibase/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
new file mode 100644
index 0000000..7293e2d
--- /dev/null
+++ 
b/extensions/Wikibase/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
@@ -0,0 +1,148 @@
+<?php
+
+namespace Wikibase\Lib;
+
+use DataTypes\DataTypeFactory;
+use InvalidArgumentException;
+use ValueFormatters\FormatterOptions;
+use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
+use Wikibase\Lib\Formatters\HtmlExternalIdentifierFormatter;
+use Wikibase\Lib\Formatters\WikitextExternalIdentifierFormatter;
+use Wikibase\PropertyInfoStore;
+
+/**
+ * Low level factory for SnakFormatters for well known data types.
+ *
+ * @warning: This is a low level factory for use by boostrap code only!
+ * Program logic should use an instance of OutputFormatValueFormatterFactory
+ * resp. OutputFormatSnakFormatterFactory.
+ *
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class WikibaseSnakFormatterBuilders {
+
+       /**
+        * @var WikibaseValueFormatterBuilders
+        */
+       private $valueFormatterBuilders;
+
+       /**
+        * @var PropertyInfoStore
+        */
+       private $propertyInfoStore;
+
+       /**
+        * @var PropertyDataTypeLookup
+        */
+       private $dataTypeLookup;
+
+       /**
+        * @var DataTypeFactory
+        */
+       private $dataTypeFactory;
+
+       /**
+        * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+        */
+       public function __construct(
+               WikibaseValueFormatterBuilders $valueFormatterBuilders,
+               PropertyInfoStore $propertyInfoStore,
+               PropertyDataTypeLookup $dataTypeLookup,
+               DataTypeFactory $dataTypeFactory
+       ) {
+               $this->valueFormatterBuilders = $valueFormatterBuilders;
+               $this->propertyInfoStore = $propertyInfoStore;
+               $this->dataTypeLookup = $dataTypeLookup;
+               $this->dataTypeFactory = $dataTypeFactory;
+       }
+
+       /**
+        * @param string $format One of the SnakFormatter::FORMAT_... constants.
+        *
+        * @throws InvalidArgumentException
+        * @return string Either SnakFormatter::FORMAT_HTML, ...WIKI or 
...PLAIN.
+        */
+       private function getBaseFormat( $format ) {
+               switch ( $format ) {
+                       case SnakFormatter::FORMAT_HTML:
+                       case SnakFormatter::FORMAT_HTML_DIFF:
+                       case SnakFormatter::FORMAT_HTML_WIDGET:
+                               return SnakFormatter::FORMAT_HTML;
+                       case SnakFormatter::FORMAT_WIKI:
+                       case SnakFormatter::FORMAT_PLAIN:
+                               return $format;
+               }
+
+               throw new InvalidArgumentException( 'Unsupported output format: 
' . $format );
+       }
+
+       /**
+        * @param string $format The desired target format, see 
SnakFormatter::FORMAT_XXX
+        *
+        * @throws InvalidArgumentException
+        * @return bool True if $format is one of the 
SnakFormatter::FORMAT_HTML_XXX formats.
+        */
+       private function isHtmlFormat( $format ) {
+               return $this->getBaseFormat( $format ) === 
SnakFormatter::FORMAT_HTML;
+       }
+
+       /**
+        * Wraps the given formatter in an EscapingSnakFormatter if necessary.
+        *
+        * @param string $format The desired target format, see 
SnakFormatter::FORMAT_XXX
+        * @param SnakFormatter $formatter The plain text formatter to wrap.
+        *
+        * @throws InvalidArgumentException
+        * @return SnakFormatter
+        */
+       private function escapeSnakFormatter( $format, SnakFormatter $formatter 
) {
+               switch ( $this->getBaseFormat( $format ) ) {
+                       case SnakFormatter::FORMAT_HTML:
+                               return new EscapingSnakFormatter( $format, 
$formatter, 'htmlspecialchars' );
+                       case SnakFormatter::FORMAT_WIKI:
+                               return new EscapingSnakFormatter( $format, 
$formatter, 'wfEscapeWikiText' );
+                       case SnakFormatter::FORMAT_PLAIN:
+                               return $formatter;
+               }
+
+               throw new InvalidArgumentException( 'Unsupported output format: 
' . $format );
+       }
+
+       /**
+        * @param string $format The desired target format, see 
SnakFormatter::FORMAT_XXX
+        * @param FormatterOptions $options
+        *
+        * @throws InvalidArgumentException
+        * @return SnakFormatter
+        */
+       public function newExternalIdentifierFormatter( $format, 
FormatterOptions $options ) {
+               if ( $format === SnakFormatter::FORMAT_PLAIN ) {
+                       return new PropertyValueSnakFormatter(
+                               $format,
+                               $options,
+                               
$this->valueFormatterBuilders->newStringFormatter( $format, $options ),
+                               $this->dataTypeLookup,
+                               $this->dataTypeFactory
+                       );
+               }
+
+               $urlProvider = new FieldPropertyInfoProvider(
+                       $this->propertyInfoStore,
+                       PropertyInfoStore::KEY_FORMATTER_URL
+               );
+
+               $urlExpander = new PropertyInfoSnakUrlExpander( $urlProvider );
+
+               if ( $format === SnakFormatter::FORMAT_WIKI ) {
+                       return new WikitextExternalIdentifierFormatter( 
$urlExpander );
+               } elseif ( $this->isHtmlFormat( $format ) ) {
+                       return new HtmlExternalIdentifierFormatter( 
$urlExpander );
+               }
+
+               throw new InvalidArgumentException( 'Unsupported output format: 
' . $format );
+       }
+
+}
diff --git a/extensions/Wikibase/lib/includes/store/PropertyDataTypeMatcher.php 
b/extensions/Wikibase/lib/includes/store/PropertyDataTypeMatcher.php
deleted file mode 100644
index 96e8926..0000000
--- a/extensions/Wikibase/lib/includes/store/PropertyDataTypeMatcher.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-namespace Wikibase\Lib\Store;
-
-use Wikibase\DataModel\Entity\PropertyId;
-use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
-use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
-
-/**
- * Check if a PropertyId is for a Property with a specific data type.
- * As well, in-process caching of the lookups is done for performance reasons.
- *
- * @since 0.5
- *
- * @license GNU GPL v2+
- * @author Katie Filbert < [email protected] >
- */
-class PropertyDataTypeMatcher {
-
-       /**
-        * @var PropertyDataTypeLookup
-        */
-       private $propertyDataTypeLookup;
-
-       /**
-        * @var string[]
-        */
-       private $propertyDataTypes = array();
-
-       /**
-        * @param PropertyDataTypeLookup $propertyDataTypeLookup
-        */
-       public function __construct( PropertyDataTypeLookup 
$propertyDataTypeLookup ) {
-               $this->propertyDataTypeLookup = $propertyDataTypeLookup;
-       }
-
-       /**
-        * @param PropertyId $propertyId
-        * @param string $dataType
-        *
-        * @return bool
-        */
-       public function isMatchingDataType( PropertyId $propertyId, $dataType ) 
{
-               return $this->getDataTypeIdForProperty( $propertyId ) === 
$dataType;
-       }
-
-       /**
-        * @param PropertyId $propertyId
-        *
-        * @return string|null
-        */
-       private function getDataTypeIdForProperty( PropertyId $propertyId ) {
-               $prefixedId = $propertyId->getSerialization();
-
-               if ( !array_key_exists( $prefixedId, $this->propertyDataTypes ) 
) {
-                       $this->propertyDataTypes[$prefixedId] = 
$this->findDataTypeIdForProperty( $propertyId );
-               }
-
-               return $this->propertyDataTypes[$prefixedId];
-       }
-
-       /**
-        * @param PropertyId $propertyId
-        *
-        * @return string|null
-        */
-       private function findDataTypeIdForProperty( PropertyId $propertyId ) {
-               try {
-                       return 
$this->propertyDataTypeLookup->getDataTypeIdForProperty( $propertyId );
-               } catch ( PropertyDataTypeLookupException $ex ) {
-                       return null;
-               }
-       }
-
-}
diff --git 
a/extensions/Wikibase/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
 
b/extensions/Wikibase/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
index 76c92cc..10de96d 100644
--- 
a/extensions/Wikibase/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
+++ 
b/extensions/Wikibase/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
@@ -62,6 +62,44 @@
        }
 
        /**
+        * @dataProvider constructorProvider
+        */
+       public function testConstructor( $format, array $formattersBySnakType, 
array $formattersByDataType ) {
+               $dataTypeLookup = $this->getDataTypeLookup();
+
+               new DispatchingSnakFormatter(
+                       $format,
+                       $dataTypeLookup,
+                       $formattersBySnakType,
+                       $formattersByDataType
+               );
+
+               // we are just checking that the constructor did not throw an 
exception
+               $this->assertTrue( true );
+       }
+
+       public function constructorProvider() {
+               $formatter = new MessageSnakFormatter(
+                       'novalue',
+                       wfMessage( 'wikibase-snakview-snaktypeselector-novalue' 
),
+                       SnakFormatter::FORMAT_HTML_DIFF
+               );
+
+               return array(
+                       'plain constructor call' => array(
+                               SnakFormatter::FORMAT_HTML_DIFF,
+                               array( 'novalue' => $formatter ),
+                               array( 'string' => $formatter ),
+                       ),
+                       'constructor call with formatters for base format ID' 
=> array(
+                               SnakFormatter::FORMAT_HTML,
+                               array( 'novalue' => $formatter ),
+                               array( 'string' => $formatter ),
+                       ),
+               );
+       }
+
+       /**
         * @dataProvider constructorErrorsProvider
         */
        public function testConstructorErrors( $format, array 
$formattersBySnakType, array $formattersByDataType ) {
diff --git 
a/extensions/Wikibase/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
 
b/extensions/Wikibase/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
index 22675a2..4ac73f0 100644
--- 
a/extensions/Wikibase/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
+++ 
b/extensions/Wikibase/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
@@ -7,6 +7,8 @@
 use DataValues\StringValue;
 use DataValues\UnDeserializableValue;
 use ValueFormatters\FormatterOptions;
+use ValueFormatters\StringFormatter;
+use ValueFormatters\ValueFormatter;
 use Wikibase\DataModel\Entity\PropertyId;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
@@ -91,7 +93,7 @@
         * @dataProvider formatSnakProvider
         */
        public function testFormatSnak(
-               $snak, $dataType, $valueType, $targetFormat, $formatters,
+               $snak, $dataType, $valueType, $targetFormat, ValueFormatter 
$formatter,
                $expected, $expectedException = null
        ) {
                if ( $expectedException !== null ) {
@@ -108,7 +110,7 @@
                $formatter = new PropertyValueSnakFormatter(
                        $targetFormat,
                        $options,
-                       new DispatchingValueFormatter( $formatters ),
+                       $formatter,
                        $typeLookup,
                        $typeFactory
                );
@@ -134,13 +136,15 @@
                        'PT:commonsMedia' => $this->getMockFormatter( 
'PT:commonsMedia' )
                );
 
+               $dispatchingFormatter = new DispatchingValueFormatter( 
$formatters );
+
                return array(
                        'match PT' => array(
                                new PropertyValueSnak( 17, new StringValue( 
'Foo.jpg' ) ),
                                'commonsMedia',
                                'string',
                                SnakFormatter::FORMAT_PLAIN,
-                               $formatters,
+                               $dispatchingFormatter,
                                '/^PT:commonsMedia$/'
                        ),
 
@@ -149,8 +153,17 @@
                                'someStuff',
                                'string',
                                SnakFormatter::FORMAT_WIKI,
-                               $formatters,
+                               $dispatchingFormatter,
                                '/^VT:string$/'
+                       ),
+
+                       'use plain value formatter' => array(
+                               new PropertyValueSnak( 33, new StringValue( 
'something' ) ),
+                               'url',
+                               'string',
+                               SnakFormatter::FORMAT_WIKI,
+                               new StringFormatter(),
+                               '/^something$/'
                        ),
 
                        'UnDeserializableValue, fail' => array(
@@ -160,7 +173,7 @@
                                'globe-coordinate',
                                'globecoordinate',
                                SnakFormatter::FORMAT_HTML,
-                               $formatters,
+                               $dispatchingFormatter,
                                null,
                                
'ValueFormatters\Exceptions\MismatchingDataValueTypeException'
                        ),
@@ -170,7 +183,7 @@
                                'url',
                                'iri', // url expects an iri, but will get a 
string
                                SnakFormatter::FORMAT_WIKI,
-                               $formatters,
+                               $dispatchingFormatter,
                                null,
                                
'ValueFormatters\Exceptions\MismatchingDataValueTypeException'
                        ),
@@ -180,7 +193,7 @@
                                '', // triggers an exception from the mock 
PropertyDataTypeLookup
                                'xxx', // should not be used
                                SnakFormatter::FORMAT_HTML,
-                               $formatters,
+                               $dispatchingFormatter,
                                null,
                                
'Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException'
                        ),
diff --git 
a/extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
 
b/extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
new file mode 100644
index 0000000..719bc69
--- /dev/null
+++ 
b/extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Wikibase\Lib\Test;
+
+use DataTypes\DataTypeFactory;
+use DataValues\StringValue;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\StringFormatter;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+use Wikibase\Lib\SnakFormatter;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
+use Wikibase\PropertyInfoStore;
+use Wikibase\Test\MockPropertyInfoStore;
+
+/**
+ * @covers Wikibase\Lib\WikibaseSnakFormatterBuilders
+ *
+ * @group SnakFormatters
+ * @group DataValueExtensions
+ * @group WikibaseLib
+ * @group Wikibase
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class WikibaseSnakFormatterBuildersTest extends \PHPUnit_Framework_TestCase {
+
+       /**
+        * @return WikibaseSnakFormatterBuilders
+        */
+       private function getWikibaseSnakFormatterBuilders() {
+               $p1 = new PropertyId( 'P1' );
+
+               $valueFormatterBuilders = $this->getMockBuilder( 
'Wikibase\Lib\WikibaseValueFormatterBuilders' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $valueFormatterBuilders->expects( $this->any() )
+                       ->method( 'newStringFormatter' )
+                       ->will( $this->returnValue( new StringFormatter() ) );
+
+               $propertyInfoStore = new MockPropertyInfoStore();
+               $propertyInfoStore->setPropertyInfo( $p1, array(
+                       PropertyInfoStore::KEY_DATA_TYPE => 'external-id',
+                       PropertyInfoStore::KEY_FORMATTER_URL => 
'http://acme.com/vocab/$1',
+               ) );
+
+               $dataTypeLookup = new InMemoryDataTypeLookup();
+               $dataTypeLookup->setDataTypeForProperty( $p1, 'external-id' );
+
+               $dataTypeFactory = new DataTypeFactory( array( 'external-id' => 
'string' ) );
+
+               return new WikibaseSnakFormatterBuilders(
+                       $valueFormatterBuilders,
+                       $propertyInfoStore,
+                       $dataTypeLookup,
+                       $dataTypeFactory
+               );
+       }
+
+       public function provideNewExternalIdentifierFormatter() {
+               $p1 = new PropertyId( 'P1' );
+               $snak = new PropertyValueSnak( $p1, new StringValue( 'AB123' ) 
);
+
+               return array(
+                       array( $snak, SnakFormatter::FORMAT_PLAIN, 'AB123' ),
+                       array( $snak, SnakFormatter::FORMAT_WIKI, 
'[http://acme.com/vocab/AB123 AB123]' ),
+                       array( $snak, SnakFormatter::FORMAT_HTML, '<a 
class="wb-external-id" href="http://acme.com/vocab/AB123";>AB123</a>' ),
+               );
+       }
+
+       /**
+        * @dataProvider provideNewExternalIdentifierFormatter
+        */
+       public function testNewExternalIdentifierFormatter( Snak $snak, 
$format, $expected ) {
+               $options = new FormatterOptions();
+               $builders = $this->getWikibaseSnakFormatterBuilders();
+               $formatter = $builders->newExternalIdentifierFormatter( 
$format, $options );
+               $actual = $formatter->formatSnak( $snak );
+               $this->assertSame( $expected, $actual );
+       }
+
+       public function testNewExternalIdentifierFormatter_bad_format() {
+               $options = new FormatterOptions();
+               $builders = $this->getWikibaseSnakFormatterBuilders();
+
+               $this->setExpectedException( 'InvalidArgumentException' );
+               $builders->newExternalIdentifierFormatter( 'unknown', $options 
);
+       }
+
+}
diff --git 
a/extensions/Wikibase/lib/tests/phpunit/store/PropertyDataTypeMatcherTest.php 
b/extensions/Wikibase/lib/tests/phpunit/store/PropertyDataTypeMatcherTest.php
deleted file mode 100644
index a8f5611..0000000
--- 
a/extensions/Wikibase/lib/tests/phpunit/store/PropertyDataTypeMatcherTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-namespace Wikibase\Lib\Tests\Store;
-
-use PHPUnit_Framework_TestCase;
-use Wikibase\DataModel\Entity\PropertyId;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
-
-/**
- * @covers Wikibase\Lib\Store\PropertyDataTypeMatcher
- *
- * @group Wikibase
- * @group WikibaseLib
- * @group WikibaseStore
- *
- * @licence GNU GPL v2+
- * @author Thiemo Mättig
- */
-class PropertyDataTypeMatcherTest extends PHPUnit_Framework_TestCase {
-
-       /**
-        * @dataProvider propertyDataTypeProvider
-        */
-       public function testIsMatchingDataType( $propertyId, $dataType, 
$expected ) {
-               $lookup = $this->getMock( 
'Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup' );
-               $lookup->expects( $this->once() )
-                       ->method( 'getDataTypeIdForProperty' )
-                       ->with( new PropertyId( 'P1' ) )
-                       ->will( $this->returnValue( 'dataTypeOfP1' ) );
-
-               $instance = new PropertyDataTypeMatcher( $lookup );
-               $this->assertSame( $expected, $instance->isMatchingDataType( 
$propertyId, $dataType ) );
-       }
-
-       public function propertyDataTypeProvider() {
-               $p1 = new PropertyId( 'P1' );
-
-               return array(
-                       array( $p1, 'dataTypeOfP1', true ),
-                       array( $p1, 'otherDataType', false ),
-               );
-       }
-
-}
diff --git a/extensions/Wikibase/phpcs.xml b/extensions/Wikibase/phpcs.xml
index 602a107..c5e962b 100644
--- a/extensions/Wikibase/phpcs.xml
+++ b/extensions/Wikibase/phpcs.xml
@@ -17,7 +17,6 @@
        <rule ref="Generic.Files.LineLength">
                <properties>
                        <property name="lineLimit" value="140" />
-                       <property name="absoluteLineLimit" value="9999" />
                </properties>
                <!-- Exclude auto-generated files from the Translate extension, 
see magic-export.php. -->
                <exclude-pattern>\.i18n\.magic\.php</exclude-pattern>
@@ -25,6 +24,18 @@
        <rule ref="Generic.Files.OneInterfacePerFile" />
        <rule ref="Generic.Files.OneTraitPerFile" />
 
+       <rule ref="Generic.Metrics.CyclomaticComplexity">
+               <properties>
+                       <property name="complexity" value="16" />
+               </properties>
+               
<exclude-pattern>(RdfWriterFactory|UrlSchemeValidators)\.php</exclude-pattern>
+       </rule>
+       <rule ref="Generic.Metrics.NestingLevel">
+               <properties>
+                       <property name="nestingLevel" value="5" />
+               </properties>
+       </rule>
+
        <rule ref="Generic.PHP.CharacterBeforePHPOpeningTag" />
 
        <rule 
ref="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.SingleSpaceBeforeSingleLineComment">
diff --git a/extensions/Wikibase/purtle/tests/phpunit/RdfWriterFactoryTest.php 
b/extensions/Wikibase/purtle/tests/phpunit/RdfWriterFactoryTest.php
index d5d1dd1..9ac996f 100644
--- a/extensions/Wikibase/purtle/tests/phpunit/RdfWriterFactoryTest.php
+++ b/extensions/Wikibase/purtle/tests/phpunit/RdfWriterFactoryTest.php
@@ -47,7 +47,7 @@
        public function provideFormats() {
                return array(
                        // N3 (currently falls through to turtle)
-                       array( 'n3', 'n3', 'n3', 'text/n3' ),
+                       array( 'N3', 'n3', 'n3', 'text/n3' ),
                        array( 'text/n3', 'n3', 'n3', 'text/n3' ),
                        array( 'text/rdf+n3', 'n3', 'n3', 'text/n3' ),
 
diff --git a/extensions/Wikibase/repo/WikibaseRepo.datatypes.php 
b/extensions/Wikibase/repo/WikibaseRepo.datatypes.php
index 40e2318..174bd25 100644
--- a/extensions/Wikibase/repo/WikibaseRepo.datatypes.php
+++ b/extensions/Wikibase/repo/WikibaseRepo.datatypes.php
@@ -239,6 +239,19 @@
                                return new ObjectUriRdfBuilder();
                        },
                ),
+               'PT:id' => array(
+                       'validator-factory-callback' => function() {
+                               $factory = 
WikibaseRepo::getDefaultValidatorBuilders();
+                               return $factory->buildStringValidators();
+                       },
+                       'parser-factory-callback' => $newStringParser,
+                       // NOTE: for 'formatter-factory-callback', we fall back 
to plain text formatting
+                       'snak-formatter-factory-callback' => function( $format, 
FormatterOptions $options ) {
+                               $factory = 
WikibaseRepo::getDefaultSnakFormatterBuilders();
+                               return 
$factory->newExternalIdentifierFormatter( $format, $options );
+                       },
+                       // TODO: RDF mapping using canonical URI patterns
+               ),
                'VT:wikibase-entityid' => array(
                        'validator-factory-callback' => function() {
                                $factory = 
WikibaseRepo::getDefaultValidatorBuilders();
diff --git a/extensions/Wikibase/repo/i18n/de.json 
b/extensions/Wikibase/repo/i18n/de.json
index 869d8a8..10d744c 100644
--- a/extensions/Wikibase/repo/i18n/de.json
+++ b/extensions/Wikibase/repo/i18n/de.json
@@ -327,6 +327,8 @@
        "wikibase-listdatatypes-time-body": "Literales Datenfeld für einen 
Zeitpunkt, angegeben als Datum und Zeit mit Genauigkeit und Begrenzungen. Die 
Zeit wird immer intern im angegebenen Kalendermodell gespeichert.\n* time – 
ausdrücklicher Wert für einen Zeitpunkt; dargestellt als Zeitstempel ähnlich 
ISO 8601, z.&nbsp;B. +2013-01-01T00:00:00Z. Das Jahr ist immer 
vorzeichenbehaftet und muss mit 4 bis 16 Ziffern aufgefüllt werden.\n* timezone 
– ausdrücklicher Wert als vorzeichenbehaftete Ganzzahl. Die 
Zeitzoneninformationen werden als Unterschied zur UTC in Minuten angegeben.\n* 
before – ausdrücklicher Ganzzahlwert für eine Anzahl an Einheiten nach der 
angegebenen Zeit. Die Einheit ist als „precision“ (siehe unten) angegeben.\n* 
after – ausdrücklicher Ganzzahlwert für eine Anzahl an Einheiten vor der 
angegebenen Zeit. Die Einheit ist als „precision“ (siehe unten) angegeben.\n* 
precision – ausdrücklicher Wert, kodiert als kurze Ganzzahl mit folgender 
Bedeutung: 0: Milliarden Jahre; 1: Hundert Millionen Jahre … 6: Jahrtausende; 
7: Jahrhunderte; 8: Jahrzehnte; 9: Jahre; 10: Monate; 11: Tage; 12: Stunden; 
13: Minuten; 14: Sekunden.\n* calendarmodel – ausdrücklicher Wert, angegeben 
als URI. Er identifiziert das Kalendermodell des Zeitstempels.",
        "wikibase-listdatatypes-url-head": "URL",
        "wikibase-listdatatypes-url-body": "Literales Datenfeld für eine URL. 
URLs sind auf die Protokolle beschränkt, die auch für externe Links im Wikitext 
unterstützt werden.",
+       "wikibase-listdatatypes-external-id-head": "Externer Identifikator",
+       "wikibase-listdatatypes-external-id-body": "Literale Datenfelder für 
einen externen Identifikator. Externe Identifikatoren können automatisch mit 
einer zuverlässigen Quelle zur Anzeige verknüpft werden.",
        "wikibase-concept-uri": "Konzept-URI",
        "wikibase-concept-uri-tooltip": "URI, die das von diesem Objekt 
beschriebene Konzept identifiziert.",
        "wikibase-add-badges": "Auszeichnungen hinzufügen",
diff --git a/extensions/Wikibase/repo/i18n/en.json 
b/extensions/Wikibase/repo/i18n/en.json
index ebe82ed..1d9bb0a 100644
--- a/extensions/Wikibase/repo/i18n/en.json
+++ b/extensions/Wikibase/repo/i18n/en.json
@@ -360,6 +360,8 @@
        "wikibase-listdatatypes-time-body": "Literal data field for a point in 
time. Given as a date and time with some precision and boundaries. The time is 
saved internally in the specified calendar model.\n* time – explicit value for 
point in time, represented as a timestamp resembling ISO 8601, e.g. 
+2013-01-01T00:00:00Z. The year is always signed and padded to have between 4 
and 16 digits.\n* timezone – explicit value as a signed integer. Timezone 
information as an offset from UTC in minutes.\n* before – explicit integer 
value for how many units after the given time it could be. The unit is given by 
the precision.\n* after – explicit integer value for how many units before the 
given time it could be. The unit is given by the precision.\n* precision – 
explicit value encoded in a shortint. The numbers have the following meaning: 0 
- billion years, 1 - hundred million years, ..., 6 - millennium, 7 - century, 8 
- decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - 
second.\n* calendarmodel – explicit value given as a URI. It identifies the 
calendar model of the timestamp.",
        "wikibase-listdatatypes-url-head": "URL",
        "wikibase-listdatatypes-url-body": "Literal data field for a URL. URLs 
are restricted to the protocols also supported for external links in wikitext.",
+       "wikibase-listdatatypes-external-id-head": "External identifier",
+       "wikibase-listdatatypes-external-id-body": "Literal data field for an 
external identifier. External identifiers may automatically be linked to an 
authoritative resource for display.",
        "wikibase-concept-uri": "Concept URI",
        "wikibase-concept-uri-tooltip": "URI that identifies the concept 
described by this item",
        "wikibase-add-badges": "Add badges",
diff --git a/extensions/Wikibase/repo/i18n/fr.json 
b/extensions/Wikibase/repo/i18n/fr.json
index db701f3..ba28f1d 100644
--- a/extensions/Wikibase/repo/i18n/fr.json
+++ b/extensions/Wikibase/repo/i18n/fr.json
@@ -562,7 +562,7 @@
        "apihelp-wbsetreference-description": "Crée une référence ou initialise 
la valeur d'une référence existante.",
        "apihelp-wbsetreference-param-statement": "Un GUID identifiant l’énoncé 
pour lequel une référence a été fixée",
        "apihelp-wbsetreference-param-snaks": "Les snaks pour lesquels ont 
définit la référence. Objet JSON avec des Id de propriété qui pointent vers des 
tableaux contenant les snaks pour cette propriété",
-       "apihelp-wbsetreference-param-snaks-order": "L'ordre des snaks. Liste 
d'ID de propriété séparés par des virgules",
+       "apihelp-wbsetreference-param-snaks-order": "L'ordre des snaks. Tableau 
JSON de chaînes d’ID de propriété",
        "apihelp-wbsetreference-param-reference": "Une valeur de hachage 
associée à la référence qui doit être mise à jour. Facultatif. Si elle n'est 
pas fournie, une nouvelle référence est créée",
        "apihelp-wbsetreference-param-index": "L'indice à l'intérieur de la 
liste de références de la déclaration où il faut pour déplacer la référence. 
Facultatif. Lorsqu'il n'est pas fourni, une référence qui  existe restera au 
même endroit alors qu'une nouvelle référence sera ajoutée à la liste.",
        "apihelp-wbsetreference-param-summary": "Résumé de la 
modification.\nSera préfixé par un commentaire généré automatiquement. La 
taille limite du commentaire automatique ajouté au résumé est de 260 caractères 
pour l'ensemble. Notez bien que tout ce qui est au-delà de cette limite sera 
tronqué.",
diff --git a/extensions/Wikibase/repo/i18n/he.json 
b/extensions/Wikibase/repo/i18n/he.json
index eb726fb..7a6a749 100644
--- a/extensions/Wikibase/repo/i18n/he.json
+++ b/extensions/Wikibase/repo/i18n/he.json
@@ -528,7 +528,7 @@
        "apihelp-wbsetreference-description": "יצירת הפניה למקור או הגדרת ערך 
של אחת קיימת.",
        "apihelp-wbsetreference-param-statement": "GUID שמזהה את הקביעה שעבורה 
מוגדרת הפניה מקור",
        "apihelp-wbsetreference-param-snaks": "הסנאקים שאליהם תוגדר ההפניה 
למקור. עצם JSON עם מזהי מאפיינים שמצביעים למערכים שמכילים את הסנאקים עבור 
המאפיין",
-       "apihelp-wbsetreference-param-snaks-order": "סדר הסנאקים. רשימה מופרדת 
בפסיקים של מזהי מאפיינים",
+       "apihelp-wbsetreference-param-snaks-order": "סדר הסנאקים. מערך JSON של 
של מחרוזות מזהים",
        "apihelp-wbsetreference-param-reference": "גיבוב של הפניה למקור שצריך 
לעדכן. לא חובה. כשזה לא מסופק, תיווצר הפניה חדשה למקור",
        "apihelp-wbsetreference-param-index": "האינדקס בתור רשימת ההפניות למקור 
של הטענה שאליו תועבר ההפניה למקור. לא חובה. כשזה לא מסופק, הפניה קיימת למקור 
תישאר במקום בזמן שתתווסף הפניה חדשה למקור.",
        "apihelp-wbsetreference-param-summary": "תקציר העריכה.\nלתחילתו תצורף 
הערה שמיוצרת אוטומטית. מגבלת האורך של ההערה האוטומטית יחד עם תקציר העריכה היא 
260 תווים. יש לשים לב לכך שכל דבר מעבר לכך ייחתך.",
diff --git a/extensions/Wikibase/repo/i18n/qqq.json 
b/extensions/Wikibase/repo/i18n/qqq.json
index bc1b925..a6ebc52 100644
--- a/extensions/Wikibase/repo/i18n/qqq.json
+++ b/extensions/Wikibase/repo/i18n/qqq.json
@@ -389,6 +389,8 @@
        "wikibase-listdatatypes-time-body": "{{Wikibase-datatype-body|Time}}",
        "wikibase-listdatatypes-url-head": 
"{{Wikibase-datatype-head|Url}}\n{{Identical|URL}}",
        "wikibase-listdatatypes-url-body": "{{Wikibase-datatype-body|Url}}",
+       "wikibase-listdatatypes-external-id-head": 
"{{Wikibase-datatype-head|External identifier|external-id}}",
+       "wikibase-listdatatypes-external-id-body": 
"{{Wikibase-datatype-body|External identifier}}",
        "wikibase-concept-uri": "Label for a link in the toolbox on entity 
pages. Target of the link is the one and specific URI for the entity's concept 
(\"canonical concept link\").",
        "wikibase-concept-uri-tooltip": "Text for the canonical concept link in 
toolbox on entity pages.",
        "wikibase-add-badges": "Title for an empty (dummy) badge sign that asks 
the user to add badges to a sitelink.",
diff --git a/extensions/Wikibase/repo/i18n/zh-hans.json 
b/extensions/Wikibase/repo/i18n/zh-hans.json
index fc2743d..d3d001f 100644
--- a/extensions/Wikibase/repo/i18n/zh-hans.json
+++ b/extensions/Wikibase/repo/i18n/zh-hans.json
@@ -515,7 +515,7 @@
        "apihelp-wbsetqualifier-example-1": "设置属性P1指定声称的限定符为字符串值GdyjxP8I6XB3",
        "apihelp-wbsetreference-description": "创建一个参考文献或设置现有参考文献的值。",
        "apihelp-wbsetreference-param-statement": "识别用于已在设置中的参考资料的声明的GUID",
-       "apihelp-wbsetreference-param-snaks-order": "snak的方向。逗号分隔的属性ID列表",
+       "apihelp-wbsetreference-param-snaks-order": "snak的方向。属性ID字符串的JSON阵列",
        "apihelp-wbsetreference-param-summary": 
"编辑摘要。\n将按照自动生成的评论。自动评论与摘要的长度限制是260个字符。需要小心任何超出上述限定的东西将被裁剪掉。",
        "apihelp-wbsetreference-param-bot": 
"将此编辑标记为机器人编辑。此URL标记将只在用户属于“bot”用户组时受尊重。",
        "apihelp-wbsetreference-example-1": 
"为GUID为Q76$D4FDE516-F20C-4154-ADCE-7C5B609DFDFF的声称创建新的参考",
diff --git a/extensions/Wikibase/repo/includes/Diff/DiffOpValueFormatter.php 
b/extensions/Wikibase/repo/includes/Diff/DiffOpValueFormatter.php
index 4d567b2..17fe42e 100644
--- a/extensions/Wikibase/repo/includes/Diff/DiffOpValueFormatter.php
+++ b/extensions/Wikibase/repo/includes/Diff/DiffOpValueFormatter.php
@@ -13,6 +13,7 @@
  * @author Tobias Gritschacher < [email protected] >
  * @author Katie Filbert < [email protected] >
  * @author Daniel Kinzler
+ * @author Thiemo Mättig
  */
 class DiffOpValueFormatter {
 
@@ -69,61 +70,42 @@
        }
 
        /**
-        * Generates HTML for an change diffOp
-        *
         * @return string HTML
         */
-       private function generateChangeOpHtml() {
-               $html = Html::openElement( 'tr' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-marker' ), '-' );
+       private function generateDeletedCells() {
+               $html = Html::rawElement( 'td', array( 'class' => 'diff-marker' 
), '-' );
                $html .= Html::rawElement( 'td', array( 'class' => 
'diff-deletedline' ),
                        Html::rawElement( 'div', array(),
                                Html::rawElement( 'del', array( 'class' => 
'diffchange diffchange-inline' ),
-                                       $this->generateValueHtml( 
$this->oldValues ) ) ) );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-marker' ), '+' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-addedline' ),
-                       Html::rawElement( 'div', array(),
-                               Html::rawElement( 'ins', array( 'class' => 
'diffchange diffchange-inline' ),
-                                       $this->generateValueHtml( 
$this->newValues ) ) ) );
-               $html .= Html::closeElement( 'tr' );
-
-               return $html;
-       }
-
-       /**
-        * Generates HTML for an add diffOp
-        *
-        * @return string HTML
-        */
-       private function generateAddOpHtml() {
-               $html = Html::openElement( 'tr' );
-               $html .= Html::rawElement( 'td', array( 'colspan' => '2' ), 
'&nbsp;' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-marker' ), '+' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-addedline' ),
-                       Html::rawElement( 'div', array(),
-                               Html::rawElement( 'ins', array( 'class' => 
'diffchange diffchange-inline' ),
-                                       $this->generateValueHtml( 
$this->newValues ) )
+                                       $this->generateValueHtml( 
$this->oldValues )
+                               )
                        )
                );
-               $html .= Html::closeElement( 'tr' );
 
                return $html;
        }
 
        /**
-        * Generates HTML for an remove diffOp
-        *
         * @return string HTML
         */
-       private function generateRemoveOpHtml() {
-               $html = Html::openElement( 'tr' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-marker' ), '-' );
-               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-deletedline' ),
+       private function generateAddedCells() {
+               $html = Html::rawElement( 'td', array( 'class' => 'diff-marker' 
), '+' );
+               $html .= Html::rawElement( 'td', array( 'class' => 
'diff-addedline' ),
                        Html::rawElement( 'div', array(),
-                               Html::rawElement( 'del', array( 'class' => 
'diffchange diffchange-inline' ),
-                                       $this->generateValueHtml( 
$this->oldValues ) ) ) );
-               $html .= Html::rawElement( 'td', array( 'colspan' => '2' ), 
'&nbsp;' );
-               $html .= Html::closeElement( 'tr' );
+                               Html::rawElement( 'ins', array( 'class' => 
'diffchange diffchange-inline' ),
+                                       $this->generateValueHtml( 
$this->newValues )
+                               )
+                       )
+               );
+
+               return $html;
+       }
+
+       /**
+        * @return string HTML
+        */
+       private function generateEmptyCells() {
+               $html = Html::rawElement( 'td', array( 'colspan' => '2' ), 
'&nbsp;' );
 
                return $html;
        }
@@ -157,15 +139,22 @@
         */
        public function generateHtml() {
                $html = $this->generateHeaderHtml();
+               $html .= Html::openElement( 'tr' );
 
-               if ( $this->oldValues !== null && $this->newValues !== null ) {
-                       $html .= $this->generateChangeOpHtml();
-               } elseif ( $this->newValues !== null ) {
-                       $html .= $this->generateAddOpHtml();
-               } elseif ( $this->oldValues !== null ) {
-                       $html .= $this->generateRemoveOpHtml();
+               if ( $this->oldValues === null ) {
+                       $html .= $this->generateEmptyCells();
+               } else {
+                       $html .= $this->generateDeletedCells();
                }
 
+               if ( $this->newValues === null ) {
+                       $html .= $this->generateEmptyCells();
+               } else {
+                       $html .= $this->generateAddedCells();
+               }
+
+               $html .= Html::closeElement( 'tr' );
+
                return $html;
        }
 
diff --git 
a/extensions/Wikibase/repo/includes/ParserOutput/EntityParserOutputGeneratorFactory.php
 
b/extensions/Wikibase/repo/includes/ParserOutput/EntityParserOutputGeneratorFactory.php
index 622a8a5..d86123b 100644
--- 
a/extensions/Wikibase/repo/includes/ParserOutput/EntityParserOutputGeneratorFactory.php
+++ 
b/extensions/Wikibase/repo/includes/ParserOutput/EntityParserOutputGeneratorFactory.php
@@ -5,12 +5,12 @@
 use Language;
 use ParserOptions;
 use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
 use Wikibase\LanguageFallbackChain;
 use Wikibase\LanguageFallbackChainFactory;
 use Wikibase\Lib\Store\EntityInfoBuilderFactory;
 use Wikibase\Lib\Store\EntityTitleLookup;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 use Wikibase\Repo\LinkedData\EntityDataFormatProvider;
 use Wikibase\View\EntityViewFactory;
 use Wikibase\View\Template\TemplateFactory;
diff --git 
a/extensions/Wikibase/repo/includes/ParserOutput/ExternalLinksDataUpdater.php 
b/extensions/Wikibase/repo/includes/ParserOutput/ExternalLinksDataUpdater.php
index 5c86cf4..3b8b3fa 100644
--- 
a/extensions/Wikibase/repo/includes/ParserOutput/ExternalLinksDataUpdater.php
+++ 
b/extensions/Wikibase/repo/includes/ParserOutput/ExternalLinksDataUpdater.php
@@ -4,10 +4,10 @@
 
 use DataValues\StringValue;
 use ParserOutput;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Snak\Snak;
 use Wikibase\DataModel\Statement\Statement;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 
 /**
  * Add url data values as external links in ParserOutput.
diff --git 
a/extensions/Wikibase/repo/includes/ParserOutput/GeoDataDataUpdater.php 
b/extensions/Wikibase/repo/includes/ParserOutput/GeoDataDataUpdater.php
index e65e4b8..47a89fb 100644
--- a/extensions/Wikibase/repo/includes/ParserOutput/GeoDataDataUpdater.php
+++ b/extensions/Wikibase/repo/includes/ParserOutput/GeoDataDataUpdater.php
@@ -7,9 +7,9 @@
 use DataValues\Geo\Values\GlobeCoordinateValue;
 use ParserOutput;
 use RuntimeException;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Statement\Statement;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 
 /**
  * Extracts and stashes coordinates from Statement main snaks and
diff --git 
a/extensions/Wikibase/repo/includes/ParserOutput/ImageLinksDataUpdater.php 
b/extensions/Wikibase/repo/includes/ParserOutput/ImageLinksDataUpdater.php
index 3efc226..5f8e323 100644
--- a/extensions/Wikibase/repo/includes/ParserOutput/ImageLinksDataUpdater.php
+++ b/extensions/Wikibase/repo/includes/ParserOutput/ImageLinksDataUpdater.php
@@ -4,10 +4,10 @@
 
 use DataValues\StringValue;
 use ParserOutput;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Snak\Snak;
 use Wikibase\DataModel\Statement\Statement;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 
 /**
  * Register commonsMedia values as used images in ParserOutput.
diff --git a/extensions/Wikibase/repo/includes/Parsers/TimeParserFactory.php 
b/extensions/Wikibase/repo/includes/Parsers/TimeParserFactory.php
index 88e2219..a67c830 100644
--- a/extensions/Wikibase/repo/includes/Parsers/TimeParserFactory.php
+++ b/extensions/Wikibase/repo/includes/Parsers/TimeParserFactory.php
@@ -2,6 +2,7 @@
 
 namespace Wikibase\Repo\Parsers;
 
+use Language;
 use ValueParsers\CalendarModelParser;
 use ValueParsers\DispatchingValueParser;
 use ValueParsers\EraParser;
@@ -18,11 +19,12 @@
  * @licence GNU GPL v2+
  * @author Adam Shorland
  * @author Thiemo Mättig
- *
- * @todo move me to DataValues-time
  */
 class TimeParserFactory {
 
+       /**
+        * Default, canonical language code. In the MediaWiki world this is 
always English.
+        */
        const CANONICAL_LANGUAGE_CODE = 'en';
 
        /**
@@ -47,7 +49,10 @@
                $this->monthNameProvider = $monthNameProvider ?: new 
MediaWikiMonthNameProvider();
 
                $this->options->defaultOption( ValueParser::OPT_LANG, 
self::CANONICAL_LANGUAGE_CODE );
-
+               $this->options->defaultOption(
+                       YearTimeParser::OPT_DIGIT_GROUP_SEPARATOR,
+                       $this->getDigitGroupSeparator()
+               );
        }
 
        /**
@@ -103,4 +108,16 @@
                return new MonthNameUnlocalizer( $replacements );
        }
 
+       /**
+        * @return string
+        */
+       private function getDigitGroupSeparator() {
+               $languageCode = $this->options->getOption( 
ValueParser::OPT_LANG );
+               $language = Language::factory( $languageCode );
+               $separatorMap = $language->separatorTransformTable();
+               $canonical = YearTimeParser::CANONICAL_DIGIT_GROUP_SEPARATOR;
+
+               return isset( $separatorMap[$canonical] ) ? 
$separatorMap[$canonical] : $canonical;
+       }
+
 }
diff --git a/extensions/Wikibase/repo/includes/Parsers/YearTimeParser.php 
b/extensions/Wikibase/repo/includes/Parsers/YearTimeParser.php
index 6b5db07..4cb27c7 100644
--- a/extensions/Wikibase/repo/includes/Parsers/YearTimeParser.php
+++ b/extensions/Wikibase/repo/includes/Parsers/YearTimeParser.php
@@ -3,7 +3,6 @@
 namespace Wikibase\Repo\Parsers;
 
 use DataValues\TimeValue;
-use Language;
 use ValueParsers\CalendarModelParser;
 use ValueParsers\EraParser;
 use ValueParsers\IsoTimestampParser;
@@ -17,6 +16,7 @@
  *
  * @licence GNU GPL v2+
  * @author Adam Shorland
+ * @author Thiemo Mättig
  *
  * @todo move me to DataValues-time
  */
@@ -25,14 +25,20 @@
        const FORMAT_NAME = 'year';
 
        /**
+        * Option to allow parsing of years with localized digit group 
separators. For example, the
+        * English year -10,000 (with a comma) is written as -10.000 (with a 
dot) in German.
+        */
+       const OPT_DIGIT_GROUP_SEPARATOR = 'digitGroupSeparator';
+
+       /**
+        * Default, canonical digit group separator, as in the year -10,000.
+        */
+       const CANONICAL_DIGIT_GROUP_SEPARATOR = ',';
+
+       /**
         * @var ValueParser
         */
        private $eraParser;
-
-       /**
-        * @var Language
-        */
-       private $lang;
 
        /**
         * @var ValueParser
@@ -46,7 +52,11 @@
        public function __construct( ValueParser $eraParser = null, 
ParserOptions $options = null ) {
                parent::__construct( $options );
 
-               $this->lang = Language::factory( $this->getOption( 
ValueParser::OPT_LANG ) );
+               $this->defaultOption(
+                       self::OPT_DIGIT_GROUP_SEPARATOR,
+                       self::CANONICAL_DIGIT_GROUP_SEPARATOR
+               );
+
                $this->eraParser = $eraParser ?: new EraParser( $this->options 
);
                $this->isoTimestampParser = new IsoTimestampParser(
                        new CalendarModelParser( $this->options ),
@@ -67,17 +77,13 @@
 
                // Negative dates usually don't have a month, assume non-digits 
are thousands separators
                if ( $sign === '-' ) {
-                       $separatorMap = $this->lang->separatorTransformTable();
-
-                       if ( is_array( $separatorMap ) && array_key_exists( 
',', $separatorMap ) ) {
-                               $separator = $separatorMap[','];
-                       } else {
-                               $separator = ',';
-                       }
-
+                       $separator = $this->getOption( 
self::OPT_DIGIT_GROUP_SEPARATOR );
                        // Always accept ISO (e.g. "1 000 BC") as well as 
programming style (e.g. "-1_000")
-                       $year = preg_replace( '/(?<=\d)[' . preg_quote( 
$separator, '/' ) . '\s_](?=\d)/', '',
-                               $year );
+                       $year = preg_replace(
+                               '/(?<=\d)[' . preg_quote( $separator, '/' ) . 
'\s_](?=\d)/',
+                               '',
+                               $year
+                       );
                }
 
                if ( !preg_match( '/^\d+$/', $year ) ) {
diff --git a/extensions/Wikibase/repo/includes/WikibaseRepo.php 
b/extensions/Wikibase/repo/includes/WikibaseRepo.php
index 4bca1f1..9f85fe6 100644
--- a/extensions/Wikibase/repo/includes/WikibaseRepo.php
+++ b/extensions/Wikibase/repo/includes/WikibaseRepo.php
@@ -18,6 +18,7 @@
 use ValueFormatters\FormatterOptions;
 use ValueFormatters\ValueFormatter;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\InProcessCachingDataTypeLookup;
 use Wikibase\Lib\DataTypeDefinitions;
 use Wikibase\ChangeOp\ChangeOpFactoryProvider;
 use Wikibase\DataModel\DeserializerFactory;
@@ -37,6 +38,7 @@
 use Wikibase\DataModel\Services\Statement\StatementGuidValidator;
 use Wikibase\EditEntityFactory;
 use Wikibase\EntityFactory;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
 use Wikibase\Repo\ParserOutput\EntityParserOutputGeneratorFactory;
 use Wikibase\InternalSerialization\DeserializerFactory as 
InternalDeserializerFactory;
 use Wikibase\InternalSerialization\SerializerFactory as 
InternalSerializerFactory;
@@ -318,6 +320,48 @@
                        new LanguageNameLookup(),
                        $this->getLocalEntityUriParser(),
                        $this->getEntityTitleLookup()
+               );
+       }
+
+       /**
+        * Returns the default WikibaseSnakFormatterBuilders instance.
+        * @warning This is for use with bootstrap code in 
WikibaseRepo.datatypes.php only!
+        * Program logic should use WikibaseRepo::getSnakFormatterFactory() 
instead!
+        *
+        * @since 0.5
+        *
+        * @param string $reset Flag: Pass "reset" to reset the default instance
+        *
+        * @return WikibaseSnakFormatterBuilders
+        */
+       public static function getDefaultSnakFormatterBuilders( $reset = 
'noreset' ) {
+               static $builders;
+
+               if ( $builders === null || $reset === 'reset' ) {
+                       $builders = 
self::getDefaultInstance()->newWikibaseSnakFormatterBuilders(
+                               self::getDefaultFormatterBuilders()
+                       );
+               }
+
+               return $builders;
+       }
+
+       /**
+        * Returns a low level factory object for creating formatters for well 
known data types.
+        *
+        * @warning This is for use with getDefaultFormatterBuilders() during 
bootstrap only!
+        * Program logic should use WikibaseRepo::getSnakFormatterFactory() 
instead!
+        *
+        * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+        *
+        * @return WikibaseSnakFormatterBuilders
+        */
+       private function newWikibaseSnakFormatterBuilders( 
WikibaseValueFormatterBuilders $valueFormatterBuilders ) {
+               return new WikibaseSnakFormatterBuilders(
+                       $valueFormatterBuilders,
+                       $this->getStore()->getPropertyInfoStore(),
+                       $this->getPropertyDataTypeLookup(),
+                       $this->getDataTypeFactory()
                );
        }
 
@@ -1344,7 +1388,9 @@
                        $this->getLanguageFallbackChainFactory(),
                        $templateFactory,
                        $entityDataFormatProvider,
-                       $dataTypeLookup,
+                       // FIXME: Should this be done for all usages of this 
lookup, or is the impact of
+                       // CachingPropertyInfoStore enough?
+                       new InProcessCachingDataTypeLookup( $dataTypeLookup ),
                        $this->getLocalEntityUriParser(),
                        $this->settings->getSetting( 
'preferredGeoDataProperties' ),
                        $this->settings->getSetting( 
'preferredPageImagesProperties' ),
diff --git 
a/extensions/Wikibase/repo/includes/specials/SpecialListDatatypes.php 
b/extensions/Wikibase/repo/includes/specials/SpecialListDatatypes.php
index b40abca..86b36b0 100644
--- a/extensions/Wikibase/repo/includes/specials/SpecialListDatatypes.php
+++ b/extensions/Wikibase/repo/includes/specials/SpecialListDatatypes.php
@@ -56,6 +56,8 @@
                // 'wikibase-listdatatypes-string-body'
                // 'wikibase-listdatatypes-url-head'
                // 'wikibase-listdatatypes-url-body'
+               // 'wikibase-listdatatypes-external-id-head'
+               // 'wikibase-listdatatypes-external-id-body'
 
                foreach ( $this->getDataTypeIds() as $dataTypeId ) {
                        $this->getOutput()->addHTML( 
$this->getHtmlForDataTypeId( $dataTypeId ) );
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/EntityParserOutputGeneratorTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/EntityParserOutputGeneratorTest.php
index d8c64b0..b7d089b 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/EntityParserOutputGeneratorTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/EntityParserOutputGeneratorTest.php
@@ -13,10 +13,10 @@
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\EntityRevision;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 use Wikibase\Lib\Store\Sql\SqlEntityInfoBuilderFactory;
 use Wikibase\Repo\LinkedData\EntityDataFormatProvider;
 use Wikibase\Repo\ParserOutput\EntityParserOutputGenerator;
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ExternalLinksDataUpdaterTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ExternalLinksDataUpdaterTest.php
index 4329efa..7a4b8a1 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ExternalLinksDataUpdaterTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ExternalLinksDataUpdaterTest.php
@@ -24,8 +24,9 @@
         * @return ExternalLinksDataUpdater
         */
        private function newInstance() {
-               $matcher = $this->getMockBuilder( 
'Wikibase\Lib\Store\PropertyDataTypeMatcher' )
-                       ->disableOriginalConstructor()
+               $matcher = $this->getMockBuilder(
+                       
'Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher'
+               )->disableOriginalConstructor()
                        ->getMock();
                $matcher->expects( $this->any() )
                        ->method( 'isMatchingDataType' )
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/GeoDataDataUpdaterTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/GeoDataDataUpdaterTest.php
index 2e20fc0..5abd396 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/GeoDataDataUpdaterTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/GeoDataDataUpdaterTest.php
@@ -11,13 +11,13 @@
 use ParserOutput;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher;
 use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
 use Wikibase\DataModel\Services\Statement\GuidGenerator;
 use Wikibase\DataModel\Snak\PropertySomeValueSnak;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Snak\SnakList;
 use Wikibase\DataModel\Statement\Statement;
-use Wikibase\Lib\Store\PropertyDataTypeMatcher;
 use Wikibase\Repo\ParserOutput\GeoDataDataUpdater;
 
 /**
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ImageLinksDataUpdaterTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ImageLinksDataUpdaterTest.php
index fb8feac..cdc6bb9 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ImageLinksDataUpdaterTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/ImageLinksDataUpdaterTest.php
@@ -24,8 +24,9 @@
         * @return ImageLinksDataUpdater
         */
        private function newInstance() {
-               $matcher = $this->getMockBuilder( 
'Wikibase\Lib\Store\PropertyDataTypeMatcher' )
-                       ->disableOriginalConstructor()
+               $matcher = $this->getMockBuilder(
+                       
'Wikibase\DataModel\Services\Entity\PropertyDataTypeMatcher'
+               )->disableOriginalConstructor()
                        ->getMock();
                $matcher->expects( $this->any() )
                        ->method( 'isMatchingDataType' )
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Parsers/YearTimeParserTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Parsers/YearTimeParserTest.php
index 6f28b6e..a912831 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Parsers/YearTimeParserTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Parsers/YearTimeParserTest.php
@@ -3,6 +3,7 @@
 namespace Wikibase\Repo\Tests\Parsers;
 
 use DataValues\TimeValue;
+use ValueParsers\ParserOptions;
 use ValueParsers\Test\StringValueParserTest;
 use Wikibase\Repo\Parsers\YearTimeParser;
 
@@ -16,6 +17,7 @@
  *
  * @licence GNU GPL v2+
  * @author Adam Shorland
+ * @author Thiemo Mättig
  */
 class YearTimeParserTest extends StringValueParserTest {
 
@@ -90,6 +92,8 @@
                                array( '-1000000-00-00T00:00:00Z', 
TimeValue::PRECISION_YEAR1M, $julian ),
                        '-1 000 000' =>
                                array( '-1000000-00-00T00:00:00Z', 
TimeValue::PRECISION_YEAR1M, $julian ),
+                       '-19_000' =>
+                               array( '-19000-00-00T00:00:00Z', 
TimeValue::PRECISION_YEAR1K, $julian ),
                        // Digit grouping in the Indian numbering system
                        '-1,99,999' =>
                                array( '-199999-00-00T00:00:00Z', 
TimeValue::PRECISION_YEAR, $julian ),
@@ -107,6 +111,14 @@
                }
 
                return $argLists;
+       }
+
+       public function testDigitGroupSeparatorOption() {
+               $options = new ParserOptions();
+               $options->setOption( YearTimeParser::OPT_DIGIT_GROUP_SEPARATOR, 
'.' );
+               $parser = new YearTimeParser( null, $options );
+               $timeValue = $parser->parse( '-19.000' );
+               $this->assertSame( '-19000-00-00T00:00:00Z', 
$timeValue->getTime() );
        }
 
        /**
@@ -132,11 +144,15 @@
                        '+100 BCE',
                        '+100BCE',
 
-                       // Invalid thousands separator
+                       // Non-default and invalid thousands separators
+                       '-,999',
+                       '-999,',
+                       '-19.000',
                        '-1/000/000',
 
                        // Positive years are unlikely to have thousands 
separators, it's more likely a date
                        '1 000 000',
+                       '19_000',
                        '1,99,999',
                );
 
diff --git a/vendor/composer/autoload_classmap.php 
b/vendor/composer/autoload_classmap.php
index d8aa1b8..a74ccbe 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -785,7 +785,6 @@
     'Wikibase\\Lib\\Store\\LabelConflictFinder' => $baseDir . 
'/extensions/Wikibase/lib/includes/store/LabelConflictFinder.php',
     'Wikibase\\Lib\\Store\\LanguageFallbackLabelDescriptionLookup' => $baseDir 
. 
'/extensions/Wikibase/lib/includes/store/LanguageFallbackLabelDescriptionLookup.php',
     'Wikibase\\Lib\\Store\\LanguageFallbackLabelDescriptionLookupFactory' => 
$baseDir . 
'/extensions/Wikibase/lib/includes/store/LanguageFallbackLabelDescriptionLookupFactory.php',
-    'Wikibase\\Lib\\Store\\PropertyDataTypeMatcher' => $baseDir . 
'/extensions/Wikibase/lib/includes/store/PropertyDataTypeMatcher.php',
     'Wikibase\\Lib\\Store\\RevisionBasedEntityLookup' => $baseDir . 
'/extensions/Wikibase/lib/includes/store/RevisionBasedEntityLookup.php',
     'Wikibase\\Lib\\Store\\RevisionedUnresolvedRedirectException' => $baseDir 
. 
'/extensions/Wikibase/lib/includes/store/RevisionedUnresolvedRedirectException.php',
     'Wikibase\\Lib\\Store\\SiteLinkLookup' => $baseDir . 
'/extensions/Wikibase/lib/includes/store/SiteLinkLookup.php',
@@ -828,17 +827,18 @@
     'Wikibase\\Lib\\Test\\TimeDetailsFormatterTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/formatters/TimeDetailsFormatterTest.php',
     'Wikibase\\Lib\\Test\\UnDeserializableValueFormatterTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/formatters/UnDeserializableValueFormatterTest.php',
     'Wikibase\\Lib\\Test\\VocabularyUriFormatterTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/formatters/VocabularyUriFormatterTest.php',
+    'Wikibase\\Lib\\Test\\WikibaseSnakFormatterBuildersTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php',
     'Wikibase\\Lib\\Test\\WikibaseValueFormatterBuildersTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/formatters/WikibaseValueFormatterBuildersTest.php',
     'Wikibase\\Lib\\Tests\\DataTypeDefinitionsTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/DataTypeDefinitionsTest.php',
     'Wikibase\\Lib\\Tests\\Serialization\\CallbackFactoryTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/includes/serialization/CallbackFactoryTest.php',
     'Wikibase\\Lib\\Tests\\Store\\FieldPropertyInfoProviderTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/store/FieldPropertyInfoProviderTest.php',
-    'Wikibase\\Lib\\Tests\\Store\\PropertyDataTypeMatcherTest' => $baseDir . 
'/extensions/Wikibase/lib/tests/phpunit/store/PropertyDataTypeMatcherTest.php',
     'Wikibase\\Lib\\TimeDetailsFormatter' => $baseDir . 
'/extensions/Wikibase/lib/includes/formatters/TimeDetailsFormatter.php',
     'Wikibase\\Lib\\TypedValueFormatter' => $baseDir . 
'/extensions/Wikibase/lib/includes/TypedValueFormatter.php',
     'Wikibase\\Lib\\UnDeserializableValueFormatter' => $baseDir . 
'/extensions/Wikibase/lib/includes/formatters/UnDeserializableValueFormatter.php',
     'Wikibase\\Lib\\UserInputException' => $baseDir . 
'/extensions/Wikibase/lib/includes/UserInputException.php',
     'Wikibase\\Lib\\UserLanguageLookup' => $baseDir . 
'/extensions/Wikibase/lib/includes/UserLanguageLookup.php',
     'Wikibase\\Lib\\VocabularyUriFormatter' => $baseDir . 
'/extensions/Wikibase/lib/includes/formatters/VocabularyUriFormatter.php',
+    'Wikibase\\Lib\\WikibaseSnakFormatterBuilders' => $baseDir . 
'/extensions/Wikibase/lib/includes/formatters/WikibaseSnakFormatterBuilders.php',
     'Wikibase\\Lib\\WikibaseValueFormatterBuilders' => $baseDir . 
'/extensions/Wikibase/lib/includes/formatters/WikibaseValueFormatterBuilders.php',
     'Wikibase\\NamespaceChecker' => $baseDir . 
'/extensions/Wikibase/client/includes/NamespaceChecker.php',
     'Wikibase\\NoLangLinkHandler' => $baseDir . 
'/extensions/Wikibase/client/includes/parserhooks/NoLangLinkHandler.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index a753de3..4f9b97d 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1236,12 +1236,12 @@
         "source": {
             "type": "git",
             "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-            "reference": "ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e"
+            "reference": "b0012d18588ddefc754696aeb09b5f880f2f1dd5"
         },
         "dist": {
             "type": "zip",
-            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e";,
-            "reference": "ec1fc7ec64779f0a7f372b7ddb013f4637dbf47e",
+            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b0012d18588ddefc754696aeb09b5f880f2f1dd5";,
+            "reference": "b0012d18588ddefc754696aeb09b5f880f2f1dd5",
             "shasum": ""
         },
         "require": {
@@ -1273,7 +1273,7 @@
             "jakub-onderka/php-parallel-lint": "0.9",
             "mediawiki/mediawiki-codesniffer": "0.4.0|0.5.0"
         },
-        "time": "2015-12-16 08:26:55",
+        "time": "2015-12-16 21:37:31",
         "type": "mediawiki-extension",
         "installation-source": "dist",
         "autoload": {

-- 
To view, visit https://gerrit.wikimedia.org/r/259648
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I7805e9326b6fa40887c5502d7f476614f7574106
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikidata
Gerrit-Branch: master
Gerrit-Owner: WikidataBuilder <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to